Replace gdbus with socket for bulk communication 56/246956/10
authorhyunho <hhstark.kang@samsung.com>
Thu, 5 Nov 2020 09:49:22 +0000 (18:49 +0900)
committerHyunho Kang <hhstark.kang@samsung.com>
Tue, 17 Nov 2020 03:04:40 +0000 (03:04 +0000)
Change-Id: I485ae58573534f63bf2c0cd5f4196792474756c8
Signed-off-by: hyunho <hhstark.kang@samsung.com>
14 files changed:
notification-ex/CMakeLists.txt
notification-ex/dbus_event_listener.cc
notification-ex/dbus_event_listener_implementation.h
notification-ex/dbus_sender.cc
notification-ex/dbus_sender.h
notification-ex/dbus_sender_implementation.h
notification-ex/event_sender_interface.h
notification-ex/ex_util.cc
notification-ex/ex_util.h
notification-ex/manager.cc
notification-ex/reporter.cc
notification-ex/socket_handler.h [new file with mode: 0644]
notification-ex/stub.cc
tests/unittest/CMakeLists.txt

index 6464cf4..8c37ef6 100644 (file)
@@ -12,6 +12,8 @@ SET(VERSION "${VERSION_MAJOR}.0.0")
 INCLUDE(FindPkgConfig)
 pkg_check_modules(notification-ex REQUIRED
        glib-2.0
+       gio-2.0
+       gio-unix-2.0
        bundle
        dlog
        capi-appfw-app-control
index e37a3a2..954a634 100644 (file)
@@ -17,6 +17,7 @@
 #include <dlog.h>
 #include <glib.h>
 #include <unistd.h>
+#include <gio/gunixfdlist.h>
 
 #include <string>
 #include <map>
@@ -28,6 +29,7 @@
 #include "notification-ex/exception.h"
 #include "notification-ex/ex_util.h"
 #include "notification-ex/event_info_internal.h"
+#include "notification-ex/socket_handler.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -168,7 +170,8 @@ void DBusEventListener::Impl::SignalCb(GDBusConnection* connection,
                       const gchar* signal_name,
                       GVariant* parameters,
                       void* user_data) {
-  DBusEventListener::Impl* dl = static_cast<DBusEventListener::Impl*>(user_data);
+  DBusEventListener::Impl* dl =
+    static_cast<DBusEventListener::Impl*>(user_data);
   char* appid = nullptr;
   GVariantIter *iter = nullptr;
   char* event_info_raw = nullptr;
@@ -216,51 +219,137 @@ void DBusEventListener::Impl::SignalCb(GDBusConnection* connection,
   }
 }
 
