Merge pull request #1824 from famedly/td/fireNewPifJoined

preShareKey improvements
This commit is contained in:
td 2024-05-22 22:21:42 +05:30 committed by GitHub
commit 763bb0ba00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 63 additions and 36 deletions

View File

@ -73,6 +73,8 @@ abstract class CallBackend {
List<CallParticipant> anyLeft,
);
Future<void> preShareKey(GroupCallSession groupCall);
Future<void> requestEncrytionKey(
GroupCallSession groupCall,
List<CallParticipant> remoteParticipants,

View File

@ -52,9 +52,10 @@ class LiveKitBackend extends CallBackend {
return newIndex;
}
@override
Future<void> preShareKey(GroupCallSession groupCall) async {
await groupCall.onMemberStateChanged();
await _makeNewSenderKey(groupCall, false);
await _changeEncryptionKey(groupCall, groupCall.participants, false);
}
/// makes a new e2ee key for local user and sets it with a delay if specified
@ -120,6 +121,19 @@ class LiveKitBackend extends CallBackend {
);
}
Future<void> _changeEncryptionKey(
GroupCallSession groupCall,
List<CallParticipant> anyJoined,
bool delayBeforeUsingKeyOurself,
) async {
if (!e2eeEnabled) return;
if (groupCall.voip.enableSFUE2EEKeyRatcheting) {
await _ratchetLocalParticipantKey(groupCall, anyJoined);
} else {
await _makeNewSenderKey(groupCall, delayBeforeUsingKeyOurself);
}
}
/// sets incoming keys and also sends the key if it was for the local user
/// if sendTo is null, its sent to all _participants, see `_sendEncryptionKeysEvent`
Future<void> _setEncryptionKey(
@ -180,8 +194,6 @@ class LiveKitBackend extends CallBackend {
int keyIndex, {
List<CallParticipant>? sendTo,
}) async {
Logs().i('Sending encryption keys event');
final myKeys = _getKeysForParticipant(groupCall.localParticipant!);
final myLatestKey = myKeys?[keyIndex];
@ -235,6 +247,7 @@ class LiveKitBackend extends CallBackend {
Map<String, Object> data,
String eventType,
) async {
if (remoteParticipants.isEmpty) return;
Logs().v(
'[VOIP] _sendToDeviceEvent: sending ${data.toString()} to ${remoteParticipants.map((e) => e.id)} ');
final txid =
@ -392,14 +405,8 @@ class LiveKitBackend extends CallBackend {
Future<void> onNewParticipant(
GroupCallSession groupCall,
List<CallParticipant> anyJoined,
) async {
if (!e2eeEnabled) return;
if (groupCall.voip.enableSFUE2EEKeyRatcheting) {
await _ratchetLocalParticipantKey(groupCall, anyJoined);
} else {
await _makeNewSenderKey(groupCall, true);
}
}
) =>
_changeEncryptionKey(groupCall, anyJoined, true);
@override
Future<void> onLeftParticipant(

View File

@ -877,4 +877,9 @@ class MeshBackend extends CallBackend {
List<CallParticipant> remoteParticipants) async {
return;
}
@override
Future<void> preShareKey(GroupCallSession groupCall) async {
return;
}
}

View File

@ -48,7 +48,7 @@ class GroupCallSession {
CallParticipant? get localParticipant => voip.localParticipant;
List<CallParticipant> get participants => List.unmodifiable(_participants);
final List<CallParticipant> _participants = [];
final Set<CallParticipant> _participants = {};
String groupCallId;
@ -218,7 +218,7 @@ class GroupCallSession {
'[VOIP] Ignored ${mem.userId}\'s mem event ${mem.toJson()} while updating _participants list for callId: $groupCallId, expiry status: ${mem.isExpired}');
}
final List<CallParticipant> newP = [];
final Set<CallParticipant> newP = {};
for (final mem in memsForCurrentGroupCall) {
final rp = CallParticipant(
@ -239,23 +239,29 @@ class GroupCallSession {
await backend.setupP2PCallWithNewMember(this, rp, mem);
}
final newPcopy = List<CallParticipant>.from(newP);
final oldPcopy = List<CallParticipant>.from(_participants);
final anyJoined = newPcopy.where((element) => !oldPcopy.contains(element));
final anyLeft = oldPcopy.where((element) => !newPcopy.contains(element));
final newPcopy = Set<CallParticipant>.from(newP);
final oldPcopy = Set<CallParticipant>.from(_participants);
final anyJoined = newPcopy.difference(oldPcopy);
final anyLeft = oldPcopy.difference(newPcopy);
if (anyJoined.isNotEmpty || anyLeft.isNotEmpty) {
if (anyJoined.isNotEmpty) {
Logs().d('anyJoined: ${anyJoined.map((e) => e.id).toString()}');
final nonLocalAnyJoined = anyJoined..remove(localParticipant);
if (nonLocalAnyJoined.isNotEmpty && state == GroupCallState.entered) {
Logs().v(
'nonLocalAnyJoined: ${nonLocalAnyJoined.map((e) => e.id).toString()} roomId: ${room.id} groupCallId: $groupCallId');
await backend.onNewParticipant(this, nonLocalAnyJoined.toList());
}
_participants.addAll(anyJoined);
await backend.onNewParticipant(this, anyJoined.toList());
}
if (anyLeft.isNotEmpty) {
Logs().d('anyLeft: ${anyLeft.map((e) => e.id).toString()}');
for (final leftp in anyLeft) {
_participants.remove(leftp);
final nonLocalAnyLeft = anyLeft..remove(localParticipant);
if (nonLocalAnyLeft.isNotEmpty && state == GroupCallState.entered) {
Logs().v(
'nonLocalAnyLeft: ${nonLocalAnyLeft.map((e) => e.id).toString()} roomId: ${room.id} groupCallId: $groupCallId');
await backend.onLeftParticipant(this, nonLocalAnyLeft.toList());
}
await backend.onLeftParticipant(this, anyLeft.toList());
_participants.removeAll(anyLeft);
}
onGroupCallEvent.add(GroupCallStateChange.participantsChanged);

View File

@ -756,37 +756,44 @@ class VoIP {
/// [application] normal group call, thrirdroom, etc
///
/// [scope] room, between specifc users, etc.
///
/// [preShareKey] for livekit calls it creates and shares a key with other
/// participants in the call without entering, useful on onboarding screens.
/// does not do anything in mesh calls
Future<GroupCallSession> fetchOrCreateGroupCall(
String groupCallId,
Room room,
CallBackend backend,
String? application,
String? scope,
) async {
String? scope, {
bool preShareKey = true,
}) async {
if (!room.groupCallsEnabledForEveryone) {
await room.enableGroupCalls();
}
final groupCall = getGroupCallById(room.id, groupCallId);
if (groupCall != null) {
if (!room.canJoinGroupCall) {
throw MatrixSDKVoipException(
'User ${client.userID}:${client.deviceID} is not allowed to join famedly calls in room ${room.id}, canJoinGroupCall: ${room.canJoinGroupCall}, room.canJoinGroupCall: ${room.groupCallsEnabledForEveryone}',
);
}
return groupCall;
if (!room.canJoinGroupCall) {
throw MatrixSDKVoipException(
'User ${client.userID}:${client.deviceID} is not allowed to join famedly calls in room ${room.id}, canJoinGroupCall: ${room.canJoinGroupCall}, room.canJoinGroupCall: ${room.groupCallsEnabledForEveryone}',
);
}
// The call doesn't exist, but we can create it
return await _newGroupCall(
GroupCallSession? groupCall = getGroupCallById(room.id, groupCallId);
groupCall ??= await _newGroupCall(
groupCallId,
room,
backend,
application,
scope,
);
if (preShareKey) {
await groupCall.backend.preShareKey(groupCall);
}
return groupCall;
}
GroupCallSession? getGroupCallById(String roomId, String groupCallId) {