9 #include <package-manager.h>
10 #include <pkgmgr-info.h>
11 #include <appsvc/appsvc.h>
12 #include <eventsystem.h>
13 #include <bundle_internal.h>
16 #include <tzplatform_config.h>
17 #include <systemd/sd-login.h>
18 #include <cynara-client.h>
19 #include <cynara-creds-gdbus.h>
20 #include <cynara-session.h>
21 #include <security-manager.h>
22 #include "eventsystem_daemon.h"
24 #define DEFAULT_USER tzplatform_getuid(TZ_SYS_DEFAULT_USER)
25 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
28 #define SYS_EVENT_NAME_PREFIX "tizen.system.event"
29 #define SYS_EVENT_OBJ_PATH "/tizen/system/event"
30 #define REQUEST_LAST_DATA "request_last_data"
32 static GHashTable *event_launch_table; /* table of events for launch_on_event*/
34 static const char *event_launch_support_list[] = {
35 SYS_EVENT_BATTERY_CHARGER_STATUS,
37 SYS_EVENT_EARJACK_STATUS,
38 SYS_EVENT_INCOMMING_MSG,
39 SYS_EVENT_OUTGOING_MSG
42 struct privilege_info {
43 const char *event_name;
44 const char *privilege_name;
47 static const struct privilege_info privilege_check_list[] = {
48 {SYS_EVENT_DISPLAY_STATE, "http://tizen.org/privilege/display"},
49 {SYS_EVENT_WIFI_STATE, "http://tizen.org/privilege/network.get"},
50 {SYS_EVENT_INCOMMING_MSG, "http://tizen.org/privilege/message.read"},
51 {SYS_EVENT_OUTGOING_MSG, "http://tizen.org/privilege/message.read"}
54 static int privilege_check_size = sizeof(privilege_check_list)/sizeof(struct privilege_info);
56 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
57 static const char *earlier_event_list[] = {
60 SYS_EVENT_BOOT_COMPLETED,
61 SYS_EVENT_SYSTEM_SHUTDOWN,
62 SYS_EVENT_BATTERY_CHARGER_STATUS
65 static GHashTable *earlier_event_table; /* table of events for earlier_data */
67 typedef struct __earlier_table_item {
70 bundle *earlier_data; /* event-data from earlier occurrence */
75 static GHashTable *user_last_event_table; /* table of user events for last data */
77 struct __last_event_item {
85 static GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */
87 typedef struct __trusted_busname_item {
94 typedef struct __eventlaunch_item_param {
96 } eventlaunch_item_param_s;
98 typedef struct esd_list_item {
104 typedef struct __event_launch_table_item {
106 char *package_name; /* just for passing pointer to app-list removal func */
107 GList *app_list_evtlaunch; /* app-list for on-event-launch */
112 enum __pkg_event_type {
119 typedef struct __pkgmgr_event {
124 typedef struct __esd_event_param {
130 typedef struct esd_info {
131 pkgmgr_client *client;
133 static esd_info_s s_info;
135 typedef struct __esd_appctrl_cb_data {
139 } esd_appctrl_cb_data;
141 static void __esd_event_handler(char *event_name, bundle *data, void *user_data);
142 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data);
144 static cynara *r_cynara = NULL;
146 static int __esd_init_cynara(void)
150 ret = cynara_initialize(&r_cynara, NULL);
151 if (ret != CYNARA_API_SUCCESS) {
152 _E("cynara initialize failed.");
159 static void __esd_finish_cynara(void)
162 cynara_finish(r_cynara);
166 static void free_saved_event(struct __last_event_item *item)
171 free(item->event_name);
172 free(item->own_name);
177 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
178 static int __esd_check_earlier_support(const char *event_name)
181 int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
183 for (i = 0; i < size; i++) {
184 if (strcmp(earlier_event_list[i], event_name) == 0)
192 static int __esd_check_event_launch_support(const char *event_name)
195 int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list);
197 for (i = 0; i < size; i++) {
198 if (strcmp(event_launch_support_list[i], event_name) == 0)
205 static int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type)
207 GDBusMessage *msg = NULL;
208 GDBusMessage *reply = NULL;
214 msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
215 "org.freedesktop.DBus", type);
217 _E("Can't allocate new method call");
221 g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
222 reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
223 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
227 _E("Failed to get info [%s]", err->message);
233 body = g_dbus_message_get_body(reply);
234 g_variant_get(body, "(u)", &value);
241 g_object_unref(reply);
246 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
250 pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID");
252 _E("failed to get pid");
256 _D("sender_name(%s), pid(%d)", sender_name, pid);
261 static int __get_sender_uid(GDBusConnection *conn, const char *sender_name)
265 uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser");
267 _E("failed to get uid");
270 _D("sender_name(%s), uid(%d)", sender_name, uid);
275 static int __esd_check_certificate_match(uid_t uid, const char *app_id, uid_t from_uid, const char *from_appid)
277 pkgmgrinfo_cert_compare_result_type_e res;
280 _D("uid(%d), app_id(%s), from_uid(%d), from_appid(%s)", uid, app_id, from_uid, from_appid);
282 ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, from_appid, from_uid, &res);
284 _E("failed to check certificate");
288 if (res != PMINFO_CERT_COMPARE_MATCH) {
289 _D("certificat not match (%s)", app_id);
296 static bool __esd_check_application_validation(uid_t uid, const char *appid)
299 pkgmgrinfo_appinfo_h handle;
301 ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle);
302 if (ret != PMINFO_R_OK)
305 pkgmgrinfo_appinfo_destroy_appinfo(handle);
307 if (!aul_app_is_running_for_uid(appid, uid))
313 static void __esd_trusted_busname_print_items(void)
319 g_hash_table_iter_init(&iter, trusted_busname_table);
321 while (g_hash_table_iter_next(&iter, &key, &value)) {
322 trusted_item *item = (trusted_item *)value;
324 _D("uid(%d), appid(%s), pid(%d), busname(%s)", item->uid, item->app_id, item->pid, item->bus_name);
328 static int __esd_trusted_busname_add_item(uid_t uid, const char *appid, const char *busname, int pid)
331 char *bus_name = NULL;
332 trusted_item *item = NULL;
333 trusted_item *new_item;
335 app_id = strdup(appid);
336 if (app_id == NULL) {
341 bus_name = strdup(busname);
342 if (bus_name == NULL) {
344 FREE_AND_NULL(app_id);
348 item = (trusted_item *)g_hash_table_lookup(trusted_busname_table, app_id);
350 if (item && item->bus_name && strcmp(item->bus_name, bus_name) == 0 &&
351 (item->uid == uid)) {
352 _D("already exist (%s, %s)", app_id, bus_name);
353 FREE_AND_NULL(app_id);
354 FREE_AND_NULL(bus_name);
356 new_item = calloc(1, sizeof(trusted_item));
357 if (new_item == NULL) {
358 _E("memory alloc failed");
359 FREE_AND_NULL(app_id);
360 FREE_AND_NULL(bus_name);
364 new_item->app_id = app_id;
365 new_item->bus_name = bus_name;
367 g_hash_table_insert(trusted_busname_table, new_item->app_id, new_item);
368 _D("added busname(%s)", new_item->bus_name);
374 static int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name)
377 GError *error = NULL;
380 char tmp_appid[128] = {0, };
385 result = g_dbus_connection_call_sync(conn,
386 "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
387 list_name, NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE,
390 if (result == NULL) {
391 _E("get (%s) error(%s)", list_name, error->message);
396 g_variant_get(result, "(as)", &iter);
397 while (g_variant_iter_loop(iter, "s", &str)) {
398 if (!strstr((const char *)str, "event.busname.session"))
401 _D("list(%s), name(%s)", list_name, str);
402 pid = __get_sender_pid(conn, (const char *)str);
404 _E("failed to get pid(%d)", pid);
408 uid = __get_sender_uid(conn, (const char *)str);
410 _E("failed to get uid(%d)", uid);
415 memset(tmp_appid, 0, sizeof(tmp_appid));
416 ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), (uid_t)uid);
417 if (ret != AUL_R_OK) {
418 _E("failed to get appid by pid(%d)", pid);
422 _D("appid(%s)", tmp_appid);
423 if (__esd_check_application_validation((uid_t)uid, tmp_appid)) {
425 ret = __esd_trusted_busname_add_item((uid_t)uid, tmp_appid, (const char *)str, pid);
427 _E("failed to add item");
430 g_variant_iter_free(iter);
431 g_variant_unref(result);
436 static int __esd_check_privilege_name(const char *event_name, char **privilege_name)
440 *privilege_name = NULL;
442 for (i = 0; i < privilege_check_size; i++) {
443 if (strcmp(event_name, privilege_check_list[i].event_name) == 0) {
444 *privilege_name = (char *)privilege_check_list[i].privilege_name;
445 _D("[%d] privilege_name(%s)", i, *privilege_name);
453 static bool __esd_check_valid_privilege_by_cynara(const char *appid, const char *client,
454 const char *session, const char *user, const char *privilege_name)
457 bool has_privilege = false;
459 _D("check privilege, (%s, %s, %s, %s, %s)", appid, client, session, user, privilege_name);
461 ret = cynara_check(r_cynara, client, session, user, privilege_name);
462 if (ret == CYNARA_API_ACCESS_ALLOWED) {
463 _D("valid privilege");
464 has_privilege = true;
465 } else if (ret == CYNARA_API_ACCESS_DENIED) {
466 _E("invalid privilege");
468 _E("failed to check privilege, error(%d)", ret);
471 return has_privilege;
474 static int __esd_check_app_privileged_event(uid_t uid, const char *appid, const char *pkgid, const char *event_name)
476 char *privilege_name = NULL;
480 _D("event_name(%s), uid(%d), appid(%s), pkgid(%s)", event_name, uid, appid, pkgid);
482 __esd_check_privilege_name(event_name, &privilege_name);
484 if (privilege_name) {
485 ret = security_manager_app_has_privilege(appid, privilege_name, uid, &result);
486 if (ret != SECURITY_MANAGER_SUCCESS)
487 _E("failed to check privilege(%d)", ret);
488 _D("result(%d)", result);
496 static void __esd_print_appid_with_eventid(gpointer data, gpointer user_data)
498 esd_list_item_s *item = (esd_list_item_s *)data;
499 char *event_name = (char *)user_data;
501 _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name, item->uid, item->app_id, item->pkg_id);
504 static void __esd_print_interested_event(gpointer data, gpointer user_data)
506 event_launch_item *el_item = (event_launch_item *)data;
507 char *event_name = (char *)el_item->event_name;
508 _D("event_name = (%s)", event_name);
509 g_list_foreach(el_item->app_list_evtlaunch, __esd_print_appid_with_eventid, event_name);
512 static void __esd_launch_table_print_items(void)
518 g_hash_table_iter_init(&iter, event_launch_table);
520 while (g_hash_table_iter_next(&iter, &key, &value))
521 __esd_print_interested_event(value, NULL);
524 static int __esd_find_compare_by_list_item(gconstpointer data, gconstpointer user_data)
526 esd_list_item_s *item_1 = (esd_list_item_s *)user_data;
527 esd_list_item_s *item_2 = (esd_list_item_s *)data;
529 return (item_1->uid != item_2->uid) |
530 strcmp(item_1->app_id, item_2->app_id) |
531 strcmp(item_1->pkg_id, item_2->pkg_id);
534 static int __esd_add_list_item(uid_t uid, event_launch_item *el_item,
535 const char *app_id, const char *pkg_id)
537 esd_list_item_s *item_of_list = NULL;
539 item_of_list = calloc(1, sizeof(esd_list_item_s));
540 if (item_of_list == NULL) {
544 item_of_list->uid = uid;
545 item_of_list->app_id = (char *)app_id;
546 item_of_list->pkg_id = (char *)pkg_id;
547 el_item->app_list_evtlaunch =
548 g_list_append(el_item->app_list_evtlaunch, item_of_list);
553 static int __esd_add_launch_item(uid_t uid, const char *event_name, const char *appid, const char *pkgid)
555 GList *app_list = NULL;
556 guint subscription_id = 0;
559 esd_list_item_s *item_of_list = NULL;
560 event_launch_item *eli;
561 event_launch_item *el_item =
562 (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
565 item_of_list = calloc(1, sizeof(esd_list_item_s));
566 if (item_of_list == NULL) {
567 _E("memory alloc failed");
570 item_of_list->uid = uid;
571 item_of_list->app_id = (char *)appid;
572 item_of_list->pkg_id = (char *)pkgid;
574 app_list = g_list_find_custom(el_item->app_list_evtlaunch,
575 item_of_list, (GCompareFunc)__esd_find_compare_by_list_item);
577 if (app_list == NULL) {
578 _D("add new item (list item only)");
579 app_id = strdup((char *)appid);
584 pkg_id = strdup((char *)pkgid);
587 FREE_AND_NULL(app_id);
590 if (__esd_add_list_item(uid, el_item, app_id, pkg_id) < 0) {
591 _E("failed to add list item");
592 FREE_AND_NULL(app_id);
593 FREE_AND_NULL(pkg_id);
598 _D("add new item (all)");
599 eli = calloc(1, sizeof(event_launch_item));
601 _E("memory alloc failed");
605 eli->event_name = strdup(event_name);
606 if (!eli->event_name) {
612 app_id = strdup((char *)appid);
615 FREE_AND_NULL(eli->event_name);
620 pkg_id = strdup((char *)pkgid);
623 FREE_AND_NULL(app_id);
624 FREE_AND_NULL(eli->event_name);
629 if (__esd_add_list_item(uid, eli, app_id, pkg_id) < 0) {
630 _E("failed to add list item");
631 FREE_AND_NULL(app_id);
632 FREE_AND_NULL(pkg_id);
633 FREE_AND_NULL(eli->event_name);
638 g_hash_table_insert(event_launch_table, eli->event_name, eli);
640 eventsystem_register_event(eli->event_name, &subscription_id,
641 (eventsystem_handler)__esd_event_handler, NULL);
642 if (subscription_id == 0) {
643 _E("signal subscription error, event_name(%s), app_id(%s)",
644 eli->event_name, app_id);
647 eli->reg_id = subscription_id;
654 static void __esd_remove_all_private_usr_app_list(gpointer data, gpointer user_data)
656 esd_list_item_s *item = (esd_list_item_s *)data;
657 event_launch_item *eli = (event_launch_item *)user_data;
659 if (item->uid != GLOBAL_USER && !strcmp(eli->package_name, item->pkg_id)) {
660 _D("uid(%d), app_id(%s), pkg_id(%s)", item->uid, item->app_id, eli->package_name);
661 eli->app_list_evtlaunch = g_list_remove_all(eli->app_list_evtlaunch, data);
665 static int __esd_launch_table_remove_private_usr_items(void)
670 event_launch_item *eli = NULL;
671 GList *first_list = NULL;
673 g_hash_table_iter_init(&iter, event_launch_table);
675 while (g_hash_table_iter_next(&iter, &key, &value)) {
676 eli = (event_launch_item *)value;
677 g_list_foreach(eli->app_list_evtlaunch, __esd_remove_all_private_usr_app_list, eli);
679 first_list = g_list_first(eli->app_list_evtlaunch);
680 if (first_list == NULL) {
682 eventsystem_unregister_event(eli->reg_id);
684 g_hash_table_iter_remove(&iter);
691 static void __esd_remove_app_list(gpointer data, gpointer user_data)
694 esd_list_item_s *item = (esd_list_item_s *)data;
695 event_launch_item *eli = (event_launch_item *)user_data;
697 if (eli->uid != GLOBAL_USER && eli->uid != item->uid)
700 if (!skip && !strcmp(eli->package_name, item->pkg_id)) {
701 _D("pkg_id(%s), app_id(%s)", eli->package_name, item->app_id);
702 eli->app_list_evtlaunch =
703 g_list_remove_all(eli->app_list_evtlaunch, data);
707 static int __esd_remove_launch_item(uid_t uid, gpointer data, const char *pkg_id)
709 event_launch_item *eli = (event_launch_item *)data;
710 GList *first_list = NULL;
713 eli->package_name = (char *)pkg_id;
714 g_list_foreach(eli->app_list_evtlaunch, __esd_remove_app_list, eli);
716 first_list = g_list_first(eli->app_list_evtlaunch);
717 if (first_list == NULL) {
719 eventsystem_unregister_event(eli->reg_id);
727 static int __esd_launch_table_remove_items(uid_t uid, const char *pkg_id)
733 g_hash_table_iter_init(&iter, event_launch_table);
735 while (g_hash_table_iter_next(&iter, &key, &value)) {
736 if (__esd_remove_launch_item(uid, value, pkg_id) == ES_R_REMOVE) {
737 _D("remove item itself");
738 g_hash_table_iter_remove(&iter);
745 static void __esd_event_launch_with_appid(gpointer data, gpointer user_data)
747 esd_list_item_s *item = (esd_list_item_s *)data;
748 uid_t uid = item->uid;
749 char *app_id = item->app_id;
750 esd_event_param *eep = (esd_event_param *)user_data;
751 static unsigned int req_id;
753 char event_uri[1024];
756 _D("launch_on_event: app_id(%s), event_name(%s), uid(%d)",
757 app_id, eep->event_name, uid);
759 if (!aul_app_is_running_for_uid(app_id, uid)) {
760 snprintf(event_uri, sizeof(event_uri), "event://%s", eep->event_name);
761 b = bundle_dup(eep->event_data);
762 appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT);
763 appsvc_set_uri(b, event_uri);
764 appsvc_set_appid(b, app_id);
766 pid = appsvc_usr_run_service(b, req_id++, NULL, eep->user_data, uid);
767 _D("uid(%d), pid(%d)", uid, pid);
771 _D("already is running or launch failed");
775 static void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_data)
777 event_launch_item *el_item = (event_launch_item *)data;
778 esd_event_param *eep = (esd_event_param *)user_data;
780 if (strcmp(eep->event_name, (char *)el_item->event_name) == 0) {
781 g_list_foreach(el_item->app_list_evtlaunch,
782 __esd_event_launch_with_appid, user_data);
786 static void __esd_launch_event_handler(char *event_name, bundle *data, void *user_data)
789 const char *msg_type;
791 esd_event_param *eep;
792 event_launch_item *el_item;
794 _D("event_name(%s)", event_name);
796 el_item = (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
800 if (el_item->app_list_evtlaunch != NULL) {
801 if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) {
802 val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS);
803 _D("charger val(%s)", val);
804 if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0))
806 } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) {
807 val = bundle_get_val(data, EVT_KEY_USB_STATUS);
808 _D("usb val(%s)", val);
809 if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0))
811 } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) {
812 val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS);
813 _D("earjack val(%s)", val);
814 if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0))
816 } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) {
817 msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE);
818 _D("msg_type(%s)", msg_type);
819 if (msg_type == NULL)
822 msg_id = bundle_get_val(data, EVT_KEY_MSG_ID);
823 _D("msg_id(%s)", msg_id);
828 eep = calloc(1, sizeof(esd_event_param));
830 _E("memory alloc failed");
833 eep->event_name = event_name;
834 eep->event_data = data;
835 eep->user_data = (void *)user_data;
836 __esd_check_event_launch_with_eventid(el_item, eep);
841 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
842 static void __esd_print_earlier_event(gpointer data, gpointer user_data)
844 earlier_item *item = (earlier_item *)data;
845 char *event_name = (char *)item->event_name;
848 _D("event_name = (%s)", event_name);
850 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
851 if (item->earlier_data) {
852 val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED);
853 _D("boot_completed(%s)", val);
855 } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
856 if (item->earlier_data) {
857 val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN);
858 _D("shutdown(%s)", val);
860 } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
861 if (item->earlier_data) {
862 val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY);
863 _D("low_memory(%s)", val);
865 } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
866 if (item->earlier_data) {
867 val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS);
868 _D("charger_status(%s)", val);
873 static void __esd_earlier_table_print_items(void)
879 g_hash_table_iter_init(&iter, earlier_event_table);
881 while (g_hash_table_iter_next(&iter, &key, &value))
882 __esd_print_earlier_event(value, NULL);
885 static void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data)
888 _D("event_name(%s)", event_name);
890 item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
892 /* update earlier value */
893 if (item->earlier_data != NULL)
894 bundle_free(item->earlier_data);
896 item->earlier_data = bundle_dup(data);
901 static void __esd_event_handler(char *event_name, bundle *data, void *user_data)
903 _D("event_name(%s)", event_name);
905 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
906 if (__esd_check_earlier_support(event_name))
907 __esd_earlier_event_handler(event_name, data, user_data);
910 if (__esd_check_event_launch_support(event_name))
911 __esd_launch_event_handler(event_name, data, user_data);
914 static void __esd_trusted_busname_remove_item(char *bus_name)
921 g_hash_table_iter_init(&iter, trusted_busname_table);
923 while (g_hash_table_iter_next(&iter, &key, &value)) {
924 item = (trusted_item *)value;
926 if (strcmp(bus_name, item->bus_name) == 0) {
927 _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name);
928 FREE_AND_NULL(item->app_id);
929 FREE_AND_NULL(item->bus_name);
931 g_hash_table_iter_remove(&iter);
933 __esd_trusted_busname_print_items();
939 static void __esd_filter_name_owner_changed(GDBusConnection *connection,
940 const gchar *sender_name, const gchar *object_path,
941 const gchar *interface_name, const gchar *signal_name,
942 GVariant *parameters, gpointer user_data)
945 char *old_owner = NULL;
946 char *new_owner = NULL;
950 g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
952 if (strstr(name, "event.busname.session")) {
953 old_len = strlen(old_owner);
954 new_len = strlen(new_owner);
956 _D("changed name(%s), old_onwer(%s)(%d) -> new_onwer(%s)(%d)",
957 name, old_owner, old_len, new_owner, new_len);
959 if (old_len > 0 && new_len == 0)
960 __esd_trusted_busname_remove_item(name);
961 else if (old_len == 0 && new_len > 0)
962 _D("new name owned");
964 _E("not-expected name change");
968 static int __esd_dbus_name_monitor(GDBusConnection *connection)
970 guint name_owner_changed_id = 0;
972 name_owner_changed_id = g_dbus_connection_signal_subscribe(connection,
973 "org.freedesktop.DBus", "org.freedesktop.DBus",
974 "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE,
975 __esd_filter_name_owner_changed, NULL, NULL);
977 _I("name_owner_changed_id(%d)", name_owner_changed_id);
982 static int __esd_get_user_items(uid_t uid)
985 pkgmgrinfo_appinfo_filter_h handle = NULL;
987 _I("get user items for uid(%d)", uid);
988 /* reset user's item */
989 __esd_launch_table_remove_private_usr_items();
991 ret = pkgmgrinfo_appinfo_filter_create(&handle);
993 _E("failed to create appinfo filter");
996 ret = pkgmgrinfo_appinfo_filter_add_string(handle,
997 PMINFO_APPINFO_PROP_APP_COMPONENT, "svcapp");
999 _E("failed to add appinfo filter string");
1000 pkgmgrinfo_appinfo_filter_destroy(handle);
1003 ret = pkgmgrinfo_appinfo_filter_add_string(handle,
1004 PMINFO_APPINFO_PROP_APP_OPERATION, APPSVC_OPERATION_LAUNCH_ON_EVENT);
1006 _E("failed to add appinfo filter string");
1007 pkgmgrinfo_appinfo_filter_destroy(handle);
1010 ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle,
1011 __esd_add_appinfo_handler, &uid, uid);
1013 _E("appinfo filter foreach error");
1014 pkgmgrinfo_appinfo_filter_destroy(handle);
1017 pkgmgrinfo_appinfo_filter_destroy(handle);
1019 __esd_launch_table_print_items();
1024 static void __esd_signal_handler(GDBusConnection *connection,
1025 const gchar *sender_name,
1026 const gchar *object_path,
1027 const gchar *interface_name,
1028 const gchar *signal_name,
1029 GVariant *parameters,
1036 if (!g_strcmp0(signal_name,
1037 SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED)) {
1038 _I("System session finished");
1040 b = bundle_create();
1041 bundle_add_str(b, EVT_KEY_BOOT_COMPLETED,
1042 EVT_VAL_BOOT_COMPLETED_TRUE);
1043 eventsystem_send_system_event(SYS_EVENT_BOOT_COMPLETED, b);
1046 handle = creat(ESD_BOOT_COMPLETED, 0640);
1049 } else if (!g_strcmp0(signal_name,
1050 SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED)) {
1051 g_variant_get(parameters, "(t)", &uid);
1052 _I("User session finished uid : %d", (int)uid);
1053 if ((uid_t)uid != DEFAULT_USER)
1054 __esd_get_user_items((uid_t)uid);
1058 static GDBusNodeInfo *introspection_data;
1059 static const gchar introspection_xml[] =
1061 " <interface name='tizen.system.event.app2esd'>"
1062 " <method name='CheckSenderValidation'>"
1063 " <arg type='i' name='senderpid' direction='in'/>"
1064 " <arg type='s' name='eventname' direction='in'/>"
1065 " <arg type='i' name='ret' direction='out'/>"
1066 " <arg type='s' name='senderid' direction='out'/>"
1068 " <method name='GetTrustedPeerList'>"
1069 " <arg type='s' name='eventname' direction='in'/>"
1070 " <arg type='i' name='ret' direction='out'/>"
1071 " <arg type='as' name='dest_list' direction='out'/>"
1073 " <method name='SetupTrustedPeer'>"
1074 " <arg type='s' name='eventname' direction='in'/>"
1075 " <arg type='s' name='destination' direction='in'/>"
1076 " <arg type='i' name='ret' direction='out'/>"
1078 " <method name='CheckPrivilegeValidation'>"
1079 " <arg type='s' name='eventname' direction='in'/>"
1080 " <arg type='i' name='ret' direction='out'/>"
1082 " <method name='CheckUserSendValidation'>"
1083 " <arg type='s' name='eventname' direction='in'/>"
1084 " <arg type='i' name='ret' direction='out'/>"
1086 " <method name='RequestTrustedEventLaunch'>"
1087 " <arg type='s' name='eventname' direction='in'/>"
1088 " <arg type='s' name='eventdata' direction='in'/>"
1089 " <arg type='i' name='datalen' direction='in'/>"
1090 " <arg type='i' name='ret' direction='out'/>"
1092 " <method name='RequestEventLaunch'>"
1093 " <arg type='s' name='eventname' direction='in'/>"
1094 " <arg type='s' name='eventdata' direction='in'/>"
1095 " <arg type='i' name='datalen' direction='in'/>"
1096 " <arg type='i' name='ret' direction='out'/>"
1098 " <method name='RequestSendingEvent'>"
1099 " <arg type='s' name='eventname' direction='in'/>"
1100 " <arg type='s' name='eventdata' direction='in'/>"
1101 " <arg type='i' name='datalen' direction='in'/>"
1102 " <arg type='i' name='ret' direction='out'/>"
1104 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1105 " <method name='GetEarlierData'>"
1106 " <arg type='s' name='appid' direction='in'/>"
1107 " <arg type='i' name='ret' direction='out'/>"
1108 " <arg type='i' name='len' direction='out'/>"
1109 " <arg type='s' name='earlier_data' direction='out'/>"
1112 " <method name='KeepLastData'>"
1113 " <arg type='s' name='eventname' direction='in'/>"
1114 " <arg type='s' name='own_name' direction='in'/>"
1115 " <arg type='i' name='ret' direction='out'/>"
1117 " <method name='CheckLastData'>"
1118 " <arg type='s' name='eventname' direction='in'/>"
1119 " <arg type='s' name='own_name' direction='in'/>"
1120 " <arg type='i' name='ret' direction='out'/>"
1125 static int __esd_get_appid_by_pid(int pid, uid_t uid, char *app_id, int buf_size)
1127 int retval = ES_R_OK;
1131 _E("invalid pid(%d)", pid);
1132 retval = ES_R_ERROR;
1133 } else if (uid <= 0) {
1134 _E("invalid uid(%d)", uid);
1135 retval = ES_R_ERROR;
1137 ret = aul_app_get_appid_bypid_for_uid(pid, app_id, buf_size, (uid_t)uid);
1138 if (ret != AUL_R_OK) {
1139 _E("failed to get appid by pid");
1140 retval = ES_R_ERROR;
1142 _D("pid(%d)-uid(%d)-appid(%s)", pid, uid, app_id);
1148 static int check_user_event_sender_valid(const char *event_name, const char *app_id)
1150 char *valid_name = NULL;
1151 char *temp_name = NULL;
1153 int retval = ES_R_OK;
1155 int valid_name_len = 0;
1157 temp_name = strdup(event_name);
1158 if (temp_name == NULL) {
1159 _E("out of memory");
1163 tmp = strrchr(temp_name, '.');
1164 if (tmp == NULL || strlen(tmp) == 0) {
1165 _E("invalid event name");
1166 FREE_AND_NULL(temp_name);
1170 if (len <= 1 || len > 128) {
1171 _E("invalid length(%d) of user-defined name", len);
1172 FREE_AND_NULL(temp_name);
1177 _D("app_id(%s), len(%d)", app_id, strlen(app_id));
1179 valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1;
1180 valid_name = calloc(1, valid_name_len);
1181 if (valid_name == NULL) {
1182 _E("memory alloc failed");
1183 FREE_AND_NULL(temp_name);
1186 snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id);
1187 _D("valid_name(%s)", valid_name);
1189 if (strcmp(temp_name, valid_name) != 0) {
1190 _E("appid misamatch");
1191 retval = ES_R_EINVAL;
1194 FREE_AND_NULL(temp_name);
1195 FREE_AND_NULL(valid_name);
1200 static void check_sender_valid_method_call(GDBusConnection *connection, const gchar *sender,
1201 GVariant *parameters, GDBusMethodInvocation *invocation)
1203 GVariant *param = NULL;
1205 char *event_name = NULL;
1206 char app_id[128] = {0, };
1207 int event_sender_pid = 0;
1208 uid_t sender_uid = 0;
1210 g_variant_get(parameters, "(i&s)", &event_sender_pid, &event_name);
1211 _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name);
1213 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1214 if (__esd_get_appid_by_pid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1215 result = ES_R_ERROR;
1217 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1218 _E("invalid sender");
1219 result = ES_R_EINVAL;
1225 param = g_variant_new("(is)", result, app_id);
1226 _D("event_name(%s), result(%d)", event_name, result);
1227 g_dbus_method_invocation_return_value(invocation, param);
1230 static void check_send_event_valid_method_call(GDBusConnection *connection, const gchar *sender,
1231 GVariant *parameters, GDBusMethodInvocation *invocation)
1233 GVariant *param = NULL;
1235 char *event_name = NULL;
1236 char app_id[128] = {0, };
1238 uid_t sender_uid = 0;
1240 g_variant_get(parameters, "(&s)", &event_name);
1241 _D("event_name(%s)", event_name);
1243 sender_pid = __get_sender_pid(connection, sender);
1244 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1245 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1246 result = ES_R_ERROR;
1248 if (check_user_event_sender_valid(event_name, app_id) < 0) {
1249 _E("invalid sender");
1250 result = ES_R_EINVAL;
1256 param = g_variant_new("(i)", result);
1257 _D("event_name(%s), result(%d)", event_name, result);
1258 g_dbus_method_invocation_return_value(invocation, param);
1261 static void get_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1262 GVariant *parameters, GDBusMethodInvocation *invocation)
1264 GVariant *param = NULL;
1266 GVariantBuilder *builder = NULL;
1267 GHashTableIter iter;
1268 gpointer key, value;
1269 char *event_name = NULL;
1270 char app_id[128] = {0, };
1272 uid_t sender_uid = 0;
1275 char *_appid = NULL;
1276 char *_busname = NULL;
1279 g_variant_get(parameters, "(&s)", &event_name);
1280 _D("event_name(%s)", event_name);
1282 sender_pid = __get_sender_pid(connection, sender);
1283 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1284 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1285 result = ES_R_ERROR;
1287 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1289 g_hash_table_iter_init(&iter, trusted_busname_table);
1290 while (g_hash_table_iter_next(&iter, &key, &value)) {
1291 item = (trusted_item *)value;
1293 _appid = item->app_id;
1294 _busname = item->bus_name;
1296 if (uid != GLOBAL_USER && uid != sender_uid)
1299 ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id);
1301 g_variant_builder_add(builder, "s", _busname);
1307 param = g_variant_new("(ias)", result, builder);
1308 _D("result(%d)", result);
1309 g_dbus_method_invocation_return_value(invocation, param);
1311 g_variant_builder_unref(builder);
1314 static void setup_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender,
1315 GVariant *parameters, GDBusMethodInvocation *invocation)
1317 GVariant *param = NULL;
1319 char *event_name = NULL;
1320 char *destination_name = NULL;
1321 char app_id[128] = {0, };
1323 uid_t sender_uid = 0;
1326 g_variant_get(parameters, "(&s&s)", &event_name, &destination_name);
1327 _D("event_name(%s), destination_name(%s)", event_name, destination_name);
1329 if (destination_name && destination_name[0] != '\0') {
1330 sender_pid = __get_sender_pid(connection, sender);
1331 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1332 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1333 result = ES_R_ERROR;
1335 ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name,
1338 _E("failed to add trusted busname item");
1339 result = ES_R_ERROR;
1345 _E("invalid destination name");
1346 result = ES_R_ERROR;
1349 param = g_variant_new("(i)", result);
1350 _D("event_name(%s), result(%d)", event_name, result);
1351 g_dbus_method_invocation_return_value(invocation, param);
1354 static void check_privilege_valid_method_call(GDBusConnection *connection, const gchar *sender,
1355 GVariant *parameters, GDBusMethodInvocation *invocation)
1357 GVariant *param = NULL;
1359 char *event_name = NULL;
1360 char *privilege_name = NULL;
1361 char app_id[128] = {0, };
1363 uid_t sender_uid = 0;
1364 char *client = NULL;
1365 char *session = NULL;
1369 g_variant_get(parameters, "(&s)", &event_name);
1370 __esd_check_privilege_name(event_name, &privilege_name);
1371 _D("event_name(%s), privilege_name(%s)", event_name, privilege_name);
1373 if (privilege_name) {
1374 sender_pid = __get_sender_pid(connection, sender);
1375 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1376 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1377 result = ES_R_ERROR;
1379 ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client);
1380 if (ret != CYNARA_API_SUCCESS) {
1381 _E("failed to get client");
1382 result = ES_R_EINVAL;
1386 ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user);
1387 if (ret != CYNARA_API_SUCCESS) {
1388 _E("failed to get user");
1389 result = ES_R_EINVAL;
1393 session = cynara_session_from_pid(sender_pid);
1394 if (session == NULL) {
1395 _E("failed to get session");
1396 result = ES_R_EINVAL;
1400 _D("app_id(%s), client(%s), session(%s), user(%s)", app_id, client, session, user);
1401 if (__esd_check_valid_privilege_by_cynara(app_id, client, session, user, privilege_name))
1404 result = ES_R_EINVAL;
1414 param = g_variant_new("(i)", result);
1415 _D("event_name(%s), result(%d)", event_name, result);
1416 g_dbus_method_invocation_return_value(invocation, param);
1419 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1420 static void get_earlier_data_method_call(GVariant *parameters, GDBusMethodInvocation *invocation)
1422 GVariant *param = NULL;
1424 char *event_name = NULL;
1426 bundle_raw *raw = NULL;
1430 g_variant_get(parameters, "(&s)", &event_name);
1432 if (event_name && strlen(event_name) > 0) {
1433 _D("event_name(%s)", event_name);
1436 _E("invalid event_name(%s)", event_name);
1437 result = ES_R_ERROR;
1440 item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1442 if (item->earlier_data) {
1443 b = bundle_dup(item->earlier_data);
1444 bundle_add_str(b, "is_earlier_data", "true");
1445 bundle_encode(b, &raw, &len);
1450 param = g_variant_new("(iis)", result, len, raw);
1452 _D("result(%d), len(%d)", result, len);
1453 g_dbus_method_invocation_return_value(invocation, param);
1455 bundle_free_encoded_rawdata(&raw);
1459 static void keep_last_data_method_call(GDBusConnection *connection,
1460 const gchar *sender, GVariant *parameters,
1461 GDBusMethodInvocation *invocation)
1464 int result = ES_R_OK;
1471 struct __last_event_item *item;
1473 g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
1475 if (!event_name || !own_name) {
1476 result = ES_R_ERROR;
1477 _E("invalid event_name and own_name");
1481 sender_pid = __get_sender_pid(connection, sender);
1482 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1483 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id,
1484 sizeof(app_id)) < 0) {
1485 _E("failed to get appid by pid");
1486 result = ES_R_ERROR;
1490 key = (char *)malloc(sizeof(event_name) + 10);
1492 result = ES_R_ENOMEM;
1493 _E("out of memory");
1497 snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
1498 item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
1501 item = calloc(1, sizeof(*item));
1503 result = ES_R_ERROR;
1507 item->event_name = strdup(event_name);
1508 item->own_name = strdup(own_name);
1509 item->uid = sender_uid;
1510 item->app_id = strdup(app_id);
1511 g_hash_table_insert(user_last_event_table,
1514 free(item->own_name);
1515 item->own_name = strdup(own_name);
1519 param = g_variant_new("(i)", result);
1521 g_dbus_method_invocation_return_value(invocation, param);
1524 static void check_last_data_method_call(GDBusConnection *connection,
1525 const gchar *sender, GVariant *parameters,
1526 GDBusMethodInvocation *invocation)
1529 int result = ES_R_OK;
1536 struct __last_event_item *item;
1538 g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
1540 if (!event_name || !own_name) {
1541 result = ES_R_ERROR;
1542 _E("invalid event_name and own_name");
1546 sender_pid = __get_sender_pid(connection, sender);
1547 sender_uid = (uid_t)__get_sender_uid(connection, sender);
1548 if (__esd_get_appid_by_pid(sender_pid, sender_uid, app_id,
1549 sizeof(app_id)) < 0) {
1550 result = ES_R_ERROR;
1551 _E("failed to get appid by pid");
1555 key = (char *)malloc(sizeof(event_name) + 10);
1557 result = ES_R_ENOMEM;
1558 _E("out of memory");
1562 snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
1563 item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
1572 GError *error = NULL;
1574 b = bundle_create();
1576 result = ES_R_ERROR;
1579 bundle_add_str(b, EVT_KEY_KEPT_EVENT_NAME, event_name);
1580 bundle_add_str(b, EVT_KEY_KEPT_OWN_NAME, own_name);
1581 if (__esd_check_certificate_match(item->uid, item->app_id,
1582 sender_uid, app_id) == ES_R_OK)
1583 bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "true");
1585 bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "false");
1587 bundle_encode(b, &raw, &len);
1588 gv = g_variant_new("(us)", len, raw);
1589 ret = g_dbus_connection_emit_signal(connection,
1592 SYS_EVENT_NAME_PREFIX,
1597 _E("Unable to emit signal: %s", error->message);
1598 g_error_free(error);
1600 bundle_free_encoded_rawdata(&raw);
1605 param = g_variant_new("(i)", result);
1607 g_dbus_method_invocation_return_value(invocation, param);
1610 static void handle_method_call(GDBusConnection *connection,
1611 const gchar *sender, const gchar *object_path,
1612 const gchar *interface_name, const gchar *method_name,
1613 GVariant *parameters, GDBusMethodInvocation *invocation,
1616 if (g_strcmp0(method_name, "CheckSenderValidation") == 0) {
1617 check_sender_valid_method_call(connection, sender, parameters, invocation);
1618 } else if (g_strcmp0(method_name, "GetTrustedPeerList") == 0) {
1619 get_trusted_peer_method_call(connection, sender, parameters, invocation);
1620 } else if (g_strcmp0(method_name, "SetupTrustedPeer") == 0) {
1621 setup_trusted_peer_method_call(connection, sender, parameters, invocation);
1622 } else if (g_strcmp0(method_name, "CheckPrivilegeValidation") == 0) {
1623 check_privilege_valid_method_call(connection, sender, parameters, invocation);
1624 } else if (g_strcmp0(method_name, "CheckUserSendValidation") == 0) {
1625 check_send_event_valid_method_call(connection, sender, parameters, invocation);
1626 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1627 } else if (g_strcmp0(method_name, "GetEarlierData") == 0) {
1628 get_earlier_data_method_call(parameters, invocation);
1630 } else if (g_strcmp0(method_name, "KeepLastData") == 0) {
1631 keep_last_data_method_call(connection, sender, parameters, invocation);
1632 } else if (g_strcmp0(method_name, "CheckLastData") == 0) {
1633 check_last_data_method_call(connection, sender, parameters, invocation);
1637 static const GDBusInterfaceVTable interface_vtable = {
1643 static void __esd_on_bus_acquired(GDBusConnection *connection,
1644 const gchar *name, gpointer user_data)
1646 _I("bus acquired(%s)", name);
1650 guint user_boot_id = 0;
1651 GError *error = NULL;
1653 reg_id = g_dbus_connection_register_object(connection,
1655 introspection_data->interfaces[0],
1657 NULL, NULL, &error);
1659 _E("g_dbus_connection_register_object error(%s)", error->message);
1660 g_error_free(error);
1663 boot_id = g_dbus_connection_signal_subscribe(connection,
1665 SYSTEMD_DBUS_IFACE_MANAGER,
1666 SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED,
1669 G_DBUS_SIGNAL_FLAGS_NONE,
1670 __esd_signal_handler,
1675 _E("g_dbus_connection_signal_subscribe() is failed.");
1676 g_object_unref(connection);
1679 user_boot_id = g_dbus_connection_signal_subscribe(connection,
1681 SYSTEMD_DBUS_IFACE_MANAGER,
1682 SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED,
1685 G_DBUS_SIGNAL_FLAGS_NONE,
1686 __esd_signal_handler,
1690 if (user_boot_id == 0) {
1691 _E("g_dbus_connection_signal_subscribe() is failed.");
1692 g_object_unref(connection);
1696 static void __esd_on_name_acquired(GDBusConnection *connection,
1697 const gchar *name, gpointer user_data)
1701 _I("name acquired(%s)", name);
1703 __esd_check_trusted_events(connection, "ListNames");
1704 __esd_check_trusted_events(connection, "ListActivatableNames");
1706 b = bundle_create();
1707 bundle_add_str(b, EVT_KEY_ESD_STATUS, EVT_VAL_ESD_STARTED);
1708 eventsystem_send_system_event(SYS_EVENT_ESD_STATUS, b);
1711 __esd_register_vconf_callbacks();
1713 __esd_trusted_busname_print_items();
1715 __esd_get_user_items(DEFAULT_USER);
1717 __esd_dbus_name_monitor(connection);
1720 static void __esd_on_name_lost(GDBusConnection *connection,
1721 const gchar *name, gpointer user_data)
1723 _E("name lost(%s)", name);
1726 static int __esd_before_loop(void)
1729 GError *error = NULL;
1732 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1733 guint subscription_id = 0;
1744 earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal);
1745 user_last_event_table = g_hash_table_new_full(g_str_hash,
1746 g_str_equal, NULL, (GDestroyNotify)free_saved_event);
1748 _I("register events for earlier_data");
1749 size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
1750 for (i = 0; i < size; i++) {
1751 event_name = (char *)earlier_event_list[i];
1752 _I("event_name(%s)", event_name);
1754 item = calloc(1, sizeof(earlier_item));
1756 _E("memery alloc failed");
1759 item->event_name = strdup(event_name);
1760 if (item->event_name == NULL) {
1761 _E("out of memory");
1766 /* set initial data */
1767 if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
1768 fd = open(ESD_BOOT_COMPLETED, O_RDONLY);
1770 _D("open file error(%d)", fd);
1772 item->earlier_data = bundle_create();
1773 bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED,
1774 EVT_VAL_BOOT_COMPLETED_TRUE);
1777 } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
1778 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val);
1779 if (ret != VCONF_OK) {
1780 _E("failed to get power_off status (%d)", ret);
1782 if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT ||
1783 val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
1784 /* power-off requested */
1785 item->earlier_data = bundle_create();
1786 bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN,
1787 EVT_VAL_SYSTEM_SHUTDOWN_TRUE);
1790 } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
1791 ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status);
1792 if (ret != VCONF_OK) {
1793 _E("failed to get low_memory status (%d)", ret);
1795 item->earlier_data = bundle_create();
1796 if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
1797 bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1798 EVT_VAL_MEMORY_SOFT_WARNING);
1799 else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING)
1800 bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1801 EVT_VAL_MEMORY_HARD_WARNING);
1803 bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1804 EVT_VAL_MEMORY_NORMAL);
1806 } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
1807 ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status);
1808 if (ret != VCONF_OK) {
1809 _E("failed to get charger_status (%d)", ret);
1811 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now);
1812 if (ret != VCONF_OK)
1813 _E("failed to get charge_now (%d)", ret);
1816 if (ret == VCONF_OK) {
1817 item->earlier_data = bundle_create();
1818 if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) {
1819 if (charge_now == 0) {
1820 bundle_add_str(item->earlier_data,
1821 EVT_KEY_BATTERY_CHARGER_STATUS,
1822 EVT_VAL_BATTERY_CHARGER_DISCHARGING);
1824 bundle_add_str(item->earlier_data,
1825 EVT_KEY_BATTERY_CHARGER_STATUS,
1826 EVT_VAL_BATTERY_CHARGER_CHARGING);
1829 bundle_add_str(item->earlier_data,
1830 EVT_KEY_BATTERY_CHARGER_STATUS,
1831 EVT_VAL_BATTERY_CHARGER_DISCONNECTED);
1836 eventsystem_register_event(event_name, &subscription_id,
1837 (eventsystem_handler)__esd_event_handler, NULL);
1838 if (subscription_id == 0) {
1839 _E("signal subscription error, event_name(%s)", event_name);
1840 if (item->earlier_data)
1841 bundle_free(item->earlier_data);
1842 free(item->event_name);
1847 item->reg_id = subscription_id;
1850 g_hash_table_insert(earlier_event_table, event_name, item);
1853 __esd_earlier_table_print_items();
1856 event_launch_table = g_hash_table_new(g_str_hash, g_str_equal);
1857 trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal);
1859 /* gdbus setup for method call */
1860 introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
1861 if (!introspection_data) {
1862 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
1863 g_error_free(error);
1867 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1869 G_BUS_NAME_OWNER_FLAGS_NONE,
1870 __esd_on_bus_acquired,
1871 __esd_on_name_acquired,
1875 _E("g_bus_own_name error");
1876 g_dbus_node_info_unref(introspection_data);
1880 _I("esd before_loop done");
1885 static void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event)
1887 pkg_event->type = UNKNOWN;
1888 if (pkg_event->pkgid) {
1889 free(pkg_event->pkgid);
1890 pkg_event->pkgid = NULL;
1894 static int __esd_appcontrol_cb(const char *operation,
1895 const char *uri, const char *mime, void *data)
1897 esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data;
1900 char *event_name = NULL;
1901 const char *prefix = "event://";
1904 if (cb_data == NULL) {
1908 appid = cb_data->appid;
1909 pkgid = cb_data->pkgid;
1912 _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)",
1913 uid, appid, pkgid, operation, uri, mime);
1915 if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) {
1916 if (!strncmp(uri, prefix, strlen(prefix))) {
1917 event_name = strdup(&uri[8]);
1919 _D("appid(%s), event_name(%s)", appid, event_name);
1920 if (!__esd_check_event_launch_support(event_name)) {
1921 _E("failed to add item (not support event)");
1922 } else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name)) {
1923 _E("failed to add item (no privilege)");
1925 if (__esd_add_launch_item(uid, event_name, appid, pkgid))
1926 _E("failed to add item");
1928 FREE_AND_NULL(event_name);
1930 _E("out of memory");
1933 _E("Invalid uri(%s) for event_name", uri);
1940 static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data)
1945 uid_t *p_uid = NULL;
1952 p_uid = (uid_t *)data;
1954 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
1956 _E("failed to get appid");
1960 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
1962 _E("failed to get appid");
1966 esd_appctrl_cb_data *cb_data = calloc(1, sizeof(esd_appctrl_cb_data));
1968 if (cb_data == NULL) {
1969 _E("memory alloc failed");
1972 cb_data->appid = strdup(appid);
1973 if (cb_data->appid == NULL) {
1974 _E("out_of_memory");
1975 FREE_AND_NULL(cb_data);
1978 cb_data->pkgid = strdup(pkgid);
1979 if (cb_data->pkgid == NULL) {
1980 _E("out_of_memory");
1981 FREE_AND_NULL(cb_data->appid);
1982 FREE_AND_NULL(cb_data);
1985 cb_data->uid = *p_uid;
1987 ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
1988 (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data);
1990 FREE_AND_NULL(cb_data->pkgid);
1991 FREE_AND_NULL(cb_data->appid);
1992 FREE_AND_NULL(cb_data);
1995 _E("failed to get appcontrol info");
2002 static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id,
2003 const char *pkg_type, const char *pkgid, const char *key,
2004 const char *val, const void *pmsg, void *data)
2006 esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data;
2007 pkgmgrinfo_pkginfo_h handle = NULL;
2010 _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)",
2011 target_uid, req_id, pkg_type, pkgid, key, val);
2013 if (strncmp(key, "start", strlen(key)) == 0) {
2014 if (strcmp(val, "install") == 0) {
2015 _D("install start");
2016 pkg_event->type = INSTALL;
2017 } else if (strcmp(val, "uninstall") == 0) {
2018 _D("unistall start");
2019 pkg_event->type = UNINSTALL;
2020 } else if (strcmp(val, "update") == 0) {
2022 pkg_event->type = UPDATE;
2024 _D("val(%s) start", val);
2025 __esd_pkgmgr_event_free(pkg_event);
2027 } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) {
2028 if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) {
2029 _D("install end (ok)");
2030 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle);
2032 _E("failed to get pkginfo");
2033 __esd_pkgmgr_event_free(pkg_event);
2036 ret = pkgmgrinfo_appinfo_get_usr_list(handle,
2037 PMINFO_ALL_APP, __esd_add_appinfo_handler, &target_uid, target_uid);
2039 _E("failed to get appinfo");
2040 __esd_pkgmgr_event_free(pkg_event);
2043 ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2045 _E("failed to destroy pkginfo");
2046 __esd_pkgmgr_event_free(pkg_event);
2049 } else if (pkg_event->type == UNINSTALL) {
2050 _D("uninstall end (ok)");
2051 __esd_launch_table_remove_items(target_uid, pkgid);
2052 __esd_launch_table_print_items();
2054 __esd_pkgmgr_event_free(pkg_event);
2055 } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) {
2056 _E("pkg_event(%d) falied", pkg_event->type);
2057 __esd_pkgmgr_event_free(pkg_event);
2059 if (strcmp(key, "install_percent") != 0)
2060 __esd_pkgmgr_event_free(pkg_event);
2066 static int __esd_init()
2070 pkgmgr_client *client;
2071 esd_pkgmgr_event *pkg_event;
2073 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
2076 __esd_init_cynara();
2078 client = pkgmgr_client_new(PC_LISTENING);
2079 if (client == NULL) {
2080 _E("set pkgmgr client failed");
2081 __esd_finish_cynara();
2085 pkg_event = calloc(1, sizeof(esd_pkgmgr_event));
2086 if (pkg_event == NULL) {
2087 _E("memory alloc failed");
2088 ret = pkgmgr_client_free(client);
2089 if (ret != PKGMGR_R_OK)
2090 _E("pkgmgr_client_free failed(%d)", ret);
2091 __esd_finish_cynara();
2095 req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event);
2097 _E("pkgmgr client listen failed");
2098 ret = pkgmgr_client_free(client);
2099 if (ret != PKGMGR_R_OK)
2100 _E("pkgmgr_client_free failed(%d)", ret);
2102 __esd_finish_cynara();
2106 s_info.client = client;
2108 _I("esd init done");
2113 static void __esd_remove_esd_list_item(gpointer data, gpointer user_data)
2115 esd_list_item_s *item = (esd_list_item_s *)data;
2121 static void __esd_finalize(void)
2125 GHashTableIter iter;
2127 event_launch_item *el_item;
2129 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2130 earlier_item *er_item;
2135 if (trusted_busname_table) {
2136 g_hash_table_iter_init(&iter, trusted_busname_table);
2137 while (g_hash_table_iter_next(&iter, &key, &value)) {
2138 item = (trusted_item *)value;
2141 free(item->bus_name);
2146 g_hash_table_iter_remove(&iter);
2148 g_hash_table_unref(trusted_busname_table);
2151 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
2152 if (earlier_event_table) {
2153 g_hash_table_iter_init(&iter, earlier_event_table);
2154 while (g_hash_table_iter_next(&iter, &key, &value)) {
2155 er_item = (earlier_item *)value;
2157 eventsystem_unregister_event(er_item->reg_id);
2158 free(er_item->event_name);
2159 bundle_free(er_item->earlier_data);
2162 _E("ealier item is NULL");
2164 g_hash_table_iter_remove(&iter);
2166 g_hash_table_unref(earlier_event_table);
2169 g_hash_table_destroy(user_last_event_table);
2172 if (event_launch_table) {
2173 g_hash_table_iter_init(&iter, event_launch_table);
2174 while (g_hash_table_iter_next(&iter, &key, &value)) {
2175 el_item = (event_launch_item *)value;
2177 eventsystem_unregister_event(el_item->reg_id);
2178 free(el_item->event_name);
2179 g_list_foreach(el_item->app_list_evtlaunch,
2180 __esd_remove_esd_list_item, NULL);
2181 g_list_free(el_item->app_list_evtlaunch);
2186 g_hash_table_iter_remove(&iter);
2188 g_hash_table_unref(event_launch_table);
2191 if (introspection_data)
2192 g_dbus_node_info_unref(introspection_data);
2194 if (s_info.client) {
2195 ret = pkgmgr_client_free(s_info.client);
2196 if (ret != PKGMGR_R_OK)
2197 _E("pkgmgr_client_free failed(%d)", ret);
2200 __esd_finish_cynara();
2202 _D("esd finalize end");
2205 int main(int argc, char *argv[])
2207 GMainLoop *mainloop;
2208 _I("event system daemon : main()");
2210 mainloop = g_main_loop_new(NULL, FALSE);
2211 if (mainloop == NULL) {
2212 _E("out of memory");
2216 if (__esd_init() != 0) {
2217 _E("ESD Initialization failed!");
2218 g_main_loop_unref(mainloop);
2222 if (__esd_before_loop() < 0) {
2225 g_main_loop_unref(mainloop);
2229 g_main_loop_run(mainloop);
2235 g_main_loop_unref(mainloop);