Merge "[SB Refactor] Migrate alwaysShowDataRatIcon to the new pipeline." into tm-qpr-dev

This commit is contained in:
Caitlin Shkuratov
2022-12-19 14:37:59 +00:00
committed by Android (Google) Code Review
15 changed files with 278 additions and 23 deletions

View File

@@ -251,5 +251,22 @@ public class MobileMappings {
} }
return config; return config;
} }
/**
* Returns true if this config and the other config are semantically equal.
*
* Does not override isEquals because existing clients may be relying on the currently
* defined equals behavior.
*/
public boolean areEqual(Config other) {
return showAtLeast3G == other.showAtLeast3G
&& show4gFor3g == other.show4gFor3g
&& alwaysShowCdmaRssi == other.alwaysShowCdmaRssi
&& show4gForLte == other.show4gForLte
&& show4glteForLte == other.show4glteForLte
&& hideLtePlus == other.hideLtePlus
&& hspaDataDistinguishable == other.hspaDataDistinguishable
&& alwaysShowDataRatIcon == other.alwaysShowDataRatIcon;
}
} }
} }

View File

@@ -17,8 +17,11 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository package com.android.systemui.statusbar.pipeline.mobile.data.repository
import android.provider.Settings import android.provider.Settings
import android.telephony.CarrierConfigManager
import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager
import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.SignalIcon.MobileIconGroup
import com.android.settingslib.mobile.MobileMappings
import com.android.settingslib.mobile.MobileMappings.Config
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@@ -47,6 +50,18 @@ interface MobileConnectionsRepository {
/** Observe changes to the [Settings.Global.MOBILE_DATA] setting */ /** Observe changes to the [Settings.Global.MOBILE_DATA] setting */
val globalMobileDataSettingChangedEvent: Flow<Unit> val globalMobileDataSettingChangedEvent: Flow<Unit>
/**
* [Config] is an object that tracks relevant configuration flags for a given subscription ID.
* In the case of [MobileMappings], it's hard-coded to check the default data subscription's
* config, so this will apply to every icon that we care about.
*
* Relevant bits in the config are things like
* [CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL]
*
* This flow will produce whenever the default data subscription or the carrier config changes.
*/
val defaultDataSubRatConfig: StateFlow<Config>
/** The icon mapping from network type to [MobileIconGroup] for the default subscription */ /** The icon mapping from network type to [MobileIconGroup] for the default subscription */
val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>> val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>>

View File

@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository
import android.os.Bundle import android.os.Bundle
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import com.android.settingslib.SignalIcon import com.android.settingslib.SignalIcon
import com.android.settingslib.mobile.MobileMappings
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.demomode.DemoMode import com.android.systemui.demomode.DemoMode
@@ -123,6 +124,15 @@ constructor(
realRepository.activeMobileDataSubscriptionId.value realRepository.activeMobileDataSubscriptionId.value
) )
override val defaultDataSubRatConfig: StateFlow<MobileMappings.Config> =
activeRepo
.flatMapLatest { it.defaultDataSubRatConfig }
.stateIn(
scope,
SharingStarted.WhileSubscribed(),
realRepository.defaultDataSubRatConfig.value
)
override val defaultMobileIconMapping: Flow<Map<String, SignalIcon.MobileIconGroup>> = override val defaultMobileIconMapping: Flow<Map<String, SignalIcon.MobileIconGroup>> =
activeRepo.flatMapLatest { it.defaultMobileIconMapping } activeRepo.flatMapLatest { it.defaultMobileIconMapping }

View File

@@ -106,7 +106,8 @@ constructor(
) )
/** Demo mode doesn't currently support modifications to the mobile mappings */ /** Demo mode doesn't currently support modifications to the mobile mappings */
val defaultDataSubRatConfig = MutableStateFlow(MobileMappings.Config.readConfig(context)) override val defaultDataSubRatConfig =
MutableStateFlow(MobileMappings.Config.readConfig(context))
override val defaultMobileIconGroup = flowOf(TelephonyIcons.THREE_G) override val defaultMobileIconGroup = flowOf(TelephonyIcons.THREE_G)

View File

