Simple cache of turn server response

in memory cache in service + show active call banner only if connected
This commit is contained in:
Valere 2020-06-16 00:51:43 +02:00
parent 8662797cf8
commit d8cf44fdc9
8 changed files with 41 additions and 20 deletions

View file

@ -21,7 +21,7 @@ import im.vector.matrix.android.api.util.Cancelable
interface CallSignalingService {
fun getTurnServer(callback: MatrixCallback<TurnServer>): Cancelable
fun getTurnServer(callback: MatrixCallback<TurnServerResponse>): Cancelable
/**
* Create an outgoing call

View file

@ -20,7 +20,7 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class TurnServer(
data class TurnServerResponse(
@Json(name = "username") val username: String?,
@Json(name = "password") val password: String?,
@Json(name = "uris") val uris: List<String>?,

View file

@ -24,5 +24,5 @@ import retrofit2.http.GET
internal interface VoipApi {
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "voip/turnServer")
fun getTurnServer(): Call<TurnServer>
fun getTurnServer(): Call<TurnServerResponse>
}

View file

@ -21,7 +21,7 @@ import im.vector.matrix.android.api.extensions.tryThis
import im.vector.matrix.android.api.session.call.CallSignalingService
import im.vector.matrix.android.api.session.call.CallsListener
import im.vector.matrix.android.api.session.call.MxCall
import im.vector.matrix.android.api.session.call.TurnServer
import im.vector.matrix.android.api.session.call.TurnServerResponse
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
@ -30,6 +30,7 @@ import im.vector.matrix.android.api.session.room.model.call.CallCandidatesConten
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.api.util.Cancelable
import im.vector.matrix.android.api.util.NoOpCancellable
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.call.model.MxCallImpl
@ -54,11 +55,18 @@ internal class DefaultCallSignalingService @Inject constructor(
private val activeCalls = mutableListOf<MxCall>()
override fun getTurnServer(callback: MatrixCallback<TurnServer>): Cancelable {
private var cachedTurnServerResponse: TurnServerResponse? = null
override fun getTurnServer(callback: MatrixCallback<TurnServerResponse>): Cancelable {
if (cachedTurnServerResponse != null) {
cachedTurnServerResponse?.let { callback.onSuccess(it) }
return NoOpCancellable
}
return turnServerTask
.configureWith(GetTurnServerTask.Params) {
this.callback = object : MatrixCallback<TurnServer> {
override fun onSuccess(data: TurnServer) {
this.callback = object : MatrixCallback<TurnServerResponse> {
override fun onSuccess(data: TurnServerResponse) {
cachedTurnServerResponse = data
callback.onSuccess(data)
}

View file

@ -16,21 +16,21 @@
package im.vector.matrix.android.internal.session.call
import im.vector.matrix.android.api.session.call.TurnServer
import im.vector.matrix.android.api.session.call.TurnServerResponse
import im.vector.matrix.android.api.session.call.VoipApi
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.task.Task
import org.greenrobot.eventbus.EventBus
import javax.inject.Inject
internal abstract class GetTurnServerTask : Task<GetTurnServerTask.Params, TurnServer> {
internal abstract class GetTurnServerTask : Task<GetTurnServerTask.Params, TurnServerResponse> {
object Params
}
internal class DefaultGetTurnServerTask @Inject constructor(private val voipAPI: VoipApi,
private val eventBus: EventBus) : GetTurnServerTask() {
override suspend fun execute(params: Params): TurnServer {
override suspend fun execute(params: Params): TurnServerResponse {
return executeRequest(eventBus) {
apiCall = voipAPI.getTurnServer()
}

View file

@ -33,9 +33,20 @@ class SharedActiveCallViewModel @Inject constructor(
val activeCall: MutableLiveData<MxCall?> = MutableLiveData()
val callStateListener = object: MxCall.StateListener {
override fun onStateUpdate(call: MxCall) {
if (activeCall.value?.callId == call.callId) {
activeCall.postValue(call)
}
}
}
private val listener = object : WebRtcPeerConnectionManager.CurrentCallListener {
override fun onCurrentCallChange(call: MxCall?) {
activeCall.value?.removeListener(callStateListener)
activeCall.postValue(call)
call?.addListener(callStateListener)
}
override fun onCaptureStateChanged(captureInError: Boolean) {
@ -49,6 +60,7 @@ class SharedActiveCallViewModel @Inject constructor(
}
override fun onCleared() {
activeCall.value?.removeListener(callStateListener)
webRtcPeerConnectionManager.removeCurrentCallListener(listener)
super.onCleared()
}

View file

@ -26,7 +26,7 @@ import im.vector.matrix.android.api.session.call.CallState
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.call.MxCall
import im.vector.matrix.android.api.session.call.TurnServer
import im.vector.matrix.android.api.session.call.TurnServerResponse
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
@ -213,9 +213,9 @@ class WebRtcPeerConnectionManager @Inject constructor(
// attachViewRenderersInternal()
}
private fun createPeerConnection(callContext: CallContext, turnServer: TurnServer?) {
private fun createPeerConnection(callContext: CallContext, turnServerResponse: TurnServerResponse?) {
val iceServers = mutableListOf<PeerConnection.IceServer>().apply {
turnServer?.let { server ->
turnServerResponse?.let { server ->
server.uris?.forEach { uri ->
add(
PeerConnection
@ -250,9 +250,9 @@ class WebRtcPeerConnectionManager @Inject constructor(
}, constraints)
}
private fun getTurnServer(callback: ((TurnServer?) -> Unit)) {
sessionHolder.getActiveSession().callSignalingService().getTurnServer(object : MatrixCallback<TurnServer?> {
override fun onSuccess(data: TurnServer?) {
private fun getTurnServer(callback: ((TurnServerResponse?) -> Unit)) {
sessionHolder.getActiveSession().callSignalingService().getTurnServer(object : MatrixCallback<TurnServerResponse?> {
override fun onSuccess(data: TurnServerResponse?) {
callback(data)
}
@ -313,10 +313,10 @@ class WebRtcPeerConnectionManager @Inject constructor(
}
}
private fun internalAcceptIncomingCall(callContext: CallContext, turnServer: TurnServer?) {
private fun internalAcceptIncomingCall(callContext: CallContext, turnServerResponse: TurnServerResponse?) {
executor.execute {
// 1) create peer connection
createPeerConnection(callContext, turnServer)
createPeerConnection(callContext, turnServerResponse)
// create sdp using offer, and set remote description
// the offer has beed stored when invite was received

View file

@ -63,6 +63,7 @@ import com.jakewharton.rxbinding3.widget.textChanges
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.permalinks.PermalinkFactory
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.call.CallState
import im.vector.matrix.android.api.session.content.ContentAttachmentData
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.toModel
@ -295,8 +296,8 @@ class RoomDetailFragment @Inject constructor(
sharedCallActionViewModel
.activeCall
.observe(viewLifecycleOwner, Observer {
// TODO delay a bit if it's a new call to let call activity launch before ..
activeCallView.isVisible = it != null
val hasActiveCall = it?.state == CallState.CONNECTED
activeCallView.isVisible = hasActiveCall
})
roomDetailViewModel.selectSubscribe(this, RoomDetailViewState::tombstoneEventHandling, uniqueOnly("tombstoneEventHandling")) {