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

Commit a886be55 authored by Daniel Chapin's avatar Daniel Chapin Committed by Android (Google) Code Review
Browse files

Revert "Update face authenticating asset"

This reverts commit 5ea97062.

Reason for revert: Droidfood blocking bug: b/331920634

Change-Id: I8fce1b6f0e4d5d5e5835e20b91727796cb1bafd2
parent 5ea97062
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@

<resources>
    <!-- Dynamic colors-->
    <color name="settingslib_color_blue700">#0B57D0</color>
    <color name="settingslib_color_blue600">#1a73e8</color>
    <color name="settingslib_color_blue400">#669df6</color>
    <color name="settingslib_color_blue300">#8ab4f8</color>
+0 −3
Original line number Diff line number Diff line
@@ -55,9 +55,6 @@ public class LottieColorUtils {
        map.put(
                ".black",
                android.R.color.white);
        map.put(
                ".blue200",
                R.color.settingslib_color_blue700);
        map.put(
                ".blue400",
                R.color.settingslib_color_blue600);
+0 −1
Original line number Diff line number Diff line
{"v":"5.7.13","fr":60,"ip":0,"op":61,"w":64,"h":64,"nm":"face_scanning 3","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[32,32,0],"ix":2,"l":2},"a":{"a":0,"k":[27.25,27.25,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":30,"s":[95,95,100]},{"t":60,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.243],[-1.244,0],[0,1.243],[1.242,0]],"o":[[0,1.243],[1.242,0],[0,-1.243],[-1.244,0]],"v":[[-2.249,0.001],[0.001,2.251],[2.249,0.001],[0.001,-2.251]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[15.1,20.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.243],[-1.242,0],[0,1.243],[1.242,0]],"o":[[0,1.243],[1.242,0],[0,-1.243],[-1.242,0]],"v":[[-2.249,0],[0.001,2.25],[2.249,0],[0.001,-2.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[39.4,20.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.814,3.523],[-2.814,3.523],[-2.814,1.363],[0.652,1.363],[0.652,-3.523],[2.814,-3.523]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.791,28.479],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.154,0.15],[0,0],[0.117,-0.095],[0,0],[0.228,-0.121],[0.358,-0.103],[0.922,0.261],[0.3,0.16],[0.24,0.185],[0.14,0.139],[0.178,0.261],[0.143,0.451],[0,0],[0,0.494],[0,0],[-0.214,-0.676],[-0.392,-0.572],[-0.323,-0.317],[-0.228,-0.177],[-0.333,-0.179],[-0.503,-0.145],[-0.662,0],[-0.653,0.184],[-0.437,0.233],[-0.336,0.258],[0,0],[0,0]],"o":[[0,0],[-0.107,0.106],[0,0],[-0.24,0.185],[-0.301,0.16],[-0.92,0.261],[-0.357,-0.103],[-0.228,-0.121],[-0.158,-0.122],[-0.225,-0.221],[-0.272,-0.393],[0,0],[-0.147,-0.466],[0,0],[0,0.716],[0.206,0.656],[0.256,0.372],[0.204,0.201],[0.336,0.258],[0.436,0.233],[0.655,0.184],[0.662,0],[0.503,-0.145],[0.332,-0.179],[0,0],[0,0],[0.165,-0.136]],"v":[[6.094,1.465],[4.579,-0.076],[4.242,0.225],[4.124,0.315],[3.43,0.771],[2.439,1.165],[-0.342,1.165],[-1.331,0.771],[-2.027,0.315],[-2.48,-0.075],[-3.087,-0.801],[-3.712,-2.075],[-3.712,-2.075],[-3.934,-3.523],[-6.094,-3.523],[-5.771,-1.424],[-4.868,0.424],[-3.995,1.465],[-3.344,2.027],[-2.35,2.676],[-0.934,3.243],[1.049,3.523],[3.031,3.243],[4.449,2.676],[5.441,2.027],[5.482,1.997],[5.615,1.895]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[26.201,40.411],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.398,0],[0,-13.4],[13.398,0],[0,13.4]],"o":[[13.398,0],[0,13.4],[-13.398,0],[0,-13.4]],"v":[[0,-24.3],[24.3,0],[0,24.3],[-24.3,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[14.904,0],[0,-14.904],[-14.904,0],[0,14.904]],"o":[[-14.904,0],[0,14.904],[14.904,0],[0,-14.904]],"v":[[0,-27],[-27,0],[0,27],[27,0]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.25,27.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"bm":0}],"markers":[]}
 No newline at end of file
+53 −39
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@
package com.android.systemui.biometrics.ui.binder

import android.graphics.Rect
import android.graphics.drawable.Animatable2
import android.graphics.drawable.AnimatedVectorDrawable
import android.graphics.drawable.Drawable
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.Lifecycle
@@ -30,8 +32,8 @@ 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.res.R
import com.android.systemui.util.kotlin.Utils.Companion.toQuad
import com.android.systemui.util.kotlin.Utils.Companion.toQuint
import com.android.systemui.util.kotlin.Utils.Companion.toTriple
import com.android.systemui.util.kotlin.sample
import kotlinx.coroutines.flow.combine
@@ -61,11 +63,29 @@ object PromptIconViewBinder {

                    iconOverlayView.layoutParams.width = iconViewLayoutParamSizeOverride.first
                    iconOverlayView.layoutParams.height = iconViewLayoutParamSizeOverride.second
                } else {
                    iconView.layoutParams.width = viewModel.fingerprintIconWidth.first()
                    iconView.layoutParams.height = viewModel.fingerprintIconWidth.first()

                    iconOverlayView.layoutParams.width = viewModel.fingerprintIconWidth.first()
                    iconOverlayView.layoutParams.height = viewModel.fingerprintIconWidth.first()
                }

                var faceIcon: AnimatedVectorDrawable? = null
                val faceIconCallback =
                    object : Animatable2.AnimationCallback() {
                        override fun onAnimationStart(drawable: Drawable) {
                            viewModel.onAnimationStart()
                        }

                        override fun onAnimationEnd(drawable: Drawable) {
                            viewModel.onAnimationEnd()
                        }
                    }

                launch {
                    var width = 0
                    var height = 0
                    combine(promptViewModel.size, viewModel.activeAuthType, ::Pair).collect {
                        (_, activeAuthType) ->
                        // Every time after bp shows, [isIconViewLoaded] is set to false in
@@ -75,17 +95,6 @@ object PromptIconViewBinder {
                        when (activeAuthType) {
                            AuthType.Fingerprint,
                            AuthType.Coex -> {
                                if (iconViewLayoutParamSizeOverride == null) {
                                    iconView.layoutParams.width =
                                        viewModel.fingerprintIconWidth.first()
                                    iconView.layoutParams.height =
                                        viewModel.fingerprintIconHeight.first()

                                    iconOverlayView.layoutParams.width =
                                        viewModel.fingerprintIconWidth.first()
                                    iconOverlayView.layoutParams.height =
                                        viewModel.fingerprintIconHeight.first()
                                }
                                /**
                                 * View is only set visible in BiometricViewSizeBinder once
                                 * PromptSize is determined that accounts for iconView size, to
@@ -100,10 +109,8 @@ object PromptIconViewBinder {
                                }
                            }
                            AuthType.Face -> {
                                if (iconViewLayoutParamSizeOverride == null) {
                                    iconView.layoutParams.width = viewModel.faceIconWidth
                                    iconView.layoutParams.height = viewModel.faceIconHeight
                                }
                                width = viewModel.faceIconWidth
                                height = viewModel.faceIconHeight
                                /**
                                 * Set to true by default since face icon is a drawable, which
                                 * doesn't have a LottieOnCompositionLoadedListener equivalent.
@@ -114,6 +121,13 @@ object PromptIconViewBinder {
                                promptViewModel.setIsIconViewLoaded(true)
                            }
                        }

                        if (width != 0 && height != 0) {
                            iconView.layoutParams.width = width
                            iconView.layoutParams.height = height
                            iconOverlayView.layoutParams.width = width
                            iconOverlayView.layoutParams.height = height
                        }
                    }
                }

@@ -141,13 +155,19 @@ object PromptIconViewBinder {
                            combine(
                                viewModel.activeAuthType,
                                viewModel.shouldAnimateIconView,
                                viewModel.shouldRepeatAnimation,
                                viewModel.showingError,
                                ::Triple
                            ),
                                ::toQuad
                            ),
                            ::toQuint
                        )
                        .collect { (iconAsset, activeAuthType, shouldAnimateIconView, showingError)
                            ->
                        .collect {
                            (
                                iconAsset,
                                activeAuthType,
                                shouldAnimateIconView,
                                shouldRepeatAnimation,
                                showingError) ->
                            if (iconAsset != -1) {
                                when (activeAuthType) {
                                    AuthType.Fingerprint,
@@ -160,18 +180,10 @@ object PromptIconViewBinder {
                                        }
                                    }
                                    AuthType.Face -> {
                                        // TODO(b/318569643): Consolidate logic once all face auth
                                        // assets are migrated from drawable to json
                                        if (iconAsset == R.raw.face_dialog_authenticating) {
                                            iconView.setAnimation(iconAsset)
                                            iconView.frame = 0

                                            if (shouldAnimateIconView) {
                                                iconView.playAnimation()
                                                iconView.loop(true)
                                        faceIcon?.apply {
                                            unregisterAnimationCallback(faceIconCallback)
                                            stop()
                                        }
                                        } else {
                                            faceIcon?.apply { stop() }
                                        faceIcon =
                                            iconView.context.getDrawable(iconAsset)
                                                as AnimatedVectorDrawable
@@ -179,8 +191,10 @@ object PromptIconViewBinder {
                                            iconView.setImageDrawable(this)
                                            if (shouldAnimateIconView) {
                                                forceAnimationOnUI()
                                                    start()
                                                if (shouldRepeatAnimation) {
                                                    registerAnimationCallback(faceIconCallback)
                                                }
                                                start()
                                            }
                                        }
                                    }
+77 −19
Original line number Diff line number Diff line
@@ -31,10 +31,12 @@ import com.android.systemui.res.R
import com.android.systemui.util.kotlin.combine
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map

/**
 * Models UI of [BiometricPromptLayout.iconView] and [BiometricPromptLayout.biometric_icon_overlay]
@@ -55,8 +57,11 @@ constructor(
    }

    /**
     * Indicates what auth type the UI currently displays. Fingerprint-only auth -> Fingerprint
     * Face-only auth -> Face Co-ex auth, implicit flow -> Face Co-ex auth, explicit flow -> Coex
     * Indicates what auth type the UI currently displays.
     * Fingerprint-only auth -> Fingerprint
     * Face-only auth -> Face
     * Co-ex auth, implicit flow -> Face
     * Co-ex auth, explicit flow -> Coex
     */
    val activeAuthType: Flow<AuthType> =
        combine(
@@ -124,6 +129,35 @@ constructor(
        _previousIconOverlayWasError.value = previousIconOverlayWasError
    }

    /** Called when iconView begins animating. */
    fun onAnimationStart() {
        _animationEnded.value = false
    }

    /** Called when iconView ends animating. */
    fun onAnimationEnd() {
        _animationEnded.value = true
    }

    private val _animationEnded: MutableStateFlow<Boolean> = MutableStateFlow(false)

    /**
     * Whether a face iconView should pulse (i.e. while isAuthenticating and previous animation
     * ended).
     */
    val shouldPulseAnimation: Flow<Boolean> =
        combine(_animationEnded, promptViewModel.isAuthenticating) {
                animationEnded,
                isAuthenticating ->
                animationEnded && isAuthenticating
            }
            .distinctUntilChanged()

    private val _lastPulseLightToDark: MutableStateFlow<Boolean> = MutableStateFlow(false)

    /** Tracks whether a face iconView last pulsed light to dark (vs. dark to light) */
    val lastPulseLightToDark: Flow<Boolean> = _lastPulseLightToDark.asStateFlow()

    /** Layout params for fingerprint iconView */
    val fingerprintIconWidth: Flow<Int> = promptViewModel.fingerprintSensorDiameter
    val fingerprintIconHeight: Flow<Int> = promptViewModel.fingerprintSensorDiameter
@@ -165,6 +199,17 @@ constructor(
                        }
                    }
                AuthType.Face ->
                    shouldPulseAnimation.flatMapLatest { shouldPulseAnimation: Boolean ->
                        if (shouldPulseAnimation) {
                            val iconAsset =
                                if (_lastPulseLightToDark.value) {
                                    R.drawable.face_dialog_pulse_dark_to_light
                                } else {
                                    R.drawable.face_dialog_pulse_light_to_dark
                                }
                            _lastPulseLightToDark.value = !_lastPulseLightToDark.value
                            flowOf(iconAsset)
                        } else {
                            combine(
                                promptViewModel.isAuthenticated.distinctUntilChanged(),
                                promptViewModel.isAuthenticating.distinctUntilChanged(),
@@ -182,6 +227,8 @@ constructor(
                                    showingError
                                )
                            }
                        }
                    }
                AuthType.Coex ->
                    combine(
                        displayStateInteractor.currentRotation,
@@ -284,7 +331,8 @@ constructor(
        } else if (authState.isAuthenticated) {
            R.drawable.face_dialog_dark_to_checkmark
        } else if (isAuthenticating) {
            R.raw.face_dialog_authenticating
            _lastPulseLightToDark.value = false
            R.drawable.face_dialog_pulse_dark_to_light
        } else if (showingError) {
            R.drawable.face_dialog_dark_to_error
        } else if (_previousIconWasError.value) {
@@ -659,6 +707,16 @@ constructor(
            }
        }

    /** Whether the current BiometricPromptLayout.iconView asset animation should be repeated. */
    val shouldRepeatAnimation: Flow<Boolean> =
        activeAuthType.flatMapLatest { activeAuthType: AuthType ->
            when (activeAuthType) {
                AuthType.Fingerprint,
                AuthType.Coex -> flowOf(false)
                AuthType.Face -> promptViewModel.isAuthenticating.map { it }
            }
        }

    /** Called on configuration changes */
    fun onConfigurationChanged(newConfig: Configuration) {
        displayStateInteractor.onConfigurationChanged(newConfig)
Loading