diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 8bfa4269af1cb..ef38e8962599f 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2190,6 +2190,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
mWmService.mDisplayManagerInternal.performTraversal(transaction);
+ if (shellTransitions) {
+ // Before setDisplayProjection is applied by the start transaction of transition,
+ // set the transform hint to avoid using surface in old rotation.
+ getPendingTransaction().setFixedTransformHint(mSurfaceControl, rotation);
+ // The sync transaction should already contains setDisplayProjection, so unset the
+ // hint to restore the natural state when the transaction is applied.
+ transaction.unsetFixedTransformHint(mSurfaceControl);
+ }
scheduleAnimation();
mWmService.mRotationWatcherController.dispatchDisplayRotationChange(mDisplayId, rotation);
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 54dfdd93b26c5..abc9f8a48584b 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -865,6 +865,13 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
if (c.getSnapshot() != null) {
t.reparent(c.getSnapshot(), null);
}
+ // The fixed transform hint was set in DisplayContent#applyRotation(). Make sure to
+ // clear the hint in case the start transaction is not applied.
+ if (c.hasFlags(FLAG_IS_DISPLAY) && c.getStartRotation() != c.getEndRotation()
+ && c.getContainer() != null) {
+ t.unsetFixedTransformHint(WindowContainer.fromBinder(c.getContainer().asBinder())
+ .asDisplayContent().mSurfaceControl);
+ }
}
for (int i = info.getRootCount() - 1; i >= 0; --i) {
final SurfaceControl leash = info.getRoot(i).getLeash();
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 8af037be8d06a..b0feefe2a3b03 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -823,6 +823,7 @@ class TransitionController {
// Can reset track-count now that everything is idle.
mTrackCount = 0;
validateStates();
+ mAtm.mWindowManager.onAnimationFinished();
}
}
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index fe7cd4a5edd95..37e5da5f5eaf6 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -79,6 +79,7 @@
android:turnScreenOn="true"
android:showWhenLocked="true" />
activity.setContentView(sv));
+ sv.getHolder().addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ }
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
+ int height) {
+ surfaceChangedCount.getAndIncrement();
+ Log.i("surfaceChanged", "width=" + width + " height=" + height
+ + " getTransformHint="
+ + sv.getViewRootImpl().getSurfaceControl().getTransformHint());
+ }
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ }
+ });
+ final int rotation = activity.getResources().getConfiguration()
+ .windowConfiguration.getRotation();
+ activity.setRequestedOrientation(activity.getResources().getConfiguration().orientation
+ == Configuration.ORIENTATION_PORTRAIT
+ ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ instrumentation.getUiAutomation().syncInputTransactions();
+ instrumentation.waitForIdleSync();
+ final int newRotation = activity.getResources().getConfiguration()
+ .windowConfiguration.getRotation();
+ final int count = surfaceChangedCount.get();
+ activity.finishAndRemoveTask();
+ // The first count is triggered from creation, so the target number is 2.
+ if (rotation != newRotation && count > 2) {
+ fail("More than once surfaceChanged for rotation change: " + count);
+ }
+ }
+
private SurfaceControl buildTestSurface() {
return new SurfaceControl.Builder()
.setContainerLayer()