[atspi] make atspi proxy work for more than two sockets created in one process
authorShinwoo Kim <cinoo.kim@samsung.com>
Mon, 14 Nov 2016 01:19:57 +0000 (10:19 +0900)
committerWonki Kim <wonki_.kim@samsung.com>
Mon, 2 Jan 2017 05:37:02 +0000 (14:37 +0900)
Conflicts:
src/lib/elm_atspi_bridge.c

Change-Id: I8299a49cb8a98ddc1229ba3e4b87a903c24f4fb3

src/lib/elm_atspi_bridge.c
src/lib/elm_atspi_proxy.c
src/lib/elm_atspi_proxy.eo
src/lib/elm_interface_atspi_component.c
src/lib/elm_interface_atspi_component.eo

index ee6b173..7c3252c 100644 (file)
@@ -117,9 +117,6 @@ typedef struct _Elm_Atspi_Bridge_Data
    Eina_Hash *event_hash;
    Eina_List *socket_queue;
    Eina_List *plug_queue;
-   // TIZEN_ONLY(20160705) - enable atspi_proxy to work
-   Evas_Point socket_offset;
-   //
    Eina_Bool connected : 1;
    // TIZEN_ONLY(20160802): do not handle events if the window is not activated
    Eina_Bool window_activated : 1;
