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

Commit 7de8ef98 authored by Ioana Alexandru's avatar Ioana Alexandru Committed by Android (Google) Code Review
Browse files

Merge changes I674db920,I93b30811 into main

* changes:
  Modes tile & dialog a11y adjustments
  Set up subtitle for Priority modes tile
parents b814bbd2 66ccdfc0
Loading
Loading
Loading
Loading
+55 −31
Original line number Diff line number Diff line
@@ -22,11 +22,14 @@ 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.settingslib.notification.data.repository.FakeZenModeRepository
import com.android.systemui.SysuiTestCase
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.statusbar.policy.data.repository.fakeZenModeRepository
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
@@ -40,13 +43,17 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class ModesTileDataInteractorTest : SysuiTestCase() {
    private val zenModeRepository = FakeZenModeRepository()
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
    private val dispatcher = kosmos.testDispatcher
    private val zenModeRepository = kosmos.fakeZenModeRepository

    private val underTest = ModesTileDataInteractor(zenModeRepository)
    private val underTest = ModesTileDataInteractor(zenModeRepository, dispatcher)

    @EnableFlags(Flags.FLAG_MODES_UI)
    @Test
    fun availableWhenFlagIsOn() = runTest {
    fun availableWhenFlagIsOn() =
        testScope.runTest {
            val availability = underTest.availability(TEST_USER).toCollection(mutableListOf())

            assertThat(availability).containsExactly(true)
@@ -54,7 +61,8 @@ class ModesTileDataInteractorTest : SysuiTestCase() {

    @DisableFlags(Flags.FLAG_MODES_UI)
    @Test
    fun unavailableWhenFlagIsOff() = runTest {
    fun unavailableWhenFlagIsOff() =
        testScope.runTest {
            val availability = underTest.availability(TEST_USER).toCollection(mutableListOf())

            assertThat(availability).containsExactly(false)
@@ -62,9 +70,12 @@ class ModesTileDataInteractorTest : SysuiTestCase() {

    @EnableFlags(Flags.FLAG_MODES_UI)
    @Test
    fun isActivatedWhenModesChange() = runTest {
    fun isActivatedWhenModesChange() =
        testScope.runTest {
            val dataList: List<ModesTileModel> by
            collectValues(underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)))
                collectValues(
                    underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest))
                )
            runCurrent()
            assertThat(dataList.map { it.isActivated }).containsExactly(false).inOrder()

@@ -72,18 +83,31 @@ 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")

        // Add another mode: state hasn't changed, so this shouldn't cause another emission
        zenModeRepository.addMode(id = "Two", active = true)
            // 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")

        // Remove a mode and disable the other
            // 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())
                .containsExactly("Mode One", "Mode Three")
                .inOrder()

            // Remove a mode and deactivate the other
            zenModeRepository.removeMode("One")
            runCurrent()
        zenModeRepository.deactivateMode("Two")
            zenModeRepository.deactivateMode("Three")
            runCurrent()
        assertThat(dataList.map { it.isActivated }).containsExactly(false, true, false).inOrder()
            assertThat(dataList.map { it.isActivated })
                .containsExactly(false, true, true, true, false)
                .inOrder()
            assertThat(dataList.map { it.activeModes }.last()).isEmpty()
        }

    private companion object {
+12 −4
Original line number Diff line number Diff line
@@ -54,7 +54,11 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() {
    fun handleClick_active() = runTest {
        val expandable = mock<Expandable>()
        underTest.handleInput(
            QSTileInputTestKtx.click(data = ModesTileModel(true), expandable = expandable))
            QSTileInputTestKtx.click(
                data = ModesTileModel(true, listOf("DND")),
                expandable = expandable
            )
        )

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

        verify(mockDialogDelegate).showDialog(eq(expandable))
    }

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

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

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

        QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
            assertThat(it.intent.action).isEqualTo(Settings.ACTION_ZEN_MODE_SETTINGS)
+17 −3
Original line number Diff line number Diff line
@@ -54,21 +54,35 @@ class ModesTileMapperTest : SysuiTestCase() {

    @Test
    fun inactiveState() {
        val model = ModesTileModel(isActivated = false)
        val model = ModesTileModel(isActivated = false, activeModes = emptyList())

        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.secondaryLabel).isEqualTo("No active modes")
    }

    @Test
    fun activeState() {
        val model = ModesTileModel(isActivated = true)
    fun activeState_oneMode() {
        val model = ModesTileModel(isActivated = true, activeModes = listOf("DND"))

        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.secondaryLabel).isEqualTo("DND is active")
    }

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

        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.secondaryLabel).isEqualTo("3 modes are active")
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -1109,6 +1109,14 @@
    <!-- Priority modes: label for a mode that cannot be manually turned on [CHAR LIMIT=35] -->
    <string name="zen_mode_no_manual_invocation">Manage in settings</string>

    <string name="zen_mode_active_modes">
        {count, plural,
            =0 {No active modes}
            =1 {{mode} is active}
            other {# modes are active}
        }
    </string>

    <!-- Zen mode: Priority only introduction message on first use -->
    <string name="zen_priority_introduction">You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify. You\'ll still hear anything you choose to play including music, videos, and games.</string>

+8 −7
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.os.Looper
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.coroutineScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.internal.R.attr.contentDescription
import com.android.internal.logging.MetricsLogger
import com.android.systemui.animation.Expandable
import com.android.systemui.dagger.qualifiers.Background
@@ -30,7 +31,7 @@ import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.flags.RefactorFlagUtils.isUnexpectedlyInLegacyMode
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.qs.QSTile.BooleanState
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
@@ -64,7 +65,7 @@ constructor(
    private val tileMapper: ModesTileMapper,
    private val userActionInteractor: ModesTileUserActionInteractor,
) :
    QSTileImpl<BooleanState>(
    QSTileImpl<QSTile.State>(
        host,
        uiEventLogger,
        backgroundLooper,
@@ -93,7 +94,7 @@ constructor(

    override fun getTileLabel(): CharSequence = tileState.label

    override fun newTileState() = BooleanState()
    override fun newTileState() = QSTile.State()

    override fun handleClick(expandable: Expandable?) = runBlocking {
        userActionInteractor.handleClick(expandable)
@@ -101,17 +102,17 @@ constructor(

    override fun getLongClickIntent(): Intent = userActionInteractor.longClickIntent

    override fun handleUpdateState(booleanState: BooleanState?, arg: Any?) {
    override fun handleUpdateState(state: QSTile.State?, arg: Any?) {
        if (arg is ModesTileModel) {
            tileState = tileMapper.map(config, arg)

            booleanState?.apply {
                state = tileState.activationState.legacyState
            state?.apply {
                this.state = tileState.activationState.legacyState
                icon = ResourceIcon.get(tileState.iconRes ?: R.drawable.qs_dnd_icon_off)
                label = tileLabel
                secondaryLabel = tileState.secondaryLabel
                contentDescription = tileState.contentDescription
                forceExpandIcon = true
                expandedAccessibilityClassName = tileState.expandedAccessibilityClassName
            }
        }
    }
Loading