Change communication from dbus to socket to get list 34/165334/9
authorSeungha Son <seungha.son@samsung.com>
Thu, 28 Dec 2017 08:23:53 +0000 (17:23 +0900)
committerSeungha Son <seungha.son@samsung.com>
Mon, 8 Jan 2018 05:49:51 +0000 (14:49 +0900)
 Change the communication method from dbus to socket to get
 a very large number of notifications safely and quickly.

Related :
notification - https://review.tizen.org/gerrit/#/c/165331/

Signed-off-by: Seungha Son <seungha.son@samsung.com>
Change-Id: Ib79043677a67fb4c9a21aafd4e9a0cb5a9d75bca

CMakeLists.txt
include/notification_service.h
packaging/data-provider-master.spec
src/notification_service.c

index 01b4bcd..814a1c2 100644 (file)
@@ -15,6 +15,7 @@ pkg_check_modules(pkg REQUIRED
        db-util
        glib-2.0
        gio-2.0
+       gio-unix-2.0
        bundle
        ecore
        eina
index 5f16cc2..312fc48 100755 (executable)
@@ -32,7 +32,7 @@ int notification_update_noti_setting(GVariant *parameters, GVariant **reply_body
 int notification_update_noti_sys_setting(GVariant *parameters, GVariant **reply_body, uid_t uid);
 int notification_load_noti_by_tag(GVariant *parameters, GVariant **reply_body, uid_t uid);
 int notification_load_noti_by_priv_id(GVariant *parameters, GVariant **reply_body, uid_t uid);
-int notification_load_grouping_list(GVariant *parameters, GVariant **reply_body, uid_t uid);
+void notification_load_grouping_list(GDBusMethodInvocation *invocation, GVariant *parameters, uid_t uid);
 int notification_load_detail_list(GVariant *parameters, GVariant **reply_body, uid_t uid);
 int notification_get_setting_array(GVariant *parameters, GVariant **reply_body, uid_t uid);
 int notification_get_setting_by_app_id(GVariant *parameters, GVariant **reply_body, uid_t uid);
index faa3275..44694b6 100755 (executable)
@@ -17,6 +17,7 @@ BuildRequires: pkgconfig(sqlite3)
 BuildRequires: pkgconfig(db-util)
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(gio-unix-2.0)
 BuildRequires: pkgconfig(libsmack)
 BuildRequires: pkgconfig(bundle)
 BuildRequires: pkgconfig(capi-appfw-app-manager)
index 49562cd..f762575 100755 (executable)
 #include <stdlib.h>
 #include <unistd.h>
 
+#include <gio/gio.h>
+#include <gio/gunixfdlist.h>
+
 #include <dlog.h>
 #include <sys/smack.h>
 #include <pkgmgr-info.h>
 #include <notification.h>
-#include <gio/gio.h>
 #include <alarm.h>
 #include <aul.h>
 
@@ -145,7 +147,8 @@ static void _noti_dbus_method_call_handler(GDBusConnection *conn,
                ret = notification_load_noti_by_priv_id(parameters, &reply_body, uid);
        } else if (g_strcmp0(method_name, "load_noti_grouping_list") == 0) {
                notification_add_private_sharing_target_id(pid, sender, uid);
-               ret = notification_load_grouping_list(parameters, &reply_body, uid);
+               notification_load_grouping_list(invocation, parameters, uid);
+               return;
        } else if (g_strcmp0(method_name, "load_noti_detail_list") == 0) {
                notification_add_private_sharing_target_id(pid, sender, uid);
                ret = notification_load_detail_list(parameters, &reply_body, uid);
@@ -252,8 +255,9 @@ int notification_register_dbus_interface()
                        "        <method name='load_noti_grouping_list'>"
                        "          <arg type='i' name='type' direction='in'/>"
                        "          <arg type='i' name='count' direction='in'/>"
+                       "          <arg type='i' name='count_per_page' direction='in'/>"
                        "          <arg type='i' name='uid' direction='in'/>"
-                       "          <arg type='a(v)' name='noti_list' direction='out'/>"
+                       "          <arg type='i' name='list_count' direction='out'/>"
                        "        </method>"
 
                        "        <method name='load_noti_detail_list'>"
@@ -836,55 +840,120 @@ out:
        return ret;
 }
 
-/* load_noti_grouping_list */
-int notification_load_grouping_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
+static int __get_socket_from_invocation(GDBusMethodInvocation *invocation, int *fd)
+{
+       int ret_fd = 0;
+       GError *g_err = NULL;
+       GDBusMessage *msg = NULL;
+       GUnixFDList *fd_list = NULL;
+
+       msg = g_dbus_method_invocation_get_message(invocation);
+       fd_list = g_dbus_message_get_unix_fd_list(msg);
+       if (fd_list == NULL) {
+               ERR("fd list is null");
+               return NOTIFICATION_ERROR_IO_ERROR;
+       }
+
+       ret_fd = g_unix_fd_list_get(fd_list, 0, &g_err);
+       if (ret_fd == -1 || g_err) {
+               ERR("g_unix_fd_list_get [%s]", g_err->message);
+               g_error_free(g_err);
+               return NOTIFICATION_ERROR_IO_ERROR;
+       }
+
+       *fd = ret_fd;
+
+       INFO("sender fd : %d", ret_fd);
+       return NOTIFICATION_ERROR_NONE;
+}
+
+static int __send_list_to_socket(int fd, notification_list_h get_list, uid_t uid)
 {
        int ret;
        notification_h noti;
+       notification_list_h list_iter;
        GVariant *body = NULL;
-       notification_type_e type = NOTIFICATION_TYPE_NONE;
+
+       list_iter = notification_list_get_head(get_list);
+       do {
+               noti = notification_list_get_data(list_iter);
+               notification_set_private_sharing(noti, uid);
+               body = notification_ipc_make_gvariant_from_noti(noti, true);
+               ret = notification_ipc_socket_write_string(fd,
+                               (char *)g_variant_get_data(body),
+                               g_variant_get_size(body));
+               if (ret != NOTIFICATION_ERROR_NONE) {
+                       ERR("write string to socket fail");
+                       g_variant_unref(body);
+                       return ret;
+               }
+               list_iter = notification_list_get_next(list_iter);
+               g_variant_unref(body);
+       } while (list_iter != NULL);
+
+       return ret;
+}
+
+/* load_noti_grouping_list */
+void notification_load_grouping_list(GDBusMethodInvocation *invocation, GVariant *parameters, uid_t uid)
+{
+       int ret;
+       notification_type_e type;
        notification_list_h get_list = NULL;
-       notification_list_h list_iter;
-       GVariantBuilder *builder;
+       GVariant *reply_body = NULL;
+       int fd = 0;
        int count = 0;
+       int count_per_page;
        int list_count = 0;
        uid_t param_uid;
 
-       g_variant_get(parameters, "(iii)", &type, &count, &param_uid);
+       g_variant_get(parameters, "(iiii)", &type, &count, &count_per_page, &param_uid);
        ret = _validate_and_set_param_uid_with_uid(uid, &param_uid);
        if (ret != NOTIFICATION_ERROR_NONE)
-               return ret;
+               goto err;
 
-       ret = notification_noti_get_grouping_list(type, count, &get_list, param_uid);
-       if (ret != NOTIFICATION_ERROR_NONE)
-               return ret;
+       ret = __get_socket_from_invocation(invocation, &fd);
+       if (ret != NOTIFICATION_ERROR_NONE) {
+               ERR("get_fd_from_invocation [%d]", ret);
+               goto err;
+       }
 
-       builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
-       if (get_list) {
-               list_iter = notification_list_get_head(get_list);
-               do {
-                       noti = notification_list_get_data(list_iter);
-                       notification_set_private_sharing(noti, param_uid);
-                       body = notification_ipc_make_gvariant_from_noti(noti, true);
-                       g_variant_builder_add(builder, "(v)", body);
+       ret = notification_noti_get_grouping_list(type, count, count_per_page,
+                       &get_list, &list_count, param_uid);
+       if (ret != NOTIFICATION_ERROR_NONE) {
+               ERR("notification_noti_get_grouping_list [%d]", ret);
+               goto err;
+       }
 
-                       list_iter = notification_list_get_next(list_iter);
-                       list_count++;
-               } while (list_iter != NULL);
+       reply_body = g_variant_new("(i)", list_count);
+       if (reply_body == NULL) {
+               ERR("Failed to make reply_body");
+               ret = NOTIFICATION_ERROR_OUT_OF_MEMORY;
+               goto err;
+       }
 
+       g_dbus_method_invocation_return_value(invocation, reply_body);
+       if (get_list) {
+               ret = __send_list_to_socket(fd, get_list, param_uid);
+               if (ret != NOTIFICATION_ERROR_NONE)
+                       ERR("__send_list_to_socket [%d]", ret);
                notification_free_list(get_list);
        }
 
-       *reply_body = g_variant_new("(a(v))", builder);
-       g_variant_builder_unref(builder);
+       close(fd);
+       return;
 
-       if (*reply_body == NULL) {
-               ERR("Failed to make reply_body");
-               return NOTIFICATION_ERROR_OUT_OF_MEMORY;
-       }
+err:
+       if (fd)
+               close(fd);
+       if (get_list)
+               notification_free_list(get_list);
+       if (reply_body)
+               g_variant_unref(reply_body);
 
-       INFO("list type[%d], count[%d] ", type, list_count);
-       return ret;
+       ERR("notification service fail, method name[load_noti_grouping_list] [%d]", ret);
+       g_dbus_method_invocation_return_error(invocation, NOTIFICATION_ERROR,
+                               ret, "notification_service_error");
 }
 
 /* get_setting_array */