fix: do not proceed call if getUserMedia fails
fix: added a few missing awaits fix: add a workaround for not having state updates for staleCallChecker till sync chore: fix some logging
This commit is contained in:
parent
8f44c7f33f
commit
66a53786e7
|
|
@ -358,7 +358,7 @@ class CallSession {
|
||||||
final CachedStreamController<CallSession> onCallReplaced =
|
final CachedStreamController<CallSession> onCallReplaced =
|
||||||
CachedStreamController();
|
CachedStreamController();
|
||||||
|
|
||||||
final CachedStreamController<CallSession> onCallHangup =
|
final CachedStreamController<CallSession> onCallHangupNotifierForGroupCalls =
|
||||||
CachedStreamController();
|
CachedStreamController();
|
||||||
|
|
||||||
final CachedStreamController<CallState> onCallStateChanged =
|
final CachedStreamController<CallState> onCallStateChanged =
|
||||||
|
|
@ -435,6 +435,7 @@ class CallSession {
|
||||||
Timer? inviteTimer;
|
Timer? inviteTimer;
|
||||||
Timer? ringingTimer;
|
Timer? ringingTimer;
|
||||||
|
|
||||||
|
// outgoing call
|
||||||
Future<void> initOutboundCall(CallType type) async {
|
Future<void> initOutboundCall(CallType type) async {
|
||||||
await _preparePeerConnection();
|
await _preparePeerConnection();
|
||||||
setCallState(CallState.kCreateOffer);
|
setCallState(CallState.kCreateOffer);
|
||||||
|
|
@ -444,6 +445,7 @@ class CallSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// incoming call
|
||||||
Future<void> initWithInvite(CallType type, RTCSessionDescription offer,
|
Future<void> initWithInvite(CallType type, RTCSessionDescription offer,
|
||||||
SDPStreamMetadata? metadata, int lifetime, bool isGroupCall) async {
|
SDPStreamMetadata? metadata, int lifetime, bool isGroupCall) async {
|
||||||
if (!isGroupCall) {
|
if (!isGroupCall) {
|
||||||
|
|
@ -491,6 +493,12 @@ class CallSession {
|
||||||
final stream = await _getUserMedia(type);
|
final stream = await _getUserMedia(type);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
await addLocalStream(stream, SDPStreamMetadataPurpose.Usermedia);
|
await addLocalStream(stream, SDPStreamMetadataPurpose.Usermedia);
|
||||||
|
} else {
|
||||||
|
// we don't have a localstream, call probably crashed
|
||||||
|
// for sanity
|
||||||
|
if (state == CallState.kEnded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -597,10 +605,6 @@ class CallSession {
|
||||||
// Now we wait for the negotiationneeded event
|
// Now we wait for the negotiationneeded event
|
||||||
}
|
}
|
||||||
|
|
||||||
void initWithHangup() {
|
|
||||||
setCallState(CallState.kEnded);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> onAnswerReceived(
|
Future<void> onAnswerReceived(
|
||||||
RTCSessionDescription answer, SDPStreamMetadata? metadata) async {
|
RTCSessionDescription answer, SDPStreamMetadata? metadata) async {
|
||||||
if (metadata != null) {
|
if (metadata != null) {
|
||||||
|
|
@ -658,9 +662,9 @@ class CallSession {
|
||||||
type: answer.type!);
|
type: answer.type!);
|
||||||
await pc!.setLocalDescription(answer);
|
await pc!.setLocalDescription(answer);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e, s) {
|
||||||
_getLocalOfferFailed(e);
|
Logs().e('[VOIP] onNegotiateReceived => ', e, s);
|
||||||
Logs().e('[VOIP] onNegotiateReceived => ${e.toString()}');
|
await _getLocalOfferFailed(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -740,8 +744,8 @@ class CallSession {
|
||||||
if (pc != null && inviteOrAnswerSent && remotePartyId != null) {
|
if (pc != null && inviteOrAnswerSent && remotePartyId != null) {
|
||||||
try {
|
try {
|
||||||
await pc!.addCandidate(candidate);
|
await pc!.addCandidate(candidate);
|
||||||
} catch (e) {
|
} catch (e, s) {
|
||||||
Logs().e('[VOIP] onCandidatesReceived => ${e.toString()}');
|
Logs().e('[VOIP] onCandidatesReceived => ', e, s);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
remoteCandidates.add(candidate);
|
remoteCandidates.add(candidate);
|
||||||
|
|
@ -810,8 +814,8 @@ class CallSession {
|
||||||
await _removeStream(localScreenSharingStream!.stream!);
|
await _removeStream(localScreenSharingStream!.stream!);
|
||||||
fireCallEvent(CallEvent.kFeedsChanged);
|
fireCallEvent(CallEvent.kFeedsChanged);
|
||||||
return false;
|
return false;
|
||||||
} catch (e) {
|
} catch (e, s) {
|
||||||
Logs().e('[VOIP] stopping screen sharing track failed', e);
|
Logs().e('[VOIP] stopping screen sharing track failed', e, s);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1130,12 +1134,11 @@ class CallSession {
|
||||||
/// Reject a call
|
/// Reject a call
|
||||||
/// This used to be done by calling hangup, but is a separate method and protocol
|
/// This used to be done by calling hangup, but is a separate method and protocol
|
||||||
/// event as of MSC2746.
|
/// event as of MSC2746.
|
||||||
///
|
|
||||||
Future<void> reject({String? reason, bool shouldEmit = true}) async {
|
Future<void> reject({String? reason, bool shouldEmit = true}) async {
|
||||||
// stop play ringtone
|
|
||||||
await voip.delegate.stopRingtone();
|
|
||||||
if (state != CallState.kRinging && state != CallState.kFledgling) {
|
if (state != CallState.kRinging && state != CallState.kFledgling) {
|
||||||
Logs().e('[VOIP] Call must be in \'ringing|fledgling\' state to reject!');
|
Logs().e(
|
||||||
|
'[VOIP] Call must be in \'ringing|fledgling\' state to reject! (current state was: ${state.toString()}) Calling hangup instead');
|
||||||
|
await hangup(reason, shouldEmit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Logs().d('[VOIP] Rejecting call: $callId');
|
Logs().d('[VOIP] Rejecting call: $callId');
|
||||||
|
|
@ -1146,12 +1149,9 @@ class CallSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> hangup([String? reason, bool suppressEvent = false]) async {
|
Future<void> hangup([String? reason, bool shouldEmit = true]) async {
|
||||||
// stop play ringtone
|
|
||||||
await voip.delegate.stopRingtone();
|
|
||||||
|
|
||||||
await terminate(
|
await terminate(
|
||||||
CallParty.kLocal, reason ?? CallErrorCode.UserHangup, !suppressEvent);
|
CallParty.kLocal, reason ?? CallErrorCode.UserHangup, shouldEmit);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final res =
|
final res =
|
||||||
|
|
@ -1174,11 +1174,11 @@ class CallSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> terminate(
|
Future<void> terminate(
|
||||||
CallParty party, String reason, bool shouldEmit) async {
|
CallParty party,
|
||||||
if (state == CallState.kEnded) {
|
String reason,
|
||||||
return;
|
bool shouldEmit,
|
||||||
}
|
) async {
|
||||||
|
Logs().d('[VOIP] terminating call');
|
||||||
inviteTimer?.cancel();
|
inviteTimer?.cancel();
|
||||||
inviteTimer = null;
|
inviteTimer = null;
|
||||||
|
|
||||||
|
|
@ -1195,9 +1195,9 @@ class CallSession {
|
||||||
hangupParty = party;
|
hangupParty = party;
|
||||||
hangupReason = reason;
|
hangupReason = reason;
|
||||||
|
|
||||||
if (shouldEmit) {
|
// don't see any reason to wrap this with shouldEmit atm,
|
||||||
setCallState(CallState.kEnded);
|
// looks like a local state change only
|
||||||
}
|
setCallState(CallState.kEnded);
|
||||||
|
|
||||||
if (!isGroupCall) {
|
if (!isGroupCall) {
|
||||||
if (callId != voip.currentCID) return;
|
if (callId != voip.currentCID) return;
|
||||||
|
|
@ -1209,7 +1209,7 @@ class CallSession {
|
||||||
|
|
||||||
await cleanUp();
|
await cleanUp();
|
||||||
if (shouldEmit) {
|
if (shouldEmit) {
|
||||||
onCallHangup.add(this);
|
onCallHangupNotifierForGroupCalls.add(this);
|
||||||
await voip.delegate.handleCallEnded(this);
|
await voip.delegate.handleCallEnded(this);
|
||||||
fireCallEvent(CallEvent.kHangup);
|
fireCallEvent(CallEvent.kHangup);
|
||||||
if ((party == CallParty.kRemote && missedCall)) {
|
if ((party == CallParty.kRemote && missedCall)) {
|
||||||
|
|
@ -1273,7 +1273,6 @@ class CallSession {
|
||||||
// just incase we ended the call but already sent the invite
|
// just incase we ended the call but already sent the invite
|
||||||
if (state == CallState.kEnded) {
|
if (state == CallState.kEnded) {
|
||||||
await hangup(CallErrorCode.Replaced, false);
|
await hangup(CallErrorCode.Replaced, false);
|
||||||
setCallState(CallState.kEnded);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inviteOrAnswerSent = true;
|
inviteOrAnswerSent = true;
|
||||||
|
|
@ -1313,7 +1312,7 @@ class CallSession {
|
||||||
final offer = await pc!.createOffer({});
|
final offer = await pc!.createOffer({});
|
||||||
await _gotLocalOffer(offer);
|
await _gotLocalOffer(offer);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_getLocalOfferFailed(e);
|
await _getLocalOfferFailed(e);
|
||||||
return;
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
makingOffer = false;
|
makingOffer = false;
|
||||||
|
|
@ -1377,9 +1376,9 @@ class CallSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onAnsweredElsewhere() {
|
Future<void> onAnsweredElsewhere() async {
|
||||||
Logs().d('Call ID $callId answered elsewhere');
|
Logs().d('Call ID $callId answered elsewhere');
|
||||||
terminate(CallParty.kRemote, CallErrorCode.AnsweredElsewhere, true);
|
await terminate(CallParty.kRemote, CallErrorCode.AnsweredElsewhere, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> cleanUp() async {
|
Future<void> cleanUp() async {
|
||||||
|
|
@ -1388,8 +1387,8 @@ class CallSession {
|
||||||
await stream.dispose();
|
await stream.dispose();
|
||||||
}
|
}
|
||||||
streams.clear();
|
streams.clear();
|
||||||
} catch (e) {
|
} catch (e, s) {
|
||||||
Logs().e('[VOIP] cleaning up streams failed', e);
|
Logs().e('[VOIP] cleaning up streams failed', e, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -1397,8 +1396,8 @@ class CallSession {
|
||||||
await pc!.close();
|
await pc!.close();
|
||||||
await pc!.dispose();
|
await pc!.dispose();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e, s) {
|
||||||
Logs().e('[VOIP] removing pc failed', e);
|
Logs().e('[VOIP] removing pc failed', e, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1468,7 +1467,7 @@ class CallSession {
|
||||||
try {
|
try {
|
||||||
return await voip.delegate.mediaDevices.getUserMedia(mediaConstraints);
|
return await voip.delegate.mediaDevices.getUserMedia(mediaConstraints);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_getUserMediaFailed(e);
|
await _getUserMediaFailed(e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -1481,7 +1480,7 @@ class CallSession {
|
||||||
try {
|
try {
|
||||||
return await voip.delegate.mediaDevices.getDisplayMedia(mediaConstraints);
|
return await voip.delegate.mediaDevices.getDisplayMedia(mediaConstraints);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_getUserMediaFailed(e);
|
await _getUserMediaFailed(e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -1614,15 +1613,15 @@ class CallSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getLocalOfferFailed(dynamic err) {
|
Future<void> _getLocalOfferFailed(dynamic err) async {
|
||||||
Logs().e('Failed to get local offer ${err.toString()}');
|
Logs().e('Failed to get local offer ${err.toString()}');
|
||||||
fireCallEvent(CallEvent.kError);
|
fireCallEvent(CallEvent.kError);
|
||||||
lastError = CallError(
|
lastError = CallError(
|
||||||
CallErrorCode.LocalOfferFailed, 'Failed to get local offer!', err);
|
CallErrorCode.LocalOfferFailed, 'Failed to get local offer!', err);
|
||||||
terminate(CallParty.kLocal, CallErrorCode.LocalOfferFailed, false);
|
await terminate(CallParty.kLocal, CallErrorCode.LocalOfferFailed, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getUserMediaFailed(dynamic err) {
|
Future<void> _getUserMediaFailed(dynamic err) async {
|
||||||
if (state != CallState.kConnected) {
|
if (state != CallState.kConnected) {
|
||||||
Logs().w('Failed to get user media - ending call ${err.toString()}');
|
Logs().w('Failed to get user media - ending call ${err.toString()}');
|
||||||
fireCallEvent(CallEvent.kError);
|
fireCallEvent(CallEvent.kError);
|
||||||
|
|
@ -1630,11 +1629,11 @@ class CallSession {
|
||||||
CallErrorCode.NoUserMedia,
|
CallErrorCode.NoUserMedia,
|
||||||
'Couldn\'t start capturing media! Is your microphone set up and does this app have permission?',
|
'Couldn\'t start capturing media! Is your microphone set up and does this app have permission?',
|
||||||
err);
|
err);
|
||||||
terminate(CallParty.kLocal, CallErrorCode.NoUserMedia, false);
|
await terminate(CallParty.kLocal, CallErrorCode.NoUserMedia, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onSelectAnswerReceived(String? selectedPartyId) {
|
Future<void> onSelectAnswerReceived(String? selectedPartyId) async {
|
||||||
if (direction != CallDirection.kIncoming) {
|
if (direction != CallDirection.kIncoming) {
|
||||||
Logs().w('Got select_answer for an outbound call: ignoring');
|
Logs().w('Got select_answer for an outbound call: ignoring');
|
||||||
return;
|
return;
|
||||||
|
|
@ -1649,7 +1648,7 @@ class CallSession {
|
||||||
Logs().w(
|
Logs().w(
|
||||||
'Got select_answer for party ID $selectedPartyId: we are party ID $localPartyId.');
|
'Got select_answer for party ID $selectedPartyId: we are party ID $localPartyId.');
|
||||||
// The other party has picked somebody else's answer
|
// The other party has picked somebody else's answer
|
||||||
terminate(CallParty.kRemote, CallErrorCode.AnsweredElsewhere, true);
|
await terminate(CallParty.kRemote, CallErrorCode.AnsweredElsewhere, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,9 @@ class ConnectionTester {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e, s) {
|
||||||
Logs().e('[VOIP] ConnectionTester Error while testing TURN server: $e');
|
Logs()
|
||||||
|
.e('[VOIP] ConnectionTester Error while testing TURN server: ', e, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose();
|
dispose();
|
||||||
|
|
|
||||||
|
|
@ -340,8 +340,8 @@ class GroupCall {
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
return await voip.delegate.mediaDevices.getDisplayMedia(mediaConstraints);
|
return await voip.delegate.mediaDevices.getDisplayMedia(mediaConstraints);
|
||||||
} catch (e) {
|
} catch (e, s) {
|
||||||
setState(GroupCallState.LocalCallFeedUninitialized);
|
Logs().e('[VOIP] _getDisplayMedia failed because,', e, s);
|
||||||
}
|
}
|
||||||
return Null as MediaStream;
|
return Null as MediaStream;
|
||||||
}
|
}
|
||||||
|
|
@ -627,10 +627,10 @@ class GroupCall {
|
||||||
await sendMemberStateEvent();
|
await sendMemberStateEvent();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (e, s) {
|
||||||
Logs().e('Enabling screensharing error', error);
|
Logs().e('Enabling screensharing error', e, s);
|
||||||
lastError = GroupCallError(GroupCallErrorCode.NoUserMedia,
|
lastError = GroupCallError(GroupCallErrorCode.NoUserMedia,
|
||||||
'Failed to get screen-sharing stream: ', error);
|
'Failed to get screen-sharing stream: ', e);
|
||||||
onGroupCallEvent.add(GroupCallEvent.Error);
|
onGroupCallEvent.add(GroupCallEvent.Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -994,7 +994,7 @@ class GroupCall {
|
||||||
await onStreamsChanged(call);
|
await onStreamsChanged(call);
|
||||||
});
|
});
|
||||||
|
|
||||||
call.onCallHangup.stream.listen((event) async {
|
call.onCallHangupNotifierForGroupCalls.stream.listen((event) async {
|
||||||
await onCallHangup(call);
|
await onCallHangup(call);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@ Future<void> stopMediaStream(MediaStream? stream) async {
|
||||||
for (final track in stream.getTracks()) {
|
for (final track in stream.getTracks()) {
|
||||||
try {
|
try {
|
||||||
await track.stop();
|
await track.stop();
|
||||||
} catch (e) {
|
} catch (e, s) {
|
||||||
Logs().e('[VOIP] stopping track ${track.id} failed', e);
|
Logs().e('[VOIP] stopping track ${track.id} failed', e, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await stream.dispose();
|
await stream.dispose();
|
||||||
} catch (e) {
|
} catch (e, s) {
|
||||||
Logs().e('[VOIP] disposing stream ${stream.id} failed', e);
|
Logs().e('[VOIP] disposing stream ${stream.id} failed', e, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ class VoIP {
|
||||||
await delegate.stopRingtone();
|
await delegate.stopRingtone();
|
||||||
}
|
}
|
||||||
if (call.state == CallState.kRinging) {
|
if (call.state == CallState.kRinging) {
|
||||||
call.onAnsweredElsewhere();
|
await call.onAnsweredElsewhere();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -368,7 +368,7 @@ class VoIP {
|
||||||
}
|
}
|
||||||
await call.onRejectReceived(content['reason']);
|
await call.onRejectReceived(content['reason']);
|
||||||
} else {
|
} else {
|
||||||
Logs().v('[VOIP] onCallHangup: Session [$callId] not found!');
|
Logs().v('[VOIP] onCallReject: Session [$callId] not found!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -408,7 +408,7 @@ class VoIP {
|
||||||
'Ignoring call select answer for room $roomId claiming to be for call in room ${call.room.id}');
|
'Ignoring call select answer for room $roomId claiming to be for call in room ${call.room.id}');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
call.onSelectAnswerReceived(selectedPartyId);
|
await call.onSelectAnswerReceived(selectedPartyId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -486,8 +486,8 @@ class VoIP {
|
||||||
}
|
}
|
||||||
await call.onNegotiateReceived(metadata,
|
await call.onNegotiateReceived(metadata,
|
||||||
RTCSessionDescription(description['sdp'], description['type']));
|
RTCSessionDescription(description['sdp'], description['type']));
|
||||||
} catch (err) {
|
} catch (e, s) {
|
||||||
Logs().e('Failed to complete negotiation ${err.toString()}');
|
Logs().e('Failed to complete negotiation', e, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -498,8 +498,8 @@ class VoIP {
|
||||||
if (session['media'].indexWhere((e) => e['type'] == 'video') != -1) {
|
if (session['media'].indexWhere((e) => e['type'] == 'video') != -1) {
|
||||||
return CallType.kVideo;
|
return CallType.kVideo;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (e, s) {
|
||||||
Logs().e('Failed to getCallType ${err.toString()}');
|
Logs().e('Failed to getCallType', e, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CallType.kVoice;
|
return CallType.kVoice;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ extension GroupCallUtils on Room {
|
||||||
if (staleGroupCallsTimer.tryGet(roomId) != null) {
|
if (staleGroupCallsTimer.tryGet(roomId) != null) {
|
||||||
staleGroupCallsTimer[roomId]!.cancel();
|
staleGroupCallsTimer[roomId]!.cancel();
|
||||||
staleGroupCallsTimer.remove(roomId);
|
staleGroupCallsTimer.remove(roomId);
|
||||||
Logs().d('stopped stale group calls checker for room $id');
|
Logs().d('[VOIP] stopped stale group calls checker for room $id');
|
||||||
} else {
|
} else {
|
||||||
Logs().d('[VOIP] no stale call checker for room found');
|
Logs().d('[VOIP] no stale call checker for room found');
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +70,22 @@ extension GroupCallUtils on Room {
|
||||||
device.expires_ts! < DateTime.now().millisecondsSinceEpoch);
|
device.expires_ts! < DateTime.now().millisecondsSinceEpoch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
// Last 30 seconds to get yourself together.
|
||||||
|
// This saves us from accidentally killing calls which were just created and
|
||||||
|
// whose state event we haven't recieved yet in sync.
|
||||||
|
// (option 2 was local echo member state events, but reverting them if anything
|
||||||
|
// fails sounds pain)
|
||||||
|
|
||||||
|
final expiredfr = groupCallMemberStateEvent.originServerTs
|
||||||
|
.add(staleCallCheckerDuration)
|
||||||
|
.millisecondsSinceEpoch <
|
||||||
|
DateTime.now().millisecondsSinceEpoch;
|
||||||
|
if (!expiredfr) {
|
||||||
|
Logs().d(
|
||||||
|
'[VOIP] Last 30 seconds for state event from ${groupCallMemberStateEvent.senderId}');
|
||||||
|
}
|
||||||
|
return expiredfr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// checks for stale calls in a room and sends `m.terminated` if all the
|
/// checks for stale calls in a room and sends `m.terminated` if all the
|
||||||
|
|
@ -85,7 +100,7 @@ extension GroupCallUtils on Room {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> singleShotStaleCallCheckerOnRoom() async {
|
Future<void> singleShotStaleCallCheckerOnRoom() async {
|
||||||
Logs().d('checking for stale group calls in room $id');
|
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
|
// make sure we have all the to-device messages we are supposed to have
|
||||||
await client.oneShotSync();
|
await client.oneShotSync();
|
||||||
final copyGroupCallIds =
|
final copyGroupCallIds =
|
||||||
|
|
@ -97,7 +112,7 @@ extension GroupCallUtils on Room {
|
||||||
|
|
||||||
if (groupCallEvent.content.tryGet('m.intent') == 'm.room') return;
|
if (groupCallEvent.content.tryGet('m.intent') == 'm.room') return;
|
||||||
if (!groupCallEvent.content.containsKey('m.terminated')) {
|
if (!groupCallEvent.content.containsKey('m.terminated')) {
|
||||||
Logs().i('found non terminated group call with id $groupCallId');
|
Logs().i('[VOIP] found non terminated group call with id $groupCallId');
|
||||||
// call is not empty but check for stale participants (gone offline)
|
// call is not empty but check for stale participants (gone offline)
|
||||||
// with expire_ts
|
// with expire_ts
|
||||||
bool callExpired = true; // assume call is expired
|
bool callExpired = true; // assume call is expired
|
||||||
|
|
@ -118,7 +133,7 @@ extension GroupCallUtils on Room {
|
||||||
|
|
||||||
if (callExpired) {
|
if (callExpired) {
|
||||||
Logs().i(
|
Logs().i(
|
||||||
'Group call with only expired timestamps detected, terminating');
|
'[VOIP] Group call with only expired timestamps detected, terminating');
|
||||||
await sendGroupCallTerminateEvent(groupCallId);
|
await sendGroupCallTerminateEvent(groupCallId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -132,7 +147,7 @@ extension GroupCallUtils on Room {
|
||||||
final existingStateEvent =
|
final existingStateEvent =
|
||||||
getState(EventTypes.GroupCallPrefix, groupCallId);
|
getState(EventTypes.GroupCallPrefix, groupCallId);
|
||||||
if (existingStateEvent == null) {
|
if (existingStateEvent == null) {
|
||||||
Logs().e('could not find group call with id $groupCallId');
|
Logs().e('[VOIP] could not find group call with id $groupCallId');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,8 +159,8 @@ extension GroupCallUtils on Room {
|
||||||
|
|
||||||
Logs().i('[VOIP] Group call $groupCallId was killed uwu');
|
Logs().i('[VOIP] Group call $groupCallId was killed uwu');
|
||||||
return req;
|
return req;
|
||||||
} catch (e) {
|
} catch (e, s) {
|
||||||
Logs().e('killing stale call $groupCallId failed. reason: $e');
|
Logs().e('[VOIP] killing stale call $groupCallId failed', e, s);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue