Rework API according to new specification. 95/273895/13
authorArkadiusz Nowak <a.nowak3@samsung.com>
Thu, 14 Apr 2022 18:27:12 +0000 (20:27 +0200)
committerMateusz Majewski <m.majewski2@samsung.com>
Wed, 27 Apr 2022 12:03:57 +0000 (14:03 +0200)
This commit unifies separate wait callback registration
and handling functions into one - registration now accepts
bitmask of callback types.
User callbacks accepts incoming data as union.

Icrease dbus mtehod call timeout to 20s, because filesystem's operations needs longer time to complete.
Library is going to use dlog.

Change-Id: I438ca52fcc16a145254686a19e0db4980edfd8df

libsessiond/CMakeLists.txt
libsessiond/include/sessiond.h
libsessiond/src/lib.c
libsessiond/target_test/CMakeLists.txt
libsessiond/target_test/test_api_add_remove_user.cpp
libsessiond/target_test/test_api_add_remove_user_wait.cpp
libsessiond/target_test/test_api_adduser.cpp
libsessiond/target_test/test_api_adduserwait.cpp
libsessiond/target_test/test_api_removeuser.cpp
libsessiond/target_test/test_api_switchuser.cpp
packaging/sessiond.spec

index 15e651d83d8e0be501c0a59daf469635a6189b9e..cef1569bac1f89474b7eb24cda23e2252fbf272f 100644 (file)
@@ -1,5 +1,5 @@
 find_package(PkgConfig)
