Loading services/core/java/com/android/server/wm/ActivityRecord.java +27 −29 Original line number Diff line number Diff line Loading @@ -7786,42 +7786,40 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** Gets the horizontal centered container bounds for size compatibility mode. */ void getContainerBounds(Rect outAppBounds, Rect outBounds, int rotation, int orientation, boolean orientationRequested, boolean canChangeOrientation) { if (mIsFloating) { getFrameByOrientation(outBounds, orientation); if (mIsFloating) { outAppBounds.set(outBounds); return; } if (canChangeOrientation) { getBoundsByRotation(outBounds, rotation); if (orientationRequested) { getFrameByOrientation(outAppBounds, orientation); } else { outAppBounds.set(outBounds); } } else { if (orientationRequested) { getFrameByOrientation(outBounds, orientation); if ((outBounds.width() > outBounds.height()) != (mWidth > mHeight)) { // The orientation is mismatched but the display cannot rotate. The bounds // will fit to the short side of display. getBoundsByRotation(outAppBounds, rotation); final int dW = outAppBounds.width(); final int dH = outAppBounds.height(); final boolean isOrientationMismatched = ((outBounds.width() > outBounds.height()) != (dW > dH)); if (isOrientationMismatched && !canChangeOrientation && orientationRequested) { // The orientation is mismatched but the display cannot rotate. The bounds will fit // to the short side of container. if (orientation == ORIENTATION_LANDSCAPE) { outBounds.bottom = (int) ((float) mWidth * mWidth / mHeight); outBounds.right = mWidth; outBounds.bottom = (int) ((float) dW * dW / dH); outBounds.right = dW; } else { outBounds.bottom = mHeight; outBounds.right = (int) ((float) mHeight * mHeight / mWidth); outBounds.bottom = dH; outBounds.right = (int) ((float) dH * dH / dW); } outBounds.offset( getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */); } } else { outBounds.set(0, 0, mWidth, mHeight); outBounds.offset(getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */); } outAppBounds.set(outBounds); } if (rotation != ROTATION_UNDEFINED) { if (isOrientationMismatched) { // One side of container is smaller than the requested size, then it will be scaled // and the final position will be calculated according to the parent container and // scale, so the original size shouldn't be shrunk by insets. final Rect insets = mNonDecorInsets[rotation]; outBounds.offset(insets.left, insets.top); outAppBounds.offset(insets.left, insets.top); } else if (rotation != ROTATION_UNDEFINED) { // Ensure the app bounds won't overlap with insets. Task.intersectWithInsetsIfFits(outAppBounds, outBounds, mNonDecorInsets[rotation]); } Loading services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +33 −3 Original line number Diff line number Diff line Loading @@ -35,7 +35,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doCallRealMethod; import android.app.ActivityManager; import android.app.ActivityManagerInternal; Loading Loading @@ -216,22 +218,50 @@ public class SizeCompatTests extends WindowTestsBase { final Rect origBounds = new Rect(mActivity.getBounds()); final Rect currentBounds = mActivity.getWindowConfiguration().getBounds(); final DisplayContent display = mActivity.mDisplayContent; // Change the size of current display. resizeDisplay(mStack.mDisplayContent, 1000, 2000); resizeDisplay(display, 1000, 2000); // The bounds should be [100, 0 - 1100, 2500]. assertEquals(origBounds.width(), currentBounds.width()); assertEquals(origBounds.height(), currentBounds.height()); assertScaled(); // The scale is 2000/2500=0.8. The horizontal centered offset is (1000-(1000*0.8))/2=100. final float scale = (float) display.mBaseDisplayHeight / currentBounds.height(); final int offsetX = (int) (display.mBaseDisplayWidth - (origBounds.width() * scale)) / 2; assertEquals(offsetX, currentBounds.left); // The position of configuration bounds should be the same as compat bounds. assertEquals(mActivity.getBounds().left, currentBounds.left); assertEquals(mActivity.getBounds().top, currentBounds.top); // Change display size to a different orientation resizeDisplay(mStack.mDisplayContent, 2000, 1000); resizeDisplay(display, 2000, 1000); // The bounds should be [800, 0 - 1800, 2500]. assertEquals(origBounds.width(), currentBounds.width()); assertEquals(origBounds.height(), currentBounds.height()); assertEquals(Configuration.ORIENTATION_LANDSCAPE, display.getConfiguration().orientation); assertEquals(Configuration.ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation); // The previous resize operation doesn't consider the rotation change after size changed. // These setups apply the requested orientation to rotation as real case that the top fixed // portrait activity will determine the display rotation. final DisplayRotation displayRotation = display.getDisplayRotation(); doCallRealMethod().when(displayRotation).updateRotationUnchecked(anyBoolean()); // Skip unrelated layout procedures. mAtm.deferWindowLayout(); display.reconfigureDisplayLocked(); displayRotation.updateOrientation(display.getOrientation(), true /* forceUpdate */); display.sendNewConfiguration(); assertEquals(Configuration.ORIENTATION_PORTRAIT, display.getConfiguration().orientation); assertEquals(Configuration.ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation); // The size should still be in portrait [100, 0 - 1100, 2500] = 1000x2500. assertEquals(origBounds.width(), currentBounds.width()); assertEquals(origBounds.height(), currentBounds.height()); assertEquals(offsetX, currentBounds.left); assertScaled(); } @Test Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +27 −29 Original line number Diff line number Diff line Loading @@ -7786,42 +7786,40 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** Gets the horizontal centered container bounds for size compatibility mode. */ void getContainerBounds(Rect outAppBounds, Rect outBounds, int rotation, int orientation, boolean orientationRequested, boolean canChangeOrientation) { if (mIsFloating) { getFrameByOrientation(outBounds, orientation); if (mIsFloating) { outAppBounds.set(outBounds); return; } if (canChangeOrientation) { getBoundsByRotation(outBounds, rotation); if (orientationRequested) { getFrameByOrientation(outAppBounds, orientation); } else { outAppBounds.set(outBounds); } } else { if (orientationRequested) { getFrameByOrientation(outBounds, orientation); if ((outBounds.width() > outBounds.height()) != (mWidth > mHeight)) { // The orientation is mismatched but the display cannot rotate. The bounds // will fit to the short side of display. getBoundsByRotation(outAppBounds, rotation); final int dW = outAppBounds.width(); final int dH = outAppBounds.height(); final boolean isOrientationMismatched = ((outBounds.width() > outBounds.height()) != (dW > dH)); if (isOrientationMismatched && !canChangeOrientation && orientationRequested) { // The orientation is mismatched but the display cannot rotate. The bounds will fit // to the short side of container. if (orientation == ORIENTATION_LANDSCAPE) { outBounds.bottom = (int) ((float) mWidth * mWidth / mHeight); outBounds.right = mWidth; outBounds.bottom = (int) ((float) dW * dW / dH); outBounds.right = dW; } else { outBounds.bottom = mHeight; outBounds.right = (int) ((float) mHeight * mHeight / mWidth); outBounds.bottom = dH; outBounds.right = (int) ((float) dH * dH / dW); } outBounds.offset( getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */); } } else { outBounds.set(0, 0, mWidth, mHeight); outBounds.offset(getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */); } outAppBounds.set(outBounds); } if (rotation != ROTATION_UNDEFINED) { if (isOrientationMismatched) { // One side of container is smaller than the requested size, then it will be scaled // and the final position will be calculated according to the parent container and // scale, so the original size shouldn't be shrunk by insets. final Rect insets = mNonDecorInsets[rotation]; outBounds.offset(insets.left, insets.top); outAppBounds.offset(insets.left, insets.top); } else if (rotation != ROTATION_UNDEFINED) { // Ensure the app bounds won't overlap with insets. Task.intersectWithInsetsIfFits(outAppBounds, outBounds, mNonDecorInsets[rotation]); } Loading
services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +33 −3 Original line number Diff line number Diff line Loading @@ -35,7 +35,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doCallRealMethod; import android.app.ActivityManager; import android.app.ActivityManagerInternal; Loading Loading @@ -216,22 +218,50 @@ public class SizeCompatTests extends WindowTestsBase { final Rect origBounds = new Rect(mActivity.getBounds()); final Rect currentBounds = mActivity.getWindowConfiguration().getBounds(); final DisplayContent display = mActivity.mDisplayContent; // Change the size of current display. resizeDisplay(mStack.mDisplayContent, 1000, 2000); resizeDisplay(display, 1000, 2000); // The bounds should be [100, 0 - 1100, 2500]. assertEquals(origBounds.width(), currentBounds.width()); assertEquals(origBounds.height(), currentBounds.height()); assertScaled(); // The scale is 2000/2500=0.8. The horizontal centered offset is (1000-(1000*0.8))/2=100. final float scale = (float) display.mBaseDisplayHeight / currentBounds.height(); final int offsetX = (int) (display.mBaseDisplayWidth - (origBounds.width() * scale)) / 2; assertEquals(offsetX, currentBounds.left); // The position of configuration bounds should be the same as compat bounds. assertEquals(mActivity.getBounds().left, currentBounds.left); assertEquals(mActivity.getBounds().top, currentBounds.top); // Change display size to a different orientation resizeDisplay(mStack.mDisplayContent, 2000, 1000); resizeDisplay(display, 2000, 1000); // The bounds should be [800, 0 - 1800, 2500]. assertEquals(origBounds.width(), currentBounds.width()); assertEquals(origBounds.height(), currentBounds.height()); assertEquals(Configuration.ORIENTATION_LANDSCAPE, display.getConfiguration().orientation); assertEquals(Configuration.ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation); // The previous resize operation doesn't consider the rotation change after size changed. // These setups apply the requested orientation to rotation as real case that the top fixed // portrait activity will determine the display rotation. final DisplayRotation displayRotation = display.getDisplayRotation(); doCallRealMethod().when(displayRotation).updateRotationUnchecked(anyBoolean()); // Skip unrelated layout procedures. mAtm.deferWindowLayout(); display.reconfigureDisplayLocked(); displayRotation.updateOrientation(display.getOrientation(), true /* forceUpdate */); display.sendNewConfiguration(); assertEquals(Configuration.ORIENTATION_PORTRAIT, display.getConfiguration().orientation); assertEquals(Configuration.ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation); // The size should still be in portrait [100, 0 - 1100, 2500] = 1000x2500. assertEquals(origBounds.width(), currentBounds.width()); assertEquals(origBounds.height(), currentBounds.height()); assertEquals(offsetX, currentBounds.left); assertScaled(); } @Test Loading