Loading services/core/java/com/android/server/wm/ActivityRecord.java +16 −11 Original line number Diff line number Diff line Loading @@ -6372,7 +6372,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } final IBinder freezeToken = mayFreezeScreenLocked() ? appToken : null; onDescendantOrientationChanged(freezeToken, this); if (onDescendantOrientationChanged(freezeToken, this)) { // The app is just becoming visible, and the parent Task has updated with the // orientation request. Update the size compat mode. updateSizeCompatMode(); } } /** Loading Loading @@ -6538,6 +6542,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } if (task == null || (!handlesOrientationChangeFromDescendant() && task.getLastTaskBoundsComputeActivity() != this)) { // Don't compute when Task hasn't computed its bounds for this app, because the Task can // be letterboxed, and its bounds may not be accurate until then. return; } Configuration overrideConfig = getRequestedOverrideConfiguration(); final Configuration fullConfig = getConfiguration(); Loading @@ -6562,21 +6573,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mCompatDisplayInsets = new CompatDisplayInsets(mDisplayContent, this); } void clearSizeCompatMode(boolean recomputeTask) { @VisibleForTesting void clearSizeCompatMode() { mSizeCompatScale = 1f; mSizeCompatBounds = null; mCompatDisplayInsets = null; if (recomputeTask) { // Recompute from Task because letterbox can also happen on Task level. task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration()); } } @VisibleForTesting void clearSizeCompatMode() { clearSizeCompatMode(true /* recomputeTask */); } @Override public boolean matchParentBounds() { Loading services/core/java/com/android/server/wm/Task.java +16 −12 Original line number Diff line number Diff line Loading @@ -571,6 +571,10 @@ class Task extends WindowContainer<WindowContainer> { /** Current activity that is resumed, or null if there is none. */ ActivityRecord mResumedActivity = null; /** Last activity that is used to compute the Task bounds. */ @Nullable private ActivityRecord mLastTaskBoundsComputeActivity; private boolean mForceShowForAllUsers; /** When set, will force the task to report as invisible. */ Loading Loading @@ -1496,6 +1500,11 @@ class Task extends WindowContainer<WindowContainer> { } void cleanUpActivityReferences(ActivityRecord r) { // mLastTaskBoundsComputeActivity is set at leaf Task if (mLastTaskBoundsComputeActivity == r) { mLastTaskBoundsComputeActivity = null; } final WindowContainer parent = getParent(); if (parent != null && parent.asTask() != null) { parent.asTask().cleanUpActivityReferences(r); Loading Loading @@ -2833,6 +2842,8 @@ class Task extends WindowContainer<WindowContainer> { private void resolveLeafOnlyOverrideConfigs(Configuration newParentConfig, Rect previousBounds) { mLastTaskBoundsComputeActivity = getTopNonFinishingActivity(false /* includeOverlays */); int windowingMode = getResolvedOverrideConfiguration().windowConfiguration.getWindowingMode(); if (windowingMode == WINDOWING_MODE_UNDEFINED) { Loading Loading @@ -2963,6 +2974,11 @@ class Task extends WindowContainer<WindowContainer> { return bounds; } @Nullable ActivityRecord getLastTaskBoundsComputeActivity() { return mLastTaskBoundsComputeActivity; } /** Updates the task's bounds and override configuration to match what is expected for the * input stack. */ void updateOverrideConfigurationForStack(Task inStack) { Loading Loading @@ -3307,18 +3323,6 @@ class Task extends WindowContainer<WindowContainer> { // No one in higher hierarchy handles this request, let's adjust our bounds to fulfill // it if possible. if (getParent() != null) { final ActivityRecord activity = requestingContainer.asActivityRecord(); if (activity != null) { // Clear the size compat cache to recompute the bounds for requested orientation; // otherwise when Task#computeFullscreenBounds(), it will not try to do Task level // letterboxing because app may prefer to keep its original size (size compat). // // Normally, ActivityRecord#clearSizeCompatMode() recomputes from its parent Task, // which is the leaf Task. However, because this orientation request is new to all // Tasks, pass false to clearSizeCompatMode, and trigger onConfigurationChanged from // here (root Task) to make sure all Tasks are up-to-date. activity.clearSizeCompatMode(false /* recomputeTask */); } onConfigurationChanged(getParent().getConfiguration()); return true; } Loading services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +35 −2 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ 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; import static org.mockito.Mockito.doCallRealMethod; import android.app.ActivityManager; Loading Loading @@ -702,7 +703,6 @@ public class SizeCompatTests extends WindowTestsBase { // size compat cache. verify(mTask).onDescendantOrientationChanged(any(), same(newActivity)); verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt()); verify(newActivity).clearSizeCompatMode(false /* recomputeTask */); final Rect displayBounds = display.getBounds(); final Rect taskBounds = mTask.getBounds(); Loading Loading @@ -744,7 +744,6 @@ public class SizeCompatTests extends WindowTestsBase { // size compat cache. verify(mTask).onDescendantOrientationChanged(any(), same(newActivity)); verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt()); verify(newActivity).clearSizeCompatMode(false /* recomputeTask */); final Rect displayBounds = display.getBounds(); final Rect taskBounds = mTask.getBounds(); Loading @@ -761,6 +760,40 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(taskBounds, newActivityBounds); } @Test public void testDisplayIgnoreOrientationRequest_pausedAppNotLostSizeCompat() { // 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(0, SCREEN_ORIENTATION_PORTRAIT); clearInvocations(mActivity); assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); // Rotate display to portrait. rotateDisplay(mActivity.mDisplayContent, ROTATION_90); // App should be in size compat. assertFalse(mTask.isTaskLetterboxed()); assertScaled(); assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); final Rect activityBounds = new Rect(mActivity.getBounds()); mStack.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */); // App still in size compat, and the bounds don't change. verify(mActivity, never()).clearSizeCompatMode(); assertFalse(mTask.isTaskLetterboxed()); assertScaled(); assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); assertEquals(activityBounds, mActivity.getBounds()); } private static WindowState addWindowToActivity(ActivityRecord activity) { final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; Loading services/tests/wmtests/src/com/android/server/wm/TaskTests.java +20 −0 Original line number Diff line number Diff line Loading @@ -257,4 +257,24 @@ public class TaskTests extends WindowTestsBase { task.resolveOverrideConfiguration(parentConfig); assertThat(resolvedOverride.getWindowingMode()).isEqualTo(WINDOWING_MODE_UNDEFINED); } @Test public void testCleanUpActivityReferences_clearLastTaskBoundsComputeActivity() { final Task rootTask = createTaskStackOnDisplay(mDisplayContent); final Task leafTask = createTaskInStack(rootTask, 0 /* userId */); final ActivityRecord activity2 = createActivityRecord(mDisplayContent, leafTask); final ActivityRecord activity1 = createActivityRecord(mDisplayContent, leafTask); activity1.finishing = false; leafTask.resolveOverrideConfiguration(rootTask.getConfiguration()); assertEquals(activity1, leafTask.getLastTaskBoundsComputeActivity()); leafTask.cleanUpActivityReferences(activity2); assertNotNull(leafTask.getLastTaskBoundsComputeActivity()); leafTask.cleanUpActivityReferences(activity1); assertNull(leafTask.getLastTaskBoundsComputeActivity()); } } Loading
services/core/java/com/android/server/wm/ActivityRecord.java +16 −11 Original line number Diff line number Diff line Loading @@ -6372,7 +6372,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } final IBinder freezeToken = mayFreezeScreenLocked() ? appToken : null; onDescendantOrientationChanged(freezeToken, this); if (onDescendantOrientationChanged(freezeToken, this)) { // The app is just becoming visible, and the parent Task has updated with the // orientation request. Update the size compat mode. updateSizeCompatMode(); } } /** Loading Loading @@ -6538,6 +6542,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } if (task == null || (!handlesOrientationChangeFromDescendant() && task.getLastTaskBoundsComputeActivity() != this)) { // Don't compute when Task hasn't computed its bounds for this app, because the Task can // be letterboxed, and its bounds may not be accurate until then. return; } Configuration overrideConfig = getRequestedOverrideConfiguration(); final Configuration fullConfig = getConfiguration(); Loading @@ -6562,21 +6573,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mCompatDisplayInsets = new CompatDisplayInsets(mDisplayContent, this); } void clearSizeCompatMode(boolean recomputeTask) { @VisibleForTesting void clearSizeCompatMode() { mSizeCompatScale = 1f; mSizeCompatBounds = null; mCompatDisplayInsets = null; if (recomputeTask) { // Recompute from Task because letterbox can also happen on Task level. task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration()); } } @VisibleForTesting void clearSizeCompatMode() { clearSizeCompatMode(true /* recomputeTask */); } @Override public boolean matchParentBounds() { Loading
services/core/java/com/android/server/wm/Task.java +16 −12 Original line number Diff line number Diff line Loading @@ -571,6 +571,10 @@ class Task extends WindowContainer<WindowContainer> { /** Current activity that is resumed, or null if there is none. */ ActivityRecord mResumedActivity = null; /** Last activity that is used to compute the Task bounds. */ @Nullable private ActivityRecord mLastTaskBoundsComputeActivity; private boolean mForceShowForAllUsers; /** When set, will force the task to report as invisible. */ Loading Loading @@ -1496,6 +1500,11 @@ class Task extends WindowContainer<WindowContainer> { } void cleanUpActivityReferences(ActivityRecord r) { // mLastTaskBoundsComputeActivity is set at leaf Task if (mLastTaskBoundsComputeActivity == r) { mLastTaskBoundsComputeActivity = null; } final WindowContainer parent = getParent(); if (parent != null && parent.asTask() != null) { parent.asTask().cleanUpActivityReferences(r); Loading Loading @@ -2833,6 +2842,8 @@ class Task extends WindowContainer<WindowContainer> { private void resolveLeafOnlyOverrideConfigs(Configuration newParentConfig, Rect previousBounds) { mLastTaskBoundsComputeActivity = getTopNonFinishingActivity(false /* includeOverlays */); int windowingMode = getResolvedOverrideConfiguration().windowConfiguration.getWindowingMode(); if (windowingMode == WINDOWING_MODE_UNDEFINED) { Loading Loading @@ -2963,6 +2974,11 @@ class Task extends WindowContainer<WindowContainer> { return bounds; } @Nullable ActivityRecord getLastTaskBoundsComputeActivity() { return mLastTaskBoundsComputeActivity; } /** Updates the task's bounds and override configuration to match what is expected for the * input stack. */ void updateOverrideConfigurationForStack(Task inStack) { Loading Loading @@ -3307,18 +3323,6 @@ class Task extends WindowContainer<WindowContainer> { // No one in higher hierarchy handles this request, let's adjust our bounds to fulfill // it if possible. if (getParent() != null) { final ActivityRecord activity = requestingContainer.asActivityRecord(); if (activity != null) { // Clear the size compat cache to recompute the bounds for requested orientation; // otherwise when Task#computeFullscreenBounds(), it will not try to do Task level // letterboxing because app may prefer to keep its original size (size compat). // // Normally, ActivityRecord#clearSizeCompatMode() recomputes from its parent Task, // which is the leaf Task. However, because this orientation request is new to all // Tasks, pass false to clearSizeCompatMode, and trigger onConfigurationChanged from // here (root Task) to make sure all Tasks are up-to-date. activity.clearSizeCompatMode(false /* recomputeTask */); } onConfigurationChanged(getParent().getConfiguration()); return true; } Loading
services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +35 −2 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ 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; import static org.mockito.Mockito.doCallRealMethod; import android.app.ActivityManager; Loading Loading @@ -702,7 +703,6 @@ public class SizeCompatTests extends WindowTestsBase { // size compat cache. verify(mTask).onDescendantOrientationChanged(any(), same(newActivity)); verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt()); verify(newActivity).clearSizeCompatMode(false /* recomputeTask */); final Rect displayBounds = display.getBounds(); final Rect taskBounds = mTask.getBounds(); Loading Loading @@ -744,7 +744,6 @@ public class SizeCompatTests extends WindowTestsBase { // size compat cache. verify(mTask).onDescendantOrientationChanged(any(), same(newActivity)); verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt()); verify(newActivity).clearSizeCompatMode(false /* recomputeTask */); final Rect displayBounds = display.getBounds(); final Rect taskBounds = mTask.getBounds(); Loading @@ -761,6 +760,40 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(taskBounds, newActivityBounds); } @Test public void testDisplayIgnoreOrientationRequest_pausedAppNotLostSizeCompat() { // 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(0, SCREEN_ORIENTATION_PORTRAIT); clearInvocations(mActivity); assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); // Rotate display to portrait. rotateDisplay(mActivity.mDisplayContent, ROTATION_90); // App should be in size compat. assertFalse(mTask.isTaskLetterboxed()); assertScaled(); assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); final Rect activityBounds = new Rect(mActivity.getBounds()); mStack.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */); // App still in size compat, and the bounds don't change. verify(mActivity, never()).clearSizeCompatMode(); assertFalse(mTask.isTaskLetterboxed()); assertScaled(); assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); assertEquals(activityBounds, mActivity.getBounds()); } private static WindowState addWindowToActivity(ActivityRecord activity) { final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; Loading
services/tests/wmtests/src/com/android/server/wm/TaskTests.java +20 −0 Original line number Diff line number Diff line Loading @@ -257,4 +257,24 @@ public class TaskTests extends WindowTestsBase { task.resolveOverrideConfiguration(parentConfig); assertThat(resolvedOverride.getWindowingMode()).isEqualTo(WINDOWING_MODE_UNDEFINED); } @Test public void testCleanUpActivityReferences_clearLastTaskBoundsComputeActivity() { final Task rootTask = createTaskStackOnDisplay(mDisplayContent); final Task leafTask = createTaskInStack(rootTask, 0 /* userId */); final ActivityRecord activity2 = createActivityRecord(mDisplayContent, leafTask); final ActivityRecord activity1 = createActivityRecord(mDisplayContent, leafTask); activity1.finishing = false; leafTask.resolveOverrideConfiguration(rootTask.getConfiguration()); assertEquals(activity1, leafTask.getLastTaskBoundsComputeActivity()); leafTask.cleanUpActivityReferences(activity2); assertNotNull(leafTask.getLastTaskBoundsComputeActivity()); leafTask.cleanUpActivityReferences(activity1); assertNull(leafTask.getLastTaskBoundsComputeActivity()); } }