1 /* <lambda>null2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.deviceentry.domain.interactor 18 19 import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository 20 import com.android.systemui.biometrics.shared.model.FingerprintSensorType 21 import com.android.systemui.dagger.SysUISingleton 22 import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository 23 import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus 24 import com.android.systemui.keyguard.shared.model.FailFingerprintAuthenticationStatus 25 import com.android.systemui.keyguard.shared.model.FingerprintAuthenticationStatus 26 import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus 27 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus 28 import javax.inject.Inject 29 import kotlinx.coroutines.ExperimentalCoroutinesApi 30 import kotlinx.coroutines.flow.Flow 31 import kotlinx.coroutines.flow.StateFlow 32 import kotlinx.coroutines.flow.combine 33 import kotlinx.coroutines.flow.filterIsInstance 34 import kotlinx.coroutines.flow.flatMapLatest 35 import kotlinx.coroutines.flow.flowOf 36 import kotlinx.coroutines.flow.map 37 38 @OptIn(ExperimentalCoroutinesApi::class) 39 @SysUISingleton 40 class DeviceEntryFingerprintAuthInteractor 41 @Inject 42 constructor( 43 repository: DeviceEntryFingerprintAuthRepository, 44 biometricSettingsInteractor: DeviceEntryBiometricSettingsInteractor, 45 fingerprintPropertyRepository: FingerprintPropertyRepository, 46 ) { 47 /** 48 * Whether fingerprint authentication is currently running or not. This does not mean the user 49 * [isEngaged] with the fingerprint. 50 */ 51 val isRunning: Flow<Boolean> = repository.isRunning 52 53 /** Whether the user is actively engaging with the fingerprint sensor */ 54 val isEngaged: StateFlow<Boolean> = repository.isEngaged 55 56 /** Provide the current status of fingerprint authentication. */ 57 val authenticationStatus: Flow<FingerprintAuthenticationStatus> = 58 repository.authenticationStatus 59 60 val isLockedOut: Flow<Boolean> = repository.isLockedOut 61 62 val fingerprintFailure: Flow<FailFingerprintAuthenticationStatus> = 63 repository.authenticationStatus.filterIsInstance<FailFingerprintAuthenticationStatus>() 64 val fingerprintError: Flow<ErrorFingerprintAuthenticationStatus> = 65 repository.authenticationStatus.filterIsInstance<ErrorFingerprintAuthenticationStatus>() 66 val fingerprintHelp: Flow<HelpFingerprintAuthenticationStatus> = 67 repository.authenticationStatus.filterIsInstance<HelpFingerprintAuthenticationStatus>() 68 69 val fingerprintSuccess: Flow<SuccessFingerprintAuthenticationStatus> = 70 repository.authenticationStatus.filterIsInstance<SuccessFingerprintAuthenticationStatus>() 71 72 /** 73 * Whether fingerprint authentication is currently allowed for the user. This is true if the 74 * user has fingerprint auth enabled, enrolled, it is not disabled by any security timeouts by 75 * [com.android.systemui.keyguard.shared.model.AuthenticationFlags] and not locked out due to 76 * too many incorrect attempts. 77 */ 78 val isFingerprintAuthCurrentlyAllowed: Flow<Boolean> = 79 combine(isLockedOut, biometricSettingsInteractor.fingerprintAuthCurrentlyAllowed, ::Pair) 80 .map { (lockedOut, currentlyAllowed) -> !lockedOut && currentlyAllowed } 81 82 /** 83 * Whether the fingerprint sensor is present under the display as opposed to being on the power 84 * button or behind/rear of the phone. 85 */ 86 val isSensorUnderDisplay = 87 fingerprintPropertyRepository.sensorType.map(FingerprintSensorType::isUdfps) 88 89 /** Whether fingerprint authentication is currently allowed while on the bouncer. */ 90 val isFingerprintCurrentlyAllowedOnBouncer = 91 isSensorUnderDisplay.flatMapLatest { sensorBelowDisplay -> 92 if (sensorBelowDisplay) { 93 flowOf(false) 94 } else { 95 isFingerprintAuthCurrentlyAllowed 96 } 97 } 98 } 99