sync with private git
authoryoungsub ko <ys4610.ko@samsung.com>
Thu, 2 May 2013 06:15:46 +0000 (15:15 +0900)
committeryoungsub ko <ys4610.ko@samsung.com>
Thu, 2 May 2013 06:15:46 +0000 (15:15 +0900)
CMakeLists.txt
include/notification.h
include/notification_error.h
include/notification_ipc.h [new file with mode: 0755]
include/notification_type.h
packaging/notification.spec
src/notification.c
src/notification_ipc.c [new file with mode: 0755]
src/notification_noti.c

index 9c27ffe..fba58f1 100755 (executable)
@@ -17,12 +17,15 @@ SET(SRCS ./src/notification.c
        ./src/notification_group.c
        ./src/notification_db.c
        ./src/notification_list.c
-       ./src/notification_status.c)
+       ./src/notification_status.c
+       ./src/notification_ipc.c)
 SET(HEADERS ./include/notification.h 
        ./include/notification_error.h 
        ./include/notification_type.h 
        ./include/notification_list.h
-       ./include/notification_status.h)
+       ./include/notification_status.h
+       ./include/notification_ipc.h
+       ./include/notification_noti.h)
 
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
 
@@ -38,6 +41,7 @@ pkg_check_modules(pkgs REQUIRED
        appsvc
        dbus-1
        dbus-glib-1
+       com-core
 )
 
 FOREACH(flag ${pkgs_CFLAGS})
index 219221d..3f0123f 100755 (executable)
@@ -2005,6 +2005,17 @@ notification_error_e notification_op_get_data(notification_op *noti_op,
 /**
  * @}
  */
+
+void notification_call_changed_cb(notification_op *op_list, int op_num);
+
+int notification_is_service_ready(void);
+
+notification_error_e notification_add_deffered_task(
+               void (*deffered_task_cb)(void *data), void *user_data);
+
+notification_error_e notification_del_deffered_task(
+               void (*deffered_task_cb)(void *data));
+
 #ifdef __cplusplus
 }
 #endif
index cd4dbab..75512a2 100755 (executable)
@@ -39,6 +39,7 @@ typedef enum _notification_error {
        NOTIFICATION_ERROR_FROM_DBUS = -5,      /**< Error from DBus */
        NOTIFICATION_ERROR_NOT_EXIST_ID = -6,   /**< Not exist private ID */
        NOTIFICATION_ERROR_IO = -7,     /**< disk i/o error */
+       NOTIFICATION_ERROR_SERVICE_NOT_READY = -8,      /**< no reponse from master */
 } notification_error_e;
 
 /** 
diff --git a/include/notification_ipc.h b/include/notification_ipc.h
new file mode 100755 (executable)
index 0000000..4dd2656
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  libnotification
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungtaek Chung <seungtaek.chung@samsung.com>, Mi-Ju Lee <miju52.lee@samsung.com>, Xi Zhichan <zhichan.xi@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __NOTIFICATION_IPC_H__
+#define __NOTIFICATION_IPC_H__
+
+#include <notification.h>
+
+#define NOTIFICATION_ADDR "/tmp/.notification.service"
+#define NOTIFICATION_DEL_PACKET_UNIT 10
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct packet;
+
+notification_error_e notification_ipc_monitor_init(void);
+notification_error_e notification_ipc_monitor_fini(void);
+
+notification_error_e notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet);
+struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type);
+
+notification_error_e notification_ipc_request_insert(notification_h noti, int *priv_id);
+notification_error_e notification_ipc_request_update(notification_h noti);
+notification_error_e notification_ipc_request_refresh(void);
+notification_error_e notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id);
+notification_error_e notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname);
+
+int notification_ipc_is_master_ready(void);
+notification_error_e notification_ipc_add_deffered_task(void (*deffered_task_cb)(void *data), void *user_data);
+notification_error_e notification_ipc_del_deffered_task(void (*deffered_task_cb)(void *data));
+
+#ifdef __cplusplus
+}
+#endif
+#endif
index ab431ad..1431bae 100755 (executable)
@@ -47,6 +47,7 @@ typedef enum _notification_op_type {
        NOTIFICATION_OP_DELETE,
        NOTIFICATION_OP_DELETE_ALL,
        NOTIFICATION_OP_REFRESH,
+       NOTIFICATION_OP_SERVICE_READY,
 } notification_op_type_e;
 
 /**
@@ -56,6 +57,7 @@ typedef enum _notification_op_data_type {
        NOTIFICATION_OP_DATA_MIN = 0,
        NOTIFICATION_OP_DATA_TYPE,
        NOTIFICATION_OP_DATA_PRIV_ID,
+       NOTIFICATION_OP_DATA_NOTI,
        NOTIFICATION_OP_DATA_EXTRA_INFO_1,
        NOTIFICATION_OP_DATA_EXTRA_INFO_2,
        NOTIFICATION_OP_DATA_MAX,
@@ -328,6 +330,7 @@ typedef struct _notification_op {
        int priv_id;
        int extra_info_1;
        int extra_info_2;
+       notification_h noti;
 } notification_op;
 /** 
  * @}
index e341e32..a5472eb 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       notification
 Summary:    notification library
-Version:    0.2.0
+Version:    0.2.1
 Release:    1
 Group:      TBD
 License:    Apache-2.0
@@ -16,6 +16,7 @@ BuildRequires: pkgconfig(ail)
 BuildRequires: pkgconfig(aul)
 BuildRequires: pkgconfig(appsvc)
 BuildRequires: pkgconfig(dbus-glib-1)
+BuildRequires: pkgconfig(com-core)
 
 BuildRequires: cmake
 Requires(post): /sbin/ldconfig
index 65702d0..a88b9cb 100755 (executable)
@@ -41,6 +41,7 @@
 #include <notification_noti.h>
 #include <notification_ongoing.h>
 #include <notification_group.h>
+#include <notification_ipc.h>
 
 typedef struct _notification_cb_list notification_cb_list_s;
 
@@ -60,7 +61,6 @@ struct _notification_cb_list {
 };
 
 static notification_cb_list_s *g_notification_cb_list = NULL;
-static DBusConnection *g_dbus_handle;
 
 #define NOTI_TEXT_RESULT_LEN 2048
 #define NOTI_PKGNAME_LEN       512
@@ -73,15 +73,17 @@ static DBusConnection *g_dbus_handle;
 
 static char *_notification_get_pkgname_by_pid(void)
 {
-       char buf[NOTI_PKGNAME_LEN + 1] = { 0, };
        char pkgname[NOTI_PKGNAME_LEN + 1] = { 0, };
        int pid = 0, ret = AUL_R_OK;
        int fd;
+       char  *dup_pkgname;
 
        pid = getpid();
 
        ret = aul_app_get_pkgname_bypid(pid, pkgname, sizeof(pkgname));
        if (ret != AUL_R_OK) {
+               char buf[NOTI_PKGNAME_LEN + 1] = { 0, };
+
                snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
 
                fd = open(buf, O_RDONLY);
@@ -90,83 +92,29 @@ static char *_notification_get_pkgname_by_pid(void)
                }
 
                ret = read(fd, pkgname, sizeof(pkgname) - 1);
+               close(fd);
+
                if (ret <= 0) {
-                       close(fd);
                        return NULL;
                }
 
-               if (ret > NOTI_PKGNAME_LEN)
-                       pkgname[NOTI_PKGNAME_LEN] = '\0';
-               else
-                       pkgname[ret] = '\0';
-
-               close(fd);
-       }
-
-       if (strlen(pkgname) <= 0) {
-               return NULL;
+               pkgname[ret] = '\0';
+               /*!
+                * \NOTE
+                * "ret" is not able to be larger than "sizeof(pkgname) - 1",
+                * if the system is not going wrong.
+                */
        } else {
-               return strdup(pkgname);
-       }
-}
-
-static void _notification_pack_operation_msg(DBusMessageIter *iter, notification_op *op_list, int op_num)
-{
-       int i = 0;
-
-       if (op_list == NULL) {
-               int tmp_op_num = 0;
-
-               dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &tmp_op_num);
-               return ;
-       }
-
-       dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &op_num);
-       for (i = 0; i < op_num; i++) {
-               NOTIFICATION_ERR("pack:%d/%d", i, op_num);
-               notification_op *op = op_list + i;
-               dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &(op->type));
-               dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &(op->priv_id));
-               dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &(op->extra_info_1));
-               dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &(op->extra_info_2));
-       }
-}
-
-static void _notification_unpack_operation_msg(DBusMessageIter *iter, notification_op **op_list, int *op_num)
-{
-       int i = 0;
-
-       if (iter == NULL || op_list == NULL || op_num == NULL) {
-               return;
-       }
-
-       dbus_message_iter_get_basic(iter, op_num);
-
-       int tmp_op_num = *op_num;
-
-       if (tmp_op_num <= 0) {
-               *op_list = NULL;
-               *op_num = 0;
-               return;
+               if (strlen(pkgname) <= 0) {
+                       return NULL;
+               }
        }
 
-       *op_list = (notification_op*)malloc(sizeof(notification_op) * (tmp_op_num));
+       dup_pkgname = strdup(pkgname);
+       if (!dup_pkgname)
+               NOTIFICATION_ERR("Heap: %s\n", strerror(errno));
 
-       dbus_message_iter_next(iter);
-
-       if (*op_list != NULL) {
-               for (i = 0; i < tmp_op_num; i++) {
-                       notification_op *op = (*op_list) + i;
-                       dbus_message_iter_get_basic(iter, &(op->type));
-                       dbus_message_iter_next(iter);
-                       dbus_message_iter_get_basic(iter, &(op->priv_id));
-                       dbus_message_iter_next(iter);
-                       dbus_message_iter_get_basic(iter, &(op->extra_info_1));
-                       dbus_message_iter_next(iter);
-                       dbus_message_iter_get_basic(iter, &(op->extra_info_2));
-                       dbus_message_iter_next(iter);
-               }
-       }
+       return dup_pkgname;
 }
 
 static char *_notification_get_icon(const char *package)
@@ -236,251 +184,6 @@ static void _notification_get_text_domain(notification_h noti)
        }
 }
 
