Release version 0.2.4
[platform/core/appfw/event-system.git] / src / esd_main.c
index b3c7732..dee892c 100644 (file)
@@ -1,10 +1,11 @@
 #include <stdio.h>
+#include <stdlib.h>
 #include <glib.h>
 #include <aul.h>
+#include <aul_svc.h>
 #include <unistd.h>
 #include <ctype.h>
 #include <dlog.h>
-#include <Ecore.h>
 #include <gio/gio.h>
 #include <package-manager.h>
 #include <pkgmgr-info.h>
 #include <fcntl.h>
 #include <vconf.h>
 #include <tzplatform_config.h>
-#include <systemd/sd-login.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc/cinstance.h>
 #include <cynara-client.h>
 #include <cynara-creds-gdbus.h>
 #include <cynara-session.h>
 #include <security-manager.h>
 #include "eventsystem_daemon.h"
 
+#define DEFAULT_USER tzplatform_getuid(TZ_SYS_DEFAULT_USER)
 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
 #define ROOT_USER 0
 
+#define SYS_EVENT_NAME_PREFIX "tizen.system.event"
+#define SYS_EVENT_OBJ_PATH "/tizen/system/event"
+#define REQUEST_LAST_DATA "request_last_data"
+
 static GHashTable *event_launch_table; /* table of events for launch_on_event*/
 
 static const char *event_launch_support_list[] = {
@@ -31,7 +38,8 @@ static const char *event_launch_support_list[] = {
        SYS_EVENT_USB_STATUS,
        SYS_EVENT_EARJACK_STATUS,
        SYS_EVENT_INCOMMING_MSG,
-       SYS_EVENT_OUTGOING_MSG
+       SYS_EVENT_OUTGOING_MSG,
+       SYS_EVENT_WIFI_STATE
 };
 
 struct privilege_info {
@@ -65,9 +73,18 @@ typedef struct __earlier_table_item {
        bundle *earlier_data; /* event-data from earlier occurrence */
 } earlier_item;
 
-static bool g_is_bootcompleted = false;
 #endif
 
+static GHashTable *user_last_event_table; /* table of user events for last data */
+
+struct __last_event_item {
+       char *key;
+       char *app_id;
+       char *event_name;
+       char *own_name;
+       uid_t uid;
+};
+
 static GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */
 
 typedef struct __trusted_busname_item {
@@ -81,9 +98,16 @@ typedef struct __eventlaunch_item_param {
        char *app_id;
 } eventlaunch_item_param_s;
 
+enum trusted_result {
+       TRUSTED_UNKNOWN,
+       TRUSTED_ALLOWED,
+       TRUSTED_DENIED,
+};
+
 typedef struct esd_list_item {
        char *pkg_id;
        char *app_id;
+       int trusted_info;
        uid_t uid;
 } esd_list_item_s;
 
@@ -110,6 +134,10 @@ typedef struct __pkgmgr_event {
 typedef struct __esd_event_param {
        char *event_name;
        bundle *event_data;
+       uid_t sender_uid;
+       char *sender_appid;
+       bool is_user_event;
+       bool trusted;
        void *user_data;
 } esd_event_param;
 
@@ -118,9 +146,6 @@ typedef struct esd_info {
 } esd_info_s;
 static esd_info_s s_info;
 
-static Ecore_Fd_Handler *g_fd_handler;
-sd_login_monitor *g_sd_monitor;
-
 typedef struct __esd_appctrl_cb_data {
        char *appid;
        char *pkgid;
@@ -130,7 +155,7 @@ typedef struct __esd_appctrl_cb_data {
 static void __esd_event_handler(char *event_name, bundle *data, void *user_data);
 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data);
 
-static cynara *r_cynara = NULL;
+static cynara *r_cynara;
 
 static int __esd_init_cynara(void)
 {
@@ -152,6 +177,17 @@ static void __esd_finish_cynara(void)
        r_cynara = NULL;
 }
 
+static void free_saved_event(struct __last_event_item *item)
+{
+       if (!item)
+               return;
+
+       free(item->event_name);
+       free(item->own_name);
+       free(item->app_id);
+       free(item);
+}
+
 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
 static int __esd_check_earlier_support(const char *event_name)
 {
@@ -167,6 +203,74 @@ static int __esd_check_earlier_support(const char *event_name)
 }
 #endif
 
+static bool __esd_check_platform_cert(const char *pkgid, uid_t uid)
+{
+       _D("Checking if %s has a platform certification", pkgid);
+
+       int r;
+       const char *cert_value;
+       pkgmgrinfo_certinfo_h certinfo;
+       CertSvcInstance instance;
+       CertSvcCertificate certificate;
+       CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
+
+       r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
+       if (r != PMINFO_R_OK) {
+               _E("Failed to create certinfo");
+               return false;
+       }
+
+       r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid);
+       if (r != PMINFO_R_OK) {
+               _E("Failed to load certinfo");
+               pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
+               return false;
+       }
+
+       r = pkgmgrinfo_pkginfo_get_cert_value(certinfo,
+                       PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value);
+       if (r != PMINFO_R_OK || cert_value == NULL) {
+               _E("Failed to get cert value");
+               pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
+               return false;
+       }
+
+       r = certsvc_instance_new(&instance);
+       if (r != CERTSVC_SUCCESS) {
+               _E("certsvc_instance_new() is failed.");
+               pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
+               return false;
+       }
+
+       r = certsvc_certificate_new_from_memory(instance,
+                       (const unsigned char *)cert_value,
+                       strlen(cert_value),
+                       CERTSVC_FORM_DER_BASE64,
+                       &certificate);
+       if (r != CERTSVC_SUCCESS) {
+               _E("certsvc_certificate_new_from_memory() is failed.");
+               pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
+               certsvc_instance_free(instance);
+               return false;
+       }
+
+       r = certsvc_certificate_get_visibility(certificate, &visibility);
+       if (r != CERTSVC_SUCCESS)
+               _E("certsvc_certificate_get_visibility() is failed.");
+
+       pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
+       certsvc_certificate_free(certificate);
+       certsvc_instance_free(instance);
+
+       _D("visibility is %d", visibility);
+       if (visibility & CERTSVC_VISIBILITY_PLATFORM) {
+               _D("%s has a platform certification", pkgid);
+               return true;
+       }
+
+       return false;
+}
+
 static int __esd_check_event_launch_support(const char *event_name)
 {
        int i = 0;
@@ -241,9 +345,8 @@ static int __get_sender_uid(GDBusConnection *conn, const char *sender_name)
        int uid = -1;
 
        uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser");
-       if (uid < 0) {
+       if (uid < 0)
                _E("failed to get uid");
-       }
 
        _D("sender_name(%s), uid(%d)", sender_name, uid);
 
@@ -522,13 +625,15 @@ static int __esd_add_list_item(uid_t uid, event_launch_item *el_item,
        item_of_list->uid = uid;
        item_of_list->app_id = (char *)app_id;
        item_of_list->pkg_id = (char *)pkg_id;
+       item_of_list->trusted_info = TRUSTED_UNKNOWN;
        el_item->app_list_evtlaunch =
                g_list_append(el_item->app_list_evtlaunch, item_of_list);
 
        return ES_R_OK;
 }
 
-static int __esd_add_launch_item(uid_t uid, const char *event_name, const char *appid, const char *pkgid)
+static int __esd_add_launch_item(uid_t uid, const char *event_name,
+               const char *appid, const char *pkgid)
 {
        GList *app_list = NULL;
        guint subscription_id = 0;
@@ -730,18 +835,39 @@ static void __esd_event_launch_with_appid(gpointer data, gpointer user_data)
        int pid;
        char event_uri[1024];
        bundle *b;
+       int ret;
 
-       _D("launch_on_event: app_id(%s), event_name(%s), uid(%d)",
-                       app_id, eep->event_name, uid);
+       _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d), trusted(%d)",
+                       app_id, eep->event_name, uid, eep->is_user_event, eep->trusted);
+
+       if (eep->is_user_event && eep->trusted) {
+               if (item->trusted_info == TRUSTED_UNKNOWN) {
+                       ret = __esd_check_certificate_match(uid, app_id, eep->sender_uid, eep->sender_appid);
+                       if (ret == ES_R_EINVAL) {
+                               item->trusted_info = TRUSTED_DENIED;
+                               return;
+                       } else if (ret == ES_R_ERROR) {
+                               return;
+                       } else {
+                               item->trusted_info = TRUSTED_ALLOWED;
+                       }
+               } else if (item->trusted_info == TRUSTED_DENIED) {
+                       return;
+               }
+       }
 
        if (!aul_app_is_running_for_uid(app_id, uid)) {
-               snprintf(event_uri, sizeof(event_uri), "event://%s", eep->event_name);
                b = bundle_dup(eep->event_data);
+               if (eep->is_user_event)
+                       snprintf(event_uri, sizeof(event_uri), "%s%s", USER_EVENT_NAME_PREFIX, eep->event_name);
+               else
+                       snprintf(event_uri, sizeof(event_uri), "%s%s", SYSTEM_EVENT_NAME_PREFIX, eep->event_name);
+
                appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT);
                appsvc_set_uri(b, event_uri);
                appsvc_set_appid(b, app_id);
 
-               pid = appsvc_usr_run_service(b, req_id++, NULL, eep->user_data, uid);
+               pid = aul_svc_run_service_async_for_uid(b, req_id++, NULL, eep->user_data, uid);
                _D("uid(%d), pid(%d)", uid, pid);
 
                bundle_free(b);
@@ -761,7 +887,9 @@ static void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_d
        }
 }
 
-static void __esd_launch_event_handler(char *event_name, bundle *data, void *user_data)
+static void __esd_launch_event_handler(char *event_name, bundle *data,
+               const bool is_user_event, gboolean trusted,
+               const uid_t sender_uid, char *sender_appid, void *user_data)
 {
        const char *val;
        const char *msg_type;
@@ -776,31 +904,40 @@ static void __esd_launch_event_handler(char *event_name, bundle *data, void *use
                return;
 
        if (el_item->app_list_evtlaunch != NULL) {
-               if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) {
-                       val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS);
-                       _D("charger val(%s)", val);
-                       if (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0)
-                               return;
-               } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) {
-                       val = bundle_get_val(data, EVT_KEY_USB_STATUS);
-                       _D("usb val(%s)", val);
-                       if (strcmp(EVT_VAL_USB_CONNECTED, val) != 0)
-                               return;
-               } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) {
-                       val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS);
-                       _D("earjack val(%s)", val);
-                       if (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0)
-                               return;
-               } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) {
-                       msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE);
-                       _D("msg_type(%s)", msg_type);
-                       if (msg_type == NULL)
-                               return;
-
-                       msg_id = bundle_get_val(data, EVT_KEY_MSG_ID);
-                       _D("msg_id(%s)", msg_id);
-                       if (msg_id == NULL)
-                               return;
+               if (is_user_event == false) {
+                       if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) {
+                               val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS);
+                               _D("charger val(%s)", val);
+                               if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0))
+                                       return;
+                       } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) {
+                               val = bundle_get_val(data, EVT_KEY_USB_STATUS);
+                               _D("usb val(%s)", val);
+                               if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0))
+                                       return;
+                       } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) {
+                               val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS);
+                               _D("earjack val(%s)", val);
+                               if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0))
+                                       return;
+                       } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) {
+                               msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE);
+                               _D("msg_type(%s)", msg_type);
+                               if (msg_type == NULL)
+                                       return;
+
+                               msg_id = bundle_get_val(data, EVT_KEY_MSG_ID);
+                               _D("msg_id(%s)", msg_id);
+                               if (msg_id == NULL)
+                                       return;
+                       } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) {
+                               val = bundle_get_val(data, EVT_KEY_WIFI_STATE);
+                               if (val == NULL)
+                                       return;
+                               _D("wifi_state(%s)", val);
+                               if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0)
+                                       return;
+                       }
                }
 
                eep = calloc(1, sizeof(esd_event_param));
