Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2583a8f4 authored by Lucas Silva's avatar Lucas Silva
Browse files

Handle invalid values in ResizeableItemFrameViewModel

If the maxSpans is less than the currentSpans, the anchors are
calculated incorrectly which leads to a crash in SystemUI. This fix
ensures that we always coerce the max to be at least the current spans.

This can happen when Compose is initializing, and the padding values
haven't been finalized yet. In this intermediate state, we may receive
invalid values before the grid stabilizes.

Fixes: 376490959
Test: atest ResizeableItemFrameViewModelTest
Flag: com.android.systemui.communal_widget_resizing
Change-Id: Ic9b569fb1894b950882aeaeea5065c99c762dc74
parent 067c153f
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -366,6 +366,39 @@ class ResizeableItemFrameViewModelTest : SysuiTestCase() {
            assertThat(bottomState.anchors.toList()).containsExactly(0 to 0f)
        }

    @Test
    fun testMaxSpansLessThanCurrentSpan() =
        testScope.runTest {
            // heightPerSpan =
            // (viewportHeightPx - verticalContentPaddingPx - (totalSpans - 1)
            // * verticalItemSpacingPx) / totalSpans
            // = 145.3333
            // maxSpans = (maxHeightPx + verticalItemSpacing) /
            // (heightPerSpanPx + verticalItemSpacingPx)
            // = 4.72
            // This is invalid because the max span calculation comes out to be less than
            // the current span. Ensure we handle this case correctly.
            val layout =
                GridLayout(
                    verticalItemSpacingPx = 100f,
                    currentRow = 0,
                    minHeightPx = 480,
                    maxHeightPx = 1060,
                    currentSpan = 6,
                    resizeMultiple = 3,
                    totalSpans = 6,
                    viewportHeightPx = 1600,
                    verticalContentPaddingPx = 228f,
                )
            updateGridLayout(layout)

            val topState = underTest.topDragState
            val bottomState = underTest.bottomDragState

            assertThat(topState.anchors.toList()).containsExactly(0 to 0f)
            assertThat(bottomState.anchors.toList()).containsExactly(0 to 0f, -3 to -736f)
        }

    @Test
    fun testCanExpand_atTopPosition_withMultipleAnchors_returnsTrue() =
        testScope.runTest {
+2 −2
Original line number Diff line number Diff line
@@ -76,10 +76,10 @@ class ResizeableItemFrameViewModel : ExclusiveActivatable() {
            floor(spans.toDouble() / resizeMultiple).toInt() * resizeMultiple

        val maxSpans: Int
            get() = roundDownToMultiple(getSpansForPx(maxHeightPx))
            get() = roundDownToMultiple(getSpansForPx(maxHeightPx)).coerceAtLeast(currentSpan)

        val minSpans: Int
            get() = roundDownToMultiple(getSpansForPx(minHeightPx))
            get() = roundDownToMultiple(getSpansForPx(minHeightPx)).coerceAtMost(currentSpan)
    }

    /** Check if widget can expanded based on current drag states */