-static void _notification_chagned_noti_cb(DBusMessage *message, void *data)
-{
-       notification_cb_list_s *noti_cb_list = NULL;
-       DBusMessageIter iter;
-
-       int op_num = 0;
-       notification_op *op_list = NULL;
-
-       if (g_notification_cb_list == NULL) {
-               return;
-       }
-
-       noti_cb_list = g_notification_cb_list;
-
-       while (noti_cb_list->prev != NULL) {
-               noti_cb_list = noti_cb_list->prev;
-       }
-
-       if (message != NULL) {
-               if (dbus_message_iter_init(message, &iter)) {
-                       _notification_unpack_operation_msg(&iter, &op_list, &op_num);
-                       NOTIFICATION_ERR("operation num:%d", op_num);
-               }
-       }
-
-       while (noti_cb_list != NULL) {
-               if (noti_cb_list->cb_type == NOTIFICATION_CB_NORMAL && noti_cb_list->changed_cb) {
-                       noti_cb_list->changed_cb(noti_cb_list->data,
-                                                NOTIFICATION_TYPE_NOTI);
-               }
-               if (noti_cb_list->cb_type == NOTIFICATION_CB_DETAILED && noti_cb_list->detailed_changed_cb) {
-                       noti_cb_list->detailed_changed_cb(noti_cb_list->data,
-                                                NOTIFICATION_TYPE_NOTI, op_list, op_num);
-               }
-
-               noti_cb_list = noti_cb_list->next;
-       }
-
-       if (op_list != NULL) {
-               free(op_list);
-       }
-}
-
-#if 0
-static void _notification_chagned_ongoing_cb(void *data)
-{
-       notification_cb_list_s *noti_cb_list = NULL;
-
-       if (g_notification_cb_list == NULL) {
-               return;
-       }
-
-       noti_cb_list = g_notification_cb_list;
-
-       while (noti_cb_list->prev != NULL) {
-               noti_cb_list = noti_cb_list->prev;
-       }
-
-       while (noti_cb_list != NULL) {
-               if (noti_cb_list->changed_cb) {
-                       noti_cb_list->changed_cb(noti_cb_list->data,
-                                                NOTIFICATION_TYPE_ONGOING);
-               }
-
-               noti_cb_list = noti_cb_list->next;
-       }
-}
-#endif
-
-static void _notification_pack_and_send_dbus_message(const char *type, notification_op *op_list , int op_num)
-{
-       DBusConnection *connection = NULL;
-       DBusMessage *message = NULL;
-       DBusMessageIter iter;
-       DBusError err;
-       dbus_bool_t ret;
-       int i = 0;
-
-       if (!type) {
-               NOTIFICATION_ERR("type is NULL");
-               return;
-       }
-
-       dbus_error_init(&err);
-       connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
-       if (!connection) {
-               NOTIFICATION_ERR("Fail to dbus_bus_get : %s", err.message);
-               return;
-       }
-
-       message = dbus_message_new_signal(NOTI_DBUS_PATH,
-                               NOTI_DBUS_INTERFACE,
-                               type);
-
-       if (!message) {
-               NOTIFICATION_ERR("fail to create dbus message");
-               goto release_n_return;
-       }
-
-       if (op_num > 0 && op_list != NULL) {
-               dbus_message_iter_init_append(message, &iter);
-               _notification_pack_operation_msg(&iter, op_list, op_num);
-       }
-
-       ret = dbus_connection_send(connection, message, NULL);
-       if (!ret) {
-               NOTIFICATION_ERR("fail to send dbus message : %s", type);
-               goto release_n_return;
-       }
-
-       dbus_connection_flush(connection);
-
-       NOTIFICATION_DBG("success to emit signal [%s]", type);
-
-release_n_return:
-       dbus_error_free(&err);
-
-       if (message)
-               dbus_message_unref(message);
-
-       if (connection)
-               dbus_connection_unref(connection);
-}
-
-#define SET_DBUS_MESSAGE 30
-
-static void _notification_changed(const char *type, notification_op *op_list , int op_num)
-{
-       int set = 0;
-       int set_total = 0;
-       int set_modular = 0;
-
-       if (op_num <= SET_DBUS_MESSAGE) {
-               _notification_pack_and_send_dbus_message(type, op_list, op_num);
-       } else {
-               set_total = op_num / SET_DBUS_MESSAGE;
-               set_modular = op_num - (set_total * SET_DBUS_MESSAGE);
-
-               for (set = 0; set < set_total; set++) {
-                       _notification_pack_and_send_dbus_message(type, op_list + (set * SET_DBUS_MESSAGE), SET_DBUS_MESSAGE);
-               }
-
-               if (set_modular > 0) {
-                       _notification_pack_and_send_dbus_message(type,
-                                       op_list + (set_total * SET_DBUS_MESSAGE), set_modular);
-               }
-       }
-}
-
-static DBusHandlerResult _dbus_signal_filter(DBusConnection *conn,
-               DBusMessage *msg, void *user_data)
-{
-       const char *interface = NULL;
-       
-       interface = dbus_message_get_interface(msg);
-       NOTIFICATION_DBG("path : %s", dbus_message_get_path(msg));
-       NOTIFICATION_DBG("interface : %s", interface);
-
-       if (strcmp(NOTI_DBUS_INTERFACE, interface))
-               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-
-       switch (dbus_message_get_type(msg)) {
-               case DBUS_MESSAGE_TYPE_SIGNAL:
-                       _notification_chagned_noti_cb(msg, NULL);
-                       return DBUS_HANDLER_RESULT_HANDLED;
-               default:
-                       break;
-       }
-       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-static DBusConnection *_noti_changed_monitor_init()
-{
-       DBusError err;
-       DBusConnection *conn = NULL;
-       char rule[1024];
-
-       dbus_error_init(&err);
-       conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
-       if (!conn) {
-               printf("fail to get bus\n");
-               return NULL;
-       }
-       dbus_connection_setup_with_g_main(conn, NULL);
-       snprintf(rule, 1024, 
-               "path='%s',type='signal',interface='%s',member='%s'",
-               NOTI_DBUS_PATH, 
-               NOTI_DBUS_INTERFACE,
-               NOTI_CHANGED_NOTI);
-
-       dbus_bus_add_match(conn, rule, &err);
-       if (dbus_connection_add_filter(conn,_dbus_signal_filter, 
-                                       NULL, NULL) == FALSE) {
-               NOTIFICATION_ERR("fail to dbus_connection_add_filter");
-               dbus_connection_close(conn);
-               return NULL;
-       }
-
-       dbus_connection_set_exit_on_disconnect(conn, FALSE);
-       return conn;
-}
-
-static void _noti_chanaged_monitor_fini()
-{
-       DBusConnection *conn = g_dbus_handle;
-       char rule[1024];
-
-       if (!conn)
-               return;
-       dbus_connection_remove_filter(conn, _dbus_signal_filter, NULL);
-
-       snprintf(rule, 1024, 
-               "path='%s',type='signal',interface='%s',member='%s'",
-               NOTI_DBUS_PATH, 
-               NOTI_DBUS_INTERFACE,
-               NOTI_CHANGED_NOTI);
-       dbus_bus_remove_match(conn, rule, NULL);
-
-       dbus_connection_close(conn);
-       g_dbus_handle = NULL;
-}      
-
-notification_op *_notification_make_basic_op(notification_op_type_e type, int num_op, int *list_priv_id, int num_priv_id)
-{
-       int i = 0;
-       notification_op *op_list = NULL;
-
-       if (num_op <= 0) {
-               return NULL;
-       }
-
-       op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
-       memset(op_list, 0x0, sizeof(notification_op) * num_op);
-
-       for (i = 0; i < num_priv_id; i++) {
-               (op_list + i)->type = type;
-               if (list_priv_id != NULL) {
-                       (op_list + i)->priv_id = *(list_priv_id + i);
-               }
-       }
-
-       return op_list;
-}
-
 /* notification_set_icon will be removed */
 EXPORT_API notification_error_e notification_set_icon(notification_h noti,
                                                      const char *icon_path)
@@ -2272,6 +1975,7 @@ EXPORT_API notification_error_e notification_insert(notification_h noti,
                                                    int *priv_id)
 {
        int ret = 0;
+       int id = 0;
 
        /* Check noti is vaild data */
        if (noti == NULL) {
@@ -2286,25 +1990,12 @@ EXPORT_API notification_error_e notification_insert(notification_h noti,
 
        /* Save insert time */
        noti->insert_time = time(NULL);
-
-       /* Insert into DB */
-       ret = notification_noti_insert(noti);
+       ret = notification_ipc_request_insert(noti, &id);
        if (ret != NOTIFICATION_ERROR_NONE) {
                return ret;
        }
-
-       /* Check disable update on insert property */
-       if (noti->flags_for_property
-               & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
-               /* Disable changed cb */
-       } else {
-               /* Enable changed cb */
-               notification_op *noti_op = _notification_make_basic_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1);
-               if (noti_op != NULL) {
-                       _notification_changed(NOTI_CHANGED_NOTI, noti_op, 1);
-                       free(noti_op);
-               }
-       }
+       noti->priv_id = id;
+       NOTIFICATION_DBG("from master:%d", id);
 
        /* If priv_id is valid data, set priv_id */
        if (priv_id != NULL) {
@@ -2322,23 +2013,14 @@ EXPORT_API notification_error_e notification_update(notification_h noti)
        if (noti != NULL) {
                /* Update insert time ? */
                noti->insert_time = time(NULL);
-
-               ret = notification_noti_update(noti);
+               ret = notification_ipc_request_update(noti);
                if (ret != NOTIFICATION_ERROR_NONE) {
                        return ret;
                }
-
-               notification_op *noti_op = _notification_make_basic_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1);
-               if (noti_op != NULL) {
-                       _notification_changed(NOTI_CHANGED_NOTI, noti_op, 1);
-                       free(noti_op);
-               }
        } else {
-               /* Send changed notification */
-               notification_op *noti_op = _notification_make_basic_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0);
-               if (noti_op != NULL) {
-                       _notification_changed(NOTI_CHANGED_NOTI, noti_op, 1);
-                       free(noti_op);
+               ret = notification_ipc_request_refresh();
+               if (ret != NOTIFICATION_ERROR_NONE) {
+                       return ret;
                }
        }
        return NOTIFICATION_ERROR_NONE;
@@ -2347,30 +2029,12 @@ EXPORT_API notification_error_e notification_update(notification_h noti)
 EXPORT_API notification_error_e notifiation_clear(notification_type_e type)
 {
        int ret = 0;
-       int num_deleted = 0;
-       int *list_deleted = NULL;
 
-       /* Delete all notification of type */
-       ret = notification_noti_delete_all(type, NULL, &num_deleted, &list_deleted);
+       ret = notification_ipc_request_delete_multiple(type, NULL);
        if (ret != NOTIFICATION_ERROR_NONE) {
                return ret;
        }
 
-       /* Send chagned notification */
-
-       if (num_deleted > 0 && list_deleted != NULL) {
-               notification_op *noti_op = _notification_make_basic_op(NOTIFICATION_OP_DELETE, num_deleted, list_deleted, num_deleted);
-               if (noti_op != NULL) {
-                       NOTIFICATION_ERR("noti_op %x", noti_op);
-                       _notification_changed(NOTI_CHANGED_NOTI, noti_op, num_deleted);
-                       free(noti_op);
-               }
-       }
-
-       if (list_deleted != NULL) {
-               free(list_deleted);
-       }
-
        return NOTIFICATION_ERROR_NONE;
 }
 
@@ -2378,8 +2042,6 @@ EXPORT_API notification_error_e notification_delete_all_by_type(const char *pkgn
                                                                notification_type_e type)
 {
        int ret = 0;
-       int num_deleted = 0;
-       int *list_deleted = NULL;
        char *caller_pkgname = NULL;
 
        if (pkgname == NULL) {
@@ -2388,30 +2050,12 @@ EXPORT_API notification_error_e notification_delete_all_by_type(const char *pkgn
                caller_pkgname = strdup(pkgname);
        }
 
-       ret = notification_noti_delete_all(type, caller_pkgname, &num_deleted, &list_deleted);
+       ret = notification_ipc_request_delete_multiple(type, caller_pkgname);
        if (ret != NOTIFICATION_ERROR_NONE) {
-               free(caller_pkgname);
                return ret;
        }
 
-       /* Send chagned notification */
-       if (num_deleted > 0 && list_deleted != NULL) {
-               notification_op *noti_op = _notification_make_basic_op(NOTIFICATION_OP_DELETE, num_deleted, list_deleted, num_deleted);
-               if (noti_op != NULL) {
-                       _notification_changed(NOTI_CHANGED_NOTI, noti_op, num_deleted);
-                       free(noti_op);
-               }
-       }
-       if (caller_pkgname != NULL) {
-               free(caller_pkgname);
-               caller_pkgname = NULL;
-       }
-       if (list_deleted != NULL) {
-               free(list_deleted);
-               list_deleted = NULL;
-       }
-
-       return ret;
+       return NOTIFICATION_ERROR_NONE;
 }
 
 EXPORT_API notification_error_e notification_delete_group_by_group_id(const char *pkgname,
@@ -2419,46 +2063,20 @@ EXPORT_API notification_error_e notification_delete_group_by_group_id(const char
                                                                      int group_id)
 {
        int ret = 0;
-       int num_deleted = 0;
-       int *list_deleted = NULL;
        char *caller_pkgname = NULL;
 
-       if (group_id < NOTIFICATION_GROUP_ID_NONE) {
-               return NOTIFICATION_ERROR_INVALID_DATA;
-       }
-
        if (pkgname == NULL) {
                caller_pkgname = _notification_get_pkgname_by_pid();
        } else {
                caller_pkgname = strdup(pkgname);
        }
 
-       ret =
-           notification_noti_delete_group_by_group_id(caller_pkgname,
-                                                      group_id, &num_deleted, &list_deleted);
+       ret = notification_ipc_request_delete_multiple(type, caller_pkgname);
        if (ret != NOTIFICATION_ERROR_NONE) {
-               free(caller_pkgname);
                return ret;
        }
 
-       if (num_deleted > 0 && list_deleted != NULL) {
-               notification_op *noti_op = _notification_make_basic_op(NOTIFICATION_OP_DELETE, num_deleted, list_deleted, num_deleted);
-               if (noti_op != NULL) {
-                       _notification_changed(NOTI_CHANGED_NOTI, noti_op, num_deleted);
-                       free(noti_op);
-               }
-       }
-
-       if (caller_pkgname != NULL) {
-               free(caller_pkgname);
-               caller_pkgname = NULL;
-       }
-       if (list_deleted != NULL) {
-               free(list_deleted);
-               list_deleted = NULL;
-       }
-
-       return ret;
+       return NOTIFICATION_ERROR_NONE;
 }
 
 EXPORT_API notification_error_e notification_delete_group_by_priv_id(const char *pkgname,
@@ -2468,32 +2086,18 @@ EXPORT_API notification_error_e notification_delete_group_by_priv_id(const char
        int ret = 0;
        char *caller_pkgname = NULL;
 
-       if (priv_id < NOTIFICATION_PRIV_ID_NONE) {
-               return NOTIFICATION_ERROR_INVALID_DATA;
-       }
-
        if (pkgname == NULL) {
                caller_pkgname = _notification_get_pkgname_by_pid();
        } else {
                caller_pkgname = strdup(pkgname);
        }
 
-       ret =
-           notification_noti_delete_group_by_priv_id(caller_pkgname, priv_id);
+       ret = notification_ipc_request_delete_single(type, caller_pkgname, priv_id);
        if (ret != NOTIFICATION_ERROR_NONE) {
-               free(caller_pkgname);
                return ret;
        }
 
-       notification_op *noti_op = _notification_make_basic_op(NOTIFICATION_OP_DELETE, 1, NULL, 0);
-       if (noti_op != NULL) {
-               _notification_changed(NOTI_CHANGED_NOTI, noti_op, 1);
-               free(noti_op);
-       }
-
-       free(caller_pkgname);
-
-       return ret;
+       return NOTIFICATION_ERROR_NONE;
 }
 
 EXPORT_API notification_error_e notification_delete_by_priv_id(const char *pkgname,
@@ -2513,20 +2117,11 @@ EXPORT_API notification_error_e notification_delete_by_priv_id(const char *pkgna
                caller_pkgname = strdup(pkgname);
        }
 
-       ret = notification_noti_delete_by_priv_id(caller_pkgname, priv_id);
+       ret = notification_ipc_request_delete_single(type, caller_pkgname, priv_id);
        if (ret != NOTIFICATION_ERROR_NONE) {
-               free(caller_pkgname);
                return ret;
        }
 
-       notification_op *noti_op = _notification_make_basic_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1);
-       if (noti_op != NULL) {
-               _notification_changed(NOTI_CHANGED_NOTI, noti_op, 1);
-               free(noti_op);
-       }
-
-       free(caller_pkgname);
-
        return ret;
 }
 
@@ -2538,24 +2133,11 @@ EXPORT_API notification_error_e notification_delete(notification_h noti)
                return NOTIFICATION_ERROR_INVALID_DATA;
        }
 
-       ret =
-           notification_noti_delete_by_priv_id(noti->caller_pkgname,
-                                               noti->priv_id);
+       ret = notification_ipc_request_delete_single(NOTIFICATION_TYPE_NONE, noti->caller_pkgname, noti->priv_id);
        if (ret != NOTIFICATION_ERROR_NONE) {
                return ret;
        }
 
-       if (noti->flags_for_property
-               & NOTIFICATION_PROP_DISABLE_UPDATE_ON_DELETE) {
-               NOTIFICATION_INFO("Disabled update while delete.");
-       } else {
-               notification_op *noti_op = _notification_make_basic_op(NOTIFICATION_OP_DELETE, 1, &(noti->priv_id), 1);
-               if (noti_op != NULL) {
-                       _notification_changed(NOTI_CHANGED_NOTI, noti_op, 1);
-                       free(noti_op);
-               }
-       }
-
        return NOTIFICATION_ERROR_NONE;
 }
 
@@ -2674,7 +2256,8 @@ EXPORT_API notification_error_e notification_update_content(notification_h noti,
        return NOTIFICATION_ERROR_NONE;
 }
 
-static notification_h _notification_create(notification_type_e type) {
+static notification_h _notification_create(notification_type_e type)
+{
        notification_h noti = NULL;
 
        if (type <= NOTIFICATION_TYPE_NONE || type >= NOTIFICATION_TYPE_MAX) {
@@ -2682,12 +2265,11 @@ static notification_h _notification_create(notification_type_e type) {
                return NULL;
        }
 
-       noti = (notification_h) malloc(sizeof(struct _notification));
+       noti = (notification_h) calloc(1, sizeof(struct _notification));
        if (noti == NULL) {
                NOTIFICATION_ERR("NO MEMORY : noti == NULL");
                return NULL;
        }
-       memset(noti, 0x00, sizeof(struct _notification));
 
        noti->type = type;
 
@@ -2696,53 +2278,17 @@ static notification_h _notification_create(notification_type_e type) {
        else if (type == NOTIFICATION_TYPE_ONGOING)
                noti->layout = NOTIFICATION_LY_ONGOING_PROGRESS;
 
+       noti->caller_pkgname = _notification_get_pkgname_by_pid();
        noti->group_id = NOTIFICATION_GROUP_ID_NONE;
-       noti->internal_group_id = 0;
        noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
-
-       noti->caller_pkgname = _notification_get_pkgname_by_pid();
-       noti->launch_pkgname = NULL;
-       noti->args = NULL;
-       noti->group_args = NULL;
-
-       noti->b_execute_option = NULL;
-       noti->b_service_responding = NULL;
-       noti->b_service_single_launch = NULL;
-       noti->b_service_multi_launch = NULL;
-
        noti->sound_type = NOTIFICATION_SOUND_TYPE_NONE;
-       noti->sound_path = NULL;
-
        noti->vibration_type = NOTIFICATION_VIBRATION_TYPE_NONE;
-       noti->vibration_path = NULL;
-
        noti->led_operation = NOTIFICATION_LED_OP_OFF;
-       noti->led_argb = 0;
-
-       noti->domain = NULL;
-       noti->dir = NULL;
-
-       noti->b_text = NULL;
-       noti->b_key = NULL;
-       noti->b_format_args = NULL;
-       noti->num_format_args = 0;
-
-       noti->b_image_path = NULL;
-
-       noti->time = 0;
-       noti->insert_time = 0;
-
-       noti->flags_for_property = 0;
        noti->display_applist = NOTIFICATION_DISPLAY_APP_ALL;
-
-       noti->progress_size = 0.0;
-       noti->progress_percentage = 0.0;
-
-       noti->app_icon_path = NULL;
-       noti->app_name = NULL;
-       noti->temp_title = NULL;
-       noti->temp_content = NULL;
-
+       /*!
+        * \NOTE
+        * Other fields are already initialized with ZERO.
+        */
        return noti;
 }
 
@@ -3000,10 +2546,8 @@ notification_resister_changed_cb(void (*changed_cb)
        notification_cb_list_s *noti_cb_list_new = NULL;
        notification_cb_list_s *noti_cb_list = NULL;
 
-       if (!g_dbus_handle) {
-               g_dbus_handle = _noti_changed_monitor_init();
-               if (!g_dbus_handle)
-                       return NOTIFICATION_ERROR_FROM_DBUS;
+       if (notification_ipc_monitor_init() != NOTIFICATION_ERROR_NONE) {
+               return NOTIFICATION_ERROR_IO;
        }
 
        noti_cb_list_new =
@@ -3072,7 +2616,7 @@ notification_unresister_changed_cb(void (*changed_cb)
                        free(noti_cb_list);
 
                        if (g_notification_cb_list == NULL)
-                               _noti_chanaged_monitor_fini();
+                               notification_ipc_monitor_fini();
 
                        return NOTIFICATION_ERROR_NONE;
                }
@@ -3090,10 +2634,8 @@ notification_register_detailed_changed_cb(
        notification_cb_list_s *noti_cb_list_new = NULL;
        notification_cb_list_s *noti_cb_list = NULL;
 
-       if (!g_dbus_handle) {
-               g_dbus_handle = _noti_changed_monitor_init();
-               if (!g_dbus_handle)
-                       return NOTIFICATION_ERROR_FROM_DBUS;
+       if (notification_ipc_monitor_init() != NOTIFICATION_ERROR_NONE) {
+               return NOTIFICATION_ERROR_IO;
        }
 
        noti_cb_list_new =
@@ -3163,7 +2705,7 @@ notification_unregister_detailed_changed_cb(
                        free(noti_cb_list);
 
                        if (g_notification_cb_list == NULL)
-                               _noti_chanaged_monitor_fini();
+                               notification_ipc_monitor_fini();
 
                        return NOTIFICATION_ERROR_NONE;
                }
@@ -3293,7 +2835,7 @@ EXPORT_API notification_error_e notification_free_list(notification_list_h list)
 EXPORT_API notification_error_e notification_op_get_data(notification_op *noti_op, notification_op_data_type_e type,
                                                       void *data)
 {
-       if (noti_op == NULL) {
+       if (noti_op == NULL || data == NULL) {
                return NOTIFICATION_ERROR_INVALID_DATA;
        }
 
@@ -3304,6 +2846,9 @@ EXPORT_API notification_error_e notification_op_get_data(notification_op *noti_o
                case NOTIFICATION_OP_DATA_PRIV_ID:
                        *((int*)data) = noti_op->priv_id;
                        break;
+               case NOTIFICATION_OP_DATA_NOTI:
+                       *((notification_h *)data) = noti_op->noti;
+                       break;
                case NOTIFICATION_OP_DATA_EXTRA_INFO_1:
                        *((int*)data) = noti_op->extra_info_1;
                        break;
@@ -3317,3 +2862,55 @@ EXPORT_API notification_error_e notification_op_get_data(notification_op *noti_o
 
        return NOTIFICATION_ERROR_NONE;
 }
+
+void notification_call_changed_cb(notification_op *op_list, int op_num)
+{
+       notification_cb_list_s *noti_cb_list = NULL;
+
+
+       if (g_notification_cb_list == NULL) {
+               return;
+       }
+       noti_cb_list = g_notification_cb_list;
+
+       while (noti_cb_list->prev != NULL) {
+               noti_cb_list = noti_cb_list->prev;
+       }
+
+       if (op_list == NULL) {
+               NOTIFICATION_ERR("invalid data");
+               return ;
+       }
+
+       while (noti_cb_list != NULL) {
+               if (noti_cb_list->cb_type == NOTIFICATION_CB_NORMAL && noti_cb_list->changed_cb) {
+                       noti_cb_list->changed_cb(noti_cb_list->data,
+                                                NOTIFICATION_TYPE_NOTI);
+               }
+               if (noti_cb_list->cb_type == NOTIFICATION_CB_DETAILED && noti_cb_list->detailed_changed_cb) {
+                       noti_cb_list->detailed_changed_cb(noti_cb_list->data,
+                                                NOTIFICATION_TYPE_NOTI, op_list, op_num);
+               }
+
+               noti_cb_list = noti_cb_list->next;
+       }
+}
+
+EXPORT_API int notification_is_service_ready(void)
+{
+       return notification_ipc_is_master_ready();
+}
+
+EXPORT_API notification_error_e
+notification_add_deffered_task(
+               void (*deffered_task_cb)(void *data), void *user_data)
+{
+       return notification_ipc_add_deffered_task(deffered_task_cb, user_data);
+}
+
+EXPORT_API notification_error_e
+notification_del_deffered_task(
+               void (*deffered_task_cb)(void *data))
+{
+       return notification_ipc_del_deffered_task(deffered_task_cb);
+}
diff --git a/src/notification_ipc.c b/src/notification_ipc.c
new file mode 100755 (executable)
index 0000000..845702f
--- /dev/null
@@ -0,0 +1,1065 @@
+/*
+ *  libnotification
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungtaek Chung <seungtaek.chung@samsung.com>, Mi-Ju Lee <miju52.lee@samsung.com>, Xi Zhichan <zhichan.xi@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <vconf.h>
+
+#include <packet.h>
+#include <com-core.h>
+#include <com-core_packet.h>
+
+#include <notification_ipc.h>
+#include <notification_db.h>
+#include <notification_type.h>
+#include <notification_internal.h>
+#include <notification_debug.h>
+
+#define NOTIFICATION_IPC_TIMEOUT 1.0
+
+#if !defined(VCONFKEY_MASTER_STARTED)
+#define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started"
+#endif
+
+static struct info {
+       int server_fd;
+       int client_fd;
+       const char *socket_file;
+       struct {
+               int (*request_cb)(const char *appid, const char *name, int type, const char *content, const char *icon, pid_t pid, double period, int allow_duplicate, void *data);
+               void *data;
+       } server_cb;
+       int initialized;
+       int is_started_cb_set_svc;
+       int is_started_cb_set_task;
+} s_info = {
+       .server_fd = -1,
+       .client_fd = -1,
+       .socket_file = NOTIFICATION_ADDR,
+       .initialized = 0,
+       .is_started_cb_set_svc = 0,
+       .is_started_cb_set_task = 0,
+};
+
+typedef struct _task_list task_list;
+struct _task_list {
+       task_list *prev;
+       task_list *next;
+
+       void (*task_cb) (void *data);
+       void *data;
+};
+
+static task_list *g_task_list;
+
+static notification_error_e notification_ipc_monitor_register(void);
+static notification_error_e notification_ipc_monitor_deregister(void);
+static void _do_deffered_task(void);
+static void _master_started_cb_task(keynode_t *node, void *data);
+
+/*!
+ * functions to check state of master
+ */
+static inline void _set_master_started_cb(vconf_callback_fn cb) {
+       int ret = -1;
+
+       ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED,
+                       cb, NULL);
+       if (ret != 0) {
+               NOTIFICATION_ERR("failed to notify key(%s) : %d",
+                               VCONFKEY_MASTER_STARTED, ret);
+       }
+}
+
+static inline void _unset_master_started_cb(vconf_callback_fn cb) {
+       int ret = -1;
+
+       ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED,
+                       cb);
+       if (ret != 0) {
+               NOTIFICATION_ERR("failed to notify key(%s) : %d",
+                               VCONFKEY_MASTER_STARTED, ret);
+       }
+}
+
+int notification_ipc_is_master_ready(void)
+{
+       int ret = -1, is_master_started = 0;
+
+       ret = vconf_get_bool(VCONFKEY_MASTER_STARTED, &is_master_started);
+       if (ret == 0 && is_master_started == 1) {
+               NOTIFICATION_ERR("the master has been started");
+       } else {
+               is_master_started = 0;
+               NOTIFICATION_ERR("the master has been stopped");
+       }
+
+       return is_master_started;
+}
+
+notification_error_e
+notification_ipc_add_deffered_task(
+               void (*deffered_task_cb)(void *data),
+               void *user_data)
+{
+       task_list *list = NULL;
+       task_list *list_new = NULL;
+
+       list_new =
+           (task_list *) malloc(sizeof(task_list));
+
+       if (list_new == NULL) {
+               return NOTIFICATION_ERROR_NO_MEMORY;
+       }
+
+       if (s_info.is_started_cb_set_task == 0) {
+               _set_master_started_cb(_master_started_cb_task);
+               s_info.is_started_cb_set_task = 1;
+       }
+
+       list_new->next = NULL;
+       list_new->prev = NULL;
+
+       list_new->task_cb = deffered_task_cb;
+       list_new->data = user_data;
+
+       if (g_task_list == NULL) {
+               g_task_list = list_new;
+       } else {
+               list = g_task_list;
+
+               while (list->next != NULL) {
+                       list = list->next;
+               }
+
+               list->next = list_new;
+               list_new->prev = list;
+       }
+       return NOTIFICATION_ERROR_NONE;
+}
+
+notification_error_e
+notification_ipc_del_deffered_task(
+               void (*deffered_task_cb)(void *data))
+{
+       task_list *list_del = NULL;
+       task_list *list_prev = NULL;
+       task_list *list_next = NULL;
+
+       list_del = g_task_list;
+
+       if (list_del == NULL) {
+               return NOTIFICATION_ERROR_INVALID_DATA;
+       }
+
+       while (list_del->prev != NULL) {
+               list_del = list_del->prev;
+       }
+
+       do {
+               if (list_del->task_cb == deffered_task_cb) {
+                       list_prev = list_del->prev;
+                       list_next = list_del->next;
+
+                       if (list_prev == NULL) {
+                               g_task_list = list_next;
+                       } else {
+                               list_prev->next = list_next;
+                       }
+
+                       if (list_next == NULL) {
+                               if (list_prev != NULL) {
+                                       list_prev->next = NULL;
+                               }
+                       } else {
+                               list_next->prev = list_prev;
+                       }
+
+                       free(list_del);
+
+                       if (g_task_list == NULL) {
+                               if (s_info.is_started_cb_set_task == 1) {
+                                       _unset_master_started_cb(_master_started_cb_task);
+                                       s_info.is_started_cb_set_task = 0;
+                               }
+                       }
+
+                       return NOTIFICATION_ERROR_NONE;
+               }
+               list_del = list_del->next;
+       } while (list_del != NULL);
+
+       return NOTIFICATION_ERROR_INVALID_DATA;
+}
+
+static void _do_deffered_task(void) {
+       task_list *list_do = NULL;
+       task_list *list_temp = NULL;
+
+       if (g_task_list == NULL) {
+               return;
+       }
+
+       list_do = g_task_list;
+       g_task_list = NULL;
+       if (s_info.is_started_cb_set_task == 1) {
+               _unset_master_started_cb(_master_started_cb_task);
+               s_info.is_started_cb_set_task = 0;
+       }
+
+       while (list_do->prev != NULL) {
+               list_do = list_do->prev;
+       }
+
+       while (list_do != NULL) {
+               if (list_do->task_cb != NULL) {
+                       list_do->task_cb(list_do->data);
+                       NOTIFICATION_DBG("called:%p", list_do->task_cb);
+               }
+               list_temp = list_do->next;
+               free(list_do);
+               list_do = list_temp;
+       }
+}
+
+static void _master_started_cb_service(keynode_t *node,
+               void *data) {
+       int ret = NOTIFICATION_ERROR_NONE;
+
+       if (notification_ipc_is_master_ready()) {
+               ret = notification_ipc_monitor_register();
+               if (ret != NOTIFICATION_ERROR_NONE) {
+                       NOTIFICATION_ERR("failed to register a monitor");
+               }
+       } else {
+               ret = notification_ipc_monitor_deregister();
+               if (ret != NOTIFICATION_ERROR_NONE) {
+                       NOTIFICATION_ERR("failed to deregister a monitor");
+               }
+       }
+}
+
+static void _master_started_cb_task(keynode_t *node,
+               void *data) {
+
+       if (notification_ipc_is_master_ready()) {
+               _do_deffered_task();
+       }
+}
+
+/*!
+ * functions to create operation list
+ */
+notification_op *notification_ipc_create_op(notification_op_type_e type, int num_op, int *list_priv_id, int num_priv_id, notification_h *noti_list)
+{
+       int i = 0;
+       notification_op *op_list = NULL;
+
+       if (num_op <= 0) {
+               return NULL;
+       }
+
+       op_list = (notification_op *)malloc(sizeof(notification_op) * num_op);
+       memset(op_list, 0x0, sizeof(notification_op) * num_op);
+
+       for (i = 0; i < num_op; i++) {
+               (op_list + i)->type = type;
+               if (list_priv_id != NULL) {
+                       (op_list + i)->priv_id = *(list_priv_id + i);
+               }
+               if (noti_list != NULL) {
+                       (op_list + i)->noti = *(noti_list + i);
+               }
+       }
+
+       return op_list;
+}
+
+/*!
+ * utility functions creating notification packet
+ */
+static inline char *_dup_string(const char *string)
+{
+       char *ret;
+
+       if (string == NULL) {
+               return NULL;
+       }
+       if (string[0] == '\0') {
+               return NULL;
+       }
+
+       ret = strdup(string);
+       if (!ret)
+               NOTIFICATION_ERR("Error: %s\n", strerror(errno));
+
+       return ret;
+}
+
+static inline bundle *_create_bundle_from_string(unsigned char *string)
+{
+       if (string == NULL) {
+               return NULL;
+       }
+       if (string[0] == '\0') {
+               return NULL;
+       }
+
+       return bundle_decode(string, strlen((char *)string));
+}
+
+/*!
+ * functions creating notification packet
+ */
+EXPORT_API notification_error_e notification_ipc_make_noti_from_packet(notification_h noti, const struct packet *packet)
+{
+       int ret = 0;
+       int type;
+       int layout;
+       int group_id;
+       int internal_group_id;
+       int priv_id;
+       char *caller_pkgname = NULL;
+       char *launch_pkgname = NULL;
+       unsigned char *args = NULL;
+       unsigned char *group_args = NULL;
+       unsigned char *b_execute_option = NULL;
+       unsigned char *b_service_responding = NULL;
+       unsigned char *b_service_single_launch = NULL;
+       unsigned char *b_service_multi_launch = NULL;
+       char *domain = NULL;
+       char *dir = NULL;
+       unsigned char *b_text = NULL;
+       unsigned char *b_key = NULL;
+       unsigned char *b_format_args = NULL;
+       int num_format_args;
+       unsigned char *b_image_path = NULL;
+       int sound_type;
+       char *sound_path = NULL;
+       int vibration_type;
+       char *vibration_path = NULL;
+       int led_operation;
+       int led_argb;
+       time_t time;
+       time_t insert_time;
+       int flags_for_property;
+       int display_applist;
+       double progress_size;
+       double progress_percentage;
+       char *app_icon_path = NULL;
+       char *app_name = NULL;
+       char *temp_title = NULL;
+       char *temp_content = NULL;
+
+       if (noti == NULL) {
+               NOTIFICATION_ERR("invalid data");
+               return NOTIFICATION_ERROR_INVALID_DATA;
+       }
+
+       ret = packet_get(packet,
+                       "iiiiisssssssssssssisisisiiiiiiddssss",
+                       &type,
+                       &layout,
+                       &group_id,
+                       &internal_group_id,
+                       &priv_id,
+                       &caller_pkgname,
+                       &launch_pkgname,
+                       &args,
+                       &group_args,
+                       &b_execute_option,
+                       &b_service_responding,
+                       &b_service_single_launch,
+                       &b_service_multi_launch,
+                       &domain,
+                       &dir,
+                       &b_text,
+                       &b_key,
+                       &b_format_args,
+                       &num_format_args,
+                       &b_image_path,
+                       &sound_type,
+                       &sound_path,
+                       &vibration_type,
+                       &vibration_path,
+                       &led_operation,
+                       &led_argb,
+                       &time,
+                       &insert_time,
+                       &flags_for_property,
+                       &display_applist,
+                       &progress_size,
+                       &progress_percentage,
+                       &app_icon_path,
+                       &app_name,
+                       &temp_title,
+                       &temp_content);
+
+       if (ret != 36) {
+               NOTIFICATION_ERR("failed to create a noti from packet");
+               return NOTIFICATION_ERROR_INVALID_DATA;
+       }
+
+       /*!
+        * This is already allocated from the notification_create function.
+        * Before reallocate string to here.
+        * We have to release old one first.
+        */
+       free(noti->caller_pkgname);
+       noti->caller_pkgname = _dup_string(caller_pkgname);
+       noti->launch_pkgname = _dup_string(launch_pkgname);
+       noti->args = _create_bundle_from_string(args);
+       noti->group_args = _create_bundle_from_string(group_args);
+       noti->b_execute_option = _create_bundle_from_string(b_execute_option);
+       noti->b_service_responding = _create_bundle_from_string(b_service_responding);
+       noti->b_service_single_launch = _create_bundle_from_string(b_service_single_launch);
+       noti->b_service_multi_launch = _create_bundle_from_string(b_service_multi_launch);
+       noti->domain = _dup_string(domain);
+       noti->dir = _dup_string(dir);
+       noti->b_text = _create_bundle_from_string(b_text);
+       noti->b_key = _create_bundle_from_string(b_key);
+       noti->b_format_args = _create_bundle_from_string(b_format_args);
+       noti->b_image_path = _create_bundle_from_string(b_image_path);
+       noti->sound_path = _dup_string(sound_path);
+       noti->vibration_path = _dup_string(vibration_path);
+       noti->app_icon_path = _dup_string(app_icon_path);
+       noti->app_name = _dup_string(app_name);
+       noti->temp_title = _dup_string(temp_title);
+       noti->temp_content = _dup_string(temp_content);
+
+       noti->type = type;
+       noti->layout = layout;
+       noti->group_id = group_id;
+       noti->internal_group_id = internal_group_id;
+       noti->priv_id = priv_id;
+       noti->num_format_args = num_format_args;
+       noti->sound_type = sound_type;
+       noti->vibration_type = vibration_type;
+       noti->led_operation = led_operation;
+       noti->led_argb = led_argb;
+       noti->time = time;
+       noti->insert_time = insert_time;
+       noti->flags_for_property = flags_for_property;
+       noti->display_applist = display_applist;
+       noti->progress_size = progress_size;
+       noti->progress_percentage = progress_percentage;
+
+       return NOTIFICATION_ERROR_NONE;
+}
+
+EXPORT_API struct packet *notification_ipc_make_packet_from_noti(notification_h noti, const char *command, int packet_type)
+{
+       struct packet *result = NULL;
+       char *args = NULL;
+       char *group_args = NULL;
+       char *b_image_path = NULL;
+       char *b_execute_option = NULL;
+       char *b_service_responding = NULL;
+       char *b_service_single_launch = NULL;
+       char *b_service_multi_launch = NULL;
+       char *b_text = NULL;
+       char *b_key = NULL;
+       char *b_format_args = NULL;
+       int flag_simmode = 0;
+       struct packet *(*func_to_create_packet)(const char *command, const char *fmt, ...);
+       const char *title_key = NULL;
+       char buf_key[32] = { 0, };
+
+       /* Decode bundle to insert DB */
+       if (noti->args) {
+               bundle_encode(noti->args, (bundle_raw **) & args, NULL);
+       }
+       if (noti->group_args) {
+               bundle_encode(noti->group_args, (bundle_raw **) & group_args,
+                             NULL);
+       }
+
+       if (noti->b_execute_option) {
+               bundle_encode(noti->b_execute_option,
+                             (bundle_raw **) & b_execute_option, NULL);
+       }
+       if (noti->b_service_responding) {
+               bundle_encode(noti->b_service_responding,
+                             (bundle_raw **) & b_service_responding, NULL);
+       }
+       if (noti->b_service_single_launch) {
+               bundle_encode(noti->b_service_single_launch,
+                             (bundle_raw **) & b_service_single_launch, NULL);
+       }
+       if (noti->b_service_multi_launch) {
+               bundle_encode(noti->b_service_multi_launch,
+                             (bundle_raw **) & b_service_multi_launch, NULL);
+       }
+
+       if (noti->b_text) {
+               bundle_encode(noti->b_text, (bundle_raw **) & b_text, NULL);
+       }
+       if (noti->b_key) {
+               bundle_encode(noti->b_key, (bundle_raw **) & b_key, NULL);
+       }
+       if (noti->b_format_args) {
+               bundle_encode(noti->b_format_args,
+                             (bundle_raw **) & b_format_args, NULL);
+       }
+
+       if (noti->b_image_path) {
+               bundle_encode(noti->b_image_path,
+                             (bundle_raw **) & b_image_path, NULL);
+       }
+
+       /* Check only simmode property is enable */
+       if (noti->flags_for_property & NOTIFICATION_PROP_DISPLAY_ONLY_SIMMODE) {
+               flag_simmode = 1;
+       }
+
+       if (noti->b_key != NULL) {
+               snprintf(buf_key, sizeof(buf_key), "%d",
+                        NOTIFICATION_TEXT_TYPE_TITLE);
+
+               title_key = bundle_get_val(noti->b_key, buf_key);
+       }
+
+       if (title_key == NULL && noti->b_text != NULL) {
+               snprintf(buf_key, sizeof(buf_key), "%d",
+                        NOTIFICATION_TEXT_TYPE_TITLE);
+
+               title_key = bundle_get_val(noti->b_text, buf_key);
+       }
+
+       if (title_key == NULL) {
+               title_key = noti->caller_pkgname;
+       }
+
+       if (packet_type == 1)
+               func_to_create_packet = packet_create;
+       else if (packet_type == 2)
+               func_to_create_packet = packet_create_noack;
+       else {
+               goto out;
+       }
+
+       result = func_to_create_packet(command,
+                       "iiiiisssssssssssssisisisiiiiiiddssss",
+                       noti->type,
+                       noti->layout,
+                       noti->group_id,
+                       noti->internal_group_id,
+                       noti->priv_id,
+                       NOTIFICATION_CHECK_STR(noti->caller_pkgname),
+                       NOTIFICATION_CHECK_STR(noti->launch_pkgname),
+                       NOTIFICATION_CHECK_STR(args),
+                       NOTIFICATION_CHECK_STR(group_args),
+                       NOTIFICATION_CHECK_STR(b_execute_option),
+                       NOTIFICATION_CHECK_STR(b_service_responding),
+                       NOTIFICATION_CHECK_STR(b_service_single_launch),
+                       NOTIFICATION_CHECK_STR(b_service_multi_launch),
+                       NOTIFICATION_CHECK_STR(noti->domain),
+                       NOTIFICATION_CHECK_STR(noti->dir),
+                       NOTIFICATION_CHECK_STR(b_text),
+                       NOTIFICATION_CHECK_STR(b_key),
+                       NOTIFICATION_CHECK_STR(b_format_args),
+                       noti->num_format_args,
+                       NOTIFICATION_CHECK_STR(b_image_path),
+                       noti->sound_type,
+                       NOTIFICATION_CHECK_STR(noti->sound_path),
+                       noti->vibration_type,
+                       NOTIFICATION_CHECK_STR(noti->vibration_path),
+                       noti->led_operation,
+                       noti->led_argb,
+                       noti->time,
+                       noti->insert_time,
+                       noti->flags_for_property,
+                       noti->display_applist,
+                       noti->progress_size,
+                       noti->progress_percentage,
+                       NOTIFICATION_CHECK_STR(noti->app_icon_path),
+                       NOTIFICATION_CHECK_STR(noti->app_name),
+                       NOTIFICATION_CHECK_STR(noti->temp_title),
+                       NOTIFICATION_CHECK_STR(noti->temp_content));
+
+out:
+       /* Free decoded data */
+       if (args) {
+               free(args);
+       }
+       if (group_args) {
+               free(group_args);
+       }
+
+       if (b_execute_option) {
+               free(b_execute_option);
+       }
+       if (b_service_responding) {
+               free(b_service_responding);
+       }
+       if (b_service_single_launch) {
+               free(b_service_single_launch);
+       }
+       if (b_service_multi_launch) {
+               free(b_service_multi_launch);
+       }
+
+       if (b_text) {
+               free(b_text);
+       }
+       if (b_key) {
+               free(b_key);
+       }
+       if (b_format_args) {
+               free(b_format_args);
+       }
+
+       if (b_image_path) {
+               free(b_image_path);
+       }
+
+       return result;
+}
+
+/*!
+ * functions to handler services
+ */
+static struct packet *_handler_insert(pid_t pid, int handle, const struct packet *packet)
+{
+       notification_h noti = NULL;
+
+       if (!packet) {
+               NOTIFICATION_ERR("a packet is null");
+               return NULL;
+       }
+       noti = notification_create(NOTIFICATION_TYPE_NOTI);
+       if (!noti) {
+               NOTIFICATION_ERR("failed to create a notification");
+               return NULL;
+       }
+       notification_ipc_make_noti_from_packet(noti, packet);
+
+       if (noti->flags_for_property
+               & NOTIFICATION_PROP_DISABLE_UPDATE_ON_INSERT) {
+               /* Disable changed cb */
+       } else {
+               /* Enable changed cb */
+               notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_INSERT, 1, &(noti->priv_id), 1, &noti);
+               if (noti_op != NULL) {
+                       notification_call_changed_cb(noti_op, 1);
+                       free(noti_op);
+               }
+       }
+       notification_free(noti);
+
+       return NULL;
+}
+
+static struct packet *_handler_update(pid_t pid, int handle, const struct packet *packet)
+{
+       notification_h noti = NULL;
+
+       if (!packet) {
+               NOTIFICATION_ERR("a packet is null");
+               return NULL;
+       }
+
+       noti = notification_create(NOTIFICATION_TYPE_NOTI);
+       if (!noti) {
+               NOTIFICATION_ERR("failed to create a notification");
+               return NULL;
+       }
+
+       notification_ipc_make_noti_from_packet(noti, packet);
+
+       notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_UPDATE, 1, &(noti->priv_id), 1, &noti);
+       if (noti_op != NULL) {
+               notification_call_changed_cb(noti_op, 1);
+               free(noti_op);
+       }
+
+       notification_free(noti);
+
+       return NULL;
+}
+
+static struct packet *_handler_refresh(pid_t pid, int handle, const struct packet *packet)
+{
+       if (!packet) {
+               NOTIFICATION_ERR("a packet is null");
+               return NULL;
+       }
+       notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_REFRESH, 1, NULL, 0, NULL);
+       if (noti_op != NULL) {
+               notification_call_changed_cb(noti_op, 1);
+               free(noti_op);
+       }
+
+       return NULL;
+}
+
+static struct packet *_handler_delete_single(pid_t pid, int handle, const struct packet *packet)
+{
+       int num_deleted = 0;
+       int priv_id = NOTIFICATION_PRIV_ID_NONE;
+
+       if (!packet) {
+               NOTIFICATION_ERR("a packet is null");
+               return NULL;
+       }
+       if (packet_get(packet, "ii", &num_deleted, &priv_id) == 2) {
+               notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_DELETE, 1, &priv_id, 1, NULL);
+               if (noti_op != NULL) {
+                       notification_call_changed_cb(noti_op, 1);
+                       free(noti_op);
+               }
+       }
+
+       return NULL;
+}
+
+static struct packet *_handler_delete_multiple(pid_t pid, int handle, const struct packet *packet)
+{
+       int ret = 0;
+       int buf[10] = {0,};
+       int num_deleted = 0;
+
+       NOTIFICATION_ERR("delete_noti_multiple");
+
+       if (!packet) {
+               NOTIFICATION_ERR("a packet is null");
+               return NULL;
+       }
+       ret = packet_get(packet, "iiiiiiiiiii", &num_deleted,
+                       &(buf[0]),
+                       &(buf[1]),
+                       &(buf[2]),
+                       &(buf[3]),
+                       &(buf[4]),
+                       &(buf[5]),
+                       &(buf[6]),
+                       &(buf[7]),
+                       &(buf[8]),
+                       &(buf[9]));
+
+       NOTIFICATION_ERR("packet data count:%d", ret);
+       NOTIFICATION_ERR("packet data num deleted:%d", num_deleted);
+
+       int i = 0;
+       for (i = 0 ; i < 10 ; i++) {
+               NOTIFICATION_ERR("packet data[%d]:%d",i, buf[i]);
+       }
+
+       if (ret == 11) {
+               notification_op *noti_op = notification_ipc_create_op(
+                               NOTIFICATION_OP_DELETE, num_deleted, buf, num_deleted, NULL);
+               if (noti_op != NULL) {
+                       notification_call_changed_cb(noti_op, num_deleted);
+                       free(noti_op);
+               }
+       }
+
+       return NULL;
+}
+
+static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data)
+{
+       int ret;
+
+       if (!packet) {
+               NOTIFICATION_ERR("Packet is not valid\n");
+               ret = NOTIFICATION_ERROR_INVALID_DATA;
+       } else if (packet_get(packet, "i", &ret) != 1) {
+               NOTIFICATION_ERR("Packet is not valid\n");
+               ret = NOTIFICATION_ERROR_INVALID_DATA;
+       } else {
+               if (ret == 0) {
+                       notification_op *noti_op = notification_ipc_create_op(NOTIFICATION_OP_SERVICE_READY, 1, NULL, 1, NULL);
+                       if (noti_op != NULL) {
+                               notification_call_changed_cb(noti_op, 1);
+                               free(noti_op);
+                       }
+               }
+       }
+       return ret;
+}
+
+/*!
+ * functions to initialize and register a monitor
+ */
+static notification_error_e notification_ipc_monitor_register(void)
+{
+       int ret;
+       struct packet *packet;
+       static struct method service_table[] = {
+               {
+                       .cmd = "add_noti",
+                       .handler = _handler_insert,
+               },
+               {
+                       .cmd = "update_noti",
+                       .handler = _handler_update,
+               },
+               {
+                       .cmd = "refresh_noti",
+                       .handler = _handler_refresh,
+               },
+               {
+                       .cmd = "del_noti_single",
+                       .handler = _handler_delete_single,
+               },
+               {
+                       .cmd = "del_noti_multiple",
+                       .handler = _handler_delete_multiple,
+               },
+               {
+                       .cmd = NULL,
+                       .handler = NULL,
+               },
+       };
+
+       if (s_info.initialized == 1) {
+               return NOTIFICATION_ERROR_NONE;
+       } else {
+               s_info.initialized = 1;
+       }
+
+       NOTIFICATION_ERR("register a service\n");
+
+       s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
+       if (s_info.server_fd < 0) {
+               NOTIFICATION_ERR("Failed to make a connection to the master\n");
+               return NOTIFICATION_ERROR_IO;
+       }
+
+       packet = packet_create("service_register", "");
+       if (!packet) {
+               NOTIFICATION_ERR("Failed to build a packet\n");
+               return NOTIFICATION_ERROR_IO;
+       }
+
+       ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL);
+       NOTIFICATION_DBG("Service register sent: %d\n", ret);
+       packet_destroy(packet);
+       if (ret != 0) {
+               com_core_packet_client_fini(s_info.server_fd);
+               s_info.server_fd = NOTIFICATION_ERROR_INVALID_DATA;
+               ret = NOTIFICATION_ERROR_IO;
+       } else {
+               ret = NOTIFICATION_ERROR_NONE;
+       }
+
+       NOTIFICATION_DBG("Server FD: %d\n", s_info.server_fd);
+       return ret;
+}
+
+notification_error_e notification_ipc_monitor_deregister(void)
+{
+       if (s_info.initialized == 0) {
+               return NOTIFICATION_ERROR_NONE;
+       }
+
+       com_core_packet_client_fini(s_info.server_fd);
+       s_info.server_fd = NOTIFICATION_ERROR_INVALID_DATA;
+
+       s_info.initialized = 0;
+
+       return NOTIFICATION_ERROR_NONE;
+}
+
+notification_error_e notification_ipc_monitor_init(void)
+{
+       int ret = NOTIFICATION_ERROR_NONE;
+
+       if (notification_ipc_is_master_ready()) {
+               ret = notification_ipc_monitor_register();
+       }
+
+       if (s_info.is_started_cb_set_svc == 0) {
+               _set_master_started_cb(_master_started_cb_service);
+               s_info.is_started_cb_set_svc = 1;
+       }
+
+       return ret;
+}
+
+notification_error_e notification_ipc_monitor_fini(void)
+{
+       int ret = NOTIFICATION_ERROR_NONE;
+
+       if (s_info.is_started_cb_set_svc == 1) {
+               _unset_master_started_cb(_master_started_cb_service);
+               s_info.is_started_cb_set_svc = 0;
+       }
+
+       ret = notification_ipc_monitor_deregister();
+
+       return ret;
+}
+
+/*!
+ * functions to request the service
+ */
+notification_error_e notification_ipc_request_insert(notification_h noti, int *priv_id)
+{
+       int status = 0;
+       int id = NOTIFICATION_PRIV_ID_NONE;
+       struct packet *packet;
+       struct packet *result;
+
+       /* Initialize private ID */
+       noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
+       noti->group_id = NOTIFICATION_GROUP_ID_NONE;
+       noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
+
+       packet = notification_ipc_make_packet_from_noti(noti, "add_noti", 1);
+       result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
+                       packet,
+                       NOTIFICATION_IPC_TIMEOUT);
+       packet_destroy(packet);
+
+       if (result != NULL) {
+               if (packet_get(result, "ii", &status, &id) != 2) {
+                       NOTIFICATION_ERR("Failed to get a result packet");
+                       packet_unref(result);
+                       return NOTIFICATION_ERROR_IO;
+               }
+
+               if (status != NOTIFICATION_ERROR_NONE) {
+                       return status;
+               }
+       } else {
+               notification_ipc_is_master_ready();
+               return NOTIFICATION_ERROR_SERVICE_NOT_READY;
+       }
+
+       if (priv_id != NULL) {
+               *priv_id = id;
+       }
+
+       return NOTIFICATION_ERROR_NONE;
+}
+
+notification_error_e notification_ipc_request_delete_single(notification_type_e type, char *pkgname, int priv_id)
+{
+       int status = 0;
+       int id = NOTIFICATION_PRIV_ID_NONE;
+       struct packet *packet;
+       struct packet *result;
+
+       packet = packet_create("del_noti_single", "si", pkgname, priv_id);
+       result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
+                       packet,
+                       NOTIFICATION_IPC_TIMEOUT);
+       packet_destroy(packet);
+
+       if (result != NULL) {
+               if (packet_get(result, "ii", &status, &id) != 2) {
+                       NOTIFICATION_ERR("Failed to get a result packet");
+                       packet_unref(result);
+                       return NOTIFICATION_ERROR_IO;
+               }
+       } else {
+               notification_ipc_is_master_ready();
+               return NOTIFICATION_ERROR_SERVICE_NOT_READY;
+       }
+
+       return status;
+}
+
+notification_error_e notification_ipc_request_delete_multiple(notification_type_e type, char *pkgname)
+{
+       int status = 0;
+       int num_deleted = 0;
+       struct packet *packet;
+       struct packet *result;
+
+       packet = packet_create("del_noti_multiple", "si", pkgname, type);
+       result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
+                       packet,
+                       NOTIFICATION_IPC_TIMEOUT);
+       packet_destroy(packet);
+
+       if (result != NULL) {
+               if (packet_get(result, "ii", &status, &num_deleted) != 2) {
+                       NOTIFICATION_ERR("Failed to get a result packet");
+                       packet_unref(result);
+                       return NOTIFICATION_ERROR_IO;
+               }
+               NOTIFICATION_ERR("num deleted:%d", num_deleted);
+       } else {
+               notification_ipc_is_master_ready();
+               return NOTIFICATION_ERROR_SERVICE_NOT_READY;
+       }
+
+       return status;
+}
+
+notification_error_e notification_ipc_request_update(notification_h noti)
+{
+       int status = 0;
+       int id = NOTIFICATION_PRIV_ID_NONE;
+       struct packet *packet;
+       struct packet *result;
+
+       packet = notification_ipc_make_packet_from_noti(noti, "update_noti", 1);
+       result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
+                       packet,
+                       NOTIFICATION_IPC_TIMEOUT);
+       packet_destroy(packet);
+
+       if (result != NULL) {
+               if (packet_get(result, "ii", &status, &id) != 2) {
+                       NOTIFICATION_ERR("Failed to get a result packet");
+                       packet_unref(result);
+                       return NOTIFICATION_ERROR_IO;
+               }
+       } else {
+               notification_ipc_is_master_ready();
+               return NOTIFICATION_ERROR_SERVICE_NOT_READY;
+       }
+
+       return status;
+}
+
+notification_error_e notification_ipc_request_refresh(void)
+{
+       int status = 0;
+       struct packet *packet;
+       struct packet *result;
+
+       packet = packet_create("refresh_noti", "i", NOTIFICATION_OP_REFRESH);
+       result = com_core_packet_oneshot_send(NOTIFICATION_ADDR,
+                       packet,
+                       NOTIFICATION_IPC_TIMEOUT);
+       packet_destroy(packet);
+
+       if (result != NULL) {
+               if (packet_get(result, "i", &status) != 1) {
+                       NOTIFICATION_ERR("Failed to get a result packet");
+                       packet_unref(result);
+                       return NOTIFICATION_ERROR_IO;
+               }
+       } else {
+               notification_ipc_is_master_ready();
+               return NOTIFICATION_ERROR_SERVICE_NOT_READY;
+       }
+
+       return status;
+}
index b90a716..9e534e6 100755 (executable)
@@ -67,11 +67,9 @@ static int _notification_noti_bind_query_double(sqlite3_stmt * stmt, const char
                return NOTIFICATION_ERROR_FROM_DB;
        }
 
-       ret =
-           sqlite3_bind_double(stmt, index, val);
+       ret = sqlite3_bind_double(stmt, index, val);
        if (ret != SQLITE_OK) {
-               NOTIFICATION_ERR("Insert double : %f",
-                               val);
+               NOTIFICATION_ERR("Insert double : %f", val);
                return NOTIFICATION_ERROR_FROM_DB;
        }
 
@@ -743,7 +741,7 @@ static int _notification_noti_update_priv_id(sqlite3 * db, int rowid)
        return notification_db_exec(db, query);
 }
 
