From f101dcc734894f4fc408ae2417bb01479919f0b3 Mon Sep 17 00:00:00 2001 From: Myungki Lee Date: Thu, 19 May 2016 11:17:24 +0900 Subject: [PATCH] Add new api for ongoing_update_cb Change-Id: I2e11dac3ae7ced42b0c752b6de7dcfb167209b3b Signed-off-by: Myungki Lee --- CMakeLists.txt | 1 + include/notification_ongoing.h | 63 +++++++++ packaging/notification.spec | 1 + src/notification_ongoing.c | 293 +++++++++++++++++++++++++++-------------- 4 files changed, 256 insertions(+), 102 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f05b92e..a7ebcd6 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ SET(HEADERS-DEVEL ./include/notification_error.h ./include/notification_type.h ./include/notification_list.h + ./include/notification_ongoing.h ./include/notification_ongoing_flag.h ./include/notification_text_domain.h ./include/notification_status.h diff --git a/include/notification_ongoing.h b/include/notification_ongoing.h index 0d60ab6..3b42f8b 100644 --- a/include/notification_ongoing.h +++ b/include/notification_ongoing.h @@ -18,6 +18,62 @@ #define __NOTIFICATION_ONGOING_H__ #include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @file notification_ongoing.h + */ + +typedef enum { + ONGOING_TYPE_PROGRESS, + ONGOING_TYPE_SIZE, + ONGOING_TYPE_CONTENT, +} ongoing_type_e; + +struct ongoing_info_s { + char *pkgname; + int priv_id; + ongoing_type_e type; + double progress; + double size; + char *content; +}; + +/** + * @internal + * @brief Called when a notification ongoing data is updated. + * @since_tizen 3.0 + * @param[in] info The ongoing information handle + * @param[in] data The user data + * @pre notification_ongoing_update_cb_set() used to register this callback. + * @see notification_ongoing_update_cb_set() +*/ +typedef void (*notification_ongoing_update_cb)(struct ongoing_info_s *info, void *data); + +/** + * @internal + * @brief Registers a callback to receive the ongoing progress, size ,content. + * @since_tizen 3.0 + * @param[in] callback The callback function + * @param[in] data The user_data + * @return #NOTIFICATION_ERROR_NONE if success, other value if failure + * @retval #NOTIFICATION_ERROR_NONE Success + * @retval #NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #NOTIFICATION_ERROR_FROM_DBUS Error from DBus + */ +int notification_ongoing_update_cb_set(notification_ongoing_update_cb callback, void *user_data); + +/** + * @internal + * @brief Unregisters a callback to receive. + * @since_tizen 3.0 + * @retval #NOTIFICATION_ERROR_NONE Success + */ +int notification_ongoing_update_cb_unset(void); + int notification_ongoing_update_progress(const char *caller_pkgname, int priv_id, double progress); @@ -28,5 +84,12 @@ int notification_ongoing_update_size(const char *caller_pkgname, int notification_ongoing_update_content(const char *caller_pkgname, int priv_id, const char *content); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ #endif /* __NOTIFICATION_ONGOING_H__ */ diff --git a/packaging/notification.spec b/packaging/notification.spec index 91c32dc..575a78f 100755 --- a/packaging/notification.spec +++ b/packaging/notification.spec @@ -101,6 +101,7 @@ fi %{_includedir}/notification/notification_error.h %{_includedir}/notification/notification_type.h %{_includedir}/notification/notification_list.h +%{_includedir}/notification/notification_ongoing.h %{_includedir}/notification/notification_ongoing_flag.h %{_includedir}/notification/notification_text_domain.h %{_includedir}/notification/notification_status.h diff --git a/src/notification_ongoing.c b/src/notification_ongoing.c index 699338a..2daaabb 100755 --- a/src/notification_ongoing.c +++ b/src/notification_ongoing.c @@ -18,147 +18,236 @@ #include #include -#include +#include +#include #include #include #include #include -int notification_ongoing_update_progress(const char *caller_pkgname, - int priv_id, - double progress) +#define PATH_NAME "/dbus/signal" +#define INTERFACE_NAME "notification.ongoing" +#define MEMBER_PROGRESS "update_progress" +#define MEMBER_SIZE "update_size" +#define MEMBER_CONTENT "update_content" + +struct _ongoing_update_cb_data { + notification_ongoing_update_cb callback; + void *data; + GDBusConnection *conn; + guint subscribe_id; +}; + +static struct _ongoing_update_cb_data od; + +static void __notification_ongoing_update_callback(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) { - DBusConnection *connection = NULL; - DBusMessage *signal = NULL; - DBusError err; - dbus_bool_t ret; - - dbus_error_init(&err); - connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err); - if (!connection) { - NOTIFICATION_ERR("Fail to dbus_bus_get"); - return NOTIFICATION_ERROR_FROM_DBUS; + struct ongoing_info_s *info; + char *pkgname = NULL; + int priv_id = 0; + double progress = 0; + double size = 0; + char *content = NULL; + + info = calloc(1, sizeof(struct ongoing_info_s)); + if (info == NULL) { + NOTIFICATION_ERR("Out of memory"); + return; } - signal = - dbus_message_new_signal("/dbus/signal", "notification.ongoing", - "update_progress"); - if (!signal) { - NOTIFICATION_ERR("Fail to dbus_message_new_signal"); - return NOTIFICATION_ERROR_FROM_DBUS; + if (g_strcmp0(signal_name, MEMBER_PROGRESS) == 0) { + g_variant_get(parameters, "(sid)", &pkgname, &priv_id, &progress); + info->type = ONGOING_TYPE_PROGRESS; } - ret = dbus_message_append_args(signal, - DBUS_TYPE_STRING, &caller_pkgname, - DBUS_TYPE_INT32, &priv_id, - DBUS_TYPE_DOUBLE, &progress, - DBUS_TYPE_INVALID); + if (g_strcmp0(signal_name, MEMBER_SIZE) == 0) { + g_variant_get(parameters, "(sid)", &pkgname, &priv_id, &size); + info->type = ONGOING_TYPE_SIZE; - if (ret) { - ret = dbus_connection_send(connection, signal, NULL); - if (ret) - dbus_connection_flush(connection); } - dbus_message_unref(signal); + if (g_strcmp0(signal_name, MEMBER_CONTENT) == 0) { + g_variant_get(parameters, "(sis)", &pkgname, &priv_id, &content); + info->type = ONGOING_TYPE_CONTENT; + } + + if (pkgname == NULL) { + NOTIFICATION_ERR("pkgname is null"); + free(info); + return; + } - if (ret) - return NOTIFICATION_ERROR_NONE; + info->pkgname = strdup(pkgname); + info->priv_id = priv_id; + info->progress = progress; + info->size = size; + info->content = content; - return NOTIFICATION_ERROR_FROM_DBUS; + od.callback(info, od.data); } -int notification_ongoing_update_size(const char *caller_pkgname, - int priv_id, double size) +static int __send_ongoing_update_signal(const char *signal_name, GVariant *param) { - DBusConnection *connection = NULL; - DBusMessage *signal = NULL; - DBusError err; - dbus_bool_t ret; - - dbus_error_init(&err); - connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err); - if (!connection) { - NOTIFICATION_ERR("Fail to dbus_bus_get"); - return NOTIFICATION_ERROR_FROM_DBUS; + GError *err = NULL; + GDBusConnection *conn; + int ret = NOTIFICATION_ERROR_NONE; + + if (signal_name == NULL) + return NOTIFICATION_ERROR_INVALID_PARAMETER; + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + if (conn == NULL) { + NOTIFICATION_ERR("g_bus_get_sync() failed: %s", err->message); + ret = NOTIFICATION_ERROR_FROM_DBUS; + goto end; } - signal = - dbus_message_new_signal("/dbus/signal", "notification.ongoing", - "update_size"); - if (!signal) { - NOTIFICATION_ERR("Fail to dbus_message_new_signal"); - return NOTIFICATION_ERROR_FROM_DBUS; + if (g_dbus_connection_emit_signal(conn, + NULL, + PATH_NAME, + INTERFACE_NAME, + signal_name, + param, + &err) == FALSE) { + NOTIFICATION_ERR("g_dbus_connection_emit_signal() failed: %s", + err->message); + ret = NOTIFICATION_ERROR_FROM_DBUS; + goto end; } - ret = dbus_message_append_args(signal, - DBUS_TYPE_STRING, &caller_pkgname, - DBUS_TYPE_INT32, &priv_id, - DBUS_TYPE_DOUBLE, &size, - DBUS_TYPE_INVALID); - if (ret) { - ret = dbus_connection_send(connection, signal, NULL); - - if (ret) - dbus_connection_flush(connection); + if (g_dbus_connection_flush_sync(conn, NULL, &err) == FALSE) { + NOTIFICATION_ERR("g_dbus_connection_flush_sync() failed: %s", + err->message); + ret = NOTIFICATION_ERROR_FROM_DBUS; + goto end; } - dbus_message_unref(signal); - if (ret) - return NOTIFICATION_ERROR_NONE; +end: + if (err) + g_error_free(err); + + if (conn) + g_object_unref(conn); - return NOTIFICATION_ERROR_FROM_DBUS; + + return ret; } -int notification_ongoing_update_content(const char *caller_pkgname, - int priv_id, const char *content) +EXPORT_API +int notification_ongoing_update_cb_set(notification_ongoing_update_cb callback, + void *user_data) { - DBusConnection *connection = NULL; - DBusMessage *signal = NULL; - DBusError err; - dbus_bool_t ret; - - dbus_error_init(&err); - connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err); - if (!connection) { - NOTIFICATION_ERR("Fail to dbus_bus_get"); + GError *error = NULL; + + if (!callback) + return NOTIFICATION_ERROR_INVALID_PARAMETER; + + od.conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (od.conn == NULL) { + NOTIFICATION_ERR("Failed to connect to the D-BUS Daemon: %s", + error->message); + g_error_free(error); return NOTIFICATION_ERROR_FROM_DBUS; } - signal = - dbus_message_new_signal("/dbus/signal", "notification.ongoing", - "update_content"); - if (!signal) { - NOTIFICATION_ERR("Fail to dbus_message_new_signal"); + od.subscribe_id = g_dbus_connection_signal_subscribe(od.conn, + NULL, + INTERFACE_NAME, + NULL, + PATH_NAME, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + __notification_ongoing_update_callback, + NULL, + NULL); + if (od.subscribe_id == 0) { + NOTIFICATION_ERR("g_dbus_connection_signal_subscribe() failed"); + g_object_unref(od.conn); return NOTIFICATION_ERROR_FROM_DBUS; } - if (content == NULL) - ret = dbus_message_append_args(signal, - DBUS_TYPE_STRING, &caller_pkgname, - DBUS_TYPE_INT32, &priv_id, - DBUS_TYPE_INVALID); - else - ret = dbus_message_append_args(signal, - DBUS_TYPE_STRING, &caller_pkgname, - DBUS_TYPE_INT32, &priv_id, - DBUS_TYPE_STRING, &content, - DBUS_TYPE_INVALID); - - if (ret) { - ret = dbus_connection_send(connection, signal, NULL); - - if (ret) - dbus_connection_flush(connection); + od.callback = callback; + od.data = user_data; + + return NOTIFICATION_ERROR_NONE; +} + +EXPORT_API +int notification_ongoing_update_cb_unset(void) +{ + if (od.subscribe_id) { + g_dbus_connection_signal_unsubscribe(od.conn, od.subscribe_id); + od.subscribe_id = 0; + } + + if (od.conn) { + g_object_unref(od.conn); + od.conn = NULL; } - dbus_message_unref(signal); + od.callback = NULL; + od.data = NULL; - if (ret) - return NOTIFICATION_ERROR_NONE; + return NOTIFICATION_ERROR_NONE; +} + +int notification_ongoing_update_progress(const char *caller_pkgname, + int priv_id, double progress) +{ + GVariant *param; + int ret; + + param = g_variant_new("(sid)", caller_pkgname, priv_id, progress); - return NOTIFICATION_ERROR_FROM_DBUS; + ret = __send_ongoing_update_signal(MEMBER_PROGRESS, param); + if (ret != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("notification_ongoing_update_progress failed %d", + ret); + return ret; + } + + return NOTIFICATION_ERROR_NONE; } +int notification_ongoing_update_size(const char *caller_pkgname, + int priv_id, double size) +{ + GVariant *param; + int ret; + + param = g_variant_new("(sid)", caller_pkgname, priv_id, size); + + ret = __send_ongoing_update_signal(MEMBER_SIZE, param); + if (ret != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("notification_ongoing_update_size failed %d", + ret); + return ret; + } + + return NOTIFICATION_ERROR_NONE; +} + +int notification_ongoing_update_content(const char *caller_pkgname, + int priv_id, const char *content) +{ + GVariant *param; + int ret; + + param = g_variant_new("(sis)", caller_pkgname, priv_id, content); + + ret = __send_ongoing_update_signal(MEMBER_CONTENT, param); + if (ret != NOTIFICATION_ERROR_NONE) { + NOTIFICATION_ERR("notification_ongoing_update_content failed %d", + ret); + return ret; + } + return NOTIFICATION_ERROR_NONE; +} -- 2.7.4