From: Hyunho Kang Date: Wed, 19 Apr 2017 05:05:53 +0000 (+0900) Subject: Fix toolkit_table destroy bug X-Git-Tag: accepted/tizen/unified/20170421.114316~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e5b91194895ffb1bb3b1b32a77c14dbb42963c64;p=platform%2Fcore%2Fappfw%2Fscreen-connector.git Fix toolkit_table destroy bug screen_connector_toolkit_evas_fini is called remote surface is destroyed but screen_connector_toolkit_evas_h will not freed, so callback which have a screen_connector_toolkit_evas_h as a user data like __rs_cb_mouse_move callback could cause crash when they try to send event through already destroyed remote surface Change-Id: Ifda77fa1cb0244186179c7ffe2dc77b536593586 Signed-off-by: Hyunho Kang --- diff --git a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c index 7dc3cec..bf2585d 100644 --- a/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c +++ b/screen_connector_watcher_evas/src/screen_connector_toolkit_evas.c @@ -34,6 +34,7 @@ #endif #define LOG_TAG "SC_WATCHER_EVAS" +#define SC_TOOLKIT_HANDLE_TAG "SC_TOOLKIT_HANDLE_TAG" struct _screen_connector_type_evas_h { GHashTable *toolkit_table; @@ -70,6 +71,53 @@ static void __destroy_type_h(gpointer data) free(type_h); } +static void __clear_img_tbm(screen_connector_toolkit_evas_h toolkit_evas_h) +{ + char *plug_id; + + if (toolkit_evas_h->img_tbm == NULL) + return; + + plug_id = evas_object_data_del(toolkit_evas_h->img_tbm, "___PLUGID"); + if (plug_id) + free(plug_id); + + evas_object_del(toolkit_evas_h->img_tbm); + toolkit_evas_h->img_tbm = NULL; +} + +static void __clear_img_file(screen_connector_toolkit_evas_h toolkit_evas_h) +{ + if (toolkit_evas_h->img_file == NULL) + return; + + evas_object_del(toolkit_evas_h->img_file); + toolkit_evas_h->img_file = NULL; +} + +static void __destroy_toolkit_evas_h(gpointer data) +{ + char *plug_id; + screen_connector_toolkit_evas_h toolkit_evas_h = data; + + if (!toolkit_evas_h) + return; + + if (toolkit_evas_h->img_tbm != NULL) { + plug_id = evas_object_data_del(toolkit_evas_h->img_tbm, "___PLUGID"); + if (plug_id) + free(plug_id); + } + + if (toolkit_evas_h->toolkit_h) + screen_connector_toolkit_remove(toolkit_evas_h->toolkit_h); + + if (toolkit_evas_h->ops) + free(toolkit_evas_h->ops); + + free(toolkit_evas_h); +} + EXPORT_API int screen_connector_toolkit_evas_init(Evas_Object *win, screen_connector_screen_type_e type) { screen_connector_type_evas_h type_h; @@ -85,7 +133,7 @@ EXPORT_API int screen_connector_toolkit_evas_init(Evas_Object *win, screen_conne return -1; } - type_h->toolkit_table = g_hash_table_new(g_direct_hash, g_direct_equal); + type_h->toolkit_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, __destroy_toolkit_evas_h); if (!type_h->toolkit_table) { LOGE("failed to create table"); free(type_h); @@ -124,7 +172,7 @@ EXPORT_API int screen_connector_toolkit_evas_fini(screen_connector_screen_type_e return screen_connector_toolkit_fini(type); } -static bool __obj_is_visible(Evas_Object *obj, screen_connector_toolkit_evas_h toolkit_evas_h) +static bool __obj_is_visible(screen_connector_toolkit_evas_h toolkit_evas_h) { int x, y, w, h; Ecore_Wl_Window *window = NULL; @@ -136,9 +184,14 @@ static bool __obj_is_visible(Evas_Object *obj, screen_connector_toolkit_evas_h t return false; } + if (toolkit_evas_h->img_tbm == NULL) { + LOGE("img_tbm is NULL"); + return false; + } + window = elm_win_wl_window_get(toolkit_evas_h->type_h->viewer_win); ecore_wl_window_geometry_get(window, &window_x, &window_y, &window_w, &window_h); - evas_object_geometry_get(obj, &x, &y, &w, &h); + evas_object_geometry_get(toolkit_evas_h->img_tbm, &x, &y, &w, &h); rotation = ecore_wl_window_rotation_get(window); if (x >= 0 && x < window_w && @@ -196,7 +249,7 @@ static void __obj_update_visibility(void *data, Evas *e, Evas_Object *obj, void return; } - if (__obj_is_visible(obj, toolkit_evas_h)) + if (__obj_is_visible(toolkit_evas_h)) __set_visibility(toolkit_evas_h, VISIBILITY_TYPE_UNOBSCURED); else __set_visibility(toolkit_evas_h, VISIBILITY_TYPE_FULLY_OBSCURED); @@ -390,25 +443,6 @@ static void __rs_cb_resize(void *data, Evas *e, Evas_Object *obj, void *event_in __obj_update_visibility(data, e, obj, event_info); } -static void __clear_img_tbm(screen_connector_toolkit_evas_h toolkit_evas_h) -{ - if (toolkit_evas_h->img_tbm == NULL) - return; - - g_hash_table_remove(toolkit_evas_h->type_h->toolkit_table, toolkit_evas_h->img_tbm); - evas_object_del(toolkit_evas_h->img_tbm); - toolkit_evas_h->img_tbm = NULL; -} - -static void __clear_img_file(screen_connector_toolkit_evas_h toolkit_evas_h) -{ - if (toolkit_evas_h->img_file == NULL) - return; - - evas_object_del(toolkit_evas_h->img_file); - toolkit_evas_h->img_file = NULL; -} - static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, struct wl_buffer *tbm, int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys, const char *appid, const char *instance_id, const int pid, void *data) @@ -455,11 +489,13 @@ static void __toolkit_update_cb(struct tizen_remote_surface *trs, uint32_t type, __rs_cb_resize, toolkit_evas_h); /* Store toolkit_evas_h */ - g_hash_table_insert(toolkit_evas_h->type_h->toolkit_table, toolkit_evas_h->img_tbm, toolkit_evas_h); + g_hash_table_insert(toolkit_evas_h->type_h->toolkit_table, strdup(instance_id), toolkit_evas_h); /* Set data to use in accessibility */ snprintf(plug_id, sizeof(plug_id), "%s:%d", instance_id, pid); evas_object_data_set(toolkit_evas_h->img_tbm, "___PLUGID", strdup(plug_id)); + + evas_object_data_set(toolkit_evas_h->img_tbm, SC_TOOLKIT_HANDLE_TAG, toolkit_evas_h); evas_object_event_callback_add(toolkit_evas_h->img_tbm, EVAS_CALLBACK_MOVE, __obj_update_visibility, toolkit_evas_h); } @@ -538,25 +574,6 @@ static void __toolkit_added_cb(const char *appid, const char *instance_id, const { } -static void __free_toolkit_evas_h(screen_connector_toolkit_evas_h toolkit_evas_h) -{ - if (!toolkit_evas_h) - return; - - if (toolkit_evas_h->toolkit_h) - screen_connector_toolkit_remove(toolkit_evas_h->toolkit_h); - - __clear_img_file(toolkit_evas_h); - __clear_img_tbm(toolkit_evas_h); - - if (toolkit_evas_h->ops) { - free(toolkit_evas_h->ops); - toolkit_evas_h->ops = NULL; - } - - free(toolkit_evas_h); -} - static void __toolkit_removed_cb(const char *appid, const char *instance_id, const int pid, void *data) { screen_connector_toolkit_evas_h toolkit_evas_h; @@ -569,20 +586,18 @@ static void __toolkit_removed_cb(const char *appid, const char *instance_id, con return; } - if (toolkit_evas_h->type_h->toolkit_table != NULL && toolkit_evas_h->img_tbm != NULL) { - g_hash_table_remove(toolkit_evas_h->type_h->toolkit_table, toolkit_evas_h->img_tbm); - - /* Remove data used in accessibility */ + if (toolkit_evas_h->img_tbm != NULL) { plug_id = evas_object_data_del(toolkit_evas_h->img_tbm, "___PLUGID"); - free(plug_id); - } + if (plug_id) + free(plug_id); - if (toolkit_evas_h->img_tbm != NULL) + evas_object_data_del(toolkit_evas_h->img_tbm, SC_TOOLKIT_HANDLE_TAG); toolkit_evas_h->ops->removed_cb(appid, instance_id, pid, toolkit_evas_h->img_tbm, toolkit_evas_h->data); - else if (toolkit_evas_h->img_file != NULL) + } else if (toolkit_evas_h->img_file != NULL) { toolkit_evas_h->ops->removed_cb(appid, instance_id, pid, toolkit_evas_h->img_file, toolkit_evas_h->data); + } - __free_toolkit_evas_h(toolkit_evas_h); + g_hash_table_remove(toolkit_evas_h->type_h->toolkit_table, instance_id); } EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(screen_connector_toolkit_evas_ops *ops, char *id, @@ -628,10 +643,18 @@ EXPORT_API screen_connector_toolkit_evas_h screen_connector_toolkit_evas_add(scr EXPORT_API int screen_connector_toolkit_evas_remove(screen_connector_toolkit_evas_h handle) { + const char *instance_id; + if (handle == NULL) return -1; - __free_toolkit_evas_h(handle); + instance_id = screen_connector_toolkit_get_instance_id(handle->toolkit_h); + if (instance_id == NULL) { + LOGE("Null instance_id"); + return -1; + } + g_hash_table_remove(handle->type_h->toolkit_table, instance_id); + return 0; } @@ -643,7 +666,6 @@ EXPORT_API int screen_connector_toolkit_evas_update(const char *appid, const cha static void __send_visibility(gpointer key, gpointer value, gpointer user_data) { screen_connector_toolkit_evas_h toolkit_evas_h = (screen_connector_toolkit_evas_h)value; - Evas_Object *evas_obj = (Evas_Object *)key; unsigned int event = GPOINTER_TO_INT(user_data); int ret; visibility_type type; @@ -651,7 +673,7 @@ static void __send_visibility(gpointer key, gpointer value, gpointer user_data) if (toolkit_evas_h->freeze) return; - if (!__obj_is_visible(evas_obj, toolkit_evas_h)) + if (!__obj_is_visible(toolkit_evas_h)) return; if (event) @@ -661,7 +683,7 @@ static void __send_visibility(gpointer key, gpointer value, gpointer user_data) ret = __set_visibility(toolkit_evas_h, type); if (ret == -1) - LOGE("failed to set object visibility set %p to %d", evas_obj, type); + LOGE("failed to set object visibility set %p to %d", toolkit_evas_h->img_tbm, type); } static Eina_Bool __visibility_cb(void *data, int type, void *event) @@ -712,21 +734,10 @@ EXPORT_API int screen_connector_toolkit_evas_stop_visibility_notify(void) screen_connector_toolkit_evas_h __find_toolkit_evas_h(Evas_Object *obj) { screen_connector_toolkit_evas_h toolkit_evas_h; - GHashTableIter iter; - gpointer key, value; - screen_connector_type_evas_h cur_type; - g_hash_table_iter_init(&iter, __type_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - cur_type = (screen_connector_type_evas_h)value; - if (cur_type->toolkit_table) { - toolkit_evas_h = g_hash_table_lookup(cur_type->toolkit_table, obj); - if (toolkit_evas_h != NULL) - return toolkit_evas_h; - } - } + toolkit_evas_h = evas_object_data_get(obj, SC_TOOLKIT_HANDLE_TAG); - return NULL; + return toolkit_evas_h; } EXPORT_API int screen_connector_toolkit_evas_freeze_visibility(Evas_Object *obj, visibility_type type)