| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 1 | <!doctype html> |
| 2 | <meta charset=utf-8> |
| 3 | <title>RTCPeerConnection.prototype.connectionState</title> |
| 4 | <script src="/resources/testharness.js"></script> |
| 5 | <script src="/resources/testharnessreport.js"></script> |
| 6 | <script src="RTCPeerConnection-helper.js"></script> |
| 7 | <script> |
| 8 | 'use strict'; |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 9 | // Test is based on the following editor draft: |
| 10 | // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.htm |
| 11 | |
| 12 | // The following helper functions are called from RTCPeerConnection-helper.js: |
| 13 | // exchangeIceCandidates |
| 14 | // doSignalingHandshake |
| 15 | |
| 16 | /* |
| 17 | 4.3.2. Interface Definition |
| 18 | interface RTCPeerConnection : EventTarget { |
| 19 | ... |
| 20 | readonly attribute RTCPeerConnectionState connectionState; |
| 21 | attribute EventHandler onconnectionstatechange; |
| 22 | }; |
| 23 | |
| 24 | 4.4.3. RTCPeerConnectionState Enum |
| 25 | enum RTCPeerConnectionState { |
| 26 | "new", |
| 27 | "connecting", |
| 28 | "connected", |
| 29 | "disconnected", |
| 30 | "failed", |
| 31 | "closed" |
| 32 | }; |
| 33 | |
| 34 | 5.5. RTCDtlsTransport Interface |
| 35 | interface RTCDtlsTransport { |
| Philipp Hancke | c05700b | 2018-11-06 11:23:28 | [diff] [blame] | 36 | readonly attribute RTCIceTransport iceTransport; |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 37 | readonly attribute RTCDtlsTransportState state; |
| 38 | ... |
| 39 | }; |
| 40 | |
| 41 | enum RTCDtlsTransportState { |
| 42 | "new", |
| 43 | "connecting", |
| 44 | "connected", |
| 45 | "closed", |
| 46 | "failed" |
| 47 | }; |
| 48 | |
| 49 | 5.6. RTCIceTransport Interface |
| 50 | interface RTCIceTransport { |
| 51 | readonly attribute RTCIceTransportState state; |
| 52 | ... |
| 53 | }; |
| 54 | |
| 55 | enum RTCIceTransportState { |
| 56 | "new", |
| 57 | "checking", |
| 58 | "connected", |
| 59 | "completed", |
| 60 | "failed", |
| 61 | "disconnected", |
| 62 | "closed" |
| 63 | }; |
| 64 | */ |
| 65 | |
| 66 | /* |
| 67 | 4.4.3. RTCPeerConnectionState Enum |
| 68 | new |
| 69 | Any of the RTCIceTransports or RTCDtlsTransports are in the new |
| 70 | state and none of the transports are in the connecting, checking, |
| 71 | failed or disconnected state, or all transports are in the closed state. |
| 72 | */ |
| 73 | test(t => { |
| 74 | const pc = new RTCPeerConnection(); |
| 75 | assert_equals(pc.connectionState, 'new'); |
| 76 | }, 'Initial connectionState should be new'); |
| 77 | |
| Jonas Olsson | a8fb179 | 2018-11-23 14:51:08 | [diff] [blame] | 78 | test(t => { |
| 79 | const pc = new RTCPeerConnection(); |
| 80 | pc.close(); |
| 81 | assert_equals(pc.connectionState, 'closed'); |
| 82 | }, 'Closing the connection should set connectionState to closed'); |
| 83 | |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 84 | /* |
| 85 | 4.4.3. RTCPeerConnectionState Enum |
| 86 | connected |
| 87 | All RTCIceTransports and RTCDtlsTransports are in the connected, |
| 88 | completed or closed state and at least of them is in the connected |
| 89 | or completed state. |
| 90 | |
| 91 | 5.5. RTCDtlsTransportState |
| 92 | connected |
| 93 | DTLS has completed negotiation of a secure connection. |
| 94 | |
| 95 | 5.6. RTCIceTransportState |
| 96 | connected |
| 97 | The RTCIceTransport has found a usable connection, but is still |
| 98 | checking other candidate pairs to see if there is a better connection. |
| 99 | It may also still be gathering and/or waiting for additional remote |
| 100 | candidates. If consent checks [RFC7675] fail on the connection in use, |
| 101 | and there are no other successful candidate pairs available, then the |
| 102 | state transitions to "checking" (if there are candidate pairs remaining |
| 103 | to be checked) or "disconnected" (if there are no candidate pairs to |
| 104 | check, but the peer is still gathering and/or waiting for additional |
| 105 | remote candidates). |
| 106 | |
| 107 | completed |
| 108 | The RTCIceTransport has finished gathering, received an indication that |
| 109 | there are no more remote candidates, finished checking all candidate |
| 110 | pairs and found a connection. If consent checks [RFC7675] subsequently |
| 111 | fail on all successful candidate pairs, the state transitions to "failed". |
| 112 | */ |
| Jonas Olsson | a8fb179 | 2018-11-23 14:51:08 | [diff] [blame] | 113 | |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 114 | async_test(t => { |
| 115 | const pc1 = new RTCPeerConnection(); |
| Philipp Hancke | 1622a02 | 2018-06-11 10:00:53 | [diff] [blame] | 116 | t.add_cleanup(() => pc1.close()); |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 117 | const pc2 = new RTCPeerConnection(); |
| Jonas Olsson | a8fb179 | 2018-11-23 14:51:08 | [diff] [blame] | 118 | t.add_cleanup(() => pc2.close()); |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 119 | |
| Jonas Olsson | a8fb179 | 2018-11-23 14:51:08 | [diff] [blame] | 120 | let had_connecting = false; |
| 121 | |
| 122 | const onConnectionStateChange = t.step_func(() => { |
| 123 | const {connectionState} = pc1; |
| 124 | if (connectionState === 'connecting') { |
| 125 | had_connecting = true; |
| 126 | } else if (connectionState === 'connected') { |
| 127 | assert_true(had_connecting, "state should pass connecting before reaching connected"); |
| 128 | t.done(); |
| 129 | } |
| 130 | }); |
| 131 | |
| 132 | pc1.createDataChannel('test'); |
| 133 | |
| 134 | pc1.addEventListener('connectionstatechange', onConnectionStateChange); |
| 135 | |
| 136 | exchangeIceCandidates(pc1, pc2); |
| 137 | doSignalingHandshake(pc1, pc2); |
| 138 | }, 'connection with one data channel should eventually have connected connection state'); |
| 139 | |
| 140 | async_test(t => { |
| 141 | const pc1 = new RTCPeerConnection(); |
| 142 | t.add_cleanup(() => pc1.close()); |
| 143 | const pc2 = new RTCPeerConnection(); |
| Philipp Hancke | 1622a02 | 2018-06-11 10:00:53 | [diff] [blame] | 144 | t.add_cleanup(() => pc2.close()); |
| 145 | |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 146 | const onConnectionStateChange = t.step_func(() => { |
| Jonas Olsson | a8fb179 | 2018-11-23 14:51:08 | [diff] [blame] | 147 | const {connectionState} = pc1; |
| 148 | if (connectionState === 'connected') { |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 149 | const sctpTransport = pc1.sctp; |
| 150 | |
| 151 | const dtlsTransport = sctpTransport.transport; |
| 152 | assert_equals(dtlsTransport.state, 'connected', |
| 153 | 'Expect DTLS transport to be in connected state'); |
| 154 | |
| Philipp Hancke | c05700b | 2018-11-06 11:23:28 | [diff] [blame] | 155 | const iceTransport = dtlsTransport.iceTransport |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 156 | assert_true(iceTransport.state === 'connected' || |
| 157 | iceTransport.state === 'completed', |
| 158 | 'Expect ICE transport to be in connected or completed state'); |
| 159 | |
| 160 | t.done(); |
| 161 | } |
| 162 | }); |
| 163 | |
| 164 | pc1.createDataChannel('test'); |
| 165 | |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 166 | pc1.addEventListener('connectionstatechange', onConnectionStateChange); |
| 167 | |
| 168 | exchangeIceCandidates(pc1, pc2); |
| 169 | doSignalingHandshake(pc1, pc2); |
| Jonas Olsson | a8fb179 | 2018-11-23 14:51:08 | [diff] [blame] | 170 | }, 'connection with one data channel should eventually have transports in connected state'); |
| Soares Chen | 300db38 | 2017-06-19 20:46:42 | [diff] [blame] | 171 | |
| 172 | /* |
| 173 | TODO |
| 174 | 4.4.3. RTCPeerConnectionState Enum |
| 175 | connecting |
| 176 | Any of the RTCIceTransports or RTCDtlsTransports are in the |
| 177 | connecting or checking state and none of them is in the failed state. |
| 178 | |
| 179 | disconnected |
| 180 | Any of the RTCIceTransports or RTCDtlsTransports are in the disconnected |
| 181 | state and none of them are in the failed or connecting or checking state. |
| 182 | |
| 183 | failed |
| 184 | Any of the RTCIceTransports or RTCDtlsTransports are in a failed state. |
| 185 | |
| 186 | closed |
| 187 | The RTCPeerConnection object's [[isClosed]] slot is true. |
| 188 | |
| 189 | 5.5. RTCDtlsTransportState |
| 190 | new |
| 191 | DTLS has not started negotiating yet. |
| 192 | |
| 193 | connecting |
| 194 | DTLS is in the process of negotiating a secure connection. |
| 195 | |
| 196 | closed |
| 197 | The transport has been closed. |
| 198 | |
| 199 | failed |
| 200 | The transport has failed as the result of an error (such as a failure |
| 201 | to validate the remote fingerprint). |
| 202 | |
| 203 | 5.6. RTCIceTransportState |
| 204 | new |
| 205 | The RTCIceTransport is gathering candidates and/or waiting for |
| 206 | remote candidates to be supplied, and has not yet started checking. |
| 207 | |
| 208 | checking |
| 209 | The RTCIceTransport has received at least one remote candidate and |
| 210 | is checking candidate pairs and has either not yet found a connection |
| 211 | or consent checks [RFC7675] have failed on all previously successful |
| 212 | candidate pairs. In addition to checking, it may also still be gathering. |
| 213 | |
| 214 | failed |
| 215 | The RTCIceTransport has finished gathering, received an indication that |
| 216 | there are no more remote candidates, finished checking all candidate pairs, |
| 217 | and all pairs have either failed connectivity checks or have lost consent. |
| 218 | |
| 219 | disconnected |
| 220 | The ICE Agent has determined that connectivity is currently lost for this |
| 221 | RTCIceTransport . This is more aggressive than failed, and may trigger |
| 222 | intermittently (and resolve itself without action) on a flaky network. |
| 223 | The way this state is determined is implementation dependent. |
| 224 | |
| 225 | Examples include: |
| 226 | Losing the network interface for the connection in use. |
| 227 | Repeatedly failing to receive a response to STUN requests. |
| 228 | |
| 229 | Alternatively, the RTCIceTransport has finished checking all existing |
| 230 | candidates pairs and failed to find a connection (or consent checks |
| 231 | [RFC7675] once successful, have now failed), but it is still gathering |
| 232 | and/or waiting for additional remote candidates. |
| 233 | |
| 234 | closed |
| 235 | The RTCIceTransport has shut down and is no longer responding to STUN requests. |
| 236 | */ |
| 237 | </script> |