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

Commit 99d2e63d authored by Beverly's avatar Beverly Committed by Beverly Tai
Browse files

Fade in the UDFPS icon from HOME => AOD

Animate the fade in on the first signal from onDozeAmountChanged
when the unlockedScreenOffAnimation is running.

Remove the callbacks from the UnlockedScreenOffAnimationController
progress which starts the animation much sooner than when the AOD
UI starts to come in. It was also causing a pulsing bug where
the UDFPS bouncer would be reset and be out of sync with the scrims.

Test: atest SystemUITest
Test: manually transition between the home screen
and the AOD screen with udfps enrolled
Test: manually transition between the lock screen
and AOD with udfps enrolled
Test: Tap on a pulsing notification in AOD when
udfps is enrolled
Fixes: 220219675

Change-Id: Idfe6144d1d46443db52583b165a836c69f17b259
parent d62c6e6c
Loading
Loading
Loading
Loading
+26 −20
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.StatusBarState;

import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.LottieProperty;
@@ -68,6 +67,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
    private float mBurnInOffsetY;
    private float mBurnInProgress;
    private float mInterpolatedDarkAmount;
    private boolean mAnimatingBetweenAodAndLockscreen; // As opposed to Unlocked => AOD
    private boolean mFullyInflated;

    public UdfpsKeyguardView(Context context, @Nullable AttributeSet attrs) {
@@ -114,23 +114,32 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
            return;
        }

        final float darkAmountForAnimation = mAnimatingBetweenAodAndLockscreen
                ? mInterpolatedDarkAmount : 1f /* animating from unlocked to AOD */;
        mBurnInOffsetX = MathUtils.lerp(0f,
            getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
                - mMaxBurnInOffsetX, mInterpolatedDarkAmount);
                - mMaxBurnInOffsetX, darkAmountForAnimation);
        mBurnInOffsetY = MathUtils.lerp(0f,
            getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
                - mMaxBurnInOffsetY, mInterpolatedDarkAmount);
        mBurnInProgress = MathUtils.lerp(0f, getBurnInProgressOffset(), mInterpolatedDarkAmount);
                - mMaxBurnInOffsetY, darkAmountForAnimation);
        mBurnInProgress = MathUtils.lerp(0f, getBurnInProgressOffset(), darkAmountForAnimation);

        mAodFp.setTranslationX(mBurnInOffsetX);
        mAodFp.setTranslationY(mBurnInOffsetY);
        mAodFp.setProgress(mBurnInProgress);
        mAodFp.setAlpha(255 * mInterpolatedDarkAmount);
        if (mAnimatingBetweenAodAndLockscreen) {
            mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);

            mLockScreenFp.setTranslationX(mBurnInOffsetX);
            mLockScreenFp.setTranslationY(mBurnInOffsetY);
            mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
        mLockScreenFp.setAlpha((1f - mInterpolatedDarkAmount) * 255);
            mLockScreenFp.setAlpha(1f - mInterpolatedDarkAmount);
        } else {
            mBgProtection.setAlpha(0f);
            mLockScreenFp.setAlpha(0f);
        }

        mAodFp.setTranslationX(mBurnInOffsetX);
        mAodFp.setTranslationY(mBurnInOffsetY);
        mAodFp.setProgress(mBurnInProgress);
        mAodFp.setAlpha(mInterpolatedDarkAmount);
    }

    void requestUdfps(boolean request, int color) {
@@ -171,15 +180,14 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
    protected int updateAlpha() {
        int alpha = super.updateAlpha();
        if (mFullyInflated) {
            if (mInterpolatedDarkAmount == 0f) {
                mLockScreenFp.setAlpha(alpha / 255f);
            if (mInterpolatedDarkAmount != 0f) {
                mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);
            } else {
                mBgProtection.setAlpha(alpha / 255f);
            } else {
                updateBurnInOffsets();
            }
        }


        return alpha;
    }

@@ -191,8 +199,10 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
        return mAlpha;
    }

    void onDozeAmountChanged(float linear, float eased) {
    void onDozeAmountChanged(float linear, float eased, boolean animatingBetweenAodAndLockscreen) {
        mAnimatingBetweenAodAndLockscreen = animatingBetweenAodAndLockscreen;
        mInterpolatedDarkAmount = eased;

        updateAlpha();
        updateBurnInOffsets();
    }
@@ -225,10 +235,6 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
        mBackgroundInAnimator.start();
    }

    private boolean isShadeLocked() {
        return mStatusBarState == StatusBarState.SHADE_LOCKED;
    }

    private final AsyncLayoutInflater.OnInflateFinishedListener mLayoutInflaterFinishListener =
            new AsyncLayoutInflater.OnInflateFinishedListener() {
        @Override
+37 −7
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.biometrics;

import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;

import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.content.res.Configuration;
import android.util.MathUtils;
@@ -30,6 +31,7 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.SystemUIDialogManager;
@@ -57,6 +59,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
    @NonNull private final UnlockedScreenOffAnimationController
            mUnlockedScreenOffAnimationController;
    @NonNull private final ActivityLaunchAnimator mActivityLaunchAnimator;
    private final ValueAnimator mUnlockedScreenOffDozeAnimator = ValueAnimator.ofFloat(0f, 1f);

    private boolean mShowingUdfpsBouncer;
    private boolean mUdfpsRequested;
@@ -105,6 +108,18 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
        mUdfpsController = udfpsController;
        mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
        mActivityLaunchAnimator = activityLaunchAnimator;

        mUnlockedScreenOffDozeAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
        mUnlockedScreenOffDozeAnimator.addUpdateListener(
                new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        mView.onDozeAmountChanged(
                                animation.getAnimatedFraction(),
                                (float) animation.getAnimatedValue(),
                                /* animatingBetweenAodAndLockScreen */ false);
                    }
                });
    }

    @Override