@@ -810,6 +947,10 @@ static void __esd_launch_event_handler(char *event_name, bundle *data, void *use
                }
                eep->event_name = event_name;
                eep->event_data = data;
+               eep->sender_uid = sender_uid;
+               eep->sender_appid = sender_appid;
+               eep->is_user_event = is_user_event;
+               eep->trusted = (bool)trusted;
                eep->user_data = (void *)user_data;
                __esd_check_event_launch_with_eventid(el_item, eep);
                free(eep);
@@ -862,7 +1003,6 @@ static void __esd_earlier_table_print_items(void)
 
 static void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data)
 {
-       int handle;
        earlier_item *item;
        _D("event_name(%s)", event_name);
 
@@ -873,15 +1013,6 @@ static void __esd_earlier_event_handler(char *event_name, bundle *data, void *us
                        bundle_free(item->earlier_data);
 
                item->earlier_data = bundle_dup(data);
-
-               if (!g_is_bootcompleted) {
-                       if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
-                               handle = creat(ESD_BOOT_COMPLETED, 0640);
-                               if (handle != -1)
-                                       close(handle);
-                               g_is_bootcompleted = true;
-                       }
-               }
        }
 }
 #endif
@@ -896,7 +1027,8 @@ static void __esd_event_handler(char *event_name, bundle *data, void *user_data)
 #endif
 
        if (__esd_check_event_launch_support(event_name))
