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; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 'video': 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 ' + | 46 'video': 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 ' + |
47 'inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj', | 47 'inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj', |
48 'data': 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 ' + | 48 'data': 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 ' + |
49 'inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj' | 49 'inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj' |
50 }; | 50 }; |
51 | 51 |
52 // When using GICE, the ICE credentials can be chosen by javascript. | 52 // When using GICE, the ICE credentials can be chosen by javascript. |
53 var EXTERNAL_GICE_UFRAG = '1234567890123456'; | 53 var EXTERNAL_GICE_UFRAG = '1234567890123456'; |
54 var EXTERNAL_GICE_PWD = '123456789012345678901234'; | 54 var EXTERNAL_GICE_PWD = '123456789012345678901234'; |
55 | 55 |
56 setAllEventsOccuredHandler(function() { | 56 setAllEventsOccuredHandler(reportTestSuccess); |
57 // The C++ tests look for this 'OK' in the title. | |
58 document.title = 'OK'; | |
59 }); | |
60 | 57 |
61 // Test that we can setup call with an audio and video track. | 58 // Test that we can setup call with an audio and video track. |
62 function call(constraints) { | 59 function call(constraints) { |
63 createConnections(null); | 60 createConnections(null); |
64 navigator.webkitGetUserMedia(constraints, | 61 navigator.webkitGetUserMedia(constraints, |
65 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 62 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
66 waitForVideo('remote-view-1'); | 63 waitForVideo('remote-view-1'); |
67 waitForVideo('remote-view-2'); | 64 waitForVideo('remote-view-2'); |
68 } | 65 } |
69 | 66 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 navigator.webkitGetUserMedia({audio: true, video: true}, | 134 navigator.webkitGetUserMedia({audio: true, video: true}, |
138 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 135 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
139 waitForVideo('remote-view-1'); | 136 waitForVideo('remote-view-1'); |
140 waitForVideo('remote-view-2'); | 137 waitForVideo('remote-view-2'); |
141 } | 138 } |
142 | 139 |
143 // Test that we can't setup a call with an unsupported video codec | 140 // Test that we can't setup a call with an unsupported video codec |
144 function negotiateUnsupportedVideoCodec() { | 141 function negotiateUnsupportedVideoCodec() { |
145 createConnections(null); | 142 createConnections(null); |
146 transformSdp = removeVideoCodec; | 143 transformSdp = removeVideoCodec; |
| 144 |
147 onLocalDescriptionError = function(error) { | 145 onLocalDescriptionError = function(error) { |
148 var expectedMsg = 'Failed to set local offer sdp:' + | 146 var expectedMsg = 'Failed to set local offer sdp:' + |
149 ' Session error code: ERROR_CONTENT. Session error description:' + | 147 ' Session error code: ERROR_CONTENT. Session error description:' + |
150 ' Failed to set video receive codecs..'; | 148 ' Failed to set video receive codecs..'; |
151 expectEquals(expectedMsg, error); | 149 assertEquals(expectedMsg, error); |
152 | 150 reportTestSuccess(); |
153 // Got the right message, test succeeded. | |
154 document.title = 'OK'; | |
155 }; | 151 }; |
156 navigator.webkitGetUserMedia({audio: true, video: true}, | 152 navigator.webkitGetUserMedia({audio: true, video: true}, |
157 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 153 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
158 } | 154 } |
159 | 155 |
160 // Test that we can't setup a call if one peer does not support encryption | 156 // Test that we can't setup a call if one peer does not support encryption |
161 function negotiateNonCryptoCall() { | 157 function negotiateNonCryptoCall() { |
162 createConnections(null); | 158 createConnections(null); |
163 transformSdp = removeCrypto; | 159 transformSdp = removeCrypto; |
164 onLocalDescriptionError = function(error) { | 160 onLocalDescriptionError = function(error) { |
165 var expectedMsg = 'Failed to set local offer sdp:' + | 161 var expectedMsg = 'Failed to set local offer sdp:' + |
166 ' Called with SDP without DTLS fingerprint.'; | 162 ' Called with SDP without DTLS fingerprint.'; |
167 expectEquals(expectedMsg, error); | |
168 | 163 |
169 // Got the right message, test succeeded. | 164 assertEquals(expectedMsg, error); |
170 document.title = 'OK'; | 165 reportTestSuccess(); |
171 }; | 166 }; |
172 navigator.webkitGetUserMedia({audio: true, video: true}, | 167 navigator.webkitGetUserMedia({audio: true, video: true}, |
173 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 168 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
174 } | 169 } |
175 | 170 |
176 // Test that we can negotiate a call with an SDP offer that includes a | 171 // Test that we can negotiate a call with an SDP offer that includes a |
177 // b=AS:XX line to control audio and video bandwidth | 172 // b=AS:XX line to control audio and video bandwidth |
178 function negotiateOfferWithBLine() { | 173 function negotiateOfferWithBLine() { |
179 createConnections(null); | 174 createConnections(null); |
180 transformSdp = addBandwithControl; | 175 transformSdp = addBandwithControl; |
181 navigator.webkitGetUserMedia({audio: true, video: true}, | 176 navigator.webkitGetUserMedia({audio: true, video: true}, |
182 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 177 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
183 waitForVideo('remote-view-1'); | 178 waitForVideo('remote-view-1'); |
184 waitForVideo('remote-view-2'); | 179 waitForVideo('remote-view-2'); |
185 } | 180 } |
186 | 181 |
187 // Test that we can setup call with legacy settings. | 182 // Test that we can setup call with legacy settings. |
188 function callWithLegacySdp() { | 183 function callWithLegacySdp() { |
189 transformSdp = function(sdp) { | 184 transformSdp = function(sdp) { |
190 return removeBundle(useGice(useExternalSdes(sdp))); | 185 return removeBundle(useGice(useExternalSdes(sdp))); |
191 }; | 186 }; |
192 transformCandidate = addGiceCredsToCandidate; | 187 transformCandidate = addGiceCredsToCandidate; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 | 232 |
238 // Test call with a data channel and later add audio and video. | 233 // Test call with a data channel and later add audio and video. |
239 function callWithDataAndLaterAddMedia() { | 234 function callWithDataAndLaterAddMedia() { |
240 createConnections({optional:[{RtpDataChannels: true}]}); | 235 createConnections({optional:[{RtpDataChannels: true}]}); |
241 setupDataChannel({reliable: false}); | 236 setupDataChannel({reliable: false}); |
242 negotiate(); | 237 negotiate(); |
243 | 238 |
244 // Set an event handler for when the data channel has been closed. | 239 // Set an event handler for when the data channel has been closed. |
245 setAllEventsOccuredHandler(function() { | 240 setAllEventsOccuredHandler(function() { |
246 // When the video is flowing the test is done. | 241 // When the video is flowing the test is done. |
247 setAllEventsOccuredHandler(function() { | 242 setAllEventsOccuredHandler(reportTestSuccess); |
248 document.title = 'OK'; | |
249 }); | |
250 navigator.webkitGetUserMedia({audio: true, video: true}, | 243 navigator.webkitGetUserMedia({audio: true, video: true}, |
251 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 244 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
252 waitForVideo('remote-view-1'); | 245 waitForVideo('remote-view-1'); |
253 waitForVideo('remote-view-2'); | 246 waitForVideo('remote-view-2'); |
254 }); | 247 }); |
255 } | 248 } |
256 | 249 |
257 // Test that we can setup call and send DTMF. | 250 // Test that we can setup call and send DTMF. |
258 function callAndSendDtmf(tones) { | 251 function callAndSendDtmf(tones) { |
259 createConnections(null); | 252 createConnections(null); |
260 navigator.webkitGetUserMedia({audio: true, video: true}, | 253 navigator.webkitGetUserMedia({audio: true, video: true}, |
261 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 254 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
262 var onCallEstablished = function() { | 255 var onCallEstablished = function() { |
263 // Send DTMF tones. | 256 // Send DTMF tones. |
264 var localAudioTrack = gLocalStream.getAudioTracks()[0]; | 257 var localAudioTrack = gLocalStream.getAudioTracks()[0]; |
265 var dtmfSender = gFirstConnection.createDTMFSender(localAudioTrack); | 258 var dtmfSender = gFirstConnection.createDTMFSender(localAudioTrack); |
266 dtmfSender.ontonechange = onToneChange; | 259 dtmfSender.ontonechange = onToneChange; |
267 dtmfSender.insertDTMF(tones); | 260 dtmfSender.insertDTMF(tones); |
268 // Wait for the DTMF tones callback. | 261 // Wait for the DTMF tones callback. |
269 document.title = 'Waiting for dtmf...'; | |
270 addExpectedEvent(); | 262 addExpectedEvent(); |
271 var waitDtmf = setInterval(function() { | 263 var waitDtmf = setInterval(function() { |
272 if (gSentTones == tones) { | 264 if (gSentTones == tones) { |
273 clearInterval(waitDtmf); | 265 clearInterval(waitDtmf); |
274 eventOccured(); | 266 eventOccured(); |
275 } | 267 } |
276 }, 100); | 268 }, 100); |
277 } | 269 } |
278 | 270 |
279 // Do the DTMF test after we have received video. | 271 // Do the DTMF test after we have received video. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 function callAndEnsureAudioMutingWorks() { | 308 function callAndEnsureAudioMutingWorks() { |
317 callAndEnsureAudioIsPlaying(); | 309 callAndEnsureAudioIsPlaying(); |
318 setAllEventsOccuredHandler(function() { | 310 setAllEventsOccuredHandler(function() { |
319 // Call is up, now mute the track and check everything goes silent (give | 311 // Call is up, now mute the track and check everything goes silent (give |
320 // it a small delay though, we don't expect it to happen instantly). | 312 // it a small delay though, we don't expect it to happen instantly). |
321 enableRemoteAudio(gSecondConnection, false); | 313 enableRemoteAudio(gSecondConnection, false); |
322 | 314 |
323 setTimeout(function() { | 315 setTimeout(function() { |
324 gatherAudioLevelSamples(gSecondConnection, 200, 100, function(samples) { | 316 gatherAudioLevelSamples(gSecondConnection, 200, 100, function(samples) { |
325 verifyIsSilent(samples); | 317 verifyIsSilent(samples); |
326 document.title = 'OK'; | 318 reportTestSuccess(); |
327 }); | 319 }); |
328 }, 500); | 320 }, 500); |
329 }); | 321 }); |
330 } | 322 } |
331 | 323 |
332 function callAndEnsureVideoMutingWorks() { | 324 function callAndEnsureVideoMutingWorks() { |
333 createConnections(null); | 325 createConnections(null); |
334 navigator.webkitGetUserMedia({audio: true, video: true}, | 326 navigator.webkitGetUserMedia({audio: true, video: true}, |
335 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 327 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
336 | 328 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 // Add an audio track to the local stream and remove the video track and | 369 // Add an audio track to the local stream and remove the video track and |
378 // then renegotiate. But first - setup the expectations. | 370 // then renegotiate. But first - setup the expectations. |
379 local_stream = gFirstConnection.getLocalStreams()[0]; | 371 local_stream = gFirstConnection.getLocalStreams()[0]; |
380 | 372 |
381 remote_stream_1 = gFirstConnection.getRemoteStreams()[0]; | 373 remote_stream_1 = gFirstConnection.getRemoteStreams()[0]; |
382 // Add an expected event that onaddtrack will be called on the remote | 374 // Add an expected event that onaddtrack will be called on the remote |
383 // mediastream received on gFirstConnection when the audio track is | 375 // mediastream received on gFirstConnection when the audio track is |
384 // received. | 376 // received. |
385 addExpectedEvent(); | 377 addExpectedEvent(); |
386 remote_stream_1.onaddtrack = function(){ | 378 remote_stream_1.onaddtrack = function(){ |
387 expectEquals(remote_stream_1.getAudioTracks()[0].id, | 379 assertEquals(remote_stream_1.getAudioTracks()[0].id, |
388 local_stream.getAudioTracks()[0].id); | 380 local_stream.getAudioTracks()[0].id); |
389 eventOccured(); | 381 eventOccured(); |
390 } | 382 } |
391 | 383 |
392 // Add an expectation that the received video track is removed from | 384 // Add an expectation that the received video track is removed from |
393 // gFirstConnection. | 385 // gFirstConnection. |
394 addExpectedEvent(); | 386 addExpectedEvent(); |
395 remote_stream_1.onremovetrack = function() { | 387 remote_stream_1.onremovetrack = function() { |
396 eventOccured(); | 388 eventOccured(); |
397 } | 389 } |
398 | 390 |
399 // Add an expected event that onaddtrack will be called on the remote | 391 // Add an expected event that onaddtrack will be called on the remote |
400 // mediastream received on gSecondConnection when the audio track is | 392 // mediastream received on gSecondConnection when the audio track is |
401 // received. | 393 // received. |
402 remote_stream_2 = gSecondConnection.getRemoteStreams()[0]; | 394 remote_stream_2 = gSecondConnection.getRemoteStreams()[0]; |
403 addExpectedEvent(); | 395 addExpectedEvent(); |
404 remote_stream_2.onaddtrack = function() { | 396 remote_stream_2.onaddtrack = function() { |
405 expectEquals(remote_stream_2.getAudioTracks()[0].id, | 397 assertEquals(remote_stream_2.getAudioTracks()[0].id, |
406 local_stream.getAudioTracks()[0].id); | 398 local_stream.getAudioTracks()[0].id); |
407 eventOccured(); | 399 eventOccured(); |
408 } | 400 } |
409 | 401 |
410 // Add an expectation that the received video track is removed from | 402 // Add an expectation that the received video track is removed from |
411 // gSecondConnection. | 403 // gSecondConnection. |
412 addExpectedEvent(); | 404 addExpectedEvent(); |
413 remote_stream_2.onremovetrack = function() { | 405 remote_stream_2.onremovetrack = function() { |
414 eventOccured(); | 406 eventOccured(); |
415 } | 407 } |
416 // When all the above events have occurred- the test pass. | 408 // When all the above events have occurred- the test pass. |
417 setAllEventsOccuredHandler(function() { document.title = 'OK'; }); | 409 setAllEventsOccuredHandler(reportTestSuccess); |
418 | 410 |
419 local_stream.addTrack(gLocalStream.getAudioTracks()[0]); | 411 local_stream.addTrack(gLocalStream.getAudioTracks()[0]); |
420 local_stream.removeTrack(local_stream.getVideoTracks()[0]); | 412 local_stream.removeTrack(local_stream.getVideoTracks()[0]); |
421 negotiate(); | 413 negotiate(); |
422 }); | 414 }); |
423 } | 415 } |
424 | 416 |
425 // This function is used for setting up a test that: | 417 // This function is used for setting up a test that: |
426 // 1. Creates a data channel on |gFirstConnection| and sends data to | 418 // 1. Creates a data channel on |gFirstConnection| and sends data to |
427 // |gSecondConnection|. | 419 // |gSecondConnection|. |
428 // 2. When data is received on |gSecondConnection| a message | 420 // 2. When data is received on |gSecondConnection| a message |
429 // is sent to |gFirstConnection|. | 421 // is sent to |gFirstConnection|. |
430 // 3. When data is received on |gFirstConnection|, the data | 422 // 3. When data is received on |gFirstConnection|, the data |
431 // channel is closed. The test passes when the state transition completes. | 423 // channel is closed. The test passes when the state transition completes. |
432 function setupDataChannel(params) { | 424 function setupDataChannel(params) { |
433 var sendDataString = "send some text on a data channel." | 425 var sendDataString = "send some text on a data channel." |
434 firstDataChannel = gFirstConnection.createDataChannel( | 426 firstDataChannel = gFirstConnection.createDataChannel( |
435 "sendDataChannel", params); | 427 "sendDataChannel", params); |
436 expectEquals('connecting', firstDataChannel.readyState); | 428 assertEquals('connecting', firstDataChannel.readyState); |
437 | 429 |
438 // When |firstDataChannel| transition to open state, send a text string. | 430 // When |firstDataChannel| transition to open state, send a text string. |
439 firstDataChannel.onopen = function() { | 431 firstDataChannel.onopen = function() { |
440 expectEquals('open', firstDataChannel.readyState); | 432 assertEquals('open', firstDataChannel.readyState); |
441 firstDataChannel.send(sendDataString); | 433 firstDataChannel.send(sendDataString); |
442 } | 434 } |
443 | 435 |
444 // When |firstDataChannel| receive a message, close the channel and | 436 // When |firstDataChannel| receive a message, close the channel and |
445 // initiate a new offer/answer exchange to complete the closure. | 437 // initiate a new offer/answer exchange to complete the closure. |
446 firstDataChannel.onmessage = function(event) { | 438 firstDataChannel.onmessage = function(event) { |
447 expectEquals(event.data, sendDataString); | 439 assertEquals(event.data, sendDataString); |
448 firstDataChannel.close(); | 440 firstDataChannel.close(); |
449 negotiate(); | 441 negotiate(); |
450 } | 442 } |
451 | 443 |
452 // When |firstDataChannel| transition to closed state, the test pass. | 444 // When |firstDataChannel| transition to closed state, the test pass. |
| 445 // TODO(phoglund): This is flaky, at least in the setupLegacyCall case. |
| 446 // See http://crbug.com/350388. |
453 addExpectedEvent(); | 447 addExpectedEvent(); |
454 firstDataChannel.onclose = function() { | 448 firstDataChannel.onclose = function() { |
455 expectEquals('closed', firstDataChannel.readyState); | 449 assertEquals('closed', firstDataChannel.readyState); |
456 eventOccured(); | 450 eventOccured(); |
457 } | 451 } |
458 | 452 |
459 // Event handler for when |gSecondConnection| receive a new dataChannel. | 453 // Event handler for when |gSecondConnection| receive a new dataChannel. |
460 gSecondConnection.ondatachannel = function (event) { | 454 gSecondConnection.ondatachannel = function (event) { |
461 var secondDataChannel = event.channel; | 455 var secondDataChannel = event.channel; |
462 | 456 |
463 // When |secondDataChannel| receive a message, send a message back. | 457 // When |secondDataChannel| receive a message, send a message back. |
464 secondDataChannel.onmessage = function(event) { | 458 secondDataChannel.onmessage = function(event) { |
465 expectEquals(event.data, sendDataString); | 459 assertEquals(event.data, sendDataString); |
466 expectEquals('open', secondDataChannel.readyState); | 460 assertEquals('open', secondDataChannel.readyState); |
467 secondDataChannel.send(sendDataString); | 461 secondDataChannel.send(sendDataString); |
468 } | 462 } |
469 } | 463 } |
470 } | 464 } |
471 | 465 |
472 // SCTP data channel setup is slightly different then RTP based | 466 // SCTP data channel setup is slightly different then RTP based |
473 // channels. Due to a bug in libjingle, we can't send data immediately | 467 // channels. Due to a bug in libjingle, we can't send data immediately |
474 // after channel becomes open. So for that reason in SCTP, | 468 // after channel becomes open. So for that reason in SCTP, |
475 // we are sending data from second channel, when ondatachannel event is | 469 // we are sending data from second channel, when ondatachannel event is |
476 // received. So data flow happens 2 -> 1 -> 2. | 470 // received. So data flow happens 2 -> 1 -> 2. |
477 function setupSctpDataChannel(params) { | 471 function setupSctpDataChannel(params) { |
478 var sendDataString = "send some text on a data channel." | 472 var sendDataString = "send some text on a data channel." |
479 firstDataChannel = gFirstConnection.createDataChannel( | 473 firstDataChannel = gFirstConnection.createDataChannel( |
480 "sendDataChannel", params); | 474 "sendDataChannel", params); |
481 expectEquals('connecting', firstDataChannel.readyState); | 475 assertEquals('connecting', firstDataChannel.readyState); |
482 | 476 |
483 // When |firstDataChannel| transition to open state, send a text string. | 477 // When |firstDataChannel| transition to open state, send a text string. |
484 firstDataChannel.onopen = function() { | 478 firstDataChannel.onopen = function() { |
485 expectEquals('open', firstDataChannel.readyState); | 479 assertEquals('open', firstDataChannel.readyState); |
486 } | 480 } |
487 | 481 |
488 // When |firstDataChannel| receive a message, send message back. | 482 // When |firstDataChannel| receive a message, send message back. |
489 // initiate a new offer/answer exchange to complete the closure. | 483 // initiate a new offer/answer exchange to complete the closure. |
490 firstDataChannel.onmessage = function(event) { | 484 firstDataChannel.onmessage = function(event) { |
491 expectEquals('open', firstDataChannel.readyState); | 485 assertEquals('open', firstDataChannel.readyState); |
492 expectEquals(event.data, sendDataString); | 486 assertEquals(event.data, sendDataString); |
493 firstDataChannel.send(sendDataString); | 487 firstDataChannel.send(sendDataString); |
494 } | 488 } |
495 | 489 |
496 | 490 |
497 // Event handler for when |gSecondConnection| receive a new dataChannel. | 491 // Event handler for when |gSecondConnection| receive a new dataChannel. |
498 gSecondConnection.ondatachannel = function (event) { | 492 gSecondConnection.ondatachannel = function (event) { |
499 var secondDataChannel = event.channel; | 493 var secondDataChannel = event.channel; |
500 secondDataChannel.onopen = function() { | 494 secondDataChannel.onopen = function() { |
501 secondDataChannel.send(sendDataString); | 495 secondDataChannel.send(sendDataString); |
502 } | 496 } |
503 | 497 |
504 // When |secondDataChannel| receive a message, close the channel and | 498 // When |secondDataChannel| receive a message, close the channel and |
505 // initiate a new offer/answer exchange to complete the closure. | 499 // initiate a new offer/answer exchange to complete the closure. |
506 secondDataChannel.onmessage = function(event) { | 500 secondDataChannel.onmessage = function(event) { |
507 expectEquals(event.data, sendDataString); | 501 assertEquals(event.data, sendDataString); |
508 expectEquals('open', secondDataChannel.readyState); | 502 assertEquals('open', secondDataChannel.readyState); |
509 secondDataChannel.close(); | 503 secondDataChannel.close(); |
510 negotiate(); | 504 negotiate(); |
511 } | 505 } |
512 | 506 |
513 // When |secondDataChannel| transition to closed state, the test pass. | 507 // When |secondDataChannel| transition to closed state, the test pass. |
514 addExpectedEvent(); | 508 addExpectedEvent(); |
515 secondDataChannel.onclose = function() { | 509 secondDataChannel.onclose = function() { |
516 expectEquals('closed', secondDataChannel.readyState); | 510 assertEquals('closed', secondDataChannel.readyState); |
517 eventOccured(); | 511 eventOccured(); |
518 } | 512 } |
519 } | 513 } |
520 } | 514 } |
521 | 515 |
522 // Test call with a stream that has been created by getUserMedia, clone | 516 // Test call with a stream that has been created by getUserMedia, clone |
523 // the stream to a cloned stream, send them via the same peer connection. | 517 // the stream to a cloned stream, send them via the same peer connection. |
524 function addTwoMediaStreamsToOneConnection() { | 518 function addTwoMediaStreamsToOneConnection() { |
525 createConnections(null); | 519 createConnections(null); |
526 navigator.webkitGetUserMedia({audio: true, video: true}, | 520 navigator.webkitGetUserMedia({audio: true, video: true}, |
527 CloneStreamAndAddTwoStreamstoOneConnection, printGetUserMediaError); | 521 CloneStreamAndAddTwoStreamstoOneConnection, printGetUserMediaError); |
528 } | 522 } |
529 | 523 |
530 function onToneChange(tone) { | 524 function onToneChange(tone) { |
531 gSentTones += tone.tone; | 525 gSentTones += tone.tone; |
532 document.title = gSentTones; | |
533 } | 526 } |
534 | 527 |
535 function createConnections(constraints) { | 528 function createConnections(constraints) { |
536 gFirstConnection = createConnection(constraints, 'remote-view-1'); | 529 gFirstConnection = createConnection(constraints, 'remote-view-1'); |
537 expectEquals('stable', gFirstConnection.signalingState); | 530 assertEquals('stable', gFirstConnection.signalingState); |
538 | 531 |
539 gSecondConnection = createConnection(constraints, 'remote-view-2'); | 532 gSecondConnection = createConnection(constraints, 'remote-view-2'); |
540 expectEquals('stable', gSecondConnection.signalingState); | 533 assertEquals('stable', gSecondConnection.signalingState); |
541 } | 534 } |
542 | 535 |
543 function createConnection(constraints, remoteView) { | 536 function createConnection(constraints, remoteView) { |
544 var pc = new webkitRTCPeerConnection(null, constraints); | 537 var pc = new webkitRTCPeerConnection(null, constraints); |
545 pc.onaddstream = function(event) { | 538 pc.onaddstream = function(event) { |
546 onRemoteStream(event, remoteView); | 539 onRemoteStream(event, remoteView); |
547 } | 540 } |
548 return pc; | 541 return pc; |
549 } | 542 } |
550 | 543 |
551 function displayAndRemember(localStream) { | 544 function displayAndRemember(localStream) { |
552 var localStreamUrl = URL.createObjectURL(localStream); | 545 var localStreamUrl = URL.createObjectURL(localStream); |
553 $('local-view').src = localStreamUrl; | 546 $('local-view').src = localStreamUrl; |
554 | 547 |
555 gLocalStream = localStream; | 548 gLocalStream = localStream; |
556 } | 549 } |
557 | 550 |
558 // Called if getUserMedia fails. | 551 // Called if getUserMedia fails. |
559 function printGetUserMediaError(error) { | 552 function printGetUserMediaError(error) { |
560 document.title = 'getUserMedia request failed:'; | 553 var message = 'getUserMedia request unexpectedly failed:'; |
561 if (error.constraintName) | 554 if (error.constraintName) |
562 document.title += ' could not satisfy constraint ' + error.constraintName; | 555 message += ' could not satisfy constraint ' + error.constraintName; |
563 else | 556 else |
564 document.title += ' devices not working/user denied access.'; | 557 message += ' devices not working/user denied access.'; |
565 console.log(document.title); | 558 failTest(message); |
566 } | 559 } |
567 | 560 |
568 // Called if getUserMedia succeeds and we want to send from both connections. | 561 // Called if getUserMedia succeeds and we want to send from both connections. |
569 function addStreamToBothConnectionsAndNegotiate(localStream) { | 562 function addStreamToBothConnectionsAndNegotiate(localStream) { |
570 displayAndRemember(localStream); | 563 displayAndRemember(localStream); |
571 gFirstConnection.addStream(localStream); | 564 gFirstConnection.addStream(localStream); |
572 gSecondConnection.addStream(localStream); | 565 gSecondConnection.addStream(localStream); |
573 negotiate(); | 566 negotiate(); |
574 } | 567 } |
575 | 568 |
576 // Called if getUserMedia succeeds when we want to send from one connection. | 569 // Called if getUserMedia succeeds when we want to send from one connection. |
577 function addStreamToTheFirstConnectionAndNegotiate(localStream) { | 570 function addStreamToTheFirstConnectionAndNegotiate(localStream) { |
578 displayAndRemember(localStream); | 571 displayAndRemember(localStream); |
579 gFirstConnection.addStream(localStream); | 572 gFirstConnection.addStream(localStream); |
580 negotiate(); | 573 negotiate(); |
581 } | 574 } |
582 | 575 |
583 function verifyHasOneAudioAndVideoTrack(stream) { | 576 function verifyHasOneAudioAndVideoTrack(stream) { |
584 expectEquals(1, stream.getAudioTracks().length); | 577 assertEquals(1, stream.getAudioTracks().length); |
585 expectEquals(1, stream.getVideoTracks().length); | 578 assertEquals(1, stream.getVideoTracks().length); |
586 } | 579 } |
587 | 580 |
588 // Called if getUserMedia succeeds, then clone the stream, send two streams | 581 // Called if getUserMedia succeeds, then clone the stream, send two streams |
589 // from one peer connection. | 582 // from one peer connection. |
590 function CloneStreamAndAddTwoStreamstoOneConnection(localStream) { | 583 function CloneStreamAndAddTwoStreamstoOneConnection(localStream) { |
591 displayAndRemember(localStream); | 584 displayAndRemember(localStream); |
592 | 585 |
593 var clonedStream = null; | 586 var clonedStream = null; |
594 if (typeof localStream.clone === "function") { | 587 if (typeof localStream.clone === "function") { |
595 clonedStream = localStream.clone(); | 588 clonedStream = localStream.clone(); |
596 } else { | 589 } else { |
597 clonedStream = new webkitMediaStream(localStream); | 590 clonedStream = new webkitMediaStream(localStream); |
598 } | 591 } |
599 | 592 |
600 gFirstConnection.addStream(localStream); | 593 gFirstConnection.addStream(localStream); |
601 gFirstConnection.addStream(clonedStream); | 594 gFirstConnection.addStream(clonedStream); |
602 | 595 |
603 // Verify the local streams are correct. | 596 // Verify the local streams are correct. |
604 expectEquals(2, gFirstConnection.getLocalStreams().length); | 597 assertEquals(2, gFirstConnection.getLocalStreams().length); |
605 verifyHasOneAudioAndVideoTrack(gFirstConnection.getLocalStreams()[0]); | 598 verifyHasOneAudioAndVideoTrack(gFirstConnection.getLocalStreams()[0]); |
606 verifyHasOneAudioAndVideoTrack(gFirstConnection.getLocalStreams()[1]); | 599 verifyHasOneAudioAndVideoTrack(gFirstConnection.getLocalStreams()[1]); |
607 | 600 |
608 // The remote side should receive two streams. After that, verify the | 601 // The remote side should receive two streams. After that, verify the |
609 // remote side has the correct number of streams and tracks. | 602 // remote side has the correct number of streams and tracks. |
610 addExpectedEvent(); | 603 addExpectedEvent(); |
611 addExpectedEvent(); | 604 addExpectedEvent(); |
612 gSecondConnection.onaddstream = function(event) { | 605 gSecondConnection.onaddstream = function(event) { |
613 eventOccured(); | 606 eventOccured(); |
614 } | 607 } |
615 setAllEventsOccuredHandler(function() { | 608 setAllEventsOccuredHandler(function() { |
616 // Negotiation complete, verify remote streams on the receiving side. | 609 // Negotiation complete, verify remote streams on the receiving side. |
617 expectEquals(2, gSecondConnection.getRemoteStreams().length); | 610 assertEquals(2, gSecondConnection.getRemoteStreams().length); |
618 verifyHasOneAudioAndVideoTrack(gSecondConnection.getRemoteStreams()[0]); | 611 verifyHasOneAudioAndVideoTrack(gSecondConnection.getRemoteStreams()[0]); |
619 verifyHasOneAudioAndVideoTrack(gSecondConnection.getRemoteStreams()[1]); | 612 verifyHasOneAudioAndVideoTrack(gSecondConnection.getRemoteStreams()[1]); |
620 | 613 |
621 document.title = "OK"; | 614 reportTestSuccess(); |
622 }); | 615 }); |
623 | 616 |
624 negotiate(); | 617 negotiate(); |
625 } | 618 } |
626 | 619 |
627 // Called if getUserMedia succeeds when we want to send a modified | 620 // Called if getUserMedia succeeds when we want to send a modified |
628 // MediaStream. A new MediaStream is created and the video track from | 621 // MediaStream. A new MediaStream is created and the video track from |
629 // |localStream| is added. | 622 // |localStream| is added. |
630 function createNewVideoStreamAndAddToBothConnections(localStream) { | 623 function createNewVideoStreamAndAddToBothConnections(localStream) { |
631 displayAndRemember(localStream); | 624 displayAndRemember(localStream); |
(...skipping 19 matching lines...) Expand all Loading... |
651 | 644 |
652 caller.createOffer( | 645 caller.createOffer( |
653 function (offer) { | 646 function (offer) { |
654 onOfferCreated(offer, caller, callee); | 647 onOfferCreated(offer, caller, callee); |
655 }); | 648 }); |
656 } | 649 } |
657 | 650 |
658 function onOfferCreated(offer, caller, callee) { | 651 function onOfferCreated(offer, caller, callee) { |
659 offer.sdp = maybeForceIsac16K(transformSdp(offer.sdp)); | 652 offer.sdp = maybeForceIsac16K(transformSdp(offer.sdp)); |
660 caller.setLocalDescription(offer, function() { | 653 caller.setLocalDescription(offer, function() { |
661 expectEquals('have-local-offer', caller.signalingState); | 654 assertEquals('have-local-offer', caller.signalingState); |
662 receiveOffer(offer.sdp, caller, callee); | 655 receiveOffer(offer.sdp, caller, callee); |
663 }, onLocalDescriptionError); | 656 }, onLocalDescriptionError); |
664 } | 657 } |
665 | 658 |
666 function receiveOffer(offerSdp, caller, callee) { | 659 function receiveOffer(offerSdp, caller, callee) { |
667 console.log("Receiving offer..."); | 660 console.log("Receiving offer..."); |
668 offerSdp = transformRemoteSdp(offerSdp); | 661 offerSdp = transformRemoteSdp(offerSdp); |
669 | 662 |
670 var parsedOffer = new RTCSessionDescription({ type: 'offer', | 663 var parsedOffer = new RTCSessionDescription({ type: 'offer', |
671 sdp: offerSdp }); | 664 sdp: offerSdp }); |
672 callee.setRemoteDescription(parsedOffer); | 665 callee.setRemoteDescription(parsedOffer); |
673 callee.createAnswer(function (answer) { | 666 callee.createAnswer(function (answer) { |
674 onAnswerCreated(answer, caller, callee); | 667 onAnswerCreated(answer, caller, callee); |
675 }); | 668 }); |
676 expectEquals('have-remote-offer', callee.signalingState); | 669 assertEquals('have-remote-offer', callee.signalingState); |
677 } | 670 } |
678 | 671 |
679 function removeMsid(offerSdp) { | 672 function removeMsid(offerSdp) { |
680 offerSdp = offerSdp.replace(/a=msid-semantic.*\r\n/g, ''); | 673 offerSdp = offerSdp.replace(/a=msid-semantic.*\r\n/g, ''); |
681 offerSdp = offerSdp.replace('a=mid:audio\r\n', ''); | 674 offerSdp = offerSdp.replace('a=mid:audio\r\n', ''); |
682 offerSdp = offerSdp.replace('a=mid:video\r\n', ''); | 675 offerSdp = offerSdp.replace('a=mid:video\r\n', ''); |
683 offerSdp = offerSdp.replace(/a=ssrc.*\r\n/g, ''); | 676 offerSdp = offerSdp.replace(/a=ssrc.*\r\n/g, ''); |
684 return offerSdp; | 677 return offerSdp; |
685 } | 678 } |
686 | 679 |
687 function removeVideoCodec(offerSdp) { | 680 function removeVideoCodec(offerSdp) { |
688 offerSdp = offerSdp.replace('a=rtpmap:100 VP8/90000\r\n', | 681 offerSdp = offerSdp.replace('a=rtpmap:100 VP8/90000\r\n', |
689 'a=rtpmap:100 XVP8/90000\r\n'); | 682 'a=rtpmap:100 XVP8/90000\r\n'); |
690 return offerSdp; | 683 return offerSdp; |
691 } | 684 } |
692 | 685 |
693 function removeCrypto(offerSdp) { | 686 function removeCrypto(offerSdp) { |
694 offerSdp = offerSdp.replace(/a=crypto.*\r\n/g, 'a=Xcrypto\r\n'); | 687 offerSdp = offerSdp.replace(/a=crypto.*\r\n/g, 'a=Xcrypto\r\n'); |
695 offerSdp = offerSdp.replace(/a=fingerprint.*\r\n/g, ''); | 688 offerSdp = offerSdp.replace(/a=fingerprint.*\r\n/g, ''); |
696 return offerSdp; | 689 return offerSdp; |
697 } | 690 } |
698 | 691 |
699 function addBandwithControl(offerSdp) { | 692 function addBandwithControl(offerSdp) { |
700 offerSdp = offerSdp.replace('a=mid:audio\r\n', 'a=mid:audio\r\n'+ | 693 offerSdp = offerSdp.replace('a=mid:audio\r\n', 'a=mid:audio\r\n'+ |
701 'b=AS:16\r\n'); | 694 'b=AS:16\r\n'); |
702 offerSdp = offerSdp.replace('a=mid:video\r\n', 'a=mid:video\r\n'+ | 695 offerSdp = offerSdp.replace('a=mid:video\r\n', 'a=mid:video\r\n'+ |
703 'b=AS:512\r\n'); | 696 'b=AS:512\r\n'); |
704 return offerSdp; | 697 return offerSdp; |
705 } | 698 } |
706 | 699 |
707 function removeBundle(sdp) { | 700 function removeBundle(sdp) { |
708 return sdp.replace(/a=group:BUNDLE .*\r\n/g, ''); | 701 return sdp.replace(/a=group:BUNDLE .*\r\n/g, ''); |
709 } | 702 } |
710 | 703 |
711 function useGice(sdp) { | 704 function useGice(sdp) { |
712 sdp = sdp.replace(/t=.*\r\n/g, function(subString) { | 705 sdp = sdp.replace(/t=.*\r\n/g, function(subString) { |
713 return subString + 'a=ice-options:google-ice\r\n'; | 706 return subString + 'a=ice-options:google-ice\r\n'; |
714 }); | 707 }); |
715 sdp = sdp.replace(/a=ice-ufrag:.*\r\n/g, | 708 sdp = sdp.replace(/a=ice-ufrag:.*\r\n/g, |
716 'a=ice-ufrag:' + EXTERNAL_GICE_UFRAG + '\r\n'); | 709 'a=ice-ufrag:' + EXTERNAL_GICE_UFRAG + '\r\n'); |
717 sdp = sdp.replace(/a=ice-pwd:.*\r\n/g, | 710 sdp = sdp.replace(/a=ice-pwd:.*\r\n/g, |
718 'a=ice-pwd:' + EXTERNAL_GICE_PWD + '\r\n'); | 711 'a=ice-pwd:' + EXTERNAL_GICE_PWD + '\r\n'); |
719 return sdp; | 712 return sdp; |
720 } | 713 } |
721 | 714 |
722 function useExternalSdes(sdp) { | 715 function useExternalSdes(sdp) { |
723 // Remove current crypto specification. | 716 // Remove current crypto specification. |
724 sdp = sdp.replace(/a=crypto.*\r\n/g, ''); | 717 sdp = sdp.replace(/a=crypto.*\r\n/g, ''); |
725 sdp = sdp.replace(/a=fingerprint.*\r\n/g, ''); | 718 sdp = sdp.replace(/a=fingerprint.*\r\n/g, ''); |
726 // Add external crypto. This is not compatible with |removeMsid|. | 719 // Add external crypto. This is not compatible with |removeMsid|. |
727 sdp = sdp.replace(/a=mid:(\w+)\r\n/g, function(subString, group) { | 720 sdp = sdp.replace(/a=mid:(\w+)\r\n/g, function(subString, group) { |
728 return subString + EXTERNAL_SDES_LINES[group] + '\r\n'; | 721 return subString + EXTERNAL_SDES_LINES[group] + '\r\n'; |
729 }); | 722 }); |
730 return sdp; | 723 return sdp; |
731 } | 724 } |
732 | 725 |
733 function onAnswerCreated(answer, caller, callee) { | 726 function onAnswerCreated(answer, caller, callee) { |
734 answer.sdp = maybeForceIsac16K(transformSdp(answer.sdp)); | 727 answer.sdp = maybeForceIsac16K(transformSdp(answer.sdp)); |
735 callee.setLocalDescription(answer); | 728 callee.setLocalDescription(answer); |
736 expectEquals('stable', callee.signalingState); | 729 assertEquals('stable', callee.signalingState); |
737 receiveAnswer(answer.sdp, caller); | 730 receiveAnswer(answer.sdp, caller); |
738 } | 731 } |
739 | 732 |
740 function receiveAnswer(answerSdp, caller) { | 733 function receiveAnswer(answerSdp, caller) { |
741 console.log("Receiving answer..."); | 734 console.log("Receiving answer..."); |
742 answerSdp = transformRemoteSdp(answerSdp); | 735 answerSdp = transformRemoteSdp(answerSdp); |
743 var parsedAnswer = new RTCSessionDescription({ type: 'answer', | 736 var parsedAnswer = new RTCSessionDescription({ type: 'answer', |
744 sdp: answerSdp }); | 737 sdp: answerSdp }); |
745 caller.setRemoteDescription(parsedAnswer); | 738 caller.setRemoteDescription(parsedAnswer); |
746 expectEquals('stable', caller.signalingState); | 739 assertEquals('stable', caller.signalingState); |
747 } | 740 } |
748 | 741 |
749 function connectOnIceCandidate(caller, callee) { | 742 function connectOnIceCandidate(caller, callee) { |
750 caller.onicecandidate = function(event) { onIceCandidate(event, callee); } | 743 caller.onicecandidate = function(event) { onIceCandidate(event, callee); } |
751 callee.onicecandidate = function(event) { onIceCandidate(event, caller); } | 744 callee.onicecandidate = function(event) { onIceCandidate(event, caller); } |
752 } | 745 } |
753 | 746 |
754 function addGiceCredsToCandidate(candidate) { | 747 function addGiceCredsToCandidate(candidate) { |
755 return candidate.trimRight() + | 748 return candidate.trimRight() + |
756 ' username ' + EXTERNAL_GICE_UFRAG + ' password ' + EXTERNAL_GICE_PWD; | 749 ' username ' + EXTERNAL_GICE_UFRAG + ' password ' + EXTERNAL_GICE_PWD; |
757 } | 750 } |
758 | 751 |
759 function onIceCandidate(event, target) { | 752 function onIceCandidate(event, target) { |
760 if (event.candidate) { | 753 if (event.candidate) { |
761 console.log("onIceCandidate, candidate is:" + event.candidate.candidate); | 754 console.log("onIceCandidate, candidate is:" + event.candidate.candidate); |
762 var candidate = new RTCIceCandidate(event.candidate); | 755 var candidate = new RTCIceCandidate(event.candidate); |
763 candidate.candidate = transformCandidate(candidate.candidate); | 756 candidate.candidate = transformCandidate(candidate.candidate); |
764 target.addIceCandidate(candidate); | 757 target.addIceCandidate(candidate); |
765 } | 758 } |
766 } | 759 } |
767 | 760 |
768 function onRemoteStream(e, target) { | 761 function onRemoteStream(e, target) { |
769 console.log("Receiving remote stream..."); | 762 console.log("Receiving remote stream..."); |
770 if (gTestWithoutMsid && e.stream.id != "default") { | 763 if (gTestWithoutMsid && e.stream.id != "default") { |
771 document.title = 'a default remote stream was expected but instead ' + | 764 failTest('a default remote stream was expected but instead ' + |
772 e.stream.id + ' was received.'; | 765 e.stream.id + ' was received.'); |
773 return; | |
774 } | 766 } |
775 gRemoteStreams[target] = e.stream; | 767 gRemoteStreams[target] = e.stream; |
776 var remoteStreamUrl = URL.createObjectURL(e.stream); | 768 var remoteStreamUrl = URL.createObjectURL(e.stream); |
777 var remoteVideo = $(target); | 769 var remoteVideo = $(target); |
778 remoteVideo.src = remoteStreamUrl; | 770 remoteVideo.src = remoteStreamUrl; |
779 } | 771 } |
780 | 772 |
781 </script> | 773 </script> |
782 </head> | 774 </head> |
783 <body> | 775 <body> |
(...skipping 22 matching lines...) Expand all Loading... |
806 <td><canvas width="320" height="240" id="remote-view-2-canvas" | 798 <td><canvas width="320" height="240" id="remote-view-2-canvas" |
807 style="display:none"></canvas></td> | 799 style="display:none"></canvas></td> |
808 <td><canvas width="320" height="240" id="remote-view-3-canvas" | 800 <td><canvas width="320" height="240" id="remote-view-3-canvas" |
809 style="display:none"></canvas></td> | 801 style="display:none"></canvas></td> |
810 <td><canvas width="320" height="240" id="remote-view-4-canvas" | 802 <td><canvas width="320" height="240" id="remote-view-4-canvas" |
811 style="display:none"></canvas></td> | 803 style="display:none"></canvas></td> |
812 </tr> | 804 </tr> |
813 </table> | 805 </table> |
814 </body> | 806 </body> |
815 </html> | 807 </html> |
OLD | NEW |