| Index: chrome/test/data/webrtc/message_handling.js
|
| diff --git a/chrome/test/data/webrtc/message_handling.js b/chrome/test/data/webrtc/message_handling.js
|
| index 377f95f1aa63298f77b5e8e95334f55ba27f5a14..6329ed303480e5863dcfbecbe23664f2becfa87b 100644
|
| --- a/chrome/test/data/webrtc/message_handling.js
|
| +++ b/chrome/test/data/webrtc/message_handling.js
|
| @@ -5,162 +5,117 @@
|
| */
|
|
|
| // This file requires these functions to be defined globally by someone else:
|
| -// function handleMessage(peerConnection, message)
|
| // function createPeerConnection(stun_server, useRtpDataChannel)
|
| -// function setupCall(peerConnection)
|
| -// function answerCall(peerConnection, message)
|
| +// function createOffer(peerConnection, constraints, callback)
|
| +// function receiveOffer(peerConnection, offer, constraints, callback)
|
| +// function receiveAnswer(peerConnection, answer, callback)
|
|
|
| // Currently these functions are supplied by jsep01_call.js.
|
|
|
| /**
|
| - * This object represents the call.
|
| - * @private
|
| - */
|
| -var gPeerConnection = null;
|
| -
|
| -/**
|
| - * True if we are accepting incoming calls.
|
| - * @private
|
| - */
|
| -var gAcceptsIncomingCalls = true;
|
| -
|
| -/**
|
| - * Our peer id as assigned by the peerconnection_server.
|
| - * @private
|
| - */
|
| -var gOurPeerId = null;
|
| -
|
| -/**
|
| - * The client id we use to identify to peerconnection_server.
|
| - * @private
|
| - */
|
| -var gOurClientName = null;
|
| -
|
| -/**
|
| - * The URL to the peerconnection_server.
|
| - * @private
|
| - */
|
| -var gServerUrl = null;
|
| -
|
| -/**
|
| - * The remote peer's id. We receive this one either when we connect (in the case
|
| - * our peer connects before us) or in a notification later.
|
| + * We need a STUN server for some API calls.
|
| * @private
|
| */
|
| -var gRemotePeerId = null;
|
| +var STUN_SERVER = 'stun.l.google.com:19302';
|
|
|
| /**
|
| - * Whether or not to auto-respond by adding our local stream when we are called.
|
| + * This object represents the call.
|
| * @private
|
| */
|
| -var gAutoAddLocalToPeerConnectionStreamWhenCalled = true;
|
| +var gPeerConnection = null;
|
|
|
| /**
|
| - * The one and only data channel.
|
| - * @private
|
| + * If true, any created peer connection will use RTP data
|
| + * channels. Otherwise it will use SCTP data channels.
|
| */
|
| -var gDataChannel = null;
|
| +var gUseRtpDataChannels = true;
|
|
|
| /**
|
| - * The DTMF sender.
|
| + * This stores ICE candidates generated on this side.
|
| * @private
|
| */
|
| -var gDtmfSender = null;
|
| +var gIceCandidates = [];
|
|
|
| -/**
|
| - * We need a STUN server for some API calls.
|
| - * @private
|
| - */
|
| -var STUN_SERVER = 'stun.l.google.com:19302';
|
| +// Public interface to tests. These are expected to be called with
|
| +// ExecuteJavascript invocations from the browser tests and will return answers
|
| +// through the DOM automation controller.
|
|
|
| /**
|
| - * If true, any created peer connection will use RTP data
|
| - * channels. Otherwise it will use SCTP data channels.
|
| + * Creates a peer connection. Must be called before most other public functions
|
| + * in this file.
|
| */
|
| -var gUseRtpDataChannels = true;
|
| -
|
| -// Public interface to tests.
|
| +function preparePeerConnection() {
|
| + if (gPeerConnection != null)
|
| + throw failTest('creating peer connection, but we already have one.');
|
|
|
| + gPeerConnection = createPeerConnection(STUN_SERVER, gUseRtpDataChannels);
|
| + returnToTest('ok-peerconnection-created');
|
| +}
|
|
|
| /**
|
| - * Connects to the provided peerconnection_server.
|
| + * Asks this page to create a local offer.
|
| *
|
| - * @param{string} serverUrl The server URL in string form without an ending
|
| - * slash, something like http://localhost:8888.
|
| - * @param{string} clientName The name to use when connecting to the server.
|
| + * Returns a string on the format ok-(JSON encoded session description).
|
| + *
|
| + * @param {!object} constraints Any createOffer constraints.
|
| */
|
| -function connect(serverUrl, clientName) {
|
| - if (gOurPeerId != null)
|
| - throw failTest('connecting, but is already connected.');
|
| -
|
| - debug('Connecting to ' + serverUrl + ' as ' + clientName);
|
| - gServerUrl = serverUrl;
|
| - gOurClientName = clientName;
|
| -
|
| - request = new XMLHttpRequest();
|
| - request.open('GET', serverUrl + '/sign_in?' + clientName, true);
|
| - debug(serverUrl + '/sign_in?' + clientName);
|
| - request.onreadystatechange = function() {
|
| - connectCallback_(request);
|
| - }
|
| - request.send();
|
| -}
|
| +function createLocalOffer(constraints) {
|
| + if (gPeerConnection == null)
|
| + throw failTest('Negotiating call, but we have no peer connection.');
|
|
|
| -/**
|
| - * Checks if the remote peer has connected. Returns peer-connected if that is
|
| - * the case, otherwise no-peer-connected.
|
| - */
|
| -function remotePeerIsConnected() {
|
| - if (gRemotePeerId == null)
|
| - returnToTest('no-peer-connected');
|
| - else
|
| - returnToTest('peer-connected');
|
| + // TODO(phoglund): move jsep01.call stuff into this file and remove need
|
| + // of the createOffer method, etc.
|
| + createOffer(gPeerConnection, constraints, function(localOffer) {
|
| + returnToTest('ok-' + JSON.stringify(localOffer));
|
| + });
|
| }
|
|
|
| /**
|
| - * Set if RTP data channels should be used for peerconnections.
|
| - * @param{boolean} useRtpDataChannel
|
| + * Asks this page to accept an offer and generate an answer.
|
| + *
|
| + * Returns a string on the format ok-(JSON encoded session description).
|
| + *
|
| + * @param {!string} sessionDescJson A JSON-encoded session description of type
|
| + * 'offer'.
|
| + * @param {!object} constraints Any createAnswer constraints.
|
| */
|
| -function useRtpDataChannelsForNewPeerConnections(useRtpDataChannels) {
|
| - gUseRtpDataChannels = useRtpDataChannels;
|
| -}
|
| +function receiveOfferFromPeer(sessionDescJson, constraints) {
|
| + if (gPeerConnection == null)
|
| + throw failTest('Receiving offer, but we have no peer connection.');
|
|
|
| -/**
|
| - * Creates a peer connection. Must be called before most other public functions
|
| - * in this file.
|
| - */
|
| -function preparePeerConnection() {
|
| - if (gPeerConnection != null)
|
| - throw failTest('creating peer connection, but we already have one.');
|
| + offer = parseJson_(sessionDescJson);
|
| + if (!offer.type)
|
| + failTest('Got invalid session description from peer: ' + sessionDescJson);
|
| + if (offer.type != 'offer')
|
| + failTest('Expected to receive offer from peer, got ' + offer.type);
|
|
|
| - gPeerConnection = createPeerConnection(STUN_SERVER, gUseRtpDataChannels);
|
| - returnToTest('ok-peerconnection-created');
|
| + receiveOffer(gPeerConnection, offer , constraints, function(answer) {
|
| + returnToTest('ok-' + JSON.stringify(answer));
|
| + });
|
| }
|
|
|
| /**
|
| - * Negotiates a call with the other side. This will create a peer connection on
|
| - * the other side if there isn't one. The other side will automatically add any
|
| - * stream it has unless doNotAutoAddLocalStreamWhenCalled() has been called.
|
| + * Asks this page to accept an answer generated by the peer in response to a
|
| + * previous offer by this page
|
| *
|
| - * To call this method we need to be aware of the other side, e.g. we must be
|
| - * connected to peerconnection_server and we must have exactly one peer on that
|
| - * server.
|
| + * Returns a string ok-accepted-answer on success.
|
| *
|
| - * This method may be called any number of times. If you haven't added any
|
| - * streams to the call, an "empty" call will result. The method will return
|
| - * ok-negotiating immediately to the test if the negotiation was successfully
|
| - * sent.
|
| + * @param {!string} sessionDescJson A JSON-encoded session description of type
|
| + * 'answer'.
|
| */
|
| -function negotiateCall() {
|
| +function receiveAnswerFromPeer(sessionDescJson) {
|
| if (gPeerConnection == null)
|
| - throw failTest('negotiating call, but we have no peer connection.');
|
| - if (gOurPeerId == null)
|
| - throw failTest('negotiating call, but not connected.');
|
| - if (gRemotePeerId == null)
|
| - throw failTest('negotiating call, but missing remote peer.');
|
| -
|
| - setupCall(gPeerConnection);
|
| - returnToTest('ok-negotiating');
|
| + throw failTest('Receiving offer, but we have no peer connection.');
|
| +
|
| + answer = parseJson_(sessionDescJson);
|
| + if (!answer.type)
|
| + failTest('Got invalid session description from peer: ' + sessionDescJson);
|
| + if (answer.type != 'answer')
|
| + failTest('Expected to receive answer from peer, got ' + answer.type);
|
| +
|
| + receiveAnswer(gPeerConnection, answer, function() {
|
| + returnToTest('ok-accepted-answer');
|
| + });
|
| }
|
|
|
| /**
|
| @@ -226,374 +181,86 @@ function playAudioFile() {
|
| }
|
|
|
| /**
|
| - * Removes the local stream from the peer connection. You will have to
|
| - * re-negotiate the call for this to take effect in the call.
|
| - */
|
| -function removeLocalStream() {
|
| - if (gPeerConnection == null)
|
| - throw failTest('attempting to remove local stream, but no call is up');
|
| -
|
| - removeLocalStreamFromPeerConnection(gPeerConnection);
|
| - returnToTest('ok-local-stream-removed');
|
| -}
|
| -
|
| -/**
|
| - * (see getReadyState)
|
| - */
|
| -function getPeerConnectionReadyState() {
|
| - returnToTest(getReadyState());
|
| -}
|
| -
|
| -/**
|
| - * Toggles the remote audio stream's enabled state on the peer connection, given
|
| - * that a call is active. Returns ok-[typeToToggle]-toggled-to-[true/false]
|
| - * on success.
|
| - *
|
| - * @param selectAudioOrVideoTrack: A function that takes a remote stream as
|
| - * argument and returns a track (e.g. either the video or audio track).
|
| - * @param typeToToggle: Either "audio" or "video" depending on what the selector
|
| - * function selects.
|
| - */
|
| -function toggleRemoteStream(selectAudioOrVideoTrack, typeToToggle) {
|
| - if (gPeerConnection == null)
|
| - throw failTest('Tried to toggle remote stream, ' +
|
| - 'but have no peer connection.');
|
| - if (gPeerConnection.getRemoteStreams().length == 0)
|
| - throw failTest('Tried to toggle remote stream, ' +
|
| - 'but not receiving any stream.');
|
| -
|
| - var track = selectAudioOrVideoTrack(gPeerConnection.getRemoteStreams()[0]);
|
| - toggle_(track, 'remote', typeToToggle);
|
| -}
|
| -
|
| -/**
|
| - * See documentation on toggleRemoteStream (this function is the same except
|
| - * we are looking at local streams).
|
| - */
|
| -function toggleLocalStream(selectAudioOrVideoTrack, typeToToggle) {
|
| - if (gPeerConnection == null)
|
| - throw failTest('Tried to toggle local stream, ' +
|
| - 'but have no peer connection.');
|
| - if (gPeerConnection.getLocalStreams().length == 0)
|
| - throw failTest('Tried to toggle local stream, but there is no local ' +
|
| - 'stream in the call.');
|
| -
|
| - var track = selectAudioOrVideoTrack(gPeerConnection.getLocalStreams()[0]);
|
| - toggle_(track, 'local', typeToToggle);
|
| -}
|
| -
|
| -/**
|
| - * Hangs up a started call. Returns ok-call-hung-up on success. This tab will
|
| - * not accept any incoming calls after this call.
|
| + * Hangs up a started call. Returns ok-call-hung-up on success.
|
| */
|
| function hangUp() {
|
| if (gPeerConnection == null)
|
| throw failTest('hanging up, but has no peer connection');
|
| - if (getReadyState() != 'active')
|
| - throw failTest('hanging up, but ready state is not active (no call up).');
|
| - sendToPeer(gRemotePeerId, 'BYE');
|
| - closeCall_();
|
| - gAcceptsIncomingCalls = false;
|
| + gPeerConnection.close();
|
| + gPeerConnection = null;
|
| returnToTest('ok-call-hung-up');
|
| }
|
|
|
| /**
|
| - * Start accepting incoming calls again after a hangup.
|
| - */
|
| -function acceptIncomingCallsAgain() {
|
| - gAcceptsIncomingCalls = true;
|
| -}
|
| -
|
| -/**
|
| - * Do not auto-add the local stream when called.
|
| - */
|
| -function doNotAutoAddLocalStreamWhenCalled() {
|
| - gAutoAddLocalToPeerConnectionStreamWhenCalled = false;
|
| -}
|
| -
|
| -/**
|
| - * Disconnects from the peerconnection server. Returns ok-disconnected on
|
| - * success.
|
| - */
|
| -function disconnect() {
|
| - if (gOurPeerId == null)
|
| - throw failTest('Disconnecting, but we are not connected.');
|
| -
|
| - request = new XMLHttpRequest();
|
| - request.open('GET', gServerUrl + '/sign_out?peer_id=' + gOurPeerId, false);
|
| - request.send();
|
| - gOurPeerId = null;
|
| - returnToTest('ok-disconnected');
|
| -}
|
| -
|
| -/**
|
| - * Creates a DataChannel on the current PeerConnection. Only one DataChannel can
|
| - * be created on each PeerConnection.
|
| - * Returns ok-datachannel-created on success.
|
| + * Retrieves all ICE candidates generated on this side. Must be called after
|
| + * ICE candidate generation is triggered (for instance by running a call
|
| + * negotiation). This function will wait if necessary if we're not done
|
| + * generating ICE candidates on this side.
|
| + *
|
| + * Returns a JSON-encoded array of RTCIceCandidate instances to the test.
|
| */
|
| -function createDataChannelOnPeerConnection() {
|
| +function getAllIceCandidates() {
|
| if (gPeerConnection == null)
|
| - throw failTest('Tried to create data channel, ' +
|
| - 'but have no peer connection.');
|
| + throw failTest('Trying to get ICE candidates, but has no peer connection.');
|
|
|
| - createDataChannel(gPeerConnection, gOurClientName);
|
| - returnToTest('ok-datachannel-created');
|
| -}
|
| -
|
| -/**
|
| - * Close the DataChannel on the current PeerConnection.
|
| - * Returns ok-datachannel-close on success.
|
| - */
|
| -function closeDataChannelOnPeerConnection() {
|
| - if (gPeerConnection == null)
|
| - throw failTest('Tried to close data channel, ' +
|
| - 'but have no peer connection.');
|
| + if (gPeerConnection.iceGatheringState != 'complete') {
|
| + console.log('Still ICE gathering - waiting...');
|
| + setTimeout(getAllIceCandidates, 100);
|
| + return;
|
| + }
|
|
|
| - closeDataChannel(gPeerConnection);
|
| - returnToTest('ok-datachannel-close');
|
| + returnToTest(JSON.stringify(gIceCandidates));
|
| }
|
|
|
| /**
|
| - * Creates a DTMF sender on the current PeerConnection.
|
| - * Returns ok-dtmfsender-created on success.
|
| + * Receives ICE candidates from the peer.
|
| + *
|
| + * Returns ok-received-candidates to the test on success.
|
| + *
|
| + * @param iceCandidatesJson a JSON-encoded array of RTCIceCandidate instances.
|
| */
|
| -function createDtmfSenderOnPeerConnection() {
|
| +function receiveIceCandidates(iceCandidatesJson) {
|
| if (gPeerConnection == null)
|
| - throw failTest('Tried to create DTMF sender, ' +
|
| - 'but have no peer connection.');
|
| + throw failTest('Received ICE candidate, but has no peer connection');
|
|
|
| - createDtmfSender(gPeerConnection);
|
| - returnToTest('ok-dtmfsender-created');
|
| -}
|
| + var iceCandidates = parseJson_(iceCandidatesJson);
|
| + if (!iceCandidates.length)
|
| + throw failTest('Received invalid ICE candidate list from peer: ' +
|
| + iceCandidatesJson);
|
|
|
| -/**
|
| - * Send DTMF tones on the gDtmfSender.
|
| - * Returns ok-dtmf-sent on success.
|
| - */
|
| -function insertDtmfOnSender(tones, duration, interToneGap) {
|
| - if (gDtmfSender == null)
|
| - throw failTest('Tried to insert DTMF tones, ' +
|
| - 'but have no DTMF sender.');
|
| + iceCandidates.forEach(function(iceCandidate) {
|
| + if (!iceCandidate.candidate)
|
| + failTest('Received invalid ICE candidate from peer: ' +
|
| + iceCandidatesJson);
|
| +
|
| + gPeerConnection.addIceCandidate(new RTCIceCandidate(iceCandidate));
|
| + });
|
|
|
| - insertDtmf(tones, duration, interToneGap);
|
| - returnToTest('ok-dtmf-sent');
|
| + returnToTest('ok-received-candidates');
|
| }
|
|
|
| // Public interface to signaling implementations, such as JSEP.
|
|
|
| /**
|
| - * Sends a message to a peer through the peerconnection_server.
|
| - */
|
| -function sendToPeer(peer, message) {
|
| - var messageToLog = message.sdp ? message.sdp : message;
|
| - debug('Sending message ' + messageToLog + ' to peer ' + peer + '.');
|
| -
|
| - var request = new XMLHttpRequest();
|
| - var url = gServerUrl + '/message?peer_id=' + gOurPeerId + '&to=' + peer;
|
| - request.open('POST', url, false);
|
| - request.setRequestHeader('Content-Type', 'text/plain');
|
| - request.send(message);
|
| -}
|
| -
|
| -/**
|
| - * Returns true if we are disconnected from peerconnection_server.
|
| + * Enqueues an ICE candidate for sending to the peer.
|
| + *
|
| + * @param {!RTCIceCandidate} The ICE candidate to send.
|
| */
|
| -function isDisconnected() {
|
| - return gOurPeerId == null;
|
| +function sendIceCandidate(message) {
|
| + gIceCandidates.push(message);
|
| }
|
|
|
| /**
|
| - * @return {!string} The current peer connection's ready state, or
|
| - * 'no-peer-connection' if there is no peer connection up.
|
| - *
|
| - * NOTE: The PeerConnection states are changing and until chromium has
|
| - * implemented the new states we have to use this interim solution of
|
| - * always assuming that the PeerConnection is 'active'.
|
| + * Parses JSON-encoded session descriptions and ICE candidates.
|
| + * @private
|
| */
|
| -function getReadyState() {
|
| - if (gPeerConnection == null)
|
| - return 'no-peer-connection';
|
| -
|
| - return 'active';
|
| -}
|
| -
|
| -// Internals.
|
| -
|
| -/** @private */
|
| -function toggle_(track, localOrRemote, audioOrVideo) {
|
| - if (!track)
|
| - throw failTest('Tried to toggle ' + localOrRemote + ' ' + audioOrVideo +
|
| - ' stream, but has no such stream.');
|
| -
|
| - track.enabled = !track.enabled;
|
| - returnToTest('ok-' + audioOrVideo + '-toggled-to-' + track.enabled);
|
| -}
|
| -
|
| -/** @private */
|
| -function connectCallback_(request) {
|
| - debug('Connect callback: ' + request.status + ', ' + request.readyState);
|
| - if (request.status == 0) {
|
| - debug('peerconnection_server doesn\'t seem to be up.');
|
| - returnToTest('failed-to-connect');
|
| - }
|
| - if (request.readyState == 4 && request.status == 200) {
|
| - gOurPeerId = parseOurPeerId_(request.responseText);
|
| - gRemotePeerId = parseRemotePeerIdIfConnected_(request.responseText);
|
| - startHangingGet_(gServerUrl, gOurPeerId);
|
| - returnToTest('ok-connected');
|
| - }
|
| -}
|
| -
|
| -/** @private */
|
| -function parseOurPeerId_(responseText) {
|
| - // According to peerconnection_server's protocol.
|
| - var peerList = responseText.split('\n');
|
| - return parseInt(peerList[0].split(',')[1]);
|
| -}
|
| -
|
| -/** @private */
|
| -function parseRemotePeerIdIfConnected_(responseText) {
|
| - var peerList = responseText.split('\n');
|
| - if (peerList.length == 1) {
|
| - // No peers have connected yet - we'll get their id later in a notification.
|
| - return null;
|
| - }
|
| - var remotePeerId = null;
|
| - for (var i = 0; i < peerList.length; i++) {
|
| - if (peerList[i].length == 0)
|
| - continue;
|
| -
|
| - var parsed = peerList[i].split(',');
|
| - var name = parsed[0];
|
| - var id = parsed[1];
|
| -
|
| - if (id != gOurPeerId) {
|
| - debug('Found remote peer with name ' + name + ', id ' +
|
| - id + ' when connecting.');
|
| -
|
| - // There should be at most one remote peer in this test.
|
| - if (remotePeerId != null)
|
| - throw failTest('Expected just one remote peer in this test: ' +
|
| - 'found several.');
|
| -
|
| - // Found a remote peer.
|
| - remotePeerId = id;
|
| - }
|
| - }
|
| - return remotePeerId;
|
| -}
|
| -
|
| -/** @private */
|
| -function startHangingGet_(server, ourId) {
|
| - if (isDisconnected())
|
| - return;
|
| - hangingGetRequest = new XMLHttpRequest();
|
| - hangingGetRequest.onreadystatechange = function() {
|
| - hangingGetCallback_(hangingGetRequest, server, ourId);
|
| - }
|
| - hangingGetRequest.ontimeout = function() {
|
| - hangingGetTimeoutCallback_(hangingGetRequest, server, ourId);
|
| - }
|
| - callUrl = server + '/wait?peer_id=' + ourId;
|
| - debug('Sending ' + callUrl);
|
| - hangingGetRequest.open('GET', callUrl, true);
|
| - hangingGetRequest.send();
|
| -}
|
| -
|
| -/** @private */
|
| -function hangingGetCallback_(hangingGetRequest, server, ourId) {
|
| - if (hangingGetRequest.readyState != 4 || hangingGetRequest.status == 0) {
|
| - // Code 0 is not possible if the server actually responded. Ignore.
|
| - return;
|
| - }
|
| - if (hangingGetRequest.status != 200) {
|
| - throw failTest('Error ' + hangingGetRequest.status + ' from server: ' +
|
| - hangingGetRequest.statusText);
|
| - }
|
| - var targetId = readResponseHeader_(hangingGetRequest, 'Pragma');
|
| - if (targetId == ourId)
|
| - handleServerNotification_(hangingGetRequest.responseText);
|
| - else
|
| - handlePeerMessage_(targetId, hangingGetRequest.responseText);
|
| -
|
| - hangingGetRequest.abort();
|
| - restartHangingGet_(server, ourId);
|
| -}
|
| -
|
| -/** @private */
|
| -function hangingGetTimeoutCallback_(hangingGetRequest, server, ourId) {
|
| - debug('Hanging GET times out, re-issuing...');
|
| - hangingGetRequest.abort();
|
| - restartHangingGet_(server, ourId);
|
| -}
|
| -
|
| -/** @private */
|
| -function handleServerNotification_(message) {
|
| - var parsed = message.split(',');
|
| - if (parseInt(parsed[2]) == 1) {
|
| - // Peer connected - this must be our remote peer, and it must mean we
|
| - // connected before them (except if we happened to connect to the server
|
| - // at precisely the same moment).
|
| - debug('Found remote peer with name ' + parsed[0] + ', id ' +
|
| - parsed[1] + ' when connecting.');
|
| - gRemotePeerId = parseInt(parsed[1]);
|
| - }
|
| -}
|
| -
|
| -/** @private */
|
| -function closeCall_() {
|
| - if (gPeerConnection == null)
|
| - throw failTest('Closing call, but no call active.');
|
| - gPeerConnection.close();
|
| - gPeerConnection = null;
|
| -}
|
| -
|
| -/** @private */
|
| -function handlePeerMessage_(peerId, message) {
|
| - debug('Received message from peer ' + peerId + ': ' + message);
|
| - if (peerId != gRemotePeerId) {
|
| - throw failTest('Received notification from unknown peer ' + peerId +
|
| - ' (only know about ' + gRemotePeerId + '.');
|
| - }
|
| - if (message.search('BYE') == 0) {
|
| - debug('Received BYE from peer: closing call');
|
| - closeCall_();
|
| - return;
|
| - }
|
| - if (gPeerConnection == null && gAcceptsIncomingCalls) {
|
| - // The other side is calling us.
|
| - debug('We are being called: answer...');
|
| -
|
| - gPeerConnection = createPeerConnection(STUN_SERVER, gUseRtpDataChannels);
|
| - if (gAutoAddLocalToPeerConnectionStreamWhenCalled &&
|
| - obtainGetUserMediaResult() == 'ok-got-stream') {
|
| - debug('We have a local stream, so hook it up automatically.');
|
| - addLocalStreamToPeerConnection(gPeerConnection);
|
| - }
|
| - answerCall(gPeerConnection, message);
|
| - return;
|
| - }
|
| - if (gPeerConnection == null) {
|
| - debug('Discarding message ' + message + '; already disconnected.');
|
| - return;
|
| - }
|
| -
|
| - handleMessage(gPeerConnection, message);
|
| -}
|
| -
|
| -/** @private */
|
| -function restartHangingGet_(server, ourId) {
|
| - window.setTimeout(function() {
|
| - startHangingGet_(server, ourId);
|
| - }, 0);
|
| -}
|
| -
|
| -/** @private */
|
| -function readResponseHeader_(request, key) {
|
| - var value = request.getResponseHeader(key)
|
| - if (value == null || value.length == 0) {
|
| - throw failTest('Received empty value ' + value +
|
| - ' for response header key ' + key + '.');
|
| +function parseJson_(json) {
|
| + // Escape since the \r\n in the SDP tend to get unescaped.
|
| + jsonWithEscapedLineBreaks = json.replace(/\r\n/g, '\\r\\n');
|
| + try {
|
| + return JSON.parse(jsonWithEscapedLineBreaks);
|
| + } catch (exception) {
|
| + failTest('Failed to parse JSON: ' + jsonWithEscapedLineBreaks + ', got ' +
|
| + exception);
|
| }
|
| - return parseInt(value);
|
| }
|
|
|