summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webrtc/RTCPeerConnection-setDescription-transceiver.html
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/webrtc/RTCPeerConnection-setDescription-transceiver.html')
-rw-r--r--testing/web-platform/tests/webrtc/RTCPeerConnection-setDescription-transceiver.html295
1 files changed, 295 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webrtc/RTCPeerConnection-setDescription-transceiver.html b/testing/web-platform/tests/webrtc/RTCPeerConnection-setDescription-transceiver.html
new file mode 100644
index 0000000000..9bbab30d56
--- /dev/null
+++ b/testing/web-platform/tests/webrtc/RTCPeerConnection-setDescription-transceiver.html
@@ -0,0 +1,295 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>RTCPeerConnection Set Session Description - Transceiver Tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="RTCPeerConnection-helper.js"></script>
+<script>
+ 'use strict';
+
+ // Test is based on the following editor draft:
+ // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+
+ // The following helper functions are called from RTCPeerConnection-helper.js:
+ // generateAnswer
+
+ /*
+ 4.3.2. Interface Definition
+
+ [Constructor(optional RTCConfiguration configuration)]
+ interface RTCPeerConnection : EventTarget {
+ Promise<void> setLocalDescription(
+ RTCSessionDescriptionInit description);
+
+ Promise<void> setRemoteDescription(
+ RTCSessionDescriptionInit description);
+ ...
+ };
+
+ 4.6.2. RTCSessionDescription Class
+ dictionary RTCSessionDescriptionInit {
+ required RTCSdpType type;
+ DOMString sdp = "";
+ };
+
+ 4.6.1. RTCSdpType
+ enum RTCSdpType {
+ "offer",
+ "pranswer",
+ "answer",
+ "rollback"
+ };
+
+ 5.4. RTCRtpTransceiver Interface
+
+ interface RTCRtpTransceiver {
+ readonly attribute DOMString? mid;
+ [SameObject]
+ readonly attribute RTCRtpSender sender;
+ [SameObject]
+ readonly attribute RTCRtpReceiver receiver;
+ readonly attribute RTCRtpTransceiverDirection direction;
+ readonly attribute RTCRtpTransceiverDirection? currentDirection;
+ ...
+ };
+ */
+
+ /*
+ 4.3.1.6. Set the RTCSessionSessionDescription
+ 7. If description is set as a local description, then run the following steps for
+ each media description in description that is not yet associated with an
+ RTCRtpTransceiver object:
+ 1. Let transceiver be the RTCRtpTransceiver used to create the media
+ description.
+ 2. Set transceiver's mid value to the mid of the corresponding media
+ description.
+ */
+ promise_test(t => {
+ const pc = new RTCPeerConnection();
+ t.add_cleanup(() => pc.close());
+ const transceiver = pc.addTransceiver('audio');
+ assert_equals(transceiver.mid, null);
+
+ return pc.createOffer()
+ .then(offer => {
+ assert_equals(transceiver.mid, null,
+ 'Expect transceiver.mid to still be null after createOffer');
+
+ return pc.setLocalDescription(offer)
+ .then(() => {
+ assert_equals(typeof transceiver.mid, 'string',
+ 'Expect transceiver.mid to set to valid string value');
+
+ assert_equals(offer.sdp.includes(`\r\na=mid:${transceiver.mid}`), true,
+ 'Expect transceiver mid to be found in offer SDP');
+ });
+ });
+ }, 'setLocalDescription(offer) with m= section should assign mid to corresponding transceiver');
+
+ /*
+ 4.3.1.6. Set the RTCSessionSessionDescription
+ 8. If description is set as a remote description, then run the following steps
+ for each media description in description:
+ 2. If no suitable transceiver is found (transceiver is unset), run the following
+ steps:
+ 1. Create an RTCRtpSender, sender, from the media description.
+ 2. Create an RTCRtpReceiver, receiver, from the media description.
+ 3. Create an RTCRtpTransceiver with sender, receiver and direction, and let
+ transceiver be the result.
+ 3. Set transceiver's mid value to the mid of the corresponding media description.
+ */
+ promise_test(t => {
+ const pc1 = new RTCPeerConnection();
+ t.add_cleanup(() => pc1.close());
+ const pc2 = new RTCPeerConnection();
+
+ t.add_cleanup(() => pc2.close());
+
+ const transceiver1 = pc1.addTransceiver('audio');
+ assert_array_equals(pc1.getTransceivers(), [transceiver1]);
+ assert_array_equals(pc2.getTransceivers(), []);
+
+ return pc1.createOffer()
+ .then(offer => {
+ return Promise.all([
+ pc1.setLocalDescription(offer),
+ pc2.setRemoteDescription(offer)
+ ])
+ .then(() => {
+ const transceivers = pc2.getTransceivers();
+ assert_equals(transceivers.length, 1,
+ 'Expect new transceiver added to pc2 after setRemoteDescription');
+
+ const [ transceiver2 ] = transceivers;
+
+ assert_equals(typeof transceiver2.mid, 'string',
+ 'Expect transceiver2.mid to be set');
+
+ assert_equals(transceiver1.mid, transceiver2.mid,
+ 'Expect transceivers of both side to have the same mid');
+
+ assert_equals(offer.sdp.includes(`\r\na=mid:${transceiver2.mid}`), true,
+ 'Expect transceiver mid to be found in offer SDP');
+ });
+ });
+ }, 'setRemoteDescription(offer) with m= section and no existing transceiver should create corresponding transceiver');
+
+ /*
+ 4.3.1.6. Set the RTCSessionSessionDescription
+ 9. If description is of type "rollback", then run the following steps:
+ 1. If the mid value of an RTCRtpTransceiver was set to a non-null value by
+ the RTCSessionDescription that is being rolled back, set the mid value
+ of that transceiver to null, as described by [JSEP] (section 4.1.8.2.).
+ */
+ promise_test(t => {
+ const pc = new RTCPeerConnection();
+ t.add_cleanup(() => pc.close());
+ const transceiver = pc.addTransceiver('audio');
+ assert_equals(transceiver.mid, null);
+
+ return pc.createOffer()
+ .then(offer => {
+ assert_equals(transceiver.mid, null);
+ return pc.setLocalDescription(offer);
+ })
+ .then(() => {
+ assert_not_equals(transceiver.mid, null);
+ return pc.setLocalDescription({ type: 'rollback' });
+ })
+ .then(() => {
+ assert_equals(transceiver.mid, null,
+ 'Expect transceiver.mid to become null again after rollback');
+ });
+ }, 'setLocalDescription(rollback) should unset transceiver.mid');
+
+ promise_test(t => {
+ const pc = new RTCPeerConnection();
+ t.add_cleanup(() => pc.close());
+ const transceiver1 = pc.addTransceiver('audio');
+ assert_equals(transceiver1.mid, null);
+
+ return pc.createOffer()
+ .then(offer =>
+ pc.setLocalDescription(offer)
+ .then(() => generateAnswer(offer)))
+ .then(answer => pc.setRemoteDescription(answer))
+ .then(() => {
+ // pc is back to stable state
+ // create another transceiver
+ const transceiver2 = pc.addTransceiver('video');
+
+ assert_not_equals(transceiver1.mid, null);
+ assert_equals(transceiver2.mid, null);
+
+ return pc.createOffer()
+ .then(offer => pc.setLocalDescription(offer))
+ .then(() => {
+ assert_not_equals(transceiver1.mid, null);
+ assert_not_equals(transceiver2.mid, null,
+ 'Expect transceiver2.mid to become set');
+
+ return pc.setLocalDescription({ type: 'rollback' });
+ })
+ .then(() => {
+ assert_not_equals(transceiver1.mid, null,
+ 'Expect transceiver1.mid to stay set');
+
+ assert_equals(transceiver2.mid, null,
+ 'Expect transceiver2.mid to be rolled back to null');
+ });
+ })
+ }, 'setLocalDescription(rollback) should only unset transceiver mids associated with current round');
+
+ /*
+ 4.3.1.6. Set the RTCSessionSessionDescription
+ 9. If description is of type "rollback", then run the following steps:
+ 2. If an RTCRtpTransceiver was created by applying the RTCSessionDescription
+ that is being rolled back, and a track has not been attached to it via
+ addTrack, remove that transceiver from connection's set of transceivers,
+ as described by [JSEP] (section 4.1.8.2.).
+ */
+ promise_test(t => {
+ const pc1 = new RTCPeerConnection();
+ t.add_cleanup(() => pc1.close());
+ const pc2 = new RTCPeerConnection();
+
+ t.add_cleanup(() => pc2.close());
+
+ pc1.addTransceiver('audio');
+
+ return pc1.createOffer()
+ .then(offer => pc2.setRemoteDescription(offer))
+ .then(() => {
+ const transceivers = pc2.getTransceivers();
+ assert_equals(transceivers.length, 1);
+ const [ transceiver ] = transceivers;
+
+ assert_equals(typeof transceiver.mid, 'string',
+ 'Expect transceiver.mid to be set');
+
+ return pc2.setRemoteDescription({ type: 'rollback' })
+ .then(() => {
+ assert_equals(transceiver.mid, null,
+ 'Expect transceiver.mid to be unset');
+
+ assert_array_equals(pc2.getTransceivers(), [],
+ `Expect transceiver to be removed from pc2's transceiver list`);
+ });
+ });
+ }, 'setRemoteDescription(rollback) should remove newly created transceiver from transceiver list');
+
+ promise_test(async t => {
+ const pc1 = new RTCPeerConnection();
+ t.add_cleanup(() => pc1.close());
+ const pc2 = new RTCPeerConnection();
+ t.add_cleanup(() => pc2.close());
+
+ pc1.addTransceiver('audio');
+ const offer = await pc1.createOffer();
+ await pc1.setLocalDescription(offer);
+
+ await pc2.setRemoteDescription(offer);
+ pc2.getTransceivers()[0].stop();
+ const answer = await pc2.createAnswer();
+
+ await pc1.setRemoteDescription(answer);
+
+ assert_equals(pc1.getTransceivers()[0].currentDirection, 'inactive', 'A stopped m-line should give an inactive transceiver');
+ }, 'setRemoteDescription should set transceiver inactive if its corresponding m section is rejected');
+
+ /*
+ TODO
+ - Steps for transceiver direction is added to tip of tree draft, but not yet
+ published as editor's draft
+
+ 4.3.1.6. Set the RTCSessionSessionDescription
+ 8. If description is set as a remote description, then run the following steps
+ for each media description in description:
+ 1. As described by [JSEP] (section 5.9.), attempt to find an existing
+ RTCRtpTransceiver object, transceiver, to represent the media description.
+ 3. If the media description has no MID, and transceiver's mid is unset, generate
+ a random value as described in [JSEP] (section 5.9.).
+ 4. If the direction of the media description is sendrecv or sendonly, and
+ transceiver.receiver.track has not yet been fired in a track event, process
+ the remote track for the media description, given transceiver.
+ 5. If the media description is rejected, and transceiver is not already stopped,
+ stop the RTCRtpTransceiver transceiver.
+
+ [JSEP]
+ 5.9. Applying a Remote Description
+ - If the m= section is not associated with any RtpTransceiver
+ (possibly because it was dissociated in the previous step),
+ either find an RtpTransceiver or create one according to the
+ following steps:
+
+ - If the m= section is sendrecv or recvonly, and there are
+ RtpTransceivers of the same type that were added to the
+ PeerConnection by addTrack and are not associated with any
+ m= section and are not stopped, find the first (according to
+ the canonical order described in Section 5.2.1) such
+ RtpTransceiver.
+
+ - If no RtpTransceiver was found in the previous step, create
+ one with a recvonly direction.
+ */
+</script>