enum
{
- LIST_PROP_0,
- LIST_PROP_NUM_USERS,
+ LIST_PROP_NUM_USERS = 1,
LIST_PROP_USERS,
};
enum
{
- USER_PROP_0,
- USER_PROP_NAME,
+ USER_PROP_NAME = 1,
USER_PROP_REAL_NAME,
USER_PROP_DISPLAY_NAME,
USER_PROP_HOME_DIRECTORY,
enum
{
CHANGED,
+ GET_LOGGED_IN,
LAST_USER_SIGNAL
};
static guint user_signals[LAST_USER_SIGNAL] = { 0 };
typedef struct
{
- /* User list this user is part of */
- CommonUserList *user_list;
-
/* TRUE if have loaded the DMRC file */
gboolean loaded_dmrc;
+ /* Bus we are listening for accounts service on */
+ GDBusConnection *bus;
+
/* Accounts service path */
gchar *path;
/* Shell for user */
gchar *shell;
- /* TRUE if a system account */
- gboolean system_account;
-
/* Image for user */
gchar *image;
void
common_user_list_cleanup (void)
{
- if (singleton)
- g_object_unref (singleton);
- singleton = NULL;
+ g_clear_object (&singleton);
}
static CommonUser *
return TRUE;
}
+static void load_sessions (CommonUserList *user_list);
+
+static gboolean
+get_logged_in_cb (CommonUser *user, CommonUserList *user_list)
+{
+ CommonUserListPrivate *priv = GET_LIST_PRIVATE (user_list);
+ const gchar *username;
+ GList *link;
+
+ // Lazily decide to load/listen to sessions
+ if (priv->session_added_signal == 0)
+ load_sessions (user_list);
+
+ username = GET_USER_PRIVATE (user)->name;
+ for (link = priv->sessions; link; link = link->next)
+ {
+ CommonSession *session = link->data;
+ if (strcmp (session->username, username) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void
-user_changed_cb (CommonUser *user)
+user_changed_cb (CommonUser *user, CommonUserList *user_list)
{
- g_signal_emit (GET_USER_PRIVATE (user)->user_list, list_signals[USER_CHANGED], 0, user);
+ g_signal_emit (user_list, list_signals[USER_CHANGED], 0, user);
}
static CommonUser *
char **tokens;
gchar *real_name, *image;
+ g_signal_connect (user, "get-logged-in", G_CALLBACK (get_logged_in_cb), user_list);
+
tokens = g_strsplit (entry->pw_gecos, ",", -1);
if (tokens[0] != NULL && tokens[0][0] != '\0')
real_name = g_strdup (tokens[0]);
}
}
- priv->user_list = user_list;
priv->name = g_strdup (entry->pw_name);
priv->real_name = real_name;
priv->home_directory = g_strdup (entry->pw_dir);
{
CommonUser *info = link->data;
g_debug ("User %s added", common_user_get_name (info));
- g_signal_connect (info, USER_SIGNAL_CHANGED, G_CALLBACK (user_changed_cb), NULL);
+ g_signal_connect (info, USER_SIGNAL_CHANGED, G_CALLBACK (user_changed_cb), user_list);
if (emit_add_signal)
g_signal_emit (user_list, list_signals[USER_ADDED], 0, info);
}
}
}
-static gboolean
-update_user_property (CommonUser *user, const gchar *name, GVariant *value)
-{
- CommonUserPrivate *priv = GET_USER_PRIVATE (user);
-
- if (strcmp (name, "UserName") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- g_free (priv->name);
- priv->name = g_variant_dup_string (value, NULL);
- return TRUE;
- }
-
- if (strcmp (name, "RealName") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- g_free (priv->real_name);
- priv->real_name = g_variant_dup_string (value, NULL);
- return TRUE;
- }
-
- if (strcmp (name, "HomeDirectory") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- g_free (priv->home_directory);
- priv->home_directory = g_variant_dup_string (value, NULL);
- return TRUE;
- }
-
- if (strcmp (name, "Shell") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- g_free (priv->shell);
- priv->shell = g_variant_dup_string (value, NULL);
- return TRUE;
- }
-
- if (strcmp (name, "SystemAccount") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN))
- {
- priv->system_account = g_variant_get_boolean (value);
- return TRUE;
- }
-
- if (strcmp (name, "Language") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- if (priv->language)
- g_free (priv->language);
- priv->language = g_variant_dup_string (value, NULL);
- return TRUE;
- }
-
- if (strcmp (name, "IconFile") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- g_free (priv->image);
- priv->image = g_variant_dup_string (value, NULL);
- if (strcmp (priv->image, "") == 0)
- {
- g_free (priv->image);
- priv->image = NULL;
- }
- return TRUE;
- }
-
- if (strcmp (name, "XSession") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- g_free (priv->session);
- priv->session = g_variant_dup_string (value, NULL);
- return TRUE;
- }
-
- if (strcmp (name, "BackgroundFile") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- {
- g_free (priv->background);
- priv->background = g_variant_dup_string (value, NULL);
- if (strcmp (priv->background, "") == 0)
- {
- g_free (priv->background);
- priv->background = NULL;
- }
- return TRUE;
- }
-
- if (strcmp (name, "XKeyboardLayouts") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY))
- {
- g_strfreev (priv->layouts);
- priv->layouts = g_variant_dup_strv (value, NULL);
- if (!priv->layouts)
- {
- priv->layouts = g_malloc (sizeof (gchar *) * 1);
- priv->layouts[0] = NULL;
- }
- return TRUE;
- }
-
- if (strcmp (name, "XHasMessages") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN))
- {
- priv->has_messages = g_variant_get_boolean (value);
- return TRUE;
- }
-
- if (strcmp (name, "Uid") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_UINT64))
- {
- priv->uid = g_variant_get_uint64 (value);
- return TRUE;
- }
-
- return FALSE;
-}
+static gboolean load_accounts_user (CommonUser *user);
static void
accounts_user_changed_cb (GDBusConnection *connection,
gpointer data)
{
CommonUser *user = data;
- CommonUserPrivate *priv = GET_USER_PRIVATE (user);
- gboolean changed = FALSE;
- GVariantIter *iter;
- GVariantIter *invalidated_properties;
- gchar *name;
- GVariant *value;
-
- g_variant_get (parameters, "(sa{sv}as)", NULL, &iter, &invalidated_properties);
- while (g_variant_iter_loop (iter, "{&sv}", &name, &value))
- {
- if (update_user_property (user, name, value))
- changed = TRUE;
- }
- g_variant_iter_free (iter);
- while (g_variant_iter_loop (invalidated_properties, "&s", &name))
- {
- GVariant *result;
- GError *error = NULL;
-
- result = g_dbus_connection_call_sync (connection,
- "org.freedesktop.Accounts",
- priv->path,
- "org.freedesktop.DBus.Properties",
- "Get",
- g_variant_new ("(ss)", "org.freedesktop.Accounts.User", name),
- G_VARIANT_TYPE ("(v)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- if (error)
- g_warning ("Error updating user property %s: %s", name, error->message);
- g_clear_error (&error);
-
- if (result)
- {
- GVariant *value;
-
- g_variant_get (result, "(v)", &value);
- if (update_user_property (user, name, value))
- changed = TRUE;
- g_variant_unref (value);
- g_variant_unref (result);
- }
- }
+ /*CommonUserPrivate *priv = GET_USER_PRIVATE (user);*/
- if (changed)
- {
- g_debug ("User %s changed", priv->path);
+ /* Log message disabled as AccountsService can have arbitrary plugins that
+ * might cause us to log when properties change we don't use. LP: #1376357
+ */
+ /*g_debug ("User %s changed", priv->path);*/
+ if (load_accounts_user (user))
g_signal_emit (user, user_signals[CHANGED], 0);
- }
}
static gboolean
GVariant *result, *value;
GVariantIter *iter;
gchar *name;
+ gboolean system_account = FALSE;
GError *error = NULL;
/* Get the properties for this user */
if (!priv->changed_signal)
- priv->changed_signal = g_dbus_connection_signal_subscribe (GET_LIST_PRIVATE (priv->user_list)->bus,
+ priv->changed_signal = g_dbus_connection_signal_subscribe (priv->bus,
"org.freedesktop.Accounts",
- "org.freedesktop.DBus.Properties",
- "PropertiesChanged",
- priv->path,
"org.freedesktop.Accounts.User",
+ "Changed",
+ priv->path,
+ NULL,
G_DBUS_SIGNAL_FLAGS_NONE,
accounts_user_changed_cb,
user,
NULL);
- result = g_dbus_connection_call_sync (GET_LIST_PRIVATE (priv->user_list)->bus,
+ result = g_dbus_connection_call_sync (priv->bus,
"org.freedesktop.Accounts",
priv->path,
"org.freedesktop.DBus.Properties",
/* Store the properties we need */
g_variant_get (result, "(a{sv})", &iter);
while (g_variant_iter_loop (iter, "{&sv}", &name, &value))
- update_user_property (user, name, value);
+ {
+ if (strcmp (name, "UserName") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ {
+ g_free (priv->name);
+ priv->name = g_variant_dup_string (value, NULL);
+ }
+ else if (strcmp (name, "RealName") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ {
+ g_free (priv->real_name);
+ priv->real_name = g_variant_dup_string (value, NULL);
+ }
+ else if (strcmp (name, "HomeDirectory") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ {
+ g_free (priv->home_directory);
+ priv->home_directory = g_variant_dup_string (value, NULL);
+ }
+ else if (strcmp (name, "Shell") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ {
+ g_free (priv->shell);
+ priv->shell = g_variant_dup_string (value, NULL);
+ }
+ else if (strcmp (name, "SystemAccount") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN))
+ system_account = g_variant_get_boolean (value);
+ else if (strcmp (name, "Language") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ {
+ if (priv->language)
+ g_free (priv->language);
+ priv->language = g_variant_dup_string (value, NULL);
+ }
+ else if (strcmp (name, "IconFile") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ {
+ g_free (priv->image);
+ priv->image = g_variant_dup_string (value, NULL);
+ if (strcmp (priv->image, "") == 0)
+ {
+ g_free (priv->image);
+ priv->image = NULL;
+ }
+ }
+ else if (strcmp (name, "XSession") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ {
+ g_free (priv->session);
+ priv->session = g_variant_dup_string (value, NULL);
+ }
+ else if (strcmp (name, "BackgroundFile") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ {
+ g_free (priv->background);
+ priv->background = g_variant_dup_string (value, NULL);
+ if (strcmp (priv->background, "") == 0)
+ {
+ g_free (priv->background);
+ priv->background = NULL;
+ }
+ }
+ else if (strcmp (name, "XKeyboardLayouts") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY))
+ {
+ g_strfreev (priv->layouts);
+ priv->layouts = g_variant_dup_strv (value, NULL);
+ if (!priv->layouts)
+ {
+ priv->layouts = g_malloc (sizeof (gchar *) * 1);
+ priv->layouts[0] = NULL;
+ }
+ }
+ else if (strcmp (name, "XHasMessages") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN))
+ priv->has_messages = g_variant_get_boolean (value);
+ else if (strcmp (name, "Uid") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_UINT64))
+ priv->uid = g_variant_get_uint64 (value);
+ }
g_variant_iter_free (iter);
g_variant_unref (result);
- return !priv->system_account;
+ return !system_account;
}
static void
priv = GET_USER_PRIVATE (user);
g_debug ("User %s added", path);
- priv->user_list = user_list;
+ priv->bus = g_object_ref (list_priv->bus);
priv->path = g_strdup (path);
- g_signal_connect (user, USER_SIGNAL_CHANGED, G_CALLBACK (user_changed_cb), NULL);
+ g_signal_connect (user, USER_SIGNAL_CHANGED, G_CALLBACK (user_changed_cb), user_list);
+ g_signal_connect (user, "get-logged-in", G_CALLBACK (get_logged_in_cb), user_list);
if (load_accounts_user (user))
{
list_priv->users = g_list_insert_sorted (list_priv->users, user, compare_user);
g_dbus_connection_signal_unsubscribe (priv->bus, priv->user_removed_signal);
priv->user_removed_signal = 0;
- load_passwd_file (user_list, FALSE);
-
/* Watch for changes to user list */
passwd_file = g_file_new_for_path (PASSWD_FILE);
g_return_val_if_fail (COMMON_IS_USER_LIST (user_list), NULL);
g_return_val_if_fail (username != NULL, NULL);
+ /* Load users from AccountsService, do nothing when it does not run */
load_users (user_list);
CommonUser *user = get_user_by_name (user_list, username);
}
static void
-common_user_list_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+common_user_list_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
common_user_list_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
CommonUserList *self;
if (priv->session_removed_signal)
g_dbus_connection_signal_unsubscribe (priv->bus, priv->session_removed_signal);
g_object_unref (priv->bus);
- if (priv->passwd_monitor)
- g_object_unref (priv->passwd_monitor);
+ g_clear_object (&priv->passwd_monitor);
G_OBJECT_CLASS (common_user_list_parent_class)->finalize (object);
}
{
GVariant *answer;
GError *error = NULL;
- CommonUserPrivate *user_priv = GET_USER_PRIVATE (user);
- CommonUserListPrivate *list_priv = GET_LIST_PRIVATE (user_priv->user_list);
+ CommonUserPrivate *priv = GET_USER_PRIVATE (user);
- answer = g_dbus_connection_call_sync (list_priv->bus,
+ answer = g_dbus_connection_call_sync (priv->bus,
"org.freedesktop.Accounts",
- user_priv->path,
+ priv->path,
"org.freedesktop.Accounts.User",
method,
args,
gboolean
common_user_get_logged_in (CommonUser *user)
{
- CommonUserPrivate *priv;
- CommonUserListPrivate *list_priv;
- GList *link;
+ gboolean result;
g_return_val_if_fail (COMMON_IS_USER (user), FALSE);
- priv = GET_USER_PRIVATE (user);
- list_priv = GET_LIST_PRIVATE (priv->user_list);
-
- // Lazily decide to load/listen to sessions
- if (list_priv->session_added_signal == 0)
- load_sessions (priv->user_list);
-
- for (link = list_priv->sessions; link; link = link->next)
- {
- CommonSession *session = link->data;
- if (strcmp (session->username, priv->name) == 0)
- return TRUE;
- }
+ g_signal_emit (user, user_signals[GET_LOGGED_IN], 0, &result);
- return FALSE;
+ return result;
}
/**
g_free (priv->path);
if (priv->changed_signal)
- g_dbus_connection_signal_unsubscribe (GET_LIST_PRIVATE (priv->user_list)->bus, priv->changed_signal);
+ g_dbus_connection_signal_unsubscribe (priv->bus, priv->changed_signal);
+ g_clear_object (&priv->bus);
g_free (priv->name);
g_free (priv->real_name);
g_free (priv->home_directory);
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
+
+ user_signals[GET_LOGGED_IN] =
+ g_signal_new ("get-logged-in",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ g_signal_accumulator_first_wins,
+ NULL,
+ NULL,
+ G_TYPE_BOOLEAN, 0);
}
static void