@@ -37,7 +37,6 @@ import android.telephony.TelephonyManager
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import com.android.internal.telephony.PhoneConstants import com.android.internal.telephony.PhoneConstants
import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.SignalIcon.MobileIconGroup
import com.android.settingslib.mobile.MobileMappings
import com.android.settingslib.mobile.MobileMappings.Config import com.android.settingslib.mobile.MobileMappings.Config
import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -152,17 +151,7 @@ constructor(
IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED) IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
) )
/** override val defaultDataSubRatConfig: StateFlow<Config> =
* [Config] is an object that tracks relevant configuration flags for a given subscription ID.
* In the case of [MobileMappings], it's hard-coded to check the default data subscription's
* config, so this will apply to every icon that we care about.
*
* Relevant bits in the config are things like
* [CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL]
*
* This flow will produce whenever the default data subscription or the carrier config changes.
*/
private val defaultDataSubRatConfig: StateFlow<Config> =
merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent) merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent)
.mapLatest { Config.readConfig(context) } .mapLatest { Config.readConfig(context) }
.stateIn( .stateIn(

View File

@@ -45,6 +45,9 @@ interface MobileIconInteractor {
/** Observable for the data enabled state of this connection */ /** Observable for the data enabled state of this connection */
val isDataEnabled: StateFlow<Boolean> val isDataEnabled: StateFlow<Boolean>
/** True if the RAT icon should always be displayed and false otherwise. */
val alwaysShowDataRatIcon: StateFlow<Boolean>
/** Observable for RAT type (network type) indicator */ /** Observable for RAT type (network type) indicator */
val networkTypeIconGroup: StateFlow<MobileIconGroup> val networkTypeIconGroup: StateFlow<MobileIconGroup>
@@ -64,6 +67,7 @@ interface MobileIconInteractor {
class MobileIconInteractorImpl( class MobileIconInteractorImpl(
@Application scope: CoroutineScope, @Application scope: CoroutineScope,
defaultSubscriptionHasDataEnabled: StateFlow<Boolean>, defaultSubscriptionHasDataEnabled: StateFlow<Boolean>,
override val alwaysShowDataRatIcon: StateFlow<Boolean>,
defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>, defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>,
defaultMobileIconGroup: StateFlow<MobileIconGroup>, defaultMobileIconGroup: StateFlow<MobileIconGroup>,
override val isDefaultConnectionFailed: StateFlow<Boolean>, override val isDefaultConnectionFailed: StateFlow<Boolean>,

View File

@@ -55,6 +55,8 @@ interface MobileIconsInteractor {
val filteredSubscriptions: Flow<List<SubscriptionModel>> val filteredSubscriptions: Flow<List<SubscriptionModel>>
/** True if the active mobile data subscription has data enabled */ /** True if the active mobile data subscription has data enabled */
val activeDataConnectionHasDataEnabled: StateFlow<Boolean> val activeDataConnectionHasDataEnabled: StateFlow<Boolean>
/** True if the RAT icon should always be displayed and false otherwise. */
val alwaysShowDataRatIcon: StateFlow<Boolean>
/** The icon mapping from network type to [MobileIconGroup] for the default subscription */ /** The icon mapping from network type to [MobileIconGroup] for the default subscription */
val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>> val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>
/** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */ /** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */
@@ -158,6 +160,11 @@ constructor(
initialValue = mapOf() initialValue = mapOf()
) )
override val alwaysShowDataRatIcon: StateFlow<Boolean> =
mobileConnectionsRepo.defaultDataSubRatConfig
.mapLatest { it.alwaysShowDataRatIcon }
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
/** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */ /** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */
override val defaultMobileIconGroup: StateFlow<MobileIconGroup> = override val defaultMobileIconGroup: StateFlow<MobileIconGroup> =
mobileConnectionsRepo.defaultMobileIconGroup.stateIn( mobileConnectionsRepo.defaultMobileIconGroup.stateIn(
@@ -188,6 +195,7 @@ constructor(
MobileIconInteractorImpl( MobileIconInteractorImpl(
scope, scope,
activeDataConnectionHasDataEnabled, activeDataConnectionHasDataEnabled,
alwaysShowDataRatIcon,
defaultMobileIconMapping, defaultMobileIconMapping,
defaultMobileIconGroup, defaultMobileIconGroup,
isDefaultConnectionFailed, isDefaultConnectionFailed,

View File

@@ -71,15 +71,19 @@ constructor(
iconInteractor.isDataConnected, iconInteractor.isDataConnected,
iconInteractor.isDataEnabled, iconInteractor.isDataEnabled,
iconInteractor.isDefaultConnectionFailed, iconInteractor.isDefaultConnectionFailed,
) { networkTypeIconGroup, dataConnected, dataEnabled, failedConnection -> iconInteractor.alwaysShowDataRatIcon,
if (!dataConnected || !dataEnabled || failedConnection) { ) { networkTypeIconGroup, dataConnected, dataEnabled, failedConnection, alwaysShow ->
null
} else {
val desc = val desc =
if (networkTypeIconGroup.dataContentDescription != 0) if (networkTypeIconGroup.dataContentDescription != 0)
ContentDescription.Resource(networkTypeIconGroup.dataContentDescription) ContentDescription.Resource(networkTypeIconGroup.dataContentDescription)
else null else null
Icon.Resource(networkTypeIconGroup.dataType, desc) val icon = Icon.Resource(networkTypeIconGroup.dataType, desc)
return@combine when {
alwaysShow -> icon
!dataConnected -> null
!dataEnabled -> null
failedConnection -> null
else -> icon
} }
} }

View File

@@ -20,6 +20,7 @@ import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import android.telephony.TelephonyDisplayInfo import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import com.android.settingslib.SignalIcon import com.android.settingslib.SignalIcon
import com.android.settingslib.mobile.MobileMappings
import com.android.settingslib.mobile.TelephonyIcons import com.android.settingslib.mobile.TelephonyIcons
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
@@ -68,6 +69,8 @@ class FakeMobileConnectionsRepository(mobileMappings: MobileMappingsProxy) :
private val _globalMobileDataSettingChangedEvent = MutableStateFlow(Unit) private val _globalMobileDataSettingChangedEvent = MutableStateFlow(Unit)
override val globalMobileDataSettingChangedEvent = _globalMobileDataSettingChangedEvent override val globalMobileDataSettingChangedEvent = _globalMobileDataSettingChangedEvent
override val defaultDataSubRatConfig = MutableStateFlow(MobileMappings.Config())
private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING) private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING)
override val defaultMobileIconMapping = _defaultMobileIconMapping override val defaultMobileIconMapping = _defaultMobileIconMapping

View File

@@ -23,6 +23,7 @@ import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.provider.Settings import android.provider.Settings
import android.telephony.CarrierConfigManager
import android.telephony.SubscriptionInfo import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager
import android.telephony.TelephonyCallback import android.telephony.TelephonyCallback
@@ -30,6 +31,8 @@ import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.internal.telephony.PhoneConstants import com.android.internal.telephony.PhoneConstants
import com.android.settingslib.R
import com.android.settingslib.mobile.MobileMappings
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
@@ -50,6 +53,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.After import org.junit.After
import org.junit.Assert.assertThrows import org.junit.Assert.assertThrows
import org.junit.Assert.assertTrue
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyInt
@@ -63,6 +67,7 @@ import org.mockito.MockitoAnnotations
class MobileConnectionsRepositoryTest : SysuiTestCase() { class MobileConnectionsRepositoryTest : SysuiTestCase() {
private lateinit var underTest: MobileConnectionsRepositoryImpl private lateinit var underTest: MobileConnectionsRepositoryImpl
private lateinit var connectionFactory: MobileConnectionRepositoryImpl.Factory
@Mock private lateinit var connectivityManager: ConnectivityManager @Mock private lateinit var connectivityManager: ConnectivityManager
@Mock private lateinit var subscriptionManager: SubscriptionManager @Mock private lateinit var subscriptionManager: SubscriptionManager
@Mock private lateinit var telephonyManager: TelephonyManager @Mock private lateinit var telephonyManager: TelephonyManager
@@ -84,7 +89,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
} }
} }
val connectionFactory: MobileConnectionRepositoryImpl.Factory = connectionFactory =
MobileConnectionRepositoryImpl.Factory( MobileConnectionRepositoryImpl.Factory(
context = context, context = context,
telephonyManager = telephonyManager, telephonyManager = telephonyManager,
@@ -385,6 +390,92 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun config_initiallyFromContext() =
runBlocking(IMMEDIATE) {
overrideResource(R.bool.config_showMin3G, true)
val configFromContext = MobileMappings.Config.readConfig(context)
assertThat(configFromContext.showAtLeast3G).isTrue()
// The initial value will be fetched when the repo is created, so we need to override
// the resources and then re-create the repo.
underTest =
MobileConnectionsRepositoryImpl(
connectivityManager,
subscriptionManager,
telephonyManager,
logger,
mobileMappings,
fakeBroadcastDispatcher,
globalSettings,
context,
IMMEDIATE,
scope,
connectionFactory,
)
var latest: MobileMappings.Config? = null
val job = underTest.defaultDataSubRatConfig.onEach { latest = it }.launchIn(this)
assertTrue(latest!!.areEqual(configFromContext))
assertTrue(latest!!.showAtLeast3G)
job.cancel()
}
@Test
fun config_subIdChangeEvent_updated() =
runBlocking(IMMEDIATE) {
var latest: MobileMappings.Config? = null
val job = underTest.defaultDataSubRatConfig.onEach { latest = it }.launchIn(this)
assertThat(latest!!.showAtLeast3G).isFalse()
overrideResource(R.bool.config_showMin3G, true)
val configFromContext = MobileMappings.Config.readConfig(context)
assertThat(configFromContext.showAtLeast3G).isTrue()
// WHEN the change event is fired
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
receiver.onReceive(
context,
Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
.putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
)
}
// THEN the config is updated
assertTrue(latest!!.areEqual(configFromContext))
assertTrue(latest!!.showAtLeast3G)
job.cancel()
}
@Test
fun config_carrierConfigChangeEvent_updated() =
runBlocking(IMMEDIATE) {
var latest: MobileMappings.Config? = null
val job = underTest.defaultDataSubRatConfig.onEach { latest = it }.launchIn(this)
assertThat(latest!!.showAtLeast3G).isFalse()
overrideResource(R.bool.config_showMin3G, true)
val configFromContext = MobileMappings.Config.readConfig(context)
assertThat(configFromContext.showAtLeast3G).isTrue()
// WHEN the change event is fired
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
receiver.onReceive(
context,
Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
)
}
// THEN the config is updated
assertThat(latest!!.areEqual(configFromContext)).isTrue()
assertThat(latest!!.showAtLeast3G).isTrue()
job.cancel()
}
private fun createCapabilities(connected: Boolean, validated: Boolean): NetworkCapabilities = private fun createCapabilities(connected: Boolean, validated: Boolean): NetworkCapabilities =
mock<NetworkCapabilities>().also { mock<NetworkCapabilities>().also {
whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(connected) whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(connected)

View File

@@ -22,6 +22,8 @@ import com.android.settingslib.mobile.TelephonyIcons
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
class FakeMobileIconInteractor : MobileIconInteractor { class FakeMobileIconInteractor : MobileIconInteractor {
override val alwaysShowDataRatIcon = MutableStateFlow(false)
private val _iconGroup = MutableStateFlow<SignalIcon.MobileIconGroup>(TelephonyIcons.THREE_G) private val _iconGroup = MutableStateFlow<SignalIcon.MobileIconGroup>(TelephonyIcons.THREE_G)
override val networkTypeIconGroup = _iconGroup override val networkTypeIconGroup = _iconGroup

View File

@@ -54,6 +54,8 @@ class FakeMobileIconsInteractor(mobileMappings: MobileMappingsProxy) : MobileIco
private val _activeDataConnectionHasDataEnabled = MutableStateFlow(false) private val _activeDataConnectionHasDataEnabled = MutableStateFlow(false)
override val activeDataConnectionHasDataEnabled = _activeDataConnectionHasDataEnabled override val activeDataConnectionHasDataEnabled = _activeDataConnectionHasDataEnabled
override val alwaysShowDataRatIcon = MutableStateFlow(false)
private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING) private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING)
override val defaultMobileIconMapping = _defaultMobileIconMapping override val defaultMobileIconMapping = _defaultMobileIconMapping

View File

@@ -59,6 +59,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
MobileIconInteractorImpl( MobileIconInteractorImpl(
scope, scope,
mobileIconsInteractor.activeDataConnectionHasDataEnabled, mobileIconsInteractor.activeDataConnectionHasDataEnabled,
mobileIconsInteractor.alwaysShowDataRatIcon,
mobileIconsInteractor.defaultMobileIconMapping, mobileIconsInteractor.defaultMobileIconMapping,
mobileIconsInteractor.defaultMobileIconGroup, mobileIconsInteractor.defaultMobileIconGroup,
mobileIconsInteractor.isDefaultConnectionFailed, mobileIconsInteractor.isDefaultConnectionFailed,
@@ -222,6 +223,21 @@ class MobileIconInteractorTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun alwaysShowDataRatIcon_matchesParent() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this)
mobileIconsInteractor.alwaysShowDataRatIcon.value = true
assertThat(latest).isTrue()
mobileIconsInteractor.alwaysShowDataRatIcon.value = false
assertThat(latest).isFalse()
job.cancel()
}
@Test @Test
fun test_isDefaultDataEnabled_matchesParent() = fun test_isDefaultDataEnabled_matchesParent() =
runBlocking(IMMEDIATE) { runBlocking(IMMEDIATE) {

View File

@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.settingslib.mobile.MobileMappings
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
@@ -255,6 +256,38 @@ class MobileIconsInteractorTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun alwaysShowDataRatIcon_configHasTrue() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this)
val config = MobileMappings.Config()
config.alwaysShowDataRatIcon = true
connectionsRepository.defaultDataSubRatConfig.value = config
yield()
assertThat(latest).isTrue()
job.cancel()
}
@Test
fun alwaysShowDataRatIcon_configHasFalse() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this)
val config = MobileMappings.Config()
config.alwaysShowDataRatIcon = false
connectionsRepository.defaultDataSubRatConfig.value = config
yield()
assertThat(latest).isFalse()
job.cancel()
}
companion object { companion object {
private val IMMEDIATE = Dispatchers.Main.immediate private val IMMEDIATE = Dispatchers.Main.immediate

View File

@@ -174,6 +174,66 @@ class MobileIconViewModelTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun networkType_alwaysShow_shownEvenWhenDisabled() =
runBlocking(IMMEDIATE) {
interactor.setIconGroup(THREE_G)
interactor.setIsDataEnabled(true)
interactor.alwaysShowDataRatIcon.value = true
var latest: Icon? = null
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
val expected =
Icon.Resource(
THREE_G.dataType,
ContentDescription.Resource(THREE_G.dataContentDescription)
)
assertThat(latest).isEqualTo(expected)
job.cancel()
}
@Test
fun networkType_alwaysShow_shownEvenWhenDisconnected() =
runBlocking(IMMEDIATE) {
interactor.setIconGroup(THREE_G)
interactor.isDataConnected.value = false
interactor.alwaysShowDataRatIcon.value = true
var latest: Icon? = null
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
val expected =
Icon.Resource(
THREE_G.dataType,
ContentDescription.Resource(THREE_G.dataContentDescription)
)
assertThat(latest).isEqualTo(expected)
job.cancel()
}
@Test
fun networkType_alwaysShow_shownEvenWhenFailedConnection() =
runBlocking(IMMEDIATE) {
interactor.setIconGroup(THREE_G)
interactor.setIsFailedConnection(true)
interactor.alwaysShowDataRatIcon.value = true
var latest: Icon? = null
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
val expected =
Icon.Resource(
THREE_G.dataType,
ContentDescription.Resource(THREE_G.dataContentDescription)
)
assertThat(latest).isEqualTo(expected)
job.cancel()
}
/** Convenience constructor for these tests */ /** Convenience constructor for these tests */
private fun defaultSignal( private fun defaultSignal(
level: Int = 1, level: Int = 1,