-               __esd_launch_event_handler(event_name, data, user_data);
+               __esd_launch_event_handler(event_name, data,
+                               false, TRUE, ROOT_USER, NULL, user_data);
 }
 
 static void __esd_trusted_busname_remove_item(char *bus_name)
@@ -935,7 +1067,7 @@ static void __esd_filter_name_owner_changed(GDBusConnection *connection,
        int old_len = 0;
        int new_len = 0;
 
-       g_variant_get(parameters, "(sss)", &name, &old_owner, &new_owner);
+       g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
 
        if (strstr(name, "event.busname.session")) {
                old_len = strlen(old_owner);
@@ -967,97 +1099,80 @@ static int __esd_dbus_name_monitor(GDBusConnection *connection)
        return ES_R_OK;
 }
 
-static int __esd_get_user_items(void)
+static int __esd_get_user_items(uid_t uid)
 {
        int ret = 0;
-       int i = 0;
-       uid_t *uids = NULL;
-       uid_t cur_uid = 0;
+       pkgmgrinfo_appinfo_filter_h handle = NULL;
+
+       _I("get user items for uid(%d)", uid);
+       /* reset user's item */
+       __esd_launch_table_remove_private_usr_items();
 
-       ret = sd_get_uids(&uids);
+       ret = pkgmgrinfo_appinfo_filter_create(&handle);
        if (ret < 0) {
-               _E("failed to get uids (%d)", ret);
+               _E("failed to create appinfo filter");
                return ES_R_ERROR;
        }
-
-       if (ret == 0 || uids == NULL) {
-               _I("there is no uid for now");
-       } else {
-               /* reset user's item */
-               __esd_launch_table_remove_private_usr_items();
-               for (i = 0; i < ret; i++) {
-                       cur_uid = uids[i];
-                       _I("found uid(%d)", cur_uid);
-
-                       ret = pkgmgrinfo_appinfo_get_usr_installed_list(__esd_add_appinfo_handler, cur_uid, &cur_uid);
-                       if (ret < 0)
-                               _E("failed to get user(%d)-app list (%d)", cur_uid, ret);
-               }
-       }
-
-       __esd_launch_table_print_items();
-
-       return ES_R_OK;
-}
-
-static Eina_Bool __esd_fd_handler_func(void *data, Ecore_Fd_Handler *fd_handler)
-{
-       if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
-               _I("fd read");
-               __esd_get_user_items();
-       }
-
-       return ECORE_CALLBACK_CANCEL;
-}
-
-static int __esd_start_sd_monitor(void)
-{
-       int ret = 0;
-       int fd = 0;
-
-       ret = __esd_get_user_items();
-       if (ret < 0)
-               return ES_R_ERROR;
-
-       ret = sd_login_monitor_new("uid", &g_sd_monitor);
+       ret = pkgmgrinfo_appinfo_filter_add_string(handle,
+                       PMINFO_APPINFO_PROP_APP_COMPONENT, "svcapp");
        if (ret < 0) {
-               _E("sd_login_monitor_new error (%d)", ret);
+               _E("failed to add appinfo filter string");
+               pkgmgrinfo_appinfo_filter_destroy(handle);
                return ES_R_ERROR;
        }
-
-       fd = sd_login_monitor_get_fd(g_sd_monitor);
-       if (fd < 0) {
-               _E("sd_login_monitor_get_fd error");
-               sd_login_monitor_unref(g_sd_monitor);
+       ret = pkgmgrinfo_appinfo_filter_add_string(handle,
+                       PMINFO_APPINFO_PROP_APP_OPERATION, APPSVC_OPERATION_LAUNCH_ON_EVENT);
+       if (ret < 0) {
+               _E("failed to add appinfo filter string");
+               pkgmgrinfo_appinfo_filter_destroy(handle);
                return ES_R_ERROR;
        }
-
-       g_fd_handler = ecore_main_fd_handler_add(fd,
-               (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR),
-               __esd_fd_handler_func, NULL, NULL, NULL);
-       if (g_fd_handler == NULL) {
-               _E("fd_handler is NULL");
-               sd_login_monitor_unref(g_sd_monitor);
+       ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle,
+                       __esd_add_appinfo_handler, &uid, uid);
+       if (ret < 0) {
+               _E("appinfo filter foreach error");
+               pkgmgrinfo_appinfo_filter_destroy(handle);
                return ES_R_ERROR;
        }
+       pkgmgrinfo_appinfo_filter_destroy(handle);
 
-       _I("setup sd-monitor done");
+       __esd_launch_table_print_items();
 
        return ES_R_OK;
 }
 
-static int __esd_stop_sd_monitor(void)
+static void __esd_signal_handler(GDBusConnection *connection,
+               const gchar *sender_name,
+               const gchar *object_path,
+               const gchar *interface_name,
+               const gchar *signal_name,
+               GVariant *parameters,
+               gpointer user_data)
 {
-       _I("stop sd_monitor");
-       if (g_fd_handler) {
-               ecore_main_fd_handler_del(g_fd_handler);
-               g_fd_handler = NULL;
-       }
+       int handle;
+       bundle *b;
+       guint64 uid = 0;
 
-       sd_login_monitor_unref(g_sd_monitor);
-       g_sd_monitor = 0;
+       if (!g_strcmp0(signal_name,
+                               SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED)) {
+               _I("System session finished");
 
-       return ES_R_OK;
+               b = bundle_create();
+               bundle_add_str(b, EVT_KEY_BOOT_COMPLETED,
+                       EVT_VAL_BOOT_COMPLETED_TRUE);
+               eventsystem_send_system_event(SYS_EVENT_BOOT_COMPLETED, b);
+               bundle_free(b);
+
+               handle = creat(ESD_BOOT_COMPLETED, 0640);
+               if (handle != -1)
+                       close(handle);
+       } else if (!g_strcmp0(signal_name,
+                               SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED)) {
+               g_variant_get(parameters, "(t)", &uid);
+               _I("User session finished uid : %d", (int)uid);
+               if ((uid_t)uid != DEFAULT_USER)
+                       __esd_get_user_items((uid_t)uid);
+       }
 }
 
 static GDBusNodeInfo *introspection_data;
@@ -1114,10 +1229,51 @@ static const gchar introspection_xml[] =
 "                      <arg type='s' name='earlier_data' direction='out'/>"
 "              </method>"
 #endif
+"              <method name='KeepLastData'>"
+"                      <arg type='s' name='eventname' direction='in'/>"
+"                      <arg type='s' name='own_name' direction='in'/>"
+"                      <arg type='i' name='ret' direction='out'/>"
+"              </method>"
+"              <method name='CheckLastData'>"
+"                      <arg type='s' name='eventname' direction='in'/>"
+"                      <arg type='s' name='own_name' direction='in'/>"
+"                      <arg type='i' name='ret' direction='out'/>"
+"              </method>"
+"              <method name='LaunchOnEventFromUserEvent'>"
+"                      <arg type='s' name='eventname' direction='in'/>"
+"                      <arg type='s' name='eventdata' direction='in'/>"
+"                      <arg type='i' name='datalen' direction='in'/>"
+"                      <arg type='b' name='trusted' direction='in'/>"
+"                      <arg type='i' name='ret' direction='out'/>"
+"              </method>"
+"              <method name='CionGetUuid'>"
+"                      <arg type='i' name='ret' direction='out'/>"
+"                      <arg type='s' name='uuid' direction='out'/>"
+"              </method>"
+"              <method name='CionSetDisplayName'>"
+"                      <arg type='s' name='service_name' direction='in'/>"
+"                      <arg type='s' name='display_name' direction='in'/>"
+"                      <arg type='i' name='ret' direction='out'/>"
+"              </method>"
+"              <method name='CionGetDisplayName'>"
+"                      <arg type='s' name='service_name' direction='in'/>"
+"                      <arg type='i' name='ret' direction='out'/>"
+"                      <arg type='s' name='display_name' direction='out'/>"
+"              </method>"
+"              <method name='CionSetEnabled'>"
+"                      <arg type='s' name='service_name' direction='in'/>"
+"                      <arg type='b' name='enabled' direction='in'/>"
+"                      <arg type='i' name='ret' direction='out'/>"
+"              </method>"
+"              <method name='CionGetEnabled'>"
+"                      <arg type='s' name='service_name' direction='in'/>"
+"                      <arg type='i' name='ret' direction='out'/>"
+"                      <arg type='b' name='enabled' direction='out'/>"
+"              </method>"
 "      </interface>"
 "</node>";
 
-static int __esd_get_appid_by_pid(int pid, uid_t uid, char *app_id, int buf_size)
+static int __esd_get_appid_by_pid_for_uid(int pid, uid_t uid, char *app_id, int buf_size)
 {
        int retval = ES_R_OK;
        int ret = 0;
@@ -1140,6 +1296,33 @@ static int __esd_get_appid_by_pid(int pid, uid_t uid, char *app_id, int buf_size
        return retval;
 }
 
+static int __esd_get_appid_by_pid(int pid, char *app_id, int buf_size)
+{
+       int ret;
+       int fd;
+       char buf[128] = { 0, };
+
+       ret = aul_app_get_appid_bypid(pid, app_id, buf_size);
+       if (ret != AUL_R_OK) {
+               snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
+
+               fd = open(buf, O_RDONLY);
+               if (fd < 0)
+                       return ES_R_ERROR;
+
+               ret = read(fd, app_id, buf_size - 1);
+               close(fd);
+
+               if (ret <= 0)
+                       return ES_R_ERROR;
+
+               app_id[ret] = '\0';
+               ret = ES_R_OK;
+       }
+
+       return ret;
+}
+
 static int check_user_event_sender_valid(const char *event_name, const char *app_id)
 {
        char *valid_name = NULL;
@@ -1163,13 +1346,13 @@ static int check_user_event_sender_valid(const char *event_name, const char *app
        }
        len = strlen(tmp);
        if (len <= 1 || len > 128) {
-               _E("invalid length(%d) of user-defined name");
+               _E("invalid length(%d) of user-defined name", len);
                FREE_AND_NULL(temp_name);
                return ES_R_EINVAL;
        }
        *tmp = '\0';
 
-       _D("app_id(%s), len(%d)", app_id, strlen(app_id));
+       _D("app_id(%s), len(%zu)", app_id, strlen(app_id));
 
        valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1;
        valid_name = calloc(1, valid_name_len);
@@ -1202,11 +1385,11 @@ static void check_sender_valid_method_call(GDBusConnection *connection, const gc
        int event_sender_pid = 0;
        uid_t sender_uid = 0;
 
-       g_variant_get(parameters, "(is)", &event_sender_pid, &event_name);
+       g_variant_get(parameters, "(i&s)", &event_sender_pid, &event_name);
        _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name);
 
        sender_uid = (uid_t)__get_sender_uid(connection, sender);
-       if (__esd_get_appid_by_pid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
+       if (__esd_get_appid_by_pid_for_uid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
                result = ES_R_ERROR;
        } else {
                if (check_user_event_sender_valid(event_name, app_id) < 0) {
@@ -1232,12 +1415,12 @@ static void check_send_event_valid_method_call(GDBusConnection *connection, cons
        int sender_pid = 0;
        uid_t sender_uid = 0;
 
-       g_variant_get(parameters, "(s)", &event_name);
+       g_variant_get(parameters, "(&s)", &event_name);
        _D("event_name(%s)", event_name);
 
        sender_pid = __get_sender_pid(connection, sender);
        sender_uid = (uid_t)__get_sender_uid(connection, sender);
-       if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
+       if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
                result = ES_R_ERROR;
        } else {
                if (check_user_event_sender_valid(event_name, app_id) < 0) {
@@ -1271,12 +1454,12 @@ static void get_trusted_peer_method_call(GDBusConnection *connection, const gcha
        char *_busname = NULL;
        trusted_item *item;
 
-       g_variant_get(parameters, "(s)", &event_name);
+       g_variant_get(parameters, "(&s)", &event_name);
        _D("event_name(%s)", event_name);
 
        sender_pid = __get_sender_pid(connection, sender);
        sender_uid = (uid_t)__get_sender_uid(connection, sender);
-       if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
+       if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
                result = ES_R_ERROR;
        } else {
                builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
@@ -1318,13 +1501,13 @@ static void setup_trusted_peer_method_call(GDBusConnection *connection, const gc
        uid_t sender_uid = 0;
        int ret = 0;
 
-       g_variant_get(parameters, "(ss)", &event_name, &destination_name);
+       g_variant_get(parameters, "(&s&s)", &event_name, &destination_name);
        _D("event_name(%s), destination_name(%s)", event_name, destination_name);
 
        if (destination_name && destination_name[0] != '\0') {
                sender_pid = __get_sender_pid(connection, sender);
                sender_uid = (uid_t)__get_sender_uid(connection, sender);
-               if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
+               if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
                        result = ES_R_ERROR;
                } else {
                        ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name,
@@ -1361,14 +1544,14 @@ static void check_privilege_valid_method_call(GDBusConnection *connection, const
        char *user = NULL;
        int ret = 0;
 
-       g_variant_get(parameters, "(s)", &event_name);
+       g_variant_get(parameters, "(&s)", &event_name);
        __esd_check_privilege_name(event_name, &privilege_name);
        _D("event_name(%s), privilege_name(%s)", event_name, privilege_name);
 
        if (privilege_name) {
                sender_pid = __get_sender_pid(connection, sender);
                sender_uid = (uid_t)__get_sender_uid(connection, sender);
-               if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
+               if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
                        result = ES_R_ERROR;
                } else {
                        ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client);
@@ -1415,33 +1598,31 @@ out:
 static void get_earlier_data_method_call(GVariant *parameters, GDBusMethodInvocation *invocation)
 {
        GVariant *param = NULL;
-       int result = 0;
+       int result = ES_R_ERROR;
        char *event_name = NULL;
        bundle *b = NULL;
        bundle_raw *raw = NULL;
        int len = 0;
        earlier_item *item;
 
-       g_variant_get(parameters, "(s)", &event_name);
-
-       if (event_name && strlen(event_name) > 0) {
-               _D("event_name(%s)", event_name);
-               result = ES_R_OK;
-       } else {
-               _E("invalid event_name(%s)", event_name);
-               result = ES_R_ERROR;
-       }
+       g_variant_get(parameters, "(&s)", &event_name);
+       _D("event_name(%s)", event_name);
 
        item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
        if (item != NULL) {
                if (item->earlier_data) {
                        b = bundle_dup(item->earlier_data);
                        bundle_add_str(b, "is_earlier_data", "true");
-                       bundle_encode(b, &raw, &len);
-                       bundle_free(b);
+                       result = ES_R_OK;
                }
        }
 
+       if (result == ES_R_ERROR)
+               b = bundle_create();
+
+       bundle_encode(b, &raw, &len);
+       bundle_free(b);
+
        param = g_variant_new("(iis)", result, len, raw);
 
        _D("result(%d), len(%d)", result, len);
@@ -1451,6 +1632,364 @@ static void get_earlier_data_method_call(GVariant *parameters, GDBusMethodInvoca
 }
 #endif
 
+static void keep_last_data_method_call(GDBusConnection *connection,
+               const gchar *sender, GVariant *parameters,
+               GDBusMethodInvocation *invocation)
+{
+       GVariant *param;
+       int result = ES_R_OK;
+       char *event_name;
+       char *own_name;
+       char *key;
+       char app_id[128];
+       int sender_pid;
+       uid_t sender_uid;
+       struct __last_event_item *item;
+
+       g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
+
+       if (!event_name || !own_name) {
+               result = ES_R_ERROR;
+               _E("invalid event_name and own_name");
+               goto out;
+       }
+
+       sender_pid = __get_sender_pid(connection, sender);
+       sender_uid = (uid_t)__get_sender_uid(connection, sender);
+       if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id,
+                               sizeof(app_id)) < 0) {
+               _E("failed to get appid by pid");
+               result = ES_R_ERROR;
+               goto out;
+       }
+
+       key = (char *)malloc(sizeof(event_name) + 10);
+       if (!key) {
+               result = ES_R_ENOMEM;
+               _E("out of memory");
+               goto out;
+       }
+
+       snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
+       item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
+                       key);
+       if (!item) {
+               item = calloc(1, sizeof(*item));
+               if (!item) {
+                       result = ES_R_ERROR;
+                       goto out;
+               }
+               item->key = key;
+               item->event_name = strdup(event_name);
+               item->own_name = strdup(own_name);
+               item->uid = sender_uid;
+               item->app_id = strdup(app_id);
+               g_hash_table_insert(user_last_event_table,
+                               item->key, item);
+       } else {
+               free(item->own_name);
+               item->own_name = strdup(own_name);
+       }
+
+out:
+       param = g_variant_new("(i)", result);
+
+       g_dbus_method_invocation_return_value(invocation, param);
+}
+
+static void check_last_data_method_call(GDBusConnection *connection,
+               const gchar *sender, GVariant *parameters,
+               GDBusMethodInvocation *invocation)
+{
+       GVariant *param;
+       int result = ES_R_OK;
+       char *event_name;
+       char *own_name;
+       char *key;
+       char app_id[128];
+       int sender_pid;
+       uid_t sender_uid;
+       struct __last_event_item *item;
+
+       g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
+
+       if (!event_name || !own_name) {
+               result = ES_R_ERROR;
+               _E("invalid event_name and own_name");
+               goto out;
+       }
+
+       sender_pid = __get_sender_pid(connection, sender);
+       sender_uid = (uid_t)__get_sender_uid(connection, sender);
+       if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id,
+                               sizeof(app_id)) < 0) {
+               result = ES_R_ERROR;
+               _E("failed to get appid by pid");
+               goto out;
+       }
+
+       key = (char *)malloc(sizeof(event_name) + 10);
+       if (!key) {
+               result = ES_R_ENOMEM;
+               _E("out of memory");
+               goto out;
+       }
+
+       snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
+       item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
+                       key);
+       free(key);
+       if (item) {
+               GVariant *gv;
+               bundle *b;
+               bundle_raw *raw;
+               int len;
+               int ret;
+               GError *error = NULL;
+
+               b = bundle_create();
+               if (!b) {
+                       result = ES_R_ERROR;
+                       goto out;
+               }
+               bundle_add_str(b, EVT_KEY_KEPT_EVENT_NAME, event_name);
+               bundle_add_str(b, EVT_KEY_KEPT_OWN_NAME, own_name);
+               if (__esd_check_certificate_match(item->uid, item->app_id,
+                               sender_uid, app_id) == ES_R_OK)
+                       bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "true");
+               else
+                       bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "false");
+
+               bundle_encode(b, &raw, &len);
+               gv  = g_variant_new("(us)", len, raw);
+               ret = g_dbus_connection_emit_signal(connection,
+                               item->own_name,
+                               SYS_EVENT_OBJ_PATH,
+                               SYS_EVENT_NAME_PREFIX,
+                               REQUEST_LAST_DATA,
+                               gv,
+                               &error);
+               if (ret == FALSE) {
+                       _E("Unable to emit signal: %s", error->message);
+                       g_error_free(error);
+               }
+               bundle_free_encoded_rawdata(&raw);
+               bundle_free(b);
+       }
+
+out:
+       param = g_variant_new("(i)", result);
+
+       g_dbus_method_invocation_return_value(invocation, param);
+}
+
+static void launch_on_event_from_userevent(GDBusConnection *connection,
+               const gchar *sender, GVariant *parameters,
+               GDBusMethodInvocation *invocation)
+{
+       GVariant *param;
+       int result = ES_R_OK;
+       int len;
+       gboolean trusted;
+       int sender_pid;
+       uid_t sender_uid;
+       char *event_name;
+       char app_id[128];
+       char *buf;
+       bundle *b;
+
+       g_variant_get(parameters, "(&s&sib)", &event_name, &buf, &len, &trusted);
+
+       if (!event_name) {
+               result = ES_R_ERROR;
+               _E("invalid event_name");
+               goto out;
+       }
+
+       sender_pid = __get_sender_pid(connection, sender);
+       sender_uid = (uid_t)__get_sender_uid(connection, sender);
+       if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id,
+                               sizeof(app_id)) < 0) {
+               _E("failed to get appid by pid");
+               result = ES_R_ERROR;
+               goto out;
+       }
+
+       b = bundle_decode((bundle_raw *)buf, len);
+       if (b == NULL) {
+               _E("Out of memory");
+               result = ES_R_ENOMEM;
+               goto out;
+       }
+
+       __esd_launch_event_handler(event_name, b, true, trusted,
+                       sender_uid, app_id, NULL);
+
+       bundle_free(b);
+
+out:
+       param = g_variant_new("(i)", result);
+
+       g_dbus_method_invocation_return_value(invocation, param);
+}
+
+static void get_uuid_method_call(GDBusConnection *connection,
+               const gchar *sender, GVariant *parameters,
+               GDBusMethodInvocation *invocation)
+{
+       GVariant *param = NULL;
+       int result = ES_R_OK;
+       char *uuid;
+       char app_id[128] = { 0, };
+       int sender_pid;
+
+       sender_pid = __get_sender_pid(connection, sender);
+       if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
+               _E("failed to get appid by pid");
+               result = ES_R_ERROR;
+               goto out;
+       }
+
+       if (esd_cion_get_uuid_with_generate(app_id, &uuid) == 0) {
+               param = g_variant_new("(is)", result, uuid);
+               free(uuid);
+       } else {
+               result = ES_R_ERROR;
+       }
+
+out:
+       if (param == NULL)
+               param = g_variant_new("(is)", result, "");
+
+       g_dbus_method_invocation_return_value(invocation, param);
+}
+
+static void set_display_name_method_call(GDBusConnection *connection,
+               const gchar *sender, GVariant *parameters,
+               GDBusMethodInvocation *invocation)
+{
+       GVariant *param = NULL;
+       int result = ES_R_OK;
+       char app_id[128] = { 0, };
+       int sender_pid;
+       char *display_name = NULL;
+       char *service_name = NULL;
+
+       sender_pid = __get_sender_pid(connection, sender);
+       if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
+               _E("failed to get appid by pid");
+               result = ES_R_ERROR;
+               goto out;
+       }
+
+       g_variant_get(parameters, "(&s&s)", &service_name, &display_name);
+
+       if (esd_cion_set_display_name(app_id, service_name, display_name) != 0)
+               result = ES_R_ERROR;
+
+out:
+       param = g_variant_new("(i)", result);
+       g_dbus_method_invocation_return_value(invocation, param);
+}
+
+static void get_display_name_method_call(GDBusConnection *connection,
+               const gchar *sender, GVariant *parameters,
+               GDBusMethodInvocation *invocation)
+{
+       GVariant *param = NULL;
+       int result = ES_R_OK;
+       char app_id[128] = { 0, };
+       int sender_pid;
+       char *service_name = NULL;
+       char *display_name = NULL;
+
+       sender_pid = __get_sender_pid(connection, sender);
+       if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
+               _E("failed to get appid by pid");
+               result = ES_R_ERROR;
+               goto out;
+       }
+
+       g_variant_get(parameters, "(&s)", &service_name);
+
+       if (esd_cion_get_display_name(app_id, service_name, &display_name) == 0) {
+               if (display_name != NULL) {
+                       param = g_variant_new("(is)", result, display_name);
+                       free(display_name);
+               } else {
+                       goto out;
+               }
+       } else {
+               result = ES_R_ERROR;
+       }
+
+out:
+       if (param == NULL)
+               param = g_variant_new("(is)", result, "");
+
+       g_dbus_method_invocation_return_value(invocation, param);
+}
+
+static void set_enabled_method_call(GDBusConnection *connection,
+               const gchar *sender, GVariant *parameters,
+               GDBusMethodInvocation *invocation)
+{
+       GVariant *param = NULL;
+       int result = ES_R_OK;
+       char app_id[128] = { 0, };
+       int sender_pid;
+       gboolean enabled;
+       char *service_name = NULL;
+
+       sender_pid = __get_sender_pid(connection, sender);
+       if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
+               _E("failed to get appid by pid");
+               result = ES_R_ERROR;
+               goto out;
+       }
+
+       g_variant_get(parameters, "(&sb)", &service_name, &enabled);
+
+       if (esd_cion_set_enabled(app_id, service_name, (bool)enabled) != 0)
+               result = ES_R_ERROR;
+
+out:
+       param = g_variant_new("(i)", result);
+       g_dbus_method_invocation_return_value(invocation, param);
+}
+
+static void get_enabled_method_call(GDBusConnection *connection,
+               const gchar *sender, GVariant *parameters,
+               GDBusMethodInvocation *invocation)
+{
+       GVariant *param = NULL;
+       int result = ES_R_OK;
+       char app_id[128] = { 0, };
+       int sender_pid;
+       char *service_name = NULL;
+       int enabled;
+
+       sender_pid = __get_sender_pid(connection, sender);
+       if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
+               _E("failed to get appid by pid");
+               result = ES_R_ERROR;
+               goto out;
+       }
+
+       g_variant_get(parameters, "(&s)", &service_name);
+
+       if (esd_cion_get_enabled(app_id, service_name, &enabled) == 0)
+               param = g_variant_new("(ib)", result, (bool)enabled);
+       else
+               result = ES_R_ERROR;
+
+out:
+       if (param == NULL)
+               param = g_variant_new("(ib)", result, false);
+
+       g_dbus_method_invocation_return_value(invocation, param);
+}
+
 static void handle_method_call(GDBusConnection *connection,
        const gchar *sender, const gchar *object_path,
        const gchar *interface_name, const gchar *method_name,
@@ -1471,6 +2010,22 @@ static void handle_method_call(GDBusConnection *connection,
        } else if (g_strcmp0(method_name, "GetEarlierData") == 0) {
                get_earlier_data_method_call(parameters, invocation);
 #endif
+       } else if (g_strcmp0(method_name, "KeepLastData") == 0) {
+               keep_last_data_method_call(connection, sender, parameters, invocation);
+       } else if (g_strcmp0(method_name, "CheckLastData") == 0) {
+               check_last_data_method_call(connection, sender, parameters, invocation);
+       } else if (g_strcmp0(method_name, "LaunchOnEventFromUserEvent") == 0) {
+               launch_on_event_from_userevent(connection, sender, parameters, invocation);
+       } else if (g_strcmp0(method_name, "CionGetUuid") == 0) {
+               get_uuid_method_call(connection, sender, parameters, invocation);
+       } else if (g_strcmp0(method_name, "CionSetDisplayName") == 0) {
+               set_display_name_method_call(connection, sender, parameters, invocation);
+       } else if (g_strcmp0(method_name, "CionGetDisplayName") == 0) {
+               get_display_name_method_call(connection, sender, parameters, invocation);
+       } else if (g_strcmp0(method_name, "CionSetEnabled") == 0) {
+               set_enabled_method_call(connection, sender, parameters, invocation);
+       } else if (g_strcmp0(method_name, "CionGetEnabled") == 0) {
+               get_enabled_method_call(connection, sender, parameters, invocation);
        }
 }
 
