Fix NPE when using hinge split type without FoldingFeature

Before this CL, we only compute SplitType in getRelBounds.
However, we actually obtain the bounds to check minimum
dimensions in #computeSplitAttributes.

This CL moves the splitType calculation to
 #getPrimaryBounds and #getSecondaryBounds to cover the
minimum dimensions to fix NPE.

Test: atest SplitPresenterTest
Bug: 263565586
fixes: 275714114

Merged-In: Ibb826c25f072cdffd5b5adcd19571fe446d64f51
Change-Id: Ibb826c25f072cdffd5b5adcd19571fe446d64f51
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 668a7d5..c23ac75 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -661,21 +661,14 @@
             @NonNull SplitAttributes splitAttributes) {
         final Configuration taskConfiguration = taskProperties.getConfiguration();
         final FoldingFeature foldingFeature = getFoldingFeature(taskProperties);
-        final SplitType splitType = computeSplitType(splitAttributes, taskConfiguration,
-                foldingFeature);
-        final SplitAttributes computedSplitAttributes = new SplitAttributes.Builder()
-                .setSplitType(splitType)
-                .setLayoutDirection(splitAttributes.getLayoutDirection())
-                .build();
-        if (!shouldShowSplit(computedSplitAttributes)) {
+        if (!shouldShowSplit(splitAttributes)) {
             return new Rect();
         }
         switch (position) {
             case POSITION_START:
-                return getPrimaryBounds(taskConfiguration, computedSplitAttributes, foldingFeature);
+                return getPrimaryBounds(taskConfiguration, splitAttributes, foldingFeature);
             case POSITION_END:
-                return getSecondaryBounds(taskConfiguration, computedSplitAttributes,
-                        foldingFeature);
+                return getSecondaryBounds(taskConfiguration, splitAttributes, foldingFeature);
             case POSITION_FILL:
             default:
                 return new Rect();
@@ -685,29 +678,76 @@
     @NonNull
     private Rect getPrimaryBounds(@NonNull Configuration taskConfiguration,
             @NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
-        if (!shouldShowSplit(splitAttributes)) {
+        final SplitAttributes computedSplitAttributes = updateSplitAttributesType(splitAttributes,
+                computeSplitType(splitAttributes, taskConfiguration, foldingFeature));
+        if (!shouldShowSplit(computedSplitAttributes)) {
             return new Rect();
         }
-        switch (splitAttributes.getLayoutDirection()) {
+        switch (computedSplitAttributes.getLayoutDirection()) {
             case SplitAttributes.LayoutDirection.LEFT_TO_RIGHT: {
-                return getLeftContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
+                return getLeftContainerBounds(taskConfiguration, computedSplitAttributes,
+                        foldingFeature);
             }
             case SplitAttributes.LayoutDirection.RIGHT_TO_LEFT: {
-                return getRightContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
+                return getRightContainerBounds(taskConfiguration, computedSplitAttributes,
+                        foldingFeature);
             }
             case SplitAttributes.LayoutDirection.LOCALE: {
                 final boolean isLtr = taskConfiguration.getLayoutDirection()
                         == View.LAYOUT_DIRECTION_LTR;
                 return isLtr
-                        ? getLeftContainerBounds(taskConfiguration, splitAttributes, foldingFeature)
-                        : getRightContainerBounds(taskConfiguration, splitAttributes,
+                        ? getLeftContainerBounds(taskConfiguration, computedSplitAttributes,
+                                foldingFeature)
+                        : getRightContainerBounds(taskConfiguration, computedSplitAttributes,
                                 foldingFeature);
             }
             case SplitAttributes.LayoutDirection.TOP_TO_BOTTOM: {
-                return getTopContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
+                return getTopContainerBounds(taskConfiguration, computedSplitAttributes,
+                        foldingFeature);
             }
             case SplitAttributes.LayoutDirection.BOTTOM_TO_TOP: {
-                return getBottomContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
+                return getBottomContainerBounds(taskConfiguration, computedSplitAttributes,
+                        foldingFeature);
+            }
+            default:
+                throw new IllegalArgumentException("Unknown layout direction:"
+                        + computedSplitAttributes.getLayoutDirection());
+        }
+    }
+
+    @NonNull
+    private Rect getSecondaryBounds(@NonNull Configuration taskConfiguration,
+            @NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
+        final SplitAttributes computedSplitAttributes = updateSplitAttributesType(splitAttributes,
+                computeSplitType(splitAttributes, taskConfiguration, foldingFeature));
+        if (!shouldShowSplit(computedSplitAttributes)) {
+            return new Rect();
+        }
+        switch (computedSplitAttributes.getLayoutDirection()) {
+            case SplitAttributes.LayoutDirection.LEFT_TO_RIGHT: {
+                return getRightContainerBounds(taskConfiguration, computedSplitAttributes,
+                        foldingFeature);
+            }
+            case SplitAttributes.LayoutDirection.RIGHT_TO_LEFT: {
+                return getLeftContainerBounds(taskConfiguration, computedSplitAttributes,
+                        foldingFeature);
+            }
+            case SplitAttributes.LayoutDirection.LOCALE: {
+                final boolean isLtr = taskConfiguration.getLayoutDirection()
+                        == View.LAYOUT_DIRECTION_LTR;
+                return isLtr
+                        ? getRightContainerBounds(taskConfiguration, computedSplitAttributes,
+                                foldingFeature)
+                        : getLeftContainerBounds(taskConfiguration, computedSplitAttributes,
+                                foldingFeature);
+            }
+            case SplitAttributes.LayoutDirection.TOP_TO_BOTTOM: {
+                return getBottomContainerBounds(taskConfiguration, computedSplitAttributes,
+                        foldingFeature);
+            }
+            case SplitAttributes.LayoutDirection.BOTTOM_TO_TOP: {
+                return getTopContainerBounds(taskConfiguration, computedSplitAttributes,
+                        foldingFeature);
             }
             default:
                 throw new IllegalArgumentException("Unknown layout direction:"
@@ -715,38 +755,17 @@
         }
     }
 
-    @NonNull
-    private Rect getSecondaryBounds(@NonNull Configuration taskConfiguration,
-            @NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
-        if (!shouldShowSplit(splitAttributes)) {
-            return new Rect();
-        }
-        switch (splitAttributes.getLayoutDirection()) {
-            case SplitAttributes.LayoutDirection.LEFT_TO_RIGHT: {
-                return getRightContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
-            }
-            case SplitAttributes.LayoutDirection.RIGHT_TO_LEFT: {
-                return getLeftContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
-            }
-            case SplitAttributes.LayoutDirection.LOCALE: {
-                final boolean isLtr = taskConfiguration.getLayoutDirection()
-                        == View.LAYOUT_DIRECTION_LTR;
-                return isLtr
-                        ? getRightContainerBounds(taskConfiguration, splitAttributes,
-                                foldingFeature)
-                        : getLeftContainerBounds(taskConfiguration, splitAttributes,
-                                foldingFeature);
-            }
-            case SplitAttributes.LayoutDirection.TOP_TO_BOTTOM: {
-                return getBottomContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
-            }
-            case SplitAttributes.LayoutDirection.BOTTOM_TO_TOP: {
-                return getTopContainerBounds(taskConfiguration, splitAttributes, foldingFeature);
-            }
-            default:
-                throw new IllegalArgumentException("Unknown layout direction:"
-                        + splitAttributes.getLayoutDirection());
-        }
+    /**
+     * Returns the {@link SplitAttributes} that update the {@link SplitType} to
+     * {@code splitTypeToUpdate}.
+     */
+    private static SplitAttributes updateSplitAttributesType(
+            @NonNull SplitAttributes splitAttributes, @NonNull SplitType splitTypeToUpdate) {
+        return new SplitAttributes.Builder()
+                .setSplitType(splitTypeToUpdate)
+                .setLayoutDirection(splitAttributes.getLayoutDirection())
+                .setAnimationBackgroundColor(splitAttributes.getAnimationBackgroundColor())
+                .build();
     }
 
     @NonNull
@@ -841,7 +860,8 @@
     }
 
     @Nullable
-    private FoldingFeature getFoldingFeature(@NonNull TaskProperties taskProperties) {
+    @VisibleForTesting
+    FoldingFeature getFoldingFeature(@NonNull TaskProperties taskProperties) {
         final int displayId = taskProperties.getDisplayId();
         final WindowConfiguration windowConfiguration = taskProperties.getConfiguration()
                 .windowConfiguration;
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
index a288fd6..d286d23 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
@@ -572,6 +572,27 @@
                 splitPairRule, null /* minDimensionsPair */));
     }
 
+    @Test
+    public void testComputeSplitAttributesOnHingeSplitTypeOnDeviceWithoutFoldingFeature() {
+        final SplitAttributes hingeSplitAttrs = new SplitAttributes.Builder()
+                .setSplitType(new SplitAttributes.SplitType.HingeSplitType(
+                        SplitAttributes.SplitType.RatioSplitType.splitEqually()))
+                .build();
+        final SplitPairRule splitPairRule = createSplitPairRuleBuilder(
+                activityPair -> true,
+                activityIntentPair -> true,
+                windowMetrics -> windowMetrics.getBounds().equals(TASK_BOUNDS))
+                .setFinishSecondaryWithPrimary(DEFAULT_FINISH_SECONDARY_WITH_PRIMARY)
+                .setFinishPrimaryWithSecondary(DEFAULT_FINISH_PRIMARY_WITH_SECONDARY)
+                .setDefaultSplitAttributes(hingeSplitAttrs)
+                .build();
+        final TaskContainer.TaskProperties taskProperties = getTaskProperty();
+        doReturn(null).when(mPresenter).getFoldingFeature(any());
+
+        assertEquals(hingeSplitAttrs, mPresenter.computeSplitAttributes(taskProperties,
+                splitPairRule, null /* minDimensionsPair */));
+    }
+
     private Activity createMockActivity() {
         final Activity activity = mock(Activity.class);
         final Configuration activityConfig = new Configuration();