Merge from tizen 2.4 latest.
[platform/core/api/notification.git] / src / notification_noti.c
old mode 100755 (executable)
new mode 100644 (file)
index 825b0dd..6c3e7c6
@@ -3,7 +3,7 @@
  *
  * 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>, Youngsub Ko <ys4610.ko@samsung.com>
+ * 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.
 #include <stdlib.h>
 
 #include <vconf.h>
+#include <Ecore.h>
+#include <Elementary.h>
+#include <Eina.h>
+#include <pkgmgr-info.h>
+#include <package_manager.h>
 
 #include <notification.h>
 #include <notification_db.h>
+#include <notification_list.h>
 #include <notification_noti.h>
 #include <notification_debug.h>
-#include <notification_internal.h>
+#include <notification_private.h>
+#include <notification_setting.h>
+#include <notification_setting_internal.h>
 
 #define NOTI_BURST_DELETE_UNIT 10
 
+static void __free_and_set(void **target_ptr, void *new_ptr) {
+       if (target_ptr != NULL) {
+               if (*target_ptr != NULL) {
+                       free(*target_ptr);
+               }
+               *target_ptr = new_ptr;
+       }
+}
+
 static int _notification_noti_bind_query_text(sqlite3_stmt * stmt, const char *name,
                                         const char *str)
 {
@@ -80,20 +97,25 @@ static int _notification_noti_bind_query_double(sqlite3_stmt * stmt, const char
 
 static int _notification_noti_check_priv_id(notification_h noti, sqlite3 * db)
 {
+       int result = 0;
+       int ret = NOTIFICATION_ERROR_NONE;
+       char *query = NULL;
        sqlite3_stmt *stmt = NULL;
-       char query[NOTIFICATION_QUERY_MAX] = { 0, };
-       int ret = NOTIFICATION_ERROR_NONE, result = 0;
 
        /* Make query to check priv_id exist */
-       snprintf(query, sizeof(query),
-                "select count(*) from noti_list where caller_pkgname = '%s' and priv_id = %d",
+       query = sqlite3_mprintf("SELECT count(*) FROM noti_list WHERE caller_pkgname = '%s' AND priv_id = %d",
                 noti->caller_pkgname, noti->priv_id);
+       if (query == NULL) {
+               ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               goto err;
+       }
 
        ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
        if (ret != SQLITE_OK) {
                NOTIFICATION_ERR("Get count DB err(%d) : %s", ret,
                                 sqlite3_errmsg(db));
-               return NOTIFICATION_ERROR_FROM_DB;
+               ret = NOTIFICATION_ERROR_FROM_DB;
+               goto err;
        }
 
        ret = sqlite3_step(stmt);
@@ -107,96 +129,38 @@ static int _notification_noti_check_priv_id(notification_h noti, sqlite3 * db)
 
        /* If result > 0, there is priv_id in DB */
        if (result > 0) {
-               return NOTIFICATION_ERROR_ALREADY_EXIST_ID;
+               ret = NOTIFICATION_ERROR_ALREADY_EXIST_ID;
        }
 
-       return NOTIFICATION_ERROR_NONE;
-}
-
-static int _notification_noti_get_priv_id(notification_h noti, sqlite3 * db)
-{
-       sqlite3_stmt *stmt = NULL;
-       char query[NOTIFICATION_QUERY_MAX] = { 0, };
-       int ret = NOTIFICATION_ERROR_NONE, result = 0;
-
-       /* Make query to get max priv_id */
-       snprintf(query, sizeof(query),
-                "select max(priv_id) from noti_list where caller_pkgname = '%s'",
-                noti->caller_pkgname);
-
-       ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
-       if (ret != SQLITE_OK) {
-               NOTIFICATION_ERR("Get count DB err(%d) : %s", ret,
-                                sqlite3_errmsg(db));
-               return NOTIFICATION_ERROR_FROM_DB;
-       }
-
-       ret = sqlite3_step(stmt);
-       if (ret == SQLITE_ROW) {
-               result = sqlite3_column_int(stmt, 0);
-       } else {
-               result = 0;
-       }
-
-       sqlite3_finalize(stmt);
-
-       if (result < 0) {
-               return NOTIFICATION_ERROR_FROM_DB;
+err:
+       if (query) {
+               sqlite3_free(query);
        }
 
-       /* Increase result(max priv_id value) for next priv_id */
-       noti->priv_id = result + 1;
-
-       return NOTIFICATION_ERROR_NONE;
+       return ret;
 }
 
 static int _notification_noti_get_internal_group_id_by_priv_id(const char *pkgname,
                                                               int priv_id,
                                                               sqlite3 * db)
 {
+       char *query = NULL;
        sqlite3_stmt *stmt = NULL;
-       char query[NOTIFICATION_QUERY_MAX] = { 0, };
        int ret = NOTIFICATION_ERROR_NONE, result = 0;
 
-       snprintf(query, sizeof(query),
-                "select internal_group_id from noti_list where caller_pkgname = '%s' and priv_id = %d",
+       query = sqlite3_mprintf("SELECT internal_group_id FROM noti_list WHERE caller_pkgname = '%s' AND priv_id = %d",
                 pkgname, priv_id);
-
-       ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
-       if (ret != SQLITE_OK) {
-               NOTIFICATION_ERR("Get count DB err(%d) : %s", ret,
-                                sqlite3_errmsg(db));
-               return NOTIFICATION_ERROR_FROM_DB;
-       }
-
-       ret = sqlite3_step(stmt);
-       if (ret == SQLITE_ROW) {
-               result = sqlite3_column_int(stmt, 0);
-       } else {
-               result = 0;
+       if (query == NULL) {
+               ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               goto err;
        }
 
-       sqlite3_finalize(stmt);
-
-       return result;
-}
-
-static int _notification_noti_get_max_internal_group_id(notification_h noti,
-                                                       sqlite3 * db)
-{
-       sqlite3_stmt *stmt = NULL;
-       char query[NOTIFICATION_QUERY_MAX] = { 0, };
-       int ret = NOTIFICATION_ERROR_NONE, result = 0;
-
-       /* Get max internal group id */
-       snprintf(query, sizeof(query),
-                "select max(internal_group_id) from noti_list");
-
        ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
        if (ret != SQLITE_OK) {
                NOTIFICATION_ERR("Get count DB err(%d) : %s", ret,
                                 sqlite3_errmsg(db));
-               return NOTIFICATION_ERROR_FROM_DB;
+               ret = NOTIFICATION_ERROR_FROM_DB;
+               goto err;
        }
 
        ret = sqlite3_step(stmt);
@@ -206,107 +170,26 @@ static int _notification_noti_get_max_internal_group_id(notification_h noti,
                result = 0;
        }
 
-       sqlite3_finalize(stmt);
-
-       return result;
-}
-
-static int _notification_noti_get_internal_group_id(notification_h noti,
-                                                   sqlite3 * db)
-{
-       sqlite3_stmt *stmt = NULL;
-       char query[NOTIFICATION_QUERY_MAX] = { 0, };
-       int ret = NOTIFICATION_ERROR_NONE, result = 0;
-       const char *ret_title = NULL;
-       char buf_key[32] = { 0, };
-
-       if (noti->group_id == NOTIFICATION_GROUP_ID_NONE) {
-               /* If Group ID is NONE Get max internal group ID */
-               result = _notification_noti_get_max_internal_group_id(noti, db);
-               if (result < 0) {
-                       return NOTIFICATION_ERROR_FROM_DB;
-               }
-
-               /* Internal Group ID is max internal group ID + 1 */
-               noti->internal_group_id = result + 1;
-
-               return NOTIFICATION_ERROR_NONE;
-       } else if (noti->group_id == NOTIFICATION_GROUP_ID_DEFAULT) {
-               /* If Group ID is DEFAULT, Get internal group id if it exist */
-               if (noti->b_key != NULL) {
-                       snprintf(buf_key, sizeof(buf_key), "%d",
-                                NOTIFICATION_TEXT_TYPE_TITLE);
-
-                       ret_title = bundle_get_val(noti->b_key, buf_key);
-               }
-
-               if (ret_title == NULL && noti->b_text != NULL) {
-                       snprintf(buf_key, sizeof(buf_key), "%d",
-                                NOTIFICATION_TEXT_TYPE_TITLE);
-
-                       ret_title = bundle_get_val(noti->b_text, buf_key);
-               }
-
-               if (ret_title == NULL) {
-                       ret_title = noti->caller_pkgname;
-               }
-
-               snprintf(query, sizeof(query),
-                        "select internal_group_id from noti_list where title_key = $title_key and group_id = %d",
-                        NOTIFICATION_GROUP_ID_DEFAULT);
-       } else {
-               /* If Group ID is > DEFAULT, Get internal group id if it exit */
-               snprintf(query, sizeof(query),
-                        "select internal_group_id from noti_list where caller_pkgname = '%s' and group_id = %d",
-                        NOTIFICATION_CHECK_STR(noti->caller_pkgname),
-                        noti->group_id);
-       }
-
-       ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
-       if (ret != SQLITE_OK) {
-               NOTIFICATION_ERR("Select Query : %s", query);
-               NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
-                                sqlite3_errmsg(db));
-               if (stmt) {
-                       sqlite3_finalize(stmt);
-               }
-               return NOTIFICATION_ERROR_FROM_DB;
+err:
+       if (stmt) {
+               sqlite3_finalize(stmt);
        }
 
-       /* Bind query */
-       if (ret_title != NULL) {
-               ret =
-                   _notification_noti_bind_query_text(stmt, "$title_key",
-                                                 NOTIFICATION_CHECK_STR
-                                                 (ret_title));
-               if (ret != NOTIFICATION_ERROR_NONE) {
-                       NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
-                       if (stmt) {
-                               sqlite3_finalize(stmt);
-                       }
-                       return ret;
-               }
+       if (query) {
+               sqlite3_free(query);
        }
 
-       ret = sqlite3_step(stmt);
-       if (ret == SQLITE_ROW) {
-               result = sqlite3_column_int(stmt, 0);
-       } else {
-               /* If there is not internal_group_id, create new one */
-               result = _notification_noti_get_max_internal_group_id(noti, db);
-               result++;
+       if (ret != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_ERR("failed to internal group ID:%d", ret);
        }
 
-       sqlite3_finalize(stmt);
-
-       noti->internal_group_id = result;
-
-       return NOTIFICATION_ERROR_NONE;
+       return result;
 }
 
-static int _notification_noti_make_query(notification_h noti, char *query,
-                                        int query_size)
+static int _insertion_query_create(notification_h noti, char **query)
 {
+       int i = 0;
+       int b_encode_len = 0;
        char *args = NULL;
        char *group_args = NULL;
        char *b_image_path = NULL;
@@ -314,51 +197,63 @@ static int _notification_noti_make_query(notification_h noti, char *query,
        char *b_service_responding = NULL;
        char *b_service_single_launch = NULL;
        char *b_service_multi_launch = NULL;
+       char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
        char *b_text = NULL;
        char *b_key = NULL;
        char *b_format_args = NULL;
        int flag_simmode = 0;
 
+       if (query == NULL) {
+               return NOTIFICATION_ERROR_INVALID_PARAMETER;
+       }
+
        /* Decode bundle to insert DB */
        if (noti->args) {
-               bundle_encode(noti->args, (bundle_raw **) & args, NULL);
+               bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len);
        }
        if (noti->group_args) {
                bundle_encode(noti->group_args, (bundle_raw **) & group_args,
-                             NULL);
+                             &b_encode_len);
        }
 
        if (noti->b_execute_option) {
                bundle_encode(noti->b_execute_option,
-                             (bundle_raw **) & b_execute_option, NULL);
+                             (bundle_raw **) & b_execute_option, &b_encode_len);
        }
        if (noti->b_service_responding) {
                bundle_encode(noti->b_service_responding,
-                             (bundle_raw **) & b_service_responding, NULL);
+                             (bundle_raw **) & b_service_responding, &b_encode_len);
        }
        if (noti->b_service_single_launch) {
                bundle_encode(noti->b_service_single_launch,
-                             (bundle_raw **) & b_service_single_launch, NULL);
+                             (bundle_raw **) & b_service_single_launch, &b_encode_len);
        }
        if (noti->b_service_multi_launch) {
                bundle_encode(noti->b_service_multi_launch,
-                             (bundle_raw **) & b_service_multi_launch, NULL);
+                             (bundle_raw **) & b_service_multi_launch, &b_encode_len);
+       }
+
+       for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
+               if (noti->b_event_handler[i]) {
+                       bundle_encode(noti->b_event_handler[i],
+                                       (bundle_raw **) & b_event_handler[i], &b_encode_len);
+               }
        }
 
        if (noti->b_text) {
-               bundle_encode(noti->b_text, (bundle_raw **) & b_text, NULL);
+               bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
        }
        if (noti->b_key) {
-               bundle_encode(noti->b_key, (bundle_raw **) & b_key, NULL);
+               bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
        }
        if (noti->b_format_args) {
                bundle_encode(noti->b_format_args,
-                             (bundle_raw **) & b_format_args, NULL);
+                             (bundle_raw **) & b_format_args, &b_encode_len);
        }
 
        if (noti->b_image_path) {
                bundle_encode(noti->b_image_path,
-                             (bundle_raw **) & b_image_path, NULL);
+                             (bundle_raw **) & b_image_path, &b_encode_len);
        }
 
        /* Check only simmode property is enable */
@@ -367,37 +262,43 @@ static int _notification_noti_make_query(notification_h noti, char *query,
        }
 
        /* Make query */
-       snprintf(query, query_size, "insert into noti_list ("
+       *query = sqlite3_mprintf("INSERT INTO noti_list ("
                 "type, "
                 "layout, "
                 "caller_pkgname, launch_pkgname, "
                 "image_path, "
                 "group_id, internal_group_id, priv_id, "
                 "title_key, "
-                "b_text, b_key, b_format_args, num_format_args, "
+                "b_text, b_key, tag, b_format_args, num_format_args, "
                 "text_domain, text_dir, "
                 "time, insert_time, "
                 "args, group_args, "
                 "b_execute_option, "
                 "b_service_responding, b_service_single_launch, b_service_multi_launch, "
+                "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
+                "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
+                "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
                 "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
                 "flags_for_property, flag_simmode, display_applist, "
-                "progress_size, progress_percentage) values ("
+                "progress_size, progress_percentage, ongoing_flag, auto_remove) values ("
                 "%d, "
                 "%d, "
                 "'%s', '%s', "
                 "'%s', "
                 "%d, %d, %d, "
                 "$title_key, "
-                "'%s', '%s', '%s', %d, "
+                "'%s', '%s', $tag, '%s', %d, "
                 "'%s', '%s', "
                 "%d, %d, "
                 "'%s', '%s', "
                 "'%s', "
                 "'%s', '%s', '%s', "
+                "'%s', '%s', '%s', "
+                "'%s', '%s', '%s', "
+                "'%s', '%s', "
                 "%d, '%s', %d, '%s', %d, %d, %d, %d,"
                 "%d, %d, %d, "
-                "$progress_size, $progress_percentage)",
+                "$progress_size, $progress_percentage, %d, %d)",
                 noti->type,
                 noti->layout,
                 NOTIFICATION_CHECK_STR(noti->caller_pkgname),
@@ -414,6 +315,14 @@ static int _notification_noti_make_query(notification_h noti, char *query,
                 NOTIFICATION_CHECK_STR(b_service_responding),
                 NOTIFICATION_CHECK_STR(b_service_single_launch),
                 NOTIFICATION_CHECK_STR(b_service_multi_launch),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
                 noti->sound_type, NOTIFICATION_CHECK_STR(noti->sound_path),
                 noti->vibration_type,
                 NOTIFICATION_CHECK_STR(noti->vibration_path),
@@ -421,7 +330,9 @@ static int _notification_noti_make_query(notification_h noti, char *query,
                 noti->led_argb,
                 noti->led_on_ms,
                 noti->led_off_ms,
-                noti->flags_for_property, flag_simmode, noti->display_applist);
+                noti->flags_for_property, flag_simmode, noti->display_applist,
+                noti->ongoing_flag,
+                noti->auto_remove);
 
        /* Free decoded data */
        if (args) {
@@ -458,13 +369,18 @@ static int _notification_noti_make_query(notification_h noti, char *query,
                free(b_image_path);
        }
 
+       if (*query == NULL) {
+               return NOTIFICATION_ERROR_OUT_OF_MEMORY;
+       }
+
        return NOTIFICATION_ERROR_NONE;
 }
 
 
-static int _notification_noti_make_update_query(notification_h noti, char *query,
-                                        int query_size)
+static int _update_query_create(notification_h noti, char **query)
 {
+       int i = 0;
+       int b_encode_len = 0;
        char *args = NULL;
        char *group_args = NULL;
        char *b_image_path = NULL;
@@ -472,51 +388,63 @@ static int _notification_noti_make_update_query(notification_h noti, char *query
        char *b_service_responding = NULL;
        char *b_service_single_launch = NULL;
        char *b_service_multi_launch = NULL;
+       char *b_event_handler[NOTIFICATION_EVENT_TYPE_MAX] = { NULL , };
        char *b_text = NULL;
        char *b_key = NULL;
        char *b_format_args = NULL;
        int flag_simmode = 0;
 
+       if (query == NULL) {
+               return NOTIFICATION_ERROR_INVALID_PARAMETER;
+       }
+
        /* Decode bundle to update DB */
        if (noti->args) {
-               bundle_encode(noti->args, (bundle_raw **) & args, NULL);
+               bundle_encode(noti->args, (bundle_raw **) & args, &b_encode_len);
        }
        if (noti->group_args) {
                bundle_encode(noti->group_args, (bundle_raw **) & group_args,
-                             NULL);
+                             &b_encode_len);
        }
 
        if (noti->b_execute_option) {
                bundle_encode(noti->b_execute_option,
-                             (bundle_raw **) & b_execute_option, NULL);
+                             (bundle_raw **) & b_execute_option, &b_encode_len);
        }
        if (noti->b_service_responding) {
                bundle_encode(noti->b_service_responding,
-                             (bundle_raw **) & b_service_responding, NULL);
+                             (bundle_raw **) & b_service_responding, &b_encode_len);
        }
        if (noti->b_service_single_launch) {
                bundle_encode(noti->b_service_single_launch,
-                             (bundle_raw **) & b_service_single_launch, NULL);
+                             (bundle_raw **) & b_service_single_launch, &b_encode_len);
        }
        if (noti->b_service_multi_launch) {
                bundle_encode(noti->b_service_multi_launch,
-                             (bundle_raw **) & b_service_multi_launch, NULL);
+                             (bundle_raw **) & b_service_multi_launch, &b_encode_len);
+       }
+
+       for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
+               if (noti->b_event_handler[i]) {
+                       bundle_encode(noti->b_event_handler[i],
+                                       (bundle_raw **) & b_event_handler[i], &b_encode_len);
+               }
        }
 
        if (noti->b_text) {
-               bundle_encode(noti->b_text, (bundle_raw **) & b_text, NULL);
+               bundle_encode(noti->b_text, (bundle_raw **) & b_text, &b_encode_len);
        }
        if (noti->b_key) {
-               bundle_encode(noti->b_key, (bundle_raw **) & b_key, NULL);
+               bundle_encode(noti->b_key, (bundle_raw **) & b_key, &b_encode_len);
        }
        if (noti->b_format_args) {
                bundle_encode(noti->b_format_args,
-                             (bundle_raw **) & b_format_args, NULL);
+                             (bundle_raw **) & b_format_args, &b_encode_len);
        }
 
        if (noti->b_image_path) {
                bundle_encode(noti->b_image_path,
-                             (bundle_raw **) & b_image_path, NULL);
+                             (bundle_raw **) & b_image_path, &b_encode_len);
        }
 
        /* Check only simmode property is enable */
