Loading services/core/java/com/android/server/wm/ActivityRecord.java +48 −21 Original line number Diff line number Diff line Loading @@ -6492,8 +6492,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mLastReportedConfiguration.setConfiguration(global, override); } boolean hasCompatDisplayInsets() { return mCompatDisplayInsets != null; @Nullable CompatDisplayInsets getCompatDisplayInsets() { return mCompatDisplayInsets; } /** Loading Loading @@ -7816,13 +7817,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** * The precomputed insets of the display in each rotation. This is used to make the size * compatibility mode activity compute the configuration without relying on its current display. * This currently only supports fullscreen and freeform windowing mode. */ static class CompatDisplayInsets { /** The container width on rotation 0. */ private final int mWidth; /** The container height on rotation 0. */ private final int mHeight; /** Whether the {@link Task} windowingMode represents a floating window*/ final boolean mIsFloating; /** Whether the {@link Task} is letterboxed when the unresizable activity is first shown. */ final boolean mIsTaskLetterboxed; /** * The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. It * is used to compute the appBounds. Loading @@ -7849,27 +7853,24 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mNonDecorInsets[rotation] = emptyRect; mStableInsets[rotation] = emptyRect; } mIsTaskLetterboxed = false; return; } final Task task = container.getTask(); if (task != null && task.isTaskLetterboxed()) { // For apps in Task letterbox, it should fill the task bounds. final Point dimensions = getRotationZeroDimensions(task); mWidth = dimensions.x; mHeight = dimensions.y; } else { // If the activity is not floating nor letterboxed, assume it fills the root. final RootDisplayArea root = container.getRootDisplayArea(); if (root == null || root == display) { mWidth = display.mBaseDisplayWidth; mHeight = display.mBaseDisplayHeight; } else { final Point dimensions = getRotationZeroDimensions(root); mIsTaskLetterboxed = task != null && task.isTaskLetterboxed(); // Store the bounds of the Task for the non-resizable activity to use in size compat // mode so that the activity will not be resized regardless the windowing mode it is // currently in. final WindowContainer filledContainer = task != null ? task : display; final Point dimensions = getRotationZeroDimensions(filledContainer); mWidth = dimensions.x; mHeight = dimensions.y; } } // Bounds of the filled container if it doesn't fill the display. final Rect unfilledContainerBounds = filledContainer.getBounds().equals(display.getBounds()) ? null : new Rect(); final DisplayPolicy policy = display.getDisplayPolicy(); for (int rotation = 0; rotation < 4; rotation++) { mNonDecorInsets[rotation] = new Rect(); Loading @@ -7882,6 +7883,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]); mStableInsets[rotation].set(mNonDecorInsets[rotation]); policy.convertNonDecorInsetsToStableInsets(mStableInsets[rotation], rotation); if (unfilledContainerBounds == null) { continue; } // The insets is based on the display, but the container may be smaller than the // display, so update the insets to exclude parts that are not intersected with the // container. unfilledContainerBounds.set(filledContainer.getBounds()); display.rotateBounds( filledContainer.getConfiguration().windowConfiguration.getRotation(), rotation, unfilledContainerBounds); updateInsetsForBounds(unfilledContainerBounds, dw, dh, mNonDecorInsets[rotation]); updateInsetsForBounds(unfilledContainerBounds, dw, dh, mStableInsets[rotation]); } } Loading @@ -7899,6 +7914,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return rotated ? new Point(height, width) : new Point(width, height); } /** * Updates the display insets to exclude the parts that are not intersected with the given * bounds. */ private static void updateInsetsForBounds(Rect bounds, int displayWidth, int displayHeight, Rect inset) { inset.left = Math.max(0, inset.left - bounds.left); inset.top = Math.max(0, inset.top - bounds.top); inset.right = Math.max(0, bounds.right - displayWidth + inset.right); inset.bottom = Math.max(0, bounds.bottom - displayHeight + inset.bottom); } void getBoundsByRotation(Rect outBounds, int rotation) { final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final int dw = rotated ? mHeight : mWidth; Loading services/core/java/com/android/server/wm/Task.java +28 −12 Original line number Diff line number Diff line Loading @@ -2825,9 +2825,7 @@ class Task extends WindowContainer<WindowContainer> { getResolvedOverrideConfiguration().windowConfiguration.getBounds(); if (windowingMode == WINDOWING_MODE_FULLSCREEN) { computeFullscreenBounds(outOverrideBounds, null /* refActivity */, newParentConfig.windowConfiguration.getBounds(), newParentConfig.orientation); computeFullscreenBounds(outOverrideBounds, newParentConfig); // The bounds for fullscreen mode shouldn't be adjusted by minimal size. Otherwise if // the parent or display is smaller than the size, the content may be cropped. return; Loading Loading @@ -2867,19 +2865,19 @@ class Task extends WindowContainer<WindowContainer> { * {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN} when the parent doesn't handle the * orientation change and the requested orientation is different from the parent. */ void computeFullscreenBounds(@NonNull Rect outBounds, @Nullable ActivityRecord refActivity, @NonNull Rect parentBounds, int parentOrientation) { void computeFullscreenBounds(@NonNull Rect outBounds, @NonNull Configuration newParentConfig) { // In FULLSCREEN mode, always start with empty bounds to indicate "fill parent". outBounds.setEmpty(); if (handlesOrientationChangeFromDescendant()) { // No need to letterbox at task level. Display will handle fixed-orientation requests. return; } if (refActivity == null) { final int parentOrientation = newParentConfig.orientation; // Use the top activity as the reference of orientation. Don't include overlays because // it is usually not the actual content or just temporarily shown. // E.g. ForcedResizableInfoActivity. refActivity = getTopNonFinishingActivity(false /* includeOverlays */); } final ActivityRecord refActivity = getTopNonFinishingActivity(false /* includeOverlays */); // If the task or the reference activity requires a different orientation (either by // override or activityInfo), make it fit the available bounds by scaling down its bounds. Loading @@ -2891,11 +2889,17 @@ class Task extends WindowContainer<WindowContainer> { return; } if (refActivity != null && refActivity.hasCompatDisplayInsets()) { final ActivityRecord.CompatDisplayInsets compatDisplayInsets = refActivity == null ? null : refActivity.getCompatDisplayInsets(); if (compatDisplayInsets != null && !compatDisplayInsets.mIsTaskLetterboxed) { // App prefers to keep its original size. // If the size compat is from previous task letterboxing, we may want to have task // letterbox again, otherwise it will show the size compat restart button even if the // restart bounds will be the same. return; } final Rect parentBounds = newParentConfig.windowConfiguration.getBounds(); final int parentWidth = parentBounds.width(); final int parentHeight = parentBounds.height(); float aspect = Math.max(parentWidth, parentHeight) Loading Loading @@ -2930,6 +2934,18 @@ class Task extends WindowContainer<WindowContainer> { final int left = parentBounds.centerX() - width / 2; outBounds.set(left, parentBounds.top, left + width, parentBounds.bottom); } if (compatDisplayInsets != null) { compatDisplayInsets.getBoundsByRotation( mTmpBounds, newParentConfig.windowConfiguration.getRotation()); if (outBounds.width() != mTmpBounds.width() || outBounds.height() != mTmpBounds.height()) { // The app shouldn't be resized, we only do task letterboxing if the compat bounds // is also from the same task letterbox. Otherwise, clear the task bounds to show // app in size compat mode. outBounds.setEmpty(); } } } Rect updateOverrideConfigurationFromLaunchBounds() { Loading services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +87 −4 Original line number Diff line number Diff line Loading @@ -20,8 +20,10 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static android.view.SurfaceProto.ROTATION_180; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; Loading @@ -39,7 +41,6 @@ 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.clearInvocations; Loading Loading @@ -243,7 +244,7 @@ public class SizeCompatTests extends WindowTestsBase { // 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(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. Loading Loading @@ -729,7 +730,7 @@ public class SizeCompatTests extends WindowTestsBase { // Update with new activity requested orientation and recompute bounds with no previous // size compat cache. verify(mTask).onDescendantOrientationChanged(same(newActivity)); verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt()); verify(mTask).computeFullscreenBounds(any(), any()); final Rect displayBounds = new Rect(display.getBounds()); final Rect taskBounds = new Rect(mTask.getBounds()); Loading Loading @@ -770,7 +771,7 @@ public class SizeCompatTests extends WindowTestsBase { // Update with new activity requested orientation and recompute bounds with no previous // size compat cache. verify(mTask).onDescendantOrientationChanged(same(newActivity)); verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt()); verify(mTask).computeFullscreenBounds(any(), any()); final Rect displayBounds = new Rect(display.getBounds()); final Rect taskBounds = new Rect(mTask.getBounds()); Loading Loading @@ -821,6 +822,88 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(activityBounds, mActivity.getBounds()); } @Test public void testDisplayIgnoreOrientationRequest_rotated180_notInSizeCompat() { // 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. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT); // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); // Rotate display to portrait. rotateDisplay(display, ROTATION_90); // App should be in size compat. assertFalse(mTask.isTaskLetterboxed()); assertScaled(); // Rotate display to landscape. rotateDisplay(display, ROTATION_180); // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); } @Test public void testDisplayIgnoreOrientationRequestWithInsets_rotated180_notInSizeCompat() { // Set up a display in portrait with display cutout and ignoring orientation request. final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1400, 2800) .setNotch(75) .build(); setUpApp(display); display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); // Landscape fixed app. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_LANDSCAPE); // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); // Rotate display to portrait. rotateDisplay(display, ROTATION_90); // App should be in size compat. assertFalse(mTask.isTaskLetterboxed()); assertScaled(); // Rotate display to landscape. rotateDisplay(display, ROTATION_180); // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); } @Test public void testTaskDisplayAreaNotFillDisplay() { setUpDisplaySizeWithApp(1400, 2800); final DisplayContent display = mActivity.mDisplayContent; final TaskDisplayArea taskDisplayArea = mActivity.getDisplayArea(); taskDisplayArea.setBounds(0, 0, 1000, 2400); // Portrait fixed app. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_LANDSCAPE); final Rect displayBounds = new Rect(display.getBounds()); assertEquals(ORIENTATION_LANDSCAPE, display.getConfiguration().orientation); assertEquals(2800, displayBounds.width()); assertEquals(1400, displayBounds.height()); taskDisplayArea.setBounds(0, 0, 2400, 1000); final Rect activityBounds = new Rect(mActivity.getBounds()); assertFalse(mActivity.inSizeCompatMode()); assertEquals(2400, activityBounds.width()); assertEquals(1000, activityBounds.height()); } private static WindowState addWindowToActivity(ActivityRecord activity) { final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +48 −21 Original line number Diff line number Diff line Loading @@ -6492,8 +6492,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mLastReportedConfiguration.setConfiguration(global, override); } boolean hasCompatDisplayInsets() { return mCompatDisplayInsets != null; @Nullable CompatDisplayInsets getCompatDisplayInsets() { return mCompatDisplayInsets; } /** Loading Loading @@ -7816,13 +7817,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** * The precomputed insets of the display in each rotation. This is used to make the size * compatibility mode activity compute the configuration without relying on its current display. * This currently only supports fullscreen and freeform windowing mode. */ static class CompatDisplayInsets { /** The container width on rotation 0. */ private final int mWidth; /** The container height on rotation 0. */ private final int mHeight; /** Whether the {@link Task} windowingMode represents a floating window*/ final boolean mIsFloating; /** Whether the {@link Task} is letterboxed when the unresizable activity is first shown. */ final boolean mIsTaskLetterboxed; /** * The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. It * is used to compute the appBounds. Loading @@ -7849,27 +7853,24 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mNonDecorInsets[rotation] = emptyRect; mStableInsets[rotation] = emptyRect; } mIsTaskLetterboxed = false; return; } final Task task = container.getTask(); if (task != null && task.isTaskLetterboxed()) { // For apps in Task letterbox, it should fill the task bounds. final Point dimensions = getRotationZeroDimensions(task); mWidth = dimensions.x; mHeight = dimensions.y; } else { // If the activity is not floating nor letterboxed, assume it fills the root. final RootDisplayArea root = container.getRootDisplayArea(); if (root == null || root == display) { mWidth = display.mBaseDisplayWidth; mHeight = display.mBaseDisplayHeight; } else { final Point dimensions = getRotationZeroDimensions(root); mIsTaskLetterboxed = task != null && task.isTaskLetterboxed(); // Store the bounds of the Task for the non-resizable activity to use in size compat // mode so that the activity will not be resized regardless the windowing mode it is // currently in. final WindowContainer filledContainer = task != null ? task : display; final Point dimensions = getRotationZeroDimensions(filledContainer); mWidth = dimensions.x; mHeight = dimensions.y; } } // Bounds of the filled container if it doesn't fill the display. final Rect unfilledContainerBounds = filledContainer.getBounds().equals(display.getBounds()) ? null : new Rect(); final DisplayPolicy policy = display.getDisplayPolicy(); for (int rotation = 0; rotation < 4; rotation++) { mNonDecorInsets[rotation] = new Rect(); Loading @@ -7882,6 +7883,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]); mStableInsets[rotation].set(mNonDecorInsets[rotation]); policy.convertNonDecorInsetsToStableInsets(mStableInsets[rotation], rotation); if (unfilledContainerBounds == null) { continue; } // The insets is based on the display, but the container may be smaller than the // display, so update the insets to exclude parts that are not intersected with the // container. unfilledContainerBounds.set(filledContainer.getBounds()); display.rotateBounds( filledContainer.getConfiguration().windowConfiguration.getRotation(), rotation, unfilledContainerBounds); updateInsetsForBounds(unfilledContainerBounds, dw, dh, mNonDecorInsets[rotation]); updateInsetsForBounds(unfilledContainerBounds, dw, dh, mStableInsets[rotation]); } } Loading @@ -7899,6 +7914,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return rotated ? new Point(height, width) : new Point(width, height); } /** * Updates the display insets to exclude the parts that are not intersected with the given * bounds. */ private static void updateInsetsForBounds(Rect bounds, int displayWidth, int displayHeight, Rect inset) { inset.left = Math.max(0, inset.left - bounds.left); inset.top = Math.max(0, inset.top - bounds.top); inset.right = Math.max(0, bounds.right - displayWidth + inset.right); inset.bottom = Math.max(0, bounds.bottom - displayHeight + inset.bottom); } void getBoundsByRotation(Rect outBounds, int rotation) { final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final int dw = rotated ? mHeight : mWidth; Loading
services/core/java/com/android/server/wm/Task.java +28 −12 Original line number Diff line number Diff line Loading @@ -2825,9 +2825,7 @@ class Task extends WindowContainer<WindowContainer> { getResolvedOverrideConfiguration().windowConfiguration.getBounds(); if (windowingMode == WINDOWING_MODE_FULLSCREEN) { computeFullscreenBounds(outOverrideBounds, null /* refActivity */, newParentConfig.windowConfiguration.getBounds(), newParentConfig.orientation); computeFullscreenBounds(outOverrideBounds, newParentConfig); // The bounds for fullscreen mode shouldn't be adjusted by minimal size. Otherwise if // the parent or display is smaller than the size, the content may be cropped. return; Loading Loading @@ -2867,19 +2865,19 @@ class Task extends WindowContainer<WindowContainer> { * {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN} when the parent doesn't handle the * orientation change and the requested orientation is different from the parent. */ void computeFullscreenBounds(@NonNull Rect outBounds, @Nullable ActivityRecord refActivity, @NonNull Rect parentBounds, int parentOrientation) { void computeFullscreenBounds(@NonNull Rect outBounds, @NonNull Configuration newParentConfig) { // In FULLSCREEN mode, always start with empty bounds to indicate "fill parent". outBounds.setEmpty(); if (handlesOrientationChangeFromDescendant()) { // No need to letterbox at task level. Display will handle fixed-orientation requests. return; } if (refActivity == null) { final int parentOrientation = newParentConfig.orientation; // Use the top activity as the reference of orientation. Don't include overlays because // it is usually not the actual content or just temporarily shown. // E.g. ForcedResizableInfoActivity. refActivity = getTopNonFinishingActivity(false /* includeOverlays */); } final ActivityRecord refActivity = getTopNonFinishingActivity(false /* includeOverlays */); // If the task or the reference activity requires a different orientation (either by // override or activityInfo), make it fit the available bounds by scaling down its bounds. Loading @@ -2891,11 +2889,17 @@ class Task extends WindowContainer<WindowContainer> { return; } if (refActivity != null && refActivity.hasCompatDisplayInsets()) { final ActivityRecord.CompatDisplayInsets compatDisplayInsets = refActivity == null ? null : refActivity.getCompatDisplayInsets(); if (compatDisplayInsets != null && !compatDisplayInsets.mIsTaskLetterboxed) { // App prefers to keep its original size. // If the size compat is from previous task letterboxing, we may want to have task // letterbox again, otherwise it will show the size compat restart button even if the // restart bounds will be the same. return; } final Rect parentBounds = newParentConfig.windowConfiguration.getBounds(); final int parentWidth = parentBounds.width(); final int parentHeight = parentBounds.height(); float aspect = Math.max(parentWidth, parentHeight) Loading Loading @@ -2930,6 +2934,18 @@ class Task extends WindowContainer<WindowContainer> { final int left = parentBounds.centerX() - width / 2; outBounds.set(left, parentBounds.top, left + width, parentBounds.bottom); } if (compatDisplayInsets != null) { compatDisplayInsets.getBoundsByRotation( mTmpBounds, newParentConfig.windowConfiguration.getRotation()); if (outBounds.width() != mTmpBounds.width() || outBounds.height() != mTmpBounds.height()) { // The app shouldn't be resized, we only do task letterboxing if the compat bounds // is also from the same task letterbox. Otherwise, clear the task bounds to show // app in size compat mode. outBounds.setEmpty(); } } } Rect updateOverrideConfigurationFromLaunchBounds() { Loading
services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +87 −4 Original line number Diff line number Diff line Loading @@ -20,8 +20,10 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static android.view.SurfaceProto.ROTATION_180; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; Loading @@ -39,7 +41,6 @@ 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.clearInvocations; Loading Loading @@ -243,7 +244,7 @@ public class SizeCompatTests extends WindowTestsBase { // 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(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. Loading Loading @@ -729,7 +730,7 @@ public class SizeCompatTests extends WindowTestsBase { // Update with new activity requested orientation and recompute bounds with no previous // size compat cache. verify(mTask).onDescendantOrientationChanged(same(newActivity)); verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt()); verify(mTask).computeFullscreenBounds(any(), any()); final Rect displayBounds = new Rect(display.getBounds()); final Rect taskBounds = new Rect(mTask.getBounds()); Loading Loading @@ -770,7 +771,7 @@ public class SizeCompatTests extends WindowTestsBase { // Update with new activity requested orientation and recompute bounds with no previous // size compat cache. verify(mTask).onDescendantOrientationChanged(same(newActivity)); verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt()); verify(mTask).computeFullscreenBounds(any(), any()); final Rect displayBounds = new Rect(display.getBounds()); final Rect taskBounds = new Rect(mTask.getBounds()); Loading Loading @@ -821,6 +822,88 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(activityBounds, mActivity.getBounds()); } @Test public void testDisplayIgnoreOrientationRequest_rotated180_notInSizeCompat() { // 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. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT); // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); // Rotate display to portrait. rotateDisplay(display, ROTATION_90); // App should be in size compat. assertFalse(mTask.isTaskLetterboxed()); assertScaled(); // Rotate display to landscape. rotateDisplay(display, ROTATION_180); // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); } @Test public void testDisplayIgnoreOrientationRequestWithInsets_rotated180_notInSizeCompat() { // Set up a display in portrait with display cutout and ignoring orientation request. final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1400, 2800) .setNotch(75) .build(); setUpApp(display); display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); // Landscape fixed app. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_LANDSCAPE); // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); // Rotate display to portrait. rotateDisplay(display, ROTATION_90); // App should be in size compat. assertFalse(mTask.isTaskLetterboxed()); assertScaled(); // Rotate display to landscape. rotateDisplay(display, ROTATION_180); // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); } @Test public void testTaskDisplayAreaNotFillDisplay() { setUpDisplaySizeWithApp(1400, 2800); final DisplayContent display = mActivity.mDisplayContent; final TaskDisplayArea taskDisplayArea = mActivity.getDisplayArea(); taskDisplayArea.setBounds(0, 0, 1000, 2400); // Portrait fixed app. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_LANDSCAPE); final Rect displayBounds = new Rect(display.getBounds()); assertEquals(ORIENTATION_LANDSCAPE, display.getConfiguration().orientation); assertEquals(2800, displayBounds.width()); assertEquals(1400, displayBounds.height()); taskDisplayArea.setBounds(0, 0, 2400, 1000); final Rect activityBounds = new Rect(mActivity.getBounds()); assertFalse(mActivity.inSizeCompatMode()); assertEquals(2400, activityBounds.width()); assertEquals(1000, activityBounds.height()); } private static WindowState addWindowToActivity(ActivityRecord activity) { final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; Loading