2 * empathy-call-factory.c - Source for EmpathyCallFactory
3 * Copyright (C) 2008 Collabora Ltd.
4 * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <telepathy-glib/account-channel-request.h>
26 #include <telepathy-glib/simple-handler.h>
27 #include <telepathy-glib/interfaces.h>
28 #include <telepathy-glib/util.h>
30 #include <telepathy-yell/telepathy-yell.h>
32 #include <libempathy/empathy-channel-factory.h>
33 #include <libempathy/empathy-request-util.h>
34 #include <libempathy/empathy-tp-contact-factory.h>
35 #include <libempathy/empathy-utils.h>
37 #include "empathy-call-factory.h"
38 #include "empathy-call-handler.h"
39 #include "src-marshal.h"
41 #define DEBUG_FLAG EMPATHY_DEBUG_VOIP
42 #include <libempathy/empathy-debug.h>
44 G_DEFINE_TYPE(EmpathyCallFactory, empathy_call_factory, G_TYPE_OBJECT)
46 static void handle_channels_cb (TpSimpleHandler *handler,
48 TpConnection *connection,
50 GList *requests_satisfied,
51 gint64 user_action_time,
52 TpHandleChannelsContext *context,
62 static guint signals[LAST_SIGNAL] = {0};
64 /* private structure */
66 TpBaseClient *handler;
67 gboolean dispose_has_run;
68 } EmpathyCallFactoryPriv;
70 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyCallFactory)
72 static GObject *call_factory = NULL;
75 empathy_call_factory_init (EmpathyCallFactory *obj)
77 EmpathyCallFactoryPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (obj,
78 EMPATHY_TYPE_CALL_FACTORY, EmpathyCallFactoryPriv);
80 EmpathyChannelFactory *factory;
85 dbus = tp_dbus_daemon_dup (&error);
88 g_warning ("Failed to get TpDBusDaemon: %s", error->message);
93 priv->handler = tp_simple_handler_new (dbus, FALSE, FALSE,
94 EMPATHY_CALL_BUS_NAME_SUFFIX, FALSE, handle_channels_cb, obj, NULL);
96 factory = empathy_channel_factory_new ();
97 tp_base_client_set_channel_factory (priv->handler,
98 TP_CLIENT_CHANNEL_FACTORY (factory));
99 g_object_unref (factory);
101 tp_base_client_take_handler_filter (priv->handler, tp_asv_new (
102 TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
103 TPY_IFACE_CHANNEL_TYPE_CALL,
104 TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
105 G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
108 tp_base_client_take_handler_filter (priv->handler, tp_asv_new (
109 TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
110 TPY_IFACE_CHANNEL_TYPE_CALL,
111 TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
112 G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
113 TPY_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, G_TYPE_BOOLEAN, TRUE,
116 tp_base_client_take_handler_filter (priv->handler, tp_asv_new (
117 TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
118 TPY_IFACE_CHANNEL_TYPE_CALL,
119 TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
120 G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
121 TPY_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO, G_TYPE_BOOLEAN, TRUE,
124 tp_base_client_add_handler_capabilities_varargs (priv->handler,
125 "org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/ice-udp",
126 "org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/gtalk-p2p",
127 "org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/video/h264",
130 g_object_unref (dbus);
134 empathy_call_factory_constructor (GType type, guint n_construct_params,
135 GObjectConstructParam *construct_params)
137 g_return_val_if_fail (call_factory == NULL, NULL);
139 call_factory = G_OBJECT_CLASS (empathy_call_factory_parent_class)->constructor
140 (type, n_construct_params, construct_params);
141 g_object_add_weak_pointer (call_factory, (gpointer)&call_factory);
147 empathy_call_factory_finalize (GObject *object)
149 /* free any data held directly by the object here */
151 if (G_OBJECT_CLASS (empathy_call_factory_parent_class)->finalize)
152 G_OBJECT_CLASS (empathy_call_factory_parent_class)->finalize (object);
156 empathy_call_factory_dispose (GObject *object)
158 EmpathyCallFactoryPriv *priv = GET_PRIV (object);
160 if (priv->dispose_has_run)
163 priv->dispose_has_run = TRUE;
165 tp_clear_object (&priv->handler);
167 if (G_OBJECT_CLASS (empathy_call_factory_parent_class)->dispose)
168 G_OBJECT_CLASS (empathy_call_factory_parent_class)->dispose (object);
172 empathy_call_factory_class_init (
173 EmpathyCallFactoryClass *empathy_call_factory_class)
175 GObjectClass *object_class = G_OBJECT_CLASS (empathy_call_factory_class);
177 g_type_class_add_private (empathy_call_factory_class,
178 sizeof (EmpathyCallFactoryPriv));
180 object_class->constructor = empathy_call_factory_constructor;
181 object_class->dispose = empathy_call_factory_dispose;
182 object_class->finalize = empathy_call_factory_finalize;
184 signals[NEW_CALL_HANDLER] =
185 g_signal_new ("new-call-handler",
186 G_TYPE_FROM_CLASS (empathy_call_factory_class),
187 G_SIGNAL_RUN_LAST, 0,
189 _src_marshal_VOID__OBJECT_BOOLEAN,
191 2, EMPATHY_TYPE_CALL_HANDLER, G_TYPE_BOOLEAN);
195 empathy_call_factory_initialise (void)
197 g_return_val_if_fail (call_factory == NULL, NULL);
199 return EMPATHY_CALL_FACTORY (g_object_new (EMPATHY_TYPE_CALL_FACTORY, NULL));
203 empathy_call_factory_get (void)
205 g_return_val_if_fail (call_factory != NULL, NULL);
207 return EMPATHY_CALL_FACTORY (call_factory);
211 call_channel_got_contact (TpConnection *connection,
212 EmpathyContact *contact,
215 GObject *weak_object)
217 EmpathyCallFactory *factory = EMPATHY_CALL_FACTORY (weak_object);
218 EmpathyCallHandler *handler;
219 TpyCallChannel *call = TPY_CALL_CHANNEL (user_data);
223 /* FIXME use hangup with an appropriate error */
224 tp_channel_close_async (TP_CHANNEL (call), NULL, NULL);
228 handler = empathy_call_handler_new_for_channel (call, contact);
230 g_signal_emit (factory, signals[NEW_CALL_HANDLER], 0,
233 g_object_unref (handler);
237 call_channel_ready (EmpathyCallFactory *factory,
238 TpyCallChannel *call)
240 TpChannel *channel = TP_CHANNEL (call);
243 id = tp_channel_get_identifier (channel);
245 /* The ready callback has a reference, so pass that on */
246 empathy_tp_contact_factory_get_from_id (
247 tp_channel_borrow_connection (channel),
249 call_channel_got_contact,
252 (GObject *) factory);
256 call_channel_ready_cb (TpyCallChannel *call,
258 EmpathyCallFactory *factory)
262 g_object_get (call, "ready", &ready, NULL);
266 call_channel_ready (factory, call);
271 handle_channels_cb (TpSimpleHandler *handler,
273 TpConnection *connection,
275 GList *requests_satisfied,
276 gint64 user_action_time,
277 TpHandleChannelsContext *context,
280 EmpathyCallFactory *self = user_data;
283 for (l = channels; l != NULL; l = g_list_next (l))
285 TpChannel *channel = l->data;
286 TpyCallChannel *call;
289 if (tp_proxy_get_invalidated (channel) != NULL)
292 if (tp_channel_get_channel_type_id (channel) !=
293 TPY_IFACE_QUARK_CHANNEL_TYPE_CALL)
296 if (!TPY_IS_CALL_CHANNEL (channel))
299 call = TPY_CALL_CHANNEL (channel);
301 /* Take a ref to keep while hopping through the async callbacks */
303 g_object_get (call, "ready", &ready, NULL);
306 tp_g_signal_connect_object (call, "notify::ready",
307 G_CALLBACK (call_channel_ready_cb), self, 0);
309 call_channel_ready (self, call);
312 tp_handle_channels_context_accept (context);
316 empathy_call_factory_register (EmpathyCallFactory *self,
319 EmpathyCallFactoryPriv *priv = GET_PRIV (self);
321 return tp_base_client_register (priv->handler, error);