mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Added dialog when ZRTP SAS token doesn't match or when clicking on 'nothing matches' button
This commit is contained in:
parent
ceb3679975
commit
8f34c3ea5c
13 changed files with 281 additions and 8 deletions
|
|
@ -42,6 +42,7 @@ import org.linphone.core.tools.Log
|
|||
import org.linphone.databinding.CallActiveFragmentBinding
|
||||
import org.linphone.ui.GenericActivity
|
||||
import org.linphone.ui.call.CallActivity
|
||||
import org.linphone.ui.call.model.ZrtpAlertDialogModel
|
||||
import org.linphone.ui.call.model.ZrtpSasConfirmationDialogModel
|
||||
import org.linphone.ui.call.viewmodel.CallsViewModel
|
||||
import org.linphone.ui.call.viewmodel.CurrentCallViewModel
|
||||
|
|
@ -238,10 +239,7 @@ class ActiveCallFragment : GenericCallFragment() {
|
|||
doNotTint = true
|
||||
)
|
||||
} else {
|
||||
(requireActivity() as GenericActivity).showRedToast(
|
||||
getString(R.string.call_can_not_be_trusted_alert_toast),
|
||||
R.drawable.warning_circle
|
||||
)
|
||||
showZrtpAlertDialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -445,4 +443,26 @@ class ActiveCallFragment : GenericCallFragment() {
|
|||
dialog.show()
|
||||
zrtpSasDialog = dialog
|
||||
}
|
||||
|
||||
private fun showZrtpAlertDialog() {
|
||||
val model = ZrtpAlertDialogModel()
|
||||
val dialog = DialogUtils.getZrtpAlertDialog(requireActivity(), model)
|
||||
|
||||
model.tryAgainEvent.observe(viewLifecycleOwner) { event ->
|
||||
event.consume {
|
||||
callViewModel.showZrtpSasDialogIfPossible()
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
model.hangUpEvent.observe(viewLifecycleOwner) { event ->
|
||||
event.consume {
|
||||
callViewModel.hangUp()
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
dialog.show()
|
||||
zrtpSasDialog = dialog
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-android
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.linphone.ui.call.model
|
||||
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import org.linphone.ui.GenericViewModel
|
||||
import org.linphone.utils.Event
|
||||
|
||||
class ZrtpAlertDialogModel @UiThread constructor() : GenericViewModel() {
|
||||
companion object {
|
||||
private const val TAG = "[ZRTP Alert Dialog]"
|
||||
}
|
||||
|
||||
val tryAgainEvent = MutableLiveData<Event<Boolean>>()
|
||||
|
||||
val hangUpEvent = MutableLiveData<Event<Boolean>>()
|
||||
|
||||
@UiThread
|
||||
fun tryAgain() {
|
||||
tryAgainEvent.value = Event(true)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun hangUp() {
|
||||
hangUpEvent.value = Event(true)
|
||||
}
|
||||
}
|
||||
|
|
@ -245,6 +245,9 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() {
|
|||
)
|
||||
isZrtpSasValidationRequired.postValue(!verified)
|
||||
zrtpAuthTokenVerifiedEvent.postValue(Event(verified))
|
||||
if (verified) {
|
||||
isMediaEncrypted.postValue(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRemoteRecording(call: Call, recording: Boolean) {
|
||||
|
|
@ -956,13 +959,19 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() {
|
|||
coreContext.postOnCoreThread {
|
||||
if (currentCall.currentParams.mediaEncryption == MediaEncryption.ZRTP) {
|
||||
val isDeviceTrusted = currentCall.authenticationTokenVerified
|
||||
val cacheMismatch = currentCall.zrtpCacheMismatchFlag
|
||||
Log.i(
|
||||
"$TAG Current call media encryption is ZRTP, auth token is [${if (isDeviceTrusted) "trusted" else "not trusted yet"}]"
|
||||
)
|
||||
val tokenToRead = currentCall.localAuthenticationToken
|
||||
val tokensToDisplay = currentCall.remoteAuthenticationTokens.toList()
|
||||
if (!tokenToRead.isNullOrEmpty() && tokensToDisplay.size == 4) {
|
||||
showZrtpSasDialogEvent.postValue(Event(Pair(tokenToRead, tokensToDisplay)))
|
||||
val event = Event(Pair(tokenToRead, tokensToDisplay))
|
||||
if (cacheMismatch) {
|
||||
showZrtpSasCacheMismatchDialogEvent.postValue(event)
|
||||
} else {
|
||||
showZrtpSasDialogEvent.postValue(event)
|
||||
}
|
||||
} else {
|
||||
Log.w(
|
||||
"$TAG Either local auth token is null/empty or remote tokens list doesn't contains 4 elements!"
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ import org.linphone.databinding.DialogAssistantAcceptConditionsAndPolicyBinding
|
|||
import org.linphone.databinding.DialogAssistantCreateAccountConfirmPhoneNumberBinding
|
||||
import org.linphone.databinding.DialogCancelContactChangesBinding
|
||||
import org.linphone.databinding.DialogCancelMeetingBinding
|
||||
import org.linphone.databinding.DialogConfirmZrtpSasBinding
|
||||
import org.linphone.databinding.DialogContactConfirmTrustCallBinding
|
||||
import org.linphone.databinding.DialogContactTrustProcessBinding
|
||||
import org.linphone.databinding.DialogDeleteContactBinding
|
||||
|
|
@ -53,8 +52,11 @@ import org.linphone.databinding.DialogRemoveConversationHistoryBinding
|
|||
import org.linphone.databinding.DialogSetOrEditGroupSubjectBindingImpl
|
||||
import org.linphone.databinding.DialogUpdateAccountPasswordBinding
|
||||
import org.linphone.databinding.DialogUpdateAvailableBinding
|
||||
import org.linphone.databinding.DialogZrtpSasValidationBinding
|
||||
import org.linphone.databinding.DialogZrtpSecurityAlertBinding
|
||||
import org.linphone.ui.assistant.model.AcceptConditionsAndPolicyDialogModel
|
||||
import org.linphone.ui.assistant.model.ConfirmPhoneNumberDialogModel
|
||||
import org.linphone.ui.call.model.ZrtpAlertDialogModel
|
||||
import org.linphone.ui.call.model.ZrtpSasConfirmationDialogModel
|
||||
import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel
|
||||
import org.linphone.ui.main.contacts.model.TrustCallDialogModel
|
||||
|
|
@ -343,9 +345,25 @@ class DialogUtils {
|
|||
context: Context,
|
||||
viewModel: ZrtpSasConfirmationDialogModel
|
||||
): Dialog {
|
||||
val binding: DialogConfirmZrtpSasBinding = DataBindingUtil.inflate(
|
||||
val binding: DialogZrtpSasValidationBinding = DataBindingUtil.inflate(
|
||||
LayoutInflater.from(context),
|
||||
R.layout.dialog_confirm_zrtp_sas,
|
||||
R.layout.dialog_zrtp_sas_validation,
|
||||
null,
|
||||
false
|
||||
)
|
||||
binding.viewModel = viewModel
|
||||
|
||||
return getDialog(context, binding)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun getZrtpAlertDialog(
|
||||
context: Context,
|
||||
viewModel: ZrtpAlertDialogModel
|
||||
): Dialog {
|
||||
val binding: DialogZrtpSecurityAlertBinding = DataBindingUtil.inflate(
|
||||
LayoutInflater.from(context),
|
||||
R.layout.dialog_zrtp_security_alert,
|
||||
null,
|
||||
false
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<corners android:radius="48dp" />
|
||||
<solid android:color="?attr/color_danger_500" />
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:bottomLeftRadius="15dp" android:bottomRightRadius="15dp" />
|
||||
<solid
|
||||
android:color="@color/red_danger_500"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:bottom="2dp">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="15dp" />
|
||||
<solid
|
||||
android:color="@color/white" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:topLeftRadius="15dp" android:topRightRadius="15dp" />
|
||||
<solid android:color="@color/red_danger_500"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
9
app/src/main/res/drawable/shield_warning.xml
Normal file
9
app/src/main/res/drawable/shield_warning.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="256"
|
||||
android:viewportHeight="256">
|
||||
<path
|
||||
android:pathData="M120,136L120,96a8,8 0,0 1,16 0v40a8,8 0,0 1,-16 0ZM128,184a12,12 0,1 0,-12 -12A12,12 0,0 0,128 184ZM224,56v56c0,52.72 -25.52,84.67 -46.93,102.19 -23.06,18.86 -46,25.27 -47,25.53a8,8 0,0 1,-4.2 0c-1,-0.26 -23.91,-6.67 -47,-25.53C57.52,196.67 32,164.72 32,112L32,56A16,16 0,0 1,48 40L208,40A16,16 0,0 1,224 56ZM208,56L48,56l0,56c0,37.3 13.82,67.51 41.07,89.81A128.25,128.25 0,0 0,128 223.62a129.3,129.3 0,0 0,39.41 -22.2C194.34,179.16 208,149.07 208,112Z"
|
||||
android:fillColor="#364860"/>
|
||||
</vector>
|
||||
133
app/src/main/res/layout/dialog_zrtp_security_alert.xml
Normal file
133
app/src/main/res/layout/dialog_zrtp_security_alert.xml
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<import type="android.graphics.Typeface" />
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="org.linphone.ui.call.model.ZrtpAlertDialogModel" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/shape_zrtp_dialog_error_header_background"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/body">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/header_icon"
|
||||
android:layout_width="@dimen/icon_size"
|
||||
android:layout_height="@dimen/icon_size"
|
||||
android:layout_marginTop="10dp"
|
||||
android:src="@drawable/shield_warning"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:tint="@color/white" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style_700"
|
||||
android:id="@id/header_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:text="@string/call_dialog_zrtp_security_alert_title"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/white"
|
||||
app:layout_constraintTop_toBottomOf="@id/header_icon"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/body"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/shape_zrtp_dialog_error_background"
|
||||
app:layout_constraintTop_toBottomOf="@id/header"
|
||||
app:layout_constraintBottom_toBottomOf="parent">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/message"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/call_dialog_zrtp_security_alert_message"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/gray_main2_600"
|
||||
android:gravity="center"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style_600"
|
||||
android:id="@+id/try_again"
|
||||
android:onClick="@{() -> viewModel.tryAgain()}"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginStart="30dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
|
||||
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/shape_red_outlined_button_background"
|
||||
android:text="@string/call_dialog_zrtp_security_alert_try_again"
|
||||
android:textSize="18sp"
|
||||
android:textColor="?attr/color_danger_500"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintWidth_max="@dimen/button_max_width"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/message"
|
||||
app:layout_constraintBottom_toTopOf="@id/hang_up"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style_600"
|
||||
android:id="@+id/hang_up"
|
||||
android:onClick="@{() -> viewModel.hangUp()}"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:layout_marginStart="30dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
|
||||
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/shape_red_button_background"
|
||||
android:text="@string/call_action_hang_up"
|
||||
android:textSize="18sp"
|
||||
android:textColor="@color/white"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintWidth_max="@dimen/button_max_width"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/try_again"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</layout>
|
||||
|
|
@ -592,6 +592,9 @@
|
|||
<string name="call_dialog_zrtp_validate_trust_local_code_label">Votre code :</string>
|
||||
<string name="call_dialog_zrtp_validate_trust_remote_code_label">Code correspondant : </string>
|
||||
<string name="call_dialog_zrtp_validate_trust_letters_do_not_match">Aucune correspondance</string>
|
||||
<string name="call_dialog_zrtp_security_alert_title">Security alert</string>
|
||||
<string name="call_dialog_zrtp_security_alert_try_again">Réessayer</string>
|
||||
<string name="call_dialog_zrtp_security_alert_message">La confidentialité de votre appel peut être compromise !</string>
|
||||
|
||||
<string name="call_audio_device_type_earpiece">Oreilette</string>
|
||||
<string name="call_audio_device_type_speaker">Haut parleur</string>
|
||||
|
|
|
|||
|
|
@ -629,6 +629,9 @@
|
|||
<string name="call_dialog_zrtp_validate_trust_local_code_label">Your code:</string>
|
||||
<string name="call_dialog_zrtp_validate_trust_remote_code_label">Correspondent code:</string>
|
||||
<string name="call_dialog_zrtp_validate_trust_letters_do_not_match">Nothing matches</string>
|
||||
<string name="call_dialog_zrtp_security_alert_title">Security alert</string>
|
||||
<string name="call_dialog_zrtp_security_alert_try_again">Try again</string>
|
||||
<string name="call_dialog_zrtp_security_alert_message">This call confidentiality may be compromise!</string>
|
||||
|
||||
<string name="call_audio_device_type_earpiece">Earpiece</string>
|
||||
<string name="call_audio_device_type_speaker">Speaker</string>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue