Merge "Clear the previous CompatDisplayInsets when new activity is launched"

This commit is contained in:
Chris Li
2020-10-26 00:45:25 +00:00
committed by Android (Google) Code Review
5 changed files with 118 additions and 10 deletions

View File

@@ -6552,14 +6552,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mCompatDisplayInsets = new CompatDisplayInsets(mDisplayContent, this);
}
@VisibleForTesting
void clearSizeCompatMode() {
void clearSizeCompatMode(boolean recomputeTask) {
mSizeCompatScale = 1f;
mSizeCompatBounds = null;
mCompatDisplayInsets = null;
// Recompute from Task because letterbox can also happen on Task level.
task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration());
if (recomputeTask) {
// Recompute from Task because letterbox can also happen on Task level.
task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration());
}
}
@VisibleForTesting
void clearSizeCompatMode() {
clearSizeCompatMode(true /* recomputeTask */);
}
@Override

View File

@@ -1303,7 +1303,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@Override
boolean onDescendantOrientationChanged(IBinder freezeDisplayToken,
ConfigurationContainer requestingContainer) {
WindowContainer requestingContainer) {
final Configuration config = updateOrientation(
getRequestedOverrideConfiguration(), freezeDisplayToken, false /* forceUpdate */);
// If display rotation class tells us that it doesn't consider app requested orientation,

View File

@@ -3283,7 +3283,7 @@ class Task extends WindowContainer<WindowContainer> {
@Override
public boolean onDescendantOrientationChanged(IBinder freezeDisplayToken,
ConfigurationContainer requestingContainer) {
WindowContainer requestingContainer) {
if (super.onDescendantOrientationChanged(freezeDisplayToken, requestingContainer)) {
return true;
}
@@ -3291,6 +3291,18 @@ class Task extends WindowContainer<WindowContainer> {
// No one in higher hierarchy handles this request, let's adjust our bounds to fulfill
// it if possible.
if (getParent() != null) {
final ActivityRecord activity = requestingContainer.asActivityRecord();
if (activity != null) {
// Clear the size compat cache to recompute the bounds for requested orientation;
// otherwise when Task#computeFullscreenBounds(), it will not try to do Task level
// letterboxing because app may prefer to keep its original size (size compat).
//
// Normally, ActivityRecord#clearSizeCompatMode() recomputes from its parent Task,
// which is the leaf Task. However, because this orientation request is new to all
// Tasks, pass false to clearSizeCompatMode, and trigger onConfigurationChanged from
// here (root Task) to make sure all Tasks are up-to-date.
activity.clearSizeCompatMode(false /* recomputeTask */);
}
onConfigurationChanged(getParent().getConfiguration());
return true;
}

View File

@@ -1144,7 +1144,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* @return {@code true} if handled; {@code false} otherwise.
*/
boolean onDescendantOrientationChanged(@Nullable IBinder freezeDisplayToken,
@Nullable ConfigurationContainer requestingContainer) {
@Nullable WindowContainer requestingContainer) {
final WindowContainer parent = getParent();
if (parent == null) {
return false;
@@ -1156,7 +1156,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
/**
* Check if this container or its parent will handle orientation changes from descendants. It's
* different from the return value of {@link #onDescendantOrientationChanged(IBinder,
* ConfigurationContainer)} in the sense that the return value of this method tells if this
* WindowContainer)} in the sense that the return value of this method tells if this
* container or its parent will handle the request eventually, while the return value of the
* other method is if it handled the request synchronously.
*
@@ -1230,7 +1230,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* to ensure it gets correct configuration.
*/
void setOrientation(int orientation, @Nullable IBinder freezeDisplayToken,
@Nullable ConfigurationContainer requestingContainer) {
@Nullable WindowContainer requestingContainer) {
if (mOrientation == orientation) {
return;
}

View File

@@ -28,6 +28,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.Task.ActivityState.STOPPED;
@@ -35,8 +36,11 @@ 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.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.doCallRealMethod;
import android.app.ActivityManager;
@@ -628,7 +632,6 @@ public class SizeCompatTests extends WindowTestsBase {
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
final Rect displayBounds = mActivity.mDisplayContent.getBounds();
final Rect newTaskBounds = mTask.getBounds();
final Rect newActivityBounds = mActivity.getBounds();
assertTrue(displayBounds.width() < displayBounds.height());
@@ -673,6 +676,93 @@ public class SizeCompatTests extends WindowTestsBase {
activityBounds.width());
}
@Test
public void testDisplayIgnoreOrientationRequest_newLaunchedOrientationAppInTaskLetterbox() {
// Set up a display in landscape and ignoring orientation request.
setUpDisplaySizeWithApp(2800, 1400);
final DisplayContent display = mActivity.mDisplayContent;
display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Portrait fixed app without max aspect.
prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
assertTrue(mTask.isTaskLetterboxed());
assertFalse(mActivity.inSizeCompatMode());
// Launch another portrait fixed app.
spyOn(mTask);
setBooted(display.mWmService.mAtmService);
final ActivityRecord newActivity = new ActivityBuilder(display.mWmService.mAtmService)
.setResizeMode(RESIZE_MODE_UNRESIZEABLE)
.setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
.setTask(mTask)
.build();
// Update with new activity requested orientation and recompute bounds with no previous
// size compat cache.
verify(mTask).onDescendantOrientationChanged(any(), same(newActivity));
verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt());
verify(newActivity).clearSizeCompatMode(false /* recomputeTask */);
final Rect displayBounds = display.getBounds();
final Rect taskBounds = mTask.getBounds();
final Rect newActivityBounds = newActivity.getBounds();
// Task and app bounds should be 700x1400 with the ratio as the display.
assertTrue(mTask.isTaskLetterboxed());
assertFalse(newActivity.inSizeCompatMode());
assertEquals(taskBounds, newActivityBounds);
assertEquals(displayBounds.height(), taskBounds.height());
assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(),
taskBounds.width());
}
@Test
public void testDisplayIgnoreOrientationRequest_newLaunchedMaxAspectApp() {
// Set up a display in landscape and ignoring orientation request.
setUpDisplaySizeWithApp(2800, 1400);
final DisplayContent display = mActivity.mDisplayContent;
display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Portrait fixed app without max aspect.
prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
assertTrue(mTask.isTaskLetterboxed());
assertFalse(mActivity.inSizeCompatMode());
// Launch another portrait fixed app with max aspect ratio as 1.3.
spyOn(mTask);
setBooted(display.mWmService.mAtmService);
final ActivityRecord newActivity = new ActivityBuilder(display.mWmService.mAtmService)
.setResizeMode(RESIZE_MODE_UNRESIZEABLE)
.setMaxAspectRatio(1.3f)
.setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
.setTask(mTask)
.build();
// Update with new activity requested orientation and recompute bounds with no previous
// size compat cache.
verify(mTask).onDescendantOrientationChanged(any(), same(newActivity));
verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt());
verify(newActivity).clearSizeCompatMode(false /* recomputeTask */);
final Rect displayBounds = display.getBounds();
final Rect taskBounds = mTask.getBounds();
final Rect newActivityBounds = newActivity.getBounds();
// Task bounds should be 700x1400 with the ratio as the display.
assertTrue(mTask.isTaskLetterboxed());
assertEquals(displayBounds.height(), taskBounds.height());
assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(),
taskBounds.width());
// App bounds should be 700x(710 x 1.3 = 910)
assertFalse(newActivity.inSizeCompatMode());
assertEquals(taskBounds.width(), newActivityBounds.width());
assertEquals((long) Math.rint(taskBounds.width() * newActivity.info.maxAspectRatio),
newActivityBounds.height());
}
private static WindowState addWindowToActivity(ActivityRecord activity) {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;