Beta release
[framework/api/application.git] / src / ui_notification.c
index 0de048a..0129eb8 100755 (executable)
@@ -24,9 +24,8 @@
 #include <dlog.h>
 #include <notification.h>
 
-#include <app_service.h>
+#include <app.h>
 #include <app_service_private.h>
-#include <app_ui_notification.h>
 
 #ifdef LOG_TAG
 #undef LOG_TAG
 #define LOG_TAG "TIZEN_N_UI_NOTIFICATION"
 
 struct ui_notification_s {
-       notification_h core;
+       notification_h raw_handle;
        bool ongoing;
        bool posted;
+       bool removed;
        char *icon;
        struct tm *time;
        char *title;
@@ -72,8 +72,9 @@ static int ui_notification_error_handler(int error, const char *func, const char
                break;          
 
        case NOTIFICATION_ERROR_ALREADY_EXIST_ID:
-               retcode = UI_NOTIFICATION_ERROR_ALREADY_POSTED;
-               error_msg = "ALREADY_POSTED";
+       case NOTIFICATION_ERROR_NOT_EXIST_ID:
+               retcode = UI_NOTIFICATION_ERROR_INVALID_STATE;
+               error_msg = "INVALID_STATE";
                break;
 
        default:
@@ -100,16 +101,18 @@ int ui_notification_create(bool ongoing, ui_notification_h *notification)
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       notification_out = (ui_notification_h)malloc(sizeof(struct ui_notification_s));
+       notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s));
 
        if (notification_out == NULL)
        {
                LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
                return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
        }
-
+       
+       notification_out->raw_handle = NULL;
        notification_out->ongoing = ongoing;
        notification_out->posted = false;
+       notification_out->removed = false;
        notification_out->icon = NULL;
        notification_out->time = NULL;
        notification_out->title = NULL;
@@ -121,6 +124,88 @@ int ui_notification_create(bool ongoing, ui_notification_h *notification)
        return UI_NOTIFICATION_ERROR_NONE;
 }
 
+static int ui_notification_construct(bool ongoing, notification_h raw_handle, ui_notification_h *notification)
+{
+       int retcode;
+       ui_notification_h notification_out;
+       char *icon;
+       time_t time;
+       char *title;
+       char *content;
+       bundle *service_data;
+
+       if (notification == NULL)
+       {
+               LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+               return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+       }
+
+       notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s));
+
+       if (notification_out == NULL)
+       {
+               LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
+               return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+       }
+
+       retcode = ui_notification_error_handler(notification_clone(raw_handle, &(notification_out->raw_handle)),\
+                                __FUNCTION__, "failed to clone the notification handle");
+
+       if (retcode != NOTIFICATION_ERROR_NONE)
+       {
+               return retcode;
+       }
+       
+       notification_out->ongoing = ongoing;
+
+       notification_out->posted = true;
+
+       notification_out->removed = false;
+
+       if (!notification_get_image(raw_handle, NOTIFICATION_IMAGE_TYPE_ICON, &icon))
+       {
+               notification_out->icon = icon;
+       }
+
+       if (!notification_get_time(raw_handle, &time))
+       {
+               notification_out->time = malloc(sizeof(struct tm));
+               
+               if (notification_out->time == NULL)
+               {
+                       ui_notification_destroy(notification_out);
+                       LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
+                       return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               }
+
+               localtime_r(&time, notification_out->time);
+       }
+
+       if (!notification_get_text(raw_handle, NOTIFICATION_TEXT_TYPE_TITLE, &title))
+       {
+               notification_out->title = title;
+       }
+
+       if (!   notification_get_text(raw_handle, NOTIFICATION_TEXT_TYPE_CONTENT, &content))
+       {
+               notification_out->content = content;
+       }
+
+       if (!notification_get_execute_option(raw_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, &service_data))
+       {
+               service_h service;
+
+               if (!service_create_request(service_data, &service))
+               {
+                       notification_out->service = service;
+               }
+       }
+
+       *notification = notification_out;
+
+       return UI_NOTIFICATION_ERROR_NONE;
+}
+
 int ui_notification_destroy(ui_notification_h notification)
 {
        if (notification == NULL)
@@ -129,8 +214,8 @@ int ui_notification_destroy(ui_notification_h notification)
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       if (notification->core)
-               notification_free(notification->core);
+       if (notification->raw_handle)
+               notification_free(notification->raw_handle);
 
        if (notification->icon)
                free(notification->icon);
@@ -152,29 +237,101 @@ int ui_notification_destroy(ui_notification_h notification)
        return UI_NOTIFICATION_ERROR_NONE;
 }
 
