Loading packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +2 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.data.quickaffordance.KeyguardDataQuickAffordanceModule; import com.android.systemui.keyguard.data.repository.KeyguardFaceAuthModule; import com.android.systemui.keyguard.data.repository.KeyguardRepositoryModule; import com.android.systemui.keyguard.domain.interactor.StartKeyguardTransitionModule; import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceModule; Loading @@ -66,8 +67,6 @@ import java.util.concurrent.Executor; import dagger.Lazy; import dagger.Module; import dagger.Provides; import kotlinx.coroutines.CoroutineDispatcher; import kotlinx.coroutines.CoroutineScope; /** * Dagger Module providing keyguard. Loading @@ -82,6 +81,7 @@ import kotlinx.coroutines.CoroutineScope; KeyguardDataQuickAffordanceModule.class, KeyguardQuickAffordanceModule.class, KeyguardRepositoryModule.class, KeyguardFaceAuthModule.class, StartKeyguardTransitionModule.class, }) public class KeyguardModule { Loading packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt +50 −11 Original line number Diff line number Diff line Loading @@ -87,6 +87,13 @@ interface BiometricSettingsRepository { */ val isStrongBiometricAllowed: StateFlow<Boolean> /** * Whether the current user is allowed to use a convenience biometric for device entry based on * Android Security policies. If false, the user may be able to use strong biometric or primary * authentication for device entry. */ val isNonStrongBiometricAllowed: StateFlow<Boolean> /** Whether fingerprint feature is enabled for the current user by the DevicePolicy */ val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean> Loading Loading @@ -276,6 +283,16 @@ constructor( ) ) override val isNonStrongBiometricAllowed: StateFlow<Boolean> = strongAuthTracker.isNonStrongBiometricAllowed.stateIn( scope, SharingStarted.Eagerly, strongAuthTracker.isBiometricAllowedForUser( false, userRepository.getSelectedUserInfo().id ) ) override val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean> = selectedUserId .flatMapLatest { userId -> Loading @@ -297,40 +314,62 @@ constructor( private class StrongAuthTracker(private val userRepository: UserRepository, context: Context?) : LockPatternUtils.StrongAuthTracker(context) { private val _authFlags = // Backing field for onStrongAuthRequiredChanged private val _strongAuthFlags = MutableStateFlow( StrongAuthenticationFlags(currentUserId, getStrongAuthForUser(currentUserId)) ) // Backing field for onIsNonStrongBiometricAllowedChanged private val _nonStrongBiometricAllowed = MutableStateFlow( Pair(currentUserId, isNonStrongBiometricAllowedAfterIdleTimeout(currentUserId)) ) val currentUserAuthFlags: Flow<StrongAuthenticationFlags> = userRepository.selectedUserInfo .map { it.id } .distinctUntilChanged() .flatMapLatest { currUserId -> _authFlags .filter { it.userId == currUserId } .flatMapLatest { userId -> _strongAuthFlags .filter { it.userId == userId } .onEach { Log.d(TAG, "currentUser authFlags changed, new value: $it") } .onStart { emit( StrongAuthenticationFlags( currentUserId, getStrongAuthForUser(currentUserId) ) ) emit(StrongAuthenticationFlags(userId, getStrongAuthForUser(userId))) } } /** isStrongBiometricAllowed for the current user. */ val isStrongBiometricAllowed: Flow<Boolean> = currentUserAuthFlags.map { isBiometricAllowedForUser(true, it.userId) } /** isNonStrongBiometricAllowed for the current user. */ val isNonStrongBiometricAllowed: Flow<Boolean> = userRepository.selectedUserInfo .map { it.id } .distinctUntilChanged() .flatMapLatest { userId -> _nonStrongBiometricAllowed .filter { it.first == userId } .map { it.second } .onEach { Log.d(TAG, "isNonStrongBiometricAllowed changed for current user") } .onStart { emit(isNonStrongBiometricAllowedAfterIdleTimeout(userId)) } } private val currentUserId get() = userRepository.getSelectedUserInfo().id override fun onStrongAuthRequiredChanged(userId: Int) { val newFlags = getStrongAuthForUser(userId) _authFlags.value = StrongAuthenticationFlags(userId, newFlags) _strongAuthFlags.value = StrongAuthenticationFlags(userId, newFlags) Log.d(TAG, "onStrongAuthRequiredChanged for userId: $userId, flag value: $newFlags") } override fun onIsNonStrongBiometricAllowedChanged(userId: Int) { val allowed = isNonStrongBiometricAllowedAfterIdleTimeout(userId) _nonStrongBiometricAllowed.value = Pair(userId, allowed) Log.d(TAG, "onIsNonStrongBiometricAllowedChanged for userId: $userId, $allowed") } } private fun DevicePolicyManager.isFaceDisabled(userId: Int): Boolean = Loading packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt +37 −6 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.keyguard.data.repository import android.hardware.biometrics.BiometricAuthenticator import android.hardware.biometrics.BiometricAuthenticator.Modality import android.hardware.biometrics.BiometricSourceType import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback Loading @@ -33,6 +35,7 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.stateIn /** Encapsulates state about device entry fingerprint auth mechanism. */ Loading @@ -49,7 +52,7 @@ interface DeviceEntryFingerprintAuthRepository { /** * Fingerprint sensor type present on the device, null if fingerprint sensor is not available. */ val availableFpSensorType: BiometricType? val availableFpSensorType: Flow<BiometricType?> } /** Loading Loading @@ -77,11 +80,39 @@ constructor( pw.println("isLockedOut=${isLockedOut.value}") } override val availableFpSensorType: BiometricType? get() = if (authController.isUdfpsSupported) BiometricType.UNDER_DISPLAY_FINGERPRINT override val availableFpSensorType: Flow<BiometricType?> get() { return if (authController.areAllFingerprintAuthenticatorsRegistered()) { flowOf(getFpSensorType()) } else { conflatedCallbackFlow { val callback = object : AuthController.Callback { override fun onAllAuthenticatorsRegistered(@Modality modality: Int) { if (modality == BiometricAuthenticator.TYPE_FINGERPRINT) trySendWithFailureLogging( getFpSensorType(), TAG, "onAllAuthenticatorsRegistered, emitting fpSensorType" ) } } authController.addCallback(callback) trySendWithFailureLogging( getFpSensorType(), TAG, "initial value for fpSensorType" ) awaitClose { authController.removeCallback(callback) } } } } private fun getFpSensorType(): BiometricType? { return if (authController.isUdfpsSupported) BiometricType.UNDER_DISPLAY_FINGERPRINT else if (authController.isSfpsSupported) BiometricType.SIDE_FINGERPRINT else if (authController.isRearFpsSupported) BiometricType.REAR_FINGERPRINT else null } override val isLockedOut: StateFlow<Boolean> = conflatedCallbackFlow { Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +2 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.data.quickaffordance.KeyguardDataQuickAffordanceModule; import com.android.systemui.keyguard.data.repository.KeyguardFaceAuthModule; import com.android.systemui.keyguard.data.repository.KeyguardRepositoryModule; import com.android.systemui.keyguard.domain.interactor.StartKeyguardTransitionModule; import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceModule; Loading @@ -66,8 +67,6 @@ import java.util.concurrent.Executor; import dagger.Lazy; import dagger.Module; import dagger.Provides; import kotlinx.coroutines.CoroutineDispatcher; import kotlinx.coroutines.CoroutineScope; /** * Dagger Module providing keyguard. Loading @@ -82,6 +81,7 @@ import kotlinx.coroutines.CoroutineScope; KeyguardDataQuickAffordanceModule.class, KeyguardQuickAffordanceModule.class, KeyguardRepositoryModule.class, KeyguardFaceAuthModule.class, StartKeyguardTransitionModule.class, }) public class KeyguardModule { Loading
packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt +50 −11 Original line number Diff line number Diff line Loading @@ -87,6 +87,13 @@ interface BiometricSettingsRepository { */ val isStrongBiometricAllowed: StateFlow<Boolean> /** * Whether the current user is allowed to use a convenience biometric for device entry based on * Android Security policies. If false, the user may be able to use strong biometric or primary * authentication for device entry. */ val isNonStrongBiometricAllowed: StateFlow<Boolean> /** Whether fingerprint feature is enabled for the current user by the DevicePolicy */ val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean> Loading Loading @@ -276,6 +283,16 @@ constructor( ) ) override val isNonStrongBiometricAllowed: StateFlow<Boolean> = strongAuthTracker.isNonStrongBiometricAllowed.stateIn( scope, SharingStarted.Eagerly, strongAuthTracker.isBiometricAllowedForUser( false, userRepository.getSelectedUserInfo().id ) ) override val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean> = selectedUserId .flatMapLatest { userId -> Loading @@ -297,40 +314,62 @@ constructor( private class StrongAuthTracker(private val userRepository: UserRepository, context: Context?) : LockPatternUtils.StrongAuthTracker(context) { private val _authFlags = // Backing field for onStrongAuthRequiredChanged private val _strongAuthFlags = MutableStateFlow( StrongAuthenticationFlags(currentUserId, getStrongAuthForUser(currentUserId)) ) // Backing field for onIsNonStrongBiometricAllowedChanged private val _nonStrongBiometricAllowed = MutableStateFlow( Pair(currentUserId, isNonStrongBiometricAllowedAfterIdleTimeout(currentUserId)) ) val currentUserAuthFlags: Flow<StrongAuthenticationFlags> = userRepository.selectedUserInfo .map { it.id } .distinctUntilChanged() .flatMapLatest { currUserId -> _authFlags .filter { it.userId == currUserId } .flatMapLatest { userId -> _strongAuthFlags .filter { it.userId == userId } .onEach { Log.d(TAG, "currentUser authFlags changed, new value: $it") } .onStart { emit( StrongAuthenticationFlags( currentUserId, getStrongAuthForUser(currentUserId) ) ) emit(StrongAuthenticationFlags(userId, getStrongAuthForUser(userId))) } } /** isStrongBiometricAllowed for the current user. */ val isStrongBiometricAllowed: Flow<Boolean> = currentUserAuthFlags.map { isBiometricAllowedForUser(true, it.userId) } /** isNonStrongBiometricAllowed for the current user. */ val isNonStrongBiometricAllowed: Flow<Boolean> = userRepository.selectedUserInfo .map { it.id } .distinctUntilChanged() .flatMapLatest { userId -> _nonStrongBiometricAllowed .filter { it.first == userId } .map { it.second } .onEach { Log.d(TAG, "isNonStrongBiometricAllowed changed for current user") } .onStart { emit(isNonStrongBiometricAllowedAfterIdleTimeout(userId)) } } private val currentUserId get() = userRepository.getSelectedUserInfo().id override fun onStrongAuthRequiredChanged(userId: Int) { val newFlags = getStrongAuthForUser(userId) _authFlags.value = StrongAuthenticationFlags(userId, newFlags) _strongAuthFlags.value = StrongAuthenticationFlags(userId, newFlags) Log.d(TAG, "onStrongAuthRequiredChanged for userId: $userId, flag value: $newFlags") } override fun onIsNonStrongBiometricAllowedChanged(userId: Int) { val allowed = isNonStrongBiometricAllowedAfterIdleTimeout(userId) _nonStrongBiometricAllowed.value = Pair(userId, allowed) Log.d(TAG, "onIsNonStrongBiometricAllowedChanged for userId: $userId, $allowed") } } private fun DevicePolicyManager.isFaceDisabled(userId: Int): Boolean = Loading
packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt +37 −6 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.keyguard.data.repository import android.hardware.biometrics.BiometricAuthenticator import android.hardware.biometrics.BiometricAuthenticator.Modality import android.hardware.biometrics.BiometricSourceType import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback Loading @@ -33,6 +35,7 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.stateIn /** Encapsulates state about device entry fingerprint auth mechanism. */ Loading @@ -49,7 +52,7 @@ interface DeviceEntryFingerprintAuthRepository { /** * Fingerprint sensor type present on the device, null if fingerprint sensor is not available. */ val availableFpSensorType: BiometricType? val availableFpSensorType: Flow<BiometricType?> } /** Loading Loading @@ -77,11 +80,39 @@ constructor( pw.println("isLockedOut=${isLockedOut.value}") } override val availableFpSensorType: BiometricType? get() = if (authController.isUdfpsSupported) BiometricType.UNDER_DISPLAY_FINGERPRINT override val availableFpSensorType: Flow<BiometricType?> get() { return if (authController.areAllFingerprintAuthenticatorsRegistered()) { flowOf(getFpSensorType()) } else { conflatedCallbackFlow { val callback = object : AuthController.Callback { override fun onAllAuthenticatorsRegistered(@Modality modality: Int) { if (modality == BiometricAuthenticator.TYPE_FINGERPRINT) trySendWithFailureLogging( getFpSensorType(), TAG, "onAllAuthenticatorsRegistered, emitting fpSensorType" ) } } authController.addCallback(callback) trySendWithFailureLogging( getFpSensorType(), TAG, "initial value for fpSensorType" ) awaitClose { authController.removeCallback(callback) } } } } private fun getFpSensorType(): BiometricType? { return if (authController.isUdfpsSupported) BiometricType.UNDER_DISPLAY_FINGERPRINT else if (authController.isSfpsSupported) BiometricType.SIDE_FINGERPRINT else if (authController.isRearFpsSupported) BiometricType.REAR_FINGERPRINT else null } override val isLockedOut: StateFlow<Boolean> = conflatedCallbackFlow { Loading