[telepathy-gabble/master] Support name="" on <active/> and <mute/>
Will Thompson
will.thompson at collabora.co.uk
Thu Apr 2 07:49:24 PDT 2009
---
src/jingle-media-rtp.c | 23 +++++++--
tests/twisted/jingle/call-state.py | 102 ++++++++++++++++++++++++++++++++---
tests/twisted/jingle/jingletest2.py | 25 +++++++++
3 files changed, 139 insertions(+), 11 deletions(-)
diff --git a/src/jingle-media-rtp.c b/src/jingle-media-rtp.c
index bccf926..92cae40 100644
--- a/src/jingle-media-rtp.c
+++ b/src/jingle-media-rtp.c
@@ -821,6 +821,8 @@ gabble_jingle_media_rtp_handle_info (GabbleJingleContent *content,
GabbleJingleMediaRtp *self = GABBLE_JINGLE_MEDIA_RTP (content);
const gchar *ns = lm_message_node_get_namespace (payload);
const gchar *elt = lm_message_node_get_name (payload);
+ const gchar *name_attr = lm_message_node_get_attribute (payload, "name");
+ const gchar *content_name = gabble_jingle_content_get_name (content);
JingleRtpRemoteState new_state;
if (tp_strdiff (ns, NS_JINGLE_RTP_INFO))
@@ -831,14 +833,27 @@ gabble_jingle_media_rtp_handle_info (GabbleJingleContent *content,
*handled = TRUE;
+ /* The XEP only says active and mute can have name="". */
if (!tp_strdiff (elt, "active"))
- new_state = JINGLE_RTP_REMOTE_STATE_ACTIVE;
+ {
+ if (name_attr != NULL && tp_strdiff (name_attr, content_name))
+ return TRUE;
+ new_state = JINGLE_RTP_REMOTE_STATE_ACTIVE;
+ }
else if (!tp_strdiff (elt, "ringing"))
- new_state = JINGLE_RTP_REMOTE_STATE_RINGING;
+ {
+ new_state = JINGLE_RTP_REMOTE_STATE_RINGING;
+ }
else if (!tp_strdiff (elt, "hold"))
- new_state = JINGLE_RTP_REMOTE_STATE_HOLD;
+ {
+ new_state = JINGLE_RTP_REMOTE_STATE_HOLD;
+ }
else if (!tp_strdiff (elt, "mute"))
- new_state = JINGLE_RTP_REMOTE_STATE_MUTE;
+ {
+ if (name_attr != NULL && tp_strdiff (name_attr, content_name))
+ return TRUE;
+ new_state = JINGLE_RTP_REMOTE_STATE_MUTE;
+ }
else
{
g_set_error (error, GABBLE_XMPP_ERROR, XMPP_ERROR_JINGLE_UNSUPPORTED_INFO,
diff --git a/tests/twisted/jingle/call-state.py b/tests/twisted/jingle/call-state.py
index 39640a2..5e0690e 100644
--- a/tests/twisted/jingle/call-state.py
+++ b/tests/twisted/jingle/call-state.py
@@ -7,7 +7,7 @@ from twisted.words.xish import xpath
from gabbletest import make_result_iq, sync_stream
from servicetest import wrap_channel, make_channel_proxy, call_async, \
- EventPattern
+ EventPattern, tp_path_prefix
import ns
import constants as cs
@@ -47,8 +47,9 @@ def test(jp, q, bus, conn, stream):
session_handler.Ready()
e = q.expect('dbus-signal', signal='NewStreamHandler')
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
+ audio_path = e.args[0]
+ audio_path_suffix = audio_path[len(tp_path_prefix):]
+ stream_handler = make_channel_proxy(conn, audio_path, 'Media.StreamHandler')
stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
stream_handler.Ready(jt.get_audio_codecs_dbus())
@@ -76,7 +77,8 @@ def test(jp, q, bus, conn, stream):
# Various misc happens; among other things, Gabble tells s-e to start
# sending.
- q.expect('dbus-signal', signal='SetStreamSending', args=[True])
+ q.expect('dbus-signal', signal='SetStreamSending', args=[True],
+ path=audio_path_suffix)
# Plus, the other person's client decides it's not ringing any more
node = jp.SetIq(jt.peer, jt.jid, [
@@ -98,7 +100,8 @@ def test(jp, q, bus, conn, stream):
q.expect_many(
EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[False]),
+ EventPattern('dbus-signal', signal='SetStreamSending', args=[False],
+ path=audio_path_suffix),
EventPattern('dbus-signal', signal='CallStateChanged',
args=[handle, cs.CALL_STATE_HELD]),
)
@@ -138,7 +141,8 @@ def test(jp, q, bus, conn, stream):
q.expect_many(
EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[True]),
+ EventPattern('dbus-signal', signal='SetStreamSending', args=[True],
+ path=audio_path_suffix),
EventPattern('dbus-signal', signal='CallStateChanged',
args=[handle, 0]),
)
@@ -146,7 +150,91 @@ def test(jp, q, bus, conn, stream):
call_states = chan.CallState.GetCallStates()
assert call_states == { handle: 0 } or call_states == {}, call_states
- # Test completed, close the connection
+ # Okay, let's get a second stream involved!
+
+ chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_VIDEO])
+
+ e = q.expect('dbus-signal', signal='NewStreamHandler')
+ video_path = e.args[0]
+ video_path_suffix = video_path[len(tp_path_prefix):]
+ stream_handler2 = make_channel_proxy(conn, video_path, 'Media.StreamHandler')
+
+ stream_handler2.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
+ stream_handler2.Ready(jt.get_video_codecs_dbus())
+ stream_handler2.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
+
+ e = q.expect('stream-iq', predicate=lambda e:
+ jp.match_jingle_action(e.query, 'content-add'))
+ stream.send(make_result_iq(stream, e.stanza))
+
+ jt.content_accept(e.query, 'video')
+
+ q.expect('dbus-signal', signal='SetStreamSending', args=[True],
+ path=video_path_suffix)
+
+ call_states = chan.CallState.GetCallStates()
+ assert call_states == { handle: 0 } or call_states == {}, call_states
+
+ # The other person puts us on hold. Gabble should ack the session-info IQ,
+ # tell s-e to stop sending on both streams, and set the call state.
+ node = jp.SetIq(jt.peer, jt.jid, [
+ jp.Jingle(jt.sid, jt.jid, 'session-info', [
+ ('hold', ns.JINGLE_RTP_INFO_1, {}, []) ]) ])
+ stream.send(jp.xml(node))
+
+ q.expect_many(
+ EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
+ EventPattern('dbus-signal', signal='SetStreamSending', args=[False],
+ path=audio_path_suffix),
+ EventPattern('dbus-signal', signal='SetStreamSending', args=[False],
+ path=video_path_suffix),
+ EventPattern('dbus-signal', signal='CallStateChanged',
+ args=[handle, cs.CALL_STATE_HELD]),
+ )
+
+ call_states = chan.CallState.GetCallStates()
+ assert call_states == { handle: cs.CALL_STATE_HELD }, call_states
+
+ # The other person sets the video stream back to <active/>. (XEP-0167
+ # says that <active/> and <mute/> can have name='', but <hold/> can't.
+ # Gabble should expose this as "start sending video again, but the call's
+ # still held."
+ # FIXME: hardcoded stream id
+ node = jp.SetIq(jt.peer, jt.jid, [
+ jp.Jingle(jt.sid, jt.jid, 'session-info', [
+ ('active', ns.JINGLE_RTP_INFO_1, {'name': 'stream2'}, []) ]) ])
+ stream.send(jp.xml(node))
+
+ q.expect_many(
+ EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
+ EventPattern('dbus-signal', signal='SetStreamSending', args=[True],
+ path=video_path_suffix),
+ )
+
+ call_states = chan.CallState.GetCallStates()
+ assert call_states == { handle: cs.CALL_STATE_HELD }, call_states
+
+ # Now the other person sets the audio stream to mute. Gabble should expose
+ # this as the call being active again (since we can't represent mute yet!)
+ # and tell s-e to start sending audio again.
+ # FIXME: hardcoded stream id
+ node = jp.SetIq(jt.peer, jt.jid, [
+ jp.Jingle(jt.sid, jt.jid, 'session-info', [
+ ('mute', ns.JINGLE_RTP_INFO_1, {'name': 'stream1'}, []) ]) ])
+ stream.send(jp.xml(node))
+
+ q.expect_many(
+ EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
+ EventPattern('dbus-signal', signal='SetStreamSending', args=[True],
+ path=audio_path_suffix),
+ EventPattern('dbus-signal', signal='CallStateChanged',
+ args=[ handle, 0 ]),
+ )
+
+ call_states = chan.CallState.GetCallStates()
+ assert call_states == { handle: 0 } or call_states == {}, call_states
+
+ # That'll do, pig.
chan.Group.RemoveMembers([self_handle], 'closed')
e = q.expect('dbus-signal', signal='Close') #XXX - match against the path
diff --git a/tests/twisted/jingle/jingletest2.py b/tests/twisted/jingle/jingletest2.py
index f42ee71..b1482c8 100644
--- a/tests/twisted/jingle/jingletest2.py
+++ b/tests/twisted/jingle/jingletest2.py
@@ -393,6 +393,31 @@ class JingleTest2:
audio + video) ])
self.stream.send(jp.xml(node))
+ def content_accept(self, query, media):
+ """
+ Accepts a content-add stanza containing a single <content> of the given
+ media type.
+ """
+ jp = self.jp
+ c = query.firstChildElement()
+
+ if media == 'audio':
+ codecs = self.audio_codecs
+ elif media == 'video':
+ codecs = self.video_codecs
+ else:
+ assert False
+
+ # Remote end finally accepts
+ node = jp.SetIq(self.peer, self.jid, [
+ jp.Jingle(self.sid, self.peer, 'content-accept', [
+ jp.Content(c['name'], c['creator'], c['senders'], [
+ jp.Description(media, [
+ jp.PayloadType(name, str(rate), str(id)) for
+ (name, id, rate) in codecs ]),
+ jp.TransportGoogleP2P() ]) ]) ])
+ self.stream.send(jp.xml(node))
+
def terminate(self, reason=None):
jp = self.jp
--
1.5.6.5
More information about the telepathy-commits
mailing list