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

Commit 2a0284b1 authored by Bryce Lee's avatar Bryce Lee
Browse files

Use configuration delta to determine if still in orientation change.

We currently track this change in the WindowState with a variable
called mOrientationChanging. This value is set and cleared in a
variety of classes. It is possible for this value to be cleared
before processing an orientation changing frame. This can lead to us
prematurely unfreezing.

Since the orientation is present in the configuration, we can use the
orientation delta between the last and current frame's configuration
to determine whether we are in the middle of an orientation change.
The existing signal has been moved behind a setter/getter where the
latter is combined with the configuration state.

Bug: 62846907
Test: go/wm-smoke
Test: turn launcher rotation on, open dialer in portrait, turn off
      screen, rotate to landscape, unlock with fingerprint, press
      home while rotating. make sure layout is correct.

Change-Id: Ie0b78b76565125fd1cb036545cfb59f2a9075328
parent 96decad2
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1073,7 +1073,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            }
            if (w.mHasSurface && !rotateSeamlessly) {
                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Set mOrientationChanging of " + w);
                w.mOrientationChanging = true;
                w.setOrientationChanging(true);
                mService.mRoot.mOrientationChangeComplete = false;
                w.mLastFreezeDuration = 0;
            }
@@ -2679,10 +2679,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;

        forAllWindows(w -> {
            if (!w.mOrientationChanging) {
            if (!w.getOrientationChanging()) {
                return;
            }
            w.mOrientationChanging = false;
            w.setOrientationChanging(false);
            w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                    - mService.mDisplayFreezeTime);
            Slog.w(TAG_WM, "Force clearing orientation change: " + w);
+1 −1
Original line number Diff line number Diff line
@@ -5785,7 +5785,7 @@ public class WindowManagerService extends IWindowManager.Stub
        // orientation.
        if (!okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w);
            w.mOrientationChanging = true;
            w.setOrientationChanging(true);
            w.mLastFreezeDuration = 0;
            mRoot.mOrientationChangeComplete = false;
            if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
+28 −8
Original line number Diff line number Diff line
@@ -441,7 +441,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
     * Set when the orientation is changing and this window has not yet
     * been updated for the new orientation.
     */
    boolean mOrientationChanging;
    private boolean mOrientationChanging;

    /**
     * The orientation during the last visible call to relayout. If our
@@ -1156,7 +1156,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            // then we need to hold off on unfreezing the display until this window has been
            // redrawn; to do that, we need to go through the process of getting informed by the
            // application when it has finished drawing.
            if (mOrientationChanging || dragResizingChanged || isResizedWhileNotDragResizing()) {
            if (getOrientationChanging() || dragResizingChanged
                    || isResizedWhileNotDragResizing()) {
                if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
                    Slog.v(TAG_WM, "Orientation or resize start waiting for draw"
                            + ", mDrawState=DRAW_PENDING in " + this
@@ -1171,17 +1172,33 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG_WM, "Resizing window " + this);
                mService.mResizingWindows.add(this);
            }
        } else if (mOrientationChanging) {
        } else if (getOrientationChanging()) {
            if (isDrawnLw()) {
                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Orientation not waiting for draw in "
                        + this + ", surfaceController " + winAnimator.mSurfaceController);
                mOrientationChanging = false;
                setOrientationChanging(false);
                mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                        - mService.mDisplayFreezeTime);
            }
        }
    }

    boolean getOrientationChanging() {
        // In addition to the local state flag, we must also consider the difference in the last
        // reported configuration vs. the current state. If the client code has not been informed of
        // the change, logic dependent on having finished processing the orientation, such as
        // unfreezing, could be improperly triggered.
        // TODO(b/62846907): Checking against {@link mLastReportedConfiguration} could be flaky as
        //                   this is not necessarily what the client has processed yet. Find a
        //                   better indicator consistent with the client.
        return mOrientationChanging
                || getConfiguration().orientation != mLastReportedConfiguration.orientation;
    }

    void setOrientationChanging(boolean changing) {
        mOrientationChanging = changing;
    }

    DisplayContent getDisplayContent() {
        return mToken.getDisplayContent();
    }
@@ -2635,10 +2652,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

        mAppFreezing = false;

        if (mHasSurface && !mOrientationChanging
        if (mHasSurface && !getOrientationChanging()
                && mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + this);
            mOrientationChanging = true;
            setOrientationChanging(true);
            mService.mRoot.mOrientationChangeComplete = false;
        }
        mLastFreezeDuration = 0;
@@ -3057,7 +3074,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            mWinAnimator.mSurfaceResized = false;
            mReportOrientationChanged = false;
        } catch (RemoteException e) {
            mOrientationChanging = false;
            setOrientationChanging(false);
            mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                    - mService.mDisplayFreezeTime);
            // We are assuming the hosting process is dead or in a zombie state.
@@ -3416,10 +3433,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                    pw.print(" mDestroying="); pw.print(mDestroying);
                    pw.print(" mRemoved="); pw.println(mRemoved);
        }
        if (mOrientationChanging || mAppFreezing || mTurnOnScreen
        if (getOrientationChanging() || mAppFreezing || mTurnOnScreen
                || mReportOrientationChanged) {
            pw.print(prefix); pw.print("mOrientationChanging=");
                    pw.print(mOrientationChanging);
                    pw.print(" configOrientationChanging=");
                    pw.print(mLastReportedConfiguration.orientation
                            != getConfiguration().orientation);
                    pw.print(" mAppFreezing="); pw.print(mAppFreezing);
                    pw.print(" mTurnOnScreen="); pw.print(mTurnOnScreen);
                    pw.print(" mReportOrientationChanged="); pw.println(mReportOrientationChanged);
+7 −7
Original line number Diff line number Diff line
@@ -1527,11 +1527,11 @@ class WindowStateAnimator {

            // There is no need to wait for an animation change if our window is gone for layout
            // already as we'll never be visible.
            if (w.mOrientationChanging && w.isGoneForLayoutLw()) {
            if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
                if (DEBUG_ORIENTATION) {
                    Slog.v(TAG, "Orientation change skips hidden " + w);
                }
                w.mOrientationChanging = false;
                w.setOrientationChanging(false);
            }
            return;
        }
@@ -1564,8 +1564,8 @@ class WindowStateAnimator {
            // really hidden (gone for layout), there is no point in still waiting for it.
            // Note that this does introduce a potential glitch if the window becomes unhidden
            // before it has drawn for the new orientation.
            if (w.mOrientationChanging && w.isGoneForLayoutLw()) {
                w.mOrientationChanging = false;
            if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
                w.setOrientationChanging(false);
                if (DEBUG_ORIENTATION) Slog.v(TAG,
                        "Orientation change skips hidden " + w);
            }
@@ -1618,7 +1618,7 @@ class WindowStateAnimator {
                    mAnimator.setPendingLayoutChanges(w.getDisplayId(),
                            WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
                } else {
                    w.mOrientationChanging = false;
                    w.setOrientationChanging(false);
                }
            }
            if (hasSurface()) {
@@ -1631,14 +1631,14 @@ class WindowStateAnimator {
            displayed = true;
        }

        if (w.mOrientationChanging) {
        if (w.getOrientationChanging()) {
            if (!w.isDrawnLw()) {
                mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
                mAnimator.mLastWindowFreezeSource = w;
                if (DEBUG_ORIENTATION) Slog.v(TAG,
                        "Orientation continue waiting for draw in " + w);
            } else {
                w.mOrientationChanging = false;
                w.setOrientationChanging(false);
                if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
            }
        }