@@ -525,12 +453,12 @@ static int _notification_noti_make_update_query(notification_h noti, char *query
        }
 
        /* Make query */
-       snprintf(query, query_size, "update noti_list set "
+       *query = sqlite3_mprintf("UPDATE noti_list SET "
                 "type = %d, "
                 "layout = %d, "
                 "launch_pkgname = '%s', "
                 "image_path = '%s', "
-                "b_text = '%s', b_key = '%s', "
+                "b_text = '%s', b_key = '%s', tag = $tag, "
                 "b_format_args = '%s', num_format_args = %d, "
                 "text_domain = '%s', text_dir = '%s', "
                 "time = %d, insert_time = %d, "
@@ -539,13 +467,22 @@ static int _notification_noti_make_update_query(notification_h noti, char *query
                 "b_service_responding = '%s', "
                 "b_service_single_launch = '%s', "
                 "b_service_multi_launch = '%s', "
+                "b_event_handler_click_on_button_1 = '%s', "
+                "b_event_handler_click_on_button_2= '%s', "
+                "b_event_handler_click_on_button_3= '%s', "
+                "b_event_handler_click_on_button_4= '%s', "
+                "b_event_handler_click_on_button_5= '%s', "
+                "b_event_handler_click_on_button_6= '%s', "
+                "b_event_handler_click_on_icon= '%s', "
+                "b_event_handler_click_on_thumbnail= '%s', "
                 "sound_type = %d, sound_path = '%s', "
                 "vibration_type = %d, vibration_path = '%s', "
                 "led_operation = %d, led_argb = %d, "
                 "led_on_ms = %d, led_off_ms = %d, "
                 "flags_for_property = %d, flag_simmode = %d, "
                 "display_applist = %d, "
-                "progress_size = $progress_size, progress_percentage = $progress_percentage "
+                "progress_size = $progress_size, progress_percentage = $progress_percentage, "
+                "ongoing_flag = %d, auto_remove = %d "
                 "where priv_id = %d ",
                 noti->type,
                 noti->layout,
@@ -561,6 +498,14 @@ static int _notification_noti_make_update_query(notification_h noti, char *query
                 NOTIFICATION_CHECK_STR(b_service_responding),
                 NOTIFICATION_CHECK_STR(b_service_single_launch),
                 NOTIFICATION_CHECK_STR(b_service_multi_launch),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_1]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_2]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_3]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_4]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_5]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_BUTTON_6]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_ICON]),
