1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>RTCPeerConnection No-Media Connection Test</title>
</head>
<body>
<div id="log"></div>
<h2>iceConnectionState info</h2>
<div id="stateinfo">
</div>
<!-- These files are in place when executing on W3C. -->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="RTCPeerConnection-helper.js"></script>
<script type="text/javascript">
let gFirstConnection = null;
let gSecondConnection = null;
function onIceCandidate(otherConnction, event, reject) {
try {
otherConnction.addIceCandidate(event.candidate);
} catch(e) {
reject(e);
}
};
function onIceConnectionStateChange(done, failed) {
try {
assert_equals(event.type, 'iceconnectionstatechange');
assert_not_equals(gFirstConnection.iceConnectionState, "failed",
"iceConnectionState of first connection");
assert_not_equals(gSecondConnection.iceConnectionState, "failed",
"iceConnectionState of second connection");
const stateinfo = document.getElementById('stateinfo');
stateinfo.innerHTML = 'First: ' + gFirstConnection.iceConnectionState
+ '<br>Second: ' + gSecondConnection.iceConnectionState;
// Note: All these combinations are legal states indicating that the
// call has connected. All browsers should end up in completed/completed,
// but as of this moment, we've chosen to terminate the test early.
// TODO: Revise test to ensure completed/completed is reached.
const allowedStates = [ 'connected', 'completed'];
if (allowedStates.includes(gFirstConnection.iceConnectionState) &&
allowedStates.includes(gSecondConnection.iceConnectionState)) {
done();
}
} catch(e) {
failed(e);
}
};
// This function starts the test.
promise_test((test) => {
return new Promise(async (resolve, reject) => {
gFirstConnection = new RTCPeerConnection(null);
test.add_cleanup(() => gFirstConnection.close());
gFirstConnection.onicecandidate =
(event) => onIceCandidate(gSecondConnection, event, reject);
gFirstConnection.oniceconnectionstatechange =
() => onIceConnectionStateChange(resolve, reject);
gSecondConnection = new RTCPeerConnection(null);
test.add_cleanup(() => gSecondConnection.close());
gSecondConnection.onicecandidate =
(event) => onIceCandidate(gFirstConnection, event, reject);
gSecondConnection.oniceconnectionstatechange =
() => onIceConnectionStateChange(resolve, reject);
const offer = await generateVideoReceiveOnlyOffer(gFirstConnection);
await gFirstConnection.setLocalDescription(offer);
// This would normally go across the application's signaling solution.
// In our case, the "signaling" is to call this function.
await gSecondConnection.setRemoteDescription({ type: 'offer',
sdp: offer.sdp });
const answer = await gSecondConnection.createAnswer();
await gSecondConnection.setLocalDescription(answer);
assert_equals(gSecondConnection.getSenders().length, 1);
assert_not_equals(gSecondConnection.getSenders()[0], null);
assert_not_equals(gSecondConnection.getSenders()[0].transport, null);
// Similarly, this would go over the application's signaling solution.
await gFirstConnection.setRemoteDescription({ type: 'answer',
sdp: answer.sdp });
// The test is terminated by onIceConnectionStateChange() calling resolve
// once both connections are connected.
})
});
</script>
</body>
</html>
|