fix: Only trigger onCall streams by latest call event for a call_id

This should fix that calls can get
started on
This commit is contained in:
Christian Pauly 2022-06-28 11:10:27 +02:00
parent c591c1d4b5
commit 0f17fec3f4
1 changed files with 69 additions and 34 deletions

View File

@ -1793,6 +1793,10 @@ class Client extends MatrixApi {
List<BasicEvent> events, List<BasicEvent> events,
EventUpdateType type, EventUpdateType type,
) async { ) async {
// Calling events can be omitted if they are outdated from the same sync. So
// we collect them first before we handle them.
final callEvents = <Event>{};
for (final event in events) { for (final event in events) {
// The client must ignore any new m.room.encryption event to prevent // The client must ignore any new m.room.encryption event to prevent
// man-in-the-middle attacks! // man-in-the-middle attacks!
@ -1828,44 +1832,75 @@ class Client extends MatrixApi {
} }
onEvent.add(update); onEvent.add(update);
final rawUnencryptedEvent = update.content;
if (prevBatch != null && type == EventUpdateType.timeline) { if (prevBatch != null && type == EventUpdateType.timeline) {
if (rawUnencryptedEvent['type'] == EventTypes.CallInvite) { if (update.content.tryGet<String>('type')?.startsWith('m.call.') ??
onCallInvite.add(Event.fromJson(rawUnencryptedEvent, room)); false) {
} else if (rawUnencryptedEvent['type'] == EventTypes.CallHangup) { final callEvent = Event.fromJson(update.content, room);
onCallHangup.add(Event.fromJson(rawUnencryptedEvent, room)); final callId = callEvent.content.tryGet<String>('call_id');
} else if (rawUnencryptedEvent['type'] == EventTypes.CallAnswer) { callEvents.add(callEvent);
onCallAnswer.add(Event.fromJson(rawUnencryptedEvent, room));
} else if (rawUnencryptedEvent['type'] == EventTypes.CallCandidates) { // Call Invites should be omitted for a call that is already answered,
onCallCandidates.add(Event.fromJson(rawUnencryptedEvent, room)); // has ended, is rejectd or replaced.
} else if (rawUnencryptedEvent['type'] == EventTypes.CallSelectAnswer) { const callEndedEventTypes = {
onCallSelectAnswer.add(Event.fromJson(rawUnencryptedEvent, room)); EventTypes.CallAnswer,
} else if (rawUnencryptedEvent['type'] == EventTypes.CallReject) { EventTypes.CallHangup,
onCallReject.add(Event.fromJson(rawUnencryptedEvent, room)); EventTypes.CallReject,
} else if (rawUnencryptedEvent['type'] == EventTypes.CallNegotiate) { EventTypes.CallReplaces,
onCallNegotiate.add(Event.fromJson(rawUnencryptedEvent, room)); };
} else if (rawUnencryptedEvent['type'] == EventTypes.CallReplaces) { const ommitWhenCallEndedTypes = {
onCallReplaces.add(Event.fromJson(rawUnencryptedEvent, room)); EventTypes.CallInvite,
} else if (rawUnencryptedEvent['type'] == EventTypes.CallCandidates,
EventTypes.CallAssertedIdentity || EventTypes.CallNegotiate,
rawUnencryptedEvent['type'] == EventTypes.CallSDPStreamMetadataChanged,
EventTypes.CallAssertedIdentityPrefix) { EventTypes.CallSDPStreamMetadataChangedPrefix,
onAssertedIdentityReceived };
.add(Event.fromJson(rawUnencryptedEvent, room));
} else if (rawUnencryptedEvent['type'] == if (callEndedEventTypes.contains(callEvent.type)) {
EventTypes.CallSDPStreamMetadataChanged || callEvents.removeWhere((event) {
rawUnencryptedEvent['type'] == if (ommitWhenCallEndedTypes.contains(event.type) &&
EventTypes.CallSDPStreamMetadataChangedPrefix) { event.content.tryGet<String>('call_id') == callId) {
onSDPStreamMetadataChangedReceived Logs().v(
.add(Event.fromJson(rawUnencryptedEvent, room)); 'Ommit "${event.type}" event for an already terminated call');
// TODO(duan): Only used (org.matrix.msc3401.call) during the current test, return true;
// need to add GroupCallPrefix in matrix_api_lite }
} else if (rawUnencryptedEvent['type'] == EventTypes.GroupCallPrefix) { return false;
onGroupCallRequest.add(Event.fromJson(rawUnencryptedEvent, room)); });
}
} }
} }
} }
callEvents.forEach(_callStreamByCallEvent);
}
void _callStreamByCallEvent(Event event) {
if (event.type == EventTypes.CallInvite) {
onCallInvite.add(event);
} else if (event.type == EventTypes.CallHangup) {
onCallHangup.add(event);
} else if (event.type == EventTypes.CallAnswer) {
onCallAnswer.add(event);
} else if (event.type == EventTypes.CallCandidates) {
onCallCandidates.add(event);
} else if (event.type == EventTypes.CallSelectAnswer) {
onCallSelectAnswer.add(event);
} else if (event.type == EventTypes.CallReject) {
onCallReject.add(event);
} else if (event.type == EventTypes.CallNegotiate) {
onCallNegotiate.add(event);
} else if (event.type == EventTypes.CallReplaces) {
onCallReplaces.add(event);
} else if (event.type == EventTypes.CallAssertedIdentity ||
event.type == EventTypes.CallAssertedIdentityPrefix) {
onAssertedIdentityReceived.add(event);
} else if (event.type == EventTypes.CallSDPStreamMetadataChanged ||
event.type == EventTypes.CallSDPStreamMetadataChangedPrefix) {
onSDPStreamMetadataChangedReceived.add(event);
// TODO(duan): Only used (org.matrix.msc3401.call) during the current test,
// need to add GroupCallPrefix in matrix_api_lite
} else if (event.type == EventTypes.GroupCallPrefix) {
onGroupCallRequest.add(event);
}
} }
Room _updateRoomsByRoomUpdate(String roomId, SyncRoomUpdate chatUpdate) { Room _updateRoomsByRoomUpdate(String roomId, SyncRoomUpdate chatUpdate) {