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

Commit 3aebc4e2 authored by Lucas Dupin's avatar Lucas Dupin Committed by Android (Google) Code Review
Browse files

Merge "Deduplicate the same app icons." into main

parents 743bc3d4 f32b97a8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ fun Chip(action: ActionViewModel, modifier: Modifier = Modifier) {
                .combinedClickable(onClick = action.onClick, onLongClick = action.onLongClick)
                .padding(start = 12.dp, end = 16.dp, top = 4.dp, bottom = 4.dp),
    ) {
        val painter = rememberDrawablePainter(action.icon)
        val painter = rememberDrawablePainter(action.icon.drawable)
        Image(
            painter = painter,
            contentDescription = action.label,
+19 −14
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import androidx.compose.ui.util.lerp
import com.android.compose.PlatformIconButton
import com.android.compose.ui.graphics.painter.rememberDrawablePainter
import com.android.systemui.ambientcue.ui.compose.modifier.animatedActionBorder
import com.android.systemui.ambientcue.ui.utils.FilterUtils
import com.android.systemui.ambientcue.ui.viewmodel.ActionType
import com.android.systemui.ambientcue.ui.viewmodel.ActionViewModel
import com.android.systemui.res.R
@@ -197,7 +198,8 @@ fun NavBarPill(
                ) {
                    // Should have at most 1 expanded chip
                    var expandedChip = false
                    actions.fastForEachIndexed { index, action ->
                    val filteredActions = FilterUtils.filterActions(actions)
                    filteredActions.fastForEachIndexed { index, action ->
                        val isMrAction = action.actionType == ActionType.MR

                        // Pill rounded container
@@ -219,9 +221,9 @@ fun NavBarPill(
                                        shape = CircleShape,
                                    )
                                }
                            if ((actions.size == 1 || isMrAction) && !expandedChip) {
                            if ((filteredActions.size == 1 || isMrAction) && !expandedChip) {
                                expandedChip = true
                                val hasBackground = actions.size > 1
                                val hasBackground = filteredActions.size > 1
                                // Expanded chip for single action or MR
                                Row(
                                    horizontalArrangement = Arrangement.spacedBy(6.dp),
@@ -238,11 +240,12 @@ fun NavBarPill(
                                            .padding(4.dp),
                                ) {
                                    Image(
                                        painter = rememberDrawablePainter(action.icon),
                                        painter = rememberDrawablePainter(action.icon.drawable),
                                        contentDescription = action.label,
                                        modifier =
                                            Modifier.size(16.dp).then(iconBorder).clip(CircleShape),
                                    )
                                    if (!action.icon.repeated) {
                                        Text(
                                            text = action.label,
                                            style = MaterialTheme.typography.labelMedium,
@@ -252,16 +255,18 @@ fun NavBarPill(
                                            modifier = Modifier.widthIn(0.dp, maxPillWidth * 0.5f),
                                        )
                                    }
                                }
                            } else {
                                // Smaller app icons
                                Image(
                                    painter = rememberDrawablePainter(action.icon),
                                    painter = rememberDrawablePainter(action.icon.drawable),
                                    contentDescription = action.label,
                                    modifier =
                                        Modifier.then(
                                                when (index) {
                                                    0 -> Modifier.padding(start = 5.dp)
                                                    actions.size - 1 -> Modifier.padding(end = 5.dp)
                                                    filteredActions.size - 1 ->
                                                        Modifier.padding(end = 5.dp)
                                                    else -> Modifier
                                                }
                                            )
+6 −3
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ import androidx.compose.ui.util.fastForEach
import com.android.compose.PlatformIconButton
import com.android.compose.ui.graphics.painter.rememberDrawablePainter
import com.android.systemui.ambientcue.ui.compose.modifier.animatedActionBorder
import com.android.systemui.ambientcue.ui.utils.FilterUtils
import com.android.systemui.ambientcue.ui.viewmodel.ActionType
import com.android.systemui.ambientcue.ui.viewmodel.ActionViewModel
import com.android.systemui.res.R
@@ -167,6 +168,8 @@ fun ShortPill(
                .then(if (expanded) Modifier else Modifier.clickable { onClick() })
                .padding(4.dp)

        val filteredActions = FilterUtils.filterActions(actions)

        if (horizontal) {
            Row(
                horizontalArrangement = Arrangement.spacedBy(8.dp),
@@ -181,7 +184,7 @@ fun ShortPill(
                    verticalAlignment = Alignment.CenterVertically,
                    modifier = pillModifier.defaultMinSize(minWidth = minSize),
                ) {
                    actions.take(3).fastForEach { action ->
                    filteredActions.take(3).fastForEach { action ->
                        Icon(action, backgroundColor)
                        if (actions.size == 1) {
                            Text(
@@ -215,7 +218,7 @@ fun ShortPill(
                    verticalArrangement = Arrangement.spacedBy(-4.dp, Alignment.CenterVertically),
                    modifier = pillModifier.defaultMinSize(minHeight = minSize),
                ) {
                    actions.take(3).fastForEach { action -> Icon(action, backgroundColor) }
                    filteredActions.take(3).fastForEach { action -> Icon(action, backgroundColor) }
                }

                CloseButton(
@@ -257,7 +260,7 @@ private fun CloseButton(
@Composable
private fun Icon(action: ActionViewModel, backgroundColor: Color, modifier: Modifier = Modifier) {
    Image(
        painter = rememberDrawablePainter(action.icon),
        painter = rememberDrawablePainter(action.icon.drawable),
        contentDescription = action.label,
        modifier =
            modifier
+7 −3
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.ambientcue.data.repository.ambientCueRepository
import com.android.systemui.ambientcue.data.repository.fake
import com.android.systemui.ambientcue.shared.model.ActionModel
import com.android.systemui.ambientcue.shared.model.IconModel
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.res.R
@@ -60,10 +61,13 @@ class AmbientCueInteractorTest : SysuiTestCase() {
                listOf(
                    ActionModel(
                        icon =
                            IconModel(
                                applicationContext.resources.getDrawable(
                                    R.drawable.ic_content_paste_spark,
                                    applicationContext.theme,
                                ),
                                "test.icon",
                            ),
                        label = "Sunday Morning",
                        attribution = null,
                        onPerformAction = {},
+88 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.ambientcue.ui.utils

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.ambientcue.ui.viewmodel.ActionType
import com.android.systemui.ambientcue.ui.viewmodel.ActionViewModel
import com.android.systemui.ambientcue.ui.viewmodel.IconViewModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock

@RunWith(AndroidJUnit4::class)
@SmallTest
class FilterUtilsTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    private lateinit var calendarAction1: ActionViewModel
    private lateinit var calendarAction2: ActionViewModel
    private lateinit var mapsAction: ActionViewModel

    @Before
    fun setUp() {
        calendarAction1 =
            ActionViewModel(
                icon = IconViewModel(mock(), "calendar_icon", false),
                label = "Sunday Morning",
                attribution = null,
                onClick = {},
                onLongClick = {},
                actionType = ActionType.MA,
            )
        calendarAction2 =
            ActionViewModel(
                icon = IconViewModel(mock(), "calendar_icon", false),
                label = "Sunday Evening",
                attribution = null,
                onClick = {},
                onLongClick = {},
                actionType = ActionType.MA,
            )
        mapsAction =
            ActionViewModel(
                icon = IconViewModel(mock(), "map_icon", false),
                label = "Philz Coffee San Carlos",
                onClick = {},
                onLongClick = {},
                actionType = ActionType.MA,
            )
    }

    @Test
    fun filterActions_noRepeatedAction_returnOriginalActions() {
        val filterActions = FilterUtils.filterActions(listOf(calendarAction1, mapsAction))

        assertThat(filterActions.size).isEqualTo(2)
        assertThat(filterActions).contains(calendarAction1)
        assertThat(filterActions).contains(mapsAction)
    }

    @Test
    fun filterActions_repeatedCalendarAction_filterCalendarAction() {
        val filterActions = FilterUtils.filterActions(listOf(calendarAction1, calendarAction2))

        assertThat(filterActions.size).isEqualTo(1)
        assertThat(filterActions[0].label).isEqualTo("Sunday Morning Sunday Evening")
        assertThat(filterActions[0].icon.repeated).isTrue()
    }
}
Loading