diff options
7 files changed, 261 insertions, 9 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 8c116585e3b8..390f5768680a 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -6063,6 +6063,18 @@      <!-- Whether displaying letterbox education is enabled for letterboxed fullscreen apps. -->      <bool name="config_letterboxIsEducationEnabled">false</bool> +    <!-- The width in dp to use to detect vertical thin letterboxing. +         If W is the available width and w is the letterbox width, an app +         is thin letterboxed if the value here is < (W - w) / 2 +         If the value is < 0 the thin letterboxing policy is disabled --> +    <dimen name="config_letterboxThinLetterboxWidthDp">-1dp</dimen> + +    <!-- The height in dp to use to detect horizontal thin letterboxing +         If H is the available height and h is the letterbox height, an app +         is thin letterboxed if the value here is < (H - h) / 2 +         If the value is < 0 the thin letterboxing policy is disabled --> +    <dimen name="config_letterboxThinLetterboxHeightDp">-1dp</dimen> +      <!-- Default min aspect ratio for unresizable apps which are eligible for size compat mode.           Values <= 1.0 will be ignored. Activity min/max aspect ratio restrictions will still be           espected so this override can control the maximum screen area that can be occupied by diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7a8611dd85d7..58f4436d4f69 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4693,6 +4693,8 @@    <java-symbol type="integer" name="config_letterboxDefaultPositionForTabletopModeReachability" />    <java-symbol type="bool" name="config_letterboxIsPolicyForIgnoringRequestedOrientationEnabled" />    <java-symbol type="bool" name="config_letterboxIsEducationEnabled" /> +  <java-symbol type="dimen" name="config_letterboxThinLetterboxWidthDp" /> +  <java-symbol type="dimen" name="config_letterboxThinLetterboxHeightDp" />    <java-symbol type="dimen" name="config_letterboxDefaultMinAspectRatioForUnresizableApps" />    <java-symbol type="bool" name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled" />    <java-symbol type="bool" name="config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled" /> diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java index 5aa0ed7ce76c..ce1a72deb523 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java +++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java @@ -25,7 +25,6 @@ import android.annotation.Nullable;  import android.content.Context;  import android.graphics.Color;  import android.provider.DeviceConfig; -import android.util.Slog;  import com.android.internal.R;  import com.android.internal.annotations.VisibleForTesting; @@ -33,6 +32,7 @@ import com.android.internal.annotations.VisibleForTesting;  import java.lang.annotation.Retention;  import java.lang.annotation.RetentionPolicy;  import java.util.function.Function; +import java.util.function.IntSupplier;  /** Reads letterbox configs from resources and controls their overrides at runtime. */  final class LetterboxConfiguration { @@ -265,6 +265,12 @@ final class LetterboxConfiguration {      // unresizable apps      private boolean mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox; +    // Supplier for the value in pixel to consider when detecting vertical thin letterboxing +    private final IntSupplier mThinLetterboxWidthFn; + +    // Supplier for the value in pixel to consider when detecting horizontal thin letterboxing +    private final IntSupplier mThinLetterboxHeightFn; +      // Allows to enable letterboxing strategy for translucent activities ignoring flags.      private boolean mTranslucentLetterboxingOverrideEnabled; @@ -358,6 +364,10 @@ final class LetterboxConfiguration {                  R.bool.config_isWindowManagerCameraCompatSplitScreenAspectRatioEnabled);          mIsPolicyForIgnoringRequestedOrientationEnabled = mContext.getResources().getBoolean(                  R.bool.config_letterboxIsPolicyForIgnoringRequestedOrientationEnabled); +        mThinLetterboxWidthFn = () ->  mContext.getResources().getDimensionPixelSize( +                R.dimen.config_letterboxThinLetterboxWidthDp); +        mThinLetterboxHeightFn = () -> mContext.getResources().getDimensionPixelSize( +                R.dimen.config_letterboxThinLetterboxHeightDp);          mLetterboxConfigurationPersister = letterboxConfigurationPersister;          mLetterboxConfigurationPersister.start(); @@ -1129,6 +1139,24 @@ final class LetterboxConfiguration {      }      /** +     * @return Width in pixel about the padding to use to understand if the letterbox for an +     *         activity is thin. If the available space has width W and the app has width w, this +     *         is the maximum value for (W - w) / 2 to be considered for a thin letterboxed app. +     */ +    int getThinLetterboxWidthPx() { +        return mThinLetterboxWidthFn.getAsInt(); +    } + +    /** +     * @return Height in pixel about the padding to use to understand if a letterbox is thin. +     *         If the available space has height H and the app has height h, this is the maximum +     *         value for (H - h) / 2 to be considered for a thin letterboxed app. +     */ +    int getThinLetterboxHeightPx() { +        return mThinLetterboxHeightFn.getAsInt(); +    } + +    /**       * Overrides whether using split screen aspect ratio as a default aspect ratio for unresizable       * apps.       */ diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index e327f57c611f..b75869cf3812 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -131,6 +131,7 @@ import com.android.internal.statusbar.LetterboxDetails;  import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;  import com.android.server.wm.utils.OptPropFactory;  import com.android.server.wm.utils.OptPropFactory.OptProp; +import com.android.window.flags.Flags;  import java.io.PrintWriter;  import java.util.ArrayList; @@ -1004,6 +1005,67 @@ final class LetterboxUiController {          return getSplitScreenAspectRatio();      } +    /** +     * @return {@value true} if the resulting app is letterboxed in a way defined as thin. +     */ +    boolean isVerticalThinLetterboxed() { +        final int thinHeight = mLetterboxConfiguration.getThinLetterboxHeightPx(); +        if (thinHeight < 0) { +            return false; +        } +        final Task task = mActivityRecord.getTask(); +        if (task == null) { +            return false; +        } +        final int padding = Math.abs( +                task.getBounds().height() - mActivityRecord.getBounds().height()) / 2; +        return padding <= thinHeight; +    } + +    /** +     * @return {@value true} if the resulting app is pillarboxed in a way defined as thin. +     */ +    boolean isHorizontalThinLetterboxed() { +        final int thinWidth = mLetterboxConfiguration.getThinLetterboxWidthPx(); +        if (thinWidth < 0) { +            return false; +        } +        final Task task = mActivityRecord.getTask(); +        if (task == null) { +            return false; +        } +        final int padding = Math.abs( +                task.getBounds().width() - mActivityRecord.getBounds().width()) / 2; +        return padding <= thinWidth; +    } + + +    /** +     * @return {@value true} if the vertical reachability should be allowed in case of +     * thin letteboxing +     */ +    boolean allowVerticalReachabilityForThinLetterbox() { +        if (!Flags.disableThinLetterboxingReachability()) { +            return true; +        } +        // When the flag is enabled we allow vertical reachability only if the +        // app is not thin letterboxed vertically. +        return !isVerticalThinLetterboxed(); +    } + +    /** +     * @return {@value true} if the vertical reachability should be enabled in case of +     * thin letteboxing +     */ +    boolean allowHorizontalReachabilityForThinLetterbox() { +        if (!Flags.disableThinLetterboxingReachability()) { +            return true; +        } +        // When the flag is enabled we allow horizontal reachability only if the +        // app is not thin pillarboxed. +        return !isHorizontalThinLetterboxed(); +    } +      float getSplitScreenAspectRatio() {          // Getting the same aspect ratio that apps get in split screen.          final DisplayArea displayArea = mActivityRecord.getDisplayArea(); @@ -1243,6 +1305,9 @@ final class LetterboxUiController {       * </ul>       */      private boolean isHorizontalReachabilityEnabled(Configuration parentConfiguration) { +        if (!allowHorizontalReachabilityForThinLetterbox()) { +            return false; +        }          // Use screen resolved bounds which uses resolved bounds or size compat bounds          // as activity bounds can sometimes be empty          final Rect opaqueActivityBounds = hasInheritedLetterboxBehavior() @@ -1278,6 +1343,9 @@ final class LetterboxUiController {       * </ul>       */      private boolean isVerticalReachabilityEnabled(Configuration parentConfiguration) { +        if (!allowVerticalReachabilityForThinLetterbox()) { +            return false; +        }          // Use screen resolved bounds which uses resolved bounds or size compat bounds          // as activity bounds can sometimes be empty          final Rect opaqueActivityBounds = hasInheritedLetterboxBehavior() @@ -1551,6 +1619,8 @@ final class LetterboxUiController {          if (!shouldShowLetterboxUi) {              return;          } +        pw.println(prefix + "  isVerticalThinLetterboxed=" + isVerticalThinLetterboxed()); +        pw.println(prefix + "  isHorizontalThinLetterboxed=" + isHorizontalThinLetterboxed());          pw.println(prefix + "  letterboxBackgroundColor=" + Integer.toHexString(                  getLetterboxBackgroundColor().toArgb()));          pw.println(prefix + "  letterboxBackgroundType=" diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 1353ff09b292..d7bed5d155b6 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -3546,8 +3546,6 @@ class Task extends TaskFragment {          info.isVisibleRequested = isVisibleRequested();          info.isSleeping = shouldSleepActivities();          info.isTopActivityTransparent = top != null && !top.fillsParent(); -        appCompatTaskInfo.isLetterboxDoubleTapEnabled = top != null -                && top.mLetterboxUiController.isLetterboxDoubleTapEducationEnabled();          appCompatTaskInfo.topActivityLetterboxVerticalPosition = TaskInfo.PROPERTY_VALUE_UNSET;          appCompatTaskInfo.topActivityLetterboxHorizontalPosition = TaskInfo.PROPERTY_VALUE_UNSET;          appCompatTaskInfo.topActivityLetterboxWidth = TaskInfo.PROPERTY_VALUE_UNSET; @@ -3562,15 +3560,29 @@ class Task extends TaskFragment {              appCompatTaskInfo.topActivityLetterboxWidth = top.getBounds().width();              appCompatTaskInfo.topActivityLetterboxHeight = top.getBounds().height();          } +        // We need to consider if letterboxed or pillarboxed +        // TODO(b/336807329) Encapsulate reachability logic +        appCompatTaskInfo.isLetterboxDoubleTapEnabled = top != null +                && top.mLetterboxUiController.isLetterboxDoubleTapEducationEnabled();          if (appCompatTaskInfo.isLetterboxDoubleTapEnabled) {              if (appCompatTaskInfo.isTopActivityPillarboxed()) { -                // Pillarboxed -                appCompatTaskInfo.topActivityLetterboxHorizontalPosition = -                        top.mLetterboxUiController.getLetterboxPositionForHorizontalReachability(); +                if (top.mLetterboxUiController.allowHorizontalReachabilityForThinLetterbox()) { +                    // Pillarboxed +                    appCompatTaskInfo.topActivityLetterboxHorizontalPosition = +                            top.mLetterboxUiController +                                    .getLetterboxPositionForHorizontalReachability(); +                } else { +                    appCompatTaskInfo.isLetterboxDoubleTapEnabled = false; +                }              } else { -                // Letterboxed -                appCompatTaskInfo.topActivityLetterboxVerticalPosition = -                        top.mLetterboxUiController.getLetterboxPositionForVerticalReachability(); +                if (top.mLetterboxUiController.allowVerticalReachabilityForThinLetterbox()) { +                    // Letterboxed +                    appCompatTaskInfo.topActivityLetterboxVerticalPosition = +                            top.mLetterboxUiController +                                    .getLetterboxPositionForVerticalReachability(); +                } else { +                    appCompatTaskInfo.isLetterboxDoubleTapEnabled = false; +                }              }          }          appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton = top != null diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java index b717d981244b..6806f6a9e461 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java @@ -83,6 +83,8 @@ import android.content.pm.PackageManager;  import android.content.pm.PackageManager.Property;  import android.content.res.Resources;  import android.graphics.Rect; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags;  import android.platform.test.annotations.Presubmit;  import android.view.InsetsSource;  import android.view.InsetsState; @@ -94,6 +96,7 @@ import android.view.WindowManager;  import androidx.test.filters.SmallTest;  import com.android.internal.R; +import com.android.window.flags.Flags;  import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;  import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; @@ -1486,6 +1489,98 @@ public class LetterboxUiControllerTest extends WindowTestsBase {                          mActivity.getParent().getConfiguration()), /* delta */  0.01);      } +    @Test +    public void testIsVerticalThinLetterboxed() { +        // Vertical thin letterbox disabled +        doReturn(-1).when(mActivity.mWmService.mLetterboxConfiguration) +                .getThinLetterboxHeightPx(); +        assertFalse(mController.isVerticalThinLetterboxed()); +        // Define a Task 100x100 +        final Task task = mock(Task.class); +        doReturn(new Rect(0, 0, 100, 100)).when(task).getBounds(); +        doReturn(10).when(mActivity.mWmService.mLetterboxConfiguration) +                .getThinLetterboxHeightPx(); + +        // Vertical thin letterbox disabled without Task +        doReturn(null).when(mActivity).getTask(); +        assertFalse(mController.isVerticalThinLetterboxed()); +        // Assign a Task for the Activity +        doReturn(task).when(mActivity).getTask(); + +        // (task.width() - act.width()) / 2  = 5 < 10 +        doReturn(new Rect(5, 5, 95, 95)).when(mActivity).getBounds(); +        assertTrue(mController.isVerticalThinLetterboxed()); + +        // (task.width() - act.width()) / 2  = 10 = 10 +        doReturn(new Rect(10, 10, 90, 90)).when(mActivity).getBounds(); +        assertTrue(mController.isVerticalThinLetterboxed()); + +        // (task.width() - act.width()) / 2  = 11 > 10 +        doReturn(new Rect(11, 11, 89, 89)).when(mActivity).getBounds(); +        assertFalse(mController.isVerticalThinLetterboxed()); +    } + +    @Test +    public void testIsHorizontalThinLetterboxed() { +        // Horizontal thin letterbox disabled +        doReturn(-1).when(mActivity.mWmService.mLetterboxConfiguration) +                .getThinLetterboxWidthPx(); +        assertFalse(mController.isHorizontalThinLetterboxed()); +        // Define a Task 100x100 +        final Task task = mock(Task.class); +        doReturn(new Rect(0, 0, 100, 100)).when(task).getBounds(); +        doReturn(10).when(mActivity.mWmService.mLetterboxConfiguration) +                .getThinLetterboxWidthPx(); + +        // Vertical thin letterbox disabled without Task +        doReturn(null).when(mActivity).getTask(); +        assertFalse(mController.isHorizontalThinLetterboxed()); +        // Assign a Task for the Activity +        doReturn(task).when(mActivity).getTask(); + +        // (task.height() - act.height()) / 2  = 5 < 10 +        doReturn(new Rect(5, 5, 95, 95)).when(mActivity).getBounds(); +        assertTrue(mController.isHorizontalThinLetterboxed()); + +        // (task.height() - act.height()) / 2  = 10 = 10 +        doReturn(new Rect(10, 10, 90, 90)).when(mActivity).getBounds(); +        assertTrue(mController.isHorizontalThinLetterboxed()); + +        // (task.height() - act.height()) / 2  = 11 > 10 +        doReturn(new Rect(11, 11, 89, 89)).when(mActivity).getBounds(); +        assertFalse(mController.isHorizontalThinLetterboxed()); +    } + +    @Test +    @EnableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_REACHABILITY) +    public void testAllowReachabilityForThinLetterboxWithFlagEnabled() { +        spyOn(mController); +        doReturn(true).when(mController).isVerticalThinLetterboxed(); +        assertFalse(mController.allowVerticalReachabilityForThinLetterbox()); +        doReturn(true).when(mController).isHorizontalThinLetterboxed(); +        assertFalse(mController.allowHorizontalReachabilityForThinLetterbox()); + +        doReturn(false).when(mController).isVerticalThinLetterboxed(); +        assertTrue(mController.allowVerticalReachabilityForThinLetterbox()); +        doReturn(false).when(mController).isHorizontalThinLetterboxed(); +        assertTrue(mController.allowHorizontalReachabilityForThinLetterbox()); +    } + +    @Test +    @DisableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_REACHABILITY) +    public void testAllowReachabilityForThinLetterboxWithFlagDisabled() { +        spyOn(mController); +        doReturn(true).when(mController).isVerticalThinLetterboxed(); +        assertTrue(mController.allowVerticalReachabilityForThinLetterbox()); +        doReturn(true).when(mController).isHorizontalThinLetterboxed(); +        assertTrue(mController.allowHorizontalReachabilityForThinLetterbox()); + +        doReturn(false).when(mController).isVerticalThinLetterboxed(); +        assertTrue(mController.allowVerticalReachabilityForThinLetterbox()); +        doReturn(false).when(mController).isHorizontalThinLetterboxed(); +        assertTrue(mController.allowHorizontalReachabilityForThinLetterbox()); +    } +      private void mockThatProperty(String propertyName, boolean value) throws Exception {          Property property = new Property(propertyName, /* value */ value, /* packageName */ "",                   /* className */ ""); 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 606070c64a2a..36c1c8cc7659 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -3612,11 +3612,27 @@ public class SizeCompatTests extends WindowTestsBase {      }      @Test +    public void testIsReachabilityEnabled_thisLetterbox_false() { +        // Case when the reachability would be enabled otherwise +        setUpDisplaySizeWithApp(/* dw */ 1000, /* dh */ 2800); +        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); +        mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true); +        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); +        mActivity.getWindowConfiguration().setBounds(null); + +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ false); + +        assertFalse(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled()); +        assertFalse(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled()); +    } + +    @Test      public void testIsHorizontalReachabilityEnabled_splitScreen_false() {          mAtm.mDevEnableNonResizableMultiWindow = true;          setUpDisplaySizeWithApp(2800, 1000);          mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);          mWm.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true); +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);          final TestSplitOrganizer organizer =                  new TestSplitOrganizer(mAtm, mActivity.getDisplayContent()); @@ -3639,6 +3655,7 @@ public class SizeCompatTests extends WindowTestsBase {          setUpDisplaySizeWithApp(1000, 2800);          mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);          mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true); +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);          final TestSplitOrganizer organizer =                  new TestSplitOrganizer(mAtm, mActivity.getDisplayContent()); @@ -3660,6 +3677,7 @@ public class SizeCompatTests extends WindowTestsBase {          setUpDisplaySizeWithApp(1000, 2800);          mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);          mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true); +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);          // Unresizable landscape-only activity.          prepareUnresizable(mActivity, 1.1f, SCREEN_ORIENTATION_LANDSCAPE); @@ -3681,6 +3699,7 @@ public class SizeCompatTests extends WindowTestsBase {          setUpDisplaySizeWithApp(/* dw */ 1000, /* dh */ 2800);          mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);          mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true); +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);          prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); @@ -3697,6 +3716,7 @@ public class SizeCompatTests extends WindowTestsBase {          setUpDisplaySizeWithApp(/* dw */ 2800, /* dh */ 1000);          mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);          mWm.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true); +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);          prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); @@ -3713,6 +3733,7 @@ public class SizeCompatTests extends WindowTestsBase {          // Portrait display          setUpDisplaySizeWithApp(1400, 1600);          mActivity.mWmService.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true); +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);          // 16:9f unresizable portrait app          prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, @@ -3726,6 +3747,7 @@ public class SizeCompatTests extends WindowTestsBase {          // Landscape display          setUpDisplaySizeWithApp(1600, 1500);          mActivity.mWmService.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true); +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);          // 16:9f unresizable landscape app          prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, @@ -3739,6 +3761,7 @@ public class SizeCompatTests extends WindowTestsBase {          setUpDisplaySizeWithApp(2800, 1000);          mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);          mWm.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true); +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);          // Unresizable portrait-only activity.          prepareUnresizable(mActivity, 1.1f, SCREEN_ORIENTATION_PORTRAIT); @@ -3760,6 +3783,7 @@ public class SizeCompatTests extends WindowTestsBase {          setUpDisplaySizeWithApp(1800, 2200);          mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);          mWm.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true); +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);          // Unresizable portrait-only activity.          prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); @@ -3781,6 +3805,7 @@ public class SizeCompatTests extends WindowTestsBase {          setUpDisplaySizeWithApp(2200, 1800);          mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);          mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true); +        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);          // Unresizable landscape-only activity.          prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); @@ -4947,6 +4972,14 @@ public class SizeCompatTests extends WindowTestsBase {          assertFalse(activity.shouldSendCompatFakeFocus());      } +    private void setUpAllowThinLetterboxed(boolean thinLetterboxAllowed) { +        spyOn(mActivity.mLetterboxUiController); +        doReturn(thinLetterboxAllowed).when(mActivity.mLetterboxUiController) +                .allowVerticalReachabilityForThinLetterbox(); +        doReturn(thinLetterboxAllowed).when(mActivity.mLetterboxUiController) +                .allowHorizontalReachabilityForThinLetterbox(); +    } +      private int getExpectedSplitSize(int dimensionToSplit) {          int dividerWindowWidth =                  mActivity.mWmService.mContext.getResources().getDimensionPixelSize(  |