remove local media promises (handle them outside of call code) + glare

This commit is contained in:
Bruno Windels 2022-03-11 16:56:21 +01:00
parent 3c160c8a37
commit f674492685
3 changed files with 17 additions and 36 deletions

View File

@ -114,18 +114,12 @@ export class PeerCall implements IDisposable {
return this.peerConnection.remoteTracks; return this.peerConnection.remoteTracks;
} }
async call(localMediaPromise: Promise<LocalMedia>): Promise<void> { async call(localMedia: LocalMedia): Promise<void> {
if (this._state !== CallState.Fledgling) { if (this._state !== CallState.Fledgling) {
return; return;
} }
this.localMedia = localMedia;
this.direction = CallDirection.Outbound; this.direction = CallDirection.Outbound;
this.setState(CallState.WaitLocalMedia);
try {
this.localMedia = await localMediaPromise;
} catch (err) {
this.setState(CallState.Ended);
return;
}
this.setState(CallState.CreateOffer); this.setState(CallState.CreateOffer);
for (const t of this.localMedia.tracks) { for (const t of this.localMedia.tracks) {
this.peerConnection.addTrack(t); this.peerConnection.addTrack(t);
@ -135,17 +129,11 @@ export class PeerCall implements IDisposable {
await this.waitForState([CallState.InviteSent, CallState.CreateAnswer]); await this.waitForState([CallState.InviteSent, CallState.CreateAnswer]);
} }
async answer(localMediaPromise: Promise<LocalMedia>): Promise<void> { async answer(localMedia: LocalMedia): Promise<void> {
if (this._state !== CallState.Ringing) { if (this._state !== CallState.Ringing) {
return; return;
} }
this.setState(CallState.WaitLocalMedia); this.localMedia = localMedia;
try {
this.localMedia = await localMediaPromise;
} catch (err) {
this.setState(CallState.Ended);
return;
}
this.setState(CallState.CreateAnswer); this.setState(CallState.CreateAnswer);
for (const t of this.localMedia.tracks) { for (const t of this.localMedia.tracks) {
this.peerConnection.addTrack(t); this.peerConnection.addTrack(t);
@ -274,7 +262,7 @@ export class PeerCall implements IDisposable {
lifetime: CALL_TIMEOUT_MS lifetime: CALL_TIMEOUT_MS
}; };
if (this._state === CallState.CreateOffer) { 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); this.setState(CallState.InviteSent);
} else if (this._state === CallState.Connected || this._state === CallState.Connecting) { } else if (this._state === CallState.Connected || this._state === CallState.Connecting) {
// send Negotiate message // send Negotiate message
@ -304,21 +292,15 @@ export class PeerCall implements IDisposable {
"Glare detected: answering incoming call " + newCallId + "Glare detected: answering incoming call " + newCallId +
" and canceling outgoing call " + this.callId, " 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? // 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 { } else {
await this.sendHangupWithCallId(this.callId, CallErrorCode.Replaced); await this.sendHangupWithCallId(this.callId, CallErrorCode.Replaced);
} }
await this.handleInvite(content, partyId); await this.handleInvite(content, partyId);
await this.answer(Promise.resolve(this.localMedia!)); // TODO: need to skip state check
await this.answer(this.localMedia!);
} else { } else {
this.logger.log( this.logger.log(
"Glare detected: rejecting incoming call " + newCallId + "Glare detected: rejecting incoming call " + newCallId +
@ -328,7 +310,7 @@ export class PeerCall implements IDisposable {
} }
} }
private async handleFirstInvite(content: MCallInvite, partyId: PartyId): Promise<void> { private async handleFirstInvite(content: MCallInvite<MCallBase>, partyId: PartyId): Promise<void> {
if (this._state !== CallState.Fledgling || this.opponentPartyId !== undefined) { if (this._state !== CallState.Fledgling || this.opponentPartyId !== undefined) {
// TODO: hangup or ignore? // TODO: hangup or ignore?
return; return;
@ -336,7 +318,7 @@ export class PeerCall implements IDisposable {
await this.handleInvite(content, partyId); await this.handleInvite(content, partyId);
} }
private async handleInvite(content: MCallInvite, partyId: PartyId): Promise<void> { private async handleInvite(content: MCallInvite<MCallBase>, partyId: PartyId): Promise<void> {
// we must set the party ID before await-ing on anything: the call event // 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 // handler will start giving us more call events (eg. candidates) so if
@ -705,7 +687,6 @@ export enum CallParty {
export enum CallState { export enum CallState {
Fledgling = 'fledgling', Fledgling = 'fledgling',
WaitLocalMedia = 'wait_local_media',
CreateOffer = 'create_offer', CreateOffer = 'create_offer',
InviteSent = 'invite_sent', InviteSent = 'invite_sent',
CreateAnswer = 'create_answer', CreateAnswer = 'create_answer',

View File

@ -145,10 +145,10 @@ FROM CALLER FROM CALLEE
Fledgling Fledgling Fledgling Fledgling
V `call()` V `handleInvite()`: setRemoteDescription(event.offer), add buffered candidates V `call()` V `handleInvite()`: setRemoteDescription(event.offer), add buffered candidates
WaitLocalMedia Ringing V Ringing
V media promise resolves V `answer()` V V `answer()`
V add local tracks WaitLocalMedia CreateOffer V
CreateOffer V media promise resolves V add local tracks V
V wait for negotionneeded events V add local tracks V wait for negotionneeded events V add local tracks
V setLocalDescription() CreateAnswer V setLocalDescription() CreateAnswer
V send invite event V setLocalDescription(createAnswer()) V send invite event V setLocalDescription(createAnswer())

View File

@ -60,7 +60,7 @@ export class Member {
// otherwise wait for it to connect // otherwise wait for it to connect
if (this.member.userId < this.options.ownUserId) { if (this.member.userId < this.options.ownUserId) {
this.peerCall = this._createPeerCall(makeId("c")); 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 */ /** @internal */
emitUpdate = (peerCall: PeerCall, params: any) => { emitUpdate = (peerCall: PeerCall, params: any) => {
if (peerCall.state === CallState.Ringing) { if (peerCall.state === CallState.Ringing) {
peerCall.answer(Promise.resolve(this.localMedia!)); peerCall.answer(this.localMedia!);
} }
this.options.emitUpdate(this, params); this.options.emitUpdate(this, params);
} }