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

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

When deactivating a mode via QS toggle, keep it as "quick mode" until the shade closes

After that, it reverts to the last manually activated mode, or DND.

Bug: 405988332
Test: atest ModesTileDataInteractorTest + manual
Flag: android.app.modes_ui_tile_reactivates_last
Change-Id: I6ef1c2857aedc5b624a2605d7d93a88bc95008c4
parent d834246a
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.settingslib.notification.modes.TestModeBuilder
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.common.shared.model.asIcon
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.mainCoroutineContext
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
@@ -45,8 +46,10 @@ import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor
import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileUserActionInteractor
import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel.ActiveMode
import com.android.systemui.qs.tiles.impl.modes.ui.mapper.ModesTileMapper
import com.android.systemui.res.R
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.policy.data.repository.zenModeRepository
import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate
@@ -95,7 +98,14 @@ class ModesTileTest : SysuiTestCase() {
    private val inputHandler = FakeQSTileIntentUserInputHandler()
    private val zenModeRepository = kosmos.zenModeRepository
    private val tileDataInteractor =
        ModesTileDataInteractor(context, kosmos.zenModeInteractor, testDispatcher)
        ModesTileDataInteractor(
            context,
            kosmos.zenModeInteractor,
            kosmos.shadeInteractor,
            kosmos.keyguardRepository,
            testDispatcher,
            testScope,
        )
    private val mapper = ModesTileMapper(context.resources, context.theme)

    private lateinit var userActionInteractor: ModesTileUserActionInteractor
@@ -130,6 +140,7 @@ class ModesTileTest : SysuiTestCase() {
                inputHandler,
                dialogDelegate,
                kosmos.zenModeInteractor,
                tileDataInteractor,
                kosmos.modesDialogEventLogger,
            )

@@ -186,7 +197,7 @@ class ModesTileTest : SysuiTestCase() {
            val model =
                ModesTileModel(
                    isActivated = true,
                    activeModes = listOf("One", "Two"),
                    activeModes = listOf(ActiveMode("1", "One"), ActiveMode("2", "Two")),
                    icon = TestStubDrawable().asIcon(),
                    quickMode = TestModeBuilder.MANUAL_DND,
                )
+71 −7
Original line number Diff line number Diff line
@@ -31,10 +31,14 @@ import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.asIcon
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository
import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
import com.android.systemui.testKosmos
@@ -57,9 +61,18 @@ class ModesTileDataInteractorTest : SysuiTestCase() {
    private val testScope = kosmos.testScope
    private val dispatcher = kosmos.testDispatcher
    private val zenModeRepository = kosmos.fakeZenModeRepository
    private val keyguardRepository = kosmos.fakeKeyguardRepository
    private val shadeTestUtil by lazy { kosmos.shadeTestUtil }

    private val underTest by lazy {
        ModesTileDataInteractor(context, kosmos.zenModeInteractor, dispatcher)
        ModesTileDataInteractor(
            context,
            kosmos.zenModeInteractor,
            kosmos.shadeInteractor,
            keyguardRepository,
            dispatcher,
            testScope,
        )
    }

    @Before
@@ -99,19 +112,21 @@ class ModesTileDataInteractorTest : SysuiTestCase() {
            zenModeRepository.addMode(id = "One", active = true)
            runCurrent()
            assertThat(dataList.map { it.isActivated }).containsExactly(false, true).inOrder()
            assertThat(dataList.map { it.activeModes }.last()).containsExactly("Mode One")
            assertThat(dataList.map { it.activeModes }.last().map { it.name })
                .containsExactly("Mode One")

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

            // Add another active mode
            zenModeRepository.addMode(id = "Three", active = true)
            runCurrent()
            assertThat(dataList.map { it.isActivated }).containsExactly(false, true, true).inOrder()
            assertThat(dataList.map { it.activeModes }.last())
            assertThat(dataList.map { it.activeModes }.last().map { it.name })
                .containsExactly("Mode One", "Mode Three")
                .inOrder()

@@ -244,6 +259,53 @@ class ModesTileDataInteractorTest : SysuiTestCase() {
            assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON)
        }

    @Test
    @EnableFlags(
        Flags.FLAG_MODES_UI_TILE_REACTIVATES_LAST,
        com.android.systemui.Flags.FLAG_QS_UI_REFACTOR_COMPOSE_FRAGMENT,
    )
    fun tileData_withRecentManualDeactivation_quickModeIsLastDeactivatedMode() =
        testScope.runTest {
            val tileData by
                collectLastValue(
                    underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest))
                )
            zenModeRepository.addMode(
                TestModeBuilder()
                    .setId("mode1")
                    .setManualInvocationAllowed(true)
                    .setPackage("android")
                    .setIconResId(BEDTIME_DRAWABLE_ID)
                    .build()
            )

            // Starts with DND as quick mode and icon.
            runCurrent()
            assertThat(tileData?.quickMode?.id).isEqualTo(TestModeBuilder.MANUAL_DND.id)
            assertThat(tileData?.icon).isEqualTo(MODES_ICON)

            // Active mode -> shows mode icon
            zenModeRepository.activateMode("mode1")
            runCurrent()
            assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON)

            // Open shade, deactivate mode and use it as override -> quick mode is deactivated mode
            keyguardRepository.setStatusBarState(StatusBarState.SHADE)
            // TODO: b/381869885 - Here and below, replace by setShadeExpansion.
            shadeTestUtil.setLegacyExpandedOrAwaitingInputTransfer(true)
            zenModeRepository.deactivateMode("mode1")
            underTest.setQuickModeOverride(listOf("mode1"))
            runCurrent()
            assertThat(tileData?.quickMode?.id).isEqualTo("mode1")
            assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON)

            // Shade closes -> Tile reverts to DND as quick mode
            shadeTestUtil.setLegacyExpandedOrAwaitingInputTransfer(false)
            runCurrent()
            assertThat(tileData?.quickMode?.id).isEqualTo(TestModeBuilder.MANUAL_DND.id)
            assertThat(tileData?.icon).isEqualTo(MODES_ICON)
        }

    @EnableFlags(Flags.FLAG_MODES_UI_TILE_REACTIVATES_LAST)
    fun tileData_withPastManualActivation_mruManualModeAsQuickMode() =
        testScope.runTest {
@@ -299,19 +361,21 @@ class ModesTileDataInteractorTest : SysuiTestCase() {
        zenModeRepository.addMode(id = "One", active = true)
        tileData = underTest.getCurrentTileModel()
        assertThat(tileData.isActivated).isTrue()
        assertThat(tileData.activeModes).containsExactly("Mode One")
        assertThat(tileData.activeModes.map { it.name }).containsExactly("Mode One")

        // Add an inactive mode: state hasn't changed
        zenModeRepository.addMode(id = "Two", active = false)
        tileData = underTest.getCurrentTileModel()
        assertThat(tileData.isActivated).isTrue()
        assertThat(tileData.activeModes).containsExactly("Mode One")
        assertThat(tileData.activeModes.map { it.name }).containsExactly("Mode One")

        // Add another active mode
        zenModeRepository.addMode(id = "Three", active = true)
        tileData = underTest.getCurrentTileModel()
        assertThat(tileData.isActivated).isTrue()
        assertThat(tileData.activeModes).containsExactly("Mode One", "Mode Three").inOrder()
        assertThat(tileData.activeModes.map { it.name })
            .containsExactly("Mode One", "Mode Three")
            .inOrder()

        // Remove a mode and deactivate the other
        zenModeRepository.removeMode("One")
+10 −2
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() {
    private val mockDialogDelegate = kosmos.mockModesDialogDelegate
    private val zenModeRepository = kosmos.zenModeRepository
    private val zenModeInteractor = kosmos.zenModeInteractor
    private val tileDataInteractor = kosmos.modesTileDataInteractor

    private val underTest =
        ModesTileUserActionInteractor(
@@ -66,6 +67,7 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() {
            inputHandler,
            mockDialogDelegate,
            zenModeInteractor,
            tileDataInteractor,
            kosmos.modesDialogEventLogger,
        )

@@ -183,12 +185,18 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() {

    private fun modelOf(
        isActivated: Boolean,
        activeModeNames: List<String>,
        activeModeIdsAndNames: List<String>,
        quickMode: ZenMode? = MANUAL_DND,
    ): ModesTileModel {
        return ModesTileModel(
            isActivated,
            activeModeNames,
            activeModeIdsAndNames.map {
                // For testing purposes, we use the same value for id and name, but replicate
                // the flagged behavior of the DataInteractor.
                if (android.app.Flags.modesUiTileReactivatesLast())
                    ModesTileModel.ActiveMode(it, it)
                else ModesTileModel.ActiveMode(null, it)
            },
            TestStubDrawable("icon").asIcon(res = 123),
            quickMode,
        )
+13 −4
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ class ModesTileMapperTest : SysuiTestCase() {
        val model =
            ModesTileModel(
                isActivated = true,
                activeModes = listOf("DND"),
                activeModes = activeModesList("DND"),
                icon = icon,
                quickMode = TestModeBuilder.MANUAL_DND,
            )
@@ -102,7 +102,7 @@ class ModesTileMapperTest : SysuiTestCase() {
        val model =
            ModesTileModel(
                isActivated = true,
                activeModes = listOf("Mode 1", "Mode 2", "Mode 3"),
                activeModes = activeModesList("Mode 1", "Mode 2", "Mode 3"),
                icon = icon,
                quickMode = TestModeBuilder.MANUAL_DND,
            )
@@ -141,7 +141,7 @@ class ModesTileMapperTest : SysuiTestCase() {
        val model =
            ModesTileModel(
                isActivated = true,
                activeModes = listOf("DND"),
                activeModes = activeModesList("DND"),
                icon = icon,
                quickMode = TestModeBuilder.MANUAL_DND,
            )
@@ -161,7 +161,7 @@ class ModesTileMapperTest : SysuiTestCase() {
        val model =
            ModesTileModel(
                isActivated = true,
                activeModes = listOf("Mode 1", "Mode 2", "Mode 3"),
                activeModes = activeModesList("Mode 1", "Mode 2", "Mode 3"),
                icon = icon,
                quickMode = TestModeBuilder.MANUAL_DND,
            )
@@ -189,4 +189,13 @@ class ModesTileMapperTest : SysuiTestCase() {

        assertThat(state.icon).isEqualTo(icon)
    }

    private fun activeModesList(vararg modeIdsAndNames: String): List<ModesTileModel.ActiveMode> {
        return modeIdsAndNames.map {
            // For testing purposes, we use the same value for id and name, but replicate
            // the flagged behavior of the DataInteractor.
            if (Flags.modesUiTileReactivatesLast()) ModesTileModel.ActiveMode(it, it)
            else ModesTileModel.ActiveMode(null, it)
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.app.AutomaticZenRule.TYPE_OTHER
import android.app.Flags
import android.app.NotificationManager.Policy
import android.media.AudioManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.provider.Settings
import android.provider.Settings.Secure.ZEN_DURATION
@@ -308,6 +309,7 @@ class ZenModeInteractorTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(Flags.FLAG_MODES_UI_TILE_REACTIVATES_LAST) // getActiveModes will be deleted
    fun getActiveModes_computesMainActiveMode() =
        kosmos.runTest {
            zenModeRepository.addMode(id = "Bedtime", type = AutomaticZenRule.TYPE_BEDTIME)
Loading