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()