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

Commit ee89a547 authored by Josh Tsuji's avatar Josh Tsuji
Browse files

Adds the ScreenOffAnimationController, which fixes multiple issues with unlocked screen off.

This changes the screen off animation so that the controller directly animates the LightRevealScrim and the shade keyguard UI, rather then tying these to the dozeAmount. This makes it easier for us to manage/cancel these animations, such as during the camera launch gesture, since the various doze components update their state asynchronously.

This approach also means that instead of actually changing everything to KEYGUARD as soon as the power button is pressed, we actually just show the LightRevealScrim and the shade's AOD UI. This results in far less jank. We then actually show the keyguard once the animation finishes or is cancelled.

Bug: 169693662
Bug: 169739682
Bug: 181020504
Fixes: 185567665
Fixes: 189342687
Fixes: 185567665
Fixes: 183195436
Test: atest SystemUITests
Test: trigger screen off and cancel it
Test: trigger screen off and don't cancel it, make sure it wakes up fine
Test: disable 'power button locks instantly' and make sure it doesn't lock the device, both when the animation finishes or when it's cancelled
Test: press the power button twice in rapid succession
Test: press the power button twice in slower succession about 200ms apart (which triggers the camera onWakingUp vs onFinishedGoingToSleep)
Test: press the power button 5 times, make sure emergency gesture comes up
Test: disable AOD, observe no screen off animation and lock functionality works
Change-Id: I1c44304becdadfd37bab7fd81286a9702e5d6141
parent 018e1142
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -63,8 +63,10 @@ oneway interface IKeyguardService {

     * @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the reason we're waking up,
     * such as WAKE_REASON_POWER_BUTTON or WAKE_REASON_GESTURE.
     * @param cameraGestureTriggered Whether we're waking up due to a power button double tap
     * gesture.
     */
    void onStartedWakingUp(int pmWakeReason);
    void onStartedWakingUp(int pmWakeReason,  boolean cameraGestureTriggered);

    /**
     * Called when the device has finished waking up.
+21 −18
Original line number Diff line number Diff line
@@ -107,6 +107,21 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
        }
    };

    private final StatusBarStateController.StateListener mStatusBarStatePersistentListener =
            new StatusBarStateController.StateListener() {
                @Override
                public void onDozeAmountChanged(float linear, float eased) {
                    boolean noAnimation = (mDozeAmount == 0f && linear == 1f)
                            || (mDozeAmount == 1f && linear == 0f);
                    boolean isDozing = linear > mDozeAmount;
                    mDozeAmount = linear;
                    if (mIsDozing != isDozing) {
                        mIsDozing = isDozing;
                        mView.animateDoze(mIsDozing, !noAnimation);
                    }
                }
            };

    private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
            new KeyguardUpdateMonitorCallback() {
        @Override
@@ -133,14 +148,15 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
        updateLocale();
        mBroadcastDispatcher.registerReceiver(mLocaleBroadcastReceiver,
                new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
        mStatusBarStateController.addCallback(mStatusBarStateListener);

        mIsDozing = mStatusBarStateController.isDozing();
        mDozeAmount = mStatusBarStateController.getDozeAmount();
        mBatteryController.addCallback(mBatteryCallback);
        mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
        mKeyguardShowing = true;

        mStatusBarStateController.removeCallback(mStatusBarStatePersistentListener);
        mStatusBarStateController.addCallback(mStatusBarStatePersistentListener);

        refreshTime();
        initColors();
        mView.animateDoze(mIsDozing, false);
@@ -149,9 +165,11 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
    @Override
    protected void onViewDetached() {
        mBroadcastDispatcher.unregisterReceiver(mLocaleBroadcastReceiver);
        mStatusBarStateController.removeCallback(mStatusBarStateListener);
        mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
        mBatteryController.removeCallback(mBatteryCallback);
        if (!mView.isAttachedToWindow()) {
            mStatusBarStateController.removeCallback(mStatusBarStatePersistentListener);
        }
    }

    /** Animate the clock appearance */
@@ -199,19 +217,4 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
        mView.setColors(mDozingColor, mLockScreenColor);
        mView.animateDoze(mIsDozing, false);
    }

    private final StatusBarStateController.StateListener mStatusBarStateListener =
            new StatusBarStateController.StateListener() {
                @Override
                public void onDozeAmountChanged(float linear, float eased) {
                    boolean noAnimation = (mDozeAmount == 0f && linear == 1f)
                            || (mDozeAmount == 1f && linear == 0f);
                    boolean isDozing = linear > mDozeAmount;
                    mDozeAmount = linear;
                    if (mIsDozing != isDozing) {
                        mIsDozing = isDozing;
                        mView.animateDoze(mIsDozing, !noAnimation);
                    }
                }
            };
}
+4 −9
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ViewController;
@@ -66,7 +67,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
            ConfigurationController configurationController,
            DozeParameters dozeParameters,
            KeyguardUnlockAnimationController keyguardUnlockAnimationController,
            SmartspaceTransitionController smartspaceTransitionController) {
            SmartspaceTransitionController smartspaceTransitionController,
            UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
        super(keyguardStatusView);
        mKeyguardSliceViewController = keyguardSliceViewController;
        mKeyguardClockSwitchController = keyguardClockSwitchController;
@@ -75,7 +77,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
        mDozeParameters = dozeParameters;
        mKeyguardStateController = keyguardStateController;
        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
                dozeParameters);
                dozeParameters, unlockedScreenOffAnimationController);
        mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
        mSmartspaceTransitionController = smartspaceTransitionController;

