summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Stanislawski <l.stanislaws@samsung.com>2017-06-07 11:19:27 +0200
committerLukasz Stanislawski <l.stanislaws@samsung.com>2017-06-07 12:04:21 +0200
commit88dc4e9ee97b332f43afc37ed22dc2a4dfe242e9 (patch)
treefeebc5665f3e3cd8cd86024a5d88de5f173f2cbf
parentf3abe0b0f4dd87fc05e7fa4c4ae55c7ff75d24a0 (diff)
elementary: refactor initialization process
Change-Id: I32e6ece138c8425052adb858a093c708a2147274
-rw-r--r--src/lib/elementary/elm_atspi_bridge.c449
1 files changed, 272 insertions, 177 deletions
diff --git a/src/lib/elementary/elm_atspi_bridge.c b/src/lib/elementary/elm_atspi_bridge.c
index f7c8263970..0517ec8701 100644
--- a/src/lib/elementary/elm_atspi_bridge.c
+++ b/src/lib/elementary/elm_atspi_bridge.c
@@ -68,7 +68,6 @@ typedef struct _Elm_Atspi_Bridge_Data
68 Eldbus_Connection *a11y_bus; 68 Eldbus_Connection *a11y_bus;
69 Eina_List *reemited_events; 69 Eina_List *reemited_events;
70 Eina_Hash *cache; 70 Eina_Hash *cache;
71 Eldbus_Service_Interface *cache_interface;
72 Eldbus_Signal_Handler *register_hdl; 71 Eldbus_Signal_Handler *register_hdl;
73 Eldbus_Signal_Handler *unregister_hdl; 72 Eldbus_Signal_Handler *unregister_hdl;
74 unsigned long object_broadcast_mask; 73 unsigned long object_broadcast_mask;
@@ -82,6 +81,7 @@ typedef struct _Elm_Atspi_Bridge_Data
82 int id; 81 int id;
83 Eina_Hash *state_hash; 82 Eina_Hash *state_hash;
84 struct { 83 struct {
84 Eldbus_Service_Interface *cache;
85 Eldbus_Service_Interface *accessible; 85 Eldbus_Service_Interface *accessible;
86 Eldbus_Service_Interface *application; 86 Eldbus_Service_Interface *application;
87 Eldbus_Service_Interface *action; 87 Eldbus_Service_Interface *action;
@@ -93,6 +93,9 @@ typedef struct _Elm_Atspi_Bridge_Data
93 Eldbus_Service_Interface *text; 93 Eldbus_Service_Interface *text;
94 Eldbus_Service_Interface *value; 94 Eldbus_Service_Interface *value;
95 } interfaces; 95 } interfaces;
96 Eldbus_Pending *connect_request;
97 Eldbus_Pending *stack_status_request;
98 Eldbus_Proxy *status_proxy;
96 Eina_Bool connected : 1; 99 Eina_Bool connected : 1;
97} Elm_Atspi_Bridge_Data; 100} Elm_Atspi_Bridge_Data;
98 101
@@ -110,7 +113,6 @@ struct collection_match_rule {
110}; 113};
111 114
112static Eo *_instance; 115static Eo *_instance;
113static int _init_count = 0;
114 116
115// Object Event handlers 117// Object Event handlers
116static void _state_changed_event_handle(Elm_Atspi_Bridge *data, const Elm_Accessible_Event *event); 118static void _state_changed_event_handle(Elm_Atspi_Bridge *data, const Elm_Accessible_Event *event);
@@ -135,6 +137,14 @@ static const char * _path_from_object(const Eo *eo);
135static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *ifc, const Eldbus_Signal *signal, const char *minor, unsigned int det1, unsigned int det2, const char *variant_sig, ...); 137static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *ifc, const Eldbus_Signal *signal, const char *minor, unsigned int det1, unsigned int det2, const char *variant_sig, ...);
136static Eo * _bridge_object_from_path(Eo *bridge, const char *path); 138static Eo * _bridge_object_from_path(Eo *bridge, const char *path);
137static void _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter *iter, const Eo *obj); 139static void _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter *iter, const Eo *obj);
140static void _bridge_disconnect(Elm_Atspi_Bridge *bridge);
141static void _bridge_connect(Elm_Atspi_Bridge *bridge);
142static void _bridge_enabled_set(Elm_Atspi_Bridge *bridge, Eina_Bool value);
143static void _bridge_on_disconnected(Elm_Atspi_Bridge *bridge);
144static void _bridge_on_connected(Elm_Atspi_Bridge *bridge);
145static void _bridge_pending_del(Elm_Atspi_Bridge *bridge, Eldbus_Pending *pending);
146static void _bridge_pending_add(Elm_Atspi_Bridge *bridge, Eldbus_Pending *pending);
147static void _bridge_pending_cancel_all(Elm_Atspi_Bridge *bridge);
138 148
139// utility functions 149// utility functions
140static void _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj); 150static void _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj);
@@ -3559,7 +3569,7 @@ static const Eldbus_Service_Interface_Desc component_iface_desc = {
3559}; 3569};
3560 3570
3561static void 3571static void
3562_on_elm_atspi_bridge_app_register(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED) 3572_on_bridge_app_register(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
3563{ 3573{
3564 const char *errname, *errmsg; 3574 const char *errname, *errmsg;
3565 3575
@@ -3572,7 +3582,7 @@ _on_elm_atspi_bridge_app_register(void *data EINA_UNUSED, const Eldbus_Message *
3572} 3582}
3573 3583
3574EAPI Eina_Bool 3584EAPI Eina_Bool
3575_elm_atspi_bridge_app_register(Eo *bridge) 3585_bridge_app_register(Eo *bridge)
3576{ 3586{
3577 Eo *root; 3587 Eo *root;
3578 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE); 3588 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
@@ -3585,13 +3595,14 @@ _elm_atspi_bridge_app_register(Eo *bridge)
3585 3595
3586 root = elm_interface_atspi_accessible_root_get(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN); 3596 root = elm_interface_atspi_accessible_root_get(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN);
3587 _bridge_iter_object_reference_append(bridge, iter, root); 3597 _bridge_iter_object_reference_append(bridge, iter, root);
3588 eldbus_connection_send(pd->a11y_bus, message, _on_elm_atspi_bridge_app_register, NULL, -1); 3598 _bridge_object_register(bridge, root);
3599 eldbus_connection_send(pd->a11y_bus, message, _on_bridge_app_register, NULL, -1);
3589 3600
3590 return EINA_TRUE; 3601 return EINA_TRUE;
3591} 3602}
3592 3603
3593EAPI Eina_Bool 3604EAPI Eina_Bool
3594_elm_atspi_bridge_app_unregister(Eo *bridge) 3605_bridge_app_unregister(Eo *bridge)
3595{ 3606{
3596 Eo *root; 3607 Eo *root;
3597 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE); 3608 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
@@ -3611,14 +3622,6 @@ _elm_atspi_bridge_app_unregister(Eo *bridge)
3611} 3622}
3612 3623
3613static void 3624static void
3614_cache_register(Eo *obj)
3615{
3616 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd);
3617 pd->cache_interface = eldbus_service_interface_register(pd->a11y_bus, CACHE_INTERFACE_PATH, &cache_iface_desc);
3618 eldbus_service_object_data_set(pd->cache_interface, ELM_ATSPI_BRIDGE_CLASS_NAME, obj);
3619}
3620
3621static void
3622_set_broadcast_flag(const char *event, Eo *bridge) 3625_set_broadcast_flag(const char *event, Eo *bridge)
3623{ 3626{
3624 char **tokens; 3627 char **tokens;
@@ -3714,7 +3717,7 @@ _registered_listeners_get(void *data, const Eldbus_Message *msg, Eldbus_Pending
3714{ 3717{
3715 const char *event, *bus; 3718 const char *event, *bus;
3716 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd); 3719 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
3717 pd->pending_requests = eina_list_remove(pd->pending_requests, pending); 3720 _bridge_pending_del(data, pending);
3718 3721
3719 DBG("Updating registered ATSPI signals list."); 3722 DBG("Updating registered ATSPI signals list.");
3720 pd->object_broadcast_mask = 0; 3723 pd->object_broadcast_mask = 0;
@@ -3754,7 +3757,7 @@ _registered_events_list_update(Eo *bridge)
3754 3757
3755 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "GetRegisteredEvents"); 3758 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "GetRegisteredEvents");
3756 p = eldbus_connection_send(pd->a11y_bus, msg, _registered_listeners_get, bridge, -1); 3759 p = eldbus_connection_send(pd->a11y_bus, msg, _registered_listeners_get, bridge, -1);
3757 pd->pending_requests = eina_list_append(pd->pending_requests, p); 3760 _bridge_pending_add(bridge, p);
3758} 3761}
3759 3762
3760static void 3763static void
@@ -4110,7 +4113,7 @@ _text_selection_event_handle(Elm_Atspi_Bridge *data, const Elm_Accessible_Event
4110} 4113}
4111 4114
4112static void 4115static void
4113_event_handlers_register(Eo *bridge) 4116_bridge_event_handlers_register(Eo *bridge)
4114{ 4117{
4115 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4118 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4116 4119
@@ -4153,11 +4156,11 @@ _object_added_event_handle(Elm_Atspi_Bridge *data, const Elm_Accessible_Event *e
4153 4156
4154 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd); 4157 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
4155 4158
4156 sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_ACCESSIBLE_ADDED); 4159 sig = eldbus_service_signal_new(pd->interfaces.cache, ATSPI_OBJECT_ACCESSIBLE_ADDED);
4157 iter = eldbus_message_iter_get(sig); 4160 iter = eldbus_message_iter_get(sig);
4158 _cache_item_reference_append_cb(data, event->object, iter); 4161 _cache_item_reference_append_cb(data, event->object, iter);
4159 4162
4160 eldbus_service_signal_send(pd->cache_interface, sig); 4163 eldbus_service_signal_send(pd->interfaces.cache, sig);
4161} 4164}
4162 4165
4163static void 4166static void
@@ -4169,14 +4172,14 @@ _object_del_event_handle(Elm_Atspi_Bridge *data, const Elm_Accessible_Event *eve
4169 4172
4170 _bridge_object_unregister(data, event->object); 4173 _bridge_object_unregister(data, event->object);
4171 4174
4172 sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_ACCESSIBLE_REMOVED); 4175 sig = eldbus_service_signal_new(pd->interfaces.cache, ATSPI_OBJECT_ACCESSIBLE_REMOVED);
4173 Eldbus_Message_Iter *iter = eldbus_message_iter_get(sig); 4176 Eldbus_Message_Iter *iter = eldbus_message_iter_get(sig);
4174 _bridge_iter_object_reference_append(data, iter, event->object); 4177 _bridge_iter_object_reference_append(data, iter, event->object);
4175 eldbus_service_signal_send(pd->cache_interface, sig); 4178 eldbus_service_signal_send(pd->interfaces.cache, sig);
4176} 4179}
4177 4180
4178static void 4181static void
4179_interfaces_unregister(Eo *bridge) 4182_bridge_interfaces_unregister(Eo *bridge)
4180{ 4183{
4181 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4184 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4182 4185
@@ -4195,61 +4198,17 @@ _interfaces_unregister(Eo *bridge)
4195 INTERFACE_SAFE_FREE(pd->interfaces.selection); 4198 INTERFACE_SAFE_FREE(pd->interfaces.selection);
4196 INTERFACE_SAFE_FREE(pd->interfaces.text); 4199 INTERFACE_SAFE_FREE(pd->interfaces.text);
4197 INTERFACE_SAFE_FREE(pd->interfaces.value); 4200 INTERFACE_SAFE_FREE(pd->interfaces.value);
4201 INTERFACE_SAFE_FREE(pd->interfaces.cache);
4198#undef INTERFACE_SAFE_FREE 4202#undef INTERFACE_SAFE_FREE
4199} 4203}
4200 4204
4201static void 4205static void
4202_a11y_connection_shutdown(Eo *bridge) 4206_bridge_interfaces_register(Eo *bridge)
4203{
4204 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4205 Eldbus_Pending *pending;
4206
4207 if (pd->connected)
4208 _elm_atspi_bridge_app_unregister(bridge);
4209
4210 if (pd->cache)
4211 eina_hash_free(pd->cache);
4212 pd->cache = NULL;
4213
4214 if (pd->cache_interface)
4215 eldbus_service_object_unregister(pd->cache_interface);
4216 pd->cache_interface = NULL;
4217
4218 _interfaces_unregister(bridge);
4219
4220 if (pd->key_flr) ecore_event_filter_del(pd->key_flr);
4221 pd->key_flr = NULL;
4222
4223 if (pd->register_hdl) eldbus_signal_handler_del(pd->register_hdl);
4224 pd->register_hdl = NULL;
4225
4226 if (pd->unregister_hdl) eldbus_signal_handler_del(pd->unregister_hdl);
4227 pd->unregister_hdl = NULL;
4228
4229 EINA_LIST_FREE(pd->pending_requests, pending)
4230 eldbus_pending_cancel(pending);
4231 pd->pending_requests = NULL;
4232
4233 if (pd->a11y_bus) eldbus_connection_unref(pd->a11y_bus);
4234 pd->a11y_bus = NULL;
4235
4236 if (pd->state_hash) eina_hash_free(pd->state_hash);
4237 pd->state_hash = NULL;
4238
4239 efl_event_callback_legacy_call(bridge, ELM_ATSPI_BRIDGE_EVENT_DISCONNECTED, NULL);
4240 pd->connected = EINA_FALSE;
4241}
4242
4243static void _disconnect_cb(void *data, Eldbus_Connection *conn EINA_UNUSED, void *event_info EINA_UNUSED)
4244{
4245 _a11y_connection_shutdown(data);
4246}
4247
4248static void
4249_interfaces_register(Eo *bridge)
4250{ 4207{
4251 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4208 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4252 4209
4210 pd->interfaces.cache = eldbus_service_interface_register(pd->a11y_bus, CACHE_INTERFACE_PATH, &cache_iface_desc);
4211 eldbus_service_object_data_set(pd->interfaces.cache, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
4253 pd->interfaces.accessible = 4212 pd->interfaces.accessible =
4254 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &accessible_iface_desc); 4213 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &accessible_iface_desc);
4255 eldbus_service_object_data_set(pd->interfaces.accessible, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge); 4214 eldbus_service_object_data_set(pd->interfaces.accessible, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
@@ -4342,96 +4301,51 @@ _elm_atspi_bridge_elm_interface_accessible_observer_on_event(Elm_Atspi_Bridge *b
4342} 4301}
4343 4302
4344static void 4303static void
4345_a11y_bus_initialize(Eo *obj, const char *socket_addr) 4304_bridge_on_connection_lost(void *data, Eldbus_Connection *conn EINA_UNUSED, void *event_info EINA_UNUSED)
4346{ 4305{
4347 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd); 4306 Elm_Atspi_Bridge *bridge = data;
4348 4307 _bridge_disconnect(bridge);
4349 pd->a11y_bus = eldbus_private_address_connection_get(socket_addr);
4350 if (!pd->a11y_bus)
4351 return;
4352
4353 eldbus_connection_event_callback_add(pd->a11y_bus, ELDBUS_CONNECTION_EVENT_DISCONNECTED, _disconnect_cb, obj);
4354
4355 // init data structures
4356 pd->cache = eina_hash_pointer_new(NULL);
4357 pd->state_hash = _elm_atspi_state_hash_build();
4358
4359 // dbus init
4360 _cache_register(obj);
4361 _interfaces_register(obj);
4362 _event_handlers_register(obj);
4363 _elm_atspi_bridge_app_register(obj);
4364} 4308}
4365 4309
4366static void 4310static void
4367_a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending) 4311_bridge_connection_init(Elm_Atspi_Bridge *bridge, const char *address)
4368{ 4312{
4369 const char *errname, *errmsg, *sock_addr = NULL; 4313 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4370 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
4371
4372 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
4373
4374 if (eldbus_message_error_get(msg, &errname, &errmsg))
4375 {
4376 ERR("%s %s", errname, errmsg);
4377 return;
4378 }
4379 4314
4380 if (!eldbus_message_arguments_get(msg, "s", &sock_addr) || !sock_addr) 4315 pd->a11y_bus = eldbus_private_address_connection_get(address);
4316 if (pd->a11y_bus)
4381 { 4317 {
4382 ERR("Could not get A11Y Bus socket address."); 4318 pd->connected = EINA_TRUE;
4383 return; 4319 _bridge_on_connected(bridge);
4320 eldbus_connection_event_callback_add(pd->a11y_bus, ELDBUS_CONNECTION_EVENT_DISCONNECTED,
4321 _bridge_on_connection_lost, bridge);
4322 efl_event_callback_call(bridge, ELM_ATSPI_BRIDGE_EVENT_CONNECTED, NULL);
4384 } 4323 }
4385 4324 else
4386 _a11y_bus_initialize((Eo*)data, sock_addr); 4325 ERR("Unable to establish a11y dbus connection");
4387}
4388
4389static void _a11y_connection_init(Eo *bridge)
4390{
4391 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4392 Eina_Bool is_connected;
4393
4394 is_connected = elm_obj_atspi_bridge_connected_get(bridge);
4395
4396 if (is_connected) return;
4397
4398 Eldbus_Message *m = eldbus_object_method_call_new(pd->bus_obj, A11Y_DBUS_INTERFACE, "GetAddress");
4399 Eldbus_Pending *p = eldbus_object_send(pd->bus_obj, m, _a11y_bus_address_get, bridge, 100);
4400
4401 if (p)
4402 pd->pending_requests = eina_list_append(pd->pending_requests, p);
4403} 4326}
4404 4327
4405static void 4328static void
4406_screen_reader_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending) 4329_bridge_a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
4407{ 4330{
4408 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd); 4331 const char *errname, *errmsg, *sock_addr = NULL;
4409 const char *errname, *errmsg; 4332 Elm_Atspi_Bridge *bridge = data;
4410 Eina_Bool is_enabled; 4333 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4411 Eldbus_Message_Iter *variant;
4412 4334
4413 pd->pending_requests = eina_list_remove(pd->pending_requests, pending); 4335 pd->connect_request = NULL;
4414 4336
4415 if (eldbus_message_error_get(msg, &errname, &errmsg)) 4337 if (eldbus_message_error_get(msg, &errname, &errmsg))
4416 { 4338 {
4417 WRN("%s %s", errname, errmsg); 4339 ERR("%s %s", errname, errmsg);
4418 return;
4419 }
4420 if (!eldbus_message_arguments_get(msg, "v", &variant))
4421 {
4422 ERR("'ScreenReaderEnabled' not packed into variant.");
4423 return; 4340 return;
4424 } 4341 }
4425 if (!eldbus_message_iter_arguments_get(variant, "b", &is_enabled)) 4342
4343 if (!eldbus_message_arguments_get(msg, "s", &sock_addr) || !sock_addr)
4426 { 4344 {
4427 ERR("Could not get 'ScreenReaderEnabled' boolean property"); 4345 ERR("Could not get A11Y Bus socket address.");
4428 return; 4346 return;
4429 } 4347 }
4430 4348 _bridge_connection_init(bridge, sock_addr);
4431 if (is_enabled)
4432 _a11y_connection_init(data);
4433 else
4434 DBG("AT-SPI2 stack not enabled.");
4435} 4349}
4436 4350
4437static void _bridge_object_register(Eo *bridge, Eo *obj) 4351static void _bridge_object_register(Eo *bridge, Eo *obj)
@@ -4463,11 +4377,10 @@ static void _bridge_object_register(Eo *bridge, Eo *obj)
4463void 4377void
4464_elm_atspi_bridge_init(void) 4378_elm_atspi_bridge_init(void)
4465{ 4379{
4466 if (!_init_count) 4380 if (!_instance)
4467 { 4381 {
4468 _instance = efl_add(ELM_ATSPI_BRIDGE_CLASS, NULL); 4382 _instance = efl_add(ELM_ATSPI_BRIDGE_CLASS, NULL);
4469 elm_interface_atspi_accessible_event_observer_add(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, _instance); 4383 elm_interface_atspi_accessible_event_observer_add(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, _instance);
4470 _init_count = 1;
4471 } 4384 }
4472} 4385}
4473 4386
@@ -4480,11 +4393,10 @@ _elm_atspi_bridge_get(void)
4480void 4393void
4481_elm_atspi_bridge_shutdown(void) 4394_elm_atspi_bridge_shutdown(void)
4482{ 4395{
4483 if (_init_count) 4396 if (_instance)
4484 { 4397 {
4485 elm_interface_atspi_accessible_event_observer_del(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, _instance); 4398 elm_interface_atspi_accessible_event_observer_del(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, _instance);
4486 efl_del(_instance); 4399 efl_del(_instance);
4487 _init_count = 0;
4488 } 4400 }
4489} 4401}
4490 4402
@@ -4644,11 +4556,12 @@ _elm_atspi_bridge_connected_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
4644} 4556}
4645 4557
4646static void 4558static void
4647_properties_changed_cb(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event) 4559_bridge_status_proxy_properties_changed(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event)
4648{ 4560{
4649 Eldbus_Proxy_Event_Property_Changed *ev = event; 4561 Eldbus_Proxy_Event_Property_Changed *ev = event;
4650 Eo *bridge = data; 4562 Eo *bridge = data;
4651 Eina_Bool val; 4563 Eina_Bool val;
4564
4652 const char *ifc = eldbus_proxy_interface_get(ev->proxy); 4565 const char *ifc = eldbus_proxy_interface_get(ev->proxy);
4653 if (ev->name && !strcmp(ev->name, "ScreenReaderEnabled" ) && 4566 if (ev->name && !strcmp(ev->name, "ScreenReaderEnabled" ) &&
4654 ifc && !strcmp(A11Y_DBUS_STATUS_INTERFACE, ifc)) 4567 ifc && !strcmp(A11Y_DBUS_STATUS_INTERFACE, ifc))
@@ -4658,69 +4571,251 @@ _properties_changed_cb(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event)
4658 ERR("Unable to get ScreenReaderEnabled property value"); 4571 ERR("Unable to get ScreenReaderEnabled property value");
4659 return; 4572 return;
4660 } 4573 }
4661 if (val) 4574 _bridge_enabled_set(bridge, val);
4662 _a11y_connection_init(bridge);
4663 else
4664 _a11y_connection_shutdown(bridge);
4665 } 4575 }
4666} 4576}
4667 4577
4668EOLIAN Efl_Object* 4578static void
4669_elm_atspi_bridge_efl_object_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd) 4579_bridge_a11y_stack_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
4580{
4581 Elm_Atspi_Bridge *bridge = data;
4582 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4583 const char *errname, *errmsg;
4584 Eina_Bool is_enabled;
4585 Eldbus_Message_Iter *variant;
4586
4587 pd->stack_status_request = NULL;
4588
4589 if (eldbus_message_error_get(msg, &errname, &errmsg))
4590 {
4591 WRN("%s %s", errname, errmsg);
4592 return;
4593 }
4594 if (!eldbus_message_arguments_get(msg, "v", &variant))
4595 {
4596 ERR("'ScreenReaderEnabled' not packed into variant.");
4597 return;
4598 }
4599 if (!eldbus_message_iter_arguments_get(variant, "b", &is_enabled))
4600 {
4601 ERR("Could not get 'ScreenReaderEnabled' boolean property");
4602 return;
4603 }
4604
4605 _bridge_enabled_set(bridge, is_enabled);
4606}
4607
4608static Eina_Bool
4609_bridge_platform_a11y_status_monitor_init(Elm_Atspi_Bridge *bridge)
4670{ 4610{
4671 Eldbus_Proxy *proxy; 4611 Eldbus_Proxy *proxy;
4672 Eldbus_Pending *req; 4612 Eldbus_Pending *req;
4613 Eldbus_Object *obj;
4673 4614
4674 efl_constructor(efl_super(obj, ELM_ATSPI_BRIDGE_CLASS)); 4615 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
4675 4616
4676 elm_need_eldbus(); 4617 if (pd->bus_obj) return EINA_TRUE;
4677 4618
4678 if (!(pd->session_bus = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION))) 4619 if (!(obj = eldbus_object_get(pd->session_bus, A11Y_DBUS_NAME, A11Y_DBUS_PATH)))
4679 {
4680 ERR("Unable to connect to Session Bus");
4681 return NULL;
4682 }
4683 if (!(pd->bus_obj = eldbus_object_get(pd->session_bus, A11Y_DBUS_NAME, A11Y_DBUS_PATH)))
4684 { 4620 {
4685 ERR("Could not get /org/a11y/bus object"); 4621 ERR("Could not get /org/a11y/bus object");
4686 goto obj_err; 4622 return EINA_FALSE;
4687 } 4623 }
4688 if (!(proxy = eldbus_proxy_get(pd->bus_obj, A11Y_DBUS_STATUS_INTERFACE))) 4624 if (!(proxy = eldbus_proxy_get(obj, A11Y_DBUS_STATUS_INTERFACE)))
4689 { 4625 {
4690 ERR("Could not get proxy object for %s interface", A11Y_DBUS_STATUS_INTERFACE); 4626 ERR("Could not get proxy object for %s interface", A11Y_DBUS_STATUS_INTERFACE);
4691 goto proxy_err; 4627 eldbus_object_unref(obj);
4628 return EINA_FALSE;
4692 } 4629 }
4693 if (!(req = eldbus_proxy_property_get(proxy, "ScreenReaderEnabled", _screen_reader_enabled_get, obj))) 4630 if (!(req = eldbus_proxy_property_get(proxy, "ScreenReaderEnabled",
4631 _bridge_a11y_stack_enabled_get, bridge)))
4694 { 4632 {
4695 ERR("Could not send PropertyGet request"); 4633 ERR("Could not send PropertyGet request");
4696 goto proxy_err; 4634 eldbus_object_unref(obj);
4635 return EINA_FALSE;
4697 } 4636 }
4698 pd->pending_requests = eina_list_append(pd->pending_requests, req); 4637 pd->bus_obj = obj;
4638 pd->stack_status_request = req;
4639 pd->status_proxy = proxy;
4699 4640
4700 eldbus_proxy_properties_monitor(proxy, EINA_TRUE); 4641 eldbus_proxy_properties_monitor(proxy, EINA_TRUE);
4701 eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED, 4642 eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
4702 _properties_changed_cb, obj); 4643 _bridge_status_proxy_properties_changed, bridge);
4644 return EINA_TRUE;
4645}
4703 4646
4704 return obj; 4647EOLIAN Efl_Object*
4648_elm_atspi_bridge_efl_object_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
4649{
4650 efl_constructor(efl_super(obj, ELM_ATSPI_BRIDGE_CLASS));
4705 4651
4706proxy_err: 4652 elm_need_eldbus();
4707 eldbus_object_unref(pd->bus_obj); 4653
4708 pd->bus_obj = NULL; 4654 if (!(pd->session_bus = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION)))
4709obj_err: 4655 {
4710 eldbus_connection_unref(pd->session_bus); 4656 ERR("Unable to connect to Session Bus");
4711 pd->session_bus = NULL; 4657 return NULL;
4712 return NULL; 4658 }
4659
4660 if (!_bridge_platform_a11y_status_monitor_init(obj))
4661 {
4662 ERR("Unable to get platform's a11y status.");
4663 eldbus_connection_unref(pd->session_bus);
4664 return NULL;
4665 }
4666
4667 return obj;
4713} 4668}
4714 4669
4715EOLIAN void 4670static void
4716_elm_atspi_bridge_efl_object_destructor(Eo *obj, Elm_Atspi_Bridge_Data *pd) 4671_bridge_platform_a11y_status_monitor_shutdown(Elm_Atspi_Bridge *bridge)
4717{ 4672{
4718 _a11y_connection_shutdown(obj); 4673 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4719 4674
4675 if (pd->stack_status_request) eldbus_pending_cancel(pd->stack_status_request);
4676 if (pd->status_proxy)
4677 {
4678 eldbus_proxy_event_callback_del(pd->status_proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
4679 _bridge_status_proxy_properties_changed, bridge);
4680 eldbus_proxy_properties_monitor(pd->status_proxy, EINA_FALSE);
4681 eldbus_proxy_unref(pd->status_proxy);
4682 }
4720 if (pd->bus_obj) eldbus_object_unref(pd->bus_obj); 4683 if (pd->bus_obj) eldbus_object_unref(pd->bus_obj);
4721 if (pd->session_bus) eldbus_connection_unref(pd->session_bus); 4684}
4722 4685
4686EOLIAN void
4687_elm_atspi_bridge_efl_object_destructor(Eo *obj, Elm_Atspi_Bridge_Data *pd EINA_UNUSED)
4688{
4689 _bridge_disconnect(obj);
4690 _bridge_platform_a11y_status_monitor_shutdown(obj);
4691 eldbus_connection_unref(pd->session_bus);
4723 efl_destructor(efl_super(obj, ELM_ATSPI_BRIDGE_CLASS)); 4692 efl_destructor(efl_super(obj, ELM_ATSPI_BRIDGE_CLASS));
4724} 4693}
4725 4694
4695static void
4696_bridge_connect(Elm_Atspi_Bridge *bridge)
4697{
4698 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4699
4700 if (pd->connected || pd->connect_request)
4701 return;
4702
4703 Eldbus_Message *msg =
4704 eldbus_message_method_call_new(A11Y_DBUS_NAME, A11Y_DBUS_PATH, A11Y_DBUS_INTERFACE, "GetAddress");
4705 if (!msg)
4706 {
4707 ERR("eldbus_object_method_call_new failed");
4708 return;
4709 }
4710 pd->connect_request = eldbus_connection_send(pd->session_bus, msg,
4711 _bridge_a11y_bus_address_get, bridge, 100);
4712 if (!pd->connect_request)
4713 {
4714 ERR("eldbus_object_send failed");
4715 eldbus_message_unref(msg);
4716 return;
4717 }
4718}
4719
4720static void
4721_bridge_disconnect(Elm_Atspi_Bridge *bridge)
4722{
4723 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4724
4725 if (pd->connect_request)
4726 {
4727 eldbus_pending_cancel(pd->connect_request);
4728 pd->connect_request = NULL;
4729 }
4730
4731 if (!pd->connected)
4732 return;
4733
4734 pd->connected = EINA_FALSE;
4735 _bridge_on_disconnected(bridge);
4736 eldbus_connection_unref(pd->a11y_bus);
4737 efl_event_callback_call(bridge, ELM_ATSPI_BRIDGE_EVENT_DISCONNECTED, NULL);
4738}
4739
4740static void
4741_bridge_pending_add(Elm_Atspi_Bridge *bridge, Eldbus_Pending *pending)
4742{
4743 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4744 pd->pending_requests = eina_list_append(pd->pending_requests, pending);
4745}
4746
4747static void
4748_bridge_pending_del(Elm_Atspi_Bridge *bridge, Eldbus_Pending *pending)
4749{
4750 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4751 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
4752}
4753
4754static void
4755_bridge_pending_cancel_all(Elm_Atspi_Bridge *bridge)
4756{
4757 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4758 Eldbus_Pending *pending;
4759
4760 EINA_LIST_FREE(pd->pending_requests, pending)
4761 eldbus_pending_cancel(pending);
4762 pd->pending_requests = NULL;
4763}
4764
4765static void
4766_bridge_event_handlers_unregister(Eo *bridge)
4767{
4768 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4769 eldbus_signal_handler_del(pd->register_hdl);
4770 eldbus_signal_handler_del(pd->unregister_hdl);
4771 ecore_event_filter_del(pd->key_flr);
4772}
4773
4774/**
4775 * Function called when bridge disconnects from a11y bus.
4776 * the pd->a11y_bus variable still contains valid dbus-connection,
4777 * which will be deleted after function returns.
4778 */
4779static void
4780_bridge_on_disconnected(Elm_Atspi_Bridge *bridge)
4781{
4782 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4783
4784 _bridge_pending_cancel_all(bridge);
4785
4786 _bridge_app_unregister(bridge);
4787 _bridge_event_handlers_unregister(bridge);
4788 _bridge_interfaces_unregister(bridge);
4789
4790 eina_hash_free(pd->cache);
4791 eina_hash_free(pd->state_hash);
4792}
4793
4794/**
4795 * Function called when bridge connects to a11y bus.
4796 * the pd->a11y_bus variable contains valid dbus-connection.
4797 */
4798static void
4799_bridge_on_connected(Elm_Atspi_Bridge *bridge)
4800{
4801 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4802
4803 pd->cache = eina_hash_pointer_new(NULL);
4804 pd->state_hash = _elm_atspi_state_hash_build();
4805
4806 _bridge_interfaces_register(bridge);
4807 _bridge_event_handlers_register(bridge);
4808 _bridge_app_register(bridge);
4809}
4810
4811
4812static void
4813_bridge_enabled_set(Elm_Atspi_Bridge *bridge, Eina_Bool value)
4814{
4815 if (value)
4816 _bridge_connect(bridge);
4817 else
4818 _bridge_disconnect(bridge);
4819}
4820
4726#include "elm_atspi_bridge.eo.c" 4821#include "elm_atspi_bridge.eo.c"