Merge "Sandbox only if an activity may enter size compat mode." into sc-dev
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 3988043..5dd8f74 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -7318,11 +7318,6 @@
         if (info != null && info.alwaysSandboxDisplayApis()) {
             return true;
         }
-        // Max bounds should be sandboxed where an activity is letterboxed (activity bounds will be
-        // smaller than task bounds).
-        if (!matchParentBounds()) {
-            return true;
-        }
         // Max bounds should be sandboxed when an activity should have compatDisplayInsets, and it
         // will keep the same bounds and screen configuration when it was first launched regardless
         // how its parent window changes, so that the sandbox API will provide a consistent result.
@@ -7330,8 +7325,9 @@
             return true;
         }
 
-        // No need to sandbox for resizable apps in multi-window because resizableActivity=true
-        // indicates that they support multi-window.
+        // No need to sandbox for resizable apps in (including in multi-window) because
+        // resizableActivity=true indicates that they support multi-window. Likewise, do not sandbox
+        // for activities in letterbox since the activity has declared it can handle resizing.
         return false;
     }
 
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 45818a2..221c8b9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -1252,9 +1252,11 @@
 
         // Task and display bounds should be equal while activity should be letterboxed and
         // has 700x1400 bounds with the ratio as the display.
-        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        assertTrue(newActivity.isLetterboxedForFixedOrientationAndAspectRatio());
         assertFalse(newActivity.inSizeCompatMode());
-        assertActivityMaxBoundsSandboxed();
+        // Activity max bounds are sandboxed due to size compat mode.
+        assertThat(newActivity.getConfiguration().windowConfiguration.getMaxBounds())
+                .isEqualTo(newActivity.getWindowConfiguration().getBounds());
         assertEquals(taskBounds, displayBounds);
         assertEquals(displayBounds.height(), newActivityBounds.height());
         assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(),
@@ -1412,7 +1414,7 @@
     }
 
     @Test
-    public void testSandboxDisplayApis_letterboxAppNotSandboxed() {
+    public void testSandboxDisplayApis_unresizableAppNotSandboxed() {
         // Set up a display in landscape with an unresizable app.
         setUpDisplaySizeWithApp(2500, 1000);
         mActivity.mDisplayContent.setSandboxDisplayApis(false /* sandboxDisplayApis */);
@@ -1420,11 +1422,11 @@
         assertFitted();
 
         // Activity max bounds not be sandboxed since sandboxing is disabled.
-        assertThat(mActivity.getMaxBounds()).isEqualTo(mActivity.mDisplayContent.getBounds());
+        assertMaxBoundsInheritDisplayAreaBounds();
     }
 
     @Test
-    public void testSandboxDisplayApis_letterboxAppSandboxed() {
+    public void testSandboxDisplayApis_unresizableAppSandboxed() {
         // Set up a display in landscape with an unresizable app.
         setUpDisplaySizeWithApp(2500, 1000);
         mActivity.mDisplayContent.setSandboxDisplayApis(true /* sandboxDisplayApis */);
@@ -1435,6 +1437,89 @@
         assertActivityMaxBoundsSandboxed();
     }
 
+    @Test
+    public void testResizableApp_notSandboxed() {
+        // Set up a display in landscape with a fully resizable app.
+        setUpDisplaySizeWithApp(2500, 1000);
+        prepareLimitedBounds(mActivity, /* maxAspect= */ -1,
+                SCREEN_ORIENTATION_UNSPECIFIED, /* isUnresizable= */ false);
+        assertFitted();
+
+        // Activity max bounds not be sandboxed since app is fully resizable.
+        assertMaxBoundsInheritDisplayAreaBounds();
+    }
+
+    @Test
+    public void testResizableMaxAspectApp_notSandboxed() {
+        // Set up a display in landscape with a fully resizable app.
+        setUpDisplaySizeWithApp(2500, 1000);
+        prepareLimitedBounds(mActivity, /* maxAspect= */ 1,
+                SCREEN_ORIENTATION_UNSPECIFIED, /* isUnresizable= */ false);
+        assertFitted();
+
+        // Activity max bounds not be sandboxed since app is fully resizable.
+        assertMaxBoundsInheritDisplayAreaBounds();
+    }
+
+    @Test
+    public void testResizableOrientationRequestApp_notSandboxed() {
+        // Set up a display in landscape with a fully resizable app.
+        setUpDisplaySizeWithApp(2500, 1000);
+        prepareLimitedBounds(mActivity, /* maxAspect= */ -1,
+                SCREEN_ORIENTATION_PORTRAIT, /* isUnresizable= */ false);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        assertFitted();
+
+        // Activity max bounds not be sandboxed since app is fully resizable.
+        assertMaxBoundsInheritDisplayAreaBounds();
+    }
+
+    @Test
+    public void testResizableMaxAspectOrientationRequestApp_notSandboxed() {
+        // Set up a display in landscape with a fully resizable app.
+        setUpDisplaySizeWithApp(2500, 1000);
+        prepareLimitedBounds(mActivity, /* maxAspect= */ 1,
+                SCREEN_ORIENTATION_PORTRAIT, /* isUnresizable= */ false);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        assertFitted();
+
+        // Activity max bounds not be sandboxed since app is fully resizable.
+        assertMaxBoundsInheritDisplayAreaBounds();
+    }
+
+    @Test
+    public void testUnresizableApp_isSandboxed() {
+        // Set up a display in landscape with a fully resizable app.
+        setUpDisplaySizeWithApp(2500, 1000);
+        prepareLimitedBounds(mActivity, /* maxAspect= */ -1,
+                SCREEN_ORIENTATION_UNSPECIFIED, /* isUnresizable= */ true);
+        assertFitted();
+
+        // Activity max bounds are sandboxed since app may enter size compat mode.
+        assertActivityMaxBoundsSandboxed();
+        assertFalse(mActivity.inSizeCompatMode());
+    }
+
+    @Test
+    public void testUnresizableMaxAspectApp_isSandboxed() {
+        // Set up a display in landscape with a fully resizable app.
+        setUpDisplaySizeWithApp(2500, 1000);
+        prepareLimitedBounds(mActivity, /* maxAspect= */ 1,
+                SCREEN_ORIENTATION_UNSPECIFIED, /* isUnresizable= */ true);
+        assertFitted();
+
+        // Activity max bounds are sandboxed since app may enter size compat mode.
+        assertActivityMaxBoundsSandboxed();
+        assertFalse(mActivity.inSizeCompatMode());
+        assertTrue(mActivity.shouldCreateCompatDisplayInsets());
+
+        // Resize display to half the width.
+        resizeDisplay(mActivity.getDisplayContent(), 500, 1000);
+
+        // Activity now in size compat mode.
+        assertActivityMaxBoundsSandboxed();
+        assertTrue(mActivity.inSizeCompatMode());
+    }
 
     @Test
     public void testTaskDisplayAreaNotFillDisplay() {