From 7f21c591aeac5cfc545b4d29ac6cfa834d383241 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 9 Oct 2020 18:45:45 +0100 Subject: [PATCH] Fixes for call state machine * Set 'connecting' state before sending answer, otherwise it can race with ICE connecting * Ignore completed ice connection state: connected is what we care about * Null-check remotestream when stopping media * Comments --- src/webrtc/call.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index 25c2b3fb8..441034cf4 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -645,8 +645,8 @@ export class MatrixCall extends EventEmitter { }; private sendAnswer() { + this.setState(CallState.Connecting); this.sendEvent('m.call.answer', this.answerContent).then(() => { - this.setState(CallState.Connecting); // If this isn't the first time we've tried to send the answer, // we may have candidates queued up, so send them now. this.sendCandidateQueue(); @@ -896,12 +896,11 @@ export class MatrixCall extends EventEmitter { return; // because ICE can still complete as we're ending the call } logger.debug( - "Ice connection state changed to: " + this.peerConn.iceConnectionState, + "ICE connection state changed to: " + this.peerConn.iceConnectionState, ); // ideally we'd consider the call to be connected when we get media but // chrome doesn't implement any of the 'onstarted' events yet - if (this.peerConn.iceConnectionState == 'completed' || - this.peerConn.iceConnectionState == 'connected') { + if (this.peerConn.iceConnectionState == 'connected') { this.setState(CallState.Connected); } else if (this.peerConn.iceConnectionState == 'failed') { this.hangup(CallErrorCode.IceFailed, false); @@ -1099,8 +1098,10 @@ export class MatrixCall extends EventEmitter { } } - for (const track of this.remoteStream.getTracks()) { - track.stop(); + if (this.remoteStream) { + for (const track of this.remoteStream.getTracks()) { + track.stop(); + } } } @@ -1174,6 +1175,7 @@ export class MatrixCall extends EventEmitter { iceServers: this.turnServers, }); + // 'connectionstatechange' would be better, but firefox doesn't implement that. pc.addEventListener('iceconnectionstatechange', this.onIceConnectionStateChanged); pc.addEventListener('signalingstatechange', this.onSignallingStateChanged); pc.addEventListener('icecandidate', this.gotLocalIceCandidate);