/**
* @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.
*/
* @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);
* @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.
* @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).
*/
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]);
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)", ¶ms_session_uid, ¶ms_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(
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(
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,
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