1655228ee723cb23aaffd409239801031f2c77f2
[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         SYS_EVENT_WIFI_STATE
41 };
42
43 struct privilege_info {
44         const char *event_name;
45         const char *privilege_name;
46 };
47
48 static const struct privilege_info privilege_check_list[] = {
49         {SYS_EVENT_DISPLAY_STATE, "http://tizen.org/privilege/display"},
50         {SYS_EVENT_WIFI_STATE, "http://tizen.org/privilege/network.get"},
51         {SYS_EVENT_INCOMMING_MSG, "http://tizen.org/privilege/message.read"},
52         {SYS_EVENT_OUTGOING_MSG, "http://tizen.org/privilege/message.read"}
53 };
54
55 static int privilege_check_size = sizeof(privilege_check_list)/sizeof(struct privilege_info);
56
57 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
58 static const char *earlier_event_list[] = {
59         SYS_EVENT_ESD_STATUS,
60         SYS_EVENT_LOW_MEMORY,
61         SYS_EVENT_BOOT_COMPLETED,
62         SYS_EVENT_SYSTEM_SHUTDOWN,
63         SYS_EVENT_BATTERY_CHARGER_STATUS
64 };
65
66 static GHashTable *earlier_event_table; /* table of events for earlier_data */
67
68 typedef struct __earlier_table_item {
69         char *event_name;
70         guint reg_id;
71         bundle *earlier_data; /* event-data from earlier occurrence */
72 } earlier_item;
73
74 #endif
75
76 static GHashTable *user_last_event_table; /* table of user events for last data */
77
78 struct __last_event_item {
79         char *key;
80         char *app_id;
81         char *event_name;
82         char *own_name;
83         uid_t uid;
84 };
85
86 static GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */
87
88 typedef struct __trusted_busname_item {
89         char *app_id;
90         char *bus_name;
91         int pid;
92         uid_t uid;
93 } trusted_item;
94
95 typedef struct __eventlaunch_item_param {
96         char *app_id;
97 } eventlaunch_item_param_s;
98
99 typedef struct esd_list_item {
100         char *pkg_id;
101         char *app_id;
102         uid_t uid;
103 } esd_list_item_s;
104
105 typedef struct  __event_launch_table_item {
106         char *event_name;
107         char *package_name; /* just for passing pointer to app-list removal func */
108         GList *app_list_evtlaunch; /* app-list for on-event-launch */
109         guint reg_id;
110         uid_t uid;
111 } event_launch_item;
112
113 enum __pkg_event_type {
114         UNKNOWN = 0,
115         INSTALL,
116         UNINSTALL,
117         UPDATE,
118 };
119
120 typedef struct __pkgmgr_event {
121         int type;
122         char *pkgid;
123 } esd_pkgmgr_event;
124
125 typedef struct __esd_event_param {
126         char *event_name;
127         bundle *event_data;
128         void *user_data;
129 } esd_event_param;
130
131 typedef struct esd_info {
132         pkgmgr_client *client;
133 } esd_info_s;
134 static esd_info_s s_info;
135
136 typedef struct __esd_appctrl_cb_data {
137         char *appid;
138         char *pkgid;
139         uid_t uid;
140 } esd_appctrl_cb_data;
141
142 static void __esd_event_handler(char *event_name, bundle *data, void *user_data);
143 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data);
144
145 static cynara *r_cynara;
146
147 static int __esd_init_cynara(void)
148 {
149         int ret;
150
151         ret  = cynara_initialize(&r_cynara, NULL);
152         if (ret != CYNARA_API_SUCCESS) {
153                 _E("cynara initialize failed.");
154                 return ret;
155         }
156
157         return 0;
158 }
159
160 static void __esd_finish_cynara(void)
161 {
162         if (r_cynara)
163                 cynara_finish(r_cynara);
164         r_cynara = NULL;
165 }
166
167 static void free_saved_event(struct __last_event_item *item)
168 {
169         if (!item)
170                 return;
171
172         free(item->event_name);
173         free(item->own_name);
174         free(item->app_id);
175         free(item);
176 }
177
178 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
179 static int __esd_check_earlier_support(const char *event_name)
180 {
181         int i = 0;
182         int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
183
184         for (i = 0; i < size; i++) {
185                 if (strcmp(earlier_event_list[i], event_name) == 0)
186                         return true;
187         }
188
189         return false;
190 }
191 #endif
192
193 static int __esd_check_event_launch_support(const char *event_name)
194 {
195         int i = 0;
196         int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list);
197
198         for (i = 0; i < size; i++) {
199                 if (strcmp(event_launch_support_list[i], event_name) == 0)
200                         return true;
201         }
202
203         return false;
204 }
205
206 static int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type)
207 {
208         GDBusMessage *msg = NULL;
209         GDBusMessage *reply = NULL;
210         GError *err = NULL;
211         GVariant *body;
212         int ret = -1;
213         unsigned int value;
214
215         msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
216                 "org.freedesktop.DBus", type);
217         if (!msg) {
218                 _E("Can't allocate new method call");
219                 goto out;
220         }
221
222         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
223         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
224                 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
225
226         if (!reply) {
227                 if (err != NULL) {
228                         _E("Failed to get info [%s]", err->message);
229                         g_error_free(err);
230                 }
231                 goto out;
232         }
233
234         body = g_dbus_message_get_body(reply);
235         g_variant_get(body, "(u)", &value);
236         ret = (int)value;
237
238 out:
239         if (msg)
240                 g_object_unref(msg);
241         if (reply)
242                 g_object_unref(reply);
243
244         return ret;
245 }
246
247 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
248 {
249         int pid = 0;
250
251         pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID");
252         if (pid < 0) {
253                 _E("failed to get pid");
254                 pid = 0;
255         }
256
257         _D("sender_name(%s), pid(%d)", sender_name, pid);
258
259         return pid;
260 }
261
262 static int __get_sender_uid(GDBusConnection *conn, const char *sender_name)
263 {
264         int uid = -1;
265
266         uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser");
267         if (uid < 0)
268                 _E("failed to get uid");
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                 } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) {
827                         val = bundle_get_val(data, EVT_KEY_WIFI_STATE);
828                         if (val == NULL)
829                                 return;
830                         _D("wifi_state(%s)", val);
831                         if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0)
832                                 return;
833                 }
834
835                 eep = calloc(1, sizeof(esd_event_param));
836                 if (!eep) {
837                         _E("memory alloc failed");
838                         return;
839                 }
840                 eep->event_name = event_name;
841                 eep->event_data = data;
842                 eep->user_data = (void *)user_data;
843                 __esd_check_event_launch_with_eventid(el_item, eep);
844                 free(eep);
845         }
846 }
847
848 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
849 static void __esd_print_earlier_event(gpointer data, gpointer user_data)
850 {
851         earlier_item *item = (earlier_item *)data;
852         char *event_name = (char *)item->event_name;
853         const char *val;
854
855         _D("event_name = (%s)", event_name);
856
857         if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
858                 if (item->earlier_data) {
859                         val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED);
860                         _D("boot_completed(%s)", val);
861                 }
862         } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
863                 if (item->earlier_data) {
864                         val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN);
865                         _D("shutdown(%s)", val);
866                 }
867         } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
868                 if (item->earlier_data) {
869                         val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY);
870                         _D("low_memory(%s)", val);
871                 }
872         } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
873                 if (item->earlier_data) {
874                         val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS);
875                         _D("charger_status(%s)", val);
876                 }
877         }
878 }
879
880 static void __esd_earlier_table_print_items(void)
881 {
882         GHashTableIter iter;
883         gpointer key;
884         gpointer value;
885
886         g_hash_table_iter_init(&iter, earlier_event_table);
887
888         while (g_hash_table_iter_next(&iter, &key, &value))
889                 __esd_print_earlier_event(value, NULL);
890 }
891
892 static void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data)
893 {
894         earlier_item *item;
895         _D("event_name(%s)", event_name);
896
897         item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
898         if (item) {
899                 /* update earlier value */
900                 if (item->earlier_data != NULL)
901                         bundle_free(item->earlier_data);
902
903                 item->earlier_data = bundle_dup(data);
904         }
905 }
906 #endif
907
908 static void __esd_event_handler(char *event_name, bundle *data, void *user_data)
909 {
910         _D("event_name(%s)", event_name);
911
912 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
913         if (__esd_check_earlier_support(event_name))
914                 __esd_earlier_event_handler(event_name, data, user_data);
915 #endif
916
917         if (__esd_check_event_launch_support(event_name))
918                 __esd_launch_event_handler(event_name, data, user_data);
919 }
920
921 static void __esd_trusted_busname_remove_item(char *bus_name)
922 {
923         GHashTableIter iter;
924         gpointer key;
925         gpointer value;
926         trusted_item *item;
927
928         g_hash_table_iter_init(&iter, trusted_busname_table);
929
930         while (g_hash_table_iter_next(&iter, &key, &value)) {
931                 item = (trusted_item *)value;
932                 if (item) {
933                         if (strcmp(bus_name, item->bus_name) == 0) {
934                                 _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name);
935                                 FREE_AND_NULL(item->app_id);
936                                 FREE_AND_NULL(item->bus_name);
937                                 FREE_AND_NULL(item);
938                                 g_hash_table_iter_remove(&iter);
939
940                                 __esd_trusted_busname_print_items();
941                         }
942                 }
943         }
944 }
945
946 static void __esd_filter_name_owner_changed(GDBusConnection *connection,
947                 const gchar *sender_name, const gchar *object_path,
948                 const gchar *interface_name, const gchar *signal_name,
949                 GVariant *parameters, gpointer user_data)
950 {
951         char *name = NULL;
952         char *old_owner = NULL;
953         char *new_owner = NULL;
954         int old_len = 0;
955         int new_len = 0;
956
957         g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
958
959         if (strstr(name, "event.busname.session")) {
960                 old_len = strlen(old_owner);
961                 new_len = strlen(new_owner);
962
963                 _D("changed name(%s), old_onwer(%s)(%d) -> new_onwer(%s)(%d)",
964                         name, old_owner, old_len, new_owner, new_len);
965
966                 if (old_len > 0 && new_len == 0)
967                         __esd_trusted_busname_remove_item(name);
968                 else if (old_len == 0 && new_len > 0)
969                         _D("new name owned");
970                 else
971                         _E("not-expected name change");
972         }
973 }
974
975 static int __esd_dbus_name_monitor(GDBusConnection *connection)
976 {
977         guint name_owner_changed_id = 0;
978
979         name_owner_changed_id = g_dbus_connection_signal_subscribe(connection,
980                 "org.freedesktop.DBus", "org.freedesktop.DBus",
981                 "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE,
982                 __esd_filter_name_owner_changed, NULL, NULL);
983
984         _I("name_owner_changed_id(%d)", name_owner_changed_id);
985
986         return ES_R_OK;
987 }
988
989 static int __esd_get_user_items(uid_t uid)
990 {
991         int ret = 0;
992         pkgmgrinfo_appinfo_filter_h handle = NULL;
993
994         _I("get user items for uid(%d)", uid);
995         /* reset user's item */
996         __esd_launch_table_remove_private_usr_items();
997
998         ret = pkgmgrinfo_appinfo_filter_create(&handle);
999         if (ret < 0) {
1000                 _E("failed to create appinfo filter");
1001                 return ES_R_ERROR;
1002         }
1003         ret = pkgmgrinfo_appinfo_filter_add_string(handle,
1004                         PMINFO_APPINFO_PROP_APP_COMPONENT, "svcapp");
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_filter_add_string(handle,
1011                         PMINFO_APPINFO_PROP_APP_OPERATION, APPSVC_OPERATION_LAUNCH_ON_EVENT);
1012         if (ret < 0) {
1013                 _E("failed to add appinfo filter string");
1014                 pkgmgrinfo_appinfo_filter_destroy(handle);
1015                 return ES_R_ERROR;
1016         }
1017         ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle,
1018                         __esd_add_appinfo_handler, &uid, uid);
1019         if (ret < 0) {
1020                 _E("appinfo filter foreach error");
1021                 pkgmgrinfo_appinfo_filter_destroy(handle);
1022                 return ES_R_ERROR;
1023         }
1024         pkgmgrinfo_appinfo_filter_destroy(handle);
1025
1026         __esd_launch_table_print_items();
1027
1028         return ES_R_OK;
1029 }
1030
1031 static void __esd_signal_handler(GDBusConnection *connection,
1032                 const gchar *sender_name,
1033                 const gchar *object_path,
1034                 const gchar *interface_name,
1035                 const gchar *signal_name,
1036                 GVariant *parameters,
1037                 gpointer user_data)
1038 {
1039         int handle;
1040         bundle *b;
1041         guint64 uid = 0;
1042
1043         if (!g_strcmp0(signal_name,
1044                                 SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED)) {
1045                 _I("System session finished");
1046
1047                 b = bundle_create();
1048                 bundle_add_str(b, EVT_KEY_BOOT_COMPLETED,
1049                         EVT_VAL_BOOT_COMPLETED_TRUE);
1050                 eventsystem_send_system_event(SYS_EVENT_BOOT_COMPLETED, b);
1051                 bundle_free(b);
1052
1053                 handle = creat(ESD_BOOT_COMPLETED, 0640);
1054                 if (handle != -1)
1055                         close(handle);
1056         } else if (!g_strcmp0(signal_name,
1057                                 SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED)) {
1058                 g_variant_get(parameters, "(t)", &uid);
1059                 _I("User session finished uid : %d", (int)uid);
1060                 if ((uid_t)uid != DEFAULT_USER)
1061                         __esd_get_user_items((uid_t)uid);
1062         }
1063 }
1064
1065 static GDBusNodeInfo *introspection_data;
1066 static const gchar introspection_xml[] =
1067 "<node>"
1068 "       <interface name='tizen.system.event.app2esd'>"
1069 "               <method name='CheckSenderValidation'>"
1070 "                       <arg type='i' name='senderpid' direction='in'/>"
1071 "                       <arg type='s' name='eventname' direction='in'/>"
1072 "                       <arg type='i' name='ret' direction='out'/>"
1073 "                       <arg type='s' name='senderid' direction='out'/>"
1074 "               </method>"
1075 "               <method name='GetTrustedPeerList'>"
1076 "                       <arg type='s' name='eventname' direction='in'/>"
1077 "                       <arg type='i' name='ret' direction='out'/>"
1078 "                       <arg type='as' name='dest_list' direction='out'/>"
1079 "               </method>"
1080 "               <method name='SetupTrustedPeer'>"
1081 "                       <arg type='s' name='eventname' direction='in'/>"
1082 "                       <arg type='s' name='destination' direction='in'/>"
1083 "                       <arg type='i' name='ret' direction='out'/>"
1084 "               </method>"
1085 "               <method name='CheckPrivilegeValidation'>"
1086 "                       <arg type='s' name='eventname' direction='in'/>"
1087 "                       <arg type='i' name='ret' direction='out'/>"
1088 "               </method>"
1089 "               <method name='CheckUserSendValidation'>"
1090 "                       <arg type='s' name='eventname' direction='in'/>"
1091 "                       <arg type='i' name='ret' direction='out'/>"
1092 "               </method>"
1093 "               <method name='RequestTrustedEventLaunch'>"
1094 "                       <arg type='s' name='eventname' direction='in'/>"
1095 "                       <arg type='s' name='eventdata' direction='in'/>"
1096 "                       <arg type='i' name='datalen' direction='in'/>"
1097 "                       <arg type='i' name='ret' direction='out'/>"
1098 "               </method>"
1099 "               <method name='RequestEventLaunch'>"
1100 "                       <arg type='s' name='eventname' direction='in'/>"
1101 "                       <arg type='s' name='eventdata' direction='in'/>"
1102 "                       <arg type='i' name='datalen' direction='in'/>"
1103 "                       <arg type='i' name='ret' direction='out'/>"
1104 "               </method>"
1105 "               <method name='RequestSendingEvent'>"
1106 "                       <arg type='s' name='eventname' direction='in'/>"
1107 "                       <arg type='s' name='eventdata' direction='in'/>"
1108 "                       <arg type='i' name='datalen' direction='in'/>"
1109 "                       <arg type='i' name='ret' direction='out'/>"
1110 "               </method>"
1111 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1112 "               <method name='GetEarlierData'>"
1113 "                       <arg type='s' name='appid' direction='in'/>"
1114 "                       <arg type='i' name='ret' direction='out'/>"
1115 "                       <arg type='i' name='len' direction='out'/>"
1116 "                       <arg type='s' name='earlier_data' direction='out'/>"
1117 "               </method>"
1118 #endif
1119 "               <method name='KeepLastData'>"
1120 "                       <arg type='s' name='eventname' direction='in'/>"
1121 "                       <arg type='s' name='own_name' direction='in'/>"
1122 "                       <arg type='i' name='ret' direction='out'/>"
1123 "               </method>"
1124 "               <method name='CheckLastData'>"
1125 "                       <arg type='s' name='eventname' direction='in'/>"
1126 "                       <arg type='s' name='own_name' direction='in'/>"
1127 "                       <arg type='i' name='ret' direction='out'/>"
1128 "               </method>"
1129 "       </interface>"
1130 "</node>";
1131
1132 static int __esd_get_appid_by_pid(int pid, uid_t uid, char *app_id, int buf_size)
1133 {
1134         int retval = ES_R_OK;
1135         int ret = 0;
1136
1137         if (pid <= 0) {
1138                 _E("invalid pid(%d)", pid);
1139                 retval = ES_R_ERROR;
1140         } else if (uid <= 0) {
1141                 _E("invalid uid(%d)", uid);
1142                 retval = ES_R_ERROR;
1143         } else {
1144                 ret = aul_app_get_appid_bypid_for_uid(pid, app_id, buf_size, (uid_t)uid);
1145                 if (ret != AUL_R_OK) {
1146                         _E("failed to get appid by pid");
1147                         retval = ES_R_ERROR;
1148                 }
1149                 _D("pid(%d)-uid(%d)-appid(%s)", pid, uid, app_id);
1150         }
1151
1152         return retval;
1153 }
1154
1155 static int check_user_event_sender_valid(const char *event_name, const char *app_id)
1156 {
1157         char *valid_name = NULL;
1158         char *temp_name = NULL;
1159         char *tmp = NULL;
1160         int retval = ES_R_OK;
1161         int len = 0;
1162         int valid_name_len = 0;
1163
1164         temp_name = strdup(event_name);
1165         if (temp_name == NULL) {
1166                 _E("out of memory");
1167                 return ES_R_ENOMEM;
1168         }
1169
1170         tmp = strrchr(temp_name, '.');
1171         if (tmp == NULL || strlen(tmp) == 0) {
1172                 _E("invalid event name");
1173                 FREE_AND_NULL(temp_name);
1174                 return ES_R_EINVAL;
1175         }
1176         len = strlen(tmp);
1177         if (len <= 1 || len > 128) {
1178                 _E("invalid length(%d) of user-defined name", len);
1179                 FREE_AND_NULL(temp_name);
1180                 return ES_R_EINVAL;
1181         }
1182         *tmp = '\0';
1183
1184         _D("app_id(%s), len(%d)", app_id, strlen(app_id));
1185
1186         valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1;
1187         valid_name = calloc(1, valid_name_len);
1188         if (valid_name == NULL) {
1189                 _E("memory alloc failed");
1190                 FREE_AND_NULL(temp_name);
1191                 return ES_R_ENOMEM;
1192         }
1193         snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id);
1194         _D("valid_name(%s)", valid_name);
1195
1196         if (strcmp(temp_name, valid_name) != 0) {
1197                 _E("appid misamatch");
1198                 retval = ES_R_EINVAL;
1199         }
1200
1201         FREE_AND_NULL(temp_name);
1202         FREE_AND_NULL(valid_name);
1203
1204         return retval;
1205 }
1206
1207 static void check_sender_valid_method_call(GDBusConnection *connection, const gchar *sender,
1208         GVariant *parameters, GDBusMethodInvocation *invocation)
1209 {
1210         GVariant *param = NULL;
1211         int result = 0;
1212         char *event_name = NULL;
1213         char app_id[128] = {0, };
1214         int event_sender_pid = 0;
1215         uid_t sender_uid = 0;
1216
1217         g_variant_get(parameters, "(i&s)", &event_sender_pid, &event_name);
1218         _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name);
1219
1220         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1221         if (__esd_get_appid_by_pid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1222                 result = ES_R_ERROR;
1223         } else {
1224                 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1225                         _E("invalid sender");
1226                         result = ES_R_EINVAL;
1227                 } else {
1228                         result = 1;
1229                 }
1230         }
1231
1232         param = g_variant_new("(is)", result, app_id);
1233         _D("event_name(%s), result(%d)", event_name, result);
1234         g_dbus_method_invocation_return_value(invocation, param);
1235 }
1236
1237 static void check_send_event_valid_method_call(GDBusConnection *connection, const gchar *sender,
1238         GVariant *parameters, GDBusMethodInvocation *invocation)
1239 {
1240         GVariant *param = NULL;
1241         int result = 0;
1242         char *event_name = NULL;
1243         char app_id[128] = {0, };
1244         int sender_pid = 0;
1245         uid_t sender_uid = 0;
1246
1247         g_variant_get(parameters, "(&s)", &event_name);
1248         _D("event_name(%s)", event_name);
1249
1250         sender_pid = __get_sender_pid(connection, sender);
1251         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1252         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1253                 result = ES_R_ERROR;
1254         } else {
1255                 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1256                         _E("invalid sender");
1257                         result = ES_R_EINVAL;
1258                 } else {
1259                         result = 1;
1260                 }
1261         }
1262
1263         param = g_variant_new("(i)", result);
1264         _D("event_name(%s), result(%d)", event_name, result);
1265         g_dbus_method_invocation_return_value(invocation, param);
1266 }
1267
1268 static void get_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1269         GVariant *parameters, GDBusMethodInvocation *invocation)
1270 {
1271         GVariant *param = NULL;
1272         int result = 0;
1273         GVariantBuilder *builder = NULL;
1274         GHashTableIter iter;
1275         gpointer key, value;
1276         char *event_name = NULL;
1277         char app_id[128] = {0, };
1278         int sender_pid = 0;
1279         uid_t sender_uid = 0;
1280         int ret = 0;
1281         uid_t uid = 0;
1282         char *_appid = NULL;
1283         char *_busname = NULL;
1284         trusted_item *item;
1285
1286         g_variant_get(parameters, "(&s)", &event_name);
1287         _D("event_name(%s)", event_name);
1288
1289         sender_pid = __get_sender_pid(connection, sender);
1290         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1291         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1292                 result = ES_R_ERROR;
1293         } else {
1294                 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1295
1296                 g_hash_table_iter_init(&iter, trusted_busname_table);
1297                 while (g_hash_table_iter_next(&iter, &key, &value)) {
1298                         item = (trusted_item *)value;
1299                         uid = item->uid;
1300                         _appid = item->app_id;
1301                         _busname = item->bus_name;
1302
1303                         if (uid != GLOBAL_USER && uid != sender_uid)
1304                                 continue;
1305
1306                         ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id);
1307                         if (ret == ES_R_OK)
1308                                 g_variant_builder_add(builder, "s", _busname);
1309                 }
1310
1311                 result = 1;
1312         }
1313
1314         param = g_variant_new("(ias)", result, builder);
1315         _D("result(%d)", result);
1316         g_dbus_method_invocation_return_value(invocation, param);
1317         if (builder)
1318                 g_variant_builder_unref(builder);
1319 }
1320
1321 static void setup_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1322         GVariant *parameters, GDBusMethodInvocation *invocation)
1323 {
1324         GVariant *param = NULL;
1325         int result = 0;
1326         char *event_name = NULL;
1327         char *destination_name = NULL;
1328         char app_id[128] = {0, };
1329         int sender_pid = 0;
1330         uid_t sender_uid = 0;
1331         int ret = 0;
1332
1333         g_variant_get(parameters, "(&s&s)", &event_name, &destination_name);
1334         _D("event_name(%s), destination_name(%s)", event_name, destination_name);
1335
1336         if (destination_name && destination_name[0] != '\0') {
1337                 sender_pid = __get_sender_pid(connection, sender);
1338                 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1339                 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1340                         result = ES_R_ERROR;
1341                 } else {
1342                         ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name,
1343                                 sender_pid);
1344                         if (ret < 0) {
1345                                 _E("failed to add trusted busname item");
1346                                 result = ES_R_ERROR;
1347                         } else {
1348                                 result = 1;
1349                         }
1350                 }
1351         } else {
1352                 _E("invalid destination name");
1353                 result = ES_R_ERROR;
1354         }
1355
1356         param = g_variant_new("(i)", result);
1357         _D("event_name(%s), result(%d)", event_name, result);
1358         g_dbus_method_invocation_return_value(invocation, param);
1359 }
1360
1361 static void check_privilege_valid_method_call(GDBusConnection *connection, const gchar *sender,
1362         GVariant *parameters, GDBusMethodInvocation *invocation)
1363 {
1364         GVariant *param = NULL;
1365         int result = 0;
1366         char *event_name = NULL;
1367         char *privilege_name = NULL;
1368         char app_id[128] = {0, };
1369         int sender_pid = 0;
1370         uid_t sender_uid = 0;
1371         char *client = NULL;
1372         char *session = NULL;
1373         char *user = NULL;
1374         int ret = 0;
1375
1376         g_variant_get(parameters, "(&s)", &event_name);
1377         __esd_check_privilege_name(event_name, &privilege_name);
1378         _D("event_name(%s), privilege_name(%s)", event_name, privilege_name);
1379
1380         if (privilege_name) {
1381                 sender_pid = __get_sender_pid(connection, sender);
1382                 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1383                 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1384                         result = ES_R_ERROR;
1385                 } else {
1386                         ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client);
1387                         if (ret != CYNARA_API_SUCCESS) {
1388                                 _E("failed to get client");
1389                                 result = ES_R_EINVAL;
1390                                 goto out;
1391                         }
1392
1393                         ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user);
1394                         if (ret != CYNARA_API_SUCCESS) {
1395                                 _E("failed to get user");
1396                                 result = ES_R_EINVAL;
1397                                 goto out;
1398                         }
1399
1400                         session = cynara_session_from_pid(sender_pid);
1401                         if (session == NULL) {
1402                                 _E("failed to get session");
1403                                 result = ES_R_EINVAL;
1404                                 goto out;
1405                         }
1406
1407                         _D("app_id(%s), client(%s), session(%s), user(%s)", app_id, client, session, user);
1408                         if (__esd_check_valid_privilege_by_cynara(app_id, client, session, user, privilege_name))
1409                                 result = 1;
1410                         else
1411                                 result = ES_R_EINVAL;
1412                 }
1413         } else {
1414                 result = 1;
1415         }
1416
1417 out:
1418         g_free(client);
1419         g_free(user);
1420         g_free(session);
1421         param = g_variant_new("(i)", result);
1422         _D("event_name(%s), result(%d)", event_name, result);
1423         g_dbus_method_invocation_return_value(invocation, param);
1424 }
1425
1426 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1427 static void get_earlier_data_method_call(GVariant *parameters, GDBusMethodInvocation *invocation)
1428 {
1429         GVariant *param = NULL;
1430         int result = 0;
1431         char *event_name = NULL;
1432         bundle *b = NULL;
1433         bundle_raw *raw = NULL;
1434         int len = 0;
1435         earlier_item *item;
1436
1437         g_variant_get(parameters, "(&s)", &event_name);
1438
1439         if (event_name && strlen(event_name) > 0) {
1440                 _D("event_name(%s)", event_name);
1441                 result = ES_R_OK;
1442         } else {
1443                 _E("invalid event_name(%s)", event_name);
1444                 result = ES_R_ERROR;
1445         }
1446
1447         item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1448         if (item != NULL) {
1449                 if (item->earlier_data) {
1450                         b = bundle_dup(item->earlier_data);
1451                         bundle_add_str(b, "is_earlier_data", "true");
1452                         bundle_encode(b, &raw, &len);
1453                         bundle_free(b);
1454                 }
1455         }
1456
1457         param = g_variant_new("(iis)", result, len, raw);
1458
1459         _D("result(%d), len(%d)", result, len);
1460         g_dbus_method_invocation_return_value(invocation, param);
1461
1462         bundle_free_encoded_rawdata(&raw);
1463 }
1464 #endif
1465
1466 static void keep_last_data_method_call(GDBusConnection *connection,
1467                 const gchar *sender, GVariant *parameters,
1468                 GDBusMethodInvocation *invocation)
1469 {
1470         GVariant *param;
1471         int result = ES_R_OK;
1472         char *event_name;
1473         char *own_name;
1474         char *key;
1475         char app_id[128];
1476         int sender_pid;
1477         uid_t sender_uid;
1478         struct __last_event_item *item;
1479
1480         g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
1481
1482         if (!event_name || !own_name) {
1483                 result = ES_R_ERROR;
1484                 _E("invalid event_name and own_name");
1485                 goto out;
1486         }
1487
1488         sender_pid = __get_sender_pid(connection, sender);
1489         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1490         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id,
1491                                 sizeof(app_id)) < 0) {
1492                 _E("failed to get appid by pid");
1493                 result = ES_R_ERROR;
1494                 goto out;
1495         }
1496
1497         key = (char *)malloc(sizeof(event_name) + 10);
1498         if (!key) {
1499                 result = ES_R_ENOMEM;
1500                 _E("out of memory");
1501                 goto out;
1502         }
1503
1504         snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
1505         item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
1506                         key);
1507         if (!item) {
1508                 item = calloc(1, sizeof(*item));
1509                 if (!item) {
1510                         result = ES_R_ERROR;
1511                         goto out;
1512                 }
1513                 item->key = key;
1514                 item->event_name = strdup(event_name);
1515                 item->own_name = strdup(own_name);
1516                 item->uid = sender_uid;
1517                 item->app_id = strdup(app_id);
1518                 g_hash_table_insert(user_last_event_table,
1519                                 item->key, item);
1520         } else {
1521                 free(item->own_name);
1522                 item->own_name = strdup(own_name);
1523         }
1524
1525 out:
1526         param = g_variant_new("(i)", result);
1527
1528         g_dbus_method_invocation_return_value(invocation, param);
1529 }
1530
1531 static void check_last_data_method_call(GDBusConnection *connection,
1532                 const gchar *sender, GVariant *parameters,
1533                 GDBusMethodInvocation *invocation)
1534 {
1535         GVariant *param;
1536         int result = ES_R_OK;
1537         char *event_name;
1538         char *own_name;
1539         char *key;
1540         char app_id[128];
1541         int sender_pid;
1542         uid_t sender_uid;
1543         struct __last_event_item *item;
1544
1545         g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
1546
1547         if (!event_name || !own_name) {
1548                 result = ES_R_ERROR;
1549                 _E("invalid event_name and own_name");
1550                 goto out;
1551         }
1552
1553         sender_pid = __get_sender_pid(connection, sender);
1554         sender_uid = (uid_t)__get_sender_uid(connection, sender);
1555         if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id,
1556                                 sizeof(app_id)) < 0) {
1557                 result = ES_R_ERROR;
1558                 _E("failed to get appid by pid");
1559                 goto out;
1560         }
1561
1562         key = (char *)malloc(sizeof(event_name) + 10);
1563         if (!key) {
1564                 result = ES_R_ENOMEM;
1565                 _E("out of memory");
1566                 goto out;
1567         }
1568
1569         snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
1570         item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
1571                         key);
1572         free(key);
1573         if (item) {
1574                 GVariant *gv;
1575                 bundle *b;
1576                 bundle_raw *raw;
1577                 int len;
1578                 int ret;
1579                 GError *error = NULL;
1580
1581                 b = bundle_create();
1582                 if (!b) {
1583                         result = ES_R_ERROR;
1584                         goto out;
1585                 }
1586                 bundle_add_str(b, EVT_KEY_KEPT_EVENT_NAME, event_name);
1587                 bundle_add_str(b, EVT_KEY_KEPT_OWN_NAME, own_name);
1588                 if (__esd_check_certificate_match(item->uid, item->app_id,
1589                                 sender_uid, app_id) == ES_R_OK)
1590                         bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "true");
1591                 else
1592                         bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "false");
1593
1594                 bundle_encode(b, &raw, &len);
1595                 gv  = g_variant_new("(us)", len, raw);
1596                 ret = g_dbus_connection_emit_signal(connection,
1597                                 item->own_name,
1598                                 SYS_EVENT_OBJ_PATH,
1599                                 SYS_EVENT_NAME_PREFIX,
1600                                 REQUEST_LAST_DATA,
1601                                 gv,
1602                                 &error);
1603                 if (ret == FALSE) {
1604                         _E("Unable to emit signal: %s", error->message);
1605                         g_error_free(error);
1606                 }
1607                 bundle_free_encoded_rawdata(&raw);
1608                 bundle_free(b);
1609         }
1610
1611 out:
1612         param = g_variant_new("(i)", result);
1613
1614         g_dbus_method_invocation_return_value(invocation, param);
1615 }
1616
1617 static void handle_method_call(GDBusConnection *connection,
1618         const gchar *sender, const gchar *object_path,
1619         const gchar *interface_name, const gchar *method_name,
1620         GVariant *parameters, GDBusMethodInvocation *invocation,
1621         gpointer user_data)
1622 {
1623         if (g_strcmp0(method_name, "CheckSenderValidation") == 0) {
1624                 check_sender_valid_method_call(connection, sender, parameters, invocation);
1625         } else if (g_strcmp0(method_name, "GetTrustedPeerList") == 0) {
1626                 get_trusted_peer_method_call(connection, sender, parameters, invocation);
1627         } else if (g_strcmp0(method_name, "SetupTrustedPeer") == 0) {
1628                 setup_trusted_peer_method_call(connection, sender, parameters, invocation);
1629         } else if (g_strcmp0(method_name, "CheckPrivilegeValidation") == 0) {
1630                 check_privilege_valid_method_call(connection, sender, parameters, invocation);
1631         } else if (g_strcmp0(method_name, "CheckUserSendValidation") == 0) {
1632                 check_send_event_valid_method_call(connection, sender, parameters, invocation);
1633 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1634         } else if (g_strcmp0(method_name, "GetEarlierData") == 0) {
1635                 get_earlier_data_method_call(parameters, invocation);
1636 #endif
1637         } else if (g_strcmp0(method_name, "KeepLastData") == 0) {
1638                 keep_last_data_method_call(connection, sender, parameters, invocation);
1639         } else if (g_strcmp0(method_name, "CheckLastData") == 0) {
1640                 check_last_data_method_call(connection, sender, parameters, invocation);
1641         }
1642 }
1643
1644 static const GDBusInterfaceVTable interface_vtable = {
1645         handle_method_call,
1646         NULL,
1647         NULL
1648 };
1649
1650 static void __esd_on_bus_acquired(GDBusConnection *connection,
1651                 const gchar *name, gpointer user_data)
1652 {
1653         _I("bus acquired(%s)", name);
1654
1655         guint reg_id = 0;
1656         guint boot_id = 0;
1657         guint user_boot_id = 0;
1658         GError *error = NULL;
1659
1660         reg_id = g_dbus_connection_register_object(connection,
1661                 ESD_OBJECT_PATH,
1662                 introspection_data->interfaces[0],
1663                 &interface_vtable,
1664                 NULL, NULL, &error);
1665         if (reg_id == 0) {
1666                 _E("g_dbus_connection_register_object error(%s)", error->message);
1667                 g_error_free(error);
1668         }
1669
1670         boot_id = g_dbus_connection_signal_subscribe(connection,
1671                         NULL,
1672                         SYSTEMD_DBUS_IFACE_MANAGER,
1673                         SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED,
1674                         SYSTEMD_DBUS_PATH,
1675                         NULL,
1676                         G_DBUS_SIGNAL_FLAGS_NONE,
1677                         __esd_signal_handler,
1678                         NULL,
1679                         NULL);
1680
1681         if (boot_id == 0) {
1682                 _E("g_dbus_connection_signal_subscribe() is failed.");
1683                 g_object_unref(connection);
1684         }
1685
1686         user_boot_id = g_dbus_connection_signal_subscribe(connection,
1687                         NULL,
1688                         SYSTEMD_DBUS_IFACE_MANAGER,
1689                         SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED,
1690                         SYSTEMD_DBUS_PATH,
1691                         NULL,
1692                         G_DBUS_SIGNAL_FLAGS_NONE,
1693                         __esd_signal_handler,
1694                         NULL,
1695                         NULL);
1696
1697         if (user_boot_id == 0) {
1698                 _E("g_dbus_connection_signal_subscribe() is failed.");
1699                 g_object_unref(connection);
1700         }
1701 }
1702
1703 static void __esd_on_name_acquired(GDBusConnection *connection,
1704                 const gchar *name, gpointer user_data)
1705 {
1706         bundle *b;
1707
1708         _I("name acquired(%s)", name);
1709
1710         __esd_check_trusted_events(connection, "ListNames");
1711         __esd_check_trusted_events(connection, "ListActivatableNames");
1712
1713         b = bundle_create();
1714         bundle_add_str(b, EVT_KEY_ESD_STATUS, EVT_VAL_ESD_STARTED);
1715         eventsystem_send_system_event(SYS_EVENT_ESD_STATUS, b);
1716         bundle_free(b);
1717
1718         __esd_register_vconf_callbacks();
1719
1720         __esd_trusted_busname_print_items();
1721
1722         __esd_get_user_items(DEFAULT_USER);
1723
1724         __esd_dbus_name_monitor(connection);
1725 }
1726
1727 static void __esd_on_name_lost(GDBusConnection *connection,
1728                 const gchar *name, gpointer user_data)
1729 {
1730         _E("name lost(%s)", name);
1731 }
1732
1733 static int __esd_before_loop(void)
1734 {
1735         int ret = 0;
1736         GError *error = NULL;
1737         guint owner_id = 0;
1738
1739 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1740         guint subscription_id = 0;
1741         int i;
1742         int size;
1743         char *event_name;
1744         int fd;
1745         int val;
1746         int status;
1747         int charger_status;
1748         int charge_now;
1749         earlier_item *item;
1750
1751         earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal);
1752         user_last_event_table = g_hash_table_new_full(g_str_hash,
1753                         g_str_equal, NULL, (GDestroyNotify)free_saved_event);
1754
1755         _I("register events for earlier_data");
1756         size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
1757         for (i = 0; i < size; i++) {
1758                 event_name = (char *)earlier_event_list[i];
1759                 _I("event_name(%s)", event_name);
1760
1761                 item = calloc(1, sizeof(earlier_item));
1762                 if (item == NULL) {
1763                         _E("memery alloc failed");
1764                         return ES_R_ENOMEM;
1765                 }
1766                 item->event_name = strdup(event_name);
1767                 if (item->event_name == NULL) {
1768                         _E("out of memory");
1769                         free(item);
1770                         return ES_R_ENOMEM;
1771                 }
1772
1773                 /* set initial data */
1774                 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
1775                         fd = open(ESD_BOOT_COMPLETED, O_RDONLY);
1776                         if (fd < 0) {
1777                                 _D("open file error(%d)", fd);
1778                         } else {
1779                                 item->earlier_data = bundle_create();
1780                                 bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED,
1781                                         EVT_VAL_BOOT_COMPLETED_TRUE);
1782                                 close(fd);
1783                         }
1784                 } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
1785                         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val);
1786                         if (ret != VCONF_OK) {
1787                                 _E("failed to get power_off status (%d)", ret);
1788                         } else {
1789                                 if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT ||
1790                                         val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
1791                                         /* power-off requested */
1792                                         item->earlier_data = bundle_create();
1793                                         bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN,
1794                                                 EVT_VAL_SYSTEM_SHUTDOWN_TRUE);
1795                                 }
1796                         }
1797                 } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
1798                         ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status);
1799                         if (ret != VCONF_OK) {
1800                                 _E("failed to get low_memory status (%d)", ret);
1801                         } else {
1802                                 item->earlier_data = bundle_create();
1803                                 if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
1804                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1805                                                 EVT_VAL_MEMORY_SOFT_WARNING);
1806                                 else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING)
1807                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1808                                                 EVT_VAL_MEMORY_HARD_WARNING);
1809                                 else
1810                                         bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1811                                                 EVT_VAL_MEMORY_NORMAL);
1812                         }
1813                 } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
1814                         ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status);
1815                         if (ret != VCONF_OK) {
1816                                 _E("failed to get charger_status (%d)", ret);
1817                         } else {
1818                                 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now);
1819                                 if (ret != VCONF_OK)
1820                                         _E("failed to get charge_now (%d)", ret);
1821                         }
1822
1823                         if (ret == VCONF_OK) {
1824                                 item->earlier_data = bundle_create();
1825                                 if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) {
1826                                         if (charge_now == 0) {
1827                                                 bundle_add_str(item->earlier_data,
1828                                                         EVT_KEY_BATTERY_CHARGER_STATUS,
1829                                                         EVT_VAL_BATTERY_CHARGER_DISCHARGING);
1830                                         } else {
1831                                                 bundle_add_str(item->earlier_data,
1832                                                         EVT_KEY_BATTERY_CHARGER_STATUS,
1833                                                         EVT_VAL_BATTERY_CHARGER_CHARGING);
1834                                         }
1835                                 } else {
1836                                         bundle_add_str(item->earlier_data,
1837                                                 EVT_KEY_BATTERY_CHARGER_STATUS,
1838                                                 EVT_VAL_BATTERY_CHARGER_DISCONNECTED);
1839                                 }
1840                         }
1841                 }
1842
1843                 eventsystem_register_event(event_name, &subscription_id,
1844                         (eventsystem_handler)__esd_event_handler, NULL);
1845                 if (subscription_id == 0) {
1846                         _E("signal subscription error, event_name(%s)", event_name);
1847                         if (item->earlier_data)
1848                                 bundle_free(item->earlier_data);
1849                         free(item->event_name);
1850                         free(item);
1851
1852                         return ES_R_ERROR;
1853                 } else {
1854                         item->reg_id = subscription_id;
1855                 }
1856
1857                 g_hash_table_insert(earlier_event_table, event_name, item);
1858         }
1859
1860         __esd_earlier_table_print_items();
1861 #endif
1862
1863         event_launch_table = g_hash_table_new(g_str_hash, g_str_equal);
1864         trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal);
1865
1866         /* gdbus setup for method call */
1867         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
1868         if (!introspection_data) {
1869                 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
1870                 g_error_free(error);
1871                 return ES_R_ERROR;
1872         }
1873
1874         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1875                 ESD_BUS_NAME,
1876                 G_BUS_NAME_OWNER_FLAGS_NONE,
1877                 __esd_on_bus_acquired,
1878                 __esd_on_name_acquired,
1879                 __esd_on_name_lost,
1880                 NULL, NULL);
1881         if (!owner_id) {
1882                 _E("g_bus_own_name error");
1883                 g_dbus_node_info_unref(introspection_data);
1884                 return ES_R_ERROR;
1885         }
1886
1887         _I("esd before_loop done");
1888
1889         return ES_R_OK;
1890 }
1891
1892 static void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event)
1893 {
1894         pkg_event->type = UNKNOWN;
1895         if (pkg_event->pkgid) {
1896                 free(pkg_event->pkgid);
1897                 pkg_event->pkgid = NULL;
1898         }
1899 }
1900
1901 static int __esd_appcontrol_cb(const char *operation,
1902                 const char *uri, const char *mime, void *data)
1903 {
1904         esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data;
1905         char *appid = NULL;
1906         char *pkgid = NULL;
1907         char *event_name = NULL;
1908         const char *prefix = "event://";
1909         uid_t uid = 0;
1910
1911         if (cb_data == NULL) {
1912                 _E("invalid data");
1913                 return 0;
1914         }
1915         appid = cb_data->appid;
1916         pkgid = cb_data->pkgid;
1917         uid = cb_data->uid;
1918
1919         _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)",
1920                 uid, appid, pkgid, operation, uri, mime);
1921
1922         if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) {
1923                 if (uri && !strncmp(uri, prefix, strlen(prefix))) {
1924                         event_name = strdup(&uri[8]);
1925                         if (event_name) {
1926                                 _D("appid(%s), event_name(%s)", appid, event_name);
1927                                 if (!__esd_check_event_launch_support(event_name)) {
1928                                         _E("failed to add item (not support event)");
1929                                 } else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name)) {
1930                                         _E("failed to add item (no privilege)");
1931                                 } else {
1932                                         if (__esd_add_launch_item(uid, event_name, appid, pkgid))
1933                                                 _E("failed to add item");
1934                                 }
1935                                 FREE_AND_NULL(event_name);
1936                         } else {
1937                                 _E("out of memory");
1938                         }
1939                 } else {
1940                         _E("Invalid uri(%s) for event_name", uri);
1941                 }
1942         }
1943
1944         return 0;
1945 }
1946
1947 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data)
1948 {
1949         char *appid = NULL;
1950         char *pkgid = NULL;
1951         int ret = 0;
1952         uid_t *p_uid = NULL;
1953
1954         if (data == NULL) {
1955                 _E("invalid data");
1956                 return ES_R_ERROR;
1957         }
1958
1959         p_uid = (uid_t *)data;
1960
1961         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
1962         if (ret < 0) {
1963                 _E("failed to get appid");
1964                 return ES_R_ERROR;
1965         }
1966
1967         ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
1968         if (ret < 0) {
1969                 _E("failed to get appid");
1970                 return ES_R_ERROR;
1971         }
1972
1973         esd_appctrl_cb_data *cb_data = calloc(1, sizeof(esd_appctrl_cb_data));
1974
1975         if (cb_data == NULL) {
1976                 _E("memory alloc failed");
1977                 return ES_R_ENOMEM;
1978         }
1979         cb_data->appid = strdup(appid);
1980         if (cb_data->appid == NULL) {
1981                 _E("out_of_memory");
1982                 FREE_AND_NULL(cb_data);
1983                 return ES_R_ENOMEM;
1984         }
1985         cb_data->pkgid = strdup(pkgid);
1986         if (cb_data->pkgid == NULL) {
1987                 _E("out_of_memory");
1988                 FREE_AND_NULL(cb_data->appid);
1989                 FREE_AND_NULL(cb_data);
1990                 return ES_R_ENOMEM;
1991         }
1992         cb_data->uid = *p_uid;
1993
1994         ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
1995                 (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data);
1996
1997         FREE_AND_NULL(cb_data->pkgid);
1998         FREE_AND_NULL(cb_data->appid);
1999         FREE_AND_NULL(cb_data);
2000
2001         if (ret < 0) {
2002                 _E("failed to get appcontrol info");
2003                 return ES_R_ERROR;
2004         }
2005
2006         return ES_R_OK;
2007 }
2008
2009 static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id,
2010                 const char *pkg_type, const char *pkgid, const char *key,
2011                 const char *val, const void *pmsg, void *data)
2012 {
2013         esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data;
2014         pkgmgrinfo_pkginfo_h handle = NULL;
2015         int ret = 0;
2016
2017         _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)",
2018                 target_uid, req_id, pkg_type, pkgid, key, val);
2019
2020         if (strncmp(key, "start", strlen(key)) == 0) {
2021                 if (strcmp(val, "install") == 0) {
2022                         _D("install start");
2023                         pkg_event->type = INSTALL;
2024                 } else if (strcmp(val, "uninstall") == 0) {
2025                         _D("unistall start");
2026                         pkg_event->type = UNINSTALL;
2027                 } else if (strcmp(val, "update") == 0) {
2028                         _D("update start");
2029                         pkg_event->type = UPDATE;
2030                 } else {
2031                         _D("val(%s) start", val);
2032                         __esd_pkgmgr_event_free(pkg_event);
2033                 }
2034         } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) {
2035                 if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) {
2036                         _D("install end (ok)");
2037                         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle);
2038                         if (ret < 0) {
2039                                 _E("failed to get pkginfo");
2040                                 __esd_pkgmgr_event_free(pkg_event);
2041                                 return 0;
2042                         }
2043                         ret = pkgmgrinfo_appinfo_get_usr_list(handle,
2044                                 PMINFO_ALL_APP, __esd_add_appinfo_handler, &target_uid, target_uid);
2045                         if (ret < 0) {
2046                                 _E("failed to get appinfo");
2047                                 __esd_pkgmgr_event_free(pkg_event);
2048                                 return 0;
2049                         }
2050                         ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2051                         if (ret < 0) {
2052                                 _E("failed to destroy pkginfo");
2053                                 __esd_pkgmgr_event_free(pkg_event);
2054                                 return 0;
2055                         }
2056                 } else if (pkg_event->type == UNINSTALL) {
2057                         _D("uninstall end (ok)");
2058                         __esd_launch_table_remove_items(target_uid, pkgid);
2059                         __esd_launch_table_print_items();
2060                 }
2061                 __esd_pkgmgr_event_free(pkg_event);
2062         } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) {
2063                 _E("pkg_event(%d) falied", pkg_event->type);
2064                 __esd_pkgmgr_event_free(pkg_event);
2065         } else {
2066                 if (strcmp(key, "install_percent") != 0)
2067                         __esd_pkgmgr_event_free(pkg_event);
2068         }
2069
2070         return 0;
2071 }
2072
2073 static int __esd_init()
2074 {
2075         int req_id = 0;
2076         int ret = 0;
2077         pkgmgr_client *client;
2078         esd_pkgmgr_event *pkg_event;
2079
2080 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
2081         g_type_init();
2082 #endif
2083         __esd_init_cynara();
2084
2085         client = pkgmgr_client_new(PC_LISTENING);
2086         if (client == NULL) {
2087                 _E("set pkgmgr client failed");
2088                 __esd_finish_cynara();
2089                 return ES_R_ERROR;
2090         }
2091
2092         pkg_event = calloc(1, sizeof(esd_pkgmgr_event));
2093         if (pkg_event == NULL) {
2094                 _E("memory alloc failed");
2095                 ret = pkgmgr_client_free(client);
2096                 if (ret != PKGMGR_R_OK)
2097                         _E("pkgmgr_client_free failed(%d)", ret);
2098                 __esd_finish_cynara();
2099                 return ES_R_ENOMEM;
2100         }
2101
2102         req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event);
2103         if (req_id < 0) {
2104                 _E("pkgmgr client listen failed");
2105                 ret = pkgmgr_client_free(client);
2106                 if (ret != PKGMGR_R_OK)
2107                         _E("pkgmgr_client_free failed(%d)", ret);
2108                 free(pkg_event);
2109                 __esd_finish_cynara();
2110                 return ES_R_ERROR;
2111         }
2112
2113         s_info.client = client;
2114
2115         _I("esd init done");
2116
2117         return 0;
2118 }
2119
2120 static void __esd_remove_esd_list_item(gpointer data, gpointer user_data)
2121 {
2122         esd_list_item_s *item = (esd_list_item_s *)data;
2123
2124         free(item->app_id);
2125         free(item->pkg_id);
2126 }
2127
2128 static void __esd_finalize(void)
2129 {
2130         gpointer key;
2131         gpointer value;
2132         GHashTableIter iter;
2133         trusted_item *item;
2134         event_launch_item *el_item;
2135         int ret = 0;
2136 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2137         earlier_item *er_item;
2138 #endif
2139
2140         _D("esd finalize");
2141
2142         if (trusted_busname_table) {
2143                 g_hash_table_iter_init(&iter, trusted_busname_table);
2144                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2145                         item = (trusted_item *)value;
2146                         if (item) {
2147                                 free(item->app_id);
2148                                 free(item->bus_name);
2149                                 free(item);
2150                         } else {
2151                                 _E("item is null");
2152                         }
2153                         g_hash_table_iter_remove(&iter);
2154                 }
2155                 g_hash_table_unref(trusted_busname_table);
2156         }
2157
2158 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2159         if (earlier_event_table) {
2160                 g_hash_table_iter_init(&iter, earlier_event_table);
2161                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2162                         er_item = (earlier_item *)value;
2163                         if (er_item) {
2164                                 eventsystem_unregister_event(er_item->reg_id);
2165                                 free(er_item->event_name);
2166                                 bundle_free(er_item->earlier_data);
2167                                 free(er_item);
2168                         } else {
2169                                 _E("ealier item is NULL");
2170                         }
2171                         g_hash_table_iter_remove(&iter);
2172                 }
2173                 g_hash_table_unref(earlier_event_table);
2174         }
2175
2176         g_hash_table_destroy(user_last_event_table);
2177 #endif
2178
2179         if (event_launch_table) {
2180                 g_hash_table_iter_init(&iter, event_launch_table);
2181                 while (g_hash_table_iter_next(&iter, &key, &value)) {
2182                         el_item = (event_launch_item *)value;
2183                         if (el_item) {
2184                                 eventsystem_unregister_event(el_item->reg_id);
2185                                 free(el_item->event_name);
2186                                 g_list_foreach(el_item->app_list_evtlaunch,
2187                                         __esd_remove_esd_list_item, NULL);
2188                                 g_list_free(el_item->app_list_evtlaunch);
2189                                 free(el_item);
2190                         } else {
2191                                 _E("item is NULL");
2192                         }
2193                         g_hash_table_iter_remove(&iter);
2194                 }
2195                 g_hash_table_unref(event_launch_table);
2196         }
2197
2198         if (introspection_data)
2199                 g_dbus_node_info_unref(introspection_data);
2200
2201         if (s_info.client) {
2202                 ret = pkgmgr_client_free(s_info.client);
2203                 if (ret != PKGMGR_R_OK)
2204                         _E("pkgmgr_client_free failed(%d)", ret);
2205         }
2206
2207         __esd_finish_cynara();
2208
2209         _D("esd finalize end");
2210 }
2211
2212 int main(int argc, char *argv[])
2213 {
2214         GMainLoop *mainloop;
2215         _I("event system daemon : main()");
2216
2217         mainloop = g_main_loop_new(NULL, FALSE);
2218         if (mainloop == NULL) {
2219                 _E("out of memory");
2220                 return ES_R_ERROR;
2221         }
2222
2223         if (__esd_init() != 0) {
2224                 _E("ESD Initialization failed!");
2225                 g_main_loop_unref(mainloop);
2226                 return ES_R_ERROR;
2227         }
2228
2229         if (__esd_before_loop() < 0) {
2230                 _E("ESD failed!");
2231                 __esd_finalize();
2232                 g_main_loop_unref(mainloop);
2233                 return ES_R_ERROR;
2234         }
2235
2236         g_main_loop_run(mainloop);
2237
2238         _E("shutdown");
2239
2240         __esd_finalize();
2241
2242         g_main_loop_unref(mainloop);
2243
2244         return 0;
2245 }