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

Commit 75cc6c07 authored by Beverly Tai's avatar Beverly Tai Committed by Automerger Merge Worker
Browse files

Merge "On UDFPS auth success, fade out the dwell ripple" into tm-dev am: a545b2b7

parents 10c8b566 a545b2b7
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -652,7 +652,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
        // pre-emptively set to true to hide view
        // pre-emptively set to true to hide view
        mIsBouncerShowing = true;
        mIsBouncerShowing = true;
        if (mUdfpsSupported && mShowUnlockIcon && mAuthRippleController != null) {
        if (mUdfpsSupported && mShowUnlockIcon && mAuthRippleController != null) {
            mAuthRippleController.showRipple(FINGERPRINT);
            mAuthRippleController.showUnlockRipple(FINGERPRINT);
        }
        }
        updateVisibility();
        updateVisibility();
        if (mOnGestureDetectedRunnable != null) {
        if (mOnGestureDetectedRunnable != null) {
+26 −9
Original line number Original line Diff line number Diff line
@@ -52,7 +52,11 @@ import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Provider


/***
/***
 * Controls the ripple effect that shows when authentication is successful.
 * Controls two ripple effects:
 *   1. Unlocked ripple: shows when authentication is successful
 *   2. UDFPS dwell ripple: shows when the user has their finger down on the UDFPS area and reacts
 *   to errors and successes
 *
 * The ripple uses the accent color of the current theme.
 * The ripple uses the accent color of the current theme.
 */
 */
@CentralSurfacesScope
@CentralSurfacesScope
@@ -115,7 +119,7 @@ class AuthRippleController @Inject constructor(
        notificationShadeWindowController.setForcePluginOpen(false, this)
        notificationShadeWindowController.setForcePluginOpen(false, this)
    }
    }


    fun showRipple(biometricSourceType: BiometricSourceType?) {
    fun showUnlockRipple(biometricSourceType: BiometricSourceType?) {
        if (!(keyguardUpdateMonitor.isKeyguardVisible || keyguardUpdateMonitor.isDreaming) ||
        if (!(keyguardUpdateMonitor.isKeyguardVisible || keyguardUpdateMonitor.isDreaming) ||
            keyguardUpdateMonitor.userNeedsStrongAuth()) {
            keyguardUpdateMonitor.userNeedsStrongAuth()) {
            return
            return
@@ -252,11 +256,16 @@ class AuthRippleController @Inject constructor(
                biometricSourceType: BiometricSourceType?,
                biometricSourceType: BiometricSourceType?,
                isStrongBiometric: Boolean
                isStrongBiometric: Boolean
            ) {
            ) {
                showRipple(biometricSourceType)
                if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
                    mView.fadeDwellRipple()
                }
                showUnlockRipple(biometricSourceType)
            }
            }


        override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType?) {
        override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType?) {
            mView.retractRipple()
            if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
                mView.retractDwellRipple()
            }
        }
        }


        override fun onBiometricAcquired(
        override fun onBiometricAcquired(
@@ -264,8 +273,16 @@ class AuthRippleController @Inject constructor(
            acquireInfo: Int
            acquireInfo: Int
        ) {
        ) {
            if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
            if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
                    acquireInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_PARTIAL) {
                    BiometricFingerprintConstants.shouldTurnOffHbm(acquireInfo) &&
                mView.retractRipple()
                    acquireInfo != BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
                // received an 'acquiredBad' message, so immediately retract
                mView.retractDwellRipple()
            }
        }

        override fun onKeyguardBouncerChanged(bouncerIsOrWillBeShowing: Boolean) {
            if (bouncerIsOrWillBeShowing) {
                mView.fadeDwellRipple()
            }
            }
        }
        }
    }
    }
@@ -294,7 +311,7 @@ class AuthRippleController @Inject constructor(
            }
            }


            override fun onFingerUp() {
            override fun onFingerUp() {
                mView.retractRipple()
                mView.retractDwellRipple()
            }
            }
        }
        }


@@ -337,12 +354,12 @@ class AuthRippleController @Inject constructor(
                    "fingerprint" -> {
                    "fingerprint" -> {
                        updateSensorLocation()
                        updateSensorLocation()
                        pw.println("fingerprint ripple sensorLocation=$fingerprintSensorLocation")
                        pw.println("fingerprint ripple sensorLocation=$fingerprintSensorLocation")
                        showRipple(BiometricSourceType.FINGERPRINT)
                        showUnlockRipple(BiometricSourceType.FINGERPRINT)
                    }
                    }
                    "face" -> {
                    "face" -> {
                        updateSensorLocation()
                        updateSensorLocation()
                        pw.println("face ripple sensorLocation=$faceSensorLocation")
                        pw.println("face ripple sensorLocation=$faceSensorLocation")
                        showRipple(BiometricSourceType.FACE)
                        showUnlockRipple(BiometricSourceType.FACE)
                    }
                    }
                    "custom" -> {
                    "custom" -> {
                        if (args.size != 3 ||
                        if (args.size != 3 ||
+54 −14
Original line number Original line Diff line number Diff line
@@ -35,12 +35,13 @@ import com.android.systemui.statusbar.charging.RippleShader
private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f
private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f


/**
/**
 * Expanding ripple effect
 * Handles two ripple effects: dwell ripple and unlocked ripple
 * - startUnlockedRipple for the transition from biometric authentication success to showing
 * Dwell Ripple:
 * launcher.
 *     - startDwellRipple: dwell ripple expands outwards around the biometric area
 * - startDwellRipple for the ripple expansion out when the user has their finger down on the UDFPS
 *     - retractDwellRipple: retracts the dwell ripple to radius 0 to signal a failure
 * sensor area
 *     - fadeDwellRipple: fades the dwell ripple away to alpha 0
 * - retractRipple for the ripple animation inwards to signal a failure
 * Unlocked ripple:
 *     - startUnlockedRipple: ripple expands from biometric auth location to the edges of the screen
 */
 */
class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
    private val retractInterpolator = PathInterpolator(.05f, .93f, .1f, 1f)
    private val retractInterpolator = PathInterpolator(.05f, .93f, .1f, 1f)
@@ -52,6 +53,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
    private var drawRipple: Boolean = false
    private var drawRipple: Boolean = false


    private var lockScreenColorVal = Color.WHITE
    private var lockScreenColorVal = Color.WHITE
    private val fadeDuration = 83L
    private val retractDuration = 400L
    private val retractDuration = 400L
    private var alphaInDuration: Long = 0
    private var alphaInDuration: Long = 0
    private var unlockedRippleInProgress: Boolean = false
    private var unlockedRippleInProgress: Boolean = false
@@ -59,7 +61,8 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
    private val dwellPaint = Paint()
    private val dwellPaint = Paint()
    private val rippleShader = RippleShader()
    private val rippleShader = RippleShader()
    private val ripplePaint = Paint()
    private val ripplePaint = Paint()
    private var retractAnimator: Animator? = null
    private var fadeDwellAnimator: Animator? = null
    private var retractDwellAnimator: Animator? = null
    private var dwellPulseOutAnimator: Animator? = null
    private var dwellPulseOutAnimator: Animator? = null
    private var dwellRadius: Float = 0f
    private var dwellRadius: Float = 0f
        set(value) {
        set(value) {
@@ -112,15 +115,15 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
    }
    }


    /**
    /**
     * Animate ripple inwards back to radius 0
     * Animate dwell ripple inwards back to radius 0
     */
     */
    fun retractRipple() {
    fun retractDwellRipple() {
        if (retractAnimator?.isRunning == true) {
        if (retractDwellAnimator?.isRunning == true || fadeDwellAnimator?.isRunning == true) {
            return // let the animation finish
            return // let the animation finish
        }
        }


        if (dwellPulseOutAnimator?.isRunning == true) {
        if (dwellPulseOutAnimator?.isRunning == true) {
            val retractRippleAnimator = ValueAnimator.ofFloat(dwellShader.progress, 0f)
            val retractDwellRippleAnimator = ValueAnimator.ofFloat(dwellShader.progress, 0f)
                    .apply {
                    .apply {
                interpolator = retractInterpolator
                interpolator = retractInterpolator
                duration = retractDuration
                duration = retractDuration
@@ -145,8 +148,8 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
                }
                }
            }
            }


            retractAnimator = AnimatorSet().apply {
            retractDwellAnimator = AnimatorSet().apply {
                playTogether(retractRippleAnimator, retractAlphaAnimator)
                playTogether(retractDwellRippleAnimator, retractAlphaAnimator)
                addListener(object : AnimatorListenerAdapter() {
                addListener(object : AnimatorListenerAdapter() {
                    override fun onAnimationStart(animation: Animator?) {
                    override fun onAnimationStart(animation: Animator?) {
                        dwellPulseOutAnimator?.cancel()
                        dwellPulseOutAnimator?.cancel()
@@ -163,6 +166,42 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
        }
        }
    }
    }


    /**
     * Animate ripple fade to alpha=0
     */
    fun fadeDwellRipple() {
        if (fadeDwellAnimator?.isRunning == true) {
            return // let the animation finish
        }

        if (dwellPulseOutAnimator?.isRunning == true || retractDwellAnimator?.isRunning == true) {
            fadeDwellAnimator = ValueAnimator.ofInt(Color.alpha(dwellShader.color), 0).apply {
                interpolator = Interpolators.LINEAR
                duration = fadeDuration
                addUpdateListener { animator ->
                    dwellShader.color = ColorUtils.setAlphaComponent(
                            dwellShader.color,
                            animator.animatedValue as Int
                    )
                    invalidate()
                }
                addListener(object : AnimatorListenerAdapter() {
                    override fun onAnimationStart(animation: Animator?) {
                        retractDwellAnimator?.cancel()
                        dwellPulseOutAnimator?.cancel()
                        drawDwell = true
                    }

                    override fun onAnimationEnd(animation: Animator?) {
                        drawDwell = false
                        resetDwellAlpha()
                    }
                })
                start()
            }
        }
    }

    /**
    /**
     * Plays a ripple animation that grows to the dwellRadius with distortion.
     * Plays a ripple animation that grows to the dwellRadius with distortion.
     */
     */
@@ -205,7 +244,8 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
            )
            )
            addListener(object : AnimatorListenerAdapter() {
            addListener(object : AnimatorListenerAdapter() {
                override fun onAnimationStart(animation: Animator?) {
                override fun onAnimationStart(animation: Animator?) {
                    retractAnimator?.cancel()
                    retractDwellAnimator?.cancel()
                    fadeDwellAnimator?.cancel()
                    visibility = VISIBLE
                    visibility = VISIBLE
                    drawDwell = true
                    drawDwell = true
                }
                }
+1 −1
Original line number Original line Diff line number Diff line
@@ -299,7 +299,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
        `when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true)
        `when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true)
        `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
        `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)


        controller.showRipple(BiometricSourceType.FINGERPRINT)
        controller.showUnlockRipple(BiometricSourceType.FINGERPRINT)
        assertTrue("reveal didn't start on keyguardFadingAway",
        assertTrue("reveal didn't start on keyguardFadingAway",
            controller.startLightRevealScrimOnKeyguardFadingAway)
            controller.startLightRevealScrimOnKeyguardFadingAway)
        `when`(keyguardStateController.isKeyguardFadingAway).thenReturn(true)
        `when`(keyguardStateController.isKeyguardFadingAway).thenReturn(true)