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