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