Release version 1.6.27
[platform/core/appfw/data-provider-master.git] / src / service_common.c
index 6fd0909..a79ddf6 100644 (file)
@@ -1,11 +1,11 @@
 /*
- * Copyright 2013  Samsung Electronics Co., Ltd
+ * Copyright 2016  Samsung Electronics Co., Ltd
  *
- * Licensed under the Flora License, Version 1.1 (the "License");
+ * 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://floralicense.org/license/
+ * 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,
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define _GNU_SOURCE
 #include <stdio.h>
-#include <pthread.h>
-#include <secure_socket.h>
-#include <packet.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/timerfd.h>
+#include <stdlib.h>
 #include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-
+#include <gio/gio.h>
 #include <dlog.h>
-#include <Eina.h>
-#include <com-core.h>
-#if defined(HAVE_LIVEBOX)
-#include <dynamicbox_errno.h>
-#else
-#include <lite-errno.h>
-#endif
+#include <notification_setting.h>
+#include <notification_setting_internal.h>
+#include <notification_setting_service.h>
+#include <notification_noti.h>
+#include <badge_setting.h>
+#include <badge_setting_service.h>
+#include <badge_db.h>
+#include <package-manager.h>
+#include <tzplatform_config.h>
+#include <pkgmgr-info.h>
 
-#include "service_common.h"
-#include "util.h"
 #include "debug.h"
-#include "conf.h"
-
-#define EVT_CH         'e'
-#define EVT_END_CH     'x'
-#define DEFAULT_TIMEOUT        2.0f
-
-int errno;
-
-struct service_event_item {
-    enum {
-       SERVICE_EVENT_TIMER
-    } type;
-
-    union {
-       struct {
-           int fd;
-       } timer;
-    } info;
-
-    int (*event_cb)(struct service_context *svc_cx, void *data);
-    void *cbdata;
-};
-
-struct tcb_event_cbdata {
-    struct tcb *tcb;
-    void (*cb)(struct service_context *svc_ctx, struct tcb *tcb, void *data);
-    void *data;
-};
-
-/*!
- * \note
- * Server information and global (only in this file-scope) variables are defined
- */
-struct service_context {
-    pthread_t server_thid; /*!< Server thread Id */
-    int fd; /*!< Server socket handle */
-
-    Eina_List *tcb_list; /*!< TCB list, list of every thread for client connections */
-    pthread_mutex_t tcb_list_lock;
-
-    Eina_List *packet_list;
-    pthread_mutex_t packet_list_lock;
-    int evt_pipe[PIPE_MAX];
-    int tcb_pipe[PIPE_MAX];
-
-    int (*service_thread_main)(struct tcb *tcb, struct packet *packet, void *data);
-    void *service_thread_data;
+#include "pkgmgr.h"
+#include "service_common.h"
+#include "notification_service.h"
+#include "badge_service.h"
+#include "shortcut_service.h"
 
-    Eina_List *event_list;
+#define DBUS_NAME "org.freedesktop.DBus"
+#define DBUS_OBJECT_PATH "/org/freedesktop/DBus"
+#define DBUS_INTERFACE_NAME "org.freedesktop.DBus"
 
-    Eina_List *tcb_create_cb_list;
-    Eina_List *tcb_destroy_cb_list;
-};
+#define PROVIDER_BUS_NAME "org.tizen.data_provider_service"
+#define PROVIDER_OBJECT_PATH "/org/tizen/data_provider_service"
 
-struct packet_info {
-    struct tcb *tcb;
-    struct packet *packet;
-};
+static GDBusConnection *_gdbus_conn;
+static GHashTable *_noti_pkg_privilege_info;
+static GHashTable *_badge_pkg_privilege_info;
 
