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

Commit ac3368dd authored by Evan Laird's avatar Evan Laird
Browse files

[QS] Add contentDescription and stateDescription to tile

These values were missing from the initial implementation. Since the
states are broken out from the way the old tile defined them, they're
generally simpler to see here. Mostly the content description is the
same as the underlying flow's description prepended by "Internet,".

Note that ethernet didn't have a content description defined in the old
tile impl. It's been added here.

Test: InternetTileViewModelTest
Test: manually testing different connections

Fixes: 299292270
Change-Id: Ieb16b594d235f8144014bc88dc3c565153661a07
parent 99c86797
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.content.Context
import android.graphics.drawable.Drawable
import android.service.quicksettings.Tile
import com.android.settingslib.graph.SignalDrawable
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
import com.android.systemui.common.shared.model.Text
import com.android.systemui.common.shared.model.Text.Companion.loadText
import com.android.systemui.plugins.qs.QSTile
@@ -31,6 +33,8 @@ sealed interface InternetTileModel {
    val secondaryLabel: Text?
    val iconId: Int?
    val icon: QSTile.Icon?
    val stateDescription: ContentDescription?
    val contentDescription: ContentDescription?

    fun applyTo(state: QSTile.BooleanState, context: Context) {
        if (secondaryLabel != null) {
@@ -39,6 +43,9 @@ sealed interface InternetTileModel {
            state.secondaryLabel = secondaryTitle
        }

        state.stateDescription = stateDescription.loadContentDescription(context)
        state.contentDescription = contentDescription.loadContentDescription(context)

        // To support both SignalDrawable and other icons, give priority to icons over IDs
        if (icon != null) {
            state.icon = icon
@@ -59,6 +66,8 @@ sealed interface InternetTileModel {
        override val secondaryLabel: Text? = null,
        override val iconId: Int? = null,
        override val icon: QSTile.Icon? = null,
        override val stateDescription: ContentDescription? = null,
        override val contentDescription: ContentDescription? = null,
    ) : InternetTileModel

    data class Inactive(
@@ -66,6 +75,8 @@ sealed interface InternetTileModel {
        override val secondaryLabel: Text? = null,
        override val iconId: Int? = null,
        override val icon: QSTile.Icon? = null,
        override val stateDescription: ContentDescription? = null,
        override val contentDescription: ContentDescription? = null,
    ) : InternetTileModel
}

+32 −10
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel

import android.content.Context
import com.android.systemui.R
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Text
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -61,16 +62,21 @@ constructor(
    private val context: Context,
    @Application scope: CoroutineScope,
) {
    private val internetLabel: String = context.getString(R.string.quick_settings_internet_label)

    // Three symmetrical Flows that can be switched upon based on the value of
    // [DefaultConnectionModel]
    private val wifiIconFlow: Flow<InternetTileModel> =
        wifiInteractor.wifiNetwork.flatMapLatest {
            val wifiIcon = WifiIcon.fromModel(it, context, showHotspotInfo = true)
            if (it is WifiNetworkModel.Active && wifiIcon is WifiIcon.Visible) {
                val secondary = removeDoubleQuotes(it.ssid)
                flowOf(
                    InternetTileModel.Active(
                        secondaryTitle = removeDoubleQuotes(it.ssid),
                        icon = ResourceIcon.get(wifiIcon.icon.res)
                        secondaryTitle = secondary,
                        icon = ResourceIcon.get(wifiIcon.icon.res),
                        stateDescription = wifiIcon.contentDescription,
                        contentDescription = ContentDescription.Loaded("$internetLabel,$secondary"),
                    )
                )
            } else {
@@ -109,10 +115,13 @@ constructor(
                    it.signalLevelIcon,
                    mobileDataContentName,
                ) { networkNameModel, signalIcon, dataContentDescription ->
                    val secondary =
                        mobileDataContentConcat(networkNameModel.name, dataContentDescription)
                    InternetTileModel.Active(
                        secondaryTitle =
                            mobileDataContentConcat(networkNameModel.name, dataContentDescription),
                        secondaryTitle = secondary,
                        icon = SignalIcon(signalIcon.toSignalDrawableState()),
                        stateDescription = ContentDescription.Loaded(secondary),
                        contentDescription = ContentDescription.Loaded(internetLabel),
                    )
                }
            }
@@ -148,10 +157,13 @@ constructor(
            if (it == null) {
                notConnectedFlow
            } else {
                val secondary = it.contentDescription.toString()
                flowOf(
                    InternetTileModel.Active(
                        secondaryTitle = it.contentDescription.toString(),
                        iconId = it.res
                        secondaryTitle = secondary,
                        iconId = it.res,
                        stateDescription = null,
                        contentDescription = ContentDescription.Loaded(secondary),
                    )
                )
            }
@@ -164,16 +176,23 @@ constructor(
            ) { networksAvailable, isAirplaneMode ->
                when {
                    isAirplaneMode -> {
                        val secondary = context.getString(R.string.status_bar_airplane)
                        InternetTileModel.Inactive(
                            secondaryTitle = context.getString(R.string.status_bar_airplane),
                            icon = ResourceIcon.get(R.drawable.ic_qs_no_internet_unavailable)
                            secondaryTitle = secondary,
                            icon = ResourceIcon.get(R.drawable.ic_qs_no_internet_unavailable),
                            stateDescription = null,
                            contentDescription = ContentDescription.Loaded(secondary),
                        )
                    }
                    networksAvailable -> {
                        val secondary =
                            context.getString(R.string.quick_settings_networks_available)
                        InternetTileModel.Inactive(
                            secondaryTitle =
                                context.getString(R.string.quick_settings_networks_available),
                            secondaryTitle = secondary,
                            iconId = R.drawable.ic_qs_no_internet_available,
                            stateDescription = null,
                            contentDescription =
                                ContentDescription.Loaded("$internetLabel,$secondary")
                        )
                    }
                    else -> {
@@ -206,6 +225,9 @@ constructor(
            InternetTileModel.Inactive(
                secondaryLabel = Text.Resource(R.string.quick_settings_networks_unavailable),
                iconId = R.drawable.ic_qs_no_internet_unavailable,
                stateDescription = null,
                contentDescription =
                    ContentDescription.Resource(R.string.quick_settings_networks_unavailable),
            )

        private fun removeDoubleQuotes(string: String?): String? {
+26 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
import com.android.systemui.common.shared.model.Text
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.log.table.TableLogBuffer
@@ -42,6 +43,7 @@ import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepo
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry
import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
import com.android.systemui.util.CarrierConfigTracker
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
@@ -72,6 +74,8 @@ class InternetTileViewModelTest : SysuiTestCase() {
    private val mobileConnectionRepository =
        FakeMobileConnectionRepository(SUB_1_ID, tableLogBuffer)

    private val internet = context.getString(R.string.quick_settings_internet_label)

    @Before
    fun setUp() {
        mobileConnectionRepository.apply {
@@ -139,6 +143,9 @@ class InternetTileViewModelTest : SysuiTestCase() {
                    level = 4,
                    ssid = "test ssid",
                )
            val wifiIcon =
                WifiIcon.fromModel(model = networkModel, context = context, showHotspotInfo = false)
                    as WifiIcon.Visible

            connectivityRepository.setWifiConnected()
            wifiRepository.setIsWifiDefault(true)
@@ -149,6 +156,10 @@ class InternetTileViewModelTest : SysuiTestCase() {
            assertThat(latest?.icon)
                .isEqualTo(ResourceIcon.get(WifiIcons.WIFI_NO_INTERNET_ICONS[4]))
            assertThat(latest?.iconId).isNull()
            assertThat(latest?.contentDescription.loadContentDescription(context))
                .isEqualTo("$internet,test ssid")
            val expectedSd = wifiIcon.contentDescription
            assertThat(latest?.stateDescription).isEqualTo(expectedSd)
        }

    @Test
@@ -281,6 +292,11 @@ class InternetTileViewModelTest : SysuiTestCase() {
                .isEqualTo(context.getString(R.string.quick_settings_networks_available))
            assertThat(latest?.icon).isNull()
            assertThat(latest?.iconId).isEqualTo(R.drawable.ic_qs_no_internet_available)
            assertThat(latest?.stateDescription).isNull()
            val expectedCd =
                "$internet,${context.getString(R.string.quick_settings_networks_available)}"
            assertThat(latest?.contentDescription.loadContentDescription(context))
                .isEqualTo(expectedCd)
        }

    @Test
@@ -300,6 +316,10 @@ class InternetTileViewModelTest : SysuiTestCase() {
            assertThat(latest?.secondaryLabel).isNull()
            assertThat(latest?.icon).isInstanceOf(SignalIcon::class.java)
            assertThat(latest?.iconId).isNull()
            assertThat(latest?.stateDescription.loadContentDescription(context))
                .isEqualTo(latest?.secondaryTitle)
            assertThat(latest?.contentDescription.loadContentDescription(context))
                .isEqualTo(internet)
        }

    @Test
@@ -315,6 +335,9 @@ class InternetTileViewModelTest : SysuiTestCase() {
                .isEqualTo(ethernetIcon!!.contentDescription.toString())
            assertThat(latest?.iconId).isEqualTo(R.drawable.stat_sys_ethernet_fully)
            assertThat(latest?.icon).isNull()
            assertThat(latest?.stateDescription).isNull()
            assertThat(latest?.contentDescription.loadContentDescription(context))
                .isEqualTo(latest?.secondaryTitle)
        }

    @Test
@@ -330,6 +353,9 @@ class InternetTileViewModelTest : SysuiTestCase() {
                .isEqualTo(ethernetIcon!!.contentDescription.toString())
            assertThat(latest?.iconId).isEqualTo(R.drawable.stat_sys_ethernet)
            assertThat(latest?.icon).isNull()
            assertThat(latest?.stateDescription).isNull()
            assertThat(latest?.contentDescription.loadContentDescription(context))
                .isEqualTo(latest?.secondaryTitle)
        }

    private fun setWifiNetworkWithHotspot(hotspot: WifiNetworkModel.HotspotDeviceType) {