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
This commit is contained in:
@@ -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);
|
||||
|
||||
if (mAnimatingBetweenAodAndLockscreen) {
|
||||
mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);
|
||||
|
||||
mLockScreenFp.setTranslationX(mBurnInOffsetX);
|
||||
mLockScreenFp.setTranslationY(mBurnInOffsetY);
|
||||
mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
|
||||
mLockScreenFp.setAlpha(1f - mInterpolatedDarkAmount);
|
||||
} else {
|
||||
mBgProtection.setAlpha(0f);
|
||||
mLockScreenFp.setAlpha(0f);
|
||||
}
|
||||
|
||||
mAodFp.setTranslationX(mBurnInOffsetX);
|
||||
mAodFp.setTranslationY(mBurnInOffsetY);
|
||||
mAodFp.setProgress(mBurnInProgress);
|
||||
mAodFp.setAlpha(255 * mInterpolatedDarkAmount);
|
||||
|
||||
mLockScreenFp.setTranslationX(mBurnInOffsetX);
|
||||
mLockScreenFp.setTranslationY(mBurnInOffsetY);
|
||||
mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
|
||||
mLockScreenFp.setAlpha((1f - mInterpolatedDarkAmount) * 255);
|
||||
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) {
|
||||
mLockScreenFp.setAlpha(alpha / 255f);
|
||||
if (mInterpolatedDarkAmount != 0f) {
|
||||
mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);
|
||||
} else {
|
||||
if (mInterpolatedDarkAmount == 0f) {
|
||||
mLockScreenFp.setAlpha(alpha / 255f);
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user