OLD | NEW |
1 <html> | 1 <html> |
2 <head> | 2 <head> |
3 <script type="text/javascript" src="webrtc_test_utilities.js"></script> | 3 <script type="text/javascript" src="webrtc_test_utilities.js"></script> |
4 <script type="text/javascript" src="webrtc_test_audio.js"></script> | 4 <script type="text/javascript" src="webrtc_test_audio.js"></script> |
5 <script type="text/javascript"> | 5 <script type="text/javascript"> |
6 $ = function(id) { | 6 $ = function(id) { |
7 return document.getElementById(id); | 7 return document.getElementById(id); |
8 }; | 8 }; |
9 | 9 |
10 var gFirstConnection = null; | 10 var gFirstConnection = null; |
11 var gSecondConnection = null; | 11 var gSecondConnection = null; |
12 var gTestWithoutMsid = false; | 12 var gTestWithoutMsid = false; |
13 var gLocalStream = null; | 13 var gLocalStream = null; |
14 var gSentTones = ''; | 14 var gSentTones = ''; |
15 | 15 |
16 var gRemoteStreams = {}; | 16 var gRemoteStreams = {}; |
17 | 17 |
18 // Default transform functions, overridden by some test cases. | 18 // Default transform functions, overridden by some test cases. |
19 var transformSdp = function(sdp) { return sdp; }; | 19 var transformSdp = function(sdp) { return sdp; }; |
20 var transformRemoteSdp = function(sdp) { return sdp; }; | 20 var transformRemoteSdp = function(sdp) { return sdp; }; |
21 var transformCandidate = function(candidate) { return candidate; }; | 21 var transformCandidate = function(candidate) { return candidate; }; |
22 var onLocalDescriptionError = function(error) { }; | 22 var onLocalDescriptionError = function(error) { }; |
23 | 23 |
| 24 // Temporary measure to be able to force iSAC 16K where needed, particularly |
| 25 // on Android. This applies to every test which is why it's implemented like |
| 26 // this. |
| 27 var maybeForceIsac16K = function(sdp) { return sdp; }; |
| 28 function forceIsac16KInSdp() { |
| 29 maybeForceIsac16K = function(sdp) { |
| 30 // Remove all other codecs (not the video codecs though). |
| 31 sdp = sdp.replace(/m=audio (\d+) RTP\/SAVPF.*\r\n/g, |
| 32 'm=audio $1 RTP/SAVPF 103\r\n'); |
| 33 sdp = sdp.replace('a=fmtp:111 minptime=10', 'a=fmtp:103 minptime=10'); |
| 34 sdp = sdp.replace(/a=rtpmap:(?!103)\d{1,3} (?!VP8|red|ulpfec).*\r\n/g, |
| 35 ''); |
| 36 return sdp; |
| 37 }; |
| 38 } |
| 39 |
24 // When using external SDES, the crypto key is chosen by javascript. | 40 // When using external SDES, the crypto key is chosen by javascript. |
25 var EXTERNAL_SDES_LINES = { | 41 var EXTERNAL_SDES_LINES = { |
26 'audio': 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 ' + | 42 'audio': 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 ' + |
27 'inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR', | 43 'inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR', |
28 'video': 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 ' + | 44 'video': 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 ' + |
29 'inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj', | 45 'inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj', |
30 'data': 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 ' + | 46 'data': 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 ' + |
31 'inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj' | 47 'inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj' |
32 }; | 48 }; |
33 | 49 |
34 // When using GICE, the ICE credentials can be chosen by javascript. | 50 // When using GICE, the ICE credentials can be chosen by javascript. |
35 var EXTERNAL_GICE_UFRAG = '1234567890123456'; | 51 var EXTERNAL_GICE_UFRAG = '1234567890123456'; |
36 var EXTERNAL_GICE_PWD = '123456789012345678901234'; | 52 var EXTERNAL_GICE_PWD = '123456789012345678901234'; |
37 | 53 |
38 setAllEventsOccuredHandler(function() { | 54 setAllEventsOccuredHandler(function() { |
| 55 // The C++ tests look for this 'OK' in the title. |
39 document.title = 'OK'; | 56 document.title = 'OK'; |
40 }); | 57 }); |
41 | 58 |
42 // Test that we can setup call with an audio and video track. | 59 // Test that we can setup call with an audio and video track. |
43 function call(constraints) { | 60 function call(constraints) { |
44 createConnections(null); | 61 createConnections(null); |
45 navigator.webkitGetUserMedia(constraints, | 62 navigator.webkitGetUserMedia(constraints, |
46 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 63 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
47 waitForVideo('remote-view-1'); | 64 waitForVideo('remote-view-1'); |
48 waitForVideo('remote-view-2'); | 65 waitForVideo('remote-view-2'); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 clearInterval(waitDtmf); | 258 clearInterval(waitDtmf); |
242 eventOccured(); | 259 eventOccured(); |
243 } | 260 } |
244 }, 100); | 261 }, 100); |
245 } | 262 } |
246 | 263 |
247 // Do the DTMF test after we have received video. | 264 // Do the DTMF test after we have received video. |
248 detectVideoPlaying('remote-view-2', onCallEstablished); | 265 detectVideoPlaying('remote-view-2', onCallEstablished); |
249 } | 266 } |
250 | 267 |
251 //TODO(phoglund): do this for all tests on android if this works on bots. | 268 function callAndEnsureAudioIsPlaying() { |
252 /** @private */ | |
253 function forceIsac16k_(sdp) { | |
254 // Remove all other codecs (not the video codecs though). | |
255 sdp = sdp.replace(/m=audio (\d+) RTP\/SAVPF.*\r\n/g, | |
256 'm=audio $1 RTP/SAVPF 103\r\n'); | |
257 sdp = sdp.replace('a=fmtp:111 minptime=10', 'a=fmtp:103 minptime=10'); | |
258 sdp = sdp.replace(/a=rtpmap:(?!103)\d{1,3} (?!VP8|red|ulpfec).*\r\n/g, ''); | |
259 return sdp; | |
260 } | |
261 | |
262 function callAndEnsureAudioIsPlaying(force_isac_16k) { | |
263 if (force_isac_16k) | |
264 transformSdp = forceIsac16k_; | |
265 createConnections(null); | 269 createConnections(null); |
266 navigator.webkitGetUserMedia({audio: true, video: true}, | 270 navigator.webkitGetUserMedia({audio: true, video: true}, |
267 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 271 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
268 | 272 |
269 // Wait until we have gathered samples and can conclude if audio is playing. | 273 // Wait until we have gathered samples and can conclude if audio is playing. |
270 addExpectedEvent(); | 274 addExpectedEvent(); |
271 var onCallEstablished = function() { | 275 var onCallEstablished = function() { |
272 gatherAudioLevelSamples(gSecondConnection, 300, 100, | 276 gatherAudioLevelSamples(gSecondConnection, 300, 100, |
273 function(samples) { | 277 function(samples) { |
274 verifyAudioIsPlaying(samples); | 278 verifyAudioIsPlaying(samples); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 addExpectedEvent(); | 365 addExpectedEvent(); |
362 remote_stream_2.onremovetrack = function() { | 366 remote_stream_2.onremovetrack = function() { |
363 eventOccured(); | 367 eventOccured(); |
364 } | 368 } |
365 // When all the above events have occurred- the test pass. | 369 // When all the above events have occurred- the test pass. |
366 setAllEventsOccuredHandler(function() { document.title = 'OK'; }); | 370 setAllEventsOccuredHandler(function() { document.title = 'OK'; }); |
367 | 371 |
368 local_stream.addTrack(gLocalStream.getAudioTracks()[0]); | 372 local_stream.addTrack(gLocalStream.getAudioTracks()[0]); |
369 local_stream.removeTrack(local_stream.getVideoTracks()[0]); | 373 local_stream.removeTrack(local_stream.getVideoTracks()[0]); |
370 negotiate(); | 374 negotiate(); |
371 }); // End of setAllEventsOccuredHandler. | 375 }); |
372 } | 376 } |
373 | 377 |
374 // This function is used for setting up a test that: | 378 // This function is used for setting up a test that: |
375 // 1. Creates a data channel on |gFirstConnection| and sends data to | 379 // 1. Creates a data channel on |gFirstConnection| and sends data to |
376 // |gSecondConnection|. | 380 // |gSecondConnection|. |
377 // 2. When data is received on |gSecondConnection| a message | 381 // 2. When data is received on |gSecondConnection| a message |
378 // is sent to |gFirstConnection|. | 382 // is sent to |gFirstConnection|. |
379 // 3. When data is received on |gFirstConnection|, the data | 383 // 3. When data is received on |gFirstConnection|, the data |
380 // channel is closed. The test passes when the state transition completes. | 384 // channel is closed. The test passes when the state transition completes. |
381 function setupDataChannel(params) { | 385 function setupDataChannel(params) { |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 | 601 |
598 connectOnIceCandidate(caller, callee); | 602 connectOnIceCandidate(caller, callee); |
599 | 603 |
600 caller.createOffer( | 604 caller.createOffer( |
601 function (offer) { | 605 function (offer) { |
602 onOfferCreated(offer, caller, callee); | 606 onOfferCreated(offer, caller, callee); |
603 }); | 607 }); |
604 } | 608 } |
605 | 609 |
606 function onOfferCreated(offer, caller, callee) { | 610 function onOfferCreated(offer, caller, callee) { |
607 offer.sdp = transformSdp(offer.sdp); | 611 offer.sdp = maybeForceIsac16K(transformSdp(offer.sdp)); |
608 caller.setLocalDescription(offer, function() { | 612 caller.setLocalDescription(offer, function() { |
609 expectEquals('have-local-offer', caller.signalingState); | 613 expectEquals('have-local-offer', caller.signalingState); |
610 receiveOffer(offer.sdp, caller, callee); | 614 receiveOffer(offer.sdp, caller, callee); |
611 }, onLocalDescriptionError); | 615 }, onLocalDescriptionError); |
612 } | 616 } |
613 | 617 |
614 function receiveOffer(offerSdp, caller, callee) { | 618 function receiveOffer(offerSdp, caller, callee) { |
615 offerSdp = transformRemoteSdp(offerSdp); | 619 offerSdp = transformRemoteSdp(offerSdp); |
616 | 620 |
617 var parsedOffer = new RTCSessionDescription({ type: 'offer', | 621 var parsedOffer = new RTCSessionDescription({ type: 'offer', |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 sdp = sdp.replace(/a=crypto.*\r\n/g, ''); | 667 sdp = sdp.replace(/a=crypto.*\r\n/g, ''); |
664 sdp = sdp.replace(/a=fingerprint.*\r\n/g, ''); | 668 sdp = sdp.replace(/a=fingerprint.*\r\n/g, ''); |
665 // Add external crypto. This is not compatible with |removeMsid|. | 669 // Add external crypto. This is not compatible with |removeMsid|. |
666 sdp = sdp.replace(/a=mid:(\w+)\r\n/g, function(subString, group) { | 670 sdp = sdp.replace(/a=mid:(\w+)\r\n/g, function(subString, group) { |
667 return subString + EXTERNAL_SDES_LINES[group] + '\r\n'; | 671 return subString + EXTERNAL_SDES_LINES[group] + '\r\n'; |
668 }); | 672 }); |
669 return sdp; | 673 return sdp; |
670 } | 674 } |
671 | 675 |
672 function onAnswerCreated(answer, caller, callee) { | 676 function onAnswerCreated(answer, caller, callee) { |
673 answer.sdp = transformSdp(answer.sdp); | 677 answer.sdp = maybeForceIsac16K(transformSdp(answer.sdp)); |
674 callee.setLocalDescription(answer); | 678 callee.setLocalDescription(answer); |
675 expectEquals('stable', callee.signalingState); | 679 expectEquals('stable', callee.signalingState); |
676 receiveAnswer(answer.sdp, caller); | 680 receiveAnswer(answer.sdp, caller); |
677 } | 681 } |
678 | 682 |
679 function receiveAnswer(answerSdp, caller) { | 683 function receiveAnswer(answerSdp, caller) { |
680 answerSdp = transformRemoteSdp(answerSdp); | 684 answerSdp = transformRemoteSdp(answerSdp); |
681 var parsedAnswer = new RTCSessionDescription({ type: 'answer', | 685 var parsedAnswer = new RTCSessionDescription({ type: 'answer', |
682 sdp: answerSdp }); | 686 sdp: answerSdp }); |
683 caller.setRemoteDescription(parsedAnswer); | 687 caller.setRemoteDescription(parsedAnswer); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 <td><canvas width="320" height="240" id="remote-view-2-canvas" | 746 <td><canvas width="320" height="240" id="remote-view-2-canvas" |
743 style="display:none"></canvas></td> | 747 style="display:none"></canvas></td> |
744 <td><canvas width="320" height="240" id="remote-view-3-canvas" | 748 <td><canvas width="320" height="240" id="remote-view-3-canvas" |
745 style="display:none"></canvas></td> | 749 style="display:none"></canvas></td> |
746 <td><canvas width="320" height="240" id="remote-view-4-canvas" | 750 <td><canvas width="320" height="240" id="remote-view-4-canvas" |
747 style="display:none"></canvas></td> | 751 style="display:none"></canvas></td> |
748 </tr> | 752 </tr> |
749 </table> | 753 </table> |
750 </body> | 754 </body> |
751 </html> | 755 </html> |
OLD | NEW |