Skip to content

Commit

Permalink
Fix lack of media when a user reconnects (#3318)
Browse files Browse the repository at this point in the history
* 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.

* Fix tests
  • Loading branch information
dbkr authored Apr 26, 2023
1 parent 73dbd70 commit cfffa9c
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
4 changes: 4 additions & 0 deletions spec/unit/webrtc/groupCall.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,10 @@ describe("Group Call", function () {
call = new MockMatrixCall(room.roomId, groupCall.groupCallId);

await groupCall.create();

const deviceCallMap = new Map<string, MatrixCall>();
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 () => {
Expand Down
15 changes: 13 additions & 2 deletions src/webrtc/groupCall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
};

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit cfffa9c

Please sign in to comment.