Fix embedding after stoping and restarting at-spi 19/159519/5
authorRadoslaw Cybulski <r.cybulski@partner.samsung.com>
Thu, 9 Nov 2017 10:21:12 +0000 (11:21 +0100)
committerRadoslaw Cybulski <r.cybulski@partner.samsung.com>
Tue, 5 Dec 2017 12:28:37 +0000 (12:28 +0000)
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

src/lib/elm_atspi_bridge.c
src/lib/elm_widget.c
src/lib/elm_win.c

index ef2674b..fbb1549 100644 (file)
@@ -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)
index 9f66aa8..d89062b 100644 (file)
@@ -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)
                           {
index d3e42bd..3219202 100644 (file)
@@ -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);
           }
+        //
      }
 }
 //