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

Commit 836c889e authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Update last surface position before unrotating

Because the surface position will be set to the unrotated position
according to the last surface position, that also means the current
position is applied. Otherwise the reference position for seamless
rotator may be zero.

This also fixes testSeamlesslyRotateWindow didn't verify the exact
rotated position because WindowState#updateSurfacePosition was
changed to check isGoneForLayout.

Fixes: 174666072
Test: WindowStateTests#testSeamlesslyRotateWindow
Change-Id: I99105fcda9b2252a3a9fb50c10b9cba1a4f732f1
parent 386bec73
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -770,6 +770,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            }
            mPendingSeamlessRotate = new SeamlessRotator(oldRotation, rotation, getDisplayInfo(),
                    false /* applyFixedTransformationHint */);
            // The surface position is going to be unrotated according to the last position.
            // Make sure the source position is up-to-date.
            mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y);
            mPendingSeamlessRotate.unrotate(transaction, this);
            getDisplayContent().getDisplayRotation().markForSeamlessRotation(this,
                    true /* seamlesslyRotated */);
+44 −27
Original line number Diff line number Diff line
@@ -19,9 +19,10 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -480,33 +481,49 @@ public class WindowStateTests extends WindowTestsBase {
        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
        final SurfaceControl.Transaction t = spy(StubTransaction.class);

        app.mHasSurface = true;
        makeWindowVisible(app);
        app.mSurfaceControl = mock(SurfaceControl.class);
        try {
            app.getFrame().set(10, 20, 60, 80);
        final Rect frame = app.getFrame();
        frame.set(10, 20, 60, 80);
        app.updateSurfacePosition(t);

            app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_90, true);

        assertTrue(app.mLastSurfacePosition.equals(frame.left, frame.top));
        app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_90, true /* requested */);
        assertTrue(app.mSeamlesslyRotated);

        // Verify we un-rotate the window state surface.
            Matrix matrix = new Matrix();
            // Un-rotate 90 deg
        final Matrix matrix = new Matrix();
        // Un-rotate 90 deg.
        matrix.setRotate(270);
            // Translate it back to origin
        // Translate it back to origin.
        matrix.postTranslate(0, mDisplayInfo.logicalWidth);
        verify(t).setMatrix(eq(app.mSurfaceControl), eq(matrix), any(float[].class));

        // Verify we update the position as well.
            float[] currentSurfacePos = {app.mLastSurfacePosition.x, app.mLastSurfacePosition.y};
            matrix.mapPoints(currentSurfacePos);
            verify(t).setPosition(eq(app.mSurfaceControl), eq(currentSurfacePos[0]),
                    eq(currentSurfacePos[1]));
        } finally {
            app.mSurfaceControl = null;
            app.mHasSurface = false;
        }
        final float[] curSurfacePos = {app.mLastSurfacePosition.x, app.mLastSurfacePosition.y};
        matrix.mapPoints(curSurfacePos);
        verify(t).setPosition(eq(app.mSurfaceControl), eq(curSurfacePos[0]), eq(curSurfacePos[1]));

        app.finishSeamlessRotation(false /* timeout */);
        assertFalse(app.mSeamlesslyRotated);
        assertNull(app.mPendingSeamlessRotate);

        // Simulate the case with deferred layout and animation.
        app.resetSurfacePositionForAnimationLeash(t);
        clearInvocations(t);
        mWm.mWindowPlacerLocked.deferLayout();
        app.updateSurfacePosition(t);
        // Because layout is deferred, the position should keep the reset value.
        assertTrue(app.mLastSurfacePosition.equals(0, 0));

        app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_270, true /* requested */);
        // The last position must be updated so the surface can be unrotated properly.
        assertTrue(app.mLastSurfacePosition.equals(frame.left, frame.top));
        matrix.setRotate(90);
        matrix.postTranslate(mDisplayInfo.logicalHeight, 0);
        curSurfacePos[0] = frame.left;
        curSurfacePos[1] = frame.top;
        matrix.mapPoints(curSurfacePos);
        verify(t).setPosition(eq(app.mSurfaceControl), eq(curSurfacePos[0]), eq(curSurfacePos[1]));
    }

    @Test