From e17ef904e5e77d41afd07db6fb621bba66bcea28 Mon Sep 17 00:00:00 2001 From: Vali Calinescu Date: Tue, 21 Mar 2023 18:21:08 +0000 Subject: [PATCH] Clear mInheritedCompatDisplayInsets when clearing size compat mode Translucent activities inherit the compatDisplayInsets of the first opaque activity beneath them, so they can go into an infinite loop of clearing size compat mode because they would appear to be in size compat mode indefinitely. To fix this we will also clear the compatDisplayInsets of the opaque activity when clearing size compat mode for the translucent activity. Fix: 273768507 Test: Manual with test app Test: atest WmTests:SizeCompatTests#testTranslucentActivity_clearSizeCompatMode_inheritedCompatDisplayInsetsCleared Change-Id: I84c42872cc4fad296a069960f2b1983dfab25bfc --- .../com/android/server/wm/ActivityRecord.java | 1 + .../server/wm/LetterboxUiController.java | 4 +++ .../android/server/wm/SizeCompatTests.java | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index b946e7e060443..71802b22d4b4f 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -8071,6 +8071,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mSizeCompatScale = 1f; mSizeCompatBounds = null; mCompatDisplayInsets = null; + mLetterboxUiController.clearInheritedCompatDisplayInsets(); } @VisibleForTesting diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index 0db76bfe347ff..cf97edc342f68 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -1477,6 +1477,10 @@ final class LetterboxUiController { return mInheritedCompatDisplayInsets; } + void clearInheritedCompatDisplayInsets() { + mInheritedCompatDisplayInsets = null; + } + /** * In case of translucent activities, it consumes the {@link ActivityRecord} of the first opaque * activity beneath using the given consumer and returns {@code true}. diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 3ab9ea9061282..e097d891d39f8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -63,6 +63,8 @@ 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.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -458,6 +460,33 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(translucentActivity.getBounds(), mActivity.getBounds()); } + @Test + public void testTranslucentActivity_clearSizeCompatMode_inheritedCompatDisplayInsetsCleared() { + mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true); + setUpDisplaySizeWithApp(2800, 1400); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + prepareUnresizable(mActivity, -1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT); + // Rotate to put activity in size compat mode. + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + assertTrue(mActivity.inSizeCompatMode()); + + // We launch a transparent activity + final ActivityRecord translucentActivity = new ActivityBuilder(mAtm) + .setLaunchedFromUid(mActivity.getUid()) + .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT) + .build(); + doReturn(false).when(translucentActivity).fillsParent(); + mTask.addChild(translucentActivity); + + // The transparent activity inherits the compat display insets of the opaque activity + // beneath it + assertNotNull(translucentActivity.getCompatDisplayInsets()); + + // Clearing SCM should also clear the inherited compat display insets + translucentActivity.clearSizeCompatMode(); + assertNull(translucentActivity.getCompatDisplayInsets()); + } + @Test public void testRestartProcessIfVisible() { setUpDisplaySizeWithApp(1000, 2500);