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

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

Merge "Update ZenModeInteractor.activeModes to include all relevant data" into main

parents 78599021 e4f5f6c4
Loading
Loading
Loading
Loading
+60 −21
Original line number Diff line number Diff line
@@ -24,9 +24,11 @@ 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.internal.R
import com.android.settingslib.notification.modes.ZenIconLoader
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.asIcon
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
@@ -60,9 +62,11 @@ class ModesTileDataInteractorTest : SysuiTestCase() {
    @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)
            addOverride(MODES_DRAWABLE_ID, MODES_DRAWABLE)
            addOverride(R.drawable.ic_zen_mode_type_bedtime, BEDTIME_DRAWABLE)
            addOverride(R.drawable.ic_zen_mode_type_driving, DRIVING_DRAWABLE)
        }
        // TODO: b/360399800 - Remove; ZenIconLoader should always use direct executor for tests
        ZenIconLoader.setInstance(ZenIconLoader(MoreExecutors.newDirectExecutorService()))
    }

@@ -128,28 +132,34 @@ class ModesTileDataInteractorTest : SysuiTestCase() {

    @Test
    @EnableFlags(Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS)
    fun changesIconWhenActiveModesChange() =
    fun tileData_iconsFlagEnabled_changesIconWhenActiveModesChange() =
        testScope.runTest {
            val dataList: List<ModesTileModel> by
                collectValues(
            val tileData by
                collectLastValue(
                    underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest))
                )

            // Tile starts with the generic Modes icon.
            runCurrent()
            assertThat(dataList.map { it.icon }).containsExactly(null).inOrder()
            assertThat(tileData?.icon).isEqualTo(MODES_ICON)
            assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID)

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

            // Add an active mode: icon should be the mode icon
            // Add an active mode: icon should be the mode icon. No iconResId, because we don't
            // really know that it's a system icon.
            zenModeRepository.addMode(
                id = "Bedtime",
                type = AutomaticZenRule.TYPE_BEDTIME,
                active = true
            )
            runCurrent()
            assertThat(dataList.map { it.icon }).containsExactly(null, BEDTIME_ICON).inOrder()
            assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON)
            assertThat(tileData?.iconResId).isNull()

            // Add another, less-prioritized mode: icon should remain the first mode icon
            zenModeRepository.addMode(
@@ -158,29 +168,58 @@ class ModesTileDataInteractorTest : SysuiTestCase() {
                active = true
            )
            runCurrent()
            assertThat(dataList.map { it.icon })
                .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON)
                .inOrder()
            assertThat(tileData?.icon).isEqualTo(BEDTIME_ICON)
            assertThat(tileData?.iconResId).isNull()

            // Deactivate more important mode: icon should be the less important, still active mode.
            // 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()
            assertThat(tileData?.icon).isEqualTo(DRIVING_ICON)
            assertThat(tileData?.iconResId).isNull()

            // Deactivate remaining mode: no icon
            // Deactivate remaining mode: back to the default modes icon
            zenModeRepository.deactivateMode("Driving")
            runCurrent()
            assertThat(dataList.map { it.icon })
                .containsExactly(null, BEDTIME_ICON, BEDTIME_ICON, DRIVING_ICON, null)
                .inOrder()
            assertThat(tileData?.icon).isEqualTo(MODES_ICON)
            assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID)
        }

    @Test
    @EnableFlags(Flags.FLAG_MODES_UI)
    @DisableFlags(Flags.FLAG_MODES_UI_ICONS)
    fun tileData_iconsFlagDisabled_hasPriorityModesIcon() =
        testScope.runTest {
            val tileData by
                collectLastValue(
                    underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest))
                )

            runCurrent()
            assertThat(tileData?.icon).isEqualTo(MODES_ICON)
            assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID)

            // Activate a Mode -> Icon doesn't change.
            zenModeRepository.addMode(id = "Mode", active = true)
            runCurrent()
            assertThat(tileData?.icon).isEqualTo(MODES_ICON)
            assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID)

            zenModeRepository.deactivateMode(id = "Mode")
            runCurrent()
            assertThat(tileData?.icon).isEqualTo(MODES_ICON)
            assertThat(tileData?.iconResId).isEqualTo(MODES_DRAWABLE_ID)
        }

    private companion object {
        val TEST_USER = UserHandle.of(1)!!

        val MODES_DRAWABLE_ID = com.android.systemui.res.R.drawable.qs_dnd_icon_off

        val MODES_DRAWABLE = TestStubDrawable("modes_icon")
        val BEDTIME_DRAWABLE = TestStubDrawable("bedtime")
        val DRIVING_DRAWABLE = TestStubDrawable("driving")

        val MODES_ICON = MODES_DRAWABLE.asIcon()
        val BEDTIME_ICON = BEDTIME_DRAWABLE.asIcon()
        val DRIVING_ICON = DRIVING_DRAWABLE.asIcon()
    }
