From: Radoslaw Cybulski Date: Thu, 9 Nov 2017 10:21:12 +0000 (+0100) Subject: Fix embedding after stoping and restarting at-spi X-Git-Tag: submit/tizen/20171214.113147~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=888c1b13fdec0b752533ff24737657ff0e7e7cb5;p=platform%2Fupstream%2Felementary.git Fix embedding after stoping and restarting at-spi Restarting at-spi doesnt remove __widget_proxy property from smart object. As a result, when proxy is queried for children, it will return previous at-spi object, which is already defuncted. This patch adds checking for defunct flag on object and reinitialization, if such object is found in __widget_proxy. Change-Id: I7fe7c494738f223ced81629f78397b8ca21d43a5 --- diff --git a/src/lib/elm_atspi_bridge.c b/src/lib/elm_atspi_bridge.c index ef2674b7e..fbb154947 100644 --- a/src/lib/elm_atspi_bridge.c +++ b/src/lib/elm_atspi_bridge.c @@ -120,6 +120,9 @@ typedef struct _Elm_Atspi_Bridge_Data Eina_Hash *event_hash; Eina_List *socket_queue; Eina_List *plug_queue; + // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted + Eina_List *connected_plugs_sockets; + // Eina_Bool connected : 1; // TIZEN_ONLY(20160802): do not handle events if the window is not activated Eina_Bool window_activated : 1; @@ -186,6 +189,10 @@ static void _object_get_bus_name_and_path(Eo *bridge, const Eo *obj, const char static Eo *_calculate_navigable_accessible_at_point(Eo *bridge, Eo *root, Eina_Bool coord_type, int x, int y); static Eo *_calculate_neighbor(Eo *bridge, Eo *root, Eo *current, Eina_Bool forward, int search_mode); // +// TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted +Eo *plug_type_proxy_get(Eo *obj, Evas_Object *widget); +// + typedef struct { const Eo_Event_Description *desc; @@ -1054,9 +1061,10 @@ _accessible_get_navigable_at_point(const Eldbus_Service_Interface *iface EINA_UN EINA_LIST_FOREACH(wd->subobjs, l, widget) { - Eo *proxy; + // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted + Eo *proxy = plug_type_proxy_get(parent, widget); + // - proxy = evas_object_data_get(widget, "__widget_proxy"); if (proxy) { int px, py, pw, ph; @@ -6105,6 +6113,13 @@ static void _a11y_connection_shutdown(Eo *bridge) { ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); + + // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted + Eo *socket; + EINA_LIST_FREE(pd->connected_plugs_sockets, socket) + evas_object_data_set(socket, "__proxy_invalid", (void*)1); + // + Eldbus_Pending *pending; if (pd->connected) @@ -6678,11 +6693,24 @@ obj_err: return NULL; } +static Eina_Bool _from_list_remove(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Eina_List **list = data; + *list = eina_list_remove(*list, obj); + return EINA_TRUE; +} + EOLIAN void _elm_atspi_bridge_eo_base_destructor(Eo *obj, Elm_Atspi_Bridge_Data *pd) { _a11y_connection_shutdown(obj); + Eo *socket_elem = NULL; + EINA_LIST_FREE(pd->connected_plugs_sockets, socket_elem) + { + eo_do(socket_elem, eo_event_callback_del(EO_EV_DEL, _from_list_remove, &pd->connected_plugs_sockets)); + } + if (pd->bus_obj) eldbus_object_unref(pd->bus_obj); if (pd->session_bus) eldbus_connection_unref(pd->session_bus); if (pd->root) eo_del(pd->root); @@ -6869,6 +6897,14 @@ _plug_address_discover(Eldbus_Connection *conn, Eo *proxy, const char *svc_bus, eldbus_object_send(dobj, msg, _socket_addr_get_cb, proxy, 100); } +static void _add_plug_or_socket_to_connected_list_in_bridge(Eo *plug_or_socket) +{ + Eo *bridge = _elm_atspi_bridge_get(); + ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); + pd->connected_plugs_sockets = eina_list_append(pd->connected_plugs_sockets, plug_or_socket); + eo_do(plug_or_socket, eo_event_callback_add(EO_EV_DEL, _from_list_remove, &pd->connected_plugs_sockets)); +} + static void _plug_connect(Eldbus_Connection *conn, Eo *proxy) { const char *bus, *path; @@ -6876,6 +6912,7 @@ static void _plug_connect(Eldbus_Connection *conn, Eo *proxy) eo_do(proxy, bus = eo_key_data_get("__svc_bus")); eo_do(proxy, path = eo_key_data_get("__svc_path")); + _add_plug_or_socket_to_connected_list_in_bridge(proxy); if (bus && path) { _plug_address_discover(conn, proxy, bus, path); @@ -6895,13 +6932,6 @@ static void _plug_connect(Eldbus_Connection *conn, Eo *proxy) return; } -static Eina_Bool _from_list_remove(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Eina_List **list = data; - *list = eina_list_remove(*list, obj); - return EINA_TRUE; -} - EAPI void elm_atspi_bridge_utils_proxy_connect(Eo *proxy) { Eo *bridge = _elm_atspi_bridge_get(); @@ -7039,6 +7069,8 @@ static void _socket_ifc_create(Eldbus_Connection *conn, Eo *proxy) pd->interfaces.socket = eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &socket_iface_desc); // + + _add_plug_or_socket_to_connected_list_in_bridge(proxy); } EAPI void elm_atspi_bridge_utils_proxy_listen(Eo *proxy) diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c index 9f66aa866..d89062bda 100644 --- a/src/lib/elm_widget.c +++ b/src/lib/elm_widget.c @@ -6880,8 +6880,8 @@ _on_proxy_connected_cb(void *data, Eo *obj, const Eo_Event_Description *desc EIN // TIZEN ONLY - END //TIZEN_ONLY(20170621) handle atspi proxy connection at runtime -static Eo * -_plug_type_proxy_get(Eo *obj, Evas_Object *widget) +Eo * +plug_type_proxy_get(Eo *obj, Evas_Object *widget) { Eo *proxy = NULL; const char *plug_id; @@ -6893,7 +6893,13 @@ _plug_type_proxy_get(Eo *obj, Evas_Object *widget) eo_do_super(obj, MY_CLASS, elm_interface_atspi_accessible_attribute_append("___PlugID", plug_id)); proxy = evas_object_data_get(widget, "__widget_proxy"); - if (proxy) return proxy; + // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted + if (proxy) + { + if (!evas_object_data_get(proxy, "__proxy_invalid")) return proxy; + evas_object_data_del(widget, "__widget_proxy"); + } + // if (_elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum)) { @@ -6923,8 +6929,7 @@ elm_widget_atspi_plug_type_proxy_get(Evas_Object *obj) Eo *proxy = NULL; EINA_LIST_FOREACH(wd->subobjs, l, widget) { - if (evas_object_data_get(widget, "___PLUGID")) - proxy = _plug_type_proxy_get(obj, widget); + proxy = plug_type_proxy_get(obj, widget); if (proxy) break; } return proxy; @@ -6968,7 +6973,7 @@ _elm_widget_elm_interface_atspi_accessible_children_get(Eo *obj, Elm_Widget_Smar /* This assumes that only one proxy exists in obj */ if (!proxy) { - proxy = _plug_type_proxy_get(obj, widget); + proxy = plug_type_proxy_get(obj, widget); if (proxy) { accs = eina_list_append(accs, proxy); @@ -7551,6 +7556,11 @@ _accessible_at_point_top_down_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSE proxy = evas_object_data_get(smart_parent, "__widget_proxy"); if (proxy) { + // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted + Eo *parent; + eo_do(smart_parent, parent = elm_interface_atspi_accessible_parent_get()); + proxy = plug_type_proxy_get(parent, smart_parent); + // evas_object_geometry_get(smart_parent, &px, &py, &pw, &ph); if (x >= px && x <= px + pw && y >= py && y <= py +ph) { diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c index d3e42bd05..3219202f4 100644 --- a/src/lib/elm_win.c +++ b/src/lib/elm_win.c @@ -1861,13 +1861,20 @@ _atspi_socket_proxy_listen(Eo * obj) if ((plug_id) != NULL) { char *svcname, *svcnum; - if (!sd->socket_proxy && _elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum)) + // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted + if (_elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum)) { + if (sd->socket_proxy) + { + if (!evas_object_data_get(sd->socket_proxy, "__proxy_invalid")) return; + eo_unref(sd->socket_proxy); + } sd->socket_proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, atoi(svcnum), ELM_ATSPI_PROXY_TYPE_SOCKET); elm_atspi_bridge_utils_proxy_listen(sd->socket_proxy); free(svcname); free(svcnum); } + // } } //