Merge "Use orientation to determine size compat bounds"

This commit is contained in:
Riddle Hsu
2020-09-02 08:00:26 +00:00
committed by Android (Google) Code Review
2 changed files with 61 additions and 33 deletions

View File

@@ -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) {
getFrameByOrientation(outBounds, orientation);
if (mIsFloating) {
getFrameByOrientation(outBounds, orientation);
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.
if (orientation == ORIENTATION_LANDSCAPE) {
outBounds.bottom = (int) ((float) mWidth * mWidth / mHeight);
outBounds.right = mWidth;
} else {
outBounds.bottom = mHeight;
outBounds.right = (int) ((float) mHeight * mHeight / mWidth);
}
outBounds.offset(
getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */);
}
} else {
outBounds.set(0, 0, mWidth, mHeight);
}
outAppBounds.set(outBounds);
}
getBoundsByRotation(outAppBounds, rotation);
final int dW = outAppBounds.width();
final int dH = outAppBounds.height();
final boolean isOrientationMismatched =
((outBounds.width() > outBounds.height()) != (dW > dH));
if (rotation != ROTATION_UNDEFINED) {
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) dW * dW / dH);
outBounds.right = dW;
} else {
outBounds.bottom = dH;
outBounds.right = (int) ((float) dH * dH / dW);
}
outBounds.offset(getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */);
}
outAppBounds.set(outBounds);
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]);
}

View File

@@ -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;
@@ -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