diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 00c6f3a65d09a..6d53786ddf414 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -7677,12 +7677,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } win.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets); - if (isFixedRotationTransforming()) { - // This activity has been rotated but the display is still in old rotation. Because the - // animation applies in display space coordinates, the rotated animation frames need to - // be unrotated to avoid being cropped. - unrotateAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets); - } } void setPictureInPictureParams(PictureInPictureParams p) { diff --git a/services/core/java/com/android/server/wm/SeamlessRotator.java b/services/core/java/com/android/server/wm/SeamlessRotator.java index 8e1c6329f39d9..c79cb04a824f6 100644 --- a/services/core/java/com/android/server/wm/SeamlessRotator.java +++ b/services/core/java/com/android/server/wm/SeamlessRotator.java @@ -20,7 +20,6 @@ import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import android.graphics.Matrix; -import android.graphics.Rect; import android.os.IBinder; import android.view.DisplayInfo; import android.view.Surface.Rotation; @@ -28,7 +27,6 @@ import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import com.android.server.wm.utils.CoordinateTransforms; -import com.android.server.wm.utils.InsetUtils; import java.io.PrintWriter; import java.io.StringWriter; @@ -47,22 +45,18 @@ public class SeamlessRotator { private final float[] mFloat9 = new float[9]; private final int mOldRotation; private final int mNewRotation; - private final int mRotationDelta; - private final int mW; - private final int mH; public SeamlessRotator(@Rotation int oldRotation, @Rotation int newRotation, DisplayInfo info) { mOldRotation = oldRotation; mNewRotation = newRotation; - mRotationDelta = DisplayContent.deltaRotation(oldRotation, newRotation); final boolean flipped = info.rotation == ROTATION_90 || info.rotation == ROTATION_270; - mH = flipped ? info.logicalWidth : info.logicalHeight; - mW = flipped ? info.logicalHeight : info.logicalWidth; - + final int pH = flipped ? info.logicalWidth : info.logicalHeight; + final int pW = flipped ? info.logicalHeight : info.logicalWidth; + // Initialize transform matrix by physical size. final Matrix tmp = new Matrix(); - CoordinateTransforms.transformLogicalToPhysicalCoordinates(oldRotation, mW, mH, mTransform); - CoordinateTransforms.transformPhysicalToLogicalCoordinates(newRotation, mW, mH, tmp); + CoordinateTransforms.transformLogicalToPhysicalCoordinates(oldRotation, pW, pH, mTransform); + CoordinateTransforms.transformPhysicalToLogicalCoordinates(newRotation, pW, pH, tmp); mTransform.postConcat(tmp); } @@ -78,20 +72,6 @@ public class SeamlessRotator { transaction.setPosition(win.getSurfaceControl(), winSurfacePos[0], winSurfacePos[1]); } - /** Rotates the frame from {@link #mNewRotation} to {@link #mOldRotation}. */ - void unrotateFrame(Rect inOut) { - if (mRotationDelta == ROTATION_90) { - inOut.set(inOut.top, mH - inOut.right, inOut.bottom, mH - inOut.left); - } else if (mRotationDelta == ROTATION_270) { - inOut.set(mW - inOut.bottom, inOut.left, mW - inOut.top, inOut.right); - } - } - - /** Rotates the insets from {@link #mNewRotation} to {@link #mOldRotation}. */ - void unrotateInsets(Rect inOut) { - InsetUtils.rotateInsets(inOut, mRotationDelta); - } - /** * Returns the rotation of the display before it started rotating. * diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 36175705b8486..161152ba0d747 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5656,7 +5656,12 @@ class WindowState extends WindowContainer implements WindowManagerP // the status bar). In that case we need to use the final frame. if (inFreeformWindowingMode()) { outFrame.set(getFrameLw()); - } else if (isLetterboxedAppWindow()) { + } else if (isLetterboxedAppWindow() || mToken.isFixedRotationTransforming()) { + // 1. The letterbox surfaces should be animated with the owner activity, so use task + // bounds to include them. + // 2. If the activity has fixed rotation transform, its windows are rotated in activity + // level. Because the animation runs before display is rotated, task bounds should + // represent the frames in display space coordinates. outFrame.set(getTask().getBounds()); } else if (isDockedResizing()) { // If we are animating while docked resizing, then use the stack bounds as the diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index b7c6af2f7a0de..f965f7b80ee94 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -154,7 +154,10 @@ class WindowToken extends WindowContainer { void resetTransform() { for (int i = mRotatedContainers.size() - 1; i >= 0; i--) { final WindowContainer c = mRotatedContainers.get(i); - mRotator.finish(c.getPendingTransaction(), c); + // If the window is detached (no parent), its surface may have been released. + if (c.getParent() != null) { + mRotator.finish(c.getPendingTransaction(), c); + } } } } @@ -509,19 +512,6 @@ class WindowToken extends WindowContainer { } } - /** - * Converts the rotated animation frames and insets back to display space for local animation. - * It should only be called when {@link #hasFixedRotationTransform} is true. - */ - void unrotateAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets, - Rect outSurfaceInsets) { - final SeamlessRotator rotator = mFixedRotationTransformState.mRotator; - rotator.unrotateFrame(outFrame); - rotator.unrotateInsets(outInsets); - rotator.unrotateInsets(outStableInsets); - rotator.unrotateInsets(outSurfaceInsets); - } - /** * Gives a chance to this {@link WindowToken} to adjust the {@link * android.view.WindowManager.LayoutParams} of its windows. diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index b3c6b22bf265c..218c8169e7e60 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1016,6 +1016,15 @@ public class DisplayContentTests extends WindowTestsBase { assertTrue(mDisplayContent.getDisplayRotation().shouldRotateSeamlessly( ROTATION_0 /* oldRotation */, ROTATION_90 /* newRotation */, false /* forceUpdate */)); + + final Rect outFrame = new Rect(); + final Rect outInsets = new Rect(); + final Rect outStableInsets = new Rect(); + final Rect outSurfaceInsets = new Rect(); + mAppWindow.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets); + // The animation frames should not be rotated because display hasn't rotated. + assertEquals(mDisplayContent.getBounds(), outFrame); + // The display should keep current orientation and the rotated configuration should apply // to the activity. assertEquals(config.orientation, mDisplayContent.getConfiguration().orientation);