Merge branch 'voip/fix-bugs-for-group-call' into 'main'
Fix bugs in 1v1 and group calls. See merge request famedly/company/frontend/famedlysdk!1132
This commit is contained in:
		
						commit
						64f2a4b3c6
					
				|  | @ -82,13 +82,16 @@ class WrappedMediaStream { | ||||||
| 
 | 
 | ||||||
|   Future<void> dispose() async { |   Future<void> dispose() async { | ||||||
|     renderer.srcObject = null; |     renderer.srcObject = null; | ||||||
|     if (isLocal() && stream != null && isWeb) { |     if (isLocal()) { | ||||||
|       for (final element in stream!.getTracks()) { |       if (isWeb) { | ||||||
|         await element.stop(); |         await stopMediaStream(stream); | ||||||
|  |       } else { | ||||||
|  |         if (!isGroupCall) { | ||||||
|  |           await stopMediaStream(stream); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|       await stream?.dispose(); |  | ||||||
|     stream = null; |     stream = null; | ||||||
|     } |  | ||||||
|     await renderer.dispose(); |     await renderer.dispose(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -827,7 +830,7 @@ class CallSession { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (callFeed.purpose == SDPStreamMetadataPurpose.Screenshare) { |     if (callFeed.purpose == SDPStreamMetadataPurpose.Screenshare) { | ||||||
|       stopMediaStream(callFeed.stream); |       await stopMediaStream(callFeed.stream); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Empty the array |     // Empty the array | ||||||
|  | @ -932,20 +935,19 @@ class CallSession { | ||||||
|   /// 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() async { |   Future<void> reject({String? reason, bool shouldEmit = true}) async { | ||||||
|     // stop play ringtone |     // stop play ringtone | ||||||
|     voip.delegate.stopRingtone(); |     voip.delegate.stopRingtone(); | ||||||
| 
 |     if (state != CallState.kRinging && state != CallState.kFledgling) { | ||||||
|     if (state != CallState.kRinging) { |       Logs().e('[VOIP] Call must be in \'ringing|fledgling\' state to reject!'); | ||||||
|       Logs().e('[VOIP] Call must be in \'ringing\' state to reject!'); |  | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     Logs().d('[VOIP] Rejecting call: $callId'); |     Logs().d('[VOIP] Rejecting call: $callId'); | ||||||
|     await terminate(CallParty.kLocal, CallErrorCode.UserHangup, true); |     await terminate(CallParty.kLocal, CallErrorCode.UserHangup, shouldEmit); | ||||||
|     await sendCallReject(room, callId, lifetimeMs, localPartyId); |     await sendCallReject(room, callId, lifetimeMs, localPartyId, reason); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Future<void> hangup([String? reason, bool suppressEvent = true]) async { |   Future<void> hangup([String? reason, bool suppressEvent = false]) async { | ||||||
|     // stop play ringtone |     // stop play ringtone | ||||||
|     voip.delegate.stopRingtone(); |     voip.delegate.stopRingtone(); | ||||||
| 
 | 
 | ||||||
|  | @ -987,15 +989,15 @@ class CallSession { | ||||||
|     hangupParty = party; |     hangupParty = party; | ||||||
|     hangupReason = reason; |     hangupReason = reason; | ||||||
| 
 | 
 | ||||||
|  |     if (shouldEmit) { | ||||||
|       setCallState(CallState.kEnded); |       setCallState(CallState.kEnded); | ||||||
|  |     } | ||||||
|     voip.currentCID = null; |     voip.currentCID = null; | ||||||
|     voip.calls.remove(callId); |     voip.calls.remove(callId); | ||||||
|     await cleanUp(); |     await cleanUp(); | ||||||
| 
 |  | ||||||
|     onCallHangup.add(this); |  | ||||||
| 
 |  | ||||||
|     voip.delegate.handleCallEnded(this); |  | ||||||
|     if (shouldEmit) { |     if (shouldEmit) { | ||||||
|  |       onCallHangup.add(this); | ||||||
|  |       voip.delegate.handleCallEnded(this); | ||||||
|       fireCallEvent(CallEvent.kHangup); |       fireCallEvent(CallEvent.kHangup); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | @ -1432,7 +1434,7 @@ class CallSession { | ||||||
|   /// [version] is the version of the VoIP specification this message adheres to. This specification is version 1. |   /// [version] is the version of the VoIP specification this message adheres to. This specification is version 1. | ||||||
|   /// [party_id] The party ID for call, Can be set to client.deviceId. |   /// [party_id] The party ID for call, Can be set to client.deviceId. | ||||||
|   Future<String?> sendCallReject( |   Future<String?> sendCallReject( | ||||||
|       Room room, String callId, int lifetime, String party_id, |       Room room, String callId, int lifetime, String party_id, String? reason, | ||||||
|       {String version = voipProtoVersion, String? txid}) async { |       {String version = voipProtoVersion, String? txid}) async { | ||||||
|     txid ??= 'txid${DateTime.now().millisecondsSinceEpoch}'; |     txid ??= 'txid${DateTime.now().millisecondsSinceEpoch}'; | ||||||
| 
 | 
 | ||||||
|  | @ -1440,6 +1442,7 @@ class CallSession { | ||||||
|       'call_id': callId, |       'call_id': callId, | ||||||
|       'party_id': party_id, |       'party_id': party_id, | ||||||
|       if (groupCallId != null) 'conf_id': groupCallId, |       if (groupCallId != null) 'conf_id': groupCallId, | ||||||
|  |       if (reason != null) 'reason': reason, | ||||||
|       'version': version, |       'version': version, | ||||||
|       'lifetime': lifetime, |       'lifetime': lifetime, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  | @ -594,9 +594,10 @@ class GroupCall { | ||||||
| 
 | 
 | ||||||
|         onGroupCallEvent.add(GroupCallEvent.LocalScreenshareStateChanged); |         onGroupCallEvent.add(GroupCallEvent.LocalScreenshareStateChanged); | ||||||
| 
 | 
 | ||||||
|         calls.forEach((call) { |         calls.forEach((call) async { | ||||||
|           call.addLocalStream( |           await call.addLocalStream( | ||||||
|               localScreenshareStream!.stream!, localScreenshareStream!.purpose); |               await voip.delegate.cloneStream(localScreenshareStream!.stream!), | ||||||
|  |               localScreenshareStream!.purpose); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         await sendMemberStateEvent(); |         await sendMemberStateEvent(); | ||||||
|  | @ -613,7 +614,7 @@ class GroupCall { | ||||||
|       calls.forEach((call) { |       calls.forEach((call) { | ||||||
|         call.removeLocalStream(call.localScreenSharingStream!); |         call.removeLocalStream(call.localScreenSharingStream!); | ||||||
|       }); |       }); | ||||||
|       stopMediaStream(localScreenshareStream!.stream); |       await stopMediaStream(localScreenshareStream?.stream); | ||||||
|       removeScreenshareStream(localScreenshareStream!); |       removeScreenshareStream(localScreenshareStream!); | ||||||
|       localScreenshareStream = null; |       localScreenshareStream = null; | ||||||
|       localDesktopCapturerSourceId = null; |       localDesktopCapturerSourceId = null; | ||||||
|  | @ -1092,12 +1093,10 @@ class GroupCall { | ||||||
| 
 | 
 | ||||||
|     onStreamRemoved.add(stream); |     onStreamRemoved.add(stream); | ||||||
| 
 | 
 | ||||||
|     stream.stream!.getTracks().forEach((element) { |     if (stream.isLocal()) { | ||||||
|       element.stop(); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     stream.stream!.dispose(); |  | ||||||
|       stream.disposeRenderer(); |       stream.disposeRenderer(); | ||||||
|  |       stopMediaStream(stream.stream); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     onGroupCallEvent.add(GroupCallEvent.UserMediaStreamsChanged); |     onGroupCallEvent.add(GroupCallEvent.UserMediaStreamsChanged); | ||||||
| 
 | 
 | ||||||
|  | @ -1187,14 +1186,11 @@ class GroupCall { | ||||||
| 
 | 
 | ||||||
|     onStreamRemoved.add(stream); |     onStreamRemoved.add(stream); | ||||||
| 
 | 
 | ||||||
|     if (voip.delegate.isWeb) { |     if (stream.isLocal()) { | ||||||
|       stream.stream!.getTracks().forEach((element) { |       stream.disposeRenderer(); | ||||||
|         element.stop(); |       stopMediaStream(stream.stream); | ||||||
|       }); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     stream.dispose(); |  | ||||||
| 
 |  | ||||||
|     onGroupCallEvent.add(GroupCallEvent.ScreenshareStreamsChanged); |     onGroupCallEvent.add(GroupCallEvent.ScreenshareStreamsChanged); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,10 +1,11 @@ | ||||||
| import 'package:random_string/random_string.dart'; | import 'package:random_string/random_string.dart'; | ||||||
| import 'package:webrtc_interface/webrtc_interface.dart'; | import 'package:webrtc_interface/webrtc_interface.dart'; | ||||||
| 
 | 
 | ||||||
| void stopMediaStream(MediaStream? stream) async { | Future<void> stopMediaStream(MediaStream? stream) async { | ||||||
|   stream?.getTracks().forEach((element) async { |   stream?.getTracks().forEach((element) async { | ||||||
|     await element.stop(); |     await element.stop(); | ||||||
|   }); |   }); | ||||||
|  |   await stream?.dispose(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void setTracksEnabled(List<MediaStreamTrack> tracks, bool enabled) { | void setTracksEnabled(List<MediaStreamTrack> tracks, bool enabled) { | ||||||
|  |  | ||||||
|  | @ -19,12 +19,12 @@ abstract class WebRTCDelegate { | ||||||
|   void stopRingtone(); |   void stopRingtone(); | ||||||
|   void handleNewCall(CallSession session); |   void handleNewCall(CallSession session); | ||||||
|   void handleCallEnded(CallSession session); |   void handleCallEnded(CallSession session); | ||||||
| 
 |   void handleMissedCall(CallSession session); | ||||||
|   void handleNewGroupCall(GroupCall groupCall); |   void handleNewGroupCall(GroupCall groupCall); | ||||||
|   void handleGroupCallEnded(GroupCall groupCall); |   void handleGroupCallEnded(GroupCall groupCall); | ||||||
| 
 |  | ||||||
|   bool get isBackgroud; |   bool get isBackgroud; | ||||||
|   bool get isWeb; |   bool get isWeb; | ||||||
|  |   bool get canHandleNewCall => true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class VoIP { | class VoIP { | ||||||
|  | @ -200,10 +200,20 @@ class VoIP { | ||||||
|     newCall.opponentDeviceId = deviceId; |     newCall.opponentDeviceId = deviceId; | ||||||
|     newCall.opponentSessionId = content['sender_session_id']; |     newCall.opponentSessionId = content['sender_session_id']; | ||||||
| 
 | 
 | ||||||
|  |     if (!delegate.canHandleNewCall && | ||||||
|  |         (confId == null || confId != currentGroupCID)) { | ||||||
|  |       Logs().v( | ||||||
|  |           '[VOIP] onCallInvite: Unable to handle new calls, maybe user is busy.'); | ||||||
|  |       await newCall.reject(reason: 'busy', shouldEmit: false); | ||||||
|  |       delegate.handleMissedCall(newCall); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     final offer = RTCSessionDescription( |     final offer = RTCSessionDescription( | ||||||
|       content['offer']['sdp'], |       content['offer']['sdp'], | ||||||
|       content['offer']['type'], |       content['offer']['type'], | ||||||
|     ); |     ); | ||||||
|  | 
 | ||||||
|     await newCall.initWithInvite( |     await newCall.initWithInvite( | ||||||
|         callType, offer, sdpStreamMetadata, lifetime, confId != null); |         callType, offer, sdpStreamMetadata, lifetime, confId != null); | ||||||
| 
 | 
 | ||||||
|  | @ -223,8 +233,10 @@ class VoIP { | ||||||
|       ///TODO: notify the callkeep that the call is incoming. |       ///TODO: notify the callkeep that the call is incoming. | ||||||
|     } |     } | ||||||
|     // Play ringtone |     // Play ringtone | ||||||
|  |     if (confId == null) { | ||||||
|       delegate.playRingtone(); |       delegate.playRingtone(); | ||||||
|     } |     } | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Future<void> onCallAnswer( |   Future<void> onCallAnswer( | ||||||
|       String roomId, String senderId, Map<String, dynamic> content) async { |       String roomId, String senderId, Map<String, dynamic> content) async { | ||||||
|  |  | ||||||
|  | @ -967,7 +967,8 @@ void main() { | ||||||
|       await call.sendCallCandidates(room, '1234', '4567', [], txid: '1234'); |       await call.sendCallCandidates(room, '1234', '4567', [], txid: '1234'); | ||||||
|       await call.sendSelectCallAnswer(room, '1234', 1234, '4567', '6789', |       await call.sendSelectCallAnswer(room, '1234', 1234, '4567', '6789', | ||||||
|           txid: '1234'); |           txid: '1234'); | ||||||
|       await call.sendCallReject(room, '1234', 1234, '4567', txid: '1234'); |       await call.sendCallReject(room, '1234', 1234, '4567', 'busy', | ||||||
|  |           txid: '1234'); | ||||||
|       await call.sendCallNegotiate(room, '1234', 1234, '4567', 'sdp', |       await call.sendCallNegotiate(room, '1234', 1234, '4567', 'sdp', | ||||||
|           txid: '1234'); |           txid: '1234'); | ||||||
|       await call.sendHangupCall(room, '1234', '4567', 'user_hangup', |       await call.sendHangupCall(room, '1234', '4567', 'user_hangup', | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue