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/CMakeLists.txt | 86 +++ src/backend-dbus/actions.c | 730 +++++++++++++++++++ src/backend-dbus/actions.h | 73 ++ src/backend-dbus/backend-dbus.c | 117 +++ src/backend-dbus/backend-dbus.h | 38 + .../com.canonical.indicators.webcredentials.xml | 82 +++ src/backend-dbus/display-manager.xml | 30 + src/backend-dbus/guest.c | 570 +++++++++++++++ src/backend-dbus/guest.h | 72 ++ src/backend-dbus/org.freedesktop.Accounts.User.xml | 744 +++++++++++++++++++ src/backend-dbus/org.freedesktop.Accounts.xml | 194 +++++ .../org.freedesktop.ConsoleKit.Manager.xml | 353 +++++++++ .../org.freedesktop.ConsoleKit.Seat.xml | 164 +++++ .../org.freedesktop.ConsoleKit.Session.xml | 435 +++++++++++ src/backend-dbus/org.gnome.ScreenSaver.xml | 16 + .../org.gnome.SessionManager.EndSessionDialog.xml | 53 ++ src/backend-dbus/org.gnome.SessionManager.xml | 451 ++++++++++++ src/backend-dbus/session-dbus.xml | 20 + src/backend-dbus/upower.xml | 309 ++++++++ src/backend-dbus/users.c | 810 +++++++++++++++++++++ src/backend-dbus/users.h | 71 ++ src/backend-dbus/utils.c | 399 ++++++++++ src/backend-dbus/utils.h | 53 ++ 23 files changed, 5870 insertions(+) create mode 100644 src/backend-dbus/CMakeLists.txt create mode 100644 src/backend-dbus/actions.c create mode 100644 src/backend-dbus/actions.h create mode 100644 src/backend-dbus/backend-dbus.c create mode 100644 src/backend-dbus/backend-dbus.h create mode 100644 src/backend-dbus/com.canonical.indicators.webcredentials.xml create mode 100644 src/backend-dbus/display-manager.xml create mode 100644 src/backend-dbus/guest.c create mode 100644 src/backend-dbus/guest.h create mode 100644 src/backend-dbus/org.freedesktop.Accounts.User.xml create mode 100644 src/backend-dbus/org.freedesktop.Accounts.xml create mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml create mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml create mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml create mode 100644 src/backend-dbus/org.gnome.ScreenSaver.xml create mode 100644 src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml create mode 100644 src/backend-dbus/org.gnome.SessionManager.xml create mode 100644 src/backend-dbus/session-dbus.xml create mode 100644 src/backend-dbus/upower.xml create mode 100644 src/backend-dbus/users.c create mode 100644 src/backend-dbus/users.h create mode 100644 src/backend-dbus/utils.c create mode 100644 src/backend-dbus/utils.h (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt new file mode 100644 index 0000000..a477cfe --- /dev/null +++ b/src/backend-dbus/CMakeLists.txt @@ -0,0 +1,86 @@ +# autogenerate source code files for our DBus proxies +function(gdbus_codegen XML_FILE INTERFACE_PREFIX SOURCE_PREFIX) + + set (SRC_C, ${SOURCE_PREFIX}.c) + set (SRC_H, ${SOURCE_PREFIX}.h) + + # check for the app + find_program (GDBUS_CODEGEN_EXECUTABLE NAMES gdbus-codegen DOC "gdbus-codegen executable") + if(NOT GDBUS_CODEGEN_EXECUTABLE) + message(FATAL_ERROR "Executable gdbus-codegen not found") + endif() + + # generate the code + add_custom_command ( + OUTPUT ${SOURCE_PREFIX}.c ${SOURCE_PREFIX}.h + COMMAND gdbus-codegen ARGS --interface-prefix ${INTERFACE_PREFIX} --generate-c-code ${SOURCE_PREFIX} ${CMAKE_CURRENT_SOURCE_DIR}/${XML_FILE} + DEPENDS ${XML_FILE}) + + # update our variables + set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_C}) + set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_H}) + set_property (SOURCE ${SRC_C} ${SRC_H} PROPERTY GENERATED) + + # cleanup + unset (SRC_C) + unset (SRC_H) + +endfunction(gdbus_codegen) +gdbus_codegen ("display-manager.xml" "org.freedesktop" "dbus-display-manager") +gdbus_codegen ("com.canonical.indicators.webcredentials.xml" "com.canonical.indicators" "dbus-webcredentials") +gdbus_codegen ("org.freedesktop.Accounts.xml" "org.freedesktop" "dbus-accounts") +gdbus_codegen ("org.freedesktop.Accounts.User.xml" "org.freedesktop" "dbus-user") +gdbus_codegen ("org.freedesktop.ConsoleKit.Manager.xml" "org.freedesktop" "dbus-consolekit-manager") +gdbus_codegen ("org.freedesktop.ConsoleKit.Seat.xml" "org.freedesktop" "dbus-consolekit-seat") +gdbus_codegen ("org.freedesktop.ConsoleKit.Session.xml" "org.freedesktop" "dbus-consolekit-session") +gdbus_codegen ("org.gnome.ScreenSaver.xml" "org" "gnome-screen-saver") +gdbus_codegen ("org.gnome.SessionManager.xml" "org" "gnome-session-manager") +gdbus_codegen ("org.gnome.SessionManager.EndSessionDialog.xml" "org.gnome.SessionManager" "dbus-end-session-dialog") +gdbus_codegen ("upower.xml" "org.freedesktop" "dbus-upower") + +# add warnings/coverage info on handwritten files +# but not the autogenerated ones... +set_source_files_properties (actions.c + backend-dbus.c + guest.c + users.c + utils.c + PROPERTIES COMPILE_FLAGS " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") + +# add the bin dir to our include path s.t. our code can find the autogenerated header files +include_directories (${CMAKE_CURRENT_BINARY_DIR} ${SERVICE_INCLUDE_DIRS}) + +add_library (backenddbus STATIC + gnome-screen-saver.c + gnome-screen-saver.h + gnome-session-manager.c + gnome-session-manager.h + dbus-display-manager.c + dbus-display-manager.h + dbus-consolekit-manager.c + dbus-consolekit-manager.h + dbus-consolekit-seat.c + dbus-consolekit-seat.h + dbus-consolekit-session.c + dbus-consolekit-session.h + dbus-accounts.c + dbus-accounts.h + dbus-upower.c + dbus-upower.h + dbus-user.c + dbus-user.h + dbus-webcredentials.c + dbus-webcredentials.h + dbus-end-session-dialog.c + dbus-end-session-dialog.h + actions.c + actions.h + backend-dbus.c + backend-dbus.h + guest.c + guest.h + users.c + users.h + utils.c + utils.h) + diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c new file mode 100644 index 0000000..8994710 --- /dev/null +++ b/src/backend-dbus/actions.c @@ -0,0 +1,730 @@ +/* + * 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-end-session-dialog.h" +#include "dbus-upower.h" +#include "dbus-webcredentials.h" +#include "gnome-screen-saver.h" +#include "gnome-session-manager.h" + +#include "actions.h" + +enum +{ + END_SESSION_TYPE_LOGOUT = 0, + END_SESSION_TYPE_SHUTDOWN, + END_SESSION_TYPE_REBOOT +}; + +struct _IndicatorSessionActionsDbusPriv +{ + GCancellable * cancellable; + + GSettings * lockdown_settings; + UPower * upower; + GnomeScreenSaver * screen_saver; + GnomeSessionManager * session_manager; + ConsoleKitManager * ck_manager; + ConsoleKitSeat * ck_seat; + DisplayManagerSeat * dm_seat; + Webcredentials * webcredentials; + EndSessionDialog * end_session_dialog; + + gboolean suspend_allowed; + gboolean hibernate_allowed; + gboolean seat_allows_activation; +}; + +typedef IndicatorSessionActionsDbusPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionActionsDbus, + indicator_session_actions_dbus, + INDICATOR_TYPE_SESSION_ACTIONS) + +/*** +**** +***/ + +static void +log_and_clear_error (GError ** err, const char * loc, const char * func) +{ + if (*err) + { + g_warning ("%s %s: %s", loc, func, (*err)->message); + g_clear_error (err); + } +} + +static void +on_can_activate_sessions (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gboolean can_activate_sessions; + + err = NULL; + can_activate_sessions = FALSE; + console_kit_seat_call_can_activate_sessions_finish (CONSOLE_KIT_SEAT(o), + &can_activate_sessions, + res, + &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + p->seat_allows_activation = can_activate_sessions; + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +set_ck_seat (IndicatorSessionActionsDbus * self, ConsoleKitSeat * seat) +{ + priv_t * p = self->priv; + + g_clear_object (&p->ck_seat); + + if (seat != NULL) + { + p->ck_seat = g_object_ref (seat); + + console_kit_seat_call_can_activate_sessions (seat, + p->cancellable, + on_can_activate_sessions, + self); + } +} + +/*** +**** +***/ + +static void +set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * 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 (seat != NULL) + { + p->dm_seat = g_object_ref (seat); + /*g_signal_connect (seat, "notify::has-actions-account", G_CALLBACK(on_notify_has_actions_account), self);*/ + } +} + +static void +on_screensaver_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + GnomeScreenSaver * ss; + + err = NULL; + ss = gnome_screen_saver_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->screen_saver = ss; + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_suspend_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gboolean allowed = FALSE; + + err = NULL; + upower_call_suspend_allowed_finish (UPOWER(o), &allowed, res, &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + + if (p->suspend_allowed != allowed) + { + p->suspend_allowed = allowed; + indicator_session_actions_notify_can_suspend (gself); + } + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_hibernate_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gboolean allowed = FALSE; + + err = NULL; + upower_call_hibernate_allowed_finish (UPOWER(o), &allowed, res, &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + + if (p->hibernate_allowed != allowed) + { + p->hibernate_allowed = allowed; + indicator_session_actions_notify_can_hibernate (gself); + } + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_upower_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + UPower * upower; + + err = NULL; + upower = upower_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + + p->upower = upower; + + g_signal_connect_swapped (upower, "notify::can-suspend", + G_CALLBACK(indicator_session_actions_notify_can_suspend), gself); + + g_signal_connect_swapped (upower, "notify::can-hibernate", + G_CALLBACK(indicator_session_actions_notify_can_hibernate), gself); + + upower_call_suspend_allowed (upower, p->cancellable, on_suspend_allowed_ready, gself); + + upower_call_hibernate_allowed (upower, p->cancellable, on_hibernate_allowed_ready, gself); + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_session_manager_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + GnomeSessionManager * sm; + + err = NULL; + sm = gnome_session_manager_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->session_manager = sm; + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_webcredentials_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + Webcredentials * webcredentials; + + err = NULL; + webcredentials = webcredentials_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->webcredentials = webcredentials; + + g_signal_connect_swapped (webcredentials, "notify::error-status", + G_CALLBACK(indicator_session_actions_notify_has_online_account_error), gself); + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_end_session_dialog_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + EndSessionDialog * end_session_dialog; + + err = NULL; + end_session_dialog = end_session_dialog_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->end_session_dialog = end_session_dialog; + + indicator_session_actions_notify_can_prompt (INDICATOR_SESSION_ACTIONS(gself)); + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +/*** +**** Virtual Functions +***/ + +static gboolean +my_can_lock (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return !g_settings_get_boolean (p->lockdown_settings, "disable-lock-screen"); +} + +static gboolean +my_can_logout (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return !g_settings_get_boolean (p->lockdown_settings, "disable-log-out"); +} + +static gboolean +my_can_switch (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p->seat_allows_activation + && !g_settings_get_boolean (p->lockdown_settings, "disable-user-switching"); +} + +static gboolean +my_can_suspend (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p && p->upower && p->suspend_allowed && upower_get_can_suspend (p->upower); +} + +static gboolean +my_can_hibernate (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p && p->upower && p->hibernate_allowed && upower_get_can_hibernate (p->upower); +} + +static gboolean +my_can_prompt (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return (p != NULL) + && (p->end_session_dialog != NULL) + && (g_dbus_proxy_get_name_owner (G_DBUS_PROXY(p->end_session_dialog)) != NULL); +} + +static gboolean +my_has_online_account_error (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p && (p->webcredentials) && (webcredentials_get_error_status (p->webcredentials)); +} + +static void +my_suspend (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->upower != NULL); + + upower_call_suspend (p->upower, p->cancellable, NULL, NULL); +} + +static void +my_hibernate (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->upower != NULL); + + upower_call_hibernate (p->upower, p->cancellable, NULL, NULL); +} + +/*** +**** End Session Dialog +***/ + +static void +logout_now (IndicatorSessionActions * self, gboolean try_to_prompt) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + const int type = try_to_prompt ? 0 : 1; + + g_return_if_fail (p->session_manager != NULL); + + gnome_session_manager_call_logout (p->session_manager, + type, + p->cancellable, + NULL, + NULL); +} + +static void +logout_now_with_prompt (IndicatorSessionActions * self) +{ + logout_now (self, TRUE); +} + +static void +logout_now_quietly (IndicatorSessionActions * self) +{ + logout_now (self, FALSE); +} + +static void +restart_now (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->ck_manager != NULL); + + console_kit_manager_call_restart (p->ck_manager, p->cancellable, NULL, NULL); +} + +static void +shutdown_now (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->ck_manager != NULL); + + console_kit_manager_call_stop (p->ck_manager, p->cancellable, NULL, NULL); +} + +static void +stop_listening_to_dialog (IndicatorSessionActionsDbus * self) +{ + g_signal_handlers_disconnect_by_data (self->priv->end_session_dialog, self); +} +static void +on_end_session_dialog_canceled (IndicatorSessionActionsDbus * self) +{ + stop_listening_to_dialog (self); +} +static void +on_end_session_dialog_closed (IndicatorSessionActionsDbus * self) +{ + stop_listening_to_dialog (self); +} + +static void +on_open_end_session_dialog_ready (GObject * o, + GAsyncResult * res, + gpointer gself G_GNUC_UNUSED) +{ + GError * err = NULL; + end_session_dialog_call_open_finish (END_SESSION_DIALOG(o), res, &err); + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + gpointer o = p->end_session_dialog; + const char * inhibitor_paths[] = { NULL }; + + g_assert (o != NULL); + + g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now_quietly), self); + g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(restart_now), self); + g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(shutdown_now), self); + g_signal_connect_swapped (o, "canceled", G_CALLBACK(on_end_session_dialog_canceled), self); + g_signal_connect_swapped (o, "closed", G_CALLBACK(on_end_session_dialog_closed), self); + + end_session_dialog_call_open (p->end_session_dialog, type, 0, 0, inhibitor_paths, + p->cancellable, + on_open_end_session_dialog_ready, + self); +} + +static void +my_logout (IndicatorSessionActions * self) +{ + if (my_can_prompt (self)) + show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_LOGOUT); + else + logout_now_with_prompt (self); +} + + +static void +my_restart (IndicatorSessionActions * self) +{ + if (my_can_prompt (self)) + show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); + else + restart_now (self); +} + +static void +my_shutdown (IndicatorSessionActions * self) +{ + /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because + the latter adds lock & logout options in Unity... */ + if (my_can_prompt (self)) + show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); + else + shutdown_now (self); +} + +/*** +**** +***/ + +static void +run_outside_app (const char * cmd) +{ + GError * err = NULL; + g_debug ("%s calling \"%s\"", G_STRFUNC, cmd); + g_spawn_command_line_async (cmd, &err); + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +my_help (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("yelp"); +} + +static void +my_settings (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("gnome-control-center"); +} + +static void +my_about (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("gnome-control-center info"); +} + +/*** +**** +***/ + +static void +my_switch_to_screensaver (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->screen_saver != NULL); + + gnome_screen_saver_call_lock (p->screen_saver, p->cancellable, NULL, NULL); +} + +static void +my_switch_to_greeter (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_greeter (p->dm_seat, p->cancellable, + NULL, NULL); +} + +static void +my_switch_to_guest (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_guest (p->dm_seat, "", + p->cancellable, + NULL, NULL); +} + +static void +my_switch_to_username (IndicatorSessionActions * self, const char * username) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_user (p->dm_seat, username, "", + p->cancellable, + NULL, NULL); +} + +static void +my_dispose (GObject * o) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (o); + priv_t * p = self->priv; + + if (p->cancellable != NULL) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + + g_clear_object (&p->lockdown_settings); + g_clear_object (&p->ck_manager); + g_clear_object (&p->upower); + g_clear_object (&p->screen_saver); + g_clear_object (&p->session_manager); + g_clear_object (&p->webcredentials); + g_clear_object (&p->end_session_dialog); + set_dm_seat (self, NULL); + set_ck_seat (self, NULL); + + G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + /*IndicatorSessionActionsDbus * u = INDICATOR_SESSION_ACTIONS_DBUS (o);*/ + + G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->finalize (o); +} + +/*** +**** GObject Boilerplate +***/ + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionActionsClass * actions_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); + actions_class->can_lock = my_can_lock; + actions_class->can_logout = my_can_logout; + actions_class->can_switch = my_can_switch; + actions_class->can_suspend = my_can_suspend; + actions_class->can_hibernate = my_can_hibernate; + actions_class->can_prompt = my_can_prompt; + actions_class->has_online_account_error = my_has_online_account_error; + actions_class->logout = my_logout; + actions_class->suspend = my_suspend; + actions_class->hibernate = my_hibernate; + actions_class->restart = my_restart; + actions_class->shutdown = my_shutdown; + actions_class->settings = my_settings; + actions_class->help = my_help; + actions_class->about = my_about; + actions_class->switch_to_screensaver = my_switch_to_screensaver; + actions_class->switch_to_greeter = my_switch_to_greeter; + actions_class->switch_to_guest = my_switch_to_guest; + actions_class->switch_to_username = my_switch_to_username; + + g_type_class_add_private (klass, sizeof (IndicatorSessionActionsDbusPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) +{ + priv_t * p; + GSettings * s; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_ACTIONS_DBUS, + IndicatorSessionActionsDbusPriv); + p->cancellable = g_cancellable_new (); + p->seat_allows_activation = TRUE; + self->priv = p; + + s = g_settings_new ("org.gnome.desktop.lockdown"); + g_signal_connect_swapped (s, "changed::disable-lock-screen", + G_CALLBACK(indicator_session_actions_notify_can_lock), self); + g_signal_connect_swapped (s, "changed::disable-log-out", + G_CALLBACK(indicator_session_actions_notify_can_logout), self); + g_signal_connect_swapped (s, "changed::disable-user-switching", + G_CALLBACK(indicator_session_actions_notify_can_switch), self); + p->lockdown_settings = s; + + gnome_screen_saver_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.ScreenSaver", + "/org/gnome/ScreenSaver", + p->cancellable, + on_screensaver_proxy_ready, + self); + + upower_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.UPower", + "/org/freedesktop/UPower", + p->cancellable, + on_upower_proxy_ready, + self); + + gnome_session_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + p->cancellable, + on_session_manager_proxy_ready, + self); + + webcredentials_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "com.canonical.indicators.webcredentials", + "/com/canonical/indicators/webcredentials", + p->cancellable, + on_webcredentials_proxy_ready, + self); + + end_session_dialog_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "com.canonical.Unity", + "/org/gnome/SessionManager/EndSessionDialog", + p->cancellable, + on_end_session_dialog_proxy_ready, + self); +} + +/*** +**** Public +***/ + +IndicatorSessionActions * +indicator_session_actions_dbus_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_ACTIONS_DBUS, NULL); + + return INDICATOR_SESSION_ACTIONS (o); +} + +void +indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, + ConsoleKitManager * ck_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * ck_seat) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS_DBUS(self)); + + self->priv->ck_manager = g_object_ref (ck_manager); + + set_dm_seat (self, dm_seat); + + set_ck_seat (self, ck_seat); +} diff --git a/src/backend-dbus/actions.h b/src/backend-dbus/actions.h new file mode 100644 index 0000000..997dd73 --- /dev/null +++ b/src/backend-dbus/actions.h @@ -0,0 +1,73 @@ +/* + * 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 . + */ + +#ifndef __INDICATOR_SESSION_ACTIONS_DBUS_H__ +#define __INDICATOR_SESSION_ACTIONS_DBUS_H__ + +#include +#include + +#include "../actions.h" /* parent class */ +#include "dbus-accounts.h" +#include "dbus-consolekit-manager.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-display-manager.h" + + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_ACTIONS_DBUS (indicator_session_actions_dbus_get_type()) +#define INDICATOR_SESSION_ACTIONS_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_ACTIONS_DBUS, IndicatorSessionActionsDbus)) +#define INDICATOR_SESSION_ACTIONS_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_ACTIONS_DBUS, IndicatorSessionActionsDbusClass)) +#define INDICATOR_IS_SESSION_ACTIONS_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_ACTIONS_DBUS)) + +typedef struct _IndicatorSessionActionsDbus IndicatorSessionActionsDbus; +typedef struct _IndicatorSessionActionsDbusPriv IndicatorSessionActionsDbusPriv; +typedef struct _IndicatorSessionActionsDbusClass IndicatorSessionActionsDbusClass; + +/** + * An implementation of IndicatorSessionActions that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionActionsDbus +{ + /*< private >*/ + IndicatorSessionActions parent; + IndicatorSessionActionsDbusPriv * priv; +}; + +struct _IndicatorSessionActionsDbusClass +{ + IndicatorSessionActionsClass parent_class; +}; + +GType indicator_session_actions_dbus_get_type (void); + +IndicatorSessionActions * indicator_session_actions_dbus_new (void); + +void indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, + ConsoleKitManager * ck_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * ck_seat); + + +G_END_DECLS + +#endif /* __INDICATOR_SESSION_ACTIONS_DBUS_H__ */ diff --git a/src/backend-dbus/backend-dbus.c b/src/backend-dbus/backend-dbus.c new file mode 100644 index 0000000..ea8f0ec --- /dev/null +++ b/src/backend-dbus/backend-dbus.c @@ -0,0 +1,117 @@ +/* + * 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 "actions.h" +#include "backend-dbus.h" +#include "guest.h" +#include "users.h" +#include "utils.h" + +struct dbus_world_data +{ + GCancellable * cancellable; + IndicatorSessionActionsDbus * actions; + IndicatorSessionUsersDbus * users; + IndicatorSessionGuestDbus * guest; +}; + +static void +on_proxies_ready (ConsoleKitManager * ck_manager, + Accounts * account_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * ck_seat, + ConsoleKitSession * ck_session, + AccountsUser * active_user G_GNUC_UNUSED, + const GError * error, + gpointer gdata) +{ + struct dbus_world_data * data = gdata; + + if (error == NULL) + { + if (data->actions != NULL) + indicator_session_actions_dbus_set_proxies (data->actions, + ck_manager, + dm_seat, + ck_seat); + + if (data->users != NULL) + indicator_session_users_dbus_set_proxies (data->users, + account_manager, + dm_seat, + ck_seat); + + if (data->guest != NULL) + indicator_session_guest_dbus_set_proxies (data->guest, + account_manager, + dm_seat, + ck_seat, + ck_session); + } + + g_free (data); +} + +/*** +**** +***/ + +void +backend_get (GCancellable * cancellable, + IndicatorSessionActions ** setme_actions, + IndicatorSessionUsers ** setme_users, + IndicatorSessionGuest ** setme_guest) +{ + struct dbus_world_data * data; + + data = g_new0 (struct dbus_world_data, 1); + + if (setme_actions != NULL) + { + IndicatorSessionActions * actions; + actions = indicator_session_actions_dbus_new (); + data->actions = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + *setme_actions = actions; + } + + if (setme_users != NULL) + { + IndicatorSessionUsers * users; + users = indicator_session_users_dbus_new (); + data->users = INDICATOR_SESSION_USERS_DBUS (users); + + *setme_users = users; + } + + if (setme_guest != NULL) + { + IndicatorSessionGuest * guest; + guest = indicator_session_guest_dbus_new (); + data->guest = INDICATOR_SESSION_GUEST_DBUS (guest); + + *setme_guest = guest; + } + + data->cancellable = g_object_ref (cancellable); + + indicator_session_util_get_session_proxies (on_proxies_ready, + data->cancellable, + data); +} diff --git a/src/backend-dbus/backend-dbus.h b/src/backend-dbus/backend-dbus.h new file mode 100644 index 0000000..daf6ac3 --- /dev/null +++ b/src/backend-dbus/backend-dbus.h @@ -0,0 +1,38 @@ +/* + * 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 . + */ + +#ifndef __INDICATOR_SESSION_BACKEND_DESKTOP_H__ +#define __INDICATOR_SESSION_BACKEND_DESKTOP_H__ + +#include /* GCancellable */ + +#include "../actions.h" +#include "../guest.h" +#include "../users.h" + +G_BEGIN_DECLS + +void backend_get (GCancellable * cancellable, + IndicatorSessionActions ** setme_actions, + IndicatorSessionUsers ** setme_users, + IndicatorSessionGuest ** setme_guest); + +G_END_DECLS + +#endif diff --git a/src/backend-dbus/com.canonical.indicators.webcredentials.xml b/src/backend-dbus/com.canonical.indicators.webcredentials.xml new file mode 100644 index 0000000..d215081 --- /dev/null +++ b/src/backend-dbus/com.canonical.indicators.webcredentials.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/display-manager.xml b/src/backend-dbus/display-manager.xml new file mode 100644 index 0000000..07b5f29 --- /dev/null +++ b/src/backend-dbus/display-manager.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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); +} diff --git a/src/backend-dbus/guest.h b/src/backend-dbus/guest.h new file mode 100644 index 0000000..03b6b28 --- /dev/null +++ b/src/backend-dbus/guest.h @@ -0,0 +1,72 @@ +/* + * 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 . + */ + +#ifndef __GUEST_DBUS_H__ +#define __GUEST_DBUS_H__ + +#include +#include + +#include "../guest.h" /* parent class */ +#include "dbus-accounts.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-display-manager.h" + + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_GUEST_DBUS (indicator_session_guest_dbus_get_type()) +#define INDICATOR_SESSION_GUEST_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_GUEST_DBUS, IndicatorSessionGuestDbus)) +#define INDICATOR_SESSION_GUEST_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_GUEST_DBUS, IndicatorSessionGuestDbusClass)) +#define INDICATOR_IS_SESSION_GUEST_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_GUEST_DBUS)) + +typedef struct _IndicatorSessionGuestDbus IndicatorSessionGuestDbus; +typedef struct _IndicatorSessionGuestDbusPriv IndicatorSessionGuestDbusPriv; +typedef struct _IndicatorSessionGuestDbusClass IndicatorSessionGuestDbusClass; + +/** + * An implementation of IndicatorSessionGuest that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionGuestDbus +{ + /*< private >*/ + IndicatorSessionGuest parent; + IndicatorSessionGuestDbusPriv * priv; +}; + +struct _IndicatorSessionGuestDbusClass +{ + IndicatorSessionGuestClass parent_class; +}; + +GType indicator_session_guest_dbus_get_type (void); + +IndicatorSessionGuest * indicator_session_guest_dbus_new (void); + +void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus *, + Accounts *, + DisplayManagerSeat *, + ConsoleKitSeat *, + ConsoleKitSession *); + +G_END_DECLS + +#endif diff --git a/src/backend-dbus/org.freedesktop.Accounts.User.xml b/src/backend-dbus/org.freedesktop.Accounts.User.xml new file mode 100644 index 0000000..53f54d4 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.Accounts.User.xml @@ -0,0 +1,744 @@ + + + + + + + + + + + The new username. + + + + + + + Sets the users username. Note that it is usually not allowed + to have multiple users with the same username. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the username of any user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new name, typically in the form "Firstname Lastname". + + + + + + + Sets the users real name. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own name + + + org.freedesktop.accounts.user-administration + To change the name of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new email address. + + + + + + + Sets the users email address. + + + Note that setting an email address in the AccountsService is + not the same as configuring a mail client. Mail clients might + default to email address that is configured here, though. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own email address + + + org.freedesktop.accounts.user-administration + To change the email address of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new language, as a locale specification like "de_DE.UTF-8". + + + + + + + Sets the users language. + + + The expectation is that display managers will start the + users session with this locale. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own language + + + org.freedesktop.accounts.user-administration + To change the language of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + + The new xsession to start (e.g. "gnome") + + + + + + + Sets the users x session. + + + The expectation is that display managers will log the user in to this + specified session, if available. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own language + + + org.freedesktop.accounts.user-administration + To change the language of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new location as a freeform string. + + + + + + + Sets the users location. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own location + + + org.freedesktop.accounts.user-administration + To change the location of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new homedir as an absolute path. + + + + + + + Sets the users home directory. + + + Note that changing the users home directory moves all the content + from the old location to the new one, and is potentially an + expensive operation. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the home directory of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new user shell. + + + + + + + Sets the users shell. + + + Note that setting the shell to a non-allowed program may + prevent the user from logging in. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the shell of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The absolute filename of a png file to use as the users icon. + + + + + + + Sets the users icon. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own icon + + + org.freedesktop.accounts.user-administration + To change the icon of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + Whether to lock or unlock the users account. + + + + + + + Locks or unlocks a users account. + + + Locking an account prevents the user from logging in. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To lock or unlock user accounts + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new account type, encoded as an integer: + + + 0 + Standard user + + + 1 + Administrator + + + + + + + + + Changes the users account type. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change an account type + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new password mode, encoded as an integer: + + + 0 + Regular password + + + 1 + Password must be set at next login + + + 2 + No password + + + + + + + + + Changes the users password mode. + + + Note that changing the password mode has the side-effect of + unlocking the account. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change a users password mode + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The crypted password. + + + + + + + The password hint. + + + + + + + Sets a new password for this user. + + + Note that setting a password has the side-effect of + unlocking the account. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the password of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + Whether to enable automatic login for this user. + + + + + + + Enables or disables automatic login for a user. + + + Note that usually only one user can have automatic login + enabled, so turning it on for a user will disable it for + the previously configured autologin user. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.set-login-option + To change the login screen configuration + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + The uid of the user. + + + + + + + + + + The username of the user. + + + + + + + + + + The users real name. + + + + + + + + + + The users account type, encoded as an integer: + + + 0 + Standard user + + + 1 + Administrator + + + + + + + + + + + + The users home directory. + + + + + + + + + + The users shell. + + + + + + + + + + The email address. + + + + + + + + + + The users language, as a locale specification like "de_DE.UTF-8". + + + + + + + + + + The users x session. + + + + + + + + + + The users location. + + + + + + + + + + How often the user has logged in. + + + + + + + + + + The filename of a png file containing the users icon. + + + + + + + + + + Whether the users account is locked. + + + + + + + + + + The password mode for the user account, encoded as an integer: + + + 0 + Regular password + + + 1 + Password must be set at next login + + + 2 + No password + + + + + + + + + + + + The password hint for the user. + + + + + + + + + + Whether automatic login is enabled for the user. + + + + + + + + + + Whether this is a 'system' account, like 'root' or 'nobody'. + System accounts should normally not appear in lists of + users, and ListCachedUsers will not include such accounts. + + + + + + + + + + Emitted when the user is changed. + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.Accounts.xml b/src/backend-dbus/org.freedesktop.Accounts.xml new file mode 100644 index 0000000..9c19761 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.Accounts.xml @@ -0,0 +1,194 @@ + + + + + + + + + + Object paths of cached users + + + + + + Lists users which have logged into the system locally before. + This is not meant to return an exhaustive list of all users. + It is possible for FindUserByName() + to return a user that's not on the list. + + + + + + + + + The uid to look up + + + Object path of user + + + + + + Finds a user by uid. + + + + if no user with the given uid exists + + + + + + + + The username to look up + + + Object path of user + + + + + + Finds a user by its username. + + + + if no user with the given username exists + + + + + + + + The username for the new user + + + + The real name for the new user + + + Object path of the new user + + + + The account type, encoded as an integer + + + + + + Creates a new user account. + + + The accountType argument can take the following values: + + + + 0 + Standard user + + + 1 + Administrator + + + 2 + Supervised user + + + + + The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + The uid to delete + + + Whether to remove the users files + + + + + + Deletes a user account. + + + + The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + Object path of the user that was added. + + + + + Emitted when a user is added. + + + + + + + + Object path of the user that was deleted. + + + + + Emitted when a user is deleted. + + + + + + + + Object path of the user that was changed. + + + + + Emitted when a user is changed. + + + + + + + + + + The version of the running daemon. + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml new file mode 100644 index 0000000..f903b55 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml @@ -0,0 +1,353 @@ + + + + + + + + + This method initiates a request to restart (ie. reboot) the computer system. + + + + + + + + + + + + + + This method initiates a request to stop (ie. shutdown) the computer system. + + + + + + + + + + + + + + The secret cookie that is used to identify the new session + + + + + This method requests that a new Session + be created for the calling process. The properties of this new Session are set automatically + from information collected about the calling process. + + This new session exists until the calling process disconnects from the system bus or + calls CloseSession(). + + It is the responsibility of the calling process to set the environment variable + XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only + be made available to child processes of the caller so that they may be identified + as members of this session. + + See this simple example: + + DBusError error; + DBusMessage *message; + DBusMessage *reply; + + message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + "OpenSession"); + if (message == NULL) { + goto out; + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connector->connection, + message, + -1, + &error); + if (reply == NULL) { + goto out; + } + + dbus_error_init (&error); + if (! dbus_message_get_args (reply, + &error, + DBUS_TYPE_STRING, &cookie, + DBUS_TYPE_INVALID)) { + goto out; + } + + + + OpenSessionWithParameters() + + + + + + + An array of sets of property names and values + + + + + The secret cookie that is used to identify the new session + + + + + This method requests that a new Session + be created for the calling process. The properties of this new Session are from the + parameters provided. + + This new session exists until the calling process disconnects from the system bus or + calls CloseSession(). + + It is the responsibility of the calling process to set the environment variable + XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only + be made available to child processes of the caller so that they may be identified + as members of this session. + + See the Session properties for a list of valid parameters. + + org.freedesktop.ConsoleKit.Session + This method is restricted to privileged users by D-Bus policy. + + + + + + + The secret cookie that is used to identify the session + + + + + Whether the session was successfully closed + + + + + This method is used to close the session identified by the supplied cookie. + + The session can only be closed by the same process that opened the session. + + + + + + + + + an array of Seat IDs + + + + + This gets a list of all the Seats + that are currently present on the system. + Each Seat ID is an D-Bus object path for the object that implements the + Seat interface. + + org.freedesktop.ConsoleKit.Seat + + + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently present on the system. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + org.freedesktop.ConsoleKit.Session + + + + + + + + The secret cookie that is used to identify the session + + + + + The object identifier for the current session + + + + + Returns the session ID that is associated with the specified cookie. + + + + + + + + + The POSIX process ID + + + + + The object identifier for the current session + + + + + Attempts to determine the session ID for the specified + POSIX process ID (pid). + + + + + + + + + The object identifier for the current session + + + + + Attempts to determine the session ID that the caller belongs to. + + See this example of using dbus-send: + + dbus-send --system --dest=org.freedesktop.ConsoleKit \ + --type=method_call --print-reply --reply-timeout=2000 \ + /org/freedesktop/ConsoleKit/Manager \ + org.freedesktop.ConsoleKit.Manager.GetCurrentSession + + + + + + + + + POSIX User identification + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently open for the specified user. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + + + + + + + User identification + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently open for the specified user. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + + + + + + + + The value of the system-idle-hint + + + + + Returns TRUE if the idle-hint + property of every open session is TRUE or if there are no open sessions. + + + + + + + + An ISO 8601 format date-type string + + + + + Returns an ISO 8601 date-time string that corresponds to + the time of the last change of the system-idle-hint. + + + + + + + + + The Seat ID for the added seat + + + + + Emitted when a Seat has been added to the system. + + + + + + + + The Seat ID for the removed seat + + + + + Emitted when a Seat has been removed from the system. + + + + + + + + The value of the system-idle-hint + + + + + Emitted when the value of the system-idle-hint has changed. + + + + + + diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml new file mode 100644 index 0000000..58c2ce7 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml @@ -0,0 +1,164 @@ + + + + + + + A seat is a collection of sessions and a set of hardware (usually at +least a keyboard and mouse). Only one session may be active on a +seat at a time. + + + + + + + Seat ID + + + + + Returns the ID for Seat. + + + + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently attached to this seat. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + + + + + + + an array of devices + + + + + This gets a list of all the devices + that are currently associated with this seat. + Each device is an D-Bus structure that represents + the device type and the device id. + + + + + + + + + Session ID + + + + + Gets the Session ID that is currently active on this Seat. + Returns NULL if there is no active session. + + + + + + + + TRUE if seat supports session activation + + + + Used to determine whether the seat supports session activation. + + + + + + + + + Session ID + + + + + Attempt to activate the specified session. In most + cases, if successful, this will cause the session to + become visible and take control of the hardware that is + associated with this seat. + + Activate() + + + + + + + Session ID + + + + + Emitted when the active session has changed. + + + + + + + Session ID + + + + + Emitted when a session has been added to the seat. + + + + + + + Session ID + + + + + Emitted when a session has been removed from the seat. + + + + + + + Device structure + + + + + Emitted when a device has been associated with the seat. + + + + + + + Device structure + + + + + Emitted when a device has been dissociated from the seat. + + + + + diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml new file mode 100644 index 0000000..b6e1cdb --- /dev/null +++ b/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml @@ -0,0 +1,435 @@ + + + + + + + Session objects represent and store information + related to a user session. + + The properties associated with the Session + specifically refer to the properties of the "session leader". + + + + + + + Session ID + + + + Returns the ID for Session. + + + + + + + Seat ID + + + + Returns the ID for the Seat the Session is + attached to. + + org.freedesktop.ConsoleKit.Seat + + + + + + Session type + + + + + Returns the type of the session. + Warning: we haven't yet defined the allowed values for this property. + It is probably best to avoid this until we do. + + + session-type + + + + + + User ID + + + + Returns the user that the session belongs to. + + + user + + + + + + POSIX User ID + + + + Returns the POSIX user ID that the session belongs to. + + unix-user + + + + + + The value of the X11 display + + + + Returns the value of the X11 DISPLAY for this session + if one is present. + + x11-display + + + + + + The value of the X11 display device + + + + Returns the value of the display device (aka TTY) that the + X11 display for the session is connected to. If there is no x11-display set then this value + is undefined. + + x11-display-device + + + + + + The value of the display device + + + + Returns the value of the display device (aka TTY) that the + session is connected to. + + display-device + + + + + + The remote host name + + + + Returns the value of the remote host name for the session. + + + remote-host-name + + + + + + The value of the native system login session ID + + + + Returns the value of the login session ID that the + underlying system uses to enforce session boundaries. If there is no login session ID + set then this value is an empty string. + + + + + + + TRUE if the session is active, otherwise FALSE + + + + Returns whether the session is active on the Seat that + it is attached to. + If the session is not attached to a seat this value is undefined. + + + active + + + + + + TRUE if the session is local, otherwise FALSE + + + + Returns whether the session is local + FIXME: we need to come up with a concrete definition for this value. + It was originally used as a way to identify XDMCP sessions that originate + from a remote system. + + + is-local + + + + + + An ISO 8601 format date-type string + + + + + Returns an ISO 8601 date-time string that corresponds to + the time that the session was opened. + + + + + + + + + + Attempt to activate the this session. In most + cases, if successful, this will cause the session to + become visible and become active on the seat that it + is attached to. + + Seat.ActivateSession() + + + + + + + This will cause a Lock + signal to be emitted for this session. + + + This method is restricted to privileged users by D-Bus policy. + Lock signal + + + + + + + This will cause an Unlock + signal to be emitted for this session. + + This can be used by login managers to unlock a session before it is + re-activated during fast-user-switching. + + + This method is restricted to privileged users by D-Bus policy. + Unlock signal + + + + + + + The value of the idle-hint + + + + + Gets the value of the idle-hint + property. + + + idle-hint + + + + + + An ISO 8601 format date-type string + + + + + Returns an ISO 8601 date-time string that corresponds to + the time of the last change of the idle-hint. + + + + + + + + + boolean value to set the idle-hint to + + + + + This may be used by the session to indicate that + it is idle. + + Use of this method is restricted to the user + that owns the session. + + + + + + + + TRUE if the session is active, otherwise FALSE + + + + + Emitted when the active property has changed. + + + + + + + the new value of idle-hint + + + + + Emitted when the idle-hint property has changed. + + + + + + + Emitted in response to a call to the Lock() method. + It is intended that the screensaver for the session should lock the screen in response to this signal. + + + + + + + Emitted in response to a call to the Unlock() method. + It is intended that the screensaver for the session should unlock the screen in response to this signal. + + + + + + + + The user assigned to the session. + + + + + + + The user assigned to the session. + + + + + + + + The type of the session. + Warning: we haven't yet defined the allowed values for this property. + It is probably best to avoid this until we do. + + + + + + + + The remote host name for the session. + + This will be set in situations where the session is + opened and controlled from a remote system. + + For example, this value will be set when the + session is created from an SSH or XDMCP connection. + + + + + + + + The display device (aka TTY) that the + session is connected to. + + + + + + + + Value of the X11 DISPLAY for this session + if one is present. + + + + + + + + + The display device (aka TTY) that the X11 display for the + session is connected to. If there is no x11-display set then + this value is undefined. + + + + + + + + + Whether the session is active on the Seat that + it is attached to. + If the session is not attached to a seat this value is undefined. + + + + + + + + + Whether the session is local + FIXME: we need to come up with a concrete definition for this value. + It was originally used as a way to identify XDMCP sessions that originate + from a remote system. + + + + + + + + + This is a hint used to indicate that the session may be idle. + + + For sessions with a x11-display set (ie. graphical + sessions), it is up to each session to delegate the + responsibility for updating this value. Typically, the + screensaver will set this. + + However, for non-graphical sessions with a display-device set + the Session object itself will periodically update this value based + on the activity detected on the display-device itself. + + + This should not be considered authoritative. + + + + + + + diff --git a/src/backend-dbus/org.gnome.ScreenSaver.xml b/src/backend-dbus/org.gnome.ScreenSaver.xml new file mode 100644 index 0000000..c21fdc5 --- /dev/null +++ b/src/backend-dbus/org.gnome.ScreenSaver.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml b/src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml new file mode 100644 index 0000000..5392de0 --- /dev/null +++ b/src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml @@ -0,0 +1,53 @@ + + + + + + + + + The type of dialog to show. + 0 for logout, 1 for shutdown, 2 for restart. + + + + + + + Timestamp of the user-initiated event which triggered + the call, or 0 if the call was not triggered by an event. + + + + + + + The number of seconds which the dialog should stay open + before automatic action is taken. + + + + + + + The object paths of all inhibitors that are registered + for the action. + + + + + + This function opens a dialog which asks the user for confirmation + of a logout, poweroff or reboot action. The dialog has a timeout + after which the action is automatically taken, and it should show + the inhibitors to the user. + + + + + + + + + + diff --git a/src/backend-dbus/org.gnome.SessionManager.xml b/src/backend-dbus/org.gnome.SessionManager.xml new file mode 100644 index 0000000..eb69180 --- /dev/null +++ b/src/backend-dbus/org.gnome.SessionManager.xml @@ -0,0 +1,451 @@ + + + + + + + + + + + The variable name + + + + + The value + + + + + Adds the variable name to the application launch environment with the specified value. May only be used during the Session Manager initialization phase. + + + + + + + + The locale category + + + + + The value + + + + + Reads the current state of the specific locale category. + + + + + + + + The error message + + + + + Whether the error should be treated as fatal + + + + + May be used by applications launched during the Session Manager initialization phase to indicate there was a problem. + + + + + + + + + + + The application identifier + + + + + Client startup identifier + + + + + The object path of the newly registered client + + + + + Register the caller as a Session Management client. + + + + + + + + + The object path of the client + + + + + Unregister the specified client from Session Management. + + + + + + + + + The application identifier + + + + + The toplevel X window identifier + + + + + The reason for the inhibit + + + + + Flags that specify what should be inhibited + + + + + The cookie + + + + + Proactively indicates that the calling application is performing an action that should not be interrupted and sets a reason to be displayed to the user when an interruption is about to take placea. + + + Applications should invoke this method when they begin an operation that + should not be interrupted, such as creating a CD or DVD. The types of actions + that may be blocked are specified by the flags parameter. When the application + completes the operation it should call Uninhibit() + or disconnect from the session bus. + + + Applications should not expect that they will always be able to block the + action. In most cases, users will be given the option to force the action + to take place. + + + Reasons should be short and to the point. + + + The flags parameter must include at least one of the following: + + + 1 + Inhibit logging out + + + 2 + Inhibit user switching + + + 4 + Inhibit suspending the session or computer + + + 8 + Inhibit the session being marked as idle + + + 16 + Inhibit auto-mounting removable media for the session + + + Values for flags may be bitwise or'ed together. + + + The returned cookie is used to uniquely identify this request. It should be used + as an argument to Uninhibit() in + order to remove the request. + + + + + + + + + + The cookie + + + + + Cancel a previous call to Inhibit() identified by the cookie. + + + + + + + + Flags that spefify what should be inhibited + + + + + Returns TRUE if any of the operations in the bitfield flags are inhibited + + + + + Determine if operation(s) specified by the flags + are currently inhibited. Flags are same as those accepted + by the + Inhibit() + method. + + + + + + + + an array of client IDs + + + + + This gets a list of all the Clients + that are currently known to the session manager. + Each Client ID is an D-Bus object path for the object that implements the + Client interface. + + org.gnome.SessionManager.Client + + + + + + + an array of inhibitor IDs + + + + + This gets a list of all the Inhibitors + that are currently known to the session manager. + Each Inhibitor ID is an D-Bus object path for the object that implements the + Inhibitor interface. + + org.gnome.SessionManager.Inhibitor + + + + + + + + The autostart condition string + + + + + True if condition is handled, false otherwise + + + + + Allows the caller to determine whether the session manager is + handling changes to the specified autostart condition. + + + + + + + + Request a shutdown dialog. + + + + + + + + Request a reboot dialog. + + + + + + + + True if shutdown is available to the user, false otherwise + + + + + Allows the caller to determine whether or not it's okay to show + a shutdown option in the UI + + + + + + + + The type of logout that is being requested + + + + + Request a logout dialog + + Allowed values for the mode parameter are: + + + 0 + Normal. + + + 1 + No confirmation inferface should be shown. + + + 2 + Forcefully logout. No confirmation will be shown and any inhibitors will be ignored. + + + Values for flags may be bitwise or'ed together. + + + + + + + + + True if the session has entered the Running phase, false otherwise + + + + + Allows the caller to determine whether the session manager + has entered the Running phase, in case the client missed the + SessionRunning signal. + + + + + + + + + + The object path for the added client + + + + + Emitted when a client has been added to the session manager. + + + + + + + + The object path for the removed client + + + + + Emitted when a client has been removed from the session manager. + + + + + + + + + The object path for the added inhibitor + + + + + Emitted when an inhibitor has been added to the session manager. + + + + + + + + The object path for the removed inhibitor + + + + + Emitted when an inhibitor has been removed from the session manager. + + + + + + + + + Indicates the session has entered the Running phase. + + + + + + + + Indicates the session is about to end. + + + + + + + + + + The name of the session that has been loaded. + + + + + + + + If true, the session is currently in the + foreground and available for user input. + + + + + + + + A bitmask of flags to indicate which actions + are inhibited. See the Inhibit() function's description + for a list of possible values. + + + + + + diff --git a/src/backend-dbus/session-dbus.xml b/src/backend-dbus/session-dbus.xml new file mode 100644 index 0000000..96e9837 --- /dev/null +++ b/src/backend-dbus/session-dbus.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/upower.xml b/src/backend-dbus/upower.xml new file mode 100644 index 0000000..18d5fbd --- /dev/null +++ b/src/backend-dbus/upower.xml @@ -0,0 +1,309 @@ + + + + + + + + The DeviceKit-power service is available via the system message + bus. To access the service, use + the org.freedesktop.UPower interface on + the /org/freedesktop/UPower object on + the D-Bus system bus service with the well-known + name org.freedesktop.UPower. + + + + +$ dbus-send --print-reply \ + --system \ + --dest=org.freedesktop.UPower \ + /org/freedesktop/UPower \ + org.freedesktop.UPower.EnumerateDevices + +method return sender=:1.386 -> dest=:1.451 reply_serial=2 + array [ + object path "/org/freedesktop/UPower/devices/line_power_AC" + object path "/org/freedesktop/UPower/devices/battery_BAT0" + ] + + + + + + + + + + + + An array of object paths for devices. + + + + + + Enumerate all power objects on the system. + + + + + + + + + + Object path of device that was added. + + + + + + Emitted when a device is added. + + + + + + + + + + Object path of device that was removed. + + + + + + Emitted when a device is removed. + + + + + + + + + + Object path of device that was changed. + + + + + + Emitted when a device changed. + + + + + + + + + + + + Emitted when one or more properties on the object changes. + + + + + + + + + + + + This signal is sent when the session is about to be suspended or + hibernated. + Session and system programs have one second to do anything required + before the sleep action is taken (such as sending out Avahi or + Jabber messages). + + + + + + + + + + + + This signal is sent when the session has just returned from + Suspend() or Hibernate(). + Session and system programs can then do anything required (such as + sending out Avahi or Jabber messages). + + + + + + + + + + + + + This method tells UPower that the Suspend() or Hibernate() method + is about to be called. + This allows UPower to emit the Suspending signal whilst + session activities are happening that have to be done before the + suspend process is started. + + + This method would typically be called by the session power + management daemon, before it locks the screen and waits for the + screen to fade to black. + The session power management component would then call Suspend() or + Hibernate() when these syncronous tasks have completed. + + + If this method is not called than nothing bad will happen and + Suspend() or Hibernate() will block for the required second. + + + + + + + + + + + + + Suspends the computer into a low power state. + System state is not preserved if the power is lost. + + + If AboutToRequestSleep() has not been called then UPower will send + the Sleeping() signal and block for one second. + + + If AboutToRequestSleep() has been called less than one second + before this method is called then UPower will block for the + remaining time to complete one second of delay. + + + + + + + + + + + TRUE if allowed, otherwise FALSE + + + + + Check if the caller has (or can get) the PolicyKit privilege to call + Suspend. + + + + + + + + + + + + + Hibernates the computer into a low power state. + System state is preserved if the power is lost. + + + If AboutToRequestSleep() has not been called then UPower will send + the Sleeping() signal and block for one second. + + + If AboutToRequestSleep() has been called less than one second + before this method is called then UPower will block for the + remaining time to complete one second of delay. + + + + + + + + + + + TRUE if allowed, otherwise FALSE + + + + + Check if the caller has (or can get) the PolicyKit privilege to call + Hibernate. + + + + + + + + + + Version of the running daemon, e.g. 002. + + + + + + Whether the system is able to suspend. + + + + + + Whether the system is able to hibernate. + + + + + + Indicates whether the system is running on battery power. + This property is provided for convenience. + + + + + + Indicates whether the system is running on battery power and if the battery is critically low. + This property is provided for convenience. + + + + + + + + Indicates if the laptop lid is closed where the display cannot be seen. + + + + + + + + + + If the system has a lid device. + + + + + + + + diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c new file mode 100644 index 0000000..4798d33 --- /dev/null +++ b/src/backend-dbus/users.c @@ -0,0 +1,810 @@ +/* + * 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 "dbus-accounts.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-consolekit-manager.h" +#include "dbus-user.h" + +#include "users.h" + +struct _IndicatorSessionUsersDbusPriv +{ + char * active_session_id; + + Accounts * accounts; + + DisplayManagerSeat * dm_seat; + + ConsoleKitSeat * seat_proxy; + + /* user's dbus object path -> AccountsUser* */ + GHashTable * path_to_user; + + /* uint32 user-id --> user's dbus object path */ + GHashTable * uid_to_user_path; + + /* uint32 user-id --> hashset of ssid strings */ + GHashTable * uid_to_sessions; + + /* ssid string --> uint32 user-id */ + GHashTable * session_to_uid; + + GCancellable * cancellable; +}; + +typedef IndicatorSessionUsersDbusPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionUsersDbus, + indicator_session_users_dbus, + INDICATOR_TYPE_SESSION_USERS) + +/*** +**** +***/ + +static void create_user_proxy_for_path (IndicatorSessionUsersDbus * self, + const char * path); + +static void create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, + const char * ssid); + +static void +emit_user_changed_for_path (IndicatorSessionUsersDbus * self, const char * path) +{ + AccountsUser * user = g_hash_table_lookup (self->priv->path_to_user, path); + + if (user && !accounts_user_get_system_account (user)) + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), path); +} + +static void +emit_user_changed_for_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + const char * path; + + if ((path = g_hash_table_lookup (self->priv->uid_to_user_path, GUINT_TO_POINTER(uid)))) + emit_user_changed_for_path (self, path); +} + +/*** +**** ACCOUNT MANAGER / USER TRACKING +***/ + +/* called when a user proxy gets the 'Changed' signal */ +static void +on_user_changed (AccountsUser * user, gpointer gself) +{ + /* Accounts.User doesn't update properties in the standard way, + * so create a new proxy to pull in the new properties. + * The older proxy is freed when it's removed from our path_to_user hash */ + const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); + create_user_proxy_for_path (gself, path); +} + +static void +track_user (IndicatorSessionUsersDbus * self, + AccountsUser * user) +{ + priv_t * p; + const char * path; + gboolean already_had_user; + + p = self->priv; + + path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); + already_had_user = g_hash_table_contains (p->path_to_user, path); + + g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); + g_hash_table_insert (p->path_to_user, g_strdup(path), user); + + if (already_had_user) + { + emit_user_changed_for_path (self, path); + } + else + { + const guint uid = (guint) accounts_user_get_uid (user); + + g_hash_table_insert (p->uid_to_user_path, + GUINT_TO_POINTER(uid), + g_strdup(path)); + + if (!accounts_user_get_system_account (user)) + indicator_session_users_added (INDICATOR_SESSION_USERS(self), path); + } +} + +static void +untrack_user (IndicatorSessionUsersDbus * self, + const gchar * path) +{ + g_hash_table_remove (self->priv->path_to_user, path); + + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), path); +} + + +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 + { + track_user (self, user); + } +} + +static void +create_user_proxy_for_path (IndicatorSessionUsersDbus * self, + const char * path) +{ + const char * name = "org.freedesktop.Accounts"; + const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + + 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 (IndicatorSessionUsersDbus * self, Accounts * a) +{ + priv_t * p = self->priv; + + if (p->accounts != NULL) + { + g_signal_handlers_disconnect_by_data (p->accounts, self); + g_clear_object (&p->accounts); + } + + if (a != NULL) + { + p->accounts = g_object_ref (a); + + accounts_call_list_cached_users (a, + self->priv->cancellable, + on_user_list_ready, + self); + + g_signal_connect_swapped (a, "user-added", + G_CALLBACK(create_user_proxy_for_path), self); + + g_signal_connect_swapped (a, "user-deleted", + G_CALLBACK(untrack_user), self); + } +} + +#if 0 +static void +create_accounts_proxy (IndicatorSessionUsersDbus * self) +{ + const char * name = "org.freedesktop.Accounts"; + const char * path = "/org/freedesktop/Accounts"; + GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + + accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, path, + self->priv->cancellable, + on_accounts_proxy_ready, self); +} +#endif + +/** + * SEAT / SESSION TRACKING + * + * There are two simple goals here: + * + * 1. Keep track of how many GUI sessions each user has + * so that we can set the 'is_logged_in' flag correctly + * + * 2. Also track which is the current session, + * so that we can compare it to those GUI sessions to + * set the 'is_current_session' flag correctly. + * + * Now that you know the goals, these steps may make more sense: + * + * 1. create a ConsoleKitManager proxy + * 2. ask it for the current session + * 3. create a corresponding Session proxy + * 4. ask that Session proxy for its seat + * 5. create a corresponding Seat proxy + * 6. connect to that seat's session-added / session-removed signals + * 7. ask the seat for a list of its current sessions + * 8. create corresponding Session proxies + * 9. of them, look for the GUI sessions by checking their X11 properties + * 10. for each GUI session, get the corresponding uid + * 11. use the information to update our uid <--> GUI sessions tables + */ + +static void +track_session (IndicatorSessionUsersDbus * self, + const char * ssid, + guint uid) +{ + gpointer uid_key; + GHashTable * sessions; + + uid_key = GUINT_TO_POINTER (uid); + sessions = g_hash_table_lookup (self->priv->uid_to_sessions, uid_key); + if (sessions == NULL) + { + sessions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_hash_table_insert (self->priv->uid_to_sessions, uid_key, sessions); + } + + g_hash_table_add (sessions, g_strdup (ssid)); + g_hash_table_insert (self->priv->session_to_uid, g_strdup(ssid), uid_key); + + g_debug ("%s %s now tracking ssid:%s uid:%u. uid has %u tracked ssids.", + G_STRLOC, G_STRFUNC, ssid, uid, g_hash_table_size (sessions)); + + emit_user_changed_for_uid (self, uid); +} + +static void +untrack_session (IndicatorSessionUsersDbus * self, + const char * ssid) +{ + gpointer uidptr; + priv_t * p = self->priv; + + if (g_hash_table_lookup_extended (p->session_to_uid, ssid, NULL, &uidptr)) + { + const guint uid = GPOINTER_TO_UINT (uidptr); + GHashTable * sessions = g_hash_table_lookup (p->uid_to_sessions, uidptr); + + g_hash_table_remove (p->session_to_uid, ssid); + g_hash_table_remove (sessions, ssid); + g_debug ("%s %s not tracking ssid:%s uid:%u. uid has %u tracked ssids.", + G_STRLOC, G_STRFUNC, ssid, uid, + sessions ? g_hash_table_size (sessions) : 0); + + emit_user_changed_for_uid (self, uid); + } +} + +static void +on_session_proxy_uid_ready (GObject * o, + GAsyncResult * res, + gpointer gself) +{ + guint uid; + GError * err; + ConsoleKitSession * session = CONSOLE_KIT_SESSION (o); + + uid = 0; + err = NULL; + console_kit_session_call_get_unix_user_finish (session, &uid, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else if (uid) + { + const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(session)); + track_session (gself, path, uid); + } + + g_object_unref (o); +} + +static void +on_session_x11_display_ready (GObject * o, + GAsyncResult * res, + gpointer gself) +{ + priv_t * p; + GError * err; + gchar * gui; + ConsoleKitSession * session; + + p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; + + err = NULL; + gui = NULL; + session = CONSOLE_KIT_SESSION (o); + console_kit_session_call_get_x11_display_finish (session, &gui, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + gboolean is_gui_session; + + is_gui_session = gui && *gui; + + if (!is_gui_session) + g_clear_object (&session); + else + console_kit_session_call_get_unix_user (session, + p->cancellable, + on_session_proxy_uid_ready, + gself); + + g_free (gui); + } +} + +static void +on_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); + g_error_free (err); + } + else if (session != NULL) + { + priv_t * p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; + + console_kit_session_call_get_x11_display (session, + p->cancellable, + on_session_x11_display_ready, + gself); + } +} + +static void +create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, + const char * ssid) +{ + const char * name = "org.freedesktop.ConsoleKit"; + GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + + console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, ssid, + self->priv->cancellable, + on_session_proxy_ready, self); +} + +static void +on_session_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar ** sessions; + + err = NULL; + sessions = NULL; + console_kit_seat_call_get_sessions_finish (CONSOLE_KIT_SEAT(o), + &sessions, 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; sessions && sessions[i]; i++) + create_session_proxy_for_ssid (gself, sessions[i]); + + g_strfreev (sessions); + } +} + +static inline guint +get_uid_for_session (IndicatorSessionUsersDbus * self, const char * ssid) +{ + guint uid = 0; + gpointer value; + + if (ssid != NULL) + if ((value = g_hash_table_lookup (self->priv->session_to_uid, ssid))) + uid = GPOINTER_TO_UINT (value); + + return uid; +} + +/* it's a live session if username is 'ubuntu' and uid is 999 */ +static gboolean +is_live_ssid (IndicatorSessionUsersDbus * self, const char * ssid) +{ + priv_t * p; + guint uid; + + p = INDICATOR_SESSION_USERS_DBUS (self)->priv; + uid = get_uid_for_session (self, ssid); + + if (uid == 999) + { + const char * path; + AccountsUser * user = NULL; + + if ((path = g_hash_table_lookup (p->uid_to_user_path, GUINT_TO_POINTER (uid)))) + user = g_hash_table_lookup (p->path_to_user, path); + + return (user != NULL) && !g_strcmp0 (accounts_user_get_user_name(user), "ubuntu"); + } + + return FALSE; +} + + +static void +set_active_session (IndicatorSessionUsersDbus * self, const char * ssid) +{ + priv_t * p = self->priv; + const guint old_uid = get_uid_for_session (self, p->active_session_id); + const guint new_uid = get_uid_for_session (self, ssid); + const gboolean old_live = is_live_ssid (self, p->active_session_id); + const gboolean new_live = is_live_ssid (self, ssid); + + g_debug ("%s %s changing active_session_id from '%s' to '%s'", + G_STRLOC, G_STRFUNC, p->active_session_id, ssid); + g_free (p->active_session_id); + p->active_session_id = g_strdup (ssid); + + if (old_uid != new_uid) + { + emit_user_changed_for_uid (self, old_uid); + emit_user_changed_for_uid (self, new_uid); + } + + if (old_live != new_live) + { + indicator_session_users_notify_is_live_session (INDICATOR_SESSION_USERS(self)); + } +} + +static void +on_seat_active_session_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar * ssid; + ConsoleKitSeat * seat; + + err = NULL; + ssid = NULL; + seat = CONSOLE_KIT_SEAT (o); + console_kit_seat_call_get_active_session_finish (seat, &ssid, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else if (ssid != NULL) + { + set_active_session (INDICATOR_SESSION_USERS_DBUS(gself), ssid); + g_free (ssid); + } +} + +static void +set_seat (IndicatorSessionUsersDbus * self, ConsoleKitSeat * seat) +{ + priv_t * p = self->priv; + + if (p->seat_proxy != NULL) + { + g_signal_handlers_disconnect_by_data (p->seat_proxy, self); + g_clear_object (&p->seat_proxy); + } + + if (seat != NULL) + { + p->seat_proxy = g_object_ref (seat); + + /* ask the seat for a list of all the sessions */ + console_kit_seat_call_get_sessions (seat, + p->cancellable, + on_session_list_ready, + self); + + /* ask the seat for the name of the active session */ + console_kit_seat_call_get_active_session (p->seat_proxy, + p->cancellable, + on_seat_active_session_ready, + self); + + /* listen for session changes in this seat */ + g_signal_connect_swapped (seat, "session-added", + G_CALLBACK(create_session_proxy_for_ssid),self); + g_signal_connect_swapped (seat, "session-removed", + G_CALLBACK(untrack_session), self); + g_signal_connect_swapped (seat, "active-session-changed", + G_CALLBACK(set_active_session), self); + } +} + +/*** +**** +***/ + +static void +set_dm_seat (IndicatorSessionUsersDbus * self, DisplayManagerSeat * dm_seat) +{ + priv_t * p = self->priv; + + g_clear_object (&p->dm_seat); + + if (dm_seat != NULL) + p->dm_seat = g_object_ref (dm_seat); +} + +static void +activate_username (IndicatorSessionUsersDbus * self, const char * username) +{ + priv_t * p = self->priv; + const char * session = ""; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_user (p->dm_seat, username, session, + p->cancellable, NULL, NULL); +} + +/*** +**** +***/ + +static void +my_dispose (GObject * o) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + priv_t * p = self->priv; + + if (p->cancellable) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + + set_seat (self, NULL); + set_dm_seat (self, NULL); + set_account_manager (self, NULL); + + g_clear_pointer (&p->path_to_user, g_hash_table_destroy); + g_clear_pointer (&p->session_to_uid, g_hash_table_destroy); + g_clear_pointer (&p->uid_to_sessions, g_hash_table_destroy); + g_clear_pointer (&p->uid_to_user_path, g_hash_table_destroy); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + IndicatorSessionUsersDbus * u = INDICATOR_SESSION_USERS_DBUS (o); + + g_free (u->priv->active_session_id); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->finalize (o); +} + +static void +my_activate_user (IndicatorSessionUsers * users, const char * key) +{ + priv_t * p; + const char * username = 0; + + p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + if (p != 0) + { + AccountsUser * au = g_hash_table_lookup (p->path_to_user, key); + + if (au != NULL) + username = accounts_user_get_user_name (au); + } + + if (username != 0) + activate_username (INDICATOR_SESSION_USERS_DBUS(users), username); + else + g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, key); +} + +static gboolean +my_is_live_session (IndicatorSessionUsers * users) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); + + return is_live_ssid (self, self->priv->active_session_id); +} + +static GStrv +my_get_keys (IndicatorSessionUsers * users) +{ + int i; + priv_t * p; + gchar ** keys; + GHashTableIter iter; + gpointer path; + gpointer user; + + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); + p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + + i = 0; + keys = g_new (gchar*, g_hash_table_size(p->path_to_user)+1); + g_hash_table_iter_init (&iter, p->path_to_user); + while (g_hash_table_iter_next (&iter, &path, &user)) + if (!accounts_user_get_system_account (user)) + keys[i++] = g_strdup (path); + keys[i] = NULL; + + return keys; +} + +static IndicatorSessionUser * +my_get_user (IndicatorSessionUsers * users, const gchar * key) +{ + priv_t * p; + AccountsUser * au; + IndicatorSessionUser * ret = NULL; + + p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + + au = g_hash_table_lookup (p->path_to_user, key); + if (au && !accounts_user_get_system_account(au)) + { + const guint uid = (guint) accounts_user_get_uid (au); + GHashTable * s; + + ret = g_new0 (IndicatorSessionUser, 1); + + s = g_hash_table_lookup (p->uid_to_sessions, GUINT_TO_POINTER(uid)); + if (s == NULL) + { + ret->is_logged_in = FALSE; + ret->is_current_user = FALSE; + } + else + { + ret->is_logged_in = g_hash_table_size (s) > 0; + ret->is_current_user = g_hash_table_contains (s, p->active_session_id); + } + + ret->uid = uid; + ret->user_name = g_strdup (accounts_user_get_user_name (au)); + ret->real_name = g_strdup (accounts_user_get_real_name (au)); + ret->icon_file = g_strdup (accounts_user_get_icon_file (au)); + ret->login_frequency = accounts_user_get_login_frequency (au); + } + + return ret; +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionUsersClass * users_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + users_class = INDICATOR_SESSION_USERS_CLASS (klass); + users_class->is_live_session = my_is_live_session; + users_class->get_keys = my_get_keys; + users_class->get_user = my_get_user; + users_class->activate_user = my_activate_user; + + g_type_class_add_private (klass, sizeof (IndicatorSessionUsersDbusPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) +{ + priv_t * p; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_USERS_DBUS, + IndicatorSessionUsersDbusPriv); + self->priv = p; + p->cancellable = g_cancellable_new (); + + p->path_to_user = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_object_unref); + + p->uid_to_user_path = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, g_free); + + p->session_to_uid = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + + p->uid_to_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, + (GDestroyNotify)g_hash_table_destroy); + +#if 0 + console_kit_manager_proxy_new_for_bus ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + p->cancellable, + on_console_kit_manager_proxy_ready, + self); +#endif +} + +/*** +**** Public +***/ + +IndicatorSessionUsers * +indicator_session_users_dbus_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_USERS_DBUS, NULL); + + return INDICATOR_SESSION_USERS (o); +} + +void +indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus * self, + Accounts * accounts, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * seat) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS_DBUS (self)); + + set_account_manager (self, accounts); + set_seat (self, seat); + set_dm_seat (self, dm_seat); +} diff --git a/src/backend-dbus/users.h b/src/backend-dbus/users.h new file mode 100644 index 0000000..ff1e0ad --- /dev/null +++ b/src/backend-dbus/users.h @@ -0,0 +1,71 @@ +/* + * 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 . + */ + +#ifndef __USERS_DBUS_H__ +#define __USERS_DBUS_H__ + +#include +#include + +#include "../users.h" /* parent class */ +#include "dbus-accounts.h" +#include "dbus-consolekit-seat.h" +#include "dbus-display-manager.h" + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_USERS_DBUS (indicator_session_users_dbus_get_type()) +#define INDICATOR_SESSION_USERS_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_USERS_DBUS, IndicatorSessionUsersDbus)) +#define INDICATOR_SESSION_USERS_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_USERS_DBUS, IndicatorSessionUsersDbusClass)) +#define INDICATOR_IS_SESSION_USERS_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_USERS_DBUS)) + +typedef struct _IndicatorSessionUsersDbus IndicatorSessionUsersDbus; +typedef struct _IndicatorSessionUsersDbusPriv IndicatorSessionUsersDbusPriv; +typedef struct _IndicatorSessionUsersDbusClass IndicatorSessionUsersDbusClass; + +/** + * An implementation of IndicatorSessionUsers that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionUsersDbus +{ + /*< private >*/ + IndicatorSessionUsers parent; + IndicatorSessionUsersDbusPriv * priv; +}; + +struct _IndicatorSessionUsersDbusClass +{ + IndicatorSessionUsersClass parent_class; +}; + +GType indicator_session_users_dbus_get_type (void); + +IndicatorSessionUsers * indicator_session_users_dbus_new (void); + +void indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus *, + Accounts *, + DisplayManagerSeat *, + ConsoleKitSeat *); + + + +G_END_DECLS + +#endif diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c new file mode 100644 index 0000000..86a5e5a --- /dev/null +++ b/src/backend-dbus/utils.c @@ -0,0 +1,399 @@ +/* + * 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 "utils.h" + +/*** +**** indicator_session_util_get_session_proxies() +***/ + +struct session_proxy_data +{ + ConsoleKitManager * ck_manager; + Accounts * account_manager; + DisplayManagerSeat * dm_seat; + + ConsoleKitSeat * current_seat; + ConsoleKitSession * current_session; + AccountsUser * active_user; + + GCancellable * cancellable; + GError * error; + int pending; + + indicator_session_util_session_proxies_func callback; + gpointer user_data; +}; + +static void +session_proxy_data_free (struct session_proxy_data * data) +{ + g_clear_object (&data->ck_manager); + g_clear_object (&data->account_manager); + g_clear_object (&data->dm_seat); + + g_clear_object (&data->current_seat); + g_clear_object (&data->current_session); + g_clear_object (&data->active_user); + + g_clear_object (&data->cancellable); + g_clear_error (&data->error); + + g_free (data); +} + +static void +finish_callback (struct session_proxy_data * data) +{ + g_assert (data != NULL); + g_debug ("%s %s: pending is %d", G_STRLOC, G_STRFUNC, (data->pending-1)); + + if (!--data->pending) + { + data->callback (data->ck_manager, + data->account_manager, + data->dm_seat, + data->current_seat, + data->current_session, + data->active_user, + data->error, + data->user_data); + + session_proxy_data_free (data); + } +} + +static void +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + data->active_user = accounts_user_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else + { + g_debug ("%s %s user proxy is %p", G_STRLOC, G_STRFUNC, (void*)data->active_user); + } + + finish_callback (data); +} + +static void +on_user_path_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + char * path = NULL; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + accounts_call_find_user_by_id_finish (data->account_manager, &path, res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (path != NULL) + { + g_debug ("%s %s user path is %s", G_STRLOC, G_STRFUNC, path); + ++data->pending; + accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.Accounts", + path, + data->cancellable, + on_user_proxy_ready, + data); + } + + finish_callback (data); + g_free (path); +} + +static void +on_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + guint uid = 0; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + console_kit_session_call_get_unix_user_finish (data->current_session, &uid, res, &data->error); + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (uid) + { + g_debug ("%s %s uid is %u", G_STRLOC, G_STRFUNC, uid); + ++data->pending; + accounts_call_find_user_by_id (data->account_manager, + uid, + data->cancellable, + on_user_path_ready, + data); + } + + finish_callback (data); +} + +static void +on_seat_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + data->current_seat = console_kit_seat_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + + finish_callback (data); +} + +static void +on_sid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + char * sid = NULL; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + console_kit_session_call_get_seat_id_finish (data->current_session, &sid, res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (sid != NULL) + { + g_debug ("%s %s sid is %s", G_STRLOC, G_STRFUNC, sid); + ++data->pending; + console_kit_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + sid, + data->cancellable, + on_seat_proxy_ready, + data); + } + + finish_callback (data); + g_free (sid); +} + +static void +on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + data->current_session = console_kit_session_proxy_new_finish (res, &data->error); + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else + { + ++data->pending; + console_kit_session_call_get_seat_id (data->current_session, + data->cancellable, + on_sid_ready, + data); + + ++data->pending; + console_kit_session_call_get_unix_user (data->current_session, + data->cancellable, + on_uid_ready, + data); + } + + finish_callback (data); +} + +static void +on_current_session_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + char * ssid = NULL; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + ssid = NULL; + console_kit_manager_call_get_current_session_finish (data->ck_manager, + &ssid, res, + &data->error); + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (ssid) + { + g_debug ("%s %s ssid is %s", G_STRLOC, G_STRFUNC, ssid); + data->pending++; + console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + ssid, + data->cancellable, + on_session_proxy_ready, + data); + + } + + finish_callback (data); + g_free (ssid); +} + +static void +on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) +{ + DisplayManagerSeat * seat; + struct session_proxy_data * data = gdata; + + seat = display_manager_seat_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (seat != NULL) + { + data->dm_seat = g_object_ref (seat); + } + + finish_callback (data); + g_clear_object (&seat); +} + +static void +on_console_kit_manager_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) +{ + ConsoleKitManager * mgr; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + if (data->error == NULL) + { + mgr = console_kit_manager_proxy_new_for_bus_finish (res, &data->error); + g_debug ("%s %s mgr is %p, err is %p", G_STRLOC, G_STRFUNC, (void*)mgr, (void*)data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else + { + data->ck_manager = mgr; + + data->pending++; + console_kit_manager_call_get_current_session (mgr, + data->cancellable, + on_current_session_ready, + data); + + } + } + + finish_callback (data); +} + +static void +on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + if (data->error == NULL) + { + data->account_manager = accounts_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + + finish_callback (data); +} + +/** + * Getting all the proxies we want is kind of a pain -- + * especially without blocking (ie, using _sync() funcs) -- + * so it's farmed out to this wrapper utility. + * + * 1. in this func, start getting the ConsoleKit and Accounts proxies + * 2. when the accounts proxy is ready, stash it in data.account_manager + * 3. when the ck manager proxy is ready, stash it in data.ck_manager and + * ask it for the current session's ssid + * 4. when the ssid is ready, start getting a proxy for it + * 5. when the session's proxy is ready, stash it in data.current_session + * and ask it for both the current seat's sid and the active user's uid + * 6. When the current seat's sid is ready, start getting a proxy for it + * 7. When the current seat's proxy is ready, stash it in data.current_seat + * 8. when the active user's uid is ready, ask data.account_manager for the path + * 9. when the user path is ready, start getting an Accounts.User proxy for it + * 10. when the Accounts.User proxy is read, stash it in data.active_user + * + * When everything is done, or if there's an error, invoke the data.callback + */ +void +indicator_session_util_get_session_proxies ( + indicator_session_util_session_proxies_func func, + GCancellable * cancellable, + gpointer user_data) +{ + struct session_proxy_data * data; + + data = g_new0 (struct session_proxy_data, 1); + data->callback = func; + data->user_data = user_data; + data->cancellable = g_object_ref (cancellable); + + data->pending++; + accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.Accounts", + "/org/freedesktop/Accounts", + data->cancellable, + on_accounts_proxy_ready, data); + + data->pending++; + console_kit_manager_proxy_new_for_bus ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + data->cancellable, + on_console_kit_manager_proxy_ready, data); + + data->pending++; + 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"), + data->cancellable, + on_display_manager_seat_proxy_ready, data); + +} diff --git a/src/backend-dbus/utils.h b/src/backend-dbus/utils.h new file mode 100644 index 0000000..b4f26c3 --- /dev/null +++ b/src/backend-dbus/utils.h @@ -0,0 +1,53 @@ +/* + * 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 . + */ + +#ifndef __DBUS_UTILS_H__ +#define __DBUS_UTILS_H__ + +#include +#include + +#include "dbus-accounts.h" +#include "dbus-display-manager.h" +#include "dbus-user.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-consolekit-manager.h" + +typedef void (*indicator_session_util_session_proxies_func)( + ConsoleKitManager * ck_manager, + Accounts * account_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * current_ck_seat, + ConsoleKitSession * current_ck_session, + AccountsUser * active_user, + const GError * error, + gpointer user_data); + +/** + * Both users-dbus and guest-dbus need some of these proxies. + * Getting them all involves a lot of steps, so instead of repeating + * ourselves, the common dbus steps are extracted to this func. + */ +void indicator_session_util_get_session_proxies ( + indicator_session_util_session_proxies_func func, + GCancellable * cancellable, + gpointer user_data); + +#endif -- cgit v1.2.3 From ca4b40ade7f432d98c21ac499a0de63244b1c3cc Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 23 Mar 2013 10:04:13 -0500 Subject: use pete woods' hud cmake code for the build.sh script to check for Ninja and to move the gdbus-codegen macros into a resuable file in the cmake/ directory. --- src/backend-dbus/CMakeLists.txt | 115 +++++++++++++++------------------------- 1 file changed, 44 insertions(+), 71 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index a477cfe..dd928cc 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -1,86 +1,59 @@ -# autogenerate source code files for our DBus proxies -function(gdbus_codegen XML_FILE INTERFACE_PREFIX SOURCE_PREFIX) +set(BACKEND_GENERATED_SOURCES +) - set (SRC_C, ${SOURCE_PREFIX}.c) - set (SRC_H, ${SOURCE_PREFIX}.h) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-display-manager + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/display-manager.xml) - # check for the app - find_program (GDBUS_CODEGEN_EXECUTABLE NAMES gdbus-codegen DOC "gdbus-codegen executable") - if(NOT GDBUS_CODEGEN_EXECUTABLE) - message(FATAL_ERROR "Executable gdbus-codegen not found") - endif() +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-webcredentials + com.canonical.indicators + ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicators.webcredentials.xml) - # generate the code - add_custom_command ( - OUTPUT ${SOURCE_PREFIX}.c ${SOURCE_PREFIX}.h - COMMAND gdbus-codegen ARGS --interface-prefix ${INTERFACE_PREFIX} --generate-c-code ${SOURCE_PREFIX} ${CMAKE_CURRENT_SOURCE_DIR}/${XML_FILE} - DEPENDS ${XML_FILE}) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-accounts + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Accounts.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-user + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Accounts.User.xml) - # update our variables - set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_C}) - set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_H}) - set_property (SOURCE ${SRC_C} ${SRC_H} PROPERTY GENERATED) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-manager + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Manager.xml) - # cleanup - unset (SRC_C) - unset (SRC_H) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-seat + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Seat.xml) -endfunction(gdbus_codegen) -gdbus_codegen ("display-manager.xml" "org.freedesktop" "dbus-display-manager") -gdbus_codegen ("com.canonical.indicators.webcredentials.xml" "com.canonical.indicators" "dbus-webcredentials") -gdbus_codegen ("org.freedesktop.Accounts.xml" "org.freedesktop" "dbus-accounts") -gdbus_codegen ("org.freedesktop.Accounts.User.xml" "org.freedesktop" "dbus-user") -gdbus_codegen ("org.freedesktop.ConsoleKit.Manager.xml" "org.freedesktop" "dbus-consolekit-manager") -gdbus_codegen ("org.freedesktop.ConsoleKit.Seat.xml" "org.freedesktop" "dbus-consolekit-seat") -gdbus_codegen ("org.freedesktop.ConsoleKit.Session.xml" "org.freedesktop" "dbus-consolekit-session") -gdbus_codegen ("org.gnome.ScreenSaver.xml" "org" "gnome-screen-saver") -gdbus_codegen ("org.gnome.SessionManager.xml" "org" "gnome-session-manager") -gdbus_codegen ("org.gnome.SessionManager.EndSessionDialog.xml" "org.gnome.SessionManager" "dbus-end-session-dialog") -gdbus_codegen ("upower.xml" "org.freedesktop" "dbus-upower") +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-session + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Session.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES gnome-screen-saver + org + ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.ScreenSaver.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES gnome-session-manager + org + ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.SessionManager.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-end-session-dialog + org.gnome.SessionManager + ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.SessionManager.EndSessionDialog.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-upower + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/upower.xml) + +set (SOURCES actions.c backend-dbus.c guest.c users.c utils.c) # add warnings/coverage info on handwritten files # but not the autogenerated ones... -set_source_files_properties (actions.c - backend-dbus.c - guest.c - users.c - utils.c +set_source_files_properties (${SOURCES} PROPERTIES COMPILE_FLAGS " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") # add the bin dir to our include path s.t. our code can find the autogenerated header files include_directories (${CMAKE_CURRENT_BINARY_DIR} ${SERVICE_INCLUDE_DIRS}) -add_library (backenddbus STATIC - gnome-screen-saver.c - gnome-screen-saver.h - gnome-session-manager.c - gnome-session-manager.h - dbus-display-manager.c - dbus-display-manager.h - dbus-consolekit-manager.c - dbus-consolekit-manager.h - dbus-consolekit-seat.c - dbus-consolekit-seat.h - dbus-consolekit-session.c - dbus-consolekit-session.h - dbus-accounts.c - dbus-accounts.h - dbus-upower.c - dbus-upower.h - dbus-user.c - dbus-user.h - dbus-webcredentials.c - dbus-webcredentials.h - dbus-end-session-dialog.c - dbus-end-session-dialog.h - actions.c - actions.h - backend-dbus.c - backend-dbus.h - guest.c - guest.h - users.c - users.h - utils.c - utils.h) +add_library (backenddbus STATIC ${SOURCES} ${BACKEND_GENERATED_SOURCES}) -- cgit v1.2.3 From 4a8c2566e3114cb30e0c79b48859e5325c1f448b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 25 Mar 2013 15:06:43 -0500 Subject: remove unused session-dbus.xml; this is a leftover from the GTK+ indicator --- src/backend-dbus/session-dbus.xml | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/backend-dbus/session-dbus.xml (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/session-dbus.xml b/src/backend-dbus/session-dbus.xml deleted file mode 100644 index 96e9837..0000000 --- a/src/backend-dbus/session-dbus.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - -- 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 ---------------------------------- src/backend-dbus/users.c | 26 -------------------------- 2 files changed, 60 deletions(-) (limited to 'src/backend-dbus') 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 } /*** diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 4798d33..34e0c97 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -229,21 +229,6 @@ set_account_manager (IndicatorSessionUsersDbus * self, Accounts * a) } } -#if 0 -static void -create_accounts_proxy (IndicatorSessionUsersDbus * self) -{ - const char * name = "org.freedesktop.Accounts"; - const char * path = "/org/freedesktop/Accounts"; - GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - - accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, path, - self->priv->cancellable, - on_accounts_proxy_ready, self); -} -#endif - /** * SEAT / SESSION TRACKING * @@ -771,17 +756,6 @@ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) p->uid_to_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_hash_table_destroy); - -#if 0 - console_kit_manager_proxy_new_for_bus ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - p->cancellable, - on_console_kit_manager_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/actions.c | 13 +++---------- src/backend-dbus/guest.c | 30 ++++++++++++++++-------------- src/backend-dbus/users.c | 28 +++++++++++++++++++++------- src/backend-dbus/utils.c | 28 ++++++++++++++++++---------- 4 files changed, 58 insertions(+), 41 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 8994710..bc196f2 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -68,7 +68,9 @@ log_and_clear_error (GError ** err, const char * loc, const char * func) { if (*err) { - g_warning ("%s %s: %s", loc, func, (*err)->message); + if (!g_error_matches (*err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", loc, func, (*err)->message); + g_clear_error (err); } } @@ -591,14 +593,6 @@ my_dispose (GObject * o) G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); } -static void -my_finalize (GObject * o) -{ - /*IndicatorSessionActionsDbus * u = INDICATOR_SESSION_ACTIONS_DBUS (o);*/ - - G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->finalize (o); -} - /*** **** GObject Boilerplate ***/ @@ -612,7 +606,6 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; - object_class->finalize = my_finalize; actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); actions_class->can_lock = my_can_lock; 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; diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 34e0c97..6d9ada6 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -154,7 +154,9 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, user = accounts_user_proxy_new_for_bus_finish (res, &err); 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 @@ -187,7 +189,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 @@ -317,7 +321,9 @@ on_session_proxy_uid_ready (GObject * o, console_kit_session_call_get_unix_user_finish (session, &uid, 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 if (uid) @@ -347,7 +353,9 @@ on_session_x11_display_ready (GObject * o, console_kit_session_call_get_x11_display_finish (session, &gui, 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 @@ -378,7 +386,9 @@ on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer session = console_kit_session_proxy_new_finish (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 if (session != NULL) @@ -417,7 +427,9 @@ on_session_list_ready (GObject * o, GAsyncResult * res, gpointer gself) &sessions, 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 @@ -508,7 +520,9 @@ on_seat_active_session_ready (GObject * o, GAsyncResult * res, gpointer gself) console_kit_seat_call_get_active_session_finish (seat, &ssid, 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 if (ssid != NULL) diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index 86a5e5a..c8abc2b 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -91,7 +91,8 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else { @@ -112,7 +113,8 @@ on_user_path_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdat if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (path != NULL) { @@ -141,7 +143,8 @@ on_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) console_kit_session_call_get_unix_user_finish (data->current_session, &uid, res, &data->error); if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (uid) { @@ -165,7 +168,7 @@ on_seat_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gda data->current_seat = console_kit_seat_proxy_new_for_bus_finish (res, &data->error); - if (data->error != NULL) + if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); finish_callback (data); @@ -182,7 +185,8 @@ on_sid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (sid != NULL) { @@ -210,7 +214,8 @@ on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer data->current_session = console_kit_session_proxy_new_finish (res, &data->error); if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else { @@ -243,7 +248,8 @@ on_current_session_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointe &data->error); if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (ssid) { @@ -275,7 +281,8 @@ on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (seat != NULL) { @@ -302,7 +309,8 @@ on_console_kit_manager_proxy_ready (GObject * o G_GNUC_UNUSED, if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else { @@ -330,7 +338,7 @@ on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer { data->account_manager = accounts_proxy_new_for_bus_finish (res, &data->error); - if (data->error != NULL) + if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } -- cgit v1.2.3 From d7bb2123f7afffd93524110b4174ad855043f57d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:14:32 -0500 Subject: add replace consolekit xml files with login1; update build files --- src/backend-dbus/CMakeLists.txt | 24 +- .../org.freedesktop.ConsoleKit.Manager.xml | 353 ----------------- .../org.freedesktop.ConsoleKit.Seat.xml | 164 -------- .../org.freedesktop.ConsoleKit.Session.xml | 435 --------------------- .../org.freedesktop.login1.Manager.xml | 199 ++++++++++ src/backend-dbus/org.freedesktop.login1.Seat.xml | 21 + .../org.freedesktop.login1.Session.xml | 49 +++ src/backend-dbus/org.freedesktop.login1.User.xml | 56 +++ src/backend-dbus/upower.xml | 309 --------------- 9 files changed, 337 insertions(+), 1273 deletions(-) delete mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml delete mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml delete mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.Manager.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.Seat.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.Session.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.User.xml delete mode 100644 src/backend-dbus/upower.xml (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index dd928cc..58d7b6a 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -3,7 +3,7 @@ set(BACKEND_GENERATED_SOURCES add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-display-manager org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/display-manager.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.DisplayManager.Seat) add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-webcredentials com.canonical.indicators @@ -17,17 +17,21 @@ add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-user org.freedesktop ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Accounts.User.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-manager +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-manager org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Manager.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Manager.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-seat +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-seat org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Seat.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Seat.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-session +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-session org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Session.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Session.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-user + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.User.xml) add_gdbus_codegen (BACKEND_GENERATED_SOURCES gnome-screen-saver org @@ -41,11 +45,7 @@ add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-end-session-dialog org.gnome.SessionManager ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.SessionManager.EndSessionDialog.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-upower - org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/upower.xml) - -set (SOURCES actions.c backend-dbus.c guest.c users.c utils.c) +set (SOURCES actions.c guest.c users.c backend-dbus.c utils.c) # add warnings/coverage info on handwritten files # but not the autogenerated ones... diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml deleted file mode 100644 index f903b55..0000000 --- a/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - - - - This method initiates a request to restart (ie. reboot) the computer system. - - - - - - - - - - - - - - This method initiates a request to stop (ie. shutdown) the computer system. - - - - - - - - - - - - - - The secret cookie that is used to identify the new session - - - - - This method requests that a new Session - be created for the calling process. The properties of this new Session are set automatically - from information collected about the calling process. - - This new session exists until the calling process disconnects from the system bus or - calls CloseSession(). - - It is the responsibility of the calling process to set the environment variable - XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only - be made available to child processes of the caller so that they may be identified - as members of this session. - - See this simple example: - - DBusError error; - DBusMessage *message; - DBusMessage *reply; - - message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager", - "OpenSession"); - if (message == NULL) { - goto out; - } - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connector->connection, - message, - -1, - &error); - if (reply == NULL) { - goto out; - } - - dbus_error_init (&error); - if (! dbus_message_get_args (reply, - &error, - DBUS_TYPE_STRING, &cookie, - DBUS_TYPE_INVALID)) { - goto out; - } - - - - OpenSessionWithParameters() - - - - - - - An array of sets of property names and values - - - - - The secret cookie that is used to identify the new session - - - - - This method requests that a new Session - be created for the calling process. The properties of this new Session are from the - parameters provided. - - This new session exists until the calling process disconnects from the system bus or - calls CloseSession(). - - It is the responsibility of the calling process to set the environment variable - XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only - be made available to child processes of the caller so that they may be identified - as members of this session. - - See the Session properties for a list of valid parameters. - - org.freedesktop.ConsoleKit.Session - This method is restricted to privileged users by D-Bus policy. - - - - - - - The secret cookie that is used to identify the session - - - - - Whether the session was successfully closed - - - - - This method is used to close the session identified by the supplied cookie. - - The session can only be closed by the same process that opened the session. - - - - - - - - - an array of Seat IDs - - - - - This gets a list of all the Seats - that are currently present on the system. - Each Seat ID is an D-Bus object path for the object that implements the - Seat interface. - - org.freedesktop.ConsoleKit.Seat - - - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently present on the system. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - org.freedesktop.ConsoleKit.Session - - - - - - - - The secret cookie that is used to identify the session - - - - - The object identifier for the current session - - - - - Returns the session ID that is associated with the specified cookie. - - - - - - - - - The POSIX process ID - - - - - The object identifier for the current session - - - - - Attempts to determine the session ID for the specified - POSIX process ID (pid). - - - - - - - - - The object identifier for the current session - - - - - Attempts to determine the session ID that the caller belongs to. - - See this example of using dbus-send: - - dbus-send --system --dest=org.freedesktop.ConsoleKit \ - --type=method_call --print-reply --reply-timeout=2000 \ - /org/freedesktop/ConsoleKit/Manager \ - org.freedesktop.ConsoleKit.Manager.GetCurrentSession - - - - - - - - - POSIX User identification - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently open for the specified user. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - User identification - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently open for the specified user. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - - The value of the system-idle-hint - - - - - Returns TRUE if the idle-hint - property of every open session is TRUE or if there are no open sessions. - - - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time of the last change of the system-idle-hint. - - - - - - - - - The Seat ID for the added seat - - - - - Emitted when a Seat has been added to the system. - - - - - - - - The Seat ID for the removed seat - - - - - Emitted when a Seat has been removed from the system. - - - - - - - - The value of the system-idle-hint - - - - - Emitted when the value of the system-idle-hint has changed. - - - - - - diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml deleted file mode 100644 index 58c2ce7..0000000 --- a/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - A seat is a collection of sessions and a set of hardware (usually at -least a keyboard and mouse). Only one session may be active on a -seat at a time. - - - - - - - Seat ID - - - - - Returns the ID for Seat. - - - - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently attached to this seat. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - an array of devices - - - - - This gets a list of all the devices - that are currently associated with this seat. - Each device is an D-Bus structure that represents - the device type and the device id. - - - - - - - - - Session ID - - - - - Gets the Session ID that is currently active on this Seat. - Returns NULL if there is no active session. - - - - - - - - TRUE if seat supports session activation - - - - Used to determine whether the seat supports session activation. - - - - - - - - - Session ID - - - - - Attempt to activate the specified session. In most - cases, if successful, this will cause the session to - become visible and take control of the hardware that is - associated with this seat. - - Activate() - - - - - - - Session ID - - - - - Emitted when the active session has changed. - - - - - - - Session ID - - - - - Emitted when a session has been added to the seat. - - - - - - - Session ID - - - - - Emitted when a session has been removed from the seat. - - - - - - - Device structure - - - - - Emitted when a device has been associated with the seat. - - - - - - - Device structure - - - - - Emitted when a device has been dissociated from the seat. - - - - - diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml deleted file mode 100644 index b6e1cdb..0000000 --- a/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - - Session objects represent and store information - related to a user session. - - The properties associated with the Session - specifically refer to the properties of the "session leader". - - - - - - - Session ID - - - - Returns the ID for Session. - - - - - - - Seat ID - - - - Returns the ID for the Seat the Session is - attached to. - - org.freedesktop.ConsoleKit.Seat - - - - - - Session type - - - - - Returns the type of the session. - Warning: we haven't yet defined the allowed values for this property. - It is probably best to avoid this until we do. - - - session-type - - - - - - User ID - - - - Returns the user that the session belongs to. - - - user - - - - - - POSIX User ID - - - - Returns the POSIX user ID that the session belongs to. - - unix-user - - - - - - The value of the X11 display - - - - Returns the value of the X11 DISPLAY for this session - if one is present. - - x11-display - - - - - - The value of the X11 display device - - - - Returns the value of the display device (aka TTY) that the - X11 display for the session is connected to. If there is no x11-display set then this value - is undefined. - - x11-display-device - - - - - - The value of the display device - - - - Returns the value of the display device (aka TTY) that the - session is connected to. - - display-device - - - - - - The remote host name - - - - Returns the value of the remote host name for the session. - - - remote-host-name - - - - - - The value of the native system login session ID - - - - Returns the value of the login session ID that the - underlying system uses to enforce session boundaries. If there is no login session ID - set then this value is an empty string. - - - - - - - TRUE if the session is active, otherwise FALSE - - - - Returns whether the session is active on the Seat that - it is attached to. - If the session is not attached to a seat this value is undefined. - - - active - - - - - - TRUE if the session is local, otherwise FALSE - - - - Returns whether the session is local - FIXME: we need to come up with a concrete definition for this value. - It was originally used as a way to identify XDMCP sessions that originate - from a remote system. - - - is-local - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time that the session was opened. - - - - - - - - - - Attempt to activate the this session. In most - cases, if successful, this will cause the session to - become visible and become active on the seat that it - is attached to. - - Seat.ActivateSession() - - - - - - - This will cause a Lock - signal to be emitted for this session. - - - This method is restricted to privileged users by D-Bus policy. - Lock signal - - - - - - - This will cause an Unlock - signal to be emitted for this session. - - This can be used by login managers to unlock a session before it is - re-activated during fast-user-switching. - - - This method is restricted to privileged users by D-Bus policy. - Unlock signal - - - - - - - The value of the idle-hint - - - - - Gets the value of the idle-hint - property. - - - idle-hint - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time of the last change of the idle-hint. - - - - - - - - - boolean value to set the idle-hint to - - - - - This may be used by the session to indicate that - it is idle. - - Use of this method is restricted to the user - that owns the session. - - - - - - - - TRUE if the session is active, otherwise FALSE - - - - - Emitted when the active property has changed. - - - - - - - the new value of idle-hint - - - - - Emitted when the idle-hint property has changed. - - - - - - - Emitted in response to a call to the Lock() method. - It is intended that the screensaver for the session should lock the screen in response to this signal. - - - - - - - Emitted in response to a call to the Unlock() method. - It is intended that the screensaver for the session should unlock the screen in response to this signal. - - - - - - - - The user assigned to the session. - - - - - - - The user assigned to the session. - - - - - - - - The type of the session. - Warning: we haven't yet defined the allowed values for this property. - It is probably best to avoid this until we do. - - - - - - - - The remote host name for the session. - - This will be set in situations where the session is - opened and controlled from a remote system. - - For example, this value will be set when the - session is created from an SSH or XDMCP connection. - - - - - - - - The display device (aka TTY) that the - session is connected to. - - - - - - - - Value of the X11 DISPLAY for this session - if one is present. - - - - - - - - - The display device (aka TTY) that the X11 display for the - session is connected to. If there is no x11-display set then - this value is undefined. - - - - - - - - - Whether the session is active on the Seat that - it is attached to. - If the session is not attached to a seat this value is undefined. - - - - - - - - - Whether the session is local - FIXME: we need to come up with a concrete definition for this value. - It was originally used as a way to identify XDMCP sessions that originate - from a remote system. - - - - - - - - - This is a hint used to indicate that the session may be idle. - - - For sessions with a x11-display set (ie. graphical - sessions), it is up to each session to delegate the - responsibility for updating this value. Typically, the - screensaver will set this. - - However, for non-graphical sessions with a display-device set - the Session object itself will periodically update this value based - on the activity detected on the display-device itself. - - - This should not be considered authoritative. - - - - - - - diff --git a/src/backend-dbus/org.freedesktop.login1.Manager.xml b/src/backend-dbus/org.freedesktop.login1.Manager.xml new file mode 100644 index 0000000..91da5f2 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.Manager.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.login1.Seat.xml b/src/backend-dbus/org.freedesktop.login1.Seat.xml new file mode 100644 index 0000000..b73f724 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.Seat.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.login1.Session.xml b/src/backend-dbus/org.freedesktop.login1.Session.xml new file mode 100644 index 0000000..24a6fac --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.Session.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.login1.User.xml b/src/backend-dbus/org.freedesktop.login1.User.xml new file mode 100644 index 0000000..8253706 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.User.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/upower.xml b/src/backend-dbus/upower.xml deleted file mode 100644 index 18d5fbd..0000000 --- a/src/backend-dbus/upower.xml +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - The DeviceKit-power service is available via the system message - bus. To access the service, use - the org.freedesktop.UPower interface on - the /org/freedesktop/UPower object on - the D-Bus system bus service with the well-known - name org.freedesktop.UPower. - - - - -$ dbus-send --print-reply \ - --system \ - --dest=org.freedesktop.UPower \ - /org/freedesktop/UPower \ - org.freedesktop.UPower.EnumerateDevices - -method return sender=:1.386 -> dest=:1.451 reply_serial=2 - array [ - object path "/org/freedesktop/UPower/devices/line_power_AC" - object path "/org/freedesktop/UPower/devices/battery_BAT0" - ] - - - - - - - - - - - - An array of object paths for devices. - - - - - - Enumerate all power objects on the system. - - - - - - - - - - Object path of device that was added. - - - - - - Emitted when a device is added. - - - - - - - - - - Object path of device that was removed. - - - - - - Emitted when a device is removed. - - - - - - - - - - Object path of device that was changed. - - - - - - Emitted when a device changed. - - - - - - - - - - - - Emitted when one or more properties on the object changes. - - - - - - - - - - - - This signal is sent when the session is about to be suspended or - hibernated. - Session and system programs have one second to do anything required - before the sleep action is taken (such as sending out Avahi or - Jabber messages). - - - - - - - - - - - - This signal is sent when the session has just returned from - Suspend() or Hibernate(). - Session and system programs can then do anything required (such as - sending out Avahi or Jabber messages). - - - - - - - - - - - - - This method tells UPower that the Suspend() or Hibernate() method - is about to be called. - This allows UPower to emit the Suspending signal whilst - session activities are happening that have to be done before the - suspend process is started. - - - This method would typically be called by the session power - management daemon, before it locks the screen and waits for the - screen to fade to black. - The session power management component would then call Suspend() or - Hibernate() when these syncronous tasks have completed. - - - If this method is not called than nothing bad will happen and - Suspend() or Hibernate() will block for the required second. - - - - - - - - - - - - - Suspends the computer into a low power state. - System state is not preserved if the power is lost. - - - If AboutToRequestSleep() has not been called then UPower will send - the Sleeping() signal and block for one second. - - - If AboutToRequestSleep() has been called less than one second - before this method is called then UPower will block for the - remaining time to complete one second of delay. - - - - - - - - - - - TRUE if allowed, otherwise FALSE - - - - - Check if the caller has (or can get) the PolicyKit privilege to call - Suspend. - - - - - - - - - - - - - Hibernates the computer into a low power state. - System state is preserved if the power is lost. - - - If AboutToRequestSleep() has not been called then UPower will send - the Sleeping() signal and block for one second. - - - If AboutToRequestSleep() has been called less than one second - before this method is called then UPower will block for the - remaining time to complete one second of delay. - - - - - - - - - - - TRUE if allowed, otherwise FALSE - - - - - Check if the caller has (or can get) the PolicyKit privilege to call - Hibernate. - - - - - - - - - - Version of the running daemon, e.g. 002. - - - - - - Whether the system is able to suspend. - - - - - - Whether the system is able to hibernate. - - - - - - Indicates whether the system is running on battery power. - This property is provided for convenience. - - - - - - Indicates whether the system is running on battery power and if the battery is critically low. - This property is provided for convenience. - - - - - - - - Indicates if the laptop lid is closed where the display cannot be seen. - - - - - - - - - - If the system has a lid device. - - - - - - - - -- cgit v1.2.3 From 463ed782d3f2480126cb11d3e18630e275526d9e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:16:43 -0500 Subject: update which proxies the dbus utils helper creates --- src/backend-dbus/backend-dbus.c | 34 ++-- src/backend-dbus/utils.c | 384 ++++++++-------------------------------- src/backend-dbus/utils.h | 16 +- 3 files changed, 96 insertions(+), 338 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/backend-dbus.c b/src/backend-dbus/backend-dbus.c index ea8f0ec..547c6ab 100644 --- a/src/backend-dbus/backend-dbus.c +++ b/src/backend-dbus/backend-dbus.c @@ -31,38 +31,36 @@ struct dbus_world_data IndicatorSessionGuestDbus * guest; }; -static void -on_proxies_ready (ConsoleKitManager * ck_manager, +static void +on_proxies_ready (Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * display_manager_seat, Accounts * account_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * ck_seat, - ConsoleKitSession * ck_session, - AccountsUser * active_user G_GNUC_UNUSED, - const GError * error, + GCancellable * cancellable, gpointer gdata) { struct dbus_world_data * data = gdata; - if (error == NULL) + if (!g_cancellable_is_cancelled (cancellable)) { if (data->actions != NULL) indicator_session_actions_dbus_set_proxies (data->actions, - ck_manager, - dm_seat, - ck_seat); + login1_manager, + login1_seat, + display_manager_seat); if (data->users != NULL) indicator_session_users_dbus_set_proxies (data->users, - account_manager, - dm_seat, - ck_seat); + login1_manager, + login1_seat, + display_manager_seat, + account_manager); if (data->guest != NULL) indicator_session_guest_dbus_set_proxies (data->guest, - account_manager, - dm_seat, - ck_seat, - ck_session); + login1_manager, + login1_seat, + display_manager_seat); } g_free (data); diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index c8abc2b..25ac7c3 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -25,346 +25,100 @@ struct session_proxy_data { - ConsoleKitManager * ck_manager; - Accounts * account_manager; + Login1Manager * login1_manager; + Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; - - ConsoleKitSeat * current_seat; - ConsoleKitSession * current_session; - AccountsUser * active_user; + Accounts * account_manager; GCancellable * cancellable; - GError * error; int pending; indicator_session_util_session_proxies_func callback; gpointer user_data; }; -static void -session_proxy_data_free (struct session_proxy_data * data) -{ - g_clear_object (&data->ck_manager); - g_clear_object (&data->account_manager); - g_clear_object (&data->dm_seat); - - g_clear_object (&data->current_seat); - g_clear_object (&data->current_session); - g_clear_object (&data->active_user); - - g_clear_object (&data->cancellable); - g_clear_error (&data->error); - - g_free (data); -} static void -finish_callback (struct session_proxy_data * data) +on_proxy_ready_impl (struct session_proxy_data * data, + gsize member_offset, + GError * err, + gpointer proxy) { - g_assert (data != NULL); - g_debug ("%s %s: pending is %d", G_STRLOC, G_STRFUNC, (data->pending-1)); - - if (!--data->pending) + if (err != NULL) { - data->callback (data->ck_manager, - data->account_manager, - data->dm_seat, - data->current_seat, - data->current_session, - data->active_user, - data->error, - data->user_data); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - session_proxy_data_free (data); - } -} - -static void -on_user_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer gdata) -{ - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - data->active_user = accounts_user_proxy_new_for_bus_finish (res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + g_error_free (err); } else { - g_debug ("%s %s user proxy is %p", G_STRLOC, G_STRFUNC, (void*)data->active_user); - } - - finish_callback (data); -} - -static void -on_user_path_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - char * path = NULL; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - accounts_call_find_user_by_id_finish (data->account_manager, &path, res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (path != NULL) - { - g_debug ("%s %s user path is %s", G_STRLOC, G_STRFUNC, path); - ++data->pending; - accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.Accounts", - path, - data->cancellable, - on_user_proxy_ready, - data); + *((gpointer*)G_STRUCT_MEMBER_P(data, member_offset)) = proxy; } - finish_callback (data); - g_free (path); -} - -static void -on_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - guint uid = 0; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - console_kit_session_call_get_unix_user_finish (data->current_session, &uid, res, &data->error); - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (uid) - { - g_debug ("%s %s uid is %u", G_STRLOC, G_STRFUNC, uid); - ++data->pending; - accounts_call_find_user_by_id (data->account_manager, - uid, - data->cancellable, - on_user_path_ready, - data); - } - - finish_callback (data); -} - -static void -on_seat_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - data->current_seat = console_kit_seat_proxy_new_for_bus_finish (res, &data->error); - - if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - - finish_callback (data); -} - -static void -on_sid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - char * sid = NULL; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - console_kit_session_call_get_seat_id_finish (data->current_session, &sid, res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (sid != NULL) - { - g_debug ("%s %s sid is %s", G_STRLOC, G_STRFUNC, sid); - ++data->pending; - console_kit_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - sid, - data->cancellable, - on_seat_proxy_ready, - data); - } - - finish_callback (data); - g_free (sid); -} - -static void -on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - data->current_session = console_kit_session_proxy_new_finish (res, &data->error); - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else + if (!--data->pending) { - ++data->pending; - console_kit_session_call_get_seat_id (data->current_session, - data->cancellable, - on_sid_ready, - data); + data->callback (data->login1_manager, + data->login1_seat, + data->dm_seat, + data->account_manager, + data->cancellable, + data->user_data); - ++data->pending; - console_kit_session_call_get_unix_user (data->current_session, - data->cancellable, - on_uid_ready, - data); + g_clear_object (&data->login1_manager); + g_clear_object (&data->login1_seat); + g_clear_object (&data->dm_seat); + g_clear_object (&data->account_manager); + g_clear_object (&data->cancellable); + g_free (data); } - - finish_callback (data); } - + static void -on_current_session_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - char * ssid = NULL; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - ssid = NULL; - console_kit_manager_call_get_current_session_finish (data->ck_manager, - &ssid, res, - &data->error); - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (ssid) - { - g_debug ("%s %s ssid is %s", G_STRLOC, G_STRFUNC, ssid); - data->pending++; - console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - ssid, - data->cancellable, - on_session_proxy_ready, - data); - - } - - finish_callback (data); - g_free (ssid); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, dm_seat); + GError * err = NULL; + gpointer proxy = display_manager_seat_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } static void -on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer gdata) +on_login1_seat_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - DisplayManagerSeat * seat; - struct session_proxy_data * data = gdata; - - seat = display_manager_seat_proxy_new_for_bus_finish (res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (seat != NULL) - { - data->dm_seat = g_object_ref (seat); - } - - finish_callback (data); - g_clear_object (&seat); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, login1_seat); + GError * err = NULL; + gpointer proxy = login1_seat_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } static void -on_console_kit_manager_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer gdata) +on_login1_manager_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - ConsoleKitManager * mgr; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - if (data->error == NULL) - { - mgr = console_kit_manager_proxy_new_for_bus_finish (res, &data->error); - g_debug ("%s %s mgr is %p, err is %p", G_STRLOC, G_STRFUNC, (void*)mgr, (void*)data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else - { - data->ck_manager = mgr; - - data->pending++; - console_kit_manager_call_get_current_session (mgr, - data->cancellable, - on_current_session_ready, - data); - - } - } - - finish_callback (data); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, login1_manager); + GError * err = NULL; + gpointer proxy = login1_manager_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } static void -on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - if (data->error == NULL) - { - data->account_manager = accounts_proxy_new_for_bus_finish (res, &data->error); - - if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - - finish_callback (data); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, account_manager); + GError * err = NULL; + gpointer proxy = accounts_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } -/** - * Getting all the proxies we want is kind of a pain -- - * especially without blocking (ie, using _sync() funcs) -- - * so it's farmed out to this wrapper utility. - * - * 1. in this func, start getting the ConsoleKit and Accounts proxies - * 2. when the accounts proxy is ready, stash it in data.account_manager - * 3. when the ck manager proxy is ready, stash it in data.ck_manager and - * ask it for the current session's ssid - * 4. when the ssid is ready, start getting a proxy for it - * 5. when the session's proxy is ready, stash it in data.current_session - * and ask it for both the current seat's sid and the active user's uid - * 6. When the current seat's sid is ready, start getting a proxy for it - * 7. When the current seat's proxy is ready, stash it in data.current_seat - * 8. when the active user's uid is ready, ask data.account_manager for the path - * 9. when the user path is ready, start getting an Accounts.User proxy for it - * 10. when the Accounts.User proxy is read, stash it in data.active_user - * - * When everything is done, or if there's an error, invoke the data.callback - */ +/* helper utility to get the dbus proxies used by the backend-dbus classes */ void indicator_session_util_get_session_proxies ( indicator_session_util_session_proxies_func func, @@ -372,12 +126,30 @@ indicator_session_util_get_session_proxies ( gpointer user_data) { struct session_proxy_data * data; + char * seat_path; data = g_new0 (struct session_proxy_data, 1); data->callback = func; data->user_data = user_data; data->cancellable = g_object_ref (cancellable); + data->pending++; + login1_manager_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.login1", + "/org/freedesktop/login1", + data->cancellable, + on_login1_manager_ready, data); + + data->pending++; + seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); + login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.login1", + seat_path, + data->cancellable, + on_login1_seat_ready, + data); data->pending++; accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, @@ -386,15 +158,6 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_accounts_proxy_ready, data); - data->pending++; - console_kit_manager_proxy_new_for_bus ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - data->cancellable, - on_console_kit_manager_proxy_ready, data); - data->pending++; display_manager_seat_proxy_new_for_bus ( G_BUS_TYPE_SYSTEM, @@ -404,4 +167,5 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_display_manager_seat_proxy_ready, data); + g_free (seat_path); } diff --git a/src/backend-dbus/utils.h b/src/backend-dbus/utils.h index b4f26c3..802dd5e 100644 --- a/src/backend-dbus/utils.h +++ b/src/backend-dbus/utils.h @@ -25,19 +25,15 @@ #include "dbus-accounts.h" #include "dbus-display-manager.h" -#include "dbus-user.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" -#include "dbus-consolekit-manager.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" typedef void (*indicator_session_util_session_proxies_func)( - ConsoleKitManager * ck_manager, + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * display_manager_seat, Accounts * account_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * current_ck_seat, - ConsoleKitSession * current_ck_session, - AccountsUser * active_user, - const GError * error, + GCancellable * cancellable, gpointer user_data); /** -- 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 ++++++++++++++++------------------------------- src/backend-dbus/guest.h | 14 +- 2 files changed, 164 insertions(+), 316 deletions(-) (limited to 'src/backend-dbus') 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); } diff --git a/src/backend-dbus/guest.h b/src/backend-dbus/guest.h index 03b6b28..aca5588 100644 --- a/src/backend-dbus/guest.h +++ b/src/backend-dbus/guest.h @@ -24,9 +24,8 @@ #include #include "../guest.h" /* parent class */ -#include "dbus-accounts.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" #include "dbus-display-manager.h" @@ -61,11 +60,10 @@ GType indicator_session_guest_dbus_get_type (void); IndicatorSessionGuest * indicator_session_guest_dbus_new (void); -void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus *, - Accounts *, - DisplayManagerSeat *, - ConsoleKitSeat *, - ConsoleKitSession *); +void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus * self, + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * display_manager_seat); G_END_DECLS -- cgit v1.2.3 From df6db45c1bf1ca1e678e8f19974f48c4ead2b06e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:20:23 -0500 Subject: in IndicatorSessionUsers, update to login1 --- src/backend-dbus/users.c | 813 +++++++++++++++++++++-------------------------- src/backend-dbus/users.h | 8 +- 2 files changed, 370 insertions(+), 451 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 6d9ada6..4466ede 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -17,35 +17,28 @@ * with this program. If not, see . */ -#include "dbus-accounts.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" -#include "dbus-consolekit-manager.h" #include "dbus-user.h" #include "users.h" struct _IndicatorSessionUsersDbusPriv { - char * active_session_id; - - Accounts * accounts; - + Login1Manager * login1_manager; + Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; + Accounts * accounts; - ConsoleKitSeat * seat_proxy; - - /* user's dbus object path -> AccountsUser* */ - GHashTable * path_to_user; + /* hash table of int uids to AccountsUser* */ + GHashTable * uid_to_account; - /* uint32 user-id --> user's dbus object path */ - GHashTable * uid_to_user_path; + /* a hashset of int uids of users who are logged in */ + GHashTable * logins; - /* uint32 user-id --> hashset of ssid strings */ - GHashTable * uid_to_sessions; + /* the user-id of the owner of the active session */ + guint active_uid; - /* ssid string --> uint32 user-id */ - GHashTable * session_to_uid; + /* true if this is a live session */ + gboolean is_live; GCancellable * cancellable; }; @@ -60,41 +53,176 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ -static void create_user_proxy_for_path (IndicatorSessionUsersDbus * self, - const char * path); +static const gchar * +get_public_key_for_uid (guint uid) +{ + static char buf[16]; + g_snprintf (buf, sizeof(buf), "%u", uid); + return buf; +} + +static void +emit_user_added (IndicatorSessionUsersDbus * self, guint uid) +{ + const gchar * const public_key = get_public_key_for_uid (uid); + indicator_session_users_added (INDICATOR_SESSION_USERS(self), public_key); +} + +static void +emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) +{ + const gchar * const public_key = get_public_key_for_uid (uid); + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), public_key); +} + +static void +emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) +{ + const gchar * const public_key = get_public_key_for_uid (uid); + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), public_key); +} -static void create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, - const char * ssid); +/*** +**** +***/ static void -emit_user_changed_for_path (IndicatorSessionUsersDbus * self, const char * path) +set_is_live_session_flag (IndicatorSessionUsersDbus * self, gboolean b) { - AccountsUser * user = g_hash_table_lookup (self->priv->path_to_user, path); + priv_t * p = self->priv; + + if (p->is_live != b) + { + p->is_live = b; - if (user && !accounts_user_get_system_account (user)) - indicator_session_users_changed (INDICATOR_SESSION_USERS(self), path); + indicator_session_users_notify_is_live_session (INDICATOR_SESSION_USERS (self)); + } } static void -emit_user_changed_for_uid (IndicatorSessionUsersDbus * self, guint uid) +set_active_uid (IndicatorSessionUsersDbus * self, guint uid) { - const char * path; + priv_t * p = self->priv; + + g_message ("%s %s setting active uid to %u", G_STRLOC, G_STRFUNC, uid); + + if (p->active_uid != uid) + { + const guint old_uid = p->active_uid; - if ((path = g_hash_table_lookup (self->priv->uid_to_user_path, GUINT_TO_POINTER(uid)))) - emit_user_changed_for_path (self, path); + p->active_uid = uid; + + if (old_uid) + emit_user_changed (self, old_uid); + + if (uid) + emit_user_changed (self, uid); + } +} + +static void +set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) +{ + GHashTable * old_logins = self->priv->logins; + gpointer key; + GHashTableIter iter; + + self->priv->logins = logins; + + /* fire 'user changed' event for users who logged out */ + g_hash_table_iter_init (&iter, old_logins); + while ((g_hash_table_iter_next (&iter, &key, NULL))) + if (!g_hash_table_contains (logins, key)) + emit_user_changed (self, GPOINTER_TO_INT(key)); + + /* fire 'user changed' event for users who logged in */ + g_hash_table_iter_init (&iter, logins); + while ((g_hash_table_iter_next (&iter, &key, NULL))) + if (!g_hash_table_contains (old_logins, key)) + emit_user_changed (self, GPOINTER_TO_INT(key)); + + g_hash_table_destroy (old_logins); } /*** -**** ACCOUNT MANAGER / USER TRACKING +**** ***/ +static GQuark +get_connection_list_quark (void) +{ + static GQuark q = 0; + + if (G_UNLIKELY (q == 0)) + q = g_quark_from_static_string ("connection-ids"); + + return q; +} + +static void +object_unref_and_disconnect (gpointer instance) +{ + GSList * l; + GSList * ids; + const GQuark q = get_connection_list_quark (); + + ids = g_object_steal_qdata (G_OBJECT(instance), q); + for (l=ids; l!=NULL; l=l->next) + { + gulong * handler_id = l->data; + g_signal_handler_disconnect (instance, *handler_id); + g_free (handler_id); + } + + g_slist_free (ids); +} + +static void +object_add_connection (GObject * o, gulong connection_id) +{ + const GQuark q = get_connection_list_quark (); + GSList * ids; + gulong * ptr; + + ptr = g_new (gulong, 1); + *ptr = connection_id; + + ids = g_object_steal_qdata (o, q); + ids = g_slist_prepend (ids, ptr); + g_object_set_qdata (o, q, ids); +} + +/*** +**** +***/ + +static AccountsUser * +get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + priv_t * p = self->priv; + + return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); +} + +static AccountsUser * +get_user_for_public_key (IndicatorSessionUsersDbus * self, const char * public_key) +{ + return get_user_for_uid (self, g_ascii_strtoull (public_key, NULL, 10)); +} + +/*** +**** User Account Tracking +***/ + +static void create_user_proxy_for_path (IndicatorSessionUsersDbus *, const char *); + /* called when a user proxy gets the 'Changed' signal */ static void on_user_changed (AccountsUser * user, gpointer gself) { /* Accounts.User doesn't update properties in the standard way, * so create a new proxy to pull in the new properties. - * The older proxy is freed when it's removed from our path_to_user hash */ + * The older proxy is freed when it's replaced in our accounts hash */ const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); create_user_proxy_for_path (gself, path); } @@ -103,32 +231,24 @@ static void track_user (IndicatorSessionUsersDbus * self, AccountsUser * user) { - priv_t * p; - const char * path; + priv_t * p = self->priv; + const guint32 uid = accounts_user_get_uid (user); + const gpointer uid_key = GUINT_TO_POINTER (uid); gboolean already_had_user; + gulong id; - p = self->priv; - - path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); - already_had_user = g_hash_table_contains (p->path_to_user, path); + already_had_user = g_hash_table_contains (p->uid_to_account, uid_key); - g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); - g_hash_table_insert (p->path_to_user, g_strdup(path), user); + id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); + object_add_connection (G_OBJECT(user), id); + g_hash_table_insert (p->uid_to_account, uid_key, user); - if (already_had_user) - { - emit_user_changed_for_path (self, path); - } - else + if (!accounts_user_get_system_account (user)) { - const guint uid = (guint) accounts_user_get_uid (user); - - g_hash_table_insert (p->uid_to_user_path, - GUINT_TO_POINTER(uid), - g_strdup(path)); - - if (!accounts_user_get_system_account (user)) - indicator_session_users_added (INDICATOR_SESSION_USERS(self), path); + if (already_had_user) + emit_user_changed (self, uid); + else + emit_user_added (self, uid); } } @@ -136,14 +256,28 @@ static void untrack_user (IndicatorSessionUsersDbus * self, const gchar * path) { - g_hash_table_remove (self->priv->path_to_user, path); + guint uid; + gpointer key; + gpointer val; + GHashTableIter iter; + priv_t * p = self->priv; - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), path); -} + uid = 0; + g_hash_table_iter_init (&iter, p->uid_to_account); + while (!uid && g_hash_table_iter_next (&iter, &key, &val)) + if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (val))) + uid = GPOINTER_TO_UINT (key); + + if (uid) + { + g_hash_table_remove (p->uid_to_account, GUINT_TO_POINTER(uid)); + emit_user_removed (self, uid); + } +} static void -on_user_proxy_ready (GObject * o G_GNUC_UNUSED, +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer self) { @@ -169,15 +303,15 @@ static void create_user_proxy_for_path (IndicatorSessionUsersDbus * self, const char * path) { - const char * name = "org.freedesktop.Accounts"; - const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, path, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.Accounts", + path, self->priv->cancellable, on_user_proxy_ready, self); } +/* create user proxies for everything in Account's user-list */ static void on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) { @@ -233,348 +367,143 @@ set_account_manager (IndicatorSessionUsersDbus * self, Accounts * a) } } -/** - * SEAT / SESSION TRACKING - * - * There are two simple goals here: - * - * 1. Keep track of how many GUI sessions each user has - * so that we can set the 'is_logged_in' flag correctly - * - * 2. Also track which is the current session, - * so that we can compare it to those GUI sessions to - * set the 'is_current_session' flag correctly. - * - * Now that you know the goals, these steps may make more sense: - * - * 1. create a ConsoleKitManager proxy - * 2. ask it for the current session - * 3. create a corresponding Session proxy - * 4. ask that Session proxy for its seat - * 5. create a corresponding Seat proxy - * 6. connect to that seat's session-added / session-removed signals - * 7. ask the seat for a list of its current sessions - * 8. create corresponding Session proxies - * 9. of them, look for the GUI sessions by checking their X11 properties - * 10. for each GUI session, get the corresponding uid - * 11. use the information to update our uid <--> GUI sessions tables - */ - -static void -track_session (IndicatorSessionUsersDbus * self, - const char * ssid, - guint uid) -{ - gpointer uid_key; - GHashTable * sessions; - - uid_key = GUINT_TO_POINTER (uid); - sessions = g_hash_table_lookup (self->priv->uid_to_sessions, uid_key); - if (sessions == NULL) - { - sessions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - g_hash_table_insert (self->priv->uid_to_sessions, uid_key, sessions); - } - - g_hash_table_add (sessions, g_strdup (ssid)); - g_hash_table_insert (self->priv->session_to_uid, g_strdup(ssid), uid_key); - - g_debug ("%s %s now tracking ssid:%s uid:%u. uid has %u tracked ssids.", - G_STRLOC, G_STRFUNC, ssid, uid, g_hash_table_size (sessions)); - - emit_user_changed_for_uid (self, uid); -} - -static void -untrack_session (IndicatorSessionUsersDbus * self, - const char * ssid) -{ - gpointer uidptr; - priv_t * p = self->priv; - - if (g_hash_table_lookup_extended (p->session_to_uid, ssid, NULL, &uidptr)) - { - const guint uid = GPOINTER_TO_UINT (uidptr); - GHashTable * sessions = g_hash_table_lookup (p->uid_to_sessions, uidptr); - - g_hash_table_remove (p->session_to_uid, ssid); - g_hash_table_remove (sessions, ssid); - g_debug ("%s %s not tracking ssid:%s uid:%u. uid has %u tracked ssids.", - G_STRLOC, G_STRFUNC, ssid, uid, - sessions ? g_hash_table_size (sessions) : 0); - - emit_user_changed_for_uid (self, uid); - } -} +/*** +**** +***/ +/* Based on the login1 manager's list of current sessions, + update our 'logins', 'is_live', and 'active_uid' fields */ static void -on_session_proxy_uid_ready (GObject * o, - GAsyncResult * res, - gpointer gself) +on_login1_manager_session_list_ready (GObject * o, + GAsyncResult * res, + gpointer gself) { - guint uid; + GVariant * sessions; GError * err; - ConsoleKitSession * session = CONSOLE_KIT_SESSION (o); - uid = 0; + sessions = NULL; err = NULL; - console_kit_session_call_get_unix_user_finish (session, &uid, 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 if (uid) - { - const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(session)); - track_session (gself, path, uid); - } + login1_manager_call_list_sessions_finish (LOGIN1_MANAGER(o), + &sessions, + res, + &err); - g_object_unref (o); -} - -static void -on_session_x11_display_ready (GObject * o, - GAsyncResult * res, - gpointer gself) -{ - priv_t * p; - GError * err; - gchar * gui; - ConsoleKitSession * session; - - p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; - - err = NULL; - gui = NULL; - session = CONSOLE_KIT_SESSION (o); - console_kit_session_call_get_x11_display_finish (session, &gui, 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_warning ("%s: %s", G_STRFUNC, err->message); g_error_free (err); } else { - gboolean is_gui_session; - - is_gui_session = gui && *gui; - - if (!is_gui_session) - g_clear_object (&session); - else - console_kit_session_call_get_unix_user (session, - p->cancellable, - on_session_proxy_uid_ready, - gself); + const gchar * const current_seat_id = g_getenv ("XDG_SEAT"); + const gchar * const current_session_id = g_getenv ("XDG_SESSION_ID"); + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (gself); + const gchar * session_id = NULL; + guint32 uid = 0; + const gchar * user_name = NULL; + const gchar * seat_id = NULL; + const gchar * path = NULL; + gboolean is_live_session = FALSE; + GHashTable * logins = g_hash_table_new (g_direct_hash, g_direct_equal); + GVariantIter iter; + + g_message ("%s %s %s", G_STRLOC, G_STRFUNC, g_variant_print (sessions, TRUE)); + + g_variant_iter_init (&iter, sessions); + while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, + &uid, + &user_name, + &seat_id, + &path)) + { + /* only track sessions on our seat */ + if (g_strcmp0 (seat_id, current_seat_id)) + continue; - g_free (gui); - } -} + if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) + is_live_session = TRUE; -static void -on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) -{ - GError * err; - ConsoleKitSession * session; + if (!g_strcmp0 (session_id, current_session_id)) + set_active_uid (self, uid); - 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); + /* only count user accounts and the live session */ + if (uid >= 999) + g_hash_table_add (logins, GINT_TO_POINTER(uid)); + } - g_error_free (err); - } - else if (session != NULL) - { - priv_t * p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; + set_is_live_session_flag (self, is_live_session); + set_logins (self, logins); - console_kit_session_call_get_x11_display (session, - p->cancellable, - on_session_x11_display_ready, - gself); + g_variant_unref (sessions); } } static void -create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, - const char * ssid) -{ - const char * name = "org.freedesktop.ConsoleKit"; - GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - - console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, ssid, - self->priv->cancellable, - on_session_proxy_ready, self); -} - -static void -on_session_list_ready (GObject * o, GAsyncResult * res, gpointer gself) -{ - GError * err; - gchar ** sessions; - - err = NULL; - sessions = NULL; - console_kit_seat_call_get_sessions_finish (CONSOLE_KIT_SEAT(o), - &sessions, 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 - { - int i; - - for (i=0; sessions && sessions[i]; i++) - create_session_proxy_for_ssid (gself, sessions[i]); - - g_strfreev (sessions); - } -} - -static inline guint -get_uid_for_session (IndicatorSessionUsersDbus * self, const char * ssid) +update_session_list (IndicatorSessionUsersDbus * self) { - guint uid = 0; - gpointer value; - - if (ssid != NULL) - if ((value = g_hash_table_lookup (self->priv->session_to_uid, ssid))) - uid = GPOINTER_TO_UINT (value); - - return uid; -} - -/* it's a live session if username is 'ubuntu' and uid is 999 */ -static gboolean -is_live_ssid (IndicatorSessionUsersDbus * self, const char * ssid) -{ - priv_t * p; - guint uid; - - p = INDICATOR_SESSION_USERS_DBUS (self)->priv; - uid = get_uid_for_session (self, ssid); + priv_t * p = self->priv; - if (uid == 999) + if (p->login1_manager != NULL) { - const char * path; - AccountsUser * user = NULL; - - if ((path = g_hash_table_lookup (p->uid_to_user_path, GUINT_TO_POINTER (uid)))) - user = g_hash_table_lookup (p->path_to_user, path); - - return (user != NULL) && !g_strcmp0 (accounts_user_get_user_name(user), "ubuntu"); + login1_manager_call_list_sessions (p->login1_manager, + p->cancellable, + on_login1_manager_session_list_ready, + self); } - - return FALSE; } - static void -set_active_session (IndicatorSessionUsersDbus * self, const char * ssid) +set_login1_manager (IndicatorSessionUsersDbus * self, Login1Manager * login1_manager) { priv_t * p = self->priv; - const guint old_uid = get_uid_for_session (self, p->active_session_id); - const guint new_uid = get_uid_for_session (self, ssid); - const gboolean old_live = is_live_ssid (self, p->active_session_id); - const gboolean new_live = is_live_ssid (self, ssid); - - g_debug ("%s %s changing active_session_id from '%s' to '%s'", - G_STRLOC, G_STRFUNC, p->active_session_id, ssid); - g_free (p->active_session_id); - p->active_session_id = g_strdup (ssid); - if (old_uid != new_uid) + if (p->login1_manager != NULL) { - emit_user_changed_for_uid (self, old_uid); - emit_user_changed_for_uid (self, new_uid); - } + g_signal_handlers_disconnect_by_data (p->login1_manager, self); - if (old_live != new_live) - { - indicator_session_users_notify_is_live_session (INDICATOR_SESSION_USERS(self)); + g_clear_object (&p->login1_manager); } -} -static void -on_seat_active_session_ready (GObject * o, GAsyncResult * res, gpointer gself) -{ - GError * err; - gchar * ssid; - ConsoleKitSeat * seat; - - err = NULL; - ssid = NULL; - seat = CONSOLE_KIT_SEAT (o); - console_kit_seat_call_get_active_session_finish (seat, &ssid, res, &err); - if (err != NULL) + if (login1_manager != NULL) { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + p->login1_manager = g_object_ref (login1_manager); - g_error_free (err); - } - else if (ssid != NULL) - { - set_active_session (INDICATOR_SESSION_USERS_DBUS(gself), ssid); - g_free (ssid); + 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_seat (IndicatorSessionUsersDbus * self, ConsoleKitSeat * seat) +set_login1_seat (IndicatorSessionUsersDbus * self, + Login1Seat * login1_seat) { priv_t * p = self->priv; - if (p->seat_proxy != NULL) + if (p->login1_seat != NULL) { - g_signal_handlers_disconnect_by_data (p->seat_proxy, self); - g_clear_object (&p->seat_proxy); + g_signal_handlers_disconnect_by_data (p->login1_seat, self); + + g_clear_object (&p->login1_seat); } - if (seat != NULL) + if (login1_seat != NULL) { - p->seat_proxy = g_object_ref (seat); - - /* ask the seat for a list of all the sessions */ - console_kit_seat_call_get_sessions (seat, - p->cancellable, - on_session_list_ready, - self); + p->login1_seat = g_object_ref (login1_seat); - /* ask the seat for the name of the active session */ - console_kit_seat_call_get_active_session (p->seat_proxy, - p->cancellable, - on_seat_active_session_ready, - self); - - /* listen for session changes in this seat */ - g_signal_connect_swapped (seat, "session-added", - G_CALLBACK(create_session_proxy_for_ssid),self); - g_signal_connect_swapped (seat, "session-removed", - G_CALLBACK(untrack_session), self); - g_signal_connect_swapped (seat, "active-session-changed", - G_CALLBACK(set_active_session), self); + g_signal_connect_swapped (login1_seat, "notify::active-session", + G_CALLBACK(update_session_list), self); + update_session_list (self); } } -/*** -**** -***/ - static void -set_dm_seat (IndicatorSessionUsersDbus * self, DisplayManagerSeat * dm_seat) +set_display_manager_seat (IndicatorSessionUsersDbus * self, + DisplayManagerSeat * dm_seat) { priv_t * p = self->priv; @@ -584,85 +513,49 @@ set_dm_seat (IndicatorSessionUsersDbus * self, DisplayManagerSeat * dm_seat) p->dm_seat = g_object_ref (dm_seat); } -static void -activate_username (IndicatorSessionUsersDbus * self, const char * username) -{ - priv_t * p = self->priv; - const char * session = ""; - - g_return_if_fail (p->dm_seat != NULL); - - display_manager_seat_call_switch_to_user (p->dm_seat, username, session, - p->cancellable, NULL, NULL); -} - /*** -**** +**** IndicatorSessionUsers virtual functions ***/ +/* switch to (or create) a session for the specified user */ static void -my_dispose (GObject * o) +my_activate_user (IndicatorSessionUsers * users, const char * public_key) { - IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); priv_t * p = self->priv; + AccountsUser * au; + const char * username; - if (p->cancellable) + au = get_user_for_public_key (self, public_key); + username = au ? accounts_user_get_user_name (au) : NULL; + + if (!username) { - g_cancellable_cancel (p->cancellable); - g_clear_object (&p->cancellable); + g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, public_key); } - - set_seat (self, NULL); - set_dm_seat (self, NULL); - set_account_manager (self, NULL); - - g_clear_pointer (&p->path_to_user, g_hash_table_destroy); - g_clear_pointer (&p->session_to_uid, g_hash_table_destroy); - g_clear_pointer (&p->uid_to_sessions, g_hash_table_destroy); - g_clear_pointer (&p->uid_to_user_path, g_hash_table_destroy); - - G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->dispose (o); -} - -static void -my_finalize (GObject * o) -{ - IndicatorSessionUsersDbus * u = INDICATOR_SESSION_USERS_DBUS (o); - - g_free (u->priv->active_session_id); - - G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->finalize (o); -} - -static void -my_activate_user (IndicatorSessionUsers * users, const char * key) -{ - priv_t * p; - const char * username = 0; - - p = INDICATOR_SESSION_USERS_DBUS (users)->priv; - if (p != 0) + else { - AccountsUser * au = g_hash_table_lookup (p->path_to_user, key); + g_return_if_fail (p->dm_seat != NULL); - if (au != NULL) - username = accounts_user_get_user_name (au); + display_manager_seat_call_switch_to_user (p->dm_seat, + username, + "", + p->cancellable, + NULL, + NULL); } - - if (username != 0) - activate_username (INDICATOR_SESSION_USERS_DBUS(users), username); - else - g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, key); } +/* returns true if this is a live session */ static gboolean my_is_live_session (IndicatorSessionUsers * users) { - IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), FALSE); - return is_live_ssid (self, self->priv->active_session_id); + return INDICATOR_SESSION_USERS_DBUS(users)->priv->is_live; } +/* get a list of public keys for the users that we know about */ static GStrv my_get_keys (IndicatorSessionUsers * users) { @@ -670,64 +563,93 @@ my_get_keys (IndicatorSessionUsers * users) priv_t * p; gchar ** keys; GHashTableIter iter; - gpointer path; + gpointer uid; gpointer user; + GHashTable * h; g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); p = INDICATOR_SESSION_USERS_DBUS (users)->priv; i = 0; - keys = g_new (gchar*, g_hash_table_size(p->path_to_user)+1); - g_hash_table_iter_init (&iter, p->path_to_user); - while (g_hash_table_iter_next (&iter, &path, &user)) + h = p->uid_to_account; + keys = g_new (gchar*, g_hash_table_size(h)+1); + g_hash_table_iter_init (&iter, h); + while (g_hash_table_iter_next (&iter, &uid, &user)) if (!accounts_user_get_system_account (user)) - keys[i++] = g_strdup (path); + keys[i++] = g_strdup (get_public_key_for_uid ((guint)uid)); keys[i] = NULL; return keys; } +/* build a new struct populated with info on the specified user */ static IndicatorSessionUser * -my_get_user (IndicatorSessionUsers * users, const gchar * key) +my_get_user (IndicatorSessionUsers * users, const gchar * public_key) { - priv_t * p; + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users); + priv_t * p = self->priv; + IndicatorSessionUser * ret; AccountsUser * au; - IndicatorSessionUser * ret = NULL; - p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + ret = NULL; + au = get_user_for_public_key (self, public_key); - au = g_hash_table_lookup (p->path_to_user, key); if (au && !accounts_user_get_system_account(au)) { - const guint uid = (guint) accounts_user_get_uid (au); - GHashTable * s; + const guint uid = accounts_user_get_uid (au); ret = g_new0 (IndicatorSessionUser, 1); - - s = g_hash_table_lookup (p->uid_to_sessions, GUINT_TO_POINTER(uid)); - if (s == NULL) - { - ret->is_logged_in = FALSE; - ret->is_current_user = FALSE; - } - else - { - ret->is_logged_in = g_hash_table_size (s) > 0; - ret->is_current_user = g_hash_table_contains (s, p->active_session_id); - } - ret->uid = uid; ret->user_name = g_strdup (accounts_user_get_user_name (au)); ret->real_name = g_strdup (accounts_user_get_real_name (au)); ret->icon_file = g_strdup (accounts_user_get_icon_file (au)); ret->login_frequency = accounts_user_get_login_frequency (au); + ret->is_logged_in = g_hash_table_contains (p->logins, GINT_TO_POINTER(uid)); + ret->is_current_user = uid == p->active_uid; } return ret; } +/*** +**** GObject virtual functions +***/ + +static void +my_dispose (GObject * o) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + priv_t * p = self->priv; + + if (p->cancellable) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + + set_account_manager (self, NULL); + set_display_manager_seat (self, NULL); + set_login1_seat (self, NULL); + set_login1_manager (self, NULL); + + g_hash_table_remove_all (p->uid_to_account); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + priv_t * p = self->priv; + + g_hash_table_destroy (p->logins); + g_hash_table_destroy (p->uid_to_account); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->finalize (o); +} + static void -/* cppcheck-suppress unusedFunction */ indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) { GObjectClass * object_class; @@ -747,7 +669,6 @@ indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) } static void -/* cppcheck-suppress unusedFunction */ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) { priv_t * p; @@ -758,18 +679,12 @@ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) self->priv = p; p->cancellable = g_cancellable_new (); - p->path_to_user = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_object_unref); - - p->uid_to_user_path = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, g_free); - - p->session_to_uid = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); + p->uid_to_account = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + object_unref_and_disconnect); - p->uid_to_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, - (GDestroyNotify)g_hash_table_destroy); + p->logins = g_hash_table_new (g_direct_hash, g_direct_equal); } /*** @@ -786,13 +701,15 @@ indicator_session_users_dbus_new (void) void indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus * self, - Accounts * accounts, + Login1Manager * login1_manager, + Login1Seat * login1_seat, DisplayManagerSeat * dm_seat, - ConsoleKitSeat * seat) + Accounts * accounts) { g_return_if_fail (INDICATOR_IS_SESSION_USERS_DBUS (self)); + set_login1_manager (self, login1_manager); + set_login1_seat (self, login1_seat); + set_display_manager_seat (self, dm_seat); set_account_manager (self, accounts); - set_seat (self, seat); - set_dm_seat (self, dm_seat); } diff --git a/src/backend-dbus/users.h b/src/backend-dbus/users.h index ff1e0ad..a9aaecf 100644 --- a/src/backend-dbus/users.h +++ b/src/backend-dbus/users.h @@ -25,7 +25,8 @@ #include "../users.h" /* parent class */ #include "dbus-accounts.h" -#include "dbus-consolekit-seat.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" #include "dbus-display-manager.h" G_BEGIN_DECLS @@ -60,9 +61,10 @@ GType indicator_session_users_dbus_get_type (void); IndicatorSessionUsers * indicator_session_users_dbus_new (void); void indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus *, - Accounts *, + Login1Manager *, + Login1Seat *, DisplayManagerSeat *, - ConsoleKitSeat *); + Accounts *); -- cgit v1.2.3 From 94f830aa6324ffa32913bfc8c8dd6c7bce07c9af Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:06:36 -0500 Subject: we don't need a login1 session proxy, so don't generate code for one. --- src/backend-dbus/CMakeLists.txt | 4 -- .../org.freedesktop.login1.Session.xml | 49 ---------------------- 2 files changed, 53 deletions(-) delete mode 100644 src/backend-dbus/org.freedesktop.login1.Session.xml (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index 58d7b6a..eb4d971 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -25,10 +25,6 @@ add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-seat org.freedesktop ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Seat.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-session - org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Session.xml) - add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-user org.freedesktop ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.User.xml) diff --git a/src/backend-dbus/org.freedesktop.login1.Session.xml b/src/backend-dbus/org.freedesktop.login1.Session.xml deleted file mode 100644 index 24a6fac..0000000 --- a/src/backend-dbus/org.freedesktop.login1.Session.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From 1b73a52e6a30b9217cdddc7b6f166a421613eaf6 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:07:12 -0500 Subject: migrate from consolekit to login1 --- src/backend-dbus/actions.c | 180 ++++++++++++++++++++++----------------------- src/backend-dbus/actions.h | 12 ++- 2 files changed, 91 insertions(+), 101 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index bc196f2..a74a524 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -20,7 +20,7 @@ #include #include "dbus-end-session-dialog.h" -#include "dbus-upower.h" +#include "dbus-login1-manager.h" #include "dbus-webcredentials.h" #include "gnome-screen-saver.h" #include "gnome-session-manager.h" @@ -39,17 +39,16 @@ struct _IndicatorSessionActionsDbusPriv GCancellable * cancellable; GSettings * lockdown_settings; - UPower * upower; GnomeScreenSaver * screen_saver; GnomeSessionManager * session_manager; - ConsoleKitManager * ck_manager; - ConsoleKitSeat * ck_seat; + Login1Manager * login1_manager; + Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; Webcredentials * webcredentials; EndSessionDialog * end_session_dialog; - gboolean suspend_allowed; - gboolean hibernate_allowed; + gboolean can_suspend; + gboolean can_hibernate; gboolean seat_allows_activation; }; @@ -75,42 +74,38 @@ log_and_clear_error (GError ** err, const char * loc, const char * func) } } +/*** +**** +***/ + static void -on_can_activate_sessions (GObject * o, GAsyncResult * res, gpointer gself) +on_seat_notify_multi_session (IndicatorSessionActionsDbus * self) { - GError * err; - gboolean can_activate_sessions; + priv_t * p = self->priv; + gboolean b; - err = NULL; - can_activate_sessions = FALSE; - console_kit_seat_call_can_activate_sessions_finish (CONSOLE_KIT_SEAT(o), - &can_activate_sessions, - res, - &err); - if (err == NULL) + b = login1_seat_get_can_multi_session (p->login1_seat); + + if (p->seat_allows_activation != b) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - p->seat_allows_activation = can_activate_sessions; - } + p->seat_allows_activation = b; - log_and_clear_error (&err, G_STRLOC, G_STRFUNC); + indicator_session_actions_notify_can_switch (INDICATOR_SESSION_ACTIONS(self)); + } } static void -set_ck_seat (IndicatorSessionActionsDbus * self, ConsoleKitSeat * seat) +set_login1_seat (IndicatorSessionActionsDbus * self, Login1Seat * seat) { priv_t * p = self->priv; - g_clear_object (&p->ck_seat); + g_clear_object (&p->login1_seat); if (seat != NULL) { - p->ck_seat = g_object_ref (seat); + p->login1_seat = g_object_ref (seat); - console_kit_seat_call_can_activate_sessions (seat, - p->cancellable, - on_can_activate_sessions, - self); + g_signal_connect_swapped (seat, "notify::can-multi-session", G_CALLBACK(on_seat_notify_multi_session), self); } } @@ -153,75 +148,83 @@ on_screensaver_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpoin } static void -on_suspend_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +on_can_suspend_ready (GObject * o, GAsyncResult * res, gpointer gself) { + char * str; GError * err; - gboolean allowed = FALSE; + str = NULL; err = NULL; - upower_call_suspend_allowed_finish (UPOWER(o), &allowed, res, &err); + login1_manager_call_can_suspend_finish (LOGIN1_MANAGER(o), &str, res, &err); if (err == NULL) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - if (p->suspend_allowed != allowed) + const gboolean b = !g_strcmp0 (str, "yes") || + !g_strcmp0 (str, "challenge"); + + if (p->can_suspend != b) { - p->suspend_allowed = allowed; + p->can_suspend = b; indicator_session_actions_notify_can_suspend (gself); } + + g_free (str); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); } static void -on_hibernate_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +on_can_hibernate_ready (GObject * o, GAsyncResult * res, gpointer gself) { + gchar * str; GError * err; - gboolean allowed = FALSE; + str = NULL; err = NULL; - upower_call_hibernate_allowed_finish (UPOWER(o), &allowed, res, &err); + login1_manager_call_can_hibernate_finish (LOGIN1_MANAGER(o), &str, res, &err); if (err == NULL) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - if (p->hibernate_allowed != allowed) + const gboolean b = !g_strcmp0 (str, "yes") || + !g_strcmp0 (str, "challenge"); + + if (p->can_hibernate != b) { - p->hibernate_allowed = allowed; + p->can_hibernate = b; indicator_session_actions_notify_can_hibernate (gself); } + + g_free (str); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); } static void -on_upower_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +set_login1_manager (IndicatorSessionActionsDbus * self, + Login1Manager * login1_manager) { - GError * err; - UPower * upower; - - err = NULL; - upower = upower_proxy_new_for_bus_finish (res, &err); - if (err == NULL) - { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - - p->upower = upower; + priv_t * p = self->priv; - g_signal_connect_swapped (upower, "notify::can-suspend", - G_CALLBACK(indicator_session_actions_notify_can_suspend), gself); + g_clear_object (&p->login1_manager); - g_signal_connect_swapped (upower, "notify::can-hibernate", - G_CALLBACK(indicator_session_actions_notify_can_hibernate), gself); + if (login1_manager != NULL) + { + p->login1_manager = g_object_ref (login1_manager); - upower_call_suspend_allowed (upower, p->cancellable, on_suspend_allowed_ready, gself); + login1_manager_call_can_suspend (p->login1_manager, + p->cancellable, + on_can_suspend_ready, + self); - upower_call_hibernate_allowed (upower, p->cancellable, on_hibernate_allowed_ready, gself); + login1_manager_call_can_hibernate (p->login1_manager, + p->cancellable, + on_can_hibernate_ready, + self); } - - log_and_clear_error (&err, G_STRLOC, G_STRFUNC); } static void @@ -311,7 +314,7 @@ my_can_suspend (IndicatorSessionActions * self) { const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return p && p->upower && p->suspend_allowed && upower_get_can_suspend (p->upower); + return p && p->can_suspend; } static gboolean @@ -319,7 +322,7 @@ my_can_hibernate (IndicatorSessionActions * self) { const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return p && p->upower && p->hibernate_allowed && upower_get_can_hibernate (p->upower); + return p && p->can_hibernate; } static gboolean @@ -345,9 +348,9 @@ my_suspend (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->upower != NULL); + g_return_if_fail (p->login1_manager != NULL); - upower_call_suspend (p->upower, p->cancellable, NULL, NULL); + login1_manager_call_suspend (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } static void @@ -355,9 +358,9 @@ my_hibernate (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->upower != NULL); + g_return_if_fail (p->login1_manager != NULL); - upower_call_hibernate (p->upower, p->cancellable, NULL, NULL); + login1_manager_call_hibernate (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } /*** @@ -392,23 +395,23 @@ logout_now_quietly (IndicatorSessionActions * self) } static void -restart_now (IndicatorSessionActions * self) +reboot_now (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->ck_manager != NULL); + g_return_if_fail (p->login1_manager != NULL); - console_kit_manager_call_restart (p->ck_manager, p->cancellable, NULL, NULL); + login1_manager_call_reboot (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } static void -shutdown_now (IndicatorSessionActions * self) +power_off_now (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->ck_manager != NULL); + g_return_if_fail (p->login1_manager != NULL); - console_kit_manager_call_stop (p->ck_manager, p->cancellable, NULL, NULL); + login1_manager_call_power_off (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } static void @@ -447,8 +450,8 @@ show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) g_assert (o != NULL); g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now_quietly), self); - g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(restart_now), self); - g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(shutdown_now), self); + g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(reboot_now), self); + g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(power_off_now), self); g_signal_connect_swapped (o, "canceled", G_CALLBACK(on_end_session_dialog_canceled), self); g_signal_connect_swapped (o, "closed", G_CALLBACK(on_end_session_dialog_closed), self); @@ -469,23 +472,23 @@ my_logout (IndicatorSessionActions * self) static void -my_restart (IndicatorSessionActions * self) +my_reboot (IndicatorSessionActions * self) { if (my_can_prompt (self)) show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); else - restart_now (self); + reboot_now (self); } static void -my_shutdown (IndicatorSessionActions * self) +my_power_off (IndicatorSessionActions * self) { /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because the latter adds lock & logout options in Unity... */ if (my_can_prompt (self)) show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); else - shutdown_now (self); + power_off_now (self); } /*** @@ -581,14 +584,13 @@ my_dispose (GObject * o) } g_clear_object (&p->lockdown_settings); - g_clear_object (&p->ck_manager); - g_clear_object (&p->upower); g_clear_object (&p->screen_saver); g_clear_object (&p->session_manager); g_clear_object (&p->webcredentials); g_clear_object (&p->end_session_dialog); set_dm_seat (self, NULL); - set_ck_seat (self, NULL); + set_login1_manager (self, NULL); + set_login1_seat (self, NULL); G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); } @@ -618,8 +620,8 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl actions_class->logout = my_logout; actions_class->suspend = my_suspend; actions_class->hibernate = my_hibernate; - actions_class->restart = my_restart; - actions_class->shutdown = my_shutdown; + actions_class->reboot = my_reboot; + actions_class->power_off = my_power_off; actions_class->settings = my_settings; actions_class->help = my_help; actions_class->about = my_about; @@ -662,14 +664,6 @@ indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) on_screensaver_proxy_ready, self); - upower_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.UPower", - "/org/freedesktop/UPower", - p->cancellable, - on_upower_proxy_ready, - self); - gnome_session_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, "org.gnome.SessionManager", @@ -709,15 +703,13 @@ indicator_session_actions_dbus_new (void) void indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, - ConsoleKitManager * ck_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * ck_seat) + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * dm_seat) { g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS_DBUS(self)); - self->priv->ck_manager = g_object_ref (ck_manager); - + set_login1_manager (self, login1_manager); + set_login1_seat (self, login1_seat); set_dm_seat (self, dm_seat); - - set_ck_seat (self, ck_seat); } diff --git a/src/backend-dbus/actions.h b/src/backend-dbus/actions.h index 997dd73..0c8bed2 100644 --- a/src/backend-dbus/actions.h +++ b/src/backend-dbus/actions.h @@ -24,10 +24,8 @@ #include #include "../actions.h" /* parent class */ -#include "dbus-accounts.h" -#include "dbus-consolekit-manager.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" #include "dbus-display-manager.h" @@ -63,9 +61,9 @@ GType indicator_session_actions_dbus_get_type (void); IndicatorSessionActions * indicator_session_actions_dbus_new (void); void indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, - ConsoleKitManager * ck_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * ck_seat); + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * dm_seat); G_END_DECLS -- cgit v1.2.3 From 9cfc9e9da79cabacf1f81e96511d10895992c47d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:13:07 -0500 Subject: get all the tests in test-actions passing again. --- src/backend-dbus/display-manager.xml | 30 ---------------------- .../org.freedesktop.DisplayManager.Seat | 30 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 30 deletions(-) delete mode 100644 src/backend-dbus/display-manager.xml create mode 100644 src/backend-dbus/org.freedesktop.DisplayManager.Seat (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/display-manager.xml b/src/backend-dbus/display-manager.xml deleted file mode 100644 index 07b5f29..0000000 --- a/src/backend-dbus/display-manager.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/backend-dbus/org.freedesktop.DisplayManager.Seat b/src/backend-dbus/org.freedesktop.DisplayManager.Seat new file mode 100644 index 0000000..07b5f29 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.DisplayManager.Seat @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 0ca4b9a4e6b552b9a59bade1d8d44cc950ded994 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 23:08:12 -0500 Subject: in backend-dbus/users.c, fix a user proxy leak --- src/backend-dbus/users.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 4466ede..c135610 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -172,6 +172,7 @@ object_unref_and_disconnect (gpointer instance) gulong * handler_id = l->data; g_signal_handler_disconnect (instance, *handler_id); g_free (handler_id); + g_object_unref (instance); } g_slist_free (ids); -- cgit v1.2.3 From b3938a1f14b687d62ad1d6e4e27bac47f58722de Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 11:16:34 -0500 Subject: in IndicatorSessionUsers, use the uid as the user's key. Users.ActivateUser is now green. --- src/backend-dbus/users.c | 73 +++++++++++++++++------------------------------- 1 file changed, 25 insertions(+), 48 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index c135610..48de06c 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -53,33 +53,22 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ -static const gchar * -get_public_key_for_uid (guint uid) -{ - static char buf[16]; - g_snprintf (buf, sizeof(buf), "%u", uid); - return buf; -} - static void emit_user_added (IndicatorSessionUsersDbus * self, guint uid) { - const gchar * const public_key = get_public_key_for_uid (uid); - indicator_session_users_added (INDICATOR_SESSION_USERS(self), public_key); + indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) { - const gchar * const public_key = get_public_key_for_uid (uid); - indicator_session_users_changed (INDICATOR_SESSION_USERS(self), public_key); + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) { - const gchar * const public_key = get_public_key_for_uid (uid); - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), public_key); + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); } /*** @@ -124,22 +113,22 @@ static void set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) { GHashTable * old_logins = self->priv->logins; - gpointer key; + gpointer uid; GHashTableIter iter; self->priv->logins = logins; /* fire 'user changed' event for users who logged out */ g_hash_table_iter_init (&iter, old_logins); - while ((g_hash_table_iter_next (&iter, &key, NULL))) - if (!g_hash_table_contains (logins, key)) - emit_user_changed (self, GPOINTER_TO_INT(key)); + while ((g_hash_table_iter_next (&iter, &uid, NULL))) + if (!g_hash_table_contains (logins, uid)) + emit_user_changed (self, GPOINTER_TO_UINT(uid)); /* fire 'user changed' event for users who logged in */ g_hash_table_iter_init (&iter, logins); - while ((g_hash_table_iter_next (&iter, &key, NULL))) - if (!g_hash_table_contains (old_logins, key)) - emit_user_changed (self, GPOINTER_TO_INT(key)); + while ((g_hash_table_iter_next (&iter, &uid, NULL))) + if (!g_hash_table_contains (old_logins, uid)) + emit_user_changed (self, GPOINTER_TO_UINT(uid)); g_hash_table_destroy (old_logins); } @@ -205,12 +194,6 @@ get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); } -static AccountsUser * -get_user_for_public_key (IndicatorSessionUsersDbus * self, const char * public_key) -{ - return get_user_for_uid (self, g_ascii_strtoull (public_key, NULL, 10)); -} - /*** **** User Account Tracking ***/ @@ -520,19 +503,19 @@ set_display_manager_seat (IndicatorSessionUsersDbus * self, /* switch to (or create) a session for the specified user */ static void -my_activate_user (IndicatorSessionUsers * users, const char * public_key) +my_activate_user (IndicatorSessionUsers * users, guint uid) { IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); priv_t * p = self->priv; AccountsUser * au; const char * username; - au = get_user_for_public_key (self, public_key); + au = get_user_for_uid (self, uid); username = au ? accounts_user_get_user_name (au) : NULL; if (!username) { - g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, public_key); + g_warning ("%s %s can't find user '%u'", G_STRLOC, G_STRFUNC, uid); } else { @@ -556,36 +539,31 @@ my_is_live_session (IndicatorSessionUsers * users) return INDICATOR_SESSION_USERS_DBUS(users)->priv->is_live; } -/* get a list of public keys for the users that we know about */ -static GStrv -my_get_keys (IndicatorSessionUsers * users) +/* get a list of our user ids */ +static GList * +my_get_uids (IndicatorSessionUsers * users) { - int i; priv_t * p; - gchar ** keys; + GList * uids; GHashTableIter iter; gpointer uid; gpointer user; - GHashTable * h; g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); p = INDICATOR_SESSION_USERS_DBUS (users)->priv; - i = 0; - h = p->uid_to_account; - keys = g_new (gchar*, g_hash_table_size(h)+1); - g_hash_table_iter_init (&iter, h); + uids = NULL; + g_hash_table_iter_init (&iter, p->uid_to_account); while (g_hash_table_iter_next (&iter, &uid, &user)) if (!accounts_user_get_system_account (user)) - keys[i++] = g_strdup (get_public_key_for_uid ((guint)uid)); - keys[i] = NULL; + uids = g_list_prepend (uids, uid); - return keys; + return uids; } /* build a new struct populated with info on the specified user */ static IndicatorSessionUser * -my_get_user (IndicatorSessionUsers * users, const gchar * public_key) +my_get_user (IndicatorSessionUsers * users, guint uid) { IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users); priv_t * p = self->priv; @@ -593,11 +571,10 @@ my_get_user (IndicatorSessionUsers * users, const gchar * public_key) AccountsUser * au; ret = NULL; - au = get_user_for_public_key (self, public_key); - + au = get_user_for_uid (self, uid); if (au && !accounts_user_get_system_account(au)) { - const guint uid = accounts_user_get_uid (au); + g_assert (uid == accounts_user_get_uid (au)); ret = g_new0 (IndicatorSessionUser, 1); ret->uid = uid; @@ -662,7 +639,7 @@ indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) users_class = INDICATOR_SESSION_USERS_CLASS (klass); users_class->is_live_session = my_is_live_session; - users_class->get_keys = my_get_keys; + users_class->get_uids = my_get_uids; users_class->get_user = my_get_user; users_class->activate_user = my_activate_user; -- cgit v1.2.3 From d16aaaed46f3381ea7ac4cb4c2cb491d4c5d2e03 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 11:39:46 -0500 Subject: all the tests in test-users pass --- src/backend-dbus/users.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 48de06c..1ecadf3 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -93,8 +93,6 @@ set_active_uid (IndicatorSessionUsersDbus * self, guint uid) { priv_t * p = self->priv; - g_message ("%s %s setting active uid to %u", G_STRLOC, G_STRFUNC, uid); - if (p->active_uid != uid) { const guint old_uid = p->active_uid; @@ -393,8 +391,6 @@ on_login1_manager_session_list_ready (GObject * o, GHashTable * logins = g_hash_table_new (g_direct_hash, g_direct_equal); GVariantIter iter; - g_message ("%s %s %s", G_STRLOC, G_STRFUNC, g_variant_print (sessions, TRUE)); - g_variant_iter_init (&iter, sessions); while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, &uid, @@ -406,11 +402,13 @@ on_login1_manager_session_list_ready (GObject * o, if (g_strcmp0 (seat_id, current_seat_id)) continue; - if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) - is_live_session = TRUE; - if (!g_strcmp0 (session_id, current_session_id)) - set_active_uid (self, uid); + { + set_active_uid (self, uid); + + if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) + is_live_session = TRUE; + } /* only count user accounts and the live session */ if (uid >= 999) -- 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') 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') 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 e986476c83c3e647dab067087865f895cd32a899 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 13:07:52 -0500 Subject: only show the restart or hibernate menuitems if login1 says these features are available --- src/backend-dbus/actions.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index a74a524..3f0e6ec 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -160,8 +160,7 @@ on_can_suspend_ready (GObject * o, GAsyncResult * res, gpointer gself) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - const gboolean b = !g_strcmp0 (str, "yes") || - !g_strcmp0 (str, "challenge"); + const gboolean b = !g_strcmp0 (str, "yes"); if (p->can_suspend != b) { @@ -188,8 +187,7 @@ on_can_hibernate_ready (GObject * o, GAsyncResult * res, gpointer gself) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - const gboolean b = !g_strcmp0 (str, "yes") || - !g_strcmp0 (str, "challenge"); + const gboolean b = !g_strcmp0 (str, "yes"); if (p->can_hibernate != b) { -- cgit v1.2.3 From 4c5a5e7146a878a17239e44ce2debffb5b525bf1 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 13:53:44 -0500 Subject: in users.c, fix bugs that leaked system accounts into the list of users to show in the indicator --- src/backend-dbus/users.c | 137 +++++++++++++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 51 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 1ecadf3..1db5ac1 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -53,22 +53,82 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ +/* returns true if the fields indicate this is the 'live cd' user */ +static gboolean +is_live_user (guint uid, const char * username) +{ + return uid==999 && !g_strcmp0 (username, "ubuntu"); +} + +/* returns true if this is a user who should be listed in the session indicator */ +static gboolean +is_public_user (IndicatorSessionUsersDbus * self G_GNUC_UNUSED, + AccountsUser * au) +{ + gboolean is_public; + + /* the 'live session' user is the only system account we'll show */ + if (is_live_user (accounts_user_get_uid(au), accounts_user_get_user_name(au))) + is_public = TRUE; + else + is_public = !accounts_user_get_system_account (au); + + return is_public; +} + +/* get our private org.freedesktop.Accounts.User proxy for the given uid */ +static AccountsUser * +get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + priv_t * p = self->priv; + + return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); +} + +/* returns true if this is a uid that should be listed in the session indicator */ +static gboolean +is_public_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + AccountsUser * au; + gboolean is_public; + + if ((au = get_user_for_uid (self, uid))) + { + is_public = is_public_user (self, au); + } + else + { + /* making a guess to serve until the user's proxy object is ready. + assuming that 999 is a 'live session' user, <999 is system account */ + is_public = uid >= 999; + } + + return is_public; +} + +/*** +**** +***/ + static void emit_user_added (IndicatorSessionUsersDbus * self, guint uid) { - indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); + if (is_public_uid (self, uid)) + indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) { - indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); + if (is_public_uid (self, uid)) + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) { - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); + if (is_public_uid (self, uid)) + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); } /*** @@ -99,11 +159,8 @@ set_active_uid (IndicatorSessionUsersDbus * self, guint uid) p->active_uid = uid; - if (old_uid) - emit_user_changed (self, old_uid); - - if (uid) - emit_user_changed (self, uid); + emit_user_changed (self, old_uid); + emit_user_changed (self, uid); } } @@ -180,18 +237,6 @@ object_add_connection (GObject * o, gulong connection_id) g_object_set_qdata (o, q, ids); } -/*** -**** -***/ - -static AccountsUser * -get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) -{ - priv_t * p = self->priv; - - return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); -} - /*** **** User Account Tracking ***/ @@ -213,25 +258,24 @@ static void track_user (IndicatorSessionUsersDbus * self, AccountsUser * user) { - priv_t * p = self->priv; const guint32 uid = accounts_user_get_uid (user); const gpointer uid_key = GUINT_TO_POINTER (uid); - gboolean already_had_user; + priv_t * p = self->priv; gulong id; + gboolean already_had_user; + + g_return_if_fail (is_public_user (self, user)); already_had_user = g_hash_table_contains (p->uid_to_account, uid_key); - id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); + id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); object_add_connection (G_OBJECT(user), id); g_hash_table_insert (p->uid_to_account, uid_key, user); - if (!accounts_user_get_system_account (user)) - { - if (already_had_user) - emit_user_changed (self, uid); - else - emit_user_added (self, uid); - } + if (already_had_user) + emit_user_changed (self, uid); + else + emit_user_added (self, uid); } static void @@ -258,6 +302,8 @@ untrack_user (IndicatorSessionUsersDbus * self, } } +/* We got a new org.freedesktop.Accounts.User proxy. + If it's one we want to remember, pass it to track_user() */ static void on_user_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, @@ -275,10 +321,14 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else + else if (is_public_user (self, user)) { track_user (self, user); } + else + { + g_object_unref (self); + } } static void @@ -293,7 +343,7 @@ create_user_proxy_for_path (IndicatorSessionUsersDbus * self, on_user_proxy_ready, self); } -/* create user proxies for everything in Account's user-list */ +/* create proxy objects for everything in Account's user-list */ static void on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) { @@ -406,12 +456,11 @@ on_login1_manager_session_list_ready (GObject * o, { set_active_uid (self, uid); - if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) + if (is_live_user (uid, user_name)) is_live_session = TRUE; } - /* only count user accounts and the live session */ - if (uid >= 999) + if (is_public_uid (self, uid)) g_hash_table_add (logins, GINT_TO_POINTER(uid)); } @@ -541,22 +590,8 @@ my_is_live_session (IndicatorSessionUsers * users) static GList * my_get_uids (IndicatorSessionUsers * users) { - priv_t * p; - GList * uids; - GHashTableIter iter; - gpointer uid; - gpointer user; - - g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); - p = INDICATOR_SESSION_USERS_DBUS (users)->priv; - - uids = NULL; - g_hash_table_iter_init (&iter, p->uid_to_account); - while (g_hash_table_iter_next (&iter, &uid, &user)) - if (!accounts_user_get_system_account (user)) - uids = g_list_prepend (uids, uid); - - return uids; + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users); + return g_hash_table_get_keys (self->priv->uid_to_account); } /* build a new struct populated with info on the specified user */ -- cgit v1.2.3 From cc57405ebf537239ab2953b41b27908b6dadfbeb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 21:43:13 -0500 Subject: in actions.c's my_can_prompt(), don't leak the string returned by g_dbus_proxy_get_name_owner --- src/backend-dbus/actions.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 3f0e6ec..67fe9f1 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -326,11 +326,18 @@ my_can_hibernate (IndicatorSessionActions * self) static gboolean my_can_prompt (IndicatorSessionActions * self) { + gboolean can_prompt = FALSE; const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return (p != NULL) - && (p->end_session_dialog != NULL) - && (g_dbus_proxy_get_name_owner (G_DBUS_PROXY(p->end_session_dialog)) != NULL); + if (p && p->end_session_dialog) + { + GDBusProxy * proxy = G_DBUS_PROXY (p->end_session_dialog); + char * name = g_dbus_proxy_get_name_owner (proxy); + can_prompt = name != NULL; + g_free (name); + } + + return can_prompt; } static gboolean -- cgit v1.2.3 From 69bf3537b0fe5aa00d015c7339ce20e9c2b80d1f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 09:48:54 -0500 Subject: finish up backend-dbus/users.c: fix an unref bug when creating user proxies. fix an async race condition where we emitted change events for users before their proxy objects had finished being asynchronously constructed. --- src/backend-dbus/users.c | 118 ++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 64 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 1db5ac1..b5a6d32 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -41,6 +41,8 @@ struct _IndicatorSessionUsersDbusPriv gboolean is_live; GCancellable * cancellable; + + guint update_list_tag; }; typedef IndicatorSessionUsersDbusPriv priv_t; @@ -53,29 +55,6 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ -/* returns true if the fields indicate this is the 'live cd' user */ -static gboolean -is_live_user (guint uid, const char * username) -{ - return uid==999 && !g_strcmp0 (username, "ubuntu"); -} - -/* returns true if this is a user who should be listed in the session indicator */ -static gboolean -is_public_user (IndicatorSessionUsersDbus * self G_GNUC_UNUSED, - AccountsUser * au) -{ - gboolean is_public; - - /* the 'live session' user is the only system account we'll show */ - if (is_live_user (accounts_user_get_uid(au), accounts_user_get_user_name(au))) - is_public = TRUE; - else - is_public = !accounts_user_get_system_account (au); - - return is_public; -} - /* get our private org.freedesktop.Accounts.User proxy for the given uid */ static AccountsUser * get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) @@ -85,50 +64,30 @@ get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); } -/* returns true if this is a uid that should be listed in the session indicator */ static gboolean -is_public_uid (IndicatorSessionUsersDbus * self, guint uid) +is_tracked_uid (IndicatorSessionUsersDbus * self, guint uid) { - AccountsUser * au; - gboolean is_public; - - if ((au = get_user_for_uid (self, uid))) - { - is_public = is_public_user (self, au); - } - else - { - /* making a guess to serve until the user's proxy object is ready. - assuming that 999 is a 'live session' user, <999 is system account */ - is_public = uid >= 999; - } - - return is_public; + return get_user_for_uid (self, uid) != NULL; } -/*** -**** -***/ - static void -emit_user_added (IndicatorSessionUsersDbus * self, guint uid) +emit_user_added (IndicatorSessionUsersDbus * self, guint32 uid) { - if (is_public_uid (self, uid)) + if (is_tracked_uid (self, uid)) indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); } static void -emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) +emit_user_changed (IndicatorSessionUsersDbus * self, guint32 uid) { - if (is_public_uid (self, uid)) + if (is_tracked_uid (self, uid)) indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); } static void -emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) +emit_user_removed (IndicatorSessionUsersDbus * self, guint32 uid) { - if (is_public_uid (self, uid)) - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); } /*** @@ -259,18 +218,13 @@ track_user (IndicatorSessionUsersDbus * self, AccountsUser * user) { const guint32 uid = accounts_user_get_uid (user); - const gpointer uid_key = GUINT_TO_POINTER (uid); priv_t * p = self->priv; gulong id; - gboolean already_had_user; - - g_return_if_fail (is_public_user (self, user)); - - already_had_user = g_hash_table_contains (p->uid_to_account, uid_key); + const gboolean already_had_user = is_tracked_uid (self, uid); id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); object_add_connection (G_OBJECT(user), id); - g_hash_table_insert (p->uid_to_account, uid_key, user); + g_hash_table_insert (p->uid_to_account, GUINT_TO_POINTER (uid), user); if (already_had_user) emit_user_changed (self, uid); @@ -321,13 +275,13 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else if (is_public_user (self, user)) + else if (!accounts_user_get_system_account (user)) { track_user (self, user); } else { - g_object_unref (self); + g_object_unref (user); } } @@ -456,12 +410,11 @@ on_login1_manager_session_list_ready (GObject * o, { set_active_uid (self, uid); - if (is_live_user (uid, user_name)) + if ((uid==999) && !g_strcmp0 (user_name, "ubuntu")) is_live_session = TRUE; } - if (is_public_uid (self, uid)) - g_hash_table_add (logins, GINT_TO_POINTER(uid)); + g_hash_table_add (logins, GINT_TO_POINTER(uid)); } set_is_live_session_flag (self, is_live_session); @@ -485,8 +438,35 @@ update_session_list (IndicatorSessionUsersDbus * self) } } +static gboolean +on_update_session_list_timer (gpointer gself) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (gself); + + update_session_list (self); + + self->priv->update_list_tag = 0; + return G_SOURCE_REMOVE; +} + +/* A dead session can still show up in list-sessions for a few seconds. + So just to be safe, queue up a rebuild for a few seconds from now */ static void -set_login1_manager (IndicatorSessionUsersDbus * self, Login1Manager * login1_manager) +update_session_list_twice (IndicatorSessionUsersDbus * self) +{ + priv_t * p = self->priv; + + update_session_list (self); + + if (p->update_list_tag == 0) + p->update_list_tag = g_timeout_add_seconds (5, + on_update_session_list_timer, + self); +} + +static void +set_login1_manager (IndicatorSessionUsersDbus * self, + Login1Manager * login1_manager) { priv_t * p = self->priv; @@ -504,7 +484,11 @@ set_login1_manager (IndicatorSessionUsersDbus * self, Login1Manager * login1_man 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_twice), self); + g_signal_connect_swapped (login1_manager, "user-new", G_CALLBACK(update_session_list), self); + g_signal_connect_swapped (login1_manager, "user-removed", + G_CALLBACK(update_session_list_twice), self); update_session_list (self); } } @@ -632,6 +616,12 @@ my_dispose (GObject * o) IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); priv_t * p = self->priv; + if (p->update_list_tag != 0) + { + g_source_remove (p->update_list_tag); + p->update_list_tag = 0; + } + if (p->cancellable) { g_cancellable_cancel (p->cancellable); -- cgit v1.2.3 From 4850b1b6ba8a1438d8c0903592108fcefc35235e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 10:31:51 -0500 Subject: update comments & documentation to reflect that we've replaced consolekit and login1 --- src/backend-dbus/actions.h | 2 +- src/backend-dbus/guest.h | 2 +- src/backend-dbus/users.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.h b/src/backend-dbus/actions.h index 0c8bed2..d3d722d 100644 --- a/src/backend-dbus/actions.h +++ b/src/backend-dbus/actions.h @@ -42,7 +42,7 @@ typedef struct _IndicatorSessionActionsDbusClass IndicatorSessionActionsDbusCl /** * An implementation of IndicatorSessionActions that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * from org.freedesktop.login1 org.freedesktop.DisplayManager over DBus. */ struct _IndicatorSessionActionsDbus { diff --git a/src/backend-dbus/guest.h b/src/backend-dbus/guest.h index aca5588..73bb3ca 100644 --- a/src/backend-dbus/guest.h +++ b/src/backend-dbus/guest.h @@ -42,7 +42,7 @@ typedef struct _IndicatorSessionGuestDbusClass IndicatorSessionGuestDbusClass; /** * An implementation of IndicatorSessionGuest that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * from org.freedesktop.login1 and org.freedesktop.Accounts over DBus. */ struct _IndicatorSessionGuestDbus { diff --git a/src/backend-dbus/users.h b/src/backend-dbus/users.h index a9aaecf..d6c17df 100644 --- a/src/backend-dbus/users.h +++ b/src/backend-dbus/users.h @@ -42,7 +42,7 @@ typedef struct _IndicatorSessionUsersDbusClass IndicatorSessionUsersDbusClass; /** * An implementation of IndicatorSessionUsers that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * from org.freedesktop.login1 and org.freedesktop.Accounts over DBus. */ struct _IndicatorSessionUsersDbus { -- cgit v1.2.3 From d176666fbd302857b7af69774f516a53fbe086fa Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 14:58:11 -0500 Subject: cleanup: put an '.xml' file suffix at the end of the DisplayManager.Seat xml file --- src/backend-dbus/CMakeLists.txt | 2 +- .../org.freedesktop.DisplayManager.Seat | 30 ---------------------- .../org.freedesktop.DisplayManager.Seat.xml | 30 ++++++++++++++++++++++ 3 files changed, 31 insertions(+), 31 deletions(-) delete mode 100644 src/backend-dbus/org.freedesktop.DisplayManager.Seat create mode 100644 src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index eb4d971..1c0df8e 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -3,7 +3,7 @@ set(BACKEND_GENERATED_SOURCES add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-display-manager org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.DisplayManager.Seat) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.DisplayManager.Seat.xml) add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-webcredentials com.canonical.indicators diff --git a/src/backend-dbus/org.freedesktop.DisplayManager.Seat b/src/backend-dbus/org.freedesktop.DisplayManager.Seat deleted file mode 100644 index 07b5f29..0000000 --- a/src/backend-dbus/org.freedesktop.DisplayManager.Seat +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml b/src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml new file mode 100644 index 0000000..07b5f29 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From b252745c8111c9be1d7e95a88daab1e2568b1afc Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:33:08 -0500 Subject: in backend-dbus/actions.c's set_login1_seat(), disconnect from the previous seat's signals before unreff'ing it --- src/backend-dbus/actions.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 67fe9f1..8c1b70b 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -99,13 +99,18 @@ set_login1_seat (IndicatorSessionActionsDbus * self, Login1Seat * seat) { priv_t * p = self->priv; - g_clear_object (&p->login1_seat); + if (p->login1_seat != NULL) + { + g_signal_handlers_disconnect_by_data (p->login1_seat, self); + g_clear_object (&p->login1_seat); + } if (seat != NULL) { p->login1_seat = g_object_ref (seat); - g_signal_connect_swapped (seat, "notify::can-multi-session", G_CALLBACK(on_seat_notify_multi_session), self); + g_signal_connect_swapped (seat, "notify::can-multi-session", + G_CALLBACK(on_seat_notify_multi_session), self); } } -- cgit v1.2.3 From 37694a94d8c188b909740f2eed7a984273dc2320 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:35:17 -0500 Subject: in backend-dbus/actions.c's set_dm_seat(), since we don't listen to displaymanager's signals anymore, remove unnecessary g_signal_handlers_disconnect() call. --- src/backend-dbus/actions.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 8c1b70b..1756a0f 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -123,17 +123,10 @@ set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * 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); - } + g_clear_object (&p->dm_seat); if (seat != NULL) - { - p->dm_seat = g_object_ref (seat); - /*g_signal_connect (seat, "notify::has-actions-account", G_CALLBACK(on_notify_has_actions_account), self);*/ - } + p->dm_seat = g_object_ref (seat); } static void -- cgit v1.2.3 From 90c7f19eeaf0c89e40ddd59f00edbb0d7b1c0789 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:41:41 -0500 Subject: in backend-dbus/actions.c, create a separate cancellable for login1_manager s.t. new calls to set_login1_manager() will cancel any previous async calls pending on the old login1 manager object. --- src/backend-dbus/actions.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 1756a0f..c40d0c6 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -37,6 +37,7 @@ enum struct _IndicatorSessionActionsDbusPriv { GCancellable * cancellable; + GCancellable * login1_manager_cancellable; GSettings * lockdown_settings; GnomeScreenSaver * screen_saver; @@ -205,19 +206,26 @@ set_login1_manager (IndicatorSessionActionsDbus * self, { priv_t * p = self->priv; - g_clear_object (&p->login1_manager); + if (p->login1_manager != NULL) + { + g_cancellable_cancel (p->login1_manager_cancellable); + g_clear_object (&p->login1_manager_cancellable); + g_clear_object (&p->login1_manager); + } if (login1_manager != NULL) { + p->login1_manager_cancellable = g_cancellable_new (); + p->login1_manager = g_object_ref (login1_manager); login1_manager_call_can_suspend (p->login1_manager, - p->cancellable, + p->login1_manager_cancellable, on_can_suspend_ready, self); login1_manager_call_can_hibernate (p->login1_manager, - p->cancellable, + p->login1_manager_cancellable, on_can_hibernate_ready, self); } @@ -353,7 +361,11 @@ my_suspend (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_suspend (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_suspend (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } static void @@ -363,7 +375,11 @@ my_hibernate (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_hibernate (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_hibernate (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } /*** @@ -404,7 +420,11 @@ reboot_now (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_reboot (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_reboot (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } static void @@ -414,7 +434,11 @@ power_off_now (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_power_off (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_power_off (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } static void -- cgit v1.2.3 From 0b5f283691222c23599ab460bb5dad7a78378aa8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:46:00 -0500 Subject: in backend-dbus/actions.c, create a separate cancellable for dm_seat s.t. new calls to set_dm_seat() will cancel any previous async calls pending on the old DisplayManager seat object. --- src/backend-dbus/actions.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index c40d0c6..c095896 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -37,14 +37,15 @@ enum struct _IndicatorSessionActionsDbusPriv { GCancellable * cancellable; - GCancellable * login1_manager_cancellable; GSettings * lockdown_settings; GnomeScreenSaver * screen_saver; GnomeSessionManager * session_manager; Login1Manager * login1_manager; + GCancellable * login1_manager_cancellable; Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; + GCancellable * dm_seat_cancellable; Webcredentials * webcredentials; EndSessionDialog * end_session_dialog; @@ -124,10 +125,18 @@ set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * seat) { priv_t * p = self->priv; - g_clear_object (&p->dm_seat); + if (p->dm_seat != NULL) + { + g_cancellable_cancel (p->dm_seat_cancellable); + g_clear_object (&p->dm_seat); + g_clear_object (&p->dm_seat); + } if (seat != NULL) - p->dm_seat = g_object_ref (seat); + { + p->dm_seat = g_object_ref (seat); + p->dm_seat_cancellable = g_cancellable_new (); + } } static void @@ -570,7 +579,8 @@ my_switch_to_greeter (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); - display_manager_seat_call_switch_to_greeter (p->dm_seat, p->cancellable, + display_manager_seat_call_switch_to_greeter (p->dm_seat, + p->dm_seat_cancellable, NULL, NULL); } @@ -582,7 +592,7 @@ my_switch_to_guest (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); display_manager_seat_call_switch_to_guest (p->dm_seat, "", - p->cancellable, + p->dm_seat_cancellable, NULL, NULL); } @@ -594,7 +604,7 @@ my_switch_to_username (IndicatorSessionActions * self, const char * username) g_return_if_fail (p->dm_seat != NULL); display_manager_seat_call_switch_to_user (p->dm_seat, username, "", - p->cancellable, + p->dm_seat_cancellable, NULL, NULL); } -- 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') 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 From 604640ebeca2fe1b2eb4aa475dbb4221dd8aeb72 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:06:17 -0500 Subject: in src/backend-dbus/users.c's set_logins(), fix ref/unref semantics of the hashtable argument --- src/backend-dbus/users.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index b5a6d32..caf6403 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -130,7 +130,7 @@ set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) gpointer uid; GHashTableIter iter; - self->priv->logins = logins; + self->priv->logins = g_hash_table_ref (logins); /* fire 'user changed' event for users who logged out */ g_hash_table_iter_init (&iter, old_logins); @@ -420,6 +420,7 @@ on_login1_manager_session_list_ready (GObject * o, set_is_live_session_flag (self, is_live_session); set_logins (self, logins); + g_hash_table_unref (logins); g_variant_unref (sessions); } } -- cgit v1.2.3 From d5421fec0a7e51ddb1979a97de271a3f1733321e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:07:33 -0500 Subject: in src/backend-dbus/users.c, use G_DEFINE_QUARK() instead of rolling our own quark func --- src/backend-dbus/users.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index caf6403..b9a79e5 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -151,23 +151,14 @@ set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) **** ***/ -static GQuark -get_connection_list_quark (void) -{ - static GQuark q = 0; - - if (G_UNLIKELY (q == 0)) - q = g_quark_from_static_string ("connection-ids"); - - return q; -} +G_DEFINE_QUARK (connection-ids, connection_list) static void object_unref_and_disconnect (gpointer instance) { - GSList * l; + const GQuark q = connection_list_quark (); GSList * ids; - const GQuark q = get_connection_list_quark (); + GSList * l; ids = g_object_steal_qdata (G_OBJECT(instance), q); for (l=ids; l!=NULL; l=l->next) @@ -184,7 +175,7 @@ object_unref_and_disconnect (gpointer instance) static void object_add_connection (GObject * o, gulong connection_id) { - const GQuark q = get_connection_list_quark (); + const GQuark q = connection_list_quark (); GSList * ids; gulong * ptr; -- cgit v1.2.3 From eb7e99b24b15a311f188754bf3d0d4f72551deab Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:12:08 -0500 Subject: in src/backend-dbus/users.c's track_user(), simplify the ref/unref semantics of the user argument --- src/backend-dbus/users.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index b9a79e5..738eda4 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -215,7 +215,9 @@ track_user (IndicatorSessionUsersDbus * self, id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); object_add_connection (G_OBJECT(user), id); - g_hash_table_insert (p->uid_to_account, GUINT_TO_POINTER (uid), user); + g_hash_table_insert (p->uid_to_account, + GUINT_TO_POINTER (uid), + g_object_ref (user)); if (already_had_user) emit_user_changed (self, uid); @@ -266,12 +268,11 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else if (!accounts_user_get_system_account (user)) - { - track_user (self, user); - } else { + if (!accounts_user_get_system_account (user)) + track_user (self, user); + g_object_unref (user); } } -- cgit v1.2.3 From bb2129f5fada412c88e5d3f739038d560a5444a9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:13:07 -0500 Subject: in src/backend-dbus/users.c's object_unref_and_disconnect(), fix an unbalanced ref/unref --- src/backend-dbus/users.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 738eda4..6f02a53 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -166,9 +166,10 @@ object_unref_and_disconnect (gpointer instance) gulong * handler_id = l->data; g_signal_handler_disconnect (instance, *handler_id); g_free (handler_id); - g_object_unref (instance); } + g_object_unref (instance); + g_slist_free (ids); } -- cgit v1.2.3 From c96e42d1d00d68b6c858d7d314c13b4d05ca0d8b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:28:05 -0500 Subject: in src/backend-dbus/users.c, use a helper struct for disconnecting the signals to the user proxies in our uid-to-user hashtable --- src/backend-dbus/users.c | 94 +++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 49 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 6f02a53..f770695 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -28,7 +28,7 @@ struct _IndicatorSessionUsersDbusPriv DisplayManagerSeat * dm_seat; Accounts * accounts; - /* hash table of int uids to AccountsUser* */ + /* hash table of int uids to UserRecord* */ GHashTable * uid_to_account; /* a hashset of int uids of users who are logged in */ @@ -55,13 +55,46 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ +struct UserRecord +{ + AccountsUser * user; + + gulong signal_id; +}; + +struct UserRecord * +user_record_new (AccountsUser * user, gulong signal_id) +{ + struct UserRecord * rec; + rec = g_new (struct UserRecord, 1); + rec->user = g_object_ref (user); + rec->signal_id = signal_id; + return rec; +} + +static void +user_record_free (struct UserRecord * rec) +{ + g_signal_handler_disconnect (rec->user, rec->signal_id); + g_object_unref (G_OBJECT (rec->user)); + g_free (rec); +} + +/*** +**** +***/ + /* get our private org.freedesktop.Accounts.User proxy for the given uid */ static AccountsUser * get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) { - priv_t * p = self->priv; + struct UserRecord * rec; + + if ((rec = g_hash_table_lookup (self->priv->uid_to_account, + GUINT_TO_POINTER(uid)))) + return rec->user; - return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); + return NULL; } static gboolean @@ -147,47 +180,6 @@ set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) g_hash_table_destroy (old_logins); } -/*** -**** -***/ - -G_DEFINE_QUARK (connection-ids, connection_list) - -static void -object_unref_and_disconnect (gpointer instance) -{ - const GQuark q = connection_list_quark (); - GSList * ids; - GSList * l; - - ids = g_object_steal_qdata (G_OBJECT(instance), q); - for (l=ids; l!=NULL; l=l->next) - { - gulong * handler_id = l->data; - g_signal_handler_disconnect (instance, *handler_id); - g_free (handler_id); - } - - g_object_unref (instance); - - g_slist_free (ids); -} - -static void -object_add_connection (GObject * o, gulong connection_id) -{ - const GQuark q = connection_list_quark (); - GSList * ids; - gulong * ptr; - - ptr = g_new (gulong, 1); - *ptr = connection_id; - - ids = g_object_steal_qdata (o, q); - ids = g_slist_prepend (ids, ptr); - g_object_set_qdata (o, q, ids); -} - /*** **** User Account Tracking ***/ @@ -215,10 +207,9 @@ track_user (IndicatorSessionUsersDbus * self, const gboolean already_had_user = is_tracked_uid (self, uid); id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); - object_add_connection (G_OBJECT(user), id); g_hash_table_insert (p->uid_to_account, GUINT_TO_POINTER (uid), - g_object_ref (user)); + user_record_new (user, id)); if (already_had_user) emit_user_changed (self, uid); @@ -236,11 +227,16 @@ untrack_user (IndicatorSessionUsersDbus * self, GHashTableIter iter; priv_t * p = self->priv; + /* find the uid matching this object path */ uid = 0; g_hash_table_iter_init (&iter, p->uid_to_account); while (!uid && g_hash_table_iter_next (&iter, &key, &val)) - if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (val))) - uid = GPOINTER_TO_UINT (key); + { + struct UserRecord * rec = val; + GDBusProxy * proxy = G_DBUS_PROXY (rec->user); + if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (proxy))) + uid = GPOINTER_TO_UINT (key); + } if (uid) { @@ -677,7 +673,7 @@ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) p->uid_to_account = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, - object_unref_and_disconnect); + (GDestroyNotify)user_record_free); p->logins = g_hash_table_new (g_direct_hash, g_direct_equal); } -- cgit v1.2.3 From e875abf22fc02939185b6aa881865cff58fc1543 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 21:00:17 -0500 Subject: in cmake files, limit scopes by moving single-target properties out of the global variables to single-target ones and moving single-use includes into the directories where they're used --- src/backend-dbus/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index 1c0df8e..fa41534 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -1,3 +1,5 @@ +include (GdbusCodegen) + set(BACKEND_GENERATED_SOURCES ) -- cgit v1.2.3 From 4168038976915aea6f73449f145d923cc63bd1be Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 10 Jul 2013 00:08:03 -0500 Subject: If g_getenv(XDG_SEAT_PATH) fails, don't try to get the DisplayManager seat. Fixes the greeter issue reported by seb128 --- src/backend-dbus/utils.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index 25ac7c3..d1511f4 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -126,13 +126,15 @@ indicator_session_util_get_session_proxies ( gpointer user_data) { struct session_proxy_data * data; - char * seat_path; + char * login1_seat_path; + const char * dm_seat_path; data = g_new0 (struct session_proxy_data, 1); data->callback = func; data->user_data = user_data; data->cancellable = g_object_ref (cancellable); + /* login1 */ data->pending++; login1_manager_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, @@ -141,15 +143,18 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_login1_manager_ready, data); - data->pending++; - seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); + /* login1 seat */ + login1_seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.login1", - seat_path, + login1_seat_path, data->cancellable, on_login1_seat_ready, data); + g_free (login1_seat_path); + + /* Accounts */ data->pending++; accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, @@ -158,14 +163,16 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_accounts_proxy_ready, data); - data->pending++; - display_manager_seat_proxy_new_for_bus ( + /* DisplayManager seat */ + if ((dm_seat_path = g_getenv ("XDG_SEAT_PATH"))) + { + data->pending++; + 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"), + dm_seat_path, data->cancellable, on_display_manager_seat_proxy_ready, data); - - g_free (seat_path); + } } -- cgit v1.2.3 From f71bc96e3131f4241256a850ab8c0b556bdac4dd Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 10 Jul 2013 00:30:45 -0500 Subject: just to be safe, check to see that g_getenv('XDG_SEAT') passes too --- src/backend-dbus/utils.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index d1511f4..bc862e8 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -126,8 +126,7 @@ indicator_session_util_get_session_proxies ( gpointer user_data) { struct session_proxy_data * data; - char * login1_seat_path; - const char * dm_seat_path; + const char * str; data = g_new0 (struct session_proxy_data, 1); data->callback = func; @@ -144,15 +143,20 @@ indicator_session_util_get_session_proxies ( on_login1_manager_ready, data); /* login1 seat */ - login1_seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); - login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + if ((str = g_getenv ("XDG_SEAT"))) + { + char * path; + data->pending++; + path = g_strconcat ("/org/freedesktop/login1/seat/", str, NULL); + login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.login1", - login1_seat_path, + path, data->cancellable, on_login1_seat_ready, data); - g_free (login1_seat_path); + g_free (path); + } /* Accounts */ data->pending++; @@ -164,14 +168,14 @@ indicator_session_util_get_session_proxies ( on_accounts_proxy_ready, data); /* DisplayManager seat */ - if ((dm_seat_path = g_getenv ("XDG_SEAT_PATH"))) + if ((str = g_getenv ("XDG_SEAT_PATH"))) { data->pending++; display_manager_seat_proxy_new_for_bus ( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.DisplayManager", - dm_seat_path, + str, data->cancellable, on_display_manager_seat_proxy_ready, data); } -- cgit v1.2.3 From c9352cd0a8363e4508d19e66ccf373b2abb2b7d3 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 12 Jul 2013 02:05:35 -0500 Subject: If the Unity dialogs aren't available (such as in the greeter) but zenity is, use it to for confirmation dialogs: - add the implementation in actions.c - add actions.c to the i18n files list - sync the unit tests - suggest zenity in debian/control --- src/backend-dbus/actions.c | 314 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 261 insertions(+), 53 deletions(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index c095896..ed1e708 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -18,6 +18,7 @@ */ #include +#include #include "dbus-end-session-dialog.h" #include "dbus-login1-manager.h" @@ -39,6 +40,7 @@ struct _IndicatorSessionActionsDbusPriv GCancellable * cancellable; GSettings * lockdown_settings; + GSettings * indicator_settings; GnomeScreenSaver * screen_saver; GnomeSessionManager * session_manager; Login1Manager * login1_manager; @@ -48,6 +50,7 @@ struct _IndicatorSessionActionsDbusPriv GCancellable * dm_seat_cancellable; Webcredentials * webcredentials; EndSessionDialog * end_session_dialog; + char * zenity; gboolean can_suspend; gboolean can_hibernate; @@ -80,6 +83,44 @@ log_and_clear_error (GError ** err, const char * loc, const char * func) **** ***/ +typedef enum +{ + PROMPT_NONE, + PROMPT_WITH_ZENITY, + PROMPT_WITH_UNITY +} +prompt_status_t; + +static prompt_status_t +get_prompt_status (IndicatorSessionActionsDbus * self) +{ + prompt_status_t prompt = PROMPT_NONE; + const priv_t * p = self->priv; + + if (!g_settings_get_boolean (p->indicator_settings, "suppress-logout-restart-shutdown")) + { + /* can we use the Unity prompt? */ + if ((prompt == PROMPT_NONE) && p && p->end_session_dialog) + { + GDBusProxy * proxy = G_DBUS_PROXY (p->end_session_dialog); + char * name = g_dbus_proxy_get_name_owner (proxy); + if (name != NULL) + prompt = PROMPT_WITH_UNITY; + g_free (name); + } + + /* can we use zenity? */ + if ((prompt == PROMPT_NONE) && p && p->zenity) + prompt = PROMPT_WITH_ZENITY; + } + + return prompt; +} + +/*** +**** +***/ + static void on_seat_notify_multi_session (IndicatorSessionActionsDbus * self) { @@ -288,6 +329,7 @@ on_end_session_dialog_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->end_session_dialog = end_session_dialog; indicator_session_actions_notify_can_prompt (INDICATOR_SESSION_ACTIONS(gself)); + indicator_session_actions_notify_can_reboot (INDICATOR_SESSION_ACTIONS(gself)); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); @@ -310,7 +352,31 @@ my_can_logout (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return !g_settings_get_boolean (p->lockdown_settings, "disable-log-out"); + if (g_settings_get_boolean (p->indicator_settings, "suppress-logout-menuitem")) + return FALSE; + + if (g_settings_get_boolean (p->lockdown_settings, "disable-log-out")) + return FALSE; + + return TRUE; +} + +static gboolean +my_can_reboot (IndicatorSessionActions * actions) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS(actions); + priv_t * p = self->priv; + + if (g_settings_get_boolean (p->indicator_settings, "suppress-restart-menuitem")) + return FALSE; + + /* Shutdown and Restart are the same dialog prompt in Unity, + so disable the redundant 'Restart' menuitem in that mode */ + if (!g_settings_get_boolean (p->indicator_settings, "suppress-shutdown-menuitem")) + if (get_prompt_status(self) == PROMPT_WITH_UNITY) + return FALSE; + + return TRUE; } static gboolean @@ -341,18 +407,7 @@ my_can_hibernate (IndicatorSessionActions * self) static gboolean my_can_prompt (IndicatorSessionActions * self) { - gboolean can_prompt = FALSE; - const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - - if (p && p->end_session_dialog) - { - GDBusProxy * proxy = G_DBUS_PROXY (p->end_session_dialog); - char * name = g_dbus_proxy_get_name_owner (proxy); - can_prompt = name != NULL; - g_free (name); - } - - return can_prompt; + return get_prompt_status(INDICATOR_SESSION_ACTIONS_DBUS(self)) != PROMPT_NONE; } static gboolean @@ -396,50 +451,51 @@ my_hibernate (IndicatorSessionActions * self) ***/ static void -logout_now (IndicatorSessionActions * self, gboolean try_to_prompt) +logout_now (IndicatorSessionActionsDbus * self) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - const int type = try_to_prompt ? 0 : 1; + priv_t * p = self->priv; g_return_if_fail (p->session_manager != NULL); gnome_session_manager_call_logout (p->session_manager, - type, + 1, /* don't prompt */ p->cancellable, NULL, NULL); } static void -logout_now_with_prompt (IndicatorSessionActions * self) +on_reboot_response (GObject * o, + GAsyncResult * res, + gpointer unused G_GNUC_UNUSED) { - logout_now (self, TRUE); -} - -static void -logout_now_quietly (IndicatorSessionActions * self) -{ - logout_now (self, FALSE); + GError * err = NULL; + login1_manager_call_reboot_finish (LOGIN1_MANAGER(o), res, &err); + if (err != NULL) + { + g_warning ("Unable to reboot: %s", err->message); + g_error_free (err); + } } static void -reboot_now (IndicatorSessionActions * self) +reboot_now (IndicatorSessionActionsDbus * self) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + priv_t * p = self->priv; g_return_if_fail (p->login1_manager != NULL); login1_manager_call_reboot (p->login1_manager, FALSE, p->login1_manager_cancellable, - NULL, + on_reboot_response, NULL); } static void -power_off_now (IndicatorSessionActions * self) +power_off_now (IndicatorSessionActionsDbus * self) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + priv_t * p = self->priv; g_return_if_fail (p->login1_manager != NULL); @@ -477,7 +533,7 @@ on_open_end_session_dialog_ready (GObject * o, } static void -show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) +show_unity_end_session_dialog (IndicatorSessionActionsDbus * self, int type) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; gpointer o = p->end_session_dialog; @@ -485,7 +541,7 @@ show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) g_assert (o != NULL); - g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now_quietly), self); + g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now), self); g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(reboot_now), self); g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(power_off_now), self); g_signal_connect_swapped (o, "canceled", G_CALLBACK(on_end_session_dialog_canceled), self); @@ -497,34 +553,140 @@ show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) self); } -static void -my_logout (IndicatorSessionActions * self) -{ - if (my_can_prompt (self)) - show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_LOGOUT); +static gboolean +zenity_question (IndicatorSessionActionsDbus * self, + const char * icon_name, + const char * title, + const char * text, + const char * ok_label, + const char * cancel_label) +{ + char * command_line; + int exit_status; + gboolean confirmed; + + command_line = g_strdup_printf ("%s" + " --question" + " --icon-name=\"%s\"" + " --title=\"%s\"" + " --text=\"%s\"" + " --ok-label=\"%s\"" + " --cancel-label=\"%s\"" + " --no-wrap", + self->priv->zenity, + icon_name, + title, + text, + ok_label, + cancel_label); + + exit_status = -1; + if (!g_spawn_command_line_sync (command_line, NULL, NULL, &exit_status, NULL)) + { + /* Treat failure-to-prompt as user confirmation. + Otherwise how will the user ever log out? */ + confirmed = TRUE; + } else - logout_now_with_prompt (self); + { + confirmed = exit_status == 0; + } + + g_free (command_line); + return confirmed; } +static void +my_logout (IndicatorSessionActions * actions) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + switch (get_prompt_status (self)) + { + case PROMPT_WITH_UNITY: + show_unity_end_session_dialog (self, END_SESSION_TYPE_LOGOUT); + break; + + case PROMPT_NONE: + logout_now (self); + break; + + case PROMPT_WITH_ZENITY: + { + const char * primary = _("Are you sure you want to close all programs and log out?"); + const char * secondary = _("Some software updates won't be applied until the computer next restarts."); + char * text = g_strdup_printf ("%s\n \n%s", primary, secondary); + + gboolean confirmed = zenity_question (self, + "system-log-out", + _("Log Out"), + text, + _("Log Out"), + _("Cancel")); + + g_free (text); + + if (confirmed) + logout_now (self); + break; + } + } +} static void -my_reboot (IndicatorSessionActions * self) +my_reboot (IndicatorSessionActions * actions) { - if (my_can_prompt (self)) - show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); - else - reboot_now (self); + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + switch (get_prompt_status (self)) + { + case PROMPT_WITH_UNITY: + show_unity_end_session_dialog (self, END_SESSION_TYPE_REBOOT); + break; + + case PROMPT_NONE: + reboot_now (self); + break; + + case PROMPT_WITH_ZENITY: + if (zenity_question (self, + "system-restart", + _("Restart"), + _("Are you sure you want to close all programs and restart the computer?"), + _("Restart"), + _("Cancel"))) + reboot_now (self); + break; + } } static void -my_power_off (IndicatorSessionActions * self) +my_power_off (IndicatorSessionActions * actions) { - /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because - the latter adds lock & logout options in Unity... */ - if (my_can_prompt (self)) - show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); - else - power_off_now (self); + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + switch (get_prompt_status (self)) + { + case PROMPT_WITH_UNITY: + /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because + the latter adds lock & logout options in Unity... */ + show_unity_end_session_dialog (self, END_SESSION_TYPE_REBOOT); + break; + + case PROMPT_WITH_ZENITY: + if (zenity_question (self, + "system-shutdown", + _("Shut Down"), + _("Are you sure you want to close all programs and shut down the computer?"), + _("Shut Down"), + _("Cancel"))) + power_off_now (self); + break; + + case PROMPT_NONE: + power_off_now (self); + break; + } } /*** @@ -620,11 +782,32 @@ my_dispose (GObject * o) g_clear_object (&p->cancellable); } - g_clear_object (&p->lockdown_settings); + if (p->indicator_settings != NULL) + { + g_signal_handlers_disconnect_by_data (p->indicator_settings, self); + g_clear_object (&p->indicator_settings); + } + + if (p->lockdown_settings != NULL) + { + g_signal_handlers_disconnect_by_data (p->lockdown_settings, self); + g_clear_object (&p->lockdown_settings); + } + + if (p->webcredentials != NULL) + { + g_signal_handlers_disconnect_by_data (p->webcredentials, self); + g_clear_object (&p->webcredentials); + } + + if (p->end_session_dialog != NULL) + { + stop_listening_to_dialog (self); + g_clear_object (&p->end_session_dialog); + } + g_clear_object (&p->screen_saver); g_clear_object (&p->session_manager); - g_clear_object (&p->webcredentials); - g_clear_object (&p->end_session_dialog); set_dm_seat (self, NULL); set_login1_manager (self, NULL); set_login1_seat (self, NULL); @@ -632,6 +815,16 @@ my_dispose (GObject * o) G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); } +static void +my_finalize (GObject * o) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (o); + priv_t * p = self->priv; + + g_free (p->zenity); +} + + /*** **** GObject Boilerplate ***/ @@ -645,10 +838,12 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; + object_class->finalize = my_finalize; actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); actions_class->can_lock = my_can_lock; actions_class->can_logout = my_can_logout; + actions_class->can_reboot = my_can_reboot; actions_class->can_switch = my_can_switch; actions_class->can_suspend = my_can_suspend; actions_class->can_hibernate = my_can_hibernate; @@ -684,6 +879,8 @@ indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) p->seat_allows_activation = TRUE; self->priv = p; + p->zenity = g_find_program_in_path ("zenity"); + s = g_settings_new ("org.gnome.desktop.lockdown"); g_signal_connect_swapped (s, "changed::disable-lock-screen", G_CALLBACK(indicator_session_actions_notify_can_lock), self); @@ -693,6 +890,17 @@ indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) G_CALLBACK(indicator_session_actions_notify_can_switch), self); p->lockdown_settings = s; + s = g_settings_new ("com.canonical.indicator.session"); + g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(indicator_session_actions_notify_can_prompt), self); + g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(indicator_session_actions_notify_can_reboot), self); + g_signal_connect_swapped (s, "changed::suppress-restart-menuitem", + G_CALLBACK(indicator_session_actions_notify_can_reboot), self); + g_signal_connect_swapped (s, "changed::suppress-shutdown-menuitem", + G_CALLBACK(indicator_session_actions_notify_can_reboot), self); + p->indicator_settings = s; + gnome_screen_saver_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, "org.gnome.ScreenSaver", -- cgit v1.2.3 From a19955f3f81b1a5eb8fc928bc5dcf8a24bb6833f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 12 Jul 2013 07:42:07 -0500 Subject: add the online-accounts action and unit tests for it --- src/backend-dbus/actions.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index ed1e708..9030ca7 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -311,6 +311,9 @@ on_webcredentials_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gp g_signal_connect_swapped (webcredentials, "notify::error-status", G_CALLBACK(indicator_session_actions_notify_has_online_account_error), gself); + + if (webcredentials_get_error_status (webcredentials)) + indicator_session_actions_notify_has_online_account_error (gself); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); @@ -714,6 +717,12 @@ my_settings (IndicatorSessionActions * self G_GNUC_UNUSED) run_outside_app ("gnome-control-center"); } +static void +my_online_accounts (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("gnome-control-center credentials"); +} + static void my_about (IndicatorSessionActions * self G_GNUC_UNUSED) { @@ -855,6 +864,7 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl actions_class->reboot = my_reboot; actions_class->power_off = my_power_off; actions_class->settings = my_settings; + actions_class->online_accounts = my_online_accounts; actions_class->help = my_help; actions_class->about = my_about; actions_class->switch_to_screensaver = my_switch_to_screensaver; -- cgit v1.2.3 From 4759a380da77dd1f8746f298a5ae051319a70ddd Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 20 Aug 2013 08:42:24 -0500 Subject: when switching to the guest session, explicitly lock the current users's session --- src/backend-dbus/actions.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 9030ca7..17547f0 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -734,7 +734,7 @@ my_about (IndicatorSessionActions * self G_GNUC_UNUSED) ***/ static void -my_switch_to_screensaver (IndicatorSessionActions * self) +lock_current_session (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; @@ -743,6 +743,12 @@ my_switch_to_screensaver (IndicatorSessionActions * self) gnome_screen_saver_call_lock (p->screen_saver, p->cancellable, NULL, NULL); } +static void +my_switch_to_screensaver (IndicatorSessionActions * self) +{ + lock_current_session (self); +} + static void my_switch_to_greeter (IndicatorSessionActions * self) { @@ -750,6 +756,7 @@ my_switch_to_greeter (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); + /* show the greeter */ display_manager_seat_call_switch_to_greeter (p->dm_seat, p->dm_seat_cancellable, NULL, NULL); @@ -762,6 +769,8 @@ my_switch_to_guest (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); + lock_current_session (self); + display_manager_seat_call_switch_to_guest (p->dm_seat, "", p->dm_seat_cancellable, NULL, NULL); -- cgit v1.2.3 From e48d65866fa228929ddc545eac456635bf763501 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 20 Aug 2013 08:43:47 -0500 Subject: fix minor GCancellable memory leak noticed while fixing 1205273 --- src/backend-dbus/actions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 17547f0..2550fdb 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -169,7 +169,7 @@ set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * seat) if (p->dm_seat != NULL) { g_cancellable_cancel (p->dm_seat_cancellable); - g_clear_object (&p->dm_seat); + g_clear_object (&p->dm_seat_cancellable); g_clear_object (&p->dm_seat); } -- cgit v1.2.3 From 14964539aec0c91e39e3abdb70c08ad8d65824bb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 20 Aug 2013 08:52:54 -0500 Subject: copyediting: remove unnecessary comment that snuck into r406 --- src/backend-dbus/actions.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/backend-dbus') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 2550fdb..fcf850d 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -756,7 +756,6 @@ my_switch_to_greeter (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); - /* show the greeter */ display_manager_seat_call_switch_to_greeter (p->dm_seat, p->dm_seat_cancellable, NULL, NULL); -- cgit v1.2.3