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

Commit bf6f5e54 authored by Evan Laird's avatar Evan Laird Committed by Android (Google) Code Review
Browse files

Merge "[QS] Add contentDescription and stateDescription to tile" into main

parents 1e61e074 ac3368dd
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) {