Change default sound, vibration name
[platform/core/api/notification.git] / notification-ex / stub.cc
index 7ca6841..3a9b575 100644 (file)
 #include <sstream>
 #include <iomanip>
 
-#include "api/notification_ex_app_control_action.h"
-#include "api/notification_ex_button.h"
-#include "api/notification_ex_chat_message.h"
-#include "api/notification_ex_checkbox.h"
-#include "api/notification_ex_entry.h"
-#include "api/notification_ex_event_info.h"
-#include "api/notification_ex_group.h"
-#include "api/notification_ex_image.h"
-#include "api/notification_ex_input_selector.h"
-#include "api/notification_ex_item.h"
-#include "api/notification_ex_manager.h"
-#include "api/notification_ex_progress.h"
-#include "api/notification_ex_reporter.h"
-#include "api/notification_ex_text.h"
-#include "api/notification_ex_time.h"
-#include "api/notification_ex_visibility_action.h"
-#include "api/notification_ex_visibility_action.h"
+#include "api/notification_ex.h"
 #include "api/notification_ex_internal.h"
 #include "notification-ex/reporter.h"
 #include "notification-ex/app_control_action.h"
@@ -58,6 +42,7 @@
 #include "notification-ex/dbus_event_listener.h"
 #include "notification-ex/exception.h"
 #include "notification-ex/iitem_info_internal.h"
+#include "notification-ex/icon_item.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -353,7 +338,15 @@ extern "C" EXPORT_API int noti_ex_action_app_control_get(
   shared_ptr<AbstractAction>* ptr =
       static_cast<shared_ptr<AbstractAction>*>(handle);
   AppControlAction* action = static_cast<AppControlAction*>(ptr->get());
