summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2013-09-17 13:30:50 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2013-09-17 14:11:47 +0100
commit4ae11f0444a2fa13339f785609f7b35d05856ea8 (patch)
tree2945f60826c9cae4f7e5e6c1542b631ee1702fd4
parentdb91188883a253cf0610d0184fe450d6a94b9e14 (diff)
downloadtelepathy-haze-4ae11f0444a2fa13339f785609f7b35d05856ea8.tar.gz
Remove StreamedMedia support
In Pidgin, it's only implemented for XMPP (for which we have Gabble), MSNP (which will disappear soon), and mxit (which I doubt anyone's actually tested). Empathy can't do StreamedMedia any more, only Call, and Telepathy 1.0 will only have Call. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69318 Reviewed-by: Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
-rw-r--r--configure.ac10
-rw-r--r--src/Makefile.am15
-rw-r--r--src/connection-capabilities.c198
-rw-r--r--src/connection-capabilities.h2
-rw-r--r--src/connection.c13
-rw-r--r--src/connection.h8
-rw-r--r--src/main.c13
-rw-r--r--src/media-backend.c614
-rw-r--r--src/media-backend.h68
-rw-r--r--src/media-channel.c1760
-rw-r--r--src/media-channel.h79
-rw-r--r--src/media-manager.c576
-rw-r--r--src/media-manager.h65
-rw-r--r--src/media-stream.c1396
-rw-r--r--src/media-stream.h126
-rw-r--r--src/protocol.c3
-rw-r--r--tests/twisted/Makefile.am12
-rw-r--r--tests/twisted/simple-caps.py28
18 files changed, 1 insertions, 4985 deletions
diff --git a/configure.ac b/configure.ac
index ae9c28f..80f47ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,16 +114,6 @@ AC_MSG_RESULT([$TEST_PYTHON])
AC_SUBST(TEST_PYTHON)
AM_CONDITIONAL([WANT_TWISTED_TESTS], test false != "$TEST_PYTHON")
-AC_ARG_ENABLE(media,
- AC_HELP_STRING([--disable-media],[disable audio/video calls]),
- [
- AM_CONDITIONAL([MEDIA_ENABLED], false)
- ],[
- AC_DEFINE(ENABLE_MEDIA, [], [Enable audio/video calls])
- AM_CONDITIONAL([MEDIA_ENABLED], true)
- ])
-AC_SUBST(ENABLE_MEDIA)
-
#AS_AC_EXPAND(DATADIR, $datadir)
#DBUS_SERVICES_DIR="$DATADIR/dbus-1/services"
#AC_SUBST(DBUS_SERVICES_DIR)
diff --git a/src/Makefile.am b/src/Makefile.am
index bc9fd28..59bae17 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,19 +8,6 @@ man_MANS = telepathy-haze.8
EXTRA_DIST = telepathy-haze.8.in
CLEANFILES = $(man_MANS)
-if MEDIA_ENABLED
-haze_media_sources = media-backend.c \
- media-backend.h \
- media-channel.c \
- media-channel.h \
- media-manager.c \
- media-manager.h \
- media-stream.c \
- media-stream.h
-else
-haze_media_sources =
-endif
-
telepathy_haze_SOURCES = main.c \
defines.h \
debug.c \
@@ -53,7 +40,7 @@ telepathy_haze_SOURCES = main.c \
request.h \
util.c \
util.h \
- $(haze_media_sources)
+ $(NULL)
telepathy_haze_LDADD = $(top_builddir)/extensions/libhaze-extensions.la
diff --git a/src/connection-capabilities.c b/src/connection-capabilities.c
index 5ccb37c..ce6fd8f 100644
--- a/src/connection-capabilities.c
+++ b/src/connection-capabilities.c
@@ -28,9 +28,6 @@
#include "connection.h"
#include "debug.h"
-#ifdef ENABLE_MEDIA
-#include "mediamanager.h"
-#endif
static void
free_rcc_list (GPtrArray *rccs)
@@ -38,33 +35,6 @@ free_rcc_list (GPtrArray *rccs)
g_boxed_free (TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST, rccs);
}
-#ifdef ENABLE_MEDIA
-static GPtrArray * haze_connection_get_handle_contact_capabilities (
- HazeConnection *self, TpHandle handle);
-
-static void
-_emit_capabilities_changed (HazeConnection *conn,
- TpHandle handle,
- PurpleMediaCaps old_caps,
- PurpleMediaCaps new_caps)
-{
- if (old_caps != new_caps)
- {
- GHashTable *ret = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify) free_rcc_list);
- GPtrArray *arr;
-
- arr = haze_connection_get_handle_contact_capabilities (conn, handle);
- g_hash_table_insert (ret, GUINT_TO_POINTER (handle), arr);
-
- tp_svc_connection_interface_contact_capabilities_emit_contact_capabilities_changed (
- conn, ret);
-
- g_hash_table_unref (ret);
- }
-}
-#endif
-
static void
haze_connection_update_capabilities (TpSvcConnectionInterfaceContactCapabilities *iface,
const GPtrArray *clients,
@@ -72,72 +42,9 @@ haze_connection_update_capabilities (TpSvcConnectionInterfaceContactCapabilities
{
HazeConnection *self = HAZE_CONNECTION (iface);
TpBaseConnection *base = (TpBaseConnection *) self;
-#ifdef ENABLE_MEDIA
- guint i;
- PurpleMediaCaps old_caps, caps;
- GHashTableIter iter;
- gpointer value;
-#endif
TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
-#ifdef ENABLE_MEDIA
- caps = PURPLE_MEDIA_CAPS_NONE;
- old_caps = purple_media_manager_get_ui_caps (
- purple_media_manager_get ());
-
- DEBUG ("enter");
-
- /* go through all the clients and if they can do audio or video save
- * it in the client_caps hash table */
- for (i = 0; i < clients->len; i++)
- {
- GValueArray *va = g_ptr_array_index (clients, i);
- const gchar *client_name = g_value_get_string (va->values + 0);
- const GPtrArray *rccs = g_value_get_boxed (va->values + 1);
- guint j;
- PurpleMediaCaps flags = 0;
-
- g_hash_table_remove (self->client_caps, client_name);
-
- for (j = 0; j < rccs->len; j++)
- {
- GHashTable *class = g_ptr_array_index (rccs, i);
-
- if (tp_strdiff (tp_asv_get_string (class, TP_PROP_CHANNEL_CHANNEL_TYPE),
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA))
- continue;
-
- if (tp_asv_get_boolean (class,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO, NULL))
- flags |= PURPLE_MEDIA_CAPS_AUDIO;
-
- if (tp_asv_get_boolean (class,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO, NULL))
- flags |= PURPLE_MEDIA_CAPS_VIDEO;
- }
-
- if (flags != 0)
- {
- g_hash_table_insert (self->client_caps, g_strdup (client_name),
- GUINT_TO_POINTER (flags));
- }
- }
-
- /* now we have an updated client_caps hash table, go through it and
- * let libpurple know */
- g_hash_table_iter_init (&iter, self->client_caps);
- while (g_hash_table_iter_next (&iter, NULL, &value))
- {
- caps |= GPOINTER_TO_UINT (value);
- }
-
- purple_media_manager_set_ui_caps (purple_media_manager_get(), caps);
-
- _emit_capabilities_changed (self, tp_base_connection_get_self_handle (base),
- old_caps, caps);
-#endif
-
tp_svc_connection_interface_contact_capabilities_return_from_update_capabilities (
context);
}
@@ -146,21 +53,6 @@ static GPtrArray *
haze_connection_get_handle_contact_capabilities (HazeConnection *self,
TpHandle handle)
{
-#ifdef ENABLE_MEDIA
- PurpleAccount *account = self->account;
- TpBaseConnection *conn = TP_BASE_CONNECTION (self);
- TpHandleRepoIface *contact_handles =
- tp_base_connection_get_handles (conn, TP_HANDLE_TYPE_CONTACT);
- const gchar *bname;
- PurpleMediaCaps caps;
- GValue media_monster = {0, };
- const gchar * const sm_allowed_audio[] = {
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO, NULL };
- const gchar * const sm_allowed_video[] = {
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO,
- NULL };
-#endif
GPtrArray *arr = g_ptr_array_new ();
GValue monster = {0, };
GHashTable *fixed_properties;
@@ -177,56 +69,6 @@ haze_connection_get_handle_contact_capabilities (HazeConnection *self,
/* TODO: Check for presence */
-#ifdef ENABLE_MEDIA
- if (handle == tp_base_connection_get_self_handle (conn))
- caps = purple_media_manager_get_ui_caps (purple_media_manager_get ());
- else
- {
- bname = tp_handle_inspect (contact_handles, handle);
- caps = purple_prpl_get_media_caps (account, bname);
- }
-
- /* we assume that VIDEO won't be present without AUDIO */
- if ((caps & PURPLE_MEDIA_CAPS_AUDIO) != 0)
- {
- const gchar * const *allowed;
-
- g_value_init (&media_monster,
- TP_STRUCT_TYPE_REQUESTABLE_CHANNEL_CLASS);
- g_value_take_boxed (&media_monster,
- dbus_g_type_specialized_construct (
- TP_STRUCT_TYPE_REQUESTABLE_CHANNEL_CLASS));
-
- fixed_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
- (GDestroyNotify) tp_g_value_slice_free);
-
- channel_type_value = tp_g_value_slice_new (G_TYPE_STRING);
- g_value_set_static_string (channel_type_value,
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
- g_hash_table_insert (fixed_properties, TP_PROP_CHANNEL_CHANNEL_TYPE,
- channel_type_value);
-
- target_handle_type_value = tp_g_value_slice_new (G_TYPE_UINT);
- g_value_set_uint (target_handle_type_value, TP_HANDLE_TYPE_CONTACT);
- g_hash_table_insert (fixed_properties, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
- target_handle_type_value);
-
- if (caps & PURPLE_MEDIA_CAPS_VIDEO)
- allowed = sm_allowed_video;
- else
- allowed = sm_allowed_audio;
-
- dbus_g_type_struct_set (&media_monster,
- 0, fixed_properties,
- 1, allowed,
- G_MAXUINT);
-
- g_hash_table_unref (fixed_properties);
-
- g_ptr_array_add (arr, g_value_get_boxed (&media_monster));
- }
-#endif
-
g_value_init (&monster, TP_STRUCT_TYPE_REQUESTABLE_CHANNEL_CLASS);
g_value_take_boxed (&monster,
dbus_g_type_specialized_construct (
@@ -343,50 +185,10 @@ haze_connection_contact_capabilities_iface_init (gpointer g_iface,
#undef IMPLEMENT
}
-#ifdef ENABLE_MEDIA
-static void
-caps_changed_cb (PurpleBuddy *buddy,
- PurpleMediaCaps caps,
- PurpleMediaCaps oldcaps)
-{
- PurpleAccount *account = purple_buddy_get_account (buddy);
- HazeConnection *conn = ACCOUNT_GET_HAZE_CONNECTION (account);
- TpBaseConnection *base_conn = TP_BASE_CONNECTION (conn);
- TpHandleRepoIface *contact_repo =
- tp_base_connection_get_handles (base_conn, TP_HANDLE_TYPE_CONTACT);
- const gchar *bname = purple_buddy_get_name(buddy);
- TpHandle contact = tp_handle_ensure (contact_repo, bname, NULL, NULL);
-
- _emit_capabilities_changed (conn, contact, oldcaps, caps);
-}
-#endif
-
-void
-haze_connection_capabilities_class_init (GObjectClass *object_class)
-{
-#ifdef ENABLE_MEDIA
- purple_signal_connect (purple_blist_get_handle (), "buddy-caps-changed",
- object_class, PURPLE_CALLBACK (caps_changed_cb), NULL);
-#endif
-}
-
void
haze_connection_capabilities_init (GObject *object)
{
- HazeConnection *self = HAZE_CONNECTION (object);
-
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
conn_capabilities_fill_contact_attributes_contact_caps);
-
- self->client_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free, NULL);
-}
-
-void
-haze_connection_capabilities_finalize (GObject *object)
-{
- HazeConnection *self = HAZE_CONNECTION (object);
-
- tp_clear_pointer (&self->client_caps, g_hash_table_unref);
}
diff --git a/src/connection-capabilities.h b/src/connection-capabilities.h
index 791581b..e98bf98 100644
--- a/src/connection-capabilities.h
+++ b/src/connection-capabilities.h
@@ -25,8 +25,6 @@
void haze_connection_contact_capabilities_iface_init (gpointer g_iface,
gpointer iface_data);
-void haze_connection_capabilities_class_init (GObjectClass *object_class);
void haze_connection_capabilities_init (GObject *object);
-void haze_connection_capabilities_finalize (GObject *object);
#endif
diff --git a/src/connection.c b/src/connection.c
index 67da039..3c98304 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -615,16 +615,6 @@ _haze_connection_create_channel_managers (TpBaseConnection *base)
g_object_new (HAZE_TYPE_IM_CHANNEL_FACTORY, "connection", self, NULL));
g_ptr_array_add (channel_managers, self->im_factory);
-#ifdef ENABLE_MEDIA
- /* Instantiate the media manager only if the protocol support calls */
- if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC (self->priv->prpl_info, initiate_media))
- {
- self->media_manager = HAZE_MEDIA_MANAGER (
- g_object_new (HAZE_TYPE_MEDIA_MANAGER, "connection", self, NULL));
- g_ptr_array_add (channel_managers, self->media_manager);
- }
-#endif
-
self->contact_list = HAZE_CONTACT_LIST (
g_object_new (HAZE_TYPE_CONTACT_LIST, "connection", self, NULL));
g_ptr_array_add (channel_managers, self->contact_list);
@@ -769,8 +759,6 @@ haze_connection_finalize (GObject *object)
tp_contacts_mixin_finalize (object);
tp_presence_mixin_finalize (object);
- haze_connection_capabilities_finalize (object);
-
g_strfreev (self->acceptable_avatar_mime_types);
g_free (priv->username);
g_free (priv->password);
@@ -867,7 +855,6 @@ haze_connection_class_init (HazeConnectionClass *klass)
haze_connection_presence_class_init (object_class);
haze_connection_aliasing_class_init (object_class);
haze_connection_avatars_class_init (object_class);
- haze_connection_capabilities_class_init (object_class);
}
static void
diff --git a/src/connection.h b/src/connection.h
index ce4b67f..1677bf1 100644
--- a/src/connection.h
+++ b/src/connection.h
@@ -29,7 +29,6 @@
#include "contact-list.h"
#include "im-channel-factory.h"
-#include "media-manager.h"
G_BEGIN_DECLS
@@ -51,7 +50,6 @@ struct _HazeConnection {
HazeContactList *contact_list;
HazeImChannelFactory *im_factory;
- HazeMediaManager *media_manager;
TpSimplePasswordManager *password_manager;
TpContactsMixin contacts;
@@ -59,12 +57,6 @@ struct _HazeConnection {
gchar **acceptable_avatar_mime_types;
- /* Telepathy client's bus name => PurpleMediaCaps */
- GHashTable *client_caps;
-
- /* Part of the hack for Jabber media caps */
- gulong status_changed_id;
-
HazeConnectionPrivate *priv;
};
diff --git a/src/main.c b/src/main.c
index 3f9b38f..bf4b601 100644
--- a/src/main.c
+++ b/src/main.c
@@ -39,10 +39,6 @@
#include <libpurple/prefs.h>
#include <libpurple/util.h>
-#ifdef ENABLE_MEDIA
-#include <libpurple/mediamanager.h>
-#endif
-
#ifdef HAVE_PURPLE_DBUS_UNINIT
#include <libpurple/dbus-server.h>
#endif
@@ -56,10 +52,6 @@
#include "request.h"
#include "util.h"
-#ifdef ENABLE_MEDIA
-#include "media-backend.h"
-#endif
-
/* Copied verbatim from nullclient, modulo changing whitespace. */
#define PURPLE_GLIB_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR)
#define PURPLE_GLIB_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)
@@ -212,11 +204,6 @@ init_libpurple (void)
PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION);
set_libpurple_preferences ();
-
-#ifdef ENABLE_MEDIA
- purple_media_manager_set_backend_type (purple_media_manager_get (),
- HAZE_TYPE_MEDIA_BACKEND);
-#endif
}
static TpBaseConnectionManager *
diff --git a/src/media-backend.c b/src/media-backend.c
deleted file mode 100644
index 99f0545..0000000
--- a/src/media-backend.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * media-backend.c - Source for HazeMediaBackend
- * Copyright © 2006-2009 Collabora Ltd.
- * Copyright © 2006-2009 Nokia Corporation
- *
- * 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 "media-backend.h"
-
-#include <libpurple/media/backend-iface.h>
-#include <telepathy-glib/telepathy-glib.h>
-#include <telepathy-glib/telepathy-glib-dbus.h>
-
-#include <string.h>
-
-#include "debug.h"
-
-static void media_backend_iface_init(PurpleMediaBackendIface *iface);
-static void session_handler_iface_init (gpointer g_iface,
- gpointer iface_data);
-static void haze_backend_state_changed_cb (PurpleMedia *media,
- PurpleMediaState state,
- const gchar *sid,
- const gchar *name,
- HazeMediaBackend *backend);
-
-G_DEFINE_TYPE_WITH_CODE (HazeMediaBackend,
- haze_media_backend,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (PURPLE_TYPE_MEDIA_BACKEND,
- media_backend_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_MEDIA_SESSION_HANDLER,
- session_handler_iface_init);
- )
-
-/* properties */
-enum
-{
- PROP_CONFERENCE_TYPE = 1,
- PROP_MEDIA,
- PROP_OBJECT_PATH,
- PROP_STREAMS,
- LAST_PROPERTY
-};
-
-/* private structure */
-struct _HazeMediaBackendPrivate
-{
- gchar *conference_type;
- gchar *object_path;
- gpointer media;
- GPtrArray *streams;
-
- guint next_stream_id;
- gboolean ready;
-};
-
-static void
-haze_media_backend_init (HazeMediaBackend *self)
-{
- HazeMediaBackendPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- HAZE_TYPE_MEDIA_BACKEND, HazeMediaBackendPrivate);
-
- self->priv = priv;
-
- priv->next_stream_id = 1;
- priv->streams = g_ptr_array_sized_new (1);
-}
-
-static void
-haze_media_backend_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- HazeMediaBackend *backend = HAZE_MEDIA_BACKEND (object);
- HazeMediaBackendPrivate *priv = backend->priv;
-
- switch (property_id)
- {
- case PROP_CONFERENCE_TYPE:
- g_value_set_string (value, priv->conference_type);
- break;
- case PROP_MEDIA:
- g_value_set_object (value, priv->media);
- break;
- case PROP_OBJECT_PATH:
- g_value_set_string (value, priv->object_path);
- break;
- case PROP_STREAMS:
- g_value_set_boxed (value, priv->streams);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-haze_media_backend_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- HazeMediaBackend *backend = HAZE_MEDIA_BACKEND (object);
- HazeMediaBackendPrivate *priv = backend->priv;
-
- switch (property_id)
- {
- case PROP_CONFERENCE_TYPE:
- g_free (priv->conference_type);
- priv->conference_type = g_value_dup_string (value);
- break;
- case PROP_MEDIA:
- g_assert (priv->media == NULL);
- priv->media = g_value_get_object (value);
-
- g_object_add_weak_pointer(G_OBJECT(priv->media), &priv->media);
- g_signal_connect (priv->media, "state-changed",
- G_CALLBACK (haze_backend_state_changed_cb), backend);
- break;
- case PROP_OBJECT_PATH:
- g_assert (priv->object_path == NULL);
- priv->object_path = g_value_dup_string (value);
-
- if (priv->object_path != NULL)
- {
- TpDBusDaemon *dbus_daemon = tp_dbus_daemon_dup (NULL);
-
- g_return_if_fail (dbus_daemon != NULL);
- tp_dbus_daemon_register_object (dbus_daemon,
- priv->object_path, G_OBJECT (backend));
- g_object_unref (dbus_daemon);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void haze_media_backend_dispose (GObject *object);
-static void haze_media_backend_finalize (GObject *object);
-
-static void
-haze_media_backend_class_init (HazeMediaBackendClass *haze_media_backend_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (haze_media_backend_class);
- GParamSpec *param_spec;
-
- g_type_class_add_private (haze_media_backend_class,
- sizeof (HazeMediaBackendPrivate));
-
- object_class->get_property = haze_media_backend_get_property;
- object_class->set_property = haze_media_backend_set_property;
-
- object_class->dispose = haze_media_backend_dispose;
- object_class->finalize = haze_media_backend_finalize;
-
- g_object_class_override_property(object_class, PROP_CONFERENCE_TYPE,
- "conference-type");
- g_object_class_override_property(object_class, PROP_MEDIA, "media");
-
- param_spec = g_param_spec_string ("object-path", "D-Bus object path",
- "The D-Bus object path used for this "
- "object on the bus.",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_OBJECT_PATH, param_spec);
-
- param_spec = g_param_spec_boxed ("streams", "Streams",
- "List of streams handled by this backend.",
- G_TYPE_PTR_ARRAY,
- G_PARAM_READABLE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_STREAMS, param_spec);
-}
-
-void
-haze_media_backend_dispose (GObject *object)
-{
- DEBUG ("called");
-
- if (G_OBJECT_CLASS (haze_media_backend_parent_class)->dispose)
- G_OBJECT_CLASS (haze_media_backend_parent_class)->dispose (object);
-}
-
-void
-haze_media_backend_finalize (GObject *object)
-{
- HazeMediaBackend *self = HAZE_MEDIA_BACKEND (object);
- HazeMediaBackendPrivate *priv = self->priv;
-
- g_free (priv->conference_type);
- g_free (priv->object_path);
-
- if (priv->streams != NULL)
- g_ptr_array_free (priv->streams, TRUE);
-
- G_OBJECT_CLASS (haze_media_backend_parent_class)->finalize (object);
-}
-
-static HazeMediaStream *
-get_stream_by_name (HazeMediaBackend *self,
- const gchar *sid)
-{
- HazeMediaBackendPrivate *priv = self->priv;
- guint i;
-
- for (i = 0; i < priv->streams->len; ++i)
- {
- HazeMediaStream *stream = g_ptr_array_index (priv->streams, i);
-
- if (!strcmp (sid, stream->name))
- return stream;
- }
-
- return NULL;
-}
-
-HazeMediaStream *
-haze_media_backend_get_stream_by_name (HazeMediaBackend *self,
- const gchar *sid)
-{
- return get_stream_by_name (self, sid);
-}
-
-static void
-haze_backend_state_changed_cb (PurpleMedia *media,
- PurpleMediaState state,
- const gchar *sid,
- const gchar *name,
- HazeMediaBackend *backend)
-{
- HazeMediaBackendPrivate *priv = backend->priv;
-
- if (state == PURPLE_MEDIA_STATE_END && sid != NULL && name == NULL)
- {
- HazeMediaStream *stream = get_stream_by_name (backend, sid);
-
- if (stream != NULL)
- {
- g_ptr_array_remove_fast (priv->streams, stream);
- g_object_unref (stream);
- }
- }
-}
-
-static void
-_emit_new_stream (HazeMediaBackend *self,
- HazeMediaStream *stream)
-{
- gchar *object_path;
- guint id, media_type;
-
- g_object_get (stream,
- "object-path", &object_path,
- "id", &id,
- "media-type", &media_type,
- NULL);
-
- /* all of the streams are bidirectional from farsight's point of view, it's
- * just in the signalling they change */
- DEBUG ("emitting MediaSessionHandler:NewStreamHandler signal for %s stream %d",
- media_type == TP_MEDIA_STREAM_TYPE_AUDIO ? "audio" : "video", id);
- tp_svc_media_session_handler_emit_new_stream_handler (self,
- object_path, id, media_type, TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL);
-
- g_free (object_path);
-}
-
-static gboolean
-haze_media_backend_add_stream (PurpleMediaBackend *self,
- const gchar *sid, const gchar *who,
- PurpleMediaSessionType type, gboolean initiator,
- const gchar *transmitter,
- guint num_params, GParameter *params)
-{
- HazeMediaBackendPrivate *priv = HAZE_MEDIA_BACKEND (self)->priv;
- HazeMediaStream *stream;
- gchar *object_path;
- guint media_type, id, stun_port = 3478; /* default stun port */
- const gchar *nat_traversal = NULL, *stun_server = NULL;
- TpDBusDaemon *dbus_daemon = tp_dbus_daemon_dup (NULL);
-
- DEBUG ("called");
-
- g_return_val_if_fail (dbus_daemon != NULL, FALSE);
-
- id = priv->next_stream_id++;
-
- object_path = g_strdup_printf ("%s/MediaStream%u",
- priv->object_path, id);
-
- if (type & PURPLE_MEDIA_AUDIO)
- media_type = TP_MEDIA_STREAM_TYPE_AUDIO;
- else
- media_type = TP_MEDIA_STREAM_TYPE_VIDEO;
-
- if (!strcmp (transmitter, "nice"))
- {
- guint i;
-
- for (i = 0; i < num_params; ++i)
- {
- if (!strcmp (params[i].name, "compatibility-mode") &&
- G_VALUE_HOLDS (&params[i].value, G_TYPE_UINT))
- {
- guint mode = g_value_get_uint (&params[i].value);
-
- switch (mode)
- {
- case 0: /* NICE_COMPATIBILITY_DRAFT19 */
- nat_traversal = "ice-udp";
- break;
- case 1: /* NICE_COMPATIBILITY_GOOGLE */
- nat_traversal = "gtalk-p2p";
- break;
- case 2: /* NICE_COMPATIBILITY_MSN */
- nat_traversal = "wlm-8.5";
- break;
- case 3: /* NICE_COMPATIBILITY_WLM2009 */
- nat_traversal = "wlm-2009";
- break;
- default:
- g_assert_not_reached ();
- }
- }
- else if (!strcmp (params[i].name, "stun-ip") &&
- G_VALUE_HOLDS (&params[i].value, G_TYPE_STRING))
- {
- stun_server = g_value_get_string (&params[i].value);
- }
- else if (!strcmp (params[i].name, "stun-port") &&
- G_VALUE_HOLDS (&params[i].value, G_TYPE_UINT))
- {
- stun_port = g_value_get_uint (&params[i].value);
- }
- }
-
- if (nat_traversal == NULL)
- nat_traversal = "ice-udp";
- }
- else if (!strcmp (transmitter, "rawudp"))
- {
- nat_traversal = "none";
- }
- else
- {
- g_assert_not_reached ();
- }
-
- stream = haze_media_stream_new (object_path, dbus_daemon, priv->media,
- sid, who, media_type, id, initiator, nat_traversal, NULL, FALSE);
-
- if (stun_server != NULL)
- haze_media_stream_add_stun_server (stream, stun_server, stun_port);
-
- g_free (object_path);
-
- DEBUG ("%p: created new MediaStream %p for sid '%s'",
- self, stream, sid);
-
- g_ptr_array_add (priv->streams, stream);
-
- if (priv->ready)
- _emit_new_stream (HAZE_MEDIA_BACKEND (self), stream);
-
- g_object_unref (dbus_daemon);
-
- return TRUE;
-}
-
-static void
-haze_media_backend_add_remote_candidates (PurpleMediaBackend *self,
- const gchar *sid,
- const gchar *who,
- GList *remote_candidates)
-{
- HazeMediaStream *stream;
-
- DEBUG ("called");
-
- stream = get_stream_by_name (HAZE_MEDIA_BACKEND (self), sid);
-
- if (stream != NULL)
- haze_media_stream_add_remote_candidates (stream, remote_candidates);
- else
- DEBUG ("Couldn't find stream");
-}
-
-static gboolean
-haze_media_backend_codecs_ready (PurpleMediaBackend *self,
- const gchar *sid)
-{
- HazeMediaStream *stream;
- gboolean ready = FALSE;
-
- DEBUG ("called");
-
- if (sid != NULL)
- {
- stream = get_stream_by_name (HAZE_MEDIA_BACKEND (self), sid);
-
- if (stream != NULL)
- g_object_get (stream, "codecs-ready", &ready, NULL);
-
- return ready;
- }
- else
- {
- HazeMediaBackendPrivate *priv = HAZE_MEDIA_BACKEND (self)->priv;
- guint i;
-
- for (i = 0; i < priv->streams->len; ++i)
- {
- stream = g_ptr_array_index (priv->streams, i);
-
- if (stream != NULL)
- g_object_get (stream, "codecs-ready", &ready, NULL);
-
- if (!ready)
- return FALSE;
- }
-
- return TRUE;
- }
-}
-
-static GList *
-haze_media_backend_get_codecs (PurpleMediaBackend *self,
- const gchar *sid)
-{
- HazeMediaStream *stream;
- GList *ret = NULL;
-
- DEBUG ("called");
-
- stream = get_stream_by_name (HAZE_MEDIA_BACKEND (self), sid);
-
- if (stream != NULL)
- ret = haze_media_stream_get_codecs (stream);
-
- return ret;
-}
-
-static GList *
-haze_media_backend_get_local_candidates (PurpleMediaBackend *self,
- const gchar *sid,
- const gchar *who)
-{
- HazeMediaStream *stream;
- GList *ret = NULL;
-
- DEBUG ("called");
-
- stream = get_stream_by_name (HAZE_MEDIA_BACKEND (self), sid);
-
- if (stream != NULL)
- ret = haze_media_stream_get_local_candidates (stream);
-
- return ret;
-}
-
-static gboolean
-haze_media_backend_set_remote_codecs (PurpleMediaBackend *self,
- const gchar *sid,
- const gchar *who,
- GList *codecs)
-{
- HazeMediaStream *stream;
-
- DEBUG ("called");
-
- stream = get_stream_by_name (HAZE_MEDIA_BACKEND (self), sid);
-
- if (stream != NULL)
- haze_media_stream_set_remote_codecs (stream, codecs);
- else
- DEBUG ("Couldn't find stream");
-
- return TRUE;
-}
-
-static gboolean
-haze_media_backend_set_send_codec (PurpleMediaBackend *self,
- const gchar *sid,
- PurpleMediaCodec *codec)
-{
- return FALSE;
-}
-
-static void
-haze_media_backend_ready (TpSvcMediaSessionHandler *iface,
- DBusGMethodInvocation *context)
-{
- HazeMediaBackend *self = HAZE_MEDIA_BACKEND (iface);
- HazeMediaBackendPrivate *priv = self->priv;
-
- if (!priv->ready)
- {
- guint i;
-
- DEBUG ("emitting NewStreamHandler for each stream");
-
- priv->ready = TRUE;
-
- for (i = 0; i < priv->streams->len; i++)
- _emit_new_stream (self, g_ptr_array_index (priv->streams, i));
- }
-
- tp_svc_media_session_handler_return_from_ready (context);
-}
-
-static void
-haze_media_backend_error (TpSvcMediaSessionHandler *iface,
- guint errno,
- const gchar *message,
- DBusGMethodInvocation *context)
-{
- HazeMediaBackend *self = HAZE_MEDIA_BACKEND (iface);
- HazeMediaBackendPrivate *priv;
- GPtrArray *tmp;
- guint i;
-
- g_assert (HAZE_IS_MEDIA_BACKEND (self));
-
- priv = self->priv;
-
- if (priv->media == NULL)
- {
- /* This could also be because someone called Error() before the
- * SessionHandler was announced. But the fact that the SessionHandler is
- * actually also the Channel, and thus this method is available before
- * NewSessionHandler is emitted, is an implementation detail. So the
- * error message describes the only legitimate situation in which this
- * could arise.
- */
- GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "call has already ended" };
-
- DEBUG ("no session, returning an error.");
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- DEBUG ("Media.SessionHandler::Error called, error %u (%s) -- "
- "emitting error on each stream", errno, message);
-
- purple_media_end (priv->media, NULL, NULL);
-
- /* Calling haze_media_stream_error () on all the streams will ultimately
- * cause them all to emit 'closed'. In response to 'closed', stream_close_cb
- * unrefs them, and removes them from priv->streams. So, we copy the stream
- * list to avoid it being modified from underneath us.
- */
- tmp = g_ptr_array_sized_new (priv->streams->len);
-
- for (i = 0; i < priv->streams->len; i++)
- g_ptr_array_add (tmp, g_ptr_array_index (priv->streams, i));
-
- for (i = 0; i < tmp->len; i++)
- {
- HazeMediaStream *stream = g_ptr_array_index (tmp, i);
-
- haze_media_stream_error (stream, errno, message, NULL);
- }
-
- g_ptr_array_free (tmp, TRUE);
-
- tp_svc_media_session_handler_return_from_error (context);
-}
-
-static void
-media_backend_iface_init (PurpleMediaBackendIface *iface)
-{
-#define IMPLEMENT(x) iface->x = haze_media_backend_##x
- IMPLEMENT(add_stream);
- IMPLEMENT(add_remote_candidates);
- IMPLEMENT(codecs_ready);
- IMPLEMENT(get_codecs);
- IMPLEMENT(get_local_candidates);
- IMPLEMENT(set_remote_codecs);
- IMPLEMENT(set_send_codec);
-#undef IMPLEMENT
-}
-
-static void
-session_handler_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcMediaSessionHandlerClass *klass =
- (TpSvcMediaSessionHandlerClass *) g_iface;
-
-#define IMPLEMENT(x) tp_svc_media_session_handler_implement_##x (\
- klass, haze_media_backend_##x)
- IMPLEMENT(error);
- IMPLEMENT(ready);
-#undef IMPLEMENT
-}
diff --git a/src/media-backend.h b/src/media-backend.h
deleted file mode 100644
index d673c55..0000000
--- a/src/media-backend.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * media-backend.h - Header for HazeMediaBackend
- * Copyright (C) 2006, 2009 Collabora Ltd.
- * Copyright (C) 2006 Nokia Corporation
- *
- * 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 __HAZE_MEDIA_BACKEND__
-#define __HAZE_MEDIA_BACKEND__
-
-#include <glib-object.h>
-
-#include "media-stream.h"
-
-G_BEGIN_DECLS
-
-typedef struct _HazeMediaBackend HazeMediaBackend;
-typedef struct _HazeMediaBackendClass HazeMediaBackendClass;
-typedef struct _HazeMediaBackendPrivate HazeMediaBackendPrivate;
-
-struct _HazeMediaBackendClass {
- GObjectClass parent_class;
-};
-
-struct _HazeMediaBackend {
- GObject parent;
-
- HazeMediaBackendPrivate *priv;
-};
-
-GType haze_media_backend_get_type (void);
-HazeMediaStream *haze_media_backend_get_stream_by_name (
- HazeMediaBackend *self,
- const gchar *sid);
-
-/* TYPE MACROS */
-#define HAZE_TYPE_MEDIA_BACKEND \
- (haze_media_backend_get_type ())
-#define HAZE_MEDIA_BACKEND(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), HAZE_TYPE_MEDIA_BACKEND, \
- HazeMediaBackend))
-#define HAZE_MEDIA_BACKEND_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), HAZE_TYPE_MEDIA_BACKEND, \
- HazeMediaBackendClass))
-#define HAZE_IS_MEDIA_BACKEND(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), HAZE_TYPE_MEDIA_BACKEND))
-#define HAZE_IS_MEDIA_BACKEND_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), HAZE_TYPE_MEDIA_BACKEND))
-#define HAZE_MEDIA_BACKEND_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), HAZE_TYPE_MEDIA_BACKEND, \
- HazeMediaBackendClass))
-
-G_END_DECLS
-
-#endif /* #ifndef __HAZE_MEDIA_BACKEND__ */
diff --git a/src/media-channel.c b/src/media-channel.c
deleted file mode 100644
index 1cfd4d8..0000000
--- a/src/media-channel.c
+++ /dev/null
@@ -1,1760 +0,0 @@
-/*
- * media-channel.c - Source for HazeMediaChannel
- * Copyright (C) 2006, 2009 Collabora Ltd.
- * Copyright (C) 2006 Nokia Corporation
- *
- * Copied heavily from telepathy-gabble
- *
- * 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 "media-channel.h"
-
-#include <libpurple/media/backend-iface.h>
-#include <libpurple/mediamanager.h>
-#include <telepathy-glib/telepathy-glib.h>
-
-#include "connection.h"
-#include "debug.h"
-#include "media-backend.h"
-#include "media-stream.h"
-
-static void channel_iface_init (gpointer, gpointer);
-static void media_signalling_iface_init (gpointer, gpointer);
-static void streamed_media_iface_init (gpointer, gpointer);
-static gboolean haze_media_channel_add_member (GObject *obj,
- TpHandle handle,
- const gchar *message,
- GError **error);
-static gboolean haze_media_channel_remove_member (GObject *obj,
- TpHandle handle, const gchar *message, guint reason, GError **error);
-
-G_DEFINE_TYPE_WITH_CODE (HazeMediaChannel, haze_media_channel,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
- tp_group_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_STREAMED_MEDIA,
- streamed_media_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_MEDIA_SIGNALLING,
- media_signalling_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL);
- G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL));
-
-static const gchar *haze_media_channel_interfaces[] = {
- TP_IFACE_CHANNEL_INTERFACE_GROUP,
- TP_IFACE_CHANNEL_INTERFACE_MEDIA_SIGNALLING,
- NULL
-};
-
-/* properties */
-enum
-{
- PROP_OBJECT_PATH = 1,
- PROP_CHANNEL_TYPE,
- PROP_HANDLE_TYPE,
- PROP_HANDLE,
- PROP_TARGET_ID,
- PROP_INITIAL_PEER,
- PROP_PEER,
- PROP_REQUESTED,
- PROP_CONNECTION,
- PROP_CREATOR,
- PROP_CREATOR_ID,
- PROP_INTERFACES,
- PROP_CHANNEL_DESTROYED,
- PROP_CHANNEL_PROPERTIES,
- PROP_INITIAL_AUDIO,
- PROP_INITIAL_VIDEO,
- PROP_MEDIA,
- LAST_PROPERTY
-};
-
-struct _HazeMediaChannelPrivate
-{
- HazeConnection *conn;
- gchar *object_path;
- TpHandle creator;
- TpHandle initial_peer;
-
- PurpleMedia *media;
-
- guint next_stream_id;
-
- /* list of PendingStreamRequest* in no particular order */
- GList *pending_stream_requests;
-
- TpLocalHoldState hold_state;
- TpLocalHoldStateReason hold_state_reason;
-
- TpChannelCallStateFlags call_state;
-
- gboolean initial_audio;
- gboolean initial_video;
-
- gboolean ready;
- gboolean media_ended;
- gboolean closed;
- gboolean dispose_has_run;
-};
-
-static void
-haze_media_channel_init (HazeMediaChannel *self)
-{
- HazeMediaChannelPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- HAZE_TYPE_MEDIA_CHANNEL, HazeMediaChannelPrivate);
-
- self->priv = priv;
-
- priv->next_stream_id = 1;
-}
-
-/**
- * make_stream_list:
- *
- * Creates an array of MediaStreamInfo structs.
- */
-static GPtrArray *
-make_stream_list (HazeMediaChannel *self,
- guint len,
- HazeMediaStream **streams)
-{
- HazeMediaChannelPrivate *priv = self->priv;
- GPtrArray *ret;
- guint i;
- GType info_type = TP_STRUCT_TYPE_MEDIA_STREAM_INFO;
-
- ret = g_ptr_array_sized_new (len);
-
- for (i = 0; i < len; i++)
- {
- GValue entry = { 0, };
- guint id;
- TpHandle peer;
- TpMediaStreamType type;
- TpMediaStreamState connection_state;
- CombinedStreamDirection combined_direction;
-
- g_object_get (streams[i],
- "id", &id,
- "media-type", &type,
- "connection-state", &connection_state,
- "combined-direction", &combined_direction,
- NULL);
-
- peer = priv->initial_peer;
-
- g_value_init (&entry, info_type);
- g_value_take_boxed (&entry,
- dbus_g_type_specialized_construct (info_type));
-
- dbus_g_type_struct_set (&entry,
- 0, id,
- 1, peer,
- 2, type,
- 3, connection_state,
- 4, COMBINED_DIRECTION_GET_DIRECTION (combined_direction),
- 5, COMBINED_DIRECTION_GET_PENDING_SEND (combined_direction),
- G_MAXUINT);
-
- g_ptr_array_add (ret, g_value_get_boxed (&entry));
- }
-
- return ret;
-}
-
-typedef struct {
- /* number of streams requested == number of content objects */
- guint len;
- /* array of @len borrowed pointers */
- guint *types;
- /* accumulates borrowed pointers to streams. Initially @len NULL pointers;
- * when the stream for contents[i] is created, it is stored at streams[i].
- */
- HazeMediaStream **streams;
- /* number of non-NULL elements in streams (0 <= satisfied <= contents) */
- guint satisfied;
- /* succeeded_cb(context, GPtrArray<TP_STRUCT_TYPE_MEDIA_STREAM_INFO>)
- * will be called if the stream request succeeds.
- */
- GFunc succeeded_cb;
- /* failed_cb(context, GError *) will be called if the stream request fails.
- */
- GFunc failed_cb;
- gpointer context;
-} PendingStreamRequest;
-
-static PendingStreamRequest *
-pending_stream_request_new (const GArray *types,
- GFunc succeeded_cb,
- GFunc failed_cb,
- gpointer context)
-{
- PendingStreamRequest *p = g_slice_new0 (PendingStreamRequest);
-
- g_assert (succeeded_cb);
- g_assert (failed_cb);
-
- p->len = types->len;
- p->types = g_memdup (types->data, types->len * sizeof (gpointer));
- p->streams = g_new0 (HazeMediaStream *, types->len);
- p->satisfied = 0;
- p->succeeded_cb = succeeded_cb;
- p->failed_cb = failed_cb;
- p->context = context;
-
- return p;
-}
-
-static gboolean
-pending_stream_request_maybe_satisfy (PendingStreamRequest *p,
- HazeMediaChannel *channel,
- guint type,
- HazeMediaStream *stream)
-{
- guint i;
-
- for (i = 0; i < p->len; i++)
- {
- if (p->types[i] == type)
- {
- g_assert (p->streams[i] == NULL);
- p->streams[i] = stream;
-
- if (++p->satisfied == p->len && p->context != NULL)
- {
- GPtrArray *ret = make_stream_list (channel, p->len, p->streams);
-
- p->succeeded_cb (p->context, ret);
- g_ptr_array_foreach (ret, (GFunc) g_value_array_free, NULL);
- g_ptr_array_free (ret, TRUE);
- p->context = NULL;
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-static void
-pending_stream_request_free (gpointer data)
-{
- PendingStreamRequest *p = data;
-
- if (p->context != NULL)
- {
- GError e = { TP_ERROR, TP_ERROR_CANCELLED,
- "The session terminated before the requested streams could be added"
- };
-
- p->failed_cb (p->context, &e);
- }
-
- g_free (p->types);
- g_free (p->streams);
-
- g_slice_free (PendingStreamRequest, p);
-}
-
-static void
-stream_direction_changed_cb (HazeMediaStream *stream,
- GParamSpec *pspec,
- HazeMediaChannel *chan)
-{
- guint id;
- CombinedStreamDirection combined;
- TpMediaStreamDirection direction;
- TpMediaStreamPendingSend pending_send;
-
- g_object_get (stream,
- "id", &id,
- "combined-direction", &combined,
- NULL);
-
- direction = COMBINED_DIRECTION_GET_DIRECTION (combined);
- pending_send = COMBINED_DIRECTION_GET_PENDING_SEND (combined);
-
- DEBUG ("direction: %u, pending_send: %u", direction, pending_send);
-
- tp_svc_channel_type_streamed_media_emit_stream_direction_changed (
- chan, id, direction, pending_send);
-}
-
-static void
-media_error_cb (PurpleMedia *media,
- const gchar *error,
- HazeMediaChannel *chan)
-{
- g_assert (HAZE_MEDIA_CHANNEL(chan)->priv != NULL);
- DEBUG ("Media error on %s: %s", chan->priv->object_path, error);
-}
-
-static void
-media_state_changed_cb (PurpleMedia *media,
- PurpleMediaState state,
- gchar *sid, gchar *name,
- HazeMediaChannel *chan)
-{
- HazeMediaChannelPrivate *priv = chan->priv;
-
- DEBUG ("%s %s %s",
- state == PURPLE_MEDIA_STATE_NEW ? "NEW" :
- state == PURPLE_MEDIA_STATE_CONNECTED ? "CONNECTED" :
- state == PURPLE_MEDIA_STATE_END ? "END" :
- "UNKNOWN", sid, name);
-
- if (state == PURPLE_MEDIA_STATE_NEW)
- {
- if (sid != NULL && name != NULL)
- {
- HazeMediaBackend *backend;
- HazeMediaStream *stream;
- TpMediaStreamType type;
- guint id;
-
- g_object_get (priv->media, "backend", &backend, NULL);
- stream = haze_media_backend_get_stream_by_name (backend, sid);
- g_object_unref (backend);
-
- g_object_get (G_OBJECT (stream), "id", &id, NULL);
- type = haze_media_stream_get_media_type (stream);
-
- /* if any RequestStreams call was waiting for a stream to be created for
- * that content, return from it successfully */
- {
- GList *iter = priv->pending_stream_requests;
-
- while (iter != NULL)
- {
- if (pending_stream_request_maybe_satisfy (iter->data,
- chan, type, stream))
- {
- GList *dead = iter;
-
- pending_stream_request_free (dead->data);
-
- iter = dead->next;
- priv->pending_stream_requests = g_list_delete_link (
- priv->pending_stream_requests, dead);
- }
- else
- {
- iter = iter->next;
- }
- }
- }
-
- g_signal_connect (stream, "notify::combined-direction",
- (GCallback) stream_direction_changed_cb, chan);
-
- tp_svc_channel_type_streamed_media_emit_stream_added (
- chan, id, priv->initial_peer, type);
-
- stream_direction_changed_cb (stream, NULL, chan);
- }
- }
-
- if (sid != NULL && name == NULL)
- {
- TpMediaStreamState tp_state;
- HazeMediaBackend *backend;
- HazeMediaStream *stream;
-
- if (state == PURPLE_MEDIA_STATE_NEW)
- tp_state = TP_MEDIA_STREAM_STATE_CONNECTING;
- else if (state == PURPLE_MEDIA_STATE_CONNECTED)
- tp_state = TP_MEDIA_STREAM_STATE_CONNECTED;
- else if (state == PURPLE_MEDIA_STATE_END)
- tp_state = TP_MEDIA_STREAM_STATE_DISCONNECTED;
- else
- {
- DEBUG ("Invalid state %d", state);
- return;
- }
-
- g_object_get (G_OBJECT (priv->media), "backend", &backend, NULL);
- stream = haze_media_backend_get_stream_by_name (backend, sid);
- g_object_unref (backend);
-
- if (stream != NULL)
- {
- guint id;
- g_object_get (stream, "id", &id, NULL);
- tp_svc_channel_type_streamed_media_emit_stream_state_changed (chan,
- id, tp_state);
- }
- }
-
- if (state == PURPLE_MEDIA_STATE_END)
- {
- if (sid != NULL && name == NULL)
- {
- HazeMediaBackend *backend;
- HazeMediaStream *stream;
-
- g_object_get (G_OBJECT (priv->media), "backend", &backend, NULL);
- stream = haze_media_backend_get_stream_by_name (backend, sid);
- g_object_unref (backend);
-
- if (stream != NULL)
- {
- guint id;
- g_object_get (stream, "id", &id, NULL);
- tp_svc_channel_type_streamed_media_emit_stream_removed (
- chan, id);
- }
- }
- else if (sid == NULL && name == NULL)
- {
- TpGroupMixin *mixin = TP_GROUP_MIXIN (chan);
- guint terminator;
- TpHandle peer;
- TpIntset *set;
-
- priv->media_ended = TRUE;
-
- peer = priv->initial_peer;
-
- /*
- * Primarily, sessions will be ended with hangup or reject. Any that
- * aren't are because of local errors so set the terminator to self.
- */
- terminator = mixin->self_handle;
-
- set = tp_intset_new ();
-
- /* remove us and the peer from the member list */
- tp_intset_add (set, mixin->self_handle);
- tp_intset_add (set, peer);
-
- tp_group_mixin_change_members ((GObject *) chan,
- "Media session ended", NULL, set, NULL, NULL,
- terminator, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
-
- tp_intset_destroy (set);
-
- /* any contents that we were waiting for have now lost */
- g_list_foreach (priv->pending_stream_requests,
- (GFunc) pending_stream_request_free, NULL);
- g_list_free (priv->pending_stream_requests);
- priv->pending_stream_requests = NULL;
-
- if (!priv->closed)
- {
- DEBUG ("calling media channel close from state changed cb");
- haze_media_channel_close (chan);
- }
- }
- }
-}
-
-static void
-media_stream_info_cb(PurpleMedia *media,
- PurpleMediaInfoType type,
- gchar *sid,
- gchar *name,
- gboolean local,
- HazeMediaChannel *chan)
-{
- HazeMediaChannelPrivate *priv = chan->priv;
- TpBaseConnection *conn = (TpBaseConnection *)priv->conn;
-
- if (type == PURPLE_MEDIA_INFO_ACCEPT)
- {
- TpIntset *set;
- TpHandle actor;
-
- if (local == FALSE)
- actor = priv->initial_peer;
- else
- actor = tp_base_connection_get_self_handle (conn);
-
- set = tp_intset_new_containing (actor);
-
- /* add the peer to the member list */
- tp_group_mixin_change_members (G_OBJECT (chan), "", set, NULL, NULL,
- NULL, actor, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
-
- if (sid != NULL && name == NULL && purple_media_is_initiator (
- media, sid, name) == FALSE)
- {
- HazeMediaBackend *backend;
- HazeMediaStream *stream;
-
- g_object_get (G_OBJECT (priv->media), "backend", &backend, NULL);
- stream = haze_media_backend_get_stream_by_name (backend, sid);
- g_object_unref (backend);
-
- g_object_set (stream, "combined-direction",
- MAKE_COMBINED_DIRECTION (
- TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL, 0), NULL);
- }
- }
- else if (type == PURPLE_MEDIA_INFO_REJECT ||
- type == PURPLE_MEDIA_INFO_HANGUP)
- {
- TpGroupMixin *mixin = TP_GROUP_MIXIN (chan);
- guint terminator;
- TpIntset *set;
-
- if (sid != NULL)
- return;
-
- if (local == TRUE)
- terminator = tp_base_connection_get_self_handle (conn);
- else
- /* This will need to get the handle from name for multi-user calls */
- terminator = priv->initial_peer;
-
- set = tp_intset_new ();
-
- if (name != NULL)
- /* Remove participant */
- tp_intset_add (set, priv->initial_peer);
- else
- /* Remove us */
- tp_intset_add (set, mixin->self_handle);
-
- tp_group_mixin_change_members ((GObject *) chan,
- NULL, NULL, set, NULL, NULL, terminator,
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
-
- tp_intset_destroy (set);
- }
-}
-
-static void
-_latch_to_session (HazeMediaChannel *chan)
-{
- HazeMediaChannelPrivate *priv = chan->priv;
- HazeMediaBackend *backend;
- gchar *object_path;
-
- g_assert (priv->media != NULL);
-
- DEBUG ("%p: Latching onto session %p", chan, priv->media);
-
- g_signal_connect(G_OBJECT(priv->media), "error",
- G_CALLBACK(media_error_cb), chan);
- g_signal_connect(G_OBJECT(priv->media), "state-changed",
- G_CALLBACK(media_state_changed_cb), chan);
- g_signal_connect(G_OBJECT(priv->media), "stream-info",
- G_CALLBACK(media_stream_info_cb), chan);
-
- object_path = g_strdup_printf ("%s/MediaSession0", priv->object_path);
-
- g_object_get (G_OBJECT (priv->media), "backend", &backend, NULL);
- g_object_set (G_OBJECT (backend), "object-path", object_path, NULL);
- g_object_unref (backend);
-
- tp_svc_channel_interface_media_signalling_emit_new_session_handler (
- G_OBJECT (chan), object_path, "rtp");
-
- g_free (object_path);
-}
-
-static GObject *
-haze_media_channel_constructor (GType type, guint n_props,
- GObjectConstructParam *props)
-{
- GObject *obj;
- HazeMediaChannelPrivate *priv;
- TpBaseConnection *conn;
- TpDBusDaemon *bus;
- TpIntset *set;
- TpHandleRepoIface *contact_handles;
- TpHandle self_handle;
-
- obj = G_OBJECT_CLASS (haze_media_channel_parent_class)->
- constructor (type, n_props, props);
-
- priv = HAZE_MEDIA_CHANNEL (obj)->priv;
- conn = (TpBaseConnection *) priv->conn;
- contact_handles = tp_base_connection_get_handles (conn,
- TP_HANDLE_TYPE_CONTACT);
- self_handle = tp_base_connection_get_self_handle (conn);
-
- /* register object on the bus */
- bus = tp_base_connection_get_dbus_daemon (conn);
- tp_dbus_daemon_register_object (bus, priv->object_path, obj);
-
- tp_group_mixin_init (obj, G_STRUCT_OFFSET (HazeMediaChannel, group),
- contact_handles, self_handle);
-
- if (priv->media != NULL)
- priv->creator = priv->initial_peer;
- else
- priv->creator = self_handle;
-
- /* automatically add creator to channel, but also ref them again (because
- * priv->creator is the InitiatorHandle) */
- g_assert (priv->creator != 0);
-
- set = tp_intset_new_containing (priv->creator);
- tp_group_mixin_change_members (obj, "", set, NULL, NULL, NULL, 0,
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
- tp_intset_destroy (set);
-
- /* We implement the 0.17.6 properties correctly, and can include a message
- * when ending a call.
- */
- tp_group_mixin_change_flags (obj,
- TP_CHANNEL_GROUP_FLAG_PROPERTIES |
- TP_CHANNEL_GROUP_FLAG_MESSAGE_REMOVE |
- TP_CHANNEL_GROUP_FLAG_MESSAGE_REJECT |
- TP_CHANNEL_GROUP_FLAG_MESSAGE_RESCIND,
- 0);
-
-
- if (priv->media != NULL)
- {
- /* This is an incoming call; make us local pending and don't set any
- * group flags (all we can do is add or remove ourselves, which is always
- * valid per the spec)
- */
- set = tp_intset_new_containing (self_handle);
- tp_group_mixin_change_members (obj, "", NULL, NULL, set, NULL,
- priv->initial_peer, TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
- tp_intset_destroy (set);
-
- /* Set up signal callbacks */
- _latch_to_session (HAZE_MEDIA_CHANNEL (obj));
- }
-
- return obj;
-}
-
-static void
-haze_media_channel_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- HazeMediaChannel *chan = HAZE_MEDIA_CHANNEL (object);
- HazeMediaChannelPrivate *priv = chan->priv;
- TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn;
-
- switch (property_id) {
- case PROP_OBJECT_PATH:
- g_value_set_string (value, priv->object_path);
- break;
- case PROP_CHANNEL_TYPE:
- g_value_set_static_string (value, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
- break;
- case PROP_HANDLE_TYPE:
- /* This is used to implement TargetHandleType, which is immutable. If
- * the peer was known at channel-creation time, this will be Contact;
- * otherwise, it must be None even if we subsequently learn who the peer
- * is.
- */
- if (priv->initial_peer != 0)
- g_value_set_uint (value, TP_HANDLE_TYPE_CONTACT);
- else
- g_value_set_uint (value, TP_HANDLE_TYPE_NONE);
- break;
- case PROP_INITIAL_PEER:
- case PROP_HANDLE:
- /* As above: TargetHandle is immutable, so non-0 only if the peer handle
- * was known at creation time.
- */
- g_value_set_uint (value, priv->initial_peer);
- break;
- case PROP_TARGET_ID:
- /* As above. */
- if (priv->initial_peer != 0)
- {
- TpHandleRepoIface *repo = tp_base_connection_get_handles (
- base_conn, TP_HANDLE_TYPE_CONTACT);
- const gchar *target_id = tp_handle_inspect (repo, priv->initial_peer);
-
- g_value_set_string (value, target_id);
- }
- else
- {
- g_value_set_static_string (value, "");
- }
-
- break;
- case PROP_PEER:
- {
- TpHandle peer = 0;
-
- if (priv->initial_peer != 0)
- peer = priv->initial_peer;
-
- g_value_set_uint (value, peer);
- break;
- }
- case PROP_CONNECTION:
- g_value_set_object (value, priv->conn);
- break;
- case PROP_CREATOR:
- g_value_set_uint (value, priv->creator);
- break;
- case PROP_CREATOR_ID:
- {
- TpHandleRepoIface *repo = tp_base_connection_get_handles (
- base_conn, TP_HANDLE_TYPE_CONTACT);
-
- g_value_set_string (value, tp_handle_inspect (repo, priv->creator));
- }
- break;
- case PROP_REQUESTED:
- g_value_set_boolean (value, (priv->creator ==
- tp_base_connection_get_self_handle (base_conn)));
- break;
- case PROP_INTERFACES:
- g_value_set_boxed (value, haze_media_channel_interfaces);
- break;
- case PROP_CHANNEL_DESTROYED:
- g_value_set_boolean (value, priv->closed);
- break;
- case PROP_CHANNEL_PROPERTIES:
- g_value_take_boxed (value,
- tp_dbus_properties_mixin_make_properties_hash (object,
- TP_IFACE_CHANNEL, "TargetHandle",
- TP_IFACE_CHANNEL, "TargetHandleType",
- TP_IFACE_CHANNEL, "ChannelType",
- TP_IFACE_CHANNEL, "TargetID",
- TP_IFACE_CHANNEL, "InitiatorHandle",
- TP_IFACE_CHANNEL, "InitiatorID",
- TP_IFACE_CHANNEL, "Requested",
- TP_IFACE_CHANNEL, "Interfaces",
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "InitialAudio",
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "InitialVideo",
- NULL));
- break;
- case PROP_MEDIA:
- g_value_set_object (value, priv->media);
- break;
- case PROP_INITIAL_AUDIO:
- g_value_set_boolean (value, priv->initial_audio);
- break;
- case PROP_INITIAL_VIDEO:
- g_value_set_boolean (value, priv->initial_video);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-haze_media_channel_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- HazeMediaChannel *chan = HAZE_MEDIA_CHANNEL (object);
- HazeMediaChannelPrivate *priv = chan->priv;
-
- switch (property_id) {
- case PROP_OBJECT_PATH:
- g_free (priv->object_path);
- priv->object_path = g_value_dup_string (value);
- break;
- case PROP_HANDLE_TYPE:
- case PROP_HANDLE:
- case PROP_CHANNEL_TYPE:
- /* these properties are writable in the interface, but not actually
- * meaningfully changable on this channel, so we do nothing */
- break;
- case PROP_CONNECTION:
- priv->conn = g_value_get_object (value);
- break;
- case PROP_CREATOR:
- priv->creator = g_value_get_uint (value);
- break;
- case PROP_INITIAL_PEER:
- priv->initial_peer = g_value_get_uint (value);
- break;
- case PROP_MEDIA:
- g_assert (priv->media == NULL);
- priv->media = g_value_dup_object (value);
- break;
- case PROP_INITIAL_AUDIO:
- priv->initial_audio = g_value_get_boolean (value);
- break;
- case PROP_INITIAL_VIDEO:
- priv->initial_video = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void haze_media_channel_dispose (GObject *object);
-static void haze_media_channel_finalize (GObject *object);
-
-static void
-haze_media_channel_class_init (HazeMediaChannelClass *haze_media_channel_class)
-{
- static TpDBusPropertiesMixinPropImpl channel_props[] = {
- { "TargetHandleType", "handle-type", NULL },
- { "TargetHandle", "handle", NULL },
- { "TargetID", "target-id", NULL },
- { "ChannelType", "channel-type", NULL },
- { "Interfaces", "interfaces", NULL },
- { "Requested", "requested", NULL },
- { "InitiatorHandle", "creator", NULL },
- { "InitiatorID", "creator-id", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinPropImpl streamed_media_props[] = {
- { "InitialAudio", "initial-audio", NULL },
- { "InitialVideo", "initial-video", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
- { TP_IFACE_CHANNEL,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- channel_props,
- },
- { TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- streamed_media_props,
- },
- { NULL }
- };
- GObjectClass *object_class = G_OBJECT_CLASS (haze_media_channel_class);
- GParamSpec *param_spec;
-
- g_type_class_add_private (haze_media_channel_class,
- sizeof (HazeMediaChannelPrivate));
-
- object_class->constructor = haze_media_channel_constructor;
-
- object_class->get_property = haze_media_channel_get_property;
- object_class->set_property = haze_media_channel_set_property;
-
- object_class->dispose = haze_media_channel_dispose;
- object_class->finalize = haze_media_channel_finalize;
-
- g_object_class_override_property (object_class, PROP_OBJECT_PATH,
- "object-path");
- g_object_class_override_property (object_class, PROP_CHANNEL_TYPE,
- "channel-type");
- g_object_class_override_property (object_class, PROP_HANDLE_TYPE,
- "handle-type");
- g_object_class_override_property (object_class, PROP_HANDLE, "handle");
-
- g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED,
- "channel-destroyed");
- g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES,
- "channel-properties");
-
- param_spec = g_param_spec_string ("target-id", "Target ID",
- "The string that would result from inspecting TargetHandle",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec);
-
- param_spec = g_param_spec_uint ("initial-peer", "Other participant",
- "The TpHandle representing the other participant in the channel if known "
- "at construct-time; 0 if the other participant was unknown at the time "
- "of channel creation",
- 0, G_MAXUINT32, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_PEER, param_spec);
-
- param_spec = g_param_spec_uint ("peer", "Other participant",
- "The TpHandle representing the other participant in the channel if "
- "currently known; 0 if this is an anonymous channel on which "
- "RequestStreams has not yet been called.",
- 0, G_MAXUINT32, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_PEER, param_spec);
-
- param_spec = g_param_spec_object ("connection", "HazeConnection object",
- "Haze connection object that owns this media channel object.",
- HAZE_TYPE_CONNECTION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
-
- param_spec = g_param_spec_uint ("creator", "Channel creator",
- "The TpHandle representing the contact who created the channel.",
- 0, G_MAXUINT32, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CREATOR, param_spec);
-
- param_spec = g_param_spec_string ("creator-id", "Creator ID",
- "The ID obtained by inspecting the creator handle.",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CREATOR_ID, param_spec);
-
- param_spec = g_param_spec_boolean ("requested", "Requested?",
- "True if this channel was requested by the local user",
- FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_REQUESTED, param_spec);
-
- param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
- "Additional Channel.Interface.* interfaces",
- G_TYPE_STRV,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
-
- param_spec = g_param_spec_object ("media", "PurpleMedia object",
- "Purple media associated with this media channel object.",
- PURPLE_TYPE_MEDIA,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_MEDIA, param_spec);
-
- param_spec = g_param_spec_boolean ("initial-audio", "InitialAudio",
- "Whether the channel initially contained an audio stream",
- FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_AUDIO,
- param_spec);
-
- param_spec = g_param_spec_boolean ("initial-video", "InitialVideo",
- "Whether the channel initially contained an video stream",
- FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_VIDEO,
- param_spec);
-
- haze_media_channel_class->dbus_props_class.interfaces = prop_interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (HazeMediaChannelClass, dbus_props_class));
-
- tp_group_mixin_class_init (object_class,
- G_STRUCT_OFFSET (HazeMediaChannelClass, group_class),
- haze_media_channel_add_member, NULL);
- tp_group_mixin_class_set_remove_with_reason_func (object_class,
- haze_media_channel_remove_member);
- tp_group_mixin_class_allow_self_removal (object_class);
-
- tp_group_mixin_init_dbus_properties (object_class);
-}
-
-void
-haze_media_channel_dispose (GObject *object)
-{
- HazeMediaChannel *self = HAZE_MEDIA_CHANNEL (object);
- HazeMediaChannelPrivate *priv = self->priv;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG ("called");
-
- priv->dispose_has_run = TRUE;
-
- if (!priv->closed)
- haze_media_channel_close (self);
-
- g_assert (priv->closed);
-
- if (priv->media != NULL)
- g_object_unref (priv->media);
- priv->media = NULL;
-
- if (G_OBJECT_CLASS (haze_media_channel_parent_class)->dispose)
- G_OBJECT_CLASS (haze_media_channel_parent_class)->dispose (object);
-}
-
-void
-haze_media_channel_finalize (GObject *object)
-{
- HazeMediaChannel *self = HAZE_MEDIA_CHANNEL (object);
- HazeMediaChannelPrivate *priv = self->priv;
-
- g_free (priv->object_path);
-
- tp_group_mixin_finalize (object);
-
- G_OBJECT_CLASS (haze_media_channel_parent_class)->finalize (object);
-}
-
-
-/**
- * haze_media_channel_close_async:
- *
- * Implements D-Bus method Close
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-haze_media_channel_close_async (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- HazeMediaChannel *self = HAZE_MEDIA_CHANNEL (iface);
-
- DEBUG ("called");
- haze_media_channel_close (self);
- tp_svc_channel_return_from_close (context);
-}
-
-void
-haze_media_channel_close (HazeMediaChannel *self)
-{
- HazeMediaChannelPrivate *priv = self->priv;
-
- DEBUG ("called on %p", self);
-
- if (!priv->closed)
- {
- priv->closed = TRUE;
-
- if (priv->media && !priv->media_ended)
- {
- priv->media_ended = TRUE;
- purple_media_stream_info (priv->media,
- PURPLE_MEDIA_INFO_HANGUP, NULL, NULL, FALSE);
- }
-
- tp_svc_channel_emit_closed (self);
- }
-}
-
-
-/**
- * haze_media_channel_get_channel_type
- *
- * Implements D-Bus method GetChannelType
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-haze_media_channel_get_channel_type (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- tp_svc_channel_return_from_get_channel_type (context,
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
-}
-
-
-/**
- * haze_media_channel_get_handle
- *
- * Implements D-Bus method GetHandle
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-haze_media_channel_get_handle (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- HazeMediaChannel *self = HAZE_MEDIA_CHANNEL (iface);
-
- if (self->priv->initial_peer == 0)
- tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_NONE, 0);
- else
- tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_CONTACT,
- self->priv->initial_peer);
-}
-
-
-/**
- * haze_media_channel_get_interfaces
- *
- * Implements D-Bus method GetInterfaces
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-haze_media_channel_get_interfaces (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- tp_svc_channel_return_from_get_interfaces (context,
- haze_media_channel_interfaces);
-}
-
-/**
- * haze_media_channel_list_streams
- *
- * Implements D-Bus method ListStreams
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-haze_media_channel_list_streams (TpSvcChannelTypeStreamedMedia *iface,
- DBusGMethodInvocation *context)
-{
- HazeMediaChannel *self = HAZE_MEDIA_CHANNEL (iface);
- HazeMediaChannelPrivate *priv;
- GPtrArray *ret;
-
- g_assert (HAZE_IS_MEDIA_CHANNEL (self));
-
- priv = self->priv;
-
- /* If the session has not yet started, return an empty array. */
- if (priv->media == NULL)
- {
- ret = g_ptr_array_new ();
- }
- else
- {
- HazeMediaBackend *backend;
- GPtrArray *streams;
-
- g_object_get (G_OBJECT (priv->media), "backend", &backend, NULL);
- g_object_get (G_OBJECT (backend), "streams", &streams, NULL);
-
- ret = make_stream_list (self, streams->len,
- (HazeMediaStream **) streams->pdata);
-
- g_ptr_array_unref (streams);
- g_object_unref (backend);
- }
-
- tp_svc_channel_type_streamed_media_return_from_list_streams (context, ret);
- g_ptr_array_foreach (ret, (GFunc) g_value_array_free, NULL);
- g_ptr_array_free (ret, TRUE);
-}
-
-/**
- * haze_media_channel_remove_streams
- *
- * Implements DBus method RemoveStreams
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-haze_media_channel_remove_streams (TpSvcChannelTypeStreamedMedia *iface,
- const GArray * streams,
- DBusGMethodInvocation *context)
-{
- HazeMediaChannel *obj = HAZE_MEDIA_CHANNEL (iface);
- HazeMediaChannelPrivate *priv;
- HazeMediaBackend *backend;
- GPtrArray *backend_streams;
- guint i, j;
- GPtrArray *media_ids;
- const gchar *target_id;
-
- g_assert (HAZE_IS_MEDIA_CHANNEL (obj));
-
- priv = obj->priv;
-
- g_object_get (obj, "target-id", &target_id, NULL);
-
- if ((purple_prpl_get_media_caps (priv->conn->account, target_id) &
- PURPLE_MEDIA_CAPS_MODIFY_SESSION) == 0)
- {
- TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn);
- gchar *name;
- GError *e;
-
- g_object_get (base_conn, "protocol", &name, NULL);
- g_set_error (&e, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
- "Streams can't be removed in Haze's \"%s\" protocol's calls", name);
- g_free (name);
-
- DEBUG ("%s", e->message);
- dbus_g_method_return_error (context, e);
-
- g_error_free(e);
- return;
- }
-
- media_ids = g_ptr_array_new ();
-
- g_object_get (G_OBJECT (priv->media), "backend", &backend, NULL);
- g_object_get (G_OBJECT (backend), "streams", &backend_streams, NULL);
- g_object_unref (backend);
-
- for (i = 0; i < streams->len; ++i)
- {
- guint id = g_array_index (streams, guint, i);
-
- for (j = 0; j < backend_streams->len; j++)
- {
- HazeMediaStream *stream = g_ptr_array_index (backend_streams, j);
- guint stream_id;
-
- g_object_get (G_OBJECT (stream), "id", &stream_id, NULL);
-
- if (id == stream_id)
- {
- g_ptr_array_add (media_ids, stream->name);
- break;
- }
- }
-
- if (j >= backend_streams->len)
- {
- GError e = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
- "Requested stream wasn't found" };
- DEBUG ("%s", e.message);
- dbus_g_method_return_error (context, &e);
- g_ptr_array_free (media_ids, TRUE);
- return;
- }
- }
-
- for (i = 0; i < media_ids->len; ++i)
- {
- gchar *id = g_ptr_array_index (media_ids, i);
- for (j = i + 1; j < media_ids->len; ++j)
- {
- if (id == g_ptr_array_index (media_ids, j))
- {
- g_ptr_array_remove_index (media_ids, j);
- --j;
- }
- }
- }
-
- for (i = 0; i < media_ids->len; ++i)
- {
- purple_media_end (priv->media, g_ptr_array_index (media_ids, i), NULL);
- }
-
- g_ptr_array_unref (backend_streams);
- g_ptr_array_free (media_ids, TRUE);
- tp_svc_channel_type_streamed_media_return_from_remove_streams (context);
-}
-
-/**
- * haze_media_channel_request_stream_direction
- *
- * Implements D-Bus method RequestStreamDirection
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-haze_media_channel_request_stream_direction (TpSvcChannelTypeStreamedMedia *iface,
- guint stream_id,
- guint stream_direction,
- DBusGMethodInvocation *context)
-{
- /* Libpurple doesn't have API for this yet */
- GError e = { TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
- "Stream direction can't be set Haze calls" };
- DEBUG ("%s", e.message);
- dbus_g_method_return_error (context, &e);
-}
-
-
-static gboolean
-init_media_cb (PurpleMediaManager *manager,
- PurpleMedia *media,
- PurpleAccount *account,
- const gchar *username,
- HazeMediaChannel *self)
-{
- HazeMediaChannelPrivate *priv = self->priv;
- TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn);
- TpHandleRepoIface *contact_repo =
- tp_base_connection_get_handles (base_conn, TP_HANDLE_TYPE_CONTACT);
- TpHandle contact = tp_handle_ensure (contact_repo, username, NULL, NULL);
-
- if (priv->conn->account != account || priv->initial_peer != contact)
- return TRUE;
-
- g_assert (priv->media == NULL);
- priv->media = g_object_ref (media);
- if (priv->media != NULL)
- {
- _latch_to_session (self);
- }
-
- g_signal_handlers_disconnect_by_func (manager, init_media_cb, self);
-
- return TRUE;
-}
-
-static gboolean
-_haze_media_channel_request_contents (HazeMediaChannel *chan,
- TpHandle peer,
- const GArray *media_types,
- GError **error)
-{
- HazeMediaChannelPrivate *priv = chan->priv;
- gboolean want_audio, want_video;
- guint idx;
- TpHandleRepoIface *contact_handles;
- const gchar *contact_id;
- guint audio_count = 0, video_count = 0;
-
- DEBUG ("called");
-
- want_audio = want_video = FALSE;
-
- for (idx = 0; idx < media_types->len; idx++)
- {
- guint media_type = g_array_index (media_types, guint, idx);
-
- if (media_type == TP_MEDIA_STREAM_TYPE_AUDIO)
- {
- want_audio = TRUE;
- }
- else if (media_type == TP_MEDIA_STREAM_TYPE_VIDEO)
- {
- want_video = TRUE;
- }
- else
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
- "given media type %u is invalid", media_type);
- return FALSE;
- }
- }
-
- /* existing call; the recipient and the mode has already been decided */
- if (priv->media != NULL)
- {
- PurpleMediaCaps caps;
- const gchar *target_id;
- g_object_get (chan, "target-id", &target_id, NULL);
- caps = purple_prpl_get_media_caps (priv->conn->account, target_id);
-
- /* Check if the contact supports modifying the session */
- if ((caps & PURPLE_MEDIA_CAPS_MODIFY_SESSION) == 0)
- {
- TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn);
- gchar *name;
-
- g_object_get (base_conn, "protocol", &name, NULL);
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "Streams can't be added in Haze's \"%s\" protocol's calls",
- name);
-
- g_free (name);
- return FALSE;
- }
-
- /* Check if contact supports the desired media type */
- if ((want_audio == FALSE || caps & PURPLE_MEDIA_CAPS_AUDIO) &&
- (want_video == FALSE || caps & PURPLE_MEDIA_CAPS_VIDEO))
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "Member does not have the desired audio/video capabilities");
- return FALSE;
- }
- }
-
- /* if we've got here, we're good to make the streams */
-
- contact_handles = tp_base_connection_get_handles (
- TP_BASE_CONNECTION (priv->conn), TP_HANDLE_TYPE_CONTACT);
- contact_id = tp_handle_inspect (contact_handles, peer);
-
- /* Be ready to retrieve the newly created media object */
- if (priv->media == NULL)
- g_signal_connect (purple_media_manager_get (), "init-media",
- G_CALLBACK (init_media_cb), chan);
-
- for (idx = 0; idx < media_types->len; idx++)
- {
- guint media_type = g_array_index (media_types, guint, idx);
-
- if (media_type == TP_MEDIA_STREAM_TYPE_AUDIO)
- ++audio_count;
- else if (media_type == TP_MEDIA_STREAM_TYPE_VIDEO)
- ++video_count;
- }
-
- while (audio_count > 0 || video_count > 0)
- {
- PurpleMediaSessionType type = PURPLE_MEDIA_NONE;
-
- if (audio_count > 0)
- {
- type |= PURPLE_MEDIA_AUDIO;
- --audio_count;
- }
-
- if (video_count > 0)
- {
- type |= PURPLE_MEDIA_VIDEO;
- --video_count;
- }
-
- if (purple_prpl_initiate_media (priv->conn->account,
- contact_id, type) == FALSE)
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-media_channel_request_streams (HazeMediaChannel *self,
- TpHandle contact_handle,
- const GArray *types,
- GFunc succeeded_cb,
- GFunc failed_cb,
- gpointer context)
-{
- HazeMediaChannelPrivate *priv = self->priv;
- PendingStreamRequest *psr = NULL;
- GError *error = NULL;
-
- if (types->len == 0)
- {
- GPtrArray *empty = g_ptr_array_sized_new (0);
-
- DEBUG ("no streams to request");
- succeeded_cb (context, empty);
- g_ptr_array_free (empty, TRUE);
-
- return;
- }
-
- if (priv->media != NULL)
- {
- TpHandle peer;
-
- peer = priv->initial_peer;
-
- if (peer != contact_handle)
- {
- g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "cannot add streams for %u: this channel's peer is %u",
- contact_handle, peer);
- goto error;
- }
- }
-
- /*
- * Pending stream requests can be completed before request_contents returns.
- * Add the pending stream request up here so it isn't missed.
- */
- psr = pending_stream_request_new (types, succeeded_cb, failed_cb,
- context);
- priv->pending_stream_requests = g_list_prepend (priv->pending_stream_requests,
- psr);
-
- if (!_haze_media_channel_request_contents (self, contact_handle,
- types, &error))
- goto error;
-
- return;
-
-error:
- if (psr != NULL)
- {
- priv->pending_stream_requests = g_list_remove (
- priv->pending_stream_requests, psr);
- pending_stream_request_free (psr);
- }
-
- DEBUG ("returning error %u: %s", error->code, error->message);
- failed_cb (context, error);
- g_error_free (error);
-}
-
-/**
- * haze_media_channel_request_streams
- *
- * Implements D-Bus method RequestStreams
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-haze_media_channel_request_streams (TpSvcChannelTypeStreamedMedia *iface,
- guint contact_handle,
- const GArray *types,
- DBusGMethodInvocation *context)
-{
- HazeMediaChannel *self = HAZE_MEDIA_CHANNEL (iface);
- TpBaseConnection *base_conn = (TpBaseConnection *) self->priv->conn;
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (
- base_conn, TP_HANDLE_TYPE_CONTACT);
- GError *error = NULL;
-
- if (!tp_handle_is_valid (contact_handles, contact_handle, &error))
- {
- DEBUG ("that's not a handle, sonny! (%u)", contact_handle);
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
- else
- {
- /* FIXME: disallow this if we've put the peer on hold? */
-
- media_channel_request_streams (self, contact_handle, types,
- (GFunc) tp_svc_channel_type_streamed_media_return_from_request_streams,
- (GFunc) dbus_g_method_return_error,
- context);
- }
-}
-
-/**
- * haze_media_channel_request_initial_streams:
- * @chan: an outgoing call, which must have just been constructed.
- * @succeeded_cb: called with arguments @user_data and a GPtrArray of
- * TP_STRUCT_TYPE_MEDIA_STREAM_INFO if the request succeeds.
- * @failed_cb: called with arguments @user_data and a GError * if the request
- * fails.
- * @user_data: context for the callbacks.
- *
- * Request streams corresponding to the values of InitialAudio and InitialVideo
- * in the channel request.
- */
-void
-haze_media_channel_request_initial_streams (HazeMediaChannel *chan,
- GFunc succeeded_cb,
- GFunc failed_cb,
- gpointer user_data)
-{
- HazeMediaChannelPrivate *priv = chan->priv;
- GArray *types = g_array_sized_new (FALSE, FALSE, sizeof (guint), 2);
- guint media_type;
-
- /* This has to be an outgoing call... */
- g_assert (priv->creator == tp_base_connection_get_self_handle (
- TP_BASE_CONNECTION (priv->conn)));
-
- if (priv->initial_audio)
- {
- media_type = TP_MEDIA_STREAM_TYPE_AUDIO;
- g_array_append_val (types, media_type);
- }
-
- if (priv->initial_video)
- {
- media_type = TP_MEDIA_STREAM_TYPE_VIDEO;
- g_array_append_val (types, media_type);
- }
-
- media_channel_request_streams (chan, priv->initial_peer, types,
- succeeded_cb, failed_cb, user_data);
-
- g_array_free (types, TRUE);
-}
-
-static gboolean
-haze_media_channel_add_member (GObject *obj,
- TpHandle handle,
- const gchar *message,
- GError **error)
-{
- HazeMediaChannel *chan = HAZE_MEDIA_CHANNEL (obj);
- HazeMediaChannelPrivate *priv = chan->priv;
- TpGroupMixin *mixin = TP_GROUP_MIXIN (obj);
- TpIntset *set;
-
- /* did we create this channel? */
- if (priv->creator == mixin->self_handle)
- {
- /* yes: check we don't have a peer already, and if not add this one to
- * remote pending (but don't send an invitation yet).
- */
- if (priv->media != NULL)
- {
- TpHandle peer;
-
- peer = priv->initial_peer;
-
- if (peer != handle)
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "handle %u cannot be added: this channel's peer is %u",
- handle, peer);
- return FALSE;
- }
- }
-
- /* make the peer remote pending */
- set = tp_intset_new_containing (handle);
- tp_group_mixin_change_members (obj, "", NULL, NULL, NULL, set,
- mixin->self_handle, TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
- tp_intset_destroy (set);
-
- /* and remove CanAdd, since it was only here to allow this deprecated
- * API. */
- tp_group_mixin_change_flags (obj, 0, TP_CHANNEL_GROUP_FLAG_CAN_ADD);
-
- return TRUE;
- }
- else
- {
- /* no: has a session been created, is the handle being added ours,
- * and are we in local pending? (call answer) */
- if (priv->media &&
- handle == mixin->self_handle &&
- tp_handle_set_is_member (mixin->local_pending, handle))
- {
- /* is the call on hold? */
- if (priv->hold_state != TP_LOCAL_HOLD_STATE_UNHELD)
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "Can't answer a call while it's on hold");
- return FALSE;
- }
-
- /* make us a member */
- set = tp_intset_new_containing (handle);
- tp_group_mixin_change_members (obj, "", set, NULL, NULL, NULL,
- handle, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
- tp_intset_destroy (set);
-
- /* signal acceptance */
- purple_media_stream_info(priv->media,
- PURPLE_MEDIA_INFO_ACCEPT, NULL, NULL, TRUE);
-
- return TRUE;
- }
- }
-
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "handle %u cannot be added in the current state", handle);
- return FALSE;
-}
-
-static gboolean
-haze_media_channel_remove_member (GObject *obj,
- TpHandle handle,
- const gchar *message,
- guint reason,
- GError **error)
-{
- HazeMediaChannel *chan = HAZE_MEDIA_CHANNEL (obj);
- HazeMediaChannelPrivate *priv = chan->priv;
- TpGroupMixin *mixin = TP_GROUP_MIXIN (obj);
-
- /* We don't set CanRemove, and did allow self removal. So tp-glib should
- * ensure this.
- */
- g_assert (handle == mixin->self_handle);
-
- /* Closing up might make HazeMediaManager release its ref. */
- g_object_ref (chan);
-
- if (priv->media == NULL)
- {
- haze_media_channel_close (chan);
- }
- else
- {
- switch (reason)
- {
- /* Should one of these trigger reject? */
- case TP_CHANNEL_GROUP_CHANGE_REASON_NONE:
- case TP_CHANNEL_GROUP_CHANGE_REASON_OFFLINE:
- case TP_CHANNEL_GROUP_CHANGE_REASON_BUSY:
- case TP_CHANNEL_GROUP_CHANGE_REASON_ERROR:
- case TP_CHANNEL_GROUP_CHANGE_REASON_NO_ANSWER:
- purple_media_stream_info(priv->media,
- PURPLE_MEDIA_INFO_HANGUP, NULL, NULL, TRUE);
- break;
- default:
- /* The remaining options don't make sense */
- g_object_unref (chan);
- return FALSE;
- }
- }
-
- /* Remove CanAdd if it was there for the deprecated anonymous channel
- * semantics, since the channel will go away RSN. */
- tp_group_mixin_change_flags (obj, 0, TP_CHANNEL_GROUP_FLAG_CAN_ADD);
-
- g_object_unref (chan);
-
- return TRUE;
-}
-
-/**
- * haze_media_channel_get_session_handlers
- *
- * Implements D-Bus method GetSessionHandlers
- * on interface org.freedesktop.Telepathy.Channel.Interface.MediaSignalling
- */
-static void
-haze_media_channel_get_session_handlers (
- TpSvcChannelInterfaceMediaSignalling *iface,
- DBusGMethodInvocation *context)
-{
- HazeMediaChannel *self = HAZE_MEDIA_CHANNEL (iface);
- HazeMediaChannelPrivate *priv;
- GPtrArray *ret;
- GType info_type = TP_STRUCT_TYPE_MEDIA_SESSION_HANDLER_INFO;
-
- g_assert (HAZE_IS_MEDIA_CHANNEL (self));
-
- priv = self->priv;
-
- if (priv->media)
- {
- GValue handler = { 0, };
- HazeMediaBackend *backend;
- gchar *object_path;
-
- g_object_get (G_OBJECT (priv->media), "backend", &backend, NULL);
- g_object_get (G_OBJECT (backend), "object-path", &object_path, NULL);
- g_object_unref (backend);
-
- g_value_init (&handler, info_type);
- g_value_take_boxed (&handler,
- dbus_g_type_specialized_construct (info_type));
-
- dbus_g_type_struct_set (&handler,
- 0, object_path,
- 1, "rtp",
- G_MAXUINT);
-
- g_free (object_path);
-
- ret = g_ptr_array_sized_new (1);
- g_ptr_array_add (ret, g_value_get_boxed (&handler));
- }
- else
- {
- ret = g_ptr_array_sized_new (0);
- }
-
- tp_svc_channel_interface_media_signalling_return_from_get_session_handlers (
- context, ret);
- g_ptr_array_foreach (ret, (GFunc) g_value_array_free, NULL);
- g_ptr_array_free (ret, TRUE);
-}
-
-static void
-channel_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelClass *klass = (TpSvcChannelClass *) g_iface;
-
-#define IMPLEMENT(x, suffix) tp_svc_channel_implement_##x (\
- klass, haze_media_channel_##x##suffix)
- IMPLEMENT(close,_async);
- IMPLEMENT(get_channel_type,);
- IMPLEMENT(get_handle,);
- IMPLEMENT(get_interfaces,);
-#undef IMPLEMENT
-}
-
-static void
-streamed_media_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelTypeStreamedMediaClass *klass =
- (TpSvcChannelTypeStreamedMediaClass *) g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_type_streamed_media_implement_##x (\
- klass, haze_media_channel_##x)
- IMPLEMENT(list_streams);
- IMPLEMENT(remove_streams);
- IMPLEMENT(request_stream_direction);
- IMPLEMENT(request_streams);
-#undef IMPLEMENT
-}
-
-static void
-media_signalling_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelInterfaceMediaSignallingClass *klass =
- (TpSvcChannelInterfaceMediaSignallingClass *) g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_interface_media_signalling_implement_##x (\
- klass, haze_media_channel_##x)
- IMPLEMENT(get_session_handlers);
-#undef IMPLEMENT
-}
diff --git a/src/media-channel.h b/src/media-channel.h
deleted file mode 100644
index ce76440..0000000
--- a/src/media-channel.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * media-channel.h - Header for HazeMediaChannel
- * Copyright (C) 2006, 2009 Collabora Ltd.
- * Copyright (C) 2006 Nokia Corporation
- *
- * Copied heavily from telepathy-gabble
- *
- * 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 __HAZE_MEDIA_CHANNEL_H__
-#define __HAZE_MEDIA_CHANNEL_H__
-
-#include <glib-object.h>
-
-#include <telepathy-glib/telepathy-glib.h>
-
-G_BEGIN_DECLS
-
-typedef struct _HazeMediaChannel HazeMediaChannel;
-typedef struct _HazeMediaChannelPrivate HazeMediaChannelPrivate;
-typedef struct _HazeMediaChannelClass HazeMediaChannelClass;
-
-struct _HazeMediaChannelClass {
- GObjectClass parent_class;
-
- TpGroupMixinClass group_class;
- TpDBusPropertiesMixinClass dbus_props_class;
-};
-
-struct _HazeMediaChannel {
- GObject parent;
-
- TpGroupMixin group;
-
- HazeMediaChannelPrivate *priv;
-};
-
-GType haze_media_channel_get_type (void);
-
-/* TYPE MACROS */
-#define HAZE_TYPE_MEDIA_CHANNEL \
- (haze_media_channel_get_type ())
-#define HAZE_MEDIA_CHANNEL(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), HAZE_TYPE_MEDIA_CHANNEL,\
- HazeMediaChannel))
-#define HAZE_MEDIA_CHANNEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), HAZE_TYPE_MEDIA_CHANNEL,\
- HazeMediaChannelClass))
-#define HAZE_IS_MEDIA_CHANNEL(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), HAZE_TYPE_MEDIA_CHANNEL))
-#define HAZE_IS_MEDIA_CHANNEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), HAZE_TYPE_MEDIA_CHANNEL))
-#define HAZE_MEDIA_CHANNEL_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), HAZE_TYPE_MEDIA_CHANNEL, \
- HazeMediaChannelClass))
-
-void haze_media_channel_request_initial_streams (HazeMediaChannel *chan,
- GFunc succeeded_cb,
- GFunc failed_cb,
- gpointer user_data);
-
-void haze_media_channel_close (HazeMediaChannel *self);
-
-G_END_DECLS
-
-#endif /* #ifndef __HAZE_MEDIA_CHANNEL_H__*/
diff --git a/src/media-manager.c b/src/media-manager.c
deleted file mode 100644
index 406b952..0000000
--- a/src/media-manager.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * media-manager.c - Source for HazeMediaManager
- * Copyright (C) 2006, 2009 Collabora Ltd.
- *
- * Copied heavily from telepathy-gabble
- *
- * 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 "media-manager.h"
-
-#include <libpurple/mediamanager.h>
-#include <telepathy-glib/telepathy-glib.h>
-
-#include "connection.h"
-#include "debug.h"
-#include "media-channel.h"
-
-static void channel_manager_iface_init (gpointer, gpointer);
-static void haze_media_manager_close_all (HazeMediaManager *self);
-static void haze_media_manager_constructed (GObject *object);
-
-G_DEFINE_TYPE_WITH_CODE (HazeMediaManager, haze_media_manager,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER,
- channel_manager_iface_init));
-
-/* properties */
-enum
-{
- PROP_CONNECTION = 1,
- LAST_PROPERTY
-};
-
-struct _HazeMediaManagerPrivate
-{
- HazeConnection *conn;
- gulong status_changed_id;
-
- GPtrArray *channels;
- guint channel_index;
-
- gboolean dispose_has_run;
-};
-
-static void
-haze_media_manager_init (HazeMediaManager *self)
-{
- HazeMediaManagerPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- HAZE_TYPE_MEDIA_MANAGER, HazeMediaManagerPrivate);
-
- self->priv = priv;
-
- priv->channels = g_ptr_array_sized_new (1);
- priv->channel_index = 0;
-
- priv->conn = NULL;
- priv->dispose_has_run = FALSE;
-}
-
-static void
-haze_media_manager_dispose (GObject *object)
-{
- HazeMediaManager *self = HAZE_MEDIA_MANAGER (object);
- HazeMediaManagerPrivate *priv = self->priv;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG ("dispose called");
- priv->dispose_has_run = TRUE;
-
- haze_media_manager_close_all (self);
- g_assert (priv->channels->len == 0);
- g_ptr_array_free (priv->channels, TRUE);
-
- if (G_OBJECT_CLASS (haze_media_manager_parent_class)->dispose)
- G_OBJECT_CLASS (haze_media_manager_parent_class)->dispose (object);
-}
-
-static void
-haze_media_manager_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- HazeMediaManager *self = HAZE_MEDIA_MANAGER (object);
- HazeMediaManagerPrivate *priv = self->priv;
-
- switch (property_id) {
- case PROP_CONNECTION:
- g_value_set_object (value, priv->conn);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-haze_media_manager_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- HazeMediaManager *self = HAZE_MEDIA_MANAGER (object);
- HazeMediaManagerPrivate *priv = self->priv;
-
- switch (property_id) {
- case PROP_CONNECTION:
- priv->conn = g_value_get_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-haze_media_manager_class_init (HazeMediaManagerClass *haze_media_manager_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (haze_media_manager_class);
- GParamSpec *param_spec;
-
- g_type_class_add_private (haze_media_manager_class,
- sizeof (HazeMediaManagerPrivate));
-
- object_class->constructed = haze_media_manager_constructed;
- object_class->dispose = haze_media_manager_dispose;
-
- object_class->get_property = haze_media_manager_get_property;
- object_class->set_property = haze_media_manager_set_property;
-
- param_spec = g_param_spec_object ("connection", "HazeConnection object",
- "Haze connection object that owns this media channel manager object.",
- HAZE_TYPE_CONNECTION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
-
-}
-
-/**
- * media_channel_closed_cb:
- *
- * Signal callback for when a media channel is closed. Removes the references
- * that #HazeMediaManager holds to them.
- */
-static void
-media_channel_closed_cb (HazeMediaChannel *chan, gpointer user_data)
-{
- HazeMediaManager *self = HAZE_MEDIA_MANAGER (user_data);
- HazeMediaManagerPrivate *priv = self->priv;
-
- tp_channel_manager_emit_channel_closed_for_object (self,
- TP_EXPORTABLE_CHANNEL (chan));
-
- DEBUG ("removing media channel %p with ref count %d",
- chan, G_OBJECT (chan)->ref_count);
-
- g_ptr_array_remove (priv->channels, chan);
- g_object_unref (chan);
-}
-
-/**
- * new_media_channel
- *
- * Creates a new empty HazeMediaChannel.
- */
-static HazeMediaChannel *
-new_media_channel (HazeMediaManager *self,
- PurpleMedia *media,
- TpHandle peer,
- gboolean initial_audio,
- gboolean initial_video)
-{
- HazeMediaManagerPrivate *priv;
- TpBaseConnection *conn;
-
- HazeMediaChannel *chan;
- gchar *object_path;
-
- g_assert (HAZE_IS_MEDIA_MANAGER (self));
-
- priv = self->priv;
- conn = (TpBaseConnection *) priv->conn;
-
- object_path = g_strdup_printf ("%s/MediaChannel%u",
- tp_base_connection_get_object_path (conn), priv->channel_index);
- priv->channel_index += 1;
-
- chan = g_object_new (HAZE_TYPE_MEDIA_CHANNEL,
- "connection", priv->conn,
- "object-path", object_path,
- "media", media,
- "initial-peer", peer,
- "initial-audio", initial_audio,
- "initial-video", initial_video,
- NULL);
-
- DEBUG ("object path %s", object_path);
-
- g_signal_connect (chan, "closed", (GCallback) media_channel_closed_cb, self);
-
- g_ptr_array_add (priv->channels, chan);
-
- g_free (object_path);
-
- return chan;
-}
-
-static void
-haze_media_manager_close_all (HazeMediaManager *self)
-{
- HazeMediaManagerPrivate *priv = self->priv;
- GPtrArray *tmp = g_ptr_array_sized_new (priv->channels->len);
- guint i;
-
- for (i = 0; i < priv->channels->len; i++)
- g_ptr_array_add (tmp, g_ptr_array_index (priv->channels, i));
-
- DEBUG ("closing channels");
-
- for (i = 0; i < tmp->len; i++)
- {
- HazeMediaChannel *chan = g_ptr_array_index (tmp, i);
-
- DEBUG ("closing %p", chan);
- haze_media_channel_close (chan);
- }
-
- if (priv->status_changed_id != 0)
- {
- g_signal_handler_disconnect (priv->conn,
- priv->status_changed_id);
- priv->status_changed_id = 0;
- }
-}
-
-static gboolean
-init_media_cb (PurpleMediaManager *manager,
- PurpleMedia *media,
- PurpleAccount *account,
- const gchar *username,
- HazeMediaManager *self)
-{
- HazeMediaManagerPrivate *priv = self->priv;
- TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn);
- TpHandleRepoIface *contact_repo =
- tp_base_connection_get_handles (base_conn, TP_HANDLE_TYPE_CONTACT);
- TpHandle contact = tp_handle_ensure (contact_repo, username, NULL, NULL);
- HazeMediaChannel *chan;
-
- if (purple_media_is_initiator (media, NULL, NULL) == TRUE)
- return TRUE;
-
- chan = new_media_channel (self, media, contact, FALSE, FALSE);
- tp_channel_manager_emit_new_channel (self,
- TP_EXPORTABLE_CHANNEL (chan), NULL);
- DEBUG ("called");
- return TRUE;
-}
-
-static void
-connection_status_changed_cb (HazeConnection *conn,
- guint status,
- guint reason,
- HazeMediaManager *self)
-{
- switch (status)
- {
- case TP_CONNECTION_STATUS_CONNECTING:
- g_signal_connect (purple_media_manager_get (), "init-media",
- G_CALLBACK (init_media_cb), self);
- break;
-
- case TP_CONNECTION_STATUS_DISCONNECTED:
- g_signal_handlers_disconnect_by_func (purple_media_manager_get (),
- G_CALLBACK (init_media_cb), self);
- haze_media_manager_close_all (self);
- break;
- }
-}
-
-static void
-haze_media_manager_constructed (GObject *object)
-{
- void (*chain_up) (GObject *) =
- G_OBJECT_CLASS (haze_media_manager_parent_class)->constructed;
- HazeMediaManager *self = HAZE_MEDIA_MANAGER (object);
- HazeMediaManagerPrivate *priv = self->priv;
-
- if (chain_up != NULL)
- chain_up (object);
-
- priv->status_changed_id = g_signal_connect (priv->conn,
- "status-changed", (GCallback) connection_status_changed_cb, object);
-}
-
-static void
-haze_media_manager_foreach_channel (TpChannelManager *manager,
- TpExportableChannelFunc foreach,
- gpointer user_data)
-{
- HazeMediaManager *self = HAZE_MEDIA_MANAGER (manager);
- HazeMediaManagerPrivate *priv = self->priv;
- guint i;
-
- for (i = 0; i < priv->channels->len; i++)
- {
- TpExportableChannel *channel = TP_EXPORTABLE_CHANNEL (
- g_ptr_array_index (priv->channels, i));
-
- foreach (channel, user_data);
- }
-}
-
-static const gchar * const media_channel_fixed_properties[] = {
- TP_IFACE_CHANNEL ".ChannelType",
- TP_IFACE_CHANNEL ".TargetHandleType",
- NULL
-};
-
-static const gchar * const named_channel_allowed_properties[] = {
- TP_IFACE_CHANNEL ".TargetHandle",
- TP_IFACE_CHANNEL ".TargetID",
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialAudio",
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialVideo",
- NULL
-};
-
-/* not advertised in foreach_channel_class - can only be requested with
- * RequestChannel, not with CreateChannel/EnsureChannel */
-static const gchar * const anon_channel_allowed_properties[] = {
- NULL
-};
-
-static GHashTable *
-haze_media_manager_channel_class (void)
-{
- return tp_asv_new (
- TP_IFACE_CHANNEL ".ChannelType", G_TYPE_STRING,
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
- TP_IFACE_CHANNEL ".TargetHandleType", G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
- NULL);
-}
-
-static void
-haze_media_manager_foreach_channel_class (TpChannelManager *manager,
- TpChannelManagerChannelClassFunc func,
- gpointer user_data)
-{
- GHashTable *table = haze_media_manager_channel_class ();
-
- func (manager, table, named_channel_allowed_properties, user_data);
-
- g_hash_table_destroy (table);
-}
-
-typedef enum
-{
- METHOD_REQUEST,
- METHOD_CREATE,
- METHOD_ENSURE,
-} RequestMethod;
-
-typedef struct
-{
- HazeMediaManager *self;
- HazeMediaChannel *channel;
- gpointer request_token;
-} MediaChannelRequest;
-
-static MediaChannelRequest *
-media_channel_request_new (HazeMediaManager *self,
- HazeMediaChannel *channel,
- gpointer request_token)
-{
- MediaChannelRequest *mcr = g_slice_new0 (MediaChannelRequest);
-
- mcr->self = self;
- mcr->channel = channel;
- mcr->request_token = request_token;
-
- return mcr;
-}
-
-static void
-media_channel_request_free (MediaChannelRequest *mcr)
-{
- g_slice_free (MediaChannelRequest, mcr);
-}
-
-static void
-media_channel_request_succeeded_cb (MediaChannelRequest *mcr,
- GPtrArray *streams)
-{
- GSList *request_tokens;
-
- request_tokens = g_slist_prepend (NULL, mcr->request_token);
- tp_channel_manager_emit_new_channel (mcr->self,
- TP_EXPORTABLE_CHANNEL (mcr->channel), request_tokens);
- g_slist_free (request_tokens);
-
- media_channel_request_free (mcr);
-}
-
-static void
-media_channel_request_failed_cb (MediaChannelRequest *mcr,
- GError *error)
-{
- tp_channel_manager_emit_request_failed (mcr->self, mcr->request_token,
- error->domain, error->code, error->message);
-
- media_channel_request_free (mcr);
-}
-
-static gboolean
-haze_media_manager_requestotron (TpChannelManager *manager,
- gpointer request_token,
- GHashTable *request_properties,
- RequestMethod method)
-{
- HazeMediaManager *self = HAZE_MEDIA_MANAGER (manager);
- HazeMediaManagerPrivate *priv = self->priv;
- TpHandleType handle_type;
- TpHandle handle;
- HazeMediaChannel *channel = NULL;
- GError *error = NULL;
- gboolean initial_audio, initial_video;
-
- /* Supported modes of operation:
- * - CreateChannel({THT: Contact, TH: n}):
- * channel has TargetHandle=n
- * n is not in the group interface at all
- * call is started when caller calls RequestStreams.
- * - EnsureChannel({THT: Contact, TH: n}):
- * look for a channel whose peer is n, and return that if found with
- * whatever properties and group membership it has;
- * otherwise the same as into CreateChannel
- */
-
- if (tp_strdiff (tp_asv_get_string (request_properties,
- TP_IFACE_CHANNEL ".ChannelType"),
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA))
- return FALSE;
-
- handle_type = tp_asv_get_uint32 (request_properties,
- TP_IFACE_CHANNEL ".TargetHandleType", NULL);
-
- handle = tp_asv_get_uint32 (request_properties,
- TP_IFACE_CHANNEL ".TargetHandle", NULL);
-
- initial_audio = tp_asv_get_boolean (request_properties,
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialAudio", NULL);
- initial_video = tp_asv_get_boolean (request_properties,
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA ".InitialVideo", NULL);
-
- switch (handle_type)
- {
- case TP_HANDLE_TYPE_NONE:
- /* already checked by TpBaseConnection */
- g_assert (handle == 0);
-
- g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
- "A valid Contact handle must be provided when requesting a media "
- "channel");
-
- goto error;
- case TP_HANDLE_TYPE_CONTACT:
- /* validity already checked by TpBaseConnection */
- g_assert (handle != 0);
-
- if (tp_channel_manager_asv_has_unknown_properties (request_properties,
- media_channel_fixed_properties, named_channel_allowed_properties,
- &error))
- goto error;
-
- if (method == METHOD_ENSURE)
- {
- guint i;
- TpHandle peer = 0;
-
- for (i = 0; i < priv->channels->len; i++)
- {
- channel = g_ptr_array_index (priv->channels, i);
- g_object_get (channel, "peer", &peer, NULL);
-
- if (peer == handle)
- {
- /* Per the spec, we ignore InitialAudio and InitialVideo when
- * looking for an existing channel.
- */
- tp_channel_manager_emit_request_already_satisfied (self,
- request_token, TP_EXPORTABLE_CHANNEL (channel));
- return TRUE;
- }
- }
- }
-
- channel = new_media_channel (self, NULL, handle,
- initial_audio, initial_video);
- break;
- default:
- return FALSE;
- }
-
- g_assert (channel != NULL);
-
- haze_media_channel_request_initial_streams (channel,
- (GFunc) media_channel_request_succeeded_cb,
- (GFunc) media_channel_request_failed_cb,
- media_channel_request_new (self, channel, request_token));
-
- return TRUE;
-
-error:
- tp_channel_manager_emit_request_failed (self, request_token,
- error->domain, error->code, error->message);
- g_error_free (error);
- return TRUE;
-}
-
-static gboolean
-haze_media_manager_request_channel (TpChannelManager *manager,
- gpointer request_token,
- GHashTable *request_properties)
-{
- return haze_media_manager_requestotron (manager, request_token,
- request_properties, METHOD_REQUEST);
-}
-
-
-static gboolean
-haze_media_manager_create_channel (TpChannelManager *manager,
- gpointer request_token,
- GHashTable *request_properties)
-{
- return haze_media_manager_requestotron (manager, request_token,
- request_properties, METHOD_CREATE);
-}
-
-static gboolean
-haze_media_manager_ensure_channel (TpChannelManager *manager,
- gpointer request_token,
- GHashTable *request_properties)
-{
- return haze_media_manager_requestotron (manager, request_token,
- request_properties, METHOD_ENSURE);
-}
-
-static void
-channel_manager_iface_init (gpointer g_iface,
- gpointer iface_data)
-{
- TpChannelManagerIface *iface = g_iface;
-
- iface->foreach_channel = haze_media_manager_foreach_channel;
- iface->foreach_channel_class = haze_media_manager_foreach_channel_class;
- iface->request_channel = haze_media_manager_request_channel;
- iface->create_channel = haze_media_manager_create_channel;
- iface->ensure_channel = haze_media_manager_ensure_channel;
-}
diff --git a/src/media-manager.h b/src/media-manager.h
deleted file mode 100644
index 72a0409..0000000
--- a/src/media-manager.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * media-manager.h - Header for HazeMediaManager
- * Copyright (C) 2006, 2009 Collabora Ltd.
- *
- * Copied heavily from telepathy-gabble
- *
- * 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 __MEDIA_MANAGER_H__
-#define __MEDIA_MANAGER_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-typedef struct _HazeMediaManager HazeMediaManager;
-typedef struct _HazeMediaManagerClass HazeMediaManagerClass;
-typedef struct _HazeMediaManagerPrivate HazeMediaManagerPrivate;
-
-struct _HazeMediaManagerClass {
- GObjectClass parent_class;
-};
-
-struct _HazeMediaManager {
- GObject parent;
-
- HazeMediaManagerPrivate *priv;
-};
-
-GType haze_media_manager_get_type (void);
-
-/* TYPE MACROS */
-#define HAZE_TYPE_MEDIA_MANAGER \
- (haze_media_manager_get_type ())
-#define HAZE_MEDIA_MANAGER(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), HAZE_TYPE_MEDIA_MANAGER,\
- HazeMediaManager))
-#define HAZE_MEDIA_MANAGER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), HAZE_TYPE_MEDIA_MANAGER,\
- HazeMediaManagerClass))
-#define HAZE_IS_MEDIA_MANAGER(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), HAZE_TYPE_MEDIA_MANAGER))
-#define HAZE_IS_MEDIA_MANAGER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), HAZE_TYPE_MEDIA_MANAGER))
-#define HAZE_MEDIA_MANAGER_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), HAZE_TYPE_MEDIA_MANAGER,\
- HazeMediaManagerClass))
-
-G_END_DECLS
-
-#endif /* #ifndef __MEDIA_MANAGER_H__ */
-
diff --git a/src/media-stream.c b/src/media-stream.c
deleted file mode 100644
index 969d5ac..0000000
--- a/src/media-stream.c
+++ /dev/null
@@ -1,1396 +0,0 @@
-/*
- * media-stream.c - Source for HazeMediaStream
- * Copyright © 2006-2009 Collabora Ltd.
- * Copyright © 2006-2009 Nokia Corporation
- *
- * Copied heavily from telepathy-gabble.
- *
- * 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 "media-stream.h"
-
-#include <libpurple/media/backend-iface.h>
-#include <string.h>
-#include <telepathy-glib/telepathy-glib.h>
-#include <telepathy-glib/telepathy-glib-dbus.h>
-
-#define DEBUG_FLAG HAZE_DEBUG_MEDIA
-
-#include "debug.h"
-
-static void stream_handler_iface_init (gpointer, gpointer);
-
-G_DEFINE_TYPE_WITH_CODE (HazeMediaStream,
- haze_media_stream,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_MEDIA_STREAM_HANDLER,
- stream_handler_iface_init)
- )
-
-/* properties */
-enum
-{
- PROP_OBJECT_PATH = 1,
- PROP_DBUS_DAEMON,
- PROP_NAME,
- PROP_PEER,
- PROP_ID,
- PROP_MEDIA_TYPE,
- PROP_CONNECTION_STATE,
- PROP_READY,
- PROP_PLAYING,
- PROP_COMBINED_DIRECTION,
- PROP_LOCAL_HOLD,
- PROP_MEDIA,
- PROP_CODECS_READY,
- PROP_STUN_SERVERS,
- PROP_RELAY_INFO,
- PROP_NAT_TRAVERSAL,
- PROP_CREATED_LOCALLY,
- LAST_PROPERTY
-};
-
-/* private structure */
-
-struct _HazeMediaStreamPrivate
-{
- PurpleMedia *media;
-
- gchar *object_path;
- TpDBusDaemon *dbus_daemon;
- guint id;
- guint media_type;
-
- GList *codecs;
- GList *remote_codecs;
- GList *local_candidates;
- GList *remote_candidates;
-
- /* Whether we're waiting for a codec intersection from the streaming
- * implementation. If FALSE, SupportedCodecs is a no-op.
- */
- gboolean awaiting_intersection;
-
- guint remote_candidate_count;
-
- gchar *nat_traversal;
- /* GPtrArray(GValueArray(STRING, UINT)) */
- GPtrArray *stun_servers;
- /* GPtrArray(GHashTable(string => GValue)) */
- GPtrArray *relay_info;
-
- gboolean on_hold;
-
- gboolean closed;
- gboolean dispose_has_run;
- gboolean local_hold;
- gboolean ready;
- gboolean sending;
- gboolean created_locally;
-};
-
-HazeMediaStream *
-haze_media_stream_new (const gchar *object_path,
- TpDBusDaemon *dbus_daemon,
- PurpleMedia *media,
- const gchar *name,
- const gchar *peer,
- guint media_type,
- guint id,
- gboolean created_locally,
- const gchar *nat_traversal,
- const GPtrArray *relay_info,
- gboolean local_hold)
-{
- GPtrArray *empty = NULL;
- HazeMediaStream *result;
-
- g_return_val_if_fail (PURPLE_IS_MEDIA (media), NULL);
-
- if (relay_info == NULL)
- {
- empty = g_ptr_array_sized_new (0);
- relay_info = empty;
- }
-
- result = g_object_new (HAZE_TYPE_MEDIA_STREAM,
- "object-path", object_path,
- "dbus-daemon", dbus_daemon,
- "media", media,
- "name", name,
- "peer", peer,
- "media-type", media_type,
- "id", id,
- "created-locally", created_locally,
- "nat-traversal", nat_traversal,
- "relay-info", relay_info,
- "local-hold", local_hold,
- NULL);
-
- if (empty != NULL)
- g_ptr_array_free (empty, TRUE);
-
- return result;
-}
-
-TpMediaStreamType
-haze_media_stream_get_media_type (HazeMediaStream *self)
-{
- return self->priv->media_type;
-}
-
-static void
-haze_media_stream_init (HazeMediaStream *self)
-{
- HazeMediaStreamPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- HAZE_TYPE_MEDIA_STREAM, HazeMediaStreamPrivate);
-
- self->priv = priv;
-
- priv->stun_servers = g_ptr_array_sized_new (1);
-}
-
-static GObject *
-haze_media_stream_constructor (GType type, guint n_props,
- GObjectConstructParam *props)
-{
- GObject *obj;
- HazeMediaStream *stream;
- HazeMediaStreamPrivate *priv;
-
- /* call base class constructor */
- obj = G_OBJECT_CLASS (haze_media_stream_parent_class)->
- constructor (type, n_props, props);
- stream = HAZE_MEDIA_STREAM (obj);
- priv = stream->priv;
-
- g_assert (priv->media != NULL);
-
- /* go for the bus */
- tp_dbus_daemon_register_object (priv->dbus_daemon, priv->object_path, obj);
-
- if (priv->created_locally)
- {
- g_object_set (stream, "combined-direction",
- MAKE_COMBINED_DIRECTION (TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- 0), NULL);
- }
- else
- {
- priv->awaiting_intersection = TRUE;
- g_object_set (stream, "combined-direction",
- MAKE_COMBINED_DIRECTION (TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- TP_MEDIA_STREAM_PENDING_LOCAL_SEND), NULL);
- }
-
- return obj;
-}
-
-static void
-haze_media_stream_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- HazeMediaStream *stream = HAZE_MEDIA_STREAM (object);
- HazeMediaStreamPrivate *priv = stream->priv;
-
- switch (property_id) {
- case PROP_OBJECT_PATH:
- g_value_set_string (value, priv->object_path);
- break;
- case PROP_DBUS_DAEMON:
- g_value_set_object (value, priv->dbus_daemon);
- break;
- case PROP_NAME:
- g_value_set_string (value, stream->name);
- break;
- case PROP_PEER:
- g_value_set_string (value, stream->peer);
- break;
- case PROP_ID:
- g_value_set_uint (value, priv->id);
- break;
- case PROP_MEDIA_TYPE:
- g_value_set_uint (value, priv->media_type);
- break;
- case PROP_CONNECTION_STATE:
- g_value_set_uint (value, stream->connection_state);
- break;
- case PROP_READY:
- g_value_set_boolean (value, priv->ready);
- break;
- case PROP_PLAYING:
- g_value_set_boolean (value, stream->playing);
- break;
- case PROP_COMBINED_DIRECTION:
- g_value_set_uint (value, stream->combined_direction);
- break;
- case PROP_LOCAL_HOLD:
- g_value_set_boolean (value, priv->local_hold);
- break;
- case PROP_MEDIA:
- g_value_set_object (value, priv->media);
- break;
- case PROP_CODECS_READY:
- g_value_set_boolean (value, priv->codecs != NULL);
- break;
- case PROP_STUN_SERVERS:
- g_value_set_boxed (value, priv->stun_servers);
- break;
- case PROP_NAT_TRAVERSAL:
- g_value_set_string (value, priv->nat_traversal);
- break;
- case PROP_CREATED_LOCALLY:
- g_value_set_boolean (value, priv->created_locally);
- break;
- case PROP_RELAY_INFO:
- g_value_set_boxed (value, priv->relay_info);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-haze_media_stream_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- HazeMediaStream *stream = HAZE_MEDIA_STREAM (object);
- HazeMediaStreamPrivate *priv = stream->priv;
-
- switch (property_id) {
- case PROP_OBJECT_PATH:
- g_free (priv->object_path);
- priv->object_path = g_value_dup_string (value);
- break;
- case PROP_DBUS_DAEMON:
- g_assert (priv->dbus_daemon == NULL); /* construct-only */
- priv->dbus_daemon = g_value_dup_object (value);
- break;
- case PROP_NAME:
- g_free (stream->name);
- stream->name = g_value_dup_string (value);
- break;
- case PROP_PEER:
- g_free (stream->peer);
- stream->peer = g_value_dup_string (value);
- break;
- case PROP_ID:
- priv->id = g_value_get_uint (value);
- break;
- case PROP_MEDIA_TYPE:
- priv->media_type = g_value_get_uint (value);
- break;
- case PROP_CONNECTION_STATE:
- DEBUG ("stream %s connection state %d",
- stream->name, stream->connection_state);
- stream->connection_state = g_value_get_uint (value);
- break;
- case PROP_READY:
- priv->ready = g_value_get_boolean (value);
- break;
- case PROP_PLAYING:
- break;
- case PROP_COMBINED_DIRECTION:
- DEBUG ("changing combined direction from %u to %u",
- stream->combined_direction, g_value_get_uint (value));
- stream->combined_direction = g_value_get_uint (value);
- break;
- case PROP_MEDIA:
- g_assert (priv->media == NULL);
- priv->media = g_value_dup_object (value);
- break;
- case PROP_NAT_TRAVERSAL:
- g_assert (priv->nat_traversal == NULL);
- priv->nat_traversal = g_value_dup_string (value);
- break;
- case PROP_CREATED_LOCALLY:
- priv->created_locally = g_value_get_boolean (value);
- break;
- case PROP_RELAY_INFO:
- g_assert (priv->relay_info == NULL);
- priv->relay_info = g_value_dup_boxed (value);
- break;
- case PROP_LOCAL_HOLD:
- priv->local_hold = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void haze_media_stream_dispose (GObject *object);
-static void haze_media_stream_finalize (GObject *object);
-
-static void
-haze_media_stream_class_init (HazeMediaStreamClass *haze_media_stream_class)
-{
- static TpDBusPropertiesMixinPropImpl stream_handler_props[] = {
- { "RelayInfo", "relay-info", NULL },
- { "STUNServers", "stun-servers", NULL },
- { "NATTraversal", "nat-traversal", NULL },
- { "CreatedLocally", "created-locally", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
- { TP_IFACE_MEDIA_STREAM_HANDLER,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- stream_handler_props,
- },
- { NULL }
- };
- GObjectClass *object_class = G_OBJECT_CLASS (haze_media_stream_class);
- GParamSpec *param_spec;
-
- g_type_class_add_private (haze_media_stream_class,
- sizeof (HazeMediaStreamPrivate));
-
- object_class->constructor = haze_media_stream_constructor;
-
- object_class->get_property = haze_media_stream_get_property;
- object_class->set_property = haze_media_stream_set_property;
-
- object_class->dispose = haze_media_stream_dispose;
- object_class->finalize = haze_media_stream_finalize;
-
- param_spec = g_param_spec_string ("object-path", "D-Bus object path",
- "The D-Bus object path used for this "
- "object on the bus.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_OBJECT_PATH, param_spec);
-
- param_spec = g_param_spec_object ("dbus-daemon", "D-Bus connection",
- "Connection to D-Bus",
- TP_TYPE_DBUS_DAEMON,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_DBUS_DAEMON, param_spec);
-
- param_spec = g_param_spec_string ("name", "Stream name",
- "An opaque name for the stream used in the signalling.", NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_NAME, param_spec);
-
- param_spec = g_param_spec_string ("peer", "Peer name",
- "The name for the peer used in the signalling.", NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_PEER, param_spec);
-
- param_spec = g_param_spec_uint ("id", "Stream ID",
- "A stream number for the stream used in the "
- "D-Bus API.",
- 0, G_MAXUINT, 0,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_ID, param_spec);
-
- param_spec = g_param_spec_uint ("media-type", "Stream media type",
- "A constant indicating which media type the stream carries.",
- TP_MEDIA_STREAM_TYPE_AUDIO, TP_MEDIA_STREAM_TYPE_VIDEO,
- TP_MEDIA_STREAM_TYPE_AUDIO,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_MEDIA_TYPE, param_spec);
-
- param_spec = g_param_spec_uint ("connection-state", "Stream connection state",
- "An integer indicating the state of the"
- "stream's connection.",
- TP_MEDIA_STREAM_STATE_DISCONNECTED,
- TP_MEDIA_STREAM_STATE_CONNECTED,
- TP_MEDIA_STREAM_STATE_DISCONNECTED,
- G_PARAM_CONSTRUCT |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_CONNECTION_STATE,
- param_spec);
-
- param_spec = g_param_spec_boolean ("ready", "Ready?",
- "A boolean signifying whether the user "
- "is ready to handle signals from this "
- "object.",
- FALSE,
- G_PARAM_CONSTRUCT |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_READY, param_spec);
-
- param_spec = g_param_spec_boolean ("playing", "Set playing",
- "A boolean signifying whether the stream "
- "has been set playing yet.",
- FALSE,
- G_PARAM_CONSTRUCT |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_PLAYING, param_spec);
-
- param_spec = g_param_spec_uint ("combined-direction",
- "Combined direction",
- "An integer indicating the directions the stream currently sends in, "
- "and the peers who have been asked to send.",
- TP_MEDIA_STREAM_DIRECTION_NONE,
- MAKE_COMBINED_DIRECTION (TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- TP_MEDIA_STREAM_PENDING_LOCAL_SEND |
- TP_MEDIA_STREAM_PENDING_REMOTE_SEND),
- TP_MEDIA_STREAM_DIRECTION_NONE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_COMBINED_DIRECTION,
- param_spec);
-
- param_spec = g_param_spec_boolean ("local-hold", "Local hold?",
- "True if resources used for this stream have been freed.", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK);
- g_object_class_install_property (object_class, PROP_LOCAL_HOLD, param_spec);
-
- param_spec = g_param_spec_object ("media", "PurpleMedia object",
- "Media object signalling this media stream.",
- PURPLE_TYPE_MEDIA,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_MEDIA, param_spec);
-
- param_spec = g_param_spec_boxed ("stun-servers", "STUN servers",
- "Array of (STRING: address literal, UINT: port) pairs",
- /* FIXME: use correct macro when available */
- tp_type_dbus_array_su (),
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STUN_SERVERS, param_spec);
-
- param_spec = g_param_spec_boxed ("relay-info", "Relay info",
- "Array of mappings containing relay server information",
- TP_ARRAY_TYPE_STRING_VARIANT_MAP_LIST,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_RELAY_INFO, param_spec);
-
- param_spec = g_param_spec_string ("nat-traversal", "NAT traversal",
- "NAT traversal mechanism for this stream", NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_NAT_TRAVERSAL,
- param_spec);
-
- param_spec = g_param_spec_boolean ("created-locally", "Created locally?",
- "True if this stream was created by the local user", FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CREATED_LOCALLY,
- param_spec);
-
- param_spec = g_param_spec_boolean ("codecs-ready", "Codecs ready",
- "True if the codecs for this stream are ready to be used", FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CODECS_READY,
- param_spec);
-
- haze_media_stream_class->dbus_props_class.interfaces = prop_interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (HazeMediaStreamClass, dbus_props_class));
-}
-
-void
-haze_media_stream_dispose (GObject *object)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (object);
- HazeMediaStreamPrivate *priv = self->priv;
-
- DEBUG ("called");
-
- if (priv->dispose_has_run)
- return;
-
- priv->dispose_has_run = TRUE;
-
- tp_clear_object (&priv->dbus_daemon);
-
- if (priv->local_candidates)
- {
- purple_media_candidate_list_free (priv->local_candidates);
- priv->local_candidates = NULL;
- }
-
- if (priv->remote_candidates)
- {
- purple_media_candidate_list_free (priv->remote_candidates);
- priv->remote_candidates = NULL;
- }
-
- if (priv->codecs)
- {
- purple_media_codec_list_free (priv->codecs);
- priv->codecs = NULL;
- }
-
- if (priv->remote_codecs)
- {
- purple_media_codec_list_free (priv->remote_codecs);
- priv->remote_codecs = NULL;
- }
-
- g_object_unref (priv->media);
- priv->media = NULL;
-
- if (G_OBJECT_CLASS (haze_media_stream_parent_class)->dispose)
- G_OBJECT_CLASS (haze_media_stream_parent_class)->dispose (object);
-}
-
-void
-haze_media_stream_finalize (GObject *object)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (object);
- HazeMediaStreamPrivate *priv = self->priv;
-
- g_free (priv->object_path);
- g_free (priv->nat_traversal);
-
- /* FIXME: use correct macro when available */
- if (priv->stun_servers != NULL)
- g_boxed_free (tp_type_dbus_array_su (), priv->stun_servers);
-
- if (priv->relay_info != NULL)
- g_boxed_free (TP_ARRAY_TYPE_STRING_VARIANT_MAP_LIST, priv->relay_info);
-
- G_OBJECT_CLASS (haze_media_stream_parent_class)->finalize (object);
-}
-
-
-GList *
-haze_media_stream_get_local_candidates (HazeMediaStream *self)
-{
- HazeMediaStreamPrivate *priv = self->priv;
- return g_list_copy (priv->local_candidates);
-}
-
-
-GList *
-haze_media_stream_get_codecs (HazeMediaStream *self)
-{
- HazeMediaStreamPrivate *priv = self->priv;
- return purple_media_codec_list_copy (priv->codecs);
-}
-
-
-static void
-pass_remote_candidates (HazeMediaStream *self)
-{
- HazeMediaStreamPrivate *priv = self->priv;
- GType transport_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_TRANSPORT;
- GType candidate_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE;
- GList *iter = priv->remote_candidates;
-
- for (; iter; iter = g_list_next (iter))
- {
- gchar *address, *username, *password, *candidate_id;
- GValue candidate = { 0, };
- GPtrArray *transports;
- GValue transport = { 0, };
- PurpleMediaCandidate *c = iter->data;
- PurpleMediaCandidateType candidate_type;
- guint type = TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL;
-
- g_value_init (&transport, transport_struct_type);
- g_value_take_boxed (&transport,
- dbus_g_type_specialized_construct (transport_struct_type));
-
- address = purple_media_candidate_get_ip (c);
- username = purple_media_candidate_get_username (c);
- password = purple_media_candidate_get_password (c);
- candidate_type = purple_media_candidate_get_candidate_type (c);
-
- if (candidate_type == PURPLE_MEDIA_CANDIDATE_TYPE_HOST)
- type = TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL;
- else if (candidate_type == PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX)
- type = TP_MEDIA_STREAM_TRANSPORT_TYPE_DERIVED;
- else if (candidate_type == PURPLE_MEDIA_CANDIDATE_TYPE_RELAY)
- type = TP_MEDIA_STREAM_TRANSPORT_TYPE_RELAY;
- else
- DEBUG ("Unknown candidate type");
-
- dbus_g_type_struct_set (&transport,
- 0, purple_media_candidate_get_component_id (c),
- 1, address,
- 2, purple_media_candidate_get_port (c),
- 3, purple_media_candidate_get_protocol (c) ==
- PURPLE_MEDIA_NETWORK_PROTOCOL_UDP ?
- TP_MEDIA_STREAM_BASE_PROTO_UDP :
- TP_MEDIA_STREAM_BASE_PROTO_TCP,
- 4, "RTP",
- 5, "AVP",
- 6, (double)purple_media_candidate_get_priority (c),
- 7, type,
- 8, username,
- 9, password,
- G_MAXUINT);
-
- g_free (password);
- g_free (username);
- g_free (address);
-
- transports = g_ptr_array_sized_new (1);
- g_ptr_array_add (transports, g_value_get_boxed (&transport));
-
- g_value_init (&candidate, candidate_struct_type);
- g_value_take_boxed (&candidate,
- dbus_g_type_specialized_construct (candidate_struct_type));
-
- candidate_id = purple_media_candidate_get_foundation (c);
-
- dbus_g_type_struct_set (&candidate,
- 0, candidate_id,
- 1, transports,
- G_MAXUINT);
-
- DEBUG ("passing 1 remote candidate to stream engine: %s", candidate_id);
-
- tp_svc_media_stream_handler_emit_add_remote_candidate (
- self, candidate_id, transports);
-
- g_free (candidate_id);
- }
-}
-
-
-void
-haze_media_stream_add_remote_candidates (HazeMediaStream *self,
- GList *remote_candidates)
-{
- HazeMediaStreamPrivate *priv = self->priv;
-
- priv->remote_candidates = g_list_concat (
- priv->remote_candidates,
- purple_media_candidate_list_copy (remote_candidates));
-
- if (priv->ready == TRUE)
- pass_remote_candidates (self);
-}
-
-
-static void
-pass_remote_codecs (HazeMediaStream *self)
-{
- HazeMediaStreamPrivate *priv = self->priv;
- GType codec_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CODEC;
- GPtrArray *codecs = g_ptr_array_new ();
- GList *iter = priv->remote_codecs;
-
- for (; iter; iter = g_list_next (iter))
- {
- GValue codec = { 0, };
- PurpleMediaCodec *c = iter->data;
- gchar *name;
- GList *codec_params;
- GHashTable *params;
-
- g_value_init (&codec, codec_struct_type);
- g_value_take_boxed (&codec,
- dbus_g_type_specialized_construct (codec_struct_type));
-
- name = purple_media_codec_get_encoding_name (c);
- codec_params = purple_media_codec_get_optional_parameters (c);
- params = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_free);
-
- for (; codec_params; codec_params = g_list_next (codec_params))
- {
- PurpleKeyValuePair *pair = codec_params->data;
- g_hash_table_insert (params, pair->key, pair->value);
- }
-
- DEBUG ("new remote %s codec: %u '%s' %u %u %u",
- priv->media_type == TP_MEDIA_STREAM_TYPE_AUDIO ? "audio" : "video",
- purple_media_codec_get_id (c), name, priv->media_type,
- purple_media_codec_get_clock_rate (c),
- purple_media_codec_get_channels (c));
-
- dbus_g_type_struct_set (&codec,
- 0, purple_media_codec_get_id (c),
- 1, name,
- 2, priv->media_type,
- 3, purple_media_codec_get_clock_rate (c),
- 4, purple_media_codec_get_channels (c),
- 5, params,
- G_MAXUINT);
-
- g_free (name);
- g_hash_table_destroy (params);
-
- g_ptr_array_add (codecs, g_value_get_boxed (&codec));
- }
-
- DEBUG ("passing %d remote codecs to stream-engine", codecs->len);
-
- tp_svc_media_stream_handler_emit_set_remote_codecs (self, codecs);
-}
-
-
-void
-haze_media_stream_set_remote_codecs (HazeMediaStream *self,
- GList *remote_codecs)
-{
- HazeMediaStreamPrivate *priv = self->priv;
- GList *iter = priv->remote_codecs;
-
- for (; iter; iter = g_list_delete_link (iter, iter))
- g_object_unref (iter->data);
-
- priv->remote_codecs = purple_media_codec_list_copy (remote_codecs);
-
- if (priv->ready == TRUE)
- pass_remote_codecs (self);
-}
-
-void
-haze_media_stream_add_stun_server (HazeMediaStream *self,
- const gchar *stun_ip,
- guint stun_port)
-{
- HazeMediaStreamPrivate *priv = self->priv;
- GValueArray *va;
- GValue ip = {0}, port = {0};
-
- if (stun_ip == NULL || stun_ip[0] == 0)
- {
- DEBUG ("Invalid STUN address passed: %s", stun_ip);
- return;
- }
- else if (stun_port > 65535)
- {
- DEBUG ("Invalid STUN port passed: %d", stun_port);
- return;
- }
-
- g_value_init (&ip, G_TYPE_STRING);
- g_value_set_string (&ip, stun_ip);
- g_value_init (&port, G_TYPE_UINT);
- g_value_set_uint (&port, stun_port);
-
- va = g_value_array_new (2);
- g_value_array_append (va, &ip);
- g_value_array_append (va, &port);
-
- g_ptr_array_add (priv->stun_servers, va);
-}
-
-
-/**
- * haze_media_stream_codec_choice
- *
- * Implements D-Bus method CodecChoice
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-haze_media_stream_codec_choice (TpSvcMediaStreamHandler *iface,
- guint codec_id,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
-
- g_assert (HAZE_IS_MEDIA_STREAM (self));
-
- tp_svc_media_stream_handler_return_from_codec_choice (context);
-}
-
-
-gboolean
-haze_media_stream_error (HazeMediaStream *self,
- guint err_no,
- const gchar *message,
- GError **error)
-{
- g_assert (HAZE_IS_MEDIA_STREAM (self));
-
- DEBUG ( "Media.StreamHandler::Error called, error %u (%s) -- emitting signal",
- err_no, message);
-
- purple_media_error (self->priv->media, message);
-
- return TRUE;
-}
-
-
-/**
- * haze_media_stream_error
- *
- * Implements D-Bus method Error
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-haze_media_stream_error_async (TpSvcMediaStreamHandler *iface,
- guint errno,
- const gchar *message,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
- GError *error = NULL;
-
- if (haze_media_stream_error (self, errno, message, &error))
- {
- tp_svc_media_stream_handler_return_from_error (context);
- }
- else
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-
-/**
- * haze_media_stream_hold:
- *
- * Tell streaming clients that the stream is going on hold, so they should
- * stop streaming and free up any resources they are currently holding
- * (e.g. close hardware devices); or that the stream is coming off hold,
- * so they should reacquire those resources.
- */
-void
-haze_media_stream_hold (HazeMediaStream *self,
- gboolean hold)
-{
- tp_svc_media_stream_handler_emit_set_stream_held (self, hold);
-}
-
-
-/**
- * haze_media_stream_hold_state:
- *
- * Called by streaming clients when the stream's hold state has been changed
- * successfully in response to SetStreamHeld.
- */
-static void
-haze_media_stream_hold_state (TpSvcMediaStreamHandler *iface,
- gboolean hold_state,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
- HazeMediaStreamPrivate *priv = self->priv;
-
- DEBUG ("%p: %s", self, hold_state ? "held" : "unheld");
- priv->local_hold = hold_state;
-
- g_object_notify ((GObject *) self, "local-hold");
-
- tp_svc_media_stream_handler_return_from_hold_state (context);
-}
-
-
-/**
- * haze_media_stream_unhold_failure:
- *
- * Called by streaming clients when an attempt to reacquire the necessary
- * hardware or software resources to unhold the stream, in response to
- * SetStreamHeld, has failed.
- */
-static void
-haze_media_stream_unhold_failure (TpSvcMediaStreamHandler *iface,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
- HazeMediaStreamPrivate *priv = self->priv;
-
- DEBUG ("%p", self);
-
- priv->local_hold = TRUE;
-
-// maybe emit unhold failed here?
- g_object_notify ((GObject *) self, "local-hold");
-
- tp_svc_media_stream_handler_return_from_unhold_failure (context);
-}
-
-
-/**
- * haze_media_stream_native_candidates_prepared
- *
- * Implements D-Bus method NativeCandidatesPrepared
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-haze_media_stream_native_candidates_prepared (TpSvcMediaStreamHandler *iface,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
- HazeMediaStreamPrivate *priv;
- PurpleMediaBackend *backend;
-
- g_assert (HAZE_IS_MEDIA_STREAM (self));
-
- priv = self->priv;
-
- g_object_get (G_OBJECT (priv->media), "backend", &backend, NULL);
- g_signal_emit_by_name (backend, "candidates-prepared",
- self->name, self->peer);
- g_object_unref (backend);
-
- tp_svc_media_stream_handler_return_from_native_candidates_prepared (context);
-}
-
-
-/**
- * haze_media_stream_new_active_candidate_pair
- *
- * Implements D-Bus method NewActiveCandidatePair
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-haze_media_stream_new_active_candidate_pair (TpSvcMediaStreamHandler *iface,
- const gchar *native_candidate_id,
- const gchar *remote_candidate_id,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
- HazeMediaStreamPrivate *priv;
- PurpleMediaBackend *backend;
- GList *l_iter;
-
- /*
- * This appears to be called for each pair of components.
- * I'm not sure how to go about differentiating between the two
- * components as the ids are the same.
- */
-
- DEBUG ("called (%s, %s)", native_candidate_id, remote_candidate_id);
-
- g_assert (HAZE_IS_MEDIA_STREAM (self));
-
- priv = self->priv;
- l_iter = priv->local_candidates;
- g_object_get (priv->media, "backend", &backend, NULL);
-
- for (; l_iter; l_iter = g_list_next (l_iter))
- {
- PurpleMediaCandidate *lc = l_iter->data;
- GList *r_iter = priv->remote_candidates;
-
- for (; r_iter; r_iter = g_list_next (r_iter))
- {
- PurpleMediaCandidate *rc = r_iter->data;
-
- if (purple_media_candidate_get_component_id (lc) ==
- purple_media_candidate_get_component_id (rc))
- {
- gchar *l_name = purple_media_candidate_get_foundation (lc);
- gchar *r_name = purple_media_candidate_get_foundation (rc);
-
- if (!strcmp (l_name, native_candidate_id) &&
- !strcmp (r_name, remote_candidate_id))
- {
- DEBUG ("Emitting new active candidate pair %d: %s - %s",
- purple_media_candidate_get_component_id (lc),
- l_name, r_name);
-
- g_signal_emit_by_name (backend, "active-candidate-pair",
- self->name, self->peer, lc, rc);
- }
-
- g_free (l_name);
- g_free (r_name);
- }
- }
- }
-
- g_object_unref (backend);
- tp_svc_media_stream_handler_return_from_new_active_candidate_pair (context);
-}
-
-
-/**
- * haze_media_stream_new_native_candidate
- *
- * Implements D-Bus method NewNativeCandidate
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-haze_media_stream_new_native_candidate (TpSvcMediaStreamHandler *iface,
- const gchar *candidate_id,
- const GPtrArray *transports,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
- HazeMediaStreamPrivate *priv;
- PurpleMediaBackend *backend;
- guint i;
-
- g_assert (HAZE_IS_MEDIA_STREAM (self));
-
- priv = self->priv;
-
- g_object_get (G_OBJECT (priv->media), "backend", &backend, NULL);
-
- for (i = 0; i < transports->len; i++)
- {
- GValueArray *transport;
- guint component, type, proto;
- PurpleMediaCandidate *c;
- PurpleMediaCandidateType candidate_type =
- PURPLE_MEDIA_CANDIDATE_TYPE_HOST;
- PurpleMediaNetworkProtocol protocol = PURPLE_MEDIA_NETWORK_PROTOCOL_UDP;
-
- transport = g_ptr_array_index (transports, i);
- component = g_value_get_uint (g_value_array_get_nth (transport, 0));
- type = g_value_get_uint (g_value_array_get_nth (transport, 7));
- proto = g_value_get_uint (g_value_array_get_nth (transport, 3));
-
- if (type == TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL)
- candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_HOST;
- else if (type == TP_MEDIA_STREAM_TRANSPORT_TYPE_DERIVED)
- candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX;
- else if (type == TP_MEDIA_STREAM_TRANSPORT_TYPE_RELAY)
- candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_RELAY;
- else
- DEBUG ("Unknown candidate type");
-
- if (proto == TP_MEDIA_STREAM_BASE_PROTO_UDP)
- protocol = PURPLE_MEDIA_NETWORK_PROTOCOL_UDP;
- else if (proto == TP_MEDIA_STREAM_BASE_PROTO_TCP)
- protocol = PURPLE_MEDIA_NETWORK_PROTOCOL_TCP;
- else
- DEBUG ("Unknown network protocol");
-
- c = purple_media_candidate_new (candidate_id, component, candidate_type,
- protocol,
- /* address */
- g_value_get_string (g_value_array_get_nth (transport, 1)),
- /* port */
- g_value_get_uint (g_value_array_get_nth (transport, 2)));
-
- g_object_set (c, "username",
- g_value_get_string (g_value_array_get_nth (transport, 8)), NULL);
- g_object_set (c, "password",
- g_value_get_string (g_value_array_get_nth (transport, 9)), NULL);
- g_object_set (c, "priority",
- (guint)g_value_get_double (
- g_value_array_get_nth (transport, 6)), NULL);
-
- DEBUG ("new-candidate: %s %s %p", self->name, self->peer, c);
-
- priv->local_candidates = g_list_append (priv->local_candidates, c);
-
- g_signal_emit_by_name (backend, "new-candidate", self->name, self->peer, c);
- }
-
- g_object_unref (backend);
-
- tp_svc_media_stream_handler_return_from_new_native_candidate (context);
-}
-
-static void haze_media_stream_set_local_codecs (TpSvcMediaStreamHandler *,
- const GPtrArray *codecs, DBusGMethodInvocation *);
-
-/**
- * haze_media_stream_ready
- *
- * Implements D-Bus method Ready
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-haze_media_stream_ready (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
- HazeMediaStreamPrivate *priv;
-
- g_assert (HAZE_IS_MEDIA_STREAM (self));
-
- priv = self->priv;
-
- DEBUG ("ready called");
-
- if (priv->ready == FALSE)
- {
- g_object_set (self, "ready", TRUE, NULL);
-
- tp_svc_media_stream_handler_emit_set_stream_playing (self, TRUE);
-
- if (purple_media_get_session_type (priv->media, self->name) &
- (PURPLE_MEDIA_SEND_AUDIO | PURPLE_MEDIA_SEND_VIDEO))
- {
- g_object_set (self, "combined-direction",
- MAKE_COMBINED_DIRECTION (TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- 0), NULL);
- tp_svc_media_stream_handler_emit_set_stream_sending (self, TRUE);
- }
-
- /* If a new stream is added while the call's on hold, it will have
- * local_hold set at construct time. So once tp-fs has called Ready(), we
- * should let it know this stream's on hold.
- */
- if (priv->local_hold)
- haze_media_stream_hold (self, priv->local_hold);
- }
- else
- {
- DEBUG ("Ready called twice, running plain SetLocalCodecs instead");
- }
-
- /* set_local_codecs and ready return the same thing, so we can do... */
- haze_media_stream_set_local_codecs (iface, codecs, context);
- pass_remote_codecs (self);
- pass_remote_candidates (self);
-}
-
-static void
-convert_param (gchar *key, gchar *value, PurpleMediaCodec *codec)
-{
- purple_media_codec_add_optional_parameter (codec, key, value);
-}
-
-static gboolean
-pass_local_codecs (HazeMediaStream *stream,
- const GPtrArray *codecs,
- gboolean ready,
- GError **error)
-{
- HazeMediaStreamPrivate *priv = stream->priv;
- PurpleMediaSessionType type = PURPLE_MEDIA_AUDIO;
- PurpleMediaCodec *c;
- guint i;
-
- DEBUG ("putting list of %d supported codecs from stream-engine into cache",
- codecs->len);
-
- if (priv->media_type == TP_MEDIA_STREAM_TYPE_AUDIO)
- type = PURPLE_MEDIA_AUDIO;
- else if (priv->media_type == TP_MEDIA_STREAM_TYPE_VIDEO)
- type = PURPLE_MEDIA_VIDEO;
- else
- g_assert_not_reached ();
-
- for (i = 0; i < codecs->len; i++)
- {
- GType codec_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CODEC;
-
- GValue codec = { 0, };
- guint id, clock_rate, channels;
- gchar *name;
- GHashTable *params;
-
- g_value_init (&codec, codec_struct_type);
- g_value_set_static_boxed (&codec, g_ptr_array_index (codecs, i));
-
- dbus_g_type_struct_get (&codec,
- 0, &id,
- 1, &name,
- 3, &clock_rate,
- 4, &channels,
- 5, &params,
- G_MAXUINT);
-
- c = purple_media_codec_new (id, name, type, clock_rate);
- g_object_set (c, "channels", channels, NULL);
-
- g_hash_table_foreach (params, (GHFunc)convert_param, c);
-
- DEBUG ("adding codec: %s", purple_media_codec_to_string (c));
-
- priv->codecs = g_list_append (priv->codecs, c);
-
- g_signal_emit_by_name (priv->media, "codecs-changed", stream->name);
- }
-
- return TRUE;
-}
-
-/**
- * haze_media_stream_set_local_codecs
- *
- * Implements D-Bus method SetLocalCodecs
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-haze_media_stream_set_local_codecs (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
- HazeMediaStreamPrivate *priv = self->priv;
- GError *error = NULL;
-
- DEBUG ("called");
-
- if (PURPLE_IS_MEDIA (priv->media) &&
- purple_media_is_initiator (priv->media, self->name, self->peer))
- {
- if (!pass_local_codecs (self, codecs, self->priv->created_locally,
- &error))
- {
- DEBUG ("failed: %s", error->message);
-
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
- }
- else
- {
- DEBUG ("ignoring local codecs, waiting for codec intersection");
- }
-
- tp_svc_media_stream_handler_return_from_set_local_codecs (context);
-}
-
-/**
- * haze_media_stream_stream_state
- *
- * Implements D-Bus method StreamState
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-haze_media_stream_stream_state (TpSvcMediaStreamHandler *iface,
- guint connection_state,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
-
- g_object_set (self, "connection-state", connection_state, NULL);
-
- // emit connection state here
-
- tp_svc_media_stream_handler_return_from_stream_state (context);
-}
-
-
-/**
- * haze_media_stream_supported_codecs
- *
- * Implements D-Bus method SupportedCodecs
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-haze_media_stream_supported_codecs (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
- HazeMediaStreamPrivate *priv = self->priv;
- GError *error = NULL;
-
- DEBUG ("called");
-
- if (priv->awaiting_intersection)
- {
- if (!pass_local_codecs (self, codecs, TRUE, &error))
- {
- DEBUG ("failed: %s", error->message);
-
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- priv->awaiting_intersection = FALSE;
- }
- else
- {
- /* If we created the stream, we don't need to send the intersection. If
- * we didn't create it, but have already sent the intersection once, we
- * don't need to send it again. In either case, extra calls to
- * SupportedCodecs are in response to an incoming description-info, which
- * can only change parameters and which XEP-0167 §10 says is purely
- * advisory.
- */
- DEBUG ("we already sent, or don't need to send, our codecs");
- }
-
- tp_svc_media_stream_handler_return_from_supported_codecs (context);
-}
-
-/**
- * haze_media_stream_codecs_updated
- *
- * Implements D-Bus method CodecsUpdated
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-haze_media_stream_codecs_updated (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- HazeMediaStream *self = HAZE_MEDIA_STREAM (iface);
- GError *error = NULL;
-
- if (self->priv->codecs == NULL)
- {
- GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "CodecsUpdated may only be called once an initial set of codecs "
- "has been set" };
-
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- if (self->priv->awaiting_intersection)
- {
- /* When awaiting an intersection the initial set of codecs should be set
- * by calling SupportedCodecs as that is the canonical set of codecs,
- * updates are only meaningful afterwards */
- tp_svc_media_stream_handler_return_from_codecs_updated (context);
- return;
- }
-
- if (pass_local_codecs (self, codecs, self->priv->created_locally, &error))
- {
- tp_svc_media_stream_handler_return_from_codecs_updated (context);
- }
- else
- {
- DEBUG ("failed: %s", error->message);
-
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-static void
-stream_handler_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcMediaStreamHandlerClass *klass =
- (TpSvcMediaStreamHandlerClass *) g_iface;
-
-#define IMPLEMENT(x,suffix) tp_svc_media_stream_handler_implement_##x (\
- klass, haze_media_stream_##x##suffix)
- IMPLEMENT(codec_choice,);
- IMPLEMENT(error,_async);
- IMPLEMENT(hold_state,);
- IMPLEMENT(native_candidates_prepared,);
- IMPLEMENT(new_active_candidate_pair,);
- IMPLEMENT(new_native_candidate,);
- IMPLEMENT(ready,);
- IMPLEMENT(set_local_codecs,);
- IMPLEMENT(stream_state,);
- IMPLEMENT(supported_codecs,);
- IMPLEMENT(unhold_failure,);
- IMPLEMENT(codecs_updated,);
-#undef IMPLEMENT
-}
diff --git a/src/media-stream.h b/src/media-stream.h
deleted file mode 100644
index 0d6f328..0000000
--- a/src/media-stream.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * media-stream.h - Header for HazeMediaStream
- * Copyright (C) 2006, 2009 Collabora Ltd.
- * Copyright (C) 2006 Nokia Corporation
- *
- * Copied heavily from telepathy-gabble.
- *
- * 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 __HAZE_MEDIA_STREAM_H__
-#define __HAZE_MEDIA_STREAM_H__
-
-#include <glib-object.h>
-#include <libpurple/media.h>
-#include <telepathy-glib/telepathy-glib.h>
-
-G_BEGIN_DECLS
-
-typedef enum
-{
- STREAM_SIG_STATE_NEW,
- STREAM_SIG_STATE_SENT,
- STREAM_SIG_STATE_ACKNOWLEDGED,
- STREAM_SIG_STATE_REMOVING
-} StreamSignallingState;
-
-typedef guint32 CombinedStreamDirection;
-
-typedef struct _HazeMediaStream HazeMediaStream;
-typedef struct _HazeMediaStreamClass HazeMediaStreamClass;
-typedef struct _HazeMediaStreamPrivate HazeMediaStreamPrivate;
-
-struct _HazeMediaStreamClass {
- GObjectClass parent_class;
-
- TpDBusPropertiesMixinClass dbus_props_class;
-};
-
-struct _HazeMediaStream {
- GObject parent;
-
- gchar *name;
- gchar *peer;
-
- TpMediaStreamState connection_state;
-
- CombinedStreamDirection combined_direction;
- gboolean playing;
-
- HazeMediaStreamPrivate *priv;
-};
-
-GType haze_media_stream_get_type (void);
-
-/* TYPE MACROS */
-#define HAZE_TYPE_MEDIA_STREAM \
- (haze_media_stream_get_type ())
-#define HAZE_MEDIA_STREAM(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), HAZE_TYPE_MEDIA_STREAM, \
- HazeMediaStream))
-#define HAZE_MEDIA_STREAM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), HAZE_TYPE_MEDIA_STREAM, \
- HazeMediaStreamClass))
-#define HAZE_IS_MEDIA_STREAM(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), HAZE_TYPE_MEDIA_STREAM))
-#define HAZE_IS_MEDIA_STREAM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), HAZE_TYPE_MEDIA_STREAM))
-#define HAZE_MEDIA_STREAM_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), HAZE_TYPE_MEDIA_STREAM, \
- HazeMediaStreamClass))
-
-#define COMBINED_DIRECTION_GET_DIRECTION(d) \
- ((TpMediaStreamDirection) ((d) & TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL))
-#define COMBINED_DIRECTION_GET_PENDING_SEND(d) \
- ((TpMediaStreamPendingSend) ((d) >> 2))
-#define MAKE_COMBINED_DIRECTION(d, p) \
- ((CombinedStreamDirection) ((d) | ((p) << 2)))
-
-gboolean haze_media_stream_error (HazeMediaStream *self, guint err_no,
- const gchar *message, GError **error);
-
-void haze_media_stream_close (HazeMediaStream *close);
-void haze_media_stream_hold (HazeMediaStream *stream, gboolean hold);
-gboolean haze_media_stream_change_direction (HazeMediaStream *stream,
- guint requested_dir, GError **error);
-void haze_media_stream_accept_pending_local_send (HazeMediaStream *stream);
-
-HazeMediaStream *haze_media_stream_new (const gchar *object_path,
- TpDBusDaemon *dbus_daemon,
- PurpleMedia *media,
- const gchar *name,
- const gchar *peer,
- guint media_type,
- guint id,
- gboolean created_locally,
- const gchar *nat_traversal,
- const GPtrArray *relay_info,
- gboolean local_hold);
-TpMediaStreamType haze_media_stream_get_media_type (HazeMediaStream *self);
-
-GList *haze_media_stream_get_local_candidates (HazeMediaStream *self);
-GList *haze_media_stream_get_codecs (HazeMediaStream *self);
-void haze_media_stream_add_remote_candidates (HazeMediaStream *self,
- GList *remote_candidates);
-void haze_media_stream_set_remote_codecs (HazeMediaStream *self,
- GList *remote_codecs);
-void haze_media_stream_add_stun_server (HazeMediaStream *self,
- const gchar *stun_ip,
- guint stun_port);
-
-G_END_DECLS
-
-#endif /* #ifndef __HAZE_MEDIA_STREAM_H__*/
diff --git a/src/protocol.c b/src/protocol.c
index aa4d864..df56071 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -913,9 +913,6 @@ haze_protocol_get_connection_details (TpBaseProtocol *base,
{
GType types[] = { HAZE_TYPE_IM_CHANNEL_FACTORY,
HAZE_TYPE_CONTACT_LIST,
-#ifdef ENABLE_MEDIA
- HAZE_TYPE_MEDIA_MANAGER,
-#endif
G_TYPE_INVALID };
*channel_manager_types = g_memdup (types, sizeof (types));
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index 81b9118..da5d473 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -52,22 +52,10 @@ EXTRA_DIST = \
servicetest.py \
ns.py
-if MEDIA_ENABLED
-MEDIA_ENABLED_PYBOOL = True
-else
-MEDIA_ENABLED_PYBOOL = False
-endif
-
-config.py: Makefile
- $(AM_V_GEN) { \
- echo "MEDIA_ENABLED = $(MEDIA_ENABLED_PYBOOL)"; \
- } > $@
-
haze-twisted-tests.list: Makefile
$(AM_V_GEN)echo $(TWISTED_TESTS) > $@
BUILT_SOURCES = \
- config.py \
haze-twisted-tests.list \
run-test.sh \
$(NULL)
diff --git a/tests/twisted/simple-caps.py b/tests/twisted/simple-caps.py
index d0088d3..862a2de 100644
--- a/tests/twisted/simple-caps.py
+++ b/tests/twisted/simple-caps.py
@@ -9,8 +9,6 @@ from servicetest import assertEquals, assertContains, EventPattern
from hazetest import exec_test, sync_stream, JabberXmlStream
import constants as cs
-import config
-
import ns
# assert this list of RCCs is only text
@@ -66,32 +64,6 @@ def test_someone_else(q, bus, conn, stream):
amy_handle = conn.RequestHandles(cs.HT_CONTACT, ['amy@foo.com'])[0]
check_rccs(conn, amy_handle)
-def test_media(q, bus, conn, stream):
- sync_stream(q, stream)
-
- conn.ContactCapabilities.UpdateCapabilities([(
- 'im.telepathy1.Client.Foobar',
- [{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.INITIAL_AUDIO: True },
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.INITIAL_VIDEO: True }],
- [],
- )])
-
- q.expect('stream-presence') # can't be bothered checking this
-
- conn.ContactCapabilities.UpdateCapabilities([(
- 'im.telepathy1.Client.Foobar',
- [], [])])
-
- q.expect('stream-presence') # can't be bothered checking this
-
if __name__ == '__main__':
exec_test(test_self_handle)
exec_test(test_someone_else, do_connect=False, protocol=JabberXmlStream)
-
- if config.MEDIA_ENABLED:
- exec_test(test_media)
-