Blob Blame Raw
From 7849fa559cdcc197524135295bdb8e8aa13e2c13 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 2 Oct 2017 16:17:43 -0400
Subject: [PATCH 07/13] lib: use new has-multiple-users property from
 accountsservice

This commit changes accountsservice to use the new has-multiple-users
property provided by the daemon.
---
 src/libaccountsservice/act-user-manager.c | 27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c
index ac06e24..30bbd78 100644
--- a/src/libaccountsservice/act-user-manager.c
+++ b/src/libaccountsservice/act-user-manager.c
@@ -856,146 +856,130 @@ add_user (ActUserManager *manager,
 {
         const char *object_path;
 
         g_debug ("ActUserManager: tracking user '%s'", act_user_get_user_name (user));
         if (act_user_is_system_account (user)) {
                 g_hash_table_insert (manager->priv->system_users_by_name,
                                      g_strdup (act_user_get_user_name (user)),
                                      g_object_ref (user));
         } else {
                 g_hash_table_insert (manager->priv->normal_users_by_name,
                                      g_strdup (act_user_get_user_name (user)),
                                      g_object_ref (user));
         }
 
         object_path = act_user_get_object_path (user);
         if (object_path != NULL) {
                 g_hash_table_replace (manager->priv->users_by_object_path,
                                       (gpointer) object_path,
                                       g_object_ref (user));
         }
 
         g_signal_connect_object (user,
                                  "sessions-changed",
                                  G_CALLBACK (on_user_sessions_changed),
                                  manager, 0);
         g_signal_connect_object (user,
                                  "changed",
                                  G_CALLBACK (on_user_changed),
                                  manager, 0);
 
-        if (g_hash_table_size (manager->priv->normal_users_by_name) > 1) {
-                set_has_multiple_users (manager, TRUE);
-        }
-
         if (manager->priv->is_loaded) {
                 g_debug ("ActUserManager: loaded, so emitting user-added signal");
                 g_signal_emit (manager, signals[USER_ADDED], 0, user);
         } else {
                 g_debug ("ActUserManager: not yet loaded, so not emitting user-added signal");
         }
 }
 
 static void
 remove_user (ActUserManager *manager,
              ActUser        *user)
 {
         g_debug ("ActUserManager: no longer tracking user '%s' (with object path %s)",
                  act_user_get_user_name (user),
                  act_user_get_object_path (user));
 
         g_object_ref (user);
 
         g_signal_handlers_disconnect_by_func (user, on_user_changed, manager);
         g_signal_handlers_disconnect_by_func (user, on_user_sessions_changed, manager);
         if (act_user_get_object_path (user) != NULL) {
                 g_hash_table_remove (manager->priv->users_by_object_path, act_user_get_object_path (user));
         }
         if (act_user_get_user_name (user) != NULL) {
                 g_hash_table_remove (manager->priv->normal_users_by_name, act_user_get_user_name (user));
                 g_hash_table_remove (manager->priv->system_users_by_name, act_user_get_user_name (user));
 
         }
 
-        if (g_hash_table_size (manager->priv->normal_users_by_name) <= 1) {
-                set_has_multiple_users (manager, FALSE);
-        }
-
         if (manager->priv->is_loaded) {
                 g_debug ("ActUserManager: loaded, so emitting user-removed signal");
                 g_signal_emit (manager, signals[USER_REMOVED], 0, user);
         } else {
                 g_debug ("ActUserManager: not yet loaded, so not emitting user-removed signal");
         }
 
         g_debug ("ActUserManager: user '%s' (with object path %s) now removed",
                  act_user_get_user_name (user),
                  act_user_get_object_path (user));
         g_object_unref (user);
 }
 
 static void
 update_user (ActUserManager *manager,
              ActUser        *user)
 {
         const char *username;
 
         g_debug ("ActUserManager: updating %s", describe_user (user));
 
         username = act_user_get_user_name (user);
         if (g_hash_table_lookup (manager->priv->system_users_by_name, username) != NULL) {
                 if (!act_user_is_system_account (user)) {
                         g_debug ("ActUserManager: %s is no longer a system account, treating as normal user",
                                  describe_user (user));
                         g_hash_table_insert (manager->priv->normal_users_by_name,
                                              g_strdup (act_user_get_user_name (user)),
                                              g_object_ref (user));
                         g_hash_table_remove (manager->priv->system_users_by_name, username);
                         g_signal_emit (manager, signals[USER_ADDED], 0, user);
-
-                        if (g_hash_table_size (manager->priv->normal_users_by_name) > 1) {
-                                set_has_multiple_users (manager, TRUE);
-                        }
                 }
         } else {
                 if (act_user_is_system_account (user)) {
                         g_debug ("ActUserManager: %s is no longer a normal account, treating as system user",
                                  describe_user (user));
                         g_hash_table_insert (manager->priv->system_users_by_name,
                                              g_strdup (act_user_get_user_name (user)),
                                              g_object_ref (user));
                         g_hash_table_remove (manager->priv->normal_users_by_name, username);
                         g_signal_emit (manager, signals[USER_REMOVED], 0, user);
-
-                        if (g_hash_table_size (manager->priv->normal_users_by_name) <= 1) {
-                                set_has_multiple_users (manager, FALSE);
-                        }
                 }
         }
 }
 
 static ActUser *
 lookup_user_by_name (ActUserManager *manager,
                      const char     *username)
 {
         ActUser *user;
 
         user = g_hash_table_lookup (manager->priv->normal_users_by_name, username);
 
         if (user == NULL) {
                 user = g_hash_table_lookup (manager->priv->system_users_by_name, username);
         }
 
         return user;
 }
 
 static void
 on_new_user_loaded (ActUser        *user,
                     GParamSpec     *pspec,
                     ActUserManager *manager)
 {
         const char *username;
         ActUser *old_user;
 
         if (!act_user_is_loaded (user)) {
                 g_debug ("ActUserManager: %s loaded function called when not loaded",
                          describe_user (user));
@@ -2682,89 +2666,92 @@ set_include_usernames (ActUserManager *manager,
 }
 
 static void
 set_exclude_usernames (ActUserManager *manager,
                        GSList         *list)
 {
         if (manager->priv->exclude_usernames != NULL) {
                 g_slist_foreach (manager->priv->exclude_usernames, (GFunc) g_free, NULL);
                 g_slist_free (manager->priv->exclude_usernames);
         }
         manager->priv->exclude_usernames = slist_deep_copy (list);
 }
 
 static void
 act_user_manager_set_property (GObject        *object,
                                guint           prop_id,
                                const GValue   *value,
                                GParamSpec     *pspec)
 {
         ActUserManager *self;
 
         self = ACT_USER_MANAGER (object);
 
         switch (prop_id) {
         case PROP_INCLUDE_USERNAMES_LIST:
                 set_include_usernames (self, g_value_get_pointer (value));
                 break;
         case PROP_EXCLUDE_USERNAMES_LIST:
                 set_exclude_usernames (self, g_value_get_pointer (value));
                 break;
+        case PROP_HAS_MULTIPLE_USERS:
+                set_has_multiple_users (self, g_value_get_boolean (value));
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
         }
 }
 
 static void
 act_user_manager_class_init (ActUserManagerClass *klass)
 {
         GObjectClass   *object_class = G_OBJECT_CLASS (klass);
 
         object_class->finalize = act_user_manager_finalize;
         object_class->get_property = act_user_manager_get_property;
         object_class->set_property = act_user_manager_set_property;
 
         g_object_class_install_property (object_class,
                                          PROP_IS_LOADED,
                                          g_param_spec_boolean ("is-loaded",
                                                                "Is loaded",
                                                                "Determines whether or not the manager object is loaded and ready to read from.",
                                                                FALSE,
                                                                G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
         g_object_class_install_property (object_class,
                                          PROP_HAS_MULTIPLE_USERS,
                                          g_param_spec_boolean ("has-multiple-users",
                                                                "Has multiple users",
                                                                "Whether more than one normal user is present",
                                                                FALSE,
-                                                               G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+                                                               G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
         g_object_class_install_property (object_class,
                                          PROP_INCLUDE_USERNAMES_LIST,
                                          g_param_spec_pointer ("include-usernames-list",
                                                                "Include usernames list",
                                                                "Usernames who are specifically included",
                                                                G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
         g_object_class_install_property (object_class,
                                          PROP_EXCLUDE_USERNAMES_LIST,
                                          g_param_spec_pointer ("exclude-usernames-list",
                                                                "Exclude usernames list",
                                                                "Usernames who are specifically excluded",
                                                                G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
         /**
          * ActUserManager::user-added:
          * @gobject: the object which received the signal
          * @user: the #ActUser that was added
          *
          * Emitted when a user is added to the user manager.
          */
         signals [USER_ADDED] =
                 g_signal_new ("user-added",
                               G_TYPE_FROM_CLASS (klass),
                               G_SIGNAL_RUN_LAST,
                               G_STRUCT_OFFSET (ActUserManagerClass, user_added),
                               NULL, NULL,
                               g_cclosure_marshal_VOID__OBJECT,
                               G_TYPE_NONE, 1, ACT_TYPE_USER);
         /**
@@ -2865,60 +2852,66 @@ act_user_manager_init (ActUserManager *manager)
 
         error = NULL;
         manager->priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
         if (manager->priv->connection == NULL) {
                 if (error != NULL) {
                         g_warning ("Failed to connect to the D-Bus daemon: %s", error->message);
                         g_error_free (error);
                 } else {
                         g_warning ("Failed to connect to the D-Bus daemon");
                 }
                 return;
         }
 
         manager->priv->accounts_proxy = accounts_accounts_proxy_new_sync (manager->priv->connection,
                                                                           G_DBUS_PROXY_FLAGS_NONE,
                                                                           ACCOUNTS_NAME,
                                                                           ACCOUNTS_PATH,
                                                                           NULL,
                                                                           &error);
         if (manager->priv->accounts_proxy == NULL) {
                 if (error != NULL) {
                         g_warning ("Failed to create accounts proxy: %s", error->message);
                         g_error_free (error);
                 } else {
                         g_warning ("Failed to create_accounts_proxy");
                 }
                 return;
         }
         g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (manager->priv->accounts_proxy), G_MAXINT);
 
+        g_object_bind_property (G_OBJECT (manager->priv->accounts_proxy),
+                                "has-multiple-users",
+                                G_OBJECT (manager),
+                                "has-multiple-users",
+                                G_BINDING_SYNC_CREATE);
+
         g_signal_connect (manager->priv->accounts_proxy,
                           "user-added",
                           G_CALLBACK (on_new_user_in_accounts_service),
                           manager);
         g_signal_connect (manager->priv->accounts_proxy,
                           "user-deleted",
                           G_CALLBACK (on_user_removed_in_accounts_service),
                           manager);
 
         manager->priv->seat.state = ACT_USER_MANAGER_SEAT_STATE_UNLOADED;
 }
 
 static void
 act_user_manager_finalize (GObject *object)
 {
         ActUserManager *manager;
         GSList         *node;
 
         g_debug ("ActUserManager: finalizing user manager");
 
         g_return_if_fail (object != NULL);
         g_return_if_fail (ACT_IS_USER_MANAGER (object));
 
         manager = ACT_USER_MANAGER (object);
 
         g_return_if_fail (manager->priv != NULL);
 
         g_slist_foreach (manager->priv->new_sessions,
                          (GFunc) unload_new_session, NULL);
         g_slist_free (manager->priv->new_sessions);
-- 
2.14.1