subsession_{add,remove,switch}_user: make async 05/276205/3
authorMichal Bloch <m.bloch@samsung.com>
Mon, 13 Jun 2022 03:31:14 +0000 (05:31 +0200)
committerArkadiusz Nowak <a.nowak3@samsung.com>
Mon, 13 Jun 2022 11:47:30 +0000 (13:47 +0200)
Also they now accept null callbacks.

Change-Id: I9a87f6bae74395d0bc374ca95c6ac2cd35c11e3c
Signed-off-by: Michal Bloch <m.bloch@samsung.com>
libsessiond/include/sessiond.h
libsessiond/src/lib.c

index 3db106a..d7d6941 100644 (file)
@@ -124,7 +124,12 @@ int subsession_unregister_event_callback(int session_uid, subsession_event_type_
 /**
  * @brief Callback fired when requested operation completes.
  * @since_tizen 7.0
- * @param[in] result Status code
+ * @param[in] result Status code, can be: \n
+ *  #SUBSESSION_ERROR_NONE Success \n
+ *  #SUBSESSION_ERROR_NOT_AVAILABLE Subsession does not exist \n
+ *  #SUBSESSION_ERROR_IO_ERROR Internal error occurred \n
+ *  #SUBSESSION_ERROR_PERMISSION_DENIED Not permitted \n
+ *  #SUBSESSION_ERROR_NOT_SUPPORTED Not supported
  * @param[in] cb_data The user data passed from the callback registration function
  * @remarks Callback will be called only when operation succeeds.
  */
@@ -142,10 +147,7 @@ typedef void (*subsession_reply_callback) (int result, void *cb_data);
  * @return 0 on success, otherwise a negative error value
  * @retval #SUBSESSION_ERROR_NONE Success
  * @retval #SUBSESSION_ERROR_INVALID_PARAMETER Provided parameter is invalid
- * @retval #SUBSESSION_ERROR_ALREADY_EXISTS Subsession already exists
- * @retval #SUBSESSION_ERROR_IO_ERROR Internal error occurred
- * @retval #SUBSESSION_ERROR_PERMISSION_DENIED Not permitted
- * @retval #SUBSESSION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #SUBSESSION_ERROR_OUT_OF_MEMORY Out of memory
  * @remarks Use `subsession_get_user_list()` to list currently used session IDs.
  */
 int subsession_add_user(int session_uid, int user, subsession_reply_callback cb, void *cb_data);
@@ -162,10 +164,7 @@ int subsession_add_user(int session_uid, int user, subsession_reply_callback cb,
  * @return 0 on success, otherwise a negative error value
  * @retval #SUBSESSION_ERROR_NONE Success
  * @retval #SUBSESSION_ERROR_INVALID_PARAMETER Provided parameter is invalid
- * @retval #SUBSESSION_ERROR_NOT_AVAILABLE Subsession does not exist
- * @retval #SUBSESSION_ERROR_IO_ERROR Internal error occurred
- * @retval #SUBSESSION_ERROR_PERMISSION_DENIED Not permitted
- * @retval #SUBSESSION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #SUBSESSION_ERROR_OUT_OF_MEMORY Out of memory
  * @remarks Only inactive session ID can be removed. \n
  * In order remove currently used session ID first switch to special session ID 0, and \n
  * only after switch completes remove previously active session ID.
@@ -184,10 +183,7 @@ int subsession_remove_user(int session_uid, int user, subsession_reply_callback
  * @return 0 on success, otherwise a negative error value
  * @retval #SUBSESSION_ERROR_NONE Success
  * @retval #SUBSESSION_ERROR_INVALID_PARAMETER Provided parameter is invalid
- * @retval #SUBSESSION_ERROR_NOT_AVAILABLE Subsession does not exist
- * @retval #SUBSESSION_ERROR_IO_ERROR Internal error occurred
- * @retval #SUBSESSION_ERROR_PERMISSION_DENIED Not permitted
- * @retval #SUBSESSION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #SUBSESSION_ERROR_OUT_OF_MEMORY Out of memory
  * @remarks Special subsession ID 0 can be switched to, when it's required to deactivate current subsession \n
  * (this step is needed when current session is to be removed).
  */
index fe28b00..e422068 100644 (file)
@@ -153,6 +153,11 @@ typedef struct {
        int signal_subscribed;
 } signal_client_data_t;
 
+typedef struct {
+       subsession_reply_callback reply_callback;
+       void *reply_data;
+} reply_client_data_t;
+
 static int get_dbus_error_mapping_to_subsession_error(const char *dbus_error)
 {
        size_t arr_size = sizeof(error_mappings) / sizeof(error_mappings[0]);
@@ -227,40 +232,6 @@ static signal_client_data_t *make_new_signal_callback_client_data(void *client_c
        return NULL;
 }
 
-
-static gint g_compare_user_params (  gconstpointer client_data,   gconstpointer parameters) {
-
-       signal_client_data_t *signal_client_data = (signal_client_data_t*)client_data;
-
-       maybe_not_comparable_if(
-               client_data_are_null(client_data)
-       )
-
-       int client_session_uid = 0;
-       int client_user = 0;
-       maybe_g_variant_get_int_(signal_client_data->params, "(ii)", &client_session_uid, &client_user);
-       maybe_not_comparable_if(
-               session_uid_is_not_valid(client_session_uid,
-               user_id_is_not_valid(client_user))
-       )
-
-       GVariant *params = (GVariant *)parameters;
-
-       int params_session_uid = 0;
-       int params_user = 0;
-       maybe_g_variant_get_int_(params, "(ii)", &params_session_uid, &params_user);
-       maybe_not_comparable_if(
-               session_uid_is_not_valid(client_session_uid,
-               user_id_is_not_valid(client_user))
-       )
-
-       if( client_session_uid == params_session_uid &&
-               client_user == params_user) {
-               return COMPARATOR_RESULT_SAME_;
-       }
-       return COMPARATOR_RESULT_DIFFERENT_;
-}
-
 static gint g_compare_session_uid_params (  gconstpointer client_data,   gconstpointer parameters) {
 
        maybe_not_comparable_if(
@@ -410,41 +381,6 @@ static void call_reply_callback(signal_client_data_t *signal_data, int ret_statu
        reply_cb(ret_status, client_callback_data);
 }
 
-static void signal_user_ops_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) {
-
-       if(client_data == NULL || parameters == NULL ) {
-               return ;
-       }
-
-       client_callbacks_data_t *client_callbacks_data = (client_callbacks_data_t *)client_data;
-
-       if(client_callbacks_data == NULL)  {
-               return;
-       }
-
-       signal_client_data_t *signal_data = take_from_callbacks_data_and_remove_from_list(client_callbacks_data, parameters, g_compare_user_params);
-
-       if(signal_data == NULL || signal_data->client_callback == NULL) {
-               return ;
-       }
-
-       call_reply_callback(signal_data, cb_result_ok);
-
-       g_variant_unref(signal_data->params);
-       free(signal_data);
-}
-
-
-#define signal_add_user_complete_handler signal_user_ops_complete_handler
-#define signal_remove_user_complete_handler signal_user_ops_complete_handler
-
 static gint g_compare_switch_user_params (  gconstpointer client_data,   gconstpointer parameters) {
 
        maybe_not_comparable_if(
@@ -487,38 +423,6 @@ static gint g_compare_switch_user_params (  gconstpointer client_data,   gconstp
        return COMPARATOR_RESULT_DIFFERENT_;
 }
 
-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) {
-
-       if(parameters == NULL) {
-               return;
-       }
-
-       client_callbacks_data_t *client_callbacks_data = &switch_user_callbacks_data_mt;
-
-       if(client_callbacks_data->list == NULL) {
-               return;
-       }
-
-       signal_client_data_t *signal_data = take_from_callbacks_data_and_remove_from_list(client_callbacks_data, parameters, g_compare_switch_user_params);
-
-       if(signal_data == NULL || signal_data->client_callback == NULL) {
-               return ;
-       }
-       call_reply_callback(signal_data, cb_result_ok);
-
-       g_variant_unref(signal_data->params);
-       free(signal_data);
-
-       return;
-}
-
 static void signal_add_user_started_handler(GDBusConnection *connection,
        const gchar *sender_name,
        const gchar *object_path,
@@ -807,99 +711,104 @@ static int append_to_callbacks_list(client_callbacks_data_t *callbacks_data_mt,
        return SUBSESSION_ERROR_NONE;
 }
 
-EXPORT_API int subsession_add_user(int session_uid, int user, subsession_reply_callback cb, void *cb_data) {
+static void async_method_reply_handler(GObject *source_obj, GAsyncResult *res, gpointer userdata)
+{
+       g_autofree reply_client_data_t * reply_info = (reply_client_data_t *) userdata;
+       GDBusConnection *const connection = (GDBusConnection *) source_obj;
+
+       g_autoptr(GError) err = NULL;
+       g_autoptr(GVariant) ret = g_dbus_connection_call_finish
+               ( connection
+               , res
+               , &err
+       );
 
-       return_if(
-               session_uid_is_not_valid(session_uid,
-               user_id_is_not_valid(user,
-               callback_is_null(cb,
-               callbacks_data_are_null(cb_data))))
-       )
+       /* The reply contains nothing useful, we only use it
+        * to receive information about the error, really. */
 
-       signal_client_data_t *signal_client_data = make_new_signal_callback_client_data(cb, cb_data,  g_variant_new("(ii)", session_uid, user));
+       reply_info->reply_callback
+               ( err
+                       ? map_dbus_call_error_to_return_value(err)
+                       : SUBSESSION_ERROR_NONE
+               , reply_info->reply_data
+       );
+}
 
-       ret_if_err_( append_to_callbacks_list(&add_user_callbacks_data_mt,
-               g_variant_new("(ii)", -1, -1),
-               signal_client_data,
-               cb, cb_data))
+static int call_method_async(gchar *method, GVariant *params, subsession_reply_callback cb, void *cb_data) {
 
+       if (!params)
+               return SUBSESSION_ERROR_OUT_OF_MEMORY;
 
-       int method_call_result = subscribe_and_call_method(
-               dbus_method_call.AddUser, signal_client_data->params,
-               dbus_signal_name.AddUserCompleted,
-               &dbus_signal_subscribed.AddUserCompleted,
-               signal_add_user_complete_handler,
-               (gpointer) &add_user_callbacks_data_mt);
+       MAKE_SURE_CONNECTION_IS_NOT_NULL();
 
-       if (method_call_result == 0) { return SUBSESSION_ERROR_NONE; }
+       reply_client_data_t *reply_info;
+       if (cb) {
+               reply_info = g_malloc(sizeof *reply_info); // freed in the callback
+               if (!reply_info)
+                       return SUBSESSION_ERROR_OUT_OF_MEMORY;
+               reply_info->reply_callback = cb;
+               reply_info->reply_data = cb_data;
+       }
 
-       client_data_cleansweep_mt(signal_client_data, &add_user_callbacks_data_mt);
+       g_dbus_connection_call
+               ( conn_config_
+               , method
+               , params
+               , NULL
+               , G_DBUS_CALL_FLAGS_NONE
+               , libsessiond_default_timeout
+               , NULL
+               , cb
+                       ? async_method_reply_handler
+                       : NULL
+               , cb
+                       ? reply_info
+                       : NULL
+       );
 
-       return method_call_result;
+       return SUBSESSION_ERROR_NONE;
 }
 
-EXPORT_API int subsession_remove_user(int session_uid, int user, subsession_reply_callback cb, void *cb_data) {
+EXPORT_API int subsession_add_user(int session_uid, int user, subsession_reply_callback cb, void *cb_data) {
 
        return_if(
-               int_not_valid(session_uid,
-               int_not_valid(user,
-               callback_is_null(cb,
-               callbacks_data_are_null(cb_data))))
+               session_uid_is_not_valid(session_uid,
+               user_id_is_not_valid(user))
        )
 
-       signal_client_data_t *signal_client_data = make_new_signal_callback_client_data(cb, cb_data, g_variant_new("(ii)", session_uid, user));
-
-       ret_if_err_( append_to_callbacks_list(&remove_user_callbacks_data_mt,
-               g_variant_new("(ii)", -1, -1),
-               signal_client_data,
-               cb, cb_data))
-
-       int method_call_result = subscribe_and_call_method(
-               dbus_method_call.RemoveUser, signal_client_data->params,
-               dbus_signal_name.RemoveUserCompleted,
-               &dbus_signal_subscribed.RemoveUserCompleted,
-               signal_remove_user_complete_handler,
-               (gpointer) &remove_user_callbacks_data_mt);
+       return call_method_async
+               ( dbus_method_call.AddUser
+               , g_variant_new("(ii)", session_uid, user)
+               , cb, cb_data
+       );
+}
 
-       if (method_call_result == 0) {
-               return SUBSESSION_ERROR_NONE;
-       }
+EXPORT_API int subsession_remove_user(int session_uid, int user, subsession_reply_callback cb, void *cb_data) {
 
-       client_data_cleansweep_mt(signal_client_data, &remove_user_callbacks_data_mt);
+       return_if(
+               int_not_valid(session_uid,
+               int_not_valid(user))
+       )
 
-       return method_call_result;
+       return call_method_async
+               ( dbus_method_call.RemoveUser
+               , g_variant_new("(ii)", session_uid, user)
+               , cb, cb_data
+       );
 }
 
 EXPORT_API int subsession_switch_user(int session_uid, int next_user, subsession_reply_callback cb, void *cb_data) {
 
        return_if(
                int_not_valid_on_switch(session_uid,
-               int_not_valid_on_switch(next_user,
-               callback_is_null(cb,
-               callbacks_data_are_null(cb_data))))
+               int_not_valid_on_switch(next_user))
        )
 
-       signal_client_data_t *signal_client_data = make_new_signal_callback_client_data(cb, cb_data, g_variant_new("(ii)", session_uid, next_user));
-
-       ret_if_err_( append_to_callbacks_list(&switch_user_callbacks_data_mt,
-               g_variant_new("(ii)", -1, -1),
-               signal_client_data,
-               cb, cb_data))
-
-       int method_call_result = subscribe_and_call_method (
-               dbus_method_call.SwitchUser, signal_client_data->params,
-               dbus_signal_name.SwitchUserCompleted,
-               &dbus_signal_subscribed.SwitchUserCompleted,
-               signal_switch_user_complete_handler,
-               NULL);
-
-       if (method_call_result == 0) {
-               return SUBSESSION_ERROR_NONE;
-       }
-
-       client_data_cleansweep_mt(signal_client_data, &switch_user_callbacks_data_mt);
-
-       return method_call_result;
+       return call_method_async
+               ( dbus_method_call.SwitchUser
+               , g_variant_new("(ii)", session_uid, next_user)
+               , cb, cb_data
+       );
 }
 
 #define cb_data_ cb, cb_data