Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e60e545 authored by Grace Cheng's avatar Grace Cheng Committed by Android (Google) Code Review
Browse files

Merge "Fix race condition between PromptIconViewBinder and BiometricSizeBinder" into main

parents d7b5b6ba 188b2bdd
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -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)
+18 −2
Original line number Diff line number Diff line
@@ -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()
                        }
                    }
+36 −14
Original line number Diff line number Diff line
@@ -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

                                /**
                                 * 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
                        }
+22 −0
Original line number Diff line number Diff line
@@ -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 ->