-pkg_check_modules(DEPS REQUIRED IMPORTED_TARGET capi-base-common gio-2.0)
+pkg_check_modules(DEPS REQUIRED IMPORTED_TARGET capi-base-common gio-2.0 dlog)
 
 set(
        libsessiond_SRCS
index 5d3471101186712be94d91e3054ff48d70582cbd..6866cd14f80fc71187229d73719cee5c5022e524 100644 (file)
@@ -33,24 +33,49 @@ int subsession_add_user(int session_uid, int user, subsession_reply_callback cb,
 int subsession_remove_user(int session_uid, int user, subsession_reply_callback cb, void *cb_data);
 int subsession_switch_user(int session_uid, int prev_user, int next_user, subsession_reply_callback cb, void *cb_data);
 
-typedef int (*subsession_add_user_wait_callback) (int session_uid, int user, void *cb_data);
-int subsession_add_user_wait(int session_uid, subsession_add_user_wait_callback cb, void *cb_data);
 int subsession_add_user_wait_done(int session_uid, int user);
 
-typedef int (*subsession_remove_user_wait_callback) (int session_uid, int user, void *cb_data);
-int subsession_remove_user_wait(int session_uid, subsession_remove_user_wait_callback cb, void *cb_data);
 int subsession_remove_user_wait_done(int session_uid, int user);
 
 typedef int (*subsession_switch_wait_callback) (int session_uid, uint64_t switch_id, int prev_user, int next_user, void *cb_data);
 int subsession_switch_wait(int session_uid, subsession_switch_wait_callback cb, void *cb_data);
 int subsession_switch_wait_done(int session_uid, uint64_t switch_id);
 
-typedef int (*subsession_switch_completion_callback)(int session_uid, int prev_user, int next_user, uint64_t switch_id);
-int subsession_switch_completion(int session_uid, subsession_switch_completion_callback cb, void *cb_data);
-
 int subsession_get_user_list(int session_uid, int **user_list, int *user_count);
 int subsession_get_current_user(int session_uid, int *user);
-int subsession_is_supported (int *supported);
+
+typedef enum {
+               SUBSESSION_ADD_USER_WAIT = 0x01,
+               SUBSESSION_REMOVE_USER_WAIT = 0x02,
+               SUBSESSION_SWITCH_USER_WAIT = 0x04,
+               SUBSESSION_SWITCH_USER_COMPLETION = 0x08,
+               SUBSESSION_EVENT_ALL = 0xFF,
+} subsession_event_type_e;
+
+typedef union subsession_event_info {
+       struct add_user {
+                       subsession_event_type_e event;
+                       int session_uid;
+                       int user;
+               } add_user;
+
+               struct remove_user {
+                       subsession_event_type_e event;
+                       int session_uid;
+                       int user;
+               } remove_user;
+
+               struct switch_user {
+                       subsession_event_type_e event;
+                               int session_uid;
+                               uint64_t switch_id;
+                               int prev_user;
+                               int next_user;
+               } switch_user;
+} subsession_event_info;
+
+typedef int (*subsession_event_callback) (subsession_event_info info, void *cb_data);
+int subsession_register_event_callback(int session_uid, subsession_event_type_e event_bits, subsession_event_callback cb, void *cb_data);
 
 #ifdef __cplusplus
 }
index 21a3add52b247eb3397a519a55370cd099192471..68955d85e7c93b6d40aa09e816ff3f3e13e1433a 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE. */
 
-
 #include <gio/gio.h>
 #include <tizen.h>
+
+#undef LOG_TAG
+#define LOG_TAG "LIBSESSIOND"
+
+#include <dlog.h>
 #include "lib.h"
 #include "sessiond.h"
 
+const int libsessiond_default_timeout = 20000;
+
 session_connection_data_t session_connection_data = {
        .connection = NULL,
        .bus_name = "org.tizen.sessiond",
@@ -34,6 +40,12 @@ session_connection_data_t session_connection_data = {
        .interface = "org.tizen.sessiond.subsession.Manager",
 };
 
+#define conn_config_ \
+               session_connection_data.connection, \
+               session_connection_data.bus_name, \
+               session_connection_data.objpath, \
+               session_connection_data.interface \
+
 static struct {
        gchar * AddUser;
        gchar * RemoveUser;
@@ -84,21 +96,47 @@ dbus_signal_subscribed_t  dbus_signal_subscribed = {
        .RemoveUserStarted = 0,
 };
 
-GList *add_user_callbacks_list = NULL;
-GMutex add_user_mutex;
+typedef struct {
+       GList *list;
+       GMutex mutex;
+       gchar * dbus_method_call;
+       gchar * dbus_signal;
+       guint dbus_signal_subscribed;
+} client_callbacks_data_t;
+
+
+
+client_callbacks_data_t add_user_callbacks_data_mt = {
+       .list = NULL,
+};
+
+client_callbacks_data_t remove_user_callbacks_data_mt = {
+       .list = NULL,
+};
 
-GList *remove_user_callbacks_list = NULL;
-GMutex remove_user_mutex;
+client_callbacks_data_t switch_user_callbacks_data_mt = {
+       .list = NULL,
+};
 
+client_callbacks_data_t add_user_wait_callbacks_data_mt = {
+       .list = NULL,
+       .dbus_method_call = "AddUserStart",
+       .dbus_signal = "AddUserStarted"
+};
 
-GList *switch_user_callbacks_list = NULL;
-GMutex switch_user_mutex;
+client_callbacks_data_t remove_user_wait_callbacks_data_mt = {
+       .list = NULL,
+       .dbus_method_call = "RemoveUserStart",
+       .dbus_signal = "RemoveUserStarted"
+};
 
+client_callbacks_data_t switch_user_listen_callbacks_data_mt = {
+       .list = NULL,
+};
 
 GList *add_user_wait_callbacks_list = NULL;
 GMutex add_user_wait_mutex;
 
-
 typedef struct {
        void *client_callback;
        void *client_callback_data;
@@ -133,9 +171,8 @@ gint g_compare_user_params (  gconstpointer client_data,   gconstpointer paramet
 
        int params_session_uid = 0;
        int params_user = 0;
-       int params_status = 0;
 
-       g_variant_get(params, "(iii)", &params_session_uid, &params_user, &params_status);
+       g_variant_get(params, "(ii)", &params_session_uid, &params_user);
 
        if( client_session_uid == params_session_uid &&
                client_user == params_user) {
@@ -145,49 +182,52 @@ gint g_compare_user_params (  gconstpointer client_data,   gconstpointer paramet
        return -1;
 }
 
-static void signal_add_user_complete_handler(
-       GDBusConnection *connection,
-       const gchar *sender_name,
-       const gchar *object_path,
-       const gchar *interface_name,
-       const gchar *signal_name,
-       GVariant *parameters,
-       gpointer client_data) {
+gint g_compare_session_uid_params (  gconstpointer client_data,   gconstpointer parameters) {
+
+       signal_client_data_t *signal_client_data = (signal_client_data_t*)client_data;
+
+       int client_session_uid = 0;
+       g_variant_get(signal_client_data->params, "(i)", &client_session_uid);
 
-       int ret_session_uid = 0;
-       int ret_user = 0;
-       int ret_status = 0;
-       g_variant_get(parameters, "(iii)", &ret_session_uid, &ret_user, &ret_status);
+       GVariant *params = (GVariant *)parameters;
+
+       int params_session_uid = 0;
+
+       g_variant_get(params, "(i)", &params_session_uid);
+
+       if( client_session_uid == params_session_uid) {
+
+                       return 0;
+               }
+       return -1;
+}
+
+signal_client_data_t *find_in_callbacks_data( client_callbacks_data_t *client_callbacks_data, gconstpointer parameters, GCompareFunc compare_user_params) {
 
        signal_client_data_t *signal_data = NULL;
-       g_mutex_lock(&add_user_mutex);
-               GList *found_data = g_list_find_custom( add_user_callbacks_list, (gconstpointer) parameters, g_compare_user_params );
+
+       g_mutex_lock(&client_callbacks_data->mutex);
+               GList *found_data = g_list_find_custom( client_callbacks_data->list, (gconstpointer) parameters, compare_user_params );
                if (found_data != NULL) {
                        signal_data = (signal_client_data_t*)found_data->data;
-                       add_user_callbacks_list = g_list_remove(add_user_callbacks_list, found_data->data);
+                       client_callbacks_data->list = g_list_remove(client_callbacks_data->list, found_data->data);
                        g_list_free (g_steal_pointer (&found_data));
                }
-       g_mutex_unlock(&add_user_mutex);
+       g_mutex_unlock(&client_callbacks_data->mutex);
 
-       if(signal_data == NULL) {
-               return;
-       }
+       return signal_data;
+}
 
-       if(signal_data->client_callback == NULL) {
-               return ;
-       }
+const int cb_result_ok = 0;
 
-       subsession_reply_callback reply_cb = signal_data->client_callback;
+void call_reply_callback(signal_client_data_t *signal_data, int ret_status) {
 
+       subsession_reply_callback reply_cb = signal_data->client_callback;
        void *client_callback_data = signal_data->client_callback_data;
        reply_cb(ret_status, client_callback_data);
-
-       g_variant_unref(signal_data->params);
-       free(signal_data);
-       return;
 }
 
-static void signal_remove_user_complete_handler(
+static void signal_user_ops_complete_handler(
        GDBusConnection *connection,
        const gchar *sender_name,
        const gchar *object_path,
@@ -196,39 +236,31 @@ static void signal_remove_user_complete_handler(
        GVariant *parameters,
        gpointer client_data) {
 
-       int ret_session_uid = 0;
-       int ret_user = 0;
-       int ret_status = 0;
-       g_variant_get(parameters, "(iii)", &ret_session_uid, &ret_user, &ret_status);
+       if(client_data == NULL) {
+               return ;
+       }
 
-       signal_client_data_t *signal_data = NULL;
-       g_mutex_lock(&remove_user_mutex);
-               GList *found_data = g_list_find_custom( remove_user_callbacks_list, (gconstpointer) parameters, g_compare_user_params );
-               if (found_data != NULL) {
-                       signal_data = (signal_client_data_t*)found_data->data;
-                       remove_user_callbacks_list = g_list_remove(remove_user_callbacks_list, found_data->data);
-                       g_list_free (g_steal_pointer (&found_data));
-               }
-       g_mutex_unlock(&remove_user_mutex);
+       client_callbacks_data_t *client_callbacks_data = (client_callbacks_data_t *)client_data;
+
+       signal_client_data_t *signal_data = find_in_callbacks_data(client_callbacks_data, parameters, g_compare_user_params);
 
        if(signal_data == NULL) {
                return;
        }
-
        if(signal_data->client_callback == NULL) {
                return ;
        }
 
-       subsession_reply_callback reply_cb = signal_data->client_callback;
-
-       void *client_callback_data = signal_data->client_callback_data;
-       reply_cb(ret_status, client_callback_data);
+       call_reply_callback(signal_data, cb_result_ok);
 
        g_variant_unref(signal_data->params);
        free(signal_data);
        return;
 }
 
+#define signal_add_user_complete_handler signal_user_ops_complete_handler
+#define signal_remove_user_complete_handler signal_user_ops_complete_handler
+
 gint g_compare_switch_user_params (  gconstpointer client_data,   gconstpointer parameters) {
 
        signal_client_data_t *signal_client_data = (signal_client_data_t*)client_data;
@@ -244,22 +276,21 @@ gint g_compare_switch_user_params (  gconstpointer client_data,   gconstpointer
        int params_switch_id = 0;
        int params_prev_user = 0;
        int params_next_user = 0;
-       int status_code = 0;
 
-       g_variant_get(params, "(ixiii)", &params_session_uid, &params_switch_id, &params_prev_user, &params_next_user, &status_code );
+       g_variant_get(params, "(ixii)", &params_session_uid, &params_switch_id, &params_prev_user, &params_next_user);
 
        gboolean all_ok = (client_session_uid == params_session_uid) &&
                                         (client_prev_user == params_prev_user) &&
                                         (client_next_user == params_next_user);
 
-
        if( all_ok) {
                        return 0;
        }
+
        return -1;
 }
 
-static void signal_switch_user_complete_handler(
+static void incoming_signal_answer_for_method_switch_user(
        GDBusConnection *connection,
        const gchar *sender_name,
        const gchar *object_path,
@@ -268,81 +299,83 @@ static void signal_switch_user_complete_handler(
        GVariant *parameters,
        gpointer client_data) {
 
+       client_callbacks_data_t *client_callbacks_data = &switch_user_callbacks_data_mt;
 
-       int ret_session_uid = 0;
-       int ret_switch_id = 0;
-       int ret_prev_user = 0;
-       int ret_next_user = 0;
-       int ret_code = 0;
-       g_variant_get(parameters, "(ixiii)", &ret_session_uid, &ret_switch_id, &ret_prev_user, &ret_next_user, &ret_code );
-
-       signal_client_data_t *signal_data = NULL;
-       g_mutex_lock(&switch_user_mutex);
+       if(client_callbacks_data->list == NULL) {
+               return;
+       }
 
-               GList *found_data = g_list_find_custom( switch_user_callbacks_list, (gconstpointer) parameters, g_compare_switch_user_params );
-               if (found_data != NULL) {
-                       signal_data = (signal_client_data_t*)found_data->data;
-                       switch_user_callbacks_list = g_list_remove(switch_user_callbacks_list, found_data->data);
-                       g_list_free (g_steal_pointer (&found_data));
-               }
-       g_mutex_unlock(&switch_user_mutex);
+       signal_client_data_t *signal_data = find_in_callbacks_data(client_callbacks_data, parameters, g_compare_switch_user_params);
 
        if(signal_data == NULL) {
                return;
        }
-
        if(signal_data->client_callback == NULL) {
                return ;
        }
 
-       subsession_reply_callback reply_cb = signal_data->client_callback;
-
-       void *client_callback_data = signal_data->client_callback_data;
-       reply_cb(ret_code, client_callback_data);
+       call_reply_callback(signal_data, cb_result_ok);
 
        g_variant_unref(signal_data->params);
        free(signal_data);
+
        return;
 }
 
-static void signal_add_user_started_callback(GDBusConnection *connection,
+static void signal_switch_user_complete_handler(GDBusConnection *connection,
        const gchar *sender_name,
        const gchar *object_path,
        const gchar *interface_name,
        const gchar *signal_name,
        GVariant *parameters,
-       gpointer client_data)
-{
+       gpointer client_data) {
 
-       signal_client_data_t *signal_data = (signal_client_data_t *)client_data;
+       incoming_signal_answer_for_method_switch_user(connection,
+                       sender_name,
+                       object_path,
+                       interface_name,
+                       signal_name,
+                       parameters,
+                       client_data     );
 
-       subsession_add_user_wait_callback add_user_wait_cb = signal_data->client_callback;
+       // function call for signal only here...
+}
 
-       int ret_session_uid = 0;
-       int ret_user_id = 0;
-       g_variant_get(parameters,"(ii)", &ret_session_uid,  &ret_user_id);
+static void signal_add_user_started_handler(GDBusConnection *connection,
+       const gchar *sender_name,
+       const gchar *object_path,
+       const gchar *interface_name,
+       const gchar *signal_name,
+       GVariant *parameters,
+       gpointer client_data)
+{
+       client_callbacks_data_t *client_callbacks_data = &switch_user_callbacks_data_mt;
 
-       int par_session_uid = 0;
+       if(client_callbacks_data->list == NULL) {
+               return;
+       }
 
-       GVariant *signal_variant_params = signal_data->params;
-       g_variant_get(signal_variant_params, "(i)", &par_session_uid );
+       signal_client_data_t *signal_data = find_in_callbacks_data(client_callbacks_data, parameters, g_compare_session_uid_params);
 
-       gboolean all_params_ok = (par_session_uid == ret_session_uid);
+       if(signal_data == NULL) {
+               return;
+       }
 
-       if (all_params_ok ) {
-                       g_variant_unref(signal_data->params);
-                       add_user_wait_cb(ret_session_uid, ret_user_id, signal_data->client_callback_data);
-               //      g_dbus_connection_signal_unsubscribe(connection, signal_data->signal_subscribed);
-                       return;
+       if(signal_data->client_callback == NULL) {
+               return ;
        }
 
-       g_variant_unref(signal_data->params);
-       add_user_wait_cb(-EFAULT, -EFAULT,  signal_data->client_callback_data);
-       //g_dbus_connection_signal_unsubscribe(connection, signal_data->signal_subscribed);
+       subsession_event_info event_info;
+
+       event_info.add_user.event = SUBSESSION_ADD_USER_WAIT;
+       g_variant_get(parameters, "(ii)", &event_info.add_user.session_uid, &event_info.add_user.user);
+
+       subsession_event_callback event_callback = signal_data->client_callback;
+       event_callback(event_info, signal_data->client_callback_data);
        return;
 }
 
-static void signal_remove_user_started_callback(GDBusConnection *connection,
+static void signal_remove_user_started_handler(GDBusConnection *connection,
        const gchar *sender_name,
        const gchar *object_path,
        const gchar *interface_name,
@@ -350,32 +383,29 @@ static void signal_remove_user_started_callback(GDBusConnection *connection,
        GVariant *parameters,
        gpointer client_data)
 {
+       client_callbacks_data_t *client_callbacks_data = &switch_user_callbacks_data_mt;
 
-       signal_client_data_t *signal_data = (signal_client_data_t *)client_data;
-
-       subsession_remove_user_wait_callback remove_user_wait_cb = signal_data->client_callback;
+       if(client_callbacks_data->list == NULL) {
+               return;
+       }
 
-       int ret_session_uid = 0;
-       int ret_user_id = 0;
-       g_variant_get(parameters,"(ii)", &ret_session_uid,  &ret_user_id);
+       signal_client_data_t *signal_data = find_in_callbacks_data(client_callbacks_data, parameters, g_compare_session_uid_params);
 
-       int par_session_uid = 0;
+       if(signal_data == NULL) {
+               return;
+       }
 
-       GVariant *signal_variant_params = signal_data->params;
-       g_variant_get(signal_variant_params, "(i)", &par_session_uid );
+       if(signal_data->client_callback == NULL) {
+               return ;
+       }
 
-       gboolean all_params_ok = (par_session_uid == ret_session_uid);
+       subsession_event_info event_info;
 
-       if (all_params_ok ) {
-                       g_variant_unref(signal_data->params);
-                       remove_user_wait_cb(ret_session_uid, ret_user_id, signal_data->client_callback_data);
-                       //g_dbus_connection_signal_unsubscribe(connection, signal_data->signal_subscribed);
-                       return;
-       }
+       event_info.remove_user.event = SUBSESSION_REMOVE_USER_WAIT;
+       g_variant_get(parameters, "(ii)", &event_info.remove_user.session_uid, &event_info.remove_user.user);
 
-       g_variant_unref(signal_data->params);
-       remove_user_wait_cb(-EFAULT, -EFAULT,  signal_data->client_callback_data);
-       //g_dbus_connection_signal_unsubscribe(connection, signal_data->signal_subscribed);
+       subsession_event_callback event_callback = signal_data->client_callback;
+       event_callback(event_info, signal_data->client_callback_data);
        return;
 }
 
@@ -387,85 +417,34 @@ static void signal_unsubscribed_callback(void *data) {
        free(signal_data);
 }
 
-int method_call(gchar *method, GVariant *params, gchar *signal_name, GDBusSignalCallback signal_callback, void *client_callback, void *client_callback_data) {
-
-       GError *error;
-       error = NULL;
-
-       if (session_connection_data.connection == NULL) {
-               session_connection_data.connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
-               g_assert_no_error(error);
-               g_assert(session_connection_data.connection != NULL);
-       }
-
-       if(client_callback == NULL || client_callback_data == NULL ) {
-               return -EINVAL;
-       }
-
-       signal_client_data_t *signal_client_data = make_new_signal_callback_client_data(client_callback, client_callback_data, params);
-
-       if(signal_client_data == NULL) {
-               return -ENOMEM;
-       }
-
-               signal_client_data->signal_subscribed = g_dbus_connection_signal_subscribe( session_connection_data.connection,
-               session_connection_data.bus_name ,
-               session_connection_data.interface,
-               signal_name,
-               session_connection_data.objpath,
-               NULL,
-               G_DBUS_SIGNAL_FLAGS_NONE,
-               signal_callback,
-               signal_client_data,
-               signal_unsubscribed_callback
-               );
-
-       g_print("signal name: %s : signal_subscribed %d\n", signal_name, signal_client_data->signal_subscribed );
-
-       GVariant *retgv = NULL;
-       GError *call_sync_error;
-       call_sync_error = NULL;
-
-       retgv = g_dbus_connection_call_sync(
-               session_connection_data.connection,
-               session_connection_data.bus_name,
-               session_connection_data.objpath,
-               session_connection_data.interface,
-               method, params,
-               NULL,
-               G_DBUS_CALL_FLAGS_NONE,
-               10,
-        NULL,
-        &call_sync_error
-       );
+#define subscribe_cfg_(_signal_name)           \
+                       session_connection_data.connection,\
+                       session_connection_data.bus_name , \
+                       session_connection_data.interface, \
+                       _signal_name, \
+                       session_connection_data.objpath
 
-       if (!retgv || call_sync_error) {
-               g_error_free(call_sync_error);
-               return -EFAULT;
-       }
-       return 0;
-}
+//deprecated
 
-int method_call_MS(gchar *method, GVariant *params, gchar *signal_name, guint *signal_subscribed_id, GDBusSignalCallback signal_callback) {
+int subscribe_and_call_method(gchar *method, GVariant *params, gchar *signal_name, guint *signal_subscribed_id, GDBusSignalCallback signal_callback, gpointer client_callbacks) {
        GError *error;
        error = NULL;
 
        if (session_connection_data.connection == NULL) {
                session_connection_data.connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
-               g_assert_no_error(error);
-               g_assert(session_connection_data.connection != NULL);
+               if(error != NULL) {
+                       g_error_free(error);
+                       return -ENOTCONN;
+               }
        }
 
        if( *signal_subscribed_id == 0 ) {
-                       *signal_subscribed_id = g_dbus_connection_signal_subscribe( session_connection_data.connection,
-                       session_connection_data.bus_name ,
-                       session_connection_data.interface,
-                       signal_name,
-                       session_connection_data.objpath,
+                       *signal_subscribed_id = g_dbus_connection_signal_subscribe(
+                       subscribe_cfg_(signal_name),
                        NULL,
                        G_DBUS_SIGNAL_FLAGS_NONE,
                        signal_callback,
-                       NULL,
+                       client_callbacks,
                        signal_unsubscribed_callback );
        }
 
@@ -474,22 +453,22 @@ int method_call_MS(gchar *method, GVariant *params, gchar *signal_name, guint *s
        call_sync_error = NULL;
 
        retgv = g_dbus_connection_call_sync(
-               session_connection_data.connection,
-               session_connection_data.bus_name,
-               session_connection_data.objpath,
-               session_connection_data.interface,
+               conn_config_,
                method, params,
                NULL,
                G_DBUS_CALL_FLAGS_NONE,
-               10,
-        NULL,
-        &call_sync_error
+               libsessiond_default_timeout,
+               NULL,
+               &call_sync_error
        );
 
        if (!retgv || call_sync_error) {
                g_error_free(call_sync_error);
+
                return -EFAULT;
        }
+       g_variant_unref(retgv);
+
        return 0;
 }
 
@@ -500,8 +479,9 @@ int method_call_no_signal(gchar *method, GVariant *params) {
 
        if (session_connection_data.connection == NULL) {
                session_connection_data.connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
-               g_assert_no_error(error);
-               g_assert(session_connection_data.connection != NULL);
+               if(error != NULL) {
+                       return -ENOTCONN;
+               }
        }
 
        GVariant *retgv = NULL;
@@ -509,175 +489,245 @@ int method_call_no_signal(gchar *method, GVariant *params) {
        call_sync_error = NULL;
 
        retgv = g_dbus_connection_call_sync(
-               session_connection_data.connection,
-               session_connection_data.bus_name,
-               session_connection_data.objpath,
-               session_connection_data.interface,
+               conn_config_,
                method, params,
                NULL,
                G_DBUS_CALL_FLAGS_NONE,
-               10,
-        NULL,
-        &call_sync_error
+               libsessiond_default_timeout,
+               NULL,
+               &call_sync_error
        );
 
        if (!retgv || call_sync_error) {
                g_error_free(call_sync_error);
                return -EFAULT;
        }
+       g_variant_unref(retgv);
        return 0;
 }
 
-EXPORT_API int subsession_add_user(int session_uid, int user, subsession_reply_callback cb, void *cb_data) {
+void client_data_cleansweep_mt( signal_client_data_t *signal_client_data, client_callbacks_data_t *callbacks_data) {
+
+       g_mutex_lock(&callbacks_data->mutex);
+               callbacks_data->list =  g_list_remove(callbacks_data->list, (gconstpointer) signal_client_data);
+       g_mutex_unlock(&callbacks_data->mutex);
+
+       g_variant_unref(signal_client_data->params);
+       free(signal_client_data);
+}
 
-       g_mutex_lock (&add_user_mutex);
+void init_callbacks_list(client_callbacks_data_t *callbacks_data, GVariant *params) {
 
-       if(add_user_callbacks_list == NULL ) {
-               GVariant * empty_params;
-               empty_params = g_variant_new("(ii)", -1, -1);
-               signal_client_data_t *signal_client_empty_data =  make_new_signal_callback_client_data(NULL, NULL, empty_params);
-               add_user_callbacks_list = g_list_append(add_user_callbacks_list, (gpointer) signal_client_empty_data);
+       if(callbacks_data->list == NULL) {
+               signal_client_data_t *signal_client_empty_data = make_new_signal_callback_client_data(NULL, NULL, params);
+               callbacks_data->list = g_list_append(callbacks_data->list, (gpointer) signal_client_empty_data);
        }
+}
+
+#define callbacks_data_append_to_list(callback_data, data) \
+       callback_data.list = g_list_append(callback_data.list, data)
+
+
+EXPORT_API int subsession_add_user(int session_uid, int user, subsession_reply_callback cb, void *cb_data) {
+
+       g_mutex_lock (&add_user_callbacks_data_mt.mutex);
+
+       init_callbacks_list(&add_user_callbacks_data_mt,  g_variant_new("(ii)", -1, -1));
 
        GVariant * params;
        params = g_variant_new("(ii)", session_uid, user);
 
        signal_client_data_t *signal_client_data = make_new_signal_callback_client_data(cb, cb_data, params);
-       add_user_callbacks_list = g_list_append(add_user_callbacks_list, (gpointer) signal_client_data);
+       callbacks_data_append_to_list(add_user_callbacks_data_mt, signal_client_data);
 
-       g_mutex_unlock(&add_user_mutex);
+       g_mutex_unlock(&add_user_callbacks_data_mt.mutex);
 
-       return  method_call_MS (
+       int method_call_result = subscribe_and_call_method(
                dbus_method_call.AddUser, params,
                dbus_signal_name.AddUserCompleted,
                &dbus_signal_subscribed.AddUserCompleted,
-               signal_add_user_complete_handler);
+               signal_add_user_complete_handler,
+               (gpointer) &add_user_callbacks_data_mt);
+
+       if (method_call_result == 0) { return 0; }
+
+       cb(method_call_result, cb_data);
+       client_data_cleansweep_mt(signal_client_data, &add_user_callbacks_data_mt);
+
+       return method_call_result;
 }
 
 EXPORT_API int subsession_remove_user(int session_uid, int user, subsession_reply_callback cb, void *cb_data) {
 
-       g_mutex_lock (&remove_user_mutex);
+       g_mutex_lock (&remove_user_callbacks_data_mt.mutex);
 
-       if(add_user_callbacks_list == NULL ) {
-               GVariant * empty_params;
-               empty_params = g_variant_new("(ii)", -1, -1);
-               signal_client_data_t *signal_client_empty_data =  make_new_signal_callback_client_data(NULL, NULL, empty_params);
-               remove_user_callbacks_list = g_list_append(remove_user_callbacks_list, (gpointer) signal_client_empty_data);
-       }
+       init_callbacks_list(&remove_user_callbacks_data_mt, g_variant_new("(ii)", -1, -1));
 
        GVariant * params;
        params = g_variant_new("(ii)", session_uid, user);
 
        signal_client_data_t *signal_client_data = make_new_signal_callback_client_data(cb, cb_data, params);
-       remove_user_callbacks_list = g_list_append(remove_user_callbacks_list, (gpointer) signal_client_data);
+       callbacks_data_append_to_list(remove_user_callbacks_data_mt, signal_client_data);
 
-       g_mutex_unlock(&remove_user_mutex);
+       g_mutex_unlock(&remove_user_callbacks_data_mt.mutex);
 
-       return  method_call_MS (
+       int method_call_result = subscribe_and_call_method(
                dbus_method_call.RemoveUser, params,
                dbus_signal_name.RemoveUserCompleted,
                &dbus_signal_subscribed.RemoveUserCompleted,
-               signal_remove_user_complete_handler);
+               signal_remove_user_complete_handler,
+               (gpointer) &remove_user_callbacks_data_mt);
+
+       if (method_call_result == 0) {
+               return 0;
+       }
+
+       cb(method_call_result, cb_data);
+       client_data_cleansweep_mt(signal_client_data, &remove_user_callbacks_data_mt);
 
+       return method_call_result;
 }
 
 EXPORT_API int subsession_switch_user(int session_uid, int prev_user, int next_user, subsession_reply_callback cb, void *cb_data) {
 
+       g_mutex_lock (&switch_user_callbacks_data_mt.mutex);
 
-       g_mutex_lock (&switch_user_mutex);
-
-       if(add_user_callbacks_list == NULL ) {
-               GVariant * empty_params;
-               empty_params = g_variant_new("(iii)", -1, -1, -1);
-               signal_client_data_t *signal_client_empty_data =  make_new_signal_callback_client_data(NULL, NULL, empty_params);
-               switch_user_callbacks_list = g_list_append(switch_user_callbacks_list, (gpointer) signal_client_empty_data);
-       }
+       init_callbacks_list(&switch_user_callbacks_data_mt,  g_variant_new("(iii)", -1, -1, -1));
 
        GVariant * params;
        params = g_variant_new("(iii)", session_uid, prev_user, next_user);
 
        signal_client_data_t *signal_client_data = make_new_signal_callback_client_data(cb, cb_data, params);
-       switch_user_callbacks_list = g_list_append(switch_user_callbacks_list, (gpointer) signal_client_data);
-
-       g_mutex_unlock(&switch_user_mutex);
+       callbacks_data_append_to_list(switch_user_callbacks_data_mt, signal_client_data);
 
+       g_mutex_unlock(&switch_user_callbacks_data_mt.mutex);
 
-       return  method_call_MS (
+       int method_call_result = subscribe_and_call_method (
                dbus_method_call.SwitchUser, params,
                dbus_signal_name.SwitchUserCompleted,
                &dbus_signal_subscribed.SwitchUserCompleted,
-               signal_switch_user_complete_handler);
-       return 0;
+               signal_switch_user_complete_handler,
+               NULL);
+
+       if (method_call_result == 0) { return 0; }
+
+       cb(method_call_result, cb_data);
+       client_data_cleansweep_mt(signal_client_data, &switch_user_callbacks_data_mt);
+
+       return method_call_result;
 }
 
-//Amd →(REGISTER WAIT CALLBACK)→ Sessiond
-//Amd ←(SIGNAL BROADCAST)← Sessiond
-//Amd →(WAIT DONE)→ Sessiond
+#define cb_data_ cb, cb_data
 
-EXPORT_API int subsession_add_user_wait(int session_uid, subsession_add_user_wait_callback cb, void *cb_data) {
+typedef struct {
+       signal_client_data_t *signal_client_data;
+       int is_registered;
+} registered_signal_t;
 
+registered_signal_t subsession_register_event_in_list(client_callbacks_data_t *callbacks_data, GVariant *init_params, GVariant *params, subsession_event_callback cb, void *cb_data) {
 
-       GVariant * params;
-       params = g_variant_new("(i)", session_uid);
-       return  method_call (
-               dbus_method_call.AddUserWait, params,
-               dbus_signal_name.AddUserStarted,
-               signal_add_user_started_callback,
-               (void*)cb, cb_data);
+       g_mutex_lock(&callbacks_data->mutex);
 
-       return TIZEN_ERROR_ACCOUNT;
-}
+       init_callbacks_list(callbacks_data, init_params);
+       signal_client_data_t *signal_client_data = NULL;
+       registered_signal_t registered_signal;
 
-EXPORT_API int subsession_add_user_wait_done(int session_uid, int user) {
+       GList *found_data = g_list_find_custom( callbacks_data->list , (gconstpointer) params, g_compare_session_uid_params );
 
-       GVariant * params;
-       params = g_variant_new("(ii)", session_uid, user);
+       if(found_data == NULL) {
+               registered_signal.is_registered = 0;
+               signal_client_data = make_new_signal_callback_client_data(cb, cb_data, params);
+               callbacks_data->list = g_list_append(callbacks_data->list, signal_client_data);
+       } else {
+               //This will change callback function and data.
+               registered_signal.is_registered = 1;
+               signal_client_data = (signal_client_data_t*)found_data->data;
+               signal_client_data->client_callback = cb;
 
-       return method_call_no_signal(dbus_method_call.AddUserDone, params);
+               signal_client_data_t *data_to_remove = signal_client_data->client_callback_data;
+               free(data_to_remove);
 
-       return TIZEN_ERROR_ACCOUNT;
+               signal_client_data->client_callback_data = cb_data;
+       }
+       registered_signal.signal_client_data = signal_client_data;
+
+       g_mutex_unlock(&callbacks_data->mutex);
+       return registered_signal;
 }
 
-EXPORT_API int subsession_remove_user_wait(int session_uid, subsession_remove_user_wait_callback cb, void *cb_data) {
+#define default_wait_params_  g_variant_new("i", -1), params
 
-       GVariant * params;
-       params = g_variant_new("(i)", session_uid);
-       return  method_call (
-               dbus_method_call.RemoveUserWait, params,
-               dbus_signal_name.RemoveUserStarted,
-               signal_remove_user_started_callback,
-               (void*)cb, cb_data);
+#define dbus_data_(callbacks_data_mt, params) \
+       callbacks_data_mt.dbus_method_call, \
+       params, \
+       callbacks_data_mt.dbus_signal, \
+       &callbacks_data_mt.dbus_signal_subscribed
 
-       return TIZEN_ERROR_ACCOUNT;
-}
 
-EXPORT_API int subsession_remove_user_wait_done(int session_uid, int user) {
+int register_event_callback(client_callbacks_data_t *callbacks_data, GDBusSignalCallback signal_callback, int session_uid, subsession_event_type_e event_bits, subsession_event_callback cb, void * cb_data) {
 
-       GVariant * params;
-       params = g_variant_new("(ii)", session_uid, user);
+       GVariant * params = g_variant_new("(i)", session_uid);
 
-       return method_call_no_signal(dbus_method_call.RemoveUserDone, params);
+       registered_signal_t registered_signal = subsession_register_event_in_list(callbacks_data, default_wait_params_, cb_data_ );
 
-       return TIZEN_ERROR_ACCOUNT;
+       if(registered_signal.is_registered) {
+               return 0;
+       }
+
+       int method_call_result = subscribe_and_call_method(
+                               dbus_data_(add_user_wait_callbacks_data_mt, params),
+                               signal_callback,
+                               (gpointer) &add_user_wait_callbacks_data_mt);
+
+       if (method_call_result == 0) { return 0;}
+
+       subsession_event_info event_info;
+       event_info.add_user.user = -1;
+       cb(event_info, cb_data);
+       client_data_cleansweep_mt(registered_signal.signal_client_data, callbacks_data);
+
+       return method_call_result;
 }
 
-EXPORT_API int subsession_switch_wait(int session_uid, subsession_switch_wait_callback cb, void *cb_data) {
+EXPORT_API int subsession_register_event_callback(int session_uid, subsession_event_type_e event_bits, subsession_event_callback cb, void *cb_data) {
 
-       return TIZEN_ERROR_ACCOUNT;
+       switch (event_bits) {
+               case SUBSESSION_ADD_USER_WAIT:
+                       return register_event_callback(&add_user_wait_callbacks_data_mt, signal_add_user_started_handler, session_uid, event_bits, cb, cb_data);
+               break;
+               case SUBSESSION_REMOVE_USER_WAIT:
+                       return register_event_callback(&remove_user_wait_callbacks_data_mt, signal_remove_user_started_handler, session_uid, event_bits, cb, cb_data);
+               break;
+
+               break;
+
+       }
+       return 0;
 }
 
-EXPORT_API int subsession_switch_wait_done(int session_uid, uint64_t switch_id) {
+EXPORT_API int subsession_add_user_wait_done(int session_uid, int user) {
 
-       return TIZEN_ERROR_ACCOUNT;
+       GVariant * params;
+       params = g_variant_new("(ii)", session_uid, user);
+
+       return method_call_no_signal(dbus_method_call.AddUserDone, params);
 }
 
 
-EXPORT_API int subsession_switch_completion(int session_uid, subsession_switch_completion_callback cb, void *cb_data) {
+EXPORT_API int subsession_remove_user_wait_done(int session_uid, int user) {
+
+       GVariant * params;
+       params = g_variant_new("(ii)", session_uid, user);
+
+       return method_call_no_signal(dbus_method_call.RemoveUserDone, params);
+}
 
+EXPORT_API int subsession_switch_wait_done(int session_uid, uint64_t switch_id) {
 
        return TIZEN_ERROR_ACCOUNT;
 }
 
+
 EXPORT_API int subsession_get_user_list(int session_uid, int **user_list, int *user_count) {
 
        return TIZEN_ERROR_ACCOUNT;
index 5194f603d8241e26ca99d1b1bc69bf57a485c66c..9dad0f8e3e92e5eef4d57d99dc1ea1c2975d8993 100644 (file)
@@ -15,5 +15,5 @@ add_libsd_target_test(api_adduser  "")
 add_libsd_target_test(api_removeuser  "")
 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_adduserwait  "")
+#add_libsd_target_test(api_add_remove_user_wait  "")
index 6483a49a85a2fa6de62a32557c3aebdfbf1b0982..0f3d3f35dd1acc47e07ae2e189ea4ce94f0a0d3c 100644 (file)
@@ -78,11 +78,11 @@ TEST(subsession_add_remove_user_test, APIAddRemoveUserTest) {
 
        test_user_data test_add_ud;
        test_add_ud.callback_result = -1;
-       int add_user_res = subsession_add_user(1, 2, test_reply_adduser_callback, (void *)&test_add_ud);
+       int add_user_res = subsession_add_user(5001, 2, test_reply_adduser_callback, (void *)&test_add_ud);
 
        test_user_data test_remove_ud;
        test_remove_ud.callback_result = -1;
-       int remove_user_res = subsession_remove_user(1, 2, test_reply_removeuser_callback, (void *)&test_remove_ud);
+       int remove_user_res = subsession_remove_user(5001, 2, test_reply_removeuser_callback, (void *)&test_remove_ud);
 
        ud_ctrl ud;
        ud.loop = loop;
index 33830708fc33d957efb0f1ce7251e257697287c5..af080e71fecf8cf06c424fb242dda33b20fe3e78 100644 (file)
@@ -164,14 +164,14 @@ TEST(subsession_add_remove_user_wait_test, APIAddRemoveUserWaitTest) {
        g_atomic_int_set(&callback_removeuserstarted_reference, 0);
 
        test_user_data test_add_wait_1_2;
-       test_add_wait_1_2.session_id = 1;
+       test_add_wait_1_2.session_id = 5001;
        test_add_wait_1_2.user_id = -3;
        test_add_wait_1_2.callback_result = -1;
        int add_user_wait_res_1_2 = subsession_add_user_wait(test_add_wait_1_2.session_id,
                 test_subsession_add_user_wait_callback, (void *)&test_add_wait_1_2);
 
        test_user_data test_add_1_2;
-       test_add_1_2.session_id = 1;
+       test_add_1_2.session_id = 5001;
        test_add_1_2.user_id = 2;
        test_add_1_2.callback_result = -1;
        int add_user_res_1_2 = subsession_add_user(test_add_1_2.session_id, test_add_1_2.user_id,
@@ -179,14 +179,14 @@ TEST(subsession_add_remove_user_wait_test, APIAddRemoveUserWaitTest) {
 
 
        test_user_data test_remove_wait_1_2;
-       test_remove_wait_1_2.session_id = 1;
+       test_remove_wait_1_2.session_id = 5001;
        test_remove_wait_1_2.user_id = -3;
        test_remove_wait_1_2.callback_result = -1;
        int remove_user_wait_res_1_2 = subsession_remove_user_wait(test_add_wait_1_2.session_id,
                 test_subsession_remove_user_wait_callback, (void *)&test_remove_wait_1_2);
 
        test_user_data test_remove_1_2;
-       test_remove_1_2.session_id = 1;
+       test_remove_1_2.session_id = 5001;
        test_remove_1_2.user_id = 2;
        test_remove_1_2.callback_result = -1;
        int remove_user_res_1_2 = subsession_remove_user(test_remove_1_2.session_id, test_remove_1_2.user_id,
index d01cb84d5eec37bff43233d1dd8f724d30184fe4..89719121541858f8f8e800a03f5b616fc89040da 100644 (file)
@@ -61,7 +61,7 @@ TEST(subsession_add_user_test, APIAddUserTest) {
        test_user_data test_ud;
        test_ud.callback_result = -1;
 
-       int add_user_res = subsession_add_user(1, 2, test_subsession_reply_callback, (void *)&test_ud);
+       int add_user_res = subsession_add_user(5001, 2, test_subsession_reply_callback, (void *)&test_ud);
 
        ud_ctrl ud;
        ud.loop = loop;
index c8dbec244746b9e6a57b08acd6d5ed0bd03bacb4..b5f57b255fac7c0b63bb4ad859bd320e91be8301 100644 (file)
@@ -128,21 +128,21 @@ TEST(subsession_add_user_wait_test, APIAddUserWaitTest) {
        g_atomic_int_set(&callback_removeuser_reference, 0);
 
        test_user_data test_add_wait_1_2;
-       test_add_wait_1_2.session_id = 1;
+       test_add_wait_1_2.session_id = 5001;
        test_add_wait_1_2.user_id = -3;
        test_add_wait_1_2.callback_result = -1;
        int add_user_wait_res_1_2 = subsession_add_user_wait(test_add_wait_1_2.session_id,
                 test_subsession_add_user_wait_callback, (void *)&test_add_wait_1_2);
 
        test_user_data test_add_1_2;
-       test_add_1_2.session_id = 1;
+       test_add_1_2.session_id = 5001;
        test_add_1_2.user_id = 2;
        test_add_1_2.callback_result = -1;
        int add_user_res_1_2 = subsession_add_user(test_add_1_2.session_id, test_add_1_2.user_id,
                 test_reply_adduser_callback, (void *)&test_add_1_2);
 
        test_user_data test_remove_1_2;
-       test_remove_1_2.session_id = 1;
+       test_remove_1_2.session_id = 5001;
        test_remove_1_2.user_id = 2;
        test_remove_1_2.callback_result = -1;
        int remove_user_res_1_2 = subsession_remove_user(test_remove_1_2.session_id, test_remove_1_2.user_id,
index f765a029292fa490a41f05f934a5b93ead900224..71dd00b84eba5042b3949a85b3b67c2a99064f9f 100644 (file)
@@ -61,7 +61,7 @@ TEST(subsession_remove_user_test, APIRemoveUserTest) {
        test_user_data test_ud;
        test_ud.callback_result = -1;
 
-       int add_user_res = subsession_remove_user(1, 2, test_subsession_reply_callback, (void *)&test_ud);
+       int add_user_res = subsession_remove_user(5001, 2, test_subsession_reply_callback, (void *)&test_ud);
 
        ud_ctrl ud;
        ud.loop = loop;
index 47220301c74cab293449e46d9899b2f3bd1122ce..501b12f821628c88f4f193f7e34b86e99824d62d 100644 (file)
@@ -38,7 +38,6 @@ gboolean callback_pending(gpointer data) {
        gint callback_removeuser_calls = g_atomic_int_get(&callback_removeuser_reference);
        gint callback_switchuser_calls = g_atomic_int_get(&callback_switchuser_reference);
 
-
        if(is_pending == TRUE) {
                return TRUE;
        }
@@ -117,19 +116,20 @@ TEST(subsession_switch_user_test, APISwitchUserTest) {
        g_atomic_int_set(&callback_removeuser_reference, 0);
 
        test_user_data test_add_1_1;
-       test_add_1_1.session_id = 1;
+       test_add_1_1.session_id = 5001;
        test_add_1_1.user_id = 1;
        test_add_1_1.callback_result = -1;
        int add_user_res_1_1 = subsession_add_user(test_add_1_1.session_id, test_add_1_1.user_id, test_reply_adduser_callback, (void *)&test_add_1_1);
 
        test_user_data test_add_1_2;
-       test_add_1_2.session_id = 1;
+       test_add_1_2.session_id = 5001;
        test_add_1_2.user_id = 2;
        test_add_1_2.callback_result = -1;
        int add_user_res_1_2 = subsession_add_user(test_add_1_2.session_id, test_add_1_2.user_id, test_reply_adduser_callback, (void *)&test_add_1_2);
 
+
        test_user_data_switch test_switch_1_1_to_2;
-       test_switch_1_1_to_2.session_id = 1;
+       test_switch_1_1_to_2.session_id = 5001;
        test_switch_1_1_to_2.prev_user_id = 1;
        test_switch_1_1_to_2.next_user_id = 2;
        test_switch_1_1_to_2.callback_result = -1;
@@ -140,13 +140,13 @@ TEST(subsession_switch_user_test, APISwitchUserTest) {
                test_reply_switchuser_callback, (void *)&test_switch_1_1_to_2);
 
        test_user_data test_remove_1_1;
-       test_remove_1_1.session_id = 1;
+       test_remove_1_1.session_id = 5001;
        test_remove_1_1.user_id = 1;
        test_remove_1_1.callback_result = -1;
        int remove_user_res_1_1 = subsession_remove_user(test_remove_1_1.session_id, test_remove_1_1.user_id, test_reply_removeuser_callback, (void *)&test_remove_1_1);
 
        test_user_data test_remove_1_2;
-       test_remove_1_2.session_id = 1;
+       test_remove_1_2.session_id = 5001;
        test_remove_1_2.user_id = 2;
        test_remove_1_2.callback_result = -1;
        int remove_user_res_1_2 = subsession_remove_user(test_remove_1_2.session_id, test_remove_1_2.user_id, test_reply_removeuser_callback, (void *)&test_remove_1_2);
index 8881df9761ae89e162faa8b87e2a66f6375849d2..e51f6002f980f4de3251834326e1e32964cf080f 100644 (file)
@@ -11,6 +11,7 @@ BuildRequires: pkgconfig(capi-base-common)
 BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: gtest-devel
 BuildRequires: pkgconfig(libsmack)
+BuildRequires: pkgconfig(dlog)
 %description
 
 %package -n libsessiond