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;
- /* TRUE if have loaded user properties */
- gboolean loaded_values;
+ /* Bus we are listening for accounts service on */
+ GDBusConnection *bus;
/* Accounts service path */
gchar *path;
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, "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);
}
gpointer data)
{
CommonUser *user = data;
- CommonUserPrivate *priv = GET_USER_PRIVATE (user);
+ /*CommonUserPrivate *priv = GET_USER_PRIVATE (user);*/
- 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);
}
/* 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.Accounts.User",
"Changed",
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",
g_variant_unref (result);
- priv->loaded_values = TRUE;
-
return !system_account;
}
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, "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);
}
* The ::user-added signal gets emitted when a user account is created.
**/
list_signals[USER_ADDED] =
- g_signal_new ("user-added",
+ g_signal_new (USER_LIST_SIGNAL_USER_ADDED,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (CommonUserListClass, user_added),
* The ::user-changed signal gets emitted when a user account is modified.
**/
list_signals[USER_CHANGED] =
- g_signal_new ("user-changed",
+ g_signal_new (USER_LIST_SIGNAL_USER_CHANGED,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (CommonUserListClass, user_changed),
* The ::user-removed signal gets emitted when a user account is removed.
**/
list_signals[USER_REMOVED] =
- g_signal_new ("user-removed",
+ g_signal_new (USER_LIST_SIGNAL_USER_REMOVED,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (CommonUserListClass, user_removed),
{
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,
g_key_file_free (dmrc);
}
+/* Loads language/layout/session info for user */
static void
load_dmrc (CommonUser *user)
{
CommonUserPrivate *priv = GET_USER_PRIVATE (user);
GKeyFile *dmrc;
+ /* We're using Accounts service instead */
+ if (priv->path)
+ return;
+
+ if (priv->loaded_dmrc)
+ return;
+ priv->loaded_dmrc = TRUE;
dmrc = dmrc_load (user);
// FIXME: Watch for changes
g_key_file_free (dmrc);
}
-/* Loads language/layout/session info for user */
-static void
-load_user_values (CommonUser *user)
-{
- CommonUserPrivate *priv = GET_USER_PRIVATE (user);
-
- if (priv->loaded_values)
- return;
- priv->loaded_values = TRUE;
-
- if (!priv->path)
- load_dmrc (user);
-
- if (g_strcmp0 (priv->session, "ubuntu-2d") == 0)
- {
- g_free(priv->session);
- priv->session = g_strdup ("ubuntu");
- }
-}
-
/**
* common_user_get_name:
* @user: A #CommonUser
common_user_get_name (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
return GET_USER_PRIVATE (user)->name;
}
common_user_get_real_name (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
return GET_USER_PRIVATE (user)->real_name;
}
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
-
priv = GET_USER_PRIVATE (user);
if (!priv->real_name || strcmp (priv->real_name, "") == 0)
return priv->name;
common_user_get_home_directory (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
return GET_USER_PRIVATE (user)->home_directory;
}
common_user_get_shell (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
return GET_USER_PRIVATE (user)->shell;
}
common_user_get_image (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
return GET_USER_PRIVATE (user)->image;
}
common_user_get_background (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
return GET_USER_PRIVATE (user)->background;
}
common_user_get_language (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
+ load_dmrc (user);
const gchar *language = GET_USER_PRIVATE (user)->language;
return (language && language[0] == 0) ? NULL : language; /* Treat "" as NULL */
}
common_user_get_layout (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
+ load_dmrc (user);
return GET_USER_PRIVATE (user)->layouts[0];
}
common_user_get_layouts (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
+ load_dmrc (user);
return (const gchar * const *) GET_USER_PRIVATE (user)->layouts;
}
common_user_get_session (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), NULL);
- load_user_values (user);
+ load_dmrc (user);
const gchar *session = GET_USER_PRIVATE (user)->session;
return (session && session[0] == 0) ? NULL : session; /* Treat "" as NULL */
}
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;
}
/**
common_user_get_has_messages (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), FALSE);
- load_user_values (user);
return GET_USER_PRIVATE (user)->has_messages;
}
common_user_get_uid (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), 0);
- load_user_values (user);
return GET_USER_PRIVATE (user)->uid;
}
common_user_get_gid (CommonUser *user)
{
g_return_val_if_fail (COMMON_IS_USER (user), 0);
- load_user_values (user);
/* gid is not actually stored in AccountsService, so if our user is from
AccountsService, we have to look up manually in passwd. gid won't
change, so just look up the first time we're asked and never again. */
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);
* The ::changed signal gets emitted this user account is modified.
**/
user_signals[CHANGED] =
- g_signal_new ("changed",
+ g_signal_new (USER_SIGNAL_CHANGED,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (CommonUserClass, changed),
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