+               NOTIFICATION_CHECK_STR(b_event_handler[NOTIFICATION_EVENT_TYPE_CLICK_ON_THUMBNAIL]),
                 noti->sound_type, NOTIFICATION_CHECK_STR(noti->sound_path),
                 noti->vibration_type,
                 NOTIFICATION_CHECK_STR(noti->vibration_path),
@@ -569,6 +514,7 @@ static int _notification_noti_make_update_query(notification_h noti, char *query
                 noti->led_on_ms,
                 noti->led_off_ms,
                 noti->flags_for_property, flag_simmode, noti->display_applist,
+                noti->ongoing_flag, noti->auto_remove,
                 noti->priv_id);
 
        /* Free decoded data */
@@ -606,11 +552,16 @@ static int _notification_noti_make_update_query(notification_h noti, char *query
                free(b_image_path);
        }
 
+       if (*query == NULL) {
+               return NOTIFICATION_ERROR_OUT_OF_MEMORY;
+       }
+
        return NOTIFICATION_ERROR_NONE;
 }
 
 static void _notification_noti_populate_from_stmt(sqlite3_stmt * stmt, notification_h noti) {
        int col = 0;
+       int i = 0;
 
        if (stmt == NULL || noti == NULL) {
                return ;
@@ -618,20 +569,21 @@ static void _notification_noti_populate_from_stmt(sqlite3_stmt * stmt, notificat
 
        noti->type = sqlite3_column_int(stmt, col++);
        noti->layout = sqlite3_column_int(stmt, col++);
-       noti->caller_pkgname = notification_db_column_text(stmt, col++);
-       noti->launch_pkgname = notification_db_column_text(stmt, col++);
+       __free_and_set((void **)&(noti->caller_pkgname), notification_db_column_text(stmt, col++));
+       __free_and_set((void **)&(noti->launch_pkgname), notification_db_column_text(stmt, col++));
        noti->b_image_path = notification_db_column_bundle(stmt, col++);
        noti->group_id = sqlite3_column_int(stmt, col++);
        noti->internal_group_id = 0;
        noti->priv_id = sqlite3_column_int(stmt, col++);
+       __free_and_set((void **)&(noti->tag), notification_db_column_text(stmt, col++));
 
        noti->b_text = notification_db_column_bundle(stmt, col++);
        noti->b_key = notification_db_column_bundle(stmt, col++);
        noti->b_format_args = notification_db_column_bundle(stmt, col++);
        noti->num_format_args = sqlite3_column_int(stmt, col++);
 
-       noti->domain = notification_db_column_text(stmt, col++);
-       noti->dir = notification_db_column_text(stmt, col++);
+       __free_and_set((void **)&(noti->domain), notification_db_column_text(stmt, col++));
+       __free_and_set((void **)&(noti->dir), notification_db_column_text(stmt, col++));
        noti->time = sqlite3_column_int(stmt, col++);
        noti->insert_time = sqlite3_column_int(stmt, col++);
        noti->args = notification_db_column_bundle(stmt, col++);
@@ -644,10 +596,14 @@ static void _notification_noti_populate_from_stmt(sqlite3_stmt * stmt, notificat
        noti->b_service_multi_launch =
            notification_db_column_bundle(stmt, col++);
 
+       for (i = 0; i < NOTIFICATION_EVENT_TYPE_MAX; i++) {
+               noti->b_event_handler[i] = notification_db_column_bundle(stmt, col++);
+       }
+
        noti->sound_type = sqlite3_column_int(stmt, col++);
-       noti->sound_path = notification_db_column_text(stmt, col++);
+       __free_and_set((void **)&(noti->sound_path), notification_db_column_text(stmt, col++));
        noti->vibration_type = sqlite3_column_int(stmt, col++);
-       noti->vibration_path = notification_db_column_text(stmt, col++);
+       __free_and_set((void **)&(noti->vibration_path), notification_db_column_text(stmt, col++));
        noti->led_operation = sqlite3_column_int(stmt, col++);
        noti->led_argb = sqlite3_column_int(stmt, col++);
        noti->led_on_ms = sqlite3_column_int(stmt, col++);
@@ -658,6 +614,9 @@ static void _notification_noti_populate_from_stmt(sqlite3_stmt * stmt, notificat
        noti->progress_size = sqlite3_column_double(stmt, col++);
        noti->progress_percentage = sqlite3_column_double(stmt, col++);
 
+       noti->ongoing_flag = sqlite3_column_int(stmt, col++);
+       noti->auto_remove = sqlite3_column_int(stmt, col++);
+
        noti->app_icon_path = NULL;
        noti->app_name = NULL;
        noti->temp_title = NULL;
@@ -668,7 +627,7 @@ static notification_h _notification_noti_get_item(sqlite3_stmt * stmt)
 {
        notification_h noti = NULL;
 
-       noti = malloc(sizeof(struct _notification));
+       noti = (notification_h) calloc(1, sizeof(struct _notification));
        if (noti == NULL) {
                return NULL;
        }
@@ -685,7 +644,7 @@ int notification_noti_set_tag(const char *tag, char *value, char *buf, int buf_l
        len_total += (strlen(tag) * 2) + 5 + strlen(value) + 1;
 
        if (buf_len <= len_total)
-               return NOTIFICATION_ERROR_INVALID_DATA;
+               return NOTIFICATION_ERROR_INVALID_PARAMETER;
 
        snprintf(buf, buf_len, "<%s>%s</%s>", tag, value, tag);
 
@@ -737,32 +696,236 @@ int notification_noti_get_tag_type(const char *tagged_str)
 
 static int _notification_noti_update_priv_id(sqlite3 * db, int rowid)
 {
-       char query[128] = { 0, };
+       int ret = NOTIFICATION_ERROR_NONE;
+       char *query = NULL;
 
        if (db == NULL) {
-               return NOTIFICATION_ERROR_INVALID_DATA;
+               ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
+               goto err;
        }
 
-       snprintf(query, sizeof(query), "update noti_list set "
-                       "priv_id = %d, internal_group_id = %d where rowid = %d",
+       query = sqlite3_mprintf("UPDATE noti_list SET "
+                       "priv_id = %d, internal_group_id = %d WHERE rowid = %d",
                        rowid, rowid, rowid);
+       if (query == NULL) {
+               ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               goto err;
+       }
+
+       ret = notification_db_exec(db, query, NULL);
+
+err:
+       if (query) {
+               sqlite3_free(query);
+       }
 
-       return notification_db_exec(db, query, NULL);
+       return ret;
+}
+
+
+static int _get_package_id_by_app_id(const char *app_id, char **package_id)
+{
+       int err = NOTIFICATION_ERROR_NONE;
+       int retval;
+       char *pkg_id = NULL;
+       char *pkg_id_dup = NULL;
+       pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo = NULL;
+
+       if (app_id == NULL || package_id == NULL) {
+               NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
+               err = NOTIFICATION_ERROR_INVALID_PARAMETER;
+               goto out;
+       }
+
+       if ((retval = pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo)) != PMINFO_R_OK) {
+               NOTIFICATION_ERR("pkgmgrinfo_appinfo_get_appinfo failed [%d]", retval);
+               err = NOTIFICATION_ERROR_INVALID_OPERATION;
+               goto out;
+       }
+
+       if ((retval = pkgmgrinfo_appinfo_get_pkgname(pkgmgrinfo_appinfo, &pkg_id)) != PMINFO_R_OK || pkg_id == NULL) {
+               NOTIFICATION_ERR("pkgmgrinfo_appinfo_get_pkgname failed [%d]", retval);
+               err = NOTIFICATION_ERROR_INVALID_OPERATION;
+               goto out;
+       }
+
+       pkg_id_dup = strdup(pkg_id);
+
+       if (pkg_id_dup == NULL) {
+               NOTIFICATION_ERR("strdup failed");
+               err = NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               goto out;
+       }
+
+       *package_id = pkg_id_dup;
+
+out:
+       if (pkgmgrinfo_appinfo)
+               pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
+
+       return err;
+}
+
+static bool _is_allowed_to_notify(const char *caller_package_name)
+{
+       notification_setting_h setting = NULL;
+       int err;
+       char *package_id = NULL;
+       bool ret = true;
+
+       err = notification_setting_get_setting_by_package_name(caller_package_name, &setting);
+       if (err != NOTIFICATION_ERROR_NONE) {
+               /* Retry with package id */
+               err = _get_package_id_by_app_id (caller_package_name, &package_id);
+
+               if (err != NOTIFICATION_ERROR_NONE || package_id == NULL) {
+                       NOTIFICATION_ERR("_get_package_id_by_app_id failed [%d]", err);
+                       goto out;
+               }
+               else {
+                       err = notification_setting_get_setting_by_package_name(package_id, &setting);
+                       if (err != NOTIFICATION_ERROR_NONE) {
+                               NOTIFICATION_ERR("notification_setting_get_setting_by_package_name failed [%d]", err);
+                               goto out;
+                       }
+               }
+       }
+
+       err = notification_setting_get_allow_to_notify(setting, &ret);
+       if (err != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_ERR("notification_setting_get_allow_to_notify failed [%d]", err);
+               goto out;
+       }
+
+       if (ret != true) {
+               NOTIFICATION_DBG("[%s] is not allowed to notify", caller_package_name);
+       }
+
+out:
+       if (package_id) {
+               free(package_id);
+       }
+
+       if (setting) {
+               notification_setting_free_notification(setting);
+       }
+
+       return ret;
+}
+
+static int _handle_do_not_disturb_option(notification_h noti)
+{
+       int err = NOTIFICATION_ERROR_NONE;
+       bool do_not_disturb = false;
+       bool do_not_disturb_exception = false;
+       char *package_id = NULL;
+       notification_system_setting_h system_setting = NULL;
+       notification_setting_h setting = NULL;
+
+       if (noti == NULL) {
+               NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
+               err = NOTIFICATION_ERROR_INVALID_PARAMETER;
+               goto out;
+       }
+
+       /* Get system setting */
+       if ((err = notification_system_setting_load_system_setting(&system_setting)) != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_ERR("notification_system_setting_load_system_setting failed [%d]", err);
+               goto out;
+       }
+
+       if ((err = notification_system_setting_get_do_not_disturb(system_setting, &do_not_disturb)) != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_ERR("notification_system_setting_get_do_not_disturb failed [%d]", err);
+               goto out;
+       }
+
+       NOTIFICATION_DBG("do_not_disturb [%d]", do_not_disturb);
+
+       if (do_not_disturb) {
+               /* Check exception option of the caller package */
+               err = notification_setting_get_setting_by_package_name(noti->caller_pkgname, &setting);
+
+               if (err != NOTIFICATION_ERROR_NONE) {
+                       /* Retry with package id */
+                       err = _get_package_id_by_app_id (noti->caller_pkgname, &package_id);
+
+                       if (err != NOTIFICATION_ERROR_NONE || package_id == NULL) {
+                               NOTIFICATION_ERR("_get_package_id_by_app_id failed [%d]", err);
+                               goto out;
+                       }
+                       else {
+                               err = notification_setting_get_setting_by_package_name(package_id, &setting);
+                               if (err != NOTIFICATION_ERROR_NONE) {
+                                       NOTIFICATION_ERR("notification_setting_get_setting_by_package_name failed [%d]", err);
+                                       goto out;
+                               }
+                       }
+               }
+
+               err = notification_setting_get_do_not_disturb_except(setting, &do_not_disturb_exception);
+               if (err != NOTIFICATION_ERROR_NONE) {
+                       NOTIFICATION_ERR("notification_setting_get_allow_to_notify failed [%d]", err);
+                       goto out;
+               }
+
+               if (do_not_disturb_exception == false) {
+                       /* do_not_disturb is ON and do_not_disturb_exception is OFF */
+                       /* Then add this notification only on quick panel and indicator*/
+                       noti->display_applist = noti->display_applist & (NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY | NOTIFICATION_DISPLAY_APP_INDICATOR);
+                       /* and reset all sound and vibration and led options*/
+                       noti->sound_type = NOTIFICATION_SOUND_TYPE_NONE;
+                       SAFE_FREE(noti->sound_path);
+                       noti->vibration_type = NOTIFICATION_VIBRATION_TYPE_NONE;
+                       SAFE_FREE(noti->vibration_path);
+                       noti->led_operation = NOTIFICATION_LED_OP_OFF;
+                       noti->led_argb = 0;
+                       noti->led_on_ms = 0;
+                       noti->led_off_ms = 0;
+               }
+
+       }
+
+out:
+       SAFE_FREE(package_id);
+
+       if (system_setting) {
+               notification_system_setting_free_system_setting(system_setting);
+       }
+
+       if (setting) {
+               notification_setting_free_notification(setting);
+       }
+
+       return err;
 }
 
 EXPORT_API int notification_noti_insert(notification_h noti)
 {
+       int ret = 0;
        sqlite3 *db = NULL;
        sqlite3_stmt *stmt = NULL;
-       char query[NOTIFICATION_QUERY_MAX] = { 0, };
-       int ret = 0;
+       char *query = NULL;
        char buf_key[32] = { 0, };
-       const char *title_key = NULL;
+       char *title_key = NULL;
+
+       if (noti == NULL) {
+               NOTIFICATION_ERR("NOTIFICATION_ERROR_INVALID_PARAMETER");
+               return NOTIFICATION_ERROR_INVALID_PARAMETER;
+       }
+
+       if (_is_allowed_to_notify((const char*)noti->caller_pkgname) == false) {
+               NOTIFICATION_DBG("[%s] is not allowed to notify", noti->caller_pkgname);
+               return NOTIFICATION_ERROR_PERMISSION_DENIED;
+       }
+
+       if (_handle_do_not_disturb_option(noti) != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_WARN("_handle_do_not_disturb_option failed");
+       }
 
        /* Open DB */
        db = notification_db_open(DBPATH);
        if (!db) {
-               return NOTIFICATION_ERROR_FROM_DB;
+               return get_last_result();
        }
 
        /* Initialize private ID */
@@ -771,7 +934,7 @@ EXPORT_API int notification_noti_insert(notification_h noti)
        noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
 
        /* make query */
-       ret = _notification_noti_make_query(noti, query, sizeof(query));
+       ret = _insertion_query_create(noti, &query);
        if (ret != NOTIFICATION_ERROR_NONE) {
                goto err;
        }
@@ -790,14 +953,14 @@ EXPORT_API int notification_noti_insert(notification_h noti)
                snprintf(buf_key, sizeof(buf_key), "%d",
                         NOTIFICATION_TEXT_TYPE_TITLE);
 
-               title_key = bundle_get_val(noti->b_key, buf_key);
+               bundle_get_str(noti->b_key, buf_key, &title_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);
+               bundle_get_str(noti->b_text, buf_key, &title_key);
        }
 
        if (title_key == NULL) {
@@ -805,6 +968,11 @@ EXPORT_API int notification_noti_insert(notification_h noti)
        }
 
        /* Bind query */
+       ret = _notification_noti_bind_query_text(stmt, "$tag", noti->tag);
+       if (ret != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
+               goto err;
+       }
        ret = _notification_noti_bind_query_text(stmt, "$title_key", title_key);
        if (ret != NOTIFICATION_ERROR_NONE) {
                NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
@@ -848,41 +1016,52 @@ err:
                notification_db_close(&db);
        }
 
+       if (query) {
+               sqlite3_free(query);
+       }
+
        return ret;
 }
 
 int notification_noti_get_by_priv_id(notification_h noti, char *pkgname, int priv_id)
 {
+       int ret = 0;
+       char *query = NULL;
        sqlite3 *db = NULL;
        sqlite3_stmt *stmt = NULL;
-       char query[NOTIFICATION_QUERY_MAX] = { 0, };
-       int ret = 0;
 
        if (priv_id < 0 || noti == NULL) {
-               ret = NOTIFICATION_ERROR_INVALID_DATA;
+               ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
                goto err;
        }
 
        /* Open DB */
        db = notification_db_open(DBPATH);
        if (!db) {
-               return NOTIFICATION_ERROR_FROM_DB;
+               return get_last_result();
        }
 
        char *base_query = "select "
                         "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
-                        "b_text, b_key, b_format_args, num_format_args, "
+                        "tag, b_text, b_key, b_format_args, num_format_args, "
                         "text_domain, text_dir, time, insert_time, args, group_args, "
                         "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
+                        "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
+                        "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
+                        "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
                         "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
-                        "flags_for_property, display_applist, progress_size, progress_percentage "
+                        "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
                         "from noti_list ";
 
        if (pkgname != NULL) {
-               snprintf(query, sizeof(query), "%s where caller_pkgname = '%s' and priv_id = %d",
+               query = sqlite3_mprintf("%s where caller_pkgname = '%s' and priv_id = %d",
                                base_query ,pkgname, priv_id);
        } else {
-               snprintf(query, sizeof(query), "%s where priv_id = %d", base_query,  priv_id);
+               query = sqlite3_mprintf("%s where priv_id = %d", base_query,  priv_id);
+       }
+       if (query == NULL) {
+               ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               goto err;
        }
 
        ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
@@ -902,6 +1081,101 @@ int notification_noti_get_by_priv_id(notification_h noti, char *pkgname, int pri
                ret = NOTIFICATION_ERROR_FROM_DB;
        }
 err:
+       if (query) {
+               sqlite3_free(query);
+       }
+
+       if (stmt) {
+               sqlite3_finalize(stmt);
+       }
+
+       /* Close DB */
+       if (db != NULL) {
+               notification_db_close(&db);
+       }
+
+       return ret;
+}
+
+EXPORT_API int notification_noti_get_by_tag(notification_h noti, char *pkgname, char* tag)
+{
+       int ret = 0;
+       sqlite3 *db = NULL;
+       sqlite3_stmt *stmt = NULL;
+
+       if (tag == NULL || noti == NULL) {
+               ret = NOTIFICATION_ERROR_INVALID_PARAMETER;
+               goto err;
+       }
+
+       /* Open DB */
+       db = notification_db_open(DBPATH);
+       if (!db) {
+               return get_last_result();
+       }
+
+       if (pkgname != NULL) {
+               ret = sqlite3_prepare_v2(db, "select "
+                        "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
+                        "tag, b_text, b_key, b_format_args, num_format_args, "
+                        "text_domain, text_dir, time, insert_time, args, group_args, "
+                        "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
+                        "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
+                        "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
+                        "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
+                        "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
+                        "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
+                        "from noti_list where caller_pkgname = ? and tag = ?", -1, &stmt, NULL);
+               if (ret != SQLITE_OK) {
+                       NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
+                       return NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               }
+
+               ret = sqlite3_bind_text(stmt, 1, pkgname, -1, SQLITE_TRANSIENT);
+               if (ret != SQLITE_OK) {
+                       NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
+                       goto err;
+               }
+
+               ret = sqlite3_bind_text(stmt, 2,  tag, -1, SQLITE_TRANSIENT);
+               if (ret != SQLITE_OK) {
+                       NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
+                       goto err;
+               } 
+       } else {
+               ret = sqlite3_prepare_v2(db, "select "
+                        "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
+                        "tag, b_text, b_key, b_format_args, num_format_args, "
+                        "text_domain, text_dir, time, insert_time, args, group_args, "
+                        "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
+                        "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
+                        "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
+                        "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
+                        "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
+                        "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
+                        "from noti_list where  tag = ?", -1, &stmt, NULL);
+               if (ret != SQLITE_OK) {
+                       NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
+                       return NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               }
+
+               ret = sqlite3_bind_text(stmt, 1, tag, -1, SQLITE_TRANSIENT);
+               if (ret != SQLITE_OK) {
+                       NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
+                       goto err;
+               }
+       }
+
+       ret = sqlite3_step(stmt);
+       if (ret == SQLITE_ROW) {
+               _notification_noti_populate_from_stmt(stmt, noti);
+               ret = NOTIFICATION_ERROR_NONE;
+       } else {
+               ret = NOTIFICATION_ERROR_FROM_DB;
+       }
+
+err:
+
        if (stmt) {
                sqlite3_finalize(stmt);
        }
@@ -916,15 +1190,24 @@ err:
 
 EXPORT_API int notification_noti_update(notification_h noti)
 {
+       int ret = 0;
        sqlite3 *db;
        sqlite3_stmt *stmt = NULL;
-       char query[NOTIFICATION_QUERY_MAX] = { 0, };
-       int ret = 0;
+       char *query = NULL;
 
        /* Open DB */
        db = notification_db_open(DBPATH);
        if (!db) {
-               return NOTIFICATION_ERROR_FROM_DB;
+               return get_last_result();
+       }
+
+       if (_is_allowed_to_notify((const char*)noti->caller_pkgname) == false) {
+               NOTIFICATION_DBG("[%s] is not allowed to notify", noti->caller_pkgname);
+               return NOTIFICATION_ERROR_PERMISSION_DENIED;
+       }
+
+       if (_handle_do_not_disturb_option(noti) != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_WARN("_handle_do_not_disturb_option failed");
        }
 
        /* Check private ID is exist */
@@ -935,7 +1218,7 @@ EXPORT_API int notification_noti_update(notification_h noti)
        }
 
        /* make update query */
-       ret = _notification_noti_make_update_query(noti, query, sizeof(query));
+       ret = _update_query_create(noti, &query);
        if (ret != NOTIFICATION_ERROR_NONE) {
                goto err;
        }
@@ -949,6 +1232,11 @@ EXPORT_API int notification_noti_update(notification_h noti)
                goto err;
        }
 
+       ret = _notification_noti_bind_query_text(stmt, "$tag", noti->tag);
+       if (ret != NOTIFICATION_ERROR_NONE) {
+               NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
+               goto err;
+       }
        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));
@@ -976,6 +1264,10 @@ err:
                notification_db_close(&db);
        }
 
+       if (query) {
+               sqlite3_free(query);
+       }
+
        return ret;
 }
 
@@ -994,7 +1286,7 @@ EXPORT_API int notification_noti_delete_all(notification_type_e type, const char
        /* Open DB */
        db = notification_db_open(DBPATH);
        if (!db) {
-               return NOTIFICATION_ERROR_FROM_DB;
+               return get_last_result();
        }
 
        if (pkgname == NULL) {
@@ -1046,7 +1338,7 @@ EXPORT_API int notification_noti_delete_all(notification_type_e type, const char
                                         */
                                        free(*list_deleted_rowid);
                                        *list_deleted_rowid = NULL;
-                                       ret = NOTIFICATION_ERROR_NO_MEMORY;
+                                       ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
                                        goto err;
                                }
                        }
@@ -1128,7 +1420,7 @@ int notification_noti_delete_group_by_group_id(const char *pkgname,
 
        /* Check pkgname is valid */
        if (pkgname == NULL) {
-               return NOTIFICATION_ERROR_INVALID_DATA;
+               return NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
        snprintf(query_where, sizeof(query_where),
@@ -1137,7 +1429,7 @@ 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;
+               return get_last_result();
        }
 
        if (num_deleted != NULL) {
@@ -1167,7 +1459,7 @@ int notification_noti_delete_group_by_group_id(const char *pkgname,
                                } else {
                                        free(*list_deleted_rowid);
                                        *list_deleted_rowid = NULL;
-                                       ret = NOTIFICATION_ERROR_NO_MEMORY;
+                                       ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
                                        goto err;
                                }
                        }
@@ -1239,13 +1531,13 @@ int notification_noti_delete_group_by_priv_id(const char *pkgname, int priv_id)
 
        /* Check pkgname is valid */
        if (pkgname == NULL) {
-               return NOTIFICATION_ERROR_INVALID_DATA;
+               return NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
        /* Open DB */
        db = notification_db_open(DBPATH);
        if (!db) {
-               return NOTIFICATION_ERROR_FROM_DB;
+               return get_last_result();
        }
 
        /* Get internal group id using priv id */
@@ -1275,13 +1567,13 @@ EXPORT_API int notification_noti_delete_by_priv_id(const char *pkgname, int priv
 
        /* Check pkgname is valid */
        if (pkgname == NULL) {
-               return NOTIFICATION_ERROR_INVALID_DATA;
+               return NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
        /* Open DB */
        db = notification_db_open(DBPATH);
        if (!db) {
-               return NOTIFICATION_ERROR_FROM_DB;
+               return get_last_result();
        }
 
        /* Make query */
@@ -1308,13 +1600,13 @@ EXPORT_API int notification_noti_delete_by_priv_id_get_changes(const char *pkgna
 
        /* Check pkgname is valid */
        if (pkgname == NULL) {
-               return NOTIFICATION_ERROR_INVALID_DATA;
+               return NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
        /* Open DB */
        db = notification_db_open(DBPATH);
        if (!db) {
-               return NOTIFICATION_ERROR_FROM_DB;
+               return get_last_result();
        }
 
        /* Make query */
@@ -1337,7 +1629,7 @@ EXPORT_API int notification_noti_delete_by_priv_id_get_changes(const char *pkgna
        return ret;
 }
 
-notification_error_e notification_noti_get_count(notification_type_e type,
+int notification_noti_get_count(notification_type_e type,
                                                 const char *pkgname,
                                                 int group_id, int priv_id,
                                                 int *count)
@@ -1358,7 +1650,7 @@ 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;
+               return get_last_result();
        }
 
        /* Check current sim status */
@@ -1471,7 +1763,7 @@ err:
        return ret;
 }
 
-notification_error_e notification_noti_get_grouping_list(notification_type_e type,
+int notification_noti_get_grouping_list(notification_type_e type,
                                                         int count,
                                                         notification_list_h *
                                                         list)
@@ -1491,7 +1783,7 @@ 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;
+               return get_last_result();
        }
 
        /* Check current sim status */
@@ -1500,11 +1792,14 @@ notification_error_e notification_noti_get_grouping_list(notification_type_e typ
        /* Make query */
        snprintf(query_base, sizeof(query_base), "select "
                 "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
-                "b_text, b_key, b_format_args, num_format_args, "
+                "tag, b_text, b_key, b_format_args, num_format_args, "
                 "text_domain, text_dir, time, insert_time, args, group_args, "
                 "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
+                "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
+                "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
+                "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
                 "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
-                "flags_for_property, display_applist, progress_size, progress_percentage "
+                "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
                 "from noti_list ");
 
        if (status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
@@ -1573,7 +1868,7 @@ err:
        return ret;
 }
 
-notification_error_e notification_noti_get_detail_list(const char *pkgname,
+int notification_noti_get_detail_list(const char *pkgname,
                                                       int group_id,
                                                       int priv_id, int count,
                                                       notification_list_h *list)
@@ -1594,7 +1889,7 @@ notification_error_e notification_noti_get_detail_list(const char *pkgname,
        /* Open DB */
        db = notification_db_open(DBPATH);
        if (!db) {
-               return NOTIFICATION_ERROR_FROM_DB;
+               return get_last_result();
        }
 
        /* Check current sim status */
@@ -1603,22 +1898,23 @@ notification_error_e notification_noti_get_detail_list(const char *pkgname,
        /* Make query */
        snprintf(query_base, sizeof(query_base), "select "
                 "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
-                "b_text, b_key, b_format_args, num_format_args, "
+                "tag, b_text, b_key, b_format_args, num_format_args, "
                 "text_domain, text_dir, time, insert_time, args, group_args, "
                 "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
+                "b_event_handler_click_on_button_1, b_event_handler_click_on_button_2, b_event_handler_click_on_button_3, "
+                "b_event_handler_click_on_button_4, b_event_handler_click_on_button_5, b_event_handler_click_on_button_6, "
+                "b_event_handler_click_on_icon, b_event_handler_click_on_thumbnail, "
                 "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
-                "flags_for_property, display_applist, progress_size, progress_percentage "
+                "flags_for_property, display_applist, progress_size, progress_percentage, ongoing_flag, auto_remove "
                 "from noti_list ");
 
        if (priv_id == NOTIFICATION_PRIV_ID_NONE && group_id == NOTIFICATION_GROUP_ID_NONE) {
                if (status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
                        snprintf(query_where, sizeof(query_where),
-                                "where  caller_pkgname = '%s' ",
-                                pkgname, internal_group_id);
+                                "where  caller_pkgname = '%s' ", pkgname);
                } else {
                        snprintf(query_where, sizeof(query_where),
-                                "where  caller_pkgname = '%s' and flag_simmode = 0 ",
-                                pkgname, internal_group_id);
+                                "where  caller_pkgname = '%s' and flag_simmode = 0 ", pkgname);
                }
        } else {
                internal_group_id =
@@ -1685,3 +1981,60 @@ err:
 
        return ret;
 }
+
+EXPORT_API int notification_noti_check_tag(notification_h noti)
+{
+       int result = 0;
+       int ret = NOTIFICATION_ERROR_NONE;
+       sqlite3 *db;
+       sqlite3_stmt *stmt = NULL;
+
+       if (noti->tag == NULL) {
+               return NOTIFICATION_ERROR_NOT_EXIST_ID;
+       }
+
+       /* Open DB */
+       db = notification_db_open(DBPATH);
+       if (!db) {
+               return get_last_result();
+       }
+
+       ret = sqlite3_prepare_v2(db, "SELECT priv_id FROM noti_list WHERE caller_pkgname = ? and tag = ?", -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
+               return NOTIFICATION_ERROR_OUT_OF_MEMORY;
+       }
+
+       ret = sqlite3_bind_text(stmt, 1, noti->caller_pkgname, -1, SQLITE_TRANSIENT);
+       if (ret != SQLITE_OK) {
+               NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
+               goto err;
+       }
+
+       ret = sqlite3_bind_text(stmt, 2, noti->tag, -1, SQLITE_TRANSIENT);
+       if (ret != SQLITE_OK) {
+               NOTIFICATION_ERR("Error: %s\n", sqlite3_errmsg(db));
+               goto err;
+       }
+
+       ret = sqlite3_step(stmt);
+       if (ret == SQLITE_ROW) {
+               result = sqlite3_column_int(stmt, 0);
+       } else {
+               result = 0;
+       }
+
+       sqlite3_finalize(stmt);
+
+       /* If result > 0, there is priv_id in DB */
+       if (result > 0) {
+               noti->priv_id = result;
+               ret = NOTIFICATION_ERROR_ALREADY_EXIST_ID;
+       } else {
+               ret = NOTIFICATION_ERROR_NOT_EXIST_ID;
+       }
+
+err:
+
+       return ret;
+}