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

Commit 1bd2be79 authored by Matías Hernández's avatar Matías Hernández
Browse files

Don't share Drawables between Modes Tile and rows in Modes Dialog

Since they are tinted differently, they were messing up each other.

Fixes: 418228600
Test: atest ModesDialogViewModelTest + manual
Flag: EXEMPT Trivial bugfix
Change-Id: I12f5b67eb6610198ecd761a2d35def29c39d030d
parent 66e62af0
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.settingslib.notification.modes.TestModeBuilder
import com.android.settingslib.notification.modes.TestModeBuilder.MANUAL_DND
import com.android.settingslib.notification.modes.ZenMode
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
@@ -457,6 +458,48 @@ class ModesDialogViewModelTest : SysuiTestCase() {
            tiles!!.forEach { assertThat(it.onLongClickLabel).isEqualTo("Open settings") }
        }

    @Test
    fun tiles_doesNotShareIcons() =
        testScope.runTest {
            val tiles by collectLastValue(underTest.tiles)
            repository.addModes(
                listOf(
                    TestModeBuilder()
                        .setId("bedtime1")
                        .setName("Bedtime Mode #1")
                        .setManualInvocationAllowed(true)
                        .setType(AutomaticZenRule.TYPE_BEDTIME)
                        .setActive(false)
                        .build(),
                    TestModeBuilder()
                        .setId("bedtime2")
                        .setName("Bedtime Mode #2")
                        .setManualInvocationAllowed(true)
                        .setType(AutomaticZenRule.TYPE_BEDTIME)
                        .setActive(false)
                        .build(),
                )
            )

            assertThat(tiles).hasSize(3) // DND + Bedtimes
            assertThat(tiles!![1].text).isEqualTo("Bedtime Mode #1")
            assertThat(tiles!![2].text).isEqualTo("Bedtime Mode #2")
            val tileIcon1 = tiles!![1].icon as Icon.Loaded
            val tileIcon2 = tiles!![2].icon as Icon.Loaded

            // The cache is actually caching...
            val bedtimeIcon = interactor.getModeIcon(repository.getMode("bedtime1")!!)
            val bedtimeIcon2 = interactor.getModeIcon(repository.getMode("bedtime2")!!)
            assertThat(bedtimeIcon2.drawable).isSameInstanceAs(bedtimeIcon.drawable)

            // ... but the tiles get COPIES of the icons
            assertThat(tileIcon1.res).isEqualTo(bedtimeIcon.key.resId)
            assertThat(tileIcon2.res).isEqualTo(bedtimeIcon.key.resId)
            assertThat(tileIcon1.drawable).isNotSameInstanceAs(bedtimeIcon.drawable)
            assertThat(tileIcon2.drawable).isNotSameInstanceAs(bedtimeIcon.drawable)
            assertThat(tileIcon2.drawable).isNotSameInstanceAs(tileIcon1.drawable)
        }

    @Test
    fun onClick_togglesTileState() =
        testScope.runTest {
+22 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.provider.Settings.ACTION_AUTOMATIC_ZEN_RULE_SETTINGS
import android.provider.Settings.EXTRA_AUTOMATIC_ZEN_RULE_ID
import com.android.settingslib.notification.modes.ZenMode
import com.android.settingslib.notification.modes.ZenModeDescriptions
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.asIcon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
@@ -45,7 +46,7 @@ class ModesDialogViewModel
@Inject
constructor(
    val context: Context,
    zenModeInteractor: ZenModeInteractor,
    private val zenModeInteractor: ZenModeInteractor,
    @Background val bgDispatcher: CoroutineDispatcher,
    private val dialogDelegate: ModesDialogDelegate,
    private val dialogEventLogger: ModesDialogEventLogger,
@@ -86,7 +87,7 @@ constructor(
                modesList.map { mode ->
                    ModeTileViewModel(
                        id = mode.id,
                        icon = zenModeInteractor.getModeIcon(mode).drawable().asIcon(),
                        icon = getIcon(mode),
                        text = mode.name,
                        subtext = getTileSubtext(mode),
                        subtextDescription =
@@ -124,6 +125,25 @@ constructor(
            }
            .flowOn(bgDispatcher)

    /**
     * Get the icon of the [ZenMode] from the cache, cloning the drawable to prevent state sharing
     * (otherwise, the modes tile will be tinted the same way as the items in the dialog).
     */
    private suspend fun getIcon(mode: ZenMode): Icon.Loaded {
        val cachedIcon = zenModeInteractor.getModeIcon(mode)
        val iconDrawable =
            cachedIcon.drawable.constantState?.newDrawable(context.resources)
                ?: cachedIcon.drawable.mutate()
        return iconDrawable.asIcon(
            res =
                if (cachedIcon.key.resPackage == null) {
                    cachedIcon.key.resId
                } else {
                    null
                }
        )
    }

    private fun openSettings(mode: ZenMode) {
        dialogEventLogger.logModeSettings(mode)
        val intent: Intent =