diff options
| author | 2023-11-02 20:57:39 +0800 | |
|---|---|---|
| committer | 2023-11-02 22:02:26 +0800 | |
| commit | b64ae3f00dc2b038a56873ae2db2841703387991 (patch) | |
| tree | 06674b98a527cb19fabe29b7f3d49001cc85f897 | |
| parent | 488eb9856a19aa14faaaca1ae056d960531278d3 (diff) | |
Pause updating surface position while seamless rotating
Since shell transition doesn't use mPendingSeamlessRotate anymore,
it needs to check the equivalent state from AsyncRotationController
to have the same behavior as legacy transition.
If the device doesn't support HWC ScreenDecoration, it will have
non-fullscreen windows with non-zero position. Then it will hit
the case that the surface is un-rotated to previous rotation but
the position is changed to be in new rotation.
Fix: 308735235
Test: atest TransitionTests#testDisplayRotationChange
Test: Display cutout is not flickering when rotating 180 degree.
Change-Id: I6c88be283e7086d81531bc3f710e2714275129e2
3 files changed, 23 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java index b87e761e5795..68d13cd6789e 100644 --- a/services/core/java/com/android/server/wm/AsyncRotationController.java +++ b/services/core/java/com/android/server/wm/AsyncRotationController.java @@ -465,6 +465,12 @@ class AsyncRotationController extends FadeAnimationController implements Consume return op != null && op.mAction == Operation.ACTION_FADE; } + /** Returns {@code true} if the window is un-rotated to original rotation. */ + boolean hasSeamlessOperation(WindowToken token) { + final Operation op = mTargetWindowTokens.get(token); + return op != null && op.mAction == Operation.ACTION_SEAMLESS; + } + /** * Whether the insets animation leash should use previous position when running fade animation * or seamless transformation in a rotated display. diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index f14a6f912af1..1ff6796427b9 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5262,10 +5262,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mSurfacePosition.offset(mXOffset, mYOffset); } - // Freeze position while we're unrotated, so the surface remains at the position it was - // prior to the rotation. - if (!mSurfaceAnimator.hasLeash() && mPendingSeamlessRotate == null - && !mLastSurfacePosition.equals(mSurfacePosition)) { + final AsyncRotationController asyncRotationController = + mDisplayContent.getAsyncRotationController(); + if ((asyncRotationController != null + && asyncRotationController.hasSeamlessOperation(mToken)) + || mPendingSeamlessRotate != null) { + // Freeze position while un-rotating the window, so its surface remains at the position + // corresponding to the original rotation. + return; + } + + if (!mSurfaceAnimator.hasLeash() && !mLastSurfacePosition.equals(mSurfacePosition)) { final boolean frameSizeChanged = mWindowFrames.isFrameSizeChangeReported(); final boolean surfaceInsetsChanged = surfaceInsetsChanging(); final boolean surfaceSizeChanged = frameSizeChanged || surfaceInsetsChanged; diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java index 47730237f675..6c173ea5b3af 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java @@ -1115,6 +1115,12 @@ public class TransitionTests extends WindowTestsBase { assertFalse(asyncRotationController.handleFinishDrawing(statusBar, mMockT)); assertTrue(asyncRotationController.isTargetToken(statusBar.mToken)); + // Window surface position is frozen while seamless rotation state is active. + final Point prevPos = new Point(screenDecor.mLastSurfacePosition); + screenDecor.getFrame().left += 1; + screenDecor.updateSurfacePosition(mMockT); + assertEquals(prevPos, screenDecor.mLastSurfacePosition); + final SurfaceControl.Transaction startTransaction = mock(SurfaceControl.Transaction.class); final SurfaceControl.TransactionCommittedListener transactionCommittedListener = onRotationTransactionReady(player, startTransaction); |