From 7fee13e56871be0449fa26088711c99ab43129d3 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Sat, 12 Nov 2016 15:00:05 +0900 Subject: [PATCH 01/16] Build DEBUG package Change-Id: Id6ce145487550d1a5cca2e7c893b1cd4e8b59793 --- packaging/at-spi2-core.spec | 3 --- 1 file changed, 3 deletions(-) diff --git a/packaging/at-spi2-core.spec b/packaging/at-spi2-core.spec index 472f089..bdb6b7c 100644 --- a/packaging/at-spi2-core.spec +++ b/packaging/at-spi2-core.spec @@ -1,4 +1,3 @@ -%define debug_package %{nil} %bcond_with x Name: at-spi2-core @@ -86,8 +85,6 @@ find %{buildroot} -name '*.la' -or -name '*.a' | xargs rm -f %make_install %find_lang %{name} -%check - %clean rm -fr %{buildroot} -- 2.7.4 From 011b9f8e62f1b61a168f4ec7d4224952fba07805 Mon Sep 17 00:00:00 2001 From: Radoslaw Cybulski Date: Tue, 6 Dec 2016 18:34:15 +0100 Subject: [PATCH 02/16] fix for non-navigatable end call window in call-ui application, by Mr Shin-Woo Kim Change-Id: I3c6fc0163e1bacac5ea3518c181cc7ef69cec62f --- atspi/atspi-misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c index 4cf7732..fdb4e9b 100644 --- a/atspi/atspi-misc.c +++ b/atspi/atspi-misc.c @@ -387,7 +387,7 @@ handle_name_owner_changed (DBusConnection *bus, DBusMessage *message, void *user else if (app_hash) { AtspiApplication *app = g_hash_table_lookup (app_hash, old); - if (app) + if (app && name && app->bus_name && !strcmp(app->bus_name, name)) g_object_run_dispose (G_OBJECT (app)); } return DBUS_HANDLER_RESULT_HANDLED; -- 2.7.4 From f584cba35f374effd21e652c80a8bf6b72ec6911 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Tue, 13 Dec 2016 10:34:13 +0900 Subject: [PATCH 03/16] Fix SVACE issue WID164553 - name is not NULL always Change-Id: Idff718d0416e98a0556f9421f1d3c76235756ab7 --- atspi/atspi-misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c index fdb4e9b..48759ca 100644 --- a/atspi/atspi-misc.c +++ b/atspi/atspi-misc.c @@ -387,7 +387,7 @@ handle_name_owner_changed (DBusConnection *bus, DBusMessage *message, void *user else if (app_hash) { AtspiApplication *app = g_hash_table_lookup (app_hash, old); - if (app && name && app->bus_name && !strcmp(app->bus_name, name)) + if (app && app->bus_name && !strcmp(app->bus_name, name)) g_object_run_dispose (G_OBJECT (app)); } return DBUS_HANDLER_RESULT_HANDLED; -- 2.7.4 From 2658d2c2bdf3a8d50d10bb290151151652caf369 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Tue, 13 Dec 2016 19:00:35 +0900 Subject: [PATCH 04/16] at_spi2_tool: return node pointer, relation flow to/from information Do not abort even though the information is too long. It was not possilbe to get next launchpad-loader application. Change-Id: Ia7e5c6ad7a989bff3425b922ef4d80cf7667be1c --- test/at_spi2_tool.c | 54 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/test/at_spi2_tool.c b/test/at_spi2_tool.c index 7a7b9a5..b8f051f 100644 --- a/test/at_spi2_tool.c +++ b/test/at_spi2_tool.c @@ -6,7 +6,7 @@ #include #define ERROR_STATE -1 -#define SAFE_BUFFER_SIZE 255 +#define SAFE_BUFFER_SIZE 2048 #define CHECK_OUTPUT_WIDTH 42 #define MINIMAL_MODULE_WIDTH 3 #define ATTR_WIDTH 50 @@ -99,7 +99,7 @@ static char *_multiply_string(char c, unsigned number) static void _print_module_legend() { - printf("\n[[node role name],[attributes list],[x,y,width,height],[node name],[states list]]\n\n"); + printf("\n[[node],[node role name],[attributes list],[x,y,width,height],[node name],[states list][flow to node, flow from node]\n\n"); } static void _print_atspi_states_legend() @@ -277,7 +277,7 @@ static char *_get_attributes(AtspiAccessible *node) int ret = snprintf(attributes_string, ATTR_WIDTH, "(%s=%s)", (char*)attr_key, (char*)attr_value); if (ret >= ATTR_WIDTH) { fprintf(stderr, "_get_attributes: generated string is too long. Buffer overflow"); - abort(); + attributes_string[ATTR_WIDTH - 1] = '\n'; } _combine_strings(&result, attributes_string); } @@ -286,6 +286,31 @@ static char *_get_attributes(AtspiAccessible *node) return result; } +static AtspiAccessible *_get_object_in_relation(AtspiAccessible * source, AtspiRelationType search_type) +{ + GArray *relations; + AtspiAccessible *ret = NULL; + AtspiRelation *relation; + AtspiRelationType type; + int i; + if (source) { + relations = atspi_accessible_get_relation_set(source, NULL); + if (relations) { + for (i = 0; i < relations->len; i++) { + relation = g_array_index(relations, AtspiRelation *, i); + type = atspi_relation_get_relation_type(relation); + + if (type == search_type) { + ret = atspi_relation_get_target(relation, 0); + break; + } + } + g_array_free(relations, TRUE); + } + } + return ret; +} + static char *_get_info(AtspiAccessible *node, int length_limit) { if (!node) @@ -301,19 +326,22 @@ static char *_get_info(AtspiAccessible *node, int length_limit) _truncate_string(states, length_limit); char result[SAFE_BUFFER_SIZE]; - int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%s],[%s],[%s,%s,%s,%s],[%s],[%s]]", - node_role_name, - attributes, - box_size->x, - box_size->y, - box_size->width, - box_size->height, - node_name, - states); + int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%p],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%p,%p]]", + node, + node_role_name, + attributes, + box_size->x, + box_size->y, + box_size->width, + box_size->height, + node_name, + states, + _get_object_in_relation(node, ATSPI_RELATION_FLOWS_TO), + _get_object_in_relation(node, ATSPI_RELATION_FLOWS_FROM)); if (ret >= SAFE_BUFFER_SIZE) { fprintf(stderr, "_get_info: generated string is too long. Buffer overflow"); - abort(); + result[SAFE_BUFFER_SIZE - 1] = '\n'; } free(node_name); -- 2.7.4 From 582f80f5874e357d19bbbc2e5884260e7e11e04e Mon Sep 17 00:00:00 2001 From: Lukasz Wlazly Date: Fri, 16 Dec 2016 15:54:58 +0100 Subject: [PATCH 05/16] [at_spi2_tool] truncation of states string added; small refactor works Change-Id: I2b3b139ae33d575951a7faa9ff96df6e285f6a1c --- test/at_spi2_tool.c | 105 ++++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 53 deletions(-) diff --git a/test/at_spi2_tool.c b/test/at_spi2_tool.c index b8f051f..af7eb97 100644 --- a/test/at_spi2_tool.c +++ b/test/at_spi2_tool.c @@ -236,7 +236,7 @@ static Box_Size *_get_box_size(AtspiAccessible *node) return box_size; } -static char *_get_states(AtspiAccessible *node) +static char *_get_states(AtspiAccessible *node, int length_limit) { AtspiStateSet *node_state_set = atspi_accessible_get_state_set(node); GArray *states = atspi_state_set_get_states(node_state_set); @@ -256,13 +256,14 @@ static char *_get_states(AtspiAccessible *node) g_array_free(states, 0); g_object_unref(node_state_set); + _truncate_string(state_string, length_limit); + return state_string; } -static char *_get_attributes(AtspiAccessible *node) +static char *_get_attributes(AtspiAccessible *node, int length_limit) { - GHashTable *attributes = NULL; - attributes = atspi_accessible_get_attributes(node, NULL); + GHashTable *attributes = atspi_accessible_get_attributes(node, NULL); if (!attributes) return NULL; @@ -274,40 +275,41 @@ static char *_get_attributes(AtspiAccessible *node) char *result = NULL; while (g_hash_table_iter_next (&attributes_iter, &attr_key, &attr_value)) { char attributes_string[ATTR_WIDTH]; - int ret = snprintf(attributes_string, ATTR_WIDTH, "(%s=%s)", (char*)attr_key, (char*)attr_value); - if (ret >= ATTR_WIDTH) { - fprintf(stderr, "_get_attributes: generated string is too long. Buffer overflow"); - attributes_string[ATTR_WIDTH - 1] = '\n'; - } + int ret = snprintf(attributes_string, ATTR_WIDTH, "(%s=%s)", (char *)attr_key, (char *)attr_value); + if (ret >= ATTR_WIDTH) + fprintf(stderr, "\n_get_attributes: generated string is too long. Buffer overflow\n"); + _combine_strings(&result, attributes_string); } g_hash_table_unref(attributes); + _truncate_string(result, length_limit); return result; } -static AtspiAccessible *_get_object_in_relation(AtspiAccessible * source, AtspiRelationType search_type) +static AtspiAccessible *_get_object_in_relation(AtspiAccessible *source, AtspiRelationType search_type) { - GArray *relations; - AtspiAccessible *ret = NULL; - AtspiRelation *relation; - AtspiRelationType type; - int i; - if (source) { - relations = atspi_accessible_get_relation_set(source, NULL); - if (relations) { - for (i = 0; i < relations->len; i++) { - relation = g_array_index(relations, AtspiRelation *, i); - type = atspi_relation_get_relation_type(relation); - - if (type == search_type) { - ret = atspi_relation_get_target(relation, 0); - break; - } - } - g_array_free(relations, TRUE); + if (source == NULL) + return NULL; + + GArray *relations = atspi_accessible_get_relation_set(source, NULL); + + if (relations == NULL) + return NULL; + + AtspiAccessible *ret; + for (int i = 0; i < relations->len; ++i) { + AtspiRelation *relation = g_array_index(relations, AtspiRelation *, i); + AtspiRelationType type = atspi_relation_get_relation_type(relation); + + if (type == search_type) { + ret = atspi_relation_get_target(relation, 0); + break; } } + + g_array_free(relations, TRUE); + return ret; } @@ -319,11 +321,9 @@ static char *_get_info(AtspiAccessible *node, int length_limit) char *node_name = atspi_accessible_get_name(node, NULL); char *node_role_name = atspi_accessible_get_role_name(node, NULL); - char *attributes = _get_attributes(node); - _truncate_string(attributes, length_limit); + char *attributes = _get_attributes(node, length_limit); Box_Size *box_size = _get_box_size(node); - char *states = _get_states(node); - _truncate_string(states, length_limit); + char *states = _get_states(node, length_limit); char result[SAFE_BUFFER_SIZE]; int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%p],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%p,%p]]", @@ -339,10 +339,8 @@ static char *_get_info(AtspiAccessible *node, int length_limit) _get_object_in_relation(node, ATSPI_RELATION_FLOWS_TO), _get_object_in_relation(node, ATSPI_RELATION_FLOWS_FROM)); - if (ret >= SAFE_BUFFER_SIZE) { - fprintf(stderr, "_get_info: generated string is too long. Buffer overflow"); - result[SAFE_BUFFER_SIZE - 1] = '\n'; - } + if (ret >= SAFE_BUFFER_SIZE) + fprintf(stderr, "\n_get_info: generated string is too long. Buffer overflow\n"); free(node_name); free(node_role_name); @@ -438,29 +436,30 @@ static void _atspi_tree_traverse(AtspiAccessible *desktop, const char *app_name, bool app_name_matched = false; for (int i = 0; i < count; i++) { AtspiAccessible *child = atspi_accessible_get_child_at_index(desktop, i, NULL); - if (child) { - char *name = atspi_accessible_get_name(child, NULL); + if (child == NULL) + break; + + char *name = atspi_accessible_get_name(child, NULL); + + if (!dump && !check) + printf("%s\n", name); - if (!dump && !check) { - printf("%s\n", name); - } + if ((check || dump) && name && !strcmp(name, app_name)) { + app_name_matched = true; - if ((check || dump) && name && !strcmp(name, app_name)) { - app_name_matched = true; + _print_module_legend(); - _print_module_legend(); + if (check) + _test_atspi_parent_child_relation(child, desktop, i); - if (check) - _test_atspi_parent_child_relation(child, desktop, i); + _print_atspi_tree_verify_maybe_r(0, child, check, length_limit); - _print_atspi_tree_verify_maybe_r(0, child, check, length_limit); + if (first_match) { + free(name); + break; + } else + printf("\n"); - if (first_match) { - free(name); - break; - } else - printf("\n"); - } free(name); } } -- 2.7.4 From 3085427fe057bd89000f828f8bb36c3553508fe8 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Mon, 13 Feb 2017 18:39:13 +0900 Subject: [PATCH 06/16] at_spi2_tool: initialize data Uninitialized data is read from local variable 'ret' Change-Id: Ib03c2dae19b5f4f87a2a090bc6c4595939e2655d --- test/at_spi2_tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/at_spi2_tool.c b/test/at_spi2_tool.c index af7eb97..594a7c8 100644 --- a/test/at_spi2_tool.c +++ b/test/at_spi2_tool.c @@ -297,7 +297,7 @@ static AtspiAccessible *_get_object_in_relation(AtspiAccessible *source, AtspiRe if (relations == NULL) return NULL; - AtspiAccessible *ret; + AtspiAccessible *ret = NULL; for (int i = 0; i < relations->len; ++i) { AtspiRelation *relation = g_array_index(relations, AtspiRelation *, i); AtspiRelationType type = atspi_relation_get_relation_type(relation); -- 2.7.4 From 28359dc838f7b390d33343821e1bfe086d2b9efc Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Wed, 6 Apr 2016 17:10:03 +0200 Subject: [PATCH 07/16] atspi-event-listener: Plug a memory leak https://bugzilla.gnome.org/show_bug.cgi?id=764688 Change-Id: I82281f9f9ad2b8c410d4d713ad12dee1343ab2bc --- atspi/atspi-event-listener.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/atspi/atspi-event-listener.c b/atspi/atspi-event-listener.c index 95af3a0..5c4b442 100644 --- a/atspi/atspi-event-listener.c +++ b/atspi/atspi-event-listener.c @@ -1002,6 +1002,9 @@ _atspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data) if (e.source == NULL) { g_warning ("Got no valid source accessible for signal for signal %s from interface %s\n", member, category); + g_free (converted_type); + g_free (name); + g_free (detail); return DBUS_HANDLER_RESULT_HANDLED; } -- 2.7.4 From 3c791208d80c80e44f602f1958cad46cfce50040 Mon Sep 17 00:00:00 2001 From: Radoslaw Cybulski Date: Tue, 6 Dec 2016 18:34:15 +0100 Subject: [PATCH 08/16] fix for non-navigatable end call window in call-ui application, by Mr Shin-Woo Kim Change-Id: I3c6fc0163e1bacac5ea3518c181cc7ef69cec62f --- atspi/atspi-misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c index 48759ca..fdb4e9b 100644 --- a/atspi/atspi-misc.c +++ b/atspi/atspi-misc.c @@ -387,7 +387,7 @@ handle_name_owner_changed (DBusConnection *bus, DBusMessage *message, void *user else if (app_hash) { AtspiApplication *app = g_hash_table_lookup (app_hash, old); - if (app && app->bus_name && !strcmp(app->bus_name, name)) + if (app && name && app->bus_name && !strcmp(app->bus_name, name)) g_object_run_dispose (G_OBJECT (app)); } return DBUS_HANDLER_RESULT_HANDLED; -- 2.7.4 From a589caf6449fd0feccc0b9bf6f14a27ce58d7e5d Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Tue, 13 Dec 2016 10:34:13 +0900 Subject: [PATCH 09/16] Fix SVACE issue WID164553 - name is not NULL always Change-Id: Idff718d0416e98a0556f9421f1d3c76235756ab7 --- atspi/atspi-misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c index fdb4e9b..48759ca 100644 --- a/atspi/atspi-misc.c +++ b/atspi/atspi-misc.c @@ -387,7 +387,7 @@ handle_name_owner_changed (DBusConnection *bus, DBusMessage *message, void *user else if (app_hash) { AtspiApplication *app = g_hash_table_lookup (app_hash, old); - if (app && name && app->bus_name && !strcmp(app->bus_name, name)) + if (app && app->bus_name && !strcmp(app->bus_name, name)) g_object_run_dispose (G_OBJECT (app)); } return DBUS_HANDLER_RESULT_HANDLED; -- 2.7.4 From 0b029582159e4080824a651c6b358f38cd5610ef Mon Sep 17 00:00:00 2001 From: Lukasz Wlazly Date: Mon, 23 Jan 2017 16:14:17 +0100 Subject: [PATCH 10/16] at_spi2_tool refactor Change-Id: I4140f479b95a1a5e91be3654f549ee845757db42 --- test/at_spi2_tool.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/at_spi2_tool.c b/test/at_spi2_tool.c index 594a7c8..743b90c 100644 --- a/test/at_spi2_tool.c +++ b/test/at_spi2_tool.c @@ -340,7 +340,7 @@ static char *_get_info(AtspiAccessible *node, int length_limit) _get_object_in_relation(node, ATSPI_RELATION_FLOWS_FROM)); if (ret >= SAFE_BUFFER_SIZE) - fprintf(stderr, "\n_get_info: generated string is too long. Buffer overflow\n"); + fprintf(stderr, "\n%s, %s %s: generated string is too long. Buffer overflow\n", __FILE__, __FUNCTION__, __LINE__); free(node_name); free(node_role_name); @@ -436,8 +436,10 @@ static void _atspi_tree_traverse(AtspiAccessible *desktop, const char *app_name, bool app_name_matched = false; for (int i = 0; i < count; i++) { AtspiAccessible *child = atspi_accessible_get_child_at_index(desktop, i, NULL); - if (child == NULL) - break; + if (child == NULL) { + fprintf(stderr, "\n%s, %s %s: Null child occured. Results may be misleading.\n", __FILE__, __FUNCTION__, __LINE__); + continue; + } char *name = atspi_accessible_get_name(child, NULL); -- 2.7.4 From 2a9f101b5bdcd8f382b6a730750e0352f711fd72 Mon Sep 17 00:00:00 2001 From: Radoslaw Cybulski Date: Tue, 21 Feb 2017 15:55:05 +0100 Subject: [PATCH 11/16] Add ability to retrieve atspi object's path, which uniquely identifies atspi object across all processes Change-Id: I60fba10c202845427f247814db40436f01fe3117 --- atspi/Makefile.am | 4 +- atspi/atspi-accessible.c | 96 ++++++++++++++++++++++++++++++------------------ atspi/atspi-accessible.h | 6 ++- test/at_spi2_tool.c | 17 +++++---- 4 files changed, 76 insertions(+), 47 deletions(-) diff --git a/atspi/Makefile.am b/atspi/Makefile.am index a860fcc..9944d44 100644 --- a/atspi/Makefile.am +++ b/atspi/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libatspi.la libatspi_la_LDFLAGS = @LDFLAGS@ @LT_VERSION_INFO@ @LIBTOOL_EXPORT_OPTIONS@ -no-undefined -libatspi_la_CFLAGS = $(DBUS_CFLAGS) \ +libatspi_la_CFLAGS = $(DBUS_CFLAGS) $(AUL_CFLAGS) \ $(DBIND_CFLAGS) \ $(GLIB_CFLAGS) \ -I$(top_srcdir)/registryd \ @@ -10,7 +10,7 @@ libatspi_la_CFLAGS = $(DBUS_CFLAGS) \ -I$(top_builddir) \ -I$(top_srcdir) -libatspi_la_LIBADD = $(DBUS_LIBS) \ +libatspi_la_LIBADD = $(DBUS_LIBS) $(AUL_LIBS) \ $(GOBJ_LIBS) \ $(X_LIBS) \ $(top_builddir)/dbind/libdbind.la diff --git a/atspi/atspi-accessible.c b/atspi/atspi-accessible.c index 2d77357..c3392bd 100644 --- a/atspi/atspi-accessible.c +++ b/atspi/atspi-accessible.c @@ -220,7 +220,7 @@ atspi_accessible_class_init (AtspiAccessibleClass *klass) * * Gets the name of an #AtspiAccessible object. * - * Returns: a UTF-8 string indicating the name of the #AtspiAccessible object + * Returns: a UTF-8 string indicating the name of the #AtspiAccessible object * or NULL on exception. **/ gchar * @@ -238,12 +238,37 @@ atspi_accessible_get_name (AtspiAccessible *obj, GError **error) } /** + * atspi_accessible_get_path: + * @obj: a pointer to the #AtspiAccessible object on which to operate. + * + * Gets the path, uniquely identifying object. + * + * Returns: a UTF-8 string describing the #AtspiAccessible object + * or empty string on exception or NULL object passed. + **/ +gchar * +atspi_accessible_get_path(AtspiAccessible *obj, GError **error) +{ + static const char *prefix = "/org/a11y/atspi/accessible/"; + static int prefix_len = 27; + + if (!obj) + return g_strdup(""); + AtspiObject *o = ATSPI_OBJECT (obj); + if (!o) + return g_strdup(""); + if (strncmp(o->path, prefix, prefix_len) == 0) + return g_strdup(o->path + prefix_len); + return g_strdup (o->path); +} + +/** * atspi_accessible_get_description: * @obj: a pointer to the #AtspiAccessible object on which to operate. * * Gets the description of an #AtspiAccessible object. * - * Returns: a UTF-8 string describing the #AtspiAccessible object + * Returns: a UTF-8 string describing the #AtspiAccessible object * or NULL on exception. **/ gchar * @@ -378,7 +403,7 @@ atspi_accessible_get_child_at_index (AtspiAccessible *obj, * atspi_accessible_get_index_in_parent: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Gets the index of an #AtspiAccessible object within its parent's + * Gets the index of an #AtspiAccessible object within its parent's * #AtspiAccessible children list. * * Returns: a #glong indicating the index of the #AtspiAccessible object @@ -523,12 +548,12 @@ atspi_accessible_get_role_name (AtspiAccessible *obj, GError **error) * atspi_accessible_get_localized_role_name: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Gets a UTF-8 string corresponding to the name of the role played by an + * Gets a UTF-8 string corresponding to the name of the role played by an * object, translated to the current locale. * This method will return useful values for roles that fall outside the * enumeration used in atspi_accessible_getRole (). * - * Returns: a localized, UTF-8 string specifying the type of UI role played + * Returns: a localized, UTF-8 string specifying the type of UI role played * by an #AtspiAccessible object. * **/ @@ -583,7 +608,6 @@ atspi_accessible_get_state_set (AtspiAccessible *obj) dbus_message_unref (reply); _atspi_accessible_add_cache (obj, ATSPI_CACHE_STATES); } - return g_object_ref (obj->states); } @@ -591,7 +615,7 @@ atspi_accessible_get_state_set (AtspiAccessible *obj) * atspi_accessible_get_attributes: * @obj: The #AtspiAccessible being queried. * - * Gets the #AttributeSet representing any assigned + * Gets the #AttributeSet representing any assigned * name-value pair attributes or annotations for this object. * For typographic, textual, or textually-semantic attributes, see * atspi_text_get_attributes instead. @@ -638,7 +662,7 @@ add_to_attribute_array (gpointer key, gpointer value, gpointer data) * atspi_accessible_get_attributes_as_array: * @obj: The #AtspiAccessible being queried. * - * Gets a #GArray representing any assigned + * Gets a #GArray representing any assigned * name-value pair attributes or annotations for this object. * For typographic, textual, or textually-semantic attributes, see * atspi_text_get_attributes_as_array instead. @@ -796,7 +820,7 @@ atspi_accessible_get_atspi_version (AtspiAccessible *obj, GError **error) * Gets the application id for a #AtspiAccessible object. * Only works on application root objects. * - * Returns: a positive #gint indicating the id for the #AtspiAccessible object + * Returns: a positive #gint indicating the id for the #AtspiAccessible object * or -1 on exception. **/ gint @@ -847,7 +871,7 @@ _atspi_accessible_is_a (AtspiAccessible *accessible, * atspi_accessible_is_action: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements the + * Query whether the specified #AtspiAccessible implements the * #AtspiAction interface. * * Returns: #TRUE if @obj implements the #AtspiAction interface, @@ -877,7 +901,7 @@ atspi_accessible_is_application (AtspiAccessible *obj) atspi_interface_application); } -/** +/** * atspi_accessible_is_collection: * @obj: a pointer to the #AtspiAccessible instance to query. * @@ -943,7 +967,7 @@ atspi_accessible_is_editable_text (AtspiAccessible *obj) return _atspi_accessible_is_a (obj, atspi_interface_editable_text); } - + /** * atspi_accessible_is_hypertext: * @obj: a pointer to the #AtspiAccessible instance to query. @@ -965,7 +989,7 @@ atspi_accessible_is_hypertext (AtspiAccessible *obj) * atspi_accessible_is_hyperlink: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements the + * Query whether the specified #AtspiAccessible implements the * #AtspiHyperlink interface. * * Returns: #TRUE if @obj implements the #AtspiHypertext interface, @@ -1072,7 +1096,7 @@ atspi_accessible_is_streamable_content (AtspiAccessible *obj) * atspi_accessible_is_text: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements the + * Query whether the specified #AtspiAccessible implements the * #AtspiText interface. * * Returns: #TRUE if @obj implements the #AtspiText interface, @@ -1117,7 +1141,7 @@ AtspiAction * atspi_accessible_get_action (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_action) ? - g_object_ref (ATSPI_ACTION (accessible)) : NULL); + g_object_ref (ATSPI_ACTION (accessible)) : NULL); } /** @@ -1133,7 +1157,7 @@ AtspiAction * atspi_accessible_get_action_iface (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_action) ? - g_object_ref (ATSPI_ACTION (accessible)) : NULL); + g_object_ref (ATSPI_ACTION (accessible)) : NULL); } /** @@ -1151,7 +1175,7 @@ AtspiCollection * atspi_accessible_get_collection (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ? - g_object_ref (ATSPI_COLLECTION (accessible)) : NULL); + g_object_ref (ATSPI_COLLECTION (accessible)) : NULL); } /** @@ -1167,7 +1191,7 @@ AtspiCollection * atspi_accessible_get_collection_iface (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ? - g_object_ref (ATSPI_COLLECTION (accessible)) : NULL); + g_object_ref (ATSPI_COLLECTION (accessible)) : NULL); } /** @@ -1219,7 +1243,7 @@ AtspiDocument * atspi_accessible_get_document (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_document) ? - g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL); + g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL); } /** @@ -1235,7 +1259,7 @@ AtspiDocument * atspi_accessible_get_document_iface (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_document) ? - g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL); + g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL); } /** @@ -1253,7 +1277,7 @@ AtspiEditableText * atspi_accessible_get_editable_text (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ? - g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL); + g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL); } /** @@ -1269,7 +1293,7 @@ AtspiEditableText * atspi_accessible_get_editable_text_iface (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ? - g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL); + g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL); } /** @@ -1303,7 +1327,7 @@ AtspiHypertext * atspi_accessible_get_hypertext (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ? - g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL); + g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL); } /** @@ -1319,7 +1343,7 @@ AtspiHypertext * atspi_accessible_get_hypertext_iface (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ? - g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL); + g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL); } /** @@ -1337,7 +1361,7 @@ AtspiImage * atspi_accessible_get_image (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_image) ? - g_object_ref (ATSPI_IMAGE (accessible)) : NULL); + g_object_ref (ATSPI_IMAGE (accessible)) : NULL); } /** @@ -1353,7 +1377,7 @@ AtspiImage * atspi_accessible_get_image_iface (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_image) ? - g_object_ref (ATSPI_IMAGE (accessible)) : NULL); + g_object_ref (ATSPI_IMAGE (accessible)) : NULL); } /** @@ -1371,7 +1395,7 @@ AtspiSelection * atspi_accessible_get_selection (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ? - g_object_ref (ATSPI_SELECTION (accessible)) : NULL); + g_object_ref (ATSPI_SELECTION (accessible)) : NULL); } /** @@ -1387,7 +1411,7 @@ AtspiSelection * atspi_accessible_get_selection_iface (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ? - g_object_ref (ATSPI_SELECTION (accessible)) : NULL); + g_object_ref (ATSPI_SELECTION (accessible)) : NULL); } #if 0 @@ -1404,7 +1428,7 @@ AtspiStreamableContent * atspi_accessible_get_streamable_content (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_streamable_content) ? - accessible : NULL); + accessible : NULL); } #endif @@ -1423,7 +1447,7 @@ AtspiTable * atspi_accessible_get_table (AtspiAccessible *obj) { return (_atspi_accessible_is_a (obj, atspi_interface_table) ? - g_object_ref (ATSPI_TABLE (obj)) : NULL); + g_object_ref (ATSPI_TABLE (obj)) : NULL); } /** @@ -1439,7 +1463,7 @@ AtspiTable * atspi_accessible_get_table_iface (AtspiAccessible *obj) { return (_atspi_accessible_is_a (obj, atspi_interface_table) ? - g_object_ref (ATSPI_TABLE (obj)) : NULL); + g_object_ref (ATSPI_TABLE (obj)) : NULL); } /** @@ -1455,7 +1479,7 @@ AtspiTableCell * atspi_accessible_get_table_cell (AtspiAccessible *obj) { return (_atspi_accessible_is_a (obj, atspi_interface_table_cell) ? - g_object_ref (ATSPI_TABLE_CELL (obj)) : NULL); + g_object_ref (ATSPI_TABLE_CELL (obj)) : NULL); } /** @@ -1507,7 +1531,7 @@ AtspiValue * atspi_accessible_get_value (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_value) ? - g_object_ref (ATSPI_VALUE (accessible)) : NULL); + g_object_ref (ATSPI_VALUE (accessible)) : NULL); } /** @@ -1523,7 +1547,7 @@ AtspiValue * atspi_accessible_get_value_iface (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_value) ? - g_object_ref (ATSPI_VALUE (accessible)) : NULL); + g_object_ref (ATSPI_VALUE (accessible)) : NULL); } static void @@ -1583,11 +1607,11 @@ atspi_accessible_get_interfaces (AtspiAccessible *obj) return ret; } -AtspiAccessible * +AtspiAccessible * _atspi_accessible_new (AtspiApplication *app, const gchar *path) { AtspiAccessible *accessible; - + accessible = g_object_new (ATSPI_TYPE_ACCESSIBLE, NULL); g_return_val_if_fail (accessible != NULL, NULL); diff --git a/atspi/atspi-accessible.h b/atspi/atspi-accessible.h index 2c3f8cc..f07394e 100644 --- a/atspi/atspi-accessible.h +++ b/atspi/atspi-accessible.h @@ -5,7 +5,7 @@ * Copyright 2002 Ximian, Inc. * 2002 Sun Microsystems Inc. * Copyright 2010, 2011 Novell, Inc. - * + * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -66,7 +66,7 @@ struct _AtspiAccessibleClass AtspiObjectClass parent_class; }; -GType atspi_accessible_get_type (void); +GType atspi_accessible_get_type (void); AtspiAccessible * _atspi_accessible_new (AtspiApplication *app, const gchar *path); @@ -75,6 +75,8 @@ gchar * atspi_accessible_get_name (AtspiAccessible *obj, GError **error); gchar * atspi_accessible_get_description (AtspiAccessible *obj, GError **error); +gchar * atspi_accessible_get_path (AtspiAccessible *obj, GError **error); + AtspiAccessible * atspi_accessible_get_parent (AtspiAccessible *obj, GError **error); gint atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error); diff --git a/test/at_spi2_tool.c b/test/at_spi2_tool.c index 743b90c..badaaa3 100644 --- a/test/at_spi2_tool.c +++ b/test/at_spi2_tool.c @@ -287,15 +287,15 @@ static char *_get_attributes(AtspiAccessible *node, int length_limit) return result; } -static AtspiAccessible *_get_object_in_relation(AtspiAccessible *source, AtspiRelationType search_type) +static char *_get_object_in_relation(AtspiAccessible *source, AtspiRelationType search_type) { if (source == NULL) - return NULL; + return ""; GArray *relations = atspi_accessible_get_relation_set(source, NULL); if (relations == NULL) - return NULL; + return ""; AtspiAccessible *ret = NULL; for (int i = 0; i < relations->len; ++i) { @@ -310,7 +310,7 @@ static AtspiAccessible *_get_object_in_relation(AtspiAccessible *source, AtspiRe g_array_free(relations, TRUE); - return ret; + return ret ? atspi_accessible_get_path(ret, NULL) : g_strdup(""); } static char *_get_info(AtspiAccessible *node, int length_limit) @@ -320,14 +320,15 @@ static char *_get_info(AtspiAccessible *node, int length_limit) char *node_name = atspi_accessible_get_name(node, NULL); char *node_role_name = atspi_accessible_get_role_name(node, NULL); + char *path = atspi_accessible_get_path(node, NULL); char *attributes = _get_attributes(node, length_limit); Box_Size *box_size = _get_box_size(node); char *states = _get_states(node, length_limit); char result[SAFE_BUFFER_SIZE]; - int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%p],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%p,%p]]", - node, + int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%s],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%s,%s]]", + path, node_role_name, attributes, box_size->x, @@ -369,7 +370,9 @@ static void _test_atspi_parent_child_relation(AtspiAccessible *obj, AtspiAccessi else snprintf(parent_status, NUMBER_WIDTH, "%d", parent_index); - snprintf(output, CHECK_OUTPUT_WIDTH, "[FAIL<%d,%s><%p,%p>]", parent_candidate_index, parent_status, parent_candidate, parent); + snprintf(output, CHECK_OUTPUT_WIDTH, "[FAIL<%d,%s><%s,%s>]", parent_candidate_index, parent_status, + atspi_accessible_get_path(parent_candidate, NULL), + atspi_accessible_get_path(parent, NULL)); } else { snprintf(output, CHECK_OUTPUT_WIDTH, "[OK]"); -- 2.7.4 From b95659e66457646684e98ccbd878e2fb346b489c Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Mon, 27 Mar 2017 12:56:54 +0900 Subject: [PATCH 12/16] tool: fix memory leak Change-Id: I90c8f22d555c36db6f66e2250e333bf32ea86d8e --- test/at_spi2_tool.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/test/at_spi2_tool.c b/test/at_spi2_tool.c index badaaa3..2eae131 100644 --- a/test/at_spi2_tool.c +++ b/test/at_spi2_tool.c @@ -326,6 +326,9 @@ static char *_get_info(AtspiAccessible *node, int length_limit) Box_Size *box_size = _get_box_size(node); char *states = _get_states(node, length_limit); + char *flows_to = _get_object_in_relation(node, ATSPI_RELATION_FLOWS_TO); + char *flows_from = _get_object_in_relation(node, ATSPI_RELATION_FLOWS_FROM); + char result[SAFE_BUFFER_SIZE]; int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%s],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%s,%s]]", path, @@ -337,14 +340,15 @@ static char *_get_info(AtspiAccessible *node, int length_limit) box_size->height, node_name, states, - _get_object_in_relation(node, ATSPI_RELATION_FLOWS_TO), - _get_object_in_relation(node, ATSPI_RELATION_FLOWS_FROM)); + flows_to, + flows_from); if (ret >= SAFE_BUFFER_SIZE) fprintf(stderr, "\n%s, %s %s: generated string is too long. Buffer overflow\n", __FILE__, __FUNCTION__, __LINE__); free(node_name); free(node_role_name); + free(path); free(attributes); if (box_size) { free(box_size->width); @@ -352,6 +356,8 @@ static char *_get_info(AtspiAccessible *node, int length_limit) free(box_size); } free(states); + free(flows_to); + free(flows_from); return _strdup(result); } @@ -370,9 +376,12 @@ static void _test_atspi_parent_child_relation(AtspiAccessible *obj, AtspiAccessi else snprintf(parent_status, NUMBER_WIDTH, "%d", parent_index); + char *parent_path = atspi_accessible_get_path(parent, NULL); + char *parent_candidate_path = atspi_accessible_get_path(parent_candidate, NULL); snprintf(output, CHECK_OUTPUT_WIDTH, "[FAIL<%d,%s><%s,%s>]", parent_candidate_index, parent_status, - atspi_accessible_get_path(parent_candidate, NULL), - atspi_accessible_get_path(parent, NULL)); + parent_candidate_path, parent_path); + free(parent_path); + free(parent_candidate_path); } else { snprintf(output, CHECK_OUTPUT_WIDTH, "[OK]"); -- 2.7.4 From 576781b36f2d342e20acdf750b7b19d3ff9c6628 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Tue, 4 Apr 2017 10:45:24 +0900 Subject: [PATCH 13/16] Fix memory leak bus/at-spi-bus-launcher.c argv[1] is allocated in memory by g_strdup_printf. but do not free. So I add g_free function. test/at_spi2_tool.c Added a null check to avoid double free. Change-Id: I80ce6af2839c4dfe9c1460885f5b93f281f7ef29 --- bus/at-spi-bus-launcher.c | 29 ++++++++++++++++------------- test/at_spi2_tool.c | 3 ++- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/bus/at-spi-bus-launcher.c b/bus/at-spi-bus-launcher.c index 3f6c917..db1db5c 100644 --- a/bus/at-spi-bus-launcher.c +++ b/bus/at-spi-bus-launcher.c @@ -1,6 +1,6 @@ /* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- - * - * at-spi-bus-launcher: Manage the a11y bus as a child process + * + * at-spi-bus-launcher: Manage the a11y bus as a child process * * Copyright 2011 Red Hat, Inc. * @@ -124,7 +124,7 @@ setup_bus_child (gpointer data) #ifdef __linux #include prctl (PR_SET_PDEATHSIG, 15); -#endif +#endif } /** @@ -156,7 +156,7 @@ on_bus_exited (GPid pid, gpointer data) { A11yBusLauncher *app = data; - + app->a11y_bus_pid = -1; app->state = A11Y_BUS_STATE_ERROR; if (app->a11y_launch_error_message == NULL) @@ -169,7 +169,7 @@ on_bus_exited (GPid pid, app->a11y_launch_error_message = g_strdup_printf ("Bus stopped by signal %d", WSTOPSIG (status)); } g_main_loop_quit (app->loop); -} +} static gboolean ensure_a11y_bus (A11yBusLauncher *app) @@ -181,12 +181,12 @@ ensure_a11y_bus (A11yBusLauncher *app) if (app->a11y_bus_pid != 0) return FALSE; - + argv[1] = g_strdup_printf ("--config-file=%s/at-spi2/accessibility.conf", SYSCONFDIR); if (pipe (app->pipefd) < 0) g_error ("Failed to create pipe: %s", strerror (errno)); - + if (!g_spawn_async (NULL, argv, NULL, @@ -241,9 +241,12 @@ ensure_a11y_bus (A11yBusLauncher *app) } #endif + if (argv[1]) g_free(argv[1]); + return TRUE; - + error: + if (argv[1]) g_free(argv[1]); close (app->pipefd[0]); close (app->pipefd[1]); app->state = A11Y_BUS_STATE_ERROR; @@ -379,7 +382,7 @@ handle_set_property (GDBusConnection *connection, A11yBusLauncher *app = user_data; const gchar *type = g_variant_get_type_string (value); gboolean enabled; - + if (g_strcmp0 (type, "b") != 0) { g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, @@ -429,7 +432,7 @@ on_bus_acquired (GDBusConnection *connection, A11yBusLauncher *app = user_data; GError *error; guint registration_id; - + if (connection == NULL) { g_main_loop_quit (app->loop); @@ -506,7 +509,7 @@ on_sigterm_pipe (GIOChannel *channel, gpointer data) { A11yBusLauncher *app = data; - + g_main_loop_quit (app->loop); return FALSE; @@ -544,7 +547,7 @@ already_running () bridge_display = XOpenDisplay (NULL); if (!bridge_display) return FALSE; - + AT_SPI_BUS = XInternAtom (bridge_display, "AT_SPI_BUS", False); XGetWindowProperty (bridge_display, XDefaultRootWindow (bridge_display), @@ -828,7 +831,7 @@ main (int argc, if (_global_app->a11y_bus_pid > 0) kill (_global_app->a11y_bus_pid, SIGTERM); - /* Clear the X property if our bus is gone; in the case where e.g. + /* Clear the X property if our bus is gone; in the case where e.g. * GDM is launching a login on an X server it was using before, * we don't want early login processes to pick up the stale address. */ diff --git a/test/at_spi2_tool.c b/test/at_spi2_tool.c index 2eae131..018acc7 100644 --- a/test/at_spi2_tool.c +++ b/test/at_spi2_tool.c @@ -240,12 +240,13 @@ static char *_get_states(AtspiAccessible *node, int length_limit) { AtspiStateSet *node_state_set = atspi_accessible_get_state_set(node); GArray *states = atspi_state_set_get_states(node_state_set); + if (!states) return NULL; g_array_sort(states, _int_sort_function); AtspiStateType state_type; char *state_string = NULL; - for (int i = 0; states && (i < states->len); i++) { + for (int i = 0; i < states->len; i++) { state_type = g_array_index(states, AtspiStateType, i); char node_state_str[8]; -- 2.7.4 From 4a435a0629752f9ee5a8a1a86566c3e48029dd20 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Tue, 16 May 2017 14:22:27 +0900 Subject: [PATCH 14/16] Convey launching condition to screen-reader The screen-reader reads "Screen reader (TTS) on" when the screen-reader launches. It is not necessary to read this information for the screen-reader launching at booting time. It is necessary only if the screen-reader is launched by the Vconf value change from the Settings application. Change-Id: I73cb17be6c6b561d77ed2f6d7226a21896f62e1a --- bus/at-spi-bus-launcher.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/bus/at-spi-bus-launcher.c b/bus/at-spi-bus-launcher.c index db1db5c..89860b6 100644 --- a/bus/at-spi-bus-launcher.c +++ b/bus/at-spi-bus-launcher.c @@ -604,7 +604,7 @@ gsettings_key_changed (GSettings *gsettings, const gchar *key, void *user_data) } static gboolean -_launch_screen_reader(gpointer user_data) +_launch_screen_reader(gpointer user_data, gboolean by_vconf_change) { A11yBusLauncher *bl = user_data; LOGD("Launching screen reader"); @@ -619,6 +619,15 @@ _launch_screen_reader(gpointer user_data) LOGD("Can't create bundle"); return FALSE; } + + if (by_vconf_change) + { + if (bundle_add_str(kb, "by_vconf_change", "yes") != BUNDLE_ERROR_NONE) + { + LOGD("Can't add information to bundle"); + } + } + int operation_error = appsvc_set_operation(kb, APP_CONTROL_OPERATION_SCREEN_READ); LOGD("appsvc_set_operation: %i", operation_error); @@ -649,7 +658,7 @@ _launch_screen_reader_repeat_until_success(gpointer user_data) { return FALSE; } - gboolean ret = _launch_screen_reader(user_data); + gboolean ret = _launch_screen_reader(user_data, FALSE); if (ret) { @@ -727,7 +736,7 @@ void screen_reader_cb(keynode_t *node, void *user_data) if (!bl->screen_reader_needed && (bl->pid > 0)) _terminate_screen_reader(bl); else if (bl->screen_reader_needed && (bl->pid <= 0)) - _launch_screen_reader(bl); + _launch_screen_reader(bl, TRUE); } int -- 2.7.4 From 67b77c5a624ccab97c840e689fed4dfcb46e0aa1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Stawicki?= Date: Thu, 16 Mar 2017 14:09:32 +0100 Subject: [PATCH 15/16] add screen-reader dead tracker to at-spi-bus-launcher Commit adds _screen_reader_dead_tracker method to track if screen-reader gets killed. Commit needs: https://review.tizen.org/gerrit/#/c/117565/ replaces: https://review.tizen.org/gerrit/#/c/117557/ invalidates: https://review.tizen.org/gerrit/#/c/117556/ Change-Id: I8ea33c75f4e2fa4c0d868deec52a574c993a21b0 --- bus/at-spi-bus-launcher.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/bus/at-spi-bus-launcher.c b/bus/at-spi-bus-launcher.c index 89860b6..87b2da7 100644 --- a/bus/at-spi-bus-launcher.c +++ b/bus/at-spi-bus-launcher.c @@ -64,6 +64,7 @@ FILE *log_file; #define LOGD(arg...) do {if (log_file) {fprintf(log_file, ##arg);fprintf(log_file, "\n"); fflush(log_file);}} while(0) #endif +static gboolean _launch_screen_reader_repeat_until_success(gpointer user_data); typedef enum { A11Y_BUS_STATE_IDLE = 0, @@ -329,6 +330,8 @@ handle_a11y_enabled_change (A11yBusLauncher *app, gboolean enabled, &builder, &invalidated_builder), NULL); + g_variant_builder_clear (&builder); + g_variant_builder_clear (&invalidated_builder); } static void @@ -367,6 +370,8 @@ handle_screen_reader_enabled_change (A11yBusLauncher *app, gboolean enabled, &builder, &invalidated_builder), NULL); + g_variant_builder_clear (&builder); + g_variant_builder_clear (&invalidated_builder); } static gboolean @@ -603,6 +608,20 @@ gsettings_key_changed (GSettings *gsettings, const gchar *key, void *user_data) handle_screen_reader_enabled_change (_global_app, new_val, FALSE); } +static int +_screen_reader_dead_tracker (int pid, void *data) +{ + A11yBusLauncher *app = data; + + if (app->pid > 0 && pid == app->pid) + { + LOGE("screen reader is dead, pid: %d, restarting", pid); + app->pid = 0; + g_timeout_add_seconds (2, _launch_screen_reader_repeat_until_success, app); + } + return 0; +} + static gboolean _launch_screen_reader(gpointer user_data, gboolean by_vconf_change) { @@ -636,6 +655,8 @@ _launch_screen_reader(gpointer user_data, gboolean by_vconf_change) if (bl->pid > 0) { LOGD("Screen reader launched with pid: %i", bl->pid); + LOGD("registering screen reader dead tracker"); + aul_listen_app_dead_signal(_screen_reader_dead_tracker, bl); ret = TRUE; } else @@ -680,6 +701,9 @@ _terminate_screen_reader(A11yBusLauncher *bl) return FALSE; + LOGD("unregistering screen reader dead tracker"); + aul_listen_app_dead_signal(NULL, NULL); + int status = aul_app_get_status_bypid(bl->pid); if (status < 0) -- 2.7.4 From e757756d750e7d736aee31c71b68116a71031f58 Mon Sep 17 00:00:00 2001 From: Pawel Kurowski Date: Thu, 1 Jun 2017 12:45:08 +0200 Subject: [PATCH 16/16] Add relation-dump option to at_spi2_tool Flags -d and -c now inform when object has relations to list. Change-Id: If831d8258aaf6d7b71f3f05ebf75e88d3fab56c1 --- test/at_spi2_tool.c | 141 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 44 deletions(-) diff --git a/test/at_spi2_tool.c b/test/at_spi2_tool.c index 018acc7..e9b3d68 100644 --- a/test/at_spi2_tool.c +++ b/test/at_spi2_tool.c @@ -4,6 +4,7 @@ #include #include #include +#include #define ERROR_STATE -1 #define SAFE_BUFFER_SIZE 2048 @@ -17,6 +18,8 @@ #define DUMP 0 #define CHECK 1 #define FIRST_MATCH 2 +#define RELATION_TABLE_COLUMN_COUNT 7 +#define RELATION_COLUMN_WIDTH 20 #define VERSION "1.1" static unsigned indent_width = 2; @@ -79,12 +82,6 @@ typedef struct _Box_Size { char *width; } Box_Size; -char *_strdup(const char *c) -{ - char *result = (char *)calloc(1, strlen(c) + 1); - return result ? strcpy(result, c) : result; -} - static char *_multiply_string(char c, unsigned number) { char *result = (char *)calloc(1, number + 1); @@ -99,7 +96,7 @@ static char *_multiply_string(char c, unsigned number) static void _print_module_legend() { - printf("\n[[node],[node role name],[attributes list],[x,y,width,height],[node name],[states list][flow to node, flow from node]\n\n"); + printf("\n[[node],[node role name],[attributes list],[x,y,width,height],[node name],[states list][relations]\n\n"); } static void _print_atspi_states_legend() @@ -250,7 +247,7 @@ static char *_get_states(AtspiAccessible *node, int length_limit) state_type = g_array_index(states, AtspiStateType, i); char node_state_str[8]; - sprintf(node_state_str, "(%d)", state_type); + snprintf(node_state_str, 8, "(%d)", state_type); _combine_strings(&state_string, node_state_str); } @@ -288,32 +285,6 @@ static char *_get_attributes(AtspiAccessible *node, int length_limit) return result; } -static char *_get_object_in_relation(AtspiAccessible *source, AtspiRelationType search_type) -{ - if (source == NULL) - return ""; - - GArray *relations = atspi_accessible_get_relation_set(source, NULL); - - if (relations == NULL) - return ""; - - AtspiAccessible *ret = NULL; - for (int i = 0; i < relations->len; ++i) { - AtspiRelation *relation = g_array_index(relations, AtspiRelation *, i); - AtspiRelationType type = atspi_relation_get_relation_type(relation); - - if (type == search_type) { - ret = atspi_relation_get_target(relation, 0); - break; - } - } - - g_array_free(relations, TRUE); - - return ret ? atspi_accessible_get_path(ret, NULL) : g_strdup(""); -} - static char *_get_info(AtspiAccessible *node, int length_limit) { if (!node) @@ -327,11 +298,10 @@ static char *_get_info(AtspiAccessible *node, int length_limit) Box_Size *box_size = _get_box_size(node); char *states = _get_states(node, length_limit); - char *flows_to = _get_object_in_relation(node, ATSPI_RELATION_FLOWS_TO); - char *flows_from = _get_object_in_relation(node, ATSPI_RELATION_FLOWS_FROM); + GArray *relations = atspi_accessible_get_relation_set(node, NULL); char result[SAFE_BUFFER_SIZE]; - int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%s],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%s,%s]]", + int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%s],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%s]]", path, node_role_name, attributes, @@ -341,8 +311,7 @@ static char *_get_info(AtspiAccessible *node, int length_limit) box_size->height, node_name, states, - flows_to, - flows_from); + (relations && relations->len) ? "*" : ""); if (ret >= SAFE_BUFFER_SIZE) fprintf(stderr, "\n%s, %s %s: generated string is too long. Buffer overflow\n", __FILE__, __FUNCTION__, __LINE__); @@ -357,10 +326,9 @@ static char *_get_info(AtspiAccessible *node, int length_limit) free(box_size); } free(states); - free(flows_to); - free(flows_from); + g_array_free(relations, TRUE); - return _strdup(result); + return g_strdup(result); } static void _test_atspi_parent_child_relation(AtspiAccessible *obj, AtspiAccessible *parent_candidate, int parent_candidate_index) @@ -373,7 +341,7 @@ static void _test_atspi_parent_child_relation(AtspiAccessible *obj, AtspiAccessi char parent_status[NUMBER_WIDTH]; if (parent == NULL) - strcpy(parent_status, "_"); + strncpy(parent_status, NUMBER_WIDTH, "_"); else snprintf(parent_status, NUMBER_WIDTH, "%d", parent_index); @@ -438,11 +406,93 @@ void _print_help() printf("\tat_spi2_tool -i1 -c starter\n"); printf("\t show AT-SPI tree with integrity test for node \"starter\" using one-space indentation\n"); } + void _print_version() { printf("AT-SPI2-CORE-UTIL v%s\n", VERSION); } +static void _print_horizontal_line_in_relation_table() { + for (int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) { + for (int j = 0; j < RELATION_COLUMN_WIDTH; j++) + printf("-"); + printf("+"); + } + printf("\n"); +} + +static void _print_legend_for_relation_table() { + char *table[] = {"OBJECT", "CONTROLLER_FOR", "CONTROLLED_BY", "FLOWS_TO", "FLOWS_FROM", "DESCRIBED_BY", "OTHER RELATION [ID]"}; + assert(sizeof(table) / sizeof(table[0]) == RELATION_TABLE_COLUMN_COUNT); + for(int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) + printf("%*s|", RELATION_COLUMN_WIDTH , table[i]); + printf("\n"); + _print_horizontal_line_in_relation_table(); +} + +static char *_get_path_to_object_in_relation(AtspiRelation *relation) { + if (!relation) + return NULL; + gint last_index = atspi_relation_get_n_targets(relation) - 1; + AtspiAccessible *target = atspi_relation_get_target(relation, last_index); + return atspi_accessible_get_path(target, NULL); +} + +static void _print_relations_for_object(AtspiAccessible *node) { + GArray *relations = atspi_accessible_get_relation_set(node, NULL); + if (!relations) + return; + + if (relations->len) { + int size = RELATION_TABLE_COLUMN_COUNT * sizeof(char *); + char **table = malloc(size); + memset(table, 0, size); + table[0] = atspi_accessible_get_path(node, NULL); + char buf[8] = ""; + for (int i = 0; i < relations->len; i++) { + AtspiRelation *relation = g_array_index(relations, AtspiRelation *, i); + AtspiRelationType type = atspi_relation_get_relation_type(relation); + switch (type) { + case ATSPI_RELATION_CONTROLLER_FOR: + table[1] = _get_path_to_object_in_relation(relation); + break; + case ATSPI_RELATION_CONTROLLED_BY: + table[2] = _get_path_to_object_in_relation(relation); + break; + case ATSPI_RELATION_FLOWS_TO: + table[3] = _get_path_to_object_in_relation(relation); + break; + case ATSPI_RELATION_FLOWS_FROM: + table[4] = _get_path_to_object_in_relation(relation); + break; + case ATSPI_RELATION_DESCRIBED_BY: + table[5] = _get_path_to_object_in_relation(relation); + break; + default: + snprintf(buf, 8, " [%d]", type); + _combine_strings(&table[RELATION_TABLE_COLUMN_COUNT - 1], buf); + } + } + + for (int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) { + printf("%*s|", RELATION_COLUMN_WIDTH, table[i] ? table[i] : ""); + free(table[i]); + } + free(table); + + printf("\n"); + _print_horizontal_line_in_relation_table(); + } + g_array_free(relations, TRUE); + + int count = atspi_accessible_get_child_count(node, NULL); + for (int i = 0; i < count; i++) { + AtspiAccessible *child = atspi_accessible_get_child_at_index(node, i, NULL); + if (child) + _print_relations_for_object(child); + } +} + static void _atspi_tree_traverse(AtspiAccessible *desktop, const char *app_name, bool dump, bool check, bool first_match, int length_limit) { int count = atspi_accessible_get_child_count(desktop, NULL); @@ -472,8 +522,11 @@ static void _atspi_tree_traverse(AtspiAccessible *desktop, const char *app_name, if (first_match) { free(name); break; - } else + } else { printf("\n"); + _print_legend_for_relation_table(); + _print_relations_for_object(child); + } free(name); } -- 2.7.4