@@ -237,13 +239,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
                animate);
    }

    /**
     * @return {@code true} if we are currently animating the screen off from unlock
     */
    public boolean isAnimatingScreenOffFromUnlocked() {
        return mKeyguardVisibilityHelper.isAnimatingScreenOffFromUnlocked();
    }

    /**
     * Set the visibility of the keyguard status view based on some new state.
     */
+13 −35
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;

/**
@@ -38,16 +39,19 @@ public class KeyguardVisibilityHelper {
    private View mView;
    private final KeyguardStateController mKeyguardStateController;
    private final DozeParameters mDozeParameters;
    private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
    private boolean mKeyguardViewVisibilityAnimating;
    private boolean mLastOccludedState = false;
    private boolean mAnimatingScreenOff;
    private final AnimationProperties mAnimationProperties = new AnimationProperties();

    public KeyguardVisibilityHelper(View view, KeyguardStateController keyguardStateController,
            DozeParameters dozeParameters) {
    public KeyguardVisibilityHelper(View view,
            KeyguardStateController keyguardStateController,
            DozeParameters dozeParameters,
            UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
        mView = view;
        mKeyguardStateController = keyguardStateController;
        mDozeParameters = dozeParameters;
        mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
    }

    public boolean isVisibilityAnimating() {
@@ -122,32 +126,14 @@ public class KeyguardVisibilityHelper {
                        .alpha(1f)
                        .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable)
                        .start();
            } else if (mDozeParameters.shouldControlUnlockedScreenOff()) {
            } else if (mUnlockedScreenOffAnimationController
                        .isScreenOffLightRevealAnimationPlaying()) {
                mKeyguardViewVisibilityAnimating = true;
                mAnimatingScreenOff = true;

                mView.setVisibility(View.VISIBLE);
                mView.setAlpha(0f);
                float currentY = mView.getY();
                mView.setY(currentY - mView.getHeight() * 0.1f);
                int duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
                int delay = (int) (duration * .6f);
                // We animate the Y properly separately using the PropertyAnimator, as the panel
                // view als needs to update the end position.
                mAnimationProperties.setDuration(duration).setDelay(delay);
                PropertyAnimator.cancelAnimation(mView, AnimatableProperty.Y);
                PropertyAnimator.setProperty(mView, AnimatableProperty.Y, currentY,
                        mAnimationProperties,
                        true /* animate */);

                mView.animate()
                        .setStartDelay(delay)
                        .setDuration(duration)
                        .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                        .alpha(1f)
                        .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable)
                        .start();

                // Ask the screen off animation controller to animate the keyguard visibility for us
                // since it may need to be cancelled due to keyguard lifecycle events.
                mUnlockedScreenOffAnimationController.animateInKeyguard(
                        mView, mAnimateKeyguardStatusViewVisibleEndRunnable);
            } else {
                mView.setVisibility(View.VISIBLE);
                mView.setAlpha(1f);
@@ -172,13 +158,5 @@ public class KeyguardVisibilityHelper {

    private final Runnable mAnimateKeyguardStatusViewVisibleEndRunnable = () -> {
        mKeyguardViewVisibilityAnimating = false;
        mAnimatingScreenOff = false;
    };

    /**
     * @return {@code true} if we are currently animating the screen off from unlock
     */
    public boolean isAnimatingScreenOffFromUnlocked() {
        return mAnimatingScreenOff;
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -232,10 +232,11 @@ public class KeyguardService extends Service {
        }

        @Override // Binder interface
        public void onStartedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
        public void onStartedWakingUp(
                @PowerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered) {
            Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp");
            checkPermission();
            mKeyguardViewMediator.onStartedWakingUp();
            mKeyguardViewMediator.onStartedWakingUp(cameraGestureTriggered);
            mKeyguardLifecyclesDispatcher.dispatch(
                    KeyguardLifecyclesDispatcher.STARTED_WAKING_UP, pmWakeReason);
            Trace.endSection();
Loading