4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 <title>RTCPeerConnection Connection Test</title>
12 <video width="320" height="240" id="remote-view" autoplay="autoplay"></video>
13 <video width="320" height="240" id="local-view" autoplay="autoplay"></video>
16 <script src="../../../resources/testharness.js"></script>
17 <script src="../../../resources/testharnessreport.js"></script>
18 <script src="/common/vendor-prefix.js"
19 data-prefixed-objects= '[{"ancestors":["navigator"], "name":"getUserMedia"},
20 {"ancestors":["window"], "name":"RTCPeerConnection"}]'
21 data-prefixed-prototypes='[{"ancestors":["HTMLMediaElement"],"name":"srcObject"}]'></script>
22 <script type="text/javascript">
23 var test = async_test('Can set up a basic WebRTC call.', {timeout: 5000});
24 var gFirstConnection = null;
25 var gSecondConnection = null;
27 function getUserMediaOkCallback(localStream) {
28 gFirstConnection = new RTCPeerConnection();
29 gFirstConnection.onicecandidate = onIceCandidateToFirst;
30 gFirstConnection.addStream(localStream);
31 gFirstConnection.createOffer(onOfferCreated);
33 var videoTag = document.getElementById('local-view');
34 videoTag.srcObject = localStream;
37 var onOfferCreated = test.step_func(function(offer) {
38 gFirstConnection.setLocalDescription(offer);
40 // This would normally go across the application's signaling solution.
41 // In our case, the "signaling" is to call this function.
42 receiveCall(offer.sdp);
45 function receiveCall(offerSdp) {
46 gSecondConnection = new RTCPeerConnection();
47 gSecondConnection.onicecandidate = onIceCandidateToSecond;
48 gSecondConnection.onaddstream = onRemoteStream;
50 var parsedOffer = new RTCSessionDescription({ type: 'offer',
52 gSecondConnection.setRemoteDescription(parsedOffer);
54 gSecondConnection.createAnswer(onAnswerCreated,
55 failed('createAnswer'));
58 var onAnswerCreated = test.step_func(function(answer) {
59 gSecondConnection.setLocalDescription(answer);
61 // Similarly, this would go over the application's signaling solution.
62 handleAnswer(answer.sdp);
65 function handleAnswer(answerSdp) {
66 var parsedAnswer = new RTCSessionDescription({ type: 'answer',
68 gFirstConnection.setRemoteDescription(parsedAnswer);
70 // Call negotiated: done.
74 // Note: the ice candidate handlers are special. We can not wrap them in test
75 // steps since that seems to cause some kind of starvation that prevents the
76 // call of being set up. Unfortunately we cannot report errors in here.
77 var onIceCandidateToFirst = function(event) {
78 // If event.candidate is null = no more candidates.
79 if (event.candidate) {
80 var candidate = new RTCIceCandidate(event.candidate);
81 gSecondConnection.addIceCandidate(candidate);
85 var onIceCandidateToSecond = function(event) {
86 if (event.candidate) {
87 var candidate = new RTCIceCandidate(event.candidate);
88 gFirstConnection.addIceCandidate(candidate);
92 var onRemoteStream = test.step_func(function(event) {
93 var videoTag = document.getElementById('remote-view');
94 videoTag.srcObject = event.stream;
97 // Returns a suitable error callback.
98 function failed(function_name) {
99 return test.step_func(function() {
100 assert_unreached('WebRTC called error callback for ' + function_name);
104 // This function starts the test.
105 test.step(function() {
106 navigator.getUserMedia({ video: true, audio: true },
107 getUserMediaOkCallback,
108 failed('getUserMedia'));