diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2011-09-29 16:49:35 +0100 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2011-09-29 16:49:35 +0100 |
commit | 6409cea39bfd9e9e6f71b4206115eda490520e9b (patch) | |
tree | 369c7c2b5e0ae2d4bef8e20f9ecaf321fb9f36eb | |
parent | 51c2d872e072a68a5a54d6f5ddaa268c029d3b80 (diff) | |
parent | a9f652cfa4485e5ba350ad9d6d78cd50ef521758 (diff) |
Merge branch 'gabble'
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | docs/reference/telepathy-ytstenut-glib-docs.sgml | 1 | ||||
-rw-r--r-- | docs/reference/telepathy-ytstenut-glib-sections.txt | 18 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/Makefile.am | 2 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/account-manager.c | 75 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/account-manager.h | 3 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/channel.c | 33 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/channel.h | 5 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/client-factory.c | 113 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/client-factory.h | 63 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/client.c | 10 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/tests/Makefile.am | 7 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/tests/server-client-ping.c | 321 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/tests/server-client-pong.c | 159 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/tests/server-nosey-status.c | 318 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/tests/server-passing-service.c | 124 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/tests/server-passing-status.c | 203 |
18 files changed, 1448 insertions, 14 deletions
@@ -50,6 +50,11 @@ tp-glib-tools/telepathy-glib-env /telepathy-ytstenut-glib/tests/nosey-status /telepathy-ytstenut-glib/tests/passing-service /telepathy-ytstenut-glib/tests/passing-status +/telepathy-ytstenut-glib/tests/server-client-ping +/telepathy-ytstenut-glib/tests/server-client-pong +/telepathy-ytstenut-glib/tests/server-nosey-status +/telepathy-ytstenut-glib/tests/server-passing-service +/telepathy-ytstenut-glib/tests/server-passing-status /docs/reference/xml /docs/reference/html diff --git a/configure.ac b/configure.ac index dbae19e..3f4ba54 100644 --- a/configure.ac +++ b/configure.ac @@ -187,7 +187,7 @@ if test x$enable_glib = xyes; then AC_SUBST(DBUS_LIBS) dnl Check for telepathy-glib - PKG_CHECK_MODULES(TP_GLIB, [telepathy-glib >= 0.13.14]) + PKG_CHECK_MODULES(TP_GLIB, [telepathy-glib >= 0.15.5]) AC_SUBST(TP_GLIB_CFLAGS) AC_SUBST(TP_GLIB_LIBS) diff --git a/docs/reference/telepathy-ytstenut-glib-docs.sgml b/docs/reference/telepathy-ytstenut-glib-docs.sgml index 8cd1ce4..c6d0c3d 100644 --- a/docs/reference/telepathy-ytstenut-glib-docs.sgml +++ b/docs/reference/telepathy-ytstenut-glib-docs.sgml @@ -17,6 +17,7 @@ <title>Using Ytstenut Objects</title> <xi:include href="xml/account-manager.xml"/> <xi:include href="xml/channel.xml"/> + <xi:include href="xml/client-factory.xml"/> <xi:include href="xml/channel-factory.xml"/> <xi:include href="xml/client.xml"/> <xi:include href="xml/status.xml"/> diff --git a/docs/reference/telepathy-ytstenut-glib-sections.txt b/docs/reference/telepathy-ytstenut-glib-sections.txt index afb6824..ad45c85 100644 --- a/docs/reference/telepathy-ytstenut-glib-sections.txt +++ b/docs/reference/telepathy-ytstenut-glib-sections.txt @@ -6,6 +6,7 @@ TpYtsAccountManager TpYtsAccountManagerClass tp_yts_account_manager_new tp_yts_account_manager_dup +tp_yts_account_manager_ensure_account tp_yts_account_manager_get_account_async tp_yts_account_manager_get_account_finish tp_yts_account_manager_hold @@ -111,6 +112,7 @@ TP_YTS_SVC_STATUS_GET_CLASS TpYtsChannel TpYtsChannelClass tp_yts_channel_new_from_properties +tp_yts_channel_new_with_factory tp_yts_channel_request_async tp_yts_channel_request_finish tp_yts_channel_reply_async @@ -168,6 +170,22 @@ TP_IS_YTS_CHANNEL_FACTORY_CLASS </SECTION> <SECTION> +<FILE>client-factory</FILE> +tp_yts_client_factory_new +TpYtsClientFactory +TpYtsClientFactoryClass +<SUBSECTION Standard> +tp_yts_client_factory_get_type +TpYtsClientFactoryPrivate +TP_YTS_CLIENT_FACTORY +TP_YTS_CLIENT_FACTORY_CLASS +TP_YTS_CLIENT_FACTORY_GET_CLASS +TP_TYPE_YTS_CLIENT_FACTORY +TP_IS_YTS_CLIENT_FACTORY +TP_IS_YTS_CLIENT_FACTORY_CLASS +</SECTION> + +<SECTION> <FILE>svc-channel</FILE> TpYtsSvcChannel TpYtsSvcChannelClass diff --git a/telepathy-ytstenut-glib/Makefile.am b/telepathy-ytstenut-glib/Makefile.am index bdb8e71..28a7243 100644 --- a/telepathy-ytstenut-glib/Makefile.am +++ b/telepathy-ytstenut-glib/Makefile.am @@ -16,6 +16,8 @@ libtelepathy_ytstenut_glib_la_SOURCES = \ channel.h \ channel-factory.c \ channel-factory.h \ + client-factory.c \ + client-factory.h \ client.c \ client.h \ generated.h \ diff --git a/telepathy-ytstenut-glib/account-manager.c b/telepathy-ytstenut-glib/account-manager.c index 19c901c..5389927 100644 --- a/telepathy-ytstenut-glib/account-manager.c +++ b/telepathy-ytstenut-glib/account-manager.c @@ -24,6 +24,8 @@ #include "account-manager.h" +#include "client-factory.h" + #include <telepathy-glib/defs.h> #include <telepathy-glib/gtypes.h> #include <telepathy-glib/interfaces.h> @@ -79,18 +81,46 @@ G_DEFINE_TYPE (TpYtsAccountManager, tp_yts_account_manager, TP_TYPE_PROXY); +struct _TpYtsAccountManagerPrivate +{ + /* We have to store this and not simply subclass it because that + * would change TpProxy:object-path from + * /org/freedesktop/Telepathy/AccountManager to + * /com/meego/xpmn/ytstenut/AccountManager which would mean loads of + * things (like how TpAM calls GetAll on ofdTp.AM) would stop + * working. This is a shame. Oh well. */ + TpAccountManager *account_manager; +}; + static void tp_yts_account_manager_init (TpYtsAccountManager *self) { + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TYPE_YTS_ACCOUNT_MANAGER, + TpYtsAccountManagerPrivate); +} + +static void +tp_yts_account_manager_dispose (GObject *object) +{ + TpYtsAccountManager *self = TP_YTS_ACCOUNT_MANAGER (object); + TpYtsAccountManagerPrivate *priv = self->priv; + tp_clear_object (&priv->account_manager); + + G_OBJECT_CLASS (tp_yts_account_manager_parent_class)->dispose (object); } static void tp_yts_account_manager_class_init (TpYtsAccountManagerClass *klass) { + GObjectClass *object_class = (GObjectClass *) klass; TpProxyClass *proxy_class = (TpProxyClass *) klass; GType tp_type = TP_TYPE_YTS_ACCOUNT_MANAGER; + g_type_class_add_private (klass, sizeof (TpYtsAccountManagerPrivate)); + + object_class->dispose = tp_yts_account_manager_dispose; + proxy_class->interface = TP_YTS_IFACE_QUARK_ACCOUNT_MANAGER; tp_proxy_init_known_interfaces (); @@ -116,6 +146,7 @@ TpYtsAccountManager * tp_yts_account_manager_new (TpDBusDaemon *bus_daemon) { TpYtsAccountManager *self; + TpSimpleClientFactory *factory; g_return_val_if_fail (TP_IS_DBUS_DAEMON (bus_daemon), NULL); @@ -126,6 +157,10 @@ tp_yts_account_manager_new (TpDBusDaemon *bus_daemon) "object-path", TP_YTS_ACCOUNT_MANAGER_OBJECT_PATH, NULL)); + factory = tp_yts_client_factory_new (bus_daemon); + self->priv->account_manager = tp_account_manager_new_with_factory (factory); + g_object_unref (factory); + return self; } @@ -150,6 +185,7 @@ TpYtsAccountManager * tp_yts_account_manager_dup (void) { TpDBusDaemon *dbus; + TpYtsAccountManager *self; if (starter_account_manager_proxy != NULL) return g_object_ref (starter_account_manager_proxy); @@ -166,9 +202,42 @@ tp_yts_account_manager_dup (void) g_object_unref (dbus); + self = starter_account_manager_proxy; + + tp_account_manager_set_default (self->priv->account_manager); + return starter_account_manager_proxy; } +/** + * tp_yts_account_manager_ensure_account: + * @self: a #TpYtsAccountManager + * @path: the account object path + * @error: a #GError to fill when an error is encountered + * + * Using the #TpYtsAccountManager ensure an account with object path + * @path. This should be used instead of tp_account_new() as it means + * the #TpYtsClientFactory will be propagated through to the new + * account and so new channel objects will be turned into + * #TpYtsChannel<!-- -->s. + * + * Returns: a #TpAccount + */ +TpAccount * +tp_yts_account_manager_ensure_account (TpYtsAccountManager *self, + const gchar *path, + GError **error) +{ + TpSimpleClientFactory *factory; + + g_return_val_if_fail (TP_IS_YTS_ACCOUNT_MANAGER (self), NULL); + g_return_val_if_fail (!tp_str_empty (path), NULL); + + factory = tp_proxy_get_factory (self->priv->account_manager); + + return tp_simple_client_factory_ensure_account (factory, path, NULL, error); +} + static void on_account_prepared (GObject *source, GAsyncResult *result, @@ -203,6 +272,7 @@ on_account_manager_get_account_returned (TpProxy *proxy, gpointer user_data, GObject *weak_object) { + TpYtsAccountManager *self = TP_YTS_ACCOUNT_MANAGER (weak_object); GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data); TpAccount *account; GError *err = NULL; @@ -211,7 +281,10 @@ on_account_manager_get_account_returned (TpProxy *proxy, if (error == NULL) { path = g_value_get_boxed (value); - account = tp_account_new (tp_proxy_get_dbus_daemon (proxy), path, &err); + + account = tp_simple_client_factory_ensure_account ( + tp_proxy_get_factory (self->priv->account_manager), + path, NULL, &err); if (err == NULL) { tp_proxy_prepare_async (account, NULL, on_account_prepared, diff --git a/telepathy-ytstenut-glib/account-manager.h b/telepathy-ytstenut-glib/account-manager.h index f591819..71e8828 100644 --- a/telepathy-ytstenut-glib/account-manager.h +++ b/telepathy-ytstenut-glib/account-manager.h @@ -71,6 +71,9 @@ TpYtsAccountManager *tp_yts_account_manager_new (TpDBusDaemon *bus_daemon) TpYtsAccountManager *tp_yts_account_manager_dup (void) G_GNUC_WARN_UNUSED_RESULT; +TpAccount *tp_yts_account_manager_ensure_account (TpYtsAccountManager *self, + const gchar *path, GError **error); + void tp_yts_account_manager_get_account_async (TpYtsAccountManager *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); diff --git a/telepathy-ytstenut-glib/channel.c b/telepathy-ytstenut-glib/channel.c index 07de6c9..029f0e6 100644 --- a/telepathy-ytstenut-glib/channel.c +++ b/telepathy-ytstenut-glib/channel.c @@ -270,16 +270,46 @@ tp_yts_channel_class_init (TpYtsChannelClass *klass) * @immutable_properties: The immutable properties of the channel. * @error: If not %NULL, used to raise an error when %NULL is returned. * + * The same as tp_yts_channel_with_factory() but without the client + * factory. + * + * This function should not be used. tp_yts_channel_with_factory() + * should be used with an appropriate client factory. + * + * Returns: A newly allocated #TpYtsChannel object. + */ +TpChannel * +tp_yts_channel_new_from_properties (TpConnection *conn, + const gchar *object_path, + GHashTable *immutable_properties, + GError **error) +{ + return tp_yts_channel_new_with_factory (NULL, conn, object_path, + immutable_properties, error); +} + +/** + * tp_yts_channel_new_with_factory: + * @factory: a #TpSimpleClientFactory + * @conn: The telepathy connection + * @object_path: The DBus object path of the channel. + * @immutable_properties: The immutable properties of the channel. + * @error: If not %NULL, used to raise an error when %NULL is returned. + * * Create a new #TpYtsChannel proxy object for a channel that exists in the * Ytstenut DBus implementation. * * In order to request a new outgoing channel use * tp_yts_client_request_channel_async() instead of this function. * + * Note that this function should only be called for incoming channels + * by the client factory, @factory. + * * Returns: A newly allocated #TpYtsChannel object. */ TpChannel * -tp_yts_channel_new_from_properties (TpConnection *conn, +tp_yts_channel_new_with_factory (TpSimpleClientFactory *factory, + TpConnection *conn, const gchar *object_path, GHashTable *immutable_properties, GError **error) @@ -301,6 +331,7 @@ tp_yts_channel_new_from_properties (TpConnection *conn, "object-path", object_path, "handle-type", (guint) TP_UNKNOWN_HANDLE_TYPE, "channel-properties", immutable_properties, + "factory", factory, NULL)); finally: diff --git a/telepathy-ytstenut-glib/channel.h b/telepathy-ytstenut-glib/channel.h index cabacbe..c1817f6 100644 --- a/telepathy-ytstenut-glib/channel.h +++ b/telepathy-ytstenut-glib/channel.h @@ -27,6 +27,7 @@ #include <telepathy-glib/dbus.h> #include <telepathy-glib/defs.h> #include <telepathy-glib/proxy.h> +#include <telepathy-glib/simple-client-factory.h> G_BEGIN_DECLS @@ -63,6 +64,10 @@ GType tp_yts_channel_get_type (void); TpChannel *tp_yts_channel_new_from_properties (TpConnection *conn, const gchar *object_path, GHashTable *immutable_properties, GError **error); +TpChannel *tp_yts_channel_new_with_factory (TpSimpleClientFactory *factory, + TpConnection *conn, const gchar *object_path, + GHashTable *immutable_properties, GError **error); + void tp_yts_channel_request_async (TpYtsChannel *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); diff --git a/telepathy-ytstenut-glib/client-factory.c b/telepathy-ytstenut-glib/client-factory.c new file mode 100644 index 0000000..efed607 --- /dev/null +++ b/telepathy-ytstenut-glib/client-factory.c @@ -0,0 +1,113 @@ +/* + * client-factory.c - client factory for TpYtsChannel + * + * Copyright (C) 2011 Intel Corp. + * + * 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 + */ + +#include "config.h" + +#include "client-factory.h" +#include "channel.h" + +#include <telepathy-glib/defs.h> +#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/util.h> + +#define DEBUG(msg, ...) \ + g_debug ("%s: " msg, G_STRFUNC, ##__VA_ARGS__) + +/** + * SECTION:client-factory + * @title: TpYtsClientFactory + * @short_description: client factory for #TpYtsChannel + * + * A #TpSimpleClientFactory for creating #TpYtsChannel objects. In general + * you won't need to use this object directly because #TpYtsAccountManager creates + * and uses it as necessary. + */ + +/** + * TpYtsClientFactory: + * + * A factory for creating #TpYtsChannel objects. + */ + +/** + * TpYtsClientFactoryClass: + * + * The class of a #TpYtsClientFactory. + */ + +G_DEFINE_TYPE (TpYtsClientFactory, tp_yts_client_factory, + TP_TYPE_AUTOMATIC_CLIENT_FACTORY) + +#define chainup ((TpSimpleClientFactoryClass *) \ + tp_yts_client_factory_parent_class) + +static void +tp_yts_client_factory_init (TpYtsClientFactory *self) +{ + +} + +static TpChannel * +tp_yts_client_factory_obj_create_channel (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_YTS_IFACE_CHANNEL)) + { + return tp_yts_channel_new_with_factory (self, conn, object_path, + (GHashTable *) properties, error); + } + + /* Chainup on parent implementation as fallback */ + return chainup->create_channel (self, conn, object_path, properties, error); +} + +static void +tp_yts_client_factory_class_init (TpYtsClientFactoryClass *klass) +{ + TpSimpleClientFactoryClass *simple_class = (TpSimpleClientFactoryClass *) klass; + + simple_class->create_channel = tp_yts_client_factory_obj_create_channel; +} + +/** + * tp_yts_client_factory_new: + * + * Create a new #TpYtsClientFactory object. In general you won't need to + * call this function because #TpYtsClient creates #TpYtsClientFactory + * objects as necessary. + * + * Returns: A newly allocated factory object. + */ +TpSimpleClientFactory * +tp_yts_client_factory_new (TpDBusDaemon *dbus) +{ + g_return_val_if_fail (TP_IS_DBUS_DAEMON (dbus), NULL); + + return g_object_new (TP_TYPE_YTS_CLIENT_FACTORY, + "dbus-daemon", dbus, + NULL); +} diff --git a/telepathy-ytstenut-glib/client-factory.h b/telepathy-ytstenut-glib/client-factory.h new file mode 100644 index 0000000..a5e543f --- /dev/null +++ b/telepathy-ytstenut-glib/client-factory.h @@ -0,0 +1,63 @@ +/* + * client-factory.h - client factory for TpYtsClient + * + * Copyright (C) 2011 Intel Corp. + * + * 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_YTS_CLIENT_FACTORY_H +#define TP_YTS_CLIENT_FACTORY_H + +#include <telepathy-glib/automatic-client-factory.h> + +G_BEGIN_DECLS + +typedef struct _TpYtsClientFactory TpYtsClientFactory; +typedef struct _TpYtsClientFactoryClass TpYtsClientFactoryClass; +typedef struct _TpYtsClientFactoryPrivate TpYtsClientFactoryPrivate; + +struct _TpYtsClientFactory { + /*<private>*/ + TpAutomaticClientFactory parent; + TpYtsClientFactoryPrivate *priv; +}; + +struct _TpYtsClientFactoryClass { + /*<private>*/ + TpAutomaticClientFactoryClass parent_class; + GCallback _padding[7]; +}; + +GType tp_yts_client_factory_get_type (void); + +#define TP_TYPE_YTS_CLIENT_FACTORY (tp_yts_client_factory_get_type ()) +#define TP_YTS_CLIENT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + TP_TYPE_YTS_CLIENT_FACTORY, TpYtsClientFactory)) +#define TP_YTS_CLIENT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + TP_TYPE_YTS_CLIENT_FACTORY, TpYtsClientFactoryClass)) +#define TP_IS_YTS_CLIENT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + TP_TYPE_YTS_CLIENT_FACTORY)) +#define TP_IS_YTS_CLIENT_FACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TYPE_YTS_CLIENT_FACTORY)) +#define TP_YTS_CLIENT_FACTORY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TYPE_YTS_CLIENT_FACTORY, \ + TpYtsClientFactoryClass)) + +TpSimpleClientFactory *tp_yts_client_factory_new (TpDBusDaemon *dbus); + +G_END_DECLS + +#endif diff --git a/telepathy-ytstenut-glib/client.c b/telepathy-ytstenut-glib/client.c index 154a1f9..245e471 100644 --- a/telepathy-ytstenut-glib/client.c +++ b/telepathy-ytstenut-glib/client.c @@ -22,7 +22,6 @@ #include "client.h" #include "channel.h" -#include "channel-factory.h" #include <telepathy-glib/account-channel-request.h> #include <telepathy-glib/contact.h> @@ -82,7 +81,6 @@ static gint signals[LAST_SIGNAL] = { 0, }; struct _TpYtsClientPrivate { gchar *service_name; TpAccount *account; - TpClientChannelFactory *factory; GQueue incoming_channels; }; @@ -120,7 +118,6 @@ tp_yts_client_init (TpYtsClient *self) TpYtsClientPrivate); g_queue_init (&self->priv->incoming_channels); - self->priv->factory = tp_yts_channel_factory_new (); } static void @@ -134,8 +131,6 @@ tp_yts_client_constructed (GObject *obj) _tp_yts_register_dbus_glib_marshallers (); - tp_base_client_set_channel_factory (client, self->priv->factory); - tp_base_client_set_handler_bypass_approval (client, FALSE); tp_base_client_take_handler_filter (client, tp_asv_new ( @@ -215,8 +210,6 @@ tp_yts_client_dispose (GObject *object) TpYtsClient *self = TP_YTS_CLIENT (object); TpChannel *channel; - tp_clear_object (&self->priv->factory); - while (!g_queue_is_empty (&self->priv->incoming_channels)) { channel = g_queue_pop_head (&self->priv->incoming_channels); @@ -667,9 +660,6 @@ tp_yts_client_request_channel_async (TpYtsClient *self, channel_request = tp_account_channel_request_new (self->priv->account, request_properties, 0); - tp_account_channel_request_set_channel_factory (channel_request, - self->priv->factory); - tp_account_channel_request_create_and_handle_channel_async (channel_request, cancellable, on_channel_request_create_and_handle_channel_returned, res); diff --git a/telepathy-ytstenut-glib/tests/Makefile.am b/telepathy-ytstenut-glib/tests/Makefile.am index 6d3e257..71b7260 100644 --- a/telepathy-ytstenut-glib/tests/Makefile.am +++ b/telepathy-ytstenut-glib/tests/Makefile.am @@ -20,4 +20,9 @@ noinst_PROGRAMS = \ client-ping \ nosey-status \ passing-service \ - passing-status + passing-status \ + server-client-pong \ + server-client-ping \ + server-nosey-status \ + server-passing-service \ + server-passing-status diff --git a/telepathy-ytstenut-glib/tests/server-client-ping.c b/telepathy-ytstenut-glib/tests/server-client-ping.c new file mode 100644 index 0000000..8b60b2e --- /dev/null +++ b/telepathy-ytstenut-glib/tests/server-client-ping.c @@ -0,0 +1,321 @@ +/* + * client-ping.c - send a message to another service + * + * Copyright (C) 2011 Intel Corp. + * + * 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 + */ + +#include "config.h" + +#include <telepathy-ytstenut-glib/telepathy-ytstenut-glib.h> + +#include <telepathy-glib/telepathy-glib.h> + +static GMainLoop *loop = NULL; + +static const gchar *local_service = NULL; +static const gchar *remote_service = NULL; +static const gchar *contact_id = NULL; + +static void +getoutofhere (void) +{ + g_main_loop_quit (loop); +} + +static void +replied_cb (TpYtsChannel *proxy, + GHashTable *attributes, + const gchar *body, + gpointer user_data, + GObject *weak_object) +{ + GHashTableIter iter; + gpointer key, value; + + g_print ("Replied! Here are the reply attributes:\n"); + + g_hash_table_iter_init (&iter, attributes); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + g_print (" * %s = %s\n", (const gchar *) key, (const gchar *) value); + } + + g_print ("body: %s\n", body); + + getoutofhere (); +} + +static void +failed_cb (TpYtsChannel *proxy, + guint error_type, + const gchar *stanza_error_name, + const gchar *ytstenut_error_name, + const gchar *text, + gpointer user_data, + GObject *weak_object) +{ + g_print ("Got a fail!\n"); + + g_print ("%u, %s, %s, %s\n", error_type, stanza_error_name, ytstenut_error_name, text); + + getoutofhere (); +} + +static void +closed_cb (TpChannel *channel, + gpointer user_data, + GObject *weak_object) +{ + g_print ("Channel closed\n"); + + getoutofhere (); +} + +static void +request_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + + if (!tp_yts_channel_request_finish ( + TP_YTS_CHANNEL (source_object), result, &error)) + { + g_printerr ("Failed to Request on channel: %s\n", error->message); + getoutofhere (); + } + else + { + /* The channel was successfully sent to the other side, let's + * see what happens now. */ + g_print ("Requested! Now we play the waiting game!\n"); + } + + g_clear_error (&error); +} + +static void +request_channel_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpYtsChannel *channel; + GError *error = NULL; + + channel = tp_yts_client_request_channel_finish ( + TP_YTS_CLIENT (source_object), result, &error); + + if (channel == NULL) + { + g_printerr ("Failed to request channel: %s\n", error->message); + getoutofhere (); + } + else + { + g_print ("Successfully requested channel!\n"); + + /* Connect to these three signals so we can see what's going + * on. */ + tp_yts_channel_connect_to_replied (channel, replied_cb, + NULL, NULL, NULL, NULL); + tp_yts_channel_connect_to_failed (channel, failed_cb, + NULL, NULL, NULL, NULL); + tp_cli_channel_connect_to_closed (TP_CHANNEL (channel), closed_cb, + NULL, NULL, NULL, NULL); + + tp_yts_channel_request_async (channel, NULL, request_cb, NULL); + + g_print ("Request called...\n"); + } + + g_object_unref (source_object); + g_clear_error (&error); +} + +static void +get_contact_cb (TpConnection *connection, + guint n_contacts, + TpContact * const *contacts, + const gchar * const *requested_ids, + GHashTable *failed_id_errors, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + TpAccount *account = user_data; + + if (error != NULL) + { + g_printerr ("Failed to get contact: %s\n", error->message); + getoutofhere (); + } + else + { + TpYtsClient *client; + TpContact *contact = contacts[0]; + + /* Now we have everything prepared to continue, let's create the + * Ytstenut channel handler with service name specified on the + * command line. */ + client = tp_yts_client_new (local_service, account); + tp_yts_client_register (client, NULL); + + /* So let's request a channel to ourselves. It's to ourselves + * because that's where client-pong is being run (hopefully!) */ + tp_yts_client_request_channel_async (client, + contact, /* the TpContact we want the channel to go to */ + remote_service, /* the remote service name */ + TP_YTS_REQUEST_TYPE_GET, /* request type */ + NULL, /* an a{ss} of request attributes or nothing */ + NULL, /* the UTF-8 XML body */ + NULL, /* a GCancellable */ + request_channel_cb, /* callback */ + NULL); /* user data */ + + g_print ("requested...\n"); + } + + g_object_unref (account); +} + +static void +connection_prepared_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpAccount *account = user_data; + GError *error = NULL; + + if (!tp_proxy_prepare_finish (source_object, result, &error)) + { + g_printerr ("Failed to prepare connection: %s\n", error->message); + getoutofhere (); + } + else + { + TpConnection *connection; + const gchar * const ids[] = { contact_id, NULL }; + + connection = tp_account_get_connection (account); + + g_print ("trying to get TpContact for %s\n", contact_id); + + tp_connection_get_contacts_by_id (connection, 1, + ids, 0, NULL, get_contact_cb, + account, NULL, NULL); + } + + g_clear_error (&error); +} + +static void +notify_connection_cb (GObject *gobject, + GParamSpec *pspec, + gpointer user_data) +{ + TpAccount *account = TP_ACCOUNT (gobject); + GQuark features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 }; + TpConnection *connection = tp_account_get_connection (account); + + if (connection == NULL) + return; + + g_print ("Trying to prepare connection, this will only continue " + "if the account is connected...\n"); + + /* account already reffed */ + tp_proxy_prepare_async (connection, features, connection_prepared_cb, + account); +} + +static void +got_account (TpAccount *account) +{ + /* We got the account fine, but we need to ensure some features + * on it so we have the :self-contact property set. */ + TpConnection *connection = tp_account_get_connection (account); + + if (connection != NULL) + { + notify_connection_cb (g_object_ref (account), NULL, NULL); + } + else + { + g_signal_connect (account, "notify::connection", + G_CALLBACK (notify_connection_cb), g_object_ref (account)); + } +} + +static void +account_prepared_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpAccount *account = TP_ACCOUNT (source_object); + GError *error = NULL; + + if (!tp_account_prepare_finish (account, result, &error)) + { + g_print ("failed to prepare account: %s\n", error->message); + g_clear_error (&error); + getoutofhere (); + return; + } + + got_account (account); +} + +int +main (int argc, + char **argv) +{ + TpYtsAccountManager *am; + TpAccount *account; + gchar *path; + + if (argc < 5 + || !tp_dbus_check_valid_interface_name (argv[3], NULL) + || !tp_dbus_check_valid_interface_name (argv[4], NULL)) + { + g_print ("usage: %s [account name] [contact id] [local service name] [remote service name]\n", argv[0]); + return 1; + } + + g_type_init (); + + contact_id = argv[2]; + local_service = argv[3]; + remote_service = argv[4]; + + am = tp_yts_account_manager_dup (); + + path = g_strdup_printf ("%s%s", TP_ACCOUNT_OBJECT_PATH_BASE, argv[1]); + account = tp_yts_account_manager_ensure_account (am, path, NULL); + g_free (path); + + tp_account_prepare_async (account, NULL, account_prepared_cb, NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_main_loop_unref (loop); + + g_object_unref (account); + g_object_unref (am); + + return 0; +} diff --git a/telepathy-ytstenut-glib/tests/server-client-pong.c b/telepathy-ytstenut-glib/tests/server-client-pong.c new file mode 100644 index 0000000..9abe780 --- /dev/null +++ b/telepathy-ytstenut-glib/tests/server-client-pong.c @@ -0,0 +1,159 @@ +/* + * client-pong.c - return a message when an incoming channel appears + * + * Copyright (C) 2011 Intel Corp. + * + * 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 + */ + +#include "config.h" + +#include <telepathy-ytstenut-glib/telepathy-ytstenut-glib.h> + +#include <telepathy-glib/account.h> + +static GMainLoop *loop = NULL; + +static void +getoutofhere (void) +{ + g_main_loop_quit (loop); +} + +static void +reply_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpYtsChannel *channel = TP_YTS_CHANNEL (source_object); + GError *error = NULL; + + /* Done */ + + if (!tp_yts_channel_reply_finish (channel, result, &error)) + g_printerr ("Failed to reply: %s\n", error->message); + else + g_print ("Successfully replied\n"); + + g_clear_error (&error); + getoutofhere (); +} + +static void +received_channels (TpYtsClient *client, + gpointer user_data) +{ + TpYtsChannel *channel; + + /* ::received-channels was emitted, so let's reply to each channel + * which has popped up. */ + + g_print ("received channels\n"); + + while ((channel = tp_yts_client_accept_channel (client)) != NULL) + { + /* We'll create some rubbish to put in the request attribute + * argument of Reply */ + GHashTable *tmp = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (tmp, "nyan", "cat"); + + g_print ("request type: %u\n", + tp_yts_channel_get_request_type (channel)); + g_print ("request attributes: %p\n", + tp_yts_channel_get_request_attributes (channel)); + g_print ("request body: %s\n", + tp_yts_channel_get_request_body (channel)); + g_print ("target service: %s\n", + tp_yts_channel_get_target_service (channel)); + g_print ("initiator service: %s\n", + tp_yts_channel_get_initiator_service (channel)); + + /* Call Reply() */ + tp_yts_channel_reply_async (channel, tmp, NULL, + NULL, reply_cb, NULL); + } +} + +static void +got_account (TpAccount *account, + gpointer user_data) +{ + TpYtsClient *client; + + /* Now we can create the Ytstenut channel handler with service + * name specified on the command line. */ + client = tp_yts_client_new ((const gchar *) user_data, account); + g_signal_connect (client, "received-channels", + G_CALLBACK (received_channels), NULL); + + tp_yts_client_register (client, NULL); + + g_print ("listening...\n"); +} + +static void +account_prepared_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpAccount *account = TP_ACCOUNT (source_object); + GError *error = NULL; + + if (!tp_account_prepare_finish (account, result, &error)) + { + g_print ("failed to prepare account: %s\n", error->message); + g_clear_error (&error); + getoutofhere (); + return; + } + + got_account (account, user_data); +} + +int +main (int argc, + char **argv) +{ + TpYtsAccountManager *am; + TpAccount *account; + gchar *path; + + if (argc < 3 + || !tp_dbus_check_valid_interface_name (argv[2], NULL)) + { + g_print ("usage: %s [account] [service name]\n", argv[0]); + return 1; + } + + g_type_init (); + + am = tp_yts_account_manager_dup (); + + path = g_strdup_printf ("%s%s", TP_ACCOUNT_OBJECT_PATH_BASE, argv[1]); + account = tp_yts_account_manager_ensure_account (am, path, NULL); + g_free (path); + + tp_account_prepare_async (account, NULL, account_prepared_cb, argv[2]); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_main_loop_unref (loop); + + g_object_unref (account); + g_object_unref (am); + + return 0; +} diff --git a/telepathy-ytstenut-glib/tests/server-nosey-status.c b/telepathy-ytstenut-glib/tests/server-nosey-status.c new file mode 100644 index 0000000..978bbe8 --- /dev/null +++ b/telepathy-ytstenut-glib/tests/server-nosey-status.c @@ -0,0 +1,318 @@ +/* + * server-nosey-status.c - a little demo to print out status/service changes + * + * Copyright (C) 2011 Intel Corp. + * + * 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 + */ + +#include "config.h" + +#include <signal.h> + +#include <telepathy-glib/util.h> + +#include <telepathy-ytstenut-glib/telepathy-ytstenut-glib.h> + +static GMainLoop *loop = NULL; +static TpYtsAccountManager *am = NULL; +static TpYtsClient *client = NULL; + +static void +getoutofhere (void) +{ + tp_clear_object (&client); + /* we called Hold in main, so let's let that go here by calling + * Release */ + g_main_loop_quit (loop); +} + +static void +status_changed_cb (TpYtsStatus *proxy, + const gchar *contact_id, + const gchar *capability, + const gchar *service_name, + const gchar *status, + gpointer user_data, + GObject *weak_object) +{ + g_print ("StatusChanged:\n"); + g_print (" - contact ID: %s\n", contact_id); + g_print (" - capability: %s\n", capability); + g_print (" - service name: %s\n", service_name); + g_print (" - status: %s\n", status); +} + +static void +service_added_cb (TpYtsStatus *proxy, + const gchar *contact_id, + const gchar *service_name, + const GValueArray *service, + gpointer user_data, + GObject *weak_object) +{ + const gchar *type; + GHashTable *names; + gchar **caps; + + GHashTableIter iter; + gpointer key, value; + + tp_value_array_unpack ((GValueArray *) service, 3, + &type, &names, &caps); + + g_print ("ServiceAdded:\n"); + g_print (" - contact ID: %s\n", contact_id); + g_print (" - service name: %s\n", service_name); + + g_hash_table_iter_init (&iter, names); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + g_print (" - name: %s: %s\n", (const gchar *) key, (const gchar *) value); + } + + while (caps != NULL && *caps != NULL) + { + g_print (" - capability: %s\n", *caps); + caps++; + } +} + +static void +service_removed_cb (TpYtsStatus *proxy, + const gchar *contact_id, + const gchar *service_name, + gpointer user_data, + GObject *weak_object) +{ + g_print ("ServiceRemoved:\n"); + g_print (" - contact ID: %s\n", contact_id); + g_print (" - service name: %s\n", service_name); +} + +static void +service_foreach (gpointer key, + gpointer value, + gpointer data) +{ + const gchar *service_name = key; + GValueArray *array = value; + + GHashTableIter iter; + gpointer one, two; + + const gchar *service_type; + GHashTable *names; + const gchar * const *capabilities; + + tp_value_array_unpack (array, 3, + &service_type, + &names, + &capabilities); + + g_print (" - service: %s\n", service_name); + g_print (" - type: %s\n", service_type); + + g_hash_table_iter_init (&iter, names); + while (g_hash_table_iter_next (&iter, &one, &two)) + { + g_print (" - name: %s: %s\n", + (const gchar *) one, (const gchar *) two); + } + + for (; capabilities != NULL && *capabilities != NULL; capabilities++) + { + g_print (" - capability: %s\n", *capabilities); + } +} + +static void +status_foreach (gpointer key, + gpointer value, + gpointer data) +{ + const gchar *capability = key; + GHashTable *info = value; + + GHashTableIter iter; + gpointer one, two; + + g_print (" - capability: %s\n", capability); + + g_hash_table_iter_init (&iter, info); + while (g_hash_table_iter_next (&iter, &one, &two)) + { + g_print (" - service: %s\n", (const gchar *) one); + g_print (" - %s\n", (const gchar *) two); + } +} + +static void +status_ensured_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpYtsStatus *status; + GError *error = NULL; + + status = tp_yts_status_ensure_finish ( + TP_ACCOUNT (source_object), result, &error); + + if (status == NULL) + { + g_printerr ("Failed to ensure status: %s\n", error->message); + getoutofhere (); + } + else + { + GHashTable *hash; + GHashTableIter iter; + gpointer key, value; + + g_print ("Got status sidecar.\n"); + + hash = tp_yts_status_get_discovered_services (status); + if (g_hash_table_size (hash) > 0) + { + g_print ("Already discovered services:\n"); + + g_hash_table_iter_init (&iter, + tp_yts_status_get_discovered_services (status)); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + const gchar *contact_id = key; + GHashTable *map = value; + + g_print (" - %s:\n", contact_id); + + g_hash_table_foreach (map, service_foreach, NULL); + } + } + + hash = tp_yts_status_get_discovered_statuses (status); + if (g_hash_table_size (hash) > 0) + { + g_print ("Already discovered statuses:\n"); + + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + const gchar *contact_id = key; + GHashTable *map = value; + + g_print (" - %s:\n", contact_id); + + g_hash_table_foreach (map, status_foreach, NULL); + } + } + + tp_yts_status_connect_to_status_changed (status, status_changed_cb, + NULL, NULL, NULL, NULL); + tp_yts_status_connect_to_service_added (status, service_added_cb, + NULL, NULL, NULL, NULL); + tp_yts_status_connect_to_service_removed (status, service_removed_cb, + NULL, NULL, NULL, NULL); + + /* or you could use the GObject signals: + g_signal_connect (status, "status-changed", + G_CALLBACK (status_changed_cb), NULL); + g_signal_connect (status, "service-added", + G_CALLBACK (service_added_cb), NULL); + g_signal_connect (status, "service-removed", + G_CALLBACK (service_removed_cb), NULL); + */ + } + + g_clear_error (&error); +} + +static void +got_account (TpAccount *account) +{ + client = tp_yts_client_new ("nosey.status", account); + + tp_yts_client_add_interests (client, + "urn:ytstenut:capabilities:yts-caps-cats", + NULL); + + tp_yts_client_register (client, NULL); + + tp_yts_status_ensure_async (account, + NULL, status_ensured_cb, NULL); + + g_object_unref (account); +} + +static void +account_prepared_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpAccount *account = TP_ACCOUNT (source_object); + GError *error = NULL; + + if (!tp_account_prepare_finish (account, result, &error)) + { + g_print ("failed to prepare account: %s\n", error->message); + g_clear_error (&error); + getoutofhere (); + return; + } + + got_account (account); +} + +static void +sigint_handler (int s) +{ + g_print ("Cleaning up...\n"); + getoutofhere (); +} + +int +main (int argc, + char **argv) +{ + TpAccount *account; + gchar *path; + + if (argc < 2) + { + g_print ("usage: %s [account name]\n", argv[0]); + return 1; + } + + signal (SIGINT, sigint_handler); + + g_type_init (); + + am = tp_yts_account_manager_dup (); + + path = g_strdup_printf ("%s%s", TP_ACCOUNT_OBJECT_PATH_BASE, argv[1]); + account = tp_yts_account_manager_ensure_account (am, path, NULL); + g_free (path); + + tp_account_prepare_async (account, NULL, account_prepared_cb, NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_main_loop_unref (loop); + + g_object_unref (account); + g_object_unref (am); + + return 0; +} diff --git a/telepathy-ytstenut-glib/tests/server-passing-service.c b/telepathy-ytstenut-glib/tests/server-passing-service.c new file mode 100644 index 0000000..f34a04e --- /dev/null +++ b/telepathy-ytstenut-glib/tests/server-passing-service.c @@ -0,0 +1,124 @@ +/* + * passing-service.c - demo to appear as a service and then disappear + * + * Copyright (C) 2011 Intel Corp. + * + * 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 + */ + +#include "config.h" + +#include <telepathy-glib/util.h> + +#include <telepathy-ytstenut-glib/telepathy-ytstenut-glib.h> + +static GMainLoop *loop = NULL; +static TpYtsAccountManager *am = NULL; + +static void +getoutofhere (void) +{ + g_main_loop_quit (loop); +} + +static gboolean +timeout_cb (gpointer data) +{ + g_object_unref (data); + getoutofhere (); + return FALSE; +} + +static void +got_account (TpAccount *account, + gpointer user_data) +{ + const gchar *service = user_data; + TpYtsClient *client = tp_yts_client_new (service, account); + + tp_yts_client_add_names (client, + "en_GB", "Magic Icecream Maker", + "en_US", "Magic Icecream Vendor", + "fr", "Machine à Glace Magique", + NULL); + + tp_yts_client_add_capabilities (client, + "urn:ytstenut:capabilities:video", + "urn:ytstenut:data:jingle:rtp", + NULL); + + tp_yts_client_add_interests (client, + "urn:ytstenut:capabilities:slipping-on-bananaskins", + NULL); + + tp_yts_client_register (client, NULL); + + g_timeout_add_seconds (10, timeout_cb, client); + + g_object_unref (account); +} + +static void +account_prepared_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpAccount *account = TP_ACCOUNT (source_object); + GError *error = NULL; + + if (!tp_account_prepare_finish (account, result, &error)) + { + g_print ("failed to prepare account: %s\n", error->message); + g_clear_error (&error); + getoutofhere (); + return; + } + + got_account (account, user_data); +} + +int +main (int argc, + char **argv) +{ + TpAccount *account; + gchar *path; + + if (argc < 3 || !tp_dbus_check_valid_interface_name (argv[2], NULL)) + { + g_print ("usage: %s [account] [service name]\n", argv[0]); + return 1; + } + + g_type_init (); + + am = tp_yts_account_manager_dup (); + + path = g_strdup_printf ("%s%s", TP_ACCOUNT_OBJECT_PATH_BASE, argv[1]); + account = tp_yts_account_manager_ensure_account (am, path, NULL); + g_free (path); + + tp_account_prepare_async (account, NULL, account_prepared_cb, argv[2]); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_main_loop_unref (loop); + + g_object_unref (account); + g_object_unref (am); + + return 0; +} diff --git a/telepathy-ytstenut-glib/tests/server-passing-status.c b/telepathy-ytstenut-glib/tests/server-passing-status.c new file mode 100644 index 0000000..1ce77ad --- /dev/null +++ b/telepathy-ytstenut-glib/tests/server-passing-status.c @@ -0,0 +1,203 @@ +/* + * passing-service.c - demo to appear as a service and then disappear + * + * Copyright (C) 2011 Intel Corp. + * + * 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 + */ + +#include "config.h" + +#include <telepathy-glib/util.h> + +#include <telepathy-ytstenut-glib/telepathy-ytstenut-glib.h> + +static GMainLoop *loop = NULL; +static TpYtsAccountManager *am = NULL; +static TpYtsClient *client = NULL; + +static void +getoutofhere (void) +{ + tp_clear_object (&client); + g_main_loop_quit (loop); +} + +static gboolean +leave_timeout_cb (gpointer data) +{ + g_print ("Let's go!\n"); + g_object_unref (data); + getoutofhere (); + return FALSE; +} + +static void +advertise_clear_status_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpYtsStatus *status = TP_YTS_STATUS (source_object); + GError *error = NULL; + + if (!tp_yts_status_advertise_status_finish (status, result, &error)) + { + g_printerr ("Failed to advertise status: %s\n", error->message); + getoutofhere (); + } + else + { + g_print ("Cleared status fine...\n"); + g_timeout_add_seconds (3, leave_timeout_cb, status); + } + + g_clear_error (&error); +} + +static gboolean +timeout_cb (gpointer data) +{ + TpYtsStatus *status = data; + + g_print ("Clearing status\n"); + + tp_yts_status_advertise_status_async (status, + "urn:ytstenut:capabilities:yts-caps-cats", + "passing.status", /* this should be the same as the client name */ + NULL, NULL, advertise_clear_status_cb, NULL); + return FALSE; +} + +static void +advertise_status_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpYtsStatus *status = TP_YTS_STATUS (source_object); + GError *error = NULL; + + if (!tp_yts_status_advertise_status_finish (status, result, &error)) + { + g_printerr ("Failed to advertise status: %s\n", error->message); + getoutofhere (); + } + else + { + g_print ("Advertised status fine...\n"); + g_timeout_add_seconds (3, timeout_cb, status); + } + + g_clear_error (&error); +} + +static void +status_ensured_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpAccount *account = user_data; + TpYtsStatus *status; + GError *error = NULL; + + status = tp_yts_status_ensure_finish ( + TP_ACCOUNT (source_object), result, &error); + + if (status == NULL) + { + g_printerr ("Failed to ensure status: %s\n", error->message); + getoutofhere (); + } + else + { + client = tp_yts_client_new ("passing.status", account); + tp_yts_client_register (client, NULL); + + /* We need the XML here otherwise the activity attribute won't + * be present and it'll think we'll be trying to remove the + * status. */ + tp_yts_status_advertise_status_async (status, + "urn:ytstenut:capabilities:yts-caps-cats", + "passing.status", /* this should be the same as the client name */ + "<status xmlns='urn:ytstenut:status' from-service='service.name' " + "capability='urn:ytstenut:capabilities:yts-caps-cats' " + "activity='looking-at-cats-ooooooh'><look>at how cute they " + "are!</look></status>", + NULL, advertise_status_cb, NULL); + } + + g_clear_error (&error); +} + +static void +got_account (TpAccount *account) +{ + tp_yts_status_ensure_async (account, + NULL, status_ensured_cb, NULL); + + g_object_unref (account); +} + +static void +account_prepared_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TpAccount *account = TP_ACCOUNT (source_object); + GError *error = NULL; + + if (!tp_account_prepare_finish (account, result, &error)) + { + g_print ("failed to prepare account: %s\n", error->message); + g_clear_error (&error); + getoutofhere (); + return; + } + + got_account (account); +} + +int +main (int argc, + char **argv) +{ + TpAccount *account; + gchar *path; + + if (argc < 2) + { + g_print ("usage: %s [account]\n", argv[0]); + return 1; + } + + g_type_init (); + + am = tp_yts_account_manager_dup (); + + path = g_strdup_printf ("%s%s", TP_ACCOUNT_OBJECT_PATH_BASE, argv[1]); + account = tp_yts_account_manager_ensure_account (am, path, NULL); + g_free (path); + + tp_account_prepare_async (account, NULL, account_prepared_cb, NULL); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + g_main_loop_unref (loop); + + g_object_unref (account); + g_object_unref (am); + + return 0; +} |