-/*!
- * \note
- * Thread Control Block
- * - The main server will create a thread for every client connections.
- *   When a new client is comming to us, this TCB block will be allocated and initialized.
- */
-struct tcb { /* Thread controll block */
-    struct service_context *svc_ctx;
-    pthread_t thid; /*!< Thread Id */
-    int fd; /*!< Connection handle */
-    enum tcb_type type;
-    int ctrl_pipe[PIPE_MAX];
-    pid_t pid; /*!< Keep the PID of client, if the client is remote one, this will be -1 */
-};
-
-/*!
- * Do services for clients
- * Routing packets to destination processes.
- * CLIENT THREAD
- */
-static void *client_packet_pump_main(void *data)
+uid_t get_sender_uid(const char *sender_name)
 {
-    struct tcb *tcb = data;
-    struct service_context *svc_ctx = tcb->svc_ctx;
-    struct packet *packet = NULL;
-    fd_set set;
-    char *ptr = NULL;
-    int size = 0;
-    int packet_offset = 0;
-    int recv_offset = 0;
-    long ret;
-    int fd;
-    char evt_ch = EVT_CH;
-    enum {
-       RECV_INIT,
-       RECV_HEADER,
-       RECV_PAYLOAD,
-       RECV_DONE,
-    } recv_state;
-    struct packet_info *packet_info;
-    Eina_List *l;
-
-    ret = 0;
-    recv_state = RECV_INIT;
-    /*!
-     * \note
-     * To escape from the switch statement, we use this ret value
-     */
-    while (ret == 0) {
-       FD_ZERO(&set);
-       FD_SET(tcb->fd, &set);
-       FD_SET(tcb->ctrl_pipe[PIPE_READ], &set);
-       fd = tcb->fd > tcb->ctrl_pipe[PIPE_READ] ? tcb->fd : tcb->ctrl_pipe[PIPE_READ];
-       ret = select(fd + 1, &set, NULL, NULL, NULL);
-       if (ret < 0) {
-           ret = -errno;
-           if (errno == EINTR) {
-               ErrPrint("INTERRUPTED\n");
-               ret = 0;
-               continue;
-           }
-           ErrPrint("Error: %s\n", strerror(errno));
-           DbgFree(ptr);
-           ptr = NULL;
-           break;
-       } else if (ret == 0) {
-           ErrPrint("Timeout\n");
-           ret = -ETIMEDOUT;
-           DbgFree(ptr);
-           ptr = NULL;
-           break;
+       GDBusMessage *msg = NULL;
+       GDBusMessage *reply = NULL;
+       GError *err = NULL;
+       GVariant *body;
+       uid_t uid = 0;
+
+       msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
+                       DBUS_INTERFACE_NAME, "GetConnectionUnixUser");
+       if (!msg) {
+               LOGE("Failed to alloc new method call");
+               goto out;
        }
 
-       if (FD_ISSET(tcb->ctrl_pipe[PIPE_READ], &set)) {
-           DbgPrint("Thread is canceled\n");
-           ret = -ECANCELED;
-           DbgFree(ptr);
-           ptr = NULL;
-           break;
-       }
+       g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
+       reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
+                       G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
 
-       if (!FD_ISSET(tcb->fd, &set)) {
-           ErrPrint("Unexpected handler is toggled\n");
-           ret = -EINVAL;
-           DbgFree(ptr);
-           ptr = NULL;
-           break;
+       if (!reply) {
+               if (err != NULL) {
+                       LOGE("Failed to get uid [%s]", err->message);
+                       g_error_free(err);
+               }
+               goto out;
        }
 
-       /*!
-        * \TODO
-        * Service!!! Receive packet & route packet
-        */
-       switch (recv_state) {
-           case RECV_INIT:
-               size = packet_header_size();
-               packet_offset = 0;
-               recv_offset = 0;
-               packet = NULL;
-               ptr = malloc(size);
-               if (!ptr) {
-                   ErrPrint("Heap: %s\n", strerror(errno));
-                   ret = -ENOMEM;
-                   break;
-               }
-               recv_state = RECV_HEADER;
-               /* Go through, don't break from here */
-           case RECV_HEADER:
-               ret = secure_socket_recv(tcb->fd, ptr, size - recv_offset, &tcb->pid);
-               if (ret <= 0) {
-                   if (ret == 0) {
-                       ret = -ECANCELED;
-                   }
-                   DbgFree(ptr);
-                   ptr = NULL;
-                   break;
-               }
+       body = g_dbus_message_get_body(reply);
+       g_variant_get(body, "(u)", &uid);
 
-               recv_offset += ret;
-               ret = 0;
-
-               if (recv_offset == size) {
-                   packet = packet_build(packet, packet_offset, ptr, size);
-                   DbgFree(ptr);
-                   ptr = NULL;
-                   if (!packet) {
-                       ret = -EFAULT;
-                       break;
-                   }
-
-                   packet_offset += recv_offset;
-
-                   size = packet_payload_size(packet);
-                   if (size <= 0) {
-                       recv_state = RECV_DONE;
-                       recv_offset = 0;
-                       break;
-                   }
-
-                   recv_state = RECV_PAYLOAD;
-                   recv_offset = 0;
-
-                   ptr = malloc(size);
-                   if (!ptr) {
-                       ErrPrint("Heap: %s\n", strerror(errno));
-                       ret = -ENOMEM;
-                   }
-               }
-               break;
-           case RECV_PAYLOAD:
-               ret = secure_socket_recv(tcb->fd, ptr, size - recv_offset, &tcb->pid);
-               if (ret <= 0) {
-                   if (ret == 0) {
-                       ret = -ECANCELED;
-                   }
-                   DbgFree(ptr);
-                   ptr = NULL;
-                   break;
-               }
+out:
+       if (msg)
+               g_object_unref(msg);
+       if (reply)
+               g_object_unref(reply);
 
-               recv_offset += ret;
-               ret = 0;
+       return uid;
+}
 
-               if (recv_offset == size) {
-                   packet = packet_build(packet, packet_offset, ptr, size);
-                   DbgFree(ptr);
-                   ptr = NULL;
-                   if (!packet) {
-                       ret = -EFAULT;
-                       break;
-                   }
+pid_t get_sender_pid(const char *sender_name)
+{
+       GDBusMessage *msg = NULL;
+       GDBusMessage *reply = NULL;
+       GError *err = NULL;
+       GVariant *body;
+       pid_t pid = 0;
+
+       msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
+                       DBUS_INTERFACE_NAME, "GetConnectionUnixProcessID");
+       if (!msg) {
+               LOGE("Failed to alloc new method call");
+               goto out;
+       }
 
-                   packet_offset += recv_offset;
+       g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
+       reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
+                       G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
 
-                   recv_state = RECV_DONE;
-                   recv_offset = 0;
+       if (!reply) {
+               if (err != NULL) {
+                       LOGE("Failed to get uid [%s]", err->message);
+                       g_error_free(err);
                }
-               break;
-           case RECV_DONE:
-           default:
-               /* Dead code */
-               break;
+               goto out;
        }
 
-       if (recv_state == RECV_DONE) {
-           /*!
-            * Push this packet to the packet list with TCB
-            * Then the service main function will get this.
-            */
-           packet_info = malloc(sizeof(*packet_info));
-           if (!packet_info) {
-               ret = -errno;
-               ErrPrint("Heap: %s\n", strerror(errno));
-               packet_destroy(packet);
-               break;
-           }
-
-           packet_info->packet = packet;
-           packet_info->tcb = tcb;
-
-           CRITICAL_SECTION_BEGIN(&svc_ctx->packet_list_lock);
-           svc_ctx->packet_list = eina_list_append(svc_ctx->packet_list, packet_info);
-           CRITICAL_SECTION_END(&svc_ctx->packet_list_lock);
-
-           if (write(svc_ctx->evt_pipe[PIPE_WRITE], &evt_ch, sizeof(evt_ch)) != sizeof(evt_ch)) {
-               ret = -errno;
-               ErrPrint("Unable to write a pipe: %s\n", strerror(errno));
-               CRITICAL_SECTION_BEGIN(&svc_ctx->packet_list_lock);
-               svc_ctx->packet_list = eina_list_remove(svc_ctx->packet_list, packet_info);
-               CRITICAL_SECTION_END(&svc_ctx->packet_list_lock);
-
-               packet_destroy(packet);
-               DbgFree(packet_info);
-               ErrPrint("Terminate thread: %p\n", tcb);
-               break;
-           } else {
-               DbgPrint("Packet received: %d bytes\n", packet_offset);
-               recv_state = RECV_INIT;
-           }
-
-           /* Take a breathe */
-           pthread_yield();
-       }
-    }
+       body = g_dbus_message_get_body(reply);
+       g_variant_get(body, "(u)", &pid);
 
-    CRITICAL_SECTION_BEGIN(&svc_ctx->packet_list_lock);
-    EINA_LIST_FOREACH(svc_ctx->packet_list, l, packet_info) {
-       if (packet_info->tcb == tcb) {
-           DbgPrint("Reset ptr of the TCB[%p] in the list of packet info\n", tcb);
-           packet_info->tcb = NULL;
-       }
-    }
-    CRITICAL_SECTION_END(&svc_ctx->packet_list_lock);
-
-    /*!
-     * \note
-     * Emit a signal to collect this TCB from the SERVER THREAD.
-     */
-    if (write(svc_ctx->tcb_pipe[PIPE_WRITE], &tcb, sizeof(tcb)) != sizeof(tcb)) {
-       ErrPrint("Unable to write pipe: %s\n", strerror(errno));
-    }
-
-    return (void *)ret;
-}
+out:
+       if (msg)
+               g_object_unref(msg);
+       if (reply)
+               g_object_unref(reply);
 
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI int service_register_tcb_callback(struct service_context *svc_ctx, struct tcb *tcb, enum tcb_event_type event, void (*cb)(struct service_context *svc_ctx, struct tcb *tcb, void *data), void *data)
-{
-    struct tcb_event_cbdata *cbdata;
-
-    cbdata = malloc(sizeof(*cbdata));
-    if (!cbdata) {
-       ErrPrint("Heap: %s\n", strerror(errno));
-       return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
-    }
-
-    cbdata->tcb = tcb;
-    cbdata->cb = cb;
-    cbdata->data = data;
-
-    switch (event) {
-       case TCB_EVENT_CREATE:
-           if (tcb) {
-               DbgPrint("To catch the create event of TCB does not requires \"tcb\" handle\n");
-           }
-           svc_ctx->tcb_create_cb_list = eina_list_append(svc_ctx->tcb_create_cb_list, cbdata);
-           break;
-       case TCB_EVENT_DESTROY:
-           svc_ctx->tcb_destroy_cb_list = eina_list_append(svc_ctx->tcb_destroy_cb_list, cbdata);
-           break;
-       default:
-           DbgFree(cbdata);
-           return DBOX_STATUS_ERROR_INVALID_PARAMETER;
-    }
-
-    return DBOX_STATUS_ERROR_NONE;
+       return pid;
 }
 
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI int service_unregister_tcb_callback(struct service_context *svc_ctx, struct tcb *tcb, enum tcb_event_type event, void (*cb)(struct service_context *svc_ctx, struct tcb *tcb, void *data), void *data)
+bool is_existed_busname(const char *sender_name)
 {
-    struct tcb_event_cbdata *cbdata;
-    Eina_List *l;
-
-    switch (event) {
-       case TCB_EVENT_CREATE:
-           EINA_LIST_FOREACH(svc_ctx->tcb_create_cb_list, l, cbdata) {
-               if (cbdata->tcb == tcb && cbdata->cb == cb && cbdata->data == data) {
-                   svc_ctx->tcb_create_cb_list = eina_list_remove(svc_ctx->tcb_create_cb_list, cbdata);
-                   DbgFree(cbdata);
-                   return DBOX_STATUS_ERROR_NONE;
-               }
-           }
-           break;
-       case TCB_EVENT_DESTROY:
-           EINA_LIST_FOREACH(svc_ctx->tcb_destroy_cb_list, l, cbdata) {
-               if (cbdata->tcb == tcb && cbdata->cb == cb && cbdata->data == data) {
-                   svc_ctx->tcb_destroy_cb_list = eina_list_remove(svc_ctx->tcb_destroy_cb_list, cbdata);
-                   DbgFree(cbdata);
-                   return DBOX_STATUS_ERROR_NONE;
-               }
-           }
-           break;
-       default:
-           return DBOX_STATUS_ERROR_INVALID_PARAMETER;
-    }
-
-    return DBOX_STATUS_ERROR_NOT_EXIST;
-}
-
-/*!
- * \note
- * SERVER THREAD
- */
-static inline struct tcb *tcb_create(struct service_context *svc_ctx, int fd)
-{
-    struct tcb *tcb;
-    int status;
-    struct tcb_event_cbdata *cbdata;
-    Eina_List *l;
-    Eina_List *n;
-
-    tcb = malloc(sizeof(*tcb));
-    if (!tcb) {
-       ErrPrint("Heap: %s\n", strerror(errno));
-       return NULL;
-    }
-
-    if (pipe2(tcb->ctrl_pipe, O_CLOEXEC) < 0) {
-       ErrPrint("pipe2: %s\n", strerror(errno));
-       DbgFree(tcb);
-       return NULL;
-    }
-
-    tcb->fd = fd;
-    tcb->svc_ctx = svc_ctx;
-    tcb->type = TCB_CLIENT_TYPE_APP;
-    tcb->pid = -1;
-
-    DbgPrint("Create a new service thread [%d]\n", fd);
-    status = pthread_create(&tcb->thid, NULL, client_packet_pump_main, tcb);
-    if (status != 0) {
-       ErrPrint("Unable to create a new thread: %s\n", strerror(status));
-       CLOSE_PIPE(tcb->ctrl_pipe);
-       DbgFree(tcb);
-       return NULL;
-    }
-
-    CRITICAL_SECTION_BEGIN(&svc_ctx->tcb_list_lock);
-    svc_ctx->tcb_list = eina_list_append(svc_ctx->tcb_list, tcb);
-    CRITICAL_SECTION_END(&svc_ctx->tcb_list_lock);
-
-    EINA_LIST_FOREACH_SAFE(svc_ctx->tcb_create_cb_list, l, n, cbdata) {
-       if (!cbdata->cb) {
-           /* ASSERT */
-           ErrPrint("invalid CB\n");
-           svc_ctx->tcb_create_cb_list = eina_list_remove(svc_ctx->tcb_create_cb_list, cbdata);
-           DbgFree(cbdata);
-           continue;
+       GDBusMessage *msg = NULL;
+       GDBusMessage *reply = NULL;
+       GError *err = NULL;
+       GVariant *body;
+       bool is_existed = false;
+
+       msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
+                       DBUS_INTERFACE_NAME, "NameHasOwner");
+       if (!msg) {
+               LOGE("Failed to alloc new method call");
+               goto out;
        }
 
-       cbdata->cb(svc_ctx, tcb, cbdata->data);
-    }
-
-    return tcb;
-}
+       g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
+       reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
+                       G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
 
-/*!
- * \note
- * SERVER THREAD
- */
-static inline void tcb_teminate_all(struct service_context *svc_ctx)
-{
-    struct tcb *tcb;
-    void *ret;
-    int status;
-    char ch = EVT_END_CH;
-
-    /*!
-     * We don't need to make critical section on here.
-     * If we call this after terminate the server thread first.
-     * Then there is no other thread to access tcb_list.
-     */
-    EINA_LIST_FREE(svc_ctx->tcb_list, tcb) {
-       /*!
-        * ASSERT(tcb->fd >= 0);
-        */
-       if (write(tcb->ctrl_pipe[PIPE_WRITE], &ch, sizeof(ch)) != sizeof(ch)) {
-           ErrPrint("write: %s\n", strerror(errno));
+       if (!reply) {
+               if (err != NULL) {
+                       LOGE("Failed to get uid [%s]", err->message);
+                       g_error_free(err);
+               }
+               goto out;
        }
 
-       status = pthread_join(tcb->thid, &ret);
-       if (status != 0) {
-           ErrPrint("Unable to join a thread: %s\n", strerror(status));
-       } else {
-           DbgPrint("Thread returns: %p\n", ret);
-       }
+       body = g_dbus_message_get_body(reply);
+       g_variant_get(body, "(b)", &is_existed);
 
-       secure_socket_destroy_handle(tcb->fd);
+out:
+       if (msg)
+               g_object_unref(msg);
+       if (reply)
+               g_object_unref(reply);
 
-       CLOSE_PIPE(tcb->ctrl_pipe);
-       DbgFree(tcb);
-    }
+       return is_existed;
 }
 
-/*!
- * \note
- * SERVER THREAD
- */
-static inline void tcb_destroy(struct service_context *svc_ctx, struct tcb *tcb)
+int send_notify(GVariant *body, char *cmd, GHashTable **monitoring_hash, char *interface_name, uid_t uid)
 {
-    void *ret;
-    int status;
-    char ch = EVT_END_CH;
-    struct tcb_event_cbdata *cbdata;
-    Eina_List *l;
-    Eina_List *n;
-
-    EINA_LIST_FOREACH_SAFE(svc_ctx->tcb_destroy_cb_list, l, n, cbdata) {
-       if (!cbdata->cb) {
-           /* ASSERT */
-           ErrPrint("invalid CB\n");
-           svc_ctx->tcb_destroy_cb_list = eina_list_remove(svc_ctx->tcb_destroy_cb_list, cbdata);
-           DbgFree(cbdata);
-           continue;
-       }
-
-       if (cbdata->tcb != tcb) {
-           continue;
+       GError *err = NULL;
+       GList *monitoring_list = NULL;
+       GList *target_list;
+       char *target_bus_name;
+       int monitoring_count = 0;
+       bool is_existed = false;
+
+       monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
+       target_list = g_list_first(monitoring_list);
+       for (; target_list != NULL; ) {
+               err = NULL;
+               target_bus_name = target_list->data;
+               target_list = target_list->next;
+
+               if (g_variant_is_floating(body))
+                       g_variant_ref(body);
+
+               if (g_dbus_connection_emit_signal(_gdbus_conn,
+                                       target_bus_name,
+                                       PROVIDER_OBJECT_PATH,
+                                       interface_name,
+                                       cmd,
+                                       body,
+                                       &err) == FALSE) {
+                       if (err != NULL) {
+                               ERR("Emit signal err [%s]", err->message);
+                               g_error_free(err);
+                       }
+                       is_existed = is_existed_busname(target_bus_name);
+                       if (is_existed == false)
+                               delete_monitoring_list(monitoring_hash, target_bus_name, uid);
+                       ERR("Fail, emit signal to [%s]", target_bus_name);
+               }
+               monitoring_count++;
+               DBG("Success, emit signal to [%s]", target_bus_name);
        }
 
-       cbdata->cb(svc_ctx, tcb, cbdata->data);
-
-       if (eina_list_data_find(svc_ctx->tcb_destroy_cb_list, cbdata)) {
-           svc_ctx->tcb_destroy_cb_list = eina_list_remove(svc_ctx->tcb_destroy_cb_list, cbdata);
-           DbgFree(cbdata);
-       }
-    }
-
-    CRITICAL_SECTION_BEGIN(&svc_ctx->tcb_list_lock);
-    svc_ctx->tcb_list = eina_list_remove(svc_ctx->tcb_list, tcb);
-    CRITICAL_SECTION_END(&svc_ctx->tcb_list_lock);
-    /*!
-     * ASSERT(tcb->fd >= 0);
-     * Close the connection, and then collecting the return value of thread
-     */
-    if (write(tcb->ctrl_pipe[PIPE_WRITE], &ch, sizeof(ch)) != sizeof(ch)) {
-       ErrPrint("write: %s\n", strerror(errno));
-    }
-
-    status = pthread_join(tcb->thid, &ret);
-    if (status != 0) {
-       ErrPrint("Unable to join a thread: %s\n", strerror(status));
-    } else {
-       DbgPrint("Thread returns: %p\n", ret);
-    }
-
-    secure_socket_destroy_handle(tcb->fd);
-
-    CLOSE_PIPE(tcb->ctrl_pipe);
-    DbgFree(tcb);
+       DBG("Success, cmd[%s] monitoring count[%d]", cmd, monitoring_count);
+       return SERVICE_COMMON_ERROR_NONE;
 }
 
-/*!
- * \note
- * SERVER THREAD
- */
-static inline int update_fdset(struct service_context *svc_ctx, fd_set *set)
+int send_event_notify_by_busname(GVariant *body, char *cmd, char *busname, char *interface_name)
 {
-    Eina_List *l;
-    struct service_event_item *item;
-    int fd = 0;
-
-    FD_ZERO(set);
-
-    FD_SET(svc_ctx->fd, set);
-    fd = svc_ctx->fd;
-
-    FD_SET(svc_ctx->tcb_pipe[PIPE_READ], set);
-    if (svc_ctx->tcb_pipe[PIPE_READ] > fd) {
-       fd = svc_ctx->tcb_pipe[PIPE_READ];
-    }
-
-    FD_SET(svc_ctx->evt_pipe[PIPE_READ], set);
-    if (svc_ctx->evt_pipe[PIPE_READ] > fd) {
-       fd = svc_ctx->evt_pipe[PIPE_READ];
-    }
-
-    EINA_LIST_FOREACH(svc_ctx->event_list, l, item) {
-       if (item->type == SERVICE_EVENT_TIMER) {
-           FD_SET(item->info.timer.fd, set);
-           if (fd < item->info.timer.fd) {
-               fd = item->info.timer.fd;
-           }
+       GError *err = NULL;
+
+       if (g_variant_is_floating(body))
+               g_variant_ref(body);
+
+       if (g_dbus_connection_emit_signal(_gdbus_conn,
+                                         busname,
+                                         PROVIDER_OBJECT_PATH,
+                                         interface_name,
+                                         cmd,
+                                         body,
+                                         &err) == FALSE) {
+               if (err != NULL) {
+                       ERR("Emit signal err [%s]",
+                                       err->message);
+                       g_error_free(err);
+               }
+               ERR("Failed to emit signal to [%s]", busname);
+               return SERVICE_COMMON_ERROR_IO_ERROR;
        }
-    }
+       DBG("Success, Emit signal to [%s] cmd[%s]", busname, cmd);
+       return SERVICE_COMMON_ERROR_NONE;
+}
 
-    return fd + 1;
+/* register service */
+
+static int _monitoring_app_list_compare_cb(gconstpointer a, gconstpointer b)
+{
+       return strcmp(a, b);
 }
 
-/*!
- * \note
- * SERVER THREAD
- */
-static inline void processing_timer_event(struct service_context *svc_ctx, fd_set *set)
+int service_register(GVariant *parameters, GVariant **reply_body, const gchar *sender,
+               GBusNameAppearedCallback name_appeared_handler,
+               GBusNameVanishedCallback name_vanished_handler,
+               GHashTable **monitoring_hash,
+               uid_t uid)
 {
-    uint64_t expired_count;
-    Eina_List *l;
-    Eina_List *n;
-    struct service_event_item *item;
-
-    EINA_LIST_FOREACH_SAFE(svc_ctx->event_list, l, n, item) {
-       switch (item->type) {
-           case SERVICE_EVENT_TIMER:
-               if (!FD_ISSET(item->info.timer.fd, set)) {
-                   break;
+       GList *added_list = NULL;
+       const char *bus_name = sender;
+       monitoring_info_s *m_info = NULL;
+       uid_t request_uid = 0;
+       GList *monitoring_list = NULL;
+
+       if (sender == NULL)
+               return SERVICE_COMMON_ERROR_IO_ERROR;
+
+       g_variant_get(parameters, "(i)", &request_uid);
+       if (uid > NORMAL_UID_BASE && uid != request_uid)
+               return SERVICE_COMMON_ERROR_IO_ERROR;
+
+       DBG("service_register : uid %d , request_uid %d", uid, request_uid);
+       monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid));
+       added_list = g_list_find_custom(monitoring_list, bus_name,
+                       (GCompareFunc)_monitoring_app_list_compare_cb);
+
+       if (added_list == NULL) {
+               DBG("add new sender to list");
+               m_info = (monitoring_info_s *)calloc(1, sizeof(monitoring_info_s));
+               if (m_info == NULL) {
+                       ERR("Failed to alloc memory");
+                       return SERVICE_COMMON_ERROR_IO_ERROR;
                }
 
-               if (read(item->info.timer.fd, &expired_count, sizeof(expired_count)) == sizeof(expired_count)) {
-                   DbgPrint("Expired %d times\n", expired_count);
-                   if (item->event_cb(svc_ctx, item->cbdata) >= 0) {
-                       break;
-                   }
-               } else {
-                   ErrPrint("read: %s\n", strerror(errno));
+               m_info->bus_name = strdup(bus_name);
+               m_info->uid = request_uid;
+               m_info->watcher_id = g_bus_watch_name_on_connection(
+                               _gdbus_conn,
+                               bus_name,
+                               G_BUS_NAME_WATCHER_FLAGS_NONE,
+                               name_appeared_handler,
+                               name_vanished_handler,
+                               m_info,
+                               NULL);
+               if (m_info->watcher_id == 0) {
+                       ERR("Fail to watch name [%s]", bus_name);
+                       free(m_info->bus_name);
+                       free(m_info);
+                       return SERVICE_COMMON_ERROR_IO_ERROR;
                }
+               DBG("Watch on [%s] success", bus_name);
 
-               if (!eina_list_data_find(svc_ctx->event_list, item)) {
-                   break;
-               }
+               monitoring_list = g_list_append(monitoring_list, strdup(bus_name));
+               DBG("Success, sender[%s] length[%d]",
+                               sender, g_list_length(monitoring_list));
+               if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid)) == NULL)
+                       g_hash_table_insert(*monitoring_hash, GUINT_TO_POINTER(request_uid), monitoring_list);
+       } else {
+               ERR("Sender [%s] already exist", sender);
+       }
 
-               svc_ctx->event_list = eina_list_remove(svc_ctx->event_list, item);
-               if (close(item->info.timer.fd) < 0) {
-                   ErrPrint("close: %s\n", strerror(errno));
+       *reply_body = g_variant_new("()");
+       if (*reply_body == NULL) {
+               if (m_info) {
+                       if (m_info->bus_name)
+                               free(m_info->bus_name);
+                       free(m_info);
                }
-               DbgFree(item);
-               break;
-           default:
-               ErrPrint("Unknown event: %d\n", item->type);
-               break;
+               monitoring_list = g_list_remove(monitoring_list, bus_name);
+               ERR("Failed to make reply");
+               return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
        }
-    }
+       return SERVICE_COMMON_ERROR_NONE;
 }
 
-/*!
- * Accept new client connections
- * And create a new thread for service.
- *
- * Create Client threads & Destroying them
- * SERVER THREAD
- */
-static void *server_main(void *data)
+int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, uid_t uid)
 {
-    struct service_context *svc_ctx = data;
-    fd_set set;
-    fd_set except_set;
-    long ret;
-    int client_fd;
-    struct tcb *tcb;
-    int fd;
-    char evt_ch;
-    struct packet_info *packet_info;
-
-    DbgPrint("Server thread is activated\n");
-    while (1) {
-       fd = update_fdset(svc_ctx, &set);
-       memcpy(&except_set, &set, sizeof(set));
-
-       ret = select(fd, &set, NULL, &except_set, NULL);
-       if (ret < 0) {
-           ret = -errno;
-           if (errno == EINTR) {
-               DbgPrint("INTERRUPTED\n");
-               continue;
-           }
-           ErrPrint("Error: %s\n", strerror(errno));
-           break;
-       } else if (ret == 0) {
-           ErrPrint("Timeout\n");
-           ret = -ETIMEDOUT;
-           break;
-       }
-
-       if (FD_ISSET(svc_ctx->fd, &set)) {
-           client_fd = secure_socket_get_connection_handle(svc_ctx->fd);
-           if (client_fd < 0) {
-               ErrPrint("Failed to establish a new connection [%d]\n", svc_ctx->fd);
-               ret = -EFAULT;
-               break;
-           }
-
-           tcb = tcb_create(svc_ctx, client_fd);
-           if (!tcb) {
-               ErrPrint("Failed to create a new TCB: %d (%d)\n", client_fd, svc_ctx->fd);
-               secure_socket_destroy_handle(client_fd);
-           }
+       GList *monitoring_list = NULL;
+       GList *del_list = NULL;
+       char *bus_name;
+
+       monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
+       if (monitoring_list == NULL) {
+               ERR("No uid[%d] in monitoring hash", uid);
+               return SERVICE_COMMON_ERROR_IO_ERROR;
        }
 
-       if (FD_ISSET(svc_ctx->evt_pipe[PIPE_READ], &set)) {
-           if (read(svc_ctx->evt_pipe[PIPE_READ], &evt_ch, sizeof(evt_ch)) != sizeof(evt_ch)) {
-               ErrPrint("Unable to read pipe: %s\n", strerror(errno));
-               ret = -EFAULT;
-               break;
-           }
-
-           CRITICAL_SECTION_BEGIN(&svc_ctx->packet_list_lock);
-           packet_info = eina_list_nth(svc_ctx->packet_list, 0);
-           svc_ctx->packet_list = eina_list_remove(svc_ctx->packet_list, packet_info);
-           CRITICAL_SECTION_END(&svc_ctx->packet_list_lock);
-
-           if (packet_info) {
-               /*!
-                * \CRITICAL
-                * What happens if the client thread is terminated, so the packet_info->tcb is deleted
-                * while processing svc_ctx->service_thread_main?
-                */
-               ret = svc_ctx->service_thread_main(packet_info->tcb, packet_info->packet, svc_ctx->service_thread_data);
-               if (ret < 0) {
-                   ErrPrint("Service thread returns: %d\n", ret);
-               }
-
-               packet_destroy(packet_info->packet);
-               DbgFree(packet_info);
-           }
-
-           /* Take a breathe */
-           pthread_yield();
-       }
+       monitoring_list = g_list_first(monitoring_list);
+       del_list = g_list_find_custom(monitoring_list, sender,
+                       (GCompareFunc)_monitoring_app_list_compare_cb);
 
-       processing_timer_event(svc_ctx, &set);
-
-       /*!
-        * \note
-        * Destroying TCB should be processed at last.
-        */
-       if (FD_ISSET(svc_ctx->tcb_pipe[PIPE_READ], &set)) {
-           Eina_List *lockfree_packet_list;
-           Eina_List *l;
-           Eina_List *n;
-
-           if (read(svc_ctx->tcb_pipe[PIPE_READ], &tcb, sizeof(tcb)) != sizeof(tcb)) {
-               ErrPrint("Unable to read pipe: %s\n", strerror(errno));
-               ret = -EFAULT;
-               break;
-           }
-
-           if (!tcb) {
-               ErrPrint("Terminate service thread\n");
-               ret = -ECANCELED;
-               break;
-           }
-
-           lockfree_packet_list = NULL;
-           CRITICAL_SECTION_BEGIN(&svc_ctx->packet_list_lock);
-           EINA_LIST_FOREACH_SAFE(svc_ctx->packet_list, l, n, packet_info) {
-               if (packet_info->tcb != tcb) {
-                   continue;
-               }
+       if (del_list) {
+               DBG("Find delete list - uid[%d] sender[%s]", uid, sender);
+               bus_name = g_list_nth_data(del_list, 0);
+               if (bus_name)
+                       free(bus_name);
+               monitoring_list = g_list_delete_link(monitoring_list, del_list);
 
-               svc_ctx->packet_list = eina_list_remove(svc_ctx->packet_list, packet_info);
-               lockfree_packet_list = eina_list_append(lockfree_packet_list, packet_info);
-           }
-           CRITICAL_SECTION_END(&svc_ctx->packet_list_lock);
-
-           EINA_LIST_FREE(lockfree_packet_list, packet_info) {
-               ret = read(svc_ctx->evt_pipe[PIPE_READ], &evt_ch, sizeof(evt_ch));
-               DbgPrint("Flushing filtered pipe: %d (%c)\n", ret, evt_ch);
-               ret = svc_ctx->service_thread_main(packet_info->tcb, packet_info->packet, svc_ctx->service_thread_data);
-               if (ret < 0) {
-                   ErrPrint("Service thread returns: %d\n", ret);
+               if (monitoring_list == NULL) {
+                       g_hash_table_steal(*monitoring_hash, GUINT_TO_POINTER(uid));
+               } else {
+                       monitoring_list = g_list_first(monitoring_list);
+                       g_hash_table_replace(*monitoring_hash, GUINT_TO_POINTER(uid), monitoring_list);
                }
-               packet_destroy(packet_info->packet);
-               DbgFree(packet_info);
-           }
-
-           /*!
-            * \note
-            * Invoke the service thread main, to notify the termination of a TCB
-            */
-           ret = svc_ctx->service_thread_main(tcb, NULL, svc_ctx->service_thread_data);
-
-           /*!
-            * at this time, the client thread can access this tcb.
-            * how can I protect this TCB from deletion without disturbing the server thread?
-            */
-           tcb_destroy(svc_ctx, tcb);
        }
+       return SERVICE_COMMON_ERROR_NONE;
+}
 
-       /* If there is no such triggered FD? */
-    }
-
-    /*!
-     * Consuming all pended packets before terminates server thread.
-     *
-     * If the server thread is terminated, we should flush all pended packets.
-     * And we should services them.
-     * While processing this routine, the mutex is locked.
-     * So every other client thread will be slowed down, sequently, every clients can meet problems.
-     * But in case of termination of server thread, there could be systemetic problem.
-     * This only should be happenes while terminating the master daemon process.
-     */
-    CRITICAL_SECTION_BEGIN(&svc_ctx->packet_list_lock);
-    EINA_LIST_FREE(svc_ctx->packet_list, packet_info) {
-       ret = read(svc_ctx->evt_pipe[PIPE_READ], &evt_ch, sizeof(evt_ch));
-       DbgPrint("Flushing pipe: %d (%c)\n", ret, evt_ch);
-       ret = svc_ctx->service_thread_main(packet_info->tcb, packet_info->packet, svc_ctx->service_thread_data);
-       if (ret < 0) {
-           ErrPrint("Service thread returns: %d\n", ret);
+static int _dbus_init(void)
+{
+       GError *error = NULL;
+
+       if (_gdbus_conn == NULL) {
+               _gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+               if (_gdbus_conn == NULL) {
+                       if (error != NULL) {
+                               ERR("Failed to get dbus [%s]", error->message);
+                               g_error_free(error);
+                       }
+                       return SERVICE_COMMON_ERROR_IO_ERROR;
+               }
        }
-       packet_destroy(packet_info->packet);
-       DbgFree(packet_info);
-    }
-    CRITICAL_SECTION_END(&svc_ctx->packet_list_lock);
 
-    tcb_teminate_all(svc_ctx);
-    return (void *)ret;
+       return SERVICE_COMMON_ERROR_NONE;
 }
 
-/*!
- * \NOTE
- * MAIN THREAD
- */
-HAPI struct service_context *service_common_create(const char *addr, int (*service_thread_main)(struct tcb *tcb, struct packet *packet, void *data), void *data)
+int service_common_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable)
 {
-    int status;
-    struct service_context *svc_ctx;
-
-    if (!service_thread_main || !addr) {
-       ErrPrint("Invalid argument\n");
-       return NULL;
-    }
-
-    if (strncmp(addr, COM_CORE_REMOTE_SCHEME, strlen(COM_CORE_REMOTE_SCHEME))) {
-       int offset = 0;
-
-       offset = strlen(COM_CORE_LOCAL_SCHEME);
-       if (strncmp(addr, COM_CORE_LOCAL_SCHEME, offset)) {
-           offset = 0;
+       int result;
+       int owner_id, noti_registration_id;
+       GError *error = NULL;
+       GDBusNodeInfo *introspection_data = NULL;
+
+       result = _dbus_init();
+       if (result != SERVICE_COMMON_ERROR_NONE) {
+                       ERR("Can't init dbus [%d]", result);
+                       result = SERVICE_COMMON_ERROR_IO_ERROR;
+                       goto out;
        }
 
-       if (unlink(addr + offset) < 0) {
-           ErrPrint("[%s] - %s\n", addr, strerror(errno));
+       owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+                       PROVIDER_BUS_NAME,
+                       G_BUS_NAME_OWNER_FLAGS_NONE,
+                       NULL,
+                       NULL,
+                       NULL,
+                       NULL, NULL);
+       if (!owner_id) {
+               ERR("Failed to own name");
+               result = SERVICE_COMMON_ERROR_IO_ERROR;
+               goto out;
        }
-    }
-
-    svc_ctx = calloc(1, sizeof(*svc_ctx));
-    if (!svc_ctx) {
-       ErrPrint("Heap: %s\n", strerror(errno));
-       return NULL;
-    }
-
-    svc_ctx->fd = secure_socket_create_server(addr);
-    if (svc_ctx->fd < 0) {
-       DbgFree(svc_ctx);
-       return NULL;
-    }
-
-    svc_ctx->service_thread_main = service_thread_main;
-    svc_ctx->service_thread_data = data;
-
-    if (fcntl(svc_ctx->fd, F_SETFD, FD_CLOEXEC) < 0) {
-       ErrPrint("fcntl: %s\n", strerror(errno));
-    }
-
-    if (fcntl(svc_ctx->fd, F_SETFL, O_NONBLOCK) < 0) {
-       ErrPrint("fcntl: %s\n", strerror(errno));
-    }
-
-    if (pipe2(svc_ctx->evt_pipe, O_CLOEXEC) < 0) {
-       ErrPrint("pipe: %d\n", strerror(errno));
-       secure_socket_destroy_handle(svc_ctx->fd);
-       DbgFree(svc_ctx);
-       return NULL;
-    }
-
-    if (pipe2(svc_ctx->tcb_pipe, O_CLOEXEC) < 0) {
-       ErrPrint("pipe: %s\n", strerror(errno));
-       CLOSE_PIPE(svc_ctx->evt_pipe);
-       secure_socket_destroy_handle(svc_ctx->fd);
-       DbgFree(svc_ctx);
-       return NULL;
-    }
-
-    status = pthread_mutex_init(&svc_ctx->packet_list_lock, NULL);
-    if (status != 0) {
-       ErrPrint("Unable to create a mutex: %s\n", strerror(status));
-       CLOSE_PIPE(svc_ctx->evt_pipe);
-       CLOSE_PIPE(svc_ctx->tcb_pipe);
-       secure_socket_destroy_handle(svc_ctx->fd);
-       DbgFree(svc_ctx);
-       return NULL;
-    }
-
-    DbgPrint("Creating server thread\n");
-    status = pthread_create(&svc_ctx->server_thid, NULL, server_main, svc_ctx);
-    if (status != 0) {
-       ErrPrint("Unable to create a thread for shortcut service: %s\n", strerror(status));
-       status = pthread_mutex_destroy(&svc_ctx->packet_list_lock);
-       if (status != 0) {
-           ErrPrint("Error: %s\n", strerror(status));
+
+       DBG("Acquiring the own name [%d]", owner_id);
+       introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
+       if (!introspection_data) {
+               ERR("g_dbus_node_info_new_for_xml is failed.");
+               result = SERVICE_COMMON_ERROR_IO_ERROR;
+               if (error != NULL) {
+                       ERR("g_dbus_node_info_new_for_xml err [%s]", error->message);
+                       g_error_free(error);
+               }
+               goto out;
        }
-       CLOSE_PIPE(svc_ctx->evt_pipe);
-       CLOSE_PIPE(svc_ctx->tcb_pipe);
-       secure_socket_destroy_handle(svc_ctx->fd);
-       DbgFree(svc_ctx);
-       return NULL;
-    }
-
-    /*!
-     * \note
-     * To give a chance to run for server thread.
-     */
-    pthread_yield();
-
-    return svc_ctx;
-}
 
-/*!
- * \note
- * MAIN THREAD
- */
-HAPI int service_common_destroy(struct service_context *svc_ctx)
-{
-    int status = 0;
-    void *ret;
-
-    if (!svc_ctx) {
-       return -EINVAL;
-    }
-
-    /*!
-     * \note
-     * Terminate server thread
-     */
-    if (write(svc_ctx->tcb_pipe[PIPE_WRITE], &status, sizeof(status)) != sizeof(status)) {
-       ErrPrint("Failed to write: %s\n", strerror(errno));
-    }
-
-    status = pthread_join(svc_ctx->server_thid, &ret);
-    if (status != 0) {
-       ErrPrint("Join: %s\n", strerror(status));
-    } else {
-       DbgPrint("Thread returns: %p\n", ret);
-    }
-
-    secure_socket_destroy_handle(svc_ctx->fd);
-
-    status = pthread_mutex_destroy(&svc_ctx->packet_list_lock);
-    if (status != 0) {
-       ErrPrint("Unable to destroy a mutex: %s\n", strerror(status));
-    }
-
-    CLOSE_PIPE(svc_ctx->evt_pipe);
-    CLOSE_PIPE(svc_ctx->tcb_pipe);
-    DbgFree(svc_ctx);
-    return 0;
-}
+       noti_registration_id = g_dbus_connection_register_object(_gdbus_conn,
+                       PROVIDER_OBJECT_PATH, introspection_data->interfaces[0],
+                       &interface_vtable, NULL, NULL, NULL);
 
-/*!
- * \note
- * SERVER THREAD or OTHER THREAD (not main)
- */
-HAPI int tcb_is_valid(struct service_context *svc_ctx, struct tcb *tcb)
-{
-    Eina_List *l;
-    struct tcb *tmp;
-    int ret = -ENOENT;
-
-    CRITICAL_SECTION_BEGIN(&svc_ctx->tcb_list_lock);
-    EINA_LIST_FOREACH(svc_ctx->tcb_list, l, tmp) {
-       if (tmp == tcb /* && tcb->svc_ctx == svc_ctx */) {
-           ret = tcb->fd;
-           break;
+       DBG("registration id[%d]", noti_registration_id);
+       if (noti_registration_id == 0) {
+               ERR("Failed to g_dbus_connection_register_object");
+               result = SERVICE_COMMON_ERROR_IO_ERROR;
+               goto out;
        }
-    }
-    CRITICAL_SECTION_END(&svc_ctx->tcb_list_lock);
 
-    return ret;
-}
-
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI int tcb_pid(struct tcb *tcb)
-{
-    if (!tcb) {
-       return -1;
-    }
+out:
+       if (introspection_data)
+               g_dbus_node_info_unref(introspection_data);
 
-    return tcb->pid;
+       return result;
 }
 
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI int tcb_fd(struct tcb *tcb)
-{
-    if (!tcb) {
-       return -EINVAL;
-    }
+static int _init_pkg_privilege_info() {
 
-    return tcb->fd;
-}
+       if (_noti_pkg_privilege_info != NULL)
+               return 0;
 
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI int tcb_client_type(struct tcb *tcb)
-{
-    if (!tcb) {
-       return -EINVAL;
-    }
-
-    return tcb->type;
+       _noti_pkg_privilege_info =
+               g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
+       _badge_pkg_privilege_info =
+               g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
+       DBG("init pkg privilege info done");
+       return 0;
 }
 
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI int tcb_client_type_set(struct tcb *tcb, enum tcb_type type)
+static int _package_install_cb(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data)
 {
-    if (!tcb) {
-       return -EINVAL;
-    }
+       int ret;
+       gpointer tmp;
+       int privilege_info;
 
-    DbgPrint("TCB[%p] Client type is changed to %d from %d\n", tcb, type, tcb->type);
-    tcb->type = type;
-    return 0;
-}
+       if (status != PKGMGR_STATUS_END)
+               return 0;
 
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI struct service_context *tcb_svc_ctx(struct tcb *tcb)
-{
-    if (!tcb) {
-       return NULL;
-    }
+       if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
+               uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
 
-    return tcb->svc_ctx;
-}
+       _init_pkg_privilege_info();
+       if (g_hash_table_contains(_noti_pkg_privilege_info, pkgname)) {
+               tmp = g_hash_table_lookup(_noti_pkg_privilege_info, pkgname);
+               privilege_info = GPOINTER_TO_UINT(tmp);
+               if (privilege_info == 1)
+                       notification_setting_db_update_pkg_disabled(pkgname, false, uid);
 
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI int service_common_unicast_packet(struct tcb *tcb, struct packet *packet)
-{
-    if (!tcb || !packet) {
-       DbgPrint("Invalid unicast: tcb[%p], packet[%p]\n", tcb, packet);
-       return -EINVAL;
-    }
+               g_hash_table_remove(_noti_pkg_privilege_info, pkgname);
+       } else {
+               /* In consideration of the reboot status, change the disable information. */
+               ret = notification_setting_db_update_pkg_disabled(pkgname, false, uid);
+               if (ret != NOTIFICATION_ERROR_NONE)
+                       notification_setting_insert_package_for_uid(pkgname, uid);
+       }
 
-    DbgPrint("Unicast packet\n");
-    return com_core_send(tcb->fd, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
-}
+       if (g_hash_table_contains(_badge_pkg_privilege_info, pkgname)) {
+               tmp = g_hash_table_lookup(_badge_pkg_privilege_info, pkgname);
+               privilege_info = GPOINTER_TO_UINT(tmp);
+               if (privilege_info == 1)
+                       badge_db_update_pkg_disabled(pkgname, false, uid);
 
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI int service_common_multicast_packet(struct tcb *tcb, struct packet *packet, int type)
-{
-    Eina_List *l;
-    struct tcb *target;
-    struct service_context *svc_ctx;
-    int ret;
-
-    if (!tcb || !packet) {
-       DbgPrint("Invalid multicast: tcb[%p], packet[%p]\n", tcb, packet);
-       return -EINVAL;
-    }
-
-    svc_ctx = tcb->svc_ctx;
-
-    DbgPrint("Multicasting packets\n");
-
-    /*!
-     * \note
-     * Does not need to make a critical section from here.
-     */
-    EINA_LIST_FOREACH(svc_ctx->tcb_list, l, target) {
-       if (target == tcb || target->type != type) {
-           DbgPrint("Skip target: %p(%d) == %p/%d\n", target, target->type, tcb, type);
-           continue;
+               g_hash_table_remove(_badge_pkg_privilege_info, pkgname);
+       } else {
+               /* In consideration of the reboot status, change the disable information. */
+               ret = badge_db_update_pkg_disabled(pkgname, false, uid);
+               if (ret != BADGE_ERROR_NONE)
+                       badge_setting_insert_package_for_uid(pkgname, uid);
        }
 
-       ret = com_core_send(target->fd, (void *)packet_data(packet), packet_size(packet), DEFAULT_TIMEOUT);
-       if (ret < 0) {
-           ErrPrint("Failed to send packet: %d\n", ret);
-       }
-    }
-    DbgPrint("Finish to multicast packet\n");
-    return 0;
+       return 0;
 }
 
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI struct service_event_item *service_common_add_timer(struct service_context *svc_ctx, double timer, int (*timer_cb)(struct service_context *svc_cx, void *data), void *data)
+static int _package_uninstall_cb(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data)
 {
-    struct service_event_item *item;
-
-    item = calloc(1, sizeof(*item));
-    if (!item) {
-       ErrPrint("Heap: %s\n", strerror(errno));
-       return NULL;
-    }
-
-    item->type = SERVICE_EVENT_TIMER;
-    item->info.timer.fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
-    if (item->info.timer.fd < 0) {
-       ErrPrint("Error: %s\n", strerror(errno));
-       DbgFree(item);
-       return NULL;
-    }
-
-    if (service_common_update_timer(item, timer) < 0) {
-       if (close(item->info.timer.fd) < 0) {
-           ErrPrint("close: %s\n", strerror(errno));
+       int ret;
+       pkgmgrinfo_pkginfo_h pkginfo;
+
+       if (status != PKGMGR_STATUS_END)
+               return 0;
+
+       if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
+               uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+
+       ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(pkgname, uid, &pkginfo);
+       if (ret == PMINFO_R_OK) {
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
+
+               _init_pkg_privilege_info();
+               ret = notification_setting_db_update_pkg_disabled(pkgname, true, uid);
+               if (ret == NOTIFICATION_ERROR_NONE)
+                       g_hash_table_insert(_noti_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(1));
+               else
+                       g_hash_table_insert(_noti_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(0));
+
+               ret = badge_db_update_pkg_disabled(pkgname, true, uid);
+               if (ret == BADGE_ERROR_NONE)
+                       g_hash_table_insert(_badge_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(1));
+               else
+                       g_hash_table_insert(_badge_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(0));
+       } else {
+               notification_setting_delete_package_for_uid(pkgname, uid);
+               badge_db_delete_by_pkgname(pkgname, uid);
+               badge_setting_delete_package_for_uid(pkgname, uid);
+               notification_noti_delete_template(pkgname);
        }
-       DbgFree(item);
-       return NULL;
-    }
-
-    item->event_cb = timer_cb;
-    item->cbdata = data;
 
-    svc_ctx->event_list = eina_list_append(svc_ctx->event_list, item);
-    return item;
+       return 0;
 }
 
-HAPI int service_common_update_timer(struct service_event_item *item, double timer)
+static int _app_enabled_cb(uid_t uid, const char *app_id, enum pkgmgr_status status, double value, void *data)
 {
-    struct itimerspec spec;
-
-    spec.it_interval.tv_sec = (time_t)timer;
-    spec.it_interval.tv_nsec = (timer - spec.it_interval.tv_sec) * 1000000000;
+       if (status == PKGMGR_STATUS_END)
+               notification_setting_db_update_app_disabled(app_id, false, uid);
 
-    if (clock_gettime(CLOCK_MONOTONIC, &spec.it_value) < 0) {
-       ErrPrint("clock_gettime: %s\n", strerror(errno));
-       return -EFAULT;
-    }
-
-    spec.it_value.tv_sec += spec.it_interval.tv_sec;
-    spec.it_value.tv_nsec += spec.it_interval.tv_nsec;
-
-    if (timerfd_settime(item->info.timer.fd, TFD_TIMER_ABSTIME, &spec, NULL) < 0) {
-       ErrPrint("Error: %s\n", strerror(errno));
-       return -EFAULT;
-    }
-
-    DbgPrint("Armed interval: %u %u\n", spec.it_interval.tv_sec, spec.it_interval.tv_nsec);
-    return 0;
+       return 0;
 }
 
-/*!
- * \note
- * SERVER THREAD
- */
-HAPI int service_common_del_timer(struct service_context *svc_ctx, struct service_event_item *item)
+static int _app_disabled_cb(uid_t uid, const char *app_id, enum pkgmgr_status status, double value, void *data)
 {
-    if (!eina_list_data_find(svc_ctx->event_list, item)) {
-       ErrPrint("Invalid event item\n");
-       return -EINVAL;
-    }
-
-    svc_ctx->event_list = eina_list_remove(svc_ctx->event_list, item);
-
-    if (close(item->info.timer.fd) < 0) {
-       ErrPrint("close: %s\n", strerror(errno));
-    }
-    DbgFree(item);
-    return 0;
+       if (status == PKGMGR_STATUS_END) {
+               notification_delete_noti_by_app_id(app_id, uid);
+               notification_setting_db_update_app_disabled(app_id, true, uid);
+       }
+
+       return 0;
 }
 
-HAPI int service_common_fd(struct service_context *ctx)
+void service_common_init(void)
 {
-    return ctx->fd;
+       pkgmgr_init();
+       pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, _package_install_cb, NULL);
+       pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, _package_install_cb, NULL);
+       pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, _package_uninstall_cb, NULL);
+       pkgmgr_add_event_callback(PKGMGR_EVENT_APP_ENABLE, _app_enabled_cb, NULL);
+       pkgmgr_add_event_callback(PKGMGR_EVENT_APP_DISABLE, _app_disabled_cb, NULL);
 }
 
-/* End of a file */
+void service_common_set_connection(GDBusConnection *conn)
+{
+       _gdbus_conn = conn;
+}
\ No newline at end of file