Prevent some issues related to ZRTP SAS confirmation dialog

This commit is contained in:
Sylvain Berfini 2023-08-02 09:55:54 +02:00
parent d4d95b7835
commit c7bb59d991
3 changed files with 49 additions and 15 deletions

View file

@ -87,7 +87,7 @@ class SingleCallFragment : GenericVideoPreviewFragment<VoipSingleCallFragmentBin
) )
navigateToIncomingCall() navigateToIncomingCall()
} }
Call.State.OutgoingInit, Call.State.OutgoingProgress, Call.State.OutgoingRinging, Call.State.OutgoingEarlyMedia -> { Call.State.OutgoingRinging, Call.State.OutgoingEarlyMedia -> {
Log.i( Log.i(
"[Single Call] New current call is in [$callState] state, switching to OutgoingCall fragment" "[Single Call] New current call is in [$callState] state, switching to OutgoingCall fragment"
) )

View file

@ -84,8 +84,11 @@ class StatusFragment : GenericFragment<VoipStatusFragmentBinding>() {
private fun showZrtpDialog(call: Call) { private fun showZrtpDialog(call: Call) {
if (zrtpDialog != null && zrtpDialog?.isShowing == true) { if (zrtpDialog != null && zrtpDialog?.isShowing == true) {
Log.e("[Status Fragment] ZRTP dialog already visible") Log.w(
return "[Status Fragment] ZRTP dialog already visible, closing it and creating a new one"
)
zrtpDialog?.dismiss()
zrtpDialog = null
} }
val token = call.authenticationToken val token = call.authenticationToken
@ -125,8 +128,19 @@ class StatusFragment : GenericFragment<VoipStatusFragmentBinding>() {
viewModel.showCancelButton( viewModel.showCancelButton(
{ {
call.authenticationTokenVerified = false if (call.state != Call.State.End && call.state != Call.State.Released) {
this@StatusFragment.viewModel.updateEncryptionInfo(call) if (call.authenticationTokenVerified) {
Log.w(
"[Status Fragment] Removing trust from previously verified ZRTP SAS auth token"
)
this@StatusFragment.viewModel.previouslyDeclineToken = true
call.authenticationTokenVerified = false
}
} else {
Log.e(
"[Status Fragment] Can't decline the ZRTP SAS token, call is in state [${call.state}]"
)
}
dialog.dismiss() dialog.dismiss()
zrtpDialog = null zrtpDialog = null
}, },
@ -135,8 +149,13 @@ class StatusFragment : GenericFragment<VoipStatusFragmentBinding>() {
viewModel.showOkButton( viewModel.showOkButton(
{ {
call.authenticationTokenVerified = true if (call.state != Call.State.End && call.state != Call.State.Released) {
this@StatusFragment.viewModel.updateEncryptionInfo(call) call.authenticationTokenVerified = true
} else {
Log.e(
"[Status Fragment] Can't verify the ZRTP SAS token, call is in state [${call.state}]"
)
}
dialog.dismiss() dialog.dismiss()
zrtpDialog = null zrtpDialog = null
}, },

View file

@ -42,6 +42,8 @@ class StatusViewModel : StatusViewModel() {
MutableLiveData<Event<Boolean>>() MutableLiveData<Event<Boolean>>()
} }
var previouslyDeclineToken = false
private val listener = object : CoreListenerStub() { private val listener = object : CoreListenerStub() {
override fun onCallStatsUpdated(core: Core, call: Call, stats: CallStats) { override fun onCallStatsUpdated(core: Core, call: Call, stats: CallStats) {
updateCallQualityIcon() updateCallQualityIcon()
@ -54,8 +56,11 @@ class StatusViewModel : StatusViewModel() {
authenticationToken: String? authenticationToken: String?
) { ) {
updateEncryptionInfo(call) updateEncryptionInfo(call)
if (call.currentParams.mediaEncryption == MediaEncryption.ZRTP && !call.authenticationTokenVerified && call.authenticationToken != null) { // Check if we just declined a previously validated token
showZrtpDialogEvent.value = Event(call) // In that case, don't show the ZRTP dialog again
if (!previouslyDeclineToken) {
previouslyDeclineToken = false
showZrtpDialog(call)
} }
} }
@ -79,10 +84,7 @@ class StatusViewModel : StatusViewModel() {
val currentCall = coreContext.core.currentCall val currentCall = coreContext.core.currentCall
if (currentCall != null) { if (currentCall != null) {
updateEncryptionInfo(currentCall) updateEncryptionInfo(currentCall)
showZrtpDialog(currentCall)
if (currentCall.currentParams.mediaEncryption == MediaEncryption.ZRTP && !currentCall.authenticationTokenVerified && currentCall.authenticationToken != null) {
showZrtpDialogEvent.value = Event(currentCall)
}
} }
} }
@ -94,8 +96,8 @@ class StatusViewModel : StatusViewModel() {
fun showZrtpDialog() { fun showZrtpDialog() {
val currentCall = coreContext.core.currentCall val currentCall = coreContext.core.currentCall
if (currentCall?.authenticationToken != null && currentCall.currentParams.mediaEncryption == MediaEncryption.ZRTP) { if (currentCall != null) {
showZrtpDialogEvent.value = Event(currentCall) showZrtpDialog(currentCall, force = true)
} }
} }
@ -112,6 +114,9 @@ class StatusViewModel : StatusViewModel() {
encryptionContentDescription.value = R.string.content_description_call_secured encryptionContentDescription.value = R.string.content_description_call_secured
return return
} }
if (call.state == Call.State.End || call.state == Call.State.Released) {
return
}
when (call.currentParams.mediaEncryption ?: MediaEncryption.None) { when (call.currentParams.mediaEncryption ?: MediaEncryption.None) {
MediaEncryption.SRTP, MediaEncryption.DTLS -> { MediaEncryption.SRTP, MediaEncryption.DTLS -> {
@ -139,6 +144,16 @@ class StatusViewModel : StatusViewModel() {
} }
} }
private fun showZrtpDialog(call: Call, force: Boolean = false) {
if (
call.currentParams.mediaEncryption == MediaEncryption.ZRTP &&
call.authenticationToken != null &&
(!call.authenticationTokenVerified || force)
) {
showZrtpDialogEvent.value = Event(call)
}
}
private fun updateCallQualityIcon() { private fun updateCallQualityIcon() {
val call = coreContext.core.currentCall ?: coreContext.core.calls.firstOrNull() val call = coreContext.core.currentCall ?: coreContext.core.calls.firstOrNull()
val quality = call?.currentQuality ?: 0f val quality = call?.currentQuality ?: 0f