[telepathy-gabble/master] Apply current held-ness to new streams
Will Thompson
will.thompson at collabora.co.uk
Fri May 22 08:22:55 PDT 2009
Fixes fd.o #21878.
---
src/media-channel.c | 4 +-
src/media-stream.c | 24 ++++++++---
src/media-stream.h | 8 +++-
tests/twisted/jingle/hold-av.py | 84 ++++++++++++++++++++++++++++++++++++++-
4 files changed, 110 insertions(+), 10 deletions(-)
diff --git a/src/media-channel.c b/src/media-channel.c
index 0731f0c..4bf8d9d 100644
--- a/src/media-channel.c
+++ b/src/media-channel.c
@@ -2471,6 +2471,8 @@ construct_stream (GabbleMediaChannel *chan,
TpMediaStreamType mtype;
guint id;
gchar *object_path;
+ gboolean local_hold = (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD ||
+ priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_HOLD);
id = priv->next_stream_id++;
@@ -2478,7 +2480,7 @@ construct_stream (GabbleMediaChannel *chan,
priv->object_path, id);
stream = gabble_media_stream_new (object_path, c, name, id,
- nat_traversal, relays);
+ nat_traversal, relays, local_hold);
DEBUG ("%p: created new MediaStream %p for content '%s'", chan, stream, name);
diff --git a/src/media-stream.c b/src/media-stream.c
index 71367db..ef3831b 100644
--- a/src/media-stream.c
+++ b/src/media-stream.c
@@ -157,11 +157,12 @@ static void update_sending (GabbleMediaStream *stream, gboolean start_sending);
GabbleMediaStream *
gabble_media_stream_new (const gchar *object_path,
- GabbleJingleContent *content,
- const gchar *name,
- guint id,
- const gchar *nat_traversal,
- const GPtrArray *relay_info)
+ GabbleJingleContent *content,
+ const gchar *name,
+ guint id,
+ const gchar *nat_traversal,
+ const GPtrArray *relay_info,
+ gboolean local_hold)
{
GPtrArray *empty = NULL;
GabbleMediaStream *result;
@@ -181,6 +182,7 @@ gabble_media_stream_new (const gchar *object_path,
"id", id,
"nat-traversal", nat_traversal,
"relay-info", relay_info,
+ "local-hold", local_hold,
NULL);
if (empty != NULL)
@@ -473,6 +475,9 @@ gabble_media_stream_set_property (GObject *object,
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;
@@ -582,7 +587,7 @@ gabble_media_stream_class_init (GabbleMediaStreamClass *gabble_media_stream_clas
param_spec = g_param_spec_boolean ("local-hold", "Local hold?",
"True if resources used for this stream have been freed.", FALSE,
- G_PARAM_READABLE |
+ 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);
@@ -1036,6 +1041,13 @@ gabble_media_stream_ready (TpSvcMediaStreamHandler *iface,
push_remote_candidates (self);
push_playing (self);
push_sending (self);
+
+ /* 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)
+ gabble_media_stream_hold (self, priv->local_hold);
}
else
{
diff --git a/src/media-stream.h b/src/media-stream.h
index 39f3342..a43b575 100644
--- a/src/media-stream.h
+++ b/src/media-stream.h
@@ -95,8 +95,12 @@ gboolean gabble_media_stream_change_direction (GabbleMediaStream *stream,
void gabble_media_stream_accept_pending_local_send (GabbleMediaStream *stream);
GabbleMediaStream *gabble_media_stream_new (const gchar *object_path,
- GabbleJingleContent *content, const gchar *name, guint id,
- const gchar *nat_traversal, const GPtrArray *relays);
+ GabbleJingleContent *content,
+ const gchar *name,
+ guint id,
+ const gchar *nat_traversal,
+ const GPtrArray *relay_info,
+ gboolean local_hold);
TpMediaStreamType gabble_media_stream_get_media_type (GabbleMediaStream *self);
GabbleJingleMediaRtp *gabble_media_stream_get_content (GabbleMediaStream *self);
diff --git a/tests/twisted/jingle/hold-av.py b/tests/twisted/jingle/hold-av.py
index eece649..d40d078 100644
--- a/tests/twisted/jingle/hold-av.py
+++ b/tests/twisted/jingle/hold-av.py
@@ -3,7 +3,10 @@ Test the Hold API.
"""
from gabbletest import make_result_iq, sync_stream
-from servicetest import make_channel_proxy, call_async, EventPattern
+from servicetest import (
+ assertEquals,
+ make_channel_proxy, call_async, EventPattern, sync_dbus, tp_path_prefix,
+ )
import constants as cs
@@ -376,6 +379,85 @@ def test(jp, q, bus, conn, stream):
sync_stream(q, stream)
q.unforbid_events(hold_event + active_event)
+ # ---- Test 13: while the call's on hold, we add a new stream ---
+ # We shouldn't go off hold locally as a result, and the new StreamHandler
+ # should tell s-e to hold the stream.
+
+ pending_hold = [
+ EventPattern('dbus-signal', signal='HoldStateChanged',
+ predicate=lambda e: e.args[0] == cs.HS_PENDING_HOLD),
+ ]
+ q.forbid_events(pending_hold)
+
+ call_async(q, media_iface, 'RequestStreams', handle,
+ [cs.MEDIA_STREAM_TYPE_AUDIO])
+
+ e = q.expect('dbus-signal', signal='NewStreamHandler')
+ audio_stream_path = e.args[0]
+ audio_stream_handler = make_channel_proxy(conn, e.args[0],
+ 'Media.StreamHandler')
+
+ # Syncing here to make sure SetStreamHeld happens after Ready...
+ sync_dbus(bus, q, conn)
+
+ audio_stream_handler.Ready(jt.get_audio_codecs_dbus())
+ audio_stream_handler.NewNativeCandidate("fake",
+ jt.get_remote_transports_dbus())
+ audio_stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
+
+ path_suffix = audio_stream_path[len(tp_path_prefix):]
+
+ q.expect_many(
+ EventPattern('dbus-signal', signal='SetStreamHeld', args=[True],
+ path=path_suffix),
+ EventPattern('dbus-signal', signal='SetStreamSending', args=[False],
+ path=path_suffix),
+ )
+
+ assertEquals(cs.HS_HELD, hold_iface.GetHoldState()[0])
+
+ sync_dbus(bus, q, conn)
+
+ # ---- Test 14: while the call's on hold, the peer adds a new stream ----
+ # Again, we shouldn't go off hold locally as a result, and the new
+ # StreamHandler should tell s-e to hold the stream.
+
+ node = jp.SetIq(jt.peer, jt.jid, [
+ jp.Jingle(jt.sid, jt.peer, 'content-add', [
+ jp.Content('videostream', 'initiator', 'both', [
+ jp.Description('video', [
+ jp.PayloadType(name, str(rate), str(id)) for
+ (name, id, rate) in jt.video_codecs ]),
+ jp.TransportGoogleP2P() ]) ]) ])
+ stream.send(jp.xml(node))
+
+ e = q.expect('dbus-signal', signal='NewStreamHandler')
+ video_stream_path = e.args[0]
+ video_stream_handler = make_channel_proxy(conn, e.args[0],
+ 'Media.StreamHandler')
+
+ # Syncing here to make sure SetStreamHeld happens after Ready...
+ sync_dbus(bus, q, conn)
+
+ video_stream_handler.Ready(jt.get_video_codecs_dbus())
+ video_stream_handler.NewNativeCandidate("fake",
+ jt.get_remote_transports_dbus())
+ video_stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
+
+ path_suffix = video_stream_path[len(tp_path_prefix):]
+
+ q.expect_many(
+ EventPattern('dbus-signal', signal='SetStreamHeld', args=[True],
+ path=path_suffix),
+ EventPattern('dbus-signal', signal='SetStreamSending', args=[False],
+ path=path_suffix),
+ )
+
+ assertEquals(cs.HS_HELD, hold_iface.GetHoldState()[0])
+
+ sync_dbus(bus, q, conn)
+ q.unforbid_events(pending_hold)
+
# ---- The end ----
group_iface.RemoveMembers([self_handle], 'closed')
--
1.5.6.5
More information about the telepathy-commits
mailing list