From 3e9ac7021771fc93f4d9647247d063b715073db8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 25 Apr 2023 18:33:20 +0100 Subject: [PATCH 1/2] Fix lack of media when a user reconnects This fixes broken media when someone reconnects to the call after a forced disconnect (when their old call gets replaced immediately by a new call). We listen for changes in the call feeds and the tearing down of the feeds for the old call caused us to remove the feed for the new call. Also adds the call to the calls map before it'as initialised, such that it's the active call for the user/device when the feedsChanged event arrives, otherwise we'll ignore the event. --- src/webrtc/groupCall.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/webrtc/groupCall.ts b/src/webrtc/groupCall.ts index 3bc18472d23..0207cf1d5a5 100644 --- a/src/webrtc/groupCall.ts +++ b/src/webrtc/groupCall.ts @@ -881,6 +881,11 @@ export class GroupCall extends TypedEventEmitter< ); if (prevCall) prevCall.hangup(CallErrorCode.Replaced, false); + // We must do this before we start initialising / answering the call as we + // need to know it is the active call for this user+deviceId and to not ignore + // events from it. + deviceMap.set(newCall.getOpponentDeviceId()!, newCall); + this.calls.set(opponentUserId, deviceMap); this.initCall(newCall); @@ -895,8 +900,6 @@ export class GroupCall extends TypedEventEmitter< } newCall.answerWithCallFeeds(feeds); - deviceMap.set(newCall.getOpponentDeviceId()!, newCall); - this.calls.set(opponentUserId, deviceMap); this.emit(GroupCallEvent.CallsChanged, this.calls); }; @@ -1138,6 +1141,14 @@ export class GroupCall extends TypedEventEmitter< const remoteUsermediaFeed = call.remoteUsermediaFeed; const remoteFeedChanged = remoteUsermediaFeed !== currentUserMediaFeed; + const deviceMap = this.calls.get(opponentMemberId); + const currentCallForUserDevice = deviceMap?.get(opponentDeviceId); + if (currentCallForUserDevice?.callId !== call.callId) { + // the call in question is not the current call for this user/deviceId + // so ignore feed events from it otherwise we'll remove our real feeds + return; + } + if (remoteFeedChanged) { if (!currentUserMediaFeed && remoteUsermediaFeed) { this.addUserMediaFeed(remoteUsermediaFeed); From fbb614fd92b185b1e6b225b0ff769ed3e49bde9d Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 25 Apr 2023 18:56:56 +0100 Subject: [PATCH 2/2] Fix tests --- spec/unit/webrtc/groupCall.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/unit/webrtc/groupCall.spec.ts b/spec/unit/webrtc/groupCall.spec.ts index 04f67c862a9..3d344266ae1 100644 --- a/spec/unit/webrtc/groupCall.spec.ts +++ b/spec/unit/webrtc/groupCall.spec.ts @@ -388,6 +388,10 @@ describe("Group Call", function () { call = new MockMatrixCall(room.roomId, groupCall.groupCallId); await groupCall.create(); + + const deviceCallMap = new Map(); + deviceCallMap.set(FAKE_DEVICE_ID_1, call.typed()); + (groupCall as any).calls.set(FAKE_USER_ID_1, deviceCallMap); }); it("ignores changes, if we can't get user id of opponent", async () => {