-
-int ui_notification_set_icon(ui_notification_h notification, const char *path)
+int ui_notification_clone(ui_notification_h *clone, ui_notification_h notification)
 {
-       char *path_dup;
+       ui_notification_h notification_out;
+       int retcode;
 
-       if (notification == NULL || path == NULL)
+       if (clone == NULL || notification == NULL)
        {
                LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       if (notification->posted == true)
+       notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s));
+
+       if (notification->raw_handle != NULL)
        {
-               LOGE("[%s] ALREADY_POSTED(0x%08x) : unable to change the notification", __FUNCTION__, UI_NOTIFICATION_ERROR_ALREADY_POSTED);
-               return UI_NOTIFICATION_ERROR_ALREADY_POSTED;
+               retcode = notification_clone(notification->raw_handle, &(notification_out->raw_handle));
+
+               if (retcode)
+               {
+                       return ui_notification_error_handler(retcode, __FUNCTION__, "failed to clone the handle");
+               }
        }
 
-       path_dup = strdup(path);
+       notification_out->ongoing = notification->ongoing;
+
+       notification_out->posted = notification->posted;
+
+       notification_out->removed = notification->removed;
+
+       if (notification->icon)
+       {
+               notification_out->icon = strdup(notification->icon);
+       }
 
-       if (path_dup == NULL)
+       if (notification->time)
        {
-               LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
-               return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               notification_out->time = malloc(sizeof(struct tm));
+               if (notification_out->time != NULL)
+               {
+                       memcpy(notification_out->time, notification->time, sizeof(struct tm));
+               }
+       }
+
+       if (notification->title)
+       {
+               notification_out->title = strdup(notification->title);
+       }
+
+       if (notification->content)
+       {
+               notification_out->content = strdup(notification->content);
+       }
+
+       if (notification->service)
+       {
+               service_clone(&(notification_out->service), notification->service);
+       }
+
+       *clone = notification_out;
+
+       return UI_NOTIFICATION_ERROR_NONE;
+}
+
+int ui_notification_is_ongoing(ui_notification_h notification, bool *ongoing)
+{
+       if (notification == NULL || ongoing == NULL)
+       {
+               LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+               return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+       }
+
+       *ongoing = notification->ongoing;
+
+       return UI_NOTIFICATION_ERROR_NONE;
+}
+
+int ui_notification_set_icon(ui_notification_h notification, const char *path)
+{
+       char *path_dup = NULL;
+
+       if (notification == NULL)
+       {
+               LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+               return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+       }
+
+       if (path != NULL)
+       {
+               path_dup = strdup(path);
+
+               if (path_dup == NULL)
+               {
+                       LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
+                       return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               }
        }
 
        if (notification->icon != NULL)
@@ -215,30 +372,27 @@ int ui_notification_get_icon(ui_notification_h notification, char **path)
 
 int ui_notification_set_time(ui_notification_h notification, struct tm *time)
 {
-       struct tm *time_dup;
+       struct tm *time_dup = NULL;
 
-       if (notification == NULL || time == NULL)
+       if (notification == NULL)
        {
                LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       if (notification->posted == true)
+       if (time != NULL)
        {
-               LOGE("[%s] ALREADY_POSTED(0x%08x) : unable to change the notification", __FUNCTION__, UI_NOTIFICATION_ERROR_ALREADY_POSTED);
-               return UI_NOTIFICATION_ERROR_ALREADY_POSTED;
-       }
+               time_dup = malloc(sizeof(struct tm));
 
-       time_dup = malloc(sizeof(struct tm));
+               if (time_dup == NULL)
+               {
+                       LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
+                       return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               }
 
-       if (time_dup == NULL)
-       {
-               LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
-               return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               memcpy(time_dup, time, sizeof(struct tm));
        }
 
-       memcpy(time_dup, time, sizeof(struct tm));
-
        if (notification->time != NULL)
        {
                free(notification->time);
@@ -279,26 +433,23 @@ int ui_notification_get_time(ui_notification_h notification, struct tm **time)
 
 int ui_notification_set_title(ui_notification_h notification, const char *title)
 {
-       char *title_dup;
+       char *title_dup = NULL;
 
-       if (notification == NULL || title == NULL)
+       if (notification == NULL)
        {
                LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       if (notification->posted == true)
+       if (title != NULL)
        {
-               LOGE("[%s] ALREADY_POSTED(0x%08x) : unable to change the notification", __FUNCTION__, UI_NOTIFICATION_ERROR_ALREADY_POSTED);
-               return UI_NOTIFICATION_ERROR_ALREADY_POSTED;
-       }
-
-       title_dup = strdup(title);
+               title_dup = strdup(title);
 
-       if (title_dup == NULL)
-       {
-               LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
-               return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               if (title_dup == NULL)
+               {
+                       LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
+                       return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               }
        }
 
        if (notification->title != NULL)
@@ -340,26 +491,23 @@ int ui_notification_get_title(ui_notification_h notification, char **title)
 
 int ui_notification_set_content(ui_notification_h notification, const char *content)
 {
-       char *content_dup;
+       char *content_dup = NULL;
 
-       if (notification == NULL || content == NULL)
+       if (notification == NULL)
        {
                LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       if (notification->posted == true)
+       if (content != NULL)
        {
-               LOGE("[%s] ALREADY_POSTED(0x%08x) : unable to change the notification", __FUNCTION__, UI_NOTIFICATION_ERROR_ALREADY_POSTED);
-               return UI_NOTIFICATION_ERROR_ALREADY_POSTED;
-       }
+               content_dup = strdup(content);
 
-       content_dup = strdup(content);
-
-       if (content_dup == NULL)
-       {
-               LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
-               return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               if (content_dup == NULL)
+               {
+                       LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
+                       return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               }
        }
 
        if (notification->content != NULL)
@@ -402,33 +550,30 @@ int ui_notification_get_content(ui_notification_h notification, char **content)
 int ui_notification_set_service(ui_notification_h notification, service_h service)
 {
        int retcode;
-       service_h service_dup;
+       service_h service_dup = NULL;
 
-       if (notification == NULL || service == NULL)
+       if (notification == NULL)
        {
                LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       if (notification->posted == true)
+       if (service != NULL)
        {
-               LOGE("[%s] ALREADY_POSTED(0x%08x) : unable to change the notification", __FUNCTION__, UI_NOTIFICATION_ERROR_ALREADY_POSTED);
-               return UI_NOTIFICATION_ERROR_ALREADY_POSTED;
-       }
+               retcode = service_clone(&service_dup, service);
 
-       retcode = service_clone(&service_dup, service);
-
-       if (retcode != SERVICE_ERROR_NONE)
-       {
-               if (retcode == SERVICE_ERROR_OUT_OF_MEMORY)
-               {
-                       LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
-                       return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
-               }
-               else
+               if (retcode != SERVICE_ERROR_NONE)
                {
-                       LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid service handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
-                       return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+                       if (retcode == SERVICE_ERROR_OUT_OF_MEMORY)
+                       {
+                               LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
+                               return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+                       }
+                       else
+                       {
+                               LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid service handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+                               return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+                       }
                }
        }
 
@@ -477,12 +622,60 @@ int ui_notification_get_service(ui_notification_h notification, service_h *servi
        return UI_NOTIFICATION_ERROR_NONE;
 }
 
+static int ui_notification_build_attributes(ui_notification_h notification)
+{
+       bundle *service_data;
+
+       if (notification == NULL)
+       {
+               LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+               return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+       }
+
+       if (notification->icon != NULL)
+       {
+               struct stat st;
+       
+               if (stat(notification->icon, &st) < 0)
+               {
+                       LOGE("[%s] NO_SUCH_FILE(0x%08x) : invalid icon", __FUNCTION__, UI_NOTIFICATION_ERROR_NO_SUCH_FILE);
+                       return UI_NOTIFICATION_ERROR_NO_SUCH_FILE;
+               }
+
+               notification_set_image(notification->raw_handle, NOTIFICATION_IMAGE_TYPE_ICON, notification->icon);
+       }
+
+       if (notification->time != NULL)
+       {
+               notification_set_time(notification->raw_handle, mktime(notification->time));
+       }
+
+       if (notification->title != NULL)
+       {
+               notification_set_text(notification->raw_handle, NOTIFICATION_TEXT_TYPE_TITLE, notification->title, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+       }
+
+       if (notification->content != NULL)
+       {
+               notification_set_text(notification->raw_handle, NOTIFICATION_TEXT_TYPE_CONTENT, notification->content, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+       }
+
+       if (notification->service != NULL && service_to_bundle(notification->service, &service_data) == SERVICE_ERROR_NONE)
+       {
+               notification_set_property(notification->raw_handle, 0);
+               notification_set_execute_option(notification->raw_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, NULL, service_data);
+       }
+       else
+       {
+               notification_set_property(notification->raw_handle, NOTIFICATION_PROP_DISABLE_APP_LAUNCH);
+       }
+
+       return UI_NOTIFICATION_ERROR_NONE;
+}
 
 int ui_notification_post(ui_notification_h notification)
 {
        int retcode;
-       notification_h core;
-       bundle *service_data;
 
        if (notification == NULL)
        {
@@ -492,82 +685,83 @@ int ui_notification_post(ui_notification_h notification)
 
        if (notification->posted == true)
        {
-               LOGE("[%s] ALREADY_POSTED(0x%08x) : unable to change the notification", __FUNCTION__, UI_NOTIFICATION_ERROR_ALREADY_POSTED);
-               return UI_NOTIFICATION_ERROR_ALREADY_POSTED;
+               LOGE("[%s] INVALID_STATE(0x%08x) : the notification was already posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
+               return UI_NOTIFICATION_ERROR_INVALID_STATE;
        }
 
-       // STEP 1: core handle
+       // STEP 1: notification handle
        if (notification->ongoing == true)
        {
-               core = notification_new(NOTIFICATION_TYPE_ONGOING, NOTIFICATION_GROUP_ID_DEFAULT, NOTIFICATION_PRIV_ID_NONE);
+               notification->raw_handle = notification_new(NOTIFICATION_TYPE_ONGOING, NOTIFICATION_GROUP_ID_DEFAULT, NOTIFICATION_PRIV_ID_NONE);
        }
        else
        {
-               core = notification_new(NOTIFICATION_TYPE_NOTI, NOTIFICATION_GROUP_ID_DEFAULT, NOTIFICATION_PRIV_ID_NONE);
+               notification->raw_handle = notification_new(NOTIFICATION_TYPE_NOTI, NOTIFICATION_GROUP_ID_DEFAULT, NOTIFICATION_PRIV_ID_NONE);
        }
 
-       if (core == NULL)
+       if (notification->raw_handle == NULL)
        {
                LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
                return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
        }
 
-       notification->core = core;
+       retcode = ui_notification_build_attributes(notification);
 
-       // STEP 2: icon
-       if (notification->icon != NULL)
+       if (retcode != UI_NOTIFICATION_ERROR_NONE)
        {
-               struct stat st;
-       
-               if (stat(notification->icon, &st) < 0)
-               {
-                       LOGE("[%s] NO_SUCH_FILE(0x%08x) : invalid icon", __FUNCTION__, UI_NOTIFICATION_ERROR_NO_SUCH_FILE);
-                       return UI_NOTIFICATION_ERROR_NO_SUCH_FILE;
-               }
-
-               notification_set_image(core, NOTIFICATION_IMAGE_TYPE_ICON, notification->icon);
+               return retcode;
        }
 
-       // STEP 3: time
-       if (notification->time != NULL)
+       retcode = ui_notification_error_handler(notification_insert(notification->raw_handle, NULL), __FUNCTION__, "failed to post a notification");
+
+       if (retcode == UI_NOTIFICATION_ERROR_NONE)
        {
-               notification_set_time(core, mktime(notification->time));
+               notification->posted = true;
        }
 
-       // STEP 4: title
-       if (notification->title != NULL)
+       return retcode;
+}
+
+int ui_notification_update(ui_notification_h notification)
+{
+       int retcode;
+
+       if (notification == NULL)
        {
-               notification_set_text(core, NOTIFICATION_TEXT_TYPE_TITLE, notification->title, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+               LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+               return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       // STEP 5: content
-       if (notification->content != NULL)
+       if (notification->posted == false)
        {
-               notification_set_text(core, NOTIFICATION_TEXT_TYPE_CONTENT, notification->content, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+               LOGE("[%s] INVALID_STATE(0x%08x) : the notification was not posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
+               return UI_NOTIFICATION_ERROR_INVALID_STATE;
        }
 
-       // STEP 6: service
-       if (notification->service != NULL && service_to_bundle(notification->service, &service_data) == SERVICE_ERROR_NONE)
+       if (notification->removed == true)
        {
-               notification_set_execute_option(core, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, NULL, service_data);
+               LOGE("[%s] INVALID_STATE(0x%08x) : the notification was canceled or cleared", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
+               return UI_NOTIFICATION_ERROR_INVALID_STATE;
        }
-       else
+
+       retcode = ui_notification_build_attributes(notification);
+
+       if (retcode != UI_NOTIFICATION_ERROR_NONE)
        {
-               notification_set_property(core, NOTIFICATION_PROP_DISABLE_APP_LAUNCH);
+               return retcode;
        }
 
-       // STEP 7: insert
-       retcode = ui_notification_error_handler(notification_insert(core, NULL), __FUNCTION__, "failed to post a notification");
+       retcode = ui_notification_error_handler(notification_update(notification->raw_handle), __FUNCTION__, "failed to post a notification");
 
-       if (retcode == UI_NOTIFICATION_ERROR_NONE)
+       if (retcode == UI_NOTIFICATION_ERROR_INVALID_STATE)
        {
-               notification->posted = true;
+               notification->removed = true;
        }
 
        return retcode;
 }
 
-int ui_notification_update_progress(ui_notification_h notification, ui_notification_progress_type_e type, double value)
+int  ui_notification_update_progress(ui_notification_h notification, ui_notification_progress_type_e type, double value)
 {
        int retcode;
 
@@ -577,23 +771,41 @@ int ui_notification_update_progress(ui_notification_h notification, ui_notificat
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       if (notification->core == NULL || notification->posted == false)
+       if (notification->raw_handle == NULL)
        {
                LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
+       if (notification->posted == false)
+       {
+               LOGE("[%s] INVALID_STATE(0x%08x) : the notification was not posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
+               return UI_NOTIFICATION_ERROR_INVALID_STATE;
+       }
+
+       if (notification->removed == true)
+       {
+               LOGE("[%s] INVALID_STATE(0x%08x) : the notification was canceled or cleared", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
+               return UI_NOTIFICATION_ERROR_INVALID_STATE;
+       }
+
+       if (value < 0)
+       {
+               LOGE("[%s] INVALID_PARAMETER(0x%08x) : the value must be greater than or equal to zero.", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+               return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+       }
+
        switch (type)
        {
        case UI_NOTIFICATION_PROGRESS_TYPE_SIZE:
                retcode = ui_notification_error_handler(
-                       notification_update_size(notification->core, NOTIFICATION_PRIV_ID_NONE, value),
+                       notification_update_size(notification->raw_handle, NOTIFICATION_PRIV_ID_NONE, value),
                        __FUNCTION__, "failed to update the progress");
                break;
                
        case UI_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE:
                retcode = ui_notification_error_handler(
-                       notification_update_progress(notification->core, NOTIFICATION_PRIV_ID_NONE, value),
+                       notification_update_progress(notification->raw_handle, NOTIFICATION_PRIV_ID_NONE, value),
                        __FUNCTION__, "failed to update the progress");
                break;
 
@@ -602,6 +814,11 @@ int ui_notification_update_progress(ui_notification_h notification, ui_notificat
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
+       if (retcode == UI_NOTIFICATION_ERROR_INVALID_STATE)
+       {
+               notification->removed = true;
+       }
+
        return retcode;
 }
 
@@ -615,23 +832,109 @@ int ui_notification_cancel(ui_notification_h notification)
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       if (notification->core == NULL || notification->posted == false)
+       if (notification->raw_handle == NULL)
        {
                LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
                return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
        }
 
-       retcode = ui_notification_error_handler(
-               notification_delete(notification->core),
-               __FUNCTION__, "failed to cancel the notification");
+       if (notification->posted == false)
+       {
+               LOGE("[%s] INVALID_STATE(0x%08x) : the notification was not posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
+               return UI_NOTIFICATION_ERROR_INVALID_STATE;
+       }
+
+       if (notification->removed == true)
+       {
+               LOGE("[%s] INVALID_STATE(0x%08x) : the notification was canceled or cleared", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE);
+               return UI_NOTIFICATION_ERROR_INVALID_STATE;
+       }
+
+       retcode = ui_notification_error_handler(notification_delete(notification->raw_handle), __FUNCTION__, "failed to cancel the notification");
+
+       if (retcode == UI_NOTIFICATION_ERROR_NONE)
+       {
+               notification->removed = true;
+       }
 
        return retcode;
 }
 
-int ui_notification_cancel_all(void)
+void ui_notification_cancel_all(void)
+{
+       notification_delete_all_by_type(NULL, NOTIFICATION_TYPE_NONE);
+}
+
+static bool ui_notification_package_equal(notification_h handle)
 {
-       return ui_notification_error_handler(
-               notification_delete_all_by_type(NULL, NOTIFICATION_TYPE_NONE),
-               __FUNCTION__, "failed to cancel the notification");
+       char *package = NULL;
+       char *handle_package = NULL;
+
+       if (app_get_package(&package))
+       {
+               return false;
+       }
+
+       if (notification_get_pkgname(handle, &handle_package))
+       {
+               return false;
+       }
+
+       if (strlen(package) == strlen(handle_package))
+       {
+               if (!strncmp(package, handle_package, strlen(package)))
+               {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+int ui_notification_foreach_notification_posted(bool ongoing, ui_notification_cb callback, void *user_data)
+{
+       notification_list_h raw_handle_list;
+       notification_h raw_handle;
+       notification_type_e notification_type = ongoing ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
+       ui_notification_h notification = NULL;
+       bool iterate_next = true;
+
+       if (callback == NULL)
+       {
+               LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+               return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+       }
+
+       if (notification_get_grouping_list(notification_type, -1, &raw_handle_list))
+       {
+               LOGE("[%s] DB_FAILED(0x%08x) : failed to get a notification list", __FUNCTION__, UI_NOTIFICATION_ERROR_DB_FAILED);
+               return UI_NOTIFICATION_ERROR_DB_FAILED;
+       }
+
+       while (raw_handle_list != NULL)
+       {
+               raw_handle = notification_list_get_data(raw_handle_list);
+
+               if (raw_handle != NULL && ui_notification_package_equal(raw_handle))
+               {
+                       if (!ui_notification_construct(ongoing, raw_handle, &notification))
+                       {
+                               iterate_next = callback(notification, user_data);
+
+                               ui_notification_destroy(notification);
+
+                               if (iterate_next == false)
+                               {
+                                       break;
+                               }
+                       }
+               }
+
+               raw_handle_list = notification_list_get_next(raw_handle_list);
+       }
+
+       notification_free_list(raw_handle_list);
+
+       return UI_NOTIFICATION_ERROR_NONE;
 }