-int notification_noti_insert(notification_h noti)
+EXPORT_API int notification_noti_insert(notification_h noti)
 {
        sqlite3 *db = NULL;
        sqlite3_stmt *stmt = NULL;
@@ -754,6 +752,9 @@ int notification_noti_insert(notification_h noti)
 
        /* Open DB */
        db = notification_db_open(DBPATH);
+       if (!db) {
+               return NOTIFICATION_ERROR_FROM_DB;
+       }
 
        /* Initialize private ID */
        noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
@@ -855,6 +856,9 @@ int notification_noti_get_by_priv_id(notification_h noti, char *pkgname, int pri
 
        /* Open DB */
        db = notification_db_open(DBPATH);
+       if (!db) {
+               return NOTIFICATION_ERROR_FROM_DB;
+       }
 
        char *base_query = "select "
                         "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
@@ -901,7 +905,7 @@ err:
        return ret;
 }
 
-int notification_noti_update(notification_h noti)
+EXPORT_API int notification_noti_update(notification_h noti)
 {
        sqlite3 *db;
        sqlite3_stmt *stmt = NULL;
@@ -910,6 +914,9 @@ int notification_noti_update(notification_h noti)
 
        /* Open DB */
        db = notification_db_open(DBPATH);
+       if (!db) {
+               return NOTIFICATION_ERROR_FROM_DB;
+       }
 
        /* Check private ID is exist */
        ret = _notification_noti_check_priv_id(noti, db);
@@ -936,18 +943,12 @@ int notification_noti_update(notification_h noti)
        ret = _notification_noti_bind_query_double(stmt, "$progress_size",noti->progress_size);
        if (ret != NOTIFICATION_ERROR_NONE) {
                NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
-               if (stmt) {
-                       sqlite3_finalize(stmt);
-               }
-               return ret;
+               goto err;
        }
        ret = _notification_noti_bind_query_double(stmt, "$progress_percentage",noti->progress_percentage);
        if (ret != NOTIFICATION_ERROR_NONE) {
                NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
-               if (stmt) {
-                       sqlite3_finalize(stmt);
-               }
-               return ret;
+               goto err;
        }
 
        ret = sqlite3_step(stmt);
@@ -969,7 +970,7 @@ err:
        return ret;
 }
 
-int notification_noti_delete_all(notification_type_e type, const char *pkgname, int *num_deleted, int **list_deleted_rowid)
+EXPORT_API int notification_noti_delete_all(notification_type_e type, const char *pkgname, int *num_deleted, int **list_deleted_rowid)
 {
        int ret = NOTIFICATION_ERROR_NONE;
        int i = 0, data_cnt = 0;
@@ -982,6 +983,9 @@ int notification_noti_delete_all(notification_type_e type, const char *pkgname,
 
        /* Open DB */
        db = notification_db_open(DBPATH);
+       if (!db) {
+               return NOTIFICATION_ERROR_FROM_DB;
+       }
 
        if (pkgname == NULL) {
                if (type != NOTIFICATION_TYPE_NONE) {
@@ -999,6 +1003,9 @@ int notification_noti_delete_all(notification_type_e type, const char *pkgname,
                }
        }
 
+       if (num_deleted != NULL) {
+               *num_deleted = 0;
+       }
        if (list_deleted_rowid != NULL) {
                *list_deleted_rowid = NULL;
                snprintf(query, sizeof(query),
@@ -1016,8 +1023,22 @@ int notification_noti_delete_all(notification_type_e type, const char *pkgname,
 
                while(sqlite3_step(stmt) == SQLITE_ROW) {
                        if (data_cnt % 8 == 0) {
-                               *list_deleted_rowid =
-                                               (int *)realloc(*list_deleted_rowid, sizeof(int) * (data_cnt + 8 + 1));
+                               int *tmp;
+
+                               tmp = (int *)realloc(*list_deleted_rowid, sizeof(int) * (data_cnt + 8 + 1));
+                               if (tmp) {
+                                       *list_deleted_rowid = tmp;
+                               } else {
+                                       NOTIFICATION_ERR("Heap: %s\n", strerror(errno));
+                                       /*!
+                                        * \TODO
+                                        * How can I handle this?
+                                        */
+                                       free(*list_deleted_rowid);
+                                       *list_deleted_rowid = NULL;
+                                       ret = NOTIFICATION_ERROR_NO_MEMORY;
+                                       goto err;
+                               }
                        }
                        *((*list_deleted_rowid) + data_cnt) = sqlite3_column_int(stmt, 0);
                        data_cnt++;
@@ -1038,7 +1059,7 @@ int notification_noti_delete_all(notification_type_e type, const char *pkgname,
                        snprintf(query, sizeof(query), "%s where priv_id in (%s)", query_base, query_where);
 
                        NOTIFICATION_ERR("check : %s", query);
-                       notification_db_exec(db, query);
+                       ret = notification_db_exec(db, query);
                } else {
                        free(*list_deleted_rowid);
                        *list_deleted_rowid = NULL;
@@ -1052,7 +1073,7 @@ int notification_noti_delete_all(notification_type_e type, const char *pkgname,
                snprintf(query_base, sizeof(query_base), "delete from noti_list ");
                snprintf(query, sizeof(query), "%s %s", query_base, query_where);
 
-               notification_db_exec(db, query);
+               ret = notification_db_exec(db, query);
 
                if (num_deleted != NULL) {
                        *num_deleted = sqlite3_changes(db);
@@ -1093,7 +1114,13 @@ int notification_noti_delete_group_by_group_id(const char *pkgname,
 
        /* Open DB */
        db = notification_db_open(DBPATH);
+       if (!db) {
+               return NOTIFICATION_ERROR_FROM_DB;
+       }
 
+       if (num_deleted != NULL) {
+               *num_deleted = 0;
+       }
        if (list_deleted_rowid != NULL) {
                *list_deleted_rowid = NULL;
                snprintf(query, sizeof(query),
@@ -1111,8 +1138,16 @@ int notification_noti_delete_group_by_group_id(const char *pkgname,
 
                while(sqlite3_step(stmt) == SQLITE_ROW) {
                        if (data_cnt % 8 == 0) {
-                               *list_deleted_rowid =
-                                               (int *)realloc(*list_deleted_rowid, sizeof(int) * (data_cnt + 8 + 1));
+                               int *tmp;
+                               tmp = (int *)realloc(*list_deleted_rowid, sizeof(int) * (data_cnt + 8 + 1));
+                               if (tmp) {
+                                       *list_deleted_rowid = tmp;
+                               } else {
+                                       free(*list_deleted_rowid);
+                                       *list_deleted_rowid = NULL;
+                                       ret = NOTIFICATION_ERROR_NO_MEMORY;
+                                       goto err;
+                               }
                        }
                        *((*list_deleted_rowid) + data_cnt) = sqlite3_column_int(stmt, 0);
                        data_cnt++;
@@ -1133,7 +1168,7 @@ int notification_noti_delete_group_by_group_id(const char *pkgname,
                        snprintf(query, sizeof(query), "%s where priv_id in (%s)", query_base, query_where);
 
                        NOTIFICATION_ERR("check : %s", query);
-                       notification_db_exec(db, query);
+                       ret = notification_db_exec(db, query);
                } else {
                        free(*list_deleted_rowid);
                        *list_deleted_rowid = NULL;
@@ -1147,9 +1182,7 @@ int notification_noti_delete_group_by_group_id(const char *pkgname,
                snprintf(query, sizeof(query), "delete from noti_list %s", query_where);
 
                /* execute DB */
-               notification_db_exec(db, query);
-
-               return NOTIFICATION_ERROR_NONE;
+               ret = notification_db_exec(db, query);
        }
 
 err:
@@ -1169,6 +1202,7 @@ int notification_noti_delete_group_by_priv_id(const char *pkgname, int priv_id)
        sqlite3 *db = NULL;
        char query[NOTIFICATION_QUERY_MAX] = { 0, };
        int internal_group_id = 0;
+       int ret;
 
        /* Check pkgname is valid */
        if (pkgname == NULL) {
@@ -1177,6 +1211,9 @@ int notification_noti_delete_group_by_priv_id(const char *pkgname, int priv_id)
 
        /* Open DB */
        db = notification_db_open(DBPATH);
+       if (!db) {
+               return NOTIFICATION_ERROR_FROM_DB;
+       }
 
        /* Get internal group id using priv id */
        internal_group_id =
@@ -1189,20 +1226,19 @@ int notification_noti_delete_group_by_priv_id(const char *pkgname, int priv_id)
                 pkgname, internal_group_id);
 
        /* execute DB */
-       notification_db_exec(db, query);
+       ret = notification_db_exec(db, query);
 
        /* Close DB */
-       if (db) {
-               notification_db_close(&db);
-       }
+       notification_db_close(&db);
 
-       return NOTIFICATION_ERROR_NONE;
+       return ret;
 }
 
-int notification_noti_delete_by_priv_id(const char *pkgname, int priv_id)
+EXPORT_API int notification_noti_delete_by_priv_id(const char *pkgname, int priv_id)
 {
        sqlite3 *db = NULL;
        char query[NOTIFICATION_QUERY_MAX] = { 0, };
+       int ret;
 
        /* Check pkgname is valid */
        if (pkgname == NULL) {
@@ -1211,6 +1247,9 @@ int notification_noti_delete_by_priv_id(const char *pkgname, int priv_id)
 
        /* Open DB */
        db = notification_db_open(DBPATH);
+       if (!db) {
+               return NOTIFICATION_ERROR_FROM_DB;
+       }
 
        /* Make query */
        snprintf(query, sizeof(query), "delete from noti_list "
@@ -1218,14 +1257,14 @@ int notification_noti_delete_by_priv_id(const char *pkgname, int priv_id)
                 priv_id);
 
        /* execute DB */
-       notification_db_exec(db, query);
+       ret = notification_db_exec(db, query);
 
        /* Close DB */
        if (db) {
                notification_db_close(&db);
        }
 
-       return NOTIFICATION_ERROR_NONE;
+       return ret;
 }
 
 notification_error_e notification_noti_get_count(notification_type_e type,
@@ -1248,6 +1287,9 @@ notification_error_e notification_noti_get_count(notification_type_e type,
 
        /* Open DB */
        db = notification_db_open(DBPATH);
+       if (!db) {
+               return NOTIFICATION_ERROR_FROM_DB;
+       }
 
        /* Check current sim status */
        ret_vconf = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
@@ -1378,6 +1420,9 @@ notification_error_e notification_noti_get_grouping_list(notification_type_e typ
 
        /* Open DB */
        db = notification_db_open(DBPATH);
+       if (!db) {
+               return NOTIFICATION_ERROR_FROM_DB;
+       }
 
        /* Check current sim status */
        ret = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
@@ -1422,8 +1467,7 @@ notification_error_e notification_noti_get_grouping_list(notification_type_e typ
                goto err;
        }
 
-       ret = sqlite3_step(stmt);
-       while (ret == SQLITE_ROW) {
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
                /* Make notification list */
                noti = _notification_noti_get_item(stmt);
                if (noti != NULL) {
@@ -1438,8 +1482,6 @@ notification_error_e notification_noti_get_grouping_list(notification_type_e typ
                                break;
                        }
                }
-
-               ret = sqlite3_step(stmt);
        }
 
        ret = NOTIFICATION_ERROR_NONE;
@@ -1477,10 +1519,13 @@ notification_error_e notification_noti_get_detail_list(const char *pkgname,
        notification_h noti = NULL;
        int internal_count = 0;
        int internal_group_id = 0;
-       int status;
+       int status = 0; /* If the vconf_get_int failed, the status will be the garbage value */
 
        /* Open DB */
        db = notification_db_open(DBPATH);
+       if (!db) {
+               return NOTIFICATION_ERROR_FROM_DB;
+       }
 
        /* Check current sim status */
        ret = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
@@ -1535,8 +1580,7 @@ notification_error_e notification_noti_get_detail_list(const char *pkgname,
                goto err;
        }
 
-       ret = sqlite3_step(stmt);
-       while (ret == SQLITE_ROW) {
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
                /* Make notification list */
                noti = _notification_noti_get_item(stmt);
                if (noti != NULL) {
@@ -1551,8 +1595,6 @@ notification_error_e notification_noti_get_detail_list(const char *pkgname,
                                break;
                        }
                }
-
-               ret = sqlite3_step(stmt);
        }
 
        ret = NOTIFICATION_ERROR_NONE;