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

Commit f8f17ca5 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[SB][RON] Add custom color to RON demo command.

Bug: 361346412
Flag: com.android.systemui.status_bar_ron_chips
Test: `adb shell cmd statusbar demo-ron -p com.android.systemui -t 10min -c 434343`
-> verify status bar chip shows with dark gray color
Test: verify call chips and screen share chips still work as expected
Test: atest DemoRonChipViewModelTest

Change-Id: I5765c83ba2038d8c9a07ef48ba4c2dab151c6c24
parent a76d8cca
Loading
Loading
Loading
Loading
+22 −6
Original line number Original line Diff line number Diff line
@@ -42,9 +42,9 @@ import kotlinx.coroutines.flow.asStateFlow
 *
 *
 * Example adb commands:
 * Example adb commands:
 *
 *
 * To show a chip with the SysUI icon and custom text:
 * To show a chip with the SysUI icon and custom text and color:
 * ```
 * ```
 * adb shell cmd statusbar demo-ron -p com.android.systemui -t 10min
 * adb shell cmd statusbar demo-ron -p com.android.systemui -t 10min -c "\\#434343"
 * ```
 * ```
 *
 *
 * To hide the chip:
 * To hide the chip:
@@ -87,6 +87,17 @@ constructor(
                valueParser = Type.String,
                valueParser = Type.String,
            )
            )


        private val backgroundColor: Int? by
            param(
                longName = "color",
                shortName = "c",
                description =
                    "The color to show as the chip background color. " +
                        "You can either just write a basic color like 'red' or 'green', " +
                        "or you can include a #RRGGBB string in this format: \"\\\\#434343\".",
                valueParser = Type.Color,
            )

        private val hide by
        private val hide by
            flag(
            flag(
                longName = "hide",
                longName = "hide",
@@ -119,21 +130,26 @@ constructor(
                return
                return
            }
            }


            val colors =
                if (backgroundColor != null) {
                    ColorsModel.Custom(backgroundColorInt = backgroundColor!!)
                } else {
                    ColorsModel.Themed
                }

            val currentText = text
            val currentText = text
            if (currentText != null) {
            if (currentText != null) {
                _chip.value =
                _chip.value =
                    OngoingActivityChipModel.Shown.Text(
                    OngoingActivityChipModel.Shown.Text(
                        icon = appIcon,
                        icon = appIcon,
                        // TODO(b/361346412): Include a demo with a custom color theme.
                        colors = colors,
                        colors = ColorsModel.Themed,
                        text = currentText,
                        text = currentText,
                    )
                    )
            } else {
            } else {
                _chip.value =
                _chip.value =
                    OngoingActivityChipModel.Shown.Timer(
                    OngoingActivityChipModel.Shown.Timer(
                        icon = appIcon,
                        icon = appIcon,
                        // TODO(b/361346412): Include a demo with a custom color theme.
                        colors = colors,
                        colors = ColorsModel.Themed,
                        startTimeMs = systemClock.elapsedRealtime(),
                        startTimeMs = systemClock.elapsedRealtime(),
                        onClickListener = null,
                        onClickListener = null,
                    )
                    )
+18 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,24 @@ sealed interface ColorsModel {
            Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
            Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
    }
    }


    /**
     * The chip should have the given background color, and text color that matches dark/light
     * theme.
     */
    data class Custom(val backgroundColorInt: Int) : ColorsModel {
        override fun background(context: Context): ColorStateList =
            ColorStateList.valueOf(backgroundColorInt)

        // TODO(b/361346412): When dark theme changes, the chip should automatically re-render with
        // the right text color. Right now, it has the right text color when the chip is first
        // created but the color doesn't update if dark theme changes.
        override fun text(context: Context) =
            Utils.getColorAttrDefaultColor(
                context,
                com.android.internal.R.attr.materialColorOnSurface,
            )
    }

    /** The chip should have a red background with white text. */
    /** The chip should have a red background with white text. */
    data object Red : ColorsModel {
    data object Red : ColorsModel {
        override fun background(context: Context): ColorStateList {
        override fun background(context: Context): ColorStateList {
+14 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.systemui.statusbar.commandline
package com.android.systemui.statusbar.commandline


import androidx.core.graphics.toColorInt
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import kotlin.contracts.contract
@@ -164,10 +165,23 @@ private val parseFloat: ValueParser<Float> = ValueParser { value ->
        ?: Result.failure(ArgParseError("Failed to parse $value as a float"))
        ?: Result.failure(ArgParseError("Failed to parse $value as a float"))
}
}


// See https://developer.android.com/reference/android/graphics/Color#parseColor(java.lang.String)
// for the supported formats of the color string. tl;dr: #RRGGBB, #AARRGGBB, or a basic color name
// like "red" or "green". For the RRGGBB values, the `#` needs to be escaped. Use `"\\#RRGGBB"` in
// the command to escape the `#` correctly.
private val parseColor: ValueParser<Int> = ValueParser { value ->
    try {
        Result.success(value.toColorInt())
    } catch (e: IllegalArgumentException) {
        Result.failure(ArgParseError("Failed to parse $value as a color: $e"))
    }
}

/** Default parsers that can be use as-is, or [map]ped to another type */
/** Default parsers that can be use as-is, or [map]ped to another type */
object Type {
object Type {
    val Boolean = parseBoolean
    val Boolean = parseBoolean
    val Int = parseInt
    val Int = parseInt
    val Float = parseFloat
    val Float = parseFloat
    val String = parseString
    val String = parseString
    val Color = parseColor
}
}
+17 −0
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.systemui.Flags.FLAG_STATUS_BAR_RON_CHIPS
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.commandline.commandRegistry
import com.android.systemui.statusbar.commandline.commandRegistry
@@ -101,6 +102,22 @@ class DemoRonChipViewModelTest : SysuiTestCase() {
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Text::class.java)
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Text::class.java)
        }
        }


    @Test
    @EnableFlags(FLAG_STATUS_BAR_RON_CHIPS)
    fun chip_supportsColor() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)

            commandRegistry.onShellCommand(
                pw,
                arrayOf("demo-ron", "-p", "com.android.systemui", "-c", "#434343")
            )

            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
            assertThat((latest as OngoingActivityChipModel.Shown).colors)
                .isInstanceOf(ColorsModel.Custom::class.java)
        }

    @Test
    @Test
    @EnableFlags(FLAG_STATUS_BAR_RON_CHIPS)
    @EnableFlags(FLAG_STATUS_BAR_RON_CHIPS)
    fun chip_hasHideArg_hidden() =
    fun chip_hasHideArg_hidden() =
+9 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,15 @@ class ValueParserTest : SysuiTestCase() {
        assertTrue(Type.Boolean.parseValue("not a Boolean").isFailure)
        assertTrue(Type.Boolean.parseValue("not a Boolean").isFailure)
    }
    }


    @Test
    fun parseColor() {
        assertThat(Type.Color.parseValue("#434343").isSuccess).isTrue()
        assertThat(Type.Color.parseValue("#aa123456").isSuccess).isTrue()
        assertThat(Type.Color.parseValue("red").isSuccess).isTrue()

        assertThat(Type.Color.parseValue("not a color").isFailure).isTrue()
    }

    @Test
    @Test
    fun mapToComplexType() {
    fun mapToComplexType() {
        val parseSquare = Type.Int.map { Rect(it, it, it, it) }
        val parseSquare = Type.Int.map { Rect(it, it, it, it) }