Add new apis to watch that remote port is registered and unregistered 03/122303/26
authorInkyun Kil <inkyun.kil@samsung.com>
Fri, 31 Mar 2017 05:07:47 +0000 (14:07 +0900)
committerInkyun Kil <inkyun.kil@samsung.com>
Mon, 24 Apr 2017 07:49:36 +0000 (16:49 +0900)
Change-Id: I1687de44ecbcbed3fd1ae3998eb1f71c3fb8dbc0
Signed-off-by: Inkyun Kil <inkyun.kil@samsung.com>
include/message-port.h
include/message_port.h
src/message-port.c
src/message_port.c

index 1014655..fe748c0 100644 (file)
@@ -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);
+
+
+/**
  * @}
  */
 
index 133dd11..59c8332 100755 (executable)
@@ -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);
+
+
+
+/**
  * @}
  */
 
index e7b2bfc..6868a5e 100755 (executable)
@@ -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;
+}
index 459bfe5..d6d50f3 100644 (file)
@@ -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);
+}