| 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 |