summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Stanislawski <l.stanislaws@samsung.com>2017-12-19 23:58:36 +0100
committerLukasz Stanislawski <lukasz.stanislawski@gmail.com>2017-12-19 23:58:36 +0100
commit949a8bb4293356d37281e5a55ccab9a817677ada (patch)
tree2760bfad586497fabcf3d1517f3cb451409c6050
parent453361cac12d587cedb9854a0747b75a598e160e (diff)
elm: refactor initialization process
Summary: Change-Id: I0d4723718509e2f5f775f398d58d4d1231a10dee Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D5684
-rw-r--r--src/lib/elementary/elm_atspi_bridge.c201
1 files changed, 107 insertions, 94 deletions
diff --git a/src/lib/elementary/elm_atspi_bridge.c b/src/lib/elementary/elm_atspi_bridge.c
index 09ea6a1693..2de63c7487 100644
--- a/src/lib/elementary/elm_atspi_bridge.c
+++ b/src/lib/elementary/elm_atspi_bridge.c
@@ -26,6 +26,8 @@
26#define A11Y_DBUS_PATH "/org/a11y/bus" 26#define A11Y_DBUS_PATH "/org/a11y/bus"
27#define A11Y_DBUS_INTERFACE "org.a11y.Bus" 27#define A11Y_DBUS_INTERFACE "org.a11y.Bus"
28#define A11Y_DBUS_STATUS_INTERFACE "org.a11y.Status" 28#define A11Y_DBUS_STATUS_INTERFACE "org.a11y.Status"
29#define A11Y_DBUS_SCREEN_READER_ENABLED_PROPERTY_NAME "ScreenReaderEnabled"
30#define A11Y_DBUS_A11Y_STACK_ENABLING_PROPERTY_NAME A11Y_DBUS_SCREEN_READER_ENABLED_PROPERTY_NAME
29#define ATSPI_DBUS_INTERFACE_EVENT_WINDOW "org.a11y.atspi.Event.Window" 31#define ATSPI_DBUS_INTERFACE_EVENT_WINDOW "org.a11y.atspi.Event.Window"
30 32
31#define CACHE_ITEM_SIGNATURE "((so)(so)(so)a(so)assusau)" 33#define CACHE_ITEM_SIGNATURE "((so)(so)(so)a(so)assusau)"
@@ -67,7 +69,12 @@ typedef struct Key_Event_Info {
67typedef struct _Elm_Atspi_Bridge_Data 69typedef struct _Elm_Atspi_Bridge_Data
68{ 70{
69 Eldbus_Connection *session_bus; 71 Eldbus_Connection *session_bus;
72 Eldbus_Proxy *status_proxy;
73 Eldbus_Object *bus_obj;
74 Eldbus_Pending *get_address_pending;
75
70 Eldbus_Connection *a11y_bus; 76 Eldbus_Connection *a11y_bus;
77
71 Eina_List *reemited_events; 78 Eina_List *reemited_events;
72 Eina_Hash *cache; 79 Eina_Hash *cache;
73 Eldbus_Service_Interface *cache_interface; 80 Eldbus_Service_Interface *cache_interface;
@@ -79,7 +86,6 @@ typedef struct _Elm_Atspi_Bridge_Data
79 unsigned long long object_state_broadcast_mask; 86 unsigned long long object_state_broadcast_mask;
80 unsigned long long window_signal_broadcast_mask; 87 unsigned long long window_signal_broadcast_mask;
81 Ecore_Event_Filter *key_flr; 88 Ecore_Event_Filter *key_flr;
82 Eldbus_Object *bus_obj;
83 Eina_List *pending_requests; 89 Eina_List *pending_requests;
84 int id; 90 int id;
85 Eina_Hash *state_hash; 91 Eina_Hash *state_hash;
@@ -3789,10 +3795,6 @@ _registered_listeners_get(void *data, const Eldbus_Message *msg, Eldbus_Pending
3789 ERR("Cannot get bus and event from registered listener"); 3795 ERR("Cannot get bus and event from registered listener");
3790 else _set_broadcast_flag(event, data); 3796 else _set_broadcast_flag(event, data);
3791 } 3797 }
3792
3793 if (!pd->connected)
3794 efl_event_callback_legacy_call(data, ELM_ATSPI_BRIDGE_EVENT_CONNECTED, NULL);
3795 pd->connected = EINA_TRUE;
3796} 3798}
3797 3799
3798static void 3800static void
@@ -4255,16 +4257,21 @@ _interfaces_unregister(Eo *bridge)
4255} 4257}
4256 4258
4257static void 4259static void
4258_a11y_connection_shutdown(Eo *bridge) 4260_elm_atspi_bridge_disconnect(Eo *bridge)
4259{ 4261{
4260 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4262 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4261 Eldbus_Pending *pending; 4263 Eldbus_Pending *pending;
4262 4264
4265 if (pd->get_address_pending)
4266 eldbus_pending_cancel(pd->get_address_pending);
4267 pd->get_address_pending = NULL;
4268
4263 if (pd->connected) 4269 if (pd->connected)
4264 _elm_atspi_bridge_app_unregister(bridge); 4270 _elm_atspi_bridge_app_unregister(bridge);
4265 4271
4266 if (pd->cache) 4272 if (pd->cache)
4267 eina_hash_free(pd->cache); 4273 eina_hash_free(pd->cache);
4274
4268 pd->cache = NULL; 4275 pd->cache = NULL;
4269 4276
4270 if (pd->cache_interface) 4277 if (pd->cache_interface)
@@ -4304,7 +4311,7 @@ _a11y_connection_shutdown(Eo *bridge)
4304 4311
4305static void _disconnect_cb(void *data, Eldbus_Connection *conn EINA_UNUSED, void *event_info EINA_UNUSED) 4312static void _disconnect_cb(void *data, Eldbus_Connection *conn EINA_UNUSED, void *event_info EINA_UNUSED)
4306{ 4313{
4307 _a11y_connection_shutdown(data); 4314 _elm_atspi_bridge_disconnect(data);
4308} 4315}
4309 4316
4310static void 4317static void
@@ -4365,16 +4372,10 @@ _bridge_accessible_event_dispatch(void *data, const Efl_Event *event)
4365} 4372}
4366 4373
4367static void 4374static void
4368_a11y_bus_initialize(Eo *obj, const char *socket_addr) 4375_a11y_bus_initialize(Eo *obj)
4369{ 4376{
4370 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd); 4377 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd);
4371 4378
4372 pd->a11y_bus = eldbus_private_address_connection_get(socket_addr);
4373 if (!pd->a11y_bus)
4374 return;
4375
4376 eldbus_connection_event_callback_add(pd->a11y_bus, ELDBUS_CONNECTION_EVENT_DISCONNECTED, _disconnect_cb, obj);
4377
4378 // init data structures 4379 // init data structures
4379 pd->cache = eina_hash_pointer_new(NULL); 4380 pd->cache = eina_hash_pointer_new(NULL);
4380 pd->state_hash = _elm_atspi_state_hash_build(); 4381 pd->state_hash = _elm_atspi_state_hash_build();
@@ -4390,13 +4391,14 @@ _a11y_bus_initialize(Eo *obj, const char *socket_addr)
4390 pd->event_hdlr = efl_access_event_handler_add(EFL_ACCESS_MIXIN, _bridge_accessible_event_dispatch, obj); 4391 pd->event_hdlr = efl_access_event_handler_add(EFL_ACCESS_MIXIN, _bridge_accessible_event_dispatch, obj);
4391} 4392}
4392 4393
4394// 2nd step of initialization process. Make real connection with accessibility bus.
4393static void 4395static void
4394_a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending) 4396_a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
4395{ 4397{
4396 const char *errname, *errmsg, *sock_addr = NULL; 4398 const char *errname, *errmsg, *sock_addr = NULL;
4397 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd); 4399 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
4398 4400
4399 pd->pending_requests = eina_list_remove(pd->pending_requests, pending); 4401 pd->get_address_pending = NULL;
4400 4402
4401 if (eldbus_message_error_get(msg, &errname, &errmsg)) 4403 if (eldbus_message_error_get(msg, &errname, &errmsg))
4402 { 4404 {
@@ -4410,55 +4412,41 @@ _a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pen
4410 return; 4412 return;
4411 } 4413 }
4412 4414
4413 _a11y_bus_initialize((Eo*)data, sock_addr); 4415 pd->a11y_bus = eldbus_private_address_connection_get(sock_addr);
4416 if (!pd->a11y_bus)
4417 return;
4418
4419 _a11y_bus_initialize((Eo*)data);
4420 eldbus_connection_event_callback_add(pd->a11y_bus, ELDBUS_CONNECTION_EVENT_DISCONNECTED, _disconnect_cb, data);
4421
4422 pd->connected = EINA_TRUE;
4414} 4423}
4415 4424
4416static void _a11y_connection_init(Eo *bridge) 4425/*
4426 * Initialize dbus connection with accessibility dbus daemon. Initialization
4427 * consists of two steps. In first address of dbus daemon is fetched
4428 * asynchronously from org.a11y.Bus interface. In second step the connection
4429 * is made and internal data of bridge get initialized.
4430 */
4431static void _elm_atspi_bridge_connect(Eo *bridge)
4417{ 4432{
4418 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4433 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4419 Eina_Bool is_connected;
4420 4434
4421 is_connected = elm_obj_atspi_bridge_connected_get(bridge); 4435 if (elm_obj_atspi_bridge_connected_get(bridge))
4422 4436 return;
4423 if (is_connected) return;
4424
4425 Eldbus_Message *m = eldbus_object_method_call_new(pd->bus_obj, A11Y_DBUS_INTERFACE, "GetAddress");
4426 Eldbus_Pending *p = eldbus_object_send(pd->bus_obj, m, _a11y_bus_address_get, bridge, 100);
4427
4428 if (p)
4429 pd->pending_requests = eina_list_append(pd->pending_requests, p);
4430}
4431 4437
4432static void 4438 if (pd->get_address_pending)
4433_screen_reader_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending) 4439 eldbus_pending_cancel(pd->get_address_pending);
4434{
4435 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
4436 const char *errname, *errmsg;
4437 Eina_Bool is_enabled;
4438 Eldbus_Message_Iter *variant;
4439 4440
4440 pd->pending_requests = eina_list_remove(pd->pending_requests, pending); 4441 Eldbus_Message *msg = eldbus_object_method_call_new(pd->bus_obj, A11Y_DBUS_INTERFACE, "GetAddress");
4442 if (!msg) return;
4441 4443
4442 if (eldbus_message_error_get(msg, &errname, &errmsg)) 4444 pd->get_address_pending = eldbus_object_send(pd->bus_obj, msg, _a11y_bus_address_get, bridge, 100);
4443 { 4445 if (!pd->get_address_pending)
4444 WRN("%s %s", errname, errmsg);
4445 return;
4446 }
4447 if (!eldbus_message_arguments_get(msg, "v", &variant))
4448 { 4446 {
4449 ERR("'ScreenReaderEnabled' not packed into variant."); 4447 eldbus_message_unref(msg);
4450 return; 4448 return;
4451 } 4449 }
4452 if (!eldbus_message_iter_arguments_get(variant, "b", &is_enabled))
4453 {
4454 ERR("Could not get 'ScreenReaderEnabled' boolean property");
4455 return;
4456 }
4457
4458 if (is_enabled)
4459 _a11y_connection_init(data);
4460 else
4461 DBG("AT-SPI2 stack not enabled.");
4462} 4450}
4463 4451
4464static void _bridge_object_register(Eo *bridge, Eo *obj) 4452static void _bridge_object_register(Eo *bridge, Eo *obj)
@@ -4659,82 +4647,107 @@ _elm_atspi_bridge_connected_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
4659 return pd->connected; 4647 return pd->connected;
4660} 4648}
4661 4649
4650static Eina_Bool
4651_proxy_get_boolean_property(Eldbus_Proxy *proxy, const char *property_name, Eina_Bool *out)
4652{
4653 Eina_Value *value;
4654 if (!proxy) return EINA_FALSE;
4655 value = eldbus_proxy_property_local_get(proxy, property_name);
4656 if (!value) return EINA_FALSE;
4657 if (eina_value_type_get(value) != EINA_VALUE_TYPE_UCHAR)
4658 return EINA_FALSE;
4659 if (!eina_value_get(value, out))
4660 return EINA_FALSE;
4661 return EINA_TRUE;
4662}
4663
4662static void 4664static void
4663_properties_changed_cb(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event) 4665_status_proxy_property_changed(void *data, Eldbus_Proxy *proxy, void *event)
4664{ 4666{
4665 Eldbus_Proxy_Event_Property_Changed *ev = event; 4667 Eldbus_Proxy_Event_Property_Changed *ev = event;
4666 Eo *bridge = data; 4668 Eo *bridge = data;
4667 Eina_Bool val; 4669 Eina_Bool enabled;
4668 const char *ifc = eldbus_proxy_interface_get(ev->proxy); 4670
4669 if (ev->name && !strcmp(ev->name, "ScreenReaderEnabled" ) && 4671 if (!ev || !ev->name || strcmp(ev->name, A11Y_DBUS_A11Y_STACK_ENABLING_PROPERTY_NAME))
4670 ifc && !strcmp(A11Y_DBUS_STATUS_INTERFACE, ifc)) 4672 return;
4673
4674 if (!_proxy_get_boolean_property(proxy, A11Y_DBUS_A11Y_STACK_ENABLING_PROPERTY_NAME, &enabled))
4671 { 4675 {
4672 if (!eina_value_get(ev->value, &val)) 4676 ERR("Failed to get " A11Y_DBUS_A11Y_STACK_ENABLING_PROPERTY_NAME " property");
4673 { 4677 return;
4674 ERR("Unable to get ScreenReaderEnabled property value");
4675 return;
4676 }
4677 if (val)
4678 _a11y_connection_init(bridge);
4679 else
4680 _a11y_connection_shutdown(bridge);
4681 } 4678 }
4679
4680 if (enabled)
4681 _elm_atspi_bridge_connect(bridge);
4682 else
4683 _elm_atspi_bridge_disconnect(bridge);
4684}
4685
4686static void
4687_status_proxy_property_loaded(void *data, Eldbus_Proxy *proxy, void *event EINA_UNUSED)
4688{
4689 Eo *bridge = data;
4690 Eina_Bool enabled;
4691
4692 if (!_proxy_get_boolean_property(proxy, A11Y_DBUS_A11Y_STACK_ENABLING_PROPERTY_NAME, &enabled))
4693 {
4694 ERR("Failed to get " A11Y_DBUS_A11Y_STACK_ENABLING_PROPERTY_NAME " property");
4695 return;
4696 }
4697
4698 if (enabled)
4699 _elm_atspi_bridge_connect(bridge);
4700 else
4701 _elm_atspi_bridge_disconnect(bridge);
4682} 4702}
4683 4703
4684EOLIAN Efl_Object* 4704EOLIAN Efl_Object*
4685_elm_atspi_bridge_efl_object_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd) 4705_elm_atspi_bridge_efl_object_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
4686{ 4706{
4687 Eldbus_Proxy *proxy;
4688 Eldbus_Pending *req;
4689
4690 efl_constructor(efl_super(obj, ELM_ATSPI_BRIDGE_CLASS)); 4707 efl_constructor(efl_super(obj, ELM_ATSPI_BRIDGE_CLASS));
4691 4708
4692 elm_need_eldbus(); 4709 elm_need_eldbus();
4693 4710
4694 if (!(pd->session_bus = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION))) 4711 pd->session_bus = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
4695 { 4712 if (!pd->session_bus)
4696 ERR("Unable to connect to Session Bus"); 4713 return NULL;
4697 return NULL; 4714
4698 } 4715 pd->bus_obj = eldbus_object_get(pd->session_bus, A11Y_DBUS_NAME, A11Y_DBUS_PATH);
4699 if (!(pd->bus_obj = eldbus_object_get(pd->session_bus, A11Y_DBUS_NAME, A11Y_DBUS_PATH))) 4716 if (!pd->bus_obj)
4700 { 4717 {
4701 ERR("Could not get /org/a11y/bus object"); 4718 ERR("Could not get " A11Y_DBUS_PATH " object");
4702 goto obj_err; 4719 goto obj_err;
4703 } 4720 }
4704 if (!(proxy = eldbus_proxy_get(pd->bus_obj, A11Y_DBUS_STATUS_INTERFACE))) 4721 pd->status_proxy = eldbus_proxy_get(pd->bus_obj, A11Y_DBUS_STATUS_INTERFACE);
4722 if (!pd->status_proxy)
4705 { 4723 {
4706 ERR("Could not get proxy object for %s interface", A11Y_DBUS_STATUS_INTERFACE); 4724 ERR("Could not get proxy object for " A11Y_DBUS_STATUS_INTERFACE " interface");
4707 goto proxy_err; 4725 goto proxy_err;
4708 } 4726 }
4709 if (!(req = eldbus_proxy_property_get(proxy, "ScreenReaderEnabled", _screen_reader_enabled_get, obj)))
4710 {
4711 ERR("Could not send PropertyGet request");
4712 goto proxy_err;
4713 }
4714 pd->pending_requests = eina_list_append(pd->pending_requests, req);
4715 4727
4716 eldbus_proxy_properties_monitor(proxy, EINA_TRUE); 4728 eldbus_proxy_event_callback_add(pd->status_proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
4717 eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED, 4729 _status_proxy_property_changed, obj);
4718 _properties_changed_cb, obj); 4730 eldbus_proxy_event_callback_add(pd->status_proxy, ELDBUS_PROXY_EVENT_PROPERTY_LOADED,
4731 _status_proxy_property_loaded, obj);
4732 eldbus_proxy_properties_monitor(pd->status_proxy, EINA_TRUE);
4719 4733
4720 return obj; 4734 return obj;
4721 4735
4722proxy_err: 4736proxy_err:
4723 eldbus_object_unref(pd->bus_obj); 4737 eldbus_object_unref(pd->bus_obj);
4724 pd->bus_obj = NULL;
4725obj_err: 4738obj_err:
4726 eldbus_connection_unref(pd->session_bus); 4739 eldbus_connection_unref(pd->session_bus);
4727 pd->session_bus = NULL;
4728 return NULL; 4740 return NULL;
4729} 4741}
4730 4742
4731EOLIAN void 4743EOLIAN void
4732_elm_atspi_bridge_efl_object_destructor(Eo *obj, Elm_Atspi_Bridge_Data *pd) 4744_elm_atspi_bridge_efl_object_destructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
4733{ 4745{
4734 _a11y_connection_shutdown(obj); 4746 _elm_atspi_bridge_disconnect(obj);
4735 4747
4736 if (pd->bus_obj) eldbus_object_unref(pd->bus_obj); 4748 eldbus_proxy_unref(pd->status_proxy);
4737 if (pd->session_bus) eldbus_connection_unref(pd->session_bus); 4749 eldbus_object_unref(pd->bus_obj);
4750 eldbus_connection_unref(pd->session_bus);
4738 4751
4739 efl_destructor(efl_super(obj, ELM_ATSPI_BRIDGE_CLASS)); 4752 efl_destructor(efl_super(obj, ELM_ATSPI_BRIDGE_CLASS));
4740} 4753}