From 0c0a6b13c642be39aa79cc8dc67d1eeb5f2045a5 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 | 45 ++++ telepathy-glib/automatic-client-factory.c | 215 ++++++++++++++++++++ telepathy-glib/automatic-client-factory.h | 66 ++++++ telepathy-glib/file-transfer-channel.c | 14 ++- telepathy-glib/introspection.am | 1 + telepathy-glib/stream-tube-channel.c | 13 ++ telepathy-glib/telepathy-glib.h | 1 + telepathy-glib/text-channel.c | 13 ++ 11 files changed, 387 insertions(+), 1 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 006e11c..1fb2de0 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 a02e4da..12da4cb 100644 --- a/docs/reference/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib-sections.txt @@ -5711,3 +5711,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 aa47439..39c4c47 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 \ @@ -145,6 +146,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..89db0c4 --- /dev/null +++ b/telepathy-glib/automatic-client-factory-internal.h @@ -0,0 +1,45 @@ +/* + * 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); + +TpFileTransferChannel *_tp_file_transfer_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..c72b851 --- /dev/null +++ b/telepathy-glib/automatic-client-factory.c @@ -0,0 +1,215 @@ +/* + * 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 #TpFileTransferChannel, if the channel is of type + * %TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER; + * + * + * 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 + * + * + * %TP_FILE_TRANSFER_CHANNEL_FEATURE_CORE + * for #TpFileTransferChannel + * + * + * + * + * 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 + +#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) + +#define chainup ((TpSimpleClientFactoryClass *) \ + tp_automatic_client_factory_parent_class) + +static TpChannel * +create_channel_impl (TpSimpleClientFactory *self, + TpConnection *conn, + const gchar *object_path, + const GHashTable *properties, + GError **error) +{ + const gchar *chan_type; + + chan_type = tp_asv_get_string (properties, TP_PROP_CHANNEL_CHANNEL_TYPE); + + if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) + { + return (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)) + { + return (TpChannel *) _tp_text_channel_new_with_factory (conn, + object_path, properties, error, self); + } + + DEBUG ("channel %s doesn't implement Messages so we can't create " + "a TpTextChannel", object_path); + } + else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER)) + { + return (TpChannel *) _tp_file_transfer_channel_new_with_factory (conn, + object_path, properties, error, self); + } + + /* Chainup on parent implementation as fallback */ + return chainup->create_channel (self, conn, object_path, properties, error); +} + +static GArray * +dup_channel_features_impl (TpSimpleClientFactory *self, + TpChannel *channel) +{ + 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); + } + else if (TP_IS_FILE_TRANSFER_CHANNEL (channel)) + { + feature = TP_FILE_TRANSFER_CHANNEL_FEATURE_CORE; + 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->create_channel = create_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..10d6c4b --- /dev/null +++ b/telepathy-glib/automatic-client-factory.h @@ -0,0 +1,66 @@ +/* + * 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 +#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/file-transfer-channel.c b/telepathy-glib/file-transfer-channel.c index bd5dc75..efe0113 100644 --- a/telepathy-glib/file-transfer-channel.c +++ b/telepathy-glib/file-transfer-channel.c @@ -58,8 +58,8 @@ #include #define DEBUG_FLAG TP_DEBUG_CHANNEL +#include "telepathy-glib/automatic-client-factory-internal.h" #include "telepathy-glib/debug-internal.h" - #include "_gen/signals-marshal.h" #include @@ -569,6 +569,17 @@ tp_file_transfer_channel_new (TpConnection *conn, const GHashTable *immutable_properties, GError **error) { + return _tp_file_transfer_channel_new_with_factory (conn, object_path, + immutable_properties, error, NULL); +} + +TpFileTransferChannel * +_tp_file_transfer_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); @@ -585,6 +596,7 @@ tp_file_transfer_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/introspection.am b/telepathy-glib/introspection.am index 1bb9a5c..827b9a8 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 64c7c3a..19d8670 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/telepathy-glib.h b/telepathy-glib/telepathy-glib.h index a7cbb17..0e2c433 100644 --- a/telepathy-glib/telepathy-glib.h +++ b/telepathy-glib/telepathy-glib.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/telepathy-glib/text-channel.c b/telepathy-glib/text-channel.c index a2683fb..22c623f 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" @@ -1187,6 +1188,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); @@ -1203,6 +1215,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