1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-28 05:03:59 +03:00

Merge pull request #1510 from matrix-org/dbkr/hang_up_your_hangups

Support m.call.reject
This commit is contained in:
David Baker
2020-10-19 09:57:00 +01:00
committed by GitHub
3 changed files with 62 additions and 8 deletions

View File

@@ -45,6 +45,7 @@ export enum EventType {
CallCandidates = "m.call.candidates", CallCandidates = "m.call.candidates",
CallAnswer = "m.call.answer", CallAnswer = "m.call.answer",
CallHangup = "m.call.hangup", CallHangup = "m.call.hangup",
CallReject = "m.call.reject",
KeyVerificationRequest = "m.key.verification.request", KeyVerificationRequest = "m.key.verification.request",
KeyVerificationStart = "m.key.verification.start", KeyVerificationStart = "m.key.verification.start",
KeyVerificationCancel = "m.key.verification.cancel", KeyVerificationCancel = "m.key.verification.cancel",

View File

@@ -164,6 +164,14 @@ export enum CallErrorCode {
Replaced = 'replaced', Replaced = 'replaced',
} }
/**
* The version field that we set in m.call.* events
* Once we are able to speak v1 VoIP sufficiently, this
* bumped to 1. While we partially speak v1 VoIP, it remains
* as 0.
*/
const VOIP_PROTO_VERSION = 0;
/** The fallback ICE server to use for STUN or TURN protocols. */ /** The fallback ICE server to use for STUN or TURN protocols. */
const FALLBACK_ICE_SERVER = 'stun:turn.matrix.org'; const FALLBACK_ICE_SERVER = 'stun:turn.matrix.org';
@@ -222,6 +230,7 @@ export class MatrixCall extends EventEmitter {
// XXX: I don't know why this is called 'config'. // XXX: I don't know why this is called 'config'.
private config: MediaStreamConstraints; private config: MediaStreamConstraints;
private successor: MatrixCall; private successor: MatrixCall;
private opponentVersion: number;
constructor(opts: CallOpts) { constructor(opts: CallOpts) {
super(); super();
@@ -439,6 +448,7 @@ export class MatrixCall extends EventEmitter {
this.setState(CallState.Ringing); this.setState(CallState.Ringing);
this.direction = CallDirection.Inbound; this.direction = CallDirection.Inbound;
this.opponentVersion = this.msg.version;
if (event.getLocalAge()) { if (event.getLocalAge()) {
setTimeout(() => { setTimeout(() => {
@@ -457,7 +467,7 @@ export class MatrixCall extends EventEmitter {
} }
/** /**
* Configure this call from a hangup event. Used by MatrixClient. * Configure this call from a hangup or reject event. Used by MatrixClient.
* @param {MatrixEvent} event The m.call.hangup event * @param {MatrixEvent} event The m.call.hangup event
*/ */
initWithHangup(event: MatrixEvent) { initWithHangup(event: MatrixEvent) {
@@ -536,7 +546,7 @@ export class MatrixCall extends EventEmitter {
logger.debug("Ending call " + this.callId); logger.debug("Ending call " + this.callId);
this.terminate(CallParty.Local, reason, !suppressEvent); this.terminate(CallParty.Local, reason, !suppressEvent);
const content = { const content = {
version: 0, version: VOIP_PROTO_VERSION,
call_id: this.callId, call_id: this.callId,
}; };
// Continue to send no reason for user hangups temporarily, until // Continue to send no reason for user hangups temporarily, until
@@ -545,6 +555,33 @@ export class MatrixCall extends EventEmitter {
this.sendEvent('m.call.hangup', content); this.sendEvent('m.call.hangup', content);
} }
/**
* Reject a call
* This used to be done by calling hangup, but is a separate method and protocol
* event as of MSC2746.
*/
reject() {
if (this.state !== CallState.Ringing) {
throw Error("Call must be in 'ringing' state to reject!");
}
if (this.opponentVersion < 1) {
logger.info(
`Opponent version is less than 1 (${this.opponentVersion}): sending hangup instead of reject`,
);
this.hangup(CallErrorCode.UserHangup, true);
return;
}
logger.debug("Rejecting call: " + this.callId);
this.terminate(CallParty.Local, CallErrorCode.UserHangup, true);
const content = {
version: VOIP_PROTO_VERSION,
call_id: this.callId,
};
this.sendEvent('m.call.reject', content);
}
/** /**
* Set whether the local video preview should be muted or not. * Set whether the local video preview should be muted or not.
* @param {boolean} muted True to mute the local video. * @param {boolean} muted True to mute the local video.
@@ -713,7 +750,7 @@ export class MatrixCall extends EventEmitter {
await this.peerConn.setLocalDescription(myAnswer); await this.peerConn.setLocalDescription(myAnswer);
this.answerContent = { this.answerContent = {
version: 0, version: VOIP_PROTO_VERSION,
call_id: this.callId, call_id: this.callId,
answer: { answer: {
sdp: this.peerConn.localDescription.sdp, sdp: this.peerConn.localDescription.sdp,
@@ -800,6 +837,8 @@ export class MatrixCall extends EventEmitter {
return; return;
} }
this.opponentVersion = msg.version;
try { try {
this.peerConn.setRemoteDescription(msg.answer); this.peerConn.setRemoteDescription(msg.answer);
} catch (e) { } catch (e) {
@@ -829,7 +868,7 @@ export class MatrixCall extends EventEmitter {
} }
const content = { const content = {
version: 0, version: VOIP_PROTO_VERSION,
call_id: this.callId, call_id: this.callId,
// OpenWebRTC appears to add extra stuff (like the DTLS fingerprint) // OpenWebRTC appears to add extra stuff (like the DTLS fingerprint)
// to the description when setting it on the peerconnection. // to the description when setting it on the peerconnection.
@@ -1004,7 +1043,17 @@ export class MatrixCall extends EventEmitter {
onHangupReceived = (msg) => { onHangupReceived = (msg) => {
logger.debug("Hangup received"); logger.debug("Hangup received");
this.terminate(CallParty.Remote, msg.reason, true); // default reason is user_hangup
this.terminate(CallParty.Remote, msg.reason || CallErrorCode.UserHangup, true);
};
onRejectReceived = (msg) => {
logger.debug("Reject received");
if (this.state === CallState.InviteSent) {
this.terminate(CallParty.Remote, CallErrorCode.UserHangup, true);
} else {
logger.debug(`Call is in state: ${this.state}: ignoring reject`);
}
}; };
onAnsweredElsewhere = (msg) => { onAnsweredElsewhere = (msg) => {
@@ -1127,7 +1176,7 @@ export class MatrixCall extends EventEmitter {
this.candidateSendQueue = []; this.candidateSendQueue = [];
++this.candidateSendTries; ++this.candidateSendTries;
const content = { const content = {
version: 0, version: VOIP_PROTO_VERSION,
call_id: this.callId, call_id: this.callId,
candidates: cands, candidates: cands,
}; };

View File

@@ -232,7 +232,7 @@ export class CallEventHandler {
call.gotRemoteIceCandidate(cand); call.gotRemoteIceCandidate(cand);
} }
} }
} else if (event.getType() === EventType.CallHangup) { } else if ([EventType.CallHangup, EventType.CallReject].includes(event.getType())) {
// Note that we also observe our own hangups here so we can see // Note that we also observe our own hangups here so we can see
// if we've already rejected a call that would otherwise be valid // if we've already rejected a call that would otherwise be valid
if (!call) { if (!call) {
@@ -247,7 +247,11 @@ export class CallEventHandler {
} }
} else { } else {
if (call.state !== CallState.Ended) { if (call.state !== CallState.Ended) {
if (event.getType() === EventType.CallHangup) {
call.onHangupReceived(content); call.onHangupReceived(content);
} else {
call.onRejectReceived(content);
}
this.calls.delete(content.call_id); this.calls.delete(content.call_id);
} }
} }