You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-28 05:03:59 +03:00
Merge pull request #1503 from matrix-org/dbkr/call_state_machine
Fixes for call state machine
This commit is contained in:
@@ -85,6 +85,13 @@ export enum CallParty {
|
|||||||
Remote = 'remote',
|
Remote = 'remote',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum CallEvent {
|
||||||
|
Hangup = 'hangup',
|
||||||
|
State = 'state',
|
||||||
|
Error = 'error',
|
||||||
|
Replaced = 'replaced',
|
||||||
|
}
|
||||||
|
|
||||||
enum MediaQueueId {
|
enum MediaQueueId {
|
||||||
RemoteVideo = 'remote_video',
|
RemoteVideo = 'remote_video',
|
||||||
RemoteAudio = 'remote_audio',
|
RemoteAudio = 'remote_audio',
|
||||||
@@ -92,6 +99,9 @@ enum MediaQueueId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum CallErrorCode {
|
export enum CallErrorCode {
|
||||||
|
/** The user chose to end the call */
|
||||||
|
UserHangup = 'user_hangup',
|
||||||
|
|
||||||
/** An error code when the local client failed to create an offer. */
|
/** An error code when the local client failed to create an offer. */
|
||||||
LocalOfferFailed = 'local_offer_failed',
|
LocalOfferFailed = 'local_offer_failed',
|
||||||
/**
|
/**
|
||||||
@@ -297,7 +307,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
const audioConstraints = getUserMediaVideoContraints(CallType.Voice);
|
const audioConstraints = getUserMediaVideoContraints(CallType.Voice);
|
||||||
this.placeCallWithConstraints(audioConstraints);
|
this.placeCallWithConstraints(audioConstraints);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.emit("error",
|
this.emit(CallEvent.Error,
|
||||||
new CallError(
|
new CallError(
|
||||||
CallErrorCode.NoUserMedia,
|
CallErrorCode.NoUserMedia,
|
||||||
"Failed to get screen-sharing stream: ", err,
|
"Failed to get screen-sharing stream: ", err,
|
||||||
@@ -440,7 +450,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
if (this.peerConn.signalingState != 'closed') {
|
if (this.peerConn.signalingState != 'closed') {
|
||||||
this.peerConn.close();
|
this.peerConn.close();
|
||||||
}
|
}
|
||||||
this.emit("hangup");
|
this.emit(CallEvent.Hangup);
|
||||||
}
|
}
|
||||||
}, this.msg.lifetime - event.getLocalAge());
|
}, this.msg.lifetime - event.getLocalAge());
|
||||||
}
|
}
|
||||||
@@ -511,7 +521,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
newCall.remoteVideoElement = this.remoteVideoElement;
|
newCall.remoteVideoElement = this.remoteVideoElement;
|
||||||
newCall.remoteAudioElement = this.remoteAudioElement;
|
newCall.remoteAudioElement = this.remoteAudioElement;
|
||||||
this.successor = newCall;
|
this.successor = newCall;
|
||||||
this.emit("replaced", newCall);
|
this.emit(CallEvent.Replaced, newCall);
|
||||||
this.hangup(CallErrorCode.Replaced, true);
|
this.hangup(CallErrorCode.Replaced, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,8 +538,10 @@ export class MatrixCall extends EventEmitter {
|
|||||||
const content = {
|
const content = {
|
||||||
version: 0,
|
version: 0,
|
||||||
call_id: this.callId,
|
call_id: this.callId,
|
||||||
reason: reason,
|
|
||||||
};
|
};
|
||||||
|
// Continue to send no reason for user hangups temporarily, until
|
||||||
|
// clients understand the user_hangup reason (voip v1)
|
||||||
|
if (reason !== CallErrorCode.UserHangup) content['reason'] = reason;
|
||||||
this.sendEvent('m.call.hangup', content);
|
this.sendEvent('m.call.hangup', content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,8 +654,8 @@ export class MatrixCall extends EventEmitter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private sendAnswer() {
|
private sendAnswer() {
|
||||||
|
this.setState(CallState.Connecting);
|
||||||
this.sendEvent('m.call.answer', this.answerContent).then(() => {
|
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,
|
// If this isn't the first time we've tried to send the answer,
|
||||||
// we may have candidates queued up, so send them now.
|
// we may have candidates queued up, so send them now.
|
||||||
this.sendCandidateQueue();
|
this.sendCandidateQueue();
|
||||||
@@ -658,7 +670,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
code = CallErrorCode.UnknownDevices;
|
code = CallErrorCode.UnknownDevices;
|
||||||
message = "Unknown devices present in the room";
|
message = "Unknown devices present in the room";
|
||||||
}
|
}
|
||||||
this.emit("error", new CallError(code, message, error));
|
this.emit(CallEvent.Error, new CallError(code, message, error));
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -854,7 +866,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
|
|
||||||
this.client.cancelPendingEvent(error.event);
|
this.client.cancelPendingEvent(error.event);
|
||||||
this.terminate(CallParty.Local, code, false);
|
this.terminate(CallParty.Local, code, false);
|
||||||
this.emit("error", new CallError(code, message, error));
|
this.emit(CallEvent.Error, new CallError(code, message, error));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -863,7 +875,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
|
|
||||||
this.terminate(CallParty.Local, CallErrorCode.LocalOfferFailed, false);
|
this.terminate(CallParty.Local, CallErrorCode.LocalOfferFailed, false);
|
||||||
this.emit(
|
this.emit(
|
||||||
"error",
|
CallEvent.Error,
|
||||||
new CallError(
|
new CallError(
|
||||||
CallErrorCode.LocalOfferFailed,
|
CallErrorCode.LocalOfferFailed,
|
||||||
"Failed to get local offer!", err,
|
"Failed to get local offer!", err,
|
||||||
@@ -879,7 +891,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
|
|
||||||
this.terminate(CallParty.Local, CallErrorCode.NoUserMedia, false);
|
this.terminate(CallParty.Local, CallErrorCode.NoUserMedia, false);
|
||||||
this.emit(
|
this.emit(
|
||||||
"error",
|
CallEvent.Error,
|
||||||
new CallError(
|
new CallError(
|
||||||
CallErrorCode.NoUserMedia,
|
CallErrorCode.NoUserMedia,
|
||||||
"Couldn't start capturing media! Is your microphone set up and " +
|
"Couldn't start capturing media! Is your microphone set up and " +
|
||||||
@@ -893,12 +905,11 @@ export class MatrixCall extends EventEmitter {
|
|||||||
return; // because ICE can still complete as we're ending the call
|
return; // because ICE can still complete as we're ending the call
|
||||||
}
|
}
|
||||||
logger.debug(
|
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
|
// ideally we'd consider the call to be connected when we get media but
|
||||||
// chrome doesn't implement any of the 'onstarted' events yet
|
// chrome doesn't implement any of the 'onstarted' events yet
|
||||||
if (this.peerConn.iceConnectionState == 'completed' ||
|
if (this.peerConn.iceConnectionState == 'connected') {
|
||||||
this.peerConn.iceConnectionState == 'connected') {
|
|
||||||
this.setState(CallState.Connected);
|
this.setState(CallState.Connected);
|
||||||
} else if (this.peerConn.iceConnectionState == 'failed') {
|
} else if (this.peerConn.iceConnectionState == 'failed') {
|
||||||
this.hangup(CallErrorCode.IceFailed, false);
|
this.hangup(CallErrorCode.IceFailed, false);
|
||||||
@@ -1004,7 +1015,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
setState(state: CallState) {
|
setState(state: CallState) {
|
||||||
const oldState = this.state;
|
const oldState = this.state;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.emit("state", state, oldState);
|
this.emit(CallEvent.State, state, oldState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1075,7 +1086,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
this.peerConn.close();
|
this.peerConn.close();
|
||||||
}
|
}
|
||||||
if (shouldEmit) {
|
if (shouldEmit) {
|
||||||
this.emit("hangup", self);
|
this.emit(CallEvent.Hangup, self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1092,8 +1103,10 @@ export class MatrixCall extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const track of this.remoteStream.getTracks()) {
|
if (this.remoteStream) {
|
||||||
track.stop();
|
for (const track of this.remoteStream.getTracks()) {
|
||||||
|
track.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1167,6 +1180,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
iceServers: this.turnServers,
|
iceServers: this.turnServers,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 'connectionstatechange' would be better, but firefox doesn't implement that.
|
||||||
pc.addEventListener('iceconnectionstatechange', this.onIceConnectionStateChanged);
|
pc.addEventListener('iceconnectionstatechange', this.onIceConnectionStateChanged);
|
||||||
pc.addEventListener('signalingstatechange', this.onSignallingStateChanged);
|
pc.addEventListener('signalingstatechange', this.onSignallingStateChanged);
|
||||||
pc.addEventListener('icecandidate', this.gotLocalIceCandidate);
|
pc.addEventListener('icecandidate', this.gotLocalIceCandidate);
|
||||||
|
|||||||
Reference in New Issue
Block a user