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

Commit 6a8161b2 authored by Josh Tsuji's avatar Josh Tsuji
Browse files

Adds the screen off animation!

The way this works is essentially:
- We tell PowerManager we want to handle the screen off animation, like we do for the Lockscreen -> AOD transition
- KeyguardViewMediator holds off on showing the activity lock screen, so that the underlying activity remains visible during the animation
- The scrim animation plays normally, which results in the 'reveal' effect in reverse
- We force the AOD views to full dozing, so that we can simply translate them in after a delay once the scrim has un-revealed the screen contents

(demo video: https://drive.google.com/file/d/1cRjg22wpQuvn9FPugJSkIF-cEOfM2qXi/view?usp=sharing)

Test: unlock/lock with no security
Test: unlock/lock with PIN/password lock set
Test: same, with face auth
Test: use all security methods with/without notifications showing on lock screen
Bug: 169693662
Change-Id: Ied66f11fc9820f2810cf931b1960041218d60b63
parent cb27bd1a
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -43,12 +43,6 @@
                   android:visibility="invisible" />
    </com.android.systemui.statusbar.BackDropView>

    <com.android.systemui.statusbar.LightRevealScrim
        android:id="@+id/light_reveal_scrim"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />

    <com.android.systemui.statusbar.ScrimView
        android:id="@+id/scrim_behind"
        android:layout_width="match_parent"
@@ -57,6 +51,12 @@
        sysui:ignoreRightInset="true"
        />

    <com.android.systemui.statusbar.LightRevealScrim
            android:id="@+id/light_reveal_scrim"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />

    <include layout="@layout/status_bar_expanded"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
+36 −12
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.systemui.statusbar.notification.AnimatableProperty;
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.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.NotificationIconContainer;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -53,8 +54,9 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    private final ConfigurationController mConfigurationController;
    private final NotificationIconAreaController mNotificationIconAreaController;
    private final DozeParameters mDozeParameters;

    private boolean mKeyguardStatusViewAnimating;
    private boolean mKeyguardStatusViewVisibilityAnimating;
    private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;

    @Inject
@@ -65,7 +67,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
            KeyguardStateController keyguardStateController,
            KeyguardUpdateMonitor keyguardUpdateMonitor,
            ConfigurationController configurationController,
            NotificationIconAreaController notificationIconAreaController) {
            NotificationIconAreaController notificationIconAreaController,
            DozeParameters dozeParameters) {
        super(keyguardStatusView);
        mKeyguardSliceViewController = keyguardSliceViewController;
        mKeyguardClockSwitchController = keyguardClockSwitchController;
@@ -73,6 +76,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
        mConfigurationController = configurationController;
        mNotificationIconAreaController = notificationIconAreaController;
        mDozeParameters = dozeParameters;
    }

    @Override
@@ -140,7 +144,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
     * Set keyguard status view alpha.
     */
    public void setAlpha(float alpha) {
        if (!mKeyguardStatusViewAnimating) {
        if (!mKeyguardStatusViewVisibilityAnimating) {
            mView.setAlpha(alpha);
        }
    }
@@ -194,8 +198,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
     * Update position of the view with an optional animation
     */
    public void updatePosition(int x, int y, float scale, boolean animate) {
        // We animate the status view visible/invisible using Y translation, so don't change it
        // while the animation is running.
        if (!mKeyguardStatusViewVisibilityAnimating) {
            PropertyAnimator.setProperty(mView, AnimatableProperty.Y, y, CLOCK_ANIMATION_PROPERTIES,
                    animate);
        }

        if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
            // reset any prior movement
@@ -223,10 +231,10 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
            boolean goingToFullShade,
            int oldStatusBarState) {
        mView.animate().cancel();
        mKeyguardStatusViewAnimating = false;
        mKeyguardStatusViewVisibilityAnimating = false;
        if ((!keyguardFadingAway && oldStatusBarState == KEYGUARD
                && statusBarState != KEYGUARD) || goingToFullShade) {
            mKeyguardStatusViewAnimating = true;
            mKeyguardStatusViewVisibilityAnimating = true;
            mView.animate()
                    .alpha(0f)
                    .setStartDelay(0)
@@ -242,7 +250,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
            }
        } else if (oldStatusBarState == StatusBarState.SHADE_LOCKED && statusBarState == KEYGUARD) {
            mView.setVisibility(View.VISIBLE);
            mKeyguardStatusViewAnimating = true;
            mKeyguardStatusViewVisibilityAnimating = true;
            mView.setAlpha(0f);
            mView.animate()
                    .alpha(1f)
@@ -252,7 +260,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
                    .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable);
        } else if (statusBarState == KEYGUARD) {
            if (keyguardFadingAway) {
                mKeyguardStatusViewAnimating = true;
                mKeyguardStatusViewVisibilityAnimating = true;
                mView.animate()
                        .alpha(0)
                        .translationYBy(-getHeight() * 0.05f)
@@ -261,6 +269,22 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
                        .setStartDelay(0)
                        .withEndAction(mAnimateKeyguardStatusViewInvisibleEndRunnable)
                        .start();
            } else if (mDozeParameters.shouldControlUnlockedScreenOff()) {
                mKeyguardStatusViewVisibilityAnimating = true;

                mView.setVisibility(View.VISIBLE);
                mView.setAlpha(0f);

                float curTranslationY = mView.getTranslationY();
                mView.setTranslationY(curTranslationY - getHeight() * 0.1f);
                mView.animate()
                        .setStartDelay((int) (StackStateAnimator.ANIMATION_DURATION_WAKEUP * .6f))
                        .setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP)
                        .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                        .alpha(1f)
                        .translationY(curTranslationY)
                        .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable)
                        .start();
            } else {
                mView.setVisibility(View.VISIBLE);
                mView.setAlpha(1f);
@@ -367,17 +391,17 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
    };

    private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = () -> {
        mKeyguardStatusViewAnimating = false;
        mKeyguardStatusViewVisibilityAnimating = false;
        mView.setVisibility(View.INVISIBLE);
    };


    private final Runnable mAnimateKeyguardStatusViewGoneEndRunnable = () -> {
        mKeyguardStatusViewAnimating = false;
        mKeyguardStatusViewVisibilityAnimating = false;
        mView.setVisibility(View.GONE);
    };

    private final Runnable mAnimateKeyguardStatusViewVisibleEndRunnable = () -> {
        mKeyguardStatusViewAnimating = false;
        mKeyguardStatusViewVisibilityAnimating = false;
    };
}
+3 −1
Original line number Diff line number Diff line
@@ -96,7 +96,9 @@ public class DozeUi implements DozeMachine.Part {
     */
    private void updateAnimateScreenOff() {
        if (mCanAnimateTransition) {
            final boolean controlScreenOff = mDozeParameters.getAlwaysOn() && mKeyguardShowing
            final boolean controlScreenOff =
                    mDozeParameters.getAlwaysOn()
                    && (mKeyguardShowing || mDozeParameters.shouldControlUnlockedScreenOff())
                    && !mHost.isPowerSaveActive();
            mDozeParameters.setControlScreenOffAnimation(controlScreenOff);
            mHost.setAnimateScreenOff(controlScreenOff);
+35 −3
Original line number Diff line number Diff line
@@ -92,8 +92,10 @@ import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.dagger.KeyguardModule;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -147,7 +149,8 @@ import dagger.Lazy;
 * directly to the keyguard UI is posted to a {@link android.os.Handler} to ensure it is taken on the UI
 * thread of the keyguard.
 */
public class KeyguardViewMediator extends SystemUI implements Dumpable {
public class KeyguardViewMediator extends SystemUI implements Dumpable,
        StatusBarStateController.StateListener {
    private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
    private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000;

@@ -221,6 +224,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
    private boolean mBootSendUserPresent;
    private boolean mShuttingDown;
    private boolean mDozing;
    private boolean mAnimatingScreenOff;
    private final FalsingCollector mFalsingCollector;

    /** High level access to the power manager for WakeLocks */
@@ -707,6 +711,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
    };

    private DeviceConfigProxy mDeviceConfig;
    private DozeParameters mDozeParameters;

    /**
     * Injected constructor. See {@link KeyguardModule}.
@@ -723,7 +728,9 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
            TrustManager trustManager,
            DeviceConfigProxy deviceConfig,
            NavigationModeController navigationModeController,
            KeyguardDisplayManager keyguardDisplayManager) {
            KeyguardDisplayManager keyguardDisplayManager,
            DozeParameters dozeParameters,
            StatusBarStateController statusBarStateController) {
        super(context);
        mFalsingCollector = falsingCollector;
        mLockPatternUtils = lockPatternUtils;
@@ -749,6 +756,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
                QuickStepContract.isGesturalMode(navigationModeController.addListener(mode -> {
                    mInGestureNavigationMode = QuickStepContract.isGesturalMode(mode);
                }));
        mDozeParameters = dozeParameters;
        statusBarStateController.addCallback(this);
    }

    public void userActivity() {
@@ -929,6 +938,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
            mDeviceInteractive = false;
            mGoingToSleep = false;
            mWakeAndUnlocking = false;
            mAnimatingScreenOff = mDozeParameters.shouldControlUnlockedScreenOff();

            resetKeyguardDonePendingLocked();
            mHideAnimationRun = false;
@@ -1081,6 +1091,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
        // TODO: Rename all screen off/on references to interactive/sleeping
        synchronized (this) {
            mDeviceInteractive = true;
            mAnimatingScreenOff = false;
            cancelDoKeyguardLaterLocked();
            cancelDoKeyguardForChildProfilesLocked();
            if (DEBUG) Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence);
@@ -1294,6 +1305,10 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
        return mHiding;
    }

    public boolean isAnimatingScreenOff() {
        return mAnimatingScreenOff;
    }

    /**
     * Handles SET_OCCLUDED message sent by setOccluded()
     */
@@ -2266,6 +2281,16 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
        setShowingLocked(mShowing);
    }

    @Override
    public void onDozeAmountChanged(float linear, float interpolated) {
        // If we were animating the screen off, and we've completed the doze animation (doze amount
        // is 1f), then show the activity lock screen.
        if (mAnimatingScreenOff && mDozing && linear == 1f) {
            mAnimatingScreenOff = false;
            setShowingLocked(mShowing);
        }
    }

    /**
     * @param pulsing true when device temporarily wakes up to display an incoming notification.
     */
@@ -2296,9 +2321,16 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
        mAodShowing = aodShowing;
        if (notifyDefaultDisplayCallbacks) {
            notifyDefaultDisplayCallbacks(showing);

            if (!showing || !mAnimatingScreenOff) {
                // Update the activity lock screen state unless we're animating in the keyguard
                // for a screen off animation. In that case, we want the activity to remain visible
                // until the animation completes. setShowingLocked is called again when the
                // animation ends, so the activity lock screen will be shown at that time.
                updateActivityLockScreenState(showing, aodShowing);
            }
        }
    }

    private void notifyDefaultDisplayCallbacks(boolean showing) {
        // TODO(b/140053364)
+7 −2
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.DeviceConfigProxy;
@@ -82,7 +83,9 @@ public class KeyguardModule {
            @UiBackground Executor uiBgExecutor,
            DeviceConfigProxy deviceConfig,
            NavigationModeController navigationModeController,
            KeyguardDisplayManager keyguardDisplayManager) {
            KeyguardDisplayManager keyguardDisplayManager,
            DozeParameters dozeParameters,
            StatusBarStateController statusBarStateController) {
        return new KeyguardViewMediator(
                context,
                falsingCollector,
@@ -97,7 +100,9 @@ public class KeyguardModule {
                trustManager,
                deviceConfig,
                navigationModeController,
                keyguardDisplayManager
                keyguardDisplayManager,
                dozeParameters,
                statusBarStateController
        );
    }

Loading