singleShotStaleCallCheckerOnRoom method

Future<void> singleShotStaleCallCheckerOnRoom()

Implementation

Future<void> singleShotStaleCallCheckerOnRoom() async {
  Logs().d('[VOIP] checking for stale group calls in room $id');
  // make sure we have all the to-device messages we are supposed to have
  await client.oneShotSync();
  final copyGroupCallIds =
      states.tryGetMap<String, Event>(EventTypes.GroupCallPrefix);
  if (copyGroupCallIds == null) return;
  for (final groupCall in copyGroupCallIds.entries) {
    final groupCallId = groupCall.key;
    final groupCallEvent = groupCall.value;

    if (groupCallEvent.content.tryGet('m.intent') == 'm.room') return;
    if (!groupCallEvent.content.containsKey('m.terminated')) {
      Logs().i('[VOIP] found non terminated group call with id $groupCallId');
      // call is not empty but check for stale participants (gone offline)
      // with expire_ts
      bool callExpired = true; // assume call is expired
      final callMemberEvents =
          states.tryGetMap<String, Event>(EventTypes.GroupCallMemberPrefix);
      if (callMemberEvents != null) {
        for (var i = 0; i < callMemberEvents.length; i++) {
          final groupCallMemberEventMap =
              callMemberEvents.entries.toList()[i];

          final groupCallMemberEvent = groupCallMemberEventMap.value;
          callExpired =
              callMemberStateIsExpired(groupCallMemberEvent, groupCallId);
          // no need to iterate further even if one participant says call isn't expired
          if (!callExpired) break;
        }
      }

      if (callExpired) {
        Logs().i(
            '[VOIP] Group call with only expired timestamps detected, terminating');
        await sendGroupCallTerminateEvent(groupCallId);
      }
    }
  }
}