Skip to content

Commit 0af2f79

Browse files
committed
Refactor state handling
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
1 parent 7799804 commit 0af2f79

File tree

2 files changed

+29
-25
lines changed

2 files changed

+29
-25
lines changed

spec/unit/webrtc/call.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,7 +1392,7 @@ describe('Call', function() {
13921392
it("ends call on onHangupReceived() if state is ringing", async () => {
13931393
expect(call.callHasEnded()).toBe(false);
13941394

1395-
call.state = CallState.Ringing;
1395+
(call as any).state = CallState.Ringing;
13961396
call.onHangupReceived({} as MCallHangupReject);
13971397

13981398
expect(call.callHasEnded()).toBe(true);
@@ -1424,7 +1424,7 @@ describe('Call', function() {
14241424
)("ends call on onRejectReceived() if in correct state (state=%s)", async (state: CallState) => {
14251425
expect(call.callHasEnded()).toBe(false);
14261426

1427-
call.state = state;
1427+
(call as any).state = state;
14281428
call.onRejectReceived({} as MCallHangupReject);
14291429

14301430
expect(call.callHasEnded()).toBe(

src/webrtc/call.ts

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,6 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
334334
public roomId?: string;
335335
public callId: string;
336336
public invitee?: string;
337-
public state = CallState.Fledgling;
338337
public hangupParty?: CallParty;
339338
public hangupReason?: string;
340339
public direction?: CallDirection;
@@ -346,6 +345,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
346345
// This should be set by the consumer on incoming & outgoing calls.
347346
public isPtt = false;
348347

348+
private _state = CallState.Fledgling;
349349
private readonly client: MatrixClient;
350350
private readonly forceTURN?: boolean;
351351
private readonly turnServers: Array<TurnServer>;
@@ -482,6 +482,16 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
482482
return this.remoteAssertedIdentity;
483483
}
484484

485+
public get state(): CallState {
486+
return this._state;
487+
}
488+
489+
private set state(state: CallState) {
490+
const oldState = this._state;
491+
this._state = state;
492+
this.emit(CallEvent.State, state, oldState);
493+
}
494+
485495
public get type(): CallType {
486496
return (this.hasLocalUserMediaVideoTrack || this.hasRemoteUserMediaVideoTrack)
487497
? CallType.Video
@@ -928,15 +938,15 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
928938
return;
929939
}
930940

931-
this.setState(CallState.Ringing);
941+
this.state = CallState.Ringing;
932942

933943
if (event.getLocalAge()) {
934944
// Time out the call if it's ringing for too long
935945
const ringingTimer = setTimeout(() => {
936946
if (this.state == CallState.Ringing) {
937947
logger.debug(`Call ${this.callId} invite has expired. Hanging up.`);
938948
this.hangupParty = CallParty.Remote; // effectively
939-
this.setState(CallState.Ended);
949+
this.state = CallState.Ended;
940950
this.stopAllMedia();
941951
if (this.peerConn!.signalingState != 'closed') {
942952
this.peerConn!.close();
@@ -963,7 +973,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
963973
// perverse as it may seem, sometimes we want to instantiate a call with a
964974
// hangup message (because when getting the state of the room on load, events
965975
// come in reverse order and we want to remember that a call has been hung up)
966-
this.setState(CallState.Ended);
976+
this.state = CallState.Ended;
967977
}
968978

969979
private shouldAnswerWithMediaType(
@@ -1004,7 +1014,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
10041014
const answerWithAudio = this.shouldAnswerWithMediaType(audio, this.hasRemoteUserMediaAudioTrack, "audio");
10051015
const answerWithVideo = this.shouldAnswerWithMediaType(video, this.hasRemoteUserMediaVideoTrack, "video");
10061016

1007-
this.setState(CallState.WaitLocalMedia);
1017+
this.state = CallState.WaitLocalMedia;
10081018
this.waitForLocalAVStream = true;
10091019

10101020
try {
@@ -1034,7 +1044,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
10341044
if (answerWithVideo) {
10351045
// Try to answer without video
10361046
logger.warn(`Call ${this.callId} Failed to getUserMedia(), trying to getUserMedia() without video`);
1037-
this.setState(prevState);
1047+
this.state = prevState;
10381048
this.waitForLocalAVStream = false;
10391049
await this.answer(answerWithAudio, false);
10401050
} else {
@@ -1043,7 +1053,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
10431053
}
10441054
}
10451055
} else if (this.waitForLocalAVStream) {
1046-
this.setState(CallState.WaitLocalMedia);
1056+
this.state = CallState.WaitLocalMedia;
10471057
}
10481058
}
10491059

@@ -1495,7 +1505,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
14951505
});
14961506
}
14971507

1498-
this.setState(CallState.CreateOffer);
1508+
this.state = CallState.CreateOffer;
14991509

15001510
logger.debug(`Call ${this.callId} gotUserMediaForInvite`);
15011511
// Now we wait for the negotiationneeded event
@@ -1530,7 +1540,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
15301540
this.inviteOrAnswerSent = true;
15311541
} catch (error) {
15321542
// We've failed to answer: back to the ringing state
1533-
this.setState(CallState.Ringing);
1543+
this.state = CallState.Ringing;
15341544
if (error instanceof MatrixError && error.event) this.client.cancelPendingEvent(error.event);
15351545

15361546
let code = CallErrorCode.SendAnswer;
@@ -1627,7 +1637,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
16271637
this.pushLocalFeed(feed);
16281638
}
16291639

1630-
this.setState(CallState.CreateAnswer);
1640+
this.state = CallState.CreateAnswer;
16311641

16321642
let answer: RTCSessionDescriptionInit;
16331643
try {
@@ -1645,7 +1655,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
16451655
// make sure we're still going
16461656
if (this.callHasEnded()) return;
16471657

1648-
this.setState(CallState.Connecting);
1658+
this.state = CallState.Connecting;
16491659

16501660
// Allow a short time for initial candidates to be gathered
16511661
await new Promise(resolve => {
@@ -1762,7 +1772,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
17621772
this.chooseOpponent(event);
17631773
await this.addBufferedIceCandidates();
17641774

1765-
this.setState(CallState.Connecting);
1775+
this.state = CallState.Connecting;
17661776

17671777
const sdpStreamMetadata = content[SDPStreamMetadataKey];
17681778
if (sdpStreamMetadata) {
@@ -2034,7 +2044,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
20342044
this.sendCandidateQueue();
20352045
if (this.state === CallState.CreateOffer) {
20362046
this.inviteOrAnswerSent = true;
2037-
this.setState(CallState.InviteSent);
2047+
this.state = CallState.InviteSent;
20382048
this.inviteTimeout = setTimeout(() => {
20392049
this.inviteTimeout = undefined;
20402050
if (this.state === CallState.InviteSent) {
@@ -2088,7 +2098,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
20882098
// chrome doesn't implement any of the 'onstarted' events yet
20892099
if (["connected", "completed"].includes(this.peerConn?.iceConnectionState ?? '')) {
20902100
clearTimeout(this.iceDisconnectedTimeout);
2091-
this.setState(CallState.Connected);
2101+
this.state = CallState.Connected;
20922102

20932103
if (!this.callLengthInterval) {
20942104
this.callLengthInterval = setInterval(() => {
@@ -2112,7 +2122,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
21122122
logger.info(`Hanging up call ${this.callId} (ICE disconnected for too long)`);
21132123
this.hangup(CallErrorCode.IceFailed, false);
21142124
}, 30 * 1000);
2115-
this.setState(CallState.Connecting);
2125+
this.state = CallState.Connecting;
21162126
}
21172127

21182128
// In PTT mode, override feed status to muted when we lose connection to
@@ -2244,12 +2254,6 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
22442254
this.terminate(CallParty.Remote, CallErrorCode.AnsweredElsewhere, true);
22452255
};
22462256

2247-
private setState(state: CallState): void {
2248-
const oldState = this.state;
2249-
this.state = state;
2250-
this.emit(CallEvent.State, state, oldState);
2251-
}
2252-
22532257
/**
22542258
* Internal
22552259
* @param {string} eventType
@@ -2444,7 +2448,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
24442448

24452449
this.hangupParty = hangupParty;
24462450
this.hangupReason = hangupReason;
2447-
this.setState(CallState.Ended);
2451+
this.state = CallState.Ended;
24482452

24492453
if (this.inviteTimeout) {
24502454
clearTimeout(this.inviteTimeout);
@@ -2578,7 +2582,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
25782582
if (!audio) {
25792583
throw new Error("You CANNOT start a call without audio");
25802584
}
2581-
this.setState(CallState.WaitLocalMedia);
2585+
this.state = CallState.WaitLocalMedia;
25822586

25832587
try {
25842588
const stream = await this.client.getMediaHandler().getUserMediaStream(audio, video);

0 commit comments

Comments
 (0)