Implement rejecting incoming call.

This commit is contained in:
onurays 2020-05-26 14:30:22 +03:00 committed by Valere
parent 743ace7e60
commit f50f81d321
2 changed files with 111 additions and 100 deletions

View file

@ -122,39 +122,37 @@ class WebRtcPeerConnectionManager @Inject constructor(
}
private fun createPeerConnectionFactory() {
executor.execute {
if (peerConnectionFactory == null) {
Timber.v("## VOIP createPeerConnectionFactory")
val eglBaseContext = rootEglBase?.eglBaseContext ?: return@execute Unit.also {
Timber.e("## VOIP No EGL BASE")
}
Timber.v("## VOIP PeerConnectionFactory.initialize")
PeerConnectionFactory.initialize(PeerConnectionFactory
.InitializationOptions.builder(context.applicationContext)
.createInitializationOptions()
)
val options = PeerConnectionFactory.Options()
val defaultVideoEncoderFactory = DefaultVideoEncoderFactory(
eglBaseContext,
/* enableIntelVp8Encoder */
true,
/* enableH264HighProfile */
true)
val defaultVideoDecoderFactory = DefaultVideoDecoderFactory(eglBaseContext)
Timber.v("## VOIP PeerConnectionFactory.createPeerConnectionFactory ...")
peerConnectionFactory = PeerConnectionFactory.builder()
.setOptions(options)
.setVideoEncoderFactory(defaultVideoEncoderFactory)
.setVideoDecoderFactory(defaultVideoDecoderFactory)
.createPeerConnectionFactory()
if (peerConnectionFactory == null) {
Timber.v("## VOIP createPeerConnectionFactory")
val eglBaseContext = rootEglBase?.eglBaseContext ?: return Unit.also {
Timber.e("## VOIP No EGL BASE")
}
Timber.v("## VOIP PeerConnectionFactory.initialize")
PeerConnectionFactory.initialize(PeerConnectionFactory
.InitializationOptions.builder(context.applicationContext)
.createInitializationOptions()
)
val options = PeerConnectionFactory.Options()
val defaultVideoEncoderFactory = DefaultVideoEncoderFactory(
eglBaseContext,
/* enableIntelVp8Encoder */
true,
/* enableH264HighProfile */
true)
val defaultVideoDecoderFactory = DefaultVideoDecoderFactory(eglBaseContext)
Timber.v("## VOIP PeerConnectionFactory.createPeerConnectionFactory ...")
peerConnectionFactory = PeerConnectionFactory.builder()
.setOptions(options)
.setVideoEncoderFactory(defaultVideoEncoderFactory)
.setVideoDecoderFactory(defaultVideoDecoderFactory)
.createPeerConnectionFactory()
}
}
private fun createPeerConnection() {
private fun createPeerConnection(observer: PeerConnectionObserverAdapter) {
val iceServers = ArrayList<PeerConnection.IceServer>().apply {
listOf("turn:turn.matrix.org:3478?transport=udp", "turn:turn.matrix.org:3478?transport=tcp", "turns:turn.matrix.org:443?transport=tcp").forEach {
add(
@ -166,40 +164,7 @@ class WebRtcPeerConnectionManager @Inject constructor(
}
}
Timber.v("## VOIP creating peer connection... ")
peerConnection = peerConnectionFactory?.createPeerConnection(
iceServers,
object : PeerConnectionObserverAdapter() {
override fun onIceCandidate(p0: IceCandidate?) {
Timber.v("## VOIP onIceCandidate local $p0")
p0?.let { iceCandidateSource.onNext(it) }
}
override fun onAddStream(mediaStream: MediaStream?) {
Timber.v("## VOIP onAddStream remote $mediaStream")
mediaStream?.videoTracks?.firstOrNull()?.let {
listener?.addRemoteVideoTrack(it)
remoteVideoTrack = it
}
}
override fun onRemoveStream(mediaStream: MediaStream?) {
mediaStream?.let {
listener?.removeRemoteVideoStream(it)
}
remoteSurfaceRenderer?.get()?.let {
remoteVideoTrack?.removeSink(it)
}
remoteVideoTrack = null
}
override fun onIceConnectionChange(p0: PeerConnection.IceConnectionState?) {
Timber.v("## VOIP onIceConnectionChange $p0")
if (p0 == PeerConnection.IceConnectionState.DISCONNECTED) {
listener?.onDisconnect()
}
}
}
)
peerConnection = peerConnectionFactory?.createPeerConnection(iceServers, observer)
}
// TODO REMOVE THIS FUNCTION
@ -244,8 +209,6 @@ class WebRtcPeerConnectionManager @Inject constructor(
// }
// .disposeOnDestroy()
localMediaStream = peerConnectionFactory?.createLocalMediaStream("ARDAMS") // magic value?
localMediaStream?.addTrack(localVideoTrack)
localMediaStream?.addTrack(audioTrack)
@ -260,6 +223,8 @@ class WebRtcPeerConnectionManager @Inject constructor(
}
fun answerReceived(callId: String, answerSdp: SessionDescription) {
this.callId = callId
executor.execute {
Timber.v("## answerReceived $callId")
peerConnection?.setRemoteDescription(object : SdpObserverAdapter() {}, answerSdp)
@ -268,50 +233,84 @@ class WebRtcPeerConnectionManager @Inject constructor(
private fun startCall() {
createPeerConnectionFactory()
createPeerConnection()
createPeerConnection(object : PeerConnectionObserverAdapter() {
override fun onIceCandidate(p0: IceCandidate?) {
Timber.v("## VOIP onIceCandidate local $p0")
p0?.let { iceCandidateSource.onNext(it) }
}
override fun onAddStream(mediaStream: MediaStream?) {
Timber.v("## VOIP onAddStream remote $mediaStream")
mediaStream?.videoTracks?.firstOrNull()?.let {
listener?.addRemoteVideoTrack(it)
remoteVideoTrack = it
}
}
override fun onRemoveStream(mediaStream: MediaStream?) {
mediaStream?.let {
listener?.removeRemoteVideoStream(it)
}
remoteSurfaceRenderer?.get()?.let {
remoteVideoTrack?.removeSink(it)
}
remoteVideoTrack = null
}
override fun onIceConnectionChange(p0: PeerConnection.IceConnectionState?) {
Timber.v("## VOIP onIceConnectionChange $p0")
if (p0 == PeerConnection.IceConnectionState.DISCONNECTED) {
listener?.onDisconnect()
}
}
})
iceCandidateDisposable = iceCandidateSource
.buffer(400, TimeUnit.MILLISECONDS)
.subscribe {
// omit empty :/
if (it.isNotEmpty()) {
Timber.v("## Sending local ice candidates to callId: $callId roomId: $signalingRoomId")
sessionHolder
.getActiveSession()
.callService()
.sendLocalIceCandidates(callId ?: "", signalingRoomId ?: "", it)
}
}
}
executor.execute {
val constraints = MediaConstraints()
constraints.mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"))
constraints.mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"))
private fun sendSdpOffer() {
val constraints = MediaConstraints()
constraints.mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"))
constraints.mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"))
Timber.v("## VOIP creating offer...")
peerConnection?.createOffer(object : SdpObserver {
override fun onSetFailure(p0: String?) {
Timber.v("## VOIP onSetFailure $p0")
}
Timber.v("## VOIP creating offer...")
peerConnection?.createOffer(object : SdpObserver {
override fun onSetFailure(p0: String?) {
Timber.v("## VOIP onSetFailure $p0")
}
override fun onSetSuccess() {
Timber.v("## VOIP onSetSuccess")
}
override fun onSetSuccess() {
Timber.v("## VOIP onSetSuccess")
}
override fun onCreateSuccess(sessionDescription: SessionDescription) {
Timber.v("## VOIP onCreateSuccess $sessionDescription")
peerConnection?.setLocalDescription(object : SdpObserverAdapter() {
override fun onSetSuccess() {
callId = UUID.randomUUID().toString()
sessionHolder.getActiveSession().callService().sendOfferSdp(callId!!, signalingRoomId!!, sessionDescription, object : MatrixCallback<String> {})
}
}, sessionDescription)
}
override fun onCreateSuccess(sessionDescription: SessionDescription) {
Timber.v("## VOIP onCreateSuccess $sessionDescription will set local description")
peerConnection?.setLocalDescription(object : SdpObserverAdapter() {
override fun onSetSuccess() {
Timber.v("## setLocalDescription success")
callId = UUID.randomUUID().toString()
Timber.v("## sending offer to callId: $callId roomId: $signalingRoomId")
sessionHolder.getActiveSession().callService().sendOfferSdp(callId ?: "", signalingRoomId
?: "", sessionDescription, object : MatrixCallback<String> {})
}
}, sessionDescription)
}
override fun onCreateFailure(p0: String?) {
Timber.v("## VOIP onCreateFailure $p0")
}
}, constraints)
}
override fun onCreateFailure(p0: String?) {
Timber.v("## VOIP onCreateFailure $p0")
}
}, constraints)
}
fun attachViewRenderers(localViewRenderer: SurfaceViewRenderer, remoteViewRenderer: SurfaceViewRenderer) {
@ -339,7 +338,7 @@ class WebRtcPeerConnectionManager @Inject constructor(
executor.execute {
// Do not dispose peer connection (https://bugs.chromium.org/p/webrtc/issues/detail?id=7543)
peerConnection?.close()
peerConnection?.removeStream(localMediaStream)
localMediaStream?.let { peerConnection?.removeStream(it) }
peerConnection = null
audioSource?.dispose()
videoSource?.dispose()
@ -377,13 +376,19 @@ class WebRtcPeerConnectionManager @Inject constructor(
fun startOutgoingCall(context: Context, signalingRoomId: String, participantUserId: String, isVideoCall: Boolean) {
this.signalingRoomId = signalingRoomId
this.participantUserId = participantUserId
startHeadsUpService(signalingRoomId, sessionHolder.getActiveSession().myUserId, false, isVideoCall)
context.startActivity(VectorCallActivity.newIntent(context, signalingRoomId, participantUserId, false, isVideoCall))
startCall()
sendSdpOffer()
}
override fun onCallInviteReceived(signalingRoomId: String, participantUserId: String, callInviteContent: CallInviteContent) {
this.callId = callInviteContent.callId
this.signalingRoomId = signalingRoomId
this.participantUserId = participantUserId
startHeadsUpService(signalingRoomId, participantUserId, true, callInviteContent.isVideo())
startCall()
@ -399,8 +404,8 @@ class WebRtcPeerConnectionManager @Inject constructor(
fun endCall() {
if (callId != null && signalingRoomId != null) {
sessionHolder.getActiveSession().callService().sendHangup(callId!!, signalingRoomId!!)
close()
}
close()
}
override fun onCallAnswerReceived(callAnswerContent: CallAnswerContent) {

View file

@ -19,11 +19,22 @@ package im.vector.riotx.features.call.service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import im.vector.riotx.core.di.HasVectorInjector
import im.vector.riotx.features.call.WebRtcPeerConnectionManager
import im.vector.riotx.features.settings.VectorLocale.context
import timber.log.Timber
class CallHeadsUpActionReceiver : BroadcastReceiver() {
private lateinit var peerConnectionManager: WebRtcPeerConnectionManager
init {
val appContext = context.applicationContext
if (appContext is HasVectorInjector) {
peerConnectionManager = appContext.injector().webRtcPeerConnectionManager()
}
}
override fun onReceive(context: Context, intent: Intent?) {
when (intent?.getIntExtra(CallHeadsUpService.EXTRA_CALL_ACTION_KEY, 0)) {
CallHeadsUpService.CALL_ACTION_ANSWER -> onCallAnswerClicked()
@ -33,15 +44,10 @@ class CallHeadsUpActionReceiver : BroadcastReceiver() {
private fun onCallRejectClicked() {
Timber.d("onCallRejectClicked")
stopService()
peerConnectionManager.endCall()
}
private fun onCallAnswerClicked() {
Timber.d("onCallAnswerClicked")
}
private fun stopService() {
context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
context.stopService(Intent(context, CallHeadsUpService::class.java))
}
}