From e3d1a811d5862639b5c3f2c81fdc79dddd4710b4 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 18 May 2026 22:19:22 +0200 Subject: [PATCH] Disable biometric unlock when we disable pin code unlock (#6781) * Disable biometric unlock when we disable pin code unlock --- .../lockscreen/impl/DefaultLockScreenService.kt | 3 ++- .../impl/biometric/BiometricAuthenticatorManager.kt | 5 +++++ .../biometric/DefaultBiometricAuthenticatorManager.kt | 10 ++++++---- .../impl/settings/LockScreenSettingsPresenter.kt | 1 + .../biometric/FakeBiometricAuthenticatorManager.kt | 5 +++++ 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/DefaultLockScreenService.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/DefaultLockScreenService.kt index 7ac42feda6..49d299b3f9 100644 --- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/DefaultLockScreenService.kt +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/DefaultLockScreenService.kt @@ -43,7 +43,7 @@ class DefaultLockScreenService( private val coroutineScope: CoroutineScope, private val sessionObserver: SessionObserver, private val appForegroundStateService: AppForegroundStateService, - biometricAuthenticatorManager: BiometricAuthenticatorManager, + private val biometricAuthenticatorManager: BiometricAuthenticatorManager, ) : LockScreenService { private val _lockState = MutableStateFlow(LockScreenLockState.Unlocked) override val lockState: StateFlow = _lockState @@ -81,6 +81,7 @@ class DefaultLockScreenService( override suspend fun onSessionDeleted(userId: String, wasLastSession: Boolean) { if (wasLastSession) { pinCodeManager.deletePinCode() + biometricAuthenticatorManager.disable() } } }) diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/biometric/BiometricAuthenticatorManager.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/biometric/BiometricAuthenticatorManager.kt index 9917845725..2ea0ed7d05 100644 --- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/biometric/BiometricAuthenticatorManager.kt +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/biometric/BiometricAuthenticatorManager.kt @@ -24,6 +24,11 @@ interface BiometricAuthenticatorManager { fun addCallback(callback: BiometricAuthenticator.Callback) fun removeCallback(callback: BiometricAuthenticator.Callback) + /** + * Disable using the biometric unlock feature and remove any data associated with it. + */ + suspend fun disable() + /** * Remember a biometric authenticator ready for unlocking the app. */ diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/biometric/DefaultBiometricAuthenticatorManager.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/biometric/DefaultBiometricAuthenticatorManager.kt index 8bb044fd06..117323ec0a 100644 --- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/biometric/DefaultBiometricAuthenticatorManager.kt +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/biometric/DefaultBiometricAuthenticatorManager.kt @@ -80,10 +80,7 @@ class DefaultBiometricAuthenticatorManager( private val internalCallback = object : DefaultBiometricUnlockCallback() { override fun onBiometricSetupError() { - coroutineScope.launch { - lockScreenStore.setIsBiometricUnlockAllowed(false) - secretKeyRepository.deleteKey(SECRET_KEY_ALIAS) - } + coroutineScope.launch { disable() } } } @@ -120,6 +117,11 @@ class DefaultBiometricAuthenticatorManager( ) } + override suspend fun disable() { + lockScreenStore.setIsBiometricUnlockAllowed(false) + secretKeyRepository.deleteKey(SECRET_KEY_ALIAS) + } + @Composable private fun rememberBiometricAuthenticator( isAvailable: Boolean, diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsPresenter.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsPresenter.kt index 83a0253f39..17a0213f63 100644 --- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsPresenter.kt +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsPresenter.kt @@ -59,6 +59,7 @@ class LockScreenSettingsPresenter( if (showRemovePinConfirmation) { showRemovePinConfirmation = false pinCodeManager.deletePinCode() + biometricAuthenticatorManager.disable() } } } diff --git a/features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/biometric/FakeBiometricAuthenticatorManager.kt b/features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/biometric/FakeBiometricAuthenticatorManager.kt index 9e9b892582..0ae8552334 100644 --- a/features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/biometric/FakeBiometricAuthenticatorManager.kt +++ b/features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/biometric/FakeBiometricAuthenticatorManager.kt @@ -15,6 +15,7 @@ class FakeBiometricAuthenticatorManager( override var isDeviceSecured: Boolean = true, override var hasAvailableAuthenticator: Boolean = false, private val createBiometricAuthenticator: () -> BiometricAuthenticator = { FakeBiometricAuthenticator() }, + private val disableLambda: suspend () -> Unit = { }, ) : BiometricAuthenticatorManager { override fun addCallback(callback: BiometricAuthenticator.Callback) { // no-op @@ -37,4 +38,8 @@ class FakeBiometricAuthenticatorManager( createBiometricAuthenticator() } } + + override suspend fun disable() { + disableLambda() + } }