Handle PR reviews.

This commit is contained in:
Benoit Marty
2026-06-17 11:11:26 +02:00
committed by Benoit Marty
parent 8e12acf62c
commit 2836bccfce
9 changed files with 14 additions and 16 deletions
@@ -242,7 +242,7 @@ class LinkNewDeviceFlowNode(
override fun onUnlockDevice(type: LinkDeviceType) { override fun onUnlockDevice(type: LinkDeviceType) {
val callback = object : DeviceUnlockEntryPoint.Callback { val callback = object : DeviceUnlockEntryPoint.Callback {
override fun onCancel() = Unit override fun onCancel() = Unit
override fun onUnlocked() = when (type) { override fun onUnlock() = when (type) {
LinkDeviceType.Mobile -> { LinkDeviceType.Mobile -> {
linkNewMobileHandler.reset() linkNewMobileHandler.reset()
linkNewMobileHandler.createAndStartNewHandler() linkNewMobileHandler.createAndStartNewHandler()
@@ -30,6 +30,6 @@ interface DeviceUnlockEntryPoint : FeatureEntryPoint {
interface Callback { interface Callback {
fun onCancel() fun onCancel()
fun onUnlocked() fun onUnlock()
} }
} }
@@ -59,6 +59,7 @@ class DefaultBiometricAuthentication(
private var cryptoObject: CryptoObject? = null private var cryptoObject: CryptoObject? = null
override suspend fun setup() { override suspend fun setup() {
if (cryptoObject != null) return
try { try {
val secretKey = ensureKey() val secretKey = ensureKey()
val cipher = encryptionDecryptionService.createEncryptionCipher(secretKey) val cipher = encryptionDecryptionService.createEncryptionCipher(secretKey)
@@ -22,7 +22,7 @@ interface BiometricAuthenticatorManager {
val hasAvailableAuthenticator: Boolean val hasAvailableAuthenticator: Boolean
/** /**
* If the device is secured for example with a pin, pattern or password, and the user has enrolled at least one biometric. * If the device is secured for example with a pin, a pattern, a password, or biometric.
*/ */
val canUseDeviceUnlock: Boolean val canUseDeviceUnlock: Boolean
@@ -71,7 +71,7 @@ class DefaultBiometricAuthenticatorManager(
biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) == BiometricManager.BIOMETRIC_SUCCESS biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) == BiometricManager.BIOMETRIC_SUCCESS
/** /**
* Returns true if a strong biometric method (i.e.: fingerprint, some face or iris unlock implementations) can be used. * Returns true if a device credential method (i.e.: pattern, pin) can be used.
*/ */
private val canUseDeviceCredentialAuth: Boolean private val canUseDeviceCredentialAuth: Boolean
get() = biometricManager.canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS get() = biometricManager.canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS
@@ -26,14 +26,14 @@ class DeviceUnlockNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: DeviceUnlockPresenter, private val presenter: DeviceUnlockPresenter,
private val presenterFactory: PinUnlockPresenter.Factory, private val pinUnlockPresenterFactory: PinUnlockPresenter.Factory,
) : Node(buildContext, plugins = plugins) { ) : Node(buildContext, plugins = plugins) {
@Composable @Composable
override fun View(modifier: Modifier) { override fun View(modifier: Modifier) {
val state = presenter.present() val state = presenter.present()
if (state.showApplicationPinCode) { if (state.showApplicationPinCode) {
val pinUnlockPresenter = remember { val pinUnlockPresenter = remember {
presenterFactory.create(forDeviceUnlock = true) pinUnlockPresenterFactory.create(forDeviceUnlock = true)
} }
val pinState = pinUnlockPresenter.present() val pinState = pinUnlockPresenter.present()
PinUnlockView( PinUnlockView(
@@ -13,7 +13,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Inject
import io.element.android.features.lockscreen.impl.biometric.BiometricAuthenticatorManager import io.element.android.features.lockscreen.impl.biometric.BiometricAuthenticatorManager
@@ -21,36 +20,34 @@ import io.element.android.features.lockscreen.impl.pin.PinCodeManager
import io.element.android.features.lockscreen.impl.unlock.PinUnlockHelper import io.element.android.features.lockscreen.impl.unlock.PinUnlockHelper
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
@Inject @Inject
class DeviceUnlockPresenter( class DeviceUnlockPresenter(
private val pinUnlockHelper: PinUnlockHelper, private val pinUnlockHelper: PinUnlockHelper,
private val biometricAuthenticatorManager: BiometricAuthenticatorManager, private val biometricAuthenticatorManager: BiometricAuthenticatorManager,
private val biometricRequester: DeviceUnlockCallbackHolder, private val deviceUnlockCallbackHolder: DeviceUnlockCallbackHolder,
private val pinCodeManager: PinCodeManager, private val pinCodeManager: PinCodeManager,
) : Presenter<DeviceUnlockState> { ) : Presenter<DeviceUnlockState> {
@Composable @Composable
override fun present(): DeviceUnlockState { override fun present(): DeviceUnlockState {
val coroutineScope = rememberCoroutineScope()
var showApplicationPinCode by remember { var showApplicationPinCode by remember {
mutableStateOf(false) mutableStateOf(false)
} }
val biometricUnlock = biometricAuthenticatorManager.rememberUnlockDeviceBiometricAuthenticator() val biometricUnlock = biometricAuthenticatorManager.rememberUnlockDeviceBiometricAuthenticator()
val deviceUnlockCallback by biometricRequester.deviceUnlockCallback.collectAsState() val deviceUnlockCallback by deviceUnlockCallbackHolder.deviceUnlockCallback.collectAsState()
val canUseDeviceUnlock = biometricAuthenticatorManager.canUseDeviceUnlock val canUseDeviceUnlock = biometricAuthenticatorManager.canUseDeviceUnlock
fun setUnlock(isUnlock: Boolean) = coroutineScope.launch { fun setUnlock(isUnlock: Boolean) {
deviceUnlockCallback?.let { deviceUnlockCallback?.let {
if (isUnlock) { if (isUnlock) {
it.onUnlocked() it.onUnlock()
} else { } else {
it.onCancel() it.onCancel()
} }
} }
showApplicationPinCode = false showApplicationPinCode = false
biometricRequester.onDone() deviceUnlockCallbackHolder.onDone()
} }
LaunchedEffect(biometricUnlock, canUseDeviceUnlock, deviceUnlockCallback) { LaunchedEffect(biometricUnlock, canUseDeviceUnlock, deviceUnlockCallback) {
@@ -145,7 +145,7 @@ class DeviceUnlockPresenterTest {
return DeviceUnlockPresenter( return DeviceUnlockPresenter(
pinUnlockHelper = pinUnlockHelper, pinUnlockHelper = pinUnlockHelper,
biometricAuthenticatorManager = biometricAuthenticatorManager, biometricAuthenticatorManager = biometricAuthenticatorManager,
biometricRequester = callbackHolder, deviceUnlockCallbackHolder = callbackHolder,
pinCodeManager = pinCodeManager, pinCodeManager = pinCodeManager,
) )
} }
@@ -15,5 +15,5 @@ class FakeDeviceUnlockEntryPointCallback(
private val onUnlockedLambda: () -> Unit = EnsureNeverCalled(), private val onUnlockedLambda: () -> Unit = EnsureNeverCalled(),
) : DeviceUnlockEntryPoint.Callback { ) : DeviceUnlockEntryPoint.Callback {
override fun onCancel() = onCancelLambda() override fun onCancel() = onCancelLambda()
override fun onUnlocked() = onUnlockedLambda() override fun onUnlock() = onUnlockedLambda()
} }