Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / test / data / webrtc / jsep01_call.js
blob2f297d80818211ec17d67dd9d479984ad1714487
1 /**
2 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
7 /** @private */
8 var gTransformOutgoingSdp = function(sdp) { return sdp; };
10 /** @private */
11 var gCreateAnswerConstraints = {};
13 /** @private */
14 var gCreateOfferConstraints = {};
16 /** @private */
17 var gDataChannel = null;
19 /** @private */
20 var gDataStatusCallback = function(status) {};
22 /** @private */
23 var gDataCallback = function(data) {};
25 /** @private */
26 var gDtmfSender = null;
28 /** @private */
29 var gDtmfOnToneChange = function(tone) {};
31 /**
32 * Sets the transform to apply just before setting the local description and
33 * sending to the peer.
34 * @param {function} transformFunction A function which takes one SDP string as
35 * argument and returns the modified SDP string.
37 function setOutgoingSdpTransform(transformFunction) {
38 gTransformOutgoingSdp = transformFunction;
41 /**
42 * Sets the MediaConstraints to be used for PeerConnection createAnswer() calls.
43 * @param {string} mediaConstraints The constraints, as defined in the
44 * PeerConnection JS API spec.
46 function setCreateAnswerConstraints(mediaConstraints) {
47 gCreateAnswerConstraints = mediaConstraints;
50 /**
51 * Sets the MediaConstraints to be used for PeerConnection createOffer() calls.
52 * @param {string} mediaConstraints The constraints, as defined in the
53 * PeerConnection JS API spec.
55 function setCreateOfferConstraints(mediaConstraints) {
56 gCreateOfferConstraints = mediaConstraints;
59 /**
60 * Sets the callback functions that will receive DataChannel readyState updates
61 * and received data.
62 * @param {function} status_callback The function that will receive a string
63 * with
64 * the current DataChannel readyState.
65 * @param {function} data_callback The function that will a string with data
66 * received from the remote peer.
68 function setDataCallbacks(status_callback, data_callback) {
69 gDataStatusCallback = status_callback;
70 gDataCallback = data_callback;
73 /**
74 * Sends data on an active DataChannel.
75 * @param {string} data The string that will be sent to the remote peer.
77 function sendDataOnChannel(data) {
78 if (gDataChannel == null)
79 throw failTest('Trying to send data, but there is no DataChannel.');
80 gDataChannel.send(data);
83 /**
84 * Sets the callback function that will receive DTMF sender ontonechange events.
85 * @param {function} ontonechange The function that will receive a string with
86 * the tone that has just begun playout.
88 function setOnToneChange(ontonechange) {
89 gDtmfOnToneChange = ontonechange;
92 /**
93 * Inserts DTMF tones on an active DTMF sender.
94 * @param {string} data The string that will be sent to the remote peer.
96 function insertDtmf(tones, duration, interToneGap) {
97 if (gDtmfSender == null)
98 throw failTest('Trying to send DTMF, but there is no DTMF sender.');
99 gDtmfSender.insertDTMF(tones, duration, interToneGap);
102 // Public interface towards the other javascript files, such as
103 // message_handling.js. The contract for these functions is described in
104 // message_handling.js.
106 function handleMessage(peerConnection, message) {
107 var parsed_msg = JSON.parse(message);
108 if (parsed_msg.type) {
109 var session_description = new RTCSessionDescription(parsed_msg);
110 peerConnection.setRemoteDescription(
111 session_description,
112 function() { success_('setRemoteDescription'); },
113 function() { failure_('setRemoteDescription'); });
114 if (session_description.type == 'offer') {
115 debug('createAnswer with constraints: ' +
116 JSON.stringify(gCreateAnswerConstraints, null, ' '));
117 peerConnection.createAnswer(
118 setLocalAndSendMessage_,
119 function() { failure_('createAnswer'); },
120 gCreateAnswerConstraints);
122 return;
123 } else if (parsed_msg.candidate) {
124 var candidate = new RTCIceCandidate(parsed_msg);
125 peerConnection.addIceCandidate(candidate);
126 return;
128 throw failTest('unknown message received');
131 function createPeerConnection(stun_server, useRtpDataChannels) {
132 servers = {iceServers: [{url: 'stun:' + stun_server}]};
133 try {
134 var constraints = { optional: [{ RtpDataChannels: useRtpDataChannels }]};
135 peerConnection = new webkitRTCPeerConnection(servers, constraints);
136 } catch (exception) {
137 throw failTest('Failed to create peer connection: ' + exception);
139 peerConnection.onaddstream = addStreamCallback_;
140 peerConnection.onremovestream = removeStreamCallback_;
141 peerConnection.onicecandidate = iceCallback_;
142 peerConnection.ondatachannel = onCreateDataChannelCallback_;
143 return peerConnection;
146 function setupCall(peerConnection) {
147 debug('createOffer with constraints: ' +
148 JSON.stringify(gCreateOfferConstraints, null, ' '));
149 peerConnection.createOffer(
150 setLocalAndSendMessage_,
151 function() { failure_('createOffer'); },
152 gCreateOfferConstraints);
155 function answerCall(peerConnection, message) {
156 handleMessage(peerConnection, message);
159 function createDataChannel(peerConnection, label) {
160 if (gDataChannel != null && gDataChannel.readyState != 'closed') {
161 throw failTest('Creating DataChannel, but we already have one.');
164 gDataChannel = peerConnection.createDataChannel(label, { reliable: false });
165 debug('DataChannel with label ' + gDataChannel.label + ' initiated locally.');
166 hookupDataChannelEvents();
169 function closeDataChannel(peerConnection) {
170 if (gDataChannel == null)
171 throw failTest('Closing DataChannel, but none exists.');
172 debug('DataChannel with label ' + gDataChannel.label + ' is beeing closed.');
173 gDataChannel.close();
176 function createDtmfSender(peerConnection) {
177 if (gDtmfSender != null)
178 throw failTest('Creating DTMF sender, but we already have one.');
180 var localStream = getLocalStream();
181 if (localStream == null)
182 throw failTest('Creating DTMF sender but local stream is null.');
183 local_audio_track = localStream.getAudioTracks()[0];
184 gDtmfSender = peerConnection.createDTMFSender(local_audio_track);
185 gDtmfSender.ontonechange = gDtmfOnToneChange;
188 // Internals.
189 /** @private */
190 function success_(method) {
191 debug(method + '(): success.');
194 /** @private */
195 function failure_(method, error) {
196 throw failTest(method + '() failed: ' + error);
199 /** @private */
200 function iceCallback_(event) {
201 if (event.candidate)
202 sendToPeer(gRemotePeerId, JSON.stringify(event.candidate));
205 /** @private */
206 function setLocalAndSendMessage_(session_description) {
207 session_description.sdp = gTransformOutgoingSdp(session_description.sdp);
208 peerConnection.setLocalDescription(
209 session_description,
210 function() { success_('setLocalDescription'); },
211 function() { failure_('setLocalDescription'); });
212 debug('Sending SDP message:\n' + session_description.sdp);
213 sendToPeer(gRemotePeerId, JSON.stringify(session_description));
216 /** @private */
217 function addStreamCallback_(event) {
218 debug('Receiving remote stream...');
219 var videoTag = document.getElementById('remote-view');
220 attachMediaStream(videoTag, event.stream);
222 // Due to crbug.com/110938 the size is 0 when onloadedmetadata fires.
223 // videoTag.onloadedmetadata = displayVideoSize_(videoTag);
224 // Use setTimeout as a workaround for now.
225 // Displays the remote video size for both the video element and the stream.
226 setTimeout(function() {displayVideoSize_(videoTag);}, 500);
229 /** @private */
230 function removeStreamCallback_(event) {
231 debug('Call ended.');
232 document.getElementById('remote-view').src = '';
235 /** @private */
236 function onCreateDataChannelCallback_(event) {
237 if (gDataChannel != null && gDataChannel.readyState != 'closed') {
238 throw failTest('Received DataChannel, but we already have one.');
241 gDataChannel = event.channel;
242 debug('DataChannel with label ' + gDataChannel.label +
243 ' initiated by remote peer.');
244 hookupDataChannelEvents();
247 /** @private */
248 function hookupDataChannelEvents() {
249 gDataChannel.onmessage = gDataCallback;
250 gDataChannel.onopen = onDataChannelReadyStateChange_;
251 gDataChannel.onclose = onDataChannelReadyStateChange_;
252 // Trigger gDataStatusCallback so an application is notified
253 // about the created data channel.
254 onDataChannelReadyStateChange_();
257 /** @private */
258 function onDataChannelReadyStateChange_() {
259 var readyState = gDataChannel.readyState;
260 debug('DataChannel state:' + readyState);
261 gDataStatusCallback(readyState);