From 69642a918b6781425c8147266ce8c565bdbdcbdf Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 10 Apr 2014 13:17:06 +0100 Subject: TpBaseProtocol: be a GDBusObjectSkeleton This means we don't need the get_interfaces_array() vfunc, because we can inspect the GDBusObject interface to find out what our interfaces are. --- .../telepathy-glib/telepathy-glib-sections.txt | 2 - examples/cm/echo-message-parts/protocol.c | 15 --- telepathy-glib/base-protocol.c | 133 +++++++-------------- telepathy-glib/base-protocol.h | 14 +-- telepathy-glib/dbus-internal.h | 4 + telepathy-glib/dbus.c | 51 ++++++++ 6 files changed, 97 insertions(+), 122 deletions(-) diff --git a/docs/reference/telepathy-glib/telepathy-glib-sections.txt b/docs/reference/telepathy-glib/telepathy-glib-sections.txt index 81a067687..f07d33db8 100644 --- a/docs/reference/telepathy-glib/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib/telepathy-glib-sections.txt @@ -4677,10 +4677,8 @@ TpBaseProtocolGetParametersFunc TpBaseProtocolNewConnectionFunc TpBaseProtocolNormalizeContactFunc TpBaseProtocolIdentifyAccountFunc -TpBaseProtocolGetInterfacesFunc TpBaseProtocolGetConnectionDetailsFunc TpBaseProtocolGetAvatarDetailsFunc -TpBaseProtocolGetInterfacesArrayFunc tp_base_protocol_get_type TP_BASE_PROTOCOL diff --git a/examples/cm/echo-message-parts/protocol.c b/examples/cm/echo-message-parts/protocol.c index 16cef0920..d18f8a431 100644 --- a/examples/cm/echo-message-parts/protocol.c +++ b/examples/cm/echo-message-parts/protocol.c @@ -123,20 +123,6 @@ identify_account (TpBaseProtocol *self G_GNUC_UNUSED, return NULL; } -static GPtrArray * -get_interfaces_array (TpBaseProtocol *self) -{ - GPtrArray *interfaces; - - interfaces = TP_BASE_PROTOCOL_CLASS ( - example_echo_2_protocol_parent_class)->get_interfaces_array (self); - - g_ptr_array_add (interfaces, TP_IFACE_PROTOCOL_INTERFACE_AVATARS1); - g_ptr_array_add (interfaces, TP_IFACE_PROTOCOL_INTERFACE_ADDRESSING1); - - return interfaces; -} - static void get_connection_details (TpBaseProtocol *self G_GNUC_UNUSED, GStrv *connection_interfaces, @@ -305,7 +291,6 @@ example_echo_2_protocol_class_init ( base_class->normalize_contact = normalize_contact; base_class->identify_account = identify_account; - base_class->get_interfaces_array = get_interfaces_array; base_class->get_connection_details = get_connection_details; base_class->get_avatar_details = get_avatar_details; } diff --git a/telepathy-glib/base-protocol.c b/telepathy-glib/base-protocol.c index 822ad6b32..9ddd2f628 100644 --- a/telepathy-glib/base-protocol.c +++ b/telepathy-glib/base-protocol.c @@ -37,6 +37,7 @@ #include #define DEBUG_FLAG TP_DEBUG_PARAMS +#include "telepathy-glib/dbus-internal.h" #include "telepathy-glib/debug-internal.h" /** @@ -355,21 +356,6 @@ tp_cm_param_filter_string_nonempty (const TpCMParamSpec *paramspec, * Since: 0.11.11 */ -/** - * TpBaseProtocolGetInterfacesFunc: - * @self: a protocol - * - * Signature of a virtual method to get the D-Bus interfaces implemented by - * @self, in addition to the Protocol interface. - * - * If you implement #TpBaseProtocolClass.get_statuses, you should include - * %TP_IFACE_PROTOCOL_INTERFACE_PRESENCE in the returned array. - * - * Returns: (transfer full): a %NULL-terminated array of D-Bus interface names - * - * Since: 0.11.11 - */ - /** * TpBaseProtocolGetConnectionDetailsFunc: * @self: a protocol @@ -421,37 +407,6 @@ tp_cm_param_filter_string_nonempty (const TpCMParamSpec *paramspec, * Since: 0.13.7 */ -/** - * TpBaseProtocolGetInterfacesArrayFunc: - * @self: a #TpBaseProtocol - * - * Signature of an implementation of - * #TpBaseProtocolClass.get_interfaces_array virtual function. - * - * Implementation must first chainup on parent class implementation and then - * add extra interfaces into the #GPtrArray. - * - * |[ - * static GPtrArray * - * my_protocol_get_interfaces_array (TpBaseProtocol *self) - * { - * GPtrArray *interfaces; - * - * interfaces = TP_BASE_PROTOCOL_CLASS ( - * my_protocol_parent_class)->get_interfaces_array (self); - * - * g_ptr_array_add (interfaces, TP_IFACE_BADGERS); - * - * return interfaces; - * } - * ]| - * - * Returns: (transfer container): a #GPtrArray of static strings for D-Bus - * interfaces implemented by this client. - * - * Since: 0.19.4 - */ - /** * TP_TYPE_PROTOCOL_ADDRESSING: * @@ -556,10 +511,6 @@ tp_cm_param_filter_string_nonempty (const TpCMParamSpec *paramspec, * and must either return a newly allocated string that represents the * "identity" of the parameters in @asv (usually the "account" parameter), * or %NULL with an error raised via @error - * @get_interfaces_array: a callback used to implement the Interfaces - * D-Bus property; The implementation must first chainup to parent - * class implementation and then add extra interfaces to the - * #GPtrArray. Replaces @get_interfaces * @get_connection_details: a callback used to implement the Protocol D-Bus * properties that represent details of the connections provided by this * protocol @@ -581,7 +532,7 @@ static void presence_iface_init (TpSvcProtocolInterfacePresence1Class *cls); static void addressing_iface_init (TpSvcProtocolInterfaceAddressing1Class *cls); G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TpBaseProtocol, tp_base_protocol, - G_TYPE_OBJECT, + G_TYPE_DBUS_OBJECT_SKELETON, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_PROTOCOL, protocol_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_PROTOCOL_INTERFACE_PRESENCE1, presence_iface_init); @@ -608,7 +559,6 @@ typedef struct struct _TpBaseProtocolPrivate { gchar *name; - GStrv interfaces; GStrv connection_interfaces; GStrv authentication_types; GPtrArray *requestable_channel_classes; @@ -665,24 +615,35 @@ tp_base_protocol_build_requestable_channel_classes ( return ret; } +static void +object_skeleton_take_interface (GDBusObjectSkeleton *skel, + GDBusInterfaceSkeleton *iface) +{ + g_dbus_object_skeleton_add_interface (skel, iface); + g_object_unref (iface); +} + +static void +object_skeleton_take_svc_interface (GDBusObjectSkeleton *skel, + GType type) +{ + object_skeleton_take_interface (skel, + tp_svc_interface_skeleton_new (skel, type)); +} + static void tp_base_protocol_constructed (GObject *object) { TpBaseProtocol *self = (TpBaseProtocol *) object; TpBaseProtocolClass *cls = TP_BASE_PROTOCOL_GET_CLASS (self); + GDBusObjectSkeleton *skel = G_DBUS_OBJECT_SKELETON (self); void (*chain_up) (GObject *) = ((GObjectClass *) tp_base_protocol_parent_class)->constructed; - GPtrArray *ifaces; if (chain_up != NULL) chain_up (object); - /* TODO: when we don't have to deal with - * TpBaseProtocolClass.get_interfaces, we won't have to do any of this */ - ifaces = (cls->get_interfaces_array) (self); - g_ptr_array_add (ifaces, NULL); - self->priv->interfaces = g_strdupv ((GStrv) ifaces->pdata); - g_ptr_array_unref (ifaces); + object_skeleton_take_svc_interface (skel, TP_TYPE_SVC_PROTOCOL); if (cls->get_connection_details != NULL) { @@ -733,6 +694,21 @@ tp_base_protocol_constructed (GObject *object) &self->priv->avatar_specs.max_height, &self->priv->avatar_specs.max_width, &self->priv->avatar_specs.max_bytes); + + object_skeleton_take_svc_interface (skel, + TP_TYPE_SVC_PROTOCOL_INTERFACE_AVATARS1); + } + + if (cls->get_statuses != NULL) + { + object_skeleton_take_svc_interface (skel, + TP_TYPE_SVC_PROTOCOL_INTERFACE_PRESENCE1); + } + + if (TP_IS_PROTOCOL_ADDRESSING (self)) + { + object_skeleton_take_svc_interface (skel, + TP_TYPE_SVC_PROTOCOL_INTERFACE_ADDRESSING1); } if (self->priv->avatar_specs.supported_mime_types == NULL) @@ -831,15 +807,13 @@ tp_base_protocol_get_immutable_properties (TpBaseProtocol *self) NULL); } - if (tp_strv_contains ((const gchar * const *) self->priv->interfaces, - TP_IFACE_PROTOCOL_INTERFACE_ADDRESSING1)) + if (TP_IS_PROTOCOL_ADDRESSING (self)) tp_dbus_properties_mixin_fill_properties_hash ((GObject *) self, table, TP_IFACE_PROTOCOL_INTERFACE_ADDRESSING1, "AddressableVCardFields", TP_IFACE_PROTOCOL_INTERFACE_ADDRESSING1, "AddressableURISchemes", NULL); - if (tp_strv_contains ((const gchar * const *) self->priv->interfaces, - TP_IFACE_PROTOCOL_INTERFACE_PRESENCE1)) + if (cls->get_statuses != NULL) tp_dbus_properties_mixin_fill_properties_hash ((GObject *) self, table, TP_IFACE_PROTOCOL_INTERFACE_PRESENCE1, "Statuses", NULL); @@ -901,7 +875,6 @@ tp_base_protocol_finalize (GObject *object) ((GObjectClass *) tp_base_protocol_parent_class)->finalize; g_free (self->priv->name); - g_strfreev (self->priv->interfaces); g_strfreev (self->priv->connection_interfaces); g_strfreev (self->priv->authentication_types); g_free (self->priv->icon); @@ -1110,7 +1083,9 @@ protocol_properties_getter (GObject *object, break; case PP_INTERFACES: - g_value_set_boxed (value, self->priv->interfaces); + g_value_take_boxed (value, + _tp_g_dbus_object_dup_interface_names (G_DBUS_OBJECT (self), + TP_IFACE_PROTOCOL, NULL)); break; case PP_CONNECTION_INTERFACES: @@ -1142,32 +1117,6 @@ protocol_properties_getter (GObject *object, } } -static GPtrArray * -tp_base_protocol_get_interfaces_array (TpBaseProtocol *self) -{ - TpBaseProtocolClass *klass = TP_BASE_PROTOCOL_GET_CLASS (self); - GPtrArray *interfaces = g_ptr_array_new (); - gchar **old_ifaces = NULL, **ptr; - - /* copy the klass->get_interfaces property value for backwards - * compatibility */ - if (klass->get_interfaces != NULL) - old_ifaces = klass->get_interfaces (self); - - for (ptr = old_ifaces; - ptr != NULL && *ptr != NULL; - ptr++) - { - g_ptr_array_add (interfaces, (char *) *ptr); - } - - /* TODO: old_ifaces is leaked because get_interfaces returns a new - * GStrv, but we want static strings nowadays. leaking is better - * than crashing though. this'll be fixed soon */ - - return interfaces; -} - static void tp_base_protocol_class_init (TpBaseProtocolClass *klass) { @@ -1234,8 +1183,6 @@ tp_base_protocol_class_init (TpBaseProtocolClass *klass) object_class->set_property = tp_base_protocol_set_property; object_class->finalize = tp_base_protocol_finalize; - klass->get_interfaces_array = tp_base_protocol_get_interfaces_array; - g_object_class_install_property (object_class, PROP_NAME, g_param_spec_string ("name", "Name of this protocol", diff --git a/telepathy-glib/base-protocol.h b/telepathy-glib/base-protocol.h index 14a8cc5f1..0c1103128 100644 --- a/telepathy-glib/base-protocol.h +++ b/telepathy-glib/base-protocol.h @@ -101,7 +101,7 @@ GType tp_base_protocol_get_type (void) G_GNUC_CONST; struct _TpBaseProtocol { /**/ - GObject parent; + GDBusObjectSkeleton parent; TpBaseProtocolPrivate *priv; }; @@ -121,8 +121,6 @@ typedef gchar *(*TpBaseProtocolIdentifyAccountFunc) (TpBaseProtocol *self, GHashTable *asv, GError **error); -typedef GStrv (*TpBaseProtocolGetInterfacesFunc) (TpBaseProtocol *self); - typedef void (*TpBaseProtocolGetConnectionDetailsFunc) (TpBaseProtocol *self, GStrv *connection_interfaces, GType **channel_manager_types, @@ -140,11 +138,9 @@ typedef void (*TpBaseProtocolGetAvatarDetailsFunc) (TpBaseProtocol *self, guint *max_width, guint *max_bytes); -typedef GPtrArray * (*TpBaseProtocolGetInterfacesArrayFunc) (TpBaseProtocol *self); - struct _TpBaseProtocolClass { - GObjectClass parent_class; + GDBusObjectSkeletonClass parent_class; TpDBusPropertiesMixinClass dbus_properties_class; gboolean is_stub; @@ -160,10 +156,6 @@ struct _TpBaseProtocolClass GHashTable *asv, GError **error); - /**/ - GStrv (*_TP_SEAL (get_interfaces)) (TpBaseProtocol *self); - /**/ - void (*get_connection_details) (TpBaseProtocol *self, GStrv *connection_interfaces, GType **channel_manager_types, @@ -177,8 +169,6 @@ struct _TpBaseProtocolClass GStrv (*dup_authentication_types) (TpBaseProtocol *self); - TpBaseProtocolGetInterfacesArrayFunc get_interfaces_array; - /**/ GCallback padding[4]; TpBaseProtocolClassPrivate *priv; diff --git a/telepathy-glib/dbus-internal.h b/telepathy-glib/dbus-internal.h index 33b4d3c25..ad0405439 100644 --- a/telepathy-glib/dbus-internal.h +++ b/telepathy-glib/dbus-internal.h @@ -34,6 +34,10 @@ gboolean _tp_dbus_connection_get_name_owner (GDBusConnection *dbus_connection, GDBusConnection *_tp_dbus_object_get_connection (gpointer object); const gchar *_tp_dbus_object_get_object_path (gpointer object); +GStrv _tp_g_dbus_object_dup_interface_names (GDBusObject *obj, + const gchar *skip_class, + const gchar *skip_type); + G_END_DECLS #endif /* __TP_INTERNAL_DBUS_GLIB_H__ */ diff --git a/telepathy-glib/dbus.c b/telepathy-glib/dbus.c index 3a7f61477..2f2e91c1b 100644 --- a/telepathy-glib/dbus.c +++ b/telepathy-glib/dbus.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -1061,3 +1062,53 @@ _tp_dbus_object_get_object_path (gpointer object) return NULL; } + +GStrv +_tp_g_dbus_object_dup_interface_names (GDBusObject *obj, + const gchar *skip_class, + const gchar *skip_type) +{ + GList *ifaces = g_dbus_object_get_interfaces (obj); + GPtrArray *ret = g_ptr_array_new (); + GList *iter; + + for (iter = ifaces; iter != NULL; iter = iter->next) + { + GDBusInterfaceInfo *info = g_dbus_interface_get_info (iter->data); + + if (info != NULL) + { + if (info->name == NULL) + { + WARNING ("%s %p lists NULL as a GDBusInterfaceInfo->name", + G_OBJECT_TYPE_NAME (iter->data), info); + } + else if (!tp_strdiff (TP_IFACE_DBUS_PROPERTIES, info->name)) + { + /* ignore org.freedesktop.DBus, which is implied/assumed */ + } + else if (skip_class != NULL && !tp_strdiff (skip_class, info->name)) + { + /* ignore im.telepathy.v1.Channel or whatever */ + } + else if (skip_type != NULL && !tp_strdiff (skip_type, info->name)) + { + /* ignore im.telepathy.v1.Channel.Type.Call1 or whatever */ + } + else + { + g_ptr_array_add (ret, g_strdup (info->name)); + } + } + else + { + CRITICAL ("%s %p has no GDBusInterfaceInfo", + G_OBJECT_TYPE_NAME (iter->data), info); + } + } + + g_list_free_full (ifaces, g_object_unref); + + g_ptr_array_add (ret, NULL); + return (GStrv) g_ptr_array_free (ret, FALSE); +} -- cgit v1.2.3