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

Commit 4e6cde2f authored by amehfooz's avatar amehfooz
Browse files

[ROSP] Add support for multiple chip icons

This CL adds support for more than one icon to be shown in the
StatusBarPopupChip. For starters, it will be used by the AvControlsChip
status chip to display a mic and camera icon.

Bug: 406518844
Test: Make sure the media control chip behavior is unchanged
Flag: com.android.systemui.status_bar_popup_chips

Change-Id: I203435d960304057d9b893249d75dba49de42fc0
parent 2ddfb2ea
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import androidx.compose.runtime.getValue
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.statusbar.featurepods.popups.shared.model.ChipIcon
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
import com.android.systemui.statusbar.featurepods.popups.ui.viewmodel.StatusBarPopupChipViewModel
@@ -57,7 +58,7 @@ constructor(avControlsChipInteractor: AvControlsChipInteractor) :
                PopupChipModel.Shown(
                    // TODO: Pass in color when the api supports it
                    chipId = chipId,
                    icon = icon(sensorActivityModel = sensorActivityModel),
                    icons = listOf(ChipIcon(icon(sensorActivityModel = sensorActivityModel))),
                    chipText = chipText(sensorActivityModel = sensorActivityModel),
                )
        }
+11 −4
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.statusbar.featurepods.media.domain.interactor.MediaControlChipInteractor
import com.android.systemui.statusbar.featurepods.media.shared.model.MediaControlChipModel
import com.android.systemui.statusbar.featurepods.popups.shared.model.ChipIcon
import com.android.systemui.statusbar.featurepods.popups.shared.model.HoverBehavior
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
@@ -80,7 +81,7 @@ constructor(
                )
        return PopupChipModel.Shown(
            chipId = PopupChipId.MediaControl,
            icon = defaultIcon,
            icons = listOf(ChipIcon(icon = defaultIcon)),
            chipText = model.songName.toString(),
            hoverBehavior = createHoverBehavior(model),
        )
@@ -94,9 +95,15 @@ constructor(
        val contentDescription =
            ContentDescription.Loaded(description = playOrPause.contentDescription.toString())

        return HoverBehavior.Button(
            icon = Icon.Loaded(drawable = icon, contentDescription = contentDescription),
            onIconPressed = { action.run() },
        return HoverBehavior.Buttons(
            icons =
                listOf(
                    ChipIcon(
                        icon =
                            Icon.Loaded(drawable = icon, contentDescription = contentDescription),
                        onClick = { action.run() },
                    )
                )
        )
    }

+8 −8
Original line number Diff line number Diff line
@@ -28,16 +28,16 @@ sealed class PopupChipId(val value: String) {
    data object AvControlsIndicator : PopupChipId("AvControlsIndicator")
}

/** Model for an optionally clickable icon that is displayed on the chip. */
data class ChipIcon(val icon: Icon, val onClick: (() -> Unit)? = null)

/** Defines the behavior of the chip when hovered over. */
sealed interface HoverBehavior {
    /** No specific hover behavior. The default icon will be shown. */
    /** No specific hover behavior. The default icons will be shown. */
    data object None : HoverBehavior

    /**
     * Shows a button on hover with the given [icon] and executes [onIconPressed] when the icon is
     * pressed.
     */
    data class Button(val icon: Icon, val onIconPressed: () -> Unit) : HoverBehavior
    /** Shows a list of buttons on hover with the given [icons] */
    data class Buttons(val icons: List<ChipIcon>) : HoverBehavior
}

/** Model for individual status bar popup chips. */
@@ -52,8 +52,8 @@ sealed class PopupChipModel {

    data class Shown(
        override val chipId: PopupChipId,
        /** Default icon displayed on the chip */
        val icon: Icon,
        /** Icons shown on the chip when no specific hover behavior. */
        val icons: List<ChipIcon>,
        val chipText: String,
        val isPopupShown: Boolean = false,
        val showPopup: () -> Unit = {},
+22 −27
Original line number Diff line number Diff line
@@ -28,15 +28,13 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.contentColorFor
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -59,6 +57,7 @@ import androidx.compose.ui.unit.dp
import com.android.compose.modifiers.thenIf
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.res.R
import com.android.systemui.statusbar.featurepods.popups.shared.model.ChipIcon
import com.android.systemui.statusbar.featurepods.popups.shared.model.HoverBehavior
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel

@@ -118,30 +117,13 @@ fun StatusBarPopupChip(viewModel: PopupChipModel.Shown, modifier: Modifier = Mod
            val hoverBehavior = viewModel.hoverBehavior
            val iconBackgroundColor = contentColorFor(chipBackgroundColor)
            val iconInteractionSource = remember { MutableInteractionSource() }
            Icon(
                icon =

            val chipIcons =
                when {
                        isHovered && hoverBehavior is HoverBehavior.Button -> hoverBehavior.icon
                        else -> viewModel.icon
                    },
                modifier =
                    Modifier.height(20.dp)
                        .width(20.dp)
                        .thenIf(isHovered) {
                            Modifier.background(color = iconBackgroundColor, shape = CircleShape)
                                .padding(2.dp)
                    isHovered && hoverBehavior is HoverBehavior.Buttons -> hoverBehavior.icons
                    else -> viewModel.icons
                }
                        .thenIf(hoverBehavior is HoverBehavior.Button) {
                            Modifier.clickable(
                                role = Role.Button,
                                onClick = (hoverBehavior as HoverBehavior.Button).onIconPressed,
                                indication = ripple(),
                                interactionSource = iconInteractionSource,
                                enabled = isHovered,
                            )
                        },
                tint = iconColor,
            )
            ChipIcons(chipIcons = chipIcons)

            val text = viewModel.chipText
            val textStyle = MaterialTheme.typography.labelLarge
@@ -185,6 +167,19 @@ fun StatusBarPopupChip(viewModel: PopupChipModel.Shown, modifier: Modifier = Mod
    }
}

@Composable
private fun ChipIcons(chipIcons: List<ChipIcon>) {
    for (chipIcon in chipIcons) {
        Icon(
            icon = chipIcon.icon,
            modifier =
                Modifier.size(20.dp).thenIf(chipIcon.onClick != null) {
                    Modifier.clickable(role = Role.Button, onClick = chipIcon.onClick!!)
                },
        )
    }
}

private fun Modifier.overflowFadeOut(hasOverflow: () -> Boolean, fadeLength: Dp): Modifier {
    return drawWithCache {
        val width = size.width