Loading services/core/java/com/android/server/wm/ActivityRecord.java +59 −3 Original line number Diff line number Diff line Loading @@ -88,6 +88,8 @@ import static android.os.Build.VERSION_CODES.HONEYCOMB; import static android.os.Build.VERSION_CODES.O; import static android.os.Process.SYSTEM_UID; import static android.view.Display.INVALID_DISPLAY; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER; import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK; Loading Loading @@ -195,6 +197,7 @@ import android.util.Slog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.view.AppTransitionAnimationSpec; import android.view.DisplayCutout; import android.view.IAppTransitionAnimationSpecsFuture; import android.view.IApplicationToken; import android.view.RemoteAnimationDefinition; Loading Loading @@ -382,6 +385,12 @@ final class ActivityRecord extends ConfigurationContainer { private int[] mHorizontalSizeConfigurations; private int[] mSmallestSizeConfigurations; /** * The precomputed display insets for resolving configuration. It will be non-null if * {@link #shouldUseSizeCompatMode} returns {@code true}. */ private CompatDisplayInsets mCompatDisplayInsets; boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session IVoiceInteractionSession voiceSession; // Voice interaction session for this activity Loading Loading @@ -2833,6 +2842,11 @@ final class ActivityRecord extends ConfigurationContainer { // The smallest screen width is the short side of screen bounds. Because the bounds // and density won't be changed, smallestScreenWidthDp is also fixed. overrideConfig.smallestScreenWidthDp = parentConfig.smallestScreenWidthDp; final ActivityDisplay display = getDisplay(); if (display != null && display.mDisplayContent != null) { mCompatDisplayInsets = new CompatDisplayInsets(display.mDisplayContent); } } } onRequestedOverrideConfigurationChanged(overrideConfig); Loading @@ -2849,7 +2863,7 @@ final class ActivityRecord extends ConfigurationContainer { super.resolveOverrideConfiguration(newParentConfiguration); if (hasOverrideBounds) { task.computeConfigResourceOverrides(getResolvedOverrideConfiguration(), newParentConfiguration, true /* insideParentBounds */); newParentConfiguration); } } Loading Loading @@ -2922,9 +2936,8 @@ final class ActivityRecord extends ConfigurationContainer { resolvedBounds.right -= resolvedAppBounds.left; } // In size compatibility mode, activity is allowed to have larger bounds than its parent. task.computeConfigResourceOverrides(resolvedConfig, newParentConfiguration, false /* insideParentBounds */); mCompatDisplayInsets); // Use parent orientation if it cannot be decided by bounds, so the activity can fit inside // the parent bounds appropriately. if (resolvedConfig.screenWidthDp == resolvedConfig.screenHeightDp) { Loading Loading @@ -3450,6 +3463,7 @@ final class ActivityRecord extends ConfigurationContainer { // configuration. getRequestedOverrideConfiguration().setToDefaults(); getResolvedOverrideConfiguration().setToDefaults(); mCompatDisplayInsets = null; if (visible) { // Configuration will be ensured when becoming visible, so if it is already visible, // then the manual update is needed. Loading Loading @@ -3796,4 +3810,46 @@ final class ActivityRecord extends ConfigurationContainer { writeToProto(proto); proto.end(token); } /** * 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. */ static class CompatDisplayInsets { final int mDisplayWidth; final int mDisplayHeight; /** The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. */ final Rect[] mNonDecorInsets = new Rect[4]; /** * The stableInsets for each rotation. Includes the status bar inset and the * nonDecorInsets. It is used to compute {@link Configuration#screenWidthDp} and * {@link Configuration#screenHeightDp}. */ final Rect[] mStableInsets = new Rect[4]; CompatDisplayInsets(DisplayContent display) { mDisplayWidth = display.mBaseDisplayWidth; mDisplayHeight = display.mBaseDisplayHeight; final DisplayPolicy policy = display.getDisplayPolicy(); final DisplayCutout cutout = display.getDisplayInfo().displayCutout; for (int rotation = 0; rotation < 4; rotation++) { mNonDecorInsets[rotation] = new Rect(); mStableInsets[rotation] = new Rect(); final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final int dw = rotated ? mDisplayHeight : mDisplayWidth; final int dh = rotated ? mDisplayWidth : mDisplayHeight; policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]); mStableInsets[rotation].set(mNonDecorInsets[rotation]); policy.convertNonDecorInsetsToStableInsets(mStableInsets[rotation], rotation); } } void getDisplayBounds(Rect outBounds, int rotation) { final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final int dw = rotated ? mDisplayHeight : mDisplayWidth; final int dh = rotated ? mDisplayWidth : mDisplayHeight; outBounds.set(0, 0, dw, dh); } } } services/core/java/com/android/server/wm/DisplayPolicy.java +11 −1 Original line number Diff line number Diff line Loading @@ -2774,6 +2774,16 @@ public class DisplayPolicy { return mShowingDream; } /** * Calculates the stable insets if we already have the non-decor insets. * * @param inOutInsets The known non-decor insets. It will be modified to stable insets. * @param rotation The current display rotation. */ void convertNonDecorInsetsToStableInsets(Rect inOutInsets, int rotation) { inOutInsets.top = Math.max(inOutInsets.top, mStatusBarHeightForRotation[rotation]); } /** * Calculates the stable insets without running a layout. * Loading @@ -2789,7 +2799,7 @@ public class DisplayPolicy { // Navigation bar and status bar. getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, displayCutout, outInsets); outInsets.top = Math.max(outInsets.top, mStatusBarHeightForRotation[displayRotation]); convertNonDecorInsetsToStableInsets(outInsets, displayRotation); } /** Loading services/core/java/com/android/server/wm/TaskRecord.java +23 −10 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED; import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.ROTATION_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; Loading Loading @@ -2048,15 +2049,12 @@ class TaskRecord extends ConfigurationContainer { } mTmpBounds.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); policy.getStableInsetsLw(displayInfo.rotation, displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout, mTmpInsets); intersectWithInsetsIfFits(outStableBounds, mTmpBounds, mTmpInsets); policy.getNonDecorInsetsLw(displayInfo.rotation, displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout, mTmpInsets); policy.getNonDecorInsetsLw(displayInfo.rotation, displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout, mTmpInsets); intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, mTmpInsets); policy.convertNonDecorInsetsToStableInsets(mTmpInsets, displayInfo.rotation); intersectWithInsetsIfFits(outStableBounds, mTmpBounds, mTmpInsets); } /** Loading @@ -2073,7 +2071,7 @@ class TaskRecord extends ConfigurationContainer { void computeConfigResourceOverrides(@NonNull Configuration inOutConfig, @NonNull Configuration parentConfig) { computeConfigResourceOverrides(inOutConfig, parentConfig, true /* insideParentBounds */); computeConfigResourceOverrides(inOutConfig, parentConfig, null /* compatInsets */); } /** Loading @@ -2085,7 +2083,8 @@ class TaskRecord extends ConfigurationContainer { * just be inherited from the parent configuration. **/ void computeConfigResourceOverrides(@NonNull Configuration inOutConfig, @NonNull Configuration parentConfig, boolean insideParentBounds) { @NonNull Configuration parentConfig, @Nullable ActivityRecord.CompatDisplayInsets compatInsets) { int windowingMode = inOutConfig.windowConfiguration.getWindowingMode(); if (windowingMode == WINDOWING_MODE_UNDEFINED) { windowingMode = parentConfig.windowConfiguration.getWindowingMode(); Loading @@ -2103,6 +2102,9 @@ class TaskRecord extends ConfigurationContainer { inOutConfig.windowConfiguration.setAppBounds(bounds); outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); } // Non-null compatibility insets means the activity prefers to keep its original size, so // the out bounds doesn't need to be restricted by the parent. final boolean insideParentBounds = compatInsets == null; if (insideParentBounds && windowingMode != WINDOWING_MODE_FREEFORM) { final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds(); if (parentAppBounds != null && !parentAppBounds.isEmpty()) { Loading @@ -2125,6 +2127,17 @@ class TaskRecord extends ConfigurationContainer { // Set to app bounds because it excludes decor insets. mTmpNonDecorBounds.set(outAppBounds); mTmpStableBounds.set(outAppBounds); // Apply the given non-decor and stable insets to calculate the corresponding bounds // for screen size of configuration. final int rotation = parentConfig.windowConfiguration.getRotation(); if (rotation != ROTATION_UNDEFINED && compatInsets != null) { compatInsets.getDisplayBounds(mTmpBounds, rotation); intersectWithInsetsIfFits(mTmpNonDecorBounds, mTmpBounds, compatInsets.mNonDecorInsets[rotation]); intersectWithInsetsIfFits(mTmpStableBounds, mTmpBounds, compatInsets.mStableInsets[rotation]); } } if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) { Loading services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +5 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.MergedConfiguration; import android.util.MutableBoolean; import android.view.DisplayInfo; import androidx.test.filters.MediumTest; Loading Loading @@ -87,6 +88,10 @@ public class ActivityRecordTests extends ActivityTestsBase { doReturn(false).when(mService).isBooting(); doReturn(true).when(mService).isBooted(); final DisplayContent displayContent = mStack.getDisplay().mDisplayContent; doReturn(mock(DisplayPolicy.class)).when(displayContent).getDisplayPolicy(); doReturn(mock(DisplayInfo.class)).when(displayContent).getDisplayInfo(); } @Test Loading services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +24 −3 Original line number Diff line number Diff line Loading @@ -25,7 +25,10 @@ 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.util.DisplayMetrics.DENSITY_DEFAULT; import static android.view.Surface.ROTATION_0; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static org.hamcrest.Matchers.not; Loading @@ -35,6 +38,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import android.app.ActivityManager; Loading Loading @@ -357,6 +362,7 @@ public class TaskRecordTests extends ActivityTestsBase { parentConfig.densityDpi = 400; parentConfig.screenHeightDp = 200; // 200 * 400 / 160 = 500px parentConfig.screenWidthDp = 100; // 100 * 400 / 160 = 250px parentConfig.windowConfiguration.setRotation(ROTATION_0); // Portrait bounds. inOutConfig.windowConfiguration.getBounds().set(0, 0, shortSide, longSide); Loading @@ -370,12 +376,27 @@ public class TaskRecordTests extends ActivityTestsBase { inOutConfig.setToDefaults(); // Landscape bounds. inOutConfig.windowConfiguration.getBounds().set(0, 0, longSide, shortSide); // Setup the display with a top stable inset. The later assertion will ensure the inset is // excluded from screenHeightDp. final int statusBarHeight = 100; final DisplayContent displayContent = mock(DisplayContent.class); final DisplayPolicy policy = mock(DisplayPolicy.class); doAnswer(invocationOnMock -> { final Rect insets = invocationOnMock.<Rect>getArgument(0); insets.top = statusBarHeight; return null; }).when(policy).convertNonDecorInsetsToStableInsets(any(), eq(ROTATION_0)); doReturn(policy).when(displayContent).getDisplayPolicy(); doReturn(mock(DisplayInfo.class)).when(displayContent).getDisplayInfo(); // Without limiting to be inside the parent bounds, the out screen size should keep relative // to the input bounds. task.computeConfigResourceOverrides(inOutConfig, parentConfig, false /* insideParentBounds */); final ActivityRecord.CompatDisplayInsets compatIntsets = new ActivityRecord.CompatDisplayInsets(displayContent); task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatIntsets); assertEquals(shortSide * DENSITY_DEFAULT / parentConfig.densityDpi, assertEquals((shortSide - statusBarHeight) * DENSITY_DEFAULT / parentConfig.densityDpi, inOutConfig.screenHeightDp); assertEquals(longSide * DENSITY_DEFAULT / parentConfig.densityDpi, inOutConfig.screenWidthDp); Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +59 −3 Original line number Diff line number Diff line Loading @@ -88,6 +88,8 @@ import static android.os.Build.VERSION_CODES.HONEYCOMB; import static android.os.Build.VERSION_CODES.O; import static android.os.Process.SYSTEM_UID; import static android.view.Display.INVALID_DISPLAY; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER; import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK; Loading Loading @@ -195,6 +197,7 @@ import android.util.Slog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.view.AppTransitionAnimationSpec; import android.view.DisplayCutout; import android.view.IAppTransitionAnimationSpecsFuture; import android.view.IApplicationToken; import android.view.RemoteAnimationDefinition; Loading Loading @@ -382,6 +385,12 @@ final class ActivityRecord extends ConfigurationContainer { private int[] mHorizontalSizeConfigurations; private int[] mSmallestSizeConfigurations; /** * The precomputed display insets for resolving configuration. It will be non-null if * {@link #shouldUseSizeCompatMode} returns {@code true}. */ private CompatDisplayInsets mCompatDisplayInsets; boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session IVoiceInteractionSession voiceSession; // Voice interaction session for this activity Loading Loading @@ -2833,6 +2842,11 @@ final class ActivityRecord extends ConfigurationContainer { // The smallest screen width is the short side of screen bounds. Because the bounds // and density won't be changed, smallestScreenWidthDp is also fixed. overrideConfig.smallestScreenWidthDp = parentConfig.smallestScreenWidthDp; final ActivityDisplay display = getDisplay(); if (display != null && display.mDisplayContent != null) { mCompatDisplayInsets = new CompatDisplayInsets(display.mDisplayContent); } } } onRequestedOverrideConfigurationChanged(overrideConfig); Loading @@ -2849,7 +2863,7 @@ final class ActivityRecord extends ConfigurationContainer { super.resolveOverrideConfiguration(newParentConfiguration); if (hasOverrideBounds) { task.computeConfigResourceOverrides(getResolvedOverrideConfiguration(), newParentConfiguration, true /* insideParentBounds */); newParentConfiguration); } } Loading Loading @@ -2922,9 +2936,8 @@ final class ActivityRecord extends ConfigurationContainer { resolvedBounds.right -= resolvedAppBounds.left; } // In size compatibility mode, activity is allowed to have larger bounds than its parent. task.computeConfigResourceOverrides(resolvedConfig, newParentConfiguration, false /* insideParentBounds */); mCompatDisplayInsets); // Use parent orientation if it cannot be decided by bounds, so the activity can fit inside // the parent bounds appropriately. if (resolvedConfig.screenWidthDp == resolvedConfig.screenHeightDp) { Loading Loading @@ -3450,6 +3463,7 @@ final class ActivityRecord extends ConfigurationContainer { // configuration. getRequestedOverrideConfiguration().setToDefaults(); getResolvedOverrideConfiguration().setToDefaults(); mCompatDisplayInsets = null; if (visible) { // Configuration will be ensured when becoming visible, so if it is already visible, // then the manual update is needed. Loading Loading @@ -3796,4 +3810,46 @@ final class ActivityRecord extends ConfigurationContainer { writeToProto(proto); proto.end(token); } /** * 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. */ static class CompatDisplayInsets { final int mDisplayWidth; final int mDisplayHeight; /** The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. */ final Rect[] mNonDecorInsets = new Rect[4]; /** * The stableInsets for each rotation. Includes the status bar inset and the * nonDecorInsets. It is used to compute {@link Configuration#screenWidthDp} and * {@link Configuration#screenHeightDp}. */ final Rect[] mStableInsets = new Rect[4]; CompatDisplayInsets(DisplayContent display) { mDisplayWidth = display.mBaseDisplayWidth; mDisplayHeight = display.mBaseDisplayHeight; final DisplayPolicy policy = display.getDisplayPolicy(); final DisplayCutout cutout = display.getDisplayInfo().displayCutout; for (int rotation = 0; rotation < 4; rotation++) { mNonDecorInsets[rotation] = new Rect(); mStableInsets[rotation] = new Rect(); final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final int dw = rotated ? mDisplayHeight : mDisplayWidth; final int dh = rotated ? mDisplayWidth : mDisplayHeight; policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]); mStableInsets[rotation].set(mNonDecorInsets[rotation]); policy.convertNonDecorInsetsToStableInsets(mStableInsets[rotation], rotation); } } void getDisplayBounds(Rect outBounds, int rotation) { final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final int dw = rotated ? mDisplayHeight : mDisplayWidth; final int dh = rotated ? mDisplayWidth : mDisplayHeight; outBounds.set(0, 0, dw, dh); } } }
services/core/java/com/android/server/wm/DisplayPolicy.java +11 −1 Original line number Diff line number Diff line Loading @@ -2774,6 +2774,16 @@ public class DisplayPolicy { return mShowingDream; } /** * Calculates the stable insets if we already have the non-decor insets. * * @param inOutInsets The known non-decor insets. It will be modified to stable insets. * @param rotation The current display rotation. */ void convertNonDecorInsetsToStableInsets(Rect inOutInsets, int rotation) { inOutInsets.top = Math.max(inOutInsets.top, mStatusBarHeightForRotation[rotation]); } /** * Calculates the stable insets without running a layout. * Loading @@ -2789,7 +2799,7 @@ public class DisplayPolicy { // Navigation bar and status bar. getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, displayCutout, outInsets); outInsets.top = Math.max(outInsets.top, mStatusBarHeightForRotation[displayRotation]); convertNonDecorInsetsToStableInsets(outInsets, displayRotation); } /** Loading
services/core/java/com/android/server/wm/TaskRecord.java +23 −10 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED; import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.ROTATION_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; Loading Loading @@ -2048,15 +2049,12 @@ class TaskRecord extends ConfigurationContainer { } mTmpBounds.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); policy.getStableInsetsLw(displayInfo.rotation, displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout, mTmpInsets); intersectWithInsetsIfFits(outStableBounds, mTmpBounds, mTmpInsets); policy.getNonDecorInsetsLw(displayInfo.rotation, displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout, mTmpInsets); policy.getNonDecorInsetsLw(displayInfo.rotation, displayInfo.logicalWidth, displayInfo.logicalHeight, displayInfo.displayCutout, mTmpInsets); intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, mTmpInsets); policy.convertNonDecorInsetsToStableInsets(mTmpInsets, displayInfo.rotation); intersectWithInsetsIfFits(outStableBounds, mTmpBounds, mTmpInsets); } /** Loading @@ -2073,7 +2071,7 @@ class TaskRecord extends ConfigurationContainer { void computeConfigResourceOverrides(@NonNull Configuration inOutConfig, @NonNull Configuration parentConfig) { computeConfigResourceOverrides(inOutConfig, parentConfig, true /* insideParentBounds */); computeConfigResourceOverrides(inOutConfig, parentConfig, null /* compatInsets */); } /** Loading @@ -2085,7 +2083,8 @@ class TaskRecord extends ConfigurationContainer { * just be inherited from the parent configuration. **/ void computeConfigResourceOverrides(@NonNull Configuration inOutConfig, @NonNull Configuration parentConfig, boolean insideParentBounds) { @NonNull Configuration parentConfig, @Nullable ActivityRecord.CompatDisplayInsets compatInsets) { int windowingMode = inOutConfig.windowConfiguration.getWindowingMode(); if (windowingMode == WINDOWING_MODE_UNDEFINED) { windowingMode = parentConfig.windowConfiguration.getWindowingMode(); Loading @@ -2103,6 +2102,9 @@ class TaskRecord extends ConfigurationContainer { inOutConfig.windowConfiguration.setAppBounds(bounds); outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); } // Non-null compatibility insets means the activity prefers to keep its original size, so // the out bounds doesn't need to be restricted by the parent. final boolean insideParentBounds = compatInsets == null; if (insideParentBounds && windowingMode != WINDOWING_MODE_FREEFORM) { final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds(); if (parentAppBounds != null && !parentAppBounds.isEmpty()) { Loading @@ -2125,6 +2127,17 @@ class TaskRecord extends ConfigurationContainer { // Set to app bounds because it excludes decor insets. mTmpNonDecorBounds.set(outAppBounds); mTmpStableBounds.set(outAppBounds); // Apply the given non-decor and stable insets to calculate the corresponding bounds // for screen size of configuration. final int rotation = parentConfig.windowConfiguration.getRotation(); if (rotation != ROTATION_UNDEFINED && compatInsets != null) { compatInsets.getDisplayBounds(mTmpBounds, rotation); intersectWithInsetsIfFits(mTmpNonDecorBounds, mTmpBounds, compatInsets.mNonDecorInsets[rotation]); intersectWithInsetsIfFits(mTmpStableBounds, mTmpBounds, compatInsets.mStableInsets[rotation]); } } if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) { Loading
services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +5 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.MergedConfiguration; import android.util.MutableBoolean; import android.view.DisplayInfo; import androidx.test.filters.MediumTest; Loading Loading @@ -87,6 +88,10 @@ public class ActivityRecordTests extends ActivityTestsBase { doReturn(false).when(mService).isBooting(); doReturn(true).when(mService).isBooted(); final DisplayContent displayContent = mStack.getDisplay().mDisplayContent; doReturn(mock(DisplayPolicy.class)).when(displayContent).getDisplayPolicy(); doReturn(mock(DisplayInfo.class)).when(displayContent).getDisplayInfo(); } @Test Loading
services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +24 −3 Original line number Diff line number Diff line Loading @@ -25,7 +25,10 @@ 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.util.DisplayMetrics.DENSITY_DEFAULT; import static android.view.Surface.ROTATION_0; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static org.hamcrest.Matchers.not; Loading @@ -35,6 +38,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import android.app.ActivityManager; Loading Loading @@ -357,6 +362,7 @@ public class TaskRecordTests extends ActivityTestsBase { parentConfig.densityDpi = 400; parentConfig.screenHeightDp = 200; // 200 * 400 / 160 = 500px parentConfig.screenWidthDp = 100; // 100 * 400 / 160 = 250px parentConfig.windowConfiguration.setRotation(ROTATION_0); // Portrait bounds. inOutConfig.windowConfiguration.getBounds().set(0, 0, shortSide, longSide); Loading @@ -370,12 +376,27 @@ public class TaskRecordTests extends ActivityTestsBase { inOutConfig.setToDefaults(); // Landscape bounds. inOutConfig.windowConfiguration.getBounds().set(0, 0, longSide, shortSide); // Setup the display with a top stable inset. The later assertion will ensure the inset is // excluded from screenHeightDp. final int statusBarHeight = 100; final DisplayContent displayContent = mock(DisplayContent.class); final DisplayPolicy policy = mock(DisplayPolicy.class); doAnswer(invocationOnMock -> { final Rect insets = invocationOnMock.<Rect>getArgument(0); insets.top = statusBarHeight; return null; }).when(policy).convertNonDecorInsetsToStableInsets(any(), eq(ROTATION_0)); doReturn(policy).when(displayContent).getDisplayPolicy(); doReturn(mock(DisplayInfo.class)).when(displayContent).getDisplayInfo(); // Without limiting to be inside the parent bounds, the out screen size should keep relative // to the input bounds. task.computeConfigResourceOverrides(inOutConfig, parentConfig, false /* insideParentBounds */); final ActivityRecord.CompatDisplayInsets compatIntsets = new ActivityRecord.CompatDisplayInsets(displayContent); task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatIntsets); assertEquals(shortSide * DENSITY_DEFAULT / parentConfig.densityDpi, assertEquals((shortSide - statusBarHeight) * DENSITY_DEFAULT / parentConfig.densityDpi, inOutConfig.screenHeightDp); assertEquals(longSide * DENSITY_DEFAULT / parentConfig.densityDpi, inOutConfig.screenWidthDp); Loading