LoggerTag: try new thing and branch more on VOIP

This commit is contained in:
ganfra 2021-07-22 15:22:15 +02:00
parent 115f00ff1a
commit 79c8ef7ebf
12 changed files with 148 additions and 202 deletions

View File

@ -17,16 +17,21 @@
package org.matrix.android.sdk.api.logger package org.matrix.android.sdk.api.logger
/** /**
* Some tags used on Timber. * Parent class for custom logger tags. Can be used with Timber :
*
* val loggerTag = LoggerTag("MyTag", LoggerTag.VOIP)
* Timber.tag(loggerTag.value).v("My log message")
*/ */
open class LoggerTag(private val value: String, private val parentTag: LoggerTag? = null) { open class LoggerTag(private val _value: String, private val parentTag: LoggerTag? = null) {
object VOIP : LoggerTag("VOIP", null) object VOIP : LoggerTag("VOIP", null)
val computedValue: String val value: String
get() { get() {
if (parentTag == null) return value return if (parentTag == null) {
return "${parentTag.computedValue}/$value" _value
} else {
"${parentTag.value}/$_value"
}
} }
} }

View File

@ -26,7 +26,7 @@ import org.matrix.android.sdk.internal.session.SessionScope
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
private val CallEventProcessorTag = LoggerTag("CallEventProcessor", LoggerTag.VOIP) private val loggerTag = LoggerTag("CallEventProcessor", LoggerTag.VOIP)
@SessionScope @SessionScope
internal class CallEventProcessor @Inject constructor(private val callSignalingHandler: CallSignalingHandler) internal class CallEventProcessor @Inject constructor(private val callSignalingHandler: CallSignalingHandler)
@ -75,7 +75,7 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH
private fun dispatchToCallSignalingHandlerIfNeeded(event: Event) { private fun dispatchToCallSignalingHandlerIfNeeded(event: Event) {
event.roomId ?: return Unit.also { event.roomId ?: return Unit.also {
Timber.tag(CallEventProcessorTag.computedValue).w("Event with no room id ${event.eventId}") Timber.tag(loggerTag.value).w("Event with no room id ${event.eventId}")
} }
callSignalingHandler.onCallEvent(event) callSignalingHandler.onCallEvent(event)
} }

View File

@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.session.call package org.matrix.android.sdk.internal.session.call
import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.session.call.CallListener import org.matrix.android.sdk.api.session.call.CallListener
import org.matrix.android.sdk.api.session.call.CallState import org.matrix.android.sdk.api.session.call.CallState
import org.matrix.android.sdk.api.session.call.MxCall import org.matrix.android.sdk.api.session.call.MxCall
@ -32,12 +33,11 @@ import org.matrix.android.sdk.api.session.room.model.call.CallRejectContent
import org.matrix.android.sdk.api.session.room.model.call.CallSelectAnswerContent import org.matrix.android.sdk.api.session.room.model.call.CallSelectAnswerContent
import org.matrix.android.sdk.api.session.room.model.call.CallSignalingContent import org.matrix.android.sdk.api.session.room.model.call.CallSignalingContent
import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.SessionScope
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
private val CallSignalingHandlerTag = LoggerTag("CallSignalingHandler", LoggerTag.VOIP) private val loggerTag = LoggerTag("CallSignalingHandler", LoggerTag.VOIP)
@SessionScope @SessionScope
internal class CallSignalingHandler @Inject constructor(private val activeCallHandler: ActiveCallHandler, internal class CallSignalingHandler @Inject constructor(private val activeCallHandler: ActiveCallHandler,
@ -114,12 +114,12 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
return return
} }
if (call.isOutgoing) { if (call.isOutgoing) {
Timber.tag(CallSignalingHandlerTag.computedValue).v("Got selectAnswer for an outbound call: ignoring") Timber.tag(loggerTag.value).v("Got selectAnswer for an outbound call: ignoring")
return return
} }
val selectedPartyId = content.selectedPartyId val selectedPartyId = content.selectedPartyId
if (selectedPartyId == null) { if (selectedPartyId == null) {
Timber.tag(CallSignalingHandlerTag.computedValue).w("Got nonsensical select_answer with null selected_party_id: ignoring") Timber.tag(loggerTag.value).w("Got nonsensical select_answer with null selected_party_id: ignoring")
return return
} }
callListenersDispatcher.onCallSelectAnswerReceived(content) callListenersDispatcher.onCallSelectAnswerReceived(content)
@ -133,7 +133,7 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
return return
} }
if (call.opponentPartyId != null && !call.partyIdsMatches(content)) { if (call.opponentPartyId != null && !call.partyIdsMatches(content)) {
Timber.tag(CallSignalingHandlerTag.computedValue).v("Ignoring candidates from party ID ${content.partyId} we have chosen party ID ${call.opponentPartyId}") Timber.tag(loggerTag.value).v("Ignoring candidates from party ID ${content.partyId} we have chosen party ID ${call.opponentPartyId}")
return return
} }
callListenersDispatcher.onCallIceCandidateReceived(call, content) callListenersDispatcher.onCallIceCandidateReceived(call, content)
@ -166,7 +166,7 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
// party ID must match (our chosen partner hanging up the call) or be undefined (we haven't chosen // party ID must match (our chosen partner hanging up the call) or be undefined (we haven't chosen
// a partner yet but we're treating the hangup as a reject as per VoIP v0) // a partner yet but we're treating the hangup as a reject as per VoIP v0)
if (call.opponentPartyId != null && !call.partyIdsMatches(content)) { if (call.opponentPartyId != null && !call.partyIdsMatches(content)) {
Timber.tag(CallSignalingHandlerTag.computedValue).v("Ignoring hangup from party ID ${content.partyId} we have chosen party ID ${call.opponentPartyId}") Timber.tag(loggerTag.value).v("Ignoring hangup from party ID ${content.partyId} we have chosen party ID ${call.opponentPartyId}")
return return
} }
if (call.state != CallState.Terminated) { if (call.state != CallState.Terminated) {
@ -186,7 +186,7 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
val now = System.currentTimeMillis() val now = System.currentTimeMillis()
val age = now - (event.ageLocalTs ?: now) val age = now - (event.ageLocalTs ?: now)
if (age > 40_000 && event.getClearType() == EventType.CALL_INVITE) { if (age > 40_000 && event.getClearType() == EventType.CALL_INVITE) {
Timber.tag(CallSignalingHandlerTag.computedValue).w("Call invite is too old to ring.") Timber.tag(loggerTag.value).w("Call invite is too old to ring.")
return return
} }
val content = event.getClearContent().toModel<CallInviteContent>() ?: return val content = event.getClearContent().toModel<CallInviteContent>() ?: return
@ -194,7 +194,7 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
content.callId ?: return content.callId ?: return
if (invitedCallIds.contains(content.callId)) { if (invitedCallIds.contains(content.callId)) {
// Call is already known, maybe due to fast lane. Ignore // Call is already known, maybe due to fast lane. Ignore
Timber.tag(CallSignalingHandlerTag.computedValue).d("Ignoring already known call invite") Timber.tag(loggerTag.value).d("Ignoring already known call invite")
return return
} }
val incomingCall = mxCallFactory.createIncomingCall( val incomingCall = mxCallFactory.createIncomingCall(
@ -223,7 +223,8 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
callListenersDispatcher.onCallManagedByOtherSession(content.callId) callListenersDispatcher.onCallManagedByOtherSession(content.callId)
} else { } else {
if (call.opponentPartyId != null) { if (call.opponentPartyId != null) {
Timber.tag(CallSignalingHandlerTag.computedValue).v("Ignoring answer from party ID ${content.partyId} we already have an answer from ${call.opponentPartyId}") Timber.tag(loggerTag.value)
.v("Ignoring answer from party ID ${content.partyId} we already have an answer from ${call.opponentPartyId}")
return return
} }
mxCallFactory.updateOutgoingCallWithOpponentData(call, event.senderId, content, content.capabilities) mxCallFactory.updateOutgoingCallWithOpponentData(call, event.senderId, content, content.capabilities)
@ -240,7 +241,7 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
activeCallHandler.getCallWithId(it) activeCallHandler.getCallWithId(it)
} }
if (currentCall == null) { if (currentCall == null) {
Timber.tag(CallSignalingHandlerTag.computedValue).v("Call with id $callId is null") Timber.tag(loggerTag.value).v("Call with id $callId is null")
} }
return currentCall return currentCall
} }

View File

@ -21,7 +21,6 @@ import org.matrix.android.sdk.api.session.call.CallSignalingService
import org.matrix.android.sdk.api.session.call.MxCall import org.matrix.android.sdk.api.session.call.MxCall
import org.matrix.android.sdk.api.session.call.TurnServerResponse import org.matrix.android.sdk.api.session.call.TurnServerResponse
import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.SessionScope
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@SessionScope @SessionScope
@ -51,7 +50,6 @@ internal class DefaultCallSignalingService @Inject constructor(
} }
override fun getCallWithId(callId: String): MxCall? { override fun getCallWithId(callId: String): MxCall? {
Timber.v("## VOIP getCallWithId $callId all calls ${activeCallHandler.getActiveCallsLiveData().value?.map { it.callId }}")
return activeCallHandler.getCallWithId(callId) return activeCallHandler.getCallWithId(callId)
} }

View File

@ -17,6 +17,7 @@
package org.matrix.android.sdk.internal.session.call.model package org.matrix.android.sdk.internal.session.call.model
import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.MatrixConfiguration
import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.session.call.CallIdGenerator import org.matrix.android.sdk.api.session.call.CallIdGenerator
import org.matrix.android.sdk.api.session.call.CallState import org.matrix.android.sdk.api.session.call.CallState
import org.matrix.android.sdk.api.session.call.MxCall import org.matrix.android.sdk.api.session.call.MxCall
@ -47,6 +48,8 @@ import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProces
import timber.log.Timber import timber.log.Timber
import java.math.BigDecimal import java.math.BigDecimal
private val loggerTag = LoggerTag("MxCallImpl", LoggerTag.VOIP)
internal class MxCallImpl( internal class MxCallImpl(
override val callId: String, override val callId: String,
override val isOutgoing: Boolean, override val isOutgoing: Boolean,
@ -93,7 +96,7 @@ internal class MxCallImpl(
try { try {
it.onStateUpdate(this) it.onStateUpdate(this)
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.d("dispatchStateChange failed for call $callId : ${failure.localizedMessage}") Timber.tag(loggerTag.value).d("dispatchStateChange failed for call $callId : ${failure.localizedMessage}")
} }
} }
} }
@ -109,7 +112,7 @@ internal class MxCallImpl(
override fun offerSdp(sdpString: String) { override fun offerSdp(sdpString: String) {
if (!isOutgoing) return if (!isOutgoing) return
Timber.v("## VOIP offerSdp $callId") Timber.tag(loggerTag.value).v("offerSdp $callId")
state = CallState.Dialing state = CallState.Dialing
CallInviteContent( CallInviteContent(
callId = callId, callId = callId,
@ -124,7 +127,7 @@ internal class MxCallImpl(
} }
override fun sendLocalCallCandidates(candidates: List<CallCandidate>) { override fun sendLocalCallCandidates(candidates: List<CallCandidate>) {
Timber.v("Send local call canditates $callId: $candidates") Timber.tag(loggerTag.value).v("Send local call canditates $callId: $candidates")
CallCandidatesContent( CallCandidatesContent(
callId = callId, callId = callId,
partyId = ourPartyId, partyId = ourPartyId,
@ -141,11 +144,11 @@ internal class MxCallImpl(
override fun reject() { override fun reject() {
if (opponentVersion < 1) { if (opponentVersion < 1) {
Timber.v("Opponent version is less than 1 ($opponentVersion): sending hangup instead of reject") Timber.tag(loggerTag.value).v("Opponent version is less than 1 ($opponentVersion): sending hangup instead of reject")
hangUp() hangUp()
return return
} }
Timber.v("## VOIP reject $callId") Timber.tag(loggerTag.value).v("reject $callId")
CallRejectContent( CallRejectContent(
callId = callId, callId = callId,
partyId = ourPartyId, partyId = ourPartyId,
@ -157,7 +160,7 @@ internal class MxCallImpl(
} }
override fun hangUp(reason: CallHangupContent.Reason?) { override fun hangUp(reason: CallHangupContent.Reason?) {
Timber.v("## VOIP hangup $callId") Timber.tag(loggerTag.value).v("hangup $callId")
CallHangupContent( CallHangupContent(
callId = callId, callId = callId,
partyId = ourPartyId, partyId = ourPartyId,
@ -170,7 +173,7 @@ internal class MxCallImpl(
} }
override fun accept(sdpString: String) { override fun accept(sdpString: String) {
Timber.v("## VOIP accept $callId") Timber.tag(loggerTag.value).v("accept $callId")
if (isOutgoing) return if (isOutgoing) return
state = CallState.Answering state = CallState.Answering
CallAnswerContent( CallAnswerContent(
@ -185,7 +188,7 @@ internal class MxCallImpl(
} }
override fun negotiate(sdpString: String, type: SdpType) { override fun negotiate(sdpString: String, type: SdpType) {
Timber.v("## VOIP negotiate $callId") Timber.tag(loggerTag.value).v("negotiate $callId")
CallNegotiateContent( CallNegotiateContent(
callId = callId, callId = callId,
partyId = ourPartyId, partyId = ourPartyId,
@ -198,7 +201,7 @@ internal class MxCallImpl(
} }
override fun selectAnswer() { override fun selectAnswer() {
Timber.v("## VOIP select answer $callId") Timber.tag(loggerTag.value).v("select answer $callId")
if (isOutgoing) return if (isOutgoing) return
state = CallState.Answering state = CallState.Answering
CallSelectAnswerContent( CallSelectAnswerContent(
@ -219,7 +222,7 @@ internal class MxCallImpl(
val profileInfo = try { val profileInfo = try {
getProfileInfoTask.execute(profileInfoParams) getProfileInfoTask.execute(profileInfoParams)
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.v("Fail fetching profile info of $targetUserId while transferring call") Timber.tag(loggerTag.value).v("Fail fetching profile info of $targetUserId while transferring call")
null null
} }
CallReplacesContent( CallReplacesContent(

View File

@ -41,7 +41,7 @@ import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MatrixItem
import timber.log.Timber import timber.log.Timber
private val CallServiceTag = LoggerTag("CallService", LoggerTag.VOIP) private val loggerTag = LoggerTag("CallService", LoggerTag.VOIP)
/** /**
* Foreground service to manage calls * Foreground service to manage calls
@ -94,7 +94,7 @@ class CallService : VectorService() {
} }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Timber.tag(CallServiceTag.computedValue).v("onStartCommand $intent") Timber.tag(loggerTag.value).v("onStartCommand $intent")
if (mediaSession == null) { if (mediaSession == null) {
mediaSession = MediaSessionCompat(applicationContext, CallService::class.java.name).apply { mediaSession = MediaSessionCompat(applicationContext, CallService::class.java.name).apply {
setCallback(mediaSessionButtonCallback) setCallback(mediaSessionButtonCallback)
@ -151,7 +151,7 @@ class CallService : VectorService() {
* *
*/ */
private fun displayIncomingCallNotification(intent: Intent) { private fun displayIncomingCallNotification(intent: Intent) {
Timber.tag(CallServiceTag.computedValue).v("displayIncomingCallNotification $intent") Timber.tag(loggerTag.value).v("displayIncomingCallNotification $intent")
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: "" val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: ""
val call = callManager.getCallById(callId) ?: return Unit.also { val call = callManager.getCallById(callId) ?: return Unit.also {
handleUnexpectedState(callId) handleUnexpectedState(callId)
@ -159,7 +159,7 @@ class CallService : VectorService() {
val isVideoCall = call.mxCall.isVideoCall val isVideoCall = call.mxCall.isVideoCall
val fromBg = intent.getBooleanExtra(EXTRA_IS_IN_BG, false) val fromBg = intent.getBooleanExtra(EXTRA_IS_IN_BG, false)
val opponentMatrixItem = getOpponentMatrixItem(call) val opponentMatrixItem = getOpponentMatrixItem(call)
Timber.tag(CallServiceTag.computedValue).v("displayIncomingCallNotification : display the dedicated notification") Timber.tag(loggerTag.value).v("displayIncomingCallNotification : display the dedicated notification")
val incomingCallAlert = IncomingCallAlert(callId, val incomingCallAlert = IncomingCallAlert(callId,
shouldBeDisplayedIn = { activity -> shouldBeDisplayedIn = { activity ->
if (activity is VectorCallActivity) { if (activity is VectorCallActivity) {
@ -195,7 +195,7 @@ class CallService : VectorService() {
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: "" val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: ""
alertManager.cancelAlert(callId) alertManager.cancelAlert(callId)
if (!knownCalls.remove(callId)) { if (!knownCalls.remove(callId)) {
Timber.tag(CallServiceTag.computedValue).v("Call terminated for unknown call $callId$") Timber.tag(loggerTag.value).v("Call terminated for unknown call $callId$")
handleUnexpectedState(callId) handleUnexpectedState(callId)
return return
} }
@ -222,7 +222,7 @@ class CallService : VectorService() {
handleUnexpectedState(callId) handleUnexpectedState(callId)
} }
val opponentMatrixItem = getOpponentMatrixItem(call) val opponentMatrixItem = getOpponentMatrixItem(call)
Timber.tag(CallServiceTag.computedValue).v("displayOutgoingCallNotification : display the dedicated notification") Timber.tag(loggerTag.value).v("displayOutgoingCallNotification : display the dedicated notification")
val notification = notificationUtils.buildOutgoingRingingCallNotification( val notification = notificationUtils.buildOutgoingRingingCallNotification(
call = call, call = call,
title = opponentMatrixItem?.getBestName() ?: call.mxCall.opponentUserId title = opponentMatrixItem?.getBestName() ?: call.mxCall.opponentUserId
@ -239,7 +239,7 @@ class CallService : VectorService() {
* Display a call in progress notification. * Display a call in progress notification.
*/ */
private fun displayCallInProgressNotification(intent: Intent) { private fun displayCallInProgressNotification(intent: Intent) {
Timber.tag(CallServiceTag.computedValue).v("displayCallInProgressNotification") Timber.tag(loggerTag.value).v("displayCallInProgressNotification")
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: "" val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: ""
val call = callManager.getCallById(callId) ?: return Unit.also { val call = callManager.getCallById(callId) ?: return Unit.also {
handleUnexpectedState(callId) handleUnexpectedState(callId)
@ -259,7 +259,7 @@ class CallService : VectorService() {
} }
private fun handleUnexpectedState(callId: String?) { private fun handleUnexpectedState(callId: String?) {
Timber.tag(CallServiceTag.computedValue).v("Fallback to clear everything") Timber.tag(loggerTag.value).v("Fallback to clear everything")
callRingPlayerIncoming?.stop() callRingPlayerIncoming?.stop()
callRingPlayerOutgoing?.stop() callRingPlayerOutgoing?.stop()
if (callId != null) { if (callId != null) {

View File

@ -54,6 +54,7 @@ import im.vector.app.features.home.room.detail.RoomDetailArgs
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.session.call.CallState import org.matrix.android.sdk.api.session.call.CallState
import org.matrix.android.sdk.api.session.call.MxPeerConnectionState import org.matrix.android.sdk.api.session.call.MxPeerConnectionState
import org.matrix.android.sdk.api.session.call.TurnServerResponse import org.matrix.android.sdk.api.session.call.TurnServerResponse
@ -71,6 +72,8 @@ data class CallArgs(
val isVideoCall: Boolean val isVideoCall: Boolean
) : Parcelable ) : Parcelable
private val loggerTag = LoggerTag("VectorCallActivity", LoggerTag.VOIP)
class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallControlsView.InteractionListener { class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallControlsView.InteractionListener {
override fun getBinding() = ActivityCallBinding.inflate(layoutInflater) override fun getBinding() = ActivityCallBinding.inflate(layoutInflater)
@ -113,11 +116,11 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
if (intent.hasExtra(MvRx.KEY_ARG)) { if (intent.hasExtra(MvRx.KEY_ARG)) {
callArgs = intent.getParcelableExtra(MvRx.KEY_ARG)!! callArgs = intent.getParcelableExtra(MvRx.KEY_ARG)!!
} else { } else {
Timber.e("## VOIP missing callArgs for VectorCall Activity") Timber.tag(loggerTag.value).e("missing callArgs for VectorCall Activity")
finish() finish()
} }
Timber.v("## VOIP EXTRA_MODE is ${intent.getStringExtra(EXTRA_MODE)}") Timber.tag(loggerTag.value).v("EXTRA_MODE is ${intent.getStringExtra(EXTRA_MODE)}")
if (intent.getStringExtra(EXTRA_MODE) == INCOMING_RINGING) { if (intent.getStringExtra(EXTRA_MODE) == INCOMING_RINGING) {
turnScreenOnAndKeyguardOff() turnScreenOnAndKeyguardOff()
} }
@ -160,7 +163,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
} }
private fun renderState(state: VectorCallViewState) { private fun renderState(state: VectorCallViewState) {
Timber.v("## VOIP renderState call $state") Timber.tag(loggerTag.value).v("renderState call $state")
if (state.callState is Fail) { if (state.callState is Fail) {
finish() finish()
return return
@ -309,7 +312,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
private fun start() { private fun start() {
rootEglBase = EglUtils.rootEglBase ?: return Unit.also { rootEglBase = EglUtils.rootEglBase ?: return Unit.also {
Timber.v("## VOIP rootEglBase is null") Timber.tag(loggerTag.value).v("rootEglBase is null")
finish() finish()
} }
@ -335,7 +338,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
} }
private fun handleViewEvents(event: VectorCallViewEvents?) { private fun handleViewEvents(event: VectorCallViewEvents?) {
Timber.v("## VOIP handleViewEvents $event") Timber.tag(loggerTag.value).v("handleViewEvents $event")
when (event) { when (event) {
VectorCallViewEvents.DismissNoCall -> { VectorCallViewEvents.DismissNoCall -> {
finish() finish()
@ -357,7 +360,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
} }
private fun onErrorTimoutConnect(turn: TurnServerResponse?) { private fun onErrorTimoutConnect(turn: TurnServerResponse?) {
Timber.d("## VOIP onErrorTimoutConnect $turn") Timber.tag(loggerTag.value).d("onErrorTimoutConnect $turn")
// TODO ask to use default stun, etc... // TODO ask to use default stun, etc...
MaterialAlertDialogBuilder(this) MaterialAlertDialogBuilder(this)
.setTitle(R.string.call_failed_no_connection) .setTitle(R.string.call_failed_no_connection)
@ -437,7 +440,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
// Needed to let you answer call when phone is locked // Needed to let you answer call when phone is locked
private fun turnScreenOnAndKeyguardOff() { private fun turnScreenOnAndKeyguardOff() {
Timber.v("## VOIP turnScreenOnAndKeyguardOff") Timber.tag(loggerTag.value).v("turnScreenOnAndKeyguardOff")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true) setShowWhenLocked(true)
setTurnScreenOn(true) setTurnScreenOn(true)
@ -458,7 +461,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
} }
private fun turnScreenOffAndKeyguardOn() { private fun turnScreenOffAndKeyguardOn() {
Timber.v("## VOIP turnScreenOnAndKeyguardOn") Timber.tag(loggerTag.value).v("turnScreenOnAndKeyguardOn")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(false) setShowWhenLocked(false)
setTurnScreenOn(false) setTurnScreenOn(false)

View File

@ -25,9 +25,12 @@ import android.media.AudioManager
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import im.vector.app.core.services.BluetoothHeadsetReceiver import im.vector.app.core.services.BluetoothHeadsetReceiver
import im.vector.app.core.services.WiredHeadsetStateReceiver import im.vector.app.core.services.WiredHeadsetStateReceiver
import org.matrix.android.sdk.api.logger.LoggerTag
import timber.log.Timber import timber.log.Timber
import java.util.HashSet import java.util.HashSet
private val loggerTag = LoggerTag("API21AudioDeviceDetector", LoggerTag.VOIP)
internal class API21AudioDeviceDetector(private val context: Context, internal class API21AudioDeviceDetector(private val context: Context,
private val audioManager: AudioManager, private val audioManager: AudioManager,
private val callAudioManager: CallAudioManager private val callAudioManager: CallAudioManager
@ -62,17 +65,17 @@ internal class API21AudioDeviceDetector(private val context: Context,
} }
private fun isBluetoothHeadsetOn(): Boolean { private fun isBluetoothHeadsetOn(): Boolean {
Timber.v("## VOIP: AudioManager isBluetoothHeadsetOn") Timber.tag(loggerTag.value).v("AudioManager isBluetoothHeadsetOn")
try { try {
if (connectedBlueToothHeadset == null) return false.also { if (connectedBlueToothHeadset == null) return false.also {
Timber.v("## VOIP: AudioManager no connected bluetooth headset") Timber.tag(loggerTag.value).v("AudioManager no connected bluetooth headset")
} }
if (!audioManager.isBluetoothScoAvailableOffCall) return false.also { if (!audioManager.isBluetoothScoAvailableOffCall) return false.also {
Timber.v("## VOIP: AudioManager isBluetoothScoAvailableOffCall false") Timber.tag(loggerTag.value).v("AudioManager isBluetoothScoAvailableOffCall false")
} }
return true return true
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.e("## VOIP: AudioManager isBluetoothHeadsetOn failure ${failure.localizedMessage}") Timber.e("AudioManager isBluetoothHeadsetOn failure ${failure.localizedMessage}")
return false return false
} }
} }
@ -91,11 +94,11 @@ internal class API21AudioDeviceDetector(private val context: Context,
bluetoothHeadsetStateReceiver = BluetoothHeadsetReceiver.createAndRegister(context, this) bluetoothHeadsetStateReceiver = BluetoothHeadsetReceiver.createAndRegister(context, this)
val bm: BluetoothManager? = context.getSystemService() val bm: BluetoothManager? = context.getSystemService()
val adapter = bm?.adapter val adapter = bm?.adapter
Timber.d("## VOIP Bluetooth adapter $adapter") Timber.tag(loggerTag.value).d("Bluetooth adapter $adapter")
bluetoothAdapter = adapter bluetoothAdapter = adapter
adapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener { adapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener {
override fun onServiceDisconnected(profile: Int) { override fun onServiceDisconnected(profile: Int) {
Timber.d("## VOIP onServiceDisconnected $profile") Timber.tag(loggerTag.value).d("onServiceDisconnected $profile")
if (profile == BluetoothProfile.HEADSET) { if (profile == BluetoothProfile.HEADSET) {
connectedBlueToothHeadset = null connectedBlueToothHeadset = null
onAudioDeviceChange() onAudioDeviceChange()
@ -103,7 +106,7 @@ internal class API21AudioDeviceDetector(private val context: Context,
} }
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile?) { override fun onServiceConnected(profile: Int, proxy: BluetoothProfile?) {
Timber.d("## VOIP onServiceConnected $profile , proxy:$proxy") Timber.tag(loggerTag.value).d("onServiceConnected $profile , proxy:$proxy")
if (profile == BluetoothProfile.HEADSET) { if (profile == BluetoothProfile.HEADSET) {
connectedBlueToothHeadset = proxy connectedBlueToothHeadset = proxy
onAudioDeviceChange() onAudioDeviceChange()
@ -122,12 +125,12 @@ internal class API21AudioDeviceDetector(private val context: Context,
} }
override fun onHeadsetEvent(event: WiredHeadsetStateReceiver.HeadsetPlugEvent) { override fun onHeadsetEvent(event: WiredHeadsetStateReceiver.HeadsetPlugEvent) {
Timber.v("onHeadsetEvent $event") Timber.tag(loggerTag.value).v("onHeadsetEvent $event")
onAudioDeviceChange() onAudioDeviceChange()
} }
override fun onBTHeadsetEvent(event: BluetoothHeadsetReceiver.BTHeadsetPlugEvent) { override fun onBTHeadsetEvent(event: BluetoothHeadsetReceiver.BTHeadsetPlugEvent) {
Timber.v("onBTHeadsetEvent $event") Timber.tag(loggerTag.value).v("onBTHeadsetEvent $event")
onAudioDeviceChange() onAudioDeviceChange()
} }
} }

View File

@ -16,6 +16,7 @@
package im.vector.app.features.call.webrtc package im.vector.app.features.call.webrtc
import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.session.call.CallState import org.matrix.android.sdk.api.session.call.CallState
import org.matrix.android.sdk.api.session.call.MxPeerConnectionState import org.matrix.android.sdk.api.session.call.MxPeerConnectionState
import org.webrtc.DataChannel import org.webrtc.DataChannel
@ -25,10 +26,12 @@ import org.webrtc.PeerConnection
import org.webrtc.RtpReceiver import org.webrtc.RtpReceiver
import timber.log.Timber import timber.log.Timber
private val loggerTag = LoggerTag("PeerConnectionObserver", LoggerTag.VOIP)
class PeerConnectionObserver(private val webRtcCall: WebRtcCall) : PeerConnection.Observer { class PeerConnectionObserver(private val webRtcCall: WebRtcCall) : PeerConnection.Observer {
override fun onConnectionChange(newState: PeerConnection.PeerConnectionState?) { override fun onConnectionChange(newState: PeerConnection.PeerConnectionState?) {
Timber.v("## VOIP StreamObserver onConnectionChange: $newState") Timber.tag(loggerTag.value).v("StreamObserver onConnectionChange: $newState")
when (newState) { when (newState) {
/** /**
* Every ICE transport used by the connection is either in use (state "connected" or "completed") * Every ICE transport used by the connection is either in use (state "connected" or "completed")
@ -79,20 +82,20 @@ class PeerConnectionObserver(private val webRtcCall: WebRtcCall) : PeerConnectio
} }
override fun onIceCandidate(iceCandidate: IceCandidate) { override fun onIceCandidate(iceCandidate: IceCandidate) {
Timber.v("## VOIP StreamObserver onIceCandidate: $iceCandidate") Timber.tag(loggerTag.value).v("StreamObserver onIceCandidate: $iceCandidate")
webRtcCall.onIceCandidate(iceCandidate) webRtcCall.onIceCandidate(iceCandidate)
} }
override fun onDataChannel(dc: DataChannel) { override fun onDataChannel(dc: DataChannel) {
Timber.v("## VOIP StreamObserver onDataChannel: ${dc.state()}") Timber.tag(loggerTag.value).v("StreamObserver onDataChannel: ${dc.state()}")
} }
override fun onIceConnectionReceivingChange(receiving: Boolean) { override fun onIceConnectionReceivingChange(receiving: Boolean) {
Timber.v("## VOIP StreamObserver onIceConnectionReceivingChange: $receiving") Timber.tag(loggerTag.value).v("StreamObserver onIceConnectionReceivingChange: $receiving")
} }
override fun onIceConnectionChange(newState: PeerConnection.IceConnectionState) { override fun onIceConnectionChange(newState: PeerConnection.IceConnectionState) {
Timber.v("## VOIP StreamObserver onIceConnectionChange IceConnectionState:$newState") Timber.tag(loggerTag.value).v("StreamObserver onIceConnectionChange IceConnectionState:$newState")
when (newState) { when (newState) {
/** /**
* the ICE agent is gathering addresses or is waiting to be given remote candidates through * the ICE agent is gathering addresses or is waiting to be given remote candidates through
@ -145,29 +148,29 @@ class PeerConnectionObserver(private val webRtcCall: WebRtcCall) : PeerConnectio
} }
override fun onAddStream(stream: MediaStream) { override fun onAddStream(stream: MediaStream) {
Timber.v("## VOIP StreamObserver onAddStream: $stream") Timber.tag(loggerTag.value).v("StreamObserver onAddStream: $stream")
webRtcCall.onAddStream(stream) webRtcCall.onAddStream(stream)
} }
override fun onRemoveStream(stream: MediaStream) { override fun onRemoveStream(stream: MediaStream) {
Timber.v("## VOIP StreamObserver onRemoveStream") Timber.tag(loggerTag.value).v("StreamObserver onRemoveStream")
webRtcCall.onRemoveStream() webRtcCall.onRemoveStream()
} }
override fun onIceGatheringChange(newState: PeerConnection.IceGatheringState) { override fun onIceGatheringChange(newState: PeerConnection.IceGatheringState) {
Timber.v("## VOIP StreamObserver onIceGatheringChange: $newState") Timber.tag(loggerTag.value).v("StreamObserver onIceGatheringChange: $newState")
} }
override fun onSignalingChange(newState: PeerConnection.SignalingState) { override fun onSignalingChange(newState: PeerConnection.SignalingState) {
Timber.v("## VOIP StreamObserver onSignalingChange: $newState") Timber.tag(loggerTag.value).v("StreamObserver onSignalingChange: $newState")
} }
override fun onIceCandidatesRemoved(candidates: Array<out IceCandidate>) { override fun onIceCandidatesRemoved(candidates: Array<out IceCandidate>) {
Timber.v("## VOIP StreamObserver onIceCandidatesRemoved: ${candidates.contentToString()}") Timber.tag(loggerTag.value).v("StreamObserver onIceCandidatesRemoved: ${candidates.contentToString()}")
} }
override fun onRenegotiationNeeded() { override fun onRenegotiationNeeded() {
Timber.v("## VOIP StreamObserver onRenegotiationNeeded") Timber.tag(loggerTag.value).v("StreamObserver onRenegotiationNeeded")
webRtcCall.onRenegotiationNeeded(restartIce = false) webRtcCall.onRenegotiationNeeded(restartIce = false)
} }
@ -178,6 +181,6 @@ class PeerConnectionObserver(private val webRtcCall: WebRtcCall) : PeerConnectio
* gets a new set of tracks because the media element being captured loaded a new source. * gets a new set of tracks because the media element being captured loaded a new source.
*/ */
override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) { override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) {
Timber.v("## VOIP StreamObserver onAddTrack") Timber.tag(loggerTag.value).v("StreamObserver onAddTrack")
} }
} }

View File

@ -1,70 +0,0 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.features.call.webrtc
import org.webrtc.DataChannel
import org.webrtc.IceCandidate
import org.webrtc.MediaStream
import org.webrtc.PeerConnection
import org.webrtc.RtpReceiver
import timber.log.Timber
abstract class PeerConnectionObserverAdapter : PeerConnection.Observer {
override fun onIceCandidate(p0: IceCandidate?) {
Timber.v("## VOIP onIceCandidate $p0")
}
override fun onDataChannel(p0: DataChannel?) {
Timber.v("## VOIP onDataChannel $p0")
}
override fun onIceConnectionReceivingChange(p0: Boolean) {
Timber.v("## VOIP onIceConnectionReceivingChange $p0")
}
override fun onIceConnectionChange(p0: PeerConnection.IceConnectionState?) {
Timber.v("## VOIP onIceConnectionChange $p0")
}
override fun onIceGatheringChange(p0: PeerConnection.IceGatheringState?) {
Timber.v("## VOIP onIceConnectionChange $p0")
}
override fun onAddStream(mediaStream: MediaStream?) {
Timber.v("## VOIP onAddStream $mediaStream")
}
override fun onSignalingChange(p0: PeerConnection.SignalingState?) {
Timber.v("## VOIP onSignalingChange $p0")
}
override fun onIceCandidatesRemoved(p0: Array<out IceCandidate>?) {
Timber.v("## VOIP onIceCandidatesRemoved $p0")
}
override fun onRemoveStream(mediaStream: MediaStream?) {
Timber.v("## VOIP onRemoveStream $mediaStream")
}
override fun onRenegotiationNeeded() {
Timber.v("## VOIP onRenegotiationNeeded")
}
override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) {
Timber.v("## VOIP onAddTrack $p0 / out: $p1")
}
}

View File

@ -89,7 +89,7 @@ private const val AUDIO_TRACK_ID = "${STREAM_ID}a0"
private const val VIDEO_TRACK_ID = "${STREAM_ID}v0" private const val VIDEO_TRACK_ID = "${STREAM_ID}v0"
private val DEFAULT_AUDIO_CONSTRAINTS = MediaConstraints() private val DEFAULT_AUDIO_CONSTRAINTS = MediaConstraints()
private val WebRtcCallTag = LoggerTag("WebRtcCall", LoggerTag.VOIP) private val loggerTag = LoggerTag("WebRtcCall", LoggerTag.VOIP)
class WebRtcCall( class WebRtcCall(
val mxCall: MxCall, val mxCall: MxCall,
@ -195,7 +195,7 @@ class WebRtcCall(
.subscribe { .subscribe {
// omit empty :/ // omit empty :/
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
Timber.tag(WebRtcCallTag.computedValue).v("Sending local ice candidates to call") Timber.tag(loggerTag.value).v("Sending local ice candidates to call")
// it.forEach { peerConnection?.addIceCandidate(it) } // it.forEach { peerConnection?.addIceCandidate(it) }
mxCall.sendLocalCallCandidates(it.mapToCallCandidate()) mxCall.sendLocalCallCandidates(it.mapToCallCandidate())
} }
@ -213,7 +213,7 @@ class WebRtcCall(
fun onRenegotiationNeeded(restartIce: Boolean) { fun onRenegotiationNeeded(restartIce: Boolean) {
sessionScope?.launch(dispatcher) { sessionScope?.launch(dispatcher) {
if (mxCall.state != CallState.CreateOffer && mxCall.opponentVersion == 0) { if (mxCall.state != CallState.CreateOffer && mxCall.opponentVersion == 0) {
Timber.tag(WebRtcCallTag.computedValue).v("Opponent does not support renegotiation: ignoring onRenegotiationNeeded event") Timber.tag(loggerTag.value).v("Opponent does not support renegotiation: ignoring onRenegotiationNeeded event")
return@launch return@launch
} }
val constraints = MediaConstraints() val constraints = MediaConstraints()
@ -221,7 +221,7 @@ class WebRtcCall(
constraints.mandatory.add(MediaConstraints.KeyValuePair("IceRestart", "true")) constraints.mandatory.add(MediaConstraints.KeyValuePair("IceRestart", "true"))
} }
val peerConnection = peerConnection ?: return@launch val peerConnection = peerConnection ?: return@launch
Timber.tag(WebRtcCallTag.computedValue).v("creating offer...") Timber.tag(loggerTag.value).v("creating offer...")
makingOffer = true makingOffer = true
try { try {
val sessionDescription = peerConnection.awaitCreateOffer(constraints) ?: return@launch val sessionDescription = peerConnection.awaitCreateOffer(constraints) ?: return@launch
@ -241,7 +241,7 @@ class WebRtcCall(
} }
} catch (failure: Throwable) { } catch (failure: Throwable) {
// Need to handle error properly. // Need to handle error properly.
Timber.tag(WebRtcCallTag.computedValue).v("Failure while creating offer") Timber.tag(loggerTag.value).v("Failure while creating offer")
} finally { } finally {
makingOffer = false makingOffer = false
} }
@ -270,7 +270,7 @@ class WebRtcCall(
} }
} }
} }
Timber.tag(WebRtcCallTag.computedValue).v("creating peer connection...with iceServers $iceServers ") Timber.tag(loggerTag.value).v("creating peer connection...with iceServers $iceServers ")
val rtcConfig = PeerConnection.RTCConfiguration(iceServers).apply { val rtcConfig = PeerConnection.RTCConfiguration(iceServers).apply {
sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN
} }
@ -317,7 +317,7 @@ class WebRtcCall(
fun acceptIncomingCall() { fun acceptIncomingCall() {
sessionScope?.launch { sessionScope?.launch {
Timber.tag(WebRtcCallTag.computedValue).v("acceptIncomingCall from state ${mxCall.state}") Timber.tag(loggerTag.value).v("acceptIncomingCall from state ${mxCall.state}")
if (mxCall.state == CallState.LocalRinging) { if (mxCall.state == CallState.LocalRinging) {
internalAcceptIncomingCall() internalAcceptIncomingCall()
} }
@ -336,7 +336,7 @@ class WebRtcCall(
sender.dtmf()?.insertDtmf(digit, 100, 70) sender.dtmf()?.insertDtmf(digit, 100, 70)
return@launch return@launch
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.tag(WebRtcCallTag.computedValue).v("Fail to send Dtmf digit") Timber.tag(loggerTag.value).v("Fail to send Dtmf digit")
} }
} }
} }
@ -345,7 +345,7 @@ class WebRtcCall(
fun attachViewRenderers(localViewRenderer: SurfaceViewRenderer?, remoteViewRenderer: SurfaceViewRenderer, mode: String?) { fun attachViewRenderers(localViewRenderer: SurfaceViewRenderer?, remoteViewRenderer: SurfaceViewRenderer, mode: String?) {
sessionScope?.launch(dispatcher) { sessionScope?.launch(dispatcher) {
Timber.tag(WebRtcCallTag.computedValue).v("attachViewRenderers localRendeder $localViewRenderer / $remoteViewRenderer") Timber.tag(loggerTag.value).v("attachViewRenderers localRendeder $localViewRenderer / $remoteViewRenderer")
localSurfaceRenderers.addIfNeeded(localViewRenderer) localSurfaceRenderers.addIfNeeded(localViewRenderer)
remoteSurfaceRenderers.addIfNeeded(remoteViewRenderer) remoteSurfaceRenderers.addIfNeeded(remoteViewRenderer)
when (mode) { when (mode) {
@ -392,7 +392,7 @@ class WebRtcCall(
} }
private suspend fun detachRenderersInternal(renderers: List<SurfaceViewRenderer>?) = withContext(dispatcher) { private suspend fun detachRenderersInternal(renderers: List<SurfaceViewRenderer>?) = withContext(dispatcher) {
Timber.tag(WebRtcCallTag.computedValue).v("detachRenderers") Timber.tag(loggerTag.value).v("detachRenderers")
if (renderers.isNullOrEmpty()) { if (renderers.isNullOrEmpty()) {
// remove all sinks // remove all sinks
localSurfaceRenderers.forEach { localSurfaceRenderers.forEach {
@ -425,12 +425,12 @@ class WebRtcCall(
// 2. Access camera (if video call) + microphone, create local stream // 2. Access camera (if video call) + microphone, create local stream
createLocalStream() createLocalStream()
attachViewRenderersInternal() attachViewRenderersInternal()
Timber.tag(WebRtcCallTag.computedValue).v("remoteCandidateSource $remoteCandidateSource") Timber.tag(loggerTag.value).v("remoteCandidateSource $remoteCandidateSource")
remoteIceCandidateDisposable = remoteCandidateSource.subscribe({ remoteIceCandidateDisposable = remoteCandidateSource.subscribe({
Timber.tag(WebRtcCallTag.computedValue).v("adding remote ice candidate $it") Timber.tag(loggerTag.value).v("adding remote ice candidate $it")
peerConnection?.addIceCandidate(it) peerConnection?.addIceCandidate(it)
}, { }, {
Timber.tag(WebRtcCallTag.computedValue).v("failed to add remote ice candidate $it") Timber.tag(loggerTag.value).v("failed to add remote ice candidate $it")
}) })
// Now we wait for negotiation callback // Now we wait for negotiation callback
} }
@ -456,14 +456,14 @@ class WebRtcCall(
SessionDescription(SessionDescription.Type.OFFER, it) SessionDescription(SessionDescription.Type.OFFER, it)
} }
if (offerSdp == null) { if (offerSdp == null) {
Timber.tag(WebRtcCallTag.computedValue).v("We don't have any offer to process") Timber.tag(loggerTag.value).v("We don't have any offer to process")
return@withContext return@withContext
} }
Timber.tag(WebRtcCallTag.computedValue).v("Offer sdp for invite: ${offerSdp.description}") Timber.tag(loggerTag.value).v("Offer sdp for invite: ${offerSdp.description}")
try { try {
peerConnection?.awaitSetRemoteDescription(offerSdp) peerConnection?.awaitSetRemoteDescription(offerSdp)
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.tag(WebRtcCallTag.computedValue).v("Failure putting remote description") Timber.tag(loggerTag.value).v("Failure putting remote description")
endCall(true, CallHangupContent.Reason.UNKWOWN_ERROR) endCall(true, CallHangupContent.Reason.UNKWOWN_ERROR)
return@withContext return@withContext
} }
@ -475,12 +475,12 @@ class WebRtcCall(
createAnswer()?.also { createAnswer()?.also {
mxCall.accept(it.description) mxCall.accept(it.description)
} }
Timber.tag(WebRtcCallTag.computedValue).v("remoteCandidateSource $remoteCandidateSource") Timber.tag(loggerTag.value).v("remoteCandidateSource $remoteCandidateSource")
remoteIceCandidateDisposable = remoteCandidateSource.subscribe({ remoteIceCandidateDisposable = remoteCandidateSource.subscribe({
Timber.tag(WebRtcCallTag.computedValue).v("adding remote ice candidate $it") Timber.tag(loggerTag.value).v("adding remote ice candidate $it")
peerConnection?.addIceCandidate(it) peerConnection?.addIceCandidate(it)
}, { }, {
Timber.tag(WebRtcCallTag.computedValue).v("failed to add remote ice candidate $it") Timber.tag(loggerTag.value).v("failed to add remote ice candidate $it")
}) })
} }
@ -492,7 +492,7 @@ class WebRtcCall(
private fun createLocalStream() { private fun createLocalStream() {
val peerConnectionFactory = peerConnectionFactoryProvider.get() ?: return val peerConnectionFactory = peerConnectionFactoryProvider.get() ?: return
Timber.tag(WebRtcCallTag.computedValue).v("Create local stream for call ${mxCall.callId}") Timber.tag(loggerTag.value).v("Create local stream for call ${mxCall.callId}")
configureAudioTrack(peerConnectionFactory) configureAudioTrack(peerConnectionFactory)
// add video track if needed // add video track if needed
if (mxCall.isVideoCall) { if (mxCall.isVideoCall) {
@ -505,7 +505,7 @@ class WebRtcCall(
val audioSource = peerConnectionFactory.createAudioSource(DEFAULT_AUDIO_CONSTRAINTS) val audioSource = peerConnectionFactory.createAudioSource(DEFAULT_AUDIO_CONSTRAINTS)
val audioTrack = peerConnectionFactory.createAudioTrack(AUDIO_TRACK_ID, audioSource) val audioTrack = peerConnectionFactory.createAudioTrack(AUDIO_TRACK_ID, audioSource)
audioTrack.setEnabled(true) audioTrack.setEnabled(true)
Timber.tag(WebRtcCallTag.computedValue).v("Add audio track $AUDIO_TRACK_ID to call ${mxCall.callId}") Timber.tag(loggerTag.value).v("Add audio track $AUDIO_TRACK_ID to call ${mxCall.callId}")
peerConnection?.addTrack(audioTrack, listOf(STREAM_ID)) peerConnection?.addTrack(audioTrack, listOf(STREAM_ID))
localAudioSource = audioSource localAudioSource = audioSource
localAudioTrack = audioTrack localAudioTrack = audioTrack
@ -547,7 +547,7 @@ class WebRtcCall(
override fun onCameraClosed() { override fun onCameraClosed() {
super.onCameraClosed() super.onCameraClosed()
Timber.tag(WebRtcCallTag.computedValue).v("onCameraClosed") Timber.tag(loggerTag.value).v("onCameraClosed")
// This could happen if you open the camera app in chat // This could happen if you open the camera app in chat
// We then register in order to restart capture as soon as the camera is available again // We then register in order to restart capture as soon as the camera is available again
videoCapturerIsInError = true videoCapturerIsInError = true
@ -555,16 +555,16 @@ class WebRtcCall(
cameraAvailabilityCallback = object : CameraManager.AvailabilityCallback() { cameraAvailabilityCallback = object : CameraManager.AvailabilityCallback() {
override fun onCameraUnavailable(cameraId: String) { override fun onCameraUnavailable(cameraId: String) {
super.onCameraUnavailable(cameraId) super.onCameraUnavailable(cameraId)
Timber.tag(WebRtcCallTag.computedValue).v("On camera unavailable: $cameraId") Timber.tag(loggerTag.value).v("On camera unavailable: $cameraId")
} }
override fun onCameraAccessPrioritiesChanged() { override fun onCameraAccessPrioritiesChanged() {
super.onCameraAccessPrioritiesChanged() super.onCameraAccessPrioritiesChanged()
Timber.tag(WebRtcCallTag.computedValue).v("onCameraAccessPrioritiesChanged") Timber.tag(loggerTag.value).v("onCameraAccessPrioritiesChanged")
} }
override fun onCameraAvailable(cameraId: String) { override fun onCameraAvailable(cameraId: String) {
Timber.tag(WebRtcCallTag.computedValue).v("On camera available: $cameraId") Timber.tag(loggerTag.value).v("On camera available: $cameraId")
if (cameraId == camera.name) { if (cameraId == camera.name) {
videoCapturer?.startCapture(currentCaptureFormat.width, currentCaptureFormat.height, currentCaptureFormat.fps) videoCapturer?.startCapture(currentCaptureFormat.width, currentCaptureFormat.height, currentCaptureFormat.fps)
cameraManager?.unregisterAvailabilityCallback(this) cameraManager?.unregisterAvailabilityCallback(this)
@ -577,7 +577,7 @@ class WebRtcCall(
val videoSource = peerConnectionFactory.createVideoSource(videoCapturer.isScreencast) val videoSource = peerConnectionFactory.createVideoSource(videoCapturer.isScreencast)
val surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", rootEglBase!!.eglBaseContext) val surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", rootEglBase!!.eglBaseContext)
Timber.tag(WebRtcCallTag.computedValue).v("Local video source created") Timber.tag(loggerTag.value).v("Local video source created")
videoCapturer.initialize(surfaceTextureHelper, context, videoSource.capturerObserver) videoCapturer.initialize(surfaceTextureHelper, context, videoSource.capturerObserver)
// HD // HD
@ -585,7 +585,7 @@ class WebRtcCall(
this.videoCapturer = videoCapturer this.videoCapturer = videoCapturer
val videoTrack = peerConnectionFactory.createVideoTrack(VIDEO_TRACK_ID, videoSource) val videoTrack = peerConnectionFactory.createVideoTrack(VIDEO_TRACK_ID, videoSource)
Timber.tag(WebRtcCallTag.computedValue).v("Add video track $VIDEO_TRACK_ID to call ${mxCall.callId}") Timber.tag(loggerTag.value).v("Add video track $VIDEO_TRACK_ID to call ${mxCall.callId}")
videoTrack.setEnabled(true) videoTrack.setEnabled(true)
peerConnection?.addTrack(videoTrack, listOf(STREAM_ID)) peerConnection?.addTrack(videoTrack, listOf(STREAM_ID))
localVideoSource = videoSource localVideoSource = videoSource
@ -595,7 +595,7 @@ class WebRtcCall(
fun setCaptureFormat(format: CaptureFormat) { fun setCaptureFormat(format: CaptureFormat) {
sessionScope?.launch(dispatcher) { sessionScope?.launch(dispatcher) {
Timber.tag(WebRtcCallTag.computedValue).v("setCaptureFormat $format") Timber.tag(loggerTag.value).v("setCaptureFormat $format")
videoCapturer?.changeCaptureFormat(format.width, format.height, format.fps) videoCapturer?.changeCaptureFormat(format.width, format.height, format.fps)
currentCaptureFormat = format currentCaptureFormat = format
} }
@ -689,14 +689,14 @@ class WebRtcCall(
fun switchCamera() { fun switchCamera() {
sessionScope?.launch(dispatcher) { sessionScope?.launch(dispatcher) {
Timber.tag(WebRtcCallTag.computedValue).v("switchCamera") Timber.tag(loggerTag.value).v("switchCamera")
if (mxCall.state is CallState.Connected && mxCall.isVideoCall) { if (mxCall.state is CallState.Connected && mxCall.isVideoCall) {
val oppositeCamera = getOppositeCameraIfAny() ?: return@launch val oppositeCamera = getOppositeCameraIfAny() ?: return@launch
videoCapturer?.switchCamera( videoCapturer?.switchCamera(
object : CameraVideoCapturer.CameraSwitchHandler { object : CameraVideoCapturer.CameraSwitchHandler {
// Invoked on success. |isFrontCamera| is true if the new camera is front facing. // Invoked on success. |isFrontCamera| is true if the new camera is front facing.
override fun onCameraSwitchDone(isFrontCamera: Boolean) { override fun onCameraSwitchDone(isFrontCamera: Boolean) {
Timber.tag(WebRtcCallTag.computedValue).v("onCameraSwitchDone isFront $isFrontCamera") Timber.tag(loggerTag.value).v("onCameraSwitchDone isFront $isFrontCamera")
cameraInUse = oppositeCamera cameraInUse = oppositeCamera
localSurfaceRenderers.forEach { localSurfaceRenderers.forEach {
it.get()?.setMirror(isFrontCamera) it.get()?.setMirror(isFrontCamera)
@ -707,7 +707,7 @@ class WebRtcCall(
} }
override fun onCameraSwitchError(errorDescription: String?) { override fun onCameraSwitchError(errorDescription: String?) {
Timber.tag(WebRtcCallTag.computedValue).v("onCameraSwitchError isFront $errorDescription") Timber.tag(loggerTag.value).v("onCameraSwitchError isFront $errorDescription")
} }
}, oppositeCamera.name }, oppositeCamera.name
) )
@ -716,7 +716,7 @@ class WebRtcCall(
} }
private suspend fun createAnswer(): SessionDescription? { private suspend fun createAnswer(): SessionDescription? {
Timber.tag(WebRtcCallTag.computedValue).w("createAnswer") Timber.tag(loggerTag.value).w("createAnswer")
val peerConnection = peerConnection ?: return null val peerConnection = peerConnection ?: return null
val constraints = MediaConstraints().apply { val constraints = MediaConstraints().apply {
mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true")) mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"))
@ -727,7 +727,7 @@ class WebRtcCall(
peerConnection.awaitSetLocalDescription(localDescription) peerConnection.awaitSetLocalDescription(localDescription)
localDescription localDescription
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.tag(WebRtcCallTag.computedValue).v("Fail to create answer") Timber.tag(loggerTag.value).v("Fail to create answer")
null null
} }
} }
@ -768,7 +768,7 @@ class WebRtcCall(
sessionScope?.launch(dispatcher) { sessionScope?.launch(dispatcher) {
// reportError("Weird-looking stream: " + stream); // reportError("Weird-looking stream: " + stream);
if (stream.audioTracks.size > 1 || stream.videoTracks.size > 1) { if (stream.audioTracks.size > 1 || stream.videoTracks.size > 1) {
Timber.tag(WebRtcCallTag.computedValue).e("## VOIP StreamObserver weird looking stream: $stream") Timber.tag(loggerTag.value).e("StreamObserver weird looking stream: $stream")
// TODO maybe do something more?? // TODO maybe do something more??
endCall(true) endCall(true)
return@launch return@launch
@ -832,7 +832,7 @@ class WebRtcCall(
if (it.sdpMid.isNullOrEmpty() || it.candidate.isNullOrEmpty()) { if (it.sdpMid.isNullOrEmpty() || it.candidate.isNullOrEmpty()) {
return@forEach return@forEach
} }
Timber.tag(WebRtcCallTag.computedValue).v("onCallIceCandidateReceived for call ${mxCall.callId} sdp: ${it.candidate}") Timber.tag(loggerTag.value).v("onCallIceCandidateReceived for call ${mxCall.callId} sdp: ${it.candidate}")
val iceCandidate = IceCandidate(it.sdpMid, it.sdpMLineIndex, it.candidate) val iceCandidate = IceCandidate(it.sdpMid, it.sdpMLineIndex, it.candidate)
remoteCandidateSource.onNext(iceCandidate) remoteCandidateSource.onNext(iceCandidate)
} }
@ -841,7 +841,7 @@ class WebRtcCall(
fun onCallAnswerReceived(callAnswerContent: CallAnswerContent) { fun onCallAnswerReceived(callAnswerContent: CallAnswerContent) {
sessionScope?.launch(dispatcher) { sessionScope?.launch(dispatcher) {
Timber.tag(WebRtcCallTag.computedValue).v("onCallAnswerReceived ${callAnswerContent.callId}") Timber.tag(loggerTag.value).v("onCallAnswerReceived ${callAnswerContent.callId}")
val sdp = SessionDescription(SessionDescription.Type.ANSWER, callAnswerContent.answer.sdp) val sdp = SessionDescription(SessionDescription.Type.ANSWER, callAnswerContent.answer.sdp)
try { try {
peerConnection?.awaitSetRemoteDescription(sdp) peerConnection?.awaitSetRemoteDescription(sdp)
@ -861,7 +861,7 @@ class WebRtcCall(
val type = description?.type val type = description?.type
val sdpText = description?.sdp val sdpText = description?.sdp
if (type == null || sdpText == null) { if (type == null || sdpText == null) {
Timber.tag(WebRtcCallTag.computedValue).i("Ignoring invalid m.call.negotiate event") Timber.tag(loggerTag.value).i("Ignoring invalid m.call.negotiate event")
return@launch return@launch
} }
val peerConnection = peerConnection ?: return@launch val peerConnection = peerConnection ?: return@launch
@ -876,7 +876,7 @@ class WebRtcCall(
ignoreOffer = !polite && offerCollision ignoreOffer = !polite && offerCollision
if (ignoreOffer) { if (ignoreOffer) {
Timber.tag(WebRtcCallTag.computedValue).i("Ignoring colliding negotiate event because we're impolite") Timber.tag(loggerTag.value).i("Ignoring colliding negotiate event because we're impolite")
return@launch return@launch
} }
val prevOnHold = computeIsLocalOnHold() val prevOnHold = computeIsLocalOnHold()
@ -889,7 +889,7 @@ class WebRtcCall(
} }
} }
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.tag(WebRtcCallTag.computedValue).e(failure, "Failed to complete negotiation") Timber.tag(loggerTag.value).e(failure, "Failed to complete negotiation")
} }
val nowOnHold = computeIsLocalOnHold() val nowOnHold = computeIsLocalOnHold()
wasLocalOnHold = nowOnHold wasLocalOnHold = nowOnHold
@ -912,7 +912,7 @@ class WebRtcCall(
val session = sessionProvider.get() ?: return@launch val session = sessionProvider.get() ?: return@launch
val newAssertedIdentity = callAssertedIdentityContent.assertedIdentity ?: return@launch val newAssertedIdentity = callAssertedIdentityContent.assertedIdentity ?: return@launch
if (newAssertedIdentity.id == null && newAssertedIdentity.displayName == null) { if (newAssertedIdentity.id == null && newAssertedIdentity.displayName == null) {
Timber.tag(WebRtcCallTag.computedValue).v("Asserted identity received with no relevant information, skip") Timber.tag(loggerTag.value).v("Asserted identity received with no relevant information, skip")
return@launch return@launch
} }
remoteAssertedIdentity = newAssertedIdentity remoteAssertedIdentity = newAssertedIdentity

View File

@ -61,7 +61,7 @@ import javax.inject.Singleton
* Manage peerConnectionFactory & Peer connections outside of activity lifecycle to resist configuration changes * Manage peerConnectionFactory & Peer connections outside of activity lifecycle to resist configuration changes
* Use app context * Use app context
*/ */
private val WebRtcCallManagerTag = LoggerTag("WebRtcCallManager", LoggerTag.VOIP) private val loggerTag = LoggerTag("WebRtcCallManager", LoggerTag.VOIP)
@Singleton @Singleton
class WebRtcCallManager @Inject constructor( class WebRtcCallManager @Inject constructor(
@ -187,7 +187,7 @@ class WebRtcCallManager @Inject constructor(
fun getAdvertisedCalls() = advertisedCalls fun getAdvertisedCalls() = advertisedCalls
fun headSetButtonTapped() { fun headSetButtonTapped() {
Timber.tag(WebRtcCallManagerTag.computedValue).v("headSetButtonTapped") Timber.tag(loggerTag.value).v("headSetButtonTapped")
val call = getCurrentCall() ?: return val call = getCurrentCall() ?: return
if (call.mxCall.state is CallState.LocalRinging) { if (call.mxCall.state is CallState.LocalRinging) {
call.acceptIncomingCall() call.acceptIncomingCall()
@ -200,12 +200,12 @@ class WebRtcCallManager @Inject constructor(
private fun createPeerConnectionFactoryIfNeeded() { private fun createPeerConnectionFactoryIfNeeded() {
if (peerConnectionFactory != null) return if (peerConnectionFactory != null) return
Timber.tag(WebRtcCallManagerTag.computedValue).v("createPeerConnectionFactory") Timber.tag(loggerTag.value).v("createPeerConnectionFactory")
val eglBaseContext = rootEglBase?.eglBaseContext ?: return Unit.also { val eglBaseContext = rootEglBase?.eglBaseContext ?: return Unit.also {
Timber.tag(WebRtcCallManagerTag.computedValue).e("No EGL BASE") Timber.tag(loggerTag.value).e("No EGL BASE")
} }
Timber.tag(WebRtcCallManagerTag.computedValue).v("PeerConnectionFactory.initialize") Timber.tag(loggerTag.value).v("PeerConnectionFactory.initialize")
PeerConnectionFactory.initialize(PeerConnectionFactory PeerConnectionFactory.initialize(PeerConnectionFactory
.InitializationOptions.builder(context.applicationContext) .InitializationOptions.builder(context.applicationContext)
.createInitializationOptions() .createInitializationOptions()
@ -219,7 +219,7 @@ class WebRtcCallManager @Inject constructor(
/* enableH264HighProfile */ /* enableH264HighProfile */
true) true)
val defaultVideoDecoderFactory = DefaultVideoDecoderFactory(eglBaseContext) val defaultVideoDecoderFactory = DefaultVideoDecoderFactory(eglBaseContext)
Timber.tag(WebRtcCallManagerTag.computedValue).v("PeerConnectionFactory.createPeerConnectionFactory ...") Timber.tag(loggerTag.value).v("PeerConnectionFactory.createPeerConnectionFactory ...")
peerConnectionFactory = PeerConnectionFactory.builder() peerConnectionFactory = PeerConnectionFactory.builder()
.setOptions(options) .setOptions(options)
.setVideoEncoderFactory(defaultVideoEncoderFactory) .setVideoEncoderFactory(defaultVideoEncoderFactory)
@ -228,7 +228,7 @@ class WebRtcCallManager @Inject constructor(
} }
private fun onCallActive(call: WebRtcCall) { private fun onCallActive(call: WebRtcCall) {
Timber.tag(WebRtcCallManagerTag.computedValue).v("WebRtcPeerConnectionManager onCall active: ${call.mxCall.callId}") Timber.tag(loggerTag.value).v("WebRtcPeerConnectionManager onCall active: ${call.mxCall.callId}")
val currentCall = getCurrentCall().takeIf { it != call } val currentCall = getCurrentCall().takeIf { it != call }
currentCall?.updateRemoteOnHold(onHold = true) currentCall?.updateRemoteOnHold(onHold = true)
audioManager.setMode(if (call.mxCall.isVideoCall) CallAudioManager.Mode.VIDEO_CALL else CallAudioManager.Mode.AUDIO_CALL) audioManager.setMode(if (call.mxCall.isVideoCall) CallAudioManager.Mode.VIDEO_CALL else CallAudioManager.Mode.AUDIO_CALL)
@ -236,9 +236,9 @@ class WebRtcCallManager @Inject constructor(
} }
private fun onCallEnded(callId: String) { private fun onCallEnded(callId: String) {
Timber.tag(WebRtcCallManagerTag.computedValue).v("WebRtcPeerConnectionManager onCall ended: $callId") Timber.tag(loggerTag.value).v("WebRtcPeerConnectionManager onCall ended: $callId")
val webRtcCall = callsByCallId.remove(callId) ?: return Unit.also { val webRtcCall = callsByCallId.remove(callId) ?: return Unit.also {
Timber.tag(WebRtcCallManagerTag.computedValue).v("On call ended for unknown call $callId") Timber.tag(loggerTag.value).v("On call ended for unknown call $callId")
} }
CallService.onCallTerminated(context, callId) CallService.onCallTerminated(context, callId)
callsByRoomId[webRtcCall.signalingRoomId]?.remove(webRtcCall) callsByRoomId[webRtcCall.signalingRoomId]?.remove(webRtcCall)
@ -250,7 +250,7 @@ class WebRtcCallManager @Inject constructor(
} }
// There is no active calls // There is no active calls
if (getCurrentCall() == null) { if (getCurrentCall() == null) {
Timber.tag(WebRtcCallManagerTag.computedValue).v("Dispose peerConnectionFactory as there is no need to keep one") Timber.tag(loggerTag.value).v("Dispose peerConnectionFactory as there is no need to keep one")
peerConnectionFactory?.dispose() peerConnectionFactory?.dispose()
peerConnectionFactory = null peerConnectionFactory = null
audioManager.setMode(CallAudioManager.Mode.DEFAULT) audioManager.setMode(CallAudioManager.Mode.DEFAULT)
@ -268,13 +268,13 @@ class WebRtcCallManager @Inject constructor(
suspend fun startOutgoingCall(nativeRoomId: String, otherUserId: String, isVideoCall: Boolean, transferee: WebRtcCall? = null) { suspend fun startOutgoingCall(nativeRoomId: String, otherUserId: String, isVideoCall: Boolean, transferee: WebRtcCall? = null) {
val signalingRoomId = callUserMapper?.getOrCreateVirtualRoomForRoom(nativeRoomId, otherUserId) ?: nativeRoomId val signalingRoomId = callUserMapper?.getOrCreateVirtualRoomForRoom(nativeRoomId, otherUserId) ?: nativeRoomId
Timber.tag(WebRtcCallManagerTag.computedValue).v("startOutgoingCall in room $signalingRoomId to $otherUserId isVideo $isVideoCall") Timber.tag(loggerTag.value).v("startOutgoingCall in room $signalingRoomId to $otherUserId isVideo $isVideoCall")
if (getCallsByRoomId(nativeRoomId).isNotEmpty()) { if (getCallsByRoomId(nativeRoomId).isNotEmpty()) {
Timber.tag(WebRtcCallManagerTag.computedValue).w("you already have a call in this room") Timber.tag(loggerTag.value).w("you already have a call in this room")
return return
} }
if (getCurrentCall() != null && getCurrentCall()?.mxCall?.state !is CallState.Connected || getCalls().size >= 2) { if (getCurrentCall() != null && getCurrentCall()?.mxCall?.state !is CallState.Connected || getCalls().size >= 2) {
Timber.tag(WebRtcCallManagerTag.computedValue).w("cannot start outgoing call") Timber.tag(loggerTag.value).w("cannot start outgoing call")
// Just ignore, maybe we could answer from other session? // Just ignore, maybe we could answer from other session?
return return
} }
@ -297,10 +297,10 @@ class WebRtcCallManager @Inject constructor(
} }
override fun onCallIceCandidateReceived(mxCall: MxCall, iceCandidatesContent: CallCandidatesContent) { override fun onCallIceCandidateReceived(mxCall: MxCall, iceCandidatesContent: CallCandidatesContent) {
Timber.tag(WebRtcCallManagerTag.computedValue).v("onCallIceCandidateReceived for call ${mxCall.callId}") Timber.tag(loggerTag.value).v("onCallIceCandidateReceived for call ${mxCall.callId}")
val call = callsByCallId[iceCandidatesContent.callId] val call = callsByCallId[iceCandidatesContent.callId]
?: return Unit.also { ?: return Unit.also {
Timber.tag(WebRtcCallManagerTag.computedValue).w("onCallIceCandidateReceived for non active call? ${iceCandidatesContent.callId}") Timber.tag(loggerTag.value).w("onCallIceCandidateReceived for non active call? ${iceCandidatesContent.callId}")
} }
call.onCallIceCandidateReceived(iceCandidatesContent) call.onCallIceCandidateReceived(iceCandidatesContent)
} }
@ -337,14 +337,14 @@ class WebRtcCallManager @Inject constructor(
} }
override fun onCallInviteReceived(mxCall: MxCall, callInviteContent: CallInviteContent) { override fun onCallInviteReceived(mxCall: MxCall, callInviteContent: CallInviteContent) {
Timber.tag(WebRtcCallManagerTag.computedValue).v("onCallInviteReceived callId ${mxCall.callId}") Timber.tag(loggerTag.value).v("onCallInviteReceived callId ${mxCall.callId}")
val nativeRoomId = callUserMapper?.nativeRoomForVirtualRoom(mxCall.roomId) ?: mxCall.roomId val nativeRoomId = callUserMapper?.nativeRoomForVirtualRoom(mxCall.roomId) ?: mxCall.roomId
if (getCallsByRoomId(nativeRoomId).isNotEmpty()) { if (getCallsByRoomId(nativeRoomId).isNotEmpty()) {
Timber.tag(WebRtcCallManagerTag.computedValue).w("you already have a call in this room") Timber.tag(loggerTag.value).w("you already have a call in this room")
return return
} }
if ((getCurrentCall() != null && getCurrentCall()?.mxCall?.state !is CallState.Connected) || getCalls().size >= 2) { if ((getCurrentCall() != null && getCurrentCall()?.mxCall?.state !is CallState.Connected) || getCalls().size >= 2) {
Timber.tag(WebRtcCallManagerTag.computedValue).w("receiving incoming call but cannot handle it") Timber.tag(loggerTag.value).w("receiving incoming call but cannot handle it")
// Just ignore, maybe we could answer from other session? // Just ignore, maybe we could answer from other session?
return return
} }
@ -373,7 +373,7 @@ class WebRtcCallManager @Inject constructor(
override fun onCallAnswerReceived(callAnswerContent: CallAnswerContent) { override fun onCallAnswerReceived(callAnswerContent: CallAnswerContent) {
val call = callsByCallId[callAnswerContent.callId] val call = callsByCallId[callAnswerContent.callId]
?: return Unit.also { ?: return Unit.also {
Timber.tag(WebRtcCallManagerTag.computedValue).w("onCallAnswerReceived for non active call? ${callAnswerContent.callId}") Timber.tag(loggerTag.value).w("onCallAnswerReceived for non active call? ${callAnswerContent.callId}")
} }
val mxCall = call.mxCall val mxCall = call.mxCall
// Update service state // Update service state
@ -387,7 +387,7 @@ class WebRtcCallManager @Inject constructor(
override fun onCallHangupReceived(callHangupContent: CallHangupContent) { override fun onCallHangupReceived(callHangupContent: CallHangupContent) {
val call = callsByCallId[callHangupContent.callId] val call = callsByCallId[callHangupContent.callId]
?: return Unit.also { ?: return Unit.also {
Timber.tag(WebRtcCallManagerTag.computedValue).w("onCallHangupReceived for non active call? ${callHangupContent.callId}") Timber.tag(loggerTag.value).w("onCallHangupReceived for non active call? ${callHangupContent.callId}")
} }
call.endCall(false) call.endCall(false)
} }
@ -395,7 +395,7 @@ class WebRtcCallManager @Inject constructor(
override fun onCallRejectReceived(callRejectContent: CallRejectContent) { override fun onCallRejectReceived(callRejectContent: CallRejectContent) {
val call = callsByCallId[callRejectContent.callId] val call = callsByCallId[callRejectContent.callId]
?: return Unit.also { ?: return Unit.also {
Timber.tag(WebRtcCallManagerTag.computedValue).w("onCallRejectReceived for non active call? ${callRejectContent.callId}") Timber.tag(loggerTag.value).w("onCallRejectReceived for non active call? ${callRejectContent.callId}")
} }
call.endCall(false) call.endCall(false)
} }
@ -403,7 +403,7 @@ class WebRtcCallManager @Inject constructor(
override fun onCallSelectAnswerReceived(callSelectAnswerContent: CallSelectAnswerContent) { override fun onCallSelectAnswerReceived(callSelectAnswerContent: CallSelectAnswerContent) {
val call = callsByCallId[callSelectAnswerContent.callId] val call = callsByCallId[callSelectAnswerContent.callId]
?: return Unit.also { ?: return Unit.also {
Timber.tag(WebRtcCallManagerTag.computedValue).w("onCallSelectAnswerReceived for non active call? ${callSelectAnswerContent.callId}") Timber.tag(loggerTag.value).w("onCallSelectAnswerReceived for non active call? ${callSelectAnswerContent.callId}")
} }
val selectedPartyId = callSelectAnswerContent.selectedPartyId val selectedPartyId = callSelectAnswerContent.selectedPartyId
if (selectedPartyId != call.mxCall.ourPartyId) { if (selectedPartyId != call.mxCall.ourPartyId) {
@ -416,13 +416,13 @@ class WebRtcCallManager @Inject constructor(
override fun onCallNegotiateReceived(callNegotiateContent: CallNegotiateContent) { override fun onCallNegotiateReceived(callNegotiateContent: CallNegotiateContent) {
val call = callsByCallId[callNegotiateContent.callId] val call = callsByCallId[callNegotiateContent.callId]
?: return Unit.also { ?: return Unit.also {
Timber.tag(WebRtcCallManagerTag.computedValue).w("onCallNegotiateReceived for non active call? ${callNegotiateContent.callId}") Timber.tag(loggerTag.value).w("onCallNegotiateReceived for non active call? ${callNegotiateContent.callId}")
} }
call.onCallNegotiateReceived(callNegotiateContent) call.onCallNegotiateReceived(callNegotiateContent)
} }
override fun onCallManagedByOtherSession(callId: String) { override fun onCallManagedByOtherSession(callId: String) {
Timber.tag(WebRtcCallManagerTag.computedValue).v("onCallManagedByOtherSession: $callId") Timber.tag(loggerTag.value).v("onCallManagedByOtherSession: $callId")
onCallEnded(callId) onCallEnded(callId)
} }
@ -432,7 +432,7 @@ class WebRtcCallManager @Inject constructor(
} }
val call = callsByCallId[callAssertedIdentityContent.callId] val call = callsByCallId[callAssertedIdentityContent.callId]
?: return Unit.also { ?: return Unit.also {
Timber.tag(WebRtcCallManagerTag.computedValue).w("onCallAssertedIdentityReceived for non active call? ${callAssertedIdentityContent.callId}") Timber.tag(loggerTag.value).w("onCallAssertedIdentityReceived for non active call? ${callAssertedIdentityContent.callId}")
} }
call.onCallAssertedIdentityReceived(callAssertedIdentityContent) call.onCallAssertedIdentityReceived(callAssertedIdentityContent)
} }