From fe216f885c32c65be9d323b660359a7c29db8f06 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Sat, 11 Jun 2011 17:07:40 +0200 Subject: [PATCH] Add TpAutomaticClientFactory This is a subclass of TpSimpleClientFactory that creates specialized TpChannel objects, like TpTextChannel and TpStreamTubeChannel --- docs/reference/telepathy-glib-docs.sgml | 1 + docs/reference/telepathy-glib-sections.txt | 17 ++ telepathy-glib/Makefile.am | 2 + telepathy-glib/automatic-client-factory-internal.h | 39 ++++ telepathy-glib/automatic-client-factory.c | 212 ++++++++++++++++++++ telepathy-glib/automatic-client-factory.h | 65 ++++++ telepathy-glib/introspection.am | 1 + telepathy-glib/stream-tube-channel.c | 13 ++ telepathy-glib/text-channel.c | 13 ++ 9 files changed, 363 insertions(+), 0 deletions(-) create mode 100644 telepathy-glib/automatic-client-factory-internal.h create mode 100644 telepathy-glib/automatic-client-factory.c create mode 100644 telepathy-glib/automatic-client-factory.h diff --git a/docs/reference/telepathy-glib-docs.sgml b/docs/reference/telepathy-glib-docs.sgml index f530815..039a78f 100644 --- a/docs/reference/telepathy-glib-docs.sgml +++ b/docs/reference/telepathy-glib-docs.sgml @@ -82,6 +82,7 @@ + diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt index 528a9b2..5c605b2 100644 --- a/docs/reference/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib-sections.txt @@ -5669,3 +5669,20 @@ TP_TYPE_SIMPLE_CLIENT_FACTORY tp_simple_client_factory_get_type TpSimpleClientFactoryPrivate + +
+automatic-client-factory +automatic-client-factory +telepathy-glib/telepathy-glib.h +TpAutomaticClientFactory +TpAutomaticClientFactoryClass +tp_automatic_client_factory_new + +TP_IS_AUTOMATIC_CLIENT_FACTORY +TP_IS_AUTOMATIC_CLIENT_FACTORY_CLASS +TP_AUTOMATIC_CLIENT_FACTORY +TP_AUTOMATIC_CLIENT_FACTORY_CLASS +TP_AUTOMATIC_CLIENT_FACTORY_GET_CLASS +TP_TYPE_AUTOMATIC_CLIENT_FACTORY +tp_automatic_client_factory_get_type +
diff --git a/telepathy-glib/Makefile.am b/telepathy-glib/Makefile.am index 000dce9..c751aee 100644 --- a/telepathy-glib/Makefile.am +++ b/telepathy-glib/Makefile.am @@ -26,6 +26,7 @@ our_headers = \ account.h \ account-channel-request.h \ account-manager.h \ + automatic-client-factory.h \ automatic-proxy-factory.h \ add-dispatch-operation-context.h \ base-client.h \ @@ -143,6 +144,7 @@ libtelepathy_glib_internal_la_SOURCES = \ account-internal.h \ account-manager.c \ account-manager-internal.h \ + automatic-client-factory.c \ automatic-proxy-factory.c \ add-dispatch-operation-context-internal.h \ add-dispatch-operation-context.c \ diff --git a/telepathy-glib/automatic-client-factory-internal.h b/telepathy-glib/automatic-client-factory-internal.h new file mode 100644 index 0000000..7ee546a --- /dev/null +++ b/telepathy-glib/automatic-client-factory-internal.h @@ -0,0 +1,39 @@ +/* + * Automatic client factory internal + * + * Copyright © 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TP_AUTOMATIC_CLIENT_FACTORY_INTERNAL_H__ +#define __TP_AUTOMATIC_CLIENT_FACTORY_INTERNAL_H__ + +#include + +G_BEGIN_DECLS + +TpTextChannel *_tp_text_channel_new_with_factory (TpConnection *conn, + const gchar *object_path, const GHashTable *immutable_properties, + GError **error, TpSimpleClientFactory *factory); + +TpStreamTubeChannel *_tp_stream_tube_channel_new_with_factory ( + TpConnection *conn, const gchar *object_path, + const GHashTable *immutable_properties, GError **error, + TpSimpleClientFactory *factory); + +G_END_DECLS + +#endif diff --git a/telepathy-glib/automatic-client-factory.c b/telepathy-glib/automatic-client-factory.c new file mode 100644 index 0000000..4822108 --- /dev/null +++ b/telepathy-glib/automatic-client-factory.c @@ -0,0 +1,212 @@ +/* + * Factory creating higher level objects + * + * Copyright © 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * SECTION:automatic-client-factory + * @title: TpAutomaticClientFactory + * @short_description: factory creating higher level objects + * @see_also: #TpSimpleClientFactory + * + * This factory overrides some #TpSimpleClientFactory virtual methods to + * create specialized #TpChannel subclasses. + * + * #TpAutomaticClientFactory will currently create #TpChannel objects + * as follows: + * + * + * + * a #TpStreamTubeChannel, if the channel is of type + * %TP_IFACE_CHANNEL_TYPE_STREAM_TUBE; + * + * + * a #TpTextChannel, if the channel is of type + * %TP_IFACE_CHANNEL_TYPE_TEXT and implements + * %TP_IFACE_CHANNEL_INTERFACE_MESSAGES; + * + * + * a plain #TpChannel, otherwise + * + * + * + * It is guaranteed that the objects returned by future versions + * will be either the class that is currently used, or a more specific + * subclass of that class. + * + * This factory asks to prepare the following features: + * + * + * + * %TP_CHANNEL_FEATURE_CORE, %TP_CHANNEL_FEATURE_GROUP + * and %TP_CHANNEL_FEATURE_PASSWORD for all + * type of channels. + * + * + * %TP_TEXT_CHANNEL_FEATURE_INCOMING_MESSAGES and + * TP_TEXT_CHANNEL_FEATURE_SMS for #TpTextChannel + * + * + * + * Since: 0.UNRELEASED + */ + +/** + * TpAutomaticClientFactory: + * + * Data structure representing a #TpAutomaticClientFactory + * + * Since: 0.UNRELEASED + */ + +/** + * TpAutomaticClientFactoryClass: + * @parent_class: the parent class + * + * The class of a #TpAutomaticClientFactory. + * + * Since: 0.UNRELEASED + */ + +#include "telepathy-glib/automatic-client-factory.h" + +#include +#include +#include +#include + +#define DEBUG_FLAG TP_DEBUG_CLIENT +#include "telepathy-glib/debug-internal.h" +#include "telepathy-glib/automatic-client-factory-internal.h" + +G_DEFINE_TYPE (TpAutomaticClientFactory, tp_automatic_client_factory, + TP_TYPE_SIMPLE_CLIENT_FACTORY) + +static TpChannel * +dup_channel_impl (TpSimpleClientFactory *self, + TpConnection *conn, + const gchar *object_path, + const GHashTable *properties, + GError **error) +{ + TpSimpleClientFactoryClass *chainup = (TpSimpleClientFactoryClass *) + tp_automatic_client_factory_parent_class; + TpChannel *channel = NULL; + const gchar *chan_type; + + channel = tp_simple_client_factory_lookup_proxy (self, object_path); + if (channel != NULL) + return g_object_ref (channel); + + chan_type = tp_asv_get_string (properties, TP_PROP_CHANNEL_CHANNEL_TYPE); + + if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) + { + channel = (TpChannel *) _tp_stream_tube_channel_new_with_factory (conn, + object_path, properties, error, self); + } + else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_TEXT)) + { + const gchar * const * interfaces; + + interfaces = tp_asv_get_strv (properties, TP_PROP_CHANNEL_INTERFACES); + + /* Create a TpTextChannel only if the channel supports Messages */ + if (tp_strv_contains (interfaces, TP_IFACE_CHANNEL_INTERFACE_MESSAGES)) + { + channel = (TpChannel *) _tp_text_channel_new_with_factory (conn, + object_path, properties, error, self); + } + else + { + DEBUG ("channel %s doesn't implement Messages so we can't create " + "a TpTextChannel", object_path); + } + } + + if (channel != NULL) + { + tp_simple_client_factory_insert_proxy (self, channel); + return channel; + } + + /* Chainup on parent implementation as fallback */ + return chainup->dup_channel (self, conn, object_path, properties, error); +} + +static GArray * +dup_channel_features_impl (TpSimpleClientFactory *self, + TpChannel *channel) +{ + TpSimpleClientFactoryClass *chainup = (TpSimpleClientFactoryClass *) + tp_automatic_client_factory_parent_class; + GArray *features; + GQuark feature; + + /* Chainup to get desired features for all channel types */ + features = chainup->dup_channel_features (self, channel); + + feature = TP_CHANNEL_FEATURE_GROUP; + g_array_append_val (features, feature); + + feature = TP_CHANNEL_FEATURE_PASSWORD; + g_array_append_val (features, feature); + + if (TP_IS_TEXT_CHANNEL (channel)) + { + feature = TP_TEXT_CHANNEL_FEATURE_INCOMING_MESSAGES; + g_array_append_val (features, feature); + + feature = TP_TEXT_CHANNEL_FEATURE_SMS; + g_array_append_val (features, feature); + } + + return features; +} + +static void +tp_automatic_client_factory_init (TpAutomaticClientFactory *self) +{ +} + +static void +tp_automatic_client_factory_class_init (TpAutomaticClientFactoryClass *cls) +{ + TpSimpleClientFactoryClass *simple_class = (TpSimpleClientFactoryClass *) cls; + + simple_class->dup_channel = dup_channel_impl; + simple_class->dup_channel_features = dup_channel_features_impl; +} + +/** + * tp_automatic_client_factory_new: + * @dbus: a #TpDBusDaemon + * + * Convenient function to create a new #TpAutomaticClientFactory instance. + * + * Returns: a new #TpAutomaticClientFactory + * + * Since: 0.UNRELEASED + */ +TpAutomaticClientFactory * +tp_automatic_client_factory_new (TpDBusDaemon *dbus) +{ + return g_object_new (TP_TYPE_AUTOMATIC_CLIENT_FACTORY, + "dbus-daemon", dbus, + NULL); +} diff --git a/telepathy-glib/automatic-client-factory.h b/telepathy-glib/automatic-client-factory.h new file mode 100644 index 0000000..53013e7 --- /dev/null +++ b/telepathy-glib/automatic-client-factory.h @@ -0,0 +1,65 @@ +/* + * Factory creating higher level objects + * + * Copyright © 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TP_AUTOMATIC_CLIENT_FACTORY_H__ +#define __TP_AUTOMATIC_CLIENT_FACTORY_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _TpAutomaticClientFactory TpAutomaticClientFactory; +typedef struct _TpAutomaticClientFactoryClass TpAutomaticClientFactoryClass; + +struct _TpAutomaticClientFactoryClass { + /**/ + TpSimpleClientFactoryClass parent_class; +}; + +struct _TpAutomaticClientFactory { + /**/ + TpSimpleClientFactory parent; +}; + +GType tp_automatic_client_factory_get_type (void); + +#define TP_TYPE_AUTOMATIC_CLIENT_FACTORY \ + (tp_automatic_client_factory_get_type ()) +#define TP_AUTOMATIC_CLIENT_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TYPE_AUTOMATIC_CLIENT_FACTORY, \ + TpAutomaticClientFactory)) +#define TP_AUTOMATIC_CLIENT_FACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TYPE_AUTOMATIC_CLIENT_FACTORY, \ + TpAutomaticClientFactoryClass)) +#define TP_IS_AUTOMATIC_CLIENT_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TYPE_AUTOMATIC_CLIENT_FACTORY)) +#define TP_IS_AUTOMATIC_CLIENT_FACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TYPE_AUTOMATIC_CLIENT_FACTORY)) +#define TP_AUTOMATIC_CLIENT_FACTORY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TYPE_AUTOMATIC_CLIENT_FACTORY, \ + TpAutomaticClientFactoryClass)) + +TpAutomaticClientFactory * tp_automatic_client_factory_new (TpDBusDaemon *dbus); + +G_END_DECLS + +#endif diff --git a/telepathy-glib/introspection.am b/telepathy-glib/introspection.am index 28f9669..0fcc422 100644 --- a/telepathy-glib/introspection.am +++ b/telepathy-glib/introspection.am @@ -12,6 +12,7 @@ INTROSPECTION_FILES = \ $(srcdir)/account.c $(srcdir)/account.h \ $(srcdir)/account-channel-request.c $(srcdir)/account-channel-request.h \ $(srcdir)/account-manager.c $(srcdir)/account-manager.h \ + $(srcdir)/automatic-client-factory.c $(srcdir)/automatic-client-factory.h \ $(srcdir)/automatic-proxy-factory.c $(srcdir)/automatic-proxy-factory.h \ $(srcdir)/basic-proxy-factory.c $(srcdir)/basic-proxy-factory.h \ $(srcdir)/client-channel-factory.c $(srcdir)/client-channel-factory.h \ diff --git a/telepathy-glib/stream-tube-channel.c b/telepathy-glib/stream-tube-channel.c index 0e644b0..639fa87 100644 --- a/telepathy-glib/stream-tube-channel.c +++ b/telepathy-glib/stream-tube-channel.c @@ -62,6 +62,7 @@ #define DEBUG_FLAG TP_DEBUG_CHANNEL #include "telepathy-glib/debug-internal.h" +#include "telepathy-glib/automatic-client-factory-internal.h" #include "_gen/signals-marshal.h" @@ -494,6 +495,17 @@ tp_stream_tube_channel_new (TpConnection *conn, const GHashTable *immutable_properties, GError **error) { + return _tp_stream_tube_channel_new_with_factory (conn, object_path, + immutable_properties, error, NULL); +} + +TpStreamTubeChannel * +_tp_stream_tube_channel_new_with_factory (TpConnection *conn, + const gchar *object_path, + const GHashTable *immutable_properties, + GError **error, + TpSimpleClientFactory *factory) +{ TpProxy *conn_proxy = (TpProxy *) conn; g_return_val_if_fail (TP_IS_CONNECTION (conn), NULL); @@ -510,6 +522,7 @@ tp_stream_tube_channel_new (TpConnection *conn, "object-path", object_path, "handle-type", (guint) TP_UNKNOWN_HANDLE_TYPE, "channel-properties", immutable_properties, + "factory", factory, NULL); } diff --git a/telepathy-glib/text-channel.c b/telepathy-glib/text-channel.c index 78956f5..9aca2c7 100644 --- a/telepathy-glib/text-channel.c +++ b/telepathy-glib/text-channel.c @@ -62,6 +62,7 @@ #define DEBUG_FLAG TP_DEBUG_CHANNEL #include "telepathy-glib/debug-internal.h" +#include "telepathy-glib/automatic-client-factory-internal.h" #include "_gen/signals-marshal.h" @@ -1175,6 +1176,17 @@ tp_text_channel_new (TpConnection *conn, const GHashTable *immutable_properties, GError **error) { + return _tp_text_channel_new_with_factory (conn, object_path, + immutable_properties, error, NULL); +} + +TpTextChannel * +_tp_text_channel_new_with_factory (TpConnection *conn, + const gchar *object_path, + const GHashTable *immutable_properties, + GError **error, + TpSimpleClientFactory *factory) +{ TpProxy *conn_proxy = (TpProxy *) conn; g_return_val_if_fail (TP_IS_CONNECTION (conn), NULL); @@ -1191,6 +1203,7 @@ tp_text_channel_new (TpConnection *conn, "object-path", object_path, "handle-type", (guint) TP_UNKNOWN_HANDLE_TYPE, "channel-properties", immutable_properties, + "factory", factory, NULL); } -- 1.7.4.1