Release version 0.2.4
[platform/core/appfw/event-system.git] / src / esd_main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <glib.h>
4 #include <aul.h>
5 #include <aul_svc.h>
6 #include <unistd.h>
7 #include <ctype.h>
8 #include <dlog.h>
9 #include <gio/gio.h>
10 #include <package-manager.h>
11 #include <pkgmgr-info.h>
12 #include <appsvc/appsvc.h>
13 #include <eventsystem.h>
14 #include <bundle_internal.h>
15 #include <fcntl.h>
16 #include <vconf.h>
17 #include <tzplatform_config.h>
18 #include <cert-svc/ccert.h>
19 #include <cert-svc/cinstance.h>
20 #include <cynara-client.h>
21 #include <cynara-creds-gdbus.h>
22 #include <cynara-session.h>
23 #include <security-manager.h>
24 #include "eventsystem_daemon.h"
25
26 #define DEFAULT_USER tzplatform_getuid(TZ_SYS_DEFAULT_USER)
27 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
28 #define ROOT_USER 0
29
30 #define SYS_EVENT_NAME_PREFIX "tizen.system.event"
31 #define SYS_EVENT_OBJ_PATH "/tizen/system/event"
32 #define REQUEST_LAST_DATA "request_last_data"
33
34 static GHashTable *event_launch_table; /* table of events for launch_on_event*/
35
36 static const char *event_launch_support_list[] = {
37         SYS_EVENT_BATTERY_CHARGER_STATUS,
38         SYS_EVENT_USB_STATUS,
39         SYS_EVENT_EARJACK_STATUS,
40         SYS_EVENT_INCOMMING_MSG,
41         SYS_EVENT_OUTGOING_MSG,
42         SYS_EVENT_WIFI_STATE
43 };
44
45 struct privilege_info {
46         const char *event_name;
47         const char *privilege_name;
48 };
49
50 static const struct privilege_info privilege_check_list[] = {
51         {SYS_EVENT_DISPLAY_STATE, "http://tizen.org/privilege/display"},
52         {SYS_EVENT_WIFI_STATE, "http://tizen.org/privilege/network.get"},
53         {SYS_EVENT_INCOMMING_MSG, "http://tizen.org/privilege/message.read"},
54         {SYS_EVENT_OUTGOING_MSG, "http://tizen.org/privilege/message.read"}
55 };
56
57 static int privilege_check_size = sizeof(privilege_check_list)/sizeof(struct privilege_info);
58
59 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
60 static const char *earlier_event_list[] = {
61         SYS_EVENT_ESD_STATUS,
62         SYS_EVENT_LOW_MEMORY,
63         SYS_EVENT_BOOT_COMPLETED,
64         SYS_EVENT_SYSTEM_SHUTDOWN,
65         SYS_EVENT_BATTERY_CHARGER_STATUS
66 };
67
68 static GHashTable *earlier_event_table; /* table of events for earlier_data */
69
70 typedef struct __earlier_table_item {
71         char *event_name;
72         guint reg_id;
73         bundle *earlier_data; /* event-data from earlier occurrence */
74 } earlier_item;
75
76 #endif
77
78 static GHashTable *user_last_event_table; /* table of user events for last data */
79
80 struct __last_event_item {
81         char *key;
82         char *app_id;
83         char *event_name;
84         char *own_name;
85         uid_t uid;
86 };
87
88 static GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */
89
90 typedef struct __trusted_busname_item {
91         char *app_id;
92         char *bus_name;
93         int pid;
94         uid_t uid;
95 } trusted_item;
96
97 typedef struct __eventlaunch_item_param {
98         char *app_id;
99 } eventlaunch_item_param_s;
100
101 enum trusted_result {
102         TRUSTED_UNKNOWN,
103         TRUSTED_ALLOWED,
104         TRUSTED_DENIED,
105 };
106
107 typedef struct esd_list_item {
108         char *pkg_id;
109         char *app_id;
110         int trusted_info;
111         uid_t uid;
112 } esd_list_item_s;
113
114 typedef struct  __event_launch_table_item {
115         char *event_name;
116         char *package_name; /* just for passing pointer to app-list removal func */
117         GList *app_list_evtlaunch; /* app-list for on-event-launch */
118         guint reg_id;
119         uid_t uid;
120 } event_launch_item;
121
122 enum __pkg_event_type {
123         UNKNOWN = 0,
124         INSTALL,
125         UNINSTALL,
126         UPDATE,
127 };
128
129 typedef struct __pkgmgr_event {
130         int type;
131         char *pkgid;
132 } esd_pkgmgr_event;
133
134 typedef struct __esd_event_param {
135         char *event_name;
136         bundle *event_data;
137         uid_t sender_uid;
138         char *sender_appid;
139         bool is_user_event;
140         bool trusted;
141         void *user_data;
142 } esd_event_param;
143
144 typedef struct esd_info {
145         pkgmgr_client *client;
146 } esd_info_s;
147 static esd_info_s s_info;
148
149 typedef struct __esd_appctrl_cb_data {
150         char *appid;
151         char *pkgid;
152         uid_t uid;
153 } esd_appctrl_cb_data;
154
155 static void __esd_event_handler(char *event_name, bundle *data, void *user_data);
156 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data);
157
158 static cynara *r_cynara;
159
160 static int __esd_init_cynara(void)
161 {
162         int ret;
163
164         ret  = cynara_initialize(&r_cynara, NULL);
165         if (ret != CYNARA_API_SUCCESS) {
166                 _E("cynara initialize failed.");
167                 return ret;
168         }
169
170         return 0;
171 }
172
173 static void __esd_finish_cynara(void)
174 {
175         if (r_cynara)
176                 cynara_finish(r_cynara);
177         r_cynara = NULL;
178 }
179
180 static void free_saved_event(struct __last_event_item *item)
181 {
182         if (!item)
183                 return;
184
185         free(item->event_name);
186         free(item->own_name);
187         free(item->app_id);
188         free(item);
189 }
190
191 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
192 static int __esd_check_earlier_support(const char *event_name)
193 {
194         int i = 0;
195         int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
196
197         for (i = 0; i < size; i++) {
198                 if (strcmp(earlier_event_list[i], event_name) == 0)
199                         return true;
200         }
201
202         return false;
203 }
204 #endif
205
206 static bool __esd_check_platform_cert(const char *pkgid, uid_t uid)
207 {
208         _D("Checking if %s has a platform certification", pkgid);
209
210         int r;
211         const char *cert_value;
212         pkgmgrinfo_certinfo_h certinfo;
213         CertSvcInstance instance;
214         CertSvcCertificate certificate;
215         CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
216
217         r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
218         if (r != PMINFO_R_OK) {
219                 _E("Failed to create certinfo");
220                 return false;
221         }
222
223         r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid);
224         if (r != PMINFO_R_OK) {
225                 _E("Failed to load certinfo");
226                 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
227                 return false;
228         }
229
230         r = pkgmgrinfo_pkginfo_get_cert_value(certinfo,
231                         PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value);
232         if (r != PMINFO_R_OK || cert_value == NULL) {
233                 _E("Failed to get cert value");
234                 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
235                 return false;
236         }
237
238         r = certsvc_instance_new(&instance);
239         if (r != CERTSVC_SUCCESS) {
240                 _E("certsvc_instance_new() is failed.");
241                 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
242                 return false;
243         }
244
245         r = certsvc_certificate_new_from_memory(instance,
246                         (const unsigned char *)cert_value,
247                         strlen(cert_value),
248                         CERTSVC_FORM_DER_BASE64,
249                         &certificate);
250         if (r != CERTSVC_SUCCESS) {
251                 _E("certsvc_certificate_new_from_memory() is failed.");
252                 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
253                 certsvc_instance_free(instance);
254                 return false;
255         }
256
257         r = certsvc_certificate_get_visibility(certificate, &visibility);
258         if (r != CERTSVC_SUCCESS)
259                 _E("certsvc_certificate_get_visibility() is failed.");
260
261         pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
262         certsvc_certificate_free(certificate);
263         certsvc_instance_free(instance);
264
265         _D("visibility is %d", visibility);
266         if (visibility & CERTSVC_VISIBILITY_PLATFORM) {
267                 _D("%s has a platform certification", pkgid);
268                 return true;
269         }
270
271         return false;
272 }
273
274 static int __esd_check_event_launch_support(const char *event_name)
275 {
276         int i = 0;
277         int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list);
278
279         for (i = 0; i < size; i++) {
280                 if (strcmp(event_launch_support_list[i], event_name) == 0)
281                         return true;
282         }
283
284         return false;
285 }
286
287 static int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type)
288 {
289         GDBusMessage *msg = NULL;
290         GDBusMessage *reply = NULL;
291         GError *err = NULL;
292         GVariant *body;
293         int ret = -1;
294         unsigned int value;
295
296         msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
297                 "org.freedesktop.DBus", type);
298         if (!msg) {
299                 _E("Can't allocate new method call");
300                 goto out;
301         }
302
303         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
304         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
305                 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
306
307         if (!reply) {
308                 if (err != NULL) {
309                         _E("Failed to get info [%s]", err->message);
310                         g_error_free(err);
311                 }
312                 goto out;
313         }
314
315         body = g_dbus_message_get_body(reply);
316         g_variant_get(body, "(u)", &value);
317         ret = (int)value;
318
319 out:
320         if (msg)
321                 g_object_unref(msg);
322         if (reply)
323                 g_object_unref(reply);
324
325         return ret;
326 }
327
328 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
329 {
330         int pid = 0;
331
332         pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID");
333         if (pid < 0) {
334                 _E("failed to get pid");
335                 pid = 0;
336         }
337
338         _D("sender_name(%s), pid(%d)", sender_name, pid);
339
340         return pid;
341 }
342
343 static int __get_sender_uid(GDBusConnection *conn, const char *sender_name)
344 {
345         int uid = -1;
346
347         uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser");
348         if (uid < 0)
349                 _E("failed to get uid");
350
351         _D("sender_name(%s), uid(%d)", sender_name, uid);
352
353         return uid;
354 }
355
356 static int __esd_check_certificate_match(uid_t uid, const char *app_id, uid_t from_uid, const char *from_appid)
357 {
358         pkgmgrinfo_cert_compare_result_type_e res;
359         int ret = 0;
360
361         _D("uid(%d), app_id(%s), from_uid(%d), from_appid(%s)", uid, app_id, from_uid, from_appid);
362
363         ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, from_appid, from_uid, &res);
364         if (ret < 0) {
365                 _E("failed to check certificate");
366                 return ES_R_ERROR;
367         }
368
369         if (res != PMINFO_CERT_COMPARE_MATCH) {
370                 _D("certificat not match (%s)", app_id);
371                 return ES_R_EINVAL;
372         }
373
374         return ES_R_OK;
375 }
376
377 static bool __esd_check_application_validation(uid_t uid, const char *appid)
378 {
379         int ret = 0;
380         pkgmgrinfo_appinfo_h handle;
381
382         ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle);
383         if (ret != PMINFO_R_OK)
384                 return false;
385
386         pkgmgrinfo_appinfo_destroy_appinfo(handle);
387
388         if (!aul_app_is_running_for_uid(appid, uid))
389                 return false;
390
391         return true;
392 }
393
394 static void __esd_trusted_busname_print_items(void)
395 {
396         GHashTableIter iter;
397         gpointer key;
398         gpointer value;
399
400         g_hash_table_iter_init(&iter, trusted_busname_table);
401
402         while (g_hash_table_iter_next(&iter, &key, &value)) {
403                 trusted_item *item = (trusted_item *)value;
404                 if (item)
405                         _D("uid(%d), appid(%s), pid(%d), busname(%s)", item->uid, item->app_id, item->pid, item->bus_name);
406         }
407 }
408
409 static int __esd_trusted_busname_add_item(uid_t uid, const char *appid, const char *busname, int pid)
410 {
411         char *app_id = NULL;
412         char *bus_name = NULL;
413         trusted_item *item = NULL;
414         trusted_item *new_item;
415
416         app_id = strdup(appid);
417         if (app_id == NULL) {
418                 _E("out of memory");
419                 return ES_R_ENOMEM;
420         }
421
422         bus_name = strdup(busname);
423         if (bus_name == NULL) {
424                 _E("out of memory");
425                 FREE_AND_NULL(app_id);
426                 return ES_R_ENOMEM;
427         }
428
429         item = (trusted_item *)g_hash_table_lookup(trusted_busname_table, app_id);
430
431         if (item && item->bus_name && strcmp(item->bus_name, bus_name) == 0 &&
432                 (item->uid == uid)) {
433                 _D("already exist (%s, %s)", app_id, bus_name);
434                 FREE_AND_NULL(app_id);
435                 FREE_AND_NULL(bus_name);
436         } else {
437                 new_item = calloc(1, sizeof(trusted_item));
438                 if (new_item == NULL) {
439                         _E("memory alloc failed");
440                         FREE_AND_NULL(app_id);
441                         FREE_AND_NULL(bus_name);
442                         return ES_R_ENOMEM;
443                 }
444                 new_item->uid = uid;
445                 new_item->app_id = app_id;
446                 new_item->bus_name = bus_name;
447                 new_item->pid = pid;
448                 g_hash_table_insert(trusted_busname_table, new_item->app_id, new_item);
449                 _D("added busname(%s)", new_item->bus_name);
450         }
451
452         return ES_R_OK;
453 }
454
455 static int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name)
456 {
457         GVariant *result;
458         GError *error = NULL;
459         GVariantIter *iter;
460         gchar *str;
461         char tmp_appid[128] = {0, };
462         int pid = 0;
463         int uid = 0;
464         int ret = 0;
465
466         result = g_dbus_connection_call_sync(conn,
467                 "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
468                 list_name, NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE,
469                 -1, NULL, &error);
470
471         if (result == NULL) {
472                 _E("get (%s) error(%s)", list_name, error->message);
473                 g_error_free(error);
474                 return ES_R_ERROR;
475         }
476
477         g_variant_get(result, "(as)", &iter);
478         while (g_variant_iter_loop(iter, "s", &str)) {
479                 if (!strstr((const char *)str, "event.busname.session"))
480                         continue;
481
482                 _D("list(%s), name(%s)", list_name, str);
483                 pid = __get_sender_pid(conn, (const char *)str);
484                 if (pid <= 0) {
485                         _E("failed to get pid(%d)", pid);
486                         continue;
487                 }
488
489                 uid = __get_sender_uid(conn, (const char *)str);
490                 if (uid < 0) {
491                         _E("failed to get uid(%d)", uid);
492                         continue;
493                 }
494                 _D("uid(%d)", uid);
495
496                 memset(tmp_appid, 0, sizeof(tmp_appid));
497                 ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), (uid_t)uid);
498                 if (ret != AUL_R_OK) {
499                         _E("failed to get appid by pid(%d)", pid);
500                         continue;
501                 }
502
503                 _D("appid(%s)", tmp_appid);
504                 if (__esd_check_application_validation((uid_t)uid, tmp_appid)) {
505                         _D("add to table");
506                         ret = __esd_trusted_busname_add_item((uid_t)uid, tmp_appid, (const char *)str, pid);
507                         if (ret < 0)
508                                 _E("failed to add item");
509                 }
510         }
511         g_variant_iter_free(iter);
512         g_variant_unref(result);
513
514         return ES_R_OK;
515 }
516
517 static int __esd_check_privilege_name(const char *event_name, char **privilege_name)
518 {
519         int i = 0;
520
521         *privilege_name = NULL;
522
523         for (i = 0; i < privilege_check_size; i++) {
524                 if (strcmp(event_name, privilege_check_list[i].event_name) == 0) {
525                         *privilege_name = (char *)privilege_check_list[i].privilege_name;
526                         _D("[%d] privilege_name(%s)", i, *privilege_name);
527                         break;
528                 }
529         }
530
531         return ES_R_OK;
532 }
533
534 static bool __esd_check_valid_privilege_by_cynara(const char *appid, const char *client,
535         const char *session, const char *user, const char *privilege_name)
536 {
537         int ret = 0;
538         bool has_privilege = false;
539
540         _D("check privilege, (%s, %s, %s, %s, %s)", appid, client, session, user, privilege_name);
541
542         ret = cynara_check(r_cynara, client, session, user, privilege_name);
543         if (ret == CYNARA_API_ACCESS_ALLOWED) {
544                 _D("valid privilege");
545                 has_privilege = true;
546         } else if (ret == CYNARA_API_ACCESS_DENIED) {
547                 _E("invalid privilege");
548         } else {
549                 _E("failed to check privilege, error(%d)", ret);
550         }
551
552         return has_privilege;
553 }
554
555 static int __esd_check_app_privileged_event(uid_t uid, const char *appid, const char *pkgid, const char *event_name)
556 {
557         char *privilege_name = NULL;
558         int ret = 0;
559         int result = 0;
560
561         _D("event_name(%s), uid(%d), appid(%s), pkgid(%s)", event_name, uid, appid, pkgid);
562
563         __esd_check_privilege_name(event_name, &privilege_name);
564
565         if (privilege_name) {
566                 ret = security_manager_app_has_privilege(appid, privilege_name, uid, &result);
567                 if (ret != SECURITY_MANAGER_SUCCESS)
568                         _E("failed to check privilege(%d)", ret);
569                 _D("result(%d)", result);
570         } else {
571                 result = 1;
572         }
573
574         return result;
575 }
576
577 static void __esd_print_appid_with_eventid(gpointer data, gpointer user_data)
578 {
579         esd_list_item_s *item = (esd_list_item_s *)data;
580         char *event_name = (char *)user_data;
581
582         _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name, item->uid, item->app_id, item->pkg_id);
583 }
584
585 static void __esd_print_interested_event(gpointer data, gpointer user_data)
586 {
587         event_launch_item *el_item = (event_launch_item *)data;
588         char *event_name = (char *)el_item->event_name;
589         _D("event_name = (%s)", event_name);
590         g_list_foreach(el_item->app_list_evtlaunch, __esd_print_appid_with_eventid, event_name);
591 }
592
593 static void __esd_launch_table_print_items(void)
594 {
595         GHashTableIter iter;
596         gpointer key;
597         gpointer value;
598
599         g_hash_table_iter_init(&iter, event_launch_table);
600
601         while (g_hash_table_iter_next(&iter, &key, &value))
602                 __esd_print_interested_event(value, NULL);
603 }
604
605 static int __esd_find_compare_by_list_item(gconstpointer data, gconstpointer user_data)
606 {
607         esd_list_item_s *item_1 = (esd_list_item_s *)user_data;
608         esd_list_item_s *item_2 = (esd_list_item_s *)data;
609
610         return (item_1->uid != item_2->uid) |
611                 strcmp(item_1->app_id, item_2->app_id) |
612                 strcmp(item_1->pkg_id, item_2->pkg_id);
613 }
614
615 static int __esd_add_list_item(uid_t uid, event_launch_item *el_item,
616                 const char *app_id, const char *pkg_id)
617 {
618         esd_list_item_s *item_of_list = NULL;
619
620         item_of_list = calloc(1, sizeof(esd_list_item_s));
621         if (item_of_list == NULL) {
622                 _E("out_of_memory");
623                 return ES_R_ENOMEM;
624         }
625         item_of_list->uid = uid;
626         item_of_list->app_id = (char *)app_id;
627         item_of_list->pkg_id = (char *)pkg_id;
628         item_of_list->trusted_info = TRUSTED_UNKNOWN;
629         el_item->app_list_evtlaunch =
630                 g_list_append(el_item->app_list_evtlaunch, item_of_list);
631
632         return ES_R_OK;
633 }
634
635 static int __esd_add_launch_item(uid_t uid, const char *event_name,
636                 const char *appid, const char *pkgid)
637 {
638         GList *app_list = NULL;
639         guint subscription_id = 0;
640         char *app_id = NULL;
641         char *pkg_id = NULL;
642         esd_list_item_s *item_of_list = NULL;
643         event_launch_item *eli;
644         event_launch_item *el_item =
645                 (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
646
647         if (el_item) {
648                 item_of_list = calloc(1, sizeof(esd_list_item_s));
649                 if (item_of_list == NULL) {
650                         _E("memory alloc failed");
651                         return ES_R_ENOMEM;
652                 }
653                 item_of_list->uid = uid;
654                 item_of_list->app_id = (char *)appid;
655                 item_of_list->pkg_id = (char *)pkgid;
656
657                 app_list = g_list_find_custom(el_item->app_list_evtlaunch,
658                         item_of_list, (GCompareFunc)__esd_find_compare_by_list_item);
659                 free(item_of_list);
660                 if (app_list == NULL) {
661                         _D("add new item (list item only)");
662                         app_id = strdup((char *)appid);
663                         if (!app_id) {
664                                 _E("out_of_memory");
665                                 return ES_R_ENOMEM;
666                         }
667                         pkg_id = strdup((char *)pkgid);
668                         if (!pkg_id) {
669                                 _E("out_of_memory");
670                                 FREE_AND_NULL(app_id);
671                                 return ES_R_ENOMEM;
672                         }
673                         if (__esd_add_list_item(uid, el_item, app_id, pkg_id) < 0) {
674                                 _E("failed to add list item");
675                                 FREE_AND_NULL(app_id);
676                                 FREE_AND_NULL(pkg_id);
677                                 return ES_R_ERROR;
678                         }
679                 }
680         } else {
681                 _D("add new item (all)");
682                 eli = calloc(1, sizeof(event_launch_item));
683                 if (!eli) {
684                         _E("memory alloc failed");
685                         return ES_R_ENOMEM;
686                 }
687
688                 eli->event_name = strdup(event_name);
689                 if (!eli->event_name) {
690                         _E("out_of_memory");
691                         FREE_AND_NULL(eli);
692                         return ES_R_ENOMEM;
693                 }
694
695                 app_id = strdup((char *)appid);
696                 if (!app_id) {
697                         _E("out_of_memory");
698                         FREE_AND_NULL(eli->event_name);
699                         FREE_AND_NULL(eli);
700                         return ES_R_ENOMEM;
701                 }
702
703                 pkg_id = strdup((char *)pkgid);
704                 if (!pkg_id) {
705                         _E("out_of_memory");
706                         FREE_AND_NULL(app_id);
707                         FREE_AND_NULL(eli->event_name);
708                         FREE_AND_NULL(eli);
709                         return ES_R_ENOMEM;
710                 }
711
712                 if (__esd_add_list_item(uid, eli, app_id, pkg_id) < 0) {
713                         _E("failed to add list item");
714                         FREE_AND_NULL(app_id);
715                         FREE_AND_NULL(pkg_id);
716                         FREE_AND_NULL(eli->event_name);
717                         FREE_AND_NULL(eli);
718                         return ES_R_ERROR;
719                 }
720
721                 g_hash_table_insert(event_launch_table, eli->event_name, eli);
722
723                 eventsystem_register_event(eli->event_name, &subscription_id,
724                         (eventsystem_handler)__esd_event_handler, NULL);
725                 if (subscription_id == 0) {
726                         _E("signal subscription error, event_name(%s), app_id(%s)",
727                                 eli->event_name, app_id);
728                         return ES_R_ERROR;
729                 } else {
730                         eli->reg_id = subscription_id;
731                 }
732         }
733
734         return ES_R_OK;
735 }
736
737 static void __esd_remove_all_private_usr_app_list(gpointer data, gpointer user_data)
738 {
739         esd_list_item_s *item = (esd_list_item_s *)data;
740         event_launch_item *eli = (event_launch_item *)user_data;
741
742         if (item->uid != GLOBAL_USER && !strcmp(eli->package_name, item->pkg_id)) {
743                 _D("uid(%d), app_id(%s), pkg_id(%s)", item->uid, item->app_id, eli->package_name);
744                 eli->app_list_evtlaunch = g_list_remove_all(eli->app_list_evtlaunch, data);
745         }
746 }
747
748 static int __esd_launch_table_remove_private_usr_items(void)
749 {
750         GHashTableIter iter;
751         gpointer key;
752         gpointer value;
753         event_launch_item *eli = NULL;
754         GList *first_list = NULL;
755
756         g_hash_table_iter_init(&iter, event_launch_table);
757
758         while (g_hash_table_iter_next(&iter, &key, &value)) {
759                 eli = (event_launch_item *)value;
760                 g_list_foreach(eli->app_list_evtlaunch, __esd_remove_all_private_usr_app_list, eli);
761
762                 first_list = g_list_first(eli->app_list_evtlaunch);
763                 if (first_list == NULL) {
764                         if (eli->reg_id)
765                                 eventsystem_unregister_event(eli->reg_id);
766
767                         g_hash_table_iter_remove(&iter);
768                 }
769         }
770
771         return ES_R_OK;
772 }
773
774 static void __esd_remove_app_list(gpointer data, gpointer user_data)
775 {
776         bool skip = false;
777         esd_list_item_s *item = (esd_list_item_s *)data;
778         event_launch_item *eli = (event_launch_item *)user_data;
779
780         if (eli->uid != GLOBAL_USER && eli->uid != item->uid)
781                 skip = true;
782
783         if (!skip && !strcmp(eli->package_name, item->pkg_id)) {
784                 _D("pkg_id(%s), app_id(%s)", eli->package_name, item->app_id);
785                 eli->app_list_evtlaunch =
786                         g_list_remove_all(eli->app_list_evtlaunch, data);
787         }
788 }
789
790 static int __esd_remove_launch_item(uid_t uid, gpointer data, const char *pkg_id)
791 {
792         event_launch_item *eli = (event_launch_item *)data;
793         GList *first_list = NULL;
794
795         eli->uid = uid;
796         eli->package_name = (char *)pkg_id;
797         g_list_foreach(eli->app_list_evtlaunch, __esd_remove_app_list, eli);
798
799         first_list = g_list_first(eli->app_list_evtlaunch);
800         if (first_list == NULL) {
801                 if (eli->reg_id)
802                         eventsystem_unregister_event(eli->reg_id);
803
804                 return ES_R_REMOVE;
805         }
806
807         return ES_R_OK;
808 }
809
810 static int __esd_launch_table_remove_items(uid_t uid, const char *pkg_id)
811 {
812         GHashTableIter iter;
813         gpointer key;
814         gpointer value;
815
816         g_hash_table_iter_init(&iter, event_launch_table);
817
818         while (g_hash_table_iter_next(&iter, &key, &value)) {
819                 if (__esd_remove_launch_item(uid, value, pkg_id) == ES_R_REMOVE) {
820                         _D("remove item itself");
821                         g_hash_table_iter_remove(&iter);
822                 }
823         }
824
825         return ES_R_OK;
826 }
827
828 static void __esd_event_launch_with_appid(gpointer data, gpointer user_data)
829 {
830         esd_list_item_s *item = (esd_list_item_s *)data;
831         uid_t uid = item->uid;
832         char *app_id = item->app_id;
833         esd_event_param *eep = (esd_event_param *)user_data;
834         static unsigned int req_id;
835         int pid;
836         char event_uri[1024];
837         bundle *b;
838         int ret;
839
840         _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d), trusted(%d)",
841                         app_id, eep->event_name, uid, eep->is_user_event, eep->trusted);
842
843         if (eep->is_user_event && eep->trusted) {
844                 if (item->trusted_info == TRUSTED_UNKNOWN) {
845                         ret = __esd_check_certificate_match(uid, app_id, eep->sender_uid, eep->sender_appid);
846                         if (ret == ES_R_EINVAL) {
847                                 item->trusted_info = TRUSTED_DENIED;
848                                 return;
849                         } else if (ret == ES_R_ERROR) {
850                                 return;
851                         } else {
852                                 item->trusted_info = TRUSTED_ALLOWED;
853                         }
854                 } else if (item->trusted_info == TRUSTED_DENIED) {
855                         return;
856                 }
857         }
858
859         if (!aul_app_is_running_for_uid(app_id, uid)) {
860                 b = bundle_dup(eep->event_data);
861                 if (eep->is_user_event)
862                         snprintf(event_uri, sizeof(event_uri), "%s%s", USER_EVENT_NAME_PREFIX, eep->event_name);
863                 else
864                         snprintf(event_uri, sizeof(event_uri), "%s%s", SYSTEM_EVENT_NAME_PREFIX, eep->event_name);
865
866                 appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT);
867                 appsvc_set_uri(b, event_uri);
868                 appsvc_set_appid(b, app_id);
869
870                 pid = aul_svc_run_service_async_for_uid(b, req_id++, NULL, eep->user_data, uid);
871                 _D("uid(%d), pid(%d)", uid, pid);
872
873                 bundle_free(b);
874         } else {
875                 _D("already is running or launch failed");
876         }
877 }
878
879 static void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_data)
880 {
881         event_launch_item *el_item = (event_launch_item *)data;
882         esd_event_param *eep = (esd_event_param *)user_data;
883
884         if (strcmp(eep->event_name, (char *)el_item->event_name) == 0) {
885                 g_list_foreach(el_item->app_list_evtlaunch,
886                         __esd_event_launch_with_appid, user_data);
887         }
888 }
889
890 static void __esd_launch_event_handler(char *event_name, bundle *data,
891                 const bool is_user_event, gboolean trusted,
892                 const uid_t sender_uid, char *sender_appid, void *user_data)
893 {
894         const char *val;
895         const char *msg_type;
896         const char *msg_id;
897         esd_event_param *eep;
898         event_launch_item *el_item;
899
900         _D("event_name(%s)", event_name);
901
902         el_item = (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
903         if (el_item == NULL)
904                 return;
905
906         if (el_item->app_list_evtlaunch != NULL) {
907                 if (is_user_event == false) {
908                         if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) {
909                                 val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS);
910                                 _D("charger val(%s)", val);
911                                 if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0))
912                                         return;
913                         } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) {
914                                 val = bundle_get_val(data, EVT_KEY_USB_STATUS);
915                                 _D("usb val(%s)", val);
916                                 if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0))
917                                         return;
918                         } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) {
919                                 val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS);
920                                 _D("earjack val(%s)", val);
921                                 if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0))
922                                         return;
923                         } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) {
924                                 msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE);
925                                 _D("msg_type(%s)", msg_type);
926                                 if (msg_type == NULL)
927                                         return;
928
929                                 msg_id = bundle_get_val(data, EVT_KEY_MSG_ID);
930                                 _D("msg_id(%s)", msg_id);
931                                 if (msg_id == NULL)
932                                         return;
933                         } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) {
934                                 val = bundle_get_val(data, EVT_KEY_WIFI_STATE);
935                                 if (val == NULL)
936                                         return;
937                                 _D("wifi_state(%s)", val);
938                                 if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0)
939                                         return;
940                         }
941                 }
942
943                 eep = calloc(1, sizeof(esd_event_param));
944                 if (!eep) {
945                         _E("memory alloc failed");
946                         return;
947                 }
948                 eep->event_name = event_name;
949                 eep->event_data = data;
950                 eep->sender_uid = sender_uid;
951                 eep->sender_appid = sender_appid;
952                 eep->is_user_event = is_user_event;
953                 eep->trusted = (bool)trusted;
954                 eep->user_data = (void *)user_data;
955                 __esd_check_event_launch_with_eventid(el_item, eep);
956                 free(eep);
957         }
958 }
959
960 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
961 static void __esd_print_earlier_event(gpointer data, gpointer user_data)
962 {
963         earlier_item *item = (earlier_item *)data;
964         char *event_name = (char *)item->event_name;
965         const char *val;
966
967         _D("event_name = (%s)", event_name);
968
969         if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
970                 if (item->earlier_data) {
971                         val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED);
972                         _D("boot_completed(%s)", val);
973                 }
974         } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
975                 if (item->earlier_data) {
976                         val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN);
977                         _D("shutdown(%s)", val);
978                 }
979         } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
980                 if (item->earlier_data) {
981                         val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY);
982                         _D("low_memory(%s)", val);
983                 }
984         } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
985                 if (item->earlier_data) {
986                         val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS);
987                         _D("charger_status(%s)", val);
988                 }
989         }
990 }
991
992 static void __esd_earlier_table_print_items(void)
993 {
994         GHashTableIter iter;
995         gpointer key;
996         gpointer value;
997
998         g_hash_table_iter_init(&iter, earlier_event_table);
999
1000         while (g_hash_table_iter_next(&iter, &key, &value))
1001                 __esd_print_earlier_event(value, NULL);
1002 }
1003
1004 static void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data)
1005 {
1006         earlier_item *item;
1007         _D("event_name(%s)", event_name);
1008
1009         item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1010         if (item) {
1011                 /* update earlier value */
1012                 if (item->earlier_data != NULL)
1013                         bundle_free(item->earlier_data);
1014
1015                 item->earlier_data = bundle_dup(data);
1016         }
1017 }
1018 #endif
1019
1020 static void __esd_event_handler(char *event_name, bundle *data, void *user_data)
1021 {
1022         _D("event_name(%s)", event_name);
1023
1024 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1025         if (__esd_check_earlier_support(event_name))
1026                 __esd_earlier_event_handler(event_name, data, user_data);
1027 #endif
1028
1029         if (__esd_check_event_launch_support(event_name))
1030                 __esd_launch_event_handler(event_name, data,
1031                                 false, TRUE, ROOT_USER, NULL, user_data);
1032 }
1033
1034 static void __esd_trusted_busname_remove_item(char *bus_name)
1035 {
1036         GHashTableIter iter;
1037         gpointer key;
1038         gpointer value;
1039         trusted_item *item;
1040
1041         g_hash_table_iter_init(&iter, trusted_busname_table);
1042
1043         while (g_hash_table_iter_next(&iter, &key, &value)) {
1044                 item = (trusted_item *)value;
1045                 if (item) {
1046                         if (strcmp(bus_name, item->bus_name) == 0) {
1047                                 _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name);
1048                                 FREE_AND_NULL(item->app_id);
1049                                 FREE_AND_NULL(item->bus_name);
1050                                 FREE_AND_NULL(item);
1051                                 g_hash_table_iter_remove(&iter);
1052
1053                                 __esd_trusted_busname_print_items();
1054                         }
1055                 }
1056         }
1057 }
1058
1059 static void __esd_filter_name_owner_changed(GDBusConnection *connection,
1060                 const gchar *sender_name, const gchar *object_path,
1061                 const gchar *interface_name, const gchar *signal_name,
1062                 GVariant *parameters, gpointer user_data)
1063 {
1064         char *name = NULL;
1065         char *old_owner = NULL;
1066         char *new_owner = NULL;
1067         int old_len = 0;
1068         int new_len = 0;
1069
1070         g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
1071
1072         if (strstr(name, "event.busname.session")) {
1073                 old_len = strlen(old_owner);
1074                 new_len = strlen(new_owner);
1075
1076                 _D("changed name(%s), old_onwer(%s)(%d) -> new_onwer(%s)(%d)",
1077                         name, old_owner, old_len, new_owner, new_len);
1078
1079                 if (old_len > 0 && new_len == 0)
1080                         __esd_trusted_busname_remove_item(name);
1081                 else if (old_len == 0 && new_len > 0)
1082                         _D("new name owned");
1083                 else
1084                         _E("not-expected name change");
1085         }
1086 }
1087
1088 static int __esd_dbus_name_monitor(GDBusConnection *connection)
1089 {
1090         guint name_owner_changed_id = 0;
1091
1092         name_owner_changed_id = g_dbus_connection_signal_subscribe(connection,
1093                 "org.freedesktop.DBus", "org.freedesktop.DBus",
1094                 "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1095                 __esd_filter_name_owner_changed, NULL, NULL);
1096
1097         _I("name_owner_changed_id(%d)", name_owner_changed_id);
1098
1099         return ES_R_OK;
1100 }
1101
1102 static int __esd_get_user_items(uid_t uid)
1103 {
1104         int ret = 0;
1105         pkgmgrinfo_appinfo_filter_h handle = NULL;
1106
1107         _I("get user items for uid(%d)", uid);
1108         /* reset user's item */
1109         __esd_launch_table_remove_private_usr_items();
1110
1111         ret = pkgmgrinfo_appinfo_filter_create(&handle);
1112         if (ret < 0) {
1113                 _E("failed to create appinfo filter");
1114                 return ES_R_ERROR;
1115         }
1116         ret = pkgmgrinfo_appinfo_filter_add_string(handle,
1117                         PMINFO_APPINFO_PROP_APP_COMPONENT, "svcapp");
1118         if (ret < 0) {
1119                 _E("failed to add appinfo filter string");
1120                 pkgmgrinfo_appinfo_filter_destroy(handle);
1121                 return ES_R_ERROR;
1122         }
1123         ret = pkgmgrinfo_appinfo_filter_add_string(handle,
1124                         PMINFO_APPINFO_PROP_APP_OPERATION, APPSVC_OPERATION_LAUNCH_ON_EVENT);
1125         if (ret < 0) {
1126                 _E("failed to add appinfo filter string");
1127                 pkgmgrinfo_appinfo_filter_destroy(handle);
1128                 return ES_R_ERROR;
1129         }
1130         ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle,
1131                         __esd_add_appinfo_handler, &uid, uid);
1132         if (ret < 0) {
1133                 _E("appinfo filter foreach error");
1134                 pkgmgrinfo_appinfo_filter_destroy(handle);
1135                 return ES_R_ERROR;
1136         }
1137         pkgmgrinfo_appinfo_filter_destroy(handle);
1138
1139         __esd_launch_table_print_items();
1140
1141         return ES_R_OK;
1142 }
1143
1144 static void __esd_signal_handler(GDBusConnection *connection,
1145                 const gchar *sender_name,
1146                 const gchar *object_path,
1147                 const gchar *interface_name,
1148                 const gchar *signal_name,
1149                 GVariant *parameters,
1150                 gpointer user_data)
1151 {
1152         int handle;
1153         bundle *b;
1154         guint64 uid = 0;
1155
1156         if (!g_strcmp0(signal_name,
1157                                 SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED)) {
1158                 _I("System session finished");
1159
1160                 b = bundle_create();
1161                 bundle_add_str(b, EVT_KEY_BOOT_COMPLETED,
1162                         EVT_VAL_BOOT_COMPLETED_TRUE);
1163                 eventsystem_send_system_event(SYS_EVENT_BOOT_COMPLETED, b);
1164                 bundle_free(b);
1165
1166                 handle = creat(ESD_BOOT_COMPLETED, 0640);
1167                 if (handle != -1)
1168                         close(handle);
1169         } else if (!g_strcmp0(signal_name,
1170                                 SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED)) {
1171                 g_variant_get(parameters, "(t)", &uid);
1172                 _I("User session finished uid : %d", (int)uid);
1173                 if ((uid_t)uid != DEFAULT_USER)
1174                         __esd_get_user_items((uid_t)uid);
1175         }
1176 }
1177
1178 static GDBusNodeInfo *introspection_data;
1179 static const gchar introspection_xml[] =
1180 "<node>"
1181 "       <interface name='tizen.system.event.app2esd'>"
1182 "               <method name='CheckSenderValidation'>"
1183 "                       <arg type='i' name='senderpid' direction='in'/>"
1184 "                       <arg type='s' name='eventname' direction='in'/>"
1185 "                       <arg type='i' name='ret' direction='out'/>"
1186 "                       <arg type='s' name='senderid' direction='out'/>"
1187 "               </method>"
1188 "               <method name='GetTrustedPeerList'>"
1189 "                       <arg type='s' name='eventname' direction='in'/>"
1190 "                       <arg type='i' name='ret' direction='out'/>"
1191 "                       <arg type='as' name='dest_list' direction='out'/>"
1192 "               </method>"
1193 "               <method name='SetupTrustedPeer'>"
1194 "                       <arg type='s' name='eventname' direction='in'/>"
1195 "                       <arg type='s' name='destination' direction='in'/>"
1196 "                       <arg type='i' name='ret' direction='out'/>"
1197 "               </method>"
1198 "               <method name='CheckPrivilegeValidation'>"
1199 "                       <arg type='s' name='eventname' direction='in'/>"
1200 "                       <arg type='i' name='ret' direction='out'/>"
1201 "               </method>"
1202 "               <method name='CheckUserSendValidation'>"
1203 "                       <arg type='s' name='eventname' direction='in'/>"
1204 "                       <arg type='i' name='ret' direction='out'/>"
1205 "               </method>"
1206 "               <method name='RequestTrustedEventLaunch'>"
1207 "                       <arg type='s' name='eventname' direction='in'/>"
1208 "                       <arg type='s' name='eventdata' direction='in'/>"
1209 "                       <arg type='i' name='datalen' direction='in'/>"
1210 "                       <arg type='i' name='ret' direction='out'/>"
1211 "               </method>"
1212 "               <method name='RequestEventLaunch'>"
1213 "                       <arg type='s' name='eventname' direction='in'/>"
1214 "                       <arg type='s' name='eventdata' direction='in'/>"
1215 "                       <arg type='i' name='datalen' direction='in'/>"
1216 "                       <arg type='i' name='ret' direction='out'/>"
1217 "               </method>"
1218 "               <method name='RequestSendingEvent'>"
1219 "                       <arg type='s' name='eventname' direction='in'/>"
1220 "                       <arg type='s' name='eventdata' direction='in'/>"
1221 "                       <arg type='i' name='datalen' direction='in'/>"
1222 "                       <arg type='i' name='ret' direction='out'/>"
1223 "               </method>"
1224 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1225 "               <method name='GetEarlierData'>"
1226 "                       <arg type='s' name='appid' direction='in'/>"
1227 "                       <arg type='i' name='ret' direction='out'/>"
1228 "                       <arg type='i' name='len' direction='out'/>"
1229 "                       <arg type='s' name='earlier_data' direction='out'/>"
1230 "               </method>"
1231 #endif
1232 "               <method name='KeepLastData'>"
1233 "                       <arg type='s' name='eventname' direction='in'/>"
1234 "                       <arg type='s' name='own_name' direction='in'/>"
1235 "                       <arg type='i' name='ret' direction='out'/>"
1236 "               </method>"
1237 "               <method name='CheckLastData'>"
1238 "                       <arg type='s' name='eventname' direction='in'/>"
1239 "                       <arg type='s' name='own_name' direction='in'/>"
1240 "                       <arg type='i' name='ret' direction='out'/>"
1241 "               </method>"
1242 "               <method name='LaunchOnEventFromUserEvent'>"
1243 "                       <arg type='s' name='eventname' direction='in'/>"
1244 "                       <arg type='s' name='eventdata' direction='in'/>"
1245 "                       <arg type='i' name='datalen' direction='in'/>"
1246 "                       <arg type='b' name='trusted' direction='in'/>"
1247 "                       <arg type='i' name='ret' direction='out'/>"
1248 "               </method>"
1249 "               <method name='CionGetUuid'>"
1250 "                       <arg type='i' name='ret' direction='out'/>"
1251 "                       <arg type='s' name='uuid' direction='out'/>"
1252 "               </method>"
1253 "               <method name='CionSetDisplayName'>"
1254 "                       <arg type='s' name='service_name' direction='in'/>"
1255 "                       <arg type='s' name='display_name' direction='in'/>"
1256 "                       <arg type='i' name='ret' direction='out'/>"
1257 "               </method>"
1258 "               <method name='CionGetDisplayName'>"
1259 "                       <arg type='s' name='service_name' direction='in'/>"
1260 "                       <arg type='i' name='ret' direction='out'/>"
1261 "                       <arg type='s' name='display_name' direction='out'/>"
1262 "               </method>"
1263 "               <method name='CionSetEnabled'>"
1264 "                       <arg type='s' name='service_name' direction='in'/>"
1265 "                       <arg type='b' name='enabled' direction='in'/>"
1266 "                       <arg type='i' name='ret' direction='out'/>"
1267 "               </method>"
1268 "               <method name='CionGetEnabled'>"
1269 "                       <arg type='s' name='service_name' direction='in'/>"
1270 "                       <arg type='i' name='ret' direction='out'/>"
1271 "                       <arg type='b' name='enabled' direction='out'/>"
1272 "               </method>"
1273 "       </interface>"
1274 "</node>";
1275
1276 static int __esd_get_appid_by_pid_for_uid(int pid, uid_t uid, char *app_id, int buf_size)
1277 {
1278         int retval = ES_R_OK;
1279         int ret = 0;
1280
1281         if (pid <= 0) {
1282                 _E("invalid pid(%d)", pid);
1283                 retval = ES_R_ERROR;
1284         } else if (uid <= 0) {
1285                 _E("invalid uid(%d)", uid);
1286                 retval = ES_R_ERROR;
1287         } else {
1288                 ret = aul_app_get_appid_bypid_for_uid(pid, app_id, buf_size, (uid_t)uid);
1289                 if (ret != AUL_R_OK) {
1290                         _E("failed to get appid by pid");
1291                         retval = ES_R_ERROR;
1292                 }
1293                 _D("pid(%d)-uid(%d)-appid(%s)", pid, uid, app_id);
1294         }
1295
1296         return retval;
1297 }
1298
1299 static int __esd_get_appid_by_pid(int pid, char *app_id, int buf_size)
1300 {
1301         int ret;
1302         int fd;
1303         char buf[128] = { 0, };
1304
1305         ret = aul_app_get_appid_bypid(pid, app_id, buf_size);
1306         if (ret != AUL_R_OK) {
1307                 snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
1308
1309                 fd = open(buf, O_RDONLY);
1310                 if (fd < 0)
1311                         return ES_R_ERROR;
1312
1313                 ret = read(fd, app_id, buf_size - 1);
1314                 close(fd);
1315
1316                 if (ret <= 0)
1317                         return ES_R_ERROR;
1318
1319                 app_id[ret] = '\0';
1320                 ret = ES_R_OK;
1321         }
1322
1323         return ret;
1324 }
1325
1326 static int check_user_event_sender_valid(const char *event_name, const char *app_id)
1327 {
1328         char *valid_name = NULL;
1329         char *temp_name = NULL;
1330         char *tmp = NULL;
1331         int retval = ES_R_OK;
1332         int len = 0;
1333         int valid_name_len = 0;
1334
1335         temp_name = strdup(event_name);
1336         if (temp_name == NULL) {
1337                 _E("out of memory");
1338                 return ES_R_ENOMEM;
1339         }
1340
1341         tmp = strrchr(temp_name, '.');
1342         if (tmp == NULL || strlen(tmp) == 0) {
1343                 _E("invalid event name");
1344                 FREE_AND_NULL(temp_name);
1345                 return ES_R_EINVAL;
1346         }
1347         len = strlen(tmp);
1348         if (len <= 1 || len > 128) {
1349                 _E("invalid length(%d) of user-defined name", len);
1350                 FREE_AND_NULL(temp_name);
1351                 return ES_R_EINVAL;
1352         }
1353         *tmp = '\0';
1354
1355         _D("app_id(%s), len(%zu)", app_id, strlen(app_id));
1356
1357         valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1;
1358         valid_name = calloc(1, valid_name_len);
1359         if (valid_name == NULL) {
1360                 _E("memory alloc failed");
1361                 FREE_AND_NULL(temp_name);
1362                 return ES_R_ENOMEM;
1363         }
1364         snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id);
1365         _D("valid_name(%s)", valid_name);
1366
1367         if (strcmp(temp_name, valid_name) != 0) {
1368                 _E("appid misamatch");
1369                 retval = ES_R_EINVAL;
1370         }
1371
1372         FREE_AND_NULL(temp_name);
1373         FREE_AND_NULL(valid_name);
1374
1375         return retval;
1376 }
1377
1378 static void check_sender_valid_method_call(GDBusConnection *connection, const gchar *sender,
1379         GVariant *parameters, GDBusMethodInvocation *invocation)
1380 {
1381         GVariant *param = NULL;
1382         int result = 0;
1383         char *event_name = NULL;
1384         char app_id[128] = {0, };
1385         int event_sender_pid = 0;
1386         uid_t sender_uid = 0;
1387
1388         g_variant_get(parameters, "(i&s)", &event_sender_pid, &event_name);
1389         _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name);
1390
1391         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1392         if (__esd_get_appid_by_pid_for_uid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1393                 result = ES_R_ERROR;
1394         } else {
1395                 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1396                         _E("invalid sender");
1397                         result = ES_R_EINVAL;
1398                 } else {
1399                         result = 1;
1400                 }
1401         }
1402
1403         param = g_variant_new("(is)", result, app_id);
1404         _D("event_name(%s), result(%d)", event_name, result);
1405         g_dbus_method_invocation_return_value(invocation, param);
1406 }
1407
1408 static void check_send_event_valid_method_call(GDBusConnection *connection, const gchar *sender,
1409         GVariant *parameters, GDBusMethodInvocation *invocation)
1410 {
1411         GVariant *param = NULL;
1412         int result = 0;
1413         char *event_name = NULL;
1414         char app_id[128] = {0, };
1415         int sender_pid = 0;
1416         uid_t sender_uid = 0;
1417
1418         g_variant_get(parameters, "(&s)", &event_name);
1419         _D("event_name(%s)", event_name);
1420
1421         sender_pid = __get_sender_pid(connection, sender);
1422         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1423         if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1424                 result = ES_R_ERROR;
1425         } else {
1426                 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1427                         _E("invalid sender");
1428                         result = ES_R_EINVAL;
1429                 } else {
1430                         result = 1;
1431                 }
1432         }
1433
1434         param = g_variant_new("(i)", result);
1435         _D("event_name(%s), result(%d)", event_name, result);
1436         g_dbus_method_invocation_return_value(invocation, param);
1437 }
1438
1439 static void get_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1440         GVariant *parameters, GDBusMethodInvocation *invocation)
1441 {
1442         GVariant *param = NULL;
1443         int result = 0;
1444         GVariantBuilder *builder = NULL;
1445         GHashTableIter iter;
1446         gpointer key, value;
1447         char *event_name = NULL;
1448         char app_id[128] = {0, };
1449         int sender_pid = 0;
1450         uid_t sender_uid = 0;
1451         int ret = 0;
1452         uid_t uid = 0;
1453         char *_appid = NULL;
1454         char *_busname = NULL;
1455         trusted_item *item;
1456
1457         g_variant_get(parameters, "(&s)", &event_name);
1458         _D("event_name(%s)", event_name);
1459
1460         sender_pid = __get_sender_pid(connection, sender);
1461         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1462         if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1463                 result = ES_R_ERROR;
1464         } else {
1465                 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1466
1467                 g_hash_table_iter_init(&iter, trusted_busname_table);
1468                 while (g_hash_table_iter_next(&iter, &key, &value)) {
1469                         item = (trusted_item *)value;
1470                         uid = item->uid;
1471                         _appid = item->app_id;
1472                         _busname = item->bus_name;
1473
1474                         if (uid != GLOBAL_USER && uid != sender_uid)
1475                                 continue;
1476
1477                         ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id);
1478                         if (ret == ES_R_OK)
1479                                 g_variant_builder_add(builder, "s", _busname);
1480                 }
1481
1482                 result = 1;
1483         }
1484
1485         param = g_variant_new("(ias)", result, builder);
1486         _D("result(%d)", result);
1487         g_dbus_method_invocation_return_value(invocation, param);
1488         if (builder)
1489                 g_variant_builder_unref(builder);
1490 }
1491
1492 static void setup_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1493         GVariant *parameters, GDBusMethodInvocation *invocation)
1494 {
1495         GVariant *param = NULL;
1496         int result = 0;
1497         char *event_name = NULL;
1498         char *destination_name = NULL;
1499         char app_id[128] = {0, };
1500         int sender_pid = 0;
1501         uid_t sender_uid = 0;
1502         int ret = 0;
1503
1504         g_variant_get(parameters, "(&s&s)", &event_name, &destination_name);
1505         _D("event_name(%s), destination_name(%s)", event_name, destination_name);
1506
1507         if (destination_name && destination_name[0] != '\0') {
1508                 sender_pid = __get_sender_pid(connection, sender);
1509                 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1510                 if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1511                         result = ES_R_ERROR;
1512                 } else {
1513                         ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name,
1514                                 sender_pid);
1515                         if (ret < 0) {
1516                                 _E("failed to add trusted busname item");
1517                                 result = ES_R_ERROR;
1518                         } else {
1519                                 result = 1;
1520                         }
1521                 }
1522         } else {
1523                 _E("invalid destination name");
1524                 result = ES_R_ERROR;
1525         }
1526
1527         param = g_variant_new("(i)", result);
1528         _D("event_name(%s), result(%d)", event_name, result);
1529         g_dbus_method_invocation_return_value(invocation, param);
1530 }
1531
1532 static void check_privilege_valid_method_call(GDBusConnection *connection, const gchar *sender,
1533         GVariant *parameters, GDBusMethodInvocation *invocation)
1534 {
1535         GVariant *param = NULL;
1536         int result = 0;
1537         char *event_name = NULL;
1538         char *privilege_name = NULL;
1539         char app_id[128] = {0, };
1540         int sender_pid = 0;
1541         uid_t sender_uid = 0;
1542         char *client = NULL;
1543         char *session = NULL;
1544         char *user = NULL;
1545         int ret = 0;
1546
1547         g_variant_get(parameters, "(&s)", &event_name);
1548         __esd_check_privilege_name(event_name, &privilege_name);
1549         _D("event_name(%s), privilege_name(%s)", event_name, privilege_name);
1550
1551         if (privilege_name) {
1552                 sender_pid = __get_sender_pid(connection, sender);
1553                 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1554                 if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1555                         result = ES_R_ERROR;
1556                 } else {
1557                         ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client);
1558                         if (ret != CYNARA_API_SUCCESS) {
1559                                 _E("failed to get client");
1560                                 result = ES_R_EINVAL;
1561                                 goto out;
1562                         }
1563
1564                         ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user);
1565                         if (ret != CYNARA_API_SUCCESS) {
1566                                 _E("failed to get user");
1567                                 result = ES_R_EINVAL;
1568                                 goto out;
1569                         }
1570
1571                         session = cynara_session_from_pid(sender_pid);
1572                         if (session == NULL) {
1573                                 _E("failed to get session");
1574                                 result = ES_R_EINVAL;
1575                                 goto out;
1576                         }
1577
1578                         _D("app_id(%s), client(%s), session(%s), user(%s)", app_id, client, session, user);
1579                         if (__esd_check_valid_privilege_by_cynara(app_id, client, session, user, privilege_name))
1580                                 result = 1;
1581                         else
1582                                 result = ES_R_EINVAL;
1583                 }
1584         } else {
1585                 result = 1;
1586         }
1587
1588 out:
1589         g_free(client);
1590         g_free(user);
1591         g_free(session);
1592         param = g_variant_new("(i)", result);
1593         _D("event_name(%s), result(%d)", event_name, result);
1594         g_dbus_method_invocation_return_value(invocation, param);
1595 }
1596
1597 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1598 static void get_earlier_data_method_call(GVariant *parameters, GDBusMethodInvocation *invocation)
1599 {
1600         GVariant *param = NULL;
1601         int result = ES_R_ERROR;
1602         char *event_name = NULL;
1603         bundle *b = NULL;
1604         bundle_raw *raw = NULL;
1605         int len = 0;
1606         earlier_item *item;
1607
1608         g_variant_get(parameters, "(&s)", &event_name);
1609         _D("event_name(%s)", event_name);
1610
1611         item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1612         if (item != NULL) {
1613                 if (item->earlier_data) {
1614                         b = bundle_dup(item->earlier_data);
1615                         bundle_add_str(b, "is_earlier_data", "true");
1616                         result = ES_R_OK;
1617                 }
1618         }
1619
1620         if (result == ES_R_ERROR)
1621                 b = bundle_create();
1622
1623         bundle_encode(b, &raw, &len);
1624         bundle_free(b);
1625
1626         param = g_variant_new("(iis)", result, len, raw);
1627
1628         _D("result(%d), len(%d)", result, len);
1629         g_dbus_method_invocation_return_value(invocation, param);
1630
1631         bundle_free_encoded_rawdata(&raw);
1632 }
1633 #endif
1634
1635 static void keep_last_data_method_call(GDBusConnection *connection,
1636                 const gchar *sender, GVariant *parameters,
1637                 GDBusMethodInvocation *invocation)
1638 {
1639         GVariant *param;
1640         int result = ES_R_OK;
1641         char *event_name;
1642         char *own_name;
1643         char *key;
1644         char app_id[128];
1645         int sender_pid;
1646         uid_t sender_uid;
1647         struct __last_event_item *item;
1648
1649         g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
1650
1651         if (!event_name || !own_name) {
1652                 result = ES_R_ERROR;
1653                 _E("invalid event_name and own_name");
1654                 goto out;
1655         }
1656
1657         sender_pid = __get_sender_pid(connection, sender);
1658         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1659         if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id,
1660                                 sizeof(app_id)) < 0) {
1661                 _E("failed to get appid by pid");
1662                 result = ES_R_ERROR;
1663                 goto out;
1664         }
1665
1666         key = (char *)malloc(sizeof(event_name) + 10);
1667         if (!key) {
1668                 result = ES_R_ENOMEM;
1669                 _E("out of memory");
1670                 goto out;
1671         }
1672
1673         snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
1674         item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
1675                         key);
1676         if (!item) {
1677                 item = calloc(1, sizeof(*item));
1678                 if (!item) {
1679                         result = ES_R_ERROR;
1680                         goto out;
1681                 }
1682                 item->key = key;
1683                 item->event_name = strdup(event_name);
1684                 item->own_name = strdup(own_name);
1685                 item->uid = sender_uid;
1686                 item->app_id = strdup(app_id);
1687                 g_hash_table_insert(user_last_event_table,
1688                                 item->key, item);
1689         } else {
1690                 free(item->own_name);
1691                 item->own_name = strdup(own_name);
1692         }
1693
1694 out:
1695         param = g_variant_new("(i)", result);
1696
1697         g_dbus_method_invocation_return_value(invocation, param);
1698 }
1699
1700 static void check_last_data_method_call(GDBusConnection *connection,
1701                 const gchar *sender, GVariant *parameters,
1702                 GDBusMethodInvocation *invocation)
1703 {
1704         GVariant *param;
1705         int result = ES_R_OK;
1706         char *event_name;
1707         char *own_name;
1708         char *key;
1709         char app_id[128];
1710         int sender_pid;
1711         uid_t sender_uid;
1712         struct __last_event_item *item;
1713
1714         g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
1715
1716         if (!event_name || !own_name) {
1717                 result = ES_R_ERROR;
1718                 _E("invalid event_name and own_name");
1719                 goto out;
1720         }
1721
1722         sender_pid = __get_sender_pid(connection, sender);
1723         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1724         if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id,
1725                                 sizeof(app_id)) < 0) {
1726                 result = ES_R_ERROR;
1727                 _E("failed to get appid by pid");
1728                 goto out;
1729         }
1730
1731         key = (char *)malloc(sizeof(event_name) + 10);
1732         if (!key) {
1733                 result = ES_R_ENOMEM;
1734                 _E("out of memory");
1735                 goto out;
1736         }
1737
1738         snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
1739         item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
1740                         key);
1741         free(key);
1742         if (item) {
1743                 GVariant *gv;
1744                 bundle *b;
1745                 bundle_raw *raw;
1746                 int len;
1747                 int ret;
1748                 GError *error = NULL;
1749
1750                 b = bundle_create();
1751                 if (!b) {
1752                         result = ES_R_ERROR;
1753                         goto out;
1754                 }
1755                 bundle_add_str(b, EVT_KEY_KEPT_EVENT_NAME, event_name);
1756                 bundle_add_str(b, EVT_KEY_KEPT_OWN_NAME, own_name);
1757                 if (__esd_check_certificate_match(item->uid, item->app_id,
1758                                 sender_uid, app_id) == ES_R_OK)
1759                         bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "true");
1760                 else
1761                         bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "false");
1762
1763                 bundle_encode(b, &raw, &len);
1764                 gv  = g_variant_new("(us)", len, raw);
1765                 ret = g_dbus_connection_emit_signal(connection,
1766                                 item->own_name,
1767                                 SYS_EVENT_OBJ_PATH,
1768                                 SYS_EVENT_NAME_PREFIX,
1769                                 REQUEST_LAST_DATA,
1770                                 gv,
1771                                 &error);
1772                 if (ret == FALSE) {
1773                         _E("Unable to emit signal: %s", error->message);
1774                         g_error_free(error);
1775                 }
1776                 bundle_free_encoded_rawdata(&raw);
1777                 bundle_free(b);
1778         }
1779
1780 out:
1781         param = g_variant_new("(i)", result);
1782
1783         g_dbus_method_invocation_return_value(invocation, param);
1784 }
1785
1786 static void launch_on_event_from_userevent(GDBusConnection *connection,
1787                 const gchar *sender, GVariant *parameters,
1788                 GDBusMethodInvocation *invocation)
1789 {
1790         GVariant *param;
1791         int result = ES_R_OK;
1792         int len;
1793         gboolean trusted;
1794         int sender_pid;
1795         uid_t sender_uid;
1796         char *event_name;
1797         char app_id[128];
1798         char *buf;
1799         bundle *b;
1800
1801         g_variant_get(parameters, "(&s&sib)", &event_name, &buf, &len, &trusted);
1802
1803         if (!event_name) {
1804                 result = ES_R_ERROR;
1805                 _E("invalid event_name");
1806                 goto out;
1807         }
1808
1809         sender_pid = __get_sender_pid(connection, sender);
1810         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1811         if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id,
1812                                 sizeof(app_id)) < 0) {
1813                 _E("failed to get appid by pid");
1814                 result = ES_R_ERROR;
1815                 goto out;
1816         }
1817
1818         b = bundle_decode((bundle_raw *)buf, len);
1819         if (b == NULL) {
1820                 _E("Out of memory");
1821                 result = ES_R_ENOMEM;
1822                 goto out;
1823         }
1824
1825         __esd_launch_event_handler(event_name, b, true, trusted,
1826                         sender_uid, app_id, NULL);
1827
1828         bundle_free(b);
1829
1830 out:
1831         param = g_variant_new("(i)", result);
1832
1833         g_dbus_method_invocation_return_value(invocation, param);
1834 }
1835
1836 static void get_uuid_method_call(GDBusConnection *connection,
1837                 const gchar *sender, GVariant *parameters,
1838                 GDBusMethodInvocation *invocation)
1839 {
1840         GVariant *param = NULL;
1841         int result = ES_R_OK;
1842         char *uuid;
1843         char app_id[128] = { 0, };
1844         int sender_pid;
1845
1846         sender_pid = __get_sender_pid(connection, sender);
1847         if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
1848                 _E("failed to get appid by pid");
1849                 result = ES_R_ERROR;
1850                 goto out;
1851         }
1852
1853         if (esd_cion_get_uuid_with_generate(app_id, &uuid) == 0) {
1854                 param = g_variant_new("(is)", result, uuid);
1855                 free(uuid);
1856         } else {
1857                 result = ES_R_ERROR;
1858         }
1859
1860 out:
1861         if (param == NULL)
1862                 param = g_variant_new("(is)", result, "");
1863
1864         g_dbus_method_invocation_return_value(invocation, param);
1865 }
1866
1867 static void set_display_name_method_call(GDBusConnection *connection,
1868                 const gchar *sender, GVariant *parameters,
1869                 GDBusMethodInvocation *invocation)
1870 {
1871         GVariant *param = NULL;
1872         int result = ES_R_OK;
1873         char app_id[128] = { 0, };
1874         int sender_pid;
1875         char *display_name = NULL;
1876         char *service_name = NULL;
1877
1878         sender_pid = __get_sender_pid(connection, sender);
1879         if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
1880                 _E("failed to get appid by pid");
1881                 result = ES_R_ERROR;
1882                 goto out;
1883         }
1884
1885         g_variant_get(parameters, "(&s&s)", &service_name, &display_name);
1886
1887         if (esd_cion_set_display_name(app_id, service_name, display_name) != 0)
1888                 result = ES_R_ERROR;
1889
1890 out:
1891         param = g_variant_new("(i)", result);
1892         g_dbus_method_invocation_return_value(invocation, param);
1893 }
1894
1895 static void get_display_name_method_call(GDBusConnection *connection,
1896                 const gchar *sender, GVariant *parameters,
1897                 GDBusMethodInvocation *invocation)
1898 {
1899         GVariant *param = NULL;
1900         int result = ES_R_OK;
1901         char app_id[128] = { 0, };
1902         int sender_pid;
1903         char *service_name = NULL;
1904         char *display_name = NULL;
1905
1906         sender_pid = __get_sender_pid(connection, sender);
1907         if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
1908                 _E("failed to get appid by pid");
1909                 result = ES_R_ERROR;
1910                 goto out;
1911         }
1912
1913         g_variant_get(parameters, "(&s)", &service_name);
1914
1915         if (esd_cion_get_display_name(app_id, service_name, &display_name) == 0) {
1916                 if (display_name != NULL) {
1917                         param = g_variant_new("(is)", result, display_name);
1918                         free(display_name);
1919                 } else {
1920                         goto out;
1921                 }
1922         } else {
1923                 result = ES_R_ERROR;
1924         }
1925
1926 out:
1927         if (param == NULL)
1928                 param = g_variant_new("(is)", result, "");
1929
1930         g_dbus_method_invocation_return_value(invocation, param);
1931 }
1932
1933 static void set_enabled_method_call(GDBusConnection *connection,
1934                 const gchar *sender, GVariant *parameters,
1935                 GDBusMethodInvocation *invocation)
1936 {
1937         GVariant *param = NULL;
1938         int result = ES_R_OK;
1939         char app_id[128] = { 0, };
1940         int sender_pid;
1941         gboolean enabled;
1942         char *service_name = NULL;
1943
1944         sender_pid = __get_sender_pid(connection, sender);
1945         if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
1946                 _E("failed to get appid by pid");
1947                 result = ES_R_ERROR;
1948                 goto out;
1949         }
1950
1951         g_variant_get(parameters, "(&sb)", &service_name, &enabled);
1952
1953         if (esd_cion_set_enabled(app_id, service_name, (bool)enabled) != 0)
1954                 result = ES_R_ERROR;
1955
1956 out:
1957         param = g_variant_new("(i)", result);
1958         g_dbus_method_invocation_return_value(invocation, param);
1959 }
1960
1961 static void get_enabled_method_call(GDBusConnection *connection,
1962                 const gchar *sender, GVariant *parameters,
1963                 GDBusMethodInvocation *invocation)
1964 {
1965         GVariant *param = NULL;
1966         int result = ES_R_OK;
1967         char app_id[128] = { 0, };
1968         int sender_pid;
1969         char *service_name = NULL;
1970         int enabled;
1971
1972         sender_pid = __get_sender_pid(connection, sender);
1973         if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
1974                 _E("failed to get appid by pid");
1975                 result = ES_R_ERROR;
1976                 goto out;
1977         }
1978
1979         g_variant_get(parameters, "(&s)", &service_name);
1980
1981         if (esd_cion_get_enabled(app_id, service_name, &enabled) == 0)
1982                 param = g_variant_new("(ib)", result, (bool)enabled);
1983         else
1984                 result = ES_R_ERROR;
1985
1986 out:
1987         if (param == NULL)
1988                 param = g_variant_new("(ib)", result, false);
1989
1990         g_dbus_method_invocation_return_value(invocation, param);
1991 }
1992
1993 static void handle_method_call(GDBusConnection *connection,
1994         const gchar *sender, const gchar *object_path,
1995         const gchar *interface_name, const gchar *method_name,
1996         GVariant *parameters, GDBusMethodInvocation *invocation,
1997         gpointer user_data)
1998 {
1999         if (g_strcmp0(method_name, "CheckSenderValidation") == 0) {
2000                 check_sender_valid_method_call(connection, sender, parameters, invocation);
2001         } else if (g_strcmp0(method_name, "GetTrustedPeerList") == 0) {
2002                 get_trusted_peer_method_call(connection, sender, parameters, invocation);
2003         } else if (g_strcmp0(method_name, "SetupTrustedPeer") == 0) {
2004                 setup_trusted_peer_method_call(connection, sender, parameters, invocation);
2005         } else if (g_strcmp0(method_name, "CheckPrivilegeValidation") == 0) {
2006                 check_privilege_valid_method_call(connection, sender, parameters, invocation);
2007         } else if (g_strcmp0(method_name, "CheckUserSendValidation") == 0) {
2008                 check_send_event_valid_method_call(connection, sender, parameters, invocation);
2009 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2010         } else if (g_strcmp0(method_name, "GetEarlierData") == 0) {
2011                 get_earlier_data_method_call(parameters, invocation);
2012 #endif
2013         } else if (g_strcmp0(method_name, "KeepLastData") == 0) {
2014                 keep_last_data_method_call(connection, sender, parameters, invocation);
2015         } else if (g_strcmp0(method_name, "CheckLastData") == 0) {
2016                 check_last_data_method_call(connection, sender, parameters, invocation);
2017         } else if (g_strcmp0(method_name, "LaunchOnEventFromUserEvent") == 0) {
2018                 launch_on_event_from_userevent(connection, sender, parameters, invocation);
2019         } else if (g_strcmp0(method_name, "CionGetUuid") == 0) {
2020                 get_uuid_method_call(connection, sender, parameters, invocation);
2021         } else if (g_strcmp0(method_name, "CionSetDisplayName") == 0) {
2022                 set_display_name_method_call(connection, sender, parameters, invocation);
2023         } else if (g_strcmp0(method_name, "CionGetDisplayName") == 0) {
2024                 get_display_name_method_call(connection, sender, parameters, invocation);
2025         } else if (g_strcmp0(method_name, "CionSetEnabled") == 0) {
2026                 set_enabled_method_call(connection, sender, parameters, invocation);
2027         } else if (g_strcmp0(method_name, "CionGetEnabled") == 0) {
2028                 get_enabled_method_call(connection, sender, parameters, invocation);
2029         }
2030 }
2031
2032 static const GDBusInterfaceVTable interface_vtable = {
2033         handle_method_call,
2034         NULL,
2035         NULL
2036 };
2037
2038 static void __esd_on_bus_acquired(GDBusConnection *connection,
2039                 const gchar *name, gpointer user_data)
2040 {
2041         _I("bus acquired(%s)", name);
2042
2043         guint reg_id = 0;
2044         guint boot_id = 0;
2045         guint user_boot_id = 0;
2046         GError *error = NULL;
2047
2048         reg_id = g_dbus_connection_register_object(connection,
2049                 ESD_OBJECT_PATH,
2050                 introspection_data->interfaces[0],
2051                 &interface_vtable,
2052                 NULL, NULL, &error);
2053         if (reg_id == 0) {
2054                 _E("g_dbus_connection_register_object error(%s)", error->message);
2055                 g_error_free(error);
2056         }
2057
2058         boot_id = g_dbus_connection_signal_subscribe(connection,
2059                         NULL,
2060                         SYSTEMD_DBUS_IFACE_MANAGER,
2061                         SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED,
2062                         SYSTEMD_DBUS_PATH,
2063                         NULL,
2064                         G_DBUS_SIGNAL_FLAGS_NONE,
2065                         __esd_signal_handler,
2066                         NULL,
2067                         NULL);
2068
2069         if (boot_id == 0)
2070                 _E("g_dbus_connection_signal_subscribe() is failed.");
2071
2072         user_boot_id = g_dbus_connection_signal_subscribe(connection,
2073                         NULL,
2074                         SYSTEMD_DBUS_IFACE_MANAGER,
2075                         SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED,
2076                         SYSTEMD_DBUS_PATH,
2077                         NULL,
2078                         G_DBUS_SIGNAL_FLAGS_NONE,
2079                         __esd_signal_handler,
2080                         NULL,
2081                         NULL);
2082
2083         if (user_boot_id == 0)
2084                 _E("g_dbus_connection_signal_subscribe() is failed.");
2085 }
2086
2087 static void __esd_on_name_acquired(GDBusConnection *connection,
2088                 const gchar *name, gpointer user_data)
2089 {
2090         bundle *b;
2091
2092         __esd_check_trusted_events(connection, "ListNames");
2093         __esd_check_trusted_events(connection, "ListActivatableNames");
2094
2095         b = bundle_create();
2096         bundle_add_str(b, EVT_KEY_ESD_STATUS, EVT_VAL_ESD_STARTED);
2097         eventsystem_send_system_event(SYS_EVENT_ESD_STATUS, b);
2098         bundle_free(b);
2099
2100         __esd_register_vconf_callbacks();
2101
2102         __esd_trusted_busname_print_items();
2103
2104         __esd_get_user_items(DEFAULT_USER);
2105
2106         __esd_dbus_name_monitor(connection);
2107 }
2108
2109 static void __esd_on_name_lost(GDBusConnection *connection,
2110                 const gchar *name, gpointer user_data)
2111 {
2112 }
2113
2114 static int __esd_before_loop(void)
2115 {
2116         int ret = 0;
2117         GError *error = NULL;
2118         guint owner_id = 0;
2119
2120 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2121         guint subscription_id = 0;
2122         int i;
2123         int size;
2124         char *event_name;
2125         int fd;
2126         int val;
2127         int status;
2128         int charger_status;
2129         int charge_now;
2130         earlier_item *item;
2131
2132         earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal);
2133         user_last_event_table = g_hash_table_new_full(g_str_hash,
2134                         g_str_equal, NULL, (GDestroyNotify)free_saved_event);
2135
2136         _I("register events for earlier_data");
2137         size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
2138         for (i = 0; i < size; i++) {
2139                 event_name = (char *)earlier_event_list[i];
2140                 _I("event_name(%s)", event_name);
2141
2142                 item = calloc(1, sizeof(earlier_item));
2143                 if (item == NULL) {
2144                         _E("memery alloc failed");
2145                         return ES_R_ENOMEM;
2146                 }
2147                 item->event_name = strdup(event_name);
2148                 if (item->event_name == NULL) {
2149                         _E("out of memory");
2150                         free(item);
2151                         return ES_R_ENOMEM;
2152                 }
2153
2154                 /* set initial data */
2155                 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
2156                         fd = open(ESD_BOOT_COMPLETED, O_RDONLY);
2157                         if (fd < 0) {
2158                                 _D("open file error(%d)", fd);
2159                         } else {
2160                                 item->earlier_data = bundle_create();
2161                                 bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED,
2162                                         EVT_VAL_BOOT_COMPLETED_TRUE);
2163                                 close(fd);
2164                         }
2165                 } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
2166                         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val);
2167                         if (ret != VCONF_OK) {
2168                                 _E("failed to get power_off status (%d)", ret);
2169                         } else {
2170                                 if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT ||
2171                                         val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
2172                                         /* power-off requested */
2173                                         item->earlier_data = bundle_create();
2174                                         bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN,
2175                                                 EVT_VAL_SYSTEM_SHUTDOWN_TRUE);
2176                                 }
2177                         }
2178                 } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
2179                         ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status);
2180                         if (ret != VCONF_OK) {
2181                                 _E("failed to get low_memory status (%d)", ret);
2182                         } else {
2183                                 item->earlier_data = bundle_create();
2184                                 if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
2185                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
2186                                                 EVT_VAL_MEMORY_SOFT_WARNING);
2187                                 else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING)
2188                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
2189                                                 EVT_VAL_MEMORY_HARD_WARNING);
2190                                 else
2191                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
2192                                                 EVT_VAL_MEMORY_NORMAL);
2193                         }
2194                 } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
2195                         ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status);
2196                         if (ret != VCONF_OK) {
2197                                 _E("failed to get charger_status (%d)", ret);
2198                         } else {
2199                                 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now);
2200                                 if (ret != VCONF_OK)
2201                                         _E("failed to get charge_now (%d)", ret);
2202                         }
2203
2204                         if (ret == VCONF_OK) {
2205                                 item->earlier_data = bundle_create();
2206                                 if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) {
2207                                         if (charge_now == 0) {
2208                                                 bundle_add_str(item->earlier_data,
2209                                                         EVT_KEY_BATTERY_CHARGER_STATUS,
2210                                                         EVT_VAL_BATTERY_CHARGER_DISCHARGING);
2211                                         } else {
2212                                                 bundle_add_str(item->earlier_data,
2213                                                         EVT_KEY_BATTERY_CHARGER_STATUS,
2214                                                         EVT_VAL_BATTERY_CHARGER_CHARGING);
2215                                         }
2216                                 } else {
2217                                         bundle_add_str(item->earlier_data,
2218                                                 EVT_KEY_BATTERY_CHARGER_STATUS,
2219                                                 EVT_VAL_BATTERY_CHARGER_DISCONNECTED);
2220                                 }
2221                         }
2222                 }
2223
2224                 eventsystem_register_event(event_name, &subscription_id,
2225                         (eventsystem_handler)__esd_event_handler, NULL);
2226                 if (subscription_id == 0) {
2227                         _E("signal subscription error, event_name(%s)", event_name);
2228                         if (item->earlier_data)
2229                                 bundle_free(item->earlier_data);
2230                         free(item->event_name);
2231                         free(item);
2232
2233                         return ES_R_ERROR;
2234                 } else {
2235                         item->reg_id = subscription_id;
2236                 }
2237
2238                 g_hash_table_insert(earlier_event_table, event_name, item);
2239         }
2240
2241         __esd_earlier_table_print_items();
2242 #endif
2243
2244         event_launch_table = g_hash_table_new(g_str_hash, g_str_equal);
2245         trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal);
2246
2247         /* gdbus setup for method call */
2248         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
2249         if (!introspection_data) {
2250                 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
2251                 g_error_free(error);
2252                 return ES_R_ERROR;
2253         }
2254
2255         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
2256                 ESD_BUS_NAME,
2257                 G_BUS_NAME_OWNER_FLAGS_NONE,
2258                 __esd_on_bus_acquired,
2259                 __esd_on_name_acquired,
2260                 __esd_on_name_lost,
2261                 NULL, NULL);
2262         if (!owner_id) {
2263                 _E("g_bus_own_name error");
2264                 g_dbus_node_info_unref(introspection_data);
2265                 return ES_R_ERROR;
2266         }
2267
2268         _I("esd before_loop done");
2269
2270         return ES_R_OK;
2271 }
2272
2273 static void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event)
2274 {
2275         pkg_event->type = UNKNOWN;
2276         if (pkg_event->pkgid) {
2277                 free(pkg_event->pkgid);
2278                 pkg_event->pkgid = NULL;
2279         }
2280 }
2281
2282 static int __esd_appcontrol_cb(const char *operation,
2283                 const char *uri, const char *mime, void *data)
2284 {
2285         esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data;
2286         char *appid = NULL;
2287         char *pkgid = NULL;
2288         char *event_name = NULL;
2289         uid_t uid = 0;
2290
2291         if (cb_data == NULL) {
2292                 _E("invalid data");
2293                 return 0;
2294         }
2295         appid = cb_data->appid;
2296         pkgid = cb_data->pkgid;
2297         uid = cb_data->uid;
2298
2299         _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)",
2300                 uid, appid, pkgid, operation, uri, mime);
2301
2302         if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) {
2303                 if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX, strlen(SYSTEM_EVENT_NAME_PREFIX))) {
2304                         event_name = strdup(&uri[8]);
2305                         if (event_name) {
2306                                 _D("appid(%s), event_name(%s)", appid, event_name);
2307                                 if (!__esd_check_event_launch_support(event_name))
2308                                         _E("failed to add item (not support event)");
2309                                 else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name))
2310                                         _E("failed to add item (no privilege)");
2311                                 else if (__esd_add_launch_item(uid, event_name, appid, pkgid))
2312                                         _E("failed to add item");
2313
2314                         } else {
2315                                 _E("out of memory");
2316                         }
2317                 } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX, strlen(USER_EVENT_NAME_PREFIX))) {
2318                         event_name = strdup(uri);
2319                         if (event_name) {
2320                                 _D("appid(%s), event_name(%s)", appid, event_name);
2321                                 if (__esd_check_platform_cert(pkgid, uid)) {
2322                                         if (__esd_add_launch_item(uid, event_name, appid, pkgid))
2323                                                 _E("failed to add item");
2324                                 }
2325                         } else {
2326                                 _E("out of memory");
2327                         }
2328                 }
2329                 FREE_AND_NULL(event_name);
2330         }
2331
2332         return 0;
2333 }
2334
2335 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data)
2336 {
2337         char *appid = NULL;
2338         char *pkgid = NULL;
2339         int ret = 0;
2340         uid_t *p_uid = NULL;
2341
2342         if (data == NULL) {
2343                 _E("invalid data");
2344                 return ES_R_ERROR;
2345         }
2346
2347         p_uid = (uid_t *)data;
2348
2349         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
2350         if (ret < 0) {
2351                 _E("failed to get appid");
2352                 return ES_R_ERROR;
2353         }
2354
2355         ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
2356         if (ret < 0) {
2357                 _E("failed to get appid");
2358                 return ES_R_ERROR;
2359         }
2360
2361         esd_appctrl_cb_data *cb_data = calloc(1, sizeof(esd_appctrl_cb_data));
2362
2363         if (cb_data == NULL) {
2364                 _E("memory alloc failed");
2365                 return ES_R_ENOMEM;
2366         }
2367         cb_data->appid = strdup(appid);
2368         if (cb_data->appid == NULL) {
2369                 _E("out_of_memory");
2370                 FREE_AND_NULL(cb_data);
2371                 return ES_R_ENOMEM;
2372         }
2373         cb_data->pkgid = strdup(pkgid);
2374         if (cb_data->pkgid == NULL) {
2375                 _E("out_of_memory");
2376                 FREE_AND_NULL(cb_data->appid);
2377                 FREE_AND_NULL(cb_data);
2378                 return ES_R_ENOMEM;
2379         }
2380         cb_data->uid = *p_uid;
2381
2382         ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
2383                 (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data);
2384
2385         FREE_AND_NULL(cb_data->pkgid);
2386         FREE_AND_NULL(cb_data->appid);
2387         FREE_AND_NULL(cb_data);
2388
2389         if (ret < 0) {
2390                 _E("failed to get appcontrol info");
2391                 return ES_R_ERROR;
2392         }
2393
2394         return ES_R_OK;
2395 }
2396
2397 static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id,
2398                 const char *pkg_type, const char *pkgid, const char *key,
2399                 const char *val, const void *pmsg, void *data)
2400 {
2401         esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data;
2402         pkgmgrinfo_pkginfo_h handle = NULL;
2403         int ret = 0;
2404
2405         _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)",
2406                 target_uid, req_id, pkg_type, pkgid, key, val);
2407
2408         if (strncmp(key, "start", strlen(key)) == 0) {
2409                 if (strcmp(val, "install") == 0) {
2410                         _D("install start");
2411                         pkg_event->type = INSTALL;
2412                 } else if (strcmp(val, "uninstall") == 0) {
2413                         _D("unistall start");
2414                         pkg_event->type = UNINSTALL;
2415                 } else if (strcmp(val, "update") == 0) {
2416                         _D("update start");
2417                         pkg_event->type = UPDATE;
2418                 } else {
2419                         _D("val(%s) start", val);
2420                         __esd_pkgmgr_event_free(pkg_event);
2421                 }
2422         } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) {
2423                 if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) {
2424                         _D("install end (ok)");
2425                         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle);
2426                         if (ret < 0) {
2427                                 _E("failed to get pkginfo");
2428                                 __esd_pkgmgr_event_free(pkg_event);
2429                                 return 0;
2430                         }
2431                         ret = pkgmgrinfo_appinfo_get_usr_list(handle,
2432                                 PMINFO_SVC_APP, __esd_add_appinfo_handler, &target_uid, target_uid);
2433                         if (ret < 0) {
2434                                 _E("failed to get appinfo");
2435                                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2436                                 __esd_pkgmgr_event_free(pkg_event);
2437                                 return 0;
2438                         }
2439                         ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2440                         if (ret < 0) {
2441                                 _E("failed to destroy pkginfo");
2442                                 __esd_pkgmgr_event_free(pkg_event);
2443                                 return 0;
2444                         }
2445                 } else if (pkg_event->type == UNINSTALL) {
2446                         _D("uninstall end (ok)");
2447                         __esd_launch_table_remove_items(target_uid, pkgid);
2448                         __esd_launch_table_print_items();
2449                 }
2450                 __esd_pkgmgr_event_free(pkg_event);
2451         } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) {
2452                 _E("pkg_event(%d) falied", pkg_event->type);
2453                 __esd_pkgmgr_event_free(pkg_event);
2454         } else {
2455                 if (strcmp(key, "install_percent") != 0)
2456                         __esd_pkgmgr_event_free(pkg_event);
2457         }
2458
2459         return 0;
2460 }
2461
2462 static int __esd_init()
2463 {
2464         int req_id = 0;
2465         int ret = 0;
2466         pkgmgr_client *client;
2467         esd_pkgmgr_event *pkg_event;
2468
2469 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
2470         g_type_init();
2471 #endif
2472         __esd_init_cynara();
2473
2474         client = pkgmgr_client_new(PC_LISTENING);
2475         if (client == NULL) {
2476                 _E("set pkgmgr client failed");
2477                 __esd_finish_cynara();
2478                 return ES_R_ERROR;
2479         }
2480
2481         pkg_event = calloc(1, sizeof(esd_pkgmgr_event));
2482         if (pkg_event == NULL) {
2483                 _E("memory alloc failed");
2484                 ret = pkgmgr_client_free(client);
2485                 if (ret != PKGMGR_R_OK)
2486                         _E("pkgmgr_client_free failed(%d)", ret);
2487                 __esd_finish_cynara();
2488                 return ES_R_ENOMEM;
2489         }
2490
2491         req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event);
2492         if (req_id < 0) {
2493                 _E("pkgmgr client listen failed");
2494                 ret = pkgmgr_client_free(client);
2495                 if (ret != PKGMGR_R_OK)
2496                         _E("pkgmgr_client_free failed(%d)", ret);
2497                 free(pkg_event);
2498                 __esd_finish_cynara();
2499                 return ES_R_ERROR;
2500         }
2501
2502         s_info.client = client;
2503
2504         _I("esd init done");
2505
2506         return 0;
2507 }
2508
2509 static void __esd_remove_esd_list_item(gpointer data, gpointer user_data)
2510 {
2511         esd_list_item_s *item = (esd_list_item_s *)data;
2512
2513         free(item->app_id);
2514         free(item->pkg_id);
2515 }
2516
2517 static void __esd_finalize(void)
2518 {
2519         gpointer key;
2520         gpointer value;
2521         GHashTableIter iter;
2522         trusted_item *item;
2523         event_launch_item *el_item;
2524         int ret = 0;
2525 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2526         earlier_item *er_item;
2527 #endif
2528
2529         _D("esd finalize");
2530
2531         if (trusted_busname_table) {
2532                 g_hash_table_iter_init(&iter, trusted_busname_table);
2533                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2534                         item = (trusted_item *)value;
2535                         if (item) {
2536                                 free(item->app_id);
2537                                 free(item->bus_name);
2538                                 free(item);
2539                         } else {
2540                                 _E("item is null");
2541                         }
2542                         g_hash_table_iter_remove(&iter);
2543                 }
2544                 g_hash_table_unref(trusted_busname_table);
2545         }
2546
2547 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2548         if (earlier_event_table) {
2549                 g_hash_table_iter_init(&iter, earlier_event_table);
2550                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2551                         er_item = (earlier_item *)value;
2552                         if (er_item) {
2553                                 eventsystem_unregister_event(er_item->reg_id);
2554                                 free(er_item->event_name);
2555                                 bundle_free(er_item->earlier_data);
2556                                 free(er_item);
2557                         } else {
2558                                 _E("ealier item is NULL");
2559                         }
2560                         g_hash_table_iter_remove(&iter);
2561                 }
2562                 g_hash_table_unref(earlier_event_table);
2563         }
2564
2565         g_hash_table_destroy(user_last_event_table);
2566 #endif
2567
2568         if (event_launch_table) {
2569                 g_hash_table_iter_init(&iter, event_launch_table);
2570                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2571                         el_item = (event_launch_item *)value;
2572                         if (el_item) {
2573                                 eventsystem_unregister_event(el_item->reg_id);
2574                                 free(el_item->event_name);
2575                                 g_list_foreach(el_item->app_list_evtlaunch,
2576                                         __esd_remove_esd_list_item, NULL);
2577                                 g_list_free(el_item->app_list_evtlaunch);
2578                                 free(el_item);
2579                         } else {
2580                                 _E("item is NULL");
2581                         }
2582                         g_hash_table_iter_remove(&iter);
2583                 }
2584                 g_hash_table_unref(event_launch_table);
2585         }
2586
2587         if (introspection_data)
2588                 g_dbus_node_info_unref(introspection_data);
2589
2590         if (s_info.client) {
2591                 ret = pkgmgr_client_free(s_info.client);
2592                 if (ret != PKGMGR_R_OK)
2593                         _E("pkgmgr_client_free failed(%d)", ret);
2594         }
2595
2596         __esd_finish_cynara();
2597
2598         _D("esd finalize end");
2599 }
2600
2601 int main(int argc, char *argv[])
2602 {
2603         GMainLoop *mainloop;
2604         _I("event system daemon : main()");
2605
2606         mainloop = g_main_loop_new(NULL, FALSE);
2607         if (mainloop == NULL) {
2608                 _E("out of memory");
2609                 return ES_R_ERROR;
2610         }
2611
2612         if (__esd_init() != 0) {
2613                 _E("ESD Initialization failed!");
2614                 g_main_loop_unref(mainloop);
2615                 return ES_R_ERROR;
2616         }
2617
2618         if (_esd_cion_init() != 0)
2619                 _E("ESD Cion Initialization failed!");
2620
2621         if (__esd_before_loop() < 0) {
2622                 _E("ESD failed!");
2623                 __esd_finalize();
2624                 g_main_loop_unref(mainloop);
2625                 return ES_R_ERROR;
2626         }
2627
2628         if (esd_cion_db_init() < 0)
2629                 _E("db init failed!");
2630
2631         g_main_loop_run(mainloop);
2632
2633         _E("shutdown");
2634
2635         __esd_finalize();
2636
2637         g_main_loop_unref(mainloop);
2638
2639         return 0;
2640 }