summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt146
-rw-r--r--packages/SystemUI/res/values/strings.xml15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileContentDescriptionViewBinder.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/MobileContentDescription.kt43
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt68
6 files changed, 256 insertions, 60 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
index 038722cd9608..bf1fbad074cd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
@@ -20,8 +20,6 @@ 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.AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH
-import com.android.settingslib.AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH_NONE
import com.android.settingslib.mobile.MobileMappings
import com.android.settingslib.mobile.TelephonyIcons.G
import com.android.settingslib.mobile.TelephonyIcons.THREE_G
@@ -40,12 +38,15 @@ import com.android.systemui.statusbar.connectivity.MobileIconCarrierIdOverridesF
import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
+import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository.Companion.DEFAULT_NETWORK_NAME
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorImpl
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorImpl
import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
@@ -255,59 +256,146 @@ class MobileIconViewModelTest : SysuiTestCase() {
@Test
fun contentDescription_notInService_usesNoPhone() =
testScope.runTest {
- var latest: ContentDescription? = null
- val job = underTest.contentDescription.onEach { latest = it }.launchIn(this)
+ val latest by collectLastValue(underTest.contentDescription)
repository.isInService.value = false
- assertThat((latest as ContentDescription.Resource).res)
- .isEqualTo(PHONE_SIGNAL_STRENGTH_NONE)
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+ }
- job.cancel()
+ @Test
+ fun contentDescription_includesNetworkName() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.contentDescription)
+
+ repository.isInService.value = true
+ repository.networkName.value = NetworkNameModel.SubscriptionDerived("Test Network Name")
+ repository.numberOfLevels.value = 5
+ repository.setAllLevels(3)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular("Test Network Name", THREE_BARS))
}
@Test
fun contentDescription_inService_usesLevel() =
testScope.runTest {
- var latest: ContentDescription? = null
- val job = underTest.contentDescription.onEach { latest = it }.launchIn(this)
+ val latest by collectLastValue(underTest.contentDescription)
repository.setAllLevels(2)
- assertThat((latest as ContentDescription.Resource).res)
- .isEqualTo(PHONE_SIGNAL_STRENGTH[2])
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
repository.setAllLevels(0)
- assertThat((latest as ContentDescription.Resource).res)
- .isEqualTo(PHONE_SIGNAL_STRENGTH[0])
- job.cancel()
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
}
@Test
- fun contentDescription_nonInflated_invalidLevelIsNull() =
+ fun contentDescription_nonInflated_invalidLevelUsesNoSignalText() =
testScope.runTest {
val latest by collectLastValue(underTest.contentDescription)
repository.inflateSignalStrength.value = false
repository.setAllLevels(-1)
- assertThat(latest).isNull()
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
repository.setAllLevels(100)
- assertThat(latest).isNull()
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+ }
+
+ @Test
+ fun contentDescription_nonInflated_levelStrings() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.contentDescription)
+
+ repository.inflateSignalStrength.value = false
+ repository.setAllLevels(0)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+
+ repository.setAllLevels(1)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
+
+ repository.setAllLevels(2)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
+
+ repository.setAllLevels(3)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
+
+ repository.setAllLevels(4)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
}
@Test
- fun contentDescription_inflated_invalidLevelIsNull() =
+ fun contentDescription_inflated_invalidLevelUsesNoSignalText() =
testScope.runTest {
val latest by collectLastValue(underTest.contentDescription)
repository.inflateSignalStrength.value = true
repository.numberOfLevels.value = 6
+
repository.setAllLevels(-2)
- assertThat(latest).isNull()
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
repository.setAllLevels(100)
- assertThat(latest).isNull()
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+ }
+
+ @Test
+ fun contentDescription_inflated_levelStrings() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.contentDescription)
+
+ repository.inflateSignalStrength.value = true
+ repository.numberOfLevels.value = 6
+
+ // Note that the _repo_ level is 1 lower than the reported level through the interactor
+
+ repository.setAllLevels(0)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
+
+ repository.setAllLevels(1)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
+
+ repository.setAllLevels(2)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
+
+ repository.setAllLevels(3)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FOUR_BARS))
+
+ repository.setAllLevels(4)
+
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
}
@Test
@@ -323,7 +411,10 @@ class MobileIconViewModelTest : SysuiTestCase() {
repository.setAllLevels(i)
when (i) {
-1,
- 5 -> assertWithMessage("Level $i is expected to be null").that(latest).isNull()
+ 5 ->
+ assertWithMessage("Level $i is expected to be 'no signal'")
+ .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
+ .isEqualTo(NO_SIGNAL)
else ->
assertWithMessage("Level $i is expected not to be null")
.that(latest)
@@ -344,7 +435,10 @@ class MobileIconViewModelTest : SysuiTestCase() {
repository.setAllLevels(i)
when (i) {
-2,
- 5 -> assertWithMessage("Level $i is expected to be null").that(latest).isNull()
+ 5 ->
+ assertWithMessage("Level $i is expected to be 'no signal'")
+ .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
+ .isEqualTo(NO_SIGNAL)
else ->
assertWithMessage("Level $i is not expected to be null")
.that(latest)
@@ -967,5 +1061,13 @@ class MobileIconViewModelTest : SysuiTestCase() {
companion object {
private const val SUB_1_ID = 1
+
+ // For convenience, just define these as constants
+ private val NO_SIGNAL = R.string.accessibility_no_signal
+ private val ONE_BAR = R.string.accessibility_one_bar
+ private val TWO_BARS = R.string.accessibility_two_bars
+ private val THREE_BARS = R.string.accessibility_three_bars
+ private val FOUR_BARS = R.string.accessibility_four_bars
+ private val FULL_BARS = R.string.accessibility_signal_full
}
}
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index fac2c4a5a9c2..c78350dfac77 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1945,6 +1945,21 @@
<!-- Text displayed indicating that the user might be able to use satellite SOS. -->
<string name="satellite_emergency_only_carrier_text">Emergency calls or SOS</string>
+ <!-- Content description skeleton. Input strings should be carrier name and signal bar description [CHAR LIMIT=NONE]-->
+ <string name="accessibility_phone_string_format"><xliff:g id="carrier_name" example="Carrier Name">%1$s</xliff:g>, <xliff:g id="signal_strength_description" example="two bars">%2$s</xliff:g>.</string>
+ <!-- Content description describing 0 signal bars. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_no_signal">no signal</string>
+ <!-- Content description describing 1 signal bar. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_one_bar">one bar</string>
+ <!-- Content description describing 2 signal bars. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_two_bars">two bars</string>
+ <!-- Content description describing 3 signal bars. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_three_bars">three bars</string>
+ <!-- Content description describing 4 signal bars. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_four_bars">four bars</string>
+ <!-- Content description describing full signal bars. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_signal_full">signal full</string>
+
<!-- Accessibility label for managed profile icon (not shown on screen) [CHAR LIMIT=NONE] -->
<string name="accessibility_managed_profile">Work profile</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileContentDescriptionViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileContentDescriptionViewBinder.kt
new file mode 100644
index 000000000000..c720b1df1e62
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileContentDescriptionViewBinder.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.ui.binder
+
+import android.view.View
+import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
+
+object MobileContentDescriptionViewBinder {
+ fun bind(contentDescription: MobileContentDescription?, view: View) {
+ view.contentDescription =
+ when (contentDescription) {
+ null -> null
+ else -> contentDescription.loadContentDescription(view.context)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
index 31d349eb4cca..788f041b38c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
@@ -29,9 +29,9 @@ import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.settingslib.graph.SignalDrawable
import com.android.systemui.Flags.statusBarStaticInoutIndicators
-import com.android.systemui.common.ui.binder.ContentDescriptionViewBinder
import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.DarkIconDispatcher
@@ -48,12 +48,8 @@ import com.android.systemui.statusbar.pipeline.shared.ui.binder.StatusBarViewBin
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
-import com.android.app.tracing.coroutines.launchTraced as launch
-private data class Colors(
- @ColorInt val tint: Int,
- @ColorInt val contrast: Int,
-)
+private data class Colors(@ColorInt val tint: Int, @ColorInt val contrast: Int)
object MobileIconBinder {
/** Binds the view to the view-model, continuing to update the former based on the latter */
@@ -87,7 +83,7 @@ object MobileIconBinder {
MutableStateFlow(
Colors(
tint = DarkIconDispatcher.DEFAULT_ICON_TINT,
- contrast = DarkIconDispatcher.DEFAULT_INVERSE_ICON_TINT
+ contrast = DarkIconDispatcher.DEFAULT_INVERSE_ICON_TINT,
)
)
val decorTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
@@ -105,7 +101,7 @@ object MobileIconBinder {
viewModel.verboseLogger?.logBinderReceivedVisibility(
view,
viewModel.subscriptionId,
- isVisible
+ isVisible,
)
view.isVisible = isVisible
// [StatusIconContainer] can get out of sync sometimes. Make sure to
@@ -152,7 +148,7 @@ object MobileIconBinder {
launch {
viewModel.contentDescription.distinctUntilChanged().collect {
- ContentDescriptionViewBinder.bind(it, view)
+ MobileContentDescriptionViewBinder.bind(it, view)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/MobileContentDescription.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/MobileContentDescription.kt
new file mode 100644
index 000000000000..84fa07379a49
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/MobileContentDescription.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.ui.model
+
+import android.annotation.StringRes
+import android.content.Context
+import com.android.systemui.res.R
+
+sealed interface MobileContentDescription {
+ fun loadContentDescription(context: Context): String
+
+ /**
+ * Content description for cellular parameterizes the [networkName] which comes from the system
+ */
+ data class Cellular(val networkName: String, @StringRes val levelDescriptionRes: Int) :
+ MobileContentDescription {
+ override fun loadContentDescription(context: Context): String =
+ context.getString(
+ R.string.accessibility_phone_string_format,
+ networkName,
+ context.getString(levelDescriptionRes),
+ )
+ }
+
+ data class SatelliteContentDescription(@StringRes val resId: Int) : MobileContentDescription {
+ override fun loadContentDescription(context: Context): String =
+ context.getString(this.resId)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
index 103b0e3a6f27..0bd3426712bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
-import com.android.settingslib.AccessibilityContentDescriptions
import com.android.systemui.Flags.statusBarStaticInoutIndicators
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
@@ -28,6 +27,7 @@ import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.Airpla
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import kotlinx.coroutines.CoroutineScope
@@ -50,7 +50,7 @@ interface MobileIconViewModelCommon {
/** True if this view should be visible at all. */
val isVisible: StateFlow<Boolean>
val icon: Flow<SignalIconModel>
- val contentDescription: Flow<ContentDescription?>
+ val contentDescription: Flow<MobileContentDescription?>
val roaming: Flow<Boolean>
/** The RAT icon (LTE, 3G, 5G, etc) to be displayed. Null if we shouldn't show anything */
val networkTypeIcon: Flow<Icon.Resource?>
@@ -95,10 +95,7 @@ class MobileIconViewModel(
}
private val satelliteProvider by lazy {
- CarrierBasedSatelliteViewModelImpl(
- subscriptionId,
- iconInteractor,
- )
+ CarrierBasedSatelliteViewModelImpl(subscriptionId, iconInteractor)
}
/**
@@ -123,7 +120,7 @@ class MobileIconViewModel(
override val icon: Flow<SignalIconModel> = vmProvider.flatMapLatest { it.icon }
- override val contentDescription: Flow<ContentDescription?> =
+ override val contentDescription: Flow<MobileContentDescription?> =
vmProvider.flatMapLatest { it.contentDescription }
override val roaming: Flow<Boolean> = vmProvider.flatMapLatest { it.roaming }
@@ -154,8 +151,7 @@ private class CarrierBasedSatelliteViewModelImpl(
override val isVisible: StateFlow<Boolean> = MutableStateFlow(true)
override val icon: Flow<SignalIconModel> = interactor.signalLevelIcon
- override val contentDescription: Flow<ContentDescription> =
- MutableStateFlow(ContentDescription.Loaded(""))
+ override val contentDescription: Flow<MobileContentDescription?> = MutableStateFlow(null)
/** These fields are not used for satellite icons currently */
override val roaming: Flow<Boolean> = flowOf(false)
@@ -206,27 +202,42 @@ private class CellularIconViewModel(
override val icon: Flow<SignalIconModel> = iconInteractor.signalLevelIcon
- override val contentDescription: Flow<ContentDescription?> =
- iconInteractor.signalLevelIcon
- .map {
- // We expect the signal icon to be cellular here since this is the cellular vm
- if (it !is SignalIconModel.Cellular) {
- null
- } else {
- val resId =
- AccessibilityContentDescriptions.getDescriptionForLevel(
- it.level,
- it.numberOfLevels
+ override val contentDescription: Flow<MobileContentDescription?> =
+ combine(iconInteractor.signalLevelIcon, iconInteractor.networkName) { icon, nameModel ->
+ when (icon) {
+ is SignalIconModel.Cellular ->
+ MobileContentDescription.Cellular(
+ nameModel.name,
+ icon.levelDescriptionRes(),
)
- if (resId != 0) {
- ContentDescription.Resource(resId)
- } else {
- null
- }
+ else -> null
}
}
.stateIn(scope, SharingStarted.WhileSubscribed(), null)
+ private fun SignalIconModel.Cellular.levelDescriptionRes() =
+ when (level) {
+ 0 -> R.string.accessibility_no_signal
+ 1 -> R.string.accessibility_one_bar
+ 2 -> R.string.accessibility_two_bars
+ 3 -> R.string.accessibility_three_bars
+ 4 -> {
+ if (numberOfLevels == 6) {
+ R.string.accessibility_four_bars
+ } else {
+ R.string.accessibility_signal_full
+ }
+ }
+ 5 -> {
+ if (numberOfLevels == 6) {
+ R.string.accessibility_signal_full
+ } else {
+ R.string.accessibility_no_signal
+ }
+ }
+ else -> R.string.accessibility_no_signal
+ }
+
private val showNetworkTypeIcon: Flow<Boolean> =
combine(
iconInteractor.isDataConnected,
@@ -248,10 +259,9 @@ private class CellularIconViewModel(
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
override val networkTypeIcon: Flow<Icon.Resource?> =
- combine(
- iconInteractor.networkTypeIconGroup,
- showNetworkTypeIcon,
- ) { networkTypeIconGroup, shouldShow ->
+ combine(iconInteractor.networkTypeIconGroup, showNetworkTypeIcon) {
+ networkTypeIconGroup,
+ shouldShow ->
val desc =
if (networkTypeIconGroup.contentDescription != 0)
ContentDescription.Resource(networkTypeIconGroup.contentDescription)