| Harald Alvestrand | 168935a | 2015-05-13 08:23:14 | [diff] [blame] | 1 | <!doctype html> | 
|  | 2 | <!-- | 
| Harald Alvestrand | 698efbc | 2015-05-18 08:53:05 | [diff] [blame] | 3 | This test uses data only, and thus does not require fake media devices. | 
| Harald Alvestrand | 168935a | 2015-05-13 08:23:14 | [diff] [blame] | 4 | --> | 
|  | 5 |  | 
|  | 6 | <html> | 
|  | 7 | <head> | 
|  | 8 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | 
| Harald Alvestrand | 698efbc | 2015-05-18 08:53:05 | [diff] [blame] | 9 | <title>RTCPeerConnection Data-Only Connection Test with Promises</title> | 
| Harald Alvestrand | 168935a | 2015-05-13 08:23:14 | [diff] [blame] | 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 |  | 
| Harald Alvestrand | 168935a | 2015-05-13 08:23:14 | [diff] [blame] | 33 | var onIceCandidateToFirst = test.step_func(function(event) { | 
|  | 34 | // If event.candidate is null = no more candidates. | 
|  | 35 | if (event.candidate) { | 
|  | 36 | var candidate = new RTCIceCandidate(event.candidate); | 
|  | 37 | gSecondConnection.addIceCandidate(candidate); | 
|  | 38 | } | 
|  | 39 | }); | 
|  | 40 |  | 
|  | 41 | var onIceCandidateToSecond = test.step_func(function(event) { | 
|  | 42 | if (event.candidate) { | 
|  | 43 | var candidate = new RTCIceCandidate(event.candidate); | 
|  | 44 | gFirstConnection.addIceCandidate(candidate); | 
|  | 45 | } | 
|  | 46 | }); | 
|  | 47 |  | 
|  | 48 | var onRemoteStream = test.step_func(function(event) { | 
|  | 49 | assert_unreached('WebRTC received a stream when there was none'); | 
|  | 50 | }); | 
|  | 51 |  | 
|  | 52 | var onIceConnectionStateChange = test.step_func(function(event) { | 
|  | 53 | assert_equals(event.type, 'iceconnectionstatechange'); | 
|  | 54 | var stateinfo = document.getElementById('stateinfo'); | 
|  | 55 | stateinfo.innerHTML = 'First: ' + gFirstConnection.iceConnectionState | 
|  | 56 | + '<br>Second: ' + gSecondConnection.iceConnectionState; | 
|  | 57 | // Note: All these combinations are legal states indicating that the | 
|  | 58 | // call has connected. All browsers should end up in completed/completed, | 
|  | 59 | // but as of this moment, we've chosen to terminate the test early. | 
|  | 60 | // TODO: Revise test to ensure completed/completed is reached. | 
|  | 61 | if (gFirstConnection.iceConnectionState == 'connected' && | 
|  | 62 | gSecondConnection.iceConnectionState == 'connected') { | 
|  | 63 | test.done() | 
|  | 64 | } | 
|  | 65 | if (gFirstConnection.iceConnectionState == 'connected' && | 
|  | 66 | gSecondConnection.iceConnectionState == 'completed') { | 
|  | 67 | test.done() | 
|  | 68 | } | 
|  | 69 | if (gFirstConnection.iceConnectionState == 'completed' && | 
|  | 70 | gSecondConnection.iceConnectionState == 'connected') { | 
|  | 71 | test.done() | 
|  | 72 | } | 
|  | 73 | if (gFirstConnection.iceConnectionState == 'completed' && | 
|  | 74 | gSecondConnection.iceConnectionState == 'completed') { | 
|  | 75 | test.done() | 
|  | 76 | } | 
|  | 77 | }); | 
|  | 78 |  | 
| Harald Alvestrand | 168935a | 2015-05-13 08:23:14 | [diff] [blame] | 79 | // This function starts the test. | 
|  | 80 | test.step(function() { | 
|  | 81 | gFirstConnection = new RTCPeerConnection(null); | 
|  | 82 | gFirstConnection.onicecandidate = onIceCandidateToFirst; | 
|  | 83 | gFirstConnection.oniceconnectionstatechange = onIceConnectionStateChange; | 
|  | 84 |  | 
|  | 85 | gSecondConnection = new RTCPeerConnection(null); | 
|  | 86 | gSecondConnection.onicecandidate = onIceCandidateToSecond; | 
|  | 87 | gSecondConnection.onaddstream = onRemoteStream; | 
|  | 88 | gSecondConnection.oniceconnectionstatechange = onIceConnectionStateChange; | 
|  | 89 |  | 
| Harald Alvestrand | 698efbc | 2015-05-18 08:53:05 | [diff] [blame] | 90 | // The createDataChannel is necessary and sufficient to make | 
|  | 91 | // sure the ICE connection be attempted. | 
|  | 92 | gFirstConnection.createDataChannel('channel'); | 
| Harald Alvestrand | 4ec420d | 2015-05-18 14:31:52 | [diff] [blame^] | 93 |  | 
| Harald Alvestrand | 698efbc | 2015-05-18 08:53:05 | [diff] [blame] | 94 | var atStep = 'createOffer first'; | 
|  | 95 | var offerSdp = null; | 
|  | 96 | var answerSdp = null; | 
|  | 97 |  | 
|  | 98 | gFirstConnection.createOffer() | 
|  | 99 | .then(function(offer) { | 
|  | 100 | offerSdp = offer.sdp; | 
|  | 101 | atStep = 'setLocalDescription first'; | 
|  | 102 | return gFirstConnection.setLocalDescription(offer); | 
|  | 103 | }) | 
|  | 104 | .then(function() { | 
|  | 105 | atStep = 'setRemoteDescription at second'; | 
|  | 106 | var parsedOffer = new RTCSessionDescription({ type: 'offer', | 
|  | 107 | sdp: offerSdp }); | 
|  | 108 | return gSecondConnection.setRemoteDescription(parsedOffer) | 
|  | 109 | }) | 
|  | 110 | .then(function() { | 
|  | 111 | atStep = 'createAnswer'; | 
|  | 112 | return gSecondConnection.createAnswer() | 
|  | 113 | }) | 
|  | 114 | .then(function(answer) { | 
|  | 115 | atStep = 'setLocalDescription second'; | 
|  | 116 | answerSdp = answer.sdp | 
|  | 117 | return gSecondConnection.setLocalDescription(answer); | 
|  | 118 | }) | 
|  | 119 | .then(function() { | 
|  | 120 | var parsedAnswer = new RTCSessionDescription({ type: 'answer', | 
|  | 121 | sdp: answerSdp }); | 
|  | 122 | atStep = 'setRemoteDescription first'; | 
|  | 123 | return gFirstConnection.setRemoteDescription(parsedAnswer); | 
|  | 124 | }) | 
|  | 125 | .then(function() { | 
|  | 126 | atStep = 'negotiation completed'; | 
|  | 127 | }) | 
|  | 128 | .catch(test.step_func(function(e) { | 
| Harald Alvestrand | 4ec420d | 2015-05-18 14:31:52 | [diff] [blame^] | 129 | assert_unreached('Error ' + e.name + ':' + e.message + | 
| Harald Alvestrand | 698efbc | 2015-05-18 08:53:05 | [diff] [blame] | 130 | ' happened at step ' + atStep); | 
|  | 131 | })); | 
| Harald Alvestrand | 168935a | 2015-05-13 08:23:14 | [diff] [blame] | 132 | }); | 
|  | 133 | </script> | 
|  | 134 |  | 
|  | 135 | </body> | 
|  | 136 | </html> |