-  *app_control = action->GetAppControl();
+
+  app_control_h clone;
+  int r = app_control_clone(&clone, action->GetAppControl());
+  if (r != APP_CONTROL_ERROR_NONE) {
+    LOGE("failed to create a app_control handle : %d", r);
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  *app_control = clone;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -439,19 +432,64 @@ extern "C" EXPORT_API int noti_ex_item_button_set_multi_language_title(
   return NOTI_EX_ERROR_NONE;
 }
 
+extern "C" EXPORT_API int noti_ex_item_button_set_image(
+    noti_ex_item_h handle, char *path) {
+  if (handle == nullptr || path == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Button)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  ButtonItem* p = static_cast<ButtonItem*>(h->Get());
+  p->SetImgPath(path);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_button_get_image(
+    noti_ex_item_h handle, char **path) {
+  if (handle == nullptr || path == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Button)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  ButtonItem* p = static_cast<ButtonItem*>(h->Get());
+  if (!p->GetImgPath().empty())
+    *path = strdup(p->GetImgPath().c_str());
+  else
+    *path = nullptr;
+
+  return NOTI_EX_ERROR_NONE;
+}
+
 extern "C" EXPORT_API int noti_ex_item_chat_message_create(
     noti_ex_item_h *handle, const char *id, noti_ex_item_h name,
     noti_ex_item_h text, noti_ex_item_h image, noti_ex_item_h time,
     noti_ex_item_chat_message_type_e message_type) {
-  if (handle == nullptr || message_type > NOTI_EX_ITEM_CHAT_MESSAGE_TYPE_SENDER) {
+  if (handle == nullptr || (text == nullptr && image == nullptr)
+      || name == nullptr || time == nullptr
+      || message_type > NOTI_EX_ITEM_CHAT_MESSAGE_TYPE_SENDER) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
   auto* p = new (std::nothrow) ChatMessageItem(id,
           dynamic_pointer_cast<TextItem>(static_cast<Handle*>(name)->GetPtr()),
-          dynamic_pointer_cast<TextItem>(static_cast<Handle*>(text)->GetPtr()),
-          dynamic_pointer_cast<ImageItem>(static_cast<Handle*>(image)->GetPtr()),
+          text == nullptr ? nullptr
+            : dynamic_pointer_cast<TextItem>(static_cast<Handle*>(text)->GetPtr()),
+          image == nullptr ? nullptr
+            : dynamic_pointer_cast<ImageItem>(static_cast<Handle*>(image)->GetPtr()),
           dynamic_pointer_cast<TimeItem>(static_cast<Handle*>(time)->GetPtr()),
           static_cast<ChatMessageItem::Type>(message_type));
   if (p == nullptr) {
@@ -476,7 +514,10 @@ extern "C" EXPORT_API int noti_ex_item_chat_message_get_name(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
   ChatMessageItem* p = static_cast<ChatMessageItem*>(h->Get());
-  *name = new Handle(&(p->GetNameItem()));
+  if (p->GetNameItem().GetType() == AbstractItem::NullObject)
+    *name = nullptr;
+  else
+    *name = new Handle(&(p->GetNameItem()));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -494,7 +535,10 @@ extern "C" EXPORT_API int noti_ex_item_chat_message_get_text(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
   ChatMessageItem* p = static_cast<ChatMessageItem*>(h->Get());
-  *text = new Handle(&(p->GetTextItem()));
+  if (p->GetTextItem().GetType() == AbstractItem::NullObject)
+    *text = nullptr;
+  else
+    *text = new Handle(&(p->GetTextItem()));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -512,7 +556,10 @@ extern "C" EXPORT_API int noti_ex_item_chat_message_get_image(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
   ChatMessageItem* p = static_cast<ChatMessageItem*>(h->Get());
-  *image =  new Handle(&(p->GetImageItem()));
+  if (p->GetImageItem().GetType() == AbstractItem::NullObject)
+    *image = nullptr;
+  else
+    *image =  new Handle(&(p->GetImageItem()));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -530,7 +577,10 @@ extern "C" EXPORT_API int noti_ex_item_chat_message_get_time(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
   ChatMessageItem* p = static_cast<ChatMessageItem*>(h->Get());
-  *time = new Handle(&(p->GetTimeItem()));
+  if (p->GetTimeItem().GetType() == AbstractItem::NullObject)
+    *time = nullptr;
+  else
+    *time = new Handle(&(p->GetTimeItem()));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1023,6 +1073,8 @@ extern "C" EXPORT_API int noti_ex_item_image_get_image_path(
       LOGE("Out-of-memory");
       return NOTI_EX_ERROR_OUT_OF_MEMORY;
     }
+  } else {
+    *image_path = nullptr;
   }
 
   return NOTI_EX_ERROR_NONE;
@@ -1454,7 +1506,8 @@ extern "C" EXPORT_API int noti_ex_style_get_padding(noti_ex_style_h handle,
       new (std::nothrow) Padding(*((*p)->GetPadding())));
   if (padd == nullptr || padd->get() == nullptr) {
     LOGE("Out-of-memory");
-    return NOTI_EX_ERROR_OUT_OF_MEMORY;
+    *padding = nullptr;
+    return NOTI_EX_ERROR_NONE;
   }
 
   *padding = padd;
@@ -1492,7 +1545,8 @@ extern "C" EXPORT_API int noti_ex_style_get_color(noti_ex_style_h handle,
   shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
   if ((*p)->GetColor() == nullptr) {
     LOGW("Color info is null");
-    return NOTI_EX_ERROR_INVALID_PARAMETER;
+    *color = nullptr;
+    return NOTI_EX_ERROR_NONE;
   }
 
   shared_ptr<Color>* col = new (std::nothrow) shared_ptr<Color>(
@@ -1536,7 +1590,8 @@ extern "C" EXPORT_API int noti_ex_style_get_geometry(noti_ex_style_h handle,
   shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
   if ((*p)->GetGeometry() == nullptr) {
     LOGW("Geometry info is null");
-    return NOTI_EX_ERROR_INVALID_PARAMETER;
+    *geometry = nullptr;
+    return NOTI_EX_ERROR_NONE;
   }
 
   shared_ptr<Geometry>* geo = new (std::nothrow) shared_ptr<Geometry>(
@@ -1578,20 +1633,27 @@ extern "C" EXPORT_API int noti_ex_style_get_background_image(
   }
 
   shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
-  *background_image = strdup((*p)->GetBackgroundImage().c_str());
+
+  if ((*p)->GetBackgroundImage().empty())
+    *background_image = nullptr;
+  else
+    *background_image = strdup((*p)->GetBackgroundImage().c_str());
 
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_style_set_background_image(
     noti_ex_style_h handle, char* background_image) {
-  if (handle == nullptr || background_image == nullptr) {
+  if (handle == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
   shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
-  (*p)->SetBackgroundImage(background_image);
+  if (background_image == nullptr)
+    (*p)->SetBackgroundImage("");
+  else
+    (*p)->SetBackgroundImage(background_image);
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1606,7 +1668,8 @@ extern "C" EXPORT_API int noti_ex_style_get_background_color(
   shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
   if ((*p)->GetBackgroundColor() == nullptr) {
     LOGW("Color info is null");
-    return NOTI_EX_ERROR_INVALID_PARAMETER;
+    *color = nullptr;
+    return NOTI_EX_ERROR_NONE;
   }
 
   shared_ptr<Color>* col = new (std::nothrow) shared_ptr<Color>(
@@ -1623,12 +1686,17 @@ extern "C" EXPORT_API int noti_ex_style_get_background_color(
 
 extern "C" EXPORT_API int noti_ex_style_set_background_color(
     noti_ex_style_h handle, noti_ex_color_h color) {
-  if (handle == nullptr || color == nullptr) {
+  if (handle == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
   shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
+  if (color == nullptr) {
+    (*p)->SetBackgroundColor(nullptr);
+    return NOTI_EX_ERROR_NONE;
+  }
+
   shared_ptr<Color>* col = static_cast<shared_ptr<Color>*>(color);
   (*p)->SetBackgroundColor(*col);
 
@@ -1637,7 +1705,7 @@ extern "C" EXPORT_API int noti_ex_style_set_background_color(
 
 extern "C" EXPORT_API int noti_ex_led_info_create(noti_ex_led_info_h *handle,
     noti_ex_color_h color) {
-  if (handle == nullptr) {
+  if (handle == nullptr || color == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
@@ -1733,8 +1801,9 @@ extern "C" EXPORT_API int noti_ex_led_info_get_color(
   shared_ptr<LEDInfo>* led_ptr =
       reinterpret_cast<shared_ptr<LEDInfo>*>(handle);
   if ((*led_ptr)->GetColor() == nullptr) {
-    LOGE("Color is null");
-    return NOTI_EX_ERROR_INVALID_PARAMETER;
+    LOGW("Color is null");
+    *color = nullptr;
+    return NOTI_EX_ERROR_NONE;
   }
 
   shared_ptr<Color>* col = new (std::nothrow) shared_ptr<Color>(
@@ -1838,6 +1907,8 @@ extern "C" EXPORT_API int noti_ex_action_get_extra(noti_ex_action_h handle,
       LOGE("Out-of-memory");
       return NOTI_EX_ERROR_OUT_OF_MEMORY;
     }
+  } else {
+    *extra = nullptr;
   }
 
   return NOTI_EX_ERROR_NONE;
@@ -1919,6 +1990,12 @@ extern "C" EXPORT_API int noti_ex_item_find_by_id(noti_ex_item_h handle,
 
   Handle* p = static_cast<Handle*>(handle);
   AbstractItem& find_item = p->Get()->FindByID(string(id));
+  if (find_item.GetType() == AbstractItem::NullObject) {
+    LOGW("Not exist ID");
+    *item = nullptr;
+    return NOTI_EX_ERROR_NONE;
+  }
+
   *item = new Handle(&find_item);
   return NOTI_EX_ERROR_NONE;
 }
@@ -1936,36 +2013,6 @@ extern "C" EXPORT_API int noti_ex_item_get_type(noti_ex_item_h handle,
   return NOTI_EX_ERROR_NONE;
 }
 
-extern "C" EXPORT_API int noti_ex_item_get_shared_paths(noti_ex_item_h handle,
-    char ***path, int *count) {
-  if (handle == nullptr || path == nullptr || count == nullptr) {
-    LOGE("Invalid parameter");
-    return NOTI_EX_ERROR_INVALID_PARAMETER;
-  }
-  Handle* p = static_cast<Handle*>(handle);
-  list<string> shared_path = p->Get()->GetSharedPath();
-  char** tmp_path = (char**)calloc(shared_path.size(), sizeof(char*));
-  if (tmp_path == nullptr) {
-    LOGE("Fail to create items");
-    return NOTI_EX_ERROR_OUT_OF_MEMORY;
-  }
-
-  int idx = 0;
-  for (auto& i : shared_path) {
-    tmp_path[idx] = strdup(i.c_str());
-    if (tmp_path[idx] == nullptr) {
-      __noti_ex_free_str_array(tmp_path, idx);
-      LOGE("Out of memory");
-      return NOTI_EX_ERROR_OUT_OF_MEMORY;
-    }
-    idx++;
-  }
-
-  *path = tmp_path;
-  *count = shared_path.size();
-  return NOTI_EX_ERROR_NONE;
-}
-
 extern "C" EXPORT_API int noti_ex_item_get_id(noti_ex_item_h handle,
     char **id) {
   if (handle == nullptr || id == nullptr) {
@@ -2008,12 +2055,16 @@ extern "C" EXPORT_API int noti_ex_item_get_action(noti_ex_item_h handle,
 
 extern "C" EXPORT_API int noti_ex_item_set_action(noti_ex_item_h handle,
     noti_ex_action_h action) {
-  if (handle == nullptr || action == nullptr) {
+  if (handle == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
   Handle* p = static_cast<Handle*>(handle);
+  if (action == nullptr) {
+    p->Get()->SetAction(nullptr);
+    return NOTI_EX_ERROR_NONE;
+  }
 
   shared_ptr<AbstractAction>* ptr =
       static_cast<shared_ptr<AbstractAction>*>(action);
@@ -2031,8 +2082,9 @@ extern "C" EXPORT_API int noti_ex_item_get_style(noti_ex_item_h handle,
   Handle* p = static_cast<Handle*>(handle);
   shared_ptr<Style> s = p->Get()->GetStyle();
   if (s.get() == nullptr) {
-    LOGE("Style is null");
-    return NOTI_EX_ERROR_INVALID_PARAMETER;
+    LOGW("Style is null");
+    *style = nullptr;
+    return NOTI_EX_ERROR_NONE;
   }
 
   auto* ptr = new (std::nothrow) shared_ptr<Style>(new (std::nothrow) Style(*s));
@@ -2047,12 +2099,17 @@ extern "C" EXPORT_API int noti_ex_item_get_style(noti_ex_item_h handle,
 
 extern "C" EXPORT_API int noti_ex_item_set_style(noti_ex_item_h handle,
     noti_ex_style_h style) {
-  if (handle == nullptr || style == nullptr) {
+  if (handle == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
   Handle* p = static_cast<Handle*>(handle);
+  if (style == nullptr) {
+    p->Get()->SetStyle(nullptr);
+    return NOTI_EX_ERROR_NONE;
+  }
+
   shared_ptr<Style>* s = static_cast<shared_ptr<Style>*>(style);
   p->Get()->SetStyle(*s);
   return NOTI_EX_ERROR_NONE;
@@ -2139,6 +2196,12 @@ extern "C" EXPORT_API int noti_ex_item_get_receiver_list(noti_ex_item_h handle,
 
   Handle* p = static_cast<Handle*>(handle);
   list<string> receivers = p->Get()->GetReceiverList();
+  if (receivers.size() == 0) {
+    *receiver_list = nullptr;
+    *count = 0;
+    return NOTI_EX_ERROR_NONE;
+  }
+
   char **tmp_list = (char**)calloc(receivers.size(), sizeof(char*));
   if (tmp_list == nullptr) {
     LOGE("Out of memory");
@@ -2222,8 +2285,8 @@ extern "C" EXPORT_API int noti_ex_item_set_led_info(noti_ex_item_h handle,
 
   Handle* p = static_cast<Handle*>(handle);
   if (led == nullptr) {
-     p->Get()->SetLEDInfo(nullptr);
-     return NOTI_EX_ERROR_NONE;
+    p->Get()->SetLEDInfo(nullptr);
+    return NOTI_EX_ERROR_NONE;
   }
   shared_ptr<LEDInfo>* led_ptr =
       reinterpret_cast<shared_ptr<LEDInfo>*>(led);
@@ -2448,11 +2511,49 @@ extern "C" EXPORT_API int noti_ex_item_find_by_main_type(noti_ex_item_h handle,
 
   GroupItem* p = static_cast<GroupItem*>(h->Get());
   AbstractItem& find_item = p->FindByMainType(static_cast<AbstractItem::MainType>(type));
+  if (find_item.GetType() == AbstractItem::NullObject) {
+    LOGW("Not exist ID");
+    *item = nullptr;
+    return NOTI_EX_ERROR_NONE;
+  }
   *item = new Handle(&find_item);
 
   return NOTI_EX_ERROR_NONE;
 }
 
+extern "C" EXPORT_API int noti_ex_item_get_extension_data(noti_ex_item_h handle,
+    const char *key, bundle **value) {
+  if (handle == nullptr || key == nullptr || value == nullptr) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+
+  Bundle b = p->Get()->GetExtensionData(key);
+  if (b.GetCount() == 0)
+    *value = nullptr;
+  else
+    *value = b.GetHandle();
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_set_extension_data(noti_ex_item_h handle,
+    const char *key, bundle *value) {
+  if (handle == nullptr || key == nullptr || value == nullptr) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Bundle b = Bundle(value);
+
+  Handle* p = static_cast<Handle*>(handle);
+  p->Get()->SetExtensionData(key, b);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
 extern "C" EXPORT_API int noti_ex_manager_create(noti_ex_manager_h *handle,
     const char *receiver_group, noti_ex_manager_events_s event_callbacks,
     void *data) {
@@ -2622,6 +2723,24 @@ extern "C" EXPORT_API int noti_ex_manager_delete_all(noti_ex_manager_h handle,
   return NOTI_EX_ERROR_NONE;
 }
 
+extern "C" EXPORT_API int noti_ex_manager_delete_by_channel(
+    noti_ex_manager_h handle, char* channel, int* request_id) {
+  if (handle == nullptr || channel == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  try {
+    ManagerStub* stub = static_cast<ManagerStub*>(handle);
+    *request_id = stub->DeleteByChannel(channel);
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return NOTI_EX_ERROR_IO_ERROR;
+  }
+
+  return NOTI_EX_ERROR_NONE;
+}
+
 extern "C" EXPORT_API int noti_ex_manager_hide(noti_ex_manager_h handle,
     noti_ex_item_h noti, int *request_id) {
   if (handle == nullptr || noti == nullptr || request_id == nullptr) {
@@ -2652,7 +2771,13 @@ extern "C" EXPORT_API int noti_ex_manager_find_by_root_id(
   }
   try {
     ManagerStub* stub = static_cast<ManagerStub*>(handle);
-    *item = new Handle(stub->FindByRootID(root_id));
+    shared_ptr<AbstractItem> ptr = stub->FindByRootID(root_id);
+    if (ptr == nullptr) {
+      LOGW("Not exist ID");
+      *item = nullptr;
+      return NOTI_EX_ERROR_NONE;
+    }
+    *item = new Handle(ptr);
   } catch (Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
     return NOTI_EX_ERROR_IO_ERROR;
@@ -2981,6 +3106,24 @@ extern "C" EXPORT_API int noti_ex_reporter_delete_all(
   return NOTI_EX_ERROR_NONE;
 }
 
+extern "C" EXPORT_API int noti_ex_reporter_delete_by_channel(
+    noti_ex_reporter_h handle, char* channel, int* request_id) {
+  if (handle == nullptr || channel == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  try {
+    ReporterStub* stub = static_cast<ReporterStub*>(handle);
+    *request_id = stub->DeleteByChannel(channel);
+  } catch (Exception &ex) {
+    LOGE("%s %d", ex.what(), ex.GetErrorCode());
+    return NOTI_EX_ERROR_IO_ERROR;
+  }
+
+  return NOTI_EX_ERROR_NONE;
+}
+
 extern "C" EXPORT_API int noti_ex_reporter_find_by_root_id(
     noti_ex_reporter_h handle, const char *root_id, noti_ex_item_h *item) {
   if (handle == nullptr || root_id == nullptr || item == nullptr) {
@@ -2989,7 +3132,13 @@ extern "C" EXPORT_API int noti_ex_reporter_find_by_root_id(
   }
   try {
     ReporterStub* stub = static_cast<ReporterStub*>(handle);
-    *item = new Handle(stub->FindByRootID(root_id));
+    shared_ptr<AbstractItem> ptr = stub->FindByRootID(root_id);
+    if (ptr == nullptr) {
+      LOGW("Not exist ID");
+      *item = nullptr;
+      return NOTI_EX_ERROR_NONE;
+    }
+    *item = new Handle(ptr);
   } catch (Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
     return NOTI_EX_ERROR_IO_ERROR;
@@ -3006,6 +3155,9 @@ extern "C" EXPORT_API int noti_ex_item_text_create(noti_ex_item_h *handle,
 
   TextItem* p;
 
+  if (id == NULL)
+    id = "";
+
   if (hyperlink)
     p = new (std::nothrow) TextItem(id, std::string(text),
                 std::string(hyperlink));
@@ -3089,6 +3241,8 @@ extern "C" EXPORT_API int noti_ex_item_text_get_hyperlink(
       LOGE("Out-of-memory");
       return NOTI_EX_ERROR_OUT_OF_MEMORY;
     }
+  } else {
+    *hyper_link = nullptr;
   }
 
   return NOTI_EX_ERROR_NONE;
@@ -3337,3 +3491,52 @@ extern "C" EXPORT_API int noti_ex_item_group_remove_children(noti_ex_item_h hand
 
   return NOTI_EX_ERROR_NONE;
 }
+
+extern "C" EXPORT_API int noti_ex_item_icon_create(noti_ex_item_h *handle,
+    const char *id, const char *icon_path) {
+  if (handle == nullptr || icon_path == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  IconItem* p;
+  if (id)
+    p = new (std::nothrow) IconItem(id, icon_path);
+  else
+    p = new (std::nothrow) IconItem(icon_path);
+
+  if (p == nullptr) {
+    LOGE("Out-of-memory");
+    return NOTI_EX_ERROR_OUT_OF_MEMORY;
+  }
+
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+int noti_ex_item_icon_get_icon_path(noti_ex_item_h handle, char **icon_path) {
+  if (handle == nullptr || icon_path == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Icon)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  IconItem* p = static_cast<IconItem*>(h->Get());
+  if (!p->GetImagePath().empty()) {
+    *icon_path = strdup(p->GetImagePath().c_str());
+    if (*icon_path == nullptr) {
+      LOGE("Out-of-memory");
+      return NOTI_EX_ERROR_OUT_OF_MEMORY;
+    }
+  } else {
+    *icon_path = nullptr;
+  }
+
+  return NOTI_EX_ERROR_NONE;
+}