From f6744926850f7e483f07b7e275a675aa2bb1915d Mon Sep 17 00:00:00 2001 From: Bruno Windels <274386+bwindels@users.noreply.github.com> Date: Fri, 11 Mar 2022 16:56:21 +0100 Subject: [PATCH] remove local media promises (handle them outside of call code) + glare --- src/matrix/calls/PeerCall.ts | 41 +++++++++----------------------- src/matrix/calls/TODO.md | 8 +++---- src/matrix/calls/group/Member.ts | 4 ++-- 3 files changed, 17 insertions(+), 36 deletions(-) diff --git a/src/matrix/calls/PeerCall.ts b/src/matrix/calls/PeerCall.ts index fa56601e..8725756f 100644 --- a/src/matrix/calls/PeerCall.ts +++ b/src/matrix/calls/PeerCall.ts @@ -114,18 +114,12 @@ export class PeerCall implements IDisposable { return this.peerConnection.remoteTracks; } - async call(localMediaPromise: Promise): Promise { + async call(localMedia: LocalMedia): Promise { if (this._state !== CallState.Fledgling) { return; } + this.localMedia = localMedia; this.direction = CallDirection.Outbound; - this.setState(CallState.WaitLocalMedia); - try { - this.localMedia = await localMediaPromise; - } catch (err) { - this.setState(CallState.Ended); - return; - } this.setState(CallState.CreateOffer); for (const t of this.localMedia.tracks) { this.peerConnection.addTrack(t); @@ -135,17 +129,11 @@ export class PeerCall implements IDisposable { await this.waitForState([CallState.InviteSent, CallState.CreateAnswer]); } - async answer(localMediaPromise: Promise): Promise { + async answer(localMedia: LocalMedia): Promise { if (this._state !== CallState.Ringing) { return; } - this.setState(CallState.WaitLocalMedia); - try { - this.localMedia = await localMediaPromise; - } catch (err) { - this.setState(CallState.Ended); - return; - } + this.localMedia = localMedia; this.setState(CallState.CreateAnswer); for (const t of this.localMedia.tracks) { this.peerConnection.addTrack(t); @@ -274,7 +262,7 @@ export class PeerCall implements IDisposable { lifetime: CALL_TIMEOUT_MS }; if (this._state === CallState.CreateOffer) { - await this.options.sendSignallingMessage({type: EventType.Invite, content}); + await this.options.sendSignallingMessage({type: EventType.Invite, content}, undefined); this.setState(CallState.InviteSent); } else if (this._state === CallState.Connected || this._state === CallState.Connecting) { // send Negotiate message @@ -304,21 +292,15 @@ export class PeerCall implements IDisposable { "Glare detected: answering incoming call " + newCallId + " and canceling outgoing call " + this.callId, ); - - /* - first, we should set CallDirection - we should anser the call - */ - - // TODO: review states to be unambigous, WaitLocalMedia for sending offer or answer? // How do we interrupt `call()`? well, perhaps we need to not just await InviteSent but also CreateAnswer? - if (this._state === CallState.Fledgling || this._state === CallState.CreateOffer || this._state === CallState.WaitLocalMedia) { - + if (this._state === CallState.Fledgling || this._state === CallState.CreateOffer) { + // TODO: don't send invite! } else { await this.sendHangupWithCallId(this.callId, CallErrorCode.Replaced); } await this.handleInvite(content, partyId); - await this.answer(Promise.resolve(this.localMedia!)); + // TODO: need to skip state check + await this.answer(this.localMedia!); } else { this.logger.log( "Glare detected: rejecting incoming call " + newCallId + @@ -328,7 +310,7 @@ export class PeerCall implements IDisposable { } } - private async handleFirstInvite(content: MCallInvite, partyId: PartyId): Promise { + private async handleFirstInvite(content: MCallInvite, partyId: PartyId): Promise { if (this._state !== CallState.Fledgling || this.opponentPartyId !== undefined) { // TODO: hangup or ignore? return; @@ -336,7 +318,7 @@ export class PeerCall implements IDisposable { await this.handleInvite(content, partyId); } - private async handleInvite(content: MCallInvite, partyId: PartyId): Promise { + private async handleInvite(content: MCallInvite, partyId: PartyId): Promise { // we must set the party ID before await-ing on anything: the call event // handler will start giving us more call events (eg. candidates) so if @@ -705,7 +687,6 @@ export enum CallParty { export enum CallState { Fledgling = 'fledgling', - WaitLocalMedia = 'wait_local_media', CreateOffer = 'create_offer', InviteSent = 'invite_sent', CreateAnswer = 'create_answer', diff --git a/src/matrix/calls/TODO.md b/src/matrix/calls/TODO.md index 23306c56..a07da60e 100644 --- a/src/matrix/calls/TODO.md +++ b/src/matrix/calls/TODO.md @@ -145,10 +145,10 @@ FROM CALLER FROM CALLEE Fledgling Fledgling V `call()` V `handleInvite()`: setRemoteDescription(event.offer), add buffered candidates -WaitLocalMedia Ringing - V media promise resolves V `answer()` - V add local tracks WaitLocalMedia -CreateOffer V media promise resolves + V Ringing + V V `answer()` +CreateOffer V + V add local tracks V V wait for negotionneeded events V add local tracks V setLocalDescription() CreateAnswer V send invite event V setLocalDescription(createAnswer()) diff --git a/src/matrix/calls/group/Member.ts b/src/matrix/calls/group/Member.ts index 0c574bb0..bd1613cd 100644 --- a/src/matrix/calls/group/Member.ts +++ b/src/matrix/calls/group/Member.ts @@ -60,7 +60,7 @@ export class Member { // otherwise wait for it to connect if (this.member.userId < this.options.ownUserId) { this.peerCall = this._createPeerCall(makeId("c")); - this.peerCall.call(Promise.resolve(localMedia.clone())); + this.peerCall.call(localMedia); } } @@ -72,7 +72,7 @@ export class Member { /** @internal */ emitUpdate = (peerCall: PeerCall, params: any) => { if (peerCall.state === CallState.Ringing) { - peerCall.answer(Promise.resolve(this.localMedia!)); + peerCall.answer(this.localMedia!); } this.options.emitUpdate(this, params); }