|  | <!doctype html> | 
|  | <!-- | 
|  | To quickly iterate when developing this test, use --use-fake-ui-for-media-stream | 
|  | for Chrome and set the media.navigator.permission.disabled property to true in | 
|  | Firefox. You must either have a webcam/mic available on the system or use for | 
|  | instance --use-fake-device-for-media-stream for Chrome. | 
|  | --> | 
|  |  | 
|  | <html> | 
|  | <head> | 
|  | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | 
|  | <title>RTCPeerConnection Connection Test</title> | 
|  | </head> | 
|  | <body> | 
|  | <div id="log"></div> | 
|  | <div> | 
|  | <video id="local-view" autoplay="autoplay"></video> | 
|  | <video id="remote-view" autoplay="autoplay"/> | 
|  | </video> | 
|  | </div> | 
|  |  | 
|  | <!-- These files are in place when executing on W3C. --> | 
|  | <script src="/resources/testharness.js"></script> | 
|  | <script src="/resources/testharnessreport.js"></script> | 
|  | <script src="/common/vendor-prefix.js" | 
|  | data-prefixed-objects= | 
|  | '[{"ancestors":["navigator"], "name":"getUserMedia"}]' | 
|  | data-prefixed-prototypes= | 
|  | '[{"ancestors":["HTMLMediaElement"],"name":"srcObject"}]'> | 
|  | </script> | 
|  | <script type="text/javascript"> | 
|  | var test = async_test('Can set up a basic WebRTC call.', {timeout: 5000}); | 
|  |  | 
|  | var gFirstConnection = null; | 
|  | var gSecondConnection = null; | 
|  |  | 
|  | function getUserMediaOkCallback(localStream) { | 
|  | gFirstConnection = new RTCPeerConnection(null); | 
|  | gFirstConnection.onicecandidate = onIceCandidateToFirst; | 
|  | gFirstConnection.addStream(localStream); | 
|  | gFirstConnection.createOffer(onOfferCreated, failed('createOffer')); | 
|  |  | 
|  | var videoTag = document.getElementById('local-view'); | 
|  | videoTag.srcObject = localStream; | 
|  | }; | 
|  |  | 
|  | var onOfferCreated = test.step_func(function(offer) { | 
|  | gFirstConnection.setLocalDescription(offer); | 
|  |  | 
|  | // This would normally go across the application's signaling solution. | 
|  | // In our case, the "signaling" is to call this function. | 
|  | receiveCall(offer.sdp); | 
|  | }); | 
|  |  | 
|  | function receiveCall(offerSdp) { | 
|  | gSecondConnection = new RTCPeerConnection(null); | 
|  | gSecondConnection.onicecandidate = onIceCandidateToSecond; | 
|  | gSecondConnection.onaddstream = onRemoteStream; | 
|  |  | 
|  | var parsedOffer = new RTCSessionDescription({ type: 'offer', | 
|  | sdp: offerSdp }); | 
|  | gSecondConnection.setRemoteDescription(parsedOffer); | 
|  |  | 
|  | gSecondConnection.createAnswer(onAnswerCreated, | 
|  | failed('createAnswer')); | 
|  | }; | 
|  |  | 
|  | var onAnswerCreated = test.step_func(function(answer) { | 
|  | gSecondConnection.setLocalDescription(answer); | 
|  |  | 
|  | // Similarly, this would go over the application's signaling solution. | 
|  | handleAnswer(answer.sdp); | 
|  | }); | 
|  |  | 
|  | function handleAnswer(answerSdp) { | 
|  | var parsedAnswer = new RTCSessionDescription({ type: 'answer', | 
|  | sdp: answerSdp }); | 
|  | gFirstConnection.setRemoteDescription(parsedAnswer); | 
|  |  | 
|  | // Call negotiated: done. | 
|  | test.done(); | 
|  | }; | 
|  |  | 
|  | var onIceCandidateToFirst = test.step_func(function(event) { | 
|  | // If event.candidate is null = no more candidates. | 
|  | if (event.candidate) { | 
|  | gSecondConnection.addIceCandidate(event.candidate); | 
|  | } | 
|  | }); | 
|  |  | 
|  | var onIceCandidateToSecond = test.step_func(function(event) { | 
|  | if (event.candidate) { | 
|  | gFirstConnection.addIceCandidate(event.candidate); | 
|  | } | 
|  | }); | 
|  |  | 
|  | var onRemoteStream = test.step_func(function(event) { | 
|  | var videoTag = document.getElementById('remote-view'); | 
|  | videoTag.srcObject = event.stream; | 
|  | }); | 
|  |  | 
|  | // Returns a suitable error callback. | 
|  | function failed(function_name) { | 
|  | return test.step_func(function() { | 
|  | assert_unreached('WebRTC called error callback for ' + function_name); | 
|  | }); | 
|  | } | 
|  |  | 
|  | // This function starts the test. | 
|  | test.step(function() { | 
|  | navigator.getUserMedia({ video: true, audio: true }, | 
|  | getUserMediaOkCallback, | 
|  | failed('getUserMedia')); | 
|  | }); | 
|  | </script> | 
|  |  | 
|  | </body> | 
|  | </html> |