[telepathy-gabble/master] make MembersChanged have the correct reason when Error is called on a stream

Dafydd Harries dafydd.harries at collabora.co.uk
Mon Sep 14 13:41:07 PDT 2009


If we had an incoming call with a single mutable stream, the fact that an
error ocurred would get lost.
---
 src/media-channel.c                                |   15 ++++--
 tests/twisted/Makefile.am                          |    1 +
 tests/twisted/jingle/incoming-call-stream-error.py |   55 ++++++++++++++++++++
 3 files changed, 67 insertions(+), 4 deletions(-)
 create mode 100644 tests/twisted/jingle/incoming-call-stream-error.py

diff --git a/src/media-channel.c b/src/media-channel.c
index 29bf99e..37b3ca0 100644
--- a/src/media-channel.c
+++ b/src/media-channel.c
@@ -2422,6 +2422,7 @@ stream_error_cb (GabbleMediaStream *stream,
 {
   GabbleMediaChannelPrivate *priv = chan->priv;
   GabbleJingleMediaRtp *c;
+  GList *contents;
   guint id;
 
   /* emit signal */
@@ -2429,7 +2430,10 @@ stream_error_cb (GabbleMediaStream *stream,
   tp_svc_channel_type_streamed_media_emit_stream_error (chan, id, errno,
       message);
 
-  if (gabble_jingle_session_can_modify_contents (priv->session))
+  contents = gabble_jingle_session_get_contents (priv->session);
+
+  if (gabble_jingle_session_can_modify_contents (priv->session) &&
+      g_list_length (contents) > 1)
     {
       /* remove stream from session (removal will be signalled
        * so we can dispose of the stream)
@@ -2440,14 +2444,17 @@ stream_error_cb (GabbleMediaStream *stream,
     }
   else
     {
-      /* We can't remove the content; let's terminate the call. (The
-       * alternative is to carry on the call with only audio/video, which will
-       * look or sound bad to the Google Talk-using peer.)
+      /* We can't remove the content, or it's the only one left; let's
+       * terminate the call. (The alternative is to carry on the call with
+       * only audio/video, which will look or sound bad to the Google
+       * Talk-using peer.)
        */
       DEBUG ("Terminating call in response to stream error");
       gabble_jingle_session_terminate (priv->session,
           TP_CHANNEL_GROUP_CHANGE_REASON_ERROR, message, NULL);
     }
+
+  g_list_free (contents);
 }
 
 static void
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index eb8c24e..b3b8d10 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -100,6 +100,7 @@ TWISTED_TESTS = \
 	jingle/hold-audio.py \
 	jingle/hold-av.py \
 	jingle/incoming-basics.py \
+	jingle/incoming-call-stream-error.py \
 	jingle/initial-audio-video.py \
 	jingle/misuse.py \
 	jingle/stun-server.py \
diff --git a/tests/twisted/jingle/incoming-call-stream-error.py b/tests/twisted/jingle/incoming-call-stream-error.py
new file mode 100644
index 0000000..8aaf90e
--- /dev/null
+++ b/tests/twisted/jingle/incoming-call-stream-error.py
@@ -0,0 +1,55 @@
+
+"""
+Test handling of Error() call on stream handler.
+
+This tests a regression in which MembersChanged was emitted with reason other
+than GC_REASON_ERROR.
+"""
+
+from servicetest import EventPattern, assertEquals, make_channel_proxy
+from jingletest2 import JingleTest2, test_all_dialects
+import constants as cs
+
+MEDIA_STREAM_ERROR_CONNECTION_FAILED = 3
+
+def test(jp, q, bus, conn, stream):
+    jt = JingleTest2(jp, conn, q, stream, 'test at localhost', 'foo at bar.com/Foo')
+    jt.prepare()
+    self_handle = conn.GetSelfHandle()
+    remote_handle = conn.RequestHandles(cs.HT_CONTACT, ["foo at bar.com/Foo"])[0]
+
+    # Ring ring!
+    jt.incoming_call()
+    new_channel, new_session_handler = q.expect_many(
+        EventPattern('dbus-signal', signal='NewChannel'),
+        EventPattern('dbus-signal', signal='NewSessionHandler'))
+    assertEquals(cs.CHANNEL_TYPE_STREAMED_MEDIA, new_channel.args[1])
+    assertEquals(cs.HT_CONTACT, new_channel.args[2])
+    assertEquals(remote_handle, new_channel.args[3])
+    assertEquals('rtp', new_session_handler.args[1])
+
+    # Client calls Ready on new session handler.
+    session_handler = make_channel_proxy(
+        conn, new_session_handler.args[0], 'Media.SessionHandler')
+    session_handler.Ready()
+
+    # Client gets notified about a newly created stream...
+    new_stream_handler = q.expect('dbus-signal', signal='NewStreamHandler')
+    stream_handler = make_channel_proxy(
+        conn, new_stream_handler.args[0], 'Media.StreamHandler')
+    # ...but something goes wrong.
+    stream_handler.Error(MEDIA_STREAM_ERROR_CONNECTION_FAILED, "o noes")
+
+    # Bye bye members.
+    q.expect('dbus-signal', signal='MembersChanged',
+        args=[u'', [], [self_handle, remote_handle], [], [], self_handle,
+            cs.GC_REASON_ERROR])
+    # Bye bye stream.
+    q.expect('dbus-signal', signal='Close')
+    q.expect('dbus-signal', signal='StreamRemoved')
+    # Bye bye channel.
+    q.expect('dbus-signal', signal='Closed')
+    q.expect('dbus-signal', signal='ChannelClosed')
+
+if __name__ == '__main__':
+    test_all_dialects(test)
-- 
1.5.6.5




More information about the telepathy-commits mailing list