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

Commit bfa81adf authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Fix unnecessary relaunches when unlocking with fingerprint sensor.

When the device is unlocked using the fingerprint sensor in an
orientation opposite to the lockscreen orientation, the app that
will be visible is first relaunched in the current lockscreen
orientation and then later relaunched in the correct orientation.
If the keygaurd is going away then:
- Don't let keyguard affect device orientation. We want to use the
orientation of the app that will be visible.
- Allow the rotation sensor to be enabled even though draw isn't
complete so window manager can get the updated or last rotation
reading.
- Don't clear the previous proposed sensor reading to allow
window manager to use the information to update the orientation as
needed vs. falling back to the previous orientation.

Change-Id: I8369723d6a77f2c602f1ef080371fa7cd9ee094e
Fixes: 38494778
Test: Launch an app that doesn't fix orientation like clock, hold
the device in landscape, press the power button, unlock the device
using the fingerprint sensor, and verify the the app isn't
relaunched.
parent 0b1b1c43
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -225,6 +225,9 @@ public abstract class WindowManagerInternal {
     */
    public abstract boolean isKeyguardLocked();

    /** @return {@code true} if the keyguard is going away. */
    public abstract boolean isKeyguardGoingAway();

    /**
     * Gets the frame of a window given its token.
     *
+7 −2
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ class KeyguardController {
        mKeyguardShowing = showing;
        dismissDockedStackIfNeeded();
        if (showing) {
            mKeyguardGoingAway = false;
            setKeyguardGoingAway(false);
            mDismissalRequested = false;
        }
        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
@@ -114,7 +114,7 @@ class KeyguardController {
        if (mKeyguardShowing) {
            mWindowManager.deferSurfaceLayout();
            try {
                mKeyguardGoingAway = true;
                setKeyguardGoingAway(true);
                mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
                        false /* alwaysKeepCurrent */, convertTransitFlags(flags),
                        false /* forceOverride */);
@@ -139,6 +139,11 @@ class KeyguardController {
        mWindowManager.dismissKeyguard(callback);
    }

    private void setKeyguardGoingAway(boolean keyguardGoingAway) {
        mKeyguardGoingAway = keyguardGoingAway;
        mWindowManager.setKeyguardGoingAway(keyguardGoingAway);
    }

    private void failCallback(IKeyguardDismissCallback callback) {
        try {
            callback.onDismissError();
+13 −5
Original line number Diff line number Diff line
@@ -60,7 +60,6 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_ST
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
@@ -1128,16 +1127,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                + ", mOrientationSensorEnabled=" + mOrientationSensorEnabled
                + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
                + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
        final boolean keyguardGoingAway = mWindowManagerInternal.isKeyguardGoingAway();

        boolean disable = true;
        // Note: We postpone the rotating of the screen until the keyguard as well as the
        // window manager have reported a draw complete.
        if (mScreenOnEarly && mAwake &&
                mKeyguardDrawComplete && mWindowManagerDrawComplete) {
        // window manager have reported a draw complete or the keyguard is going away in dismiss
        // mode.
        if (mScreenOnEarly && mAwake && ((mKeyguardDrawComplete && mWindowManagerDrawComplete)
                || keyguardGoingAway)) {
            if (needSensorRunningLp()) {
                disable = false;
                //enable listener if not already enabled
                if (!mOrientationSensorEnabled) {
                    mOrientationListener.enable();
                    // Don't clear the current sensor orientation if the keyguard is going away in
                    // dismiss mode. This allows window manager to use the last sensor reading to
                    // determine the orientation vs. falling back to the last known orientation if
                    // the sensor reading was cleared which can cause it to relaunch the app that
                    // will show in the wrong orientation first before correcting leading to app
                    // launch delays.
                    mOrientationListener.enable(!keyguardGoingAway /* clearCurrentRotation */);
                    if(localLOGV) Slog.v(TAG, "Enabling listeners");
                    mOrientationSensorEnabled = true;
                }
+39 −19
Original line number Diff line number Diff line
@@ -109,16 +109,30 @@ public abstract class WindowOrientationListener {
     * {@link #onProposedRotationChanged(int)} when the device orientation changes.
     */
    public void enable() {
        enable(true /* clearCurrentRotation */);
    }

    /**
     * Enables the WindowOrientationListener so it will monitor the sensor and call
     * {@link #onProposedRotationChanged(int)} when the device orientation changes.
     *
     * @param clearCurrentRotation True if the current proposed sensor rotation should be cleared as
     *                             part of the reset.
     */
    public void enable(boolean clearCurrentRotation) {
        synchronized (mLock) {
            if (mSensor == null) {
                Slog.w(TAG, "Cannot detect sensors. Not enabled");
                return;
            }
            if (mEnabled == false) {
            if (mEnabled) {
                return;
            }
            if (LOG) {
                    Slog.d(TAG, "WindowOrientationListener enabled");
                Slog.d(TAG, "WindowOrientationListener enabled clearCurrentRotation="
                        + clearCurrentRotation);
            }
                mOrientationJudge.resetLocked();
            mOrientationJudge.resetLocked(clearCurrentRotation);
            if (mSensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                mSensorManager.registerListener(
                        mOrientationJudge, mSensor, mRate, DEFAULT_BATCH_LATENCY, mHandler);
@@ -128,7 +142,6 @@ public abstract class WindowOrientationListener {
            mEnabled = true;
        }
    }
    }

    /**
     * Disables the WindowOrientationListener.
@@ -278,8 +291,11 @@ public abstract class WindowOrientationListener {
         * Resets the state of the judge.
         *
         * Should only be called when holding WindowOrientationListener lock.
         *
         * @param clearCurrentRotation True if the current proposed sensor rotation should be
         *                             cleared as part of the reset.
         */
        public abstract void resetLocked();
        public abstract void resetLocked(boolean clearCurrentRotation);

        /**
         * Dumps internal state of the orientation judge.
@@ -602,7 +618,7 @@ public abstract class WindowOrientationListener {
                    if (LOG) {
                        Slog.v(TAG, "Resetting orientation listener.");
                    }
                    resetLocked();
                    resetLocked(true /* clearCurrentRotation */);
                    skipSample = true;
                } else {
                    final float alpha = timeDeltaMS / (FILTER_TIME_CONSTANT_MS + timeDeltaMS);
@@ -778,9 +794,11 @@ public abstract class WindowOrientationListener {
        }

        @Override
        public void resetLocked() {
        public void resetLocked(boolean clearCurrentRotation) {
            mLastFilteredTimestampNanos = Long.MIN_VALUE;
            if (clearCurrentRotation) {
                mProposedRotation = -1;
            }
            mFlatTimestampNanos = Long.MIN_VALUE;
            mFlat = false;
            mSwingTimestampNanos = Long.MIN_VALUE;
@@ -1015,9 +1033,11 @@ public abstract class WindowOrientationListener {
        }

        @Override
        public void resetLocked() {
        public void resetLocked(boolean clearCurrentRotation) {
            if (clearCurrentRotation) {
                mProposedRotation = -1;
                mDesiredRotation = -1;
            }
            mTouching = false;
            mTouchEndedTimestampNanos = Long.MIN_VALUE;
            unscheduleRotationEvaluationLocked();
+6 −1
Original line number Diff line number Diff line
@@ -3492,10 +3492,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo

            if (win != null) {
                final int req = win.mAttrs.screenOrientation;
                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
                if (policy.isKeyguardHostWindow(win.mAttrs)) {
                    mLastKeyguardForcedOrientation = req;
                    if (mService.mKeyguardGoingAway) {
                        // Keyguard can't affect the orientation if it is going away...
                        mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
                        return SCREEN_ORIENTATION_UNSET;
                    }
                }
                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
                return (mLastWindowForcedOrientation = req);
            }

Loading