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

Commit 2ccd4af1 authored by Alejandro Nijamkin's avatar Alejandro Nijamkin Committed by Ale Nijamkin
Browse files

[flexiglass] Prevents crash when disable flags are set

There's a crash when certain disable flags are set. It comes from the
measure policy of SingleShadeMeasurePolicy which assumes that certain
elements are laid out when they're not (because the disable flags makes
those elements disappear in runtime).

This CL only prevents the crash, it doesn't fix the positioning of the
UMO in these cases, that still needs to be tested and fixed properly.
See the test lines for how to fix it properly. This is tracked in
b/379162317.

Bug: 371545613
Test: manually verified that disabling certain disable flags doesn't
crash anymore. The commands used are:
$ adb shell cmd statusbar send-disable-flag quick-settings
$ adb shell cmd statusbar send-disable-flag statusbar-expansion
$ adb shell cmd statusbar send-disable-flag none
Flag: com.android.systemui.scene_container

Change-Id: Ie26bbb743f06e2eb1549e67b9a5a3c7ca0613857
parent 5bc0fe80
Loading
Loading
Loading
Loading
+27 −20
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.offset
import androidx.compose.ui.util.fastFirst
import androidx.compose.ui.util.fastFirstOrNull
import com.android.systemui.shade.ui.composable.SingleShadeMeasurePolicy.LayoutId
import kotlin.math.max
@@ -60,18 +59,20 @@ class SingleShadeMeasurePolicy(

        val shadeHeaderPlaceable =
            measurables
                .fastFirst { it.layoutId == LayoutId.ShadeHeader }
                .measure(constraintsWithCutout)
                .fastFirstOrNull { it.layoutId == LayoutId.ShadeHeader }
                ?.measure(constraintsWithCutout)
        val mediaPlaceable =
            measurables
                .fastFirstOrNull { it.layoutId == LayoutId.Media }
                ?.measure(applyMediaConstraints(constraintsWithCutout, isMediaInRow))
        val quickSettingsPlaceable =
            measurables
                .fastFirst { it.layoutId == LayoutId.QuickSettings }
                .measure(constraintsWithCutout)
                .fastFirstOrNull { it.layoutId == LayoutId.QuickSettings }
                ?.measure(constraintsWithCutout)
        val notificationsPlaceable =
            measurables.fastFirst { it.layoutId == LayoutId.Notifications }.measure(constraints)
            measurables
                .fastFirstOrNull { it.layoutId == LayoutId.Notifications }
                ?.measure(constraints)

        val notificationsTop =
            calculateNotificationsTop(
@@ -84,23 +85,25 @@ class SingleShadeMeasurePolicy(
        onNotificationsTopChanged(notificationsTop)

        return layout(constraints.maxWidth, constraints.maxHeight) {
            shadeHeaderPlaceable.placeRelative(x = insetsLeft, y = insetsTop)
            quickSettingsPlaceable.placeRelative(
            shadeHeaderPlaceable?.placeRelative(x = insetsLeft, y = insetsTop)
            val statusBarHeaderHeight = shadeHeaderPlaceable?.height ?: 0
            quickSettingsPlaceable?.placeRelative(
                x = insetsLeft,
                y = insetsTop + shadeHeaderPlaceable.height,
                y = insetsTop + statusBarHeaderHeight,
            )

            if (mediaPlaceable != null)
            if (mediaPlaceable != null) {
                val quickSettingsHeight = quickSettingsPlaceable?.height ?: 0

                if (isMediaInRow) {
                    // mediaPlaceable height ranges from 0 to qsHeight. We want it to be centered
                    // vertically when it's smaller than the QS
                    val mediaCenteringOffset =
                        (quickSettingsPlaceable.height - mediaPlaceable.height) / 2
                    val mediaCenteringOffset = (quickSettingsHeight - mediaPlaceable.height) / 2
                    mediaPlaceable.placeRelative(
                        x = insetsLeft + constraintsWithCutout.maxWidth / 2,
                        y =
                            insetsTop +
                                shadeHeaderPlaceable.height +
                                statusBarHeaderHeight +
                                mediaCenteringOffset +
                                mediaOffset(),
                        zIndex = mediaZIndex(),
@@ -108,30 +111,34 @@ class SingleShadeMeasurePolicy(
                } else {
                    mediaPlaceable.placeRelative(
                        x = insetsLeft,
                        y = insetsTop + shadeHeaderPlaceable.height + quickSettingsPlaceable.height,
                        y = insetsTop + statusBarHeaderHeight + quickSettingsHeight,
                        zIndex = mediaZIndex(),
                    )
                }
            }

            // Notifications don't need to accommodate for horizontal insets
            notificationsPlaceable.placeRelative(x = 0, y = notificationsTop)
            notificationsPlaceable?.placeRelative(x = 0, y = notificationsTop)
        }
    }

    private fun calculateNotificationsTop(
        statusBarHeaderPlaceable: Placeable,
        quickSettingsPlaceable: Placeable,
        statusBarHeaderPlaceable: Placeable?,
        quickSettingsPlaceable: Placeable?,
        mediaPlaceable: Placeable?,
        insetsTop: Int,
        isMediaInRow: Boolean,
    ): Int {
        val mediaHeight = mediaPlaceable?.height ?: 0
        val statusBarHeaderHeight = statusBarHeaderPlaceable?.height ?: 0
        val quickSettingsHeight = quickSettingsPlaceable?.height ?: 0

        return insetsTop +
            statusBarHeaderPlaceable.height +
            statusBarHeaderHeight +
            if (isMediaInRow) {
                max(quickSettingsPlaceable.height, mediaHeight)
                max(quickSettingsHeight, mediaHeight)
            } else {
                quickSettingsPlaceable.height + mediaHeight
                quickSettingsHeight + mediaHeight
            }
    }