RTCPeerConnection-transceivers.https.html (24770B)
1 <!doctype html> 2 <meta name="timeout" content="long"/> 3 <meta charset=utf-8> 4 <title>RTCPeerConnection-transceivers.https.html</title> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="RTCPeerConnection-helper.js"></script> 8 <script> 9 'use strict'; 10 11 // The following helper functions are called from RTCPeerConnection-helper.js: 12 // exchangeOffer 13 // exchangeOfferAndListenToOntrack 14 // exchangeAnswer 15 // exchangeAnswerAndListenToOntrack 16 // addEventListenerPromise 17 // createPeerConnectionWithCleanup 18 // createTrackAndStreamWithCleanup 19 // findTransceiverForSender 20 21 promise_test(async t => { 22 const pc = createPeerConnectionWithCleanup(t); 23 const [track, stream] = await createTrackAndStreamWithCleanup(t); 24 const sender = pc.addTrack(track, stream); 25 const transceiver = findTransceiverForSender(pc, sender); 26 assert_true(transceiver instanceof RTCRtpTransceiver); 27 assert_true(transceiver.sender instanceof RTCRtpSender); 28 assert_equals(transceiver.sender, sender); 29 }, 'addTrack: creates a transceiver for the sender'); 30 31 promise_test(async t => { 32 const pc = createPeerConnectionWithCleanup(t); 33 const [track, stream] = await createTrackAndStreamWithCleanup(t); 34 const transceiver = findTransceiverForSender(pc, pc.addTrack(track, stream)); 35 assert_array_equals(pc.getTransceivers(), [transceiver], 36 'pc.getTransceivers() equals [transceiver]'); 37 assert_array_equals(pc.getSenders(), [transceiver.sender], 38 'pc.getSenders() equals [transceiver.sender]'); 39 assert_array_equals(pc.getReceivers(), [transceiver.receiver], 40 'pc.getReceivers() equals [transceiver.receiver]'); 41 }, 'addTrack: "transceiver == {sender,receiver}"'); 42 43 promise_test(async t => { 44 const pc = createPeerConnectionWithCleanup(t); 45 const [track, stream] = await createTrackAndStreamWithCleanup(t); 46 const transceiver = findTransceiverForSender(pc, pc.addTrack(track, stream)); 47 assert_true(transceiver.sender.track instanceof MediaStreamTrack, 48 'transceiver.sender.track instanceof MediaStreamTrack'); 49 assert_equals(transceiver.sender.track, track, 50 'transceiver.sender.track == track'); 51 }, 'addTrack: transceiver.sender is associated with the track'); 52 53 promise_test(async t => { 54 const pc = createPeerConnectionWithCleanup(t); 55 const [track, stream] = await createTrackAndStreamWithCleanup(t); 56 const transceiver = findTransceiverForSender(pc, pc.addTrack(track, stream)); 57 assert_true(transceiver.receiver instanceof RTCRtpReceiver, 58 'transceiver.receiver instanceof RTCRtpReceiver'); 59 assert_true(transceiver.receiver.track instanceof MediaStreamTrack, 60 'transceiver.receiver.track instanceof MediaStreamTrack'); 61 assert_not_equals(transceiver.receiver.track, track, 62 'transceiver.receiver.track != track'); 63 }, 'addTrack: transceiver.receiver has its own track'); 64 65 promise_test(async t => { 66 const pc = createPeerConnectionWithCleanup(t); 67 const [track, stream] = await createTrackAndStreamWithCleanup(t); 68 const transceiver = findTransceiverForSender(pc, pc.addTrack(track, stream)); 69 assert_true(transceiver.receiver.track.muted); 70 }, 'addTrack: transceiver.receiver\'s track is muted'); 71 72 promise_test(async t => { 73 const pc = createPeerConnectionWithCleanup(t); 74 const [track, stream] = await createTrackAndStreamWithCleanup(t); 75 const transceiver = findTransceiverForSender(pc, pc.addTrack(track, stream)); 76 assert_equals(transceiver.mid, null); 77 }, 'addTrack: transceiver is not associated with an m-section'); 78 79 promise_test(async t => { 80 const pc = createPeerConnectionWithCleanup(t); 81 const [track, stream] = await createTrackAndStreamWithCleanup(t); 82 const transceiver = findTransceiverForSender(pc, pc.addTrack(track, stream)); 83 // `stopped` is non-standard. Move to external/wpt/webrtc/legacy/? 84 assert_false(transceiver.stopped); 85 }, 'addTrack: transceiver is not stopped'); 86 87 promise_test(async t => { 88 const pc = createPeerConnectionWithCleanup(t); 89 const [track, stream] = await createTrackAndStreamWithCleanup(t); 90 const transceiver = findTransceiverForSender(pc, pc.addTrack(track, stream)); 91 assert_equals(transceiver.direction, 'sendrecv'); 92 }, 'addTrack: transceiver\'s direction is sendrecv'); 93 94 promise_test(async t => { 95 const pc = createPeerConnectionWithCleanup(t); 96 const [track, stream] = await createTrackAndStreamWithCleanup(t); 97 const transceiver = findTransceiverForSender(pc, pc.addTrack(track, stream)); 98 assert_equals(transceiver.currentDirection, null); 99 }, 'addTrack: transceiver\'s currentDirection is null'); 100 101 promise_test(async t => { 102 const pc = createPeerConnectionWithCleanup(t); 103 const [track, stream] = await createTrackAndStreamWithCleanup(t); 104 const transceiver = findTransceiverForSender(pc, pc.addTrack(track, stream)); 105 await pc.setLocalDescription(await pc.createOffer()); 106 assert_not_equals(transceiver.mid, null, 'transceiver.mid != null'); 107 }, 'setLocalDescription(offer): transceiver gets associated with an m-section'); 108 109 promise_test(async t => { 110 const pc = createPeerConnectionWithCleanup(t); 111 const [track, stream] = await createTrackAndStreamWithCleanup(t); 112 const transceiver = findTransceiverForSender(pc, pc.addTrack(track, stream)); 113 const offer = await pc.createOffer(); 114 await pc.setLocalDescription(offer); 115 let sdp = offer.sdp; 116 let sdpMidLineStart = sdp.indexOf('a=mid:'); 117 let sdpMidLineEnd = sdp.indexOf('\r\n', sdpMidLineStart); 118 assert_true(sdpMidLineStart != -1 && sdpMidLineEnd != -1, 119 'Failed to parse offer SDP for a=mid'); 120 let parsedMid = sdp.substring(sdpMidLineStart + 6, sdpMidLineEnd); 121 assert_equals(transceiver.mid, parsedMid, 'transceiver.mid == parsedMid'); 122 }, 'setLocalDescription(offer): transceiver.mid matches the offer SDP'); 123 124 promise_test(async t => { 125 const pc1 = createPeerConnectionWithCleanup(t); 126 pc1.addTrack(... await createTrackAndStreamWithCleanup(t)); 127 const pc2 = createPeerConnectionWithCleanup(t); 128 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 129 assert_true(trackEvent instanceof RTCTrackEvent, 130 'trackEvent instanceof RTCTrackEvent'); 131 assert_true(trackEvent.track instanceof MediaStreamTrack, 132 'trackEvent.track instanceof MediaStreamTrack'); 133 }, 'setRemoteDescription(offer): ontrack fires with a track'); 134 135 promise_test(async t => { 136 const pc1 = createPeerConnectionWithCleanup(t); 137 const [track, stream] = await createTrackAndStreamWithCleanup(t); 138 pc1.addTrack(track, stream); 139 const pc2 = createPeerConnectionWithCleanup(t); 140 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 141 assert_true(trackEvent.track instanceof MediaStreamTrack, 142 'trackEvent.track instanceof MediaStreamTrack'); 143 assert_equals(trackEvent.streams.length, 1, 144 'trackEvent contains a single stream'); 145 assert_true(trackEvent.streams[0] instanceof MediaStream, 146 'trackEvent has a MediaStream'); 147 assert_equals(trackEvent.streams[0].id, stream.id, 148 'trackEvent.streams[0].id == stream.id'); 149 }, 'setRemoteDescription(offer): ontrack\'s stream.id is the same as stream.id'); 150 151 promise_test(async t => { 152 const pc1 = createPeerConnectionWithCleanup(t); 153 pc1.addTrack(... await createTrackAndStreamWithCleanup(t)); 154 const pc2 = createPeerConnectionWithCleanup(t); 155 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 156 assert_true(trackEvent.transceiver instanceof RTCRtpTransceiver, 157 'trackEvent.transceiver instanceof RTCRtpTransceiver'); 158 }, 'setRemoteDescription(offer): ontrack fires with a transceiver.'); 159 160 promise_test(async t => { 161 const pc1 = createPeerConnectionWithCleanup(t); 162 const [track, stream] = await createTrackAndStreamWithCleanup(t); 163 const transceiver = findTransceiverForSender(pc1, pc1.addTrack(track, stream)); 164 const pc2 = createPeerConnectionWithCleanup(t); 165 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 166 assert_equals(transceiver.mid, trackEvent.transceiver.mid); 167 }, 'setRemoteDescription(offer): transceiver.mid is the same on both ends'); 168 169 promise_test(async t => { 170 const pc1 = createPeerConnectionWithCleanup(t); 171 pc1.addTrack(... await createTrackAndStreamWithCleanup(t)); 172 const pc2 = createPeerConnectionWithCleanup(t); 173 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 174 const transceiver = trackEvent.transceiver; 175 assert_array_equals(pc2.getTransceivers(), [transceiver], 176 'pc2.getTransceivers() equals [transceiver]'); 177 assert_array_equals(pc2.getSenders(), [transceiver.sender], 178 'pc2.getSenders() equals [transceiver.sender]'); 179 assert_array_equals(pc2.getReceivers(), [transceiver.receiver], 180 'pc2.getReceivers() equals [transceiver.receiver]'); 181 }, 'setRemoteDescription(offer): "transceiver == {sender,receiver}"'); 182 183 promise_test(async t => { 184 const pc1 = createPeerConnectionWithCleanup(t); 185 pc1.addTrack(... await createTrackAndStreamWithCleanup(t)); 186 const pc2 = createPeerConnectionWithCleanup(t); 187 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 188 assert_equals(trackEvent.transceiver.direction, 'recvonly'); 189 }, 'setRemoteDescription(offer): transceiver.direction is recvonly'); 190 191 promise_test(async t => { 192 const pc1 = createPeerConnectionWithCleanup(t); 193 pc1.addTrack(... await createTrackAndStreamWithCleanup(t)); 194 const pc2 = createPeerConnectionWithCleanup(t); 195 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 196 assert_equals(trackEvent.transceiver.currentDirection, null); 197 }, 'setRemoteDescription(offer): transceiver.currentDirection is null'); 198 199 promise_test(async t => { 200 const pc1 = createPeerConnectionWithCleanup(t); 201 pc1.addTrack(... await createTrackAndStreamWithCleanup(t)); 202 const pc2 = createPeerConnectionWithCleanup(t); 203 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 204 // `stopped` is non-standard. Move to external/wpt/webrtc/legacy/? 205 assert_false(trackEvent.transceiver.stopped); 206 }, 'setRemoteDescription(offer): transceiver.stopped is false'); 207 208 promise_test(async t => { 209 const pc1 = createPeerConnectionWithCleanup(t); 210 pc1.addTrack(... await createTrackAndStreamWithCleanup(t)); 211 const pc2 = createPeerConnectionWithCleanup(t); 212 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 213 const transceiver = trackEvent.transceiver; 214 assert_equals(transceiver.currentDirection, null, 215 'SRD(offer): transceiver.currentDirection is null'); 216 await pc2.setLocalDescription(await pc2.createAnswer()); 217 assert_equals(transceiver.currentDirection, 'recvonly', 218 'SLD(answer): transceiver.currentDirection is recvonly'); 219 }, 'setLocalDescription(answer): transceiver.currentDirection is recvonly'); 220 221 promise_test(async t => { 222 const pc1 = createPeerConnectionWithCleanup(t); 223 const [track, stream] = await createTrackAndStreamWithCleanup(t); 224 const transceiver = findTransceiverForSender(pc1, pc1.addTrack(track, stream)); 225 const pc2 = createPeerConnectionWithCleanup(t); 226 await exchangeOffer(pc1, pc2); 227 assert_equals(transceiver.currentDirection, null, 228 'SLD(offer): transceiver.currentDirection is null'); 229 await exchangeAnswer(pc1, pc2); 230 assert_equals(transceiver.currentDirection, 'sendonly', 231 'SRD(answer): transceiver.currentDirection is sendonly'); 232 }, 'setLocalDescription(answer): transceiver.currentDirection is sendonly'); 233 234 promise_test(async t => { 235 const pc = createPeerConnectionWithCleanup(t); 236 const [track, stream] = await createTrackAndStreamWithCleanup(t); 237 const transceiver = pc.addTransceiver(track); 238 assert_true(transceiver instanceof RTCRtpTransceiver); 239 assert_true(transceiver.sender instanceof RTCRtpSender); 240 assert_true(transceiver.receiver instanceof RTCRtpReceiver); 241 assert_equals(transceiver.sender.track, track); 242 }, 'addTransceiver(track): creates a transceiver for the track'); 243 244 promise_test(async t => { 245 const pc = createPeerConnectionWithCleanup(t); 246 const [track, stream] = await createTrackAndStreamWithCleanup(t); 247 const transceiver = pc.addTransceiver(track); 248 assert_array_equals(pc.getTransceivers(), [transceiver], 249 'pc.getTransceivers() equals [transceiver]'); 250 assert_array_equals(pc.getSenders(), [transceiver.sender], 251 'pc.getSenders() equals [transceiver.sender]'); 252 assert_array_equals(pc.getReceivers(), [transceiver.receiver], 253 'pc.getReceivers() equals [transceiver.receiver]'); 254 }, 'addTransceiver(track): "transceiver == {sender,receiver}"'); 255 256 promise_test(async t => { 257 const pc = createPeerConnectionWithCleanup(t); 258 const [track, stream] = await createTrackAndStreamWithCleanup(t); 259 const transceiver = pc.addTransceiver(track, {direction:'inactive'}); 260 assert_equals(transceiver.direction, 'inactive'); 261 }, 'addTransceiver(track, init): initialize direction to inactive'); 262 263 promise_test(async t => { 264 const pc = createPeerConnectionWithCleanup(t); 265 const otherPc = createPeerConnectionWithCleanup(t); 266 const [track, stream] = await createTrackAndStreamWithCleanup(t); 267 const transceiver = pc.addTransceiver(track, { 268 sendEncodings: [{active:false}] 269 }); 270 271 // Negotiate parameters. 272 const offer = await pc.createOffer(); 273 await pc.setLocalDescription(offer); 274 await otherPc.setRemoteDescription(offer); 275 const answer = await otherPc.createAnswer(); 276 await otherPc.setLocalDescription(answer); 277 await pc.setRemoteDescription(answer); 278 279 const params = transceiver.sender.getParameters(); 280 assert_false(params.encodings[0].active); 281 }, 'addTransceiver(track, init): initialize sendEncodings[0].active to false'); 282 283 promise_test(async t => { 284 const pc1 = createPeerConnectionWithCleanup(t); 285 const pc2 = createPeerConnectionWithCleanup(t); 286 const [track] = await createTrackAndStreamWithCleanup(t); 287 pc1.addTransceiver(track, {streams:[]}); 288 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 289 assert_equals(trackEvent.streams.length, 0, 'trackEvent.streams.length == 0'); 290 }, 'addTransceiver(0 streams): ontrack fires with no stream'); 291 292 promise_test(async t => { 293 const pc1 = createPeerConnectionWithCleanup(t); 294 const pc2 = createPeerConnectionWithCleanup(t); 295 const [track] = await createTrackAndStreamWithCleanup(t); 296 const stream = new MediaStream(); 297 pc1.addTransceiver(track, {streams:[stream]}); 298 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 299 assert_equals(trackEvent.streams.length, 1, 'trackEvent.streams.length == 1'); 300 assert_equals(trackEvent.streams[0].id, stream.id, 301 'trackEvent.streams[0].id == stream.id'); 302 }, 'addTransceiver(1 stream): ontrack fires with corresponding stream'); 303 304 promise_test(async t => { 305 const pc1 = createPeerConnectionWithCleanup(t); 306 const pc2 = createPeerConnectionWithCleanup(t); 307 const [track] = await createTrackAndStreamWithCleanup(t); 308 const stream0 = new MediaStream(); 309 const stream1 = new MediaStream(); 310 pc1.addTransceiver(track, {streams:[stream0, stream1]}); 311 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 312 assert_equals(trackEvent.streams.length, 2, 'trackEvent.streams.length == 2'); 313 assert_equals(trackEvent.streams[0].id, stream0.id, 314 'trackEvent.streams[0].id == stream0.id'); 315 assert_equals(trackEvent.streams[1].id, stream1.id, 316 'trackEvent.streams[1].id == stream1.id'); 317 }, 'addTransceiver(2 streams): ontrack fires with corresponding two streams'); 318 319 promise_test(async t => { 320 const pc1 = createPeerConnectionWithCleanup(t); 321 const pc2 = createPeerConnectionWithCleanup(t); 322 const [track] = await createTrackAndStreamWithCleanup(t); 323 pc1.addTrack(track); 324 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 325 assert_equals(trackEvent.streams.length, 0, 'trackEvent.streams.length == 0'); 326 }, 'addTrack(0 streams): ontrack fires with no stream'); 327 328 promise_test(async t => { 329 const pc1 = createPeerConnectionWithCleanup(t); 330 const pc2 = createPeerConnectionWithCleanup(t); 331 const [track] = await createTrackAndStreamWithCleanup(t); 332 const stream = new MediaStream(); 333 pc1.addTrack(track, stream); 334 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 335 assert_equals(trackEvent.streams.length, 1, 'trackEvent.streams.length == 1'); 336 assert_equals(trackEvent.streams[0].id, stream.id, 337 'trackEvent.streams[0].id == stream.id'); 338 }, 'addTrack(1 stream): ontrack fires with corresponding stream'); 339 340 promise_test(async t => { 341 const pc1 = createPeerConnectionWithCleanup(t); 342 const pc2 = createPeerConnectionWithCleanup(t); 343 const [track] = await createTrackAndStreamWithCleanup(t); 344 const stream0 = new MediaStream(); 345 const stream1 = new MediaStream(); 346 pc1.addTrack(track, stream0, stream1); 347 const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 348 assert_equals(trackEvent.streams.length, 2, 'trackEvent.streams.length == 2'); 349 assert_equals(trackEvent.streams[0].id, stream0.id, 350 'trackEvent.streams[0].id == stream0.id'); 351 assert_equals(trackEvent.streams[1].id, stream1.id, 352 'trackEvent.streams[1].id == stream1.id'); 353 }, 'addTrack(2 streams): ontrack fires with corresponding two streams'); 354 355 promise_test(async t => { 356 const pc = createPeerConnectionWithCleanup(t); 357 const [track, stream] = await createTrackAndStreamWithCleanup(t); 358 const transceiver = pc.addTransceiver('audio'); 359 assert_equals(transceiver.direction, 'sendrecv'); 360 }, 'addTransceiver(\'audio\'): creates a transceiver with direction sendrecv'); 361 362 promise_test(async t => { 363 const pc = createPeerConnectionWithCleanup(t); 364 const [track, stream] = await createTrackAndStreamWithCleanup(t); 365 const transceiver = pc.addTransceiver('audio'); 366 assert_equals(transceiver.receiver.track.kind, 'audio'); 367 }, 'addTransceiver(\'audio\'): transceiver.receiver.track.kind == \'audio\''); 368 369 promise_test(async t => { 370 const pc = createPeerConnectionWithCleanup(t); 371 const [track, stream] = await createTrackAndStreamWithCleanup(t); 372 const transceiver = pc.addTransceiver('video'); 373 assert_equals(transceiver.receiver.track.kind, 'video'); 374 }, 'addTransceiver(\'video\'): transceiver.receiver.track.kind == \'video\''); 375 376 promise_test(async t => { 377 const pc = createPeerConnectionWithCleanup(t); 378 const [track, stream] = await createTrackAndStreamWithCleanup(t); 379 const transceiver = pc.addTransceiver('audio'); 380 assert_equals(transceiver.sender.track, null); 381 }, 'addTransceiver(\'audio\'): transceiver.sender.track == null'); 382 383 promise_test(async t => { 384 const pc = createPeerConnectionWithCleanup(t); 385 const [track, stream] = await createTrackAndStreamWithCleanup(t); 386 const transceiver = pc.addTransceiver('audio'); 387 assert_equals(transceiver.currentDirection, null); 388 }, 'addTransceiver(\'audio\'): transceiver.currentDirection is null'); 389 390 promise_test(async t => { 391 const pc = createPeerConnectionWithCleanup(t); 392 const [track, stream] = await createTrackAndStreamWithCleanup(t); 393 const transceiver = pc.addTransceiver('audio'); 394 // `stopped` is non-standard. Move to external/wpt/webrtc/legacy/? 395 assert_false(transceiver.stopped); 396 }, 'addTransceiver(\'audio\'): transceiver.stopped is false'); 397 398 promise_test(async t => { 399 const pc = createPeerConnectionWithCleanup(t); 400 const [track, stream] = await createTrackAndStreamWithCleanup(t, 'audio'); 401 const transceiver = pc.addTransceiver('audio'); 402 const sender = pc.addTrack(track, stream); 403 assert_equals(sender, transceiver.sender, 'sender == transceiver.sender'); 404 assert_equals(sender.track, track, 'sender.track == track'); 405 }, 'addTrack reuses reusable transceivers'); 406 407 promise_test(async t => { 408 const pc = createPeerConnectionWithCleanup(t); 409 const [track, stream] = await createTrackAndStreamWithCleanup(t, 'audio'); 410 const t1 = pc.addTransceiver('audio'); 411 const t2 = pc.addTransceiver(track); 412 assert_not_equals(t2, t1, 't2 != t1'); 413 assert_equals(t2.sender.track, track, 't2.sender.track == track'); 414 }, 'addTransceiver does not reuse reusable transceivers'); 415 416 promise_test(async t => { 417 const pc1 = createPeerConnectionWithCleanup(t); 418 const pc2 = createPeerConnectionWithCleanup(t); 419 const [track, stream] = await createTrackAndStreamWithCleanup(t); 420 const pc1Transceiver = findTransceiverForSender(pc1, pc1.addTrack(track, stream)); 421 const pc2TrackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 422 const pc2Transceiver = pc2TrackEvent.transceiver; 423 assert_equals(pc2Transceiver.direction, 'recvonly', 424 'pc2Transceiver.direction is recvonly after SRD(offer)'); 425 const pc2Sender = pc2.addTrack(track, stream); 426 assert_equals(pc2Transceiver.sender, pc2Sender, 427 'pc2Transceiver.sender == sender'); 428 assert_equals(pc2Transceiver.direction, 'sendrecv', 429 'pc2Transceiver.direction is sendrecv after addTrack()'); 430 assert_equals(pc2Transceiver.currentDirection, null, 431 'pc2Transceiver.currentDirection is null before answer'); 432 const pc1TrackEvent = await exchangeAnswerAndListenToOntrack(t, pc1, pc2); 433 assert_equals(pc2Transceiver.currentDirection, 'sendrecv', 434 'pc2Transceiver.currentDirection is sendrecv after SLD(answer)'); 435 assert_equals(pc1TrackEvent.transceiver, pc1Transceiver, 436 'Answer: pc1.ontrack fires with the existing transceiver.'); 437 assert_equals(pc1Transceiver.currentDirection, 'sendrecv', 438 'pc1Transceiver.currentDirection is sendrecv'); 439 assert_equals(pc2.getTransceivers().length, 1, 440 'pc2.getTransceivers().length == 1'); 441 assert_equals(pc1.getTransceivers().length, 1, 442 'pc1.getTransceivers().length == 1'); 443 }, 'Can setup two-way call using a single transceiver'); 444 445 promise_test(async t => { 446 const pc1 = createPeerConnectionWithCleanup(t); 447 const pc2 = createPeerConnectionWithCleanup(t); 448 const [track, stream] = await createTrackAndStreamWithCleanup(t, 'audio'); 449 const transceiver = pc1.addTransceiver(track); 450 await exchangeOffer(pc1, pc2); 451 await exchangeAnswer(pc1, pc2); 452 assert_equals(transceiver.currentDirection, 'sendonly'); 453 // `stopped` is non-standard. Move to external/wpt/webrtc/legacy/? 454 assert_false(transceiver.stopped); 455 pc1.close(); 456 assert_equals(transceiver.currentDirection, 'stopped'); 457 assert_true(transceiver.stopped); 458 }, 'Closing the PC stops the transceivers'); 459 460 promise_test(async t => { 461 const pc1 = createPeerConnectionWithCleanup(t); 462 const pc1Sender = pc1.addTrack(... await createTrackAndStreamWithCleanup(t)); 463 const localTransceiver = findTransceiverForSender(pc1, pc1Sender); 464 const pc2 = createPeerConnectionWithCleanup(t); 465 exchangeIceCandidates(pc1, pc2); 466 467 const e = await exchangeOfferAndListenToOntrack(t, pc1, pc2); 468 await exchangeAnswer(pc1, pc2); 469 localTransceiver.direction = 'inactive'; 470 await exchangeOfferAnswer(pc1, pc2); 471 472 localTransceiver.direction = 'sendrecv'; 473 await exchangeOfferAndListenToOntrack(t, pc1, pc2); 474 }, 'Changing transceiver direction to \'sendrecv\' makes ontrack fire'); 475 476 // Regression test coverage for https://crbug.com/950280. 477 promise_test(async t => { 478 const pc1 = new RTCPeerConnection(); 479 t.add_cleanup(() => pc1.close()); 480 const pc2 = new RTCPeerConnection(); 481 t.add_cleanup(() => pc2.close()); 482 const pc2Promise = pc2.createOffer() 483 .then((offer) => { return pc1.setRemoteDescription(offer); }) 484 .then(() => { return pc1.createAnswer(); }) 485 .then((answer) => { return pc1.setLocalDescription(answer); }); 486 pc1.addTransceiver('audio', { direction: 'recvonly' }); 487 const pc1Promise = pc1.createOffer() 488 .then(() => { pc1.addTrack(pc1.getReceivers()[0].track); }); 489 await Promise.all([pc1Promise, pc2Promise]); 490 assert_equals(pc1.getSenders()[0].track, pc1.getReceivers()[0].track); 491 }, 'transceiver.sender.track does not revert to an old state'); 492 493 // Regression test coverage for https://crbug.com/950280. 494 promise_test(async t => { 495 const pc1 = new RTCPeerConnection(); 496 t.add_cleanup(() => pc1.close()); 497 const pc2 = new RTCPeerConnection(); 498 t.add_cleanup(() => pc2.close()); 499 const pc2Promise = pc2.createOffer() 500 .then((offer) => { return pc1.setRemoteDescription(offer); }) 501 .then(() => { return pc1.createAnswer(); }); 502 pc1.addTransceiver('audio', { direction: 'recvonly' }); 503 const pc1Promise = pc1.createOffer() 504 .then(() => { pc1.getTransceivers()[0].direction = 'inactive'; }); 505 await Promise.all([pc1Promise, pc2Promise]); 506 assert_equals(pc1.getTransceivers()[0].direction, 'inactive'); 507 }, 'transceiver.direction does not revert to an old state'); 508 509 </script>