Change default sound, vibration name
[platform/core/api/notification.git] / notification-ex / stub.cc
index 7988575..3a9b575 100644 (file)
 #include <unistd.h>
 
 #include <list>
+#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.h"
+#include "api/notification_ex_internal.h"
 #include "notification-ex/reporter.h"
 #include "notification-ex/app_control_action.h"
 #include "notification-ex/button_item.h"
 #include "notification-ex/progress_item.h"
 #include "notification-ex/time_item.h"
 #include "notification-ex/visibility_action.h"
+#include "notification-ex/event_info_internal.h"
+#include "notification-ex/manager.h"
+#include "notification-ex/dbus_sender.h"
+#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
 #define EXPORT_API __attribute__((visibility("default")))
 
 using namespace std;
+using namespace tizen_base;
 using namespace notification::item;
+using namespace notification;
+
+namespace {
+
+class Handle {
+ public:
+  explicit Handle(item::AbstractItem* ref) : ref_(ref) { }
+  explicit Handle(std::shared_ptr<item::AbstractItem> ptr)
+      : ref_(nullptr), ptr_(move(ptr)) { }
+  virtual ~Handle() = default;
+  item::AbstractItem* Get() const {
+    if (ptr_ == nullptr)
+      return ref_;
+    return ptr_.get();
+  }
+
+  bool IsValidType(int type) const {
+    return (Get()->GetType() == type
+        || Get()->GetType() >= AbstractItem::Custom);
+  }
+
+  std::shared_ptr<item::AbstractItem> GetPtr() const {
+    if (ptr_ == nullptr)
+      return std::shared_ptr<item::AbstractItem>({});
+    return ptr_;
+  }
+
+ private:
+  item::AbstractItem* ref_;
+  std::shared_ptr<item::AbstractItem> ptr_;
+};
+
+class ManagerCallbackInfo {
+ public:
+  ManagerCallbackInfo(noti_ex_manager_events_s cb, void* user_data)
+    : user_data_(user_data) {
+    cb_.added = cb.added;
+    cb_.updated = cb.updated;
+    cb_.deleted = cb.deleted;
+    cb_.error = cb.error;
+  }
+
+  void InvokeAdded(Manager* manager, const IEventInfo& info,
+      list<shared_ptr<AbstractItem>> addedItem) {
+    if (cb_.added == nullptr)
+      return;
+    noti_ex_item_h* added_item =
+        (noti_ex_item_h*)calloc(addedItem.size(), sizeof(noti_ex_item_h));
+    if (added_item == nullptr) {
+      LOGE("Out of memory");
+      return;
+    }
+
+    int idx = 0;
+    for (auto& i : addedItem) {
+      added_item[idx++] =
+          static_cast<noti_ex_item_h>(new Handle(shared_ptr<AbstractItem>(i)));
+    }
+
+    IEventInfo* c_info = const_cast<IEventInfo*>(&info);
+    cb_.added(static_cast<noti_ex_manager_h>(manager),
+        static_cast<noti_ex_event_info_h>(c_info), added_item,
+        addedItem.size(), user_data_);
+  }
+
+  void InvokeUpdated(Manager* manager, const IEventInfo& info,
+      shared_ptr<item::AbstractItem> updatedItem) {
+    if (cb_.updated == nullptr)
+      return;
+    IEventInfo* c_info = const_cast<IEventInfo*>(&info);
+    cb_.updated(static_cast<noti_ex_manager_h>(manager),
+        static_cast<noti_ex_event_info_h>(c_info),
+        static_cast<noti_ex_item_h>(new Handle(updatedItem)), user_data_);
+  }
+
+  void InvokeDeleted(Manager* manager, const IEventInfo& info,
+      shared_ptr<item::AbstractItem> deletedItem) {
+    if (cb_.deleted == nullptr)
+      return;
+    IEventInfo* c_info = const_cast<IEventInfo*>(&info);
+    if (c_info->GetEventType() == static_cast<int>(IEventInfo::EventType::DeleteAll)) {
+      cb_.deleted(static_cast<noti_ex_manager_h>(manager),
+        static_cast<noti_ex_event_info_h>(c_info),
+        nullptr, user_data_);
+    } else {
+      cb_.deleted(static_cast<noti_ex_manager_h>(manager),
+        static_cast<noti_ex_event_info_h>(c_info),
+        static_cast<noti_ex_item_h>(
+            new Handle(deletedItem)), user_data_);
+    }
+  }
+
+  void InvokeError(Manager* manager, NotificationError error, int requestId) {
+    if (cb_.error == nullptr)
+      return;
+    cb_.error(static_cast<noti_ex_manager_h>(manager),
+        static_cast<noti_ex_error_e>(error), requestId, user_data_);
+  }
+
+ private:
+  noti_ex_manager_events_s cb_;
+  void* user_data_;
+};
+
+class ManagerStub : public Manager {
+ public:
+  ManagerStub(std::unique_ptr<IEventSender> sender,
+      std::unique_ptr<IEventListener> listener, std::string receiver_group = "")
+    : Manager(move(sender), move(listener), receiver_group) {
+  }
+
+  void OnAdd(const IEventInfo& info,
+      list<shared_ptr<AbstractItem>> addedItem) override {
+    cb_->InvokeAdded(this, info, addedItem);
+  }
+
+  void OnUpdate(const IEventInfo& info,
+      std::shared_ptr<item::AbstractItem> updatedItem) override {
+    cb_->InvokeUpdated(this, info, updatedItem);
+  }
+
+  void OnDelete(const IEventInfo& info,
+      shared_ptr<item::AbstractItem> deletedItem) override {
+    cb_->InvokeDeleted(this, info, deletedItem);
+  }
+
+  void OnError(NotificationError error, int requestId) override {
+    cb_->InvokeError(this, error, requestId);
+  }
+
+  int SetManagerCallbackInfo(unique_ptr<ManagerCallbackInfo> ci) {
+    cb_ = move(ci);
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  int ClearManagerCallbackInfo() {
+    cb_.reset();
+    return NOTI_EX_ERROR_NONE;
+  }
+
+ private:
+  unique_ptr<ManagerCallbackInfo> cb_;
+};
+
+
+class ReporterCallbackInfo {
+ public:
+  ReporterCallbackInfo(noti_ex_reporter_events_s cb, void* user_data)
+    : user_data_(user_data) {
+    cb_.event = cb.event;
+    cb_.error = cb.error;
+  }
+
+  void InvokeEvent(Reporter* reporter, const IEventInfo& info,
+      list<shared_ptr<AbstractItem>> notiList) {
+    if (cb_.event == nullptr)
+      return;
+    noti_ex_item_h* noti_list =
+        (noti_ex_item_h*)calloc(notiList.size(), sizeof(noti_ex_item_h));
+    if (noti_list == nullptr) {
+      LOGE("Out of memory");
+      return;
+    }
+
+    int idx = 0;
+    for (auto& i : notiList) {
+      noti_list[idx++] =
+          static_cast<noti_ex_item_h>(new Handle(i));
+    }
+
+    IEventInfo* c_info = const_cast<IEventInfo*>(&info);
+    cb_.event(static_cast<noti_ex_reporter_h>(reporter),
+        static_cast<noti_ex_event_info_h>(c_info), noti_list,
+        notiList.size(), user_data_);
+    free(noti_list);
+  }
+
+  void InvokeError(Reporter* reporter, NotificationError error, int requestId) {
+    if (cb_.error == nullptr)
+      return;
+    cb_.error(static_cast<noti_ex_reporter_h>(reporter),
+        static_cast<noti_ex_error_e>(error), requestId, user_data_);
+  }
+
+ private:
+  noti_ex_reporter_events_s cb_;
+  void* user_data_;
+};
+
+class ReporterStub : public Reporter {
+ public:
+  ReporterStub(std::unique_ptr<IEventSender> sender,
+      std::unique_ptr<IEventListener> listener)
+    : Reporter(move(sender), move(listener)) {
+  }
+
+  void OnEvent(const IEventInfo& info,
+      std::list<std::shared_ptr<item::AbstractItem>> notiList) override {
+    cb_->InvokeEvent(this, info, notiList);
+  }
+
+  void OnError(NotificationError error, int requestId) override {
+    cb_->InvokeError(this, error, requestId);
+  }
+
+  int SetReporterCallbackInfo(unique_ptr<ReporterCallbackInfo> ci) {
+    cb_ = move(ci);
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  int ClearReporterCallbackInfo() {
+    cb_.reset();
+    return NOTI_EX_ERROR_NONE;
+  }
+
+ private:
+  unique_ptr<ReporterCallbackInfo> cb_;
+};
+
+}  // namespace
+
+void __noti_ex_free_str_array(char** val, int length) {
+  int i;
+  for (i = 0; i < length ; i++)
+    free(val[i]);
+  free(val);
+}
 
 extern "C" EXPORT_API int noti_ex_action_app_control_create(
     noti_ex_action_h *handle, app_control_h app_control,
@@ -70,7 +293,16 @@ extern "C" EXPORT_API int noti_ex_action_app_control_create(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  auto* p = new (std::nothrow) AppControlAction(app_control, extra);
+  shared_ptr<AbstractAction>* p;
+
+  if (extra) {
+    p = new (std::nothrow) shared_ptr<AbstractAction>(
+          new (std::nothrow) AppControlAction(app_control, extra));
+  } else {
+    p = new (std::nothrow) shared_ptr<AbstractAction>(
+          new (std::nothrow) AppControlAction(app_control));
+  }
+
   if (p == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
@@ -88,8 +320,10 @@ extern "C" EXPORT_API int noti_ex_action_app_control_set(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  AppControlAction* p = static_cast<AppControlAction*>(handle);
-  p->SetAppControl(app_control);
+  shared_ptr<AbstractAction>* ptr =
+      static_cast<shared_ptr<AbstractAction>*>(handle);
+  AppControlAction* action = static_cast<AppControlAction*>(ptr->get());
+  action->SetAppControl(app_control);
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -101,8 +335,18 @@ extern "C" EXPORT_API int noti_ex_action_app_control_get(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  AppControlAction* p = static_cast<AppControlAction*>(handle);
-  *app_control = p->GetAppControl();
+  shared_ptr<AbstractAction>* ptr =
+      static_cast<shared_ptr<AbstractAction>*>(handle);
+  AppControlAction* action = static_cast<AppControlAction*>(ptr->get());
+
+  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;
 }
@@ -125,8 +369,7 @@ extern "C" EXPORT_API int noti_ex_item_button_create(noti_ex_item_h *handle,
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
-
-  *handle = p;
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -138,15 +381,95 @@ extern "C" EXPORT_API int noti_ex_item_button_get_title(noti_ex_item_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  ButtonItem* p = static_cast<ButtonItem*>(handle);
-  if (!p->GetTitle().empty()) {
-    *title = strdup(p->GetTitle().c_str());
-    if (*title == nullptr) {
-      LOGE("Out-of-memory");
-      return NOTI_EX_ERROR_OUT_OF_MEMORY;
-    }
+  Handle* sp = static_cast<Handle*>(handle);
+  if (!sp->IsValidType(AbstractItem::Button)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
+  ButtonItem* p = static_cast<ButtonItem*>(sp->Get());
+  string str;
+  if (p->GetMultiLanguage() != nullptr &&
+      !p->GetMultiLanguage()->GetTranslatedString().empty())
+    str = p->GetMultiLanguage()->GetTranslatedString();
+  else if (!p->GetTitle().empty())
+    str = p->GetTitle();
+
+  *title = strdup(str.c_str());
+  if (*title == nullptr) {
+    LOGE("Out-of-memory");
+    return NOTI_EX_ERROR_OUT_OF_MEMORY;
+  }
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_button_set_multi_language_title(
+    noti_ex_item_h handle, noti_ex_multi_lang_h multi) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (!p->IsValidType(AbstractItem::Button)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  ButtonItem* bi = static_cast<ButtonItem*>(p->Get());
+  if (multi == nullptr) {
+    bi->SetMultiLanguage(nullptr);
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  shared_ptr<MultiLanguage> mul_ptr =
+      *reinterpret_cast<shared_ptr<MultiLanguage>*>(multi);
+
+  mul_ptr->UpdateString();
+  bi->SetMultiLanguage(mul_ptr);
+
+  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;
 }
 
@@ -154,28 +477,27 @@ 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;
   }
 
-  TextItem* name_ = static_cast<TextItem*>(name);
-  TextItem* text_ = static_cast<TextItem*>(text);
-  ImageItem* image_ = static_cast<ImageItem*>(image);
-  TimeItem* time_ = static_cast<TimeItem*>(time);
-
   auto* p = new (std::nothrow) ChatMessageItem(id,
-                static_cast<std::shared_ptr<TextItem>>(name_),
-                static_cast<std::shared_ptr<TextItem>>(text_),
-                static_cast<std::shared_ptr<ImageItem>>(image_),
-                static_cast<std::shared_ptr<TimeItem>>(time_),
-                static_cast<ChatMessageItem::Type>((int)message_type));
+          dynamic_pointer_cast<TextItem>(static_cast<Handle*>(name)->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) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -186,9 +508,16 @@ extern "C" EXPORT_API int noti_ex_item_chat_message_get_name(
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
-
-  ChatMessageItem* p = static_cast<ChatMessageItem*>(handle);
-  *name = &(p->GetNameItem());
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::ChatMessage)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ChatMessageItem* p = static_cast<ChatMessageItem*>(h->Get());
+  if (p->GetNameItem().GetType() == AbstractItem::NullObject)
+    *name = nullptr;
+  else
+    *name = new Handle(&(p->GetNameItem()));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -200,8 +529,16 @@ extern "C" EXPORT_API int noti_ex_item_chat_message_get_text(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  ChatMessageItem* p = static_cast<ChatMessageItem*>(handle);
-  *text = &(p->GetTextItem());
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::ChatMessage)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ChatMessageItem* p = static_cast<ChatMessageItem*>(h->Get());
+  if (p->GetTextItem().GetType() == AbstractItem::NullObject)
+    *text = nullptr;
+  else
+    *text = new Handle(&(p->GetTextItem()));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -213,8 +550,16 @@ extern "C" EXPORT_API int noti_ex_item_chat_message_get_image(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  ChatMessageItem* p = static_cast<ChatMessageItem*>(handle);
-  *image =  &(p->GetImageItem());
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::ChatMessage)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ChatMessageItem* p = static_cast<ChatMessageItem*>(h->Get());
+  if (p->GetImageItem().GetType() == AbstractItem::NullObject)
+    *image = nullptr;
+  else
+    *image =  new Handle(&(p->GetImageItem()));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -226,8 +571,16 @@ extern "C" EXPORT_API int noti_ex_item_chat_message_get_time(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  ChatMessageItem* p = static_cast<ChatMessageItem*>(handle);
-  *time = &(p->GetTimeItem());
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::ChatMessage)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ChatMessageItem* p = static_cast<ChatMessageItem*>(h->Get());
+  if (p->GetTimeItem().GetType() == AbstractItem::NullObject)
+    *time = nullptr;
+  else
+    *time = new Handle(&(p->GetTimeItem()));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -239,7 +592,12 @@ extern "C" EXPORT_API int noti_ex_item_chat_message_get_message_type(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  ChatMessageItem* p = static_cast<ChatMessageItem*>(handle);
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::ChatMessage)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ChatMessageItem* p = static_cast<ChatMessageItem*>(h->Get());
   *message_type = (noti_ex_item_chat_message_type_e)(p->GetMessageType());
 
   return NOTI_EX_ERROR_NONE;
@@ -260,7 +618,7 @@ extern "C" EXPORT_API int noti_ex_item_checkbox_create(noti_ex_item_h *handle,
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -271,32 +629,92 @@ extern "C" EXPORT_API int noti_ex_item_checkbox_get_title(noti_ex_item_h handle,
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::CheckBox)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
 
-  CheckBoxItem* p = static_cast<CheckBoxItem*>(handle);
-  if (!p->GetTitle().empty()) {
-    *title = strdup(p->GetTitle().c_str());
-    if (*title == nullptr) {
-        LOGE("Out-of-memory");
-        return NOTI_EX_ERROR_OUT_OF_MEMORY;
-    }
+  CheckBoxItem* p = static_cast<CheckBoxItem*>(h->Get());
+  string str;
+  if (p->GetMultiLanguage() != nullptr &&
+    !p->GetMultiLanguage()->GetTranslatedString().empty())
+    str = p->GetMultiLanguage()->GetTranslatedString();
+  else if (!p->GetTitle().empty())
+    str = p->GetTitle();
+
+  *title = strdup(str.c_str());
+  if (*title == nullptr) {
+    LOGE("Out-of-memory");
+    return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
   return NOTI_EX_ERROR_NONE;
 }
 
-extern "C" EXPORT_API int noti_ex_item_checkbox_is_checked(noti_ex_item_h handle,
-    bool *checked) {
-  if (handle == nullptr || checked == nullptr) {
+extern "C" EXPORT_API int noti_ex_item_checkbox_set_multi_language_title(
+    noti_ex_item_h handle, noti_ex_multi_lang_h multi) {
+  if (handle == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  CheckBoxItem* p = static_cast<CheckBoxItem*>(handle);
+  Handle* p = static_cast<Handle*>(handle);
+  if (!p->IsValidType(AbstractItem::CheckBox)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  CheckBoxItem* ci = static_cast<CheckBoxItem*>(p->Get());
+  if (multi == nullptr) {
+    ci->SetMultiLanguage(nullptr);
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  shared_ptr<MultiLanguage> mul_ptr =
+      *reinterpret_cast<shared_ptr<MultiLanguage>*>(multi);
+  mul_ptr->UpdateString();
+  ci->SetMultiLanguage(mul_ptr);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_checkbox_get_check_state(
+    noti_ex_item_h handle, bool *checked) {
+  if (handle == nullptr || checked == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::CheckBox)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  CheckBoxItem* p = static_cast<CheckBoxItem*>(h->Get());
   *checked = p->IsChecked();
 
   return NOTI_EX_ERROR_NONE;
 }
 
+extern "C" EXPORT_API int noti_ex_item_checkbox_set_check_state(
+    noti_ex_item_h handle, bool checked) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::CheckBox)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  CheckBoxItem* p = static_cast<CheckBoxItem*>(h->Get());
+  p->SetChecked(checked);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
 extern "C" EXPORT_API int noti_ex_item_entry_create(noti_ex_item_h *handle,
     const char *id) {
   EntryItem* p;
@@ -312,7 +730,7 @@ extern "C" EXPORT_API int noti_ex_item_entry_create(noti_ex_item_h *handle,
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -324,13 +742,24 @@ extern "C" EXPORT_API int noti_ex_item_entry_get_text(noti_ex_item_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  EntryItem* p = static_cast<EntryItem*>(handle);
-  if (!p->GetText().empty()) {
-    *text = strdup(p->GetText().c_str());
-    if (*text == nullptr) {
-        LOGE("Out-of-memory");
-        return NOTI_EX_ERROR_OUT_OF_MEMORY;
-    }
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Entry)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  EntryItem* p = static_cast<EntryItem*>(h->Get());
+  string str;
+  if (p->GetMultiLanguage() != nullptr &&
+      !p->GetMultiLanguage()->GetTranslatedString().empty())
+    str = p->GetMultiLanguage()->GetTranslatedString();
+  else if (!p->GetText().empty())
+    str = p->GetText();
+
+  *text = strdup(str.c_str());
+  if (*text == nullptr) {
+    LOGE("Out-of-memory");
+    return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
   return NOTI_EX_ERROR_NONE;
@@ -342,46 +771,121 @@ extern "C" EXPORT_API int noti_ex_item_entry_set_text(noti_ex_item_h handle,
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
-
-  EntryItem* p = static_cast<EntryItem*>(handle);
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Entry)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  EntryItem* p = static_cast<EntryItem*>(h->Get());
   p->SetText(std::string(text));
 
   return NOTI_EX_ERROR_NONE;
 }
 
-extern "C" EXPORT_API int noti_ex_event_info_create(noti_ex_event_info_h *handle,
-    noti_ex_event_info_type_e type, const char *owner,
-    const char *channel, const char *item_id) {
+extern "C" EXPORT_API int noti_ex_item_entry_set_multi_language(
+    noti_ex_item_h handle, noti_ex_multi_lang_h multi) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (!p->IsValidType(AbstractItem::Entry)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  EntryItem* ei = static_cast<EntryItem*>(p->Get());
+  if (multi == nullptr) {
+    ei->SetMultiLanguage(nullptr);
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  shared_ptr<MultiLanguage> mul_ptr =
+      *reinterpret_cast<shared_ptr<MultiLanguage>*>(multi);
+  ei->SetMultiLanguage(mul_ptr);
+  ei->GetMultiLanguage()->UpdateString();
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_event_info_clone(noti_ex_event_info_h handle,
+               noti_ex_event_info_h* cloned_handle) {
+  if (handle == nullptr || cloned_handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Bundle cloned = static_cast<EventInfo*>(handle)->Serialize();
+  EventInfo* info = new EventInfo(cloned);
+  *cloned_handle = info;
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_event_info_destroy(
     noti_ex_event_info_h handle) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  EventInfo* info = static_cast<EventInfo*>(handle);
+  delete info;
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_event_info_get_event_type(
     noti_ex_event_info_h handle, noti_ex_event_info_type_e *event_type) {
+  if (handle == nullptr || event_type == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  EventInfo* info = static_cast<EventInfo*>(handle);
+  *event_type = static_cast<noti_ex_event_info_type_e>(info->GetEventType());
+
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_event_info_get_owner(
     noti_ex_event_info_h handle, char **owner) {
+  if (handle == nullptr || owner == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  EventInfo* info = static_cast<EventInfo*>(handle);
+  *owner = strdup(info->GetOwner().c_str());
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_event_info_get_channel(
     noti_ex_event_info_h handle, char **channel) {
+  if (handle == nullptr || channel == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  EventInfo* info = static_cast<EventInfo*>(handle);
+  *channel = strdup(info->GetChannel().c_str());
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_event_info_get_item_id(
     noti_ex_event_info_h handle, char **item_id) {
+  if (handle == nullptr || item_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  EventInfo* info = static_cast<EventInfo*>(handle);
+  *item_id = strdup(info->GetItemId().c_str());
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_event_info_get_request_id(
     noti_ex_event_info_h handle, int *req_id) {
+  if (handle == nullptr || req_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  EventInfo* info = static_cast<EventInfo*>(handle);
+  *req_id = info->GetRequestId();
   return NOTI_EX_ERROR_NONE;
 }
 
@@ -404,7 +908,7 @@ extern "C" EXPORT_API int noti_ex_item_group_create(noti_ex_item_h *handle,
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -415,8 +919,12 @@ extern "C" EXPORT_API int noti_ex_item_group_set_direction(noti_ex_item_h handle
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
-
-  GroupItem* p = static_cast<GroupItem*>(handle);
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Group)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  GroupItem* p = static_cast<GroupItem*>(h->Get());
   p->SetDirection(vertical);
 
   return NOTI_EX_ERROR_NONE;
@@ -428,8 +936,12 @@ extern "C" EXPORT_API int noti_ex_item_group_is_vertical(noti_ex_item_h handle,
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
-
-  GroupItem* p = static_cast<GroupItem*>(handle);
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Group)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  GroupItem* p = static_cast<GroupItem*>(h->Get());
   *vertical = p->IsVertical();
 
   return NOTI_EX_ERROR_NONE;
@@ -441,8 +953,12 @@ extern "C" EXPORT_API int noti_ex_item_group_get_app_label(noti_ex_item_h handle
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
-
-  GroupItem* p = static_cast<GroupItem*>(handle);
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Group)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  GroupItem* p = static_cast<GroupItem*>(h->Get());
   if (!p->GetAppLabel().empty()) {
     *label = strdup(p->GetAppLabel().c_str());
     if (*label == nullptr) {
@@ -460,11 +976,13 @@ extern "C" EXPORT_API int noti_ex_item_group_add_child(noti_ex_item_h handle,
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
-
-  GroupItem* p = static_cast<GroupItem*>(handle);
-
-  AbstractItem* child_ = static_cast<AbstractItem*>(child);
-  p->AddChild(static_cast<std::shared_ptr<AbstractItem>>(child_));
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Group)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  auto p = static_cast<GroupItem*>(h->Get());
+  p->AddChild((static_cast<Handle*>(child))->GetPtr());
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -475,23 +993,42 @@ extern "C" EXPORT_API int noti_ex_item_group_remove_child(noti_ex_item_h handle,
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
-
-  GroupItem* p = static_cast<GroupItem*>(handle);
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Group)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  GroupItem* p = static_cast<GroupItem*>(h->Get());
   p->RemoveChild(std::string(item_id));
 
   return NOTI_EX_ERROR_NONE;
 }
 
-extern "C" EXPORT_API int noti_ex_item_group_foreach(
-    noti_ex_item_group_foreach_cb callback, void *data) {
-  if (callback == nullptr) {
+extern "C" EXPORT_API int noti_ex_item_group_foreach_child(noti_ex_item_h handle,
+    noti_ex_item_group_foreach_child_cb callback, void *data) {
+  if (handle == nullptr || callback == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  // To do
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Group)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  GroupItem* p = static_cast<GroupItem*>(h->Get());
+  list<shared_ptr<AbstractItem>> children = p->GetChildren();
+  LOGI("Retrive (%zd)", children.size());
+  for (auto i : children) {
+    int ret = callback(
+        static_cast<noti_ex_item_h>(new Handle(i)), data);
+    if (ret != NOTI_EX_ERROR_NONE) {
+      LOGW("callback return (%d) stop foreach", ret);
+      break;
+    }
+  }
 
-  return 0;
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_image_create(noti_ex_item_h *handle,
@@ -513,7 +1050,7 @@ extern "C" EXPORT_API int noti_ex_item_image_create(noti_ex_item_h *handle,
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -524,14 +1061,20 @@ extern "C" EXPORT_API int noti_ex_item_image_get_image_path(
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
-
-  ImageItem* p = static_cast<ImageItem*>(handle);
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Image)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ImageItem* p = static_cast<ImageItem*>(h->Get());
   if (!p->GetImagePath().empty()) {
     *image_path = strdup(p->GetImagePath().c_str());
     if (*image_path == nullptr) {
       LOGE("Out-of-memory");
       return NOTI_EX_ERROR_OUT_OF_MEMORY;
     }
+  } else {
+    *image_path = nullptr;
   }
 
   return NOTI_EX_ERROR_NONE;
@@ -556,19 +1099,54 @@ extern "C" EXPORT_API int noti_ex_item_input_selector_create(
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
 
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_input_selector_get_contents(
-    noti_ex_item_h handle, char ***list, int *count) {
-  if (handle == nullptr || list == nullptr || count == nullptr) {
+    noti_ex_item_h handle, char ***contents_list, int *count) {
+  if (handle == nullptr || contents_list == nullptr || count == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  // To do
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::InputSelector)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  InputSelectorItem* p = static_cast<InputSelectorItem*>(h->Get());
+  vector<shared_ptr<MultiLanguage>> arr = p->GetMultiLanguageArr();
+  list<string> contents;
+  if (arr.size() == 0) {
+    contents = p->GetContents();
+  } else {
+    for (auto& i : arr) {
+      contents.push_back(i->GetTranslatedString());
+    }
+  }
+
+  char **list = (char**)calloc(contents.size(), sizeof(char*));
+  if (list == nullptr) {
+    LOGE("Out of memory");
+    return NOTI_EX_ERROR_OUT_OF_MEMORY;
+  }
+
+  int idx = 0;
+  for (auto& i : contents) {
+    list[idx] = strdup(i.c_str());
+    if (list[idx] == nullptr) {
+      __noti_ex_free_str_array(list, idx);
+      LOGE("Out of memory");
+      return NOTI_EX_ERROR_OUT_OF_MEMORY;
+    }
+    idx++;
+  }
+
+  *count = contents.size();
+  *contents_list = list;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -580,25 +1158,63 @@ extern "C" EXPORT_API int noti_ex_item_input_selector_set_contents(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  // To do
+  list<string> new_contents;
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::InputSelector)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  InputSelectorItem* p = static_cast<InputSelectorItem*>(h->Get());
+  for (int i = 0; i < count; i++) {
+    new_contents.push_back(contents[i]);
+  }
+  p->SetContents(move(new_contents));
 
   return NOTI_EX_ERROR_NONE;
 }
 
-extern "C" EXPORT_API int noti_ex_color_create(noti_ex_color_h *handle,
+extern "C" EXPORT_API int noti_ex_item_input_selector_set_multi_language_contents(
+    noti_ex_item_h handle, noti_ex_multi_lang_h* multi_language_list, int count) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (!p->IsValidType(AbstractItem::InputSelector)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  vector<shared_ptr<MultiLanguage>> m_list;
+  for (int i = 0; i < count; i++) {
+    shared_ptr<MultiLanguage> mul_ptr =
+      *reinterpret_cast<shared_ptr<MultiLanguage>*>(multi_language_list[i]);
+    mul_ptr->UpdateString();
+    m_list.push_back(mul_ptr);
+  }
+
+  InputSelectorItem* input = static_cast<InputSelectorItem*>(p->Get());
+  input->SetMultiLanguage(m_list);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_color_create(noti_ex_color_h *handle,
     unsigned char a, unsigned char r, unsigned char g, unsigned char b) {
   if (handle == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  auto* p = new (std::nothrow) Color(a, r, g, b);
-  if (p == nullptr) {
+  auto* ptr = new (std::nothrow) shared_ptr<Color>(
+      new (std::nothrow) Color(a, r, g, b));
+  if (ptr == nullptr || ptr->get() == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = ptr;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -609,8 +1225,8 @@ extern "C" EXPORT_API int noti_ex_color_destroy(noti_ex_color_h handle) {
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Color* p = static_cast<Color*>(handle);
-  p->~Color();
+  shared_ptr<Color>* p = static_cast<shared_ptr<Color>*>(handle);
+  delete p;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -622,8 +1238,8 @@ extern "C" EXPORT_API int noti_ex_color_get_alpha(noti_ex_color_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Color* p = static_cast<Color*>(handle);
-  *val = p->GetAVal();
+  shared_ptr<Color>* p = static_cast<shared_ptr<Color>*>(handle);
+  *val = (*p)->GetAVal();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -635,8 +1251,8 @@ extern "C" EXPORT_API int noti_ex_color_get_red(noti_ex_color_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Color* p = static_cast<Color*>(handle);
-  *val = p->GetRVal();
+  shared_ptr<Color>* p = static_cast<shared_ptr<Color>*>(handle);
+  *val = (*p)->GetRVal();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -648,8 +1264,8 @@ extern "C" EXPORT_API int noti_ex_color_get_green(noti_ex_color_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Color* p = static_cast<Color*>(handle);
-  *val = p->GetGVal();
+  shared_ptr<Color>* p = static_cast<shared_ptr<Color>*>(handle);
+  *val = (*p)->GetGVal();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -661,8 +1277,8 @@ extern "C" EXPORT_API int noti_ex_color_get_blue(noti_ex_color_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Color* p = static_cast<Color*>(handle);
-  *val = p->GetBVal();
+  shared_ptr<Color>* p = static_cast<shared_ptr<Color>*>(handle);
+  *val = (*p)->GetBVal();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -674,13 +1290,14 @@ extern "C" EXPORT_API int noti_ex_padding_create(noti_ex_padding_h *handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  auto* p = new (std::nothrow) Padding(left, top, right, bottom);
-  if (p == nullptr) {
+  auto* ptr = new (std::nothrow) shared_ptr<Padding>(
+      new (std::nothrow) Padding(left, top, right, bottom));
+  if (ptr == nullptr || ptr->get() == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = ptr;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -691,8 +1308,8 @@ extern "C" EXPORT_API int noti_ex_padding_destroy(noti_ex_padding_h handle) {
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Padding* p = static_cast<Padding*>(handle);
-  p->~Padding();
+  shared_ptr<Padding>* p = static_cast<shared_ptr<Padding>*>(handle);
+  delete p;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -704,8 +1321,8 @@ extern "C" EXPORT_API int noti_ex_padding_get_left(noti_ex_padding_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Padding* p = static_cast<Padding*>(handle);
-  *val = p->GetLeft();
+  shared_ptr<Padding>* p = static_cast<shared_ptr<Padding>*>(handle);
+  *val = (*p)->GetLeft();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -717,8 +1334,8 @@ extern "C" EXPORT_API int noti_ex_padding_get_top(noti_ex_padding_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Padding* p = static_cast<Padding*>(handle);
-  *val = p->GetTop();
+  shared_ptr<Padding>* p = static_cast<shared_ptr<Padding>*>(handle);
+  *val = (*p)->GetTop();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -730,10 +1347,10 @@ extern "C" EXPORT_API int noti_ex_padding_get_right(noti_ex_padding_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Padding* p = static_cast<Padding*>(handle);
-  *val = p->GetRight();
+  shared_ptr<Padding>* p = static_cast<shared_ptr<Padding>*>(handle);
+  *val = (*p)->GetRight();
 
-  return 0;
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_padding_get_bottom(noti_ex_padding_h handle,
@@ -743,10 +1360,10 @@ extern "C" EXPORT_API int noti_ex_padding_get_bottom(noti_ex_padding_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Padding* p = static_cast<Padding*>(handle);
-  *val = p->GetBottom();
+  shared_ptr<Padding>* p = static_cast<shared_ptr<Padding>*>(handle);
+  *val = (*p)->GetBottom();
 
-  return 0;
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_geometry_create(noti_ex_geometry_h *handle,
@@ -756,13 +1373,14 @@ extern "C" EXPORT_API int noti_ex_geometry_create(noti_ex_geometry_h *handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  auto* p = new (std::nothrow) Geometry(x, y, w, h);
-  if (p == nullptr) {
+  auto* ptr = new (std::nothrow) shared_ptr<Geometry>(
+      new (std::nothrow) Geometry(x, y, w, h));
+  if (ptr == nullptr || ptr->get() == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = ptr;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -773,8 +1391,8 @@ extern "C" EXPORT_API int noti_ex_geometry_destroy(noti_ex_geometry_h handle) {
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Geometry* p = static_cast<Geometry*>(handle);
-  p->~Geometry();
+  shared_ptr<Geometry>* p = static_cast<shared_ptr<Geometry>*>(handle);
+  delete p;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -786,8 +1404,8 @@ extern "C" EXPORT_API int noti_ex_geometry_get_x(noti_ex_geometry_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Geometry* p = static_cast<Geometry*>(handle);
-  *val = p->GetX();
+  shared_ptr<Geometry>* p = static_cast<shared_ptr<Geometry>*>(handle);
+  *val = (*p)->GetX();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -799,8 +1417,8 @@ extern "C" EXPORT_API int noti_ex_geometry_get_y(noti_ex_geometry_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Geometry* p = static_cast<Geometry*>(handle);
-  *val = p->GetY();
+  shared_ptr<Geometry>* p = static_cast<shared_ptr<Geometry>*>(handle);
+  *val = (*p)->GetY();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -812,8 +1430,8 @@ extern "C" EXPORT_API int noti_ex_geometry_get_width(noti_ex_geometry_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Geometry* p = static_cast<Geometry*>(handle);
-  *val = p->GetWidth();
+  shared_ptr<Geometry>* p = static_cast<shared_ptr<Geometry>*>(handle);
+  *val = (*p)->GetWidth();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -825,8 +1443,8 @@ extern "C" EXPORT_API int noti_ex_geometry_get_height(noti_ex_geometry_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Geometry* p = static_cast<Geometry*>(handle);
-  *val = p->GetHeight();
+  shared_ptr<Geometry>* p = static_cast<shared_ptr<Geometry>*>(handle);
+  *val = (*p)->GetHeight();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -840,17 +1458,21 @@ extern "C" EXPORT_API int noti_ex_style_create(noti_ex_style_h *handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Color* color_ = static_cast<Color*>(color);
-  Padding* padding_ = static_cast<Padding*>(padding);
-  Geometry* geo_ = static_cast<Geometry*>(geometry);
+  shared_ptr<Color> col = (color == nullptr) ?
+      nullptr : *(static_cast<shared_ptr<Color>*>(color));
+  shared_ptr<Padding> padd = (padding == nullptr) ?
+      nullptr : *(static_cast<shared_ptr<Padding>*>(padding));
+  shared_ptr<Geometry> geo = (geometry == nullptr) ?
+      nullptr : *(static_cast<shared_ptr<Geometry>*>(geometry));
 
-  auto* p = new (std::nothrow) Style(*color_, *padding_, *geo_);
-  if (p == nullptr) {
+  auto* ptr = new (std::nothrow) shared_ptr<Style>(
+      new (std::nothrow) Style(col, padd, geo));
+  if (ptr == nullptr || ptr->get() == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = ptr;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -861,8 +1483,8 @@ extern "C" EXPORT_API int noti_ex_style_destroy(noti_ex_style_h handle) {
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Style* p = static_cast<Style*>(handle);
-  p->~Style();
+  shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
+  delete p;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -874,14 +1496,41 @@ extern "C" EXPORT_API int noti_ex_style_get_padding(noti_ex_style_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Style* p = static_cast<Style*>(handle);
-  Padding* padding_ = new (std::nothrow) Padding(p->GetPadding());
-  if (padding_ == nullptr) {
+  shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
+  if ((*p)->GetPadding() == nullptr) {
+    LOGW("Padding info is null");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  shared_ptr<Padding>* padd = new (std::nothrow) shared_ptr<Padding>(
+      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;
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+
+extern "C" EXPORT_API int noti_ex_style_set_padding(noti_ex_style_h handle,
+    noti_ex_padding_h padding) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
+  if (padding == nullptr) {
+    (*p)->SetPadding(nullptr);
+    return NOTI_EX_ERROR_NONE;
   }
 
-  *padding = padding_;
+  shared_ptr<Padding>* padd = static_cast<shared_ptr<Padding>*>(padding);
+  (*p)->SetPadding(*padd);
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -893,14 +1542,40 @@ extern "C" EXPORT_API int noti_ex_style_get_color(noti_ex_style_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Style* p = static_cast<Style*>(handle);
-  Color* color_ = new (std::nothrow) Color(p->GetColor());
-  if (color_ == nullptr) {
+  shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
+  if ((*p)->GetColor() == nullptr) {
+    LOGW("Color info is null");
+    *color = nullptr;
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  shared_ptr<Color>* col = new (std::nothrow) shared_ptr<Color>(
+      new (std::nothrow) Color(*((*p)->GetColor())));
+  if (col == nullptr || col->get() == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *color = color_;
+  *color = col;
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_style_set_color(
+    noti_ex_style_h handle, noti_ex_color_h color) {
+  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)->SetColor(nullptr);
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  shared_ptr<Color>* col = static_cast<shared_ptr<Color>*>(color);
+  (*p)->SetColor(*col);
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -912,27 +1587,132 @@ extern "C" EXPORT_API int noti_ex_style_get_geometry(noti_ex_style_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  Style* p = static_cast<Style*>(handle);
-  Geometry* geo_ = new (std::nothrow) Geometry(p->GetGeometry());
-  if (geo_ == nullptr) {
+  shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
+  if ((*p)->GetGeometry() == nullptr) {
+    LOGW("Geometry info is null");
+    *geometry = nullptr;
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  shared_ptr<Geometry>* geo = new (std::nothrow) shared_ptr<Geometry>(
+      new (std::nothrow) Geometry(*((*p)->GetGeometry())));
+  if (geo == nullptr || geo->get() == nullptr) {
+    LOGE("Out-of-memory");
+    return NOTI_EX_ERROR_OUT_OF_MEMORY;
+  }
+
+  *geometry = geo;
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_style_set_geometry(
+    noti_ex_style_h handle, noti_ex_geometry_h geometry) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
+  if (geometry == nullptr) {
+    (*p)->SetGeometry(nullptr);
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  shared_ptr<Geometry>* geo = static_cast<shared_ptr<Geometry>*>(geometry);
+  (*p)->SetGeometry(*geo);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_style_get_background_image(
+    noti_ex_style_h handle, char** background_image) {
+  if (handle == nullptr || background_image == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
+
+  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) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
+  if (background_image == nullptr)
+    (*p)->SetBackgroundImage("");
+  else
+    (*p)->SetBackgroundImage(background_image);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_style_get_background_color(
+    noti_ex_style_h handle, noti_ex_color_h* color) {
+  if (handle == nullptr || color == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  shared_ptr<Style>* p = static_cast<shared_ptr<Style>*>(handle);
+  if ((*p)->GetBackgroundColor() == nullptr) {
+    LOGW("Color info is null");
+    *color = nullptr;
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  shared_ptr<Color>* col = new (std::nothrow) shared_ptr<Color>(
+      new (std::nothrow) Color(*((*p)->GetBackgroundColor())));
+  if (col == nullptr || col->get() == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *geometry = geo_;
+  *color = col;
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_style_set_background_color(
+    noti_ex_style_h handle, noti_ex_color_h color) {
+  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);
 
   return NOTI_EX_ERROR_NONE;
 }
 
 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;
   }
 
-  Color* color_ = static_cast<Color*>(color);
-  auto* p = new (std::nothrow) LEDInfo(*color_);
+  shared_ptr<Color>* color_ptr = static_cast<shared_ptr<Color>*>(color);
+  shared_ptr<LEDInfo>* p = new (std::nothrow) shared_ptr<LEDInfo>(
+      new (std::nothrow) LEDInfo(*color_ptr));
   if (p == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
@@ -949,9 +1729,9 @@ extern "C" EXPORT_API int noti_ex_led_info_destroy(noti_ex_led_info_h handle) {
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  LEDInfo* p = static_cast<LEDInfo*>(handle);
-  p->~LEDInfo();
-
+  shared_ptr<LEDInfo>* led_ptr =
+      reinterpret_cast<shared_ptr<LEDInfo>*>(handle);
+  delete led_ptr;
   return NOTI_EX_ERROR_NONE;
 }
 
@@ -962,8 +1742,9 @@ extern "C" EXPORT_API int noti_ex_led_info_set_on_period(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  LEDInfo* p = static_cast<LEDInfo*>(handle);
-  p->SetOnPeriod(ms);
+  shared_ptr<LEDInfo>* led_ptr =
+      reinterpret_cast<shared_ptr<LEDInfo>*>(handle);
+  (*led_ptr)->SetOnPeriod(ms);
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -975,8 +1756,9 @@ extern "C" EXPORT_API int noti_ex_led_info_get_on_period(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  LEDInfo* p = static_cast<LEDInfo*>(handle);
-  *ms = p->GetOnPeriod();
+  shared_ptr<LEDInfo>* led_ptr =
+      reinterpret_cast<shared_ptr<LEDInfo>*>(handle);
+  *ms = (*led_ptr)->GetOnPeriod();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -988,8 +1770,9 @@ extern "C" EXPORT_API int noti_ex_led_info_set_off_period(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  LEDInfo* p = static_cast<LEDInfo*>(handle);
-  p->SetOffPeriod(ms);
+  shared_ptr<LEDInfo>* led_ptr =
+      reinterpret_cast<shared_ptr<LEDInfo>*>(handle);
+  (*led_ptr)->SetOffPeriod(ms);
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1001,8 +1784,9 @@ extern "C" EXPORT_API int noti_ex_led_info_get_off_period(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  LEDInfo* p = static_cast<LEDInfo*>(handle);
-  *ms = p->GetOffPeriod();
+  shared_ptr<LEDInfo>* led_ptr =
+      reinterpret_cast<shared_ptr<LEDInfo>*>(handle);
+  *ms = (*led_ptr)->GetOffPeriod();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1014,14 +1798,41 @@ extern "C" EXPORT_API int noti_ex_led_info_get_color(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  LEDInfo* p = static_cast<LEDInfo*>(handle);
-  Color* color_ = new (std::nothrow) Color(p->GetColor());
-  if (color_ == nullptr) {
+  shared_ptr<LEDInfo>* led_ptr =
+      reinterpret_cast<shared_ptr<LEDInfo>*>(handle);
+  if ((*led_ptr)->GetColor() == nullptr) {
+    LOGW("Color is null");
+    *color = nullptr;
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  shared_ptr<Color>* col = new (std::nothrow) shared_ptr<Color>(
+      new (std::nothrow) Color(*((*led_ptr)->GetColor())));
+  if (col == nullptr || col->get() == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *color = color_;
+  *color = col;
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_led_info_set_color(
+    noti_ex_led_info_h handle, noti_ex_color_h color) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  shared_ptr<LEDInfo>* p = static_cast<shared_ptr<LEDInfo>*>(handle);
+  if (color == nullptr) {
+    (*p)->SetColor(nullptr);
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  shared_ptr<Color>* col = static_cast<shared_ptr<Color>*>(color);
+  (*p)->SetColor(*col);
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1032,8 +1843,9 @@ extern "C" EXPORT_API int noti_ex_action_destroy(noti_ex_action_h handle) {
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  AbstractAction* p = static_cast<AbstractAction*>(handle);
-  p->~AbstractAction();
+  shared_ptr<AbstractAction>* ptr =
+      static_cast<shared_ptr<AbstractAction>*>(handle);
+  delete ptr;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1045,8 +1857,9 @@ extern "C" EXPORT_API int noti_ex_action_get_type(noti_ex_action_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  AbstractAction* p = static_cast<AbstractAction*>(handle);
-  *type = p->GetType();
+  shared_ptr<AbstractAction>* ptr =
+      static_cast<shared_ptr<AbstractAction>*>(handle);
+  *type = (*ptr)->GetType();
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1058,22 +1871,23 @@ extern "C" EXPORT_API int noti_ex_action_is_local(noti_ex_action_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  AbstractAction* p = static_cast<AbstractAction*>(handle);
-  *local = p->IsLocal();
+  shared_ptr<AbstractAction>* ptr =
+      static_cast<shared_ptr<AbstractAction>*>(handle);
+  *local = (*ptr)->IsLocal();
 
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_action_execute(noti_ex_action_h handle,
     noti_ex_item_h item) {
-  if (handle == nullptr || item==nullptr) {
+  if (handle == nullptr || item == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
-
-  AbstractAction* p = static_cast<AbstractAction*>(handle);
-  AbstractItem* item_ = static_cast<AbstractItem*>(item);
-  p->Execute(static_cast<std::shared_ptr<AbstractItem>>(item_));
+  shared_ptr<AbstractAction>* ptr =
+      static_cast<shared_ptr<AbstractAction>*>(handle);
+  Handle* ih = static_cast<Handle*>(item);
+  (*ptr)->Execute(ih->GetPtr());
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1085,13 +1899,16 @@ extern "C" EXPORT_API int noti_ex_action_get_extra(noti_ex_action_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  AbstractAction* p = static_cast<AbstractAction*>(handle);
-  if (!p->GetExtra().empty()) {
-    *extra = strdup(p->GetExtra().c_str());
+  shared_ptr<AbstractAction>* ptr =
+      static_cast<shared_ptr<AbstractAction>*>(handle);
+  if (!(*ptr)->GetExtra().empty()) {
+    *extra = strdup((*ptr)->GetExtra().c_str());
     if (*extra == nullptr) {
       LOGE("Out-of-memory");
       return NOTI_EX_ERROR_OUT_OF_MEMORY;
     }
+  } else {
+    *extra = nullptr;
   }
 
   return NOTI_EX_ERROR_NONE;
@@ -1099,236 +1916,908 @@ extern "C" EXPORT_API int noti_ex_action_get_extra(noti_ex_action_h handle,
 
 extern "C" EXPORT_API int noti_ex_item_info_get_hide_time(
     noti_ex_item_info_h handle, int *hide_time) {
-  return 0;
+  if (handle == nullptr || hide_time == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  IItemInfo* p = static_cast<IItemInfo*>(handle);
+  *hide_time = p->GetHideTime();
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_info_set_hide_time(
     noti_ex_item_info_h handle, int hide_time) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  IItemInfo* p = static_cast<IItemInfo*>(handle);
+  p->SetHideTime(hide_time);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_info_get_delete_time(
     noti_ex_item_info_h handle, int *delete_time) {
-  return 0;
+  if (handle == nullptr || delete_time == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  IItemInfo* p = static_cast<IItemInfo*>(handle);
+  *delete_time = p->GetDeleteTime();
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_info_set_delete_time(
     noti_ex_item_info_h handle, int delete_time) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  IItemInfo* p = static_cast<IItemInfo*>(handle);
+  p->SetDeleteTime(delete_time);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_info_get_time(
     noti_ex_item_info_h handle, time_t *time) {
-  return 0;
+  if (handle == nullptr || time == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  IItemInfo* p = static_cast<IItemInfo*>(handle);
+  *time = p->GetTime();
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_destroy(noti_ex_item_h handle) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* h = static_cast<Handle*>(handle);
+  delete h;
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_find_by_id(noti_ex_item_h handle,
     const char *id, noti_ex_item_h *item) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  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;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_type(noti_ex_item_h handle,
     int *type) {
-  return 0;
-}
+  if (handle == nullptr || type == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
 
-extern "C" EXPORT_API int noti_ex_item_get_shared_path(noti_ex_item_h handle,
-    char ***path, int *count) {
-  return 0;
+  Handle* h = static_cast<Handle*>(handle);
+  AbstractItem* p = h->Get();
+  *type = p->GetType();
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_id(noti_ex_item_h handle,
     char **id) {
-  return 0;
+  if (handle == nullptr || id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  Handle* h = static_cast<Handle*>(handle);
+  AbstractItem* p = h->Get();
+  *id = strdup(p->GetId().c_str());
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_set_id(noti_ex_item_h handle,
     const char *id) {
-  return 0;
+  if (handle == nullptr || id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  Handle* p = static_cast<Handle*>(handle);
+  p->Get()->SetId(id);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_action(noti_ex_item_h handle,
     noti_ex_action_h *action) {
-  return 0;
+  if (handle == nullptr || action == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  Handle* p = static_cast<Handle*>(handle);
+  if (p->Get()->GetAction() == nullptr) {
+    *action = nullptr;
+    return NOTI_EX_ERROR_NONE;
+  }
+  *action = static_cast<noti_ex_action_h>(new shared_ptr<AbstractAction>(
+      p->Get()->GetAction()));
+
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_set_action(noti_ex_item_h handle,
     noti_ex_action_h action) {
-  return 0;
+  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);
+  p->Get()->SetAction(*ptr);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_style(noti_ex_item_h handle,
     noti_ex_style_h *style) {
-  return 0;
+  if (handle == nullptr || style == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  shared_ptr<Style> s = p->Get()->GetStyle();
+  if (s.get() == nullptr) {
+    LOGW("Style is null");
+    *style = nullptr;
+    return NOTI_EX_ERROR_NONE;
+  }
+
+  auto* ptr = new (std::nothrow) shared_ptr<Style>(new (std::nothrow) Style(*s));
+  if (ptr == nullptr || ptr->get() == nullptr) {
+    LOGE("Out of memory");
+    return NOTI_EX_ERROR_OUT_OF_MEMORY;
+  }
+
+  *style = ptr;
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_set_style(noti_ex_item_h handle,
     noti_ex_style_h style) {
-  return 0;
+  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;
 }
 
 extern "C" EXPORT_API int noti_ex_item_set_visible(noti_ex_item_h handle,
     bool visible) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  p->Get()->SetVisible(visible);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_visible(noti_ex_item_h handle,
     bool *visible) {
-  return 0;
+  if (handle == nullptr || visible == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  *visible = p->Get()->GetVisible();
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_set_enable(noti_ex_item_h handle,
     bool enable) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  p->Get()->SetEnable(enable);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_enable(noti_ex_item_h handle,
     bool *enable) {
-  return 0;
+  if (handle == nullptr || enable == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  *enable = p->Get()->GetEnable();
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_add_receiver(noti_ex_item_h handle,
     const char *receiver_group) {
-  return 0;
+  if (handle == nullptr || receiver_group == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  p->Get()->AddReceiver(receiver_group);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_remove_receiver(noti_ex_item_h handle,
     const char *receiver_group) {
-  return 0;
+  if (handle == nullptr || receiver_group == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  p->Get()->RemoveReceiver(receiver_group);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_receiver_list(noti_ex_item_h handle,
-    char ***list, int *count) {
-  return 0;
-}
+    char ***receiver_list, int *count) {
+  if (handle == nullptr || receiver_list == nullptr || count == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  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");
+    return NOTI_EX_ERROR_OUT_OF_MEMORY;
+  }
+
+  int idx = 0;
+  for (auto& i : receivers) {
+    tmp_list[idx] = strdup(i.c_str());
+    if (tmp_list[idx] == nullptr) {
+      __noti_ex_free_str_array(tmp_list, idx);
+      LOGE("Out of memory");
+      return NOTI_EX_ERROR_OUT_OF_MEMORY;
+    }
+    idx++;
+  }
+
+  *receiver_list = tmp_list;
+  *count = receivers.size();
+  return NOTI_EX_ERROR_NONE;
+}
 
 extern "C" EXPORT_API int noti_ex_item_set_policy(noti_ex_item_h handle,
     int policy) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  p->Get()->SetPolicy(policy);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_policy(noti_ex_item_h handle,
     int *policy) {
-  return 0;
+  if (handle == nullptr || policy == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  *policy = p->Get()->GetPolicy();
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_channel(noti_ex_item_h handle,
     char **channel) {
-  return 0;
+  if (handle == nullptr || channel == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (!p->Get()->GetChannel().empty())
+    *channel = strdup(p->Get()->GetChannel().c_str());
+  else
+    *channel = nullptr;
+
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_set_channel(noti_ex_item_h handle,
     const char *channel) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  p->Get()->SetChannel(channel);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_set_led_info(noti_ex_item_h handle,
     noti_ex_led_info_h led) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (led == nullptr) {
+    p->Get()->SetLEDInfo(nullptr);
+    return NOTI_EX_ERROR_NONE;
+  }
+  shared_ptr<LEDInfo>* led_ptr =
+      reinterpret_cast<shared_ptr<LEDInfo>*>(led);
+  p->Get()->SetLEDInfo(*led_ptr);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_led_info(noti_ex_item_h handle,
     noti_ex_led_info_h *led) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (p->Get()->GetLEDInfo() != nullptr)
+    *led = new shared_ptr<LEDInfo>(p->Get()->GetLEDInfo());
+  else
+    *led = nullptr;
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_set_sound_path(noti_ex_item_h handle,
     const char *path) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (path == nullptr)
+    p->Get()->SetSoundPath("");
+  else
+    p->Get()->SetSoundPath(path);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_set_vibration_path(noti_ex_item_h handle,
     const char *path) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (path == nullptr)
+    p->Get()->SetVibrationPath("");
+  else
+    p->Get()->SetVibrationPath(path);
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_sound_path(noti_ex_item_h handle,
     char **path) {
-  return 0;
+  if (handle == nullptr || path == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (p->Get()->GetSoundPath().empty())
+    *path = nullptr;
+  else
+    *path = strdup(p->Get()->GetSoundPath().c_str());
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_vibration_path(noti_ex_item_h handle,
     char **path) {
-  return 0;
+  if (handle == nullptr || path == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (p->Get()->GetVibrationPath().empty())
+    *path = nullptr;
+  else
+    *path = strdup(p->Get()->GetVibrationPath().c_str());
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_info(noti_ex_item_h handle,
     noti_ex_item_info_h *info) {
-  return 0;
+  if (handle == nullptr || info == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (p->Get()->GetInfo() == nullptr)
+    *info = nullptr;
+  else
+    *info = static_cast<noti_ex_item_info_h>(p->Get()->GetInfo().get());
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_sender_app_id(noti_ex_item_h handle,
     char **id) {
-  return 0;
-}
+  if (handle == nullptr || id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
 
-extern "C" EXPORT_API int noti_ex_item_set_sender_app_id(noti_ex_item_h handle,
-    const char *id) {
-  return 0;
+  Handle* p = static_cast<Handle*>(handle);
+  if (p->Get()->GetSenderAppId().empty())
+    *id = nullptr;
+  else
+    *id = strdup(p->Get()->GetSenderAppId().c_str());
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_get_tag(noti_ex_item_h handle,
     char **tag) {
-  return 0;
+  if (handle == nullptr || tag == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (p->Get()->GetTag().empty())
+    *tag = nullptr;
+  else
+    *tag = strdup(p->Get()->GetTag().c_str());
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_set_tag(noti_ex_item_h handle,
     const char *tag) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (tag == nullptr)
+    p->Get()->SetTag("");
+  else
+    p->Get()->SetTag(tag);
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_get_ongoing_state(noti_ex_item_h handle,
+    bool* ongoing) {
+  if (handle == nullptr || ongoing == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  *ongoing = p->Get()->GetOnGoingState();
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_set_ongoing_state(noti_ex_item_h handle,
+    bool ongoing) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  p->Get()->SetOnGoingState(ongoing);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_check_type_exist(noti_ex_item_h handle,
+    int type, bool* exist) {
+  if (handle == nullptr || exist == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  *exist = p->Get()->IsItemTypeExist(type);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_get_main_type(noti_ex_item_h handle,
+    int* type) {
+  if (handle == nullptr || type == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  *type = p->Get()->GetMainType();
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_set_main_type(noti_ex_item_h handle,
+    const char* id, int type) {
+  if (handle == nullptr || id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (!(p->Get()->SetMainType(string(id),
+                    static_cast<AbstractItem::MainType>(type))))
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_find_by_main_type(noti_ex_item_h handle,
+    int type, noti_ex_item_h* item) {
+  if (handle == nullptr || item == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Group)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  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) {
-  return 0;
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  string receiver_group_str = "";
+  if (receiver_group)
+    receiver_group_str = string(receiver_group);
+
+  ManagerStub* stub = new (std::nothrow) ManagerStub(
+      unique_ptr<DBusSender>(new DBusSender(Reporter::GetPath())),
+      unique_ptr<DBusEventListener>(new DBusEventListener(Manager::GetPath())),
+      receiver_group_str);
+  if (stub == nullptr) {
+    LOGE("Fail to create manager");
+    return NOTI_EX_ERROR_IO_ERROR;
+  }
+  stub->SetManagerCallbackInfo(unique_ptr<ManagerCallbackInfo>(
+      new ManagerCallbackInfo(event_callbacks, data)));
+  *handle = static_cast<noti_ex_manager_h>(stub);
+
+  return NOTI_EX_ERROR_NONE;
 }
 
-extern "C" EXPORT_API int noti_ex_manager_deatroy(noti_ex_manager_h handle) {
-  return 0;
+extern "C" EXPORT_API int noti_ex_manager_destroy(noti_ex_manager_h handle) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ManagerStub* stub = static_cast<ManagerStub*>(handle);
+  delete stub;
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_manager_get(noti_ex_manager_h handle,
     noti_ex_item_h **items, int *count) {
-  return 0;
+  if (handle == nullptr || items == nullptr || count == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  try {
+    ManagerStub* stub = static_cast<ManagerStub*>(handle);
+    list<unique_ptr<item::AbstractItem>> item_list = stub->Get();
+    if (item_list.size() == 0) {
+      *items = nullptr;
+      *count = 0;
+      return NOTI_EX_ERROR_NONE;
+    }
+    noti_ex_item_h* added_item =
+        (noti_ex_item_h*)calloc(item_list.size(), sizeof(noti_ex_item_h));
+    if (added_item == nullptr) {
+      LOGE("Fail to create items");
+      return NOTI_EX_ERROR_OUT_OF_MEMORY;
+    }
+
+    int idx = 0;
+    for (auto& i : item_list) {
+      added_item[idx++] = static_cast<noti_ex_item_h>(new Handle(move(i)));
+    }
+    *items = added_item;
+    *count = item_list.size();
+  } 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_get_by_channel(
+    noti_ex_manager_h handle, char* channel, noti_ex_item_h** items, int* count) {
+  if (handle == nullptr || channel == nullptr ||
+      items == nullptr || count == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  try {
+    ManagerStub* stub = static_cast<ManagerStub*>(handle);
+    list<unique_ptr<item::AbstractItem>> item_list = stub->Get(channel);
+    if (item_list.size() == 0) {
+      *items = nullptr;
+      *count = 0;
+      return NOTI_EX_ERROR_NONE;
+    }
+    noti_ex_item_h* added_item =
+        (noti_ex_item_h*)calloc(item_list.size(), sizeof(noti_ex_item_h));
+    if (added_item == nullptr) {
+      LOGE("Fail to create items");
+      return NOTI_EX_ERROR_OUT_OF_MEMORY;
+    }
+
+    int idx = 0;
+    for (auto& i : item_list) {
+      added_item[idx++] = static_cast<noti_ex_item_h>(new Handle(move(i)));
+    }
+    *items = added_item;
+    *count = item_list.size();
+  } 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_update(noti_ex_manager_h handle,
     noti_ex_item_h noti, int *request_id) {
-  return 0;
+  if (handle == nullptr || noti == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ManagerStub* stub = static_cast<ManagerStub*>(handle);
+    Handle* sp = static_cast<Handle*>(noti);
+    if (sp->GetPtr().get() == nullptr) {
+      LOGE("Invalid noti reference can not be sended");
+      return NOTI_EX_ERROR_INVALID_PARAMETER;
+    } else {
+      *request_id = stub->Update(sp->GetPtr());
+    }
+  } 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_delete(noti_ex_manager_h handle,
     noti_ex_item_h noti, int *request_id) {
-  return 0;
+  if (handle == nullptr || noti == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ManagerStub* stub = static_cast<ManagerStub*>(handle);
+    Handle* item = static_cast<Handle*>(noti);
+    if (item->GetPtr().get() == nullptr) {
+      LOGE("Invalid noti reference can not be sended");
+      return NOTI_EX_ERROR_INVALID_PARAMETER;
+    } else {
+      *request_id = stub->Delete(item->GetPtr());
+    }
+  } 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_delete_all(noti_ex_manager_h handle,
     int *request_id) {
-  return 0;
+  if (handle == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ManagerStub* stub = static_cast<ManagerStub*>(handle);
+    *request_id = stub->DeleteAll();
+  } 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_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) {
-  return 0;
+  if (handle == nullptr || noti == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ManagerStub* stub = static_cast<ManagerStub*>(handle);
+    Handle* item = static_cast<Handle*>(noti);
+    if (item->GetPtr().get() == nullptr) {
+      LOGE("Invalid noti reference can not be sended");
+      return NOTI_EX_ERROR_INVALID_PARAMETER;
+    } else {
+      *request_id = stub->Hide(item->GetPtr());
+    }
+  } 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_find_by_root_id(
     noti_ex_manager_h handle, const char *root_id, noti_ex_item_h *item) {
-  return 0;
+  if (handle == nullptr || root_id == nullptr || item == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ManagerStub* stub = static_cast<ManagerStub*>(handle);
+    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;
+  }
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_manager_send_error(noti_ex_manager_h handle,
-    noti_ex_event_info_h info, noti_ex_error_e error, int *request_id) {
-  return 0;
+    noti_ex_event_info_h info, noti_ex_error_e error) {
+  if (handle == nullptr || info == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ManagerStub* stub = static_cast<ManagerStub*>(handle);
+    IEventInfo* c_info = static_cast<IEventInfo*>(info);
+    stub->SendError(static_cast<const IEventInfo&>(*c_info),
+        static_cast<NotificationError>(error));
+  } 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_get_count(noti_ex_manager_h handle,
-    int *cnt) {
-  return 0;
+extern "C" EXPORT_API int noti_ex_manager_get_notification_count(
+    noti_ex_manager_h handle, int *cnt) {
+
+  if (handle == nullptr || cnt == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ManagerStub* stub = static_cast<ManagerStub*>(handle);
+    *cnt = stub->GetCount();
+  } 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_item_progress_create(noti_ex_item_h *handle,
@@ -1350,7 +2839,7 @@ extern "C" EXPORT_API int noti_ex_item_progress_create(noti_ex_item_h *handle,
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1362,7 +2851,12 @@ extern "C" EXPORT_API int noti_ex_item_progress_get_current(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  ProgressItem* p = static_cast<ProgressItem*>(handle);
+  Handle *h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Progress)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ProgressItem* p = static_cast<ProgressItem*>(h->Get());
   *current = p->GetCurrent();
 
   return NOTI_EX_ERROR_NONE;
@@ -1375,7 +2869,12 @@ extern "C" EXPORT_API int noti_ex_item_progress_set_current(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  ProgressItem* p = static_cast<ProgressItem*>(handle);
+  Handle *h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Progress)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ProgressItem* p = static_cast<ProgressItem*>(h->Get());
   p->SetCurrent(current);
 
   return NOTI_EX_ERROR_NONE;
@@ -1388,7 +2887,12 @@ extern "C" EXPORT_API int noti_ex_item_progress_get_min(noti_ex_item_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  ProgressItem* p = static_cast<ProgressItem*>(handle);
+  Handle *h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Progress)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ProgressItem* p = static_cast<ProgressItem*>(h->Get());
   *min = p->GetMin();
 
   return NOTI_EX_ERROR_NONE;
@@ -1401,84 +2905,289 @@ extern "C" EXPORT_API int noti_ex_item_progress_get_max(noti_ex_item_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  ProgressItem* p = static_cast<ProgressItem*>(handle);
+  Handle *h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Progress)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ProgressItem* p = static_cast<ProgressItem*>(h->Get());
   *max = p->GetMax();
 
   return NOTI_EX_ERROR_NONE;
 }
 
+extern "C" EXPORT_API int noti_ex_item_progress_get_type(noti_ex_item_h handle,
+    int* type) {
+  if (handle == nullptr || type == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle *h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Progress)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ProgressItem* p = static_cast<ProgressItem*>(h->Get());
+  *type = static_cast<noti_ex_item_progress_type_e>(p->GetProgressType());
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_progress_set_type(noti_ex_item_h handle,
+    int type) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle *h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Progress)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ProgressItem* p = static_cast<ProgressItem*>(h->Get());
+  p->SetProgressType(static_cast<ProgressItem::Type>(type));
+
+  return NOTI_EX_ERROR_NONE;
+}
+
 extern "C" EXPORT_API int noti_ex_reporter_create(noti_ex_reporter_h *handle,
     noti_ex_reporter_events_s event_callbacks, void *data) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  ReporterStub* stub = new (std::nothrow) ReporterStub(
+      unique_ptr<DBusSender>(new DBusSender(Manager::GetPath())),
+      unique_ptr<DBusEventListener>(new DBusEventListener(Reporter::GetPath())));
+  if (stub == nullptr) {
+    LOGE("Fail to create manager");
+    return NOTI_EX_ERROR_IO_ERROR;
+  }
+  stub->SetReporterCallbackInfo(unique_ptr<ReporterCallbackInfo>(
+      new ReporterCallbackInfo(event_callbacks, data)));
+
+  *handle = static_cast<noti_ex_reporter_h>(stub);
+
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_reporter_destroy(noti_ex_reporter_h handle) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  ReporterStub* stub = static_cast<ReporterStub*>(handle);
+  delete stub;
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_reporter_send_error(noti_ex_reporter_h handle,
-    noti_ex_event_info_h info, noti_ex_error_e error, int *request_id) {
-  return 0;
+    noti_ex_event_info_h info, noti_ex_error_e error) {
+  if (handle == nullptr || info == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ReporterStub* stub = static_cast<ReporterStub*>(handle);
+    IEventInfo* c_info = static_cast<IEventInfo*>(info);
+    stub->SendError(static_cast<const IEventInfo&>(*c_info),
+        static_cast<NotificationError>(error));
+  } 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_post(noti_ex_reporter_h handle,
     noti_ex_item_h noti, int *request_id) {
-  return 0;
+  if (handle == nullptr || noti == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ReporterStub* stub = static_cast<ReporterStub*>(handle);
+    Handle* h = static_cast<Handle*>(noti);
+    if (h->GetPtr().get() == nullptr) {
+      LOGE("Invalid noti reference can not be sended");
+      return NOTI_EX_ERROR_INVALID_PARAMETER;
+    } else {
+      *request_id = stub->Post(h->GetPtr());
+    }
+  } 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_post_list(noti_ex_reporter_h handle,
     noti_ex_item_h *noti_list, int count, int *request_id) {
-  return 0;
+
+  if (handle == nullptr || noti_list == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ReporterStub* stub = static_cast<ReporterStub*>(handle);
+    list<shared_ptr<item::AbstractItem>> notiList;
+    for (int i = 0; i < count; i++) {
+      Handle* item = static_cast<Handle*>(noti_list[i]);
+      notiList.push_back(item->GetPtr());
+    }
+    *request_id = stub->Post(notiList);
+  } 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_update(noti_ex_reporter_h handle,
     noti_ex_item_h noti, int *request_id) {
-  return 0;
+  if (handle == nullptr || noti == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ReporterStub* stub = static_cast<ReporterStub*>(handle);
+    Handle* item = static_cast<Handle*>(noti);
+    if (item->GetPtr().get() == nullptr) {
+      LOGE("Invalid noti reference can not be sended");
+      return NOTI_EX_ERROR_INVALID_PARAMETER;
+    } else {
+      *request_id = stub->Update(item->GetPtr());
+    }
+  } 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_delete(noti_ex_reporter_h handle,
     noti_ex_item_h noti, int *request_id) {
-  return 0;
+  if (handle == nullptr || noti == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ReporterStub* stub = static_cast<ReporterStub*>(handle);
+    Handle* item = static_cast<Handle*>(noti);
+    if (item->GetPtr().get() == nullptr) {
+      LOGE("Invalid noti reference can not be sended");
+      return NOTI_EX_ERROR_INVALID_PARAMETER;
+    } else {
+      *request_id = stub->Delete(item->GetPtr());
+    }
+  } 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_delete_all(
     noti_ex_reporter_h handle, int *request_id) {
-  return 0;
+  if (handle == nullptr || request_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ReporterStub* stub = static_cast<ReporterStub*>(handle);
+    *request_id = stub->DeleteAll();
+  } 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_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) {
-  return 0;
+  if (handle == nullptr || root_id == nullptr || item == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  try {
+    ReporterStub* stub = static_cast<ReporterStub*>(handle);
+    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;
+  }
+  return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_text_create(noti_ex_item_h *handle,
-    const char *id, const char *text, const char *hyper_link) {
-  if (handle == nullptr) {
+    const char *id, const char *text, const char *hyperlink) {
+  if (handle == nullptr || text == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  auto* p = new (std::nothrow) TextItem(id, std::string(text),
-                std::string(hyper_link));
+  TextItem* p;
+
+  if (id == NULL)
+    id = "";
+
+  if (hyperlink)
+    p = new (std::nothrow) TextItem(id, std::string(text),
+                std::string(hyperlink));
+  else
+    p = new (std::nothrow) TextItem(id, std::string(text));
+
   if (p == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
 
   return NOTI_EX_ERROR_NONE;
 }
 
 extern "C" EXPORT_API int noti_ex_item_text_set_contents(noti_ex_item_h handle,
     const char *contents) {
-  if (handle == nullptr) {
+  if (handle == nullptr || contents == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  TextItem* p = static_cast<TextItem*>(handle);
-  p->SetContents(std::string(contents));
+  Handle* p = static_cast<Handle*>(handle);
+  if (!p->IsValidType(AbstractItem::Text)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  TextItem* ti = static_cast<TextItem*>(p->Get());
+  ti->SetContents(std::string(contents));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1490,34 +3199,79 @@ extern "C" EXPORT_API int noti_ex_item_text_get_contents(noti_ex_item_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  TextItem* p = static_cast<TextItem*>(handle);
-  if (!p->GetContents().empty()) {
-    *contents = strdup(p->GetContents().c_str());
-    if (*contents == nullptr) {
-      LOGE("Out-of-memory");
-      return NOTI_EX_ERROR_OUT_OF_MEMORY;
-    }
+  Handle* p = static_cast<Handle*>(handle);
+  if (!p->IsValidType(AbstractItem::Text)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  TextItem* ti = static_cast<TextItem*>(p->Get());
+  string str;
+  if (ti->GetMultiLanguage() != nullptr &&
+      !ti->GetMultiLanguage()->GetTranslatedString().empty())
+    str = ti->GetMultiLanguage()->GetTranslatedString();
+  else if (!ti->GetContents().empty())
+    str = ti->GetContents();
+
+  *contents = strdup(str.c_str());
+  if (*contents == nullptr) {
+    LOGE("Out-of-memory");
+    return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
   return NOTI_EX_ERROR_NONE;
 }
 
-extern "C" EXPORT_API int noti_ex_item_text_get_hyper_link(
+extern "C" EXPORT_API int noti_ex_item_text_get_hyperlink(
     noti_ex_item_h handle, char **hyper_link) {
   if (handle == nullptr || hyper_link == nullptr) {
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  TextItem* p = static_cast<TextItem*>(handle);
-  if (!p->GetHyperLink().empty()) {
-    *hyper_link = strdup(p->GetHyperLink().c_str());
+  Handle* p = static_cast<Handle*>(handle);
+  if (!p->IsValidType(AbstractItem::Text)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  TextItem* ti = static_cast<TextItem*>(p->Get());
+  if (!ti->GetHyperLink().empty()) {
+    *hyper_link = strdup(ti->GetHyperLink().c_str());
     if (*hyper_link == nullptr) {
       LOGE("Out-of-memory");
       return NOTI_EX_ERROR_OUT_OF_MEMORY;
     }
+  } else {
+    *hyper_link = nullptr;
+  }
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_text_set_multi_language(
+    noti_ex_item_h handle, noti_ex_multi_lang_h multi) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* p = static_cast<Handle*>(handle);
+  if (!p->IsValidType(AbstractItem::Text)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  TextItem* ti = static_cast<TextItem*>(p->Get());
+  if (multi == nullptr) {
+    ti->SetMultiLanguage(nullptr);
+    return NOTI_EX_ERROR_NONE;
   }
 
+  shared_ptr<MultiLanguage> mul_ptr =
+      *reinterpret_cast<shared_ptr<MultiLanguage>*>(multi);
+  ti->SetMultiLanguage(mul_ptr);
+  ti->GetMultiLanguage()->UpdateString();
+
   return NOTI_EX_ERROR_NONE;
 }
 
@@ -1544,7 +3298,7 @@ extern "C" EXPORT_API int noti_ex_item_time_create(noti_ex_item_h *handle,
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = new Handle(shared_ptr<AbstractItem>(p));
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1555,13 +3309,34 @@ extern "C" EXPORT_API int noti_ex_item_time_get_time(noti_ex_item_h handle,
     LOGE("Invalid parameter");
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
-
-  TimeItem*p = static_cast<TimeItem*>(handle);
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Time)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  TimeItem* p = static_cast<TimeItem*>(h->Get());
   *time = p->GetTime();
 
   return NOTI_EX_ERROR_NONE;
 }
 
+extern "C" EXPORT_API int noti_ex_item_time_set_time(noti_ex_item_h handle,
+    time_t time) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Time)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  TimeItem* p = static_cast<TimeItem*>(h->Get());
+  p->SetTime(time);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
 extern "C" EXPORT_API int noti_ex_action_visibility_create(
     noti_ex_action_h *handle, const char *extra) {
   if (handle == nullptr) {
@@ -1569,13 +3344,18 @@ extern "C" EXPORT_API int noti_ex_action_visibility_create(
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  auto* p = new (std::nothrow) VisibilityAction(extra);
-  if (p == nullptr) {
+  string extra_str = "";
+  if (extra != NULL)
+    extra_str = string(extra);
+
+  shared_ptr<AbstractAction>* ptr = new (std::nothrow) shared_ptr<AbstractAction>(
+      new (std::nothrow) VisibilityAction(extra_str));
+  if (ptr == nullptr) {
     LOGE("Out-of-memory");
     return NOTI_EX_ERROR_OUT_OF_MEMORY;
   }
 
-  *handle = p;
+  *handle = ptr;
 
   return NOTI_EX_ERROR_NONE;
 }
@@ -1587,8 +3367,176 @@ extern "C" EXPORT_API int noti_ex_action_visibility_set(noti_ex_action_h handle,
     return NOTI_EX_ERROR_INVALID_PARAMETER;
   }
 
-  VisibilityAction* p = static_cast<VisibilityAction*>(handle);
-  p->SetVisibility(id, visible);
+  shared_ptr<AbstractAction>* ptr =
+      static_cast<shared_ptr<AbstractAction>*>(handle);
+  VisibilityAction* action = static_cast<VisibilityAction*>(ptr->get());
+  action->SetVisibility(id, visible);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_multi_lang_create(noti_ex_multi_lang_h* handle,
+    const char* msgid, const char* format, ...) {
+  if (handle == nullptr || msgid == nullptr || format == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  const char* format_idx = format;
+  vector<string> arr;
+  va_list args;
+  va_start(args, format);
+  while (*format_idx != '\0') {
+    char* arg = nullptr;
+    int arg_i;
+    double arg_f;
+    stringstream stream;
+    if (*format_idx == '%') {
+      switch (*(format_idx + 1)) {
+        case 's':
+          arg = va_arg(args, char *);
+          arr.push_back(string(arg));
+          break;
+        case 'd':
+          arg_i = va_arg(args, int);
+          arr.push_back(to_string(arg_i));
+          break;
+        case 'f':
+          arg_f = va_arg(args, double);
+          stream << std::fixed << std::setprecision(2) << arg_f;
+          arr.push_back(stream.str());
+          break;
+      }
+    }
+    format_idx++;
+  }
+  va_end(args);
 
-  return 0;
+  MultiLanguage* p = new MultiLanguage(string(msgid), format, arr);
+  if (p == nullptr) {
+    LOGE("Out-of-memory");
+    return NOTI_EX_ERROR_OUT_OF_MEMORY;
+  }
+  *handle = new shared_ptr<MultiLanguage>(p);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_multi_lang_destroy(noti_ex_multi_lang_h handle) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  shared_ptr<MultiLanguage>* mul_ptr =
+      reinterpret_cast<shared_ptr<MultiLanguage>*>(handle);
+  delete mul_ptr;
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_get_private_id(
+    noti_ex_item_h item, int64_t* private_id) {
+  if (item == nullptr || private_id == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* h = static_cast<Handle*>(item);
+  *private_id = static_pointer_cast<IItemInfoInternal>(
+      h->Get()->GetInfo())->GetPrivateId();
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_set_private_id(
+    noti_ex_item_h item, int64_t priv_id) {
+  if (item == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  Handle* h = static_cast<Handle*>(item);
+  static_pointer_cast<IItemInfoInternal>(
+      h->Get()->GetInfo())->SetPrivateId(priv_id);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_free_string_list(char** list, int count) {
+  if (list == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+
+  LOGI("Free strings (%d)", count);
+  for (int i = 0; i < count; i++)
+    free(list[i]);
+  free(list);
+
+  return NOTI_EX_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int noti_ex_item_group_remove_children(noti_ex_item_h handle) {
+  if (handle == nullptr) {
+    LOGE("Invalid parameter");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  Handle* h = static_cast<Handle*>(handle);
+  if (!h->IsValidType(AbstractItem::Group)) {
+    LOGE("Invalid handle type");
+    return NOTI_EX_ERROR_INVALID_PARAMETER;
+  }
+  GroupItem* p = static_cast<GroupItem*>(h->Get());
+  p->RemoveChildren();
+
+  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;
 }