From face85c1f3cb4c44e796541d9afe63aa3a7bb2ed Mon Sep 17 00:00:00 2001 From: Inkyun Kil Date: Fri, 31 Mar 2017 14:07:47 +0900 Subject: [PATCH] Add new apis to watch that remote port is registered and unregistered Change-Id: I1687de44ecbcbed3fd1ae3998eb1f71c3fb8dbc0 Signed-off-by: Inkyun Kil --- include/message-port.h | 98 +++++++++++++++++++++++++++++++ include/message_port.h | 104 +++++++++++++++++++++++++++++++++ src/message-port.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ src/message_port.c | 49 ++++++++++++++++ 4 files changed, 403 insertions(+) diff --git a/include/message-port.h b/include/message-port.h index 1014655..fe748c0 100644 --- a/include/message-port.h +++ b/include/message-port.h @@ -40,6 +40,27 @@ extern "C" { typedef void (*messageport_message_cb)(int id, const char *remote_app_id, const char *remote_port, bool trusted_message, bundle *data, void *user_data); /** + * @brief Called when a remote port is registered or unregistered. + * @details The function is called when a remote port is registered or unregistered + * from the remote application. + * @remarks @a remote_app_id and @a remote_port can be used until + * messageport_remove_registration_event_cb() is called for the watcher which reported the event. + * @param[in] remote_app_id The ID of the remote application that sent this message + * @param[in] remote_port The name of the remote message port + * @param[in] trusted_remote_port Indicates whether remote port is trusted + * @param[in] user_data The user data passed from the register function + * @pre Called when a remote port is registered or unregistered if you add it using + * messageport_add_registered_cb() or messageport_add_unregistered_cb() respectively. + * @see messageport_add_registered_cb() + * @see messageport_add_unregistered_cb() + * @see messageport_remove_registration_event_cb() + */ +typedef void (*messageport_registration_event_cb)(const char *remote_app_id, + const char *remote_port, + bool trusted_remote_port, + void *user_data); + +/** * @brief Unregisters the local message port. @n * * @param [in] local_port_id the id of the local message port @@ -222,6 +243,83 @@ typedef void (*messageport_message_cb)(int id, const char *remote_app_id, const int messageport_send_bidirectional_trusted_message(int id, const char *remote_app_id, const char *remote_port, bundle *data); /** + * @brief Adds a callback called when a remote port is registered. + * @details When remote port is registered, @a registered_cb function is called. + * Each added callback has its own separate watcher. + * @remarks The specified callback is called only in the main thread. + * @param[in] remote_app_id The ID of the remote application + * @param[in] remote_port The name of the remote message port + * @param[in] trusted_remote_port Indicates whether remote port is trusted + * @param[in] registered_cb The callback function to be called + * when remote port is registered + * @param[in] user_data The user data to be passed to the callback function + * @param[out] watcher_id The ID of the watcher which is monitoring the remote port + * registration events + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER The specified @a remote_app_id or @a remote_port + * or @a registered_cb is NULL + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @see messageport_registration_event_cb() + * @see messageport_add_unregistered_cb() + * @see messageport_remove_registration_event_cb() + */ +int messageport_add_registered_cb(const char *remote_app_id, + const char *remote_port, + bool trusted_remote_port, + messageport_registration_event_cb registered_cb, + void *user_data, + int *watcher_id); + +/** + * @brief Adds a callback called when a remote port is unregistered. + * @details When remote port is unregistered, @a unregistered_cb function is called. + * Each added callback has its own separate watcher. + * @remarks The specified callback is called only in the main thread. + * @param[in] remote_app_id The ID of the remote application + * @param[in] remote_port The name of the remote message port + * @param[in] trusted_remote_port Indicates whether remote port is trusted + * @param[in] unregistered_cb The callback function to be called + * when remote port is unregistered + * @param[in] user_data The user data to be passed to the callback function + * @param[out] watcher_id The ID of the watcher which is monitoring the remote port + * unregistration events + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER The specified @a remote_app_id or @a remote_port + * or @a unregistered_cb is NULL + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @see messageport_registration_event_cb() + * @see messageport_add_registered_cb() + * @see messageport_remove_registration_event_cb() + */ +int messageport_add_unregistered_cb(const char *remote_app_id, + const char *remote_port, + bool trusted_remote_port, + messageport_registration_event_cb unregistered_cb, + void *user_data, + int *watcher_id); + + + +/** + * @brief Removes the registration/unregistration callbacks associated with the given watcher. + * @param[in] watcher_id The ID of watcher which is monitoring remote port + * registration/unregistration events + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a watcher_id is not correct + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @see messageport_registration_event_cb() + * @see messageport_add_registered_cb() + * @see messageport_add_unregistered_cb() + */ +int messageport_remove_registration_event_cb(int watcher_id); + + +/** * @} */ diff --git a/include/message_port.h b/include/message_port.h index 133dd11..59c8332 100755 --- a/include/message_port.h +++ b/include/message_port.h @@ -102,6 +102,30 @@ typedef void (*message_port_trusted_message_cb)(int trusted_local_port_id, const /** + * @brief Called when a remote port is registered or unregistered. + * @details The function is called when a remote port is registered or unregistered + * from the remote application. + * @since_tizen 4.0 + * @remarks @a remote_app_id and @a remote_port can be used until + * message_port_remove_registration_event_cb() is called for the watcher which reported + * the event. + * @param[in] remote_app_id The ID of the remote application that sent this message + * @param[in] remote_port The name of the remote message port + * @param[in] trusted_remote_port Indicates whether remote port is trusted + * @param[in] user_data The user data passed from the register function + * @pre Called when a remote port is registered or unregistered if you add it using + * message_port_add_registered_cb() or message_port_add_unregistered_cb() respectively. + * @see message_port_add_registered_cb() + * @see message_port_add_unregistered_cb() + * @see message_port_remove_registration_event_cb() + */ +typedef void (*message_port_registration_event_cb)(const char *remote_app_id, + const char *remote_port, + bool trusted_remote_port, + void *user_data); + + +/** * @brief Registers the local message port. * @details If the message port name is already registered, the previous local message port ID returns and the callback function is changed. \n * Multiple message ports can be registered. @@ -346,6 +370,86 @@ EXPORT_API int message_port_send_trusted_message_with_local_port(const char *rem /** + * @brief Adds a callback called when a remote port is registered. + * @details When remote port is registered, @a registered_cb function is called. + * Each added callback has its own separate watcher. + * @since_tizen 4.0 + * @remarks The specified callback is called only in the main thread. + * @param[in] remote_app_id The ID of the remote application + * @param[in] remote_port The name of the remote message port + * @param[in] trusted_remote_port Indicates whether remote port is trusted + * @param[in] registered_cb The callback function to be called + * when remote port is registered + * @param[in] user_data The user data to be passed to the callback function + * @param[out] watcher_id The ID of the watcher which is monitoring the remote port + * registration events + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER The specified @a remote_app_id or @a remote_port + * or @a registered_cb is NULL + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @see message_port_registration_event_cb() + * @see message_port_add_unregistered_cb() + * @see message_port_remove_registration_event_cb() + */ +EXPORT_API int message_port_add_registered_cb(const char *remote_app_id, + const char *remote_port, + bool trusted_remote_port, + message_port_registration_event_cb registered_cb, + void *user_data, + int *watcher_id); + +/** + * @brief Adds a callback called when a remote port is unregistered. + * @details When the remote port is unregistered, @a unregistered_cb function is called. + * Each added callback has its own separate watcher. + * @remarks The specified callback is called only in the main thread. + * @since_tizen 4.0 + * @param[in] remote_app_id The ID of the remote application + * @param[in] remote_port The name of the remote message port + * @param[in] trusted_remote_port Indicates whether remote port is trusted + * @param[in] unregistered_cb The callback function to be called + * when remote port is unregistered + * @param[in] user_data The user data to be passed to the callback function + * @param[out] watcher_id The ID of the watcher which is monitoring the remote port + * unregistration events + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER The specified @a remote_app_id or @a remote_port + * or @a unregistered_cb is NULL + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @see message_port_registration_event_cb() + * @see message_port_add_registered_cb() + * @see message_port_remove_registration_event_cb() + */ +EXPORT_API int message_port_add_unregistered_cb(const char *remote_app_id, + const char *remote_port, + bool trusted_remote_port, + message_port_registration_event_cb unregistered_cb, + void *user_data, + int *watcher_id); + + +/** + * @brief Removes the registration/unregistration callback associated with the given watcher. + * @since_tizen 4.0 + * @param[in] watcher_id The ID of watcher which is monitoring remote port + * registration/unregistration events + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a watcher_id is not correct + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @see message_port_registration_event_cb() + * @see message_port_add_registered_cb() + * @see message_port_add_unregistered_cb() + */ +EXPORT_API int message_port_remove_registration_event_cb(int watcher_id); + + + +/** * @} */ diff --git a/src/message-port.c b/src/message-port.c index e7b2bfc..6868a5e 100755 --- a/src/message-port.c +++ b/src/message-port.c @@ -86,6 +86,7 @@ static GHashTable *__remote_app_info; static GHashTable *__sender_appid_hash; static GHashTable *__trusted_app_list_hash; static GHashTable *__callback_info_hash; +static GHashTable *__registered_callback_info_hash; static const int MAX_MESSAGE_SIZE = 16 * 1024; enum __certificate_info_type { @@ -136,6 +137,16 @@ typedef struct port_list_info { int g_src_id; } port_list_info_s; +typedef struct registered_callback_info { + char *remote_app_id; + char *remote_port; + bool is_trusted; + int watcher_id; + void *user_data; + messageport_registration_event_cb registered_cb; + messageport_registration_event_cb unregistered_cb; +} registered_callback_info_s; + static void __callback_info_free(gpointer data) { message_port_callback_info_s *callback_info = (message_port_callback_info_s *)data; @@ -181,6 +192,22 @@ static void __callback_info_free_by_info(message_port_callback_info_s *callback_ g_list_free(find_list); } +static void __registered_callback_info_free(gpointer data) +{ + registered_callback_info_s *callback_info = (registered_callback_info_s *)data; + if (callback_info == NULL) + return; + + if (callback_info->remote_app_id) + free(callback_info->remote_app_id); + + if (callback_info->remote_port) + free(callback_info->remote_port); + + free(callback_info); +} + + static void __hash_destroy_callback_info(gpointer data) { @@ -1596,6 +1623,92 @@ int __message_send_bidirectional_message(int id, const char *remote_app_id, cons local_info->port_name, trusted_message, local_info->is_trusted, true, message); } +static void __name_registered(GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + + registered_callback_info_s *info = (registered_callback_info_s *)user_data; + if (info == NULL) { + LOGE("NULL registered_callback_info"); + return; + } + + _LOGI("watcher_id : %d, appeared name : %s , name_owner : %s\n", info->watcher_id, name, name_owner); + if (info->registered_cb) + info->registered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data); +} + +static void __name_unregistered(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + + registered_callback_info_s *info = (registered_callback_info_s *)user_data; + if (info == NULL) { + LOGE("NULL registered_callback_info"); + return; + } + + _LOGI("watcher_id : %d, vanished name : %s\n", info->watcher_id, name); + if (info->unregistered_cb) + info->unregistered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data); +} + +int __messageport_watch_remote_port(int *watcher_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, messageport_registration_event_cb registered_cb, messageport_registration_event_cb unregistered_cb, void *user_data) +{ + int ret_val = MESSAGEPORT_ERROR_NONE; + message_port_remote_app_info_s *remote_app_info = NULL; + port_list_info_s *port_info = NULL; + + _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id); + + ret_val = __get_remote_port_info(remote_app_id, remote_port, trusted_remote_port, &remote_app_info, &port_info); + if (ret_val != MESSAGEPORT_ERROR_NONE) + return ret_val; + + if (__registered_callback_info_hash == NULL) + __registered_callback_info_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __registered_callback_info_free); + + registered_callback_info_s *registered_cb_info = (registered_callback_info_s *)calloc(1, sizeof(registered_callback_info_s)); + registered_cb_info->registered_cb = registered_cb; + registered_cb_info->unregistered_cb = unregistered_cb; + registered_cb_info->user_data = user_data; + registered_cb_info->remote_app_id = strdup(remote_app_info->remote_app_id); + if (registered_cb_info->remote_app_id == NULL) { + free(registered_cb_info); + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + registered_cb_info->remote_port = strdup(port_info->port_name); + if (registered_cb_info->remote_port == NULL) { + free(registered_cb_info->remote_app_id); + free(registered_cb_info); + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + + registered_cb_info->watcher_id = g_bus_watch_name_on_connection( + __gdbus_conn, + port_info->encoded_bus_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + __name_registered, + __name_unregistered, + registered_cb_info, + NULL); + if (registered_cb_info->watcher_id == 0) { + free(registered_cb_info->remote_app_id); + free(registered_cb_info->remote_port); + free(registered_cb_info); + return MESSAGEPORT_ERROR_IO_ERROR; + } + + g_hash_table_insert(__registered_callback_info_hash, + GINT_TO_POINTER(registered_cb_info->watcher_id), registered_cb_info); + + *watcher_id = registered_cb_info->watcher_id; + return MESSAGEPORT_ERROR_NONE; +} + int messageport_unregister_local_port(int local_port_id, bool trusted_port) { @@ -1760,3 +1873,42 @@ int messageport_send_bidirectional_trusted_message(int id, const char *remote_ap return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message); } +int messageport_add_registered_cb(const char *remote_app_id, const char *remote_port, bool is_trusted, messageport_registration_event_cb registered_cb, void *user_data, int *watcher_id) +{ + if (!_initialized) { + if (!__initialize()) + return MESSAGEPORT_ERROR_IO_ERROR; + } + return __messageport_watch_remote_port(watcher_id, remote_app_id, remote_port, is_trusted, registered_cb, NULL, user_data); +} + +int messageport_add_unregistered_cb(const char *remote_app_id, const char *remote_port, bool is_trusted, messageport_registration_event_cb unregistered_cb, void *user_data, int *watcher_id) +{ + if (!_initialized) { + if (!__initialize()) + return MESSAGEPORT_ERROR_IO_ERROR; + } + return __messageport_watch_remote_port(watcher_id, remote_app_id, remote_port, is_trusted, NULL, unregistered_cb, user_data); +} + + +int messageport_remove_registration_event_cb(int watcher_id) +{ + registered_callback_info_s *registered_cb_info = NULL; + gboolean remove_result = FALSE; + + if (watcher_id < 1) + return MESSAGEPORT_ERROR_INVALID_PARAMETER; + + registered_cb_info = g_hash_table_lookup(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id)); + if (registered_cb_info == NULL) + return MESSAGEPORT_ERROR_INVALID_PARAMETER; + + remove_result = g_hash_table_remove(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id)); + if (!remove_result) + return MESSAGEPORT_ERROR_IO_ERROR; + + g_bus_unwatch_name(watcher_id); + + return MESSAGEPORT_ERROR_NONE; +} diff --git a/src/message_port.c b/src/message_port.c index 459bfe5..d6d50f3 100644 --- a/src/message_port.c +++ b/src/message_port.c @@ -284,3 +284,52 @@ int message_port_send_trusted_message_with_local_port(const char *remote_app_id, return convert_to_tizen_error((messageport_error_e)ret); } +int message_port_add_registered_cb(const char *remote_app_id, const char *remote_port, bool is_trusted, message_port_registration_event_cb registered_cb, void *user_data, int *watcher_id) +{ + int ret = MESSAGE_PORT_ERROR_NONE; + + if (watcher_id == NULL || remote_app_id == NULL || remote_port == NULL || + registered_cb == NULL) { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + + ret = messageport_add_registered_cb(remote_app_id, remote_port, is_trusted, registered_cb, user_data, watcher_id); + if (ret != MESSAGE_PORT_ERROR_NONE) { + _SECURE_LOGI("add registered callback fail (%d).", ret); + return convert_to_tizen_error((messageport_error_e)ret); + } + + return MESSAGE_PORT_ERROR_NONE; +} + +int message_port_add_unregistered_cb(const char *remote_app_id, const char *remote_port, bool is_trusted, message_port_registration_event_cb unregistered_cb, void *user_data, int *watcher_id) +{ + int ret = MESSAGE_PORT_ERROR_NONE; + + if (watcher_id == NULL || remote_app_id == NULL || remote_port == NULL || + unregistered_cb == NULL) { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + + ret = messageport_add_unregistered_cb(remote_app_id, remote_port, is_trusted, unregistered_cb, user_data, watcher_id); + if (ret != MESSAGE_PORT_ERROR_NONE) { + _SECURE_LOGI("add registered callback fail (%d).", ret); + return convert_to_tizen_error((messageport_error_e)ret); + } + + return MESSAGE_PORT_ERROR_NONE; +} + +int message_port_remove_registration_event_cb(int watcher_id) +{ + int ret = MESSAGE_PORT_ERROR_NONE; + if (watcher_id < 1) { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] Invalid watcher_id."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + + ret = messageport_remove_registration_event_cb(watcher_id); + return convert_to_tizen_error((messageport_error_e)ret); +} -- 2.7.4