@@ -141,7 +156,6 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud

        mKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
        mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(this);
        mUnlockedScreenOffAnimationController.addCallback(mUnlockedScreenOffCallback);
        mActivityLaunchAnimator.addListener(mActivityLaunchAnimatorListener);
    }

@@ -159,7 +173,6 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
        if (mLockScreenShadeTransitionController.getUdfpsKeyguardViewController() == this) {
            mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(null);
        }
        mUnlockedScreenOffAnimationController.removeCallback(mUnlockedScreenOffCallback);
        mActivityLaunchAnimator.removeListener(mActivityLaunchAnimatorListener);
    }

@@ -177,6 +190,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
        pw.println("mUdfpsRequested=" + mUdfpsRequested);
        pw.println("mView.mUdfpsRequested=" + mView.mUdfpsRequested);
        pw.println("mLaunchTransitionFadingAway=" + mLaunchTransitionFadingAway);
        pw.println("mLastDozeAmount=" + mLastDozeAmount);
    }

    /**
@@ -237,7 +251,11 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
            return true;
        }

        if (mStatusBarState != KEYGUARD) {
        // Only pause auth if we're not on the keyguard AND we're not transitioning to doze
        // (ie: dozeAmount = 0f). For the UnlockedScreenOffAnimation, the statusBarState is
        // delayed. However, we still animate in the UDFPS affordance with the 
        // mUnlockedScreenOffDozeAnimator.
        if (mStatusBarState != KEYGUARD && mLastDozeAmount == 0f) {
            return true;
        }

@@ -292,6 +310,10 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
        updateAlpha();
    }

    /**
     * Update alpha for the UDFPS lock screen affordance. The AoD UDFPS visual affordance's
     * alpha is based on the doze amount.
     */
    private void updateAlpha() {
        // fade icon on transitions to showing the status bar, but if mUdfpsRequested, then
        // the keyguard is occluded by some application - so instead use the input bouncer
@@ -320,7 +342,18 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
            if (mLastDozeAmount < linear) {
                showUdfpsBouncer(false);
            }
            mView.onDozeAmountChanged(linear, eased);
            mUnlockedScreenOffDozeAnimator.cancel();
            final boolean animatingFromUnlockedScreenOff =
                    mUnlockedScreenOffAnimationController.isAnimationPlaying();
            if (animatingFromUnlockedScreenOff && linear != 0f) {
                // we manually animate the fade in of the UDFPS icon since the unlocked
                // screen off animation prevents the doze amounts to be incrementally eased in
                mUnlockedScreenOffDozeAnimator.start();
            } else {
                mView.onDozeAmountChanged(linear, eased,
                    /* animatingBetweenAodAndLockScreen */ true);
            }

            mLastDozeAmount = linear;
            updatePauseAuth();
        }
