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

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

Show the icon of the active mode in the Modes Tile

Or, if multiple modes are active, the most prioritized mode.

Bug: 361052669
Test: atest ModesTileDataInteractorTest ModesTileMapperTest
Flag: android.app.modes_ui_icons
Change-Id: Ib8ae9d731f59d283566bbd995257ab21e3ff61fb
parent 78e5497b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -20,6 +20,16 @@ flag {
  bug: "270703654"
}

flag {
  name: "modes_ui_icons"
  namespace: "systemui"
  description: "Shows current Priority Mode icon in lockscreen, status bar, and QS; dependent on flags modes_api and modes_ui"
  bug: "360399800"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
  name: "modes_ui_test"
  namespace: "systemui"
+6 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.settingslib.notification.data.repository

import android.app.AutomaticZenRule
import android.app.NotificationManager
import android.provider.Settings
import com.android.settingslib.notification.modes.TestModeBuilder
@@ -58,8 +59,9 @@ class FakeZenModeRepository : ZenModeRepository {
        mutableModesFlow.value += zenModes
    }

    fun addMode(id: String, active: Boolean = false) {
        mutableModesFlow.value += newMode(id, active)
    fun addMode(id: String, @AutomaticZenRule.Type type: Int = AutomaticZenRule.TYPE_UNKNOWN,
        active: Boolean = false) {
        mutableModesFlow.value += newMode(id, type, active)
    }

    fun removeMode(id: String) {
@@ -128,6 +130,6 @@ fun FakeZenModeRepository.updateNotificationPolicy(
        )
    )

private fun newMode(id: String, active: Boolean = false): ZenMode {
    return TestModeBuilder().setId(id).setName("Mode $id").setActive(active).build()
private fun newMode(id: String, @AutomaticZenRule.Type type: Int, active: Boolean): ZenMode {
    return TestModeBuilder().setId(id).setName("Mode $id").setType(type).setActive(active).build()
}
+1 −1
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ public class ZenMode implements Parcelable {
    };

    // Manual DND first, Bedtime/Driving, then alphabetically.
    static final Comparator<ZenMode> PRIORITIZING_COMPARATOR = Comparator
    public static final Comparator<ZenMode> PRIORITIZING_COMPARATOR = Comparator
            .comparing(ZenMode::isManualDnd).reversed()
            .thenComparing(ZenMode::getType, PRIORITIZED_TYPE_COMPARATOR)
            .thenComparing(ZenMode::getName);
+76 −2
Original line number Diff line number Diff line
@@ -16,19 +16,24 @@

package com.android.systemui.qs.tiles.impl.modes.domain.interactor

import android.app.AutomaticZenRule
import android.app.Flags
import android.graphics.drawable.TestStubDrawable
import android.os.UserHandle
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.asIcon
import com.android.systemui.coroutines.collectValues
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
import com.android.systemui.shared.notifications.data.repository.NotificationSettingsRepository
import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository
import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -36,8 +41,10 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.toCollection
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -48,7 +55,20 @@ class ModesTileDataInteractorTest : SysuiTestCase() {
    private val dispatcher = kosmos.testDispatcher
    private val zenModeRepository = kosmos.fakeZenModeRepository

    private val underTest = ModesTileDataInteractor(zenModeRepository, dispatcher)
    private val underTest =
        ModesTileDataInteractor(
            context,
            ZenModeInteractor(zenModeRepository, mock<NotificationSettingsRepository>()),
            dispatcher
        )

    @Before
    fun setUp() {
        context.orCreateTestableResources.apply {
            addOverride(com.android.internal.R.drawable.ic_zen_mode_type_bedtime, BEDTIME_DRAWABLE)
            addOverride(com.android.internal.R.drawable.ic_zen_mode_type_driving, DRIVING_DRAWABLE)
        }
    }

    @EnableFlags(Flags.FLAG_MODES_UI)
    @Test
@@ -110,8 +130,62 @@ class ModesTileDataInteractorTest : SysuiTestCase() {
            assertThat(dataList.map { it.activeModes }.last()).isEmpty()
        }

    private companion object {
    @Test
    @EnableFlags(Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS)
    fun changesIconWhenActiveModesChange() =
        testScope.runTest {
            val dataList: List<ModesTileModel> by
                collectValues(
                    underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest))
                )
            runCurrent()
            assertThat(dataList.map { it.icon }).containsExactly(null).inOrder()

            // Add an inactive mode: state hasn't changed, so this shouldn't cause another emission
            zenModeRepository.addMode(id = "Mode", active = false)
            runCurrent()
            assertThat(dataList.map { it.icon }).containsExactly(null).inOrder()

            // Add an active mode: icon should be the mode icon
            zenModeRepository.addMode(
                id = "Bedtime",
                type = AutomaticZenRule.TYPE_BEDTIME,
                active = true
            )
            runCurrent()
            assertThat(dataList.map { it.icon }).containsExactly(null, BEDTIME_ICON).inOrder()

            // Add another, less-prioritized mode: icon should remain the first mode icon
            zenModeRepository.addMode(
                id = "Driving",
                type = AutomaticZenRule.TYPE_DRIVING,
                active = true
            )
            runCurrent()
            assertThat(dataList.map { it.icon })
                .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON)
                .inOrder()

            // Deactivate more important mode: icon should be the less important, still active mode.
            zenModeRepository.deactivateMode("Bedtime")
            runCurrent()
            assertThat(dataList.map { it.icon })
                .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON, DRIVING_ICON)
                .inOrder()

            // Deactivate remaining mode: no icon
            zenModeRepository.deactivateMode("Driving")
            runCurrent()
            assertThat(dataList.map { it.icon })
                .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON, DRIVING_ICON, null)
                .inOrder()
        }

    private companion object {
        val TEST_USER = UserHandle.of(1)!!
        val BEDTIME_DRAWABLE = TestStubDrawable("bedtime")
        val DRIVING_DRAWABLE = TestStubDrawable("driving")
        val BEDTIME_ICON = BEDTIME_DRAWABLE.asIcon()
        val DRIVING_ICON = DRIVING_DRAWABLE.asIcon()
    }
}
+16 −0
Original line number Diff line number Diff line
@@ -16,10 +16,13 @@

package com.android.systemui.qs.tiles.impl.modes.ui

import android.app.Flags
import android.graphics.drawable.TestStubDrawable
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder
import com.android.systemui.qs.tiles.viewmodel.QSTileState
@@ -31,6 +34,7 @@ import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
@EnableFlags(Flags.FLAG_MODES_UI)
class ModesTileMapperTest : SysuiTestCase() {
    val config =
        QSTileConfigTestBuilder.build {
@@ -85,4 +89,16 @@ class ModesTileMapperTest : SysuiTestCase() {
        assertThat(state.iconRes).isEqualTo(R.drawable.qs_dnd_icon_on)
        assertThat(state.secondaryLabel).isEqualTo("3 modes are active")
    }

    @Test
    @EnableFlags(Flags.FLAG_MODES_UI_ICONS)
    fun activeState_withIcon() {
        val icon = Icon.Resource(1234, contentDescription = null)
        val model = ModesTileModel(isActivated = true, activeModes = listOf("DND"), icon = icon)

        val state = underTest.map(config, model)

        assertThat(state.iconRes).isNull()
        assertThat(state.icon()).isEqualTo(icon)
    }
}
Loading