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

Commit dee7d80d authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[battery] batteries are like onions" into main

parents b8afec82 3ac3d7b9
Loading
Loading
Loading
Loading
+16 −26
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@ import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -43,9 +43,8 @@ import com.android.systemui.statusbar.core.RudimentaryBattery
import com.android.systemui.statusbar.events.BackgroundAnimatableView
import com.android.systemui.statusbar.pipeline.battery.domain.interactor.BatteryInteractor
import com.android.systemui.statusbar.pipeline.battery.shared.ui.BatteryColors
import com.android.systemui.statusbar.pipeline.battery.shared.ui.BatteryFrame
import com.android.systemui.statusbar.pipeline.battery.shared.ui.BatteryGlyph
import com.android.systemui.statusbar.pipeline.battery.ui.composable.BatteryCanvas
import com.android.systemui.statusbar.pipeline.battery.ui.composable.BatteryLayout
import com.android.systemui.statusbar.pipeline.battery.ui.viewmodel.BatteryViewModel
import com.android.systemui.statusbar.pipeline.battery.ui.viewmodel.UnifiedBatteryViewModel.Companion.glyphRepresentation
import java.text.NumberFormat
@@ -105,20 +104,15 @@ constructor(level: Int, context: Context, attrs: AttributeSet? = null) :
private fun UnifiedBatteryChip(level: Int) {
    val isFull = BatteryInteractor.isBatteryFull(level)
    val height = with(LocalDensity.current) { BatteryViewModel.STATUS_BAR_BATTERY_HEIGHT.toDp() }
    BatteryCanvas(
        modifier = Modifier.height(height).aspectRatio(BatteryViewModel.ASPECT_RATIO),
        path = BatteryFrame.pathSpec,
    BatteryLayout(
        attribution = BatteryGlyph.Bolt, // Always charging
        levelProvider = { level },
        isFullProvider = { isFull },
        glyphsProvider = { level.glyphRepresentation() },
        colorsProvider = { BatteryColors.DarkTheme.Charging },
        modifier = Modifier.height(height).wrapContentWidth(),
        // TODO(b/394659067): get a content description for this chip
        contentDescription = "",
        innerWidth = BatteryFrame.innerWidth,
        innerHeight = BatteryFrame.innerHeight,
        // This event only happens when plugged in, so we always show it as charging
        glyphs =
            if (isFull) listOf(BatteryGlyph.Bolt)
            else level.glyphRepresentation() + BatteryGlyph.Bolt,
        level = level,
        isFull = isFull,
        colorsProvider = { BatteryColors.DarkTheme.Charging },
    )
}

@@ -128,18 +122,14 @@ private fun BatteryAndPercentChip(level: Int) {
    val isFull = BatteryInteractor.isBatteryFull(level)
    val height = with(LocalDensity.current) { BatteryViewModel.STATUS_BAR_BATTERY_HEIGHT.toDp() }
    Row(verticalAlignment = Alignment.CenterVertically) {
        BatteryCanvas(
            modifier = Modifier.height(height).aspectRatio(BatteryViewModel.ASPECT_RATIO),
            path = BatteryFrame.pathSpec,
            // TODO(b/394659067): get a content description for this chip
            contentDescription = "",
            innerWidth = BatteryFrame.innerWidth,
            innerHeight = BatteryFrame.innerHeight,
            // This event only happens when plugged in, so we always show it as charging
            glyphs = listOf(BatteryGlyph.Bolt),
            level = level,
            isFull = isFull,
        BatteryLayout(
            attribution = BatteryGlyph.Bolt, // Always charging
            levelProvider = { level },
            isFullProvider = { isFull },
            glyphsProvider = { emptyList() },
            colorsProvider = { BatteryColors.DarkTheme.Charging },
            modifier = Modifier.height(height).wrapContentWidth(),
            contentDescription = "",
        )
        Spacer(modifier = Modifier.width(4.dp))
        Text(
+13 −13
Original line number Diff line number Diff line
@@ -38,6 +38,9 @@ sealed interface BatteryColors {
    /** Background color suitable for providing contrast with the [glyph] color */
    val backgroundWithGlyph: Color

    /** The layered attribution. Should match the tint of other status bar icons */
    val attribution: Color

    /**
     * Light theme: light background, dark icons
     *
@@ -47,11 +50,13 @@ sealed interface BatteryColors {
     * thus allow for higher contrast with the darker [glyph] colors.
     */
    sealed class LightTheme : BatteryColors {
        override val attribution = Color.Black
        override val glyph = Color.Black.copy(alpha = 0.75f)
        override val backgroundOnly = lowAlphaBg
        override val backgroundWithGlyph = lowAlphaBg

        data object Default : LightTheme() {
            override val glyph = Color.White
            override val glyph = Color.White.copy(alpha = 0.9f)
            override val fill = Color.Black

            /** Use a higher opacity here because the foreground is white */
@@ -59,22 +64,19 @@ sealed interface BatteryColors {
        }

        data object Charging : LightTheme() {
            override val glyph = Color(0xFF162100)
            override val fill = Color(0xFFB4FF1E)
            override val fill = Color(0xFF18CC47)
        }

        data object Error : LightTheme() {
            override val glyph = Color(0xFF3A0907)
            override val fill = Color(0xFFFF0101)
            override val fill = Color(0xFFFF0E01)
        }

        data object PowerSave : LightTheme() {
            override val glyph = Color(0xFF2F1400)
            override val fill = Color(0xFFFFC917)
        }

        companion object {
            private val lowAlphaBg = Color.Black.copy(alpha = 0.30f)
            private val lowAlphaBg = Color.Black.copy(alpha = 0.20f)
            private val highAlphaBg = Color.Black.copy(alpha = 0.55f)
        }
    }
@@ -88,26 +90,24 @@ sealed interface BatteryColors {
     * contrast.
     */
    sealed class DarkTheme : BatteryColors {
        override val attribution = Color.White
        override val backgroundOnly = lowAlphaBg
        override val backgroundWithGlyph = highAlphaBg
        override val glyph = Color.Black.copy(alpha = 0.75f)

        data object Default : DarkTheme() {
            override val glyph = Color.Black
            override val fill = Color.White
        }

        data object Charging : DarkTheme() {
            override val glyph = Color(0xFF162100)
            override val fill = Color(0xFFB4FF1E)
            override val fill = Color(0xFF18CC47)
        }

        data object Error : DarkTheme() {
            override val glyph = Color(0xFF3A0907)
            override val fill = Color(0xFFFF0101)
            override val fill = Color(0xFFFF0E01)
        }

        data object PowerSave : DarkTheme() {
            override val glyph = Color(0xFF2F1400)
            override val fill = Color(0xFFFFC917)
        }

+39 −2
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.systemui.statusbar.pipeline.battery.shared.ui

import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.RoundRect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.addSvg
import androidx.compose.ui.unit.Dp
@@ -36,11 +40,41 @@ object BatteryFrame {
            viewportWidth = 21.dp,
        )

    val bodyPathSpec: PathSpec =
        PathSpec(
            path =
                Path().apply {
                    addRoundRect(
                        RoundRect(
                            rect = Rect(0f, 0f, 24f, 13f),
                            topLeft = CornerRadius(4f),
                            topRight = CornerRadius(4f),
                            bottomRight = CornerRadius(4f),
                            bottomLeft = CornerRadius(4f),
                        )
                    )
                },
            viewportWidth = 24.dp,
            viewportHeight = 13.dp,
        )

    val capPathSpec: PathSpec =
        PathSpec(
            path =
                Path().apply {
                    addSvg(
                        "M0.3333,-0.0037L0,-0.0037L0,6.0234L0.3333,6.0234C0.9777,6.0234 1.5,5.5011 1.5,4.8567L1.5,1.163C1.5,0.5187 0.9777,-0.0037 0.3333,-0.0037Z"
                    )
                },
            viewportWidth = 1.5.dp,
            viewportHeight = 6.03.dp,
        )

    /** The width of the drawable that is usable for inside elements */
    const val innerWidth = 19.5f
    const val innerWidth = 24f

    /** The height of the drawable that is usable for inside elements */
    const val innerHeight = 12f
    const val innerHeight = 13f
}

/**
@@ -57,4 +91,7 @@ data class PathSpec(val path: Path, val viewportWidth: Dp, val viewportHeight: D

        return min(xScale, yScale)
    }

    fun scaledSize(scale: Float): Size =
        Size(width = viewportWidth.value * scale, height = viewportHeight.value * scale)
}
+74 −136

File changed.

Preview size limit exceeded, changes collapsed.

+2 −2
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package com.android.systemui.statusbar.pipeline.battery.ui.binder

import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
@@ -62,7 +62,7 @@ object UnifiedBatteryViewBinder {
                            UnifiedBattery(
                                modifier =
                                    Modifier.height(height)
                                        .aspectRatio(BatteryViewModel.ASPECT_RATIO)
                                        .wrapContentWidth()
                                        .sysuiResTag(BatteryViewModel.TEST_TAG),
                                viewModelFactory = viewModelFactory,
                                isDarkProvider = { isDark },
Loading