Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +8 −1 Original line number Diff line number Diff line Loading @@ -77,6 +77,13 @@ object BiometricViewBinder { applicationScope: CoroutineScope, vibratorHelper: VibratorHelper, ): Spaghetti { /** * View is only set visible in BiometricViewSizeBinder once PromptSize is determined that * accounts for iconView size, to prevent prompt resizing being visible to the user. * * TODO(b/288175072): May be able to remove this once constraint layout is implemented */ view.visibility = View.INVISIBLE val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!! val textColorError = Loading @@ -102,7 +109,7 @@ object BiometricViewBinder { iconView, iconOverlayView, view.getUpdatedFingerprintAffordanceSize(), viewModel.iconViewModel viewModel ) val indicatorMessageView = view.requireViewById<TextView>(R.id.indicator) Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +18 −2 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import androidx.core.animation.addListener import androidx.core.view.doOnLayout import androidx.core.view.isGone import androidx.lifecycle.lifecycleScope import com.android.systemui.res.R import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.ui.BiometricPromptLayout Loading @@ -41,6 +40,8 @@ import com.android.systemui.biometrics.ui.viewmodel.isMedium import com.android.systemui.biometrics.ui.viewmodel.isNullOrNotSmall import com.android.systemui.biometrics.ui.viewmodel.isSmall import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch /** Helper for [BiometricViewBinder] to handle resize transitions. */ Loading Loading @@ -93,7 +94,20 @@ object BiometricViewSizeBinder { view.repeatWhenAttached { var currentSize: PromptSize? = null lifecycleScope.launch { viewModel.size.collect { size -> /** * View is only set visible in BiometricViewSizeBinder once PromptSize is * determined that accounts for iconView size, to prevent prompt resizing being * visible to the user. * * TODO(b/288175072): May be able to remove isIconViewLoaded once constraint * layout is implemented */ combine(viewModel.isIconViewLoaded, viewModel.size, ::Pair).collect { (isIconViewLoaded, size) -> if (!isIconViewLoaded) { return@collect } // prepare for animated size transitions for (v in viewsToHideWhenSmall) { v.showTextOrHide(forceHide = size.isSmall) Loading Loading @@ -198,6 +212,8 @@ object BiometricViewSizeBinder { } currentSize = size view.visibility = View.VISIBLE viewModel.setIsIconViewLoaded(false) notifyAccessibilityChanged() } } Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt +36 −14 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.airbnb.lottie.LottieAnimationView import com.android.settingslib.widget.LottieColorUtils import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel.AuthType import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.util.kotlin.Utils.Companion.toQuad import com.android.systemui.util.kotlin.Utils.Companion.toQuint Loading @@ -45,8 +46,9 @@ object PromptIconViewBinder { iconView: LottieAnimationView, iconOverlayView: LottieAnimationView, iconViewLayoutParamSizeOverride: Pair<Int, Int>?, viewModel: PromptIconViewModel promptViewModel: PromptViewModel ) { val viewModel = promptViewModel.iconViewModel iconView.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.onConfigurationChanged(iconView.context.resources.configuration) Loading @@ -71,25 +73,45 @@ object PromptIconViewBinder { } launch { var width: Int var height: Int viewModel.activeAuthType.collect { activeAuthType -> if (iconViewLayoutParamSizeOverride == null) { val width: Int val height: Int when (activeAuthType) { AuthType.Fingerprint, AuthType.Coex -> { width = viewModel.fingerprintIconWidth height = viewModel.fingerprintIconHeight /** * View is only set visible in BiometricViewSizeBinder once * PromptSize is determined that accounts for iconView size, to * prevent prompt resizing being visible to the user. * * TODO(b/288175072): May be able to remove this once constraint * layout is implemented */ iconView.removeAllLottieOnCompositionLoadedListener() iconView.addLottieOnCompositionLoadedListener { promptViewModel.setIsIconViewLoaded(true) } } AuthType.Face -> { width = viewModel.faceIconWidth height = viewModel.faceIconHeight /** * Set to true by default since face icon is a drawable, which * doesn't have a LottieOnCompositionLoadedListener equivalent. * * TODO(b/318569643): To be updated once face assets are updated * from drawables */ promptViewModel.setIsIconViewLoaded(true) } } if (iconViewLayoutParamSizeOverride == null) { iconView.layoutParams.width = width iconView.layoutParams.height = height iconOverlayView.layoutParams.width = width iconOverlayView.layoutParams.height = height } Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +22 −0 Original line number Diff line number Diff line Loading @@ -192,6 +192,28 @@ constructor( val iconViewModel: PromptIconViewModel = PromptIconViewModel(this, displayStateInteractor, promptSelectorInteractor) private val _isIconViewLoaded = MutableStateFlow(false) /** * For prompts with an iconView, false until the prompt's iconView animation has been loaded in * the view, otherwise true by default. Used for BiometricViewSizeBinder to wait for the icon * asset to be loaded before determining the prompt size. */ val isIconViewLoaded: Flow<Boolean> = combine(credentialKind, _isIconViewLoaded.asStateFlow()) { credentialKind, isIconViewLoaded -> if (credentialKind is PromptKind.Biometric) { isIconViewLoaded } else { true } } // Sets whether the prompt's iconView animation has been loaded in the view yet. fun setIsIconViewLoaded(iconViewLoaded: Boolean) { _isIconViewLoaded.value = iconViewLoaded } /** Padding for prompt UI elements */ val promptPadding: Flow<Rect> = combine(size, displayStateInteractor.currentRotation) { size, rotation -> Loading Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +8 −1 Original line number Diff line number Diff line Loading @@ -77,6 +77,13 @@ object BiometricViewBinder { applicationScope: CoroutineScope, vibratorHelper: VibratorHelper, ): Spaghetti { /** * View is only set visible in BiometricViewSizeBinder once PromptSize is determined that * accounts for iconView size, to prevent prompt resizing being visible to the user. * * TODO(b/288175072): May be able to remove this once constraint layout is implemented */ view.visibility = View.INVISIBLE val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!! val textColorError = Loading @@ -102,7 +109,7 @@ object BiometricViewBinder { iconView, iconOverlayView, view.getUpdatedFingerprintAffordanceSize(), viewModel.iconViewModel viewModel ) val indicatorMessageView = view.requireViewById<TextView>(R.id.indicator) Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +18 −2 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import androidx.core.animation.addListener import androidx.core.view.doOnLayout import androidx.core.view.isGone import androidx.lifecycle.lifecycleScope import com.android.systemui.res.R import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.ui.BiometricPromptLayout Loading @@ -41,6 +40,8 @@ import com.android.systemui.biometrics.ui.viewmodel.isMedium import com.android.systemui.biometrics.ui.viewmodel.isNullOrNotSmall import com.android.systemui.biometrics.ui.viewmodel.isSmall import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch /** Helper for [BiometricViewBinder] to handle resize transitions. */ Loading Loading @@ -93,7 +94,20 @@ object BiometricViewSizeBinder { view.repeatWhenAttached { var currentSize: PromptSize? = null lifecycleScope.launch { viewModel.size.collect { size -> /** * View is only set visible in BiometricViewSizeBinder once PromptSize is * determined that accounts for iconView size, to prevent prompt resizing being * visible to the user. * * TODO(b/288175072): May be able to remove isIconViewLoaded once constraint * layout is implemented */ combine(viewModel.isIconViewLoaded, viewModel.size, ::Pair).collect { (isIconViewLoaded, size) -> if (!isIconViewLoaded) { return@collect } // prepare for animated size transitions for (v in viewsToHideWhenSmall) { v.showTextOrHide(forceHide = size.isSmall) Loading Loading @@ -198,6 +212,8 @@ object BiometricViewSizeBinder { } currentSize = size view.visibility = View.VISIBLE viewModel.setIsIconViewLoaded(false) notifyAccessibilityChanged() } } Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt +36 −14 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.airbnb.lottie.LottieAnimationView import com.android.settingslib.widget.LottieColorUtils import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel.AuthType import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.util.kotlin.Utils.Companion.toQuad import com.android.systemui.util.kotlin.Utils.Companion.toQuint Loading @@ -45,8 +46,9 @@ object PromptIconViewBinder { iconView: LottieAnimationView, iconOverlayView: LottieAnimationView, iconViewLayoutParamSizeOverride: Pair<Int, Int>?, viewModel: PromptIconViewModel promptViewModel: PromptViewModel ) { val viewModel = promptViewModel.iconViewModel iconView.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.onConfigurationChanged(iconView.context.resources.configuration) Loading @@ -71,25 +73,45 @@ object PromptIconViewBinder { } launch { var width: Int var height: Int viewModel.activeAuthType.collect { activeAuthType -> if (iconViewLayoutParamSizeOverride == null) { val width: Int val height: Int when (activeAuthType) { AuthType.Fingerprint, AuthType.Coex -> { width = viewModel.fingerprintIconWidth height = viewModel.fingerprintIconHeight /** * View is only set visible in BiometricViewSizeBinder once * PromptSize is determined that accounts for iconView size, to * prevent prompt resizing being visible to the user. * * TODO(b/288175072): May be able to remove this once constraint * layout is implemented */ iconView.removeAllLottieOnCompositionLoadedListener() iconView.addLottieOnCompositionLoadedListener { promptViewModel.setIsIconViewLoaded(true) } } AuthType.Face -> { width = viewModel.faceIconWidth height = viewModel.faceIconHeight /** * Set to true by default since face icon is a drawable, which * doesn't have a LottieOnCompositionLoadedListener equivalent. * * TODO(b/318569643): To be updated once face assets are updated * from drawables */ promptViewModel.setIsIconViewLoaded(true) } } if (iconViewLayoutParamSizeOverride == null) { iconView.layoutParams.width = width iconView.layoutParams.height = height iconOverlayView.layoutParams.width = width iconOverlayView.layoutParams.height = height } Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +22 −0 Original line number Diff line number Diff line Loading @@ -192,6 +192,28 @@ constructor( val iconViewModel: PromptIconViewModel = PromptIconViewModel(this, displayStateInteractor, promptSelectorInteractor) private val _isIconViewLoaded = MutableStateFlow(false) /** * For prompts with an iconView, false until the prompt's iconView animation has been loaded in * the view, otherwise true by default. Used for BiometricViewSizeBinder to wait for the icon * asset to be loaded before determining the prompt size. */ val isIconViewLoaded: Flow<Boolean> = combine(credentialKind, _isIconViewLoaded.asStateFlow()) { credentialKind, isIconViewLoaded -> if (credentialKind is PromptKind.Biometric) { isIconViewLoaded } else { true } } // Sets whether the prompt's iconView animation has been loaded in the view yet. fun setIsIconViewLoaded(iconViewLoaded: Boolean) { _isIconViewLoaded.value = iconViewLoaded } /** Padding for prompt UI elements */ val promptPadding: Flow<Rect> = combine(size, displayStateInteractor.currentRotation) { size, rotation -> Loading