From ceb36799757b19696dcdba1f741534035a6fae8b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 20 Jun 2024 17:23:33 +0200 Subject: [PATCH] New ZRTP SAS validation dialog for cache mismatch scenario --- .../ui/call/fragment/ActiveCallFragment.kt | 58 ++++++++++++------- .../model/ZrtpSasConfirmationDialogModel.kt | 3 +- .../ui/call/viewmodel/CurrentCallViewModel.kt | 11 +++- .../shape_zrtp_dialog_warning_background.xml | 18 ++++++ ..._zrtp_dialog_warning_header_background.xml | 10 ++++ app/src/main/res/drawable/trusted_white.xml | 12 ++++ .../layout-land/dialog_confirm_zrtp_sas.xml | 9 ++- .../res/layout/dialog_confirm_zrtp_sas.xml | 11 ++-- app/src/main/res/values-fr/strings.xml | 3 +- app/src/main/res/values/strings.xml | 3 +- 10 files changed, 103 insertions(+), 35 deletions(-) create mode 100644 app/src/main/res/drawable/shape_zrtp_dialog_warning_background.xml create mode 100644 app/src/main/res/drawable/shape_zrtp_dialog_warning_header_background.xml create mode 100644 app/src/main/res/drawable/trusted_white.xml diff --git a/app/src/main/java/org/linphone/ui/call/fragment/ActiveCallFragment.kt b/app/src/main/java/org/linphone/ui/call/fragment/ActiveCallFragment.kt index e37b978d0..8a32af5a6 100644 --- a/app/src/main/java/org/linphone/ui/call/fragment/ActiveCallFragment.kt +++ b/app/src/main/java/org/linphone/ui/call/fragment/ActiveCallFragment.kt @@ -217,27 +217,15 @@ class ActiveCallFragment : GenericCallFragment() { callViewModel.showZrtpSasDialogEvent.observe(viewLifecycleOwner) { it.consume { pair -> - val model = ZrtpSasConfirmationDialogModel(pair.first, pair.second) - val dialog = DialogUtils.getZrtpSasConfirmationDialog(requireActivity(), model) + callMediaEncryptionStatsBottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN + showZrtpSasValidationDialog(pair.first, pair.second, false) + } + } - model.skipEvent.observe(viewLifecycleOwner) { event -> - event.consume { - callViewModel.skipZrtpSas() - callMediaEncryptionStatsBottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN - dialog.dismiss() - } - } - - model.authTokenClickedEvent.observe(viewLifecycleOwner) { event -> - event.consume { authToken -> - callViewModel.updateZrtpSas(authToken) - callMediaEncryptionStatsBottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN - dialog.dismiss() - } - } - - dialog.show() - zrtpSasDialog = dialog + callViewModel.showZrtpSasCacheMismatchDialogEvent.observe(viewLifecycleOwner) { + it.consume { pair -> + callMediaEncryptionStatsBottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN + showZrtpSasValidationDialog(pair.first, pair.second, true) } } @@ -427,4 +415,34 @@ class ActiveCallFragment : GenericCallFragment() { set.applyTo(constraintLayout) } + + private fun showZrtpSasValidationDialog( + authTokenToRead: String, + authTokensToListen: List, + cacheMismatch: Boolean + ) { + val model = ZrtpSasConfirmationDialogModel( + authTokenToRead, + authTokensToListen, + cacheMismatch + ) + val dialog = DialogUtils.getZrtpSasConfirmationDialog(requireActivity(), model) + + model.skipEvent.observe(viewLifecycleOwner) { event -> + event.consume { + callViewModel.skipZrtpSas() + dialog.dismiss() + } + } + + model.authTokenClickedEvent.observe(viewLifecycleOwner) { event -> + event.consume { authToken -> + callViewModel.updateZrtpSas(authToken) + dialog.dismiss() + } + } + + dialog.show() + zrtpSasDialog = dialog + } } diff --git a/app/src/main/java/org/linphone/ui/call/model/ZrtpSasConfirmationDialogModel.kt b/app/src/main/java/org/linphone/ui/call/model/ZrtpSasConfirmationDialogModel.kt index f6efea533..91f1c342a 100644 --- a/app/src/main/java/org/linphone/ui/call/model/ZrtpSasConfirmationDialogModel.kt +++ b/app/src/main/java/org/linphone/ui/call/model/ZrtpSasConfirmationDialogModel.kt @@ -27,7 +27,8 @@ import org.linphone.utils.Event class ZrtpSasConfirmationDialogModel @UiThread constructor( authTokenToRead: String, - authTokensToListen: List + authTokensToListen: List, + val cacheMismatch: Boolean ) : GenericViewModel() { companion object { private const val TAG = "[ZRTP SAS Confirmation Dialog]" 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 55c238103..a7d236cc7 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 @@ -169,6 +169,10 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { MutableLiveData>>>() } + val showZrtpSasCacheMismatchDialogEvent: MutableLiveData>>> by lazy { + MutableLiveData>>>() + } + val zrtpAuthTokenVerifiedEvent: MutableLiveData> by lazy { MutableLiveData>() } @@ -1003,7 +1007,12 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { 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!" diff --git a/app/src/main/res/drawable/shape_zrtp_dialog_warning_background.xml b/app/src/main/res/drawable/shape_zrtp_dialog_warning_background.xml new file mode 100644 index 000000000..271867917 --- /dev/null +++ b/app/src/main/res/drawable/shape_zrtp_dialog_warning_background.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_zrtp_dialog_warning_header_background.xml b/app/src/main/res/drawable/shape_zrtp_dialog_warning_header_background.xml new file mode 100644 index 000000000..f8443ee7c --- /dev/null +++ b/app/src/main/res/drawable/shape_zrtp_dialog_warning_header_background.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/trusted_white.xml b/app/src/main/res/drawable/trusted_white.xml new file mode 100644 index 000000000..15ebc8740 --- /dev/null +++ b/app/src/main/res/drawable/trusted_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/layout-land/dialog_confirm_zrtp_sas.xml b/app/src/main/res/layout-land/dialog_confirm_zrtp_sas.xml index e6c9fcce7..ea2388673 100644 --- a/app/src/main/res/layout-land/dialog_confirm_zrtp_sas.xml +++ b/app/src/main/res/layout-land/dialog_confirm_zrtp_sas.xml @@ -21,7 +21,7 @@ android:id="@+id/header" android:layout_width="0dp" android:layout_height="wrap_content" - android:background="@drawable/shape_zrtp_dialog_header_background" + android:background="@{viewModel.cacheMismatch ? @drawable/shape_zrtp_dialog_warning_header_background : @drawable/shape_zrtp_dialog_header_background, default=@drawable/shape_zrtp_dialog_header_background}" app:layout_constraintVertical_chainStyle="packed" app:layout_constraintWidth_max="@dimen/dialog_max_width" app:layout_constraintTop_toTopOf="parent" @@ -34,11 +34,10 @@ android:layout_width="@dimen/icon_size" android:layout_height="@dimen/icon_size" android:layout_marginTop="10dp" - android:src="@drawable/lock_key" + android:src="@drawable/trusted_white" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:tint="@color/white" /> + app:layout_constraintEnd_toEndOf="parent" /> @@ -31,11 +31,10 @@ android:layout_width="@dimen/icon_size" android:layout_height="@dimen/icon_size" android:layout_marginTop="10dp" - android:src="@drawable/lock_key" + android:src="@drawable/trusted_white" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:tint="@color/white" /> + app:layout_constraintEnd_toEndOf="parent" /> @@ -85,7 +84,7 @@ android:layout_marginStart="15dp" android:layout_marginEnd="15dp" android:layout_marginTop="10dp" - android:text="@string/call_dialog_zrtp_validate_trust_message" + android:text="@{viewModel.cacheMismatch ? @string/call_dialog_zrtp_validate_trust_warning_message : @string/call_dialog_zrtp_validate_trust_message, default=@string/call_dialog_zrtp_validate_trust_message}" android:textSize="14sp" android:textColor="@color/gray_main2_600" android:gravity="center" diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 1f48416b4..5e3a1d141 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -587,7 +587,8 @@ Créer une conférence Vérification de sécurité - Pour votre sécurité, nous avons besoin de vérifier l\'appareil de votre correspondant.\nVeuillez échanger vos codes : + Pour garantir le chiffrement, nous avons besoin d’authentifier l’appareil de votre correspondant.\nVeuillez échanger vos codes : + Pour garantir le chiffrement, nous avons besoin de réauthentifier l’appareil de votre correspondant.\nVeuillez ré-échanger vos codes : Votre code : Code correspondant : Aucune correspondance diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a6f407c27..4df340fe1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -624,7 +624,8 @@ Create conference Validate the device - For your safety, we need to validate your correspondent device.\nPlease exchange your codes: + For your safety, we need to authenticate your correspondent device.\nPlease exchange your codes: + For your safety, we need to re-authenticate your correspondent device.\nPlease re-exchange your codes: Your code: Correspondent code: Nothing matches