diff options
| author | 2020-12-03 21:18:04 +0800 | |
|---|---|---|
| committer | 2020-12-03 21:27:17 +0800 | |
| commit | 836c889e257e9f6cbfaa2327bfc16730d1fbac81 (patch) | |
| tree | d360e5f7ca100463c66e075b8ca0b0d10eaddc13 | |
| parent | 386bec73e4184820b421f03ce56929a3322cd8fc (diff) | |
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
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowState.java | 3 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java | 71 |
2 files changed, 47 insertions, 27 deletions
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index c318fad4d0a0..bc8699e2ee39 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -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 */); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 227eba2a041b..a57de094a210 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -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); - app.updateSurfacePosition(t); - - app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_90, true); - - assertTrue(app.mSeamlesslyRotated); - - // Verify we un-rotate the window state surface. - Matrix matrix = new Matrix(); - // Un-rotate 90 deg - matrix.setRotate(270); - // 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 Rect frame = app.getFrame(); + frame.set(10, 20, 60, 80); + app.updateSurfacePosition(t); + 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. + final Matrix matrix = new Matrix(); + // Un-rotate 90 deg. + matrix.setRotate(270); + // 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. + 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 |