@@ -1486,6 +2041,8 @@ static void __esd_on_bus_acquired(GDBusConnection *connection,
        _I("bus acquired(%s)", name);
 
        guint reg_id = 0;
+       guint boot_id = 0;
+       guint user_boot_id = 0;
        GError *error = NULL;
 
        reg_id = g_dbus_connection_register_object(connection,
@@ -1497,6 +2054,34 @@ static void __esd_on_bus_acquired(GDBusConnection *connection,
                _E("g_dbus_connection_register_object error(%s)", error->message);
                g_error_free(error);
        }
+
+       boot_id = g_dbus_connection_signal_subscribe(connection,
+                       NULL,
+                       SYSTEMD_DBUS_IFACE_MANAGER,
+                       SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED,
+                       SYSTEMD_DBUS_PATH,
+                       NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       __esd_signal_handler,
+                       NULL,
+                       NULL);
+
+       if (boot_id == 0)
+               _E("g_dbus_connection_signal_subscribe() is failed.");
+
+       user_boot_id = g_dbus_connection_signal_subscribe(connection,
+                       NULL,
+                       SYSTEMD_DBUS_IFACE_MANAGER,
+                       SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED,
+                       SYSTEMD_DBUS_PATH,
+                       NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       __esd_signal_handler,
+                       NULL,
+                       NULL);
+
+       if (user_boot_id == 0)
+               _E("g_dbus_connection_signal_subscribe() is failed.");
 }
 
 static void __esd_on_name_acquired(GDBusConnection *connection,
@@ -1504,8 +2089,6 @@ static void __esd_on_name_acquired(GDBusConnection *connection,
 {
        bundle *b;
 
-       _I("name acquired(%s)", name);
-
        __esd_check_trusted_events(connection, "ListNames");
        __esd_check_trusted_events(connection, "ListActivatableNames");
 
@@ -1518,7 +2101,7 @@ static void __esd_on_name_acquired(GDBusConnection *connection,
 
        __esd_trusted_busname_print_items();
 
-       __esd_start_sd_monitor();
+       __esd_get_user_items(DEFAULT_USER);
 
        __esd_dbus_name_monitor(connection);
 }
@@ -1526,7 +2109,6 @@ static void __esd_on_name_acquired(GDBusConnection *connection,
 static void __esd_on_name_lost(GDBusConnection *connection,
                const gchar *name, gpointer user_data)
 {
-       _E("name lost(%s)", name);
 }
 
 static int __esd_before_loop(void)
@@ -1548,6 +2130,8 @@ static int __esd_before_loop(void)
        earlier_item *item;
 
        earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal);
+       user_last_event_table = g_hash_table_new_full(g_str_hash,
+                       g_str_equal, NULL, (GDestroyNotify)free_saved_event);
 
        _I("register events for earlier_data");
        size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
@@ -1702,7 +2286,6 @@ static int __esd_appcontrol_cb(const char *operation,
        char *appid = NULL;
        char *pkgid = NULL;
        char *event_name = NULL;
-       const char *prefix = "event://";
        uid_t uid = 0;
 
        if (cb_data == NULL) {
@@ -1717,25 +2300,33 @@ static int __esd_appcontrol_cb(const char *operation,
                uid, appid, pkgid, operation, uri, mime);
 
        if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) {
-               if (!strncmp(uri, prefix, strlen(prefix))) {
+               if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX, strlen(SYSTEM_EVENT_NAME_PREFIX))) {
                        event_name = strdup(&uri[8]);
                        if (event_name) {
                                _D("appid(%s), event_name(%s)", appid, event_name);
-                               if (!__esd_check_event_launch_support(event_name)) {
+                               if (!__esd_check_event_launch_support(event_name))
                                        _E("failed to add item (not support event)");
-                               } else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name)) {
+                               else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name))
                                        _E("failed to add item (no privilege)");
-                               } else {
+                               else if (__esd_add_launch_item(uid, event_name, appid, pkgid))
+                                       _E("failed to add item");
+
+                       } else {
+                               _E("out of memory");
+                       }
+               } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX, strlen(USER_EVENT_NAME_PREFIX))) {
+                       event_name = strdup(uri);
+                       if (event_name) {
+                               _D("appid(%s), event_name(%s)", appid, event_name);
+                               if (__esd_check_platform_cert(pkgid, uid)) {
                                        if (__esd_add_launch_item(uid, event_name, appid, pkgid))
                                                _E("failed to add item");
                                }
-                               FREE_AND_NULL(event_name);
                        } else {
                                _E("out of memory");
                        }
-               } else {
-                       _E("Invalid uri(%s) for event_name", uri);
                }