+10 −10
Original line number Diff line number Diff line
@@ -16,12 +16,14 @@

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

import android.graphics.drawable.TestStubDrawable
import android.platform.test.annotations.EnableFlags
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.asIcon
import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler
import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
@@ -54,10 +56,7 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() {
    fun handleClick_active() = runTest {
        val expandable = mock<Expandable>()
        underTest.handleInput(
            QSTileInputTestKtx.click(
                data = ModesTileModel(true, listOf("DND")),
                expandable = expandable
            )
            QSTileInputTestKtx.click(data = modelOf(true, listOf("DND")), expandable = expandable)
        )

        verify(mockDialogDelegate).showDialog(eq(expandable))
@@ -67,10 +66,7 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() {
    fun handleClick_inactive() = runTest {
        val expandable = mock<Expandable>()
        underTest.handleInput(
            QSTileInputTestKtx.click(
                data = ModesTileModel(false, emptyList()),
                expandable = expandable
            )
            QSTileInputTestKtx.click(data = modelOf(false, emptyList()), expandable = expandable)
        )

        verify(mockDialogDelegate).showDialog(eq(expandable))
@@ -78,7 +74,7 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() {

    @Test
    fun handleLongClick_active() = runTest {
        underTest.handleInput(QSTileInputTestKtx.longClick(ModesTileModel(true, listOf("DND"))))
        underTest.handleInput(QSTileInputTestKtx.longClick(modelOf(true, listOf("DND"))))

        QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
            assertThat(it.intent.action).isEqualTo(Settings.ACTION_ZEN_MODE_SETTINGS)
@@ -87,10 +83,14 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() {

    @Test
    fun handleLongClick_inactive() = runTest {
        underTest.handleInput(QSTileInputTestKtx.longClick(ModesTileModel(false, emptyList())))
        underTest.handleInput(QSTileInputTestKtx.longClick(modelOf(false, emptyList())))

        QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
            assertThat(it.intent.action).isEqualTo(Settings.ACTION_ZEN_MODE_SETTINGS)
        }
    }

    private fun modelOf(isActivated: Boolean, activeModeNames: List<String>): ModesTileModel {
        return ModesTileModel(isActivated, activeModeNames, TestStubDrawable("icon").asIcon(), 123)
    }
}
+52 −10
Original line number Diff line number Diff line
@@ -18,11 +18,12 @@ package com.android.systemui.qs.tiles.impl.modes.ui

import android.app.Flags
import android.graphics.drawable.TestStubDrawable
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.Icon
import com.android.systemui.common.shared.model.asIcon
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
@@ -58,47 +59,88 @@ class ModesTileMapperTest : SysuiTestCase() {

    @Test
    fun inactiveState() {
        val model = ModesTileModel(isActivated = false, activeModes = emptyList())
        val icon = TestStubDrawable("res123").asIcon()
        val model =
            ModesTileModel(
                isActivated = false,
                activeModes = emptyList(),
                icon = icon,
            )

        val state = underTest.map(config, model)

        assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.INACTIVE)
        assertThat(state.iconRes).isEqualTo(R.drawable.qs_dnd_icon_off)
        assertThat(state.icon()).isEqualTo(icon)
        assertThat(state.secondaryLabel).isEqualTo("No active modes")
    }

    @Test
    fun activeState_oneMode() {
        val model = ModesTileModel(isActivated = true, activeModes = listOf("DND"))
        val icon = TestStubDrawable("res123").asIcon()
        val model =
            ModesTileModel(
                isActivated = true,
                activeModes = listOf("DND"),
                icon = icon,
            )

        val state = underTest.map(config, model)

        assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.ACTIVE)
        assertThat(state.iconRes).isEqualTo(R.drawable.qs_dnd_icon_on)
        assertThat(state.icon()).isEqualTo(icon)
        assertThat(state.secondaryLabel).isEqualTo("DND is active")
    }

    @Test
    fun activeState_multipleModes() {
        val icon = TestStubDrawable("res123").asIcon()
        val model =
            ModesTileModel(isActivated = true, activeModes = listOf("Mode 1", "Mode 2", "Mode 3"))
            ModesTileModel(
                isActivated = true,
                activeModes = listOf("Mode 1", "Mode 2", "Mode 3"),
                icon = icon,
            )

        val state = underTest.map(config, model)

        assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.ACTIVE)
        assertThat(state.iconRes).isEqualTo(R.drawable.qs_dnd_icon_on)
        assertThat(state.icon()).isEqualTo(icon)
        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)
    fun state_withEnabledFlag_noIconResId() {
        val icon = TestStubDrawable("res123").asIcon()
        val model =
            ModesTileModel(
                isActivated = false,
                activeModes = emptyList(),
                icon = icon,
                iconResId = 123 // Should not be populated, but is ignored even if present
            )

        val state = underTest.map(config, model)

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

    @Test
    @DisableFlags(Flags.FLAG_MODES_UI_ICONS)
    fun state_withDisabledFlag_includesIconResId() {
        val icon = TestStubDrawable("res123").asIcon()
        val model =
            ModesTileModel(
                isActivated = false,
                activeModes = emptyList(),
                icon = icon,
                iconResId = 123
            )

        val state = underTest.map(config, model)

        assertThat(state.icon()).isEqualTo(icon)
        assertThat(state.iconRes).isEqualTo(123)
    }
}
+14 −10
Original line number Diff line number Diff line
@@ -220,33 +220,37 @@ class ZenModeInteractorTest : SysuiTestCase() {
        }

    @Test
    fun mainActiveMode_returnsMainActiveMode() =
    fun activeModes_computesMainActiveMode() =
        testScope.runTest {
            val mainActiveMode by collectLastValue(underTest.mainActiveMode)
            val activeModes by collectLastValue(underTest.activeModes)

            zenModeRepository.addMode(id = "Bedtime", type = AutomaticZenRule.TYPE_BEDTIME)
            zenModeRepository.addMode(id = "Other", type = AutomaticZenRule.TYPE_OTHER)

            runCurrent()
            assertThat(mainActiveMode).isNull()
            assertThat(activeModes?.modeNames).hasSize(0)
            assertThat(activeModes?.mainMode).isNull()

            zenModeRepository.activateMode("Other")
            runCurrent()
            assertThat(mainActiveMode).isNotNull()
            assertThat(mainActiveMode!!.id).isEqualTo("Other")
            assertThat(activeModes?.modeNames).containsExactly("Mode Other")
            assertThat(activeModes?.mainMode?.name).isEqualTo("Mode Other")

            zenModeRepository.activateMode("Bedtime")
            runCurrent()
            assertThat(mainActiveMode).isNotNull()
            assertThat(mainActiveMode!!.id).isEqualTo("Bedtime")
            assertThat(activeModes?.modeNames)
                .containsExactly("Mode Bedtime", "Mode Other")
                .inOrder()
            assertThat(activeModes?.mainMode?.name).isEqualTo("Mode Bedtime")

            zenModeRepository.deactivateMode("Other")
            runCurrent()
            assertThat(mainActiveMode).isNotNull()
            assertThat(mainActiveMode!!.id).isEqualTo("Bedtime")
            assertThat(activeModes?.modeNames).containsExactly("Mode Bedtime")
            assertThat(activeModes?.mainMode?.name).isEqualTo("Mode Bedtime")

            zenModeRepository.deactivateMode("Bedtime")
            runCurrent()
            assertThat(mainActiveMode).isNull()
            assertThat(activeModes?.modeNames).hasSize(0)
            assertThat(activeModes?.mainMode).isNull()
        }
}
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ class ModesDialogViewModelTest : SysuiTestCase() {

    @Before
    fun setUp() {
        // TODO: b/360399800 - Remove; ZenIconLoader should always use direct executor for tests
        ZenIconLoader.setInstance(ZenIconLoader(MoreExecutors.newDirectExecutorService()))
    }

Loading