Implement get_user_list library-side 81/274181/5
authorMateusz Majewski <m.majewski2@samsung.com>
Mon, 25 Apr 2022 05:55:17 +0000 (07:55 +0200)
committerMateusz Majewski <m.majewski2@samsung.com>
Wed, 27 Apr 2022 12:04:05 +0000 (14:04 +0200)
Change-Id: I453a35620069864b62cbae920f0e78b0acb2b971

libsessiond/src/lib.c
libsessiond/target_test/CMakeLists.txt
libsessiond/target_test/test_api_get_user_list.cpp [new file with mode: 0644]

index 68955d85e7c93b6d40aa09e816ff3f3e13e1433a..52d802654df08c8a933c5cc36bcfe7441f99bc59 100644 (file)
@@ -54,6 +54,7 @@ static struct {
        gchar * AddUserDone;
        gchar * RemoveUserWait;
        gchar * RemoveUserDone;
+       gchar * GetUserList;
 
 } dbus_method_call = {
        .AddUser = "AddUser",
@@ -63,6 +64,7 @@ static struct {
        .AddUserDone = "AddUserDone",
        .RemoveUserWait = "RemoveUserWait",
        .RemoveUserDone = "RemoveUserDone",
+       .GetUserList = "GetUserList"
 };
 
 static struct {
@@ -506,6 +508,41 @@ int method_call_no_signal(gchar *method, GVariant *params) {
        return 0;
 }
 
+int method_call_no_signal_return(gchar *method, GVariant *params, const GVariantType *out_type, GVariant **out) {
+
+       GError *error;
+       error = NULL;
+
+       if (session_connection_data.connection == NULL) {
+               session_connection_data.connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+               if(error != NULL) {
+                       return -ENOTCONN;
+               }
+       }
+
+       GVariant *retgv = NULL;
+       GError *call_sync_error;
+       call_sync_error = NULL;
+
+       retgv = g_dbus_connection_call_sync(
+               conn_config_,
+               method, params,
+               out_type,
+               G_DBUS_CALL_FLAGS_NONE,
+               libsessiond_default_timeout,
+               NULL,
+               &call_sync_error
+       );
+
+       if (!retgv || call_sync_error) {
+               g_error_free(call_sync_error);
+               return -EFAULT;
+       }
+
+       *out = retgv;
+       return 0;
+}
+
 void client_data_cleansweep_mt( signal_client_data_t *signal_client_data, client_callbacks_data_t *callbacks_data) {
 
        g_mutex_lock(&callbacks_data->mutex);
@@ -730,7 +767,30 @@ EXPORT_API int subsession_switch_wait_done(int session_uid, uint64_t switch_id)
 
 EXPORT_API int subsession_get_user_list(int session_uid, int **user_list, int *user_count) {
 
-       return TIZEN_ERROR_ACCOUNT;
+       g_autoptr(GVariant) out = NULL;
+       int ret = method_call_no_signal_return(dbus_method_call.GetUserList,
+                                              g_variant_new("(i)", session_uid),
+                                              G_VARIANT_TYPE("(ai)"),
+                                              &out);
+
+       if (ret != 0)
+               return ret;
+
+       g_autoptr(GVariant) array = g_variant_get_child_value(out, 0);
+
+       gsize elem_no = 0;
+       // We don't need to free this.
+       const guint *data = g_variant_get_fixed_array(array, &elem_no, sizeof(int));
+
+       *user_list = calloc(elem_no, sizeof(int));
+       if (!*user_list)
+               return TIZEN_ERROR_OUT_OF_MEMORY;
+       *user_count = elem_no;
+
+       for (gsize i = 0; i < elem_no; ++i)
+               (*user_list)[i] = data[i];
+
+       return TIZEN_ERROR_NONE;
 }
 
 EXPORT_API int subsession_get_current_user(int session_uid, int *user) {
index 9dad0f8e3e92e5eef4d57d99dc1ea1c2975d8993..8898d66532c1e28de7acef89b6fcb70adf1727a9 100644 (file)
@@ -17,3 +17,4 @@ add_libsd_target_test(api_add_remove_user  "")
 add_libsd_target_test(api_switchuser  "")
 #add_libsd_target_test(api_adduserwait  "")
 #add_libsd_target_test(api_add_remove_user_wait  "")
+add_libsd_target_test(api_get_user_list  "")
diff --git a/libsessiond/target_test/test_api_get_user_list.cpp b/libsessiond/target_test/test_api_get_user_list.cpp
new file mode 100644 (file)
index 0000000..922d49c
--- /dev/null
@@ -0,0 +1,70 @@
+#include <algorithm>
+#include <gtest/gtest.h>
+#include <gio/gio.h>
+#include <dirent.h>
+#include <stdlib.h>
+
+#include "sessiond.h"
+
+// Let's test against the owner user.
+constexpr int tested_user = 5001;
+
+int callback(int result, void *data) {
+
+       // The add and remove user functions will call this,
+       // which will just propagate the result.
+       return result;
+}
+
+TEST(subsession_get_user_list_test, APIGetUserListTest) {
+
+       // Let's ask for the initial user list.
+       int *user_list_0;
+       int user_count_0;
+       int ret = subsession_get_user_list(tested_user, &user_list_0, &user_count_0);
+       EXPECT_EQ(ret, 0);
+
+       // The list should be sorted, so we can easily compare.
+       std::sort(user_list_0, user_list_0 + user_count_0);
+
+       // Let's now add a new user, with ID larger than all the others.
+       int new_added = 12345;
+       if (user_count_0 != 0)
+               new_added = user_list_0[user_count_0 - 1] < new_added ? new_added : user_list_0[user_count_0 - 1] + 1;
+       ret = subsession_add_user(tested_user, new_added, callback, NULL);
+       EXPECT_EQ(ret, 0);
+
+       // Now if we ask for the list again...
+       int *user_list_1;
+       int user_count_1;
+       ret = subsession_get_user_list(tested_user, &user_list_1, &user_count_1);
+       EXPECT_EQ(ret, 0);
+
+       // ... the count should be larger by one, and the only change should be the newly added user.
+       EXPECT_EQ(user_count_1, user_count_0 + 1);
+       std::sort(user_list_1, user_list_1 + user_count_1);
+       EXPECT_EQ(new_added, user_list_1[user_count_0]);
+       for (int i = 0; i < user_count_0; ++i)
+               EXPECT_EQ(user_list_0[i], user_list_1[i]);
+
+       // Let's do this again, just to be sure.
+       ret = subsession_add_user(tested_user, new_added + 1, callback, NULL);
+       EXPECT_EQ(ret, 0);
+       int *user_list_2;
+       int user_count_2;
+       ret = subsession_get_user_list(tested_user, &user_list_2, &user_count_2);
+       EXPECT_EQ(ret, 0);
+       EXPECT_EQ(user_count_2, user_count_0 + 2);
+       std::sort(user_list_2, user_list_2 + user_count_2);
+       EXPECT_EQ(new_added, user_list_2[user_count_0]);
+       EXPECT_EQ(new_added + 1, user_list_2[user_count_0 + 1]);
+       for (int i = 0; i < user_count_0; ++i)
+               EXPECT_EQ(user_list_0[i], user_list_2[i]);
+
+       // Finally, let's cleanup (not needed, nor guaranteed to run anyway, but still a good idea).
+       subsession_remove_user(tested_user, new_added, callback, NULL);
+       subsession_remove_user(tested_user, new_added + 1, callback, NULL);
+       free(user_list_0);
+       free(user_list_1);
+       free(user_list_2);
+}