+               FREE_AND_NULL(event_name);
        }
 
        return 0;
@@ -1745,7 +2336,6 @@ static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *da
 {
        char *appid = NULL;
        char *pkgid = NULL;
-       pkgmgrinfo_app_component component_type;
        int ret = 0;
        uid_t *p_uid = NULL;
 
@@ -1756,65 +2346,57 @@ static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *da
 
        p_uid = (uid_t *)data;
 
-       ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+       ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
        if (ret < 0) {
                _E("failed to get appid");
                return ES_R_ERROR;
        }
 
-       ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
+       ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
        if (ret < 0) {
-               _E("failed to get pkgid");
+               _E("failed to get appid");
                return ES_R_ERROR;
        }
 
-       ret = pkgmgrinfo_appinfo_get_component(handle, &component_type);
-       if (ret != PMINFO_R_OK) {
-               _E("fail to get component type");
-               return ES_R_ERROR;
-       }
+       esd_appctrl_cb_data *cb_data = calloc(1, sizeof(esd_appctrl_cb_data));
 
-       _D("uid(%d), appid(%s), component_type(%d)", *p_uid, appid, component_type);
-       if (component_type == PMINFO_SVC_APP) {
-               esd_appctrl_cb_data *cb_data = calloc(1, sizeof(esd_appctrl_cb_data));
-               if (cb_data == NULL) {
-                       _E("memory alloc failed");
-                       return ES_R_ENOMEM;
-               }
-               cb_data->appid = strdup(appid);
-               if (cb_data->appid == NULL) {
-                       _E("out_of_memory");
-                       FREE_AND_NULL(cb_data);
-                       return ES_R_ENOMEM;
-               }
-               cb_data->pkgid = strdup(pkgid);
-               if (cb_data->pkgid == NULL) {
-                       _E("out_of_memory");
-                       FREE_AND_NULL(cb_data->appid);
-                       FREE_AND_NULL(cb_data);
-                       return ES_R_ENOMEM;
-               }
-               cb_data->uid = *p_uid;
-               ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
-                       (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data);
-
-               FREE_AND_NULL(cb_data->pkgid);
+       if (cb_data == NULL) {
+               _E("memory alloc failed");
+               return ES_R_ENOMEM;
+       }
+       cb_data->appid = strdup(appid);
+       if (cb_data->appid == NULL) {
+               _E("out_of_memory");
+               FREE_AND_NULL(cb_data);
+               return ES_R_ENOMEM;
+       }
+       cb_data->pkgid = strdup(pkgid);
+       if (cb_data->pkgid == NULL) {
+               _E("out_of_memory");
                FREE_AND_NULL(cb_data->appid);
                FREE_AND_NULL(cb_data);
+               return ES_R_ENOMEM;
+       }
+       cb_data->uid = *p_uid;
 
-               if (ret < 0) {
-                       _E("failed to get appcontrol info");
-                       return ES_R_ERROR;
-               }
-               __esd_launch_table_print_items();
+       ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
+               (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data);
+
+       FREE_AND_NULL(cb_data->pkgid);
+       FREE_AND_NULL(cb_data->appid);
+       FREE_AND_NULL(cb_data);
+
+       if (ret < 0) {
+               _E("failed to get appcontrol info");
+               return ES_R_ERROR;
        }
 
        return ES_R_OK;
 }
 
-static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id, const char *pkg_type,
-               const char *pkgid, const char *key, const char *val,
-               const void *pmsg, void *data)
+static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id,
+               const char *pkg_type, const char *pkgid, const char *key,
+               const char *val, const void *pmsg, void *data)
 {
        esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data;
        pkgmgrinfo_pkginfo_h handle = NULL;
@@ -1847,9 +2429,10 @@ static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id, const char
                                return 0;
                        }
                        ret = pkgmgrinfo_appinfo_get_usr_list(handle,
-                               PMINFO_ALL_APP, __esd_add_appinfo_handler, &target_uid, target_uid);
+                               PMINFO_SVC_APP, __esd_add_appinfo_handler, &target_uid, target_uid);
                        if (ret < 0) {
                                _E("failed to get appinfo");
+                               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
                                __esd_pkgmgr_event_free(pkg_event);
                                return 0;
                        }
@@ -1886,13 +2469,12 @@ static int __esd_init()
 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
        g_type_init();
 #endif
-       ecore_init();
-
        __esd_init_cynara();
 
        client = pkgmgr_client_new(PC_LISTENING);
        if (client == NULL) {
                _E("set pkgmgr client failed");
+               __esd_finish_cynara();
                return ES_R_ERROR;
        }
 
@@ -1902,7 +2484,7 @@ static int __esd_init()
                ret = pkgmgr_client_free(client);
                if (ret != PKGMGR_R_OK)
                        _E("pkgmgr_client_free failed(%d)", ret);
-
+               __esd_finish_cynara();
                return ES_R_ENOMEM;
        }
 
@@ -1912,7 +2494,8 @@ static int __esd_init()
                ret = pkgmgr_client_free(client);
                if (ret != PKGMGR_R_OK)
                        _E("pkgmgr_client_free failed(%d)", ret);
-
+               free(pkg_event);
+               __esd_finish_cynara();
                return ES_R_ERROR;
        }
 
@@ -1945,8 +2528,6 @@ static void __esd_finalize(void)
 
        _D("esd finalize");
 
-       __esd_stop_sd_monitor();
-
        if (trusted_busname_table) {
                g_hash_table_iter_init(&iter, trusted_busname_table);
                while (g_hash_table_iter_next(&iter, &key, &value)) {
@@ -1980,6 +2561,8 @@ static void __esd_finalize(void)
                }
                g_hash_table_unref(earlier_event_table);
        }
+
+       g_hash_table_destroy(user_last_event_table);
 #endif
 
        if (event_launch_table) {
@@ -2017,26 +2600,41 @@ static void __esd_finalize(void)
 
 int main(int argc, char *argv[])
 {
+       GMainLoop *mainloop;
        _I("event system daemon : main()");
 
+       mainloop = g_main_loop_new(NULL, FALSE);
+       if (mainloop == NULL) {
+               _E("out of memory");
+               return ES_R_ERROR;
+       }
+
        if (__esd_init() != 0) {
                _E("ESD Initialization failed!");
+               g_main_loop_unref(mainloop);
                return ES_R_ERROR;
        }
 
+       if (_esd_cion_init() != 0)
+               _E("ESD Cion Initialization failed!");
+
        if (__esd_before_loop() < 0) {
                _E("ESD failed!");
                __esd_finalize();
+               g_main_loop_unref(mainloop);
                return ES_R_ERROR;
        }
 
-       ecore_main_loop_begin();
+       if (esd_cion_db_init() < 0)
+               _E("db init failed!");
+
+       g_main_loop_run(mainloop);
 
        _E("shutdown");
 
        __esd_finalize();
 
-       ecore_shutdown();
+       g_main_loop_unref(mainloop);
 
        return 0;
 }