diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt index 675760533d97b..31ac7a16a9405 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt @@ -61,6 +61,9 @@ interface MobileIconInteractor { /** True if the RAT icon should always be displayed and false otherwise. */ val alwaysShowDataRatIcon: StateFlow + /** True if the CDMA level should be preferred over the primary level. */ + val alwaysUseCdmaLevel: StateFlow + /** Observable for RAT type (network type) indicator */ val networkTypeIconGroup: StateFlow @@ -97,6 +100,7 @@ class MobileIconInteractorImpl( @Application scope: CoroutineScope, defaultSubscriptionHasDataEnabled: StateFlow, override val alwaysShowDataRatIcon: StateFlow, + override val alwaysUseCdmaLevel: StateFlow, defaultMobileIconMapping: StateFlow>, defaultMobileIconGroup: StateFlow, override val isDefaultConnectionFailed: StateFlow, @@ -157,13 +161,12 @@ class MobileIconInteractorImpl( .stateIn(scope, SharingStarted.WhileSubscribed(), false) override val level: StateFlow = - connectionInfo - .mapLatest { connection -> - // TODO: incorporate [MobileMappings.Config.alwaysShowCdmaRssi] - if (connection.isGsm) { - connection.primaryLevel - } else { - connection.cdmaLevel + combine(connectionInfo, alwaysUseCdmaLevel) { connection, alwaysUseCdmaLevel -> + when { + // GSM connections should never use the CDMA level + connection.isGsm -> connection.primaryLevel + alwaysUseCdmaLevel -> connection.cdmaLevel + else -> connection.primaryLevel } } .stateIn(scope, SharingStarted.WhileSubscribed(), 0) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt index 21f6d8ee32ef6..83da1dd067806 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt @@ -55,8 +55,13 @@ interface MobileIconsInteractor { val filteredSubscriptions: Flow> /** True if the active mobile data subscription has data enabled */ val activeDataConnectionHasDataEnabled: StateFlow + /** True if the RAT icon should always be displayed and false otherwise. */ val alwaysShowDataRatIcon: StateFlow + + /** True if the CDMA level should be preferred over the primary level. */ + val alwaysUseCdmaLevel: StateFlow + /** The icon mapping from network type to [MobileIconGroup] for the default subscription */ val defaultMobileIconMapping: StateFlow> /** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */ @@ -165,6 +170,11 @@ constructor( .mapLatest { it.alwaysShowDataRatIcon } .stateIn(scope, SharingStarted.WhileSubscribed(), false) + override val alwaysUseCdmaLevel: StateFlow = + mobileConnectionsRepo.defaultDataSubRatConfig + .mapLatest { it.alwaysShowCdmaRssi } + .stateIn(scope, SharingStarted.WhileSubscribed(), false) + /** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */ override val defaultMobileIconGroup: StateFlow = mobileConnectionsRepo.defaultMobileIconGroup.stateIn( @@ -196,6 +206,7 @@ constructor( scope, activeDataConnectionHasDataEnabled, alwaysShowDataRatIcon, + alwaysUseCdmaLevel, defaultMobileIconMapping, defaultMobileIconGroup, isDefaultConnectionFailed, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt index 5889ec885e1f5..ff72715b281ff 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt @@ -29,6 +29,8 @@ class FakeMobileIconInteractor( ) : MobileIconInteractor { override val alwaysShowDataRatIcon = MutableStateFlow(false) + override val alwaysUseCdmaLevel = MutableStateFlow(false) + override val activity = MutableStateFlow( DataActivityModel( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt index 19e5516b58a27..1c0064610c52f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt @@ -58,6 +58,8 @@ class FakeMobileIconsInteractor( override val alwaysShowDataRatIcon = MutableStateFlow(false) + override val alwaysUseCdmaLevel = MutableStateFlow(false) + private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING) override val defaultMobileIconMapping = _defaultMobileIconMapping diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt index cb2ee9940c38f..5abe33523cc6f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt @@ -61,6 +61,7 @@ class MobileIconInteractorTest : SysuiTestCase() { scope, mobileIconsInteractor.activeDataConnectionHasDataEnabled, mobileIconsInteractor.alwaysShowDataRatIcon, + mobileIconsInteractor.alwaysUseCdmaLevel, mobileIconsInteractor.defaultMobileIconMapping, mobileIconsInteractor.defaultMobileIconGroup, mobileIconsInteractor.isDefaultConnectionFailed, @@ -103,7 +104,27 @@ class MobileIconInteractorTest : SysuiTestCase() { } @Test - fun cdma_level_default_unknown() = + fun gsm_alwaysShowCdmaTrue_stillUsesGsmLevel() = + runBlocking(IMMEDIATE) { + connectionRepository.setConnectionInfo( + MobileConnectionModel( + isGsm = true, + primaryLevel = GSM_LEVEL, + cdmaLevel = CDMA_LEVEL, + ), + ) + mobileIconsInteractor.alwaysUseCdmaLevel.value = true + + var latest: Int? = null + val job = underTest.level.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo(GSM_LEVEL) + + job.cancel() + } + + @Test + fun notGsm_level_default_unknown() = runBlocking(IMMEDIATE) { connectionRepository.setConnectionInfo( MobileConnectionModel(isGsm = false), @@ -117,7 +138,7 @@ class MobileIconInteractorTest : SysuiTestCase() { } @Test - fun cdma_usesCdmaLevel() = + fun notGsm_alwaysShowCdmaTrue_usesCdmaLevel() = runBlocking(IMMEDIATE) { connectionRepository.setConnectionInfo( MobileConnectionModel( @@ -126,6 +147,7 @@ class MobileIconInteractorTest : SysuiTestCase() { cdmaLevel = CDMA_LEVEL ), ) + mobileIconsInteractor.alwaysUseCdmaLevel.value = true var latest: Int? = null val job = underTest.level.onEach { latest = it }.launchIn(this) @@ -135,6 +157,26 @@ class MobileIconInteractorTest : SysuiTestCase() { job.cancel() } + @Test + fun notGsm_alwaysShowCdmaFalse_usesPrimaryLevel() = + runBlocking(IMMEDIATE) { + connectionRepository.setConnectionInfo( + MobileConnectionModel( + isGsm = false, + primaryLevel = GSM_LEVEL, + cdmaLevel = CDMA_LEVEL, + ), + ) + mobileIconsInteractor.alwaysUseCdmaLevel.value = false + + var latest: Int? = null + val job = underTest.level.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo(GSM_LEVEL) + + job.cancel() + } + @Test fun iconGroup_three_g() = runBlocking(IMMEDIATE) { @@ -239,6 +281,21 @@ class MobileIconInteractorTest : SysuiTestCase() { job.cancel() } + @Test + fun alwaysUseCdmaLevel_matchesParent() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this) + + mobileIconsInteractor.alwaysUseCdmaLevel.value = true + assertThat(latest).isTrue() + + mobileIconsInteractor.alwaysUseCdmaLevel.value = false + assertThat(latest).isFalse() + + job.cancel() + } + @Test fun test_isDefaultDataEnabled_matchesParent() = runBlocking(IMMEDIATE) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt index 2fa3467587cce..b82a58414db9e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt @@ -291,6 +291,38 @@ class MobileIconsInteractorTest : SysuiTestCase() { job.cancel() } + @Test + fun alwaysUseCdmaLevel_configHasTrue() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this) + + val config = MobileMappings.Config() + config.alwaysShowCdmaRssi = true + connectionsRepository.defaultDataSubRatConfig.value = config + yield() + + assertThat(latest).isTrue() + + job.cancel() + } + + @Test + fun alwaysUseCdmaLevel_configHasFalse() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this) + + val config = MobileMappings.Config() + config.alwaysShowCdmaRssi = false + connectionsRepository.defaultDataSubRatConfig.value = config + yield() + + assertThat(latest).isFalse() + + job.cancel() + } + companion object { private val IMMEDIATE = Dispatchers.Main.immediate private val tableLogBuffer =