| Harald Alvestrand | 168935a | 2015-05-13 08:23:14 | [diff] [blame^] | 1 | <!doctype html> | 
|  | 2 | <!-- | 
|  | 3 | This test uses no media, and thus does not require fake media devices. | 
|  | 4 | --> | 
|  | 5 |  | 
|  | 6 | <html> | 
|  | 7 | <head> | 
|  | 8 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | 
|  | 9 | <title>RTCPeerConnection No-Media Connection Test</title> | 
|  | 10 | </head> | 
|  | 11 | <body> | 
|  | 12 | <div id="log"></div> | 
|  | 13 | <h2>iceConnectionState info</h2> | 
|  | 14 | <div id="stateinfo"> | 
|  | 15 | </div> | 
|  | 16 |  | 
|  | 17 | <!-- These files are in place when executing on W3C. --> | 
|  | 18 | <script src="/resources/testharness.js"></script> | 
|  | 19 | <script src="/resources/testharnessreport.js"></script> | 
|  | 20 | <script src="/common/vendor-prefix.js" | 
|  | 21 | data-prefixed-objects= | 
|  | 22 | '[{"ancestors":["window"], "name":"RTCPeerConnection"}, | 
|  | 23 | {"ancestors":["window"], "name":"RTCSessionDescription"}, | 
|  | 24 | {"ancestors":["window"], "name":"RTCIceCandidate"}]' | 
|  | 25 | > | 
|  | 26 | </script> | 
|  | 27 | <script type="text/javascript"> | 
|  | 28 | var test = async_test('Can set up a basic WebRTC call with no data using promises.'); | 
|  | 29 |  | 
|  | 30 | var gFirstConnection = null; | 
|  | 31 | var gSecondConnection = null; | 
|  | 32 |  | 
|  | 33 | var onOfferCreated = test.step_func(function(offer) { | 
|  | 34 | // TODO: Switch to promise-based interface. | 
|  | 35 | gFirstConnection.setLocalDescription(offer) | 
|  | 36 | .catch(failed('setLocalDescription first')); | 
|  | 37 |  | 
|  | 38 | // This would normally go across the application's signaling solution. | 
|  | 39 | // In our case, the "signaling" is to call this function. | 
|  | 40 | receiveCall(offer.sdp); | 
|  | 41 | }); | 
|  | 42 |  | 
|  | 43 | function receiveCall(offerSdp) { | 
|  | 44 |  | 
|  | 45 | var parsedOffer = new RTCSessionDescription({ type: 'offer', | 
|  | 46 | sdp: offerSdp }); | 
|  | 47 | gSecondConnection.setRemoteDescription(parsedOffer) | 
|  | 48 | .then(function() { | 
|  | 49 | gSecondConnection.createAnswer().then(onAnswerCreated, | 
|  | 50 | failed('createAnswer')); | 
|  | 51 | }, | 
|  | 52 | failed('setRemoteDescription second')); | 
|  | 53 | }; | 
|  | 54 |  | 
|  | 55 | var onAnswerCreated = test.step_func(function(answer) { | 
|  | 56 | gSecondConnection.setLocalDescription(answer) | 
|  | 57 | .catch(failed('setLocalDescription second')); | 
|  | 58 |  | 
|  | 59 | // Similarly, this would go over the application's signaling solution. | 
|  | 60 | handleAnswer(answer.sdp); | 
|  | 61 | }); | 
|  | 62 |  | 
|  | 63 | function handleAnswer(answerSdp) { | 
|  | 64 | var parsedAnswer = new RTCSessionDescription({ type: 'answer', | 
|  | 65 | sdp: answerSdp }); | 
|  | 66 | gFirstConnection.setRemoteDescription(parsedAnswer) | 
|  | 67 | .catch(failed('setRemoteDescription first')); | 
|  | 68 | }; | 
|  | 69 |  | 
|  | 70 | var onIceCandidateToFirst = test.step_func(function(event) { | 
|  | 71 | // If event.candidate is null = no more candidates. | 
|  | 72 | if (event.candidate) { | 
|  | 73 | var candidate = new RTCIceCandidate(event.candidate); | 
|  | 74 | gSecondConnection.addIceCandidate(candidate); | 
|  | 75 | } | 
|  | 76 | }); | 
|  | 77 |  | 
|  | 78 | var onIceCandidateToSecond = test.step_func(function(event) { | 
|  | 79 | if (event.candidate) { | 
|  | 80 | var candidate = new RTCIceCandidate(event.candidate); | 
|  | 81 | gFirstConnection.addIceCandidate(candidate); | 
|  | 82 | } | 
|  | 83 | }); | 
|  | 84 |  | 
|  | 85 | var onRemoteStream = test.step_func(function(event) { | 
|  | 86 | assert_unreached('WebRTC received a stream when there was none'); | 
|  | 87 | }); | 
|  | 88 |  | 
|  | 89 | var onIceConnectionStateChange = test.step_func(function(event) { | 
|  | 90 | assert_equals(event.type, 'iceconnectionstatechange'); | 
|  | 91 | var stateinfo = document.getElementById('stateinfo'); | 
|  | 92 | stateinfo.innerHTML = 'First: ' + gFirstConnection.iceConnectionState | 
|  | 93 | + '<br>Second: ' + gSecondConnection.iceConnectionState; | 
|  | 94 | // Note: All these combinations are legal states indicating that the | 
|  | 95 | // call has connected. All browsers should end up in completed/completed, | 
|  | 96 | // but as of this moment, we've chosen to terminate the test early. | 
|  | 97 | // TODO: Revise test to ensure completed/completed is reached. | 
|  | 98 | if (gFirstConnection.iceConnectionState == 'connected' && | 
|  | 99 | gSecondConnection.iceConnectionState == 'connected') { | 
|  | 100 | test.done() | 
|  | 101 | } | 
|  | 102 | if (gFirstConnection.iceConnectionState == 'connected' && | 
|  | 103 | gSecondConnection.iceConnectionState == 'completed') { | 
|  | 104 | test.done() | 
|  | 105 | } | 
|  | 106 | if (gFirstConnection.iceConnectionState == 'completed' && | 
|  | 107 | gSecondConnection.iceConnectionState == 'connected') { | 
|  | 108 | test.done() | 
|  | 109 | } | 
|  | 110 | if (gFirstConnection.iceConnectionState == 'completed' && | 
|  | 111 | gSecondConnection.iceConnectionState == 'completed') { | 
|  | 112 | test.done() | 
|  | 113 | } | 
|  | 114 | }); | 
|  | 115 |  | 
|  | 116 | // Returns a suitable error callback. | 
|  | 117 | function failed(function_name) { | 
|  | 118 | return test.step_func(function() { | 
|  | 119 | assert_unreached('WebRTC called error callback for ' + function_name); | 
|  | 120 | }); | 
|  | 121 | } | 
|  | 122 |  | 
|  | 123 | // Returns a suitable do-nothing. | 
|  | 124 | function ignoreSuccess(function_name) { | 
|  | 125 | } | 
|  | 126 |  | 
|  | 127 | // This function starts the test. | 
|  | 128 | test.step(function() { | 
|  | 129 | gFirstConnection = new RTCPeerConnection(null); | 
|  | 130 | gFirstConnection.onicecandidate = onIceCandidateToFirst; | 
|  | 131 | gFirstConnection.oniceconnectionstatechange = onIceConnectionStateChange; | 
|  | 132 |  | 
|  | 133 | gSecondConnection = new RTCPeerConnection(null); | 
|  | 134 | gSecondConnection.onicecandidate = onIceCandidateToSecond; | 
|  | 135 | gSecondConnection.onaddstream = onRemoteStream; | 
|  | 136 | gSecondConnection.oniceconnectionstatechange = onIceConnectionStateChange; | 
|  | 137 |  | 
|  | 138 | // The offerToReceiveVideo is necessary and sufficient to make | 
|  | 139 | // an actual connection. | 
|  | 140 | // TODO: Use a promise-based API. This is legacy. | 
|  | 141 | gFirstConnection.createOffer({offerToReceiveVideo: true}) | 
|  | 142 | .then(onOfferCreated, failed('createOffer')); | 
|  | 143 |  | 
|  | 144 | }); | 
|  | 145 | </script> | 
|  | 146 |  | 
|  | 147 | </body> | 
|  | 148 | </html> |