1 /* 2 * 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 18 package com.android.systemui.biometrics.ui.viewmodel 19 20 import android.annotation.RawRes 21 import android.content.res.Configuration 22 import com.android.systemui.R 23 import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor 24 import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor 25 import com.android.systemui.biometrics.shared.model.DisplayRotation 26 import com.android.systemui.biometrics.shared.model.FingerprintSensorType 27 import javax.inject.Inject 28 import kotlinx.coroutines.flow.Flow 29 import kotlinx.coroutines.flow.combine 30 31 /** Models UI of [BiometricPromptLayout.iconView] */ 32 class PromptFingerprintIconViewModel 33 @Inject 34 constructor( 35 private val displayStateInteractor: DisplayStateInteractor, 36 promptSelectorInteractor: PromptSelectorInteractor, 37 ) { 38 /** Current BiometricPromptLayout.iconView asset. */ 39 val iconAsset: Flow<Int> = 40 combine( 41 displayStateInteractor.currentRotation, 42 displayStateInteractor.isFolded, 43 displayStateInteractor.isInRearDisplayMode, 44 promptSelectorInteractor.sensorType, 45 ) { 46 rotation: DisplayRotation, 47 isFolded: Boolean, 48 isInRearDisplayMode: Boolean, 49 sensorType: FingerprintSensorType -> 50 when (sensorType) { 51 FingerprintSensorType.POWER_BUTTON -> 52 getSideFpsAnimationAsset(rotation, isFolded, isInRearDisplayMode) 53 // Replace below when non-SFPS iconAsset logic is migrated to this ViewModel 54 else -> -1 55 } 56 } 57 58 @RawRes 59 private fun getSideFpsAnimationAsset( 60 rotation: DisplayRotation, 61 isDeviceFolded: Boolean, 62 isInRearDisplayMode: Boolean, 63 ): Int = 64 when (rotation) { 65 DisplayRotation.ROTATION_90 -> 66 if (isInRearDisplayMode) { 67 R.raw.biometricprompt_rear_portrait_reverse_base 68 } else if (isDeviceFolded) { 69 R.raw.biometricprompt_folded_base_topleft 70 } else { 71 R.raw.biometricprompt_portrait_base_topleft 72 } 73 DisplayRotation.ROTATION_270 -> 74 if (isInRearDisplayMode) { 75 R.raw.biometricprompt_rear_portrait_base 76 } else if (isDeviceFolded) { 77 R.raw.biometricprompt_folded_base_bottomright 78 } else { 79 R.raw.biometricprompt_portrait_base_bottomright 80 } 81 else -> 82 if (isInRearDisplayMode) { 83 R.raw.biometricprompt_rear_landscape_base 84 } else if (isDeviceFolded) { 85 R.raw.biometricprompt_folded_base_default 86 } else { 87 R.raw.biometricprompt_landscape_base 88 } 89 } 90 91 /** Called on configuration changes */ 92 fun onConfigurationChanged(newConfig: Configuration) { 93 displayStateInteractor.onConfigurationChanged(newConfig) 94 } 95 } 96