@@ -2098,17 +2095,18 @@ _socket_embedded(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus
 
 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
 static Eldbus_Message *
-_socket_offset_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
+_socket_offset_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
 {
    int x, y;
-   Eo *bridge = _elm_atspi_bridge_get();
-   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
+   Eo *parent;
+   Eo *obj = eldbus_service_object_data_get(iface, "_atspi_obj");
+   eo_do(obj, parent = eo_parent_get());
+   Evas_Object *top = elm_object_top_widget_get(parent);
 
    if (!eldbus_message_arguments_get(msg, "ii", &x, &y))
      return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
 
-   pd->socket_offset.x = x;
-   pd->socket_offset.y = y;
+   eo_do(top, elm_interface_atspi_component_socket_offset_set(x, y));
 
    return eldbus_message_method_return_new(msg);
 }
@@ -3494,8 +3492,13 @@ _component_get_accessible_at_point(const Eldbus_Service_Interface *iface EINA_UN
      return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
 
    // TIZEN_ONLY(20160705) - enable atspi_proxy to work
-   x = x - pd->socket_offset.x;
-   y = y - pd->socket_offset.y;
+   Evas_Object *top = elm_object_top_widget_get(obj);
+   int sx = 0;
+   int sy = 0;
+   eo_do(top, elm_interface_atspi_component_socket_offset_get(&sx, &sy));
+
+   x = x - sx;
+   y = y - sy;
    //
 
    ret = eldbus_message_method_return_new(msg);
@@ -5104,7 +5107,7 @@ static const Eldbus_Property proxy_properties[] = {
 };
 
 static const Eldbus_Service_Interface_Desc _proxy_iface_desc = {
-   ELM_ATSPI_DBUS_INTERFACE_PROXY, NULL, NULL, proxy_properties, NULL, NULL
+   ELM_ATSPI_DBUS_INTERFACE_PROXY, socket_methods, NULL, proxy_properties, NULL, NULL
 };
 
 static void _embedded_reply_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
@@ -5157,44 +5160,6 @@ fail:
    eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
 }
 
-// TIZEN_ONLY(20160705) - enable atspi_proxy to work
-static void
-_offset_set_reply_cb(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
-{
-   const char *err, *txt;
-
-   if (eldbus_message_error_get(msg, &err, &txt))
-     {
-        ERR("AT-SPI: SetOffset method call failed: %s %s", err, txt);
-        return;
-     }
-}
-
-static void
-_plug_offset_set_send(Eldbus_Connection *conn, const char *bus, const char *path, int x, int y)
-{
-   Eldbus_Message *msg = NULL;
-
-   msg = eldbus_message_method_call_new(bus, path, ATSPI_DBUS_INTERFACE_SOCKET, "SetOffset");
-   if (!msg) goto fail;
-
-   if (!eldbus_message_arguments_append(msg, "i", x))
-     goto fail;
-
-   if (!eldbus_message_arguments_append(msg, "i", y))
-     goto fail;
-
-   if (!eldbus_connection_send(conn, msg, _offset_set_reply_cb, NULL, 100))
-     goto fail;
-
-   return;
-
-fail:
-   ERR("AT-SPI: Unable to send SetOffset request.");
-   if (msg) eldbus_message_unref(msg);
-}
-//
-
 static void _socket_addr_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
 {
    Eo *proxy = data;
@@ -5212,7 +5177,7 @@ static void _socket_addr_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pe
    if (eldbus_message_error_get(msg, &err, &txt))
      {
         ERR("Unable to connect to socket: %s %s", err, txt);
-        goto fail;
+        goto retry;
      }
 
    iter = eldbus_message_iter_get(msg);
@@ -5242,6 +5207,10 @@ static void _socket_addr_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pe
 
 fail:
    eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
+   return;
+
+retry:
+   eo_do(proxy, elm_obj_atspi_proxy_address_get_retry_timer_add());
 }
 
 static void
@@ -5525,6 +5494,18 @@ elm_atspi_bridge_utils_say(const char* text,
 //
 
 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
+static void
+_offset_set_reply_cb(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
+{
+   const char *err, *txt;
+
+   if (eldbus_message_error_get(msg, &err, &txt))
+     {
+        ERR("AT-SPI: SetOffset method call failed: %s %s", err, txt);
+        return;
+     }
+}
+
 void elm_atspi_bridge_utils_proxy_offset_set(Eo *proxy, int x, int y)
 {
    const char *bus, *path;
@@ -5535,13 +5516,28 @@ void elm_atspi_bridge_utils_proxy_offset_set(Eo *proxy, int x, int y)
 
    if (!pd->a11y_bus) return;
 
-   eo_do(proxy, elm_obj_atspi_proxy_address_get(&bus, &path));
-   if (!bus || !path)
-     {
-        ERR("AT-SPI: Elm_Atspi_Proxy bus or path not set.");
-        return;
-     }
-   _plug_offset_set_send(pd->a11y_bus, bus, path, x, y);
+   eo_do(proxy, bus = eo_key_data_get("__svc_bus"));
+   eo_do(proxy, path = eo_key_data_get("__svc_path"));
+
+   Eldbus_Message *msg = NULL;
+
+   msg = eldbus_message_method_call_new(bus, path, ELM_ATSPI_DBUS_INTERFACE_PROXY, "SetOffset");
+   if (!msg) goto fail;
+
+   if (!eldbus_message_arguments_append(msg, "i", x))
+     goto fail;
+
+   if (!eldbus_message_arguments_append(msg, "i", y))
+     goto fail;
+
+   if (!eldbus_connection_send(pd->a11y_bus, msg, _offset_set_reply_cb, NULL, 100))
+     goto fail;
+
+   return;
+
+fail:
+   ERR("AT-SPI: Unable to send SetOffset request.");
+   if (msg) eldbus_message_unref(msg);
 }
 //
 //TIZEN_ONLY(20161027) - Export elm_atspi_bridge_utils_is_screen_reader_enabled
index 3aac6d5..86aef38 100644 (file)
@@ -18,11 +18,67 @@ struct _Elm_Atspi_Proxy_Data
    Elm_Atspi_Proxy_Type type;
    const char *bus;
    const char *path;
+   Ecore_Timer *retry_timer;
+   int retry_count;
 };
 
+#define ELM_ATSPI_PROXY_RETRY_TIME 1.0
+#define ELM_ATSPI_PROXY_RETRY_COUNT_LIMIT 5
+static Eina_Bool
+_retry_timer_cb(void *data)
+{
+   Eo *proxy;
+
+   proxy = data;
+   Elm_Atspi_Proxy_Data *_pd = eo_data_scope_get(proxy, ELM_ATSPI_PROXY_CLASS);
+
+   if (_pd->bus && _pd->path)
+     {
+        DBG("Address allocated: %s, %s", _pd->bus, _pd->path);
+        _pd->retry_count = 0;
+        _pd->retry_timer = NULL;
+        return ECORE_CALLBACK_CANCEL;
+     }
+
+   if (_pd->retry_count < ELM_ATSPI_PROXY_RETRY_COUNT_LIMIT)
+     {
+        elm_atspi_bridge_utils_proxy_connect(proxy);
+        _pd->retry_count++;
+        return ECORE_CALLBACK_RENEW;
+     }
+
+   _pd->retry_count = 0;
+   _pd->retry_timer = NULL;
+   return ECORE_CALLBACK_CANCEL;
+}
+
+EOLIAN static void
+_elm_atspi_proxy_address_get_retry_timer_add(Eo *obj, Elm_Atspi_Proxy_Data *_pd)
+{
+   if (_pd->type != ELM_ATSPI_PROXY_TYPE_PLUG)
+     {
+        ERR("Proxy type is not ELM_ATSPI_PROXY_TYPE_PLUG");
+        return;
+     }
+
+   if (_pd->retry_timer)
+     {
+        DBG("Retry timer is already added");
+        return;
+     }
+
+   _pd->retry_timer = ecore_timer_add(ELM_ATSPI_PROXY_RETRY_TIME,
+                                      _retry_timer_cb, obj);
+}
+
 EOLIAN static void
 _elm_atspi_proxy_eo_base_destructor(Eo *obj, Elm_Atspi_Proxy_Data *_pd)
 {
+   if (_pd->retry_timer)
+     {
+        ecore_timer_del(_pd->retry_timer);
+        _pd->retry_timer = NULL;
+     }
    if (_pd->type == ELM_ATSPI_PROXY_TYPE_SOCKET)
       _socket_list = eina_list_remove(_socket_list, obj);
 
index 3abe159..76b4c75 100644 (file)
@@ -26,6 +26,8 @@ class Elm_Atspi_Proxy (Elm.Widget)
             ret:Elm_Atspi_Proxy_Type;
          }
       }
+      address_get_retry_timer_add {
+      }
    }
    constructors {
       .constructor;
index c1a460d..e5387a6 100644 (file)
@@ -9,15 +9,23 @@
 
 #include "elm_priv.h"
 
+//TIZEN_ONLY(20161114): make atspi proxy work for more than two sockets created in one process
+struct _Elm_Interface_Atspi_Component_Data
+{
+   Evas_Point socket_offset;
+};
+
+typedef struct _Elm_Interface_Atspi_Component_Data Elm_Interface_Atspi_Component_Data;
+//
 
 EOLIAN static void
-_elm_interface_atspi_component_position_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, Eina_Bool type, int *x, int *y)
+_elm_interface_atspi_component_position_get(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED, Eina_Bool type, int *x, int *y)
 {
    eo_do(obj, elm_interface_atspi_component_extents_get(type, x, y, NULL, NULL));
 }
 
 EOLIAN static Eina_Bool
-_elm_interface_atspi_component_position_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, Eina_Bool type, int x, int y)
+_elm_interface_atspi_component_position_set(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED, Eina_Bool type, int x, int y)
 {
    Eina_Bool ret = EINA_FALSE;
    int c_w, c_h;
@@ -29,7 +37,7 @@ _elm_interface_atspi_component_position_set(Eo *obj EINA_UNUSED, void *_pd EINA_
 }
 
 EOLIAN static Eina_Bool
-_elm_interface_atspi_component_size_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, int w, int h)
+_elm_interface_atspi_component_size_set(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED, int w, int h)
 {
    Eina_Bool ret;
    int c_x = 0, c_y = 0;
@@ -40,13 +48,13 @@ _elm_interface_atspi_component_size_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUS
 }
 
 EOLIAN static void