-void DBusEventListener::Impl::MethodCallHandler(GVariant* parameters,
-            DBusEventListener::Impl* dl, pid_t pid, uid_t uid) {
-  char* appid = nullptr;
-  GVariantIter* iter = nullptr;
-  char* event_info_raw = nullptr;
+int DBusEventListener::Impl::GetRecvSocket(GDBusMethodInvocation* invocation) {
+  GDBusMessage* msg = g_dbus_method_invocation_get_message(invocation);
+  GUnixFDList* fd_list = g_dbus_message_get_unix_fd_list(msg);
+  if (fd_list == NULL) {
+    LOGE("fd list is null");
+    return -1;
+  }
 
-  g_variant_get(parameters, "(&s&sa(s))", &appid, &event_info_raw, &iter);
+  GError* g_err = nullptr;
+  int ret_fd = g_unix_fd_list_get(fd_list, 0, &g_err);
+  if (ret_fd == -1 || g_err) {
+    LOGE("g_unix_fd_list_get [%s]", g_err->message);
+    g_error_free(g_err);
+    return -1;
+  }
 
-  string sender_appid = string(appid);
-  string cur_appid = util::GetAppId();
-  LOGI("MethodCallHandler!! appid(%s), sender(%s), cur(%s)", appid,
-    sender_appid.c_str(), cur_appid.c_str());
+  LOGI("sender fd : %d", ret_fd);
+  return ret_fd;
+}
 
-  if (sender_appid == cur_appid) {
-    g_variant_iter_free(iter);
-    return;
+list<Bundle> DBusEventListener::Impl::ReadNotiList(
+      GDBusMethodInvocation* invocation, int noti_cnt) {
+  list<Bundle> ret_list;
+  list<Bundle> empty_list;
+  int recvfd = GetRecvSocket(invocation);
+  if (recvfd < 1) {
+    LOGE("Fail to get socket fd");
+    return ret_list;
   }
+  ret_list = util::ReadBundleList(recvfd, noti_cnt);
+  return ret_list;
+}
+
+int DBusEventListener::Impl::MethodCallHandler(
+      string sender_appid, string event_info_raw, int noti_cnt,
+      GDBusMethodInvocation* invocation, DBusEventListener::Impl* dl,
+      pid_t pid, uid_t uid) {
+  string cur_appid = util::GetAppId();
+  LOGI("MethodCallHandler!! sender(%s), cur(%s)",
+      sender_appid.c_str(), cur_appid.c_str());
+
+  if (sender_appid == cur_appid)
+    return 0;
 
   if ((!DBusConnectionManager::GetInst().IsDataProviderMaster(cur_appid)
     && !DBusConnectionManager::GetInst().IsDataProviderMaster(sender_appid))
-    || (cur_appid == sender_appid)) {
-    g_variant_iter_free(iter);
-    return;
-  }
+    || (cur_appid == sender_appid))
+    return 0;
 
-  char* raw = nullptr;
   list<Bundle> ret_list;
-  while (g_variant_iter_loop(iter, "(&s)", &raw) && raw != nullptr) {
-    Bundle ret(raw);
-    ret_list.emplace_back(ret);
+  if (noti_cnt > 0) {
+    ret_list = dl->ReadNotiList(invocation, noti_cnt);
+    if (ret_list.size() != static_cast<unsigned int>(noti_cnt)) {
+      LOGE("Read Noti List fail : Expect(%d), Actual(%d)",
+          noti_cnt, ret_list.size());
+      return -1;
+    }
   }
 
-  g_variant_iter_free(iter);
   Bundle b(event_info_raw);
   EventInfo info(b);
+  if ((info.GetEventType() == EventInfo::Post
+        || info.GetEventType() == EventInfo::Update)
+        && (uid >= NORMAL_UID_BASE)) {
+    info.SetValidatedOwner(util::GetAppId(pid));
+    info.SetValidatedUid(uid);
+  }
+  dl->parent_->NotifyObserver(info, ret_list);
+  return 0;
+}
 
-  if (info.GetEventType() == EventInfo::Post
-        || info.GetEventType() == EventInfo::Update) {
-    if (uid >= NORMAL_UID_BASE) {
-      info.SetValidatedOwner(util::GetAppId(pid));
-      info.SetValidatedUid(uid);
-    }
+void DBusEventListener::Impl::MultiNotiUpdateProcess(
+      GVariant* parameters, GDBusMethodInvocation* invocation,
+      DBusEventListener::Impl* dl, pid_t pid, uid_t uid) {
+  int noti_cnt;
+  char* appid = nullptr;
+  char* event_info_raw = nullptr;
+  g_variant_get(parameters, "(&s&si)", &appid, &event_info_raw, &noti_cnt);
+
+  g_dbus_method_invocation_return_value(invocation, nullptr);
+  MethodCallHandler(
+      appid, event_info_raw, noti_cnt, invocation, dl, pid, uid);
+}
+
+void DBusEventListener::Impl::GlobalUpdateProcess(
+      GVariant* parameters, GDBusMethodInvocation* invocation,
+      DBusEventListener::Impl* dl, pid_t pid, uid_t uid) {
+  char* appid = nullptr;
+  char* event_info_raw = nullptr;
+  g_variant_get(parameters, "(&s&s)", &appid, &event_info_raw);
+  g_dbus_method_invocation_return_value(invocation, nullptr);
+  MethodCallHandler(
+      appid, event_info_raw, 0, invocation, dl, pid, uid);
+}
+
+void DBusEventListener::Impl::GetProcess(
+      GVariant* parameters, GDBusMethodInvocation* invocation,
+      DBusEventListener::Impl* dl) {
+  char* appid = NULL;
+  char* serialized = NULL;
+  g_variant_get(parameters, "(&s&s)", &appid, &serialized);
+  int recvfd = GetRecvSocket(invocation);
+  if (recvfd < 1) {
+    g_dbus_method_invocation_return_error(invocation,
+          noti_ex_error_quark(), ERROR_IO_ERROR, "Fail to get socket");
+    return;
   }
 
-  dl->parent_->NotifyObserver(info, ret_list);
+  SocketHandler recv_sock(recvfd);
+  Bundle b(serialized);
+  EventInfo info(b);
+  list<Bundle> result = dl->parent_->NotifyObserver(info);
+  g_dbus_method_invocation_return_value(invocation,
+      g_variant_new("(i)", result.size()));
+  for (auto& i : result) {
+    unsigned int data_size = static_cast<unsigned int>(
+        strlen(reinterpret_cast<char*>(i.ToRaw().first.get())));
+    int ret = util::WriteSocket(recv_sock.Get(),
+        reinterpret_cast<char*>(&data_size), sizeof(data_size));
+    if (ret != 0) {
+      LOGE("Fail to write (%d)", ret);
+      break;
+    }
+
+    ret = util::WriteSocket(recv_sock.Get(),
+        reinterpret_cast<char*>(i.ToRaw().first.get()), data_size);
+    if (ret != 0) {
+      LOGE("Fail to write (%d)", ret);
+      break;
+    }
+  }
 }
 
 void DBusEventListener::Impl::OnMethodCall(
@@ -269,55 +358,39 @@ void DBusEventListener::Impl::OnMethodCall(
     GVariant* parameters, GDBusMethodInvocation* invocation,
     gpointer user_data) {
   LOGI("method_name[%s] sender[%s]", method_name, sender);
-  DBusEventListener::Impl* dl = static_cast<DBusEventListener::Impl*>(user_data);
-  GVariant* reply_body = NULL;
+  DBusEventListener::Impl* dl =
+      static_cast<DBusEventListener::Impl*>(user_data);
   try {
-    char* appid = NULL;
-    char* serialized = NULL;
-
     uid_t uid = GetSenderUid(conn, sender);
     pid_t pid = GetSenderPid(conn, sender);
 
     if (g_strcmp0(method_name, "Post") == 0
            || g_strcmp0(method_name, "Update") == 0
-           || g_strcmp0(method_name, "Delete") == 0
-           || g_strcmp0(method_name, "Error") == 0
+           || g_strcmp0(method_name, "Delete") == 0) {
+      MultiNotiUpdateProcess(parameters, invocation, dl, pid, uid);
+    } else if (g_strcmp0(method_name, "Error") == 0
            || g_strcmp0(method_name, "DeleteAll") == 0
            || g_strcmp0(method_name, "Register") == 0
            || g_strcmp0(method_name, "Unregister") == 0) {
-      parameters = g_variant_ref(parameters);
-      g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", 0));
-      MethodCallHandler(parameters, dl, pid, uid);
-      g_variant_unref(parameters);
-      return;
+
+      GlobalUpdateProcess(parameters, invocation, dl, pid, uid);
     } else if (g_strcmp0(method_name, "Count") == 0) {
+      char* appid = NULL;
+      char* serialized = NULL;
       g_variant_get(parameters, "(&s&s)", &appid, &serialized);
 
       Bundle b(serialized);
       EventInfo info(b);
       int num = dl->parent_->NotifyNumberRequest(info);
-      reply_body = g_variant_new("(i)", num);
+      g_dbus_method_invocation_return_value(invocation,
+          g_variant_new("(i)", num));
     } else if (g_strcmp0(method_name, "Get") == 0) {
-      g_variant_get(parameters, "(&s&s)", &appid, &serialized);
-
-      Bundle b(serialized);
-      EventInfo info(b);
-      list<Bundle> result = dl->parent_->NotifyObserver(info);
-      GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
-      for (auto& i : result) {
-        g_variant_builder_add(builder, "(s)",
-          reinterpret_cast<char*>(i.ToRaw().first.get()));
-      }
-      reply_body = g_variant_new("(a(s))", builder);
-      g_variant_builder_unref(builder);
+      GetProcess(parameters, invocation, dl);
     } else {
       g_dbus_method_invocation_return_error(invocation, noti_ex_error_quark(),
             ERROR_IO_ERROR, "invalid operation");
       return;
     }
-
-    g_dbus_method_invocation_return_value(invocation, reply_body);
-
   } catch (Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
     g_dbus_method_invocation_return_error(invocation, noti_ex_error_quark(),
@@ -337,31 +410,26 @@ int DBusEventListener::Impl::RegisterGDBusInterface() {
     "        <method name='Post'>"
     "          <arg type='s' name='appid' direction='in'/>"
     "          <arg type='s' name='info' direction='in'/>"
-    "          <arg type='a(s)' name='serialized' direction='in'/>"
-    "          <arg type='i' name='ret' direction='out'/>"
+    "          <arg type='i' name='noti_cnt' direction='in'/>"
     "        </method>"
     "        <method name='Update'>"
     "          <arg type='s' name='appid' direction='in'/>"
     "          <arg type='s' name='info' direction='in'/>"
-    "          <arg type='a(s)' name='serialized' direction='in'/>"
-    "          <arg type='i' name='ret' direction='out'/>"
+    "          <arg type='i' name='noti_cnt' direction='in'/>"
     "        </method>"
     "        <method name='Delete'>"
     "          <arg type='s' name='appid' direction='in'/>"
     "          <arg type='s' name='info' direction='in'/>"
-    "          <arg type='a(s)' name='serialized' direction='in'/>"
-    "          <arg type='i' name='ret' direction='out'/>"
+    "          <arg type='i' name='noti_cnt' direction='in'/>"
     "        </method>"
     "        <method name='Get'>"
     "          <arg type='s' name='appid' direction='in'/>"
     "          <arg type='s' name='serialized' direction='in'/>"
-    "          <arg type='a(s)' name='noti_arr' direction='out'/>"
+    "          <arg type='i' name='ret' direction='out'/>"
     "        </method>"
     "        <method name='Error'>"
     "          <arg type='s' name='appid' direction='in'/>"
     "          <arg type='s' name='info' direction='in'/>"
-    "          <arg type='a(s)' name='serialized' direction='in'/>"
-    "          <arg type='i' name='ret' direction='out'/>"
     "        </method>"
     "        <method name='Count'>"
     "          <arg type='s' name='appid' direction='in'/>"
@@ -371,20 +439,14 @@ int DBusEventListener::Impl::RegisterGDBusInterface() {
     "        <method name='DeleteAll'>"
     "          <arg type='s' name='appid' direction='in'/>"
     "          <arg type='s' name='info' direction='in'/>"
-    "          <arg type='a(s)' name='serialized' direction='in'/>"
-    "          <arg type='i' name='ret' direction='out'/>"
     "        </method>"
     "        <method name='Register'>"
     "          <arg type='s' name='appid' direction='in'/>"
     "          <arg type='s' name='info' direction='in'/>"
-    "          <arg type='a(s)' name='serialized' direction='in'/>"
-    "          <arg type='i' name='ret' direction='out'/>"
     "        </method>"
     "        <method name='Unregister'>"
     "          <arg type='s' name='appid' direction='in'/>"
     "          <arg type='s' name='info' direction='in'/>"
-    "          <arg type='a(s)' name='serialized' direction='in'/>"
-    "          <arg type='i' name='ret' direction='out'/>"
     "        </method>"
     "  </interface>"
     "  </node>";
index 5fb25da..0bc70e9 100644 (file)
@@ -36,12 +36,25 @@ class DBusEventListener::Impl {
  private:
   void UnRegisterGDBusInterface();
   int RegisterGDBusInterface();
+  std::list<tizen_base::Bundle> ReadNotiList(
+      GDBusMethodInvocation* invocation, int noti_cnt);
+  static int GetRecvSocket(GDBusMethodInvocation* invocation);
   static void OnMethodCall(
     GDBusConnection *conn, const gchar *sender, const gchar *object_path,
     const gchar *iface_name, const gchar *method_name,
     GVariant *parameters, GDBusMethodInvocation *invocation,
     gpointer user_data);
-  static void MethodCallHandler(GVariant *parameters, Impl* dl, pid_t pid, uid_t uid);
+  static int MethodCallHandler(std::string sender_appid,
+      std::string event_info_raw, int noti_cnt,
+      GDBusMethodInvocation* invocation, Impl* dl, pid_t pid, uid_t uid);
+  static void MultiNotiUpdateProcess(
+      GVariant* parameters, GDBusMethodInvocation* invocation,
+      Impl* dl, pid_t pid, uid_t uid);
+  static void GlobalUpdateProcess(
+      GVariant* parameters, GDBusMethodInvocation* invocation,
+      Impl* dl, pid_t pid, uid_t uid);
+  static void GetProcess(
+      GVariant* parameters, GDBusMethodInvocation* invocation, Impl* dl);
 
   static GDBusInterfaceVTable InterfaceVtable;
   static void SignalCb(GDBusConnection* connection,
index 202a072..36bce5c 100644 (file)
@@ -17,6 +17,7 @@
 #include <dlog.h>
 #include <glib.h>
 #include <unistd.h>
+#include <gio/gunixfdlist.h>
 
 #include <string>
 #include <list>
@@ -26,6 +27,7 @@
 #include "notification-ex/dbus_sender_implementation.h"
 #include "notification-ex/event_info_internal.h"
 #include "notification-ex/ex_util.h"
+#include "notification-ex/socket_handler.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -34,6 +36,9 @@
 #define LOG_TAG "NOTIFICATION_EX"
 #define MAX_PACKAGE_STR_SIZE 512
 
+#define RECV_SOCK_IDX 0
+#define SEND_SOCK_IDX 1
+
 using namespace std;
 using namespace tizen_base;
 namespace notification {
@@ -89,17 +94,10 @@ string DBusSender::Impl::GetBusName(string appid, string dest_appid) const {
   return DBusConnectionManager::GetInst().GetBusName(dest_appid);
 }
 
-void DBusSender::Notify(const IEventInfo& info, list<Bundle> serialized,
-    string dest_appid) {
+void DBusSender::Notify(GVariantBuilder* builder,
+    const IEventInfo& info, string dest_appid) {
   string signal_name = EventInfo::GetString(info.GetEventType());
   string appid = util::GetAppId();
-
-  GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
-  for (auto& i : serialized) {
-    g_variant_builder_add(builder, "(s)",
-        reinterpret_cast<char*>(i.ToRaw().first.get()));
-  }
-
   GVariant* data = g_variant_new("(ssa(s))",
         appid.c_str(),
         reinterpret_cast<char*>(info.Serialize().ToRaw().first.get()), builder);
@@ -109,6 +107,24 @@ void DBusSender::Notify(const IEventInfo& info, list<Bundle> serialized,
   g_variant_builder_unref(builder);
 }
 
+void DBusSender::Notify(const IEventInfo& info, list<Bundle> serialized,
+    string dest_appid) {
+  GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
+  int idx = 0;
+  for (auto& i : serialized) {
+    if (idx != 0 && idx % 10 == 0) {
+      Notify(builder, info, dest_appid);
+      g_variant_builder_unref(builder);
+      builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
+    }
+    g_variant_builder_add(builder, "(s)",
+        reinterpret_cast<char*>(i.ToRaw().first.get()));
+    idx++;
+  }
+  Notify(builder, info, dest_appid);
+}
+
+
 GDBusMessage* DBusSender::Impl::MethodCall(string appid, string method_name,
     Bundle serialized) {
   GDBusMessage* msg = g_dbus_message_new_method_call(
@@ -124,9 +140,7 @@ GDBusMessage* DBusSender::Impl::MethodCall(string appid, string method_name,
   g_dbus_message_set_body(msg,
       g_variant_new("(ss)",
         appid.c_str(),
-        reinterpret_cast<char*>(serialized.ToRaw().first.get())
-      )
-  );
+        reinterpret_cast<char*>(serialized.ToRaw().first.get())));
 
   LOGI("send message !! (%s) (%s) (%s)",
       path_.c_str(), method_name.c_str(), appid.c_str());
@@ -148,8 +162,92 @@ GDBusMessage* DBusSender::Impl::MethodCall(string appid, string method_name,
   return reply;
 }
 
+std::list<Bundle> DBusSender::Impl::MethodCallWithSocket(
+    string appid, string method_name, Bundle serialized) {
+  list<Bundle> ret_list;
+  int fds[2];
+  int ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds);
+  if (ret < 0) {
+    LOGE("socketpair [%d]", ret);
+    return ret_list;
+  }
+  SocketHandler send_sock(fds[SEND_SOCK_IDX]);
+  SocketHandler recv_sock(fds[RECV_SOCK_IDX]);
+  std::unique_ptr<GUnixFDList, decltype(g_object_unref)*> fd_list_ptr(
+          GetFdList(send_sock.Get()), g_object_unref);
+
+
+  std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> msg_ptr(
+      g_dbus_message_new_method_call(
+          DBusConnectionManager::GetInst().GetDataProviderMasterName().c_str(),
+          path_.c_str(),
+          DBusConnectionManager::GetInst().GetInterfaceName().c_str(),
+          method_name.c_str()),
+      g_object_unref);
+  if (!msg_ptr || !msg_ptr.get()) {
+    LOGE("Can't allocate new method call");
+    return ret_list;
+  }
+
+  g_dbus_message_set_unix_fd_list(msg_ptr.get(), fd_list_ptr.get());
+  g_dbus_message_set_body(msg_ptr.get(),
+      g_variant_new("(ss)",
+        appid.c_str(),
+        reinterpret_cast<char*>(serialized.ToRaw().first.get())));
+
+  LOGI("send message !! (%s) (%s) (%s)",
+      path_.c_str(), method_name.c_str(), appid.c_str());
+
+  GError* err = nullptr;
+  std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> reply_ptr(
+      g_dbus_connection_send_message_with_reply_sync(
+          DBusConnectionManager::GetInst().GetConnection(), msg_ptr.get(),
+          G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err),
+      g_object_unref);
+  if (err != NULL) {
+    LOGE("MethodCall, err[%s]", err->message);
+    if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
+      set_last_result(ERROR_PERMISSION_DENIED);
+    else
+      set_last_result(ERROR_IO_ERROR);
+    g_error_free(err);
+  } else if (CheckReplyMessage(reply_ptr.get()) == 0) {
+    GVariant *reply_body = g_dbus_message_get_body(reply_ptr.get());
+    int cnt;
+    g_variant_get(reply_body, "(i)", &cnt);
+    ret_list = util::ReadBundleList(recv_sock.Get(), cnt);
+  }
+  return ret_list;
+}
+
+GUnixFDList* DBusSender::Impl::GetFdList(int fd) {
+  GError* g_err = nullptr;
+  GUnixFDList* fd_list = g_unix_fd_list_new();
+  g_unix_fd_list_append(fd_list, fd, &g_err);
+  if (g_err != nullptr) {
+    LOGE("g_unix_fd_list_append [%s]", g_err->message);
+    g_object_unref(fd_list);
+    g_error_free(g_err);
+    return nullptr;
+  }
+  return fd_list;
+}
+
 GDBusMessage* DBusSender::Impl::MethodCall(string appid, const IEventInfo& info,
     list<Bundle> serialized) {
+  int fds[2];
+  int ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds);
+  if (ret < 0) {
+    LOGE("socketpair [%d]", ret);
+    return nullptr;
+  }
+
+  SocketHandler send_sock(fds[SEND_SOCK_IDX]);
+  SocketHandler recv_sock(fds[RECV_SOCK_IDX]);
+  GUnixFDList* fd_list = GetFdList(recv_sock.Get());
+  auto fd_list_ptr = std::unique_ptr<GUnixFDList, decltype(g_object_unref)*>(
+          fd_list, g_object_unref);
+
   GDBusMessage* msg = g_dbus_message_new_method_call(
       DBusConnectionManager::GetInst().GetDataProviderMasterName().c_str(),
       path_.c_str(),
@@ -160,22 +258,16 @@ GDBusMessage* DBusSender::Impl::MethodCall(string appid, const IEventInfo& info,
     return nullptr;
   }
 
-  GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
-  for (auto& i : serialized) {
-    g_variant_builder_add(builder, "(s)",
-        reinterpret_cast<char*>(i.ToRaw().first.get()));
-  }
-
+  g_dbus_message_set_unix_fd_list(msg, fd_list);
   g_dbus_message_set_body(msg,
-      g_variant_new("(ssa(s))",
+      g_variant_new("(ssi)",
           appid.c_str(),
           reinterpret_cast<char*>(info.Serialize().ToRaw().first.get()),
-          builder
-      )
-  );
+          serialized.size()));
 
   LOGI("send message !! (%s) (%s) (%s)",
-      path_.c_str(), EventInfo::GetString(info.GetEventType()).c_str(), appid.c_str());
+      path_.c_str(),
+      EventInfo::GetString(info.GetEventType()).c_str(), appid.c_str());
 
   GError* err = nullptr;
   GDBusMessage* reply = g_dbus_connection_send_message_with_reply_sync(
@@ -188,9 +280,21 @@ GDBusMessage* DBusSender::Impl::MethodCall(string appid, const IEventInfo& info,
     else
       set_last_result(ERROR_IO_ERROR);
     g_error_free(err);
+  } else {
+    for (auto& i : serialized) {
+      unsigned int data_size = static_cast<unsigned int>(
+          strlen(reinterpret_cast<char*>(i.ToRaw().first.get())));
+      int ret = util::WriteSocket(send_sock.Get(),
+          reinterpret_cast<char*>(&data_size), sizeof(data_size));
+      if (ret != 0)
+        break;
+      ret = util::WriteSocket(send_sock.Get(),
+          reinterpret_cast<char*>(i.ToRaw().first.get()), data_size);
+      if (ret != 0)
+        break;
+    }
   }
 
-  g_variant_builder_unref(builder);
   g_object_unref(msg);
   return reply;
 }
@@ -222,27 +326,10 @@ int DBusSender::SendMessage(const IEventInfo& info, list<Bundle> serialized,
     set_last_result(ERROR_NONE);
   }
 
-  GVariant *reply_body = g_dbus_message_get_body(reply);
-  g_variant_get(reply_body, "(i)", &ret);
-  return ret;
+  return 0;
 }
 
-std::list<Bundle> DBusSender::Request(const IEventInfo& info) {
-  string appid = info.GetOwner();
-  if (appid.length() == 0)
-    appid = util::GetAppId();
-
-  string method_name = EventInfo::GetString(info.GetEventType());
-  Bundle serialized = info.Serialize();
-
-  list<Bundle> ret_list;
-  GDBusMessage* reply = impl_->MethodCall(appid, method_name, serialized);
-  if (!reply)
-    return ret_list;
-
-  auto reply_ptr = std::unique_ptr<GDBusMessage, decltype(g_object_unref)*>(
-      reply, g_object_unref);
-
+int DBusSender::Impl::CheckReplyMessage(GDBusMessage* reply) {
   GError* err = nullptr;
   if (g_dbus_message_to_gerror(reply, &err)) {
     LOGE("Request got error %s", err->message);
@@ -252,26 +339,24 @@ std::list<Bundle> DBusSender::Request(const IEventInfo& info) {
       set_last_result(ERROR_IO_ERROR);
 
     g_error_free(err);
-    return ret_list;
+    return -1;
   } else {
     set_last_result(ERROR_NONE);
   }
+  return 0;
+}
 
-  GVariant *reply_body = g_dbus_message_get_body(reply);
-  GVariantIter *iter = nullptr;
-  g_variant_get(reply_body, "(a(s))", &iter);
-  char* raw = nullptr;
-  while (g_variant_iter_loop(iter, "(&s)", &raw) && raw != nullptr) {
-    Bundle ret(raw);
-    ret_list.emplace_back(ret);
-  }
+std::list<Bundle> DBusSender::Request(const IEventInfo& info) {
+  string appid = info.GetOwner();
+  if (appid.length() == 0)
+    appid = util::GetAppId();
 
-  if (iter)
-    g_variant_iter_free(iter);
-  return ret_list;
+  string method_name = EventInfo::GetString(info.GetEventType());
+  Bundle serialized = info.Serialize();
+  return impl_->MethodCallWithSocket(appid, method_name, serialized);
 }
 
-int DBusSender::RequestNumber(const IEventInfo& info) {
+int DBusSender::RequestReturnValue(const IEventInfo& info) {
   string appid = info.GetOwner();
   if (appid.length() == 0)
     appid = util::GetAppId();
@@ -288,7 +373,7 @@ int DBusSender::RequestNumber(const IEventInfo& info) {
 
   GError* err = nullptr;
   if (g_dbus_message_to_gerror(reply, &err)) {
-    LOGE("RequestNumber got error %s", err->message);
+    LOGE("RequestReturnValue got error %s", err->message);
     if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
       set_last_result(ERROR_PERMISSION_DENIED);
     else
index 894cc57..2198459 100644 (file)
@@ -40,7 +40,11 @@ class EXPORT_API DBusSender : public IEventSender {
   int SendMessage(const IEventInfo& info, std::list<tizen_base::Bundle> serialized,
       std::string dest_appid = "") override;
   std::list<tizen_base::Bundle> Request(const IEventInfo& info) override;
-  int RequestNumber(const IEventInfo& info) override;
+  int RequestReturnValue(const IEventInfo& info) override;
+
+ private:
+  void Notify(GVariantBuilder* builder,
+        const IEventInfo& info, std::string dest_appid);
 
  private:
   class Impl;
index d7f0d5b..7d1c501 100644 (file)
@@ -39,11 +39,16 @@ class DBusSender::Impl {
  private:
   std::string GetBusName(
       std::string appid, std::string dest_appid) const;
-  bool EmitSignal(std::string bus_name, std::string signal_name, GVariant* data);
+  bool EmitSignal(std::string bus_name,
+      std::string signal_name, GVariant* data);
   GDBusMessage* MethodCall(std::string appid, std::string method_name,
       tizen_base::Bundle serialized);
   GDBusMessage* MethodCall(std::string appid, const IEventInfo& info,
       std::list<tizen_base::Bundle> serialized);
+  std::list<tizen_base::Bundle> MethodCallWithSocket(std::string appid,
+      std::string method_name, tizen_base::Bundle serialized);
+  GUnixFDList* GetFdList(int fd);
+  int CheckReplyMessage(GDBusMessage* reply);
   std::string path_;
   DBusSender* parent_;
 };
index 523d656..ed2e965 100644 (file)
@@ -40,7 +40,7 @@ class EXPORT_API IEventSender {
       std::list<tizen_base::Bundle> serialized,
       std::string dest_appid = "") = 0;
   virtual std::list<tizen_base::Bundle> Request(const IEventInfo& info) = 0;
-  virtual int RequestNumber(const IEventInfo& info) = 0;
+  virtual int RequestReturnValue(const IEventInfo& info) = 0;
 };
 
 }  // namespace notification
index 07e5b55..2b796e5 100644 (file)
 #include <map>
 
 #include "notification-ex/ex_util.h"
+#include "notification-ex/socket_handler.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
 
 #define LOG_TAG "NOTIFICATION_EX"
-#define MAX_PACKAGE_STR_SIZE 512
-#define MAX_CACHE_SIZE 100
 
 using namespace std;
+
+namespace {
+constexpr int MAX_PACKAGE_STR_SIZE = 512;
+constexpr int MAX_CACHE_SIZE = 100;
+constexpr int MAX_RETRY_CNT = 10;
+}
+
 namespace notification {
 namespace util {
 
@@ -46,7 +52,7 @@ int GetRequestId() {
 }
 
 string GetAppId() {
- return GetAppId(getpid());
 return GetAppId(getpid());
 }
 
 string GetAppId(pid_t pid) {
@@ -179,5 +185,110 @@ string GetLocaleDirectory() {
   return locale_directory;
 }
 
+unsigned int GetSocketBufferSize(int fd, int optname) {
+  unsigned int ret_size = 0;
+  socklen_t len = sizeof(ret_size);
+
+  errno = 0;
+  if (getsockopt(fd, SOL_SOCKET, optname, &ret_size, &len) < 0) {
+    LOGE("read socket size [%d]", errno);
+    return 0;
+  }
+  return ret_size;
+}
+
+unsigned int ReadSocket(int fd, char* buffer, unsigned int nbytes) {
+  unsigned int left = nbytes;
+  ssize_t nb;
+  int retry_cnt = 0;
+  const struct timespec SLEEP_TIME = { 0, 20 * 1000 * 1000 };
+  while (left && (retry_cnt < MAX_RETRY_CNT)) {
+    errno = 0;
+    nb = read(fd, buffer, left);
+    if (nb == 0) {
+      LOGE("read socket - EOF, fd close [%d]", fd);
+      return -1;
+    } else if (nb == -1) {
+      if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
+        LOGE("errno [%d], sleep and retry", errno);
+        retry_cnt++;
+        nanosleep(&SLEEP_TIME, 0);
+        continue;
+      }
+      LOGE("errno [%d] fd [%d]", errno, fd);
+      return -1;
+    }
+    left -= nb;
+    buffer += nb;
+    retry_cnt = 0;
+  }
+
+  if (left != 0) {
+    LOGE("error fd [%d] retry_cnt [%d]", fd, retry_cnt);
+    return -1;
+  }
+  return 0;
+}
+
+list<tizen_base::Bundle> ReadBundleList(int recvfd, int noti_cnt) {
+  list<tizen_base::Bundle> ret_list;
+  list<tizen_base::Bundle> empty_list;
+  SocketHandler recv_sock(recvfd);
+  unsigned int buf_size = 0;
+  unsigned int data_size = 0;
+  buf_size = util::GetSocketBufferSize(recv_sock.Get(), SO_RCVBUF);
+  std::unique_ptr<char, decltype(std::free)*> data_ptr(
+      static_cast<char*>(calloc(buf_size, sizeof(char))), std::free);
+  for (int i = 0; i < noti_cnt; i++) {
+    int ret = util::ReadSocket(recv_sock.Get(),
+        reinterpret_cast<char*>(&data_size), sizeof(data_size));
+    if (ret != 0)
+      return empty_list;
+    if (data_size > buf_size) {
+      buf_size = data_size;
+      data_ptr.reset(static_cast<char*>(calloc(buf_size, sizeof(char))));
+    }
+    memset(data_ptr.get(), 0, buf_size);
+    ret = util::ReadSocket(recv_sock.Get(), data_ptr.get(), data_size);
+    if (ret != 0)
+      return empty_list;
+    ret_list.emplace_back(data_ptr.get());
+  }
+  return ret_list;
+}
+
+int WriteSocket(int fd, const char* buffer, unsigned int nbytes) {
+  int retry_cnt = 0;
+  unsigned int left = nbytes;
+  ssize_t nb;
+  const struct timespec SLEEP_TIME = { 0, 20 * 1000 * 1000 };
+
+  while (left && (retry_cnt < MAX_RETRY_CNT)) {
+    errno = 0;
+    nb = write(fd, buffer, left);
+    if (nb == -1) {
+      if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
+        LOGE("continue..");
+        retry_cnt++;
+        nanosleep(&SLEEP_TIME, 0);
+        continue;
+      }
+      LOGE("error fd [%d] errno [%d]", fd, errno);
+      return -1;
+    }
+
+    left -= nb;
+    buffer += nb;
+    retry_cnt = 0;
+  }
+
+  if (left != 0) {
+    LOGE("error fd [%d], retry_cnt [%d]", fd, retry_cnt);
+    return -1;
+  }
+  return 0;
+}
+
+
 }  // namespace util
 }  // namespace notification
index c4fa466..1906695 100644 (file)
 #define NOTIFICATION_EX_EX_UTIL_H_
 
 #include <gmodule.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <bundle_cpp.h>
 
 #include <string>
+#include <list>
 
 namespace notification {
 namespace util {
@@ -29,6 +33,10 @@ namespace util {
   std::string GetPkgId();
   std::string GetDomainName();
   std::string GetLocaleDirectory();
+  unsigned int GetSocketBufferSize(int fd, int optname);
+  unsigned int ReadSocket(int fd, char* buffer, unsigned int nbytes);
+  int WriteSocket(int fd, const char* buffer, unsigned int nbytes);
+  std::list<tizen_base::Bundle> ReadBundleList(int recvfd, int noti_cnt);
 }  // namespace util
 }  // namespace notification
 
index e8fab13..b5e243d 100644 (file)
@@ -52,10 +52,8 @@ Manager::~Manager() = default;
 
 Manager::Impl::~Impl() {
   listener_->UnRegisterObserver(parent_);
-
-  list<Bundle> serialized_list {};
   EventInfo info(EventInfo::Unregister, util::GetAppId(), "", "");
-  sender_->SendMessage(info, serialized_list, DATA_PROVIDER_MASTER_ID);
+  sender_->RequestReturnValue(info);
 }
 Manager::Impl::Impl(Manager* parent,
     unique_ptr<IEventSender> sender,
@@ -69,9 +67,8 @@ Manager::Impl::Impl(Manager* parent,
   if (DBusConnectionManager::GetInst().IsDataProviderMaster(util::GetAppId()))
     return;
 
-  list<Bundle> serialized_list {};
   EventInfo info(EventInfo::Register, util::GetAppId(), receiver_group, "");
-  sender_->SendMessage(info, serialized_list, DATA_PROVIDER_MASTER_ID);
+  sender_->RequestReturnValue(info);
 }
 
 int Manager::Impl::SendNotify(shared_ptr<item::AbstractItem> noti,
@@ -90,69 +87,66 @@ void Manager::SendError(const IEventInfo& info, NotificationError error) {
   IEventInfo& i = const_cast<IEventInfo&>(info);
   static_cast<IEventInfoInternal&>(i).SetError(error);
   static_cast<IEventInfoInternal&>(i).SetEventType(EventInfo::Error);
-  impl_->sender_->SendMessage(info, serialized_list, info.GetOwner());
+  impl_->sender_->Notify(info, serialized_list, info.GetOwner());
 }
 
 int Manager::Update(shared_ptr<item::AbstractItem> noti, int& request_id) {
   Bundle serialized = noti->Serialize();
-  EventInfo info(EventInfo::Update, util::GetAppId(), noti->GetChannel(), noti->GetId());
+  EventInfo info(
+      EventInfo::Update, util::GetAppId(), noti->GetChannel(), noti->GetId());
   list<Bundle> serialized_list {serialized};
 
   request_id = info.GetRequestId();
-  return impl_->sender_->SendMessage(info, serialized_list, noti->GetSenderAppId());
+  return impl_->sender_->SendMessage(
+      info, serialized_list, noti->GetSenderAppId());
 }
 
 int Manager::Delete(shared_ptr<item::AbstractItem> noti, int& request_id) {
   Bundle serialized = noti->Serialize();
-  EventInfo info(EventInfo::Delete, util::GetAppId(), noti->GetChannel(), noti->GetId());
+  EventInfo info(
+      EventInfo::Delete, util::GetAppId(), noti->GetChannel(), noti->GetId());
   list<Bundle> serialized_list {serialized};
 
   request_id = info.GetRequestId();
-  return impl_->sender_->SendMessage(info, serialized_list, noti->GetSenderAppId());
+  return impl_->sender_->SendMessage(
+      info, serialized_list, noti->GetSenderAppId());
 }
 
 int Manager::DeleteAll(int& request_id) {
-  Bundle serialized;
   EventInfo info(EventInfo::DeleteAll, util::GetAppId(), "");
-  list<Bundle> serialized_list {serialized};
-
   request_id = info.GetRequestId();
-  return impl_->sender_->SendMessage(info, serialized_list, util::GetAppId());
+  return impl_->sender_->RequestReturnValue(info);
 }
 
 int Manager::DeleteByChannel(string channel, int& request_id) {
-  Bundle serialized;
   EventInfo info(EventInfo::DeleteAll, util::GetAppId(), channel);
-  list<Bundle> serialized_list {serialized};
-
   request_id = info.GetRequestId();
-  return impl_->sender_->SendMessage(info, serialized_list, util::GetAppId());
+  return impl_->sender_->RequestReturnValue(info);
 }
 
 int Manager::DeleteByAppId(string appId, int& request_id) {
-  Bundle serialized;
   EventInfo info(EventInfo::DeleteAll, util::GetAppId(), "", appId);
-  list<Bundle> serialized_list {serialized};
-
   request_id = info.GetRequestId();
-  return impl_->sender_->SendMessage(info, serialized_list, util::GetAppId());
+  return impl_->sender_->RequestReturnValue(info);
 }
 
 int Manager::GetCount() const {
   EventInfo info(EventInfo::Count, util::GetAppId(), "");
-  int num = impl_->sender_->RequestNumber(info);
-  return num;
+  return impl_->sender_->RequestReturnValue(info);
 }
 
 int Manager::Hide(shared_ptr<item::AbstractItem> noti, int& request_id) {
-  (reinterpret_cast<IItemInfoInternal*>(noti->GetInfo().get()))->AddHideViewer(util::GetAppId());
+  (reinterpret_cast<IItemInfoInternal*>(noti->GetInfo().get()))
+      ->AddHideViewer(util::GetAppId());
 
-  EventInfo info(EventInfo::Update, util::GetAppId(), noti->GetChannel(), noti->GetId());
+  EventInfo info(
+      EventInfo::Update, util::GetAppId(), noti->GetChannel(), noti->GetId());
   Bundle serialized = noti->Serialize();
   list<Bundle> serialized_list {serialized};
 
   request_id = info.GetRequestId();
-  return impl_->sender_->SendMessage(info, serialized_list, noti->GetSenderAppId());
+  return impl_->sender_->SendMessage(
+      info, serialized_list, noti->GetSenderAppId());
 }
 
 unique_ptr<item::AbstractItem> Manager::FindByRootID(string id) {
@@ -295,7 +289,8 @@ void Manager::OnDelete(const IEventInfo& info,
 void Manager::OnError(NotificationError error, int requestId) {
 }
 
-list<shared_ptr<item::AbstractItem>> Manager::OnRequestEvent(const IEventInfo& info) {
+list<shared_ptr<item::AbstractItem>> Manager::OnRequestEvent(
+    const IEventInfo& info) {
   return list<shared_ptr<item::AbstractItem>>({});
 }
 
index c8cef07..7e03f69 100644 (file)
@@ -72,7 +72,7 @@ void Reporter::SendError(const IEventInfo& info, NotificationError error) {
   IEventInfo& i = const_cast<IEventInfo&>(info);
   static_cast<IEventInfoInternal&>(i).SetError(error);
   static_cast<IEventInfoInternal&>(i).SetEventType(EventInfo::Error);
-  impl_->sender_->SendMessage(info, serialized_list, info.GetOwner());
+  impl_->sender_->Notify(info, serialized_list, info.GetOwner());
 }
 
 int Reporter::Post(std::shared_ptr<item::AbstractItem> noti, int& request_id) {
@@ -80,7 +80,8 @@ int Reporter::Post(std::shared_ptr<item::AbstractItem> noti, int& request_id) {
   static_pointer_cast<IItemInfoInternal>(noti->GetInfo())->SetTime(time(NULL));
   Bundle serialized = noti->Serialize();
 
-  EventInfo info(EventInfo::Post, util::GetAppId(), noti->GetChannel(), noti->GetId());
+  EventInfo info(
+      EventInfo::Post, util::GetAppId(), noti->GetChannel(), noti->GetId());
   list<Bundle> serialized_list {serialized};
   SharedFile::CopyPrivateFile(noti);
 
@@ -88,7 +89,8 @@ int Reporter::Post(std::shared_ptr<item::AbstractItem> noti, int& request_id) {
   return impl_->sender_->SendMessage(info, serialized_list);
 }
 
-int Reporter::Post(std::list<std::shared_ptr<AbstractItem>> notiList, int& request_id) {
+int Reporter::Post(
+    std::list<std::shared_ptr<AbstractItem>> notiList, int& request_id) {
   LOGI("Post noti list");
   EventInfo info(EventInfo::Post, util::GetAppId(), "");
   list<Bundle> serialized_list;
@@ -107,7 +109,8 @@ int Reporter::Update(std::shared_ptr<AbstractItem> noti, int& request_id) {
   static_pointer_cast<IItemInfoInternal>(noti->GetInfo())->SetTime(time(NULL));
   Bundle serialized = noti->Serialize();
 
-  EventInfo info(EventInfo::Update, util::GetAppId(), noti->GetChannel(), noti->GetId());
+  EventInfo info(
+      EventInfo::Update, util::GetAppId(), noti->GetChannel(), noti->GetId());
   list<Bundle> serialized_list {serialized};
   SharedFile::CopyPrivateFile(noti);
 
@@ -115,7 +118,8 @@ int Reporter::Update(std::shared_ptr<AbstractItem> noti, int& request_id) {
   return impl_->sender_->SendMessage(info, serialized_list);
 }
 
-int Reporter::Update(std::list<std::shared_ptr<AbstractItem>> notiList, int& request_id) {
+int Reporter::Update(
+    std::list<std::shared_ptr<AbstractItem>> notiList, int& request_id) {
   EventInfo info(EventInfo::Update, util::GetAppId(), "");
   list<Bundle> serialized_list;
   for (auto& i : notiList) {
@@ -131,14 +135,17 @@ int Reporter::Update(std::list<std::shared_ptr<AbstractItem>> notiList, int& req
 
 int Reporter::Delete(std::shared_ptr<AbstractItem> noti, int& request_id) {
   Bundle serialized = noti->Serialize();
-  EventInfo info(EventInfo::Delete, util::GetAppId(), noti->GetChannel(), noti->GetId());
+  EventInfo info(
+      EventInfo::Delete, util::GetAppId(), noti->GetChannel(), noti->GetId());
   list<Bundle> serialized_list {serialized};
 
   request_id = info.GetRequestId();
-  return impl_->sender_->SendMessage(info, serialized_list, noti->GetSenderAppId());
+  return impl_->sender_->SendMessage(
+      info, serialized_list, noti->GetSenderAppId());
 }
 
-int Reporter::Delete(std::list<std::shared_ptr<AbstractItem>> notiList, int& request_id) {
+int Reporter::Delete(
+    std::list<std::shared_ptr<AbstractItem>> notiList, int& request_id) {
   EventInfo info(EventInfo::Delete, util::GetAppId(), "");
   list<Bundle> serialized_list;
   for (auto& i : notiList) {
@@ -153,25 +160,18 @@ int Reporter::Delete(std::list<std::shared_ptr<AbstractItem>> notiList, int& req
 }
 
 int Reporter::DeleteAll(int& request_id) {
-  Bundle serialized;
   EventInfo info(EventInfo::DeleteAll, util::GetAppId(), "");
-  list<Bundle> serialized_list {serialized};
-
   request_id = info.GetRequestId();
-  return impl_->sender_->SendMessage(info, serialized_list, util::GetAppId());
+  return impl_->sender_->RequestReturnValue(info);
 }
 
 int Reporter::DeleteByChannel(string channel, int& request_id) {
-  Bundle serialized;
   EventInfo info(EventInfo::DeleteAll, util::GetAppId(), channel);
-  list<Bundle> serialized_list {serialized};
-
   request_id = info.GetRequestId();
-  return impl_->sender_->SendMessage(info, serialized_list, util::GetAppId());
+  return impl_->sender_->RequestReturnValue(info);
 }
 
 std::unique_ptr<AbstractItem> Reporter::FindByRootID(std::string id) {
-  Bundle serialized;
   EventInfo info(EventInfo::Get, util::GetAppId(), "", id);
   list<Bundle> result = impl_->sender_->Request(info);
   if (result.size() == 0) {
@@ -184,7 +184,6 @@ std::unique_ptr<AbstractItem> Reporter::FindByRootID(std::string id) {
 }
 
 list<unique_ptr<AbstractItem>> Reporter::FindByChannel(string channel) {
-  Bundle serialized;
   EventInfo info(EventInfo::Get, util::GetAppId(), channel, "");
   list<Bundle> result = impl_->sender_->Request(info);
   if (result.size() == 0) {
@@ -200,7 +199,6 @@ list<unique_ptr<AbstractItem>> Reporter::FindByChannel(string channel) {
 }
 
 list<unique_ptr<AbstractItem>> Reporter::FindAll() {
-  Bundle serialized;
   EventInfo info(EventInfo::Get, util::GetAppId(), "", "");
   list<Bundle> result = impl_->sender_->Request(info);
   if (result.size() == 0) {
@@ -217,8 +215,7 @@ list<unique_ptr<AbstractItem>> Reporter::FindAll() {
 
 int Reporter::GetCount(string channel) const {
   EventInfo info(EventInfo::Count, util::GetAppId(), channel);
-  int num = impl_->sender_->RequestNumber(info);
-  return num;
+  return impl_->sender_->RequestReturnValue(info);
 }
 
 int Reporter::SendEvent(const IEventInfo& info,
@@ -251,7 +248,8 @@ void Reporter::OnEvent(const IEventInfo& info, list<Bundle> serialized) {
   OnEvent(info, item_list);
 }
 
-list<shared_ptr<item::AbstractItem>> Reporter::OnRequestEvent(const IEventInfo& info) {
+list<shared_ptr<item::AbstractItem>> Reporter::OnRequestEvent(
+      const IEventInfo& info) {
   return list<shared_ptr<item::AbstractItem>>({});
 }
 
diff --git a/notification-ex/socket_handler.h b/notification-ex/socket_handler.h
new file mode 100644 (file)
index 0000000..aa9747f
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NOTIFICATION_EX_SOCKET_HANDLER_H_
+#define NOTIFICATION_EX_SOCKET_HANDLER_H_
+
+#include <unistd.h>
+
+namespace notification {
+
+class SocketHandler {
+ public:
+  SocketHandler(int fd):fd_(fd){}
+  ~SocketHandler() {
+    if(fd_!=-1)
+      close(fd_);
+  }
+  operator int() const { return fd_; }
+  int Get() {
+    return fd_;
+  }
+
+ private:
+  int fd_ = -1;
+};
+
+}  // namespace notification
+#endif  // NOTIFICATION_EX_SOCKET_HANDLER_H_
\ No newline at end of file
index f79ebdb..68cb4b4 100644 (file)
@@ -2810,7 +2810,12 @@ extern "C" EXPORT_API int noti_ex_manager_delete_all(noti_ex_manager_h handle,
   }
   try {
     ManagerStub* stub = static_cast<ManagerStub*>(handle);
-    ret = stub->DeleteAll(*request_id);
+    stub->DeleteAll(*request_id);
+    ret = get_last_result();
+    if (ret != ERROR_NONE) {
+      LOGE("error(%d)", ret);
+      return ret;
+    }
   } catch (Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
     return NOTI_EX_ERROR_IO_ERROR;
@@ -2829,7 +2834,12 @@ extern "C" EXPORT_API int noti_ex_manager_delete_by_channel(
 
   try {
     ManagerStub* stub = static_cast<ManagerStub*>(handle);
-    ret = stub->DeleteByChannel(channel, *request_id);
+    stub->DeleteByChannel(channel, *request_id);
+    ret = get_last_result();
+    if (ret != ERROR_NONE) {
+      LOGE("error(%d)", ret);
+      return ret;
+    }
   } catch (Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
     return NOTI_EX_ERROR_IO_ERROR;
@@ -2849,7 +2859,12 @@ extern "C" EXPORT_API int noti_ex_manager_delete_by_appid(
 
   try {
     ManagerStub* stub = static_cast<ManagerStub*>(handle);
-    ret = stub->DeleteByAppId(app_id, *request_id);
+    stub->DeleteByAppId(app_id, *request_id);
+    ret = get_last_result();
+    if (ret != ERROR_NONE) {
+      LOGE("error(%d)", ret);
+      return ret;
+    }
   } catch (Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
     return NOTI_EX_ERROR_IO_ERROR;
@@ -3294,7 +3309,12 @@ extern "C" EXPORT_API int noti_ex_reporter_delete_all(
 
   try {
     ReporterStub* stub = static_cast<ReporterStub*>(handle);
-    ret = stub->DeleteAll(*request_id);
+    stub->DeleteAll(*request_id);
+    ret = get_last_result();
+    if (ret != ERROR_NONE) {
+      LOGE("error(%d)", ret);
+      return ret;
+    }
   } catch (Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
     return NOTI_EX_ERROR_IO_ERROR;
@@ -3314,7 +3334,12 @@ extern "C" EXPORT_API int noti_ex_reporter_delete_by_channel(
 
   try {
     ReporterStub* stub = static_cast<ReporterStub*>(handle);
-    ret = stub->DeleteByChannel(channel, *request_id);
+    stub->DeleteByChannel(channel, *request_id);
+    ret = get_last_result();
+    if (ret != ERROR_NONE) {
+      LOGE("error(%d)", ret);
+      return ret;
+    }
   } catch (Exception &ex) {
     LOGE("%s %d", ex.what(), ex.GetErrorCode());
     return NOTI_EX_ERROR_IO_ERROR;
index 5d23946..9641808 100644 (file)
@@ -7,6 +7,8 @@ PKG_CHECK_MODULES(notification-ex_unittests REQUIRED
     gmock
     capi-appfw-app-control
     glib-2.0
+    gio-2.0
+    gio-unix-2.0
     aul
     security-manager
     libtzplatform-config