Loading packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java +4 −3 Original line number Diff line number Diff line Loading @@ -293,9 +293,10 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView> && keyguardInputView instanceof KeyguardSecureLockDeviceBiometricAuthView) { return new KeyguardSecureLockDeviceBiometricAuthViewController( (KeyguardSecureLockDeviceBiometricAuthView) keyguardInputView, mSecureLockDeviceViewModelFactory, mSelectedUserInteractor, securityMode, keyguardSecurityCallback, emergencyButtonController, mMessageAreaControllerFactory, mFeatureFlags, mBouncerHapticPlayer); mSecureLockDeviceViewModelFactory, mSecureLockDeviceInteractor, mSelectedUserInteractor, securityMode, keyguardSecurityCallback, emergencyButtonController, mMessageAreaControllerFactory, mFeatureFlags, mBouncerHapticPlayer); } if (keyguardInputView instanceof KeyguardPatternView) { return new KeyguardPatternViewController((KeyguardPatternView) keyguardInputView, Loading packages/SystemUI/src/com/android/keyguard/KeyguardSecureLockDeviceBiometricAuthViewController.kt +8 −14 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ import com.android.systemui.flags.FeatureFlags import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.securelockdevice.ui.SecureLockDeviceContent import com.android.systemui.securelockdevice.domain.interactor.SecureLockDeviceInteractor import com.android.systemui.securelockdevice.ui.composable.SecureLockDeviceContent import com.android.systemui.securelockdevice.ui.viewmodel.SecureLockDeviceBiometricAuthContentViewModel import com.android.systemui.user.domain.interactor.SelectedUserInteractor import kotlinx.coroutines.launch Loading @@ -36,7 +37,9 @@ import kotlinx.coroutines.launch */ class KeyguardSecureLockDeviceBiometricAuthViewController( private val view: KeyguardSecureLockDeviceBiometricAuthView, secureLockDeviceViewModelFactory: SecureLockDeviceBiometricAuthContentViewModel.Factory, private val secureLockDeviceViewModelFactory: SecureLockDeviceBiometricAuthContentViewModel.Factory, private val secureLockDeviceInteractor: SecureLockDeviceInteractor, selectedUserInteractor: SelectedUserInteractor, securityMode: KeyguardSecurityModel.SecurityMode?, keyguardSecurityCallback: KeyguardSecurityCallback?, Loading @@ -56,9 +59,6 @@ class KeyguardSecureLockDeviceBiometricAuthViewController( bouncerHapticPlayer, ) { private val secureLockDeviceViewModel: SecureLockDeviceBiometricAuthContentViewModel = secureLockDeviceViewModelFactory.create() public override fun onInit() { if (SceneContainerFlag.isEnabled) { return Loading @@ -71,17 +71,12 @@ class KeyguardSecureLockDeviceBiometricAuthViewController( id = R.id.secure_lock_device_biometric_auth_content setContent { SecureLockDeviceContent( secureLockDeviceViewModel = secureLockDeviceViewModel, secureLockDeviceViewModelFactory = secureLockDeviceViewModelFactory, modifier = Modifier.fillMaxSize(), ) } } view.repeatWhenAttached { lifecycleScope.launch { view.addView(composeView) secureLockDeviceViewModel.activate() } } view.repeatWhenAttached { lifecycleScope.launch { view.addView(composeView) } } } override fun updateMessageAreaVisibility() {} Loading @@ -95,12 +90,11 @@ class KeyguardSecureLockDeviceBiometricAuthViewController( override fun needsInput(): Boolean = false override fun startAppearAnimation() { secureLockDeviceViewModel.startAppearAnimation() super.startAppearAnimation() } override fun startDisappearAnimation(finishRunnable: Runnable?): Boolean { secureLockDeviceViewModel.setDisappearAnimationFinishedRunnable(finishRunnable) secureLockDeviceInteractor.setDisappearAnimationFinishedRunnable(finishRunnable) return true } Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/BiometricAuthIconViewModel.kt +61 −18 Original line number Diff line number Diff line Loading @@ -25,13 +25,14 @@ import android.graphics.Rect import android.hardware.biometrics.Flags import android.security.Flags.secureLockDevice import android.util.RotationUtils import androidx.compose.runtime.getValue import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.biometrics.ui.PromptIconState import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.display.domain.interactor.DisplayStateInteractor import com.android.systemui.display.shared.model.DisplayRotation import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.HydratedActivatable import com.android.systemui.res.R import com.android.systemui.securelockdevice.ui.viewmodel.SecureLockDeviceBiometricAuthContentViewModel import com.android.systemui.util.kotlin.Quad Loading Loading @@ -64,7 +65,7 @@ constructor( @Application private val applicationContext: Context, private val displayStateInteractor: DisplayStateInteractor, udfpsOverlayInteractor: UdfpsOverlayInteractor, ) : ExclusiveActivatable() { ) : HydratedActivatable() { /** Biometric auth modalities for the UI to display */ enum class BiometricAuthModalities { Loading Loading @@ -110,22 +111,27 @@ constructor( } private val hasSfps: Flow<Boolean> = if (promptViewModel != null) { promptViewModel.modalities.map { it.hasSfps } } else if (secureLockDevice() && secureLockDeviceViewModel != null) { promptViewModel?.modalities?.map { it.hasSfps } ?: if (secureLockDevice() && secureLockDeviceViewModel != null) { secureLockDeviceViewModel.enrolledStrongBiometrics.map { it.hasSfps } } else { flowOf(false) } /** Whether UDFPS is available on the biometric prompt. */ val hasUdfps: Flow<Boolean> = if (promptViewModel != null) { promptViewModel.modalities.map { it.hasUdfps } } else if (secureLockDevice() && secureLockDeviceViewModel != null) { promptViewModel?.modalities?.map { it.hasUdfps } ?: if (secureLockDevice() && secureLockDeviceViewModel != null) { secureLockDeviceViewModel.enrolledStrongBiometrics.map { it.hasUdfps } } else { flowOf(false) } /** * Hydrated state version of [hasUdfps] for use in composables. Should replace [hasUdfps] when * legacy icon view / view-binder are fully migrated to compose. */ val hasUdfpsState: Boolean by hasUdfps.hydratedStateOf(traceName = "hasUdfps", initialValue = false) /** If the user is currently authenticating (i.e. at least one biometric is scanning). */ val isAuthenticating: Flow<Boolean> = Loading @@ -136,6 +142,12 @@ constructor( /** Whether an error message is currently being shown. */ val showingError: Flow<Boolean> = promptViewModel?.showingError ?: secureLockDeviceViewModel?.showingError ?: emptyFlow() /** * Hydrated state version of [showingError] for use in composables. Should replace * [showingError] when legacy icon view / view-binder are fully migrated to compose. */ val showingErrorState: Boolean by showingError.hydratedStateOf(traceName = "showingError", initialValue = false) /** Whether the previous icon shown displayed an error. */ internal val previousIconWasError: MutableStateFlow<Boolean> = MutableStateFlow(false) Loading @@ -151,10 +163,15 @@ constructor( ?: emptyFlow() /** If the auth is pending confirmation. */ val isPendingConfirmation: Flow<Boolean> = private val isPendingConfirmation: Flow<Boolean> = isAuthenticated.map { authState -> authState.isAuthenticated && authState.needsUserConfirmation } val isPendingConfirmationState: Boolean by isPendingConfirmation.hydratedStateOf( traceName = "isPendingConfirmation", initialValue = false, ) /** Current biometric icon asset. */ val iconAsset: Flow<Int> = Loading Loading @@ -340,6 +357,13 @@ constructor( } } /** * Hydrated state version of [iconSize] for use in composables. Should replace [iconSize] when * legacy icon view / view-binder are fully migrated to compose. */ val iconSizeState: Pair<Int, Int> by iconSize.hydratedStateOf(traceName = "iconSize", initialValue = Pair(0, 0)) /** Content description for iconView */ val contentDescriptionId: Flow<Int> = activeBiometricAuthType.flatMapLatest { modalities -> Loading Loading @@ -507,6 +531,24 @@ constructor( ) } .distinctUntilChanged() /** * Hydrated state version of [iconState] for use in composables. Should replace [iconState] when * legacy icon view / view-binder are fully migrated to compose. */ val hydratedIconState: PromptIconState by iconState.hydratedStateOf( traceName = "iconState", initialValue = PromptIconState( asset = -1, shouldAnimate = false, shouldLoop = false, contentDescriptionId = -1, rotation = 0f, activeBiometricAuthType = BiometricAuthModalities.None, showingError = false, ), ) fun onConfigurationChanged(newConfig: Configuration) { displayStateInteractor.onConfigurationChanged(newConfig) Loading Loading @@ -702,7 +744,8 @@ constructor( when { authState.isAuthenticatedAndExplicitlyConfirmed -> R.string.biometric_dialog_face_icon_description_confirmed authState.isAuthenticated -> R.string.biometric_dialog_face_icon_description_authenticated authState.isAuthenticated -> R.string.biometric_dialog_face_icon_description_authenticated isAuthenticating -> R.string.biometric_dialog_face_icon_description_authenticating showingError -> R.string.keyguard_face_failed else -> R.string.biometric_dialog_face_icon_description_idle Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt +30 −4 Original line number Diff line number Diff line Loading @@ -25,17 +25,31 @@ import com.android.systemui.biometrics.ui.PromptPosition import com.android.systemui.biometrics.ui.isMedium import com.android.systemui.biometrics.ui.isSmall import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.res.R import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged /** Models UI of [BiometricPromptLayout.iconView] */ class PromptIconViewModel( promptViewModel: PromptViewModel, class PromptIconViewModel @AssistedInject constructor( @Assisted private val promptViewModel: PromptViewModel, @Assisted private val biometricAuthIconViewModelFactory: BiometricAuthIconViewModel.Factory, @Application private val context: Context, val internal: BiometricAuthIconViewModel, ) { ) : ExclusiveActivatable() { val internal: BiometricAuthIconViewModel = biometricAuthIconViewModelFactory.create( promptViewModel = promptViewModel, secureLockDeviceViewModel = null, ) /** Padding for placing icons */ val portraitSmallBottomPadding = context.resources.getDimensionPixelSize( Loading Loading @@ -151,4 +165,16 @@ class PromptIconViewModel( fun onConfigurationChanged(newConfig: Configuration) { internal.onConfigurationChanged(newConfig) } @AssistedFactory interface Factory { fun create( promptViewModel: PromptViewModel, biometricAuthIconViewModelFactory: BiometricAuthIconViewModel.Factory, ): PromptIconViewModel } override suspend fun onActivated(): Nothing { coroutineScope { awaitCancellation() } } } packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +7 −9 Original line number Diff line number Diff line Loading @@ -102,8 +102,9 @@ constructor( accessibilityManager: AccessibilityManager, promptFallbackViewModelFactory: PromptFallbackViewModel.Factory, shadeInteractor: ShadeInteractor, promptIconViewModelFactory: PromptIconViewModel.Factory, biometricAuthIconViewModelFactory: BiometricAuthIconViewModel.Factory, private val keyguardTransitionInteractor: KeyguardTransitionInteractor, keyguardTransitionInteractor: KeyguardTransitionInteractor, ) { /** Viewmodel for the fallback view */ val promptFallbackViewModel = promptFallbackViewModelFactory.create() Loading Loading @@ -400,15 +401,12 @@ constructor( promptSelectorInteractor.prompt.map { it?.contentView }.distinctUntilChanged() /** ViewModel for the biometric icon in the prompt. */ val iconViewModel = PromptIconViewModel( this, context, biometricAuthIconViewModelFactory.create( val iconViewModel: PromptIconViewModel by lazy { promptIconViewModelFactory.create( promptViewModel = this, secureLockDeviceViewModel = null, ), biometricAuthIconViewModelFactory = biometricAuthIconViewModelFactory, ) } private val originalDescription = promptSelectorInteractor.prompt.map { it?.description ?: "" }.distinctUntilChanged() Loading Loading
packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java +4 −3 Original line number Diff line number Diff line Loading @@ -293,9 +293,10 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView> && keyguardInputView instanceof KeyguardSecureLockDeviceBiometricAuthView) { return new KeyguardSecureLockDeviceBiometricAuthViewController( (KeyguardSecureLockDeviceBiometricAuthView) keyguardInputView, mSecureLockDeviceViewModelFactory, mSelectedUserInteractor, securityMode, keyguardSecurityCallback, emergencyButtonController, mMessageAreaControllerFactory, mFeatureFlags, mBouncerHapticPlayer); mSecureLockDeviceViewModelFactory, mSecureLockDeviceInteractor, mSelectedUserInteractor, securityMode, keyguardSecurityCallback, emergencyButtonController, mMessageAreaControllerFactory, mFeatureFlags, mBouncerHapticPlayer); } if (keyguardInputView instanceof KeyguardPatternView) { return new KeyguardPatternViewController((KeyguardPatternView) keyguardInputView, Loading
packages/SystemUI/src/com/android/keyguard/KeyguardSecureLockDeviceBiometricAuthViewController.kt +8 −14 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ import com.android.systemui.flags.FeatureFlags import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.securelockdevice.ui.SecureLockDeviceContent import com.android.systemui.securelockdevice.domain.interactor.SecureLockDeviceInteractor import com.android.systemui.securelockdevice.ui.composable.SecureLockDeviceContent import com.android.systemui.securelockdevice.ui.viewmodel.SecureLockDeviceBiometricAuthContentViewModel import com.android.systemui.user.domain.interactor.SelectedUserInteractor import kotlinx.coroutines.launch Loading @@ -36,7 +37,9 @@ import kotlinx.coroutines.launch */ class KeyguardSecureLockDeviceBiometricAuthViewController( private val view: KeyguardSecureLockDeviceBiometricAuthView, secureLockDeviceViewModelFactory: SecureLockDeviceBiometricAuthContentViewModel.Factory, private val secureLockDeviceViewModelFactory: SecureLockDeviceBiometricAuthContentViewModel.Factory, private val secureLockDeviceInteractor: SecureLockDeviceInteractor, selectedUserInteractor: SelectedUserInteractor, securityMode: KeyguardSecurityModel.SecurityMode?, keyguardSecurityCallback: KeyguardSecurityCallback?, Loading @@ -56,9 +59,6 @@ class KeyguardSecureLockDeviceBiometricAuthViewController( bouncerHapticPlayer, ) { private val secureLockDeviceViewModel: SecureLockDeviceBiometricAuthContentViewModel = secureLockDeviceViewModelFactory.create() public override fun onInit() { if (SceneContainerFlag.isEnabled) { return Loading @@ -71,17 +71,12 @@ class KeyguardSecureLockDeviceBiometricAuthViewController( id = R.id.secure_lock_device_biometric_auth_content setContent { SecureLockDeviceContent( secureLockDeviceViewModel = secureLockDeviceViewModel, secureLockDeviceViewModelFactory = secureLockDeviceViewModelFactory, modifier = Modifier.fillMaxSize(), ) } } view.repeatWhenAttached { lifecycleScope.launch { view.addView(composeView) secureLockDeviceViewModel.activate() } } view.repeatWhenAttached { lifecycleScope.launch { view.addView(composeView) } } } override fun updateMessageAreaVisibility() {} Loading @@ -95,12 +90,11 @@ class KeyguardSecureLockDeviceBiometricAuthViewController( override fun needsInput(): Boolean = false override fun startAppearAnimation() { secureLockDeviceViewModel.startAppearAnimation() super.startAppearAnimation() } override fun startDisappearAnimation(finishRunnable: Runnable?): Boolean { secureLockDeviceViewModel.setDisappearAnimationFinishedRunnable(finishRunnable) secureLockDeviceInteractor.setDisappearAnimationFinishedRunnable(finishRunnable) return true } Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/BiometricAuthIconViewModel.kt +61 −18 Original line number Diff line number Diff line Loading @@ -25,13 +25,14 @@ import android.graphics.Rect import android.hardware.biometrics.Flags import android.security.Flags.secureLockDevice import android.util.RotationUtils import androidx.compose.runtime.getValue import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.biometrics.ui.PromptIconState import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.display.domain.interactor.DisplayStateInteractor import com.android.systemui.display.shared.model.DisplayRotation import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.HydratedActivatable import com.android.systemui.res.R import com.android.systemui.securelockdevice.ui.viewmodel.SecureLockDeviceBiometricAuthContentViewModel import com.android.systemui.util.kotlin.Quad Loading Loading @@ -64,7 +65,7 @@ constructor( @Application private val applicationContext: Context, private val displayStateInteractor: DisplayStateInteractor, udfpsOverlayInteractor: UdfpsOverlayInteractor, ) : ExclusiveActivatable() { ) : HydratedActivatable() { /** Biometric auth modalities for the UI to display */ enum class BiometricAuthModalities { Loading Loading @@ -110,22 +111,27 @@ constructor( } private val hasSfps: Flow<Boolean> = if (promptViewModel != null) { promptViewModel.modalities.map { it.hasSfps } } else if (secureLockDevice() && secureLockDeviceViewModel != null) { promptViewModel?.modalities?.map { it.hasSfps } ?: if (secureLockDevice() && secureLockDeviceViewModel != null) { secureLockDeviceViewModel.enrolledStrongBiometrics.map { it.hasSfps } } else { flowOf(false) } /** Whether UDFPS is available on the biometric prompt. */ val hasUdfps: Flow<Boolean> = if (promptViewModel != null) { promptViewModel.modalities.map { it.hasUdfps } } else if (secureLockDevice() && secureLockDeviceViewModel != null) { promptViewModel?.modalities?.map { it.hasUdfps } ?: if (secureLockDevice() && secureLockDeviceViewModel != null) { secureLockDeviceViewModel.enrolledStrongBiometrics.map { it.hasUdfps } } else { flowOf(false) } /** * Hydrated state version of [hasUdfps] for use in composables. Should replace [hasUdfps] when * legacy icon view / view-binder are fully migrated to compose. */ val hasUdfpsState: Boolean by hasUdfps.hydratedStateOf(traceName = "hasUdfps", initialValue = false) /** If the user is currently authenticating (i.e. at least one biometric is scanning). */ val isAuthenticating: Flow<Boolean> = Loading @@ -136,6 +142,12 @@ constructor( /** Whether an error message is currently being shown. */ val showingError: Flow<Boolean> = promptViewModel?.showingError ?: secureLockDeviceViewModel?.showingError ?: emptyFlow() /** * Hydrated state version of [showingError] for use in composables. Should replace * [showingError] when legacy icon view / view-binder are fully migrated to compose. */ val showingErrorState: Boolean by showingError.hydratedStateOf(traceName = "showingError", initialValue = false) /** Whether the previous icon shown displayed an error. */ internal val previousIconWasError: MutableStateFlow<Boolean> = MutableStateFlow(false) Loading @@ -151,10 +163,15 @@ constructor( ?: emptyFlow() /** If the auth is pending confirmation. */ val isPendingConfirmation: Flow<Boolean> = private val isPendingConfirmation: Flow<Boolean> = isAuthenticated.map { authState -> authState.isAuthenticated && authState.needsUserConfirmation } val isPendingConfirmationState: Boolean by isPendingConfirmation.hydratedStateOf( traceName = "isPendingConfirmation", initialValue = false, ) /** Current biometric icon asset. */ val iconAsset: Flow<Int> = Loading Loading @@ -340,6 +357,13 @@ constructor( } } /** * Hydrated state version of [iconSize] for use in composables. Should replace [iconSize] when * legacy icon view / view-binder are fully migrated to compose. */ val iconSizeState: Pair<Int, Int> by iconSize.hydratedStateOf(traceName = "iconSize", initialValue = Pair(0, 0)) /** Content description for iconView */ val contentDescriptionId: Flow<Int> = activeBiometricAuthType.flatMapLatest { modalities -> Loading Loading @@ -507,6 +531,24 @@ constructor( ) } .distinctUntilChanged() /** * Hydrated state version of [iconState] for use in composables. Should replace [iconState] when * legacy icon view / view-binder are fully migrated to compose. */ val hydratedIconState: PromptIconState by iconState.hydratedStateOf( traceName = "iconState", initialValue = PromptIconState( asset = -1, shouldAnimate = false, shouldLoop = false, contentDescriptionId = -1, rotation = 0f, activeBiometricAuthType = BiometricAuthModalities.None, showingError = false, ), ) fun onConfigurationChanged(newConfig: Configuration) { displayStateInteractor.onConfigurationChanged(newConfig) Loading Loading @@ -702,7 +744,8 @@ constructor( when { authState.isAuthenticatedAndExplicitlyConfirmed -> R.string.biometric_dialog_face_icon_description_confirmed authState.isAuthenticated -> R.string.biometric_dialog_face_icon_description_authenticated authState.isAuthenticated -> R.string.biometric_dialog_face_icon_description_authenticated isAuthenticating -> R.string.biometric_dialog_face_icon_description_authenticating showingError -> R.string.keyguard_face_failed else -> R.string.biometric_dialog_face_icon_description_idle Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt +30 −4 Original line number Diff line number Diff line Loading @@ -25,17 +25,31 @@ import com.android.systemui.biometrics.ui.PromptPosition import com.android.systemui.biometrics.ui.isMedium import com.android.systemui.biometrics.ui.isSmall import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.res.R import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged /** Models UI of [BiometricPromptLayout.iconView] */ class PromptIconViewModel( promptViewModel: PromptViewModel, class PromptIconViewModel @AssistedInject constructor( @Assisted private val promptViewModel: PromptViewModel, @Assisted private val biometricAuthIconViewModelFactory: BiometricAuthIconViewModel.Factory, @Application private val context: Context, val internal: BiometricAuthIconViewModel, ) { ) : ExclusiveActivatable() { val internal: BiometricAuthIconViewModel = biometricAuthIconViewModelFactory.create( promptViewModel = promptViewModel, secureLockDeviceViewModel = null, ) /** Padding for placing icons */ val portraitSmallBottomPadding = context.resources.getDimensionPixelSize( Loading Loading @@ -151,4 +165,16 @@ class PromptIconViewModel( fun onConfigurationChanged(newConfig: Configuration) { internal.onConfigurationChanged(newConfig) } @AssistedFactory interface Factory { fun create( promptViewModel: PromptViewModel, biometricAuthIconViewModelFactory: BiometricAuthIconViewModel.Factory, ): PromptIconViewModel } override suspend fun onActivated(): Nothing { coroutineScope { awaitCancellation() } } }
packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +7 −9 Original line number Diff line number Diff line Loading @@ -102,8 +102,9 @@ constructor( accessibilityManager: AccessibilityManager, promptFallbackViewModelFactory: PromptFallbackViewModel.Factory, shadeInteractor: ShadeInteractor, promptIconViewModelFactory: PromptIconViewModel.Factory, biometricAuthIconViewModelFactory: BiometricAuthIconViewModel.Factory, private val keyguardTransitionInteractor: KeyguardTransitionInteractor, keyguardTransitionInteractor: KeyguardTransitionInteractor, ) { /** Viewmodel for the fallback view */ val promptFallbackViewModel = promptFallbackViewModelFactory.create() Loading Loading @@ -400,15 +401,12 @@ constructor( promptSelectorInteractor.prompt.map { it?.contentView }.distinctUntilChanged() /** ViewModel for the biometric icon in the prompt. */ val iconViewModel = PromptIconViewModel( this, context, biometricAuthIconViewModelFactory.create( val iconViewModel: PromptIconViewModel by lazy { promptIconViewModelFactory.create( promptViewModel = this, secureLockDeviceViewModel = null, ), biometricAuthIconViewModelFactory = biometricAuthIconViewModelFactory, ) } private val originalDescription = promptSelectorInteractor.prompt.map { it?.description ?: "" }.distinctUntilChanged() Loading