Fix wrong declaration of the earlier_item pointer type
[platform/core/appfw/event-system.git] / src / esd_main.c
1 #include <stdio.h>
2 #include <glib.h>
3 #include <aul.h>
4 #include <unistd.h>
5 #include <ctype.h>
6 #include <dlog.h>
7 #include <Ecore.h>
8 #include <gio/gio.h>
9 #include <assert.h>
10 #include <package-manager.h>
11 #include <pkgmgr-info.h>
12 #include <appsvc/appsvc.h>
13 #include <eventsystem.h>
14 #include <bundle_internal.h>
15 #include <fcntl.h>
16 #include <vconf.h>
17 #include <tzplatform_config.h>
18 #include <systemd/sd-login.h>
19 #include <cynara-client.h>
20 #include <cynara-creds-gdbus.h>
21 #include <cynara-session.h>
22 #include "eventsystem_daemon.h"
23
24 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
25 #define ROOT_USER 0
26
27 static GHashTable *event_launch_table; /* table of events for launch_on_event*/
28
29 static const char *event_launch_support_list[] = {
30         SYS_EVENT_BATTERY_CHARGER_STATUS,
31         SYS_EVENT_USB_STATUS,
32         SYS_EVENT_EARJACK_STATUS,
33         SYS_EVENT_INCOMMING_MSG
34 };
35
36 struct privilege_info {
37         const char *event_name;
38         const char *privilege_name;
39 };
40
41 static const struct privilege_info privilege_check_list[] = {
42         {SYS_EVENT_DISPLAY_STATE, "http://tizen.org/privilege/display"},
43         {SYS_EVENT_WIFI_STATE, "http://tizen.org/privilege/network.get"},
44         {SYS_EVENT_INCOMMING_MSG, "http://tizen.org/privilege/message.read"}
45 };
46
47 typedef struct __esd_privilege_check {
48         char *privilege_name;
49         int validation;
50 } esd_privilege_check;
51
52 static int privilege_check_size = sizeof(privilege_check_list)/sizeof(struct privilege_info);
53
54 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
55 static const char *earlier_event_list[] = {
56         SYS_EVENT_ESD_STATUS,
57         SYS_EVENT_LOW_MEMORY,
58         SYS_EVENT_BOOT_COMPLETED,
59         SYS_EVENT_SYSTEM_SHUTDOWN,
60         SYS_EVENT_BATTERY_CHARGER_STATUS
61 };
62
63 static GHashTable *earlier_event_table; /* table of events for earlier_data */
64
65 typedef struct __earlier_table_item {
66         char *event_name;
67         guint reg_id;
68         bundle *earlier_data; /* event-data from earlier occurrence */
69 } earlier_item;
70
71 static bool g_is_bootcompleted = false;
72 #endif
73
74 static GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */
75
76 typedef struct __trusted_busname_item {
77         char *app_id;
78         char *bus_name;
79         int pid;
80         uid_t uid;
81 } trusted_item;
82
83 typedef struct __eventlaunch_item_param {
84         char *app_id;
85 } eventlaunch_item_param_s;
86
87 typedef struct esd_list_item {
88         char *pkg_id;
89         char *app_id;
90         uid_t uid;
91 } esd_list_item_s;
92
93 typedef struct  __event_launch_table_item {
94         char *event_name;
95         char *package_name; /* just for passing pointer to app-list removal func */
96         GList *app_list_evtlaunch; /* app-list for on-event-launch */
97         guint reg_id;
98         uid_t uid;
99 } event_launch_item;
100
101 enum __pkg_event_type {
102         UNKNOWN = 0,
103         INSTALL,
104         UNINSTALL,
105         UPDATE,
106 };
107
108 typedef struct __pkgmgr_event {
109         int type;
110         char *pkgid;
111 } esd_pkgmgr_event;
112
113 typedef struct __esd_event_param {
114         char *event_name;
115         bundle *event_data;
116         void *user_data;
117 } esd_event_param;
118
119 typedef struct esd_info {
120         pkgmgr_client *client;
121 } esd_info_s;
122 static esd_info_s s_info;
123
124 static Ecore_Fd_Handler *g_fd_handler;
125 sd_login_monitor *g_sd_monitor;
126
127 typedef struct __esd_appctrl_cb_data {
128         char *appid;
129         char *pkgid;
130         uid_t uid;
131 } esd_appctrl_cb_data;
132
133 static void __esd_event_handler(char *event_name, bundle *data, void *user_data);
134 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data);
135
136 static cynara *r_cynara = NULL;
137
138 static int __esd_init_cynara(void)
139 {
140         int ret;
141
142         ret  = cynara_initialize(&r_cynara, NULL);
143         if (ret != CYNARA_API_SUCCESS) {
144                 _E("cynara initialize failed.");
145                 return ret;
146         }
147
148         return 0;
149 }
150
151 static void __esd_finish_cynara(void)
152 {
153         if (r_cynara)
154                 cynara_finish(r_cynara);
155         r_cynara = NULL;
156 }
157
158 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
159 static int __esd_check_earlier_support(const char *event_name)
160 {
161         int i = 0;
162         int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
163
164         for (i = 0; i < size; i++) {
165                 if (strcmp(earlier_event_list[i], event_name) == 0)
166                         return true;
167         }
168
169         return false;
170 }
171 #endif
172
173 static int __esd_check_event_launch_support(const char *event_name)
174 {
175         int i = 0;
176         int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list);
177
178         for (i = 0; i < size; i++) {
179                 if (strcmp(event_launch_support_list[i], event_name) == 0)
180                         return true;
181         }
182
183         return false;
184 }
185
186 static uid_t __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type)
187 {
188         GDBusMessage *msg = NULL;
189         GDBusMessage *reply = NULL;
190         GError *err = NULL;
191         GVariant *body;
192         int value = -1;
193
194         msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
195                 "org.freedesktop.DBus", type);
196         if (!msg) {
197                 _E("Can't allocate new method call");
198                 goto out;
199         }
200
201         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
202         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
203                 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
204
205         if (!reply) {
206                 if (err != NULL) {
207                         _E("Failed to get info [%s]", err->message);
208                         g_error_free(err);
209                 }
210                 goto out;
211         }
212
213         body = g_dbus_message_get_body(reply);
214         g_variant_get(body, "(u)", &value);
215
216 out:
217         if (msg)
218                 g_object_unref(msg);
219         if (reply)
220                 g_object_unref(reply);
221
222         return (uid_t)value;
223 }
224
225 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
226 {
227         int pid = 0;
228
229         pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID");
230         if (pid < 0) {
231                 _E("failed to get pid");
232                 pid = 0;
233         }
234
235         _D("sender_name(%s), pid(%d)", sender_name, pid);
236
237         return pid;
238 }
239
240 static uid_t __get_sender_uid(GDBusConnection *conn, const char *sender_name)
241 {
242         uid_t uid = -1;
243
244         uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser");
245         if (uid < 0)
246                 _E("failed to get uid");
247
248         _D("sender_name(%s), uid(%d)", sender_name, uid);
249
250         return uid;
251 }
252
253 static int __esd_check_certificate_match(uid_t uid, const char *app_id, uid_t from_uid, const char *from_appid)
254 {
255         pkgmgrinfo_cert_compare_result_type_e res;
256         int ret = 0;
257
258         _D("uid(%d), app_id(%s), from_uid(%d), from_appid(%s)", uid, app_id, from_uid, from_appid);
259
260         if (uid != from_uid) {
261                 /* TODO(jongmyeong.ko): check cert result if uids are not same */
262                 _D("not same uid");
263         }
264
265         ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, from_appid, uid, &res);
266         if (ret < 0) {
267                 _E("failed to check certificate");
268                 return ES_R_ERROR;
269         }
270
271         if (res != PMINFO_CERT_COMPARE_MATCH) {
272                 _D("certificat not match (%s)", app_id);
273                 return ES_R_EINVAL;
274         }
275
276         return ES_R_OK;
277 }
278
279 static bool __esd_check_application_validation(uid_t uid, const char *appid)
280 {
281         int ret = 0;
282         pkgmgrinfo_appinfo_h handle;
283
284         ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle);
285         if (ret != PMINFO_R_OK)
286                 return false;
287
288         pkgmgrinfo_appinfo_destroy_appinfo(handle);
289
290         /* FIXME(jongmyeong.ko) */
291         /*
292         if (!aul_app_is_running(appid))
293                 return false;
294         */
295
296         return true;
297 }
298
299 static void __esd_trusted_busname_print_items(void)
300 {
301         GHashTableIter iter;
302         gpointer key;
303         gpointer value;
304
305         g_hash_table_iter_init(&iter, trusted_busname_table);
306
307         while (g_hash_table_iter_next(&iter, &key, &value)) {
308                 trusted_item *item = (trusted_item *)value;
309                 if (item)
310                         _D("uid(%d), appid(%s), pid(%d), busname(%s)", item->uid, item->app_id, item->pid, item->bus_name);
311         }
312 }
313
314 static int __esd_trusted_busname_add_item(uid_t uid, const char *appid, const char *busname, int pid)
315 {
316         char *app_id = NULL;
317         char *bus_name = NULL;
318         trusted_item *item = NULL;
319         trusted_item *new_item;
320
321         app_id = strdup(appid);
322         if (app_id == NULL) {
323                 _E("out of memory");
324                 return ES_R_ENOMEM;
325         }
326
327         bus_name = strdup(busname);
328         if (bus_name == NULL) {
329                 _E("out of memory");
330                 FREE_AND_NULL(app_id);
331                 return ES_R_ENOMEM;
332         }
333
334         item = (trusted_item *)g_hash_table_lookup(trusted_busname_table, app_id);
335
336         if (item && item->bus_name && strcmp(item->bus_name, bus_name) == 0 &&
337                 (item->uid == uid)) {
338                 _D("already exist (%s, %s)", app_id, bus_name);
339                 FREE_AND_NULL(app_id);
340                 FREE_AND_NULL(bus_name);
341         } else {
342                 new_item = calloc(1, sizeof(trusted_item));
343                 if (new_item == NULL) {
344                         _E("memory alloc failed");
345                         FREE_AND_NULL(app_id);
346                         FREE_AND_NULL(bus_name);
347                         return ES_R_ENOMEM;
348                 }
349                 new_item->uid = uid;
350                 new_item->app_id = app_id;
351                 new_item->bus_name = bus_name;
352                 new_item->pid = pid;
353                 g_hash_table_insert(trusted_busname_table, new_item->app_id, new_item);
354                 _D("added busname(%s)", new_item->bus_name);
355         }
356
357         return ES_R_OK;
358 }
359
360 static int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name)
361 {
362         GVariant *result;
363         GError *error = NULL;
364         GVariantIter *iter;
365         gchar *str;
366         char tmp_appid[128] = {0, };
367         int pid = 0;
368         uid_t uid = 0;
369         int ret = 0;
370
371         result = g_dbus_connection_call_sync(conn,
372                 "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
373                 list_name, NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE,
374                 -1, NULL, &error);
375
376         if (result == NULL) {
377                 _E("get (%s) error(%s)", list_name, error->message);
378                 g_error_free(error);
379                 return ES_R_ERROR;
380         }
381
382         g_variant_get(result, "(as)", &iter);
383         while (g_variant_iter_loop(iter, "s", &str)) {
384                 if (!strstr((const char *)str, "event.busname.session"))
385                         continue;
386
387                 _D("list(%s), name(%s)", list_name, str);
388                 pid = __get_sender_pid(conn, (const char *)str);
389                 if (pid <= 0) {
390                         _E("failed to get pid(%d)", pid);
391                         continue;
392                 }
393
394                 uid = __get_sender_uid(conn, (const char *)str);
395                 if (uid < 0) {
396                         _E("failed to get uid(%d)", uid);
397                         continue;
398                 }
399                 _D("uid(%d)", uid);
400
401                 memset(tmp_appid, 0, sizeof(tmp_appid));
402                 ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), uid);
403                 if (ret != AUL_R_OK) {
404                         _E("failed to get appid by pid(%d)", pid);
405                         continue;
406                 }
407
408                 _D("appid(%s)", tmp_appid);
409                 if (__esd_check_application_validation(uid, tmp_appid)) {
410                         _D("add to table");
411                         ret = __esd_trusted_busname_add_item(uid, tmp_appid, (const char *)str, pid);
412                         if (ret < 0)
413                                 _E("failed to add item");
414                 }
415         }
416         g_variant_iter_free(iter);
417         g_variant_unref(result);
418
419         return ES_R_OK;
420 }
421
422 static int __esd_check_privilege_name(const char *event_name, char **privilege_name)
423 {
424         int i = 0;
425
426         *privilege_name = NULL;
427
428         for (i = 0; i < privilege_check_size; i++) {
429                 if (strcmp(event_name, privilege_check_list[i].event_name) == 0) {
430                         *privilege_name = (char *)privilege_check_list[i].privilege_name;
431                         _D("[%d] privilege_name(%s)", i, *privilege_name);
432                         break;
433                 }
434         }
435
436         return ES_R_OK;
437 }
438
439 static bool __esd_check_valid_privilege_by_cynara(const char *appid, const char *client,
440         const char *session, const char *user, const char *privilege_name)
441 {
442         int ret = 0;
443         bool has_privilege = false;
444
445         _D("check privilege, (%s, %s, %s, %s, %s)", appid, client, session, user, privilege_name);
446
447         ret = cynara_check(r_cynara, client, session, user, privilege_name);
448         if (ret == CYNARA_API_ACCESS_ALLOWED) {
449                 _D("valid privilege");
450                 has_privilege = true;
451         } else if (ret == CYNARA_API_ACCESS_DENIED) {
452                 _E("invalid privilege");
453         } else {
454                 _E("failed to check privilege, error(%d)", ret);
455         }
456
457         return has_privilege;
458 }
459
460 #if 0
461 static int __esd_privilege_func(const char *name, void *user_data)
462 {
463         esd_privilege_check *epc = (esd_privilege_check *)user_data;
464
465         if (strcmp(name, epc->privilege_name) == 0) {
466                 epc->validation = 1;
467                 return -1;
468         } else {
469                 epc->validation = 0;
470                 return 0;
471         }
472 }
473 #endif
474
475 static int __esd_check_app_privileged_event(uid_t uid, const char *appid, const char *pkgid, const char *event_name)
476 {
477         char *privilege_name = NULL;
478         char client[256] = {0, };
479         char *user = NULL;
480         int retval = 1;
481
482         _D("event_name(%s), uid(%d), appid(%s), pkgid(%s)", event_name, uid, appid, pkgid);
483
484         __esd_check_privilege_name(event_name, &privilege_name);
485
486         if (privilege_name) {
487                 /* TODO(jongmyeong.ko): getting client should be replaced by cynara api */
488                 snprintf(client, 256, "User::App::%s", pkgid);
489                 user = (char *)g_strdup_printf("%u", uid);
490                 if (!__esd_check_valid_privilege_by_cynara(appid, client, "", user, privilege_name)) {
491                         _E("app(%s) has NOT privilege(%s)", appid, privilege_name);
492                         retval = 0;
493                 }
494         }
495
496         return retval;
497 }
498
499 static void __esd_print_appid_with_eventid(gpointer data, gpointer user_data)
500 {
501         esd_list_item_s *item = (esd_list_item_s *)data;
502         char *event_name = (char *)user_data;
503
504         _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name, item->uid, item->app_id, item->pkg_id);
505 }
506
507 static void __esd_print_interested_event(gpointer data, gpointer user_data)
508 {
509         event_launch_item *el_item = (event_launch_item *)data;
510         char *event_name = (char *)el_item->event_name;
511         _D("event_name = (%s)", event_name);
512         g_list_foreach(el_item->app_list_evtlaunch, __esd_print_appid_with_eventid, event_name);
513 }
514
515 static void __esd_launch_table_print_items(void)
516 {
517         GHashTableIter iter;
518         gpointer key;
519         gpointer value;
520
521         g_hash_table_iter_init(&iter, event_launch_table);
522
523         while (g_hash_table_iter_next(&iter, &key, &value))
524                 __esd_print_interested_event(value, NULL);
525 }
526
527 static int __esd_find_compare_by_list_item(gconstpointer data, gconstpointer user_data)
528 {
529         esd_list_item_s *item_1 = (esd_list_item_s *)user_data;
530         esd_list_item_s *item_2 = (esd_list_item_s *)data;
531
532         return (item_1->uid != item_2->uid) |
533                 strcmp(item_1->app_id, item_2->app_id) |
534                 strcmp(item_1->pkg_id, item_2->pkg_id);
535 }
536
537 static int __esd_add_list_item(uid_t uid, event_launch_item *el_item,
538                 const char *app_id, const char *pkg_id)
539 {
540         esd_list_item_s *item_of_list = NULL;
541
542         item_of_list = calloc(1, sizeof(esd_list_item_s));
543         if (item_of_list == NULL) {
544                 _E("out_of_memory");
545                 return ES_R_ENOMEM;
546         }
547         item_of_list->uid = uid;
548         item_of_list->app_id = (char *)app_id;
549         item_of_list->pkg_id = (char *)pkg_id;
550         el_item->app_list_evtlaunch =
551                 g_list_append(el_item->app_list_evtlaunch, item_of_list);
552
553         return ES_R_OK;
554 }
555
556 static int __esd_add_launch_item(uid_t uid, const char *event_name, const char *appid, const char *pkgid)
557 {
558         GList *app_list = NULL;
559         guint subscription_id = 0;
560         char *app_id = NULL;
561         char *pkg_id = NULL;
562         esd_list_item_s *item_of_list = NULL;
563         event_launch_item *eli;
564         event_launch_item *el_item =
565                 (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
566
567         if (el_item) {
568                 item_of_list = calloc(1, sizeof(esd_list_item_s));
569                 if (item_of_list == NULL) {
570                         _E("memory alloc failed");
571                         return ES_R_ENOMEM;
572                 }
573                 item_of_list->uid = uid;
574                 item_of_list->app_id = (char *)appid;
575                 item_of_list->pkg_id = (char *)pkgid;
576
577                 app_list = g_list_find_custom(el_item->app_list_evtlaunch,
578                         item_of_list, (GCompareFunc)__esd_find_compare_by_list_item);
579                 free(item_of_list);
580                 if (app_list == NULL) {
581                         _D("add new item (list item only)");
582                         app_id = strdup((char *)appid);
583                         if (!app_id) {
584                                 _E("out_of_memory");
585                                 return ES_R_ENOMEM;
586                         }
587                         pkg_id = strdup((char *)pkgid);
588                         if (!pkg_id) {
589                                 _E("out_of_memory");
590                                 FREE_AND_NULL(app_id);
591                                 return ES_R_ENOMEM;
592                         }
593                         if (__esd_add_list_item(uid, el_item, app_id, pkg_id) < 0) {
594                                 _E("failed to add list item");
595                                 FREE_AND_NULL(app_id);
596                                 FREE_AND_NULL(pkg_id);
597                                 return ES_R_ERROR;
598                         }
599                 }
600         } else {
601                 _D("add new item (all)");
602                 eli = calloc(1, sizeof(event_launch_item));
603                 if (!eli) {
604                         _E("memory alloc failed");
605                         return ES_R_ENOMEM;
606                 }
607
608                 eli->event_name = strdup(event_name);
609                 if (!eli->event_name) {
610                         _E("out_of_memory");
611                         FREE_AND_NULL(eli);
612                         return ES_R_ENOMEM;
613                 }
614
615                 app_id = strdup((char *)appid);
616                 if (!app_id) {
617                         _E("out_of_memory");
618                         FREE_AND_NULL(eli->event_name);
619                         FREE_AND_NULL(eli);
620                         return ES_R_ENOMEM;
621                 }
622
623                 pkg_id = strdup((char *)pkgid);
624                 if (!pkg_id) {
625                         _E("out_of_memory");
626                         FREE_AND_NULL(app_id);
627                         FREE_AND_NULL(eli->event_name);
628                         FREE_AND_NULL(eli);
629                         return ES_R_ENOMEM;
630                 }
631
632                 if (__esd_add_list_item(uid, eli, app_id, pkg_id) < 0) {
633                         _E("failed to add list item");
634                         FREE_AND_NULL(app_id);
635                         FREE_AND_NULL(pkg_id);
636                         FREE_AND_NULL(eli->event_name);
637                         FREE_AND_NULL(eli);
638                         return ES_R_ERROR;
639                 }
640
641                 g_hash_table_insert(event_launch_table, eli->event_name, eli);
642
643                 eventsystem_register_event(eli->event_name, &subscription_id,
644                         (eventsystem_handler)__esd_event_handler, NULL);
645                 if (subscription_id == 0) {
646                         _E("signal subscription error, event_name(%s), app_id(%s)",
647                                 eli->event_name, app_id);
648                         return ES_R_ERROR;
649                 } else {
650                         eli->reg_id = subscription_id;
651                 }
652         }
653
654         return ES_R_OK;
655 }
656
657 static void __esd_remove_all_private_usr_app_list(gpointer data, gpointer user_data)
658 {
659         esd_list_item_s *item = (esd_list_item_s *)data;
660         event_launch_item *eli = (event_launch_item *)user_data;
661
662         if (item->uid != GLOBAL_USER && !strcmp(eli->package_name, item->pkg_id)) {
663                 _D("uid(%d), app_id(%s), pkg_id(%s)", item->uid, item->app_id, eli->package_name);
664                 eli->app_list_evtlaunch = g_list_remove_all(eli->app_list_evtlaunch, data);
665         }
666 }
667
668 static int __esd_launch_table_remove_private_usr_items(void)
669 {
670         GHashTableIter iter;
671         gpointer key;
672         gpointer value;
673         event_launch_item *eli = NULL;
674         GList *first_list = NULL;
675
676         g_hash_table_iter_init(&iter, event_launch_table);
677
678         while (g_hash_table_iter_next(&iter, &key, &value)) {
679                 eli = (event_launch_item *)value;
680                 g_list_foreach(eli->app_list_evtlaunch, __esd_remove_all_private_usr_app_list, eli);
681
682                 first_list = g_list_first(eli->app_list_evtlaunch);
683                 if (first_list == NULL) {
684                         if (eli->reg_id)
685                                 eventsystem_unregister_event(eli->reg_id);
686
687                         g_hash_table_iter_remove(&iter);
688                 }
689         }
690
691         return ES_R_OK;
692 }
693
694 static void __esd_remove_app_list(gpointer data, gpointer user_data)
695 {
696         bool skip = false;
697         esd_list_item_s *item = (esd_list_item_s *)data;
698         event_launch_item *eli = (event_launch_item *)user_data;
699
700         if (eli->uid != GLOBAL_USER && eli->uid != item->uid)
701                 skip = true;
702
703         if (!skip && !strcmp(eli->package_name, item->pkg_id)) {
704                 _D("pkg_id(%s), app_id(%s)", eli->package_name, item->app_id);
705                 eli->app_list_evtlaunch =
706                         g_list_remove_all(eli->app_list_evtlaunch, data);
707         }
708 }
709
710 static int __esd_remove_launch_item(uid_t uid, gpointer data, const char *pkg_id)
711 {
712         event_launch_item *eli = (event_launch_item *)data;
713         GList *first_list = NULL;
714
715         eli->uid = uid;
716         eli->package_name = (char *)pkg_id;
717         g_list_foreach(eli->app_list_evtlaunch, __esd_remove_app_list, eli);
718
719         first_list = g_list_first(eli->app_list_evtlaunch);
720         if (first_list == NULL) {
721                 if (eli->reg_id)
722                         eventsystem_unregister_event(eli->reg_id);
723
724                 return ES_R_REMOVE;
725         }
726
727         return ES_R_OK;
728 }
729
730 static int __esd_launch_table_remove_items(uid_t uid, const char *pkg_id)
731 {
732         GHashTableIter iter;
733         gpointer key;
734         gpointer value;
735
736         g_hash_table_iter_init(&iter, event_launch_table);
737
738         while (g_hash_table_iter_next(&iter, &key, &value)) {
739                 if (__esd_remove_launch_item(uid, value, pkg_id) == ES_R_REMOVE) {
740                         _D("remove item itself");
741                         g_hash_table_iter_remove(&iter);
742                 }
743         }
744
745         return ES_R_OK;
746 }
747
748 static void __esd_event_launch_with_appid(gpointer data, gpointer user_data)
749 {
750         esd_list_item_s *item = (esd_list_item_s *)data;
751         uid_t uid = item->uid;
752         char *app_id = item->app_id;
753         esd_event_param *eep = (esd_event_param *)user_data;
754         static unsigned int req_id;
755         int pid;
756         char event_uri[1024];
757         bundle *b;
758         /* char *from_appid = (char *)eep->user_data; */
759         /* uid_t from_uid = 0; */
760         /* int ret = 0; */
761
762         _D("launch_on_event: app_id(%s), event_name(%s)", app_id, eep->event_name);
763
764         /* TODO(jongmyeong.ko): for launch by user-event */
765         /*
766         if (from_appid && from_appid[0] != '\0') {
767                 ret = __esd_check_certificate_match(uid, app_id, from_uid, from_appid);
768                 if (ret != ES_R_OK) {
769                         _D("from_appid(%s), no same cert", from_appid);
770                         return;
771                 }
772         }
773         */
774
775         /* FIXME(jongmyeong.ko): aul_app_is_running */
776         /*
777         if (!aul_app_is_running(app_id)) {
778         */
779         if (1) {
780                 snprintf(event_uri, sizeof(event_uri), "event://%s", eep->event_name);
781                 b = bundle_dup(eep->event_data);
782                 appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT);
783                 appsvc_set_uri(b, event_uri);
784                 appsvc_set_appid(b, app_id);
785
786                 pid = appsvc_usr_run_service(b, req_id++, NULL, eep->user_data, uid);
787                 _D("uid(%d), pid(%d)", uid, pid);
788
789                 bundle_free(b);
790         } else {
791                 _D("already is running");
792         }
793 }
794
795 static void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_data)
796 {
797         event_launch_item *el_item = (event_launch_item *)data;
798         esd_event_param *eep = (esd_event_param *)user_data;
799
800         if (strcmp(eep->event_name, (char *)el_item->event_name) == 0) {
801                 g_list_foreach(el_item->app_list_evtlaunch,
802                         __esd_event_launch_with_appid, user_data);
803         }
804 }
805
806 static void __esd_launch_event_handler(char *event_name, bundle *data, void *user_data)
807 {
808         const char *val;
809         const char *msg_type;
810         const char *msg_id;
811         esd_event_param *eep;
812         event_launch_item *el_item;
813
814         _D("event_name(%s)", event_name);
815
816         el_item = (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
817         if (el_item == NULL)
818                 return;
819
820         if (el_item->app_list_evtlaunch != NULL) {
821                 if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) {
822                         val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS);
823                         _D("charger val(%s)", val);
824                         if (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0)
825                                 return;
826                 } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) {
827                         val = bundle_get_val(data, EVT_KEY_USB_STATUS);
828                         _D("usb val(%s)", val);
829                         if (strcmp(EVT_VAL_USB_CONNECTED, val) != 0)
830                                 return;
831                 } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) {
832                         val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS);
833                         _D("earjack val(%s)", val);
834                         if (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0)
835                                 return;
836                 } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) {
837                         msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE);
838                         _D("msg_type(%s)", msg_type);
839                         if (msg_type == NULL)
840                                 return;
841
842                         msg_id = bundle_get_val(data, EVT_KEY_MSG_ID);
843                         _D("msg_id(%s)", msg_id);
844                         if (msg_id == NULL)
845                                 return;
846                 }
847
848                 eep = calloc(1, sizeof(esd_event_param));
849                 if (!eep) {
850                         _E("memory alloc failed");
851                         return;
852                 }
853                 eep->event_name = event_name;
854                 eep->event_data = data;
855                 eep->user_data = (void *)user_data;
856                 __esd_check_event_launch_with_eventid(el_item, eep);
857                 free(eep);
858         }
859 }
860
861 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
862 static void __esd_print_earlier_event(gpointer data, gpointer user_data)
863 {
864         earlier_item *item = (earlier_item *)data;
865         char *event_name = (char *)item->event_name;
866         const char *val;
867
868         _D("event_name = (%s)", event_name);
869
870         if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
871                 if (item->earlier_data) {
872                         val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED);
873                         _D("boot_completed(%s)", val);
874                 }
875         } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
876                 if (item->earlier_data) {
877                         val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN);
878                         _D("shutdown(%s)", val);
879                 }
880         } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
881                 if (item->earlier_data) {
882                         val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY);
883                         _D("low_memory(%s)", val);
884                 }
885         } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
886                 if (item->earlier_data) {
887                         val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS);
888                         _D("charger_status(%s)", val);
889                 }
890         }
891 }
892
893 static void __esd_earlier_table_print_items(void)
894 {
895         GHashTableIter iter;
896         gpointer key;
897         gpointer value;
898
899         g_hash_table_iter_init(&iter, earlier_event_table);
900
901         while (g_hash_table_iter_next(&iter, &key, &value))
902                 __esd_print_earlier_event(value, NULL);
903 }
904
905 static void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data)
906 {
907         int handle;
908         earlier_item *item;
909         _D("event_name(%s)", event_name);
910
911         item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
912         if (item) {
913                 /* update earlier value */
914                 if (item->earlier_data != NULL)
915                         bundle_free(item->earlier_data);
916
917                 item->earlier_data = bundle_dup(data);
918
919                 if (!g_is_bootcompleted) {
920                         if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
921                                 handle = creat(ESD_BOOT_COMPLETED, 0640);
922                                 if (handle != -1)
923                                         close(handle);
924                                 g_is_bootcompleted = true;
925                         }
926                 }
927         }
928 }
929 #endif
930
931 static void __esd_event_handler(char *event_name, bundle *data, void *user_data)
932 {
933         _D("event_name(%s)", event_name);
934
935 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
936         if (__esd_check_earlier_support(event_name))
937                 __esd_earlier_event_handler(event_name, data, user_data);
938 #endif
939
940         if (__esd_check_event_launch_support(event_name))
941                 __esd_launch_event_handler(event_name, data, user_data);
942 }
943
944 static void __esd_trusted_busname_remove_item(char *bus_name)
945 {
946         GHashTableIter iter;
947         gpointer key;
948         gpointer value;
949         trusted_item *item;
950
951         g_hash_table_iter_init(&iter, trusted_busname_table);
952
953         while (g_hash_table_iter_next(&iter, &key, &value)) {
954                 item = (trusted_item *)value;
955                 if (item) {
956                         if (strcmp(bus_name, item->bus_name) == 0) {
957                                 _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name);
958                                 FREE_AND_NULL(item->app_id);
959                                 FREE_AND_NULL(item->bus_name);
960                                 FREE_AND_NULL(item);
961                                 g_hash_table_iter_remove(&iter);
962
963                                 __esd_trusted_busname_print_items();
964                         }
965                 }
966         }
967 }
968
969 static void __esd_filter_name_owner_changed(GDBusConnection *connection,
970                 const gchar *sender_name, const gchar *object_path,
971                 const gchar *interface_name, const gchar *signal_name,
972                 GVariant *parameters, gpointer user_data)
973 {
974         char *name = NULL;
975         char *old_owner = NULL;
976         char *new_owner = NULL;
977         int old_len = 0;
978         int new_len = 0;
979
980         g_variant_get(parameters, "(sss)", &name, &old_owner, &new_owner);
981
982         if (strstr(name, "event.busname.session")) {
983                 old_len = strlen(old_owner);
984                 new_len = strlen(new_owner);
985
986                 _D("changed name(%s), old_onwer(%s)(%d) -> new_onwer(%s)(%d)",
987                         name, old_owner, old_len, new_owner, new_len);
988
989                 if (old_len > 0 && new_len == 0)
990                         __esd_trusted_busname_remove_item(name);
991                 else if (old_len == 0 && new_len > 0)
992                         _D("new name owned");
993                 else
994                         _E("not-expected name change");
995         }
996 }
997
998 static int __esd_dbus_name_monitor(GDBusConnection *connection)
999 {
1000         guint name_owner_changed_id = 0;
1001
1002         name_owner_changed_id = g_dbus_connection_signal_subscribe(connection,
1003                 "org.freedesktop.DBus", "org.freedesktop.DBus",
1004                 "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1005                 __esd_filter_name_owner_changed, NULL, NULL);
1006
1007         _I("name_owner_changed_id(%d)", name_owner_changed_id);
1008
1009         return ES_R_OK;
1010 }
1011
1012 static int __esd_get_user_items(void)
1013 {
1014         int ret = 0;
1015         int i = 0;
1016         uid_t *uids = NULL;
1017         uid_t cur_uid = 0;
1018
1019         ret = sd_get_uids(&uids);
1020         if (ret < 0) {
1021                 _E("failed to get uids (%d)", ret);
1022                 return ES_R_ERROR;
1023         }
1024
1025         if (ret == 0 || uids == NULL) {
1026                 _I("there is no uid for now");
1027         } else {
1028                 /* reset user's item */
1029                 __esd_launch_table_remove_private_usr_items();
1030                 for (i = 0; i < ret; i++) {
1031                         cur_uid = uids[i];
1032                         _I("found uid(%d)", cur_uid);
1033
1034                         ret = pkgmgrinfo_appinfo_get_usr_installed_list(__esd_add_appinfo_handler, cur_uid, &cur_uid);
1035                         if (ret < 0)
1036                                 _E("failed to get user(%d)-app list (%d)", cur_uid, ret);
1037                 }
1038         }
1039
1040         __esd_launch_table_print_items();
1041
1042         return ES_R_OK;
1043 }
1044
1045 static Eina_Bool __esd_fd_handler_func(void *data, Ecore_Fd_Handler *fd_handler)
1046 {
1047         if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
1048                 _I("fd read");
1049                 __esd_get_user_items();
1050         }
1051
1052         return ECORE_CALLBACK_CANCEL;
1053 }
1054
1055 static int __esd_start_sd_monitor(void)
1056 {
1057         int ret = 0;
1058         int fd = 0;
1059
1060         ret = __esd_get_user_items();
1061         if (ret < 0)
1062                 return ES_R_ERROR;
1063
1064         ret = sd_login_monitor_new("uid", &g_sd_monitor);
1065         if (ret < 0) {
1066                 _E("sd_login_monitor_new error (%d)", ret);
1067                 return ES_R_ERROR;
1068         }
1069
1070         fd = sd_login_monitor_get_fd(g_sd_monitor);
1071         if (fd < 0) {
1072                 _E("sd_login_monitor_get_fd error");
1073                 sd_login_monitor_unref(g_sd_monitor);
1074                 return ES_R_ERROR;
1075         }
1076
1077         g_fd_handler = ecore_main_fd_handler_add(fd,
1078                 (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR),
1079                 __esd_fd_handler_func, NULL, NULL, NULL);
1080         if (g_fd_handler == NULL) {
1081                 _E("fd_handler is NULL");
1082                 sd_login_monitor_unref(g_sd_monitor);
1083                 return ES_R_ERROR;
1084         }
1085
1086         _I("setup sd-monitor done");
1087
1088         return ES_R_OK;
1089 }
1090
1091 static int __esd_stop_sd_monitor(void)
1092 {
1093         _I("stop sd_monitor");
1094         if (g_fd_handler) {
1095                 ecore_main_fd_handler_del(g_fd_handler);
1096                 g_fd_handler = NULL;
1097         }
1098
1099         sd_login_monitor_unref(g_sd_monitor);
1100         g_sd_monitor = 0;
1101
1102         return ES_R_OK;
1103 }
1104
1105 static GDBusNodeInfo *introspection_data;
1106 static const gchar introspection_xml[] =
1107 "<node>"
1108 "       <interface name='tizen.system.event.app2esd'>"
1109 "               <method name='CheckSenderValidation'>"
1110 "                       <arg type='i' name='senderpid' direction='in'/>"
1111 "                       <arg type='s' name='eventname' direction='in'/>"
1112 "                       <arg type='i' name='ret' direction='out'/>"
1113 "                       <arg type='s' name='senderid' direction='out'/>"
1114 "               </method>"
1115 "               <method name='GetTrustedPeerList'>"
1116 "                       <arg type='s' name='eventname' direction='in'/>"
1117 "                       <arg type='i' name='ret' direction='out'/>"
1118 "                       <arg type='as' name='dest_list' direction='out'/>"
1119 "               </method>"
1120 "               <method name='SetupTrustedPeer'>"
1121 "                       <arg type='s' name='eventname' direction='in'/>"
1122 "                       <arg type='s' name='destination' direction='in'/>"
1123 "                       <arg type='i' name='ret' direction='out'/>"
1124 "               </method>"
1125 "               <method name='CheckPrivilegeValidation'>"
1126 "                       <arg type='s' name='eventname' direction='in'/>"
1127 "                       <arg type='i' name='ret' direction='out'/>"
1128 "               </method>"
1129 "               <method name='CheckUserSendValidation'>"
1130 "                       <arg type='s' name='eventname' direction='in'/>"
1131 "                       <arg type='i' name='ret' direction='out'/>"
1132 "               </method>"
1133 "               <method name='RequestTrustedEventLaunch'>"
1134 "                       <arg type='s' name='eventname' direction='in'/>"
1135 "                       <arg type='s' name='eventdata' direction='in'/>"
1136 "                       <arg type='i' name='datalen' direction='in'/>"
1137 "                       <arg type='i' name='ret' direction='out'/>"
1138 "               </method>"
1139 "               <method name='RequestEventLaunch'>"
1140 "                       <arg type='s' name='eventname' direction='in'/>"
1141 "                       <arg type='s' name='eventdata' direction='in'/>"
1142 "                       <arg type='i' name='datalen' direction='in'/>"
1143 "                       <arg type='i' name='ret' direction='out'/>"
1144 "               </method>"
1145 "               <method name='RequestSendingEvent'>"
1146 "                       <arg type='s' name='eventname' direction='in'/>"
1147 "                       <arg type='s' name='eventdata' direction='in'/>"
1148 "                       <arg type='i' name='datalen' direction='in'/>"
1149 "                       <arg type='i' name='ret' direction='out'/>"
1150 "               </method>"
1151 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1152 "               <method name='GetEarlierData'>"
1153 "                       <arg type='s' name='appid' direction='in'/>"
1154 "                       <arg type='i' name='ret' direction='out'/>"
1155 "                       <arg type='i' name='len' direction='out'/>"
1156 "                       <arg type='s' name='earlier_data' direction='out'/>"
1157 "               </method>"
1158 #endif
1159 "       </interface>"
1160 "</node>";
1161
1162 static int __esd_get_appid_by_pid(int pid, uid_t uid, char *app_id, int buf_size)
1163 {
1164         int retval = ES_R_OK;
1165         int ret = 0;
1166
1167         if (pid <= 0) {
1168                 _E("invalid pid(%d)", pid);
1169                 retval = ES_R_ERROR;
1170         } else if (uid <= 0) {
1171                 _E("invalid uid(%d)", uid);
1172                 retval = ES_R_ERROR;
1173         } else {
1174                 ret = aul_app_get_appid_bypid_for_uid(pid, app_id, buf_size, (uid_t)uid);
1175                 if (ret != AUL_R_OK) {
1176                         _E("failed to get appid by pid");
1177                         retval = ES_R_ERROR;
1178                 }
1179                 _D("pid(%d)-uid(%d)-appid(%s)", pid, uid, app_id);
1180         }
1181
1182         return retval;
1183 }
1184
1185 static int check_user_event_sender_valid(const char *event_name, const char *app_id)
1186 {
1187         char *valid_name = NULL;
1188         char *temp_name = NULL;
1189         char *tmp = NULL;
1190         int retval = ES_R_OK;
1191         int len = 0;
1192         int valid_name_len = 0;
1193
1194         temp_name = strdup(event_name);
1195         if (temp_name == NULL) {
1196                 _E("out of memory");
1197                 return ES_R_ENOMEM;
1198         }
1199
1200         tmp = strrchr(temp_name, '.');
1201         if (tmp == NULL || strlen(tmp) == 0) {
1202                 _E("invalid event name");
1203                 FREE_AND_NULL(temp_name);
1204                 return ES_R_EINVAL;
1205         }
1206         len = strlen(tmp);
1207         if (len <= 1 || len > 128) {
1208                 _E("invalid length(%d) of user-defined name");
1209                 FREE_AND_NULL(temp_name);
1210                 return ES_R_EINVAL;
1211         }
1212         *tmp = '\0';
1213
1214         _D("app_id(%s), len(%d)", app_id, strlen(app_id));
1215
1216         valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1;
1217         valid_name = calloc(1, valid_name_len);
1218         if (valid_name == NULL) {
1219                 _E("memory alloc failed");
1220                 FREE_AND_NULL(temp_name);
1221                 return ES_R_ENOMEM;
1222         }
1223         snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id);
1224         _D("valid_name(%s)", valid_name);
1225
1226         if (strcmp(temp_name, valid_name) != 0) {
1227                 _E("appid misamatch");
1228                 retval = ES_R_EINVAL;
1229         }
1230
1231         FREE_AND_NULL(temp_name);
1232         FREE_AND_NULL(valid_name);
1233
1234         return retval;
1235 }
1236
1237 static void check_sender_valid_method_call(GDBusConnection *connection, const gchar *sender,
1238         GVariant *parameters, GDBusMethodInvocation *invocation)
1239 {
1240         GVariant *param = NULL;
1241         int result = 0;
1242         char *event_name = NULL;
1243         char app_id[128] = {0, };
1244         int event_sender_pid = 0;
1245         uid_t sender_uid = 0;
1246
1247         g_variant_get(parameters, "(is)", &event_sender_pid, &event_name);
1248         _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name);
1249
1250         sender_uid = __get_sender_uid(connection, sender);
1251         if (__esd_get_appid_by_pid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1252                 result = ES_R_ERROR;
1253         } else {
1254                 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1255                         _E("invalid sender");
1256                         result = ES_R_EINVAL;
1257                 } else {
1258                         result = 1;
1259                 }
1260         }
1261
1262         param = g_variant_new("(is)", result, app_id);
1263         _D("event_name(%s), result(%d)", event_name, result);
1264         g_dbus_method_invocation_return_value(invocation, param);
1265 }
1266
1267 static void check_send_event_valid_method_call(GDBusConnection *connection, const gchar *sender,
1268         GVariant *parameters, GDBusMethodInvocation *invocation)
1269 {
1270         GVariant *param = NULL;
1271         int result = 0;
1272         char *event_name = NULL;
1273         char app_id[128] = {0, };
1274         int sender_pid = 0;
1275         uid_t sender_uid = 0;
1276
1277         g_variant_get(parameters, "(s)", &event_name);
1278         _D("event_name(%s)", event_name);
1279
1280         sender_pid = __get_sender_pid(connection, sender);
1281         sender_uid = __get_sender_uid(connection, sender);
1282         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1283                 result = ES_R_ERROR;
1284         } else {
1285                 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1286                         _E("invalid sender");
1287                         result = ES_R_EINVAL;
1288                 } else {
1289                         result = 1;
1290                 }
1291         }
1292
1293         param = g_variant_new("(i)", result);
1294         _D("event_name(%s), result(%d)", event_name, result);
1295         g_dbus_method_invocation_return_value(invocation, param);
1296 }
1297
1298 static void get_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1299         GVariant *parameters, GDBusMethodInvocation *invocation)
1300 {
1301         GVariant *param = NULL;
1302         int result = 0;
1303         GVariantBuilder *builder = NULL;
1304         GHashTableIter iter;
1305         gpointer key, value;
1306         char *event_name = NULL;
1307         char app_id[128] = {0, };
1308         int sender_pid = 0;
1309         uid_t sender_uid = 0;
1310         int ret = 0;
1311         uid_t uid = 0;
1312         char *_appid = NULL;
1313         char *_busname = NULL;
1314         trusted_item *item;
1315
1316         g_variant_get(parameters, "(s)", &event_name);
1317         _D("event_name(%s)", event_name);
1318
1319         sender_pid = __get_sender_pid(connection, sender);
1320         sender_uid = __get_sender_uid(connection, sender);
1321         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1322                 result = ES_R_ERROR;
1323         } else {
1324                 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1325
1326                 g_hash_table_iter_init(&iter, trusted_busname_table);
1327                 while (g_hash_table_iter_next(&iter, &key, &value)) {
1328                         item = (trusted_item *)value;
1329                         uid = item->uid;
1330                         _appid = item->app_id;
1331                         _busname = item->bus_name;
1332
1333                         if (uid != GLOBAL_USER && uid != sender_uid)
1334                                 continue;
1335
1336                         ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id);
1337                         if (ret == ES_R_OK)
1338                                 g_variant_builder_add(builder, "s", _busname);
1339                 }
1340
1341                 result = 1;
1342         }
1343
1344         param = g_variant_new("(ias)", result, builder);
1345         _D("result(%d)", result);
1346         g_dbus_method_invocation_return_value(invocation, param);
1347         if (builder)
1348                 g_variant_builder_unref(builder);
1349 }
1350
1351 static void setup_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1352         GVariant *parameters, GDBusMethodInvocation *invocation)
1353 {
1354         GVariant *param = NULL;
1355         int result = 0;
1356         char *event_name = NULL;
1357         char *destination_name = NULL;
1358         char app_id[128] = {0, };
1359         int sender_pid = 0;
1360         uid_t sender_uid = 0;
1361         int ret = 0;
1362
1363         g_variant_get(parameters, "(ss)", &event_name, &destination_name);
1364         _D("event_name(%s), destination_name(%s)", event_name, destination_name);
1365
1366         if (destination_name && destination_name[0] != '\0') {
1367                 sender_pid = __get_sender_pid(connection, sender);
1368                 sender_uid = __get_sender_uid(connection, sender);
1369                 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1370                         result = ES_R_ERROR;
1371                 } else {
1372                         ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name,
1373                                 sender_pid);
1374                         if (ret < 0) {
1375                                 _E("failed to add trusted busname item");
1376                                 result = ES_R_ERROR;
1377                         } else {
1378                                 result = 1;
1379                         }
1380                 }
1381         } else {
1382                 _E("invalid destination name");
1383                 result = ES_R_ERROR;
1384         }
1385
1386         param = g_variant_new("(i)", result);
1387         _D("event_name(%s), result(%d)", event_name, result);
1388         g_dbus_method_invocation_return_value(invocation, param);
1389 }
1390
1391 static void check_privilege_valid_method_call(GDBusConnection *connection, const gchar *sender,
1392         GVariant *parameters, GDBusMethodInvocation *invocation)
1393 {
1394         GVariant *param = NULL;
1395         int result = 0;
1396         char *event_name = NULL;
1397         char *privilege_name = NULL;
1398         char app_id[128] = {0, };
1399         int sender_pid = 0;
1400         uid_t sender_uid = 0;
1401         char *client = NULL;
1402         char *session = NULL;
1403         char *user = NULL;
1404         int ret = 0;
1405
1406         g_variant_get(parameters, "(s)", &event_name);
1407         __esd_check_privilege_name(event_name, &privilege_name);
1408         _D("event_name(%s), privilege_name(%s)", event_name, privilege_name);
1409
1410         if (privilege_name) {
1411                 sender_pid = __get_sender_pid(connection, sender);
1412                 sender_uid = __get_sender_uid(connection, sender);
1413                 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1414                         result = ES_R_ERROR;
1415                 } else {
1416                         ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client);
1417                         if (ret != CYNARA_API_SUCCESS) {
1418                                 _E("failed to get client");
1419                                 result = ES_R_EINVAL;
1420                                 goto out;
1421                         }
1422
1423                         ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user);
1424                         if (ret != CYNARA_API_SUCCESS) {
1425                                 _E("failed to get user");
1426                                 result = ES_R_EINVAL;
1427                                 goto out;
1428                         }
1429
1430                         session = cynara_session_from_pid(sender_pid);
1431                         if (session == NULL) {
1432                                 _E("failed to get session");
1433                                 result = ES_R_EINVAL;
1434                                 goto out;
1435                         }
1436
1437                         _D("app_id(%s), client(%s), session(%s), user(%s)", app_id, client, session, user);
1438                         if (__esd_check_valid_privilege_by_cynara(app_id, client, session, user, privilege_name))
1439                                 result = 1;
1440                         else
1441                                 result = ES_R_EINVAL;
1442                 }
1443         } else {
1444                 result = 1;
1445         }
1446
1447 out:
1448         g_free(client);
1449         g_free(user);
1450         g_free(session);
1451         param = g_variant_new("(i)", result);
1452         _D("event_name(%s), result(%d)", event_name, result);
1453         g_dbus_method_invocation_return_value(invocation, param);
1454 }
1455
1456 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1457 static void get_earlier_data_method_call(GVariant *parameters, GDBusMethodInvocation *invocation)
1458 {
1459         GVariant *param = NULL;
1460         int result = 0;
1461         char *event_name = NULL;
1462         bundle *b = NULL;
1463         bundle_raw *raw = NULL;
1464         int len = 0;
1465         earlier_item *item;
1466
1467         g_variant_get(parameters, "(s)", &event_name);
1468
1469         if (event_name && strlen(event_name) > 0) {
1470                 _D("event_name(%s)", event_name);
1471                 result = ES_R_OK;
1472         } else {
1473                 _E("invalid event_name(%s)", event_name);
1474                 result = ES_R_ERROR;
1475         }
1476
1477         item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1478         if (item != NULL) {
1479                 if (item->earlier_data) {
1480                         b = bundle_dup(item->earlier_data);
1481                         bundle_add_str(b, "is_earlier_data", "true");
1482                         bundle_encode(b, &raw, &len);
1483                         bundle_free(b);
1484                 }
1485         }
1486
1487         param = g_variant_new("(iis)", result, len, raw);
1488
1489         _D("result(%d), len(%d)", result, len);
1490         g_dbus_method_invocation_return_value(invocation, param);
1491
1492         bundle_free_encoded_rawdata(&raw);
1493 }
1494 #endif
1495
1496 static void handle_method_call(GDBusConnection *connection,
1497         const gchar *sender, const gchar *object_path,
1498         const gchar *interface_name, const gchar *method_name,
1499         GVariant *parameters, GDBusMethodInvocation *invocation,
1500         gpointer user_data)
1501 {
1502         if (g_strcmp0(method_name, "CheckSenderValidation") == 0) {
1503                 check_sender_valid_method_call(connection, sender, parameters, invocation);
1504         } else if (g_strcmp0(method_name, "GetTrustedPeerList") == 0) {
1505                 get_trusted_peer_method_call(connection, sender, parameters, invocation);
1506         } else if (g_strcmp0(method_name, "SetupTrustedPeer") == 0) {
1507                 setup_trusted_peer_method_call(connection, sender, parameters, invocation);
1508         } else if (g_strcmp0(method_name, "CheckPrivilegeValidation") == 0) {
1509                 check_privilege_valid_method_call(connection, sender, parameters, invocation);
1510         } else if (g_strcmp0(method_name, "CheckUserSendValidation") == 0) {
1511                 check_send_event_valid_method_call(connection, sender, parameters, invocation);
1512 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1513         } else if (g_strcmp0(method_name, "GetEarlierData") == 0) {
1514                 get_earlier_data_method_call(parameters, invocation);
1515 #endif
1516         }
1517 }
1518
1519 static const GDBusInterfaceVTable interface_vtable = {
1520         handle_method_call,
1521         NULL,
1522         NULL
1523 };
1524
1525 static void __esd_on_bus_acquired(GDBusConnection *connection,
1526                 const gchar *name, gpointer user_data)
1527 {
1528         _I("bus acquired(%s)", name);
1529
1530         guint reg_id = 0;
1531         GError *error = NULL;
1532
1533         reg_id = g_dbus_connection_register_object(connection,
1534                 ESD_OBJECT_PATH,
1535                 introspection_data->interfaces[0],
1536                 &interface_vtable,
1537                 NULL, NULL, &error);
1538         if (reg_id == 0) {
1539                 _E("g_dbus_connection_register_object error(%s)", error->message);
1540                 g_error_free(error);
1541         }
1542 }
1543
1544 static void __esd_on_name_acquired(GDBusConnection *connection,
1545                 const gchar *name, gpointer user_data)
1546 {
1547         bundle *b;
1548
1549         _I("name acquired(%s)", name);
1550
1551         __esd_check_trusted_events(connection, "ListNames");
1552         __esd_check_trusted_events(connection, "ListActivatableNames");
1553
1554         b = bundle_create();
1555         bundle_add_str(b, EVT_KEY_ESD_STATUS, EVT_VAL_ESD_STARTED);
1556         eventsystem_send_system_event(SYS_EVENT_ESD_STATUS, b);
1557         bundle_free(b);
1558
1559         __esd_register_vconf_callbacks();
1560
1561         __esd_trusted_busname_print_items();
1562
1563         __esd_start_sd_monitor();
1564
1565         __esd_dbus_name_monitor(connection);
1566 }
1567
1568 static void __esd_on_name_lost(GDBusConnection *connection,
1569                 const gchar *name, gpointer user_data)
1570 {
1571         _E("name lost(%s)", name);
1572 }
1573
1574 static int __esd_before_loop(void)
1575 {
1576         int ret = 0;
1577         uid_t uid = 0;
1578         GError *error = NULL;
1579         guint owner_id = 0;
1580
1581 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1582         guint subscription_id = 0;
1583         int i;
1584         int size;
1585         char *event_name;
1586         int fd;
1587         int val;
1588         int status;
1589         int charger_status;
1590         int charge_now;
1591         earlier_item *item;
1592
1593         earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal);
1594
1595         _I("register events for earlier_data");
1596         size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
1597         for (i = 0; i < size; i++) {
1598                 event_name = (char *)earlier_event_list[i];
1599                 _I("event_name(%s)", event_name);
1600
1601                 item = calloc(1, sizeof(earlier_item));
1602                 if (item == NULL) {
1603                         _E("memery alloc failed");
1604                         return ES_R_ENOMEM;
1605                 }
1606                 item->event_name = strdup(event_name);
1607                 if (item->event_name == NULL) {
1608                         _E("out of memory");
1609                         free(item);
1610                         return ES_R_ENOMEM;
1611                 }
1612
1613                 /* set initial data */
1614                 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
1615                         fd = open(ESD_BOOT_COMPLETED, O_RDONLY);
1616                         if (fd < 0) {
1617                                 _D("open file error(%d)", fd);
1618                         } else {
1619                                 item->earlier_data = bundle_create();
1620                                 bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED,
1621                                         EVT_VAL_BOOT_COMPLETED_TRUE);
1622                                 close(fd);
1623                         }
1624                 } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
1625                         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val);
1626                         if (ret != VCONF_OK) {
1627                                 _E("failed to get power_off status (%d)", ret);
1628                         } else {
1629                                 if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT ||
1630                                         val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
1631                                         /* power-off requested */
1632                                         item->earlier_data = bundle_create();
1633                                         bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN,
1634                                                 EVT_VAL_SYSTEM_SHUTDOWN_TRUE);
1635                                 }
1636                         }
1637                 } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
1638                         ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status);
1639                         if (ret != VCONF_OK) {
1640                                 _E("failed to get low_memory status (%d)", ret);
1641                         } else {
1642                                 item->earlier_data = bundle_create();
1643                                 if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
1644                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1645                                                 EVT_VAL_MEMORY_SOFT_WARNING);
1646                                 else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING)
1647                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1648                                                 EVT_VAL_MEMORY_HARD_WARNING);
1649                                 else
1650                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1651                                                 EVT_VAL_MEMORY_NORMAL);
1652                         }
1653                 } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
1654                         ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status);
1655                         if (ret != VCONF_OK) {
1656                                 _E("failed to get charger_status (%d)", ret);
1657                         } else {
1658                                 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now);
1659                                 if (ret != VCONF_OK)
1660                                         _E("failed to get charge_now (%d)", ret);
1661                         }
1662
1663                         if (ret == VCONF_OK) {
1664                                 item->earlier_data = bundle_create();
1665                                 if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) {
1666                                         if (charge_now == 0) {
1667                                                 bundle_add_str(item->earlier_data,
1668                                                         EVT_KEY_BATTERY_CHARGER_STATUS,
1669                                                         EVT_VAL_BATTERY_CHARGER_DISCHARGING);
1670                                         } else {
1671                                                 bundle_add_str(item->earlier_data,
1672                                                         EVT_KEY_BATTERY_CHARGER_STATUS,
1673                                                         EVT_VAL_BATTERY_CHARGER_CHARGING);
1674                                         }
1675                                 } else {
1676                                         bundle_add_str(item->earlier_data,
1677                                                 EVT_KEY_BATTERY_CHARGER_STATUS,
1678                                                 EVT_VAL_BATTERY_CHARGER_DISCONNECTED);
1679                                 }
1680                         }
1681                 }
1682
1683                 eventsystem_register_event(event_name, &subscription_id,
1684                         (eventsystem_handler)__esd_event_handler, NULL);
1685                 if (subscription_id == 0) {
1686                         _E("signal subscription error, event_name(%s)", event_name);
1687                         if (item->earlier_data)
1688                                 bundle_free(item->earlier_data);
1689                         free(item->event_name);
1690                         free(item);
1691
1692                         return ES_R_ERROR;
1693                 } else {
1694                         item->reg_id = subscription_id;
1695                 }
1696
1697                 g_hash_table_insert(earlier_event_table, event_name, item);
1698         }
1699
1700         __esd_earlier_table_print_items();
1701 #endif
1702
1703         event_launch_table = g_hash_table_new(g_str_hash, g_str_equal);
1704
1705         _I("get event launch list");
1706
1707         /* get global user info */
1708         uid = GLOBAL_USER;
1709         ret = pkgmgrinfo_appinfo_get_usr_installed_list(__esd_add_appinfo_handler, uid, &uid);
1710         if (ret < 0) {
1711                 _E("failed to get global-app list (%d)", ret);
1712                 return ES_R_ERROR;
1713         }
1714
1715         __esd_launch_table_print_items();
1716
1717         trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal);
1718
1719         /* gdbus setup for method call */
1720         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
1721         if (!introspection_data) {
1722                 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
1723                 g_error_free(error);
1724                 return ES_R_ERROR;
1725         }
1726
1727         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1728                 ESD_BUS_NAME,
1729                 G_BUS_NAME_OWNER_FLAGS_NONE,
1730                 __esd_on_bus_acquired,
1731                 __esd_on_name_acquired,
1732                 __esd_on_name_lost,
1733                 NULL, NULL);
1734         if (!owner_id) {
1735                 _E("g_bus_own_name error");
1736                 g_dbus_node_info_unref(introspection_data);
1737                 return ES_R_ERROR;
1738         }
1739
1740         _I("esd before_loop done");
1741
1742         return ES_R_OK;
1743 }
1744
1745 static void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event)
1746 {
1747         pkg_event->type = UNKNOWN;
1748         if (pkg_event->pkgid) {
1749                 free(pkg_event->pkgid);
1750                 pkg_event->pkgid = NULL;
1751         }
1752 }
1753
1754 static int __esd_appcontrol_cb(const char *operation,
1755                 const char *uri, const char *mime, void *data)
1756 {
1757         esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data;
1758         char *appid = NULL;
1759         char *pkgid = NULL;
1760         char *event_name = NULL;
1761         const char *prefix = "event://";
1762         uid_t uid = 0;
1763
1764         if (cb_data == NULL) {
1765                 _E("invalid data");
1766                 return 0;
1767         }
1768         appid = cb_data->appid;
1769         pkgid = cb_data->pkgid;
1770         uid = cb_data->uid;
1771
1772         _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)",
1773                 uid, appid, pkgid, operation, uri, mime);
1774
1775         if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) {
1776                 if (!strncmp(uri, prefix, strlen(prefix))) {
1777                         event_name = strdup(&uri[8]);
1778                         if (event_name) {
1779                                 _D("appid(%s), event_name(%s)", appid, event_name);
1780                                 if (!__esd_check_event_launch_support(event_name)) {
1781                                         _E("failed to add item (not support event)");
1782                                 } else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name)) {
1783                                         _E("failed to add item (no privilege)");
1784                                 } else {
1785                                         if (__esd_add_launch_item(uid, event_name, appid, pkgid))
1786                                                 _E("failed to add item");
1787                                 }
1788                                 FREE_AND_NULL(event_name);
1789                         } else {
1790                                 _E("out of memory");
1791                         }
1792                 } else {
1793                         _E("Invalid uri(%s) for event_name", uri);
1794                 }
1795         }
1796
1797         return 0;
1798 }
1799
1800 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data)
1801 {
1802         char *appid = NULL;
1803         char *pkgid = NULL;
1804         pkgmgrinfo_app_component component_type;
1805         int ret = 0;
1806         uid_t *p_uid = NULL;
1807
1808         if (data == NULL) {
1809                 _E("invalid data");
1810                 return ES_R_ERROR;
1811         }
1812
1813         p_uid = (uid_t *)data;
1814
1815         ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
1816         if (ret < 0) {
1817                 _E("failed to get appid");
1818                 return ES_R_ERROR;
1819         }
1820
1821         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
1822         if (ret < 0) {
1823                 _E("failed to get pkgid");
1824                 return ES_R_ERROR;
1825         }
1826
1827         ret = pkgmgrinfo_appinfo_get_component(handle, &component_type);
1828         if (ret != PMINFO_R_OK) {
1829                 _E("fail to get component type");
1830                 return ES_R_ERROR;
1831         }
1832
1833         _D("uid(%d), appid(%s), component_type(%d)", *p_uid, appid, component_type);
1834         if (component_type == PMINFO_SVC_APP) {
1835                 esd_appctrl_cb_data *cb_data = calloc(1, sizeof(esd_appctrl_cb_data));
1836                 if (cb_data == NULL) {
1837                         _E("memory alloc failed");
1838                         return ES_R_ENOMEM;
1839                 }
1840                 cb_data->appid = strdup(appid);
1841                 if (cb_data->appid == NULL) {
1842                         _E("out_of_memory");
1843                         FREE_AND_NULL(cb_data);
1844                         return ES_R_ENOMEM;
1845                 }
1846                 cb_data->pkgid = strdup(pkgid);
1847                 if (cb_data->pkgid == NULL) {
1848                         _E("out_of_memory");
1849                         FREE_AND_NULL(cb_data->appid);
1850                         FREE_AND_NULL(cb_data);
1851                         return ES_R_ENOMEM;
1852                 }
1853                 cb_data->uid = *p_uid;
1854                 ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
1855                         (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data);
1856
1857                 FREE_AND_NULL(cb_data->pkgid);
1858                 FREE_AND_NULL(cb_data->appid);
1859                 FREE_AND_NULL(cb_data);
1860
1861                 if (ret < 0) {
1862                         _E("failed to get appcontrol info");
1863                         return ES_R_ERROR;
1864                 }
1865                 __esd_launch_table_print_items();
1866         }
1867
1868         return ES_R_OK;
1869 }
1870
1871 static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id, const char *pkg_type,
1872                 const char *pkgid, const char *key, const char *val,
1873                 const void *pmsg, void *data)
1874 {
1875         esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data;
1876         pkgmgrinfo_pkginfo_h handle = NULL;
1877         int ret = 0;
1878
1879         _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)",
1880                 target_uid, req_id, pkg_type, pkgid, key, val);
1881
1882         if (strncmp(key, "start", strlen(key)) == 0) {
1883                 if (strcmp(val, "install") == 0) {
1884                         _D("install start");
1885                         pkg_event->type = INSTALL;
1886                 } else if (strcmp(val, "uninstall") == 0) {
1887                         _D("unistall start");
1888                         pkg_event->type = UNINSTALL;
1889                 } else if (strcmp(val, "update") == 0) {
1890                         _D("update start");
1891                         pkg_event->type = UPDATE;
1892                 } else {
1893                         _D("val(%s) start", val);
1894                         __esd_pkgmgr_event_free(pkg_event);
1895                 }
1896         } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) {
1897                 if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) {
1898                         _D("install end (ok)");
1899                         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle);
1900                         if (ret < 0) {
1901                                 _E("failed to get pkginfo");
1902                                 __esd_pkgmgr_event_free(pkg_event);
1903                                 return 0;
1904                         }
1905                         ret = pkgmgrinfo_appinfo_get_usr_list(handle,
1906                                 PMINFO_ALL_APP, __esd_add_appinfo_handler, &target_uid, target_uid);
1907                         if (ret < 0) {
1908                                 _E("failed to get appinfo");
1909                                 __esd_pkgmgr_event_free(pkg_event);
1910                                 return 0;
1911                         }
1912                         ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1913                         if (ret < 0) {
1914                                 _E("failed to destroy pkginfo");
1915                                 __esd_pkgmgr_event_free(pkg_event);
1916                                 return 0;
1917                         }
1918                 } else if (pkg_event->type == UNINSTALL) {
1919                         _D("uninstall end (ok)");
1920                         __esd_launch_table_remove_items(target_uid, pkgid);
1921                         __esd_launch_table_print_items();
1922                 }
1923                 __esd_pkgmgr_event_free(pkg_event);
1924         } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) {
1925                 _E("pkg_event(%d) falied", pkg_event->type);
1926                 __esd_pkgmgr_event_free(pkg_event);
1927         } else {
1928                 if (strcmp(key, "install_percent") != 0)
1929                         __esd_pkgmgr_event_free(pkg_event);
1930         }
1931
1932         return 0;
1933 }
1934
1935 static int __esd_init()
1936 {
1937         int req_id = 0;
1938         int ret = 0;
1939         pkgmgr_client *client;
1940         esd_pkgmgr_event *pkg_event;
1941
1942 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
1943         g_type_init();
1944 #endif
1945         ecore_init();
1946
1947         __esd_init_cynara();
1948
1949         client = pkgmgr_client_new(PC_LISTENING);
1950         if (client == NULL) {
1951                 _E("set pkgmgr client failed");
1952                 return ES_R_ERROR;
1953         }
1954
1955         pkg_event = calloc(1, sizeof(esd_pkgmgr_event));
1956         if (pkg_event == NULL) {
1957                 _E("memory alloc failed");
1958                 ret = pkgmgr_client_free(client);
1959                 if (ret != PKGMGR_R_OK)
1960                         _E("pkgmgr_client_free failed(%d)", ret);
1961
1962                 return ES_R_ENOMEM;
1963         }
1964
1965         req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event);
1966         if (req_id < 0) {
1967                 _E("pkgmgr client listen failed");
1968                 ret = pkgmgr_client_free(client);
1969                 if (ret != PKGMGR_R_OK)
1970                         _E("pkgmgr_client_free failed(%d)", ret);
1971
1972                 return ES_R_ERROR;
1973         }
1974
1975         s_info.client = client;
1976
1977         _I("esd init done");
1978
1979         return 0;
1980 }
1981
1982 static void __esd_remove_esd_list_item(gpointer data, gpointer user_data)
1983 {
1984         esd_list_item_s *item = (esd_list_item_s *)data;
1985
1986         free(item->app_id);
1987         free(item->pkg_id);
1988 }
1989
1990 static void __esd_finalize(void)
1991 {
1992         gpointer key;
1993         gpointer value;
1994         GHashTableIter iter;
1995         trusted_item *item;
1996         event_launch_item *el_item;
1997         int ret = 0;
1998 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1999         earlier_item *er_item;
2000 #endif
2001
2002         _D("esd finalize");
2003
2004         __esd_stop_sd_monitor();
2005
2006         if (trusted_busname_table) {
2007                 g_hash_table_iter_init(&iter, trusted_busname_table);
2008                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2009                         item = (trusted_item *)value;
2010                         if (item) {
2011                                 free(item->app_id);
2012                                 free(item->bus_name);
2013                                 free(item);
2014                         } else {
2015                                 _E("item is null");
2016                         }
2017                         g_hash_table_iter_remove(&iter);
2018                 }
2019                 g_hash_table_unref(trusted_busname_table);
2020         }
2021
2022 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2023         if (earlier_event_table) {
2024                 g_hash_table_iter_init(&iter, earlier_event_table);
2025                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2026                         er_item = (earlier_item *)value;
2027                         if (er_item) {
2028                                 eventsystem_unregister_event(er_item->reg_id);
2029                                 free(er_item->event_name);
2030                                 bundle_free(er_item->earlier_data);
2031                                 free(er_item);
2032                         } else {
2033                                 _E("ealier item is NULL");
2034                         }
2035                         g_hash_table_iter_remove(&iter);
2036                 }
2037                 g_hash_table_unref(earlier_event_table);
2038         }
2039 #endif
2040
2041         if (event_launch_table) {
2042                 g_hash_table_iter_init(&iter, event_launch_table);
2043                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2044                         el_item = (event_launch_item *)value;
2045                         if (el_item) {
2046                                 eventsystem_unregister_event(el_item->reg_id);
2047                                 free(el_item->event_name);
2048                                 g_list_foreach(el_item->app_list_evtlaunch,
2049                                         __esd_remove_esd_list_item, NULL);
2050                                 g_list_free(el_item->app_list_evtlaunch);
2051                                 free(el_item);
2052                         } else {
2053                                 _E("item is NULL");
2054                         }
2055                         g_hash_table_iter_remove(&iter);
2056                 }
2057                 g_hash_table_unref(event_launch_table);
2058         }
2059
2060         if (introspection_data)
2061                 g_dbus_node_info_unref(introspection_data);
2062
2063         if (s_info.client) {
2064                 ret = pkgmgr_client_free(s_info.client);
2065                 if (ret != PKGMGR_R_OK)
2066                         _E("pkgmgr_client_free failed(%d)", ret);
2067         }
2068
2069         __esd_finish_cynara();
2070
2071         _D("esd finalize end");
2072 }
2073
2074 int main(int argc, char *argv[])
2075 {
2076         _I("event system daemon : main()");
2077
2078         if (__esd_init() != 0) {
2079                 _E("ESD Initialization failed!");
2080                 assert(0);
2081                 return ES_R_ERROR;
2082         }
2083
2084         if (__esd_before_loop() < 0) {
2085                 _E("ESD failed!");
2086                 __esd_finalize();
2087                 assert(0);
2088                 return ES_R_ERROR;
2089         }
2090
2091         ecore_main_loop_begin();
2092
2093         _E("shutdown");
2094
2095         __esd_finalize();
2096
2097         ecore_shutdown();
2098
2099         return 0;
2100 }