@@ -439,9 +472,6 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
                }
            };

    private final UnlockedScreenOffAnimationController.Callback mUnlockedScreenOffCallback =
            (linear, eased) -> mStateListener.onDozeAmountChanged(linear, eased);

    private final ActivityLaunchAnimator.Listener mActivityLaunchAnimatorListener =
            new ActivityLaunchAnimator.Listener() {
                @Override
+0 −23
Original line number Diff line number Diff line
@@ -67,7 +67,6 @@ class UnlockedScreenOffAnimationController @Inject constructor(
    private var shouldAnimateInKeyguard = false
    private var lightRevealAnimationPlaying = false
    private var aodUiAnimationPlaying = false
    private var callbacks = HashSet<Callback>()

    /**
     * The result of our decision whether to play the screen off animation in
@@ -81,9 +80,6 @@ class UnlockedScreenOffAnimationController @Inject constructor(
        interpolator = Interpolators.LINEAR
        addUpdateListener {
            lightRevealScrim.revealAmount = it.animatedValue as Float
            sendUnlockedScreenOffProgressUpdate(
                    1f - (it.animatedFraction as Float),
                    1f - (it.animatedValue as Float))
            if (lightRevealScrim.isScrimAlmostOccludes &&
                    interactionJankMonitor.isInstrumenting(CUJ_SCREEN_OFF)) {
                // ends the instrument when the scrim almost occludes the screen.
@@ -95,7 +91,6 @@ class UnlockedScreenOffAnimationController @Inject constructor(
            override fun onAnimationCancel(animation: Animator?) {
                lightRevealScrim.revealAmount = 1f
                lightRevealAnimationPlaying = false
                sendUnlockedScreenOffProgressUpdate(0f, 0f)
                interactionJankMonitor.cancel(CUJ_SCREEN_OFF)
            }

@@ -309,20 +304,6 @@ class UnlockedScreenOffAnimationController @Inject constructor(
    override fun shouldDelayDisplayDozeTransition(): Boolean =
        dozeParameters.get().shouldControlUnlockedScreenOff()

    fun addCallback(callback: Callback) {
        callbacks.add(callback)
    }

    fun removeCallback(callback: Callback) {
        callbacks.remove(callback)
    }

    private fun sendUnlockedScreenOffProgressUpdate(linear: Float, eased: Float) {
        callbacks.forEach {
            it.onUnlockedScreenOffProgressUpdate(linear, eased)
        }
    }

    /**
     * Whether we're doing the light reveal animation or we're done with that and animating in the
     * AOD UI.
@@ -356,8 +337,4 @@ class UnlockedScreenOffAnimationController @Inject constructor(
    fun isScreenOffLightRevealAnimationPlaying(): Boolean {
        return lightRevealAnimationPlaying
    }

    interface Callback {
        fun onUnlockedScreenOffProgressUpdate(linear: Float, eased: Float)
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -166,7 +166,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {

        mController.onViewAttached();
        verify(mView, atLeast(1)).setPauseAuth(true);
        verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount);
        verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount, true);
    }

    @Test
@@ -193,7 +193,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
        final float eased = .65f;
        mStatusBarStateListener.onDozeAmountChanged(linear, eased);

        verify(mView).onDozeAmountChanged(linear, eased);
        verify(mView).onDozeAmountChanged(linear, eased, true);
    }

    @Test