Add new api for ongoing_update_cb 79/69579/8 accepted/tizen/common/20160525.155800 accepted/tizen/ivi/20160525.234930 accepted/tizen/mobile/20160525.234856 accepted/tizen/tv/20160525.234912 accepted/tizen/wearable/20160525.234918 submit/tizen/20160524.100942
authorMyungki Lee <mk5004.lee@samsung.com>
Thu, 19 May 2016 02:17:24 +0000 (11:17 +0900)
committerMyungKi Lee <mk5004.lee@samsung.com>
Tue, 24 May 2016 10:19:11 +0000 (03:19 -0700)
Change-Id: I2e11dac3ae7ced42b0c752b6de7dcfb167209b3b
Signed-off-by: Myungki Lee <mk5004.lee@samsung.com>
CMakeLists.txt
include/notification_ongoing.h
packaging/notification.spec
src/notification_ongoing.c

index f05b92e..a7ebcd6 100755 (executable)
@@ -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
index 0d60ab6..3b42f8b 100644 (file)
 #define __NOTIFICATION_ONGOING_H__
 
 #include <notification.h>
+
+#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__ */
 
index 91c32dc..575a78f 100755 (executable)
@@ -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
index 699338a..2daaabb 100755 (executable)
 #include <string.h>
 #include <stdlib.h>
 
-#include <dbus/dbus.h>
+#include <glib.h>
+#include <gio/gio.h>
 
 #include <notification_db.h>
 #include <notification_debug.h>
 #include <notification_ongoing.h>
 #include <notification_private.h>
 
-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;
+}