[telepathy-gabble/master] Split Hold implementation to a separate source file.
Will Thompson
will.thompson at collabora.co.uk
Tue Apr 14 04:11:03 PDT 2009
---
src/Makefile.am | 2 +
src/media-channel-hold.c | 312 ++++++++++++++++++++++++++++++++++++++++++
src/media-channel-internal.h | 84 +++++++++++
src/media-channel.c | 306 +----------------------------------------
4 files changed, 403 insertions(+), 301 deletions(-)
create mode 100644 src/media-channel-hold.c
create mode 100644 src/media-channel-internal.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 195d687..f550dc4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -72,7 +72,9 @@ libgabble_convenience_la_SOURCES = \
jingle-transport-iface.h \
jingle-transport-iface.c \
media-channel.h \
+ media-channel-internal.h \
media-channel.c \
+ media-channel-hold.c \
media-stream.h \
media-stream.c \
media-factory.h \
diff --git a/src/media-channel-hold.c b/src/media-channel-hold.c
new file mode 100644
index 0000000..4ee02b1
--- /dev/null
+++ b/src/media-channel-hold.c
@@ -0,0 +1,312 @@
+/*
+ * media-channel-hold.c - Hold and CallState interface implementations
+ * 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 "media-channel.h"
+#include "media-channel-internal.h"
+
+#include <telepathy-glib/channel-iface.h>
+
+#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
+
+#include "debug.h"
+#include "util.h"
+
+static void
+inform_peer_of_unhold (GabbleMediaChannel *self)
+{
+ gabble_jingle_session_send_held (self->priv->session, FALSE);
+}
+
+
+static void
+inform_peer_of_hold (GabbleMediaChannel *self)
+{
+ gabble_jingle_session_send_held (self->priv->session, TRUE);
+}
+
+
+static void
+stream_hold_state_changed (GabbleMediaStream *stream G_GNUC_UNUSED,
+ GParamSpec *unused G_GNUC_UNUSED,
+ gpointer data)
+{
+ GabbleMediaChannel *self = data;
+ GabbleMediaChannelPrivate *priv = self->priv;
+ gboolean all_held = TRUE, any_held = FALSE;
+ guint i;
+
+ for (i = 0; i < priv->streams->len; i++)
+ {
+ gboolean its_hold;
+
+ g_object_get (g_ptr_array_index (priv->streams, i),
+ "local-hold", &its_hold,
+ NULL);
+
+ DEBUG ("Stream at index %u has local-hold=%u", i, (guint) its_hold);
+
+ all_held = all_held && its_hold;
+ any_held = any_held || its_hold;
+ }
+
+ DEBUG ("all_held=%u, any_held=%u", (guint) all_held, (guint) any_held);
+
+ if (all_held)
+ {
+ /* Move to state HELD */
+
+ if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD)
+ {
+ /* nothing changed */
+ return;
+ }
+ else if (priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_UNHOLD)
+ {
+ /* This can happen if the user asks us to hold, then changes their
+ * mind. We make no particular guarantees about stream states when
+ * in PENDING_UNHOLD state, so keep claiming to be in that state */
+ return;
+ }
+ else if (priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_HOLD)
+ {
+ /* We wanted to hold, and indeed we have. Yay! Keep whatever
+ * reason code we used for going to PENDING_HOLD */
+ priv->hold_state = TP_LOCAL_HOLD_STATE_HELD;
+ }
+ else
+ {
+ /* We were previously UNHELD. So why have we gone on hold now? */
+ DEBUG ("Unexpectedly entered HELD state!");
+ priv->hold_state = TP_LOCAL_HOLD_STATE_HELD;
+ priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
+ }
+ }
+ else if (any_held)
+ {
+ if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD)
+ {
+ /* The streaming client has spontaneously changed its stream
+ * state. Why? We just don't know */
+ DEBUG ("Unexpectedly entered PENDING_UNHOLD state!");
+ priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_UNHOLD;
+ priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
+ }
+ else if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD)
+ {
+ /* Likewise */
+ DEBUG ("Unexpectedly entered PENDING_HOLD state!");
+ priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_HOLD;
+ priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
+ }
+ else
+ {
+ /* nothing particularly interesting - we're trying to change hold
+ * state already, so nothing to signal */
+ return;
+ }
+ }
+ else
+ {
+ /* Move to state UNHELD */
+
+ if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD)
+ {
+ /* nothing changed */
+ return;
+ }
+ else if (priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_HOLD)
+ {
+ /* This can happen if the user asks us to unhold, then changes their
+ * mind. We make no particular guarantees about stream states when
+ * in PENDING_HOLD state, so keep claiming to be in that state */
+ return;
+ }
+ else if (priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_UNHOLD)
+ {
+ /* We wanted to hold, and indeed we have. Yay! Keep whatever
+ * reason code we used for going to PENDING_UNHOLD */
+ priv->hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
+ }
+ else
+ {
+ /* We were previously HELD. So why have we gone off hold now? */
+ DEBUG ("Unexpectedly entered UNHELD state!");
+ priv->hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
+ priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
+ }
+
+ /* Tell the peer what's happened */
+ inform_peer_of_unhold (self);
+ }
+
+ tp_svc_channel_interface_hold_emit_hold_state_changed (self,
+ priv->hold_state, priv->hold_state_reason);
+}
+
+
+static void
+stream_unhold_failed (GabbleMediaStream *stream,
+ gpointer data)
+{
+ GabbleMediaChannel *self = data;
+ GabbleMediaChannelPrivate *priv = self->priv;
+ guint i;
+
+ DEBUG ("%p: %p", self, stream);
+
+ /* Unholding failed - let's roll back to Hold state */
+ priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_HOLD;
+ priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_RESOURCE_NOT_AVAILABLE;
+ tp_svc_channel_interface_hold_emit_hold_state_changed (self,
+ priv->hold_state, priv->hold_state_reason);
+
+ /* The stream's state may have changed from unheld to held, so re-poll.
+ * It's possible that all streams are now held, in which case we can stop. */
+ stream_hold_state_changed (stream, NULL, self);
+
+ if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD)
+ return;
+
+ /* There should be no need to notify the peer, who already thinks they're
+ * on hold, so just tell the streaming client what to do. */
+
+ for (i = 0; i < priv->streams->len; i++)
+ {
+ gabble_media_stream_hold (g_ptr_array_index (priv->streams, i),
+ TRUE);
+ }
+}
+
+
+void
+gabble_media_channel_hold_stream_closed (GabbleMediaChannel *chan,
+ GabbleMediaStream *stream)
+{
+ /* A stream closing might cause the "total" hold state to change:
+ * if there's one held and one unheld, and the unheld one closes,
+ * then our state changes from indeterminate to held. */
+ stream_hold_state_changed (stream, NULL, chan);
+}
+
+
+/* Called by construct_stream to allow the Hold code to hook itself up to a new
+ * stream.
+ */
+void
+gabble_media_channel_hold_new_stream (GabbleMediaChannel *chan,
+ GabbleMediaStream *stream)
+{
+ GObject *chan_o = (GObject *) chan;
+
+ gabble_signal_connect_weak (stream, "unhold-failed",
+ (GCallback) stream_unhold_failed, chan_o);
+ gabble_signal_connect_weak (stream, "notify::local-hold",
+ (GCallback) stream_hold_state_changed, chan_o);
+
+ /* A stream being added might cause the "total" hold state to change */
+ stream_hold_state_changed (stream, NULL, chan);
+}
+
+
+/* Implements RequestHold on Telepathy.Channel.Interface.Hold */
+static void
+gabble_media_channel_request_hold (TpSvcChannelInterfaceHold *iface,
+ gboolean hold,
+ DBusGMethodInvocation *context)
+{
+ GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
+ GabbleMediaChannelPrivate *priv = self->priv;
+ guint i;
+ TpLocalHoldState old_state = priv->hold_state;
+
+ DEBUG ("%p: RequestHold(%u)", self, !!hold);
+
+ if (hold)
+ {
+ if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD)
+ {
+ DEBUG ("No-op");
+ tp_svc_channel_interface_hold_return_from_request_hold (context);
+ return;
+ }
+
+ if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD)
+ {
+ inform_peer_of_hold (self);
+ }
+
+ priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_HOLD;
+ }
+ else
+ {
+ if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD)
+ {
+ DEBUG ("No-op");
+ tp_svc_channel_interface_hold_return_from_request_hold (context);
+ return;
+ }
+
+ priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_UNHOLD;
+ }
+
+ if (old_state != priv->hold_state ||
+ priv->hold_state_reason != TP_LOCAL_HOLD_STATE_REASON_REQUESTED)
+ {
+ tp_svc_channel_interface_hold_emit_hold_state_changed (self,
+ priv->hold_state, TP_LOCAL_HOLD_STATE_REASON_REQUESTED);
+ priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_REQUESTED;
+ }
+
+ /* Tell streaming client to release or reacquire resources */
+
+ for (i = 0; i < priv->streams->len; i++)
+ {
+ gabble_media_stream_hold (g_ptr_array_index (priv->streams, i), hold);
+ }
+
+ tp_svc_channel_interface_hold_return_from_request_hold (context);
+}
+
+
+/* Implements GetHoldState on Telepathy.Channel.Interface.Hold */
+static void
+gabble_media_channel_get_hold_state (TpSvcChannelInterfaceHold *iface,
+ DBusGMethodInvocation *context)
+{
+ GabbleMediaChannel *self = (GabbleMediaChannel *) iface;
+ GabbleMediaChannelPrivate *priv = self->priv;
+
+ tp_svc_channel_interface_hold_return_from_get_hold_state (context,
+ priv->hold_state, priv->hold_state_reason);
+}
+
+
+void
+gabble_media_channel_hold_iface_init (gpointer g_iface,
+ gpointer iface_data G_GNUC_UNUSED)
+{
+ TpSvcChannelInterfaceHoldClass *klass = g_iface;
+
+#define IMPLEMENT(x) tp_svc_channel_interface_hold_implement_##x (\
+ klass, gabble_media_channel_##x)
+ IMPLEMENT(get_hold_state);
+ IMPLEMENT(request_hold);
+#undef IMPLEMENT
+}
diff --git a/src/media-channel-internal.h b/src/media-channel-internal.h
new file mode 100644
index 0000000..d7cd345
--- /dev/null
+++ b/src/media-channel-internal.h
@@ -0,0 +1,84 @@
+/*
+ * media-channel-internal.h - implementation details shared between
+ * MediaChannel source files
+ * 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
+ */
+
+#ifndef __GABBLE_MEDIA_CHANNEL_INTERNAL_H__
+#define __GABBLE_MEDIA_CHANNEL_INTERNAL_H__
+
+#include "media-channel.h"
+
+#include <glib.h>
+
+#include "media-factory.h"
+#include "media-stream.h"
+#include "jingle-session.h"
+#include "jingle-media-rtp.h"
+
+G_BEGIN_DECLS
+
+struct _GabbleMediaChannelPrivate
+{
+ GabbleConnection *conn;
+ gchar *object_path;
+ TpHandle creator;
+ TpHandle initial_peer;
+ gboolean peer_in_rp;
+
+ GabbleMediaFactory *factory;
+ GabbleJingleSession *session;
+
+ /* array of referenced GabbleMediaStream* */
+ GPtrArray *streams;
+ /* list of PendingStreamRequest* in no particular order */
+ GList *pending_stream_requests;
+
+ /* list of StreamCreationData* in no particular order */
+ GList *stream_creation_datas;
+
+ guint next_stream_id;
+
+ TpLocalHoldState hold_state;
+ TpLocalHoldStateReason hold_state_reason;
+
+ /* The "most held" of all associated contents' current states, which is what
+ * we present on CallState.
+ */
+ JingleRtpRemoteState remote_state;
+
+ GPtrArray *delayed_request_streams;
+
+ /* These are really booleans, but gboolean is signed. Thanks, GLib */
+ unsigned ready:1;
+ unsigned closed:1;
+ unsigned dispose_has_run:1;
+};
+
+void gabble_media_channel_hold_new_stream (GabbleMediaChannel *chan,
+ GabbleMediaStream *stream);
+void gabble_media_channel_hold_stream_closed (GabbleMediaChannel *chan,
+ GabbleMediaStream *stream);
+
+void
+gabble_media_channel_hold_iface_init (gpointer g_iface,
+ gpointer iface_data G_GNUC_UNUSED);
+
+G_END_DECLS
+
+#endif /* #ifndef __GABBLE_MEDIA_CHANNEL_INTERNAL_H__ */
diff --git a/src/media-channel.c b/src/media-channel.c
index 529899b..8ec1904 100644
--- a/src/media-channel.c
+++ b/src/media-channel.c
@@ -21,6 +21,7 @@
#include "config.h"
#include "media-channel.h"
+#include "media-channel-internal.h"
#include <dbus/dbus-glib.h>
@@ -52,7 +53,6 @@
static void call_state_iface_init (gpointer, gpointer);
static void channel_iface_init (gpointer, gpointer);
-static void hold_iface_init (gpointer, gpointer);
static void media_signalling_iface_init (gpointer, gpointer);
static void streamed_media_iface_init (gpointer, gpointer);
static void session_handler_iface_init (gpointer, gpointer);
@@ -65,7 +65,7 @@ G_DEFINE_TYPE_WITH_CODE (GabbleMediaChannel, gabble_media_channel,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
tp_group_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_HOLD,
- hold_iface_init);
+ gabble_media_channel_hold_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_MEDIA_SIGNALLING,
media_signalling_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_STREAMED_MEDIA,
@@ -135,43 +135,6 @@ const TpPropertySignature channel_property_signatures[NUM_CHAN_PROPS] = {
{ "gtalk-p2p-relay-token", G_TYPE_STRING }
};
-struct _GabbleMediaChannelPrivate
-{
- GabbleConnection *conn;
- gchar *object_path;
- TpHandle creator;
- TpHandle initial_peer;
- gboolean peer_in_rp;
-
- GabbleMediaFactory *factory;
- GabbleJingleSession *session;
-
- /* array of referenced GabbleMediaStream* */
- GPtrArray *streams;
- /* list of PendingStreamRequest* in no particular order */
- GList *pending_stream_requests;
-
- /* list of StreamCreationData* in no particular order */
- GList *stream_creation_datas;
-
- guint next_stream_id;
-
- TpLocalHoldState hold_state;
- TpLocalHoldStateReason hold_state_reason;
-
- /* The "most held" of all associated contents' current states, which is what
- * we present on CallState.
- */
- JingleRtpRemoteState remote_state;
-
- GPtrArray *delayed_request_streams;
-
- /* These are really booleans, but gboolean is signed. Thanks, GLib */
- unsigned ready:1;
- unsigned closed:1;
- unsigned dispose_has_run:1;
-};
-
struct _delayed_request_streams_ctx {
GabbleMediaChannel *chan;
gulong caps_disco_id;
@@ -2168,174 +2131,6 @@ session_state_changed_cb (GabbleJingleSession *session,
tp_intset_destroy (set);
}
-
-static void
-inform_peer_of_unhold (GabbleMediaChannel *self)
-{
- gabble_jingle_session_send_held (self->priv->session, FALSE);
-}
-
-
-static void
-inform_peer_of_hold (GabbleMediaChannel *self)
-{
- gabble_jingle_session_send_held (self->priv->session, TRUE);
-}
-
-
-static void
-stream_hold_state_changed (GabbleMediaStream *stream G_GNUC_UNUSED,
- GParamSpec *unused G_GNUC_UNUSED,
- gpointer data)
-{
- GabbleMediaChannel *self = data;
- GabbleMediaChannelPrivate *priv = self->priv;
- gboolean all_held = TRUE, any_held = FALSE;
- guint i;
-
- for (i = 0; i < priv->streams->len; i++)
- {
- gboolean its_hold;
-
- g_object_get (g_ptr_array_index (priv->streams, i),
- "local-hold", &its_hold,
- NULL);
-
- DEBUG ("Stream at index %u has local-hold=%u", i, (guint) its_hold);
-
- all_held = all_held && its_hold;
- any_held = any_held || its_hold;
- }
-
- DEBUG ("all_held=%u, any_held=%u", (guint) all_held, (guint) any_held);
-
- if (all_held)
- {
- /* Move to state HELD */
-
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD)
- {
- /* nothing changed */
- return;
- }
- else if (priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_UNHOLD)
- {
- /* This can happen if the user asks us to hold, then changes their
- * mind. We make no particular guarantees about stream states when
- * in PENDING_UNHOLD state, so keep claiming to be in that state */
- return;
- }
- else if (priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_HOLD)
- {
- /* We wanted to hold, and indeed we have. Yay! Keep whatever
- * reason code we used for going to PENDING_HOLD */
- priv->hold_state = TP_LOCAL_HOLD_STATE_HELD;
- }
- else
- {
- /* We were previously UNHELD. So why have we gone on hold now? */
- DEBUG ("Unexpectedly entered HELD state!");
- priv->hold_state = TP_LOCAL_HOLD_STATE_HELD;
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
- }
- }
- else if (any_held)
- {
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD)
- {
- /* The streaming client has spontaneously changed its stream
- * state. Why? We just don't know */
- DEBUG ("Unexpectedly entered PENDING_UNHOLD state!");
- priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_UNHOLD;
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
- }
- else if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD)
- {
- /* Likewise */
- DEBUG ("Unexpectedly entered PENDING_HOLD state!");
- priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_HOLD;
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
- }
- else
- {
- /* nothing particularly interesting - we're trying to change hold
- * state already, so nothing to signal */
- return;
- }
- }
- else
- {
- /* Move to state UNHELD */
-
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD)
- {
- /* nothing changed */
- return;
- }
- else if (priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_HOLD)
- {
- /* This can happen if the user asks us to unhold, then changes their
- * mind. We make no particular guarantees about stream states when
- * in PENDING_HOLD state, so keep claiming to be in that state */
- return;
- }
- else if (priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_UNHOLD)
- {
- /* We wanted to hold, and indeed we have. Yay! Keep whatever
- * reason code we used for going to PENDING_UNHOLD */
- priv->hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
- }
- else
- {
- /* We were previously HELD. So why have we gone off hold now? */
- DEBUG ("Unexpectedly entered UNHELD state!");
- priv->hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
- }
-
- /* Tell the peer what's happened */
- inform_peer_of_unhold (self);
- }
-
- tp_svc_channel_interface_hold_emit_hold_state_changed (self,
- priv->hold_state, priv->hold_state_reason);
-}
-
-
-static void
-stream_unhold_failed (GabbleMediaStream *stream,
- gpointer data)
-{
- GabbleMediaChannel *self = data;
- GabbleMediaChannelPrivate *priv = self->priv;
- guint i;
-
- DEBUG ("%p: %p", self, stream);
-
- /* Unholding failed - let's roll back to Hold state */
- priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_HOLD;
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_RESOURCE_NOT_AVAILABLE;
- tp_svc_channel_interface_hold_emit_hold_state_changed (self,
- priv->hold_state, priv->hold_state_reason);
-
- /* The stream's state may have changed from unheld to held, so re-poll.
- * It's possible that all streams are now held, in which case we can stop. */
- stream_hold_state_changed (stream, NULL, self);
-
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD)
- return;
-
- /* There should be no need to notify the peer, who already thinks they're
- * on hold, so just tell the streaming client what to do. */
-
- for (i = 0; i < priv->streams->len; i++)
- {
- gabble_media_stream_hold (g_ptr_array_index (priv->streams, i),
- TRUE);
- }
-}
-
-
static void
stream_close_cb (GabbleMediaStream *stream,
GabbleMediaChannel *chan)
@@ -2355,10 +2150,7 @@ stream_close_cb (GabbleMediaStream *stream,
{
g_ptr_array_remove (priv->streams, stream);
- /* A stream closing might cause the "total" hold state to change:
- * if there's one held and one unheld, and the unheld one closes,
- * then our state changes from indeterminate to held. */
- stream_hold_state_changed (stream, NULL, chan);
+ gabble_media_channel_hold_stream_closed (chan, stream);
g_object_unref (stream);
}
@@ -2596,14 +2388,10 @@ construct_stream (GabbleMediaChannel *chan,
chan_o);
gabble_signal_connect_weak (stream, "error", (GCallback) stream_error_cb,
chan_o);
- gabble_signal_connect_weak (stream, "unhold-failed",
- (GCallback) stream_unhold_failed, chan_o);
gabble_signal_connect_weak (stream, "notify::connection-state",
(GCallback) stream_state_changed_cb, chan_o);
gabble_signal_connect_weak (stream, "notify::combined-direction",
(GCallback) stream_direction_changed_cb, chan_o);
- gabble_signal_connect_weak (stream, "notify::local-hold",
- (GCallback) stream_hold_state_changed, chan_o);
/* While we're here, watch the active/mute/held state of the corresponding
* content so we can keep the call state up to date, and call the callback
@@ -2622,13 +2410,12 @@ construct_stream (GabbleMediaChannel *chan,
tp_svc_channel_type_streamed_media_emit_stream_added (
chan, id, priv->session->peer, mtype);
- /* A stream being added might cause the "total" hold state to change */
- stream_hold_state_changed (stream, NULL, chan);
-
/* Initial stream direction was changed before we had time to hook up
* signal handler, so we call the handler manually to pick it up. */
stream_direction_changed_cb (stream, NULL, chan);
+ gabble_media_channel_hold_new_stream (chan, stream);
+
if (priv->ready)
{
/* all of the streams are bidirectional from farsight's point of view, it's
@@ -2850,76 +2637,6 @@ gabble_media_channel_get_call_states (TpSvcChannelInterfaceCallState *iface,
}
static void
-gabble_media_channel_get_hold_state (TpSvcChannelInterfaceHold *iface,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = (GabbleMediaChannel *) iface;
- GabbleMediaChannelPrivate *priv = self->priv;
-
- tp_svc_channel_interface_hold_return_from_get_hold_state (context,
- priv->hold_state, priv->hold_state_reason);
-}
-
-
-static void
-gabble_media_channel_request_hold (TpSvcChannelInterfaceHold *iface,
- gboolean hold,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
- GabbleMediaChannelPrivate *priv = self->priv;
- guint i;
- TpLocalHoldState old_state = priv->hold_state;
-
- DEBUG ("%p: RequestHold(%u)", self, !!hold);
-
- if (hold)
- {
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD)
- {
- DEBUG ("No-op");
- tp_svc_channel_interface_hold_return_from_request_hold (context);
- return;
- }
-
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD)
- {
- inform_peer_of_hold (self);
- }
-
- priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_HOLD;
- }
- else
- {
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD)
- {
- DEBUG ("No-op");
- tp_svc_channel_interface_hold_return_from_request_hold (context);
- return;
- }
-
- priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_UNHOLD;
- }
-
- if (old_state != priv->hold_state ||
- priv->hold_state_reason != TP_LOCAL_HOLD_STATE_REASON_REQUESTED)
- {
- tp_svc_channel_interface_hold_emit_hold_state_changed (self,
- priv->hold_state, TP_LOCAL_HOLD_STATE_REASON_REQUESTED);
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_REQUESTED;
- }
-
- /* Tell streaming client to release or reacquire resources */
-
- for (i = 0; i < priv->streams->len; i++)
- {
- gabble_media_stream_hold (g_ptr_array_index (priv->streams, i), hold);
- }
-
- tp_svc_channel_interface_hold_return_from_request_hold (context);
-}
-
-static void
_emit_new_stream (GabbleMediaChannel *chan,
GabbleMediaStream *stream)
{
@@ -3073,19 +2790,6 @@ call_state_iface_init (gpointer g_iface,
}
static void
-hold_iface_init (gpointer g_iface,
- gpointer iface_data G_GNUC_UNUSED)
-{
- TpSvcChannelInterfaceHoldClass *klass = g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_interface_hold_implement_##x (\
- klass, gabble_media_channel_##x)
- IMPLEMENT(get_hold_state);
- IMPLEMENT(request_hold);
-#undef IMPLEMENT
-}
-
-static void
session_handler_iface_init (gpointer g_iface, gpointer iface_data)
{
TpSvcMediaSessionHandlerClass *klass =
--
1.5.6.5
More information about the telepathy-commits
mailing list