Merge "Clear the previous CompatDisplayInsets when new activity is launched"
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user