diff --git a/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt b/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt index 281a39cd7..88b3b6849 100644 --- a/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt +++ b/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt @@ -94,6 +94,10 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() { val halfOpenedFolded = MutableLiveData() + val isZrtpPq = MutableLiveData() + + val isMediaEncrypted = MutableLiveData() + val incomingCallTitle: MutableLiveData by lazy { MutableLiveData() } @@ -636,18 +640,35 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() { } } + @UiThread + fun showZrtpSasDialogIfPossible() { + coreContext.postOnCoreThread { + if (currentCall.currentParams.mediaEncryption == MediaEncryption.ZRTP) { + val authToken = currentCall.authenticationToken + val isDeviceTrusted = currentCall.authenticationTokenVerified && authToken != null + Log.i( + "$TAG Current call media encryption is ZRTP, auth token is ${if (isDeviceTrusted) "trusted" else "not trusted yet"}" + ) + if (!authToken.isNullOrEmpty()) { + showZrtpSasDialog(authToken) + } + } + } + } + @WorkerThread private fun showZrtpSasDialog(authToken: String) { + val upperCaseAuthToken = authToken.uppercase(Locale.getDefault()) val toRead: String val toListen: String when (currentCall.dir) { Call.Dir.Incoming -> { - toRead = authToken.substring(0, 2) - toListen = authToken.substring(2) + toRead = upperCaseAuthToken.substring(0, 2) + toListen = upperCaseAuthToken.substring(2) } else -> { - toRead = authToken.substring(2) - toListen = authToken.substring(0, 2) + toRead = upperCaseAuthToken.substring(2) + toListen = upperCaseAuthToken.substring(0, 2) } } showZrtpSasDialogEvent.postValue(Event(Pair(toRead, toListen))) @@ -666,16 +687,24 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() { val securityLevel = if (isDeviceTrusted) SecurityLevel.Encrypted else SecurityLevel.Safe contact.value?.trust?.postValue(securityLevel) - if (!isDeviceTrusted && authToken.orEmpty().isNotEmpty()) { + isMediaEncrypted.postValue(true) + // When Post Quantum is available, ZRTP is Post Quantum + isZrtpPq.postValue(coreContext.core.postQuantumAvailable) + + if (!isDeviceTrusted && !authToken.isNullOrEmpty()) { Log.i("$TAG Showing ZRTP SAS confirmation dialog") - showZrtpSasDialog(authToken!!.uppercase(Locale.getDefault())) + showZrtpSasDialog(authToken) } return isDeviceTrusted } MediaEncryption.SRTP, MediaEncryption.DTLS -> { + isMediaEncrypted.postValue(true) + isZrtpPq.postValue(false) } else -> { + isMediaEncrypted.postValue(false) + isZrtpPq.postValue(false) } } return false diff --git a/app/src/main/res/drawable/media_encryption_srtp.xml b/app/src/main/res/drawable/media_encryption_srtp.xml new file mode 100644 index 000000000..c8eaf1824 --- /dev/null +++ b/app/src/main/res/drawable/media_encryption_srtp.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/media_encryption_zrtp_pq.xml b/app/src/main/res/drawable/media_encryption_zrtp_pq.xml new file mode 100644 index 000000000..23cacba22 --- /dev/null +++ b/app/src/main/res/drawable/media_encryption_zrtp_pq.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/layout/call_active_fragment.xml b/app/src/main/res/layout/call_active_fragment.xml index 8fa423e55..9f06353e8 100644 --- a/app/src/main/res/layout/call_active_fragment.xml +++ b/app/src/main/res/layout/call_active_fragment.xml @@ -182,7 +182,9 @@ android:layout_height="@dimen/call_top_bar_text_height" android:layout_marginStart="5dp" android:visibility="@{viewModel.isPaused || viewModel.isPausedByRemote ? View.GONE : View.VISIBLE}" + app:layout_constraintHorizontal_bias="0" app:layout_constraintStart_toEndOf="@id/separator" + app:layout_constraintEnd_toStartOf="@id/media_encryption" app:layout_constraintTop_toTopOf="@id/call_direction_label"/> + + + + + + + +