From: Mark Doffman Date: Tue, 5 Jan 2010 20:50:55 +0000 (-0800) Subject: Fix object lifecycle errors. X-Git-Tag: AT_SPI2_ATK_2_12_0~445 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git;a=commitdiff_plain;h=0c6971bdf4c2c0f3e64580287cd17555c32881dd Fix object lifecycle errors. Add an application reference to the event structure. --- diff --git a/Makefile.am b/Makefile.am index 31982fe..ca33cea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS=droute common atk-adaptor +SUBDIRS=dbind droute common atk-adaptor diff --git a/atk-adaptor/accessible-cache.c b/atk-adaptor/accessible-cache.c index 4f87b18..c7e27f9 100644 --- a/atk-adaptor/accessible-cache.c +++ b/atk-adaptor/accessible-cache.c @@ -38,7 +38,7 @@ toplevel_added_listener (AtkObject * accessible, guint index, AtkObject * child); static void -remove_object (gpointer data, GObject * gobj); +remove_object (GObject * source, GObject * gobj, gpointer data); static void add_object (SpiCache * cache, GObject * gobj); @@ -149,7 +149,7 @@ spi_cache_dispose (GObject * object) /*---------------------------------------------------------------------------*/ static void -remove_object (gpointer data, GObject * gobj) +remove_object (GObject * source, GObject * gobj, gpointer data) { SpiCache *cache = SPI_CACHE (data); @@ -167,6 +167,12 @@ add_object (SpiCache * cache, GObject * gobj) g_hash_table_insert (cache->objects, gobj, NULL); +#ifdef SPI_ATK_DEBUG + g_debug ("CACHE - %s - %d - %s", atk_object_get_name (ATK_OBJECT (gobj)), + atk_object_get_role (ATK_OBJECT (gobj)), + spi_register_object_to_path (spi_global_register, gobj)); +#endif + g_signal_emit (cache, cache_signals [OBJECT_ADDED], 0, gobj); } @@ -254,11 +260,6 @@ add_subtree (SpiCache *cache, AtkObject * accessible) if (!spi_cache_in (cache, G_OBJECT (current)) && !atk_state_set_contains_state (set, ATK_STATE_MANAGES_DESCENDANTS)) { -#ifdef SPI_ATK_DEBUG - g_debug ("REG - %s - %d - %s", atk_object_get_name (current), - atk_object_get_role (current), - atk_dbus_object_to_path (current)); -#endif append_children (current, traversal); } } @@ -386,4 +387,20 @@ spi_cache_in (SpiCache * cache, GObject * object) return FALSE; } +#ifdef SPI_ATK_DEBUG +void +spi_cache_print_info (GObject * obj) +{ + char * path = spi_register_object_to_path (spi_global_register, obj); + + if (spi_cache_in (spi_global_cache, obj)) + g_printf ("%s IC\n", path); + else + g_printf ("%s NC\n", path); + + if (path) + g_free (path); +} +#endif + /*END------------------------------------------------------------------------*/ diff --git a/atk-adaptor/accessible-leasing.c b/atk-adaptor/accessible-leasing.c index 28d4099..63f3c3a 100644 --- a/atk-adaptor/accessible-leasing.c +++ b/atk-adaptor/accessible-leasing.c @@ -26,6 +26,10 @@ #include "accessible-leasing.h" +#ifdef SPI_ATK_DEBUG +#include "accessible-cache.h" +#endif + /*---------------------------------------------------------------------------*/ SpiLeasing *spi_global_leasing; @@ -108,6 +112,11 @@ expiry_func (gpointer data) { current = g_queue_pop_head (leasing->expiry_queue); +#ifdef SPI_ATK_DEBUG + g_debug ("REVOKE - "); + spi_cache_print_info (current->object); +#endif + g_object_unref (current->object); g_slice_free (ExpiryElement, current); @@ -192,6 +201,11 @@ spi_leasing_take (SpiLeasing * leasing, GObject * object) add_expiry_timeout (leasing); +#ifdef SPI_ATK_DEBUG + g_debug ("LEASE - "); + spi_cache_print_info (object); +#endif + return object; } diff --git a/atk-adaptor/accessible-register.c b/atk-adaptor/accessible-register.c index ac93dee..97ada1d 100644 --- a/atk-adaptor/accessible-register.c +++ b/atk-adaptor/accessible-register.c @@ -198,6 +198,10 @@ deregister_object (gpointer data, GObject * gobj) 0, gobj); g_hash_table_remove (reg->ref2ptr, GINT_TO_POINTER (ref)); + +#ifdef SPI_ATK_DEBUG + g_debug ("DEREG - %d", ref); +#endif } } @@ -213,6 +217,10 @@ register_object (SpiRegister * reg, GObject * gobj) g_object_set_data (G_OBJECT (gobj), SPI_DBUS_ID, GINT_TO_POINTER (ref)); g_object_weak_ref (G_OBJECT (gobj), deregister_object, reg); +#ifdef SPI_ATK_DEBUG + g_debug ("REG - %d", ref); +#endif + g_signal_emit (reg, register_signals [OBJECT_REGISTERED], 0, gobj); } @@ -268,6 +276,9 @@ spi_register_object_to_path (SpiRegister * reg, GObject * gobj) { guint ref; + if (gobj == NULL) + return NULL; + ref = object_to_ref (gobj); if (!ref) { diff --git a/atk-adaptor/adaptors/accessible-adaptor.c b/atk-adaptor/adaptors/accessible-adaptor.c index 6359fa7..844ab6a 100644 --- a/atk-adaptor/adaptors/accessible-adaptor.c +++ b/atk-adaptor/adaptors/accessible-adaptor.c @@ -76,11 +76,59 @@ impl_set_Description (DBusMessageIter * iter, void *user_data) static dbus_bool_t impl_get_Parent (DBusMessageIter * iter, void *user_data) { - AtkObject *object = (AtkObject *) user_data; + AtkObject *obj = (AtkObject *) user_data; + AtkObject *parent; + DBusMessageIter iter_variant; + dbus_uint32_t role; g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE); - spi_object_append_v_reference (iter, atk_object_get_parent (object)); + role = spi_accessible_role_from_atk_role (atk_object_get_role (obj)); + + dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "(so)", + &iter_variant); + + parent = atk_object_get_parent (obj); + if (parent == NULL) + { +#ifdef SPI_ATK_PLUG_SOCKET + /* TODO, move in to a 'Plug' wrapper. */ + if (ATK_IS_PLUG (obj)) + { + char *id = g_object_get_data (G_OBJECT (obj), "dbus-plug-parent"); + char *bus_parent; + char *path_parent; + + if (id) + { + bus_parent = g_strdup (id); + if (bus_parent && (path_parent = g_utf8_strchr (bus_parent + 1, -1, ':'))) + { + DBusMessageIter iter_parent; + *(path_parent++) = '\0'; + dbus_message_iter_open_container (&iter_variant, DBUS_TYPE_STRUCT, NULL, + &iter_parent); + dbus_message_iter_append_basic (&iter_parent, DBUS_TYPE_STRING, &bus_parent); + dbus_message_iter_append_basic (&iter_parent, DBUS_TYPE_OBJECT_PATH, &path_parent); + dbus_message_iter_close_container (&iter_variant, &iter_parent); + } + } + } + else if (role != Accessibility_ROLE_APPLICATION) +#else + if (role != Accessibility_ROLE_APPLICATION) +#endif + spi_object_append_null_reference (&iter_variant); + else + spi_object_append_desktop_reference (&iter_variant); + } + else + { + spi_object_append_reference (&iter_variant, parent); + } + + + dbus_message_iter_close_container (iter, &iter_variant); return TRUE; } @@ -413,7 +461,7 @@ static DBusMessage * impl_GetApplication (DBusConnection * bus, DBusMessage * message, void *user_data) { - AtkObject *root = atk_get_root (); + AtkObject *root = g_object_ref (atk_get_root ()); return spi_object_return_reference (message, root); } diff --git a/atk-adaptor/adaptors/cache-adaptor.c b/atk-adaptor/adaptors/cache-adaptor.c index 45eb41b..15595a5 100644 --- a/atk-adaptor/adaptors/cache-adaptor.c +++ b/atk-adaptor/adaptors/cache-adaptor.c @@ -98,9 +98,30 @@ append_cache_item (AtkObject * obj, gpointer data) parent = atk_object_get_parent (obj); if (parent == NULL) { - /* TODO: Support getting parent of an AtkPlug */ -#ifdef __ATK_PLUG_H__ - if (role != Accessibility_ROLE_APPLICATION && !ATK_IS_PLUG (obj)) +#ifdef SPI_ATK_PLUG_SOCKET + /* TODO, move in to a 'Plug' wrapper. */ + if (ATK_IS_PLUG (obj)) + { + char *id = g_object_get_data (G_OBJECT (obj), "dbus-plug-parent"); + char *bus_parent; + char *path_parent; + + if (id) + { + bus_parent = g_strdup (id); + if (bus_parent && (path_parent = g_utf8_strchr (bus_parent + 1, -1, ':'))) + { + DBusMessageIter iter_parent; + *(path_parent++) = '\0'; + dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_STRUCT, NULL, + &iter_parent); + dbus_message_iter_append_basic (&iter_parent, DBUS_TYPE_STRING, &bus_parent); + dbus_message_iter_append_basic (&iter_parent, DBUS_TYPE_OBJECT_PATH, &path_parent); + dbus_message_iter_close_container (&iter_struct, &iter_parent); + } + } + } + else if (role != Accessibility_ROLE_APPLICATION) #else if (role != Accessibility_ROLE_APPLICATION) #endif @@ -131,7 +152,7 @@ append_cache_item (AtkObject * obj, gpointer data) g_object_unref (G_OBJECT (child)); } } -#ifdef __ATK_PLUG_H__ +#ifdef SPI_ATK_PLUG_SOCKET if (ATK_IS_SOCKET (obj) && atk_socket_is_occupied (ATK_SOCKET (obj))) { AtkSocket *socket = ATK_SOCKET (obj); @@ -144,8 +165,8 @@ append_cache_item (AtkObject * obj, gpointer data) *(child_path++) = '\0'; dbus_message_iter_open_container (&iter_sub_array, DBUS_TYPE_STRUCT, NULL, &iter_socket); - dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_STRING, &name); - dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_OBJECT_PATH, &path); + dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_STRING, &child_name); + dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_OBJECT_PATH, &child_path); dbus_message_iter_close_container (&iter_sub_array, &iter_socket); } g_free (child_name); diff --git a/atk-adaptor/bridge.c b/atk-adaptor/bridge.c index b283506..aaf2bcc 100644 --- a/atk-adaptor/bridge.c +++ b/atk-adaptor/bridge.c @@ -246,7 +246,7 @@ exit_func (void) /*---------------------------------------------------------------------------*/ -#ifdef __ATK_PLUG_H__ +#ifdef SPI_ATK_PLUG_SOCKET static AtkPlugClass *plug_class; static AtkSocketClass *socket_class; @@ -257,7 +257,7 @@ get_plug_id (AtkPlug * plug) gchar *path; GString *str = g_string_new (NULL); - path = atk_dbus_object_to_path (ATK_OBJECT (plug), TRUE); + path = spi_register_object_to_path (spi_global_register, G_OBJECT (plug)); g_string_printf (str, "%s:%s", uname, path); g_free (path); return g_string_free (str, FALSE); @@ -270,8 +270,7 @@ socket_embed_hook (AtkSocket * socket, gchar * plug_id) gchar *plug_name, *plug_path; /* Force registration */ - gchar *path = atk_dbus_object_to_path (accessible, TRUE); - spi_emit_cache_update (accessible, atk_adaptor_app_data->bus); + gchar *path = spi_register_object_to_path (spi_global_register, G_OBJECT (accessible)); /* Let the plug know that it has been embedded */ plug_name = g_strdup (plug_id); if (!plug_name) @@ -286,7 +285,7 @@ socket_embed_hook (AtkSocket * socket, gchar * plug_id) *(plug_path++) = '\0'; message = dbus_message_new_method_call (plug_name, plug_path, "org.freedesktop.atspi.Accessible", "Embedded"); dbus_message_append_args (message, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); - dbus_connection_send (atk_adaptor_app_data->bus, message, NULL); + dbus_connection_send (spi_global_app_data->bus, message, NULL); } g_free (plug_name); g_free (path); @@ -358,7 +357,7 @@ adaptor_init (gint * argc, gchar ** argv[]) /* Allocate global data and do ATK initializations */ spi_global_app_data = g_new0 (SpiBridge, 1); atk_misc = atk_misc_get_instance (); - spi_global_app_data->root = root; + spi_global_app_data->root = g_object_ref (root); /* Set up D-Bus connection and register bus name */ dbus_error_init (&error); @@ -388,6 +387,15 @@ adaptor_init (gint * argc, gchar ** argv[]) dbus_connection_setup_with_g_main (spi_global_app_data->bus, g_main_context_default ()); + /* + * Create the leasing, register and cache objects. + * The order is important here, the cache depends on the + * register object. + */ + spi_global_register = g_object_new (SPI_REGISTER_TYPE, NULL); + spi_global_leasing = g_object_new (SPI_LEASING_TYPE, NULL); + spi_global_cache = g_object_new (SPI_CACHE_TYPE, NULL); + /* Get D-Bus introspection directory */ introspection_directory = (char *) g_getenv ("ATSPI_INTROSPECTION_PATH"); if (introspection_directory == NULL) @@ -398,7 +406,7 @@ adaptor_init (gint * argc, gchar ** argv[]) droute_new (spi_global_app_data->bus, introspection_directory); treepath = droute_add_one (spi_global_app_data->droute, - "/org/at_spi/cache", NULL); + "/org/at_spi/cache", spi_global_cache); accpath = droute_add_many (spi_global_app_data->droute, "/org/at_spi/accessible", @@ -406,14 +414,6 @@ adaptor_init (gint * argc, gchar ** argv[]) (DRouteGetDatumFunction) spi_global_register_path_to_object); - /* - * Create the leasing, register and cache objects. - * The order is important here, the cache depends on the - * register object. - */ - spi_global_register = g_object_new (SPI_REGISTER_TYPE, NULL); - spi_global_leasing = g_object_new (SPI_LEASING_TYPE, NULL); - spi_global_cache = g_object_new (SPI_CACHE_TYPE, NULL); /* Register all interfaces with droute and set up application accessible db */ spi_initialize_cache (treepath); @@ -435,7 +435,7 @@ adaptor_init (gint * argc, gchar ** argv[]) /* Register methods to send D-Bus signals on certain ATK events */ spi_atk_register_event_listeners (); -#ifdef __ATK_PLUG_H__ +#ifdef SPI_ATK_PLUG_SOCKET /* Hook our plug-and socket functions */ install_plug_hooks (); #endif diff --git a/atk-adaptor/event.c b/atk-adaptor/event.c index e97046b..7dc9e45 100644 --- a/atk-adaptor/event.c +++ b/atk-adaptor/event.c @@ -285,7 +285,7 @@ emit_event (AtkObject *obj, gchar *cname, *t; DBusMessage *sig; - DBusMessageIter iter; + DBusMessageIter iter, iter_struct; if (!klass) klass = ""; if (!major) major = ""; @@ -304,6 +304,7 @@ emit_event (AtkObject *obj, dbus_message_iter_init_append(sig, &iter); + spi_object_append_reference (&iter, spi_global_app_data->root); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &minor); dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail1); dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail2); diff --git a/configure.ac b/configure.ac index f16ff7f..38f905c 100644 --- a/configure.ac +++ b/configure.ac @@ -98,19 +98,21 @@ fi AC_SUBST(EXTRA_SOCKET_LIBS) dnl find sizes & alignments -#orig_CPPFLAGS=$CPPFLAGS -#CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS" -#DBIND_CHECK_ALIGNOF(char) -#DBIND_CHECK_ALIGNOF(dbus_bool_t) -#DBIND_CHECK_ALIGNOF(dbus_int16_t) -#DBIND_CHECK_ALIGNOF(dbus_int32_t) -#DBIND_CHECK_ALIGNOF(dbus_int64_t) -#DBIND_CHECK_ALIGNOF(double) -#DBIND_CHECK_ALIGNOF(dbind_pointer) -#DBIND_CHECK_ALIGNOF(dbind_struct) -#CPPFLAGS=$orig_CPPFLAGS +orig_CPPFLAGS=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS" +DBIND_CHECK_ALIGNOF(char) +DBIND_CHECK_ALIGNOF(dbus_bool_t) +DBIND_CHECK_ALIGNOF(dbus_int16_t) +DBIND_CHECK_ALIGNOF(dbus_int32_t) +DBIND_CHECK_ALIGNOF(dbus_int64_t) +DBIND_CHECK_ALIGNOF(double) +DBIND_CHECK_ALIGNOF(dbind_pointer) +DBIND_CHECK_ALIGNOF(dbind_struct) +CPPFLAGS=$orig_CPPFLAGS AC_CONFIG_FILES([Makefile + dbind/dbind-config.h + dbind/Makefile droute/Makefile common/Makefile atk-adaptor/Makefile diff --git a/droute/droute.c b/droute/droute.c index 5ab1478..8c7bd51 100644 --- a/droute/droute.c +++ b/droute/droute.c @@ -249,6 +249,8 @@ impl_prop_GetAll (DBusMessage *message, gchar *iface; void *datum = path_get_datum (path, pathstr); + if (!datum) + return NULL; dbus_error_init (&error); if (!dbus_message_get_args @@ -299,6 +301,7 @@ impl_prop_GetSet (DBusMessage *message, StrPair pair; PropertyPair *prop_funcs = NULL; + void *datum; dbus_error_init (&error); if (!dbus_message_get_args (message, @@ -316,9 +319,13 @@ impl_prop_GetSet (DBusMessage *message, if (!prop_funcs) return dbus_message_new_error (message, DBUS_ERROR_FAILED, "Property unavailable"); + datum = path_get_datum (path, pathstr); + if (!datum) + return NULL; + if (get && prop_funcs->get) { - void *datum = path_get_datum (path, pathstr); + DBusMessageIter iter; _DROUTE_DEBUG ("DRoute (handle prop Get): %s|%s on %s\n", pair.one, pair.two, pathstr); @@ -333,7 +340,6 @@ impl_prop_GetSet (DBusMessage *message, } else if (!get && prop_funcs->set) { - void *datum = path_get_datum (path, pathstr); DBusMessageIter iter; _DROUTE_DEBUG ("DRoute (handle prop Get): %s|%s on %s\n", pair.one, pair.two, pathstr); @@ -484,15 +490,20 @@ handle_other (DBusConnection *bus, DRouteFunction func; DBusMessage *reply = NULL; + void *datum; + pair.one = iface; pair.two = member; _DROUTE_DEBUG ("DRoute (handle other): %s|%s on %s\n", member, iface, pathstr); + datum = path_get_datum (path, pathstr); + if (!datum) + return result; + func = (DRouteFunction) g_hash_table_lookup (path->methods, &pair); if (func != NULL) { - void *datum = path_get_datum (path, pathstr); reply = (func) (bus, message, datum);