DisplayContent rotateBounds not keeping same physical position for 180
Rotation_90 + rotation_90 is different from the result of rotation_180
with the current implementation. Should also take care of rotation_180.
Fix: 180751251
Bug: 173124775
Test: atest WmTests:DisplayContentTests
Test: atest WMShellUnitTests:DisplayLayoutTest
Test: atest FrameworksCoreTests:RotationUtilsTest
Change-Id: Ia1c87409b4c4cc412c3fd89e58d08b6ae2069fd0
diff --git a/core/java/android/util/RotationUtils.java b/core/java/android/util/RotationUtils.java
index 698cb77..0ac2c9c 100644
--- a/core/java/android/util/RotationUtils.java
+++ b/core/java/android/util/RotationUtils.java
@@ -24,6 +24,7 @@
import android.annotation.Dimension;
import android.graphics.Insets;
import android.graphics.Matrix;
+import android.graphics.Rect;
import android.view.Surface.Rotation;
/**
@@ -73,6 +74,60 @@
}
/**
+ * Rotates bounds as if parentBounds and bounds are a group. The group is rotated from
+ * oldRotation to newRotation. This assumes that parentBounds is at 0,0 and remains at 0,0 after
+ * rotation. The bounds will be at the same physical position in parentBounds.
+ *
+ * Only 'inOutBounds' is mutated.
+ */
+ public static void rotateBounds(Rect inOutBounds, Rect parentBounds, @Rotation int oldRotation,
+ @Rotation int newRotation) {
+ rotateBounds(inOutBounds, parentBounds, deltaRotation(oldRotation, newRotation));
+ }
+
+ /**
+ * Rotates bounds as if parentBounds and bounds are a group. The group is rotated by `delta`
+ * 90-degree counter-clockwise increments. This assumes that parentBounds is at 0,0 and
+ * remains at 0,0 after rotation. The bounds will be at the same physical position in
+ * parentBounds.
+ *
+ * Only 'inOutBounds' is mutated.
+ */
+ public static void rotateBounds(Rect inOutBounds, Rect parentBounds, @Rotation int rotation) {
+ final int origLeft = inOutBounds.left;
+ final int origTop = inOutBounds.top;
+ switch (rotation) {
+ case ROTATION_0:
+ return;
+ case ROTATION_90:
+ inOutBounds.left = inOutBounds.top;
+ inOutBounds.top = parentBounds.right - inOutBounds.right;
+ inOutBounds.right = inOutBounds.bottom;
+ inOutBounds.bottom = parentBounds.right - origLeft;
+ return;
+ case ROTATION_180:
+ inOutBounds.left = parentBounds.right - inOutBounds.right;
+ inOutBounds.right = parentBounds.right - origLeft;
+ inOutBounds.top = parentBounds.bottom - inOutBounds.bottom;
+ inOutBounds.bottom = parentBounds.bottom - origTop;
+ return;
+ case ROTATION_270:
+ inOutBounds.left = parentBounds.bottom - inOutBounds.bottom;
+ inOutBounds.bottom = inOutBounds.right;
+ inOutBounds.right = parentBounds.bottom - inOutBounds.top;
+ inOutBounds.top = origLeft;
+ }
+ }
+
+ /** @return the rotation needed to rotate from oldRotation to newRotation. */
+ @Rotation
+ public static int deltaRotation(int oldRotation, int newRotation) {
+ int delta = newRotation - oldRotation;
+ if (delta < 0) delta += 4;
+ return delta;
+ }
+
+ /**
* Sets a matrix such that given a rotation, it transforms physical display
* coordinates to that rotation's logical coordinates.
*
diff --git a/core/tests/coretests/src/android/util/RotationUtilsTest.java b/core/tests/coretests/src/android/util/RotationUtilsTest.java
new file mode 100644
index 0000000..5dbe03e
--- /dev/null
+++ b/core/tests/coretests/src/android/util/RotationUtilsTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import static android.util.RotationUtils.rotateBounds;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
+import static org.junit.Assert.assertEquals;
+
+import android.graphics.Rect;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link RotationUtils}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:RotationUtilsTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RotationUtilsTest {
+
+ @Test
+ public void testRotateBounds() {
+ Rect testParent = new Rect(0, 0, 1000, 600);
+ Rect testInner = new Rect(40, 20, 120, 80);
+
+ Rect testResult = new Rect(testInner);
+ rotateBounds(testResult, testParent, ROTATION_90);
+ assertEquals(new Rect(20, 880, 80, 960), testResult);
+
+ testResult.set(testInner);
+ rotateBounds(testResult, testParent, ROTATION_180);
+ assertEquals(new Rect(880, 520, 960, 580), testResult);
+
+ testResult.set(testInner);
+ rotateBounds(testResult, testParent, ROTATION_270);
+ assertEquals(new Rect(520, 40, 580, 120), testResult);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
index 58a4baf..4564af4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
@@ -22,6 +22,8 @@
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
import static android.os.Process.SYSTEM_UID;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
+import static android.util.RotationUtils.rotateBounds;
+import static android.util.RotationUtils.rotateInsets;
import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
@@ -37,7 +39,6 @@
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.DisplayMetrics;
-import android.util.RotationUtils;
import android.util.Size;
import android.view.Display;
import android.view.DisplayCutout;
@@ -241,38 +242,6 @@
}
/**
- * Rotates bounds as if parentBounds and bounds are a group. The group is rotated by `delta`
- * 90-degree counter-clockwise increments. This assumes that parentBounds is at 0,0 and
- * remains at 0,0 after rotation.
- *
- * Only 'bounds' is mutated.
- */
- public static void rotateBounds(Rect inOutBounds, Rect parentBounds, int delta) {
- int rdelta = ((delta % 4) + 4) % 4;
- int origLeft = inOutBounds.left;
- switch (rdelta) {
- case 0:
- return;
- case 1:
- inOutBounds.left = inOutBounds.top;
- inOutBounds.top = parentBounds.right - inOutBounds.right;
- inOutBounds.right = inOutBounds.bottom;
- inOutBounds.bottom = parentBounds.right - origLeft;
- return;
- case 2:
- inOutBounds.left = parentBounds.right - inOutBounds.right;
- inOutBounds.right = parentBounds.right - origLeft;
- return;
- case 3:
- inOutBounds.left = parentBounds.bottom - inOutBounds.bottom;
- inOutBounds.bottom = inOutBounds.right;
- inOutBounds.right = parentBounds.bottom - inOutBounds.top;
- inOutBounds.top = origLeft;
- return;
- }
- }
-
- /**
* Calculates the stable insets if we already have the non-decor insets.
*/
private static void convertNonDecorInsetsToStableInsets(Resources res, Rect inOutInsets,
@@ -359,8 +328,7 @@
if (rotation == ROTATION_0) {
return computeSafeInsets(cutout, displayWidth, displayHeight);
}
- final Insets waterfallInsets =
- RotationUtils.rotateInsets(cutout.getWaterfallInsets(), rotation);
+ final Insets waterfallInsets = rotateInsets(cutout.getWaterfallInsets(), rotation);
final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
Rect[] cutoutRects = cutout.getBoundingRectsAll();
final Rect[] newBounds = new Rect[cutoutRects.length];
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitDisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitDisplayLayout.java
index 477ec33..40244fb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitDisplayLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitDisplayLayout.java
@@ -18,6 +18,7 @@
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.util.RotationUtils.rotateBounds;
import static android.view.WindowManager.DOCKED_BOTTOM;
import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.DOCKED_LEFT;
@@ -244,7 +245,7 @@
DividerSnapAlgorithm snap = initSnapAlgorithmForRotation(context, tmpDL, dividerSize);
tmpRect.set(bounds);
- DisplayLayout.rotateBounds(tmpRect, displayRect, rotation - dl.rotation());
+ rotateBounds(tmpRect, displayRect, dl.rotation(), rotation);
rotatedDisplayRect.set(0, 0, tmpDL.width(), tmpDL.height());
final int dockSide = getPrimarySplitSide(tmpRect, rotatedDisplayRect,
tmpDL.getOrientation());
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 5ffa988..66560d3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.pip;
+import static android.util.RotationUtils.rotateBounds;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
@@ -33,7 +34,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.wm.shell.animation.Interpolators;
-import com.android.wm.shell.common.DisplayLayout;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -448,7 +448,7 @@
// Rotate the end bounds according to the rotation delta because the display will
// be rotated to the same orientation.
rotatedEndRect = new Rect(endValue);
- DisplayLayout.rotateBounds(rotatedEndRect, endValue, rotationDelta);
+ rotateBounds(rotatedEndRect, endValue, rotationDelta);
} else {
rotatedEndRect = null;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
index 2b5b77e..88e754c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
@@ -38,6 +38,12 @@
import org.junit.Test;
+/**
+ * Tests for {@link DisplayLayout}.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:DisplayLayoutTest
+ */
@SmallTest
public class DisplayLayoutTest {
@@ -70,18 +76,6 @@
@Test
public void testRotate() {
// Basic rotate utility
- Rect testParent = new Rect(0, 0, 1000, 600);
- Rect testInner = new Rect(40, 20, 120, 80);
- Rect testResult = new Rect(testInner);
- DisplayLayout.rotateBounds(testResult, testParent, 1);
- assertEquals(new Rect(20, 880, 80, 960), testResult);
- testResult.set(testInner);
- DisplayLayout.rotateBounds(testResult, testParent, 2);
- assertEquals(new Rect(880, 20, 960, 80), testResult);
- testResult.set(testInner);
- DisplayLayout.rotateBounds(testResult, testParent, 3);
- assertEquals(new Rect(520, 40, 580, 120), testResult);
-
Resources res = createResources(40, 50, false, 30, 40);
DisplayInfo info = createDisplayInfo(1000, 1500, 60, ROTATION_0);
DisplayLayout dl = new DisplayLayout(info, res, true, true);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
index 3147dab..63b9413 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.pip;
+import static android.util.RotationUtils.rotateBounds;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_90;
@@ -37,7 +38,6 @@
import androidx.test.filters.SmallTest;
import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.DisplayLayout;
import org.junit.Before;
import org.junit.Test;
@@ -141,7 +141,7 @@
// Apply fraction 1 to compute the end value.
animator.applySurfaceControlTransaction(mLeash, new DummySurfaceControlTx(), 1);
final Rect rotatedEndBounds = new Rect(endBounds);
- DisplayLayout.rotateBounds(rotatedEndBounds, endBounds, ROTATION_90);
+ rotateBounds(rotatedEndBounds, endBounds, ROTATION_90);
assertEquals("Expect 90 degree rotated bounds", rotatedEndBounds, animator.mCurrentValue);
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0143e70..4bc49d8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -36,6 +36,7 @@
import static android.os.Build.VERSION_CODES.N;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
+import static android.util.RotationUtils.deltaRotation;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.view.Display.FLAG_PRIVATE;
@@ -47,7 +48,6 @@
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.View.GONE;
@@ -158,10 +158,8 @@
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Insets;
-import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Region.Op;
import android.hardware.HardwareBuffer;
@@ -206,6 +204,7 @@
import android.view.RemoteAnimationDefinition;
import android.view.RoundedCorners;
import android.view.Surface;
+import android.view.Surface.Rotation;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
@@ -449,8 +448,6 @@
/** Save allocating when calculating rects */
private final Rect mTmpRect = new Rect();
private final Rect mTmpRect2 = new Rect();
- private final RectF mTmpRectF = new RectF();
- private final Matrix mTmpMatrix = new Matrix();
private final Region mTmpRegion = new Region();
/** Used for handing back size of display */
@@ -1289,7 +1286,7 @@
return mInsetsPolicy;
}
- @Surface.Rotation
+ @Rotation
int getRotation() {
return mDisplayRotation.getRotation();
}
@@ -1479,7 +1476,7 @@
* Returns a valid rotation if the activity can use different orientation than the display.
* Otherwise {@link #ROTATION_UNDEFINED}.
*/
- @Surface.Rotation
+ @Rotation
int rotationForActivityInDifferentOrientation(@NonNull ActivityRecord r) {
if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
return ROTATION_UNDEFINED;
@@ -1614,7 +1611,7 @@
* Sets the provided record to {@link #mFixedRotationLaunchingApp} if possible to apply fixed
* rotation transform to it and indicate that the display may be rotated after it is launched.
*/
- void setFixedRotationLaunchingApp(@NonNull ActivityRecord r, @Surface.Rotation int rotation) {
+ void setFixedRotationLaunchingApp(@NonNull ActivityRecord r, @Rotation int rotation) {
final WindowToken prevRotatedLaunchingApp = mFixedRotationLaunchingApp;
if (prevRotatedLaunchingApp == r
&& r.getWindowConfiguration().getRotation() == rotation) {
@@ -2951,27 +2948,10 @@
forAllRootTasks(Task::prepareFreezingTaskBounds);
}
- void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
- getBounds(mTmpRect, newRotation);
- rotateBounds(mTmpRect, oldRotation, newRotation, bounds);
- }
-
- void rotateBounds(Rect parentBounds, int oldRotation, int newRotation, Rect bounds) {
- // Compute a transform matrix to undo the coordinate space transformation,
- // and present the window at the same physical position it previously occupied.
- final int deltaRotation = deltaRotation(newRotation, oldRotation);
- createRotationMatrix(
- deltaRotation, parentBounds.width(), parentBounds.height(), mTmpMatrix);
-
- mTmpRectF.set(bounds);
- mTmpMatrix.mapRect(mTmpRectF);
- mTmpRectF.round(bounds);
- }
-
- static int deltaRotation(int oldRotation, int newRotation) {
- int delta = newRotation - oldRotation;
- if (delta < 0) delta += 4;
- return delta;
+ void rotateBounds(@Rotation int oldRotation, @Rotation int newRotation, Rect inOutBounds) {
+ // Get display bounds on oldRotation as parent bounds for the rotation.
+ getBounds(mTmpRect, oldRotation);
+ RotationUtils.rotateBounds(inOutBounds, mTmpRect, oldRotation, newRotation);
}
public void setRotationAnimation(ScreenRotationAnimation screenRotationAnimation) {
@@ -2985,35 +2965,6 @@
return mScreenRotationAnimation;
}
- private static void createRotationMatrix(int rotation, float displayWidth, float displayHeight,
- Matrix outMatrix) {
- // For rotations without Z-ordering we don't need the target rectangle's position.
- createRotationMatrix(rotation, 0 /* rectLeft */, 0 /* rectTop */, displayWidth,
- displayHeight, outMatrix);
- }
-
- static void createRotationMatrix(int rotation, float rectLeft, float rectTop,
- float displayWidth, float displayHeight, Matrix outMatrix) {
- switch (rotation) {
- case ROTATION_0:
- outMatrix.reset();
- break;
- case ROTATION_270:
- outMatrix.setRotate(270, 0, 0);
- outMatrix.postTranslate(0, displayHeight);
- outMatrix.postTranslate(rectTop, 0);
- break;
- case ROTATION_180:
- outMatrix.reset();
- break;
- case ROTATION_90:
- outMatrix.setRotate(90, 0, 0);
- outMatrix.postTranslate(displayWidth, 0);
- outMatrix.postTranslate(-rectTop, rectLeft);
- break;
- }
- }
-
@Override
public void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
@@ -4289,17 +4240,14 @@
out.set(left, top, left + width, top + height);
}
- private void getBounds(Rect out, int orientation) {
+ private void getBounds(Rect out, @Rotation int rotation) {
getBounds(out);
// Rotate the Rect if needed.
final int currentRotation = mDisplayInfo.rotation;
- final int rotationDelta = deltaRotation(currentRotation, orientation);
+ final int rotationDelta = deltaRotation(currentRotation, rotation);
if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
- createRotationMatrix(rotationDelta, mBaseDisplayWidth, mBaseDisplayHeight, mTmpMatrix);
- mTmpRectF.set(out);
- mTmpMatrix.mapRect(mTmpRectF);
- mTmpRectF.round(out);
+ out.set(0, 0, out.height(), out.width());
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 5460e36..f64f04c 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -24,6 +24,8 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
+import static android.util.RotationUtils.deltaRotation;
+import static android.util.RotationUtils.rotateBounds;
import static android.view.Display.TYPE_INTERNAL;
import static android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES;
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
@@ -1046,11 +1048,17 @@
return;
}
- // Get displayFrames bounds
- sTmpDisplayFrameBounds.set(0, 0, displayFrames.mDisplayWidth, displayFrames.mDisplayHeight);
+ // Get displayFrames bounds as it is on WindowState's rotation.
+ final int deltaRotation = deltaRotation(windowRotation, displayFrames.mRotation);
+ if (deltaRotation == Surface.ROTATION_90 || deltaRotation == Surface.ROTATION_270) {
+ sTmpDisplayFrameBounds.set(
+ 0, 0, displayFrames.mDisplayHeight, displayFrames.mDisplayWidth);
+ } else {
+ sTmpDisplayFrameBounds.set(
+ 0, 0, displayFrames.mDisplayWidth, displayFrames.mDisplayHeight);
+ }
// Rotate the WindowState's bounds based on the displayFrames rotation
- mDisplayContent.rotateBounds(sTmpDisplayFrameBounds, windowRotation,
- displayFrames.mRotation, outBounds);
+ rotateBounds(outBounds, sTmpDisplayFrameBounds, deltaRotation);
}
/**
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index d5ded97..63cb38a 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.util.RotationUtils.deltaRotation;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
@@ -475,7 +476,7 @@
"Display id=%d rotation changed to %d from %d, lastOrientation=%d",
displayId, rotation, oldRotation, lastOrientation);
- if (DisplayContent.deltaRotation(rotation, oldRotation) != 2) {
+ if (deltaRotation(oldRotation, rotation) != Surface.ROTATION_180) {
mDisplayContent.mWaitingForConfig = true;
}
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 533c82e..95a4f69e 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.util.RotationUtils.deltaRotation;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
@@ -174,7 +175,7 @@
// apply rotation animation because there should be a top app shown as rotated. So the
// specified original rotation customizes the direction of animation to have better look
// when restoring the rotated app to the same rotation as current display.
- final int delta = DisplayContent.deltaRotation(originalRotation, realOriginalRotation);
+ final int delta = deltaRotation(originalRotation, realOriginalRotation);
final boolean flipped = delta == Surface.ROTATION_90 || delta == Surface.ROTATION_270;
mOriginalWidth = flipped ? originalHeight : originalWidth;
mOriginalHeight = flipped ? originalWidth : originalHeight;
@@ -330,7 +331,7 @@
// Compute the transformation matrix that must be applied
// to the snapshot to make it stay in the same original position
// with the current screen rotation.
- int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0);
+ int delta = deltaRotation(rotation, Surface.ROTATION_0);
RotationAnimationUtils.createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
setRotationTransform(t, mSnapshotInitialMatrix);
@@ -352,8 +353,7 @@
mStarted = true;
// Figure out how the screen has moved from the original rotation.
- int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
-
+ int delta = deltaRotation(mCurRotation, mOriginalRotation);
final boolean customAnim;
if (exitAnim != 0 && enterAnim != 0) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index d60b6e0..7238fd6 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -2361,9 +2361,7 @@
final int newRotation = getWindowConfiguration().getRotation();
final boolean rotationChanged = prevRotation != newRotation;
if (rotationChanged) {
- mDisplayContent.rotateBounds(
- newParentConfig.windowConfiguration.getBounds(), prevRotation, newRotation,
- newBounds);
+ mDisplayContent.rotateBounds(prevRotation, newRotation, newBounds);
setBounds(newBounds);
}
}
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 dc702e6..c216bfa 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -33,6 +33,7 @@
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
@@ -1845,6 +1846,37 @@
verify(t).show(mDisplayContent.mImeScreenshot);
}
+ @Test
+ public void testRotateBounds_keepSamePhysicalPosition() {
+ final DisplayContent dc =
+ new TestDisplayContent.Builder(mAtm, 1000, 2000).build();
+ final Rect initBounds = new Rect(0, 0, 700, 1500);
+ final Rect rotateBounds = new Rect(initBounds);
+
+ // Rotate from 0 to 0
+ dc.rotateBounds(ROTATION_0, ROTATION_0, rotateBounds);
+
+ assertEquals(new Rect(0, 0, 700, 1500), rotateBounds);
+
+ // Rotate from 0 to 90
+ rotateBounds.set(initBounds);
+ dc.rotateBounds(ROTATION_0, ROTATION_90, rotateBounds);
+
+ assertEquals(new Rect(0, 300, 1500, 1000), rotateBounds);
+
+ // Rotate from 0 to 180
+ rotateBounds.set(initBounds);
+ dc.rotateBounds(ROTATION_0, ROTATION_180, rotateBounds);
+
+ assertEquals(new Rect(300, 500, 1000, 2000), rotateBounds);
+
+ // Rotate from 0 to 270
+ rotateBounds.set(initBounds);
+ dc.rotateBounds(ROTATION_0, ROTATION_270, rotateBounds);
+
+ assertEquals(new Rect(500, 0, 2000, 700), rotateBounds);
+ }
+
private boolean isOptionsPanelAtRight(int displayId) {
return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
}