Loading services/core/java/com/android/server/wm/ActivityRecord.java +1 −2 Original line number Diff line number Diff line Loading @@ -6171,8 +6171,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // The rest of the condition is that only one side is smaller than the parent, but it still // needs to exclude the cases where the size is limited by the fixed aspect ratio. if (info.maxAspectRatio > 0) { final float aspectRatio = (0.5f + Math.max(appWidth, appHeight)) / Math.min(appWidth, appHeight); final float aspectRatio = Math.max(appWidth, appHeight) / Math.min(appWidth, appHeight); if (aspectRatio >= info.maxAspectRatio) { // The current size has reached the max aspect ratio. return false; Loading services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java +0 −55 Original line number Diff line number Diff line Loading @@ -38,12 +38,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.when; import android.app.TaskStackListener; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.os.IBinder; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; Loading @@ -51,10 +46,6 @@ import androidx.test.filters.SmallTest; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; /** * Tests for the {@link ActivityDisplay} class. * Loading Loading @@ -331,50 +322,4 @@ public class ActivityDisplayTests extends ActivityTestsBase { verify(mSupervisor).removeTaskByIdLocked(eq(task1.mTaskId), anyBoolean(), anyBoolean(), any()); } /** * Ensures that {@link TaskStackListener} can receive callback about the activity in size * compatibility mode. */ @Test public void testHandleActivitySizeCompatMode() throws Exception { final ActivityDisplay display = mRootActivityContainer.getDefaultDisplay(); final ActivityRecord activity = createFullscreenStackWithSimpleActivityAt( display).topRunningActivityLocked(); activity.setState(ActivityStack.ActivityState.RESUMED, "testHandleActivitySizeCompatMode"); when(activity.getRequestedOrientation()).thenReturn( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); activity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; activity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; activity.visible = true; activity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */); final ArrayList<CompletableFuture<IBinder>> resultWrapper = new ArrayList<>(); mService.getTaskChangeNotificationController().registerTaskStackListener( new TaskStackListener() { @Override public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken) { resultWrapper.get(0).complete(activityToken); } }); resultWrapper.add(new CompletableFuture<>()); // resize the display to exercise size-compat mode final DisplayContent displayContent = display.mDisplayContent; displayContent.mBaseDisplayHeight = (int) (0.8f * displayContent.mBaseDisplayHeight); Configuration c = new Configuration(); displayContent.computeScreenConfiguration(c); display.onRequestedOverrideConfigurationChanged(c); assertEquals(activity.appToken, resultWrapper.get(0).get(2, TimeUnit.SECONDS)); // Expect null token when switching to non-size-compat mode activity. activity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; resultWrapper.set(0, new CompletableFuture<>()); display.handleActivitySizeCompatModeIfNeeded(activity); assertNull(resultWrapper.get(0).get(2, TimeUnit.SECONDS)); } } services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +0 −267 Original line number Diff line number Diff line Loading @@ -18,24 +18,18 @@ package com.android.server.wm; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.os.Process.NOBODY_UID; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_90; import static android.view.WindowManager.TRANSIT_TASK_CLOSE; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; 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.reset; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; Loading @@ -61,18 +55,13 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.WindowConfiguration; import android.app.servertransaction.ActivityConfigurationChangeItem; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.PauseActivityItem; Loading @@ -80,13 +69,11 @@ import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; import android.os.Bundle; import android.os.PersistableBundle; import android.platform.test.annotations.Presubmit; import android.util.MergedConfiguration; import android.util.MutableBoolean; import android.view.DisplayInfo; import android.view.IRemoteAnimationFinishedCallback; import android.view.IRemoteAnimationRunner.Stub; import android.view.RemoteAnimationAdapter; Loading Loading @@ -218,23 +205,6 @@ public class ActivityRecordTests extends ActivityTestsBase { assertFalse(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY + 1)); } @Test public void testRestartProcessIfVisible() { doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity); mActivity.visible = true; mActivity.setSavedState(null /* savedState */); mActivity.setState(ActivityStack.ActivityState.RESUMED, "testRestart"); prepareFixedAspectRatioUnresizableActivity(); final Rect originalOverrideBounds = new Rect(mActivity.getBounds()); setupDisplayAndParentSize(600, 1200); // The visible activity should recompute configuration according to the last parent bounds. mService.restartActivityProcessIfVisible(mActivity.appToken); assertEquals(ActivityStack.ActivityState.RESTARTING_PROCESS, mActivity.getState()); assertNotEquals(originalOverrideBounds, mActivity.getBounds()); } @Test public void testsApplyOptionsLocked() { ActivityOptions activityOptions = ActivityOptions.makeBasic(); Loading Loading @@ -483,214 +453,6 @@ public class ActivityRecordTests extends ActivityTestsBase { assertEquals(STARTED, mActivity.getState()); } @Test public void testSizeCompatMode_KeepBoundsWhenChangingFromFreeformToFullscreen() { setupDisplayContentForCompatDisplayInsets(); // put display in freeform mode ActivityDisplay display = mActivity.getDisplay(); final Configuration c = new Configuration(display.getRequestedOverrideConfiguration()); c.windowConfiguration.setBounds(new Rect(0, 0, 2000, 1000)); c.densityDpi = 300; c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM); display.onRequestedOverrideConfigurationChanged(c); // launch compat activity in freeform and store bounds when(mActivity.getRequestedOrientation()).thenReturn( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); mTask.getRequestedOverrideConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT; mTask.setBounds(100, 100, 400, 600); mActivity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; mActivity.visible = true; ensureActivityConfiguration(); final Rect bounds = new Rect(mActivity.getBounds()); final int density = mActivity.getConfiguration().densityDpi; // change display configuration to fullscreen c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN); display.onRequestedOverrideConfigurationChanged(c); // check if dimensions stay the same assertTrue(mActivity.inSizeCompatMode()); assertEquals(bounds.width(), mActivity.getBounds().width()); assertEquals(bounds.height(), mActivity.getBounds().height()); assertEquals(density, mActivity.getConfiguration().densityDpi); assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN, mActivity.getWindowingMode()); } @Test public void testSizeCompatMode_FixedAspectRatioBoundsWithDecor() { setupDisplayContentForCompatDisplayInsets(); final int decorHeight = 200; // e.g. The device has cutout. final DisplayPolicy policy = setupDisplayAndParentSize(600, 800).getDisplayPolicy(); spyOn(policy); doAnswer(invocationOnMock -> { final int rotation = invocationOnMock.<Integer>getArgument(0); final Rect insets = invocationOnMock.<Rect>getArgument(4); if (rotation == ROTATION_0) { insets.top = decorHeight; } else if (rotation == ROTATION_90) { insets.left = decorHeight; } return null; }).when(policy).getNonDecorInsetsLw(anyInt() /* rotation */, anyInt() /* width */, anyInt() /* height */, any() /* displayCutout */, any() /* outInsets */); // set appBounds to incorporate decor final Configuration c = new Configuration(mStack.getDisplay().getRequestedOverrideConfiguration()); c.windowConfiguration.getAppBounds().top = decorHeight; mStack.getDisplay().onRequestedOverrideConfigurationChanged(c); doReturn(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) .when(mActivity).getRequestedOrientation(); mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; mActivity.info.minAspectRatio = mActivity.info.maxAspectRatio = 1; mActivity.visible = true; ensureActivityConfiguration(); // The parent configuration doesn't change since the first resolved configuration, so the // activity shouldn't be in the size compatibility mode. assertFalse(mActivity.inSizeCompatMode()); final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds(); // Ensure the app bounds keep the declared aspect ratio. assertEquals(appBounds.width(), appBounds.height()); // The decor height should be a part of the effective bounds. assertEquals(mActivity.getBounds().height(), appBounds.height() + decorHeight); mTask.getConfiguration().windowConfiguration.setRotation(ROTATION_90); mActivity.onConfigurationChanged(mTask.getConfiguration()); // After changing orientation, the aspect ratio should be the same. assertEquals(appBounds.width(), appBounds.height()); // The decor height will be included in width. assertEquals(mActivity.getBounds().width(), appBounds.width() + decorHeight); } @Test public void testSizeCompatMode_FixedScreenConfigurationWhenMovingToDisplay() { // Initialize different bounds on a new display. final Rect newDisplayBounds = new Rect(0, 0, 1000, 2000); DisplayInfo info = new DisplayInfo(); mService.mContext.getDisplay().getDisplayInfo(info); info.logicalWidth = newDisplayBounds.width(); info.logicalHeight = newDisplayBounds.height(); info.logicalDensityDpi = 300; final ActivityDisplay newDisplay = addNewActivityDisplayAt(info, ActivityDisplay.POSITION_TOP); final Configuration c = new Configuration(mStack.getDisplay().getRequestedOverrideConfiguration()); c.densityDpi = 200; mStack.getDisplay().onRequestedOverrideConfigurationChanged(c); mActivity = new ActivityBuilder(mService) .setTask(mTask) .setResizeMode(RESIZE_MODE_UNRESIZEABLE) .setMaxAspectRatio(1.5f) .build(); mActivity.visible = true; final Rect originalBounds = new Rect(mActivity.getBounds()); final int originalDpi = mActivity.getConfiguration().densityDpi; // Move the non-resizable activity to the new display. mStack.reparent(newDisplay.mDisplayContent, true /* onTop */); assertEquals(originalBounds.width(), mActivity.getWindowConfiguration().getBounds().width()); assertEquals(originalBounds.height(), mActivity.getWindowConfiguration().getBounds().height()); assertEquals(originalDpi, mActivity.getConfiguration().densityDpi); assertTrue(mActivity.inSizeCompatMode()); } @Test public void testSizeCompatMode_FixedScreenBoundsWhenDisplaySizeChanged() { setupDisplayContentForCompatDisplayInsets(); when(mActivity.getRequestedOrientation()).thenReturn( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds()); mTask.getRequestedOverrideConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT; mActivity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; mActivity.visible = true; ensureActivityConfiguration(); final Rect originalBounds = new Rect(mActivity.getBounds()); // Change the size of current display. setupDisplayAndParentSize(1000, 2000); ensureActivityConfiguration(); assertEquals(originalBounds.width(), mActivity.getWindowConfiguration().getBounds().width()); assertEquals(originalBounds.height(), mActivity.getWindowConfiguration().getBounds().height()); assertTrue(mActivity.inSizeCompatMode()); } @Test public void testSizeCompatMode_FixedScreenLayoutSizeBits() { final int fixedScreenLayout = Configuration.SCREENLAYOUT_LONG_NO | Configuration.SCREENLAYOUT_SIZE_NORMAL; final int layoutMask = Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK | Configuration.SCREENLAYOUT_LAYOUTDIR_MASK; mTask.getRequestedOverrideConfiguration().screenLayout = fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR; prepareFixedAspectRatioUnresizableActivity(); // The initial configuration should inherit from parent. assertEquals(mTask.getConfiguration().screenLayout & layoutMask, mActivity.getConfiguration().screenLayout & layoutMask); mTask.getConfiguration().screenLayout = Configuration.SCREENLAYOUT_LAYOUTDIR_RTL | Configuration.SCREENLAYOUT_LONG_YES | Configuration.SCREENLAYOUT_SIZE_LARGE; mActivity.onConfigurationChanged(mTask.getConfiguration()); // The size and aspect ratio bits don't change, but the layout direction should be updated. assertEquals(fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_RTL, mActivity.getConfiguration().screenLayout & layoutMask); } @Test public void testSizeCompatMode_ResetNonVisibleActivity() { final ActivityDisplay display = mStack.getDisplay(); spyOn(display); prepareFixedAspectRatioUnresizableActivity(); mActivity.setState(STOPPED, "testSizeCompatMode"); mActivity.visible = false; mActivity.app.setReportedProcState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); // Make the parent bounds to be different so the activity is in size compatibility mode. setupDisplayAndParentSize(600, 1200); // Simulate the display changes orientation. doReturn(ActivityInfo.CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION | ActivityInfo.CONFIG_WINDOW_CONFIGURATION) .when(display).getLastOverrideConfigurationChanges(); mActivity.onConfigurationChanged(mTask.getConfiguration()); when(display.getLastOverrideConfigurationChanges()).thenCallRealMethod(); // The override configuration should not change so it is still in size compatibility mode. assertTrue(mActivity.inSizeCompatMode()); // Change display density final DisplayContent displayContent = mStack.getDisplay().mDisplayContent; displayContent.mBaseDisplayDensity = (int) (0.7f * displayContent.mBaseDisplayDensity); final Configuration c = new Configuration(); displayContent.computeScreenConfiguration(c); mService.mAmInternal = mock(ActivityManagerInternal.class); mStack.getDisplay().onRequestedOverrideConfigurationChanged(c); // The override configuration should be reset and the activity's process will be killed. assertFalse(mActivity.inSizeCompatMode()); verify(mActivity).restartProcessIfVisible(); waitHandlerIdle(mService.mH); verify(mService.mAmInternal).killProcess( eq(mActivity.app.mName), eq(mActivity.app.mUid), anyString()); } @Test public void testTakeOptions() { ActivityOptions opts = ActivityOptions.makeRemoteAnimation( Loading Loading @@ -1340,33 +1102,4 @@ public class ActivityRecordTests extends ActivityTestsBase { verify(mActivity).removeFromHistory(anyString()); } /** Setup {@link #mActivity} as a size-compat-mode-able activity without fixed orientation. */ private void prepareFixedAspectRatioUnresizableActivity() { setupDisplayContentForCompatDisplayInsets(); mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; mActivity.info.maxAspectRatio = 1.5f; mActivity.visible = true; ensureActivityConfiguration(); } private void setupDisplayContentForCompatDisplayInsets() { final Rect displayBounds = mStack.getDisplay().getBounds(); setupDisplayAndParentSize(displayBounds.width(), displayBounds.height()); } private DisplayContent setupDisplayAndParentSize(int width, int height) { final DisplayContent displayContent = mStack.getDisplay().mDisplayContent; displayContent.mBaseDisplayWidth = width; displayContent.mBaseDisplayHeight = height; final Configuration c = new Configuration(mStack.getDisplay().getRequestedOverrideConfiguration()); c.windowConfiguration.setBounds(new Rect(0, 0, width, height)); c.windowConfiguration.setAppBounds(0, 0, width, height); c.windowConfiguration.setRotation(ROTATION_0); c.orientation = width > height ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT; mStack.getDisplay().onRequestedOverrideConfigurationChanged(c); return displayContent; } } services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +1 −5 Original line number Diff line number Diff line Loading @@ -715,14 +715,10 @@ public class DisplayContentTests extends WindowTestsBase { activity.setRequestedOrientation(newOrientation); final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class); verify(dc.mActivityDisplay).updateDisplayOverrideConfigurationLocked(captor.capture(), same(activity), anyBoolean(), same(null)); final Configuration newDisplayConfig = captor.getValue(); final int expectedOrientation = newOrientation == SCREEN_ORIENTATION_PORTRAIT ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; assertEquals(expectedOrientation, newDisplayConfig.orientation); assertEquals(expectedOrientation, dc.getConfiguration().orientation); } @Test Loading services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java 0 → 100644 +426 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/wm/ActivityRecord.java +1 −2 Original line number Diff line number Diff line Loading @@ -6171,8 +6171,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // The rest of the condition is that only one side is smaller than the parent, but it still // needs to exclude the cases where the size is limited by the fixed aspect ratio. if (info.maxAspectRatio > 0) { final float aspectRatio = (0.5f + Math.max(appWidth, appHeight)) / Math.min(appWidth, appHeight); final float aspectRatio = Math.max(appWidth, appHeight) / Math.min(appWidth, appHeight); if (aspectRatio >= info.maxAspectRatio) { // The current size has reached the max aspect ratio. return false; Loading
services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java +0 −55 Original line number Diff line number Diff line Loading @@ -38,12 +38,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.when; import android.app.TaskStackListener; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.os.IBinder; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; Loading @@ -51,10 +46,6 @@ import androidx.test.filters.SmallTest; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; /** * Tests for the {@link ActivityDisplay} class. * Loading Loading @@ -331,50 +322,4 @@ public class ActivityDisplayTests extends ActivityTestsBase { verify(mSupervisor).removeTaskByIdLocked(eq(task1.mTaskId), anyBoolean(), anyBoolean(), any()); } /** * Ensures that {@link TaskStackListener} can receive callback about the activity in size * compatibility mode. */ @Test public void testHandleActivitySizeCompatMode() throws Exception { final ActivityDisplay display = mRootActivityContainer.getDefaultDisplay(); final ActivityRecord activity = createFullscreenStackWithSimpleActivityAt( display).topRunningActivityLocked(); activity.setState(ActivityStack.ActivityState.RESUMED, "testHandleActivitySizeCompatMode"); when(activity.getRequestedOrientation()).thenReturn( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); activity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; activity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; activity.visible = true; activity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */); final ArrayList<CompletableFuture<IBinder>> resultWrapper = new ArrayList<>(); mService.getTaskChangeNotificationController().registerTaskStackListener( new TaskStackListener() { @Override public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken) { resultWrapper.get(0).complete(activityToken); } }); resultWrapper.add(new CompletableFuture<>()); // resize the display to exercise size-compat mode final DisplayContent displayContent = display.mDisplayContent; displayContent.mBaseDisplayHeight = (int) (0.8f * displayContent.mBaseDisplayHeight); Configuration c = new Configuration(); displayContent.computeScreenConfiguration(c); display.onRequestedOverrideConfigurationChanged(c); assertEquals(activity.appToken, resultWrapper.get(0).get(2, TimeUnit.SECONDS)); // Expect null token when switching to non-size-compat mode activity. activity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; resultWrapper.set(0, new CompletableFuture<>()); display.handleActivitySizeCompatModeIfNeeded(activity); assertNull(resultWrapper.get(0).get(2, TimeUnit.SECONDS)); } }
services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +0 −267 Original line number Diff line number Diff line Loading @@ -18,24 +18,18 @@ package com.android.server.wm; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.os.Process.NOBODY_UID; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_90; import static android.view.WindowManager.TRANSIT_TASK_CLOSE; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; 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.reset; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; Loading @@ -61,18 +55,13 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.WindowConfiguration; import android.app.servertransaction.ActivityConfigurationChangeItem; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.PauseActivityItem; Loading @@ -80,13 +69,11 @@ import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; import android.os.Bundle; import android.os.PersistableBundle; import android.platform.test.annotations.Presubmit; import android.util.MergedConfiguration; import android.util.MutableBoolean; import android.view.DisplayInfo; import android.view.IRemoteAnimationFinishedCallback; import android.view.IRemoteAnimationRunner.Stub; import android.view.RemoteAnimationAdapter; Loading Loading @@ -218,23 +205,6 @@ public class ActivityRecordTests extends ActivityTestsBase { assertFalse(activity.canBeLaunchedOnDisplay(DEFAULT_DISPLAY + 1)); } @Test public void testRestartProcessIfVisible() { doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity); mActivity.visible = true; mActivity.setSavedState(null /* savedState */); mActivity.setState(ActivityStack.ActivityState.RESUMED, "testRestart"); prepareFixedAspectRatioUnresizableActivity(); final Rect originalOverrideBounds = new Rect(mActivity.getBounds()); setupDisplayAndParentSize(600, 1200); // The visible activity should recompute configuration according to the last parent bounds. mService.restartActivityProcessIfVisible(mActivity.appToken); assertEquals(ActivityStack.ActivityState.RESTARTING_PROCESS, mActivity.getState()); assertNotEquals(originalOverrideBounds, mActivity.getBounds()); } @Test public void testsApplyOptionsLocked() { ActivityOptions activityOptions = ActivityOptions.makeBasic(); Loading Loading @@ -483,214 +453,6 @@ public class ActivityRecordTests extends ActivityTestsBase { assertEquals(STARTED, mActivity.getState()); } @Test public void testSizeCompatMode_KeepBoundsWhenChangingFromFreeformToFullscreen() { setupDisplayContentForCompatDisplayInsets(); // put display in freeform mode ActivityDisplay display = mActivity.getDisplay(); final Configuration c = new Configuration(display.getRequestedOverrideConfiguration()); c.windowConfiguration.setBounds(new Rect(0, 0, 2000, 1000)); c.densityDpi = 300; c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM); display.onRequestedOverrideConfigurationChanged(c); // launch compat activity in freeform and store bounds when(mActivity.getRequestedOrientation()).thenReturn( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); mTask.getRequestedOverrideConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT; mTask.setBounds(100, 100, 400, 600); mActivity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; mActivity.visible = true; ensureActivityConfiguration(); final Rect bounds = new Rect(mActivity.getBounds()); final int density = mActivity.getConfiguration().densityDpi; // change display configuration to fullscreen c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN); display.onRequestedOverrideConfigurationChanged(c); // check if dimensions stay the same assertTrue(mActivity.inSizeCompatMode()); assertEquals(bounds.width(), mActivity.getBounds().width()); assertEquals(bounds.height(), mActivity.getBounds().height()); assertEquals(density, mActivity.getConfiguration().densityDpi); assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN, mActivity.getWindowingMode()); } @Test public void testSizeCompatMode_FixedAspectRatioBoundsWithDecor() { setupDisplayContentForCompatDisplayInsets(); final int decorHeight = 200; // e.g. The device has cutout. final DisplayPolicy policy = setupDisplayAndParentSize(600, 800).getDisplayPolicy(); spyOn(policy); doAnswer(invocationOnMock -> { final int rotation = invocationOnMock.<Integer>getArgument(0); final Rect insets = invocationOnMock.<Rect>getArgument(4); if (rotation == ROTATION_0) { insets.top = decorHeight; } else if (rotation == ROTATION_90) { insets.left = decorHeight; } return null; }).when(policy).getNonDecorInsetsLw(anyInt() /* rotation */, anyInt() /* width */, anyInt() /* height */, any() /* displayCutout */, any() /* outInsets */); // set appBounds to incorporate decor final Configuration c = new Configuration(mStack.getDisplay().getRequestedOverrideConfiguration()); c.windowConfiguration.getAppBounds().top = decorHeight; mStack.getDisplay().onRequestedOverrideConfigurationChanged(c); doReturn(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) .when(mActivity).getRequestedOrientation(); mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; mActivity.info.minAspectRatio = mActivity.info.maxAspectRatio = 1; mActivity.visible = true; ensureActivityConfiguration(); // The parent configuration doesn't change since the first resolved configuration, so the // activity shouldn't be in the size compatibility mode. assertFalse(mActivity.inSizeCompatMode()); final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds(); // Ensure the app bounds keep the declared aspect ratio. assertEquals(appBounds.width(), appBounds.height()); // The decor height should be a part of the effective bounds. assertEquals(mActivity.getBounds().height(), appBounds.height() + decorHeight); mTask.getConfiguration().windowConfiguration.setRotation(ROTATION_90); mActivity.onConfigurationChanged(mTask.getConfiguration()); // After changing orientation, the aspect ratio should be the same. assertEquals(appBounds.width(), appBounds.height()); // The decor height will be included in width. assertEquals(mActivity.getBounds().width(), appBounds.width() + decorHeight); } @Test public void testSizeCompatMode_FixedScreenConfigurationWhenMovingToDisplay() { // Initialize different bounds on a new display. final Rect newDisplayBounds = new Rect(0, 0, 1000, 2000); DisplayInfo info = new DisplayInfo(); mService.mContext.getDisplay().getDisplayInfo(info); info.logicalWidth = newDisplayBounds.width(); info.logicalHeight = newDisplayBounds.height(); info.logicalDensityDpi = 300; final ActivityDisplay newDisplay = addNewActivityDisplayAt(info, ActivityDisplay.POSITION_TOP); final Configuration c = new Configuration(mStack.getDisplay().getRequestedOverrideConfiguration()); c.densityDpi = 200; mStack.getDisplay().onRequestedOverrideConfigurationChanged(c); mActivity = new ActivityBuilder(mService) .setTask(mTask) .setResizeMode(RESIZE_MODE_UNRESIZEABLE) .setMaxAspectRatio(1.5f) .build(); mActivity.visible = true; final Rect originalBounds = new Rect(mActivity.getBounds()); final int originalDpi = mActivity.getConfiguration().densityDpi; // Move the non-resizable activity to the new display. mStack.reparent(newDisplay.mDisplayContent, true /* onTop */); assertEquals(originalBounds.width(), mActivity.getWindowConfiguration().getBounds().width()); assertEquals(originalBounds.height(), mActivity.getWindowConfiguration().getBounds().height()); assertEquals(originalDpi, mActivity.getConfiguration().densityDpi); assertTrue(mActivity.inSizeCompatMode()); } @Test public void testSizeCompatMode_FixedScreenBoundsWhenDisplaySizeChanged() { setupDisplayContentForCompatDisplayInsets(); when(mActivity.getRequestedOrientation()).thenReturn( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds()); mTask.getRequestedOverrideConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT; mActivity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; mActivity.visible = true; ensureActivityConfiguration(); final Rect originalBounds = new Rect(mActivity.getBounds()); // Change the size of current display. setupDisplayAndParentSize(1000, 2000); ensureActivityConfiguration(); assertEquals(originalBounds.width(), mActivity.getWindowConfiguration().getBounds().width()); assertEquals(originalBounds.height(), mActivity.getWindowConfiguration().getBounds().height()); assertTrue(mActivity.inSizeCompatMode()); } @Test public void testSizeCompatMode_FixedScreenLayoutSizeBits() { final int fixedScreenLayout = Configuration.SCREENLAYOUT_LONG_NO | Configuration.SCREENLAYOUT_SIZE_NORMAL; final int layoutMask = Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK | Configuration.SCREENLAYOUT_LAYOUTDIR_MASK; mTask.getRequestedOverrideConfiguration().screenLayout = fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR; prepareFixedAspectRatioUnresizableActivity(); // The initial configuration should inherit from parent. assertEquals(mTask.getConfiguration().screenLayout & layoutMask, mActivity.getConfiguration().screenLayout & layoutMask); mTask.getConfiguration().screenLayout = Configuration.SCREENLAYOUT_LAYOUTDIR_RTL | Configuration.SCREENLAYOUT_LONG_YES | Configuration.SCREENLAYOUT_SIZE_LARGE; mActivity.onConfigurationChanged(mTask.getConfiguration()); // The size and aspect ratio bits don't change, but the layout direction should be updated. assertEquals(fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_RTL, mActivity.getConfiguration().screenLayout & layoutMask); } @Test public void testSizeCompatMode_ResetNonVisibleActivity() { final ActivityDisplay display = mStack.getDisplay(); spyOn(display); prepareFixedAspectRatioUnresizableActivity(); mActivity.setState(STOPPED, "testSizeCompatMode"); mActivity.visible = false; mActivity.app.setReportedProcState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); // Make the parent bounds to be different so the activity is in size compatibility mode. setupDisplayAndParentSize(600, 1200); // Simulate the display changes orientation. doReturn(ActivityInfo.CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION | ActivityInfo.CONFIG_WINDOW_CONFIGURATION) .when(display).getLastOverrideConfigurationChanges(); mActivity.onConfigurationChanged(mTask.getConfiguration()); when(display.getLastOverrideConfigurationChanges()).thenCallRealMethod(); // The override configuration should not change so it is still in size compatibility mode. assertTrue(mActivity.inSizeCompatMode()); // Change display density final DisplayContent displayContent = mStack.getDisplay().mDisplayContent; displayContent.mBaseDisplayDensity = (int) (0.7f * displayContent.mBaseDisplayDensity); final Configuration c = new Configuration(); displayContent.computeScreenConfiguration(c); mService.mAmInternal = mock(ActivityManagerInternal.class); mStack.getDisplay().onRequestedOverrideConfigurationChanged(c); // The override configuration should be reset and the activity's process will be killed. assertFalse(mActivity.inSizeCompatMode()); verify(mActivity).restartProcessIfVisible(); waitHandlerIdle(mService.mH); verify(mService.mAmInternal).killProcess( eq(mActivity.app.mName), eq(mActivity.app.mUid), anyString()); } @Test public void testTakeOptions() { ActivityOptions opts = ActivityOptions.makeRemoteAnimation( Loading Loading @@ -1340,33 +1102,4 @@ public class ActivityRecordTests extends ActivityTestsBase { verify(mActivity).removeFromHistory(anyString()); } /** Setup {@link #mActivity} as a size-compat-mode-able activity without fixed orientation. */ private void prepareFixedAspectRatioUnresizableActivity() { setupDisplayContentForCompatDisplayInsets(); mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; mActivity.info.maxAspectRatio = 1.5f; mActivity.visible = true; ensureActivityConfiguration(); } private void setupDisplayContentForCompatDisplayInsets() { final Rect displayBounds = mStack.getDisplay().getBounds(); setupDisplayAndParentSize(displayBounds.width(), displayBounds.height()); } private DisplayContent setupDisplayAndParentSize(int width, int height) { final DisplayContent displayContent = mStack.getDisplay().mDisplayContent; displayContent.mBaseDisplayWidth = width; displayContent.mBaseDisplayHeight = height; final Configuration c = new Configuration(mStack.getDisplay().getRequestedOverrideConfiguration()); c.windowConfiguration.setBounds(new Rect(0, 0, width, height)); c.windowConfiguration.setAppBounds(0, 0, width, height); c.windowConfiguration.setRotation(ROTATION_0); c.orientation = width > height ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT; mStack.getDisplay().onRequestedOverrideConfigurationChanged(c); return displayContent; } }
services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +1 −5 Original line number Diff line number Diff line Loading @@ -715,14 +715,10 @@ public class DisplayContentTests extends WindowTestsBase { activity.setRequestedOrientation(newOrientation); final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class); verify(dc.mActivityDisplay).updateDisplayOverrideConfigurationLocked(captor.capture(), same(activity), anyBoolean(), same(null)); final Configuration newDisplayConfig = captor.getValue(); final int expectedOrientation = newOrientation == SCREEN_ORIENTATION_PORTRAIT ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; assertEquals(expectedOrientation, newDisplayConfig.orientation); assertEquals(expectedOrientation, dc.getConfiguration().orientation); } @Test Loading
services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java 0 → 100644 +426 −0 File added.Preview size limit exceeded, changes collapsed. Show changes