summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2023-11-02 20:57:39 +0800
committer Riddle Hsu <riddlehsu@google.com> 2023-11-02 22:02:26 +0800
commitb64ae3f00dc2b038a56873ae2db2841703387991 (patch)
tree06674b98a527cb19fabe29b7f3d49001cc85f897
parent488eb9856a19aa14faaaca1ae056d960531278d3 (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
-rw-r--r--services/core/java/com/android/server/wm/AsyncRotationController.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java15
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java6
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);