10 #include <package-manager.h>
11 #include <pkgmgr-info.h>
12 #include <appsvc/appsvc.h>
13 #include <eventsystem.h>
14 #include <bundle_internal.h>
17 #include <tzplatform_config.h>
18 #include <systemd/sd-login.h>
19 #include <cynara-client.h>
20 #include <cynara-creds-gdbus.h>
21 #include <cynara-session.h>
22 #include "eventsystem_daemon.h"
24 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
27 static GHashTable *event_launch_table; /* table of events for launch_on_event*/
29 static const char *event_launch_support_list[] = {
30 SYS_EVENT_BATTERY_CHARGER_STATUS,
32 SYS_EVENT_EARJACK_STATUS,
33 SYS_EVENT_INCOMMING_MSG
36 struct privilege_info {
37 const char *event_name;
38 const char *privilege_name;
41 static const struct privilege_info privilege_check_list[] = {
42 {SYS_EVENT_DISPLAY_STATE, "http://tizen.org/privilege/display"},
43 {SYS_EVENT_WIFI_STATE, "http://tizen.org/privilege/network.get"},
44 {SYS_EVENT_INCOMMING_MSG, "http://tizen.org/privilege/message.read"}
47 typedef struct __esd_privilege_check {
50 } esd_privilege_check;
52 static int privilege_check_size = sizeof(privilege_check_list)/sizeof(struct privilege_info);
54 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
55 static const char *earlier_event_list[] = {
58 SYS_EVENT_BOOT_COMPLETED,
59 SYS_EVENT_SYSTEM_SHUTDOWN,
60 SYS_EVENT_BATTERY_CHARGER_STATUS
63 static GHashTable *earlier_event_table; /* table of events for earlier_data */
65 typedef struct __earlier_table_item {
68 bundle *earlier_data; /* event-data from earlier occurrence */
71 static bool g_is_bootcompleted = false;
74 static GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */
76 typedef struct __trusted_busname_item {
83 typedef struct __eventlaunch_item_param {
85 } eventlaunch_item_param_s;
87 typedef struct esd_list_item {
93 typedef struct __event_launch_table_item {
95 char *package_name; /* just for passing pointer to app-list removal func */
96 GList *app_list_evtlaunch; /* app-list for on-event-launch */
101 enum __pkg_event_type {
108 typedef struct __pkgmgr_event {
113 typedef struct __esd_event_param {
119 typedef struct esd_info {
120 pkgmgr_client *client;
122 static esd_info_s s_info;
124 static Ecore_Fd_Handler *g_fd_handler;
125 sd_login_monitor *g_sd_monitor;
127 typedef struct __esd_appctrl_cb_data {
131 } esd_appctrl_cb_data;
133 static void __esd_event_handler(char *event_name, bundle *data, void *user_data);
134 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data);
136 static cynara *r_cynara = NULL;
138 static int __esd_init_cynara(void)
142 ret = cynara_initialize(&r_cynara, NULL);
143 if (ret != CYNARA_API_SUCCESS) {
144 _E("cynara initialize failed.");
151 static void __esd_finish_cynara(void)
154 cynara_finish(r_cynara);
158 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
159 static int __esd_check_earlier_support(const char *event_name)
162 int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
164 for (i = 0; i < size; i++) {
165 if (strcmp(earlier_event_list[i], event_name) == 0)
173 static int __esd_check_event_launch_support(const char *event_name)
176 int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list);
178 for (i = 0; i < size; i++) {
179 if (strcmp(event_launch_support_list[i], event_name) == 0)
186 static uid_t __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type)
188 GDBusMessage *msg = NULL;
189 GDBusMessage *reply = NULL;
194 msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
195 "org.freedesktop.DBus", type);
197 _E("Can't allocate new method call");
201 g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
202 reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
203 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
207 _E("Failed to get info [%s]", err->message);
213 body = g_dbus_message_get_body(reply);
214 g_variant_get(body, "(u)", &value);
220 g_object_unref(reply);
225 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
229 pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID");
231 _E("failed to get pid");
235 _D("sender_name(%s), pid(%d)", sender_name, pid);
240 static uid_t __get_sender_uid(GDBusConnection *conn, const char *sender_name)
244 uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser");
246 _E("failed to get uid");
248 _D("sender_name(%s), uid(%d)", sender_name, uid);
253 static int __esd_check_certificate_match(uid_t uid, const char *app_id, uid_t from_uid, const char *from_appid)
255 pkgmgrinfo_cert_compare_result_type_e res;
258 _D("uid(%d), app_id(%s), from_uid(%d), from_appid(%s)", uid, app_id, from_uid, from_appid);
260 if (uid != from_uid) {
261 /* TODO(jongmyeong.ko): check cert result if uids are not same */
265 ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, from_appid, uid, &res);
267 _E("failed to check certificate");
271 if (res != PMINFO_CERT_COMPARE_MATCH) {
272 _D("certificat not match (%s)", app_id);
279 static bool __esd_check_application_validation(uid_t uid, const char *appid)
282 pkgmgrinfo_appinfo_h handle;
284 ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle);
285 if (ret != PMINFO_R_OK)
288 pkgmgrinfo_appinfo_destroy_appinfo(handle);
290 /* FIXME(jongmyeong.ko) */
292 if (!aul_app_is_running(appid))
299 static void __esd_trusted_busname_print_items(void)
305 g_hash_table_iter_init(&iter, trusted_busname_table);
307 while (g_hash_table_iter_next(&iter, &key, &value)) {
308 trusted_item *item = (trusted_item *)value;
310 _D("uid(%d), appid(%s), pid(%d), busname(%s)", item->uid, item->app_id, item->pid, item->bus_name);
314 static int __esd_trusted_busname_add_item(uid_t uid, const char *appid, const char *busname, int pid)
317 char *bus_name = NULL;
318 trusted_item *item = NULL;
319 trusted_item *new_item;
321 app_id = strdup(appid);
322 if (app_id == NULL) {
327 bus_name = strdup(busname);
328 if (bus_name == NULL) {
330 FREE_AND_NULL(app_id);
334 item = (trusted_item *)g_hash_table_lookup(trusted_busname_table, app_id);
336 if (item && item->bus_name && strcmp(item->bus_name, bus_name) == 0 &&
337 (item->uid == uid)) {
338 _D("already exist (%s, %s)", app_id, bus_name);
339 FREE_AND_NULL(app_id);
340 FREE_AND_NULL(bus_name);
342 new_item = calloc(1, sizeof(trusted_item));
343 if (new_item == NULL) {
344 _E("memory alloc failed");
345 FREE_AND_NULL(app_id);
346 FREE_AND_NULL(bus_name);
350 new_item->app_id = app_id;
351 new_item->bus_name = bus_name;
353 g_hash_table_insert(trusted_busname_table, new_item->app_id, new_item);
354 _D("added busname(%s)", new_item->bus_name);
360 static int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name)
363 GError *error = NULL;
366 char tmp_appid[128] = {0, };
371 result = g_dbus_connection_call_sync(conn,
372 "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
373 list_name, NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE,
376 if (result == NULL) {
377 _E("get (%s) error(%s)", list_name, error->message);
382 g_variant_get(result, "(as)", &iter);
383 while (g_variant_iter_loop(iter, "s", &str)) {
384 if (!strstr((const char *)str, "event.busname.session"))
387 _D("list(%s), name(%s)", list_name, str);
388 pid = __get_sender_pid(conn, (const char *)str);
390 _E("failed to get pid(%d)", pid);
394 uid = __get_sender_uid(conn, (const char *)str);
396 _E("failed to get uid(%d)", uid);
401 memset(tmp_appid, 0, sizeof(tmp_appid));
402 ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), uid);
403 if (ret != AUL_R_OK) {
404 _E("failed to get appid by pid(%d)", pid);
408 _D("appid(%s)", tmp_appid);
409 if (__esd_check_application_validation(uid, tmp_appid)) {
411 ret = __esd_trusted_busname_add_item(uid, tmp_appid, (const char *)str, pid);
413 _E("failed to add item");
416 g_variant_iter_free(iter);
417 g_variant_unref(result);
422 static int __esd_check_privilege_name(const char *event_name, char **privilege_name)
426 *privilege_name = NULL;
428 for (i = 0; i < privilege_check_size; i++) {
429 if (strcmp(event_name, privilege_check_list[i].event_name) == 0) {
430 *privilege_name = (char *)privilege_check_list[i].privilege_name;
431 _D("[%d] privilege_name(%s)", i, *privilege_name);
439 static bool __esd_check_valid_privilege_by_cynara(const char *appid, const char *client,
440 const char *session, const char *user, const char *privilege_name)
443 bool has_privilege = false;
445 _D("check privilege, (%s, %s, %s, %s, %s)", appid, client, session, user, privilege_name);
447 ret = cynara_check(r_cynara, client, session, user, privilege_name);
448 if (ret == CYNARA_API_ACCESS_ALLOWED) {
449 _D("valid privilege");
450 has_privilege = true;
451 } else if (ret == CYNARA_API_ACCESS_DENIED) {
452 _E("invalid privilege");
454 _E("failed to check privilege, error(%d)", ret);
457 return has_privilege;
461 static int __esd_privilege_func(const char *name, void *user_data)
463 esd_privilege_check *epc = (esd_privilege_check *)user_data;
465 if (strcmp(name, epc->privilege_name) == 0) {
475 static int __esd_check_app_privileged_event(uid_t uid, const char *appid, const char *pkgid, const char *event_name)
477 char *privilege_name = NULL;
478 char client[256] = {0, };
482 _D("event_name(%s), uid(%d), appid(%s), pkgid(%s)", event_name, uid, appid, pkgid);
484 __esd_check_privilege_name(event_name, &privilege_name);
486 if (privilege_name) {
487 /* TODO(jongmyeong.ko): getting client should be replaced by cynara api */
488 snprintf(client, 256, "User::App::%s", pkgid);
489 user = (char *)g_strdup_printf("%u", uid);
490 if (!__esd_check_valid_privilege_by_cynara(appid, client, "", user, privilege_name)) {
491 _E("app(%s) has NOT privilege(%s)", appid, privilege_name);
499 static void __esd_print_appid_with_eventid(gpointer data, gpointer user_data)
501 esd_list_item_s *item = (esd_list_item_s *)data;
502 char *event_name = (char *)user_data;
504 _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name, item->uid, item->app_id, item->pkg_id);
507 static void __esd_print_interested_event(gpointer data, gpointer user_data)
509 event_launch_item *el_item = (event_launch_item *)data;
510 char *event_name = (char *)el_item->event_name;
511 _D("event_name = (%s)", event_name);
512 g_list_foreach(el_item->app_list_evtlaunch, __esd_print_appid_with_eventid, event_name);
515 static void __esd_launch_table_print_items(void)
521 g_hash_table_iter_init(&iter, event_launch_table);
523 while (g_hash_table_iter_next(&iter, &key, &value))
524 __esd_print_interested_event(value, NULL);
527 static int __esd_find_compare_by_list_item(gconstpointer data, gconstpointer user_data)
529 esd_list_item_s *item_1 = (esd_list_item_s *)user_data;
530 esd_list_item_s *item_2 = (esd_list_item_s *)data;
532 return (item_1->uid != item_2->uid) |
533 strcmp(item_1->app_id, item_2->app_id) |
534 strcmp(item_1->pkg_id, item_2->pkg_id);
537 static int __esd_add_list_item(uid_t uid, event_launch_item *el_item,
538 const char *app_id, const char *pkg_id)
540 esd_list_item_s *item_of_list = NULL;
542 item_of_list = calloc(1, sizeof(esd_list_item_s));
543 if (item_of_list == NULL) {
547 item_of_list->uid = uid;
548 item_of_list->app_id = (char *)app_id;
549 item_of_list->pkg_id = (char *)pkg_id;
550 el_item->app_list_evtlaunch =
551 g_list_append(el_item->app_list_evtlaunch, item_of_list);
556 static int __esd_add_launch_item(uid_t uid, const char *event_name, const char *appid, const char *pkgid)
558 GList *app_list = NULL;
559 guint subscription_id = 0;
562 esd_list_item_s *item_of_list = NULL;
563 event_launch_item *eli;
564 event_launch_item *el_item =
565 (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
568 item_of_list = calloc(1, sizeof(esd_list_item_s));
569 if (item_of_list == NULL) {
570 _E("memory alloc failed");
573 item_of_list->uid = uid;
574 item_of_list->app_id = (char *)appid;
575 item_of_list->pkg_id = (char *)pkgid;
577 app_list = g_list_find_custom(el_item->app_list_evtlaunch,
578 item_of_list, (GCompareFunc)__esd_find_compare_by_list_item);
580 if (app_list == NULL) {
581 _D("add new item (list item only)");
582 app_id = strdup((char *)appid);
587 pkg_id = strdup((char *)pkgid);
590 FREE_AND_NULL(app_id);
593 if (__esd_add_list_item(uid, el_item, app_id, pkg_id) < 0) {
594 _E("failed to add list item");
595 FREE_AND_NULL(app_id);
596 FREE_AND_NULL(pkg_id);
601 _D("add new item (all)");
602 eli = calloc(1, sizeof(event_launch_item));
604 _E("memory alloc failed");
608 eli->event_name = strdup(event_name);
609 if (!eli->event_name) {
615 app_id = strdup((char *)appid);
618 FREE_AND_NULL(eli->event_name);
623 pkg_id = strdup((char *)pkgid);
626 FREE_AND_NULL(app_id);
627 FREE_AND_NULL(eli->event_name);
632 if (__esd_add_list_item(uid, eli, app_id, pkg_id) < 0) {
633 _E("failed to add list item");
634 FREE_AND_NULL(app_id);
635 FREE_AND_NULL(pkg_id);
636 FREE_AND_NULL(eli->event_name);
641 g_hash_table_insert(event_launch_table, eli->event_name, eli);
643 eventsystem_register_event(eli->event_name, &subscription_id,
644 (eventsystem_handler)__esd_event_handler, NULL);
645 if (subscription_id == 0) {
646 _E("signal subscription error, event_name(%s), app_id(%s)",
647 eli->event_name, app_id);
650 eli->reg_id = subscription_id;
657 static void __esd_remove_all_private_usr_app_list(gpointer data, gpointer user_data)
659 esd_list_item_s *item = (esd_list_item_s *)data;
660 event_launch_item *eli = (event_launch_item *)user_data;
662 if (item->uid != GLOBAL_USER && !strcmp(eli->package_name, item->pkg_id)) {
663 _D("uid(%d), app_id(%s), pkg_id(%s)", item->uid, item->app_id, eli->package_name);
664 eli->app_list_evtlaunch = g_list_remove_all(eli->app_list_evtlaunch, data);
668 static int __esd_launch_table_remove_private_usr_items(void)
673 event_launch_item *eli = NULL;
674 GList *first_list = NULL;
676 g_hash_table_iter_init(&iter, event_launch_table);
678 while (g_hash_table_iter_next(&iter, &key, &value)) {
679 eli = (event_launch_item *)value;
680 g_list_foreach(eli->app_list_evtlaunch, __esd_remove_all_private_usr_app_list, eli);
682 first_list = g_list_first(eli->app_list_evtlaunch);
683 if (first_list == NULL) {
685 eventsystem_unregister_event(eli->reg_id);
687 g_hash_table_iter_remove(&iter);
694 static void __esd_remove_app_list(gpointer data, gpointer user_data)
697 esd_list_item_s *item = (esd_list_item_s *)data;
698 event_launch_item *eli = (event_launch_item *)user_data;
700 if (eli->uid != GLOBAL_USER && eli->uid != item->uid)
703 if (!skip && !strcmp(eli->package_name, item->pkg_id)) {
704 _D("pkg_id(%s), app_id(%s)", eli->package_name, item->app_id);
705 eli->app_list_evtlaunch =
706 g_list_remove_all(eli->app_list_evtlaunch, data);
710 static int __esd_remove_launch_item(uid_t uid, gpointer data, const char *pkg_id)
712 event_launch_item *eli = (event_launch_item *)data;
713 GList *first_list = NULL;
716 eli->package_name = (char *)pkg_id;
717 g_list_foreach(eli->app_list_evtlaunch, __esd_remove_app_list, eli);
719 first_list = g_list_first(eli->app_list_evtlaunch);
720 if (first_list == NULL) {
722 eventsystem_unregister_event(eli->reg_id);
730 static int __esd_launch_table_remove_items(uid_t uid, const char *pkg_id)
736 g_hash_table_iter_init(&iter, event_launch_table);
738 while (g_hash_table_iter_next(&iter, &key, &value)) {
739 if (__esd_remove_launch_item(uid, value, pkg_id) == ES_R_REMOVE) {
740 _D("remove item itself");
741 g_hash_table_iter_remove(&iter);
748 static void __esd_event_launch_with_appid(gpointer data, gpointer user_data)
750 esd_list_item_s *item = (esd_list_item_s *)data;
751 uid_t uid = item->uid;
752 char *app_id = item->app_id;
753 esd_event_param *eep = (esd_event_param *)user_data;
754 static unsigned int req_id;
756 char event_uri[1024];
758 /* char *from_appid = (char *)eep->user_data; */
759 /* uid_t from_uid = 0; */
762 _D("launch_on_event: app_id(%s), event_name(%s)", app_id, eep->event_name);
764 /* TODO(jongmyeong.ko): for launch by user-event */
766 if (from_appid && from_appid[0] != '\0') {
767 ret = __esd_check_certificate_match(uid, app_id, from_uid, from_appid);
768 if (ret != ES_R_OK) {
769 _D("from_appid(%s), no same cert", from_appid);
775 /* FIXME(jongmyeong.ko): aul_app_is_running */
777 if (!aul_app_is_running(app_id)) {
780 snprintf(event_uri, sizeof(event_uri), "event://%s", eep->event_name);
781 b = bundle_dup(eep->event_data);
782 appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT);
783 appsvc_set_uri(b, event_uri);
784 appsvc_set_appid(b, app_id);
786 pid = appsvc_usr_run_service(b, req_id++, NULL, eep->user_data, uid);
787 _D("uid(%d), pid(%d)", uid, pid);
791 _D("already is running");
795 static void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_data)
797 event_launch_item *el_item = (event_launch_item *)data;
798 esd_event_param *eep = (esd_event_param *)user_data;
800 if (strcmp(eep->event_name, (char *)el_item->event_name) == 0) {
801 g_list_foreach(el_item->app_list_evtlaunch,
802 __esd_event_launch_with_appid, user_data);
806 static void __esd_launch_event_handler(char *event_name, bundle *data, void *user_data)
809 const char *msg_type;
811 esd_event_param *eep;
812 event_launch_item *el_item;
814 _D("event_name(%s)", event_name);
816 el_item = (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
820 if (el_item->app_list_evtlaunch != NULL) {
821 if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) {
822 val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS);
823 _D("charger val(%s)", val);
824 if (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0)
826 } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) {
827 val = bundle_get_val(data, EVT_KEY_USB_STATUS);
828 _D("usb val(%s)", val);
829 if (strcmp(EVT_VAL_USB_CONNECTED, val) != 0)
831 } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) {
832 val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS);
833 _D("earjack val(%s)", val);
834 if (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0)
836 } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) {
837 msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE);
838 _D("msg_type(%s)", msg_type);
839 if (msg_type == NULL)
842 msg_id = bundle_get_val(data, EVT_KEY_MSG_ID);
843 _D("msg_id(%s)", msg_id);
848 eep = calloc(1, sizeof(esd_event_param));
850 _E("memory alloc failed");
853 eep->event_name = event_name;
854 eep->event_data = data;
855 eep->user_data = (void *)user_data;
856 __esd_check_event_launch_with_eventid(el_item, eep);
861 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
862 static void __esd_print_earlier_event(gpointer data, gpointer user_data)
864 earlier_item *item = (earlier_item *)data;
865 char *event_name = (char *)item->event_name;
868 _D("event_name = (%s)", event_name);
870 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
871 if (item->earlier_data) {
872 val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED);
873 _D("boot_completed(%s)", val);
875 } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
876 if (item->earlier_data) {
877 val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN);
878 _D("shutdown(%s)", val);
880 } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
881 if (item->earlier_data) {
882 val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY);
883 _D("low_memory(%s)", val);
885 } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
886 if (item->earlier_data) {
887 val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS);
888 _D("charger_status(%s)", val);
893 static void __esd_earlier_table_print_items(void)
899 g_hash_table_iter_init(&iter, earlier_event_table);
901 while (g_hash_table_iter_next(&iter, &key, &value))
902 __esd_print_earlier_event(value, NULL);
905 static void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data)
909 _D("event_name(%s)", event_name);
911 item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
913 /* update earlier value */
914 if (item->earlier_data != NULL)
915 bundle_free(item->earlier_data);
917 item->earlier_data = bundle_dup(data);
919 if (!g_is_bootcompleted) {
920 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
921 handle = creat(ESD_BOOT_COMPLETED, 0640);
924 g_is_bootcompleted = true;
931 static void __esd_event_handler(char *event_name, bundle *data, void *user_data)
933 _D("event_name(%s)", event_name);
935 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
936 if (__esd_check_earlier_support(event_name))
937 __esd_earlier_event_handler(event_name, data, user_data);
940 if (__esd_check_event_launch_support(event_name))
941 __esd_launch_event_handler(event_name, data, user_data);
944 static void __esd_trusted_busname_remove_item(char *bus_name)
951 g_hash_table_iter_init(&iter, trusted_busname_table);
953 while (g_hash_table_iter_next(&iter, &key, &value)) {
954 item = (trusted_item *)value;
956 if (strcmp(bus_name, item->bus_name) == 0) {
957 _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name);
958 FREE_AND_NULL(item->app_id);
959 FREE_AND_NULL(item->bus_name);
961 g_hash_table_iter_remove(&iter);
963 __esd_trusted_busname_print_items();
969 static void __esd_filter_name_owner_changed(GDBusConnection *connection,
970 const gchar *sender_name, const gchar *object_path,
971 const gchar *interface_name, const gchar *signal_name,
972 GVariant *parameters, gpointer user_data)
975 char *old_owner = NULL;
976 char *new_owner = NULL;
980 g_variant_get(parameters, "(sss)", &name, &old_owner, &new_owner);
982 if (strstr(name, "event.busname.session")) {
983 old_len = strlen(old_owner);
984 new_len = strlen(new_owner);
986 _D("changed name(%s), old_onwer(%s)(%d) -> new_onwer(%s)(%d)",
987 name, old_owner, old_len, new_owner, new_len);
989 if (old_len > 0 && new_len == 0)
990 __esd_trusted_busname_remove_item(name);
991 else if (old_len == 0 && new_len > 0)
992 _D("new name owned");
994 _E("not-expected name change");
998 static int __esd_dbus_name_monitor(GDBusConnection *connection)
1000 guint name_owner_changed_id = 0;
1002 name_owner_changed_id = g_dbus_connection_signal_subscribe(connection,
1003 "org.freedesktop.DBus", "org.freedesktop.DBus",
1004 "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1005 __esd_filter_name_owner_changed, NULL, NULL);
1007 _I("name_owner_changed_id(%d)", name_owner_changed_id);
1012 static int __esd_get_user_items(void)
1019 ret = sd_get_uids(&uids);
1021 _E("failed to get uids (%d)", ret);
1025 if (ret == 0 || uids == NULL) {
1026 _I("there is no uid for now");
1028 /* reset user's item */
1029 __esd_launch_table_remove_private_usr_items();
1030 for (i = 0; i < ret; i++) {
1032 _I("found uid(%d)", cur_uid);
1034 ret = pkgmgrinfo_appinfo_get_usr_installed_list(__esd_add_appinfo_handler, cur_uid, &cur_uid);
1036 _E("failed to get user(%d)-app list (%d)", cur_uid, ret);
1040 __esd_launch_table_print_items();
1045 static Eina_Bool __esd_fd_handler_func(void *data, Ecore_Fd_Handler *fd_handler)
1047 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
1049 __esd_get_user_items();
1052 return ECORE_CALLBACK_CANCEL;
1055 static int __esd_start_sd_monitor(void)
1060 ret = __esd_get_user_items();
1064 ret = sd_login_monitor_new("uid", &g_sd_monitor);
1066 _E("sd_login_monitor_new error (%d)", ret);
1070 fd = sd_login_monitor_get_fd(g_sd_monitor);
1072 _E("sd_login_monitor_get_fd error");
1073 sd_login_monitor_unref(g_sd_monitor);
1077 g_fd_handler = ecore_main_fd_handler_add(fd,
1078 (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR),
1079 __esd_fd_handler_func, NULL, NULL, NULL);
1080 if (g_fd_handler == NULL) {
1081 _E("fd_handler is NULL");
1082 sd_login_monitor_unref(g_sd_monitor);
1086 _I("setup sd-monitor done");
1091 static int __esd_stop_sd_monitor(void)
1093 _I("stop sd_monitor");
1095 ecore_main_fd_handler_del(g_fd_handler);
1096 g_fd_handler = NULL;
1099 sd_login_monitor_unref(g_sd_monitor);
1105 static GDBusNodeInfo *introspection_data;
1106 static const gchar introspection_xml[] =
1108 " <interface name='tizen.system.event.app2esd'>"
1109 " <method name='CheckSenderValidation'>"
1110 " <arg type='i' name='senderpid' direction='in'/>"
1111 " <arg type='s' name='eventname' direction='in'/>"
1112 " <arg type='i' name='ret' direction='out'/>"
1113 " <arg type='s' name='senderid' direction='out'/>"
1115 " <method name='GetTrustedPeerList'>"
1116 " <arg type='s' name='eventname' direction='in'/>"
1117 " <arg type='i' name='ret' direction='out'/>"
1118 " <arg type='as' name='dest_list' direction='out'/>"
1120 " <method name='SetupTrustedPeer'>"
1121 " <arg type='s' name='eventname' direction='in'/>"
1122 " <arg type='s' name='destination' direction='in'/>"
1123 " <arg type='i' name='ret' direction='out'/>"
1125 " <method name='CheckPrivilegeValidation'>"
1126 " <arg type='s' name='eventname' direction='in'/>"
1127 " <arg type='i' name='ret' direction='out'/>"
1129 " <method name='CheckUserSendValidation'>"
1130 " <arg type='s' name='eventname' direction='in'/>"
1131 " <arg type='i' name='ret' direction='out'/>"
1133 " <method name='RequestTrustedEventLaunch'>"
1134 " <arg type='s' name='eventname' direction='in'/>"
1135 " <arg type='s' name='eventdata' direction='in'/>"
1136 " <arg type='i' name='datalen' direction='in'/>"
1137 " <arg type='i' name='ret' direction='out'/>"
1139 " <method name='RequestEventLaunch'>"
1140 " <arg type='s' name='eventname' direction='in'/>"
1141 " <arg type='s' name='eventdata' direction='in'/>"
1142 " <arg type='i' name='datalen' direction='in'/>"
1143 " <arg type='i' name='ret' direction='out'/>"
1145 " <method name='RequestSendingEvent'>"
1146 " <arg type='s' name='eventname' direction='in'/>"
1147 " <arg type='s' name='eventdata' direction='in'/>"
1148 " <arg type='i' name='datalen' direction='in'/>"
1149 " <arg type='i' name='ret' direction='out'/>"
1151 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1152 " <method name='GetEarlierData'>"
1153 " <arg type='s' name='appid' direction='in'/>"
1154 " <arg type='i' name='ret' direction='out'/>"
1155 " <arg type='i' name='len' direction='out'/>"
1156 " <arg type='s' name='earlier_data' direction='out'/>"
1162 static int __esd_get_appid_by_pid(int pid, uid_t uid, char *app_id, int buf_size)
1164 int retval = ES_R_OK;
1168 _E("invalid pid(%d)", pid);
1169 retval = ES_R_ERROR;
1170 } else if (uid <= 0) {
1171 _E("invalid uid(%d)", uid);
1172 retval = ES_R_ERROR;
1174 ret = aul_app_get_appid_bypid_for_uid(pid, app_id, buf_size, (uid_t)uid);
1175 if (ret != AUL_R_OK) {
1176 _E("failed to get appid by pid");
1177 retval = ES_R_ERROR;
1179 _D("pid(%d)-uid(%d)-appid(%s)", pid, uid, app_id);
1185 static int check_user_event_sender_valid(const char *event_name, const char *app_id)
1187 char *valid_name = NULL;
1188 char *temp_name = NULL;
1190 int retval = ES_R_OK;
1192 int valid_name_len = 0;
1194 temp_name = strdup(event_name);
1195 if (temp_name == NULL) {
1196 _E("out of memory");
1200 tmp = strrchr(temp_name, '.');
1201 if (tmp == NULL || strlen(tmp) == 0) {
1202 _E("invalid event name");
1203 FREE_AND_NULL(temp_name);
1207 if (len <= 1 || len > 128) {
1208 _E("invalid length(%d) of user-defined name");
1209 FREE_AND_NULL(temp_name);
1214 _D("app_id(%s), len(%d)", app_id, strlen(app_id));
1216 valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1;
1217 valid_name = calloc(1, valid_name_len);
1218 if (valid_name == NULL) {
1219 _E("memory alloc failed");
1220 FREE_AND_NULL(temp_name);
1223 snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id);
1224 _D("valid_name(%s)", valid_name);
1226 if (strcmp(temp_name, valid_name) != 0) {
1227 _E("appid misamatch");
1228 retval = ES_R_EINVAL;
1231 FREE_AND_NULL(temp_name);
1232 FREE_AND_NULL(valid_name);
1237 static void check_sender_valid_method_call(GDBusConnection *connection, const gchar *sender,
1238 GVariant *parameters, GDBusMethodInvocation *invocation)
1240 GVariant *param = NULL;
1242 char *event_name = NULL;
1243 char app_id[128] = {0, };
1244 int event_sender_pid = 0;
1245 uid_t sender_uid = 0;
1247 g_variant_get(parameters, "(is)", &event_sender_pid, &event_name);
1248 _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name);
1250 sender_uid = __get_sender_uid(connection, sender);
1251 if (__esd_get_appid_by_pid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1252 result = ES_R_ERROR;
1254 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1255 _E("invalid sender");
1256 result = ES_R_EINVAL;
1262 param = g_variant_new("(is)", result, app_id);
1263 _D("event_name(%s), result(%d)", event_name, result);
1264 g_dbus_method_invocation_return_value(invocation, param);
1267 static void check_send_event_valid_method_call(GDBusConnection *connection, const gchar *sender,
1268 GVariant *parameters, GDBusMethodInvocation *invocation)
1270 GVariant *param = NULL;
1272 char *event_name = NULL;
1273 char app_id[128] = {0, };
1275 uid_t sender_uid = 0;
1277 g_variant_get(parameters, "(s)", &event_name);
1278 _D("event_name(%s)", event_name);
1280 sender_pid = __get_sender_pid(connection, sender);
1281 sender_uid = __get_sender_uid(connection, sender);
1282 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1283 result = ES_R_ERROR;
1285 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1286 _E("invalid sender");
1287 result = ES_R_EINVAL;
1293 param = g_variant_new("(i)", result);
1294 _D("event_name(%s), result(%d)", event_name, result);
1295 g_dbus_method_invocation_return_value(invocation, param);
1298 static void get_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1299 GVariant *parameters, GDBusMethodInvocation *invocation)
1301 GVariant *param = NULL;
1303 GVariantBuilder *builder = NULL;
1304 GHashTableIter iter;
1305 gpointer key, value;
1306 char *event_name = NULL;
1307 char app_id[128] = {0, };
1309 uid_t sender_uid = 0;
1312 char *_appid = NULL;
1313 char *_busname = NULL;
1316 g_variant_get(parameters, "(s)", &event_name);
1317 _D("event_name(%s)", event_name);
1319 sender_pid = __get_sender_pid(connection, sender);
1320 sender_uid = __get_sender_uid(connection, sender);
1321 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1322 result = ES_R_ERROR;
1324 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1326 g_hash_table_iter_init(&iter, trusted_busname_table);
1327 while (g_hash_table_iter_next(&iter, &key, &value)) {
1328 item = (trusted_item *)value;
1330 _appid = item->app_id;
1331 _busname = item->bus_name;
1333 if (uid != GLOBAL_USER && uid != sender_uid)
1336 ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id);
1338 g_variant_builder_add(builder, "s", _busname);
1344 param = g_variant_new("(ias)", result, builder);
1345 _D("result(%d)", result);
1346 g_dbus_method_invocation_return_value(invocation, param);
1348 g_variant_builder_unref(builder);
1351 static void setup_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1352 GVariant *parameters, GDBusMethodInvocation *invocation)
1354 GVariant *param = NULL;
1356 char *event_name = NULL;
1357 char *destination_name = NULL;
1358 char app_id[128] = {0, };
1360 uid_t sender_uid = 0;
1363 g_variant_get(parameters, "(ss)", &event_name, &destination_name);
1364 _D("event_name(%s), destination_name(%s)", event_name, destination_name);
1366 if (destination_name && destination_name[0] != '\0') {
1367 sender_pid = __get_sender_pid(connection, sender);
1368 sender_uid = __get_sender_uid(connection, sender);
1369 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1370 result = ES_R_ERROR;
1372 ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name,
1375 _E("failed to add trusted busname item");
1376 result = ES_R_ERROR;
1382 _E("invalid destination name");
1383 result = ES_R_ERROR;
1386 param = g_variant_new("(i)", result);
1387 _D("event_name(%s), result(%d)", event_name, result);
1388 g_dbus_method_invocation_return_value(invocation, param);
1391 static void check_privilege_valid_method_call(GDBusConnection *connection, const gchar *sender,
1392 GVariant *parameters, GDBusMethodInvocation *invocation)
1394 GVariant *param = NULL;
1396 char *event_name = NULL;
1397 char *privilege_name = NULL;
1398 char app_id[128] = {0, };
1400 uid_t sender_uid = 0;
1401 char *client = NULL;
1402 char *session = NULL;
1406 g_variant_get(parameters, "(s)", &event_name);
1407 __esd_check_privilege_name(event_name, &privilege_name);
1408 _D("event_name(%s), privilege_name(%s)", event_name, privilege_name);
1410 if (privilege_name) {
1411 sender_pid = __get_sender_pid(connection, sender);
1412 sender_uid = __get_sender_uid(connection, sender);
1413 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1414 result = ES_R_ERROR;
1416 ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client);
1417 if (ret != CYNARA_API_SUCCESS) {
1418 _E("failed to get client");
1419 result = ES_R_EINVAL;
1423 ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user);
1424 if (ret != CYNARA_API_SUCCESS) {
1425 _E("failed to get user");
1426 result = ES_R_EINVAL;
1430 session = cynara_session_from_pid(sender_pid);
1431 if (session == NULL) {
1432 _E("failed to get session");
1433 result = ES_R_EINVAL;
1437 _D("app_id(%s), client(%s), session(%s), user(%s)", app_id, client, session, user);
1438 if (__esd_check_valid_privilege_by_cynara(app_id, client, session, user, privilege_name))
1441 result = ES_R_EINVAL;
1451 param = g_variant_new("(i)", result);
1452 _D("event_name(%s), result(%d)", event_name, result);
1453 g_dbus_method_invocation_return_value(invocation, param);
1456 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1457 static void get_earlier_data_method_call(GVariant *parameters, GDBusMethodInvocation *invocation)
1459 GVariant *param = NULL;
1461 char *event_name = NULL;
1463 bundle_raw *raw = NULL;
1467 g_variant_get(parameters, "(s)", &event_name);
1469 if (event_name && strlen(event_name) > 0) {
1470 _D("event_name(%s)", event_name);
1473 _E("invalid event_name(%s)", event_name);
1474 result = ES_R_ERROR;
1477 item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1479 if (item->earlier_data) {
1480 b = bundle_dup(item->earlier_data);
1481 bundle_add_str(b, "is_earlier_data", "true");
1482 bundle_encode(b, &raw, &len);
1487 param = g_variant_new("(iis)", result, len, raw);
1489 _D("result(%d), len(%d)", result, len);
1490 g_dbus_method_invocation_return_value(invocation, param);
1492 bundle_free_encoded_rawdata(&raw);
1496 static void handle_method_call(GDBusConnection *connection,
1497 const gchar *sender, const gchar *object_path,
1498 const gchar *interface_name, const gchar *method_name,
1499 GVariant *parameters, GDBusMethodInvocation *invocation,
1502 if (g_strcmp0(method_name, "CheckSenderValidation") == 0) {
1503 check_sender_valid_method_call(connection, sender, parameters, invocation);
1504 } else if (g_strcmp0(method_name, "GetTrustedPeerList") == 0) {
1505 get_trusted_peer_method_call(connection, sender, parameters, invocation);
1506 } else if (g_strcmp0(method_name, "SetupTrustedPeer") == 0) {
1507 setup_trusted_peer_method_call(connection, sender, parameters, invocation);
1508 } else if (g_strcmp0(method_name, "CheckPrivilegeValidation") == 0) {
1509 check_privilege_valid_method_call(connection, sender, parameters, invocation);
1510 } else if (g_strcmp0(method_name, "CheckUserSendValidation") == 0) {
1511 check_send_event_valid_method_call(connection, sender, parameters, invocation);
1512 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1513 } else if (g_strcmp0(method_name, "GetEarlierData") == 0) {
1514 get_earlier_data_method_call(parameters, invocation);
1519 static const GDBusInterfaceVTable interface_vtable = {
1525 static void __esd_on_bus_acquired(GDBusConnection *connection,
1526 const gchar *name, gpointer user_data)
1528 _I("bus acquired(%s)", name);
1531 GError *error = NULL;
1533 reg_id = g_dbus_connection_register_object(connection,
1535 introspection_data->interfaces[0],
1537 NULL, NULL, &error);
1539 _E("g_dbus_connection_register_object error(%s)", error->message);
1540 g_error_free(error);
1544 static void __esd_on_name_acquired(GDBusConnection *connection,
1545 const gchar *name, gpointer user_data)
1549 _I("name acquired(%s)", name);
1551 __esd_check_trusted_events(connection, "ListNames");
1552 __esd_check_trusted_events(connection, "ListActivatableNames");
1554 b = bundle_create();
1555 bundle_add_str(b, EVT_KEY_ESD_STATUS, EVT_VAL_ESD_STARTED);
1556 eventsystem_send_system_event(SYS_EVENT_ESD_STATUS, b);
1559 __esd_register_vconf_callbacks();
1561 __esd_trusted_busname_print_items();
1563 __esd_start_sd_monitor();
1565 __esd_dbus_name_monitor(connection);
1568 static void __esd_on_name_lost(GDBusConnection *connection,
1569 const gchar *name, gpointer user_data)
1571 _E("name lost(%s)", name);
1574 static int __esd_before_loop(void)
1578 GError *error = NULL;
1581 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1582 guint subscription_id = 0;
1593 earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal);
1595 _I("register events for earlier_data");
1596 size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
1597 for (i = 0; i < size; i++) {
1598 event_name = (char *)earlier_event_list[i];
1599 _I("event_name(%s)", event_name);
1601 item = calloc(1, sizeof(earlier_item));
1603 _E("memery alloc failed");
1606 item->event_name = strdup(event_name);
1607 if (item->event_name == NULL) {
1608 _E("out of memory");
1613 /* set initial data */
1614 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
1615 fd = open(ESD_BOOT_COMPLETED, O_RDONLY);
1617 _D("open file error(%d)", fd);
1619 item->earlier_data = bundle_create();
1620 bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED,
1621 EVT_VAL_BOOT_COMPLETED_TRUE);
1624 } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
1625 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val);
1626 if (ret != VCONF_OK) {
1627 _E("failed to get power_off status (%d)", ret);
1629 if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT ||
1630 val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
1631 /* power-off requested */
1632 item->earlier_data = bundle_create();
1633 bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN,
1634 EVT_VAL_SYSTEM_SHUTDOWN_TRUE);
1637 } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
1638 ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status);
1639 if (ret != VCONF_OK) {
1640 _E("failed to get low_memory status (%d)", ret);
1642 item->earlier_data = bundle_create();
1643 if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
1644 bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1645 EVT_VAL_MEMORY_SOFT_WARNING);
1646 else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING)
1647 bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1648 EVT_VAL_MEMORY_HARD_WARNING);
1650 bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1651 EVT_VAL_MEMORY_NORMAL);
1653 } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
1654 ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status);
1655 if (ret != VCONF_OK) {
1656 _E("failed to get charger_status (%d)", ret);
1658 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now);
1659 if (ret != VCONF_OK)
1660 _E("failed to get charge_now (%d)", ret);
1663 if (ret == VCONF_OK) {
1664 item->earlier_data = bundle_create();
1665 if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) {
1666 if (charge_now == 0) {
1667 bundle_add_str(item->earlier_data,
1668 EVT_KEY_BATTERY_CHARGER_STATUS,
1669 EVT_VAL_BATTERY_CHARGER_DISCHARGING);
1671 bundle_add_str(item->earlier_data,
1672 EVT_KEY_BATTERY_CHARGER_STATUS,
1673 EVT_VAL_BATTERY_CHARGER_CHARGING);
1676 bundle_add_str(item->earlier_data,
1677 EVT_KEY_BATTERY_CHARGER_STATUS,
1678 EVT_VAL_BATTERY_CHARGER_DISCONNECTED);
1683 eventsystem_register_event(event_name, &subscription_id,
1684 (eventsystem_handler)__esd_event_handler, NULL);
1685 if (subscription_id == 0) {
1686 _E("signal subscription error, event_name(%s)", event_name);
1687 if (item->earlier_data)
1688 bundle_free(item->earlier_data);
1689 free(item->event_name);
1694 item->reg_id = subscription_id;
1697 g_hash_table_insert(earlier_event_table, event_name, item);
1700 __esd_earlier_table_print_items();
1703 event_launch_table = g_hash_table_new(g_str_hash, g_str_equal);
1705 _I("get event launch list");
1707 /* get global user info */
1709 ret = pkgmgrinfo_appinfo_get_usr_installed_list(__esd_add_appinfo_handler, uid, &uid);
1711 _E("failed to get global-app list (%d)", ret);
1715 __esd_launch_table_print_items();
1717 trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal);
1719 /* gdbus setup for method call */
1720 introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
1721 if (!introspection_data) {
1722 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
1723 g_error_free(error);
1727 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1729 G_BUS_NAME_OWNER_FLAGS_NONE,
1730 __esd_on_bus_acquired,
1731 __esd_on_name_acquired,
1735 _E("g_bus_own_name error");
1736 g_dbus_node_info_unref(introspection_data);
1740 _I("esd before_loop done");
1745 static void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event)
1747 pkg_event->type = UNKNOWN;
1748 if (pkg_event->pkgid) {
1749 free(pkg_event->pkgid);
1750 pkg_event->pkgid = NULL;
1754 static int __esd_appcontrol_cb(const char *operation,
1755 const char *uri, const char *mime, void *data)
1757 esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data;
1760 char *event_name = NULL;
1761 const char *prefix = "event://";
1764 if (cb_data == NULL) {
1768 appid = cb_data->appid;
1769 pkgid = cb_data->pkgid;
1772 _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)",
1773 uid, appid, pkgid, operation, uri, mime);
1775 if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) {
1776 if (!strncmp(uri, prefix, strlen(prefix))) {
1777 event_name = strdup(&uri[8]);
1779 _D("appid(%s), event_name(%s)", appid, event_name);
1780 if (!__esd_check_event_launch_support(event_name)) {
1781 _E("failed to add item (not support event)");
1782 } else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name)) {
1783 _E("failed to add item (no privilege)");
1785 if (__esd_add_launch_item(uid, event_name, appid, pkgid))
1786 _E("failed to add item");
1788 FREE_AND_NULL(event_name);
1790 _E("out of memory");
1793 _E("Invalid uri(%s) for event_name", uri);
1800 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data)
1804 pkgmgrinfo_app_component component_type;
1806 uid_t *p_uid = NULL;
1813 p_uid = (uid_t *)data;
1815 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
1817 _E("failed to get appid");
1821 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
1823 _E("failed to get pkgid");
1827 ret = pkgmgrinfo_appinfo_get_component(handle, &component_type);
1828 if (ret != PMINFO_R_OK) {
1829 _E("fail to get component type");
1833 _D("uid(%d), appid(%s), component_type(%d)", *p_uid, appid, component_type);
1834 if (component_type == PMINFO_SVC_APP) {
1835 esd_appctrl_cb_data *cb_data = calloc(1, sizeof(esd_appctrl_cb_data));
1836 if (cb_data == NULL) {
1837 _E("memory alloc failed");
1840 cb_data->appid = strdup(appid);
1841 if (cb_data->appid == NULL) {
1842 _E("out_of_memory");
1843 FREE_AND_NULL(cb_data);
1846 cb_data->pkgid = strdup(pkgid);
1847 if (cb_data->pkgid == NULL) {
1848 _E("out_of_memory");
1849 FREE_AND_NULL(cb_data->appid);
1850 FREE_AND_NULL(cb_data);
1853 cb_data->uid = *p_uid;
1854 ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
1855 (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data);
1857 FREE_AND_NULL(cb_data->pkgid);
1858 FREE_AND_NULL(cb_data->appid);
1859 FREE_AND_NULL(cb_data);
1862 _E("failed to get appcontrol info");
1865 __esd_launch_table_print_items();
1871 static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id, const char *pkg_type,
1872 const char *pkgid, const char *key, const char *val,
1873 const void *pmsg, void *data)
1875 esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data;
1876 pkgmgrinfo_pkginfo_h handle = NULL;
1879 _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)",
1880 target_uid, req_id, pkg_type, pkgid, key, val);
1882 if (strncmp(key, "start", strlen(key)) == 0) {
1883 if (strcmp(val, "install") == 0) {
1884 _D("install start");
1885 pkg_event->type = INSTALL;
1886 } else if (strcmp(val, "uninstall") == 0) {
1887 _D("unistall start");
1888 pkg_event->type = UNINSTALL;
1889 } else if (strcmp(val, "update") == 0) {
1891 pkg_event->type = UPDATE;
1893 _D("val(%s) start", val);
1894 __esd_pkgmgr_event_free(pkg_event);
1896 } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) {
1897 if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) {
1898 _D("install end (ok)");
1899 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle);
1901 _E("failed to get pkginfo");
1902 __esd_pkgmgr_event_free(pkg_event);
1905 ret = pkgmgrinfo_appinfo_get_usr_list(handle,
1906 PMINFO_ALL_APP, __esd_add_appinfo_handler, &target_uid, target_uid);
1908 _E("failed to get appinfo");
1909 __esd_pkgmgr_event_free(pkg_event);
1912 ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1914 _E("failed to destroy pkginfo");
1915 __esd_pkgmgr_event_free(pkg_event);
1918 } else if (pkg_event->type == UNINSTALL) {
1919 _D("uninstall end (ok)");
1920 __esd_launch_table_remove_items(target_uid, pkgid);
1921 __esd_launch_table_print_items();
1923 __esd_pkgmgr_event_free(pkg_event);
1924 } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) {
1925 _E("pkg_event(%d) falied", pkg_event->type);
1926 __esd_pkgmgr_event_free(pkg_event);
1928 if (strcmp(key, "install_percent") != 0)
1929 __esd_pkgmgr_event_free(pkg_event);
1935 static int __esd_init()
1939 pkgmgr_client *client;
1940 esd_pkgmgr_event *pkg_event;
1942 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
1947 __esd_init_cynara();
1949 client = pkgmgr_client_new(PC_LISTENING);
1950 if (client == NULL) {
1951 _E("set pkgmgr client failed");
1955 pkg_event = calloc(1, sizeof(esd_pkgmgr_event));
1956 if (pkg_event == NULL) {
1957 _E("memory alloc failed");
1958 ret = pkgmgr_client_free(client);
1959 if (ret != PKGMGR_R_OK)
1960 _E("pkgmgr_client_free failed(%d)", ret);
1965 req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event);
1967 _E("pkgmgr client listen failed");
1968 ret = pkgmgr_client_free(client);
1969 if (ret != PKGMGR_R_OK)
1970 _E("pkgmgr_client_free failed(%d)", ret);
1975 s_info.client = client;
1977 _I("esd init done");
1982 static void __esd_remove_esd_list_item(gpointer data, gpointer user_data)
1984 esd_list_item_s *item = (esd_list_item_s *)data;
1990 static void __esd_finalize(void)
1994 GHashTableIter iter;
1996 event_launch_item *el_item;
1998 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1999 earlier_item *er_item;
2004 __esd_stop_sd_monitor();
2006 if (trusted_busname_table) {
2007 g_hash_table_iter_init(&iter, trusted_busname_table);
2008 while (g_hash_table_iter_next(&iter, &key, &value)) {
2009 item = (trusted_item *)value;
2012 free(item->bus_name);
2017 g_hash_table_iter_remove(&iter);
2019 g_hash_table_unref(trusted_busname_table);
2022 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2023 if (earlier_event_table) {
2024 g_hash_table_iter_init(&iter, earlier_event_table);
2025 while (g_hash_table_iter_next(&iter, &key, &value)) {
2026 er_item = (earlier_item *)value;
2028 eventsystem_unregister_event(er_item->reg_id);
2029 free(er_item->event_name);
2030 bundle_free(er_item->earlier_data);
2033 _E("ealier item is NULL");
2035 g_hash_table_iter_remove(&iter);
2037 g_hash_table_unref(earlier_event_table);
2041 if (event_launch_table) {
2042 g_hash_table_iter_init(&iter, event_launch_table);
2043 while (g_hash_table_iter_next(&iter, &key, &value)) {
2044 el_item = (event_launch_item *)value;
2046 eventsystem_unregister_event(el_item->reg_id);
2047 free(el_item->event_name);
2048 g_list_foreach(el_item->app_list_evtlaunch,
2049 __esd_remove_esd_list_item, NULL);
2050 g_list_free(el_item->app_list_evtlaunch);
2055 g_hash_table_iter_remove(&iter);
2057 g_hash_table_unref(event_launch_table);
2060 if (introspection_data)
2061 g_dbus_node_info_unref(introspection_data);
2063 if (s_info.client) {
2064 ret = pkgmgr_client_free(s_info.client);
2065 if (ret != PKGMGR_R_OK)
2066 _E("pkgmgr_client_free failed(%d)", ret);
2069 __esd_finish_cynara();
2071 _D("esd finalize end");
2074 int main(int argc, char *argv[])
2076 _I("event system daemon : main()");
2078 if (__esd_init() != 0) {
2079 _E("ESD Initialization failed!");
2084 if (__esd_before_loop() < 0) {
2091 ecore_main_loop_begin();