-_elm_interface_atspi_component_size_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, int *w, int *h)
+_elm_interface_atspi_component_size_get(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED, int *w, int *h)
 {
    eo_do(obj, elm_interface_atspi_component_extents_get(EINA_FALSE, NULL,  NULL, w, h));
 }
 
 EOLIAN static Eina_Bool
-_elm_interface_atspi_component_contains(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, Eina_Bool type, int x, int y)
+_elm_interface_atspi_component_contains(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED, Eina_Bool type, int x, int y)
 {
    int w_x = 0, w_y = 0, w_w = 0, w_h = 0;
 
@@ -58,7 +66,7 @@ _elm_interface_atspi_component_contains(Eo *obj EINA_UNUSED, void *_pd EINA_UNUS
 }
 
 EOLIAN static double
-_elm_interface_atspi_component_alpha_get(Eo *obj, void *_pd EINA_UNUSED)
+_elm_interface_atspi_component_alpha_get(Eo *obj, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED)
 {
    int alpha;
 
@@ -67,7 +75,7 @@ _elm_interface_atspi_component_alpha_get(Eo *obj, void *_pd EINA_UNUSED)
 }
 
 EOLIAN static Eo *
-_elm_interface_atspi_component_accessible_at_point_get(Eo *obj, void *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
+_elm_interface_atspi_component_accessible_at_point_get(Eo *obj, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
 {
    Eina_List *l, *children;
    Eo *ret = NULL, *child;
@@ -99,7 +107,7 @@ _elm_interface_atspi_component_accessible_at_point_get(Eo *obj, void *_pd EINA_U
 }
 
 EOLIAN static void
-_elm_interface_atspi_component_extents_get(Eo *obj, void *_pd EINA_UNUSED, Eina_Bool screen_coords, int *x, int *y, int *w, int *h)
+_elm_interface_atspi_component_extents_get(Eo *obj, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int *x, int *y, int *w, int *h)
 {
    int ee_x, ee_y;
 
@@ -115,7 +123,7 @@ _elm_interface_atspi_component_extents_get(Eo *obj, void *_pd EINA_UNUSED, Eina_
 }
 
 EOLIAN static Eina_Bool
-_elm_interface_atspi_component_extents_set(Eo *obj, void *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y, int w, int h)
+_elm_interface_atspi_component_extents_set(Eo *obj, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y, int w, int h)
 {
    int wx, wy;
 
@@ -136,20 +144,20 @@ _elm_interface_atspi_component_extents_set(Eo *obj, void *_pd EINA_UNUSED, Eina_
 }
 
 EOLIAN static int
-_elm_interface_atspi_component_layer_get(Eo *obj, void *_pd EINA_UNUSED)
+_elm_interface_atspi_component_layer_get(Eo *obj, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED)
 {
    return evas_object_layer_get(obj);
 }
 
 EOLIAN static int
-_elm_interface_atspi_component_z_order_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED)
+_elm_interface_atspi_component_z_order_get(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED)
 {
    // Currently not used.
    return 0;
 }
 
 EOLIAN static Eina_Bool
-_elm_interface_atspi_component_focus_grab(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED)
+_elm_interface_atspi_component_focus_grab(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED)
 {
    evas_object_focus_set(obj, EINA_TRUE);
    return evas_object_focus_get(obj);
@@ -157,7 +165,7 @@ _elm_interface_atspi_component_focus_grab(Eo *obj EINA_UNUSED, void *_pd EINA_UN
 
 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
 EOLIAN static Eina_Bool
-_elm_interface_atspi_component_highlight_grab(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED)
+_elm_interface_atspi_component_highlight_grab(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED)
 {
    WRN("The %s object does not implement the \"component_highlight_grab\" function.",
        eo_class_name_get(eo_class_get(obj)));
@@ -165,12 +173,28 @@ _elm_interface_atspi_component_highlight_grab(Eo *obj EINA_UNUSED, void *_pd EIN
 }
 
 EOLIAN static Eina_Bool
-_elm_interface_atspi_component_highlight_clear(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED)
+_elm_interface_atspi_component_highlight_clear(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd EINA_UNUSED)
 {
    WRN("The %s object does not implement the \"component_highlight_clear\" function.",
        eo_class_name_get(eo_class_get(obj)));
    return EINA_FALSE;
 }
 //
+//TIZEN_ONLY(20161114): make atspi proxy work for more than two sockets created in one process
+EOLIAN static void
+_elm_interface_atspi_component_socket_offset_set(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd, int x, int y)
+{
+   _pd->socket_offset.x = x;
+   _pd->socket_offset.y = y;
+}
+
+EOLIAN static void
+_elm_interface_atspi_component_socket_offset_get(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Component_Data *_pd, int *x, int *y)
+{
+   *x = _pd->socket_offset.x;
+   *y = _pd->socket_offset.y;
+}
+//
+
 
 #include "elm_interface_atspi_component.eo.c"
index e126d38..91950a0 100644 (file)
@@ -2,7 +2,9 @@ mixin Elm_Interface_Atspi_Component ()
 {
    legacy_prefix: null;
    eo_prefix: elm_interface_atspi_component;
-   data: null;
+   //TIZEN_ONLY(20161114): make atspi proxy work for more than two sockets created in one process
+   data: Elm_Interface_Atspi_Component_Data;
+   //
    methods {
       @property size @protected {
          set {
@@ -116,5 +118,19 @@ mixin Elm_Interface_Atspi_Component ()
          return: bool;
       }
       //
+      //TIZEN_ONLY(20161114): make atspi proxy work for more than two sockets created in one process
+      @property socket_offset @protected {
+         set {
+            [[Sets position of socket offset.]]
+         }
+         get {
+            [[Gets position of socket offset.]]
+         }
+         values {
+            x: int;
+            y: int;
+         }
+      }
+      //
    }
 }