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 <cert-svc/ccert.h>
20 #include <cert-svc/cinstance.h>
21 #include <cynara-client.h>
22 #include <cynara-creds-gdbus.h>
23 #include <cynara-session.h>
24 #include <security-manager.h>
25 #include "eventsystem_daemon.h"
27 #define DEFAULT_USER tzplatform_getuid(TZ_SYS_DEFAULT_USER)
28 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
31 #define SYS_EVENT_NAME_PREFIX "tizen.system.event"
32 #define SYS_EVENT_OBJ_PATH "/tizen/system/event"
33 #define REQUEST_LAST_DATA "request_last_data"
35 static GHashTable *event_launch_table; /* table of events for launch_on_event*/
37 static const char *event_launch_support_list[] = {
38 SYS_EVENT_BATTERY_CHARGER_STATUS,
40 SYS_EVENT_EARJACK_STATUS,
41 SYS_EVENT_INCOMMING_MSG,
42 SYS_EVENT_OUTGOING_MSG,
46 struct privilege_info {
47 const char *event_name;
48 const char *privilege_name;
51 static const struct privilege_info privilege_check_list[] = {
52 {SYS_EVENT_DISPLAY_STATE, "http://tizen.org/privilege/display"},
53 {SYS_EVENT_WIFI_STATE, "http://tizen.org/privilege/network.get"},
54 {SYS_EVENT_INCOMMING_MSG, "http://tizen.org/privilege/message.read"},
55 {SYS_EVENT_OUTGOING_MSG, "http://tizen.org/privilege/message.read"}
58 static int privilege_check_size = sizeof(privilege_check_list)/sizeof(struct privilege_info);
60 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
61 static const char *earlier_event_list[] = {
64 SYS_EVENT_BOOT_COMPLETED,
65 SYS_EVENT_SYSTEM_SHUTDOWN,
66 SYS_EVENT_BATTERY_CHARGER_STATUS
69 static GHashTable *earlier_event_table; /* table of events for earlier_data */
71 typedef struct __earlier_table_item {
74 bundle *earlier_data; /* event-data from earlier occurrence */
79 static GHashTable *user_last_event_table; /* table of user events for last data */
81 struct __last_event_item {
89 static GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */
91 typedef struct __trusted_busname_item {
98 typedef struct __eventlaunch_item_param {
100 } eventlaunch_item_param_s;
102 enum trusted_result {
108 typedef struct esd_list_item {
115 typedef struct __event_launch_table_item {
117 char *package_name; /* just for passing pointer to app-list removal func */
118 GList *app_list_evtlaunch; /* app-list for on-event-launch */
123 enum __pkg_event_type {
130 typedef struct __pkgmgr_event {
135 typedef struct __esd_event_param {
145 typedef struct esd_info {
146 pkgmgr_client *client;
148 static esd_info_s s_info;
150 typedef struct __esd_appctrl_cb_data {
154 } esd_appctrl_cb_data;
156 static void __esd_event_handler(char *event_name, bundle *data, void *user_data);
157 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data);
159 static cynara *r_cynara;
161 static int __esd_init_cynara(void)
165 ret = cynara_initialize(&r_cynara, NULL);
166 if (ret != CYNARA_API_SUCCESS) {
167 _E("cynara initialize failed.");
174 static void __esd_finish_cynara(void)
177 cynara_finish(r_cynara);
181 static void free_saved_event(struct __last_event_item *item)
186 free(item->event_name);
187 free(item->own_name);
192 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
193 static int __esd_check_earlier_support(const char *event_name)
196 int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
198 for (i = 0; i < size; i++) {
199 if (strcmp(earlier_event_list[i], event_name) == 0)
207 static bool __esd_check_platform_cert(const char *pkgid, uid_t uid)
209 _D("Checking if %s has a platform certification", pkgid);
212 const char *cert_value;
213 pkgmgrinfo_certinfo_h certinfo;
214 CertSvcInstance instance;
215 CertSvcCertificate certificate;
216 CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
218 r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
219 if (r != PMINFO_R_OK) {
220 _E("Failed to create certinfo");
224 r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid);
225 if (r != PMINFO_R_OK) {
226 _E("Failed to load certinfo");
227 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
231 r = pkgmgrinfo_pkginfo_get_cert_value(certinfo,
232 PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value);
233 if (r != PMINFO_R_OK || cert_value == NULL) {
234 _E("Failed to get cert value");
235 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
239 r = certsvc_instance_new(&instance);
240 if (r != CERTSVC_SUCCESS) {
241 _E("certsvc_instance_new() is failed.");
242 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
246 r = certsvc_certificate_new_from_memory(instance,
247 (const unsigned char *)cert_value,
249 CERTSVC_FORM_DER_BASE64,
251 if (r != CERTSVC_SUCCESS) {
252 _E("certsvc_certificate_new_from_memory() is failed.");
253 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
254 certsvc_instance_free(instance);
258 r = certsvc_certificate_get_visibility(certificate, &visibility);
259 if (r != CERTSVC_SUCCESS)
260 _E("certsvc_certificate_get_visibility() is failed.");
262 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
263 certsvc_instance_free(instance);
264 certsvc_certificate_free(certificate);
266 _D("visibility is %d", visibility);
267 if (visibility & CERTSVC_VISIBILITY_PLATFORM) {
268 _D("%s has a platform certification", pkgid);
275 static int __esd_check_event_launch_support(const char *event_name)
278 int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list);
280 for (i = 0; i < size; i++) {
281 if (strcmp(event_launch_support_list[i], event_name) == 0)
288 static int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type)
290 GDBusMessage *msg = NULL;
291 GDBusMessage *reply = NULL;
297 msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
298 "org.freedesktop.DBus", type);
300 _E("Can't allocate new method call");
304 g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
305 reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
306 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
310 _E("Failed to get info [%s]", err->message);
316 body = g_dbus_message_get_body(reply);
317 g_variant_get(body, "(u)", &value);
324 g_object_unref(reply);
329 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
333 pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID");
335 _E("failed to get pid");
339 _D("sender_name(%s), pid(%d)", sender_name, pid);
344 static int __get_sender_uid(GDBusConnection *conn, const char *sender_name)
348 uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser");
350 _E("failed to get uid");
352 _D("sender_name(%s), uid(%d)", sender_name, uid);
357 static int __esd_check_certificate_match(uid_t uid, const char *app_id, uid_t from_uid, const char *from_appid)
359 pkgmgrinfo_cert_compare_result_type_e res;
362 _D("uid(%d), app_id(%s), from_uid(%d), from_appid(%s)", uid, app_id, from_uid, from_appid);
364 ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, from_appid, from_uid, &res);
366 _E("failed to check certificate");
370 if (res != PMINFO_CERT_COMPARE_MATCH) {
371 _D("certificat not match (%s)", app_id);
378 static bool __esd_check_application_validation(uid_t uid, const char *appid)
381 pkgmgrinfo_appinfo_h handle;
383 ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle);
384 if (ret != PMINFO_R_OK)
387 pkgmgrinfo_appinfo_destroy_appinfo(handle);
389 if (!aul_app_is_running_for_uid(appid, uid))
395 static void __esd_trusted_busname_print_items(void)
401 g_hash_table_iter_init(&iter, trusted_busname_table);
403 while (g_hash_table_iter_next(&iter, &key, &value)) {
404 trusted_item *item = (trusted_item *)value;
406 _D("uid(%d), appid(%s), pid(%d), busname(%s)", item->uid, item->app_id, item->pid, item->bus_name);
410 static int __esd_trusted_busname_add_item(uid_t uid, const char *appid, const char *busname, int pid)
413 char *bus_name = NULL;
414 trusted_item *item = NULL;
415 trusted_item *new_item;
417 app_id = strdup(appid);
418 if (app_id == NULL) {
423 bus_name = strdup(busname);
424 if (bus_name == NULL) {
426 FREE_AND_NULL(app_id);
430 item = (trusted_item *)g_hash_table_lookup(trusted_busname_table, app_id);
432 if (item && item->bus_name && strcmp(item->bus_name, bus_name) == 0 &&
433 (item->uid == uid)) {
434 _D("already exist (%s, %s)", app_id, bus_name);
435 FREE_AND_NULL(app_id);
436 FREE_AND_NULL(bus_name);
438 new_item = calloc(1, sizeof(trusted_item));
439 if (new_item == NULL) {
440 _E("memory alloc failed");
441 FREE_AND_NULL(app_id);
442 FREE_AND_NULL(bus_name);
446 new_item->app_id = app_id;
447 new_item->bus_name = bus_name;
449 g_hash_table_insert(trusted_busname_table, new_item->app_id, new_item);
450 _D("added busname(%s)", new_item->bus_name);
456 static int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name)
459 GError *error = NULL;
462 char tmp_appid[128] = {0, };
467 result = g_dbus_connection_call_sync(conn,
468 "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
469 list_name, NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE,
472 if (result == NULL) {
473 _E("get (%s) error(%s)", list_name, error->message);
478 g_variant_get(result, "(as)", &iter);
479 while (g_variant_iter_loop(iter, "s", &str)) {
480 if (!strstr((const char *)str, "event.busname.session"))
483 _D("list(%s), name(%s)", list_name, str);
484 pid = __get_sender_pid(conn, (const char *)str);
486 _E("failed to get pid(%d)", pid);
490 uid = __get_sender_uid(conn, (const char *)str);
492 _E("failed to get uid(%d)", uid);
497 memset(tmp_appid, 0, sizeof(tmp_appid));
498 ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), (uid_t)uid);
499 if (ret != AUL_R_OK) {
500 _E("failed to get appid by pid(%d)", pid);
504 _D("appid(%s)", tmp_appid);
505 if (__esd_check_application_validation((uid_t)uid, tmp_appid)) {
507 ret = __esd_trusted_busname_add_item((uid_t)uid, tmp_appid, (const char *)str, pid);
509 _E("failed to add item");
512 g_variant_iter_free(iter);
513 g_variant_unref(result);
518 static int __esd_check_privilege_name(const char *event_name, char **privilege_name)
522 *privilege_name = NULL;
524 for (i = 0; i < privilege_check_size; i++) {
525 if (strcmp(event_name, privilege_check_list[i].event_name) == 0) {
526 *privilege_name = (char *)privilege_check_list[i].privilege_name;
527 _D("[%d] privilege_name(%s)", i, *privilege_name);
535 static bool __esd_check_valid_privilege_by_cynara(const char *appid, const char *client,
536 const char *session, const char *user, const char *privilege_name)
539 bool has_privilege = false;
541 _D("check privilege, (%s, %s, %s, %s, %s)", appid, client, session, user, privilege_name);
543 ret = cynara_check(r_cynara, client, session, user, privilege_name);
544 if (ret == CYNARA_API_ACCESS_ALLOWED) {
545 _D("valid privilege");
546 has_privilege = true;
547 } else if (ret == CYNARA_API_ACCESS_DENIED) {
548 _E("invalid privilege");
550 _E("failed to check privilege, error(%d)", ret);
553 return has_privilege;
556 static int __esd_check_app_privileged_event(uid_t uid, const char *appid, const char *pkgid, const char *event_name)
558 char *privilege_name = NULL;
562 _D("event_name(%s), uid(%d), appid(%s), pkgid(%s)", event_name, uid, appid, pkgid);
564 __esd_check_privilege_name(event_name, &privilege_name);
566 if (privilege_name) {
567 ret = security_manager_app_has_privilege(appid, privilege_name, uid, &result);
568 if (ret != SECURITY_MANAGER_SUCCESS)
569 _E("failed to check privilege(%d)", ret);
570 _D("result(%d)", result);
578 static void __esd_print_appid_with_eventid(gpointer data, gpointer user_data)
580 esd_list_item_s *item = (esd_list_item_s *)data;
581 char *event_name = (char *)user_data;
583 _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name, item->uid, item->app_id, item->pkg_id);
586 static void __esd_print_interested_event(gpointer data, gpointer user_data)
588 event_launch_item *el_item = (event_launch_item *)data;
589 char *event_name = (char *)el_item->event_name;
590 _D("event_name = (%s)", event_name);
591 g_list_foreach(el_item->app_list_evtlaunch, __esd_print_appid_with_eventid, event_name);
594 static void __esd_launch_table_print_items(void)
600 g_hash_table_iter_init(&iter, event_launch_table);
602 while (g_hash_table_iter_next(&iter, &key, &value))
603 __esd_print_interested_event(value, NULL);
606 static int __esd_find_compare_by_list_item(gconstpointer data, gconstpointer user_data)
608 esd_list_item_s *item_1 = (esd_list_item_s *)user_data;
609 esd_list_item_s *item_2 = (esd_list_item_s *)data;
611 return (item_1->uid != item_2->uid) |
612 strcmp(item_1->app_id, item_2->app_id) |
613 strcmp(item_1->pkg_id, item_2->pkg_id);
616 static int __esd_add_list_item(uid_t uid, event_launch_item *el_item,
617 const char *app_id, const char *pkg_id)
619 esd_list_item_s *item_of_list = NULL;
621 item_of_list = calloc(1, sizeof(esd_list_item_s));
622 if (item_of_list == NULL) {
626 item_of_list->uid = uid;
627 item_of_list->app_id = (char *)app_id;
628 item_of_list->pkg_id = (char *)pkg_id;
629 item_of_list->trusted_info = TRUSTED_UNKNOWN;
630 el_item->app_list_evtlaunch =
631 g_list_append(el_item->app_list_evtlaunch, item_of_list);
636 static int __esd_add_launch_item(uid_t uid, const char *event_name,
637 const char *appid, const char *pkgid)
639 GList *app_list = NULL;
640 guint subscription_id = 0;
643 esd_list_item_s *item_of_list = NULL;
644 event_launch_item *eli;
645 event_launch_item *el_item =
646 (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
649 item_of_list = calloc(1, sizeof(esd_list_item_s));
650 if (item_of_list == NULL) {
651 _E("memory alloc failed");
654 item_of_list->uid = uid;
655 item_of_list->app_id = (char *)appid;
656 item_of_list->pkg_id = (char *)pkgid;
658 app_list = g_list_find_custom(el_item->app_list_evtlaunch,
659 item_of_list, (GCompareFunc)__esd_find_compare_by_list_item);
661 if (app_list == NULL) {
662 _D("add new item (list item only)");
663 app_id = strdup((char *)appid);
668 pkg_id = strdup((char *)pkgid);
671 FREE_AND_NULL(app_id);
674 if (__esd_add_list_item(uid, el_item, app_id, pkg_id) < 0) {
675 _E("failed to add list item");
676 FREE_AND_NULL(app_id);
677 FREE_AND_NULL(pkg_id);
682 _D("add new item (all)");
683 eli = calloc(1, sizeof(event_launch_item));
685 _E("memory alloc failed");
689 eli->event_name = strdup(event_name);
690 if (!eli->event_name) {
696 app_id = strdup((char *)appid);
699 FREE_AND_NULL(eli->event_name);
704 pkg_id = strdup((char *)pkgid);
707 FREE_AND_NULL(app_id);
708 FREE_AND_NULL(eli->event_name);
713 if (__esd_add_list_item(uid, eli, app_id, pkg_id) < 0) {
714 _E("failed to add list item");
715 FREE_AND_NULL(app_id);
716 FREE_AND_NULL(pkg_id);
717 FREE_AND_NULL(eli->event_name);
722 g_hash_table_insert(event_launch_table, eli->event_name, eli);
724 eventsystem_register_event(eli->event_name, &subscription_id,
725 (eventsystem_handler)__esd_event_handler, NULL);
726 if (subscription_id == 0) {
727 _E("signal subscription error, event_name(%s), app_id(%s)",
728 eli->event_name, app_id);
731 eli->reg_id = subscription_id;
738 static void __esd_remove_all_private_usr_app_list(gpointer data, gpointer user_data)
740 esd_list_item_s *item = (esd_list_item_s *)data;
741 event_launch_item *eli = (event_launch_item *)user_data;
743 if (item->uid != GLOBAL_USER && !strcmp(eli->package_name, item->pkg_id)) {
744 _D("uid(%d), app_id(%s), pkg_id(%s)", item->uid, item->app_id, eli->package_name);
745 eli->app_list_evtlaunch = g_list_remove_all(eli->app_list_evtlaunch, data);
749 static int __esd_launch_table_remove_private_usr_items(void)
754 event_launch_item *eli = NULL;
755 GList *first_list = NULL;
757 g_hash_table_iter_init(&iter, event_launch_table);
759 while (g_hash_table_iter_next(&iter, &key, &value)) {
760 eli = (event_launch_item *)value;
761 g_list_foreach(eli->app_list_evtlaunch, __esd_remove_all_private_usr_app_list, eli);
763 first_list = g_list_first(eli->app_list_evtlaunch);
764 if (first_list == NULL) {
766 eventsystem_unregister_event(eli->reg_id);
768 g_hash_table_iter_remove(&iter);
775 static void __esd_remove_app_list(gpointer data, gpointer user_data)
778 esd_list_item_s *item = (esd_list_item_s *)data;
779 event_launch_item *eli = (event_launch_item *)user_data;
781 if (eli->uid != GLOBAL_USER && eli->uid != item->uid)
784 if (!skip && !strcmp(eli->package_name, item->pkg_id)) {
785 _D("pkg_id(%s), app_id(%s)", eli->package_name, item->app_id);
786 eli->app_list_evtlaunch =
787 g_list_remove_all(eli->app_list_evtlaunch, data);
791 static int __esd_remove_launch_item(uid_t uid, gpointer data, const char *pkg_id)
793 event_launch_item *eli = (event_launch_item *)data;
794 GList *first_list = NULL;
797 eli->package_name = (char *)pkg_id;
798 g_list_foreach(eli->app_list_evtlaunch, __esd_remove_app_list, eli);
800 first_list = g_list_first(eli->app_list_evtlaunch);
801 if (first_list == NULL) {
803 eventsystem_unregister_event(eli->reg_id);
811 static int __esd_launch_table_remove_items(uid_t uid, const char *pkg_id)
817 g_hash_table_iter_init(&iter, event_launch_table);
819 while (g_hash_table_iter_next(&iter, &key, &value)) {
820 if (__esd_remove_launch_item(uid, value, pkg_id) == ES_R_REMOVE) {
821 _D("remove item itself");
822 g_hash_table_iter_remove(&iter);
829 static void __esd_event_launch_with_appid(gpointer data, gpointer user_data)
831 esd_list_item_s *item = (esd_list_item_s *)data;
832 uid_t uid = item->uid;
833 char *app_id = item->app_id;
834 esd_event_param *eep = (esd_event_param *)user_data;
835 static unsigned int req_id;
837 char event_uri[1024];
841 _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d), trusted(%d)",
842 app_id, eep->event_name, uid, eep->is_user_event, eep->trusted);
844 if (eep->is_user_event && eep->trusted) {
845 if (item->trusted_info == TRUSTED_UNKNOWN) {
846 ret = __esd_check_certificate_match(uid, app_id, eep->sender_uid, eep->sender_appid);
847 if (ret == ES_R_EINVAL) {
848 item->trusted_info = TRUSTED_DENIED;
850 } else if (ret == ES_R_ERROR) {
853 item->trusted_info = TRUSTED_ALLOWED;
855 } else if (item->trusted_info == TRUSTED_DENIED) {
860 if (!aul_app_is_running_for_uid(app_id, uid)) {
861 b = bundle_dup(eep->event_data);
862 if (eep->is_user_event)
863 snprintf(event_uri, sizeof(event_uri), "%s%s", USER_EVENT_NAME_PREFIX, eep->event_name);
865 snprintf(event_uri, sizeof(event_uri), "%s%s", SYSTEM_EVENT_NAME_PREFIX, eep->event_name);
867 appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT);
868 appsvc_set_uri(b, event_uri);
869 appsvc_set_appid(b, app_id);
871 pid = aul_svc_run_service_async_for_uid(b, req_id++, NULL, eep->user_data, uid);
872 _D("uid(%d), pid(%d)", uid, pid);
876 _D("already is running or launch failed");
880 static void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_data)
882 event_launch_item *el_item = (event_launch_item *)data;
883 esd_event_param *eep = (esd_event_param *)user_data;
885 if (strcmp(eep->event_name, (char *)el_item->event_name) == 0) {
886 g_list_foreach(el_item->app_list_evtlaunch,
887 __esd_event_launch_with_appid, user_data);
891 static void __esd_launch_event_handler(char *event_name, bundle *data,
892 const bool is_user_event, gboolean trusted,
893 const uid_t sender_uid, char *sender_appid, void *user_data)
896 const char *msg_type;
898 esd_event_param *eep;
899 event_launch_item *el_item;
901 _D("event_name(%s)", event_name);
903 el_item = (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
907 if (el_item->app_list_evtlaunch != NULL) {
908 if (is_user_event == false) {
909 if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) {
910 val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS);
911 _D("charger val(%s)", val);
912 if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0))
914 } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) {
915 val = bundle_get_val(data, EVT_KEY_USB_STATUS);
916 _D("usb val(%s)", val);
917 if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0))
919 } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) {
920 val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS);
921 _D("earjack val(%s)", val);
922 if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0))
924 } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) {
925 msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE);
926 _D("msg_type(%s)", msg_type);
927 if (msg_type == NULL)
930 msg_id = bundle_get_val(data, EVT_KEY_MSG_ID);
931 _D("msg_id(%s)", msg_id);
934 } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) {
935 val = bundle_get_val(data, EVT_KEY_WIFI_STATE);
938 _D("wifi_state(%s)", val);
939 if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0)
944 eep = calloc(1, sizeof(esd_event_param));
946 _E("memory alloc failed");
949 eep->event_name = event_name;
950 eep->event_data = data;
951 eep->sender_uid = sender_uid;
952 eep->sender_appid = sender_appid;
953 eep->is_user_event = is_user_event;
954 eep->trusted = (bool)trusted;
955 eep->user_data = (void *)user_data;
956 __esd_check_event_launch_with_eventid(el_item, eep);
961 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
962 static void __esd_print_earlier_event(gpointer data, gpointer user_data)
964 earlier_item *item = (earlier_item *)data;
965 char *event_name = (char *)item->event_name;
968 _D("event_name = (%s)", event_name);
970 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
971 if (item->earlier_data) {
972 val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED);
973 _D("boot_completed(%s)", val);
975 } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
976 if (item->earlier_data) {
977 val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN);
978 _D("shutdown(%s)", val);
980 } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
981 if (item->earlier_data) {
982 val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY);
983 _D("low_memory(%s)", val);
985 } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
986 if (item->earlier_data) {
987 val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS);
988 _D("charger_status(%s)", val);
993 static void __esd_earlier_table_print_items(void)
999 g_hash_table_iter_init(&iter, earlier_event_table);
1001 while (g_hash_table_iter_next(&iter, &key, &value))
1002 __esd_print_earlier_event(value, NULL);
1005 static void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data)
1008 _D("event_name(%s)", event_name);
1010 item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1012 /* update earlier value */
1013 if (item->earlier_data != NULL)
1014 bundle_free(item->earlier_data);
1016 item->earlier_data = bundle_dup(data);
1021 static void __esd_event_handler(char *event_name, bundle *data, void *user_data)
1023 _D("event_name(%s)", event_name);
1025 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1026 if (__esd_check_earlier_support(event_name))
1027 __esd_earlier_event_handler(event_name, data, user_data);
1030 if (__esd_check_event_launch_support(event_name))
1031 __esd_launch_event_handler(event_name, data,
1032 false, TRUE, ROOT_USER, NULL, user_data);
1035 static void __esd_trusted_busname_remove_item(char *bus_name)
1037 GHashTableIter iter;
1042 g_hash_table_iter_init(&iter, trusted_busname_table);
1044 while (g_hash_table_iter_next(&iter, &key, &value)) {
1045 item = (trusted_item *)value;
1047 if (strcmp(bus_name, item->bus_name) == 0) {
1048 _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name);
1049 FREE_AND_NULL(item->app_id);
1050 FREE_AND_NULL(item->bus_name);
1051 FREE_AND_NULL(item);
1052 g_hash_table_iter_remove(&iter);
1054 __esd_trusted_busname_print_items();
1060 static void __esd_filter_name_owner_changed(GDBusConnection *connection,
1061 const gchar *sender_name, const gchar *object_path,
1062 const gchar *interface_name, const gchar *signal_name,
1063 GVariant *parameters, gpointer user_data)
1066 char *old_owner = NULL;
1067 char *new_owner = NULL;
1071 g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
1073 if (strstr(name, "event.busname.session")) {
1074 old_len = strlen(old_owner);
1075 new_len = strlen(new_owner);
1077 _D("changed name(%s), old_onwer(%s)(%d) -> new_onwer(%s)(%d)",
1078 name, old_owner, old_len, new_owner, new_len);
1080 if (old_len > 0 && new_len == 0)
1081 __esd_trusted_busname_remove_item(name);
1082 else if (old_len == 0 && new_len > 0)
1083 _D("new name owned");
1085 _E("not-expected name change");
1089 static int __esd_dbus_name_monitor(GDBusConnection *connection)
1091 guint name_owner_changed_id = 0;
1093 name_owner_changed_id = g_dbus_connection_signal_subscribe(connection,
1094 "org.freedesktop.DBus", "org.freedesktop.DBus",
1095 "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1096 __esd_filter_name_owner_changed, NULL, NULL);
1098 _I("name_owner_changed_id(%d)", name_owner_changed_id);
1103 static int __esd_get_user_items(uid_t uid)
1106 pkgmgrinfo_appinfo_filter_h handle = NULL;
1108 _I("get user items for uid(%d)", uid);
1109 /* reset user's item */
1110 __esd_launch_table_remove_private_usr_items();
1112 ret = pkgmgrinfo_appinfo_filter_create(&handle);
1114 _E("failed to create appinfo filter");
1117 ret = pkgmgrinfo_appinfo_filter_add_string(handle,
1118 PMINFO_APPINFO_PROP_APP_COMPONENT, "svcapp");
1120 _E("failed to add appinfo filter string");
1121 pkgmgrinfo_appinfo_filter_destroy(handle);
1124 ret = pkgmgrinfo_appinfo_filter_add_string(handle,
1125 PMINFO_APPINFO_PROP_APP_OPERATION, APPSVC_OPERATION_LAUNCH_ON_EVENT);
1127 _E("failed to add appinfo filter string");
1128 pkgmgrinfo_appinfo_filter_destroy(handle);
1131 ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle,
1132 __esd_add_appinfo_handler, &uid, uid);
1134 _E("appinfo filter foreach error");
1135 pkgmgrinfo_appinfo_filter_destroy(handle);
1138 pkgmgrinfo_appinfo_filter_destroy(handle);
1140 __esd_launch_table_print_items();
1145 static void __esd_signal_handler(GDBusConnection *connection,
1146 const gchar *sender_name,
1147 const gchar *object_path,
1148 const gchar *interface_name,
1149 const gchar *signal_name,
1150 GVariant *parameters,
1157 if (!g_strcmp0(signal_name,
1158 SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED)) {
1159 _I("System session finished");
1161 b = bundle_create();
1162 bundle_add_str(b, EVT_KEY_BOOT_COMPLETED,
1163 EVT_VAL_BOOT_COMPLETED_TRUE);
1164 eventsystem_send_system_event(SYS_EVENT_BOOT_COMPLETED, b);
1167 handle = creat(ESD_BOOT_COMPLETED, 0640);
1170 } else if (!g_strcmp0(signal_name,
1171 SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED)) {
1172 g_variant_get(parameters, "(t)", &uid);
1173 _I("User session finished uid : %d", (int)uid);
1174 if ((uid_t)uid != DEFAULT_USER)
1175 __esd_get_user_items((uid_t)uid);
1179 static GDBusNodeInfo *introspection_data;
1180 static const gchar introspection_xml[] =
1182 " <interface name='tizen.system.event.app2esd'>"
1183 " <method name='CheckSenderValidation'>"
1184 " <arg type='i' name='senderpid' direction='in'/>"
1185 " <arg type='s' name='eventname' direction='in'/>"
1186 " <arg type='i' name='ret' direction='out'/>"
1187 " <arg type='s' name='senderid' direction='out'/>"
1189 " <method name='GetTrustedPeerList'>"
1190 " <arg type='s' name='eventname' direction='in'/>"
1191 " <arg type='i' name='ret' direction='out'/>"
1192 " <arg type='as' name='dest_list' direction='out'/>"
1194 " <method name='SetupTrustedPeer'>"
1195 " <arg type='s' name='eventname' direction='in'/>"
1196 " <arg type='s' name='destination' direction='in'/>"
1197 " <arg type='i' name='ret' direction='out'/>"
1199 " <method name='CheckPrivilegeValidation'>"
1200 " <arg type='s' name='eventname' direction='in'/>"
1201 " <arg type='i' name='ret' direction='out'/>"
1203 " <method name='CheckUserSendValidation'>"
1204 " <arg type='s' name='eventname' direction='in'/>"
1205 " <arg type='i' name='ret' direction='out'/>"
1207 " <method name='RequestTrustedEventLaunch'>"
1208 " <arg type='s' name='eventname' direction='in'/>"
1209 " <arg type='s' name='eventdata' direction='in'/>"
1210 " <arg type='i' name='datalen' direction='in'/>"
1211 " <arg type='i' name='ret' direction='out'/>"
1213 " <method name='RequestEventLaunch'>"
1214 " <arg type='s' name='eventname' direction='in'/>"
1215 " <arg type='s' name='eventdata' direction='in'/>"
1216 " <arg type='i' name='datalen' direction='in'/>"
1217 " <arg type='i' name='ret' direction='out'/>"
1219 " <method name='RequestSendingEvent'>"
1220 " <arg type='s' name='eventname' direction='in'/>"
1221 " <arg type='s' name='eventdata' direction='in'/>"
1222 " <arg type='i' name='datalen' direction='in'/>"
1223 " <arg type='i' name='ret' direction='out'/>"
1225 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1226 " <method name='GetEarlierData'>"
1227 " <arg type='s' name='appid' direction='in'/>"
1228 " <arg type='i' name='ret' direction='out'/>"
1229 " <arg type='i' name='len' direction='out'/>"
1230 " <arg type='s' name='earlier_data' direction='out'/>"
1233 " <method name='KeepLastData'>"
1234 " <arg type='s' name='eventname' direction='in'/>"
1235 " <arg type='s' name='own_name' direction='in'/>"
1236 " <arg type='i' name='ret' direction='out'/>"
1238 " <method name='CheckLastData'>"
1239 " <arg type='s' name='eventname' direction='in'/>"
1240 " <arg type='s' name='own_name' direction='in'/>"
1241 " <arg type='i' name='ret' direction='out'/>"
1243 " <method name='LaunchOnEventFromUserEvent'>"
1244 " <arg type='s' name='eventname' direction='in'/>"
1245 " <arg type='s' name='eventdata' direction='in'/>"
1246 " <arg type='i' name='datalen' direction='in'/>"
1247 " <arg type='b' name='trusted' direction='in'/>"
1248 " <arg type='i' name='ret' direction='out'/>"
1253 static int __esd_get_appid_by_pid(int pid, uid_t uid, char *app_id, int buf_size)
1255 int retval = ES_R_OK;
1259 _E("invalid pid(%d)", pid);
1260 retval = ES_R_ERROR;
1261 } else if (uid <= 0) {
1262 _E("invalid uid(%d)", uid);
1263 retval = ES_R_ERROR;
1265 ret = aul_app_get_appid_bypid_for_uid(pid, app_id, buf_size, (uid_t)uid);
1266 if (ret != AUL_R_OK) {
1267 _E("failed to get appid by pid");
1268 retval = ES_R_ERROR;
1270 _D("pid(%d)-uid(%d)-appid(%s)", pid, uid, app_id);
1276 static int check_user_event_sender_valid(const char *event_name, const char *app_id)
1278 char *valid_name = NULL;
1279 char *temp_name = NULL;
1281 int retval = ES_R_OK;
1283 int valid_name_len = 0;
1285 temp_name = strdup(event_name);
1286 if (temp_name == NULL) {
1287 _E("out of memory");
1291 tmp = strrchr(temp_name, '.');
1292 if (tmp == NULL || strlen(tmp) == 0) {
1293 _E("invalid event name");
1294 FREE_AND_NULL(temp_name);
1298 if (len <= 1 || len > 128) {
1299 _E("invalid length(%d) of user-defined name", len);
1300 FREE_AND_NULL(temp_name);
1305 _D("app_id(%s), len(%zu)", app_id, strlen(app_id));
1307 valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1;
1308 valid_name = calloc(1, valid_name_len);
1309 if (valid_name == NULL) {
1310 _E("memory alloc failed");
1311 FREE_AND_NULL(temp_name);
1314 snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id);
1315 _D("valid_name(%s)", valid_name);
1317 if (strcmp(temp_name, valid_name) != 0) {
1318 _E("appid misamatch");
1319 retval = ES_R_EINVAL;
1322 FREE_AND_NULL(temp_name);
1323 FREE_AND_NULL(valid_name);
1328 static void check_sender_valid_method_call(GDBusConnection *connection, const gchar *sender,
1329 GVariant *parameters, GDBusMethodInvocation *invocation)
1331 GVariant *param = NULL;
1333 char *event_name = NULL;
1334 char app_id[128] = {0, };
1335 int event_sender_pid = 0;
1336 uid_t sender_uid = 0;
1338 g_variant_get(parameters, "(i&s)", &event_sender_pid, &event_name);
1339 _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name);
1341 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1342 if (__esd_get_appid_by_pid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1343 result = ES_R_ERROR;
1345 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1346 _E("invalid sender");
1347 result = ES_R_EINVAL;
1353 param = g_variant_new("(is)", result, app_id);
1354 _D("event_name(%s), result(%d)", event_name, result);
1355 g_dbus_method_invocation_return_value(invocation, param);
1358 static void check_send_event_valid_method_call(GDBusConnection *connection, const gchar *sender,
1359 GVariant *parameters, GDBusMethodInvocation *invocation)
1361 GVariant *param = NULL;
1363 char *event_name = NULL;
1364 char app_id[128] = {0, };
1366 uid_t sender_uid = 0;
1368 g_variant_get(parameters, "(&s)", &event_name);
1369 _D("event_name(%s)", event_name);
1371 sender_pid = __get_sender_pid(connection, sender);
1372 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1373 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1374 result = ES_R_ERROR;
1376 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1377 _E("invalid sender");
1378 result = ES_R_EINVAL;
1384 param = g_variant_new("(i)", result);
1385 _D("event_name(%s), result(%d)", event_name, result);
1386 g_dbus_method_invocation_return_value(invocation, param);
1389 static void get_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1390 GVariant *parameters, GDBusMethodInvocation *invocation)
1392 GVariant *param = NULL;
1394 GVariantBuilder *builder = NULL;
1395 GHashTableIter iter;
1396 gpointer key, value;
1397 char *event_name = NULL;
1398 char app_id[128] = {0, };
1400 uid_t sender_uid = 0;
1403 char *_appid = NULL;
1404 char *_busname = NULL;
1407 g_variant_get(parameters, "(&s)", &event_name);
1408 _D("event_name(%s)", event_name);
1410 sender_pid = __get_sender_pid(connection, sender);
1411 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1412 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1413 result = ES_R_ERROR;
1415 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1417 g_hash_table_iter_init(&iter, trusted_busname_table);
1418 while (g_hash_table_iter_next(&iter, &key, &value)) {
1419 item = (trusted_item *)value;
1421 _appid = item->app_id;
1422 _busname = item->bus_name;
1424 if (uid != GLOBAL_USER && uid != sender_uid)
1427 ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id);
1429 g_variant_builder_add(builder, "s", _busname);
1435 param = g_variant_new("(ias)", result, builder);
1436 _D("result(%d)", result);
1437 g_dbus_method_invocation_return_value(invocation, param);
1439 g_variant_builder_unref(builder);
1442 static void setup_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1443 GVariant *parameters, GDBusMethodInvocation *invocation)
1445 GVariant *param = NULL;
1447 char *event_name = NULL;
1448 char *destination_name = NULL;
1449 char app_id[128] = {0, };
1451 uid_t sender_uid = 0;
1454 g_variant_get(parameters, "(&s&s)", &event_name, &destination_name);
1455 _D("event_name(%s), destination_name(%s)", event_name, destination_name);
1457 if (destination_name && destination_name[0] != '\0') {
1458 sender_pid = __get_sender_pid(connection, sender);
1459 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1460 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1461 result = ES_R_ERROR;
1463 ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name,
1466 _E("failed to add trusted busname item");
1467 result = ES_R_ERROR;
1473 _E("invalid destination name");
1474 result = ES_R_ERROR;
1477 param = g_variant_new("(i)", result);
1478 _D("event_name(%s), result(%d)", event_name, result);
1479 g_dbus_method_invocation_return_value(invocation, param);
1482 static void check_privilege_valid_method_call(GDBusConnection *connection, const gchar *sender,
1483 GVariant *parameters, GDBusMethodInvocation *invocation)
1485 GVariant *param = NULL;
1487 char *event_name = NULL;
1488 char *privilege_name = NULL;
1489 char app_id[128] = {0, };
1491 uid_t sender_uid = 0;
1492 char *client = NULL;
1493 char *session = NULL;
1497 g_variant_get(parameters, "(&s)", &event_name);
1498 __esd_check_privilege_name(event_name, &privilege_name);
1499 _D("event_name(%s), privilege_name(%s)", event_name, privilege_name);
1501 if (privilege_name) {
1502 sender_pid = __get_sender_pid(connection, sender);
1503 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1504 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1505 result = ES_R_ERROR;
1507 ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client);
1508 if (ret != CYNARA_API_SUCCESS) {
1509 _E("failed to get client");
1510 result = ES_R_EINVAL;
1514 ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user);
1515 if (ret != CYNARA_API_SUCCESS) {
1516 _E("failed to get user");
1517 result = ES_R_EINVAL;
1521 session = cynara_session_from_pid(sender_pid);
1522 if (session == NULL) {
1523 _E("failed to get session");
1524 result = ES_R_EINVAL;
1528 _D("app_id(%s), client(%s), session(%s), user(%s)", app_id, client, session, user);
1529 if (__esd_check_valid_privilege_by_cynara(app_id, client, session, user, privilege_name))
1532 result = ES_R_EINVAL;
1542 param = g_variant_new("(i)", result);
1543 _D("event_name(%s), result(%d)", event_name, result);
1544 g_dbus_method_invocation_return_value(invocation, param);
1547 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1548 static void get_earlier_data_method_call(GVariant *parameters, GDBusMethodInvocation *invocation)
1550 GVariant *param = NULL;
1552 char *event_name = NULL;
1554 bundle_raw *raw = NULL;
1558 g_variant_get(parameters, "(&s)", &event_name);
1560 if (event_name && strlen(event_name) > 0) {
1561 _D("event_name(%s)", event_name);
1564 _E("invalid event_name(%s)", event_name);
1565 result = ES_R_ERROR;
1568 item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1570 if (item->earlier_data) {
1571 b = bundle_dup(item->earlier_data);
1572 bundle_add_str(b, "is_earlier_data", "true");
1573 bundle_encode(b, &raw, &len);
1578 param = g_variant_new("(iis)", result, len, raw);
1580 _D("result(%d), len(%d)", result, len);
1581 g_dbus_method_invocation_return_value(invocation, param);
1583 bundle_free_encoded_rawdata(&raw);
1587 static void keep_last_data_method_call(GDBusConnection *connection,
1588 const gchar *sender, GVariant *parameters,
1589 GDBusMethodInvocation *invocation)
1592 int result = ES_R_OK;
1599 struct __last_event_item *item;
1601 g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
1603 if (!event_name || !own_name) {
1604 result = ES_R_ERROR;
1605 _E("invalid event_name and own_name");
1609 sender_pid = __get_sender_pid(connection, sender);
1610 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1611 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id,
1612 sizeof(app_id)) < 0) {
1613 _E("failed to get appid by pid");
1614 result = ES_R_ERROR;
1618 key = (char *)malloc(sizeof(event_name) + 10);
1620 result = ES_R_ENOMEM;
1621 _E("out of memory");
1625 snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
1626 item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
1629 item = calloc(1, sizeof(*item));
1631 result = ES_R_ERROR;
1635 item->event_name = strdup(event_name);
1636 item->own_name = strdup(own_name);
1637 item->uid = sender_uid;
1638 item->app_id = strdup(app_id);
1639 g_hash_table_insert(user_last_event_table,
1642 free(item->own_name);
1643 item->own_name = strdup(own_name);
1647 param = g_variant_new("(i)", result);
1649 g_dbus_method_invocation_return_value(invocation, param);
1652 static void check_last_data_method_call(GDBusConnection *connection,
1653 const gchar *sender, GVariant *parameters,
1654 GDBusMethodInvocation *invocation)
1657 int result = ES_R_OK;
1664 struct __last_event_item *item;
1666 g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
1668 if (!event_name || !own_name) {
1669 result = ES_R_ERROR;
1670 _E("invalid event_name and own_name");
1674 sender_pid = __get_sender_pid(connection, sender);
1675 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1676 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id,
1677 sizeof(app_id)) < 0) {
1678 result = ES_R_ERROR;
1679 _E("failed to get appid by pid");
1683 key = (char *)malloc(sizeof(event_name) + 10);
1685 result = ES_R_ENOMEM;
1686 _E("out of memory");
1690 snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
1691 item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
1700 GError *error = NULL;
1702 b = bundle_create();
1704 result = ES_R_ERROR;
1707 bundle_add_str(b, EVT_KEY_KEPT_EVENT_NAME, event_name);
1708 bundle_add_str(b, EVT_KEY_KEPT_OWN_NAME, own_name);
1709 if (__esd_check_certificate_match(item->uid, item->app_id,
1710 sender_uid, app_id) == ES_R_OK)
1711 bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "true");
1713 bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "false");
1715 bundle_encode(b, &raw, &len);
1716 gv = g_variant_new("(us)", len, raw);
1717 ret = g_dbus_connection_emit_signal(connection,
1720 SYS_EVENT_NAME_PREFIX,
1725 _E("Unable to emit signal: %s", error->message);
1726 g_error_free(error);
1728 bundle_free_encoded_rawdata(&raw);
1733 param = g_variant_new("(i)", result);
1735 g_dbus_method_invocation_return_value(invocation, param);
1738 static void launch_on_event_from_userevent(GDBusConnection *connection,
1739 const gchar *sender, GVariant *parameters,
1740 GDBusMethodInvocation *invocation)
1743 int result = ES_R_OK;
1753 g_variant_get(parameters, "(&s&sib)", &event_name, &buf, &len, &trusted);
1756 result = ES_R_ERROR;
1757 _E("invalid event_name");
1761 sender_pid = __get_sender_pid(connection, sender);
1762 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1763 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id,
1764 sizeof(app_id)) < 0) {
1765 _E("failed to get appid by pid");
1766 result = ES_R_ERROR;
1770 b = bundle_decode((bundle_raw *)buf, len);
1772 _E("Out of memory");
1773 result = ES_R_ENOMEM;
1777 __esd_launch_event_handler(event_name, b, true, trusted,
1778 sender_uid, app_id, NULL);
1783 param = g_variant_new("(i)", result);
1785 g_dbus_method_invocation_return_value(invocation, param);
1788 static void handle_method_call(GDBusConnection *connection,
1789 const gchar *sender, const gchar *object_path,
1790 const gchar *interface_name, const gchar *method_name,
1791 GVariant *parameters, GDBusMethodInvocation *invocation,
1794 if (g_strcmp0(method_name, "CheckSenderValidation") == 0) {
1795 check_sender_valid_method_call(connection, sender, parameters, invocation);
1796 } else if (g_strcmp0(method_name, "GetTrustedPeerList") == 0) {
1797 get_trusted_peer_method_call(connection, sender, parameters, invocation);
1798 } else if (g_strcmp0(method_name, "SetupTrustedPeer") == 0) {
1799 setup_trusted_peer_method_call(connection, sender, parameters, invocation);
1800 } else if (g_strcmp0(method_name, "CheckPrivilegeValidation") == 0) {
1801 check_privilege_valid_method_call(connection, sender, parameters, invocation);
1802 } else if (g_strcmp0(method_name, "CheckUserSendValidation") == 0) {
1803 check_send_event_valid_method_call(connection, sender, parameters, invocation);
1804 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1805 } else if (g_strcmp0(method_name, "GetEarlierData") == 0) {
1806 get_earlier_data_method_call(parameters, invocation);
1808 } else if (g_strcmp0(method_name, "KeepLastData") == 0) {
1809 keep_last_data_method_call(connection, sender, parameters, invocation);
1810 } else if (g_strcmp0(method_name, "CheckLastData") == 0) {
1811 check_last_data_method_call(connection, sender, parameters, invocation);
1812 } else if (g_strcmp0(method_name, "LaunchOnEventFromUserEvent") == 0) {
1813 launch_on_event_from_userevent(connection, sender, parameters, invocation);
1817 static const GDBusInterfaceVTable interface_vtable = {
1823 static void __esd_on_bus_acquired(GDBusConnection *connection,
1824 const gchar *name, gpointer user_data)
1826 _I("bus acquired(%s)", name);
1830 guint user_boot_id = 0;
1831 GError *error = NULL;
1833 reg_id = g_dbus_connection_register_object(connection,
1835 introspection_data->interfaces[0],
1837 NULL, NULL, &error);
1839 _E("g_dbus_connection_register_object error(%s)", error->message);
1840 g_error_free(error);
1843 boot_id = g_dbus_connection_signal_subscribe(connection,
1845 SYSTEMD_DBUS_IFACE_MANAGER,
1846 SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED,
1849 G_DBUS_SIGNAL_FLAGS_NONE,
1850 __esd_signal_handler,
1855 _E("g_dbus_connection_signal_subscribe() is failed.");
1856 g_object_unref(connection);
1859 user_boot_id = g_dbus_connection_signal_subscribe(connection,
1861 SYSTEMD_DBUS_IFACE_MANAGER,
1862 SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED,
1865 G_DBUS_SIGNAL_FLAGS_NONE,
1866 __esd_signal_handler,
1870 if (user_boot_id == 0) {
1871 _E("g_dbus_connection_signal_subscribe() is failed.");
1872 g_object_unref(connection);
1876 static void __esd_on_name_acquired(GDBusConnection *connection,
1877 const gchar *name, gpointer user_data)
1881 _I("name acquired(%s)", name);
1883 __esd_check_trusted_events(connection, "ListNames");
1884 __esd_check_trusted_events(connection, "ListActivatableNames");
1886 b = bundle_create();
1887 bundle_add_str(b, EVT_KEY_ESD_STATUS, EVT_VAL_ESD_STARTED);
1888 eventsystem_send_system_event(SYS_EVENT_ESD_STATUS, b);
1891 __esd_register_vconf_callbacks();
1893 __esd_trusted_busname_print_items();
1895 __esd_get_user_items(DEFAULT_USER);
1897 __esd_dbus_name_monitor(connection);
1900 static void __esd_on_name_lost(GDBusConnection *connection,
1901 const gchar *name, gpointer user_data)
1903 _E("name lost(%s)", name);
1906 static int __esd_before_loop(void)
1909 GError *error = NULL;
1912 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1913 guint subscription_id = 0;
1924 earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal);
1925 user_last_event_table = g_hash_table_new_full(g_str_hash,
1926 g_str_equal, NULL, (GDestroyNotify)free_saved_event);
1928 _I("register events for earlier_data");
1929 size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
1930 for (i = 0; i < size; i++) {
1931 event_name = (char *)earlier_event_list[i];
1932 _I("event_name(%s)", event_name);
1934 item = calloc(1, sizeof(earlier_item));
1936 _E("memery alloc failed");
1939 item->event_name = strdup(event_name);
1940 if (item->event_name == NULL) {
1941 _E("out of memory");
1946 /* set initial data */
1947 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
1948 fd = open(ESD_BOOT_COMPLETED, O_RDONLY);
1950 _D("open file error(%d)", fd);
1952 item->earlier_data = bundle_create();
1953 bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED,
1954 EVT_VAL_BOOT_COMPLETED_TRUE);
1957 } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
1958 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val);
1959 if (ret != VCONF_OK) {
1960 _E("failed to get power_off status (%d)", ret);
1962 if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT ||
1963 val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
1964 /* power-off requested */
1965 item->earlier_data = bundle_create();
1966 bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN,
1967 EVT_VAL_SYSTEM_SHUTDOWN_TRUE);
1970 } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
1971 ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status);
1972 if (ret != VCONF_OK) {
1973 _E("failed to get low_memory status (%d)", ret);
1975 item->earlier_data = bundle_create();
1976 if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
1977 bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1978 EVT_VAL_MEMORY_SOFT_WARNING);
1979 else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING)
1980 bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1981 EVT_VAL_MEMORY_HARD_WARNING);
1983 bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1984 EVT_VAL_MEMORY_NORMAL);
1986 } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
1987 ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status);
1988 if (ret != VCONF_OK) {
1989 _E("failed to get charger_status (%d)", ret);
1991 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now);
1992 if (ret != VCONF_OK)
1993 _E("failed to get charge_now (%d)", ret);
1996 if (ret == VCONF_OK) {
1997 item->earlier_data = bundle_create();
1998 if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) {
1999 if (charge_now == 0) {
2000 bundle_add_str(item->earlier_data,
2001 EVT_KEY_BATTERY_CHARGER_STATUS,
2002 EVT_VAL_BATTERY_CHARGER_DISCHARGING);
2004 bundle_add_str(item->earlier_data,
2005 EVT_KEY_BATTERY_CHARGER_STATUS,
2006 EVT_VAL_BATTERY_CHARGER_CHARGING);
2009 bundle_add_str(item->earlier_data,
2010 EVT_KEY_BATTERY_CHARGER_STATUS,
2011 EVT_VAL_BATTERY_CHARGER_DISCONNECTED);
2016 eventsystem_register_event(event_name, &subscription_id,
2017 (eventsystem_handler)__esd_event_handler, NULL);
2018 if (subscription_id == 0) {
2019 _E("signal subscription error, event_name(%s)", event_name);
2020 if (item->earlier_data)
2021 bundle_free(item->earlier_data);
2022 free(item->event_name);
2027 item->reg_id = subscription_id;
2030 g_hash_table_insert(earlier_event_table, event_name, item);
2033 __esd_earlier_table_print_items();
2036 event_launch_table = g_hash_table_new(g_str_hash, g_str_equal);
2037 trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal);
2039 /* gdbus setup for method call */
2040 introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
2041 if (!introspection_data) {
2042 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
2043 g_error_free(error);
2047 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
2049 G_BUS_NAME_OWNER_FLAGS_NONE,
2050 __esd_on_bus_acquired,
2051 __esd_on_name_acquired,
2055 _E("g_bus_own_name error");
2056 g_dbus_node_info_unref(introspection_data);
2060 _I("esd before_loop done");
2065 static void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event)
2067 pkg_event->type = UNKNOWN;
2068 if (pkg_event->pkgid) {
2069 free(pkg_event->pkgid);
2070 pkg_event->pkgid = NULL;
2074 static int __esd_appcontrol_cb(const char *operation,
2075 const char *uri, const char *mime, void *data)
2077 esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data;
2080 char *event_name = NULL;
2083 if (cb_data == NULL) {
2087 appid = cb_data->appid;
2088 pkgid = cb_data->pkgid;
2091 _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)",
2092 uid, appid, pkgid, operation, uri, mime);
2094 if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) {
2095 if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX, strlen(SYSTEM_EVENT_NAME_PREFIX))) {
2096 event_name = strdup(&uri[8]);
2098 _D("appid(%s), event_name(%s)", appid, event_name);
2099 if (!__esd_check_event_launch_support(event_name))
2100 _E("failed to add item (not support event)");
2101 else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name))
2102 _E("failed to add item (no privilege)");
2103 else if (__esd_add_launch_item(uid, event_name, appid, pkgid))
2104 _E("failed to add item");
2107 _E("out of memory");
2109 } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX, strlen(USER_EVENT_NAME_PREFIX))) {
2110 event_name = strdup(uri);
2112 _D("appid(%s), event_name(%s)", appid, event_name);
2113 if (__esd_check_platform_cert(pkgid, uid)) {
2114 if (__esd_add_launch_item(uid, event_name, appid, pkgid))
2115 _E("failed to add item");
2118 _E("out of memory");
2121 FREE_AND_NULL(event_name);
2127 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data)
2132 uid_t *p_uid = NULL;
2139 p_uid = (uid_t *)data;
2141 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
2143 _E("failed to get appid");
2147 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
2149 _E("failed to get appid");
2153 esd_appctrl_cb_data *cb_data = calloc(1, sizeof(esd_appctrl_cb_data));
2155 if (cb_data == NULL) {
2156 _E("memory alloc failed");
2159 cb_data->appid = strdup(appid);
2160 if (cb_data->appid == NULL) {
2161 _E("out_of_memory");
2162 FREE_AND_NULL(cb_data);
2165 cb_data->pkgid = strdup(pkgid);
2166 if (cb_data->pkgid == NULL) {
2167 _E("out_of_memory");
2168 FREE_AND_NULL(cb_data->appid);
2169 FREE_AND_NULL(cb_data);
2172 cb_data->uid = *p_uid;
2174 ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
2175 (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data);
2177 FREE_AND_NULL(cb_data->pkgid);
2178 FREE_AND_NULL(cb_data->appid);
2179 FREE_AND_NULL(cb_data);
2182 _E("failed to get appcontrol info");
2189 static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id,
2190 const char *pkg_type, const char *pkgid, const char *key,
2191 const char *val, const void *pmsg, void *data)
2193 esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data;
2194 pkgmgrinfo_pkginfo_h handle = NULL;
2197 _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)",
2198 target_uid, req_id, pkg_type, pkgid, key, val);
2200 if (strncmp(key, "start", strlen(key)) == 0) {
2201 if (strcmp(val, "install") == 0) {
2202 _D("install start");
2203 pkg_event->type = INSTALL;
2204 } else if (strcmp(val, "uninstall") == 0) {
2205 _D("unistall start");
2206 pkg_event->type = UNINSTALL;
2207 } else if (strcmp(val, "update") == 0) {
2209 pkg_event->type = UPDATE;
2211 _D("val(%s) start", val);
2212 __esd_pkgmgr_event_free(pkg_event);
2214 } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) {
2215 if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) {
2216 _D("install end (ok)");
2217 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle);
2219 _E("failed to get pkginfo");
2220 __esd_pkgmgr_event_free(pkg_event);
2223 ret = pkgmgrinfo_appinfo_get_usr_list(handle,
2224 PMINFO_SVC_APP, __esd_add_appinfo_handler, &target_uid, target_uid);
2226 _E("failed to get appinfo");
2227 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2228 __esd_pkgmgr_event_free(pkg_event);
2231 ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2233 _E("failed to destroy pkginfo");
2234 __esd_pkgmgr_event_free(pkg_event);
2237 } else if (pkg_event->type == UNINSTALL) {
2238 _D("uninstall end (ok)");
2239 __esd_launch_table_remove_items(target_uid, pkgid);
2240 __esd_launch_table_print_items();
2242 __esd_pkgmgr_event_free(pkg_event);
2243 } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) {
2244 _E("pkg_event(%d) falied", pkg_event->type);
2245 __esd_pkgmgr_event_free(pkg_event);
2247 if (strcmp(key, "install_percent") != 0)
2248 __esd_pkgmgr_event_free(pkg_event);
2254 static int __esd_init()
2258 pkgmgr_client *client;
2259 esd_pkgmgr_event *pkg_event;
2261 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
2264 __esd_init_cynara();
2266 client = pkgmgr_client_new(PC_LISTENING);
2267 if (client == NULL) {
2268 _E("set pkgmgr client failed");
2269 __esd_finish_cynara();
2273 pkg_event = calloc(1, sizeof(esd_pkgmgr_event));
2274 if (pkg_event == NULL) {
2275 _E("memory alloc failed");
2276 ret = pkgmgr_client_free(client);
2277 if (ret != PKGMGR_R_OK)
2278 _E("pkgmgr_client_free failed(%d)", ret);
2279 __esd_finish_cynara();
2283 req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event);
2285 _E("pkgmgr client listen failed");
2286 ret = pkgmgr_client_free(client);
2287 if (ret != PKGMGR_R_OK)
2288 _E("pkgmgr_client_free failed(%d)", ret);
2290 __esd_finish_cynara();
2294 s_info.client = client;
2296 _I("esd init done");
2301 static void __esd_remove_esd_list_item(gpointer data, gpointer user_data)
2303 esd_list_item_s *item = (esd_list_item_s *)data;
2309 static void __esd_finalize(void)
2313 GHashTableIter iter;
2315 event_launch_item *el_item;
2317 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2318 earlier_item *er_item;
2323 if (trusted_busname_table) {
2324 g_hash_table_iter_init(&iter, trusted_busname_table);
2325 while (g_hash_table_iter_next(&iter, &key, &value)) {
2326 item = (trusted_item *)value;
2329 free(item->bus_name);
2334 g_hash_table_iter_remove(&iter);
2336 g_hash_table_unref(trusted_busname_table);
2339 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2340 if (earlier_event_table) {
2341 g_hash_table_iter_init(&iter, earlier_event_table);
2342 while (g_hash_table_iter_next(&iter, &key, &value)) {
2343 er_item = (earlier_item *)value;
2345 eventsystem_unregister_event(er_item->reg_id);
2346 free(er_item->event_name);
2347 bundle_free(er_item->earlier_data);
2350 _E("ealier item is NULL");
2352 g_hash_table_iter_remove(&iter);
2354 g_hash_table_unref(earlier_event_table);
2357 g_hash_table_destroy(user_last_event_table);
2360 if (event_launch_table) {
2361 g_hash_table_iter_init(&iter, event_launch_table);
2362 while (g_hash_table_iter_next(&iter, &key, &value)) {
2363 el_item = (event_launch_item *)value;
2365 eventsystem_unregister_event(el_item->reg_id);
2366 free(el_item->event_name);
2367 g_list_foreach(el_item->app_list_evtlaunch,
2368 __esd_remove_esd_list_item, NULL);
2369 g_list_free(el_item->app_list_evtlaunch);
2374 g_hash_table_iter_remove(&iter);
2376 g_hash_table_unref(event_launch_table);
2379 if (introspection_data)
2380 g_dbus_node_info_unref(introspection_data);
2382 if (s_info.client) {
2383 ret = pkgmgr_client_free(s_info.client);
2384 if (ret != PKGMGR_R_OK)
2385 _E("pkgmgr_client_free failed(%d)", ret);
2388 __esd_finish_cynara();
2390 _D("esd finalize end");
2393 int main(int argc, char *argv[])
2395 GMainLoop *mainloop;
2396 _I("event system daemon : main()");
2398 mainloop = g_main_loop_new(NULL, FALSE);
2399 if (mainloop == NULL) {
2400 _E("out of memory");
2404 if (__esd_init() != 0) {
2405 _E("ESD Initialization failed!");
2406 g_main_loop_unref(mainloop);
2410 if (__esd_before_loop() < 0) {
2413 g_main_loop_unref(mainloop);
2417 g_main_loop_run(mainloop);
2423 g_main_loop_unref(mainloop);