diff options
4 files changed, 84 insertions, 17 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt index 90e4a3821634..7b8cb829e03f 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt @@ -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 = @@ -102,7 +109,7 @@ object BiometricViewBinder { iconView, iconOverlayView, view.getUpdatedFingerprintAffordanceSize(), - viewModel.iconViewModel + viewModel ) val indicatorMessageView = view.requireViewById<TextView>(R.id.indicator) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt index 7e16d1e1d668..1a7b6c974d0c 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt @@ -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 @@ -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. */ @@ -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) @@ -198,6 +212,8 @@ object BiometricViewSizeBinder { } currentSize = size + view.visibility = View.VISIBLE + viewModel.setIsIconViewLoaded(false) notifyAccessibilityChanged() } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt index 475ef18e5099..6e3bcf575072 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt @@ -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 @@ -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) @@ -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 - } - AuthType.Face -> { - width = viewModel.faceIconWidth - height = viewModel.faceIconHeight + 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 } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt index 6d0a58e202bd..d899827ebb2e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt @@ -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 -> |