diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/call/CallsListener.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/call/CallsListener.kt index 556555369a..d48841f1bb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/call/CallsListener.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/call/CallsListener.kt @@ -17,6 +17,7 @@ package im.vector.matrix.android.api.session.call import im.vector.matrix.android.api.session.room.model.call.CallAnswerContent +import im.vector.matrix.android.api.session.room.model.call.CallHangupContent import im.vector.matrix.android.api.session.room.model.call.CallInviteContent interface CallsListener { @@ -44,4 +45,6 @@ interface CallsListener { fun onCallAnswerReceived(callAnswerContent: CallAnswerContent) + fun onCallHangupReceived(callHangupContent: CallHangupContent) + } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/call/DefaultCallService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/call/DefaultCallService.kt index ab30a61ebf..61f72e5a4c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/call/DefaultCallService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/call/DefaultCallService.kt @@ -30,6 +30,7 @@ import im.vector.matrix.android.api.session.events.model.toContent import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.call.CallAnswerContent import im.vector.matrix.android.api.session.room.model.call.CallCandidatesContent +import im.vector.matrix.android.api.session.room.model.call.CallHangupContent import im.vector.matrix.android.api.session.room.model.call.CallInviteContent import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.session.SessionScope @@ -146,6 +147,19 @@ internal class DefaultCallService @Inject constructor( onCallInvite(event.roomId ?: "", it) } } + EventType.CALL_HANGUP -> { + event.getClearContent().toModel()?.let { + onCallHangup(it) + } + } + } + } + + private fun onCallHangup(hangup: CallHangupContent) { + callListeners.forEach { + tryThis { + it.onCallHangupReceived(hangup) + } } } diff --git a/vector/src/main/java/im/vector/riotx/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/riotx/features/call/VectorCallActivity.kt index c8387daa20..f1d50fd7b3 100644 --- a/vector/src/main/java/im/vector/riotx/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/call/VectorCallActivity.kt @@ -348,6 +348,9 @@ class VectorCallActivity : VectorBaseActivity(), WebRtcPeerConnectionManager.Lis peerConnectionManager.answerReceived("", sdp) // peerConnection?.setRemoteDescription(object : SdpObserverAdapter() {}, sdp) } + is VectorCallViewEvents.CallHangup -> { + finish() + } } } @@ -423,6 +426,7 @@ class VectorCallActivity : VectorBaseActivity(), WebRtcPeerConnectionManager.Lis } override fun removeRemoteVideoStream(mediaStream: MediaStream) { + } override fun onDisconnect() { diff --git a/vector/src/main/java/im/vector/riotx/features/call/VectorCallViewModel.kt b/vector/src/main/java/im/vector/riotx/features/call/VectorCallViewModel.kt index a995e3197e..95a3677f61 100644 --- a/vector/src/main/java/im/vector/riotx/features/call/VectorCallViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/call/VectorCallViewModel.kt @@ -25,6 +25,7 @@ import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.call.CallsListener import im.vector.matrix.android.api.session.room.model.call.CallAnswerContent +import im.vector.matrix.android.api.session.room.model.call.CallHangupContent import im.vector.matrix.android.api.session.room.model.call.CallInviteContent import im.vector.matrix.android.internal.util.awaitCallback import im.vector.riotx.core.extensions.exhaustive @@ -51,6 +52,7 @@ sealed class VectorCallViewActions : VectorViewModelAction { sealed class VectorCallViewEvents : VectorViewEvents { data class CallAnswered(val content: CallAnswerContent) : VectorCallViewEvents() + data class CallHangup(val content: CallHangupContent) : VectorCallViewEvents() } class VectorCallViewModel @AssistedInject constructor( @@ -70,6 +72,14 @@ class VectorCallViewModel @AssistedInject constructor( override fun onCallInviteReceived(signalingRoomId: String, callInviteContent: CallInviteContent) { } + + override fun onCallHangupReceived(callHangupContent: CallHangupContent) { + withState { state -> + if (callHangupContent.callId == state.callId) { + _viewEvents.post(VectorCallViewEvents.CallHangup(callHangupContent)) + } + } + } } init { diff --git a/vector/src/main/java/im/vector/riotx/features/call/WebRtcPeerConnectionManager.kt b/vector/src/main/java/im/vector/riotx/features/call/WebRtcPeerConnectionManager.kt index 7833ac1787..e58404d8fb 100644 --- a/vector/src/main/java/im/vector/riotx/features/call/WebRtcPeerConnectionManager.kt +++ b/vector/src/main/java/im/vector/riotx/features/call/WebRtcPeerConnectionManager.kt @@ -28,6 +28,7 @@ import androidx.core.content.ContextCompat import im.vector.matrix.android.api.session.call.CallsListener import im.vector.matrix.android.api.session.call.EglUtils import im.vector.matrix.android.api.session.room.model.call.CallAnswerContent +import im.vector.matrix.android.api.session.room.model.call.CallHangupContent import im.vector.matrix.android.api.session.room.model.call.CallInviteContent import im.vector.riotx.BuildConfig import im.vector.riotx.R @@ -72,6 +73,7 @@ class WebRtcPeerConnectionManager @Inject constructor( } var phoneAccountHandle: PhoneAccountHandle? = null + var localMediaStream: MediaStream? = null init { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -239,7 +241,7 @@ class WebRtcPeerConnectionManager @Inject constructor( } ) - val localMediaStream = peerConnectionFactory?.createLocalMediaStream("ARDAMS") // magic value? + localMediaStream = peerConnectionFactory?.createLocalMediaStream("ARDAMS") // magic value? localMediaStream?.addTrack(localVideoTrack) localMediaStream?.addTrack(audioTrack) @@ -315,13 +317,15 @@ class WebRtcPeerConnectionManager @Inject constructor( fun close() { executor.execute { - peerConnectionFactory?.stopAecDump() - peerConnectionFactory = null + // Do not dispose peer connection (https://bugs.chromium.org/p/webrtc/issues/detail?id=7543) + peerConnection?.close() + peerConnection?.removeStream(localMediaStream) + peerConnection = null audioSource?.dispose() videoSource?.dispose() - peerConnection?.dispose() - peerConnection = null videoCapturer?.dispose() + peerConnectionFactory?.stopAecDump() + peerConnectionFactory = null } } @@ -367,6 +371,10 @@ class WebRtcPeerConnectionManager @Inject constructor( override fun onCallAnswerReceived(callAnswerContent: CallAnswerContent) { } + + override fun onCallHangupReceived(callHangupContent: CallHangupContent) { + close() + } }