--- /dev/null
+#include <iostream>
+#include <gio/gio.h>
+#include <thread>
+#include "sessiond.h"
+
+#define SESSION_UID 5001
+const int firstUser = 1; // 0 user is reserved
+const int lastUser = 11;
+
+GMutex mutex;
+volatile int callbackCount;
+
+typedef struct {
+ int callback_result;
+} test_user_data;
+
+typedef struct {
+ int session_uid;
+ int user_id;
+ uint64_t switch_id;
+ int callback_result;
+ int callback_reference;
+ int prev_user_id;
+ subsession_event_type_e event;
+} test_user_data_cb_t;
+
+
+int test_subsession_switch_user_completion_callback(subsession_event_info info, void *cb_data) {
+ g_atomic_int_inc(&callbackCount);
+ test_user_data_cb_t *user_data = (test_user_data_cb_t *)cb_data;
+ user_data->session_uid = info.switch_user.session_uid;
+ user_data->switch_id = info.switch_user.switch_id;
+ user_data->user_id = info.switch_user.next_user;
+ user_data->prev_user_id = info.switch_user.prev_user;
+ user_data->callback_result = 0;
+
+ return 0;
+}
+
+typedef struct {
+ GMainLoop * loop;
+ test_user_data *user_data;
+}ud_ctrl;
+
+test_user_data userD[20];
+int callback_pending_reference;
+
+gboolean callback_pending(gpointer data) {
+
+ ud_ctrl *ud = (ud_ctrl*)data;
+ gboolean is_pending = g_main_context_pending(NULL);
+ gint ctrl_value = g_atomic_int_get(&callback_pending_reference);
+
+ if(is_pending == TRUE) {
+ return TRUE;
+ }
+
+ if(ctrl_value >= 2) {
+ g_main_loop_quit((GMainLoop*)ud->loop);
+ }
+ return TRUE;
+}
+
+int test_reply_adduser_callback (int result, void *cb_data) {
+
+ g_atomic_int_inc(&callback_pending_reference);
+
+ if (cb_data == NULL) {
+ return -EBADR;
+ }
+ test_user_data *user_data = (test_user_data *)cb_data;
+ user_data->callback_result = result;
+
+ if (result < 0) {
+ return result;
+ }
+ g_mutex_unlock(&mutex);
+ return 0;
+}
+
+int test_reply_removeuser_callback (int result, void *cb_data) {
+
+ g_atomic_int_inc(&callback_pending_reference);
+
+ if (cb_data == NULL) {
+ return -EBADR;
+ }
+ test_user_data *user_data = (test_user_data *)cb_data;
+ user_data->callback_result = result;
+
+ if (result < 0) {
+ return result;
+ }
+
+ return 0;
+}
+
+int test_reply_switchuser_callback (int result, void *cb_data){
+ test_user_data *user_data = (test_user_data *)cb_data;
+ user_data->callback_result = result;
+ g_mutex_unlock(&mutex);
+ return 0;
+}
+GMainLoop* loop = NULL;
+
+int switch_user_test(int user_id)
+{
+ int new_user = -1 ;
+ test_user_data test_switch_ud;
+ test_switch_ud.callback_result = -1;
+
+ g_mutex_trylock(&mutex);
+ int switch_user_res = subsession_switch_user(SESSION_UID,user_id, test_reply_switchuser_callback, (void *)&test_switch_ud);
+ if(switch_user_res != 0)
+ {
+ printf("Error subsession_switch_user res is%d\n",switch_user_res);
+ return -1;
+ }
+ g_mutex_lock(&mutex);
+
+ subsession_get_current_user(SESSION_UID, &new_user);
+ return new_user;
+}
+
+
+int main(int argc,char *argv[]) {
+
+ loop = g_main_loop_new (NULL, FALSE);
+ g_mutex_init(&mutex);
+ std::thread t1(g_main_loop_run, loop);
+ g_atomic_int_set(&callback_pending_reference, 0);
+
+ ///===================================///
+ printf("Test program start\nCreating test users...");
+
+ for (int i = firstUser; i < lastUser; ++i)
+ {
+ g_mutex_trylock(&mutex);
+ userD[i].callback_result = i * 10;
+ int add_user_res = subsession_add_user(SESSION_UID, i, test_reply_adduser_callback, (void *)&userD[i]);
+
+ if( add_user_res != 0)
+ {
+ printf("Error subsession_add_user res is %d\n", add_user_res);
+ return -1;
+ }
+ g_mutex_lock(&mutex);
+ }
+ printf("\033[0;32mdone\033[0;37m\n");
+
+ int registered_users;
+ int *userlist;
+ ///===================================///
+ subsession_get_user_list(SESSION_UID, (int **)&userlist, ®istered_users);
+ printf("No of registered users [%d/%d]...", registered_users, lastUser - firstUser);
+ if(lastUser - firstUser == registered_users)
+ {
+ printf("\033[0;32mok\033[0;37m\n");
+ }
+ else
+ {
+ printf("Register event callback error\n");
+ return -1;
+ }
+
+ if(registered_users != lastUser - firstUser)
+ return 1;
+
+ printf("Lp. ");
+ for(int i = 0; i< registered_users; ++i)
+ printf(" %2d ", i);
+ printf("\nId. ");
+ for(int i = 0; i< registered_users; ++i)
+ printf(" %2d ", userlist[i]);
+ printf("\n");
+ ///===================================///
+ printf("Switching users test...");
+
+ callbackCount =0;
+
+ test_user_data_cb_t data;
+ subsession_register_event_callback(SESSION_UID, SUBSESSION_SWITCH_USER_COMPLETION, test_subsession_switch_user_completion_callback, (void *)&data);
+
+ for(int i = firstUser; i< registered_users + firstUser; ++i)
+ {
+ int res = switch_user_test(i);
+ if(res != i)
+ {
+ printf("Switch user error\n");
+ return -1;
+ }
+ }
+
+ printf("\033[0;32mdone\033[0;37m\n");
+
+ printf("Register event callback test [%d/%d]...", g_atomic_int_get(&callbackCount), registered_users );
+ if(g_atomic_int_get(&callbackCount) == registered_users)
+ {
+ printf("\033[0;32mok\033[0;37m\n");
+ }
+ else
+ {
+ printf("Register event callback error\n");
+ return -1;
+ }
+ ///===================================///
+ printf("Subsession unregister event callback test...");
+
+ callbackCount =0;
+ subsession_unregister_event_callback(SESSION_UID, SUBSESSION_SWITCH_USER_COMPLETION);
+ for(int i = firstUser; i< registered_users + firstUser; ++i)
+ {
+ int res = switch_user_test(i);
+ if(res != i)
+ {
+ printf("Switch user error\n");
+ return -1;
+ }
+
+ }
+ if(g_atomic_int_get(&callbackCount) == 0)
+ {
+ printf("\033[0;32mdone\033[0;37m\n");
+ }
+ else
+ {
+ printf("Register event callback error\n");
+ return -1;
+ }
+ ///======================================///
+ printf("Removing users...");
+ int end_res = switch_user_test(0);
+ if(end_res != 0)
+ {
+ printf("Error setting user to 0\n");
+ return -1;
+ }
+ for (int i = firstUser; i < lastUser; ++i)
+ {
+ test_user_data test_remove_ud;
+ test_remove_ud.callback_result = -1;
+ int remove_user_res = subsession_remove_user(SESSION_UID, i, test_reply_removeuser_callback, (void *)&test_remove_ud);
+ if(remove_user_res != 0)
+ {
+ printf("removing user %d failed code: %d\n", i,remove_user_res);
+ return -1;
+ }
+ }
+ printf("\033[0;32mdone\033[0;37m\n");
+
+ ud_ctrl ud;
+ ud.loop = loop;
+
+ g_idle_add(callback_pending,(gpointer*)&ud);
+
+ t1.join();
+ g_mutex_unlock(&mutex);
+ g_mutex_clear(&mutex);
+ printf("Test program end\n");
+ return 0;
+}
\ No newline at end of file