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