Better mapping lookup for demo mode
Move the entire lookup into `MobileMappings` to the repository layer. So when network types come down, they are immediately transformed into `ResolvedNetworkType` objects and given a key at that moment, using the default mobile mapping config This allows us to A) better insulate us from external depenencies and B) implement a very trivial mapping for Demo mode. TBD on whether or not we should allow switching to use the real mobile mappings implementation Test: tests in tests/src/com/andrdoid/systemui/statusbar/pipeline/mobile/* Bug: 261185097 Change-Id: I727ad3ca823f3eb225a56f371aa3cef46c340f57
This commit is contained in:
@@ -27,7 +27,6 @@ import android.telephony.TelephonyCallback.ServiceStateListener
|
||||
import android.telephony.TelephonyCallback.SignalStrengthsListener
|
||||
import android.telephony.TelephonyDisplayInfo
|
||||
import android.telephony.TelephonyManager
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Disconnected
|
||||
|
||||
/**
|
||||
@@ -65,5 +64,5 @@ data class MobileSubscriptionModel(
|
||||
* [resolvedNetworkType] is the [TelephonyDisplayInfo.getOverrideNetworkType] if it exists or
|
||||
* [TelephonyDisplayInfo.getNetworkType]. This is used to look up the proper network type icon
|
||||
*/
|
||||
val resolvedNetworkType: ResolvedNetworkType = DefaultNetworkType(NETWORK_TYPE_UNKNOWN),
|
||||
val resolvedNetworkType: ResolvedNetworkType = ResolvedNetworkType.UnknownNetworkType,
|
||||
)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui.statusbar.pipeline.mobile.data.model
|
||||
|
||||
import android.telephony.Annotation.NetworkType
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
|
||||
|
||||
/**
|
||||
@@ -26,8 +27,20 @@ import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
|
||||
*/
|
||||
sealed interface ResolvedNetworkType {
|
||||
@NetworkType val type: Int
|
||||
val lookupKey: String
|
||||
|
||||
object UnknownNetworkType : ResolvedNetworkType {
|
||||
override val type: Int = NETWORK_TYPE_UNKNOWN
|
||||
override val lookupKey: String = "unknown"
|
||||
}
|
||||
|
||||
data class DefaultNetworkType(
|
||||
@NetworkType override val type: Int,
|
||||
override val lookupKey: String,
|
||||
) : ResolvedNetworkType
|
||||
|
||||
data class OverrideNetworkType(
|
||||
@NetworkType override val type: Int,
|
||||
override val lookupKey: String,
|
||||
) : ResolvedNetworkType
|
||||
}
|
||||
|
||||
data class DefaultNetworkType(@NetworkType override val type: Int) : ResolvedNetworkType
|
||||
|
||||
data class OverrideNetworkType(@NetworkType override val type: Int) : ResolvedNetworkType
|
||||
|
||||
@@ -19,8 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository
|
||||
import android.provider.Settings
|
||||
import android.telephony.SubscriptionInfo
|
||||
import android.telephony.SubscriptionManager
|
||||
import com.android.settingslib.mobile.MobileMappings
|
||||
import com.android.settingslib.mobile.MobileMappings.Config
|
||||
import com.android.settingslib.SignalIcon.MobileIconGroup
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
@@ -36,9 +35,6 @@ interface MobileConnectionsRepository {
|
||||
/** Observable for the subscriptionId of the current mobile data connection */
|
||||
val activeMobileDataSubscriptionId: StateFlow<Int>
|
||||
|
||||
/** Observable for [MobileMappings.Config] tracking the defaults */
|
||||
val defaultDataSubRatConfig: StateFlow<Config>
|
||||
|
||||
/** Tracks [SubscriptionManager.getDefaultDataSubscriptionId] */
|
||||
val defaultDataSubId: StateFlow<Int>
|
||||
|
||||
@@ -50,4 +46,10 @@ interface MobileConnectionsRepository {
|
||||
|
||||
/** Observe changes to the [Settings.Global.MOBILE_DATA] setting */
|
||||
val globalMobileDataSettingChangedEvent: Flow<Unit>
|
||||
|
||||
/** The icon mapping from network type to [MobileIconGroup] for the default subscription */
|
||||
val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>>
|
||||
|
||||
/** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */
|
||||
val defaultMobileIconGroup: Flow<MobileIconGroup>
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository
|
||||
import android.os.Bundle
|
||||
import android.telephony.SubscriptionInfo
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.android.settingslib.mobile.MobileMappings
|
||||
import com.android.settingslib.SignalIcon
|
||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.demomode.DemoMode
|
||||
@@ -127,14 +127,11 @@ constructor(
|
||||
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>> =
|
||||
activeRepo.flatMapLatest { it.defaultMobileIconMapping }
|
||||
|
||||
override val defaultMobileIconGroup: Flow<SignalIcon.MobileIconGroup> =
|
||||
activeRepo.flatMapLatest { it.defaultMobileIconGroup }
|
||||
|
||||
override val defaultDataSubId: StateFlow<Int> =
|
||||
activeRepo
|
||||
|
||||
@@ -17,26 +17,18 @@
|
||||
package com.android.systemui.statusbar.pipeline.mobile.data.repository.demo
|
||||
|
||||
import android.content.Context
|
||||
import android.telephony.Annotation
|
||||
import android.telephony.SubscriptionInfo
|
||||
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_GSM
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_LTE
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_NR
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_UMTS
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||||
import android.util.Log
|
||||
import com.android.settingslib.SignalIcon
|
||||
import com.android.settingslib.mobile.MobileMappings
|
||||
import com.android.settingslib.mobile.TelephonyIcons
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DefaultNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileSubscriptionModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.OverrideNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
|
||||
@@ -49,7 +41,9 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
@@ -133,8 +127,31 @@ constructor(
|
||||
)
|
||||
|
||||
/** Demo mode doesn't currently support modifications to the mobile mappings */
|
||||
override val defaultDataSubRatConfig =
|
||||
MutableStateFlow(MobileMappings.Config.readConfig(context))
|
||||
val defaultDataSubRatConfig = MutableStateFlow(MobileMappings.Config.readConfig(context))
|
||||
|
||||
override val defaultMobileIconGroup = flowOf(TelephonyIcons.THREE_G)
|
||||
|
||||
override val defaultMobileIconMapping = MutableStateFlow(TelephonyIcons.ICON_NAME_TO_ICON)
|
||||
|
||||
/**
|
||||
* In order to maintain compatibility with the old demo mode shell command API, reverse the
|
||||
* [MobileMappings] lookup from (NetworkType: String -> Icon: MobileIconGroup), so that we can
|
||||
* parse the string from the command line into a preferred icon group, and send _a_ valid
|
||||
* network type for that icon through the pipeline.
|
||||
*
|
||||
* Note: collisions don't matter here, because the data source (the command line) only cares
|
||||
* about the resulting icon, not the underlying network type.
|
||||
*/
|
||||
private val mobileMappingsReverseLookup: StateFlow<Map<SignalIcon.MobileIconGroup, String>> =
|
||||
defaultMobileIconMapping
|
||||
.mapLatest { networkToIconMap -> networkToIconMap.reverse() }
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.WhileSubscribed(),
|
||||
defaultMobileIconMapping.value.reverse()
|
||||
)
|
||||
|
||||
private fun <K, V> Map<K, V>.reverse() = entries.associateBy({ it.value }) { it.key }
|
||||
|
||||
// TODO(b/261029387): add a command for this value
|
||||
override val defaultDataSubId =
|
||||
@@ -229,45 +246,34 @@ constructor(
|
||||
private fun subIdsString(): String =
|
||||
_subscriptions.value.joinToString(",") { it.subscriptionId.toString() }
|
||||
|
||||
private fun Mobile.toMobileSubscriptionModel(): MobileSubscriptionModel {
|
||||
return MobileSubscriptionModel(
|
||||
isEmergencyOnly = false, // TODO(b/261029387): not yet supported
|
||||
isGsm = false, // TODO(b/261029387): not yet supported
|
||||
cdmaLevel = level ?: 0,
|
||||
primaryLevel = level ?: 0,
|
||||
dataConnectionState =
|
||||
DataConnectionState.Connected, // TODO(b/261029387): not yet supported
|
||||
dataActivityDirection = activity,
|
||||
carrierNetworkChangeActive = carrierNetworkChange,
|
||||
resolvedNetworkType = dataType.toResolvedNetworkType()
|
||||
)
|
||||
}
|
||||
|
||||
private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType {
|
||||
val key = mobileMappingsReverseLookup.value[this] ?: "dis"
|
||||
return DefaultNetworkType(DEMO_NET_TYPE, key)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "DemoMobileConnectionsRepo"
|
||||
|
||||
private const val DEFAULT_SUB_ID = 1
|
||||
|
||||
private const val DEMO_NET_TYPE = 1234
|
||||
}
|
||||
}
|
||||
|
||||
private fun Mobile.toMobileSubscriptionModel(): MobileSubscriptionModel {
|
||||
return MobileSubscriptionModel(
|
||||
isEmergencyOnly = false, // TODO(b/261029387): not yet supported
|
||||
isGsm = false, // TODO(b/261029387): not yet supported
|
||||
cdmaLevel = level ?: 0,
|
||||
primaryLevel = level ?: 0,
|
||||
dataConnectionState = DataConnectionState.Connected, // TODO(b/261029387): not yet supported
|
||||
dataActivityDirection = activity,
|
||||
carrierNetworkChangeActive = carrierNetworkChange,
|
||||
// TODO(b/261185097): once mobile mappings can be mocked at this layer, we can build our
|
||||
// own demo map
|
||||
resolvedNetworkType = dataType.toResolvedNetworkType()
|
||||
)
|
||||
}
|
||||
|
||||
@Annotation.NetworkType
|
||||
private fun SignalIcon.MobileIconGroup?.toNetworkType(): Int =
|
||||
when (this) {
|
||||
TelephonyIcons.THREE_G -> NETWORK_TYPE_GSM
|
||||
TelephonyIcons.LTE -> NETWORK_TYPE_LTE
|
||||
TelephonyIcons.FOUR_G -> NETWORK_TYPE_UMTS
|
||||
TelephonyIcons.NR_5G -> NETWORK_TYPE_NR
|
||||
TelephonyIcons.NR_5G_PLUS -> OVERRIDE_NETWORK_TYPE_NR_ADVANCED
|
||||
else -> NETWORK_TYPE_UNKNOWN
|
||||
}
|
||||
|
||||
private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType =
|
||||
when (this) {
|
||||
TelephonyIcons.NR_5G_PLUS -> OverrideNetworkType(toNetworkType())
|
||||
else -> DefaultNetworkType(toNetworkType())
|
||||
}
|
||||
|
||||
class DemoMobileConnectionRepository(override val subId: Int) : MobileConnectionRepository {
|
||||
override val subscriptionModelFlow = MutableStateFlow(MobileSubscriptionModel())
|
||||
|
||||
|
||||
@@ -27,18 +27,20 @@ import android.telephony.TelephonyCallback
|
||||
import android.telephony.TelephonyDisplayInfo
|
||||
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE
|
||||
import android.telephony.TelephonyManager
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DefaultNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileSubscriptionModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.OverrideNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.toDataConnectionType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
|
||||
import com.android.systemui.util.settings.GlobalSettings
|
||||
import java.lang.IllegalStateException
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -63,6 +65,7 @@ class MobileConnectionRepositoryImpl(
|
||||
private val globalSettings: GlobalSettings,
|
||||
defaultDataSubId: StateFlow<Int>,
|
||||
globalMobileDataSettingChangedEvent: Flow<Unit>,
|
||||
mobileMappingsProxy: MobileMappingsProxy,
|
||||
bgDispatcher: CoroutineDispatcher,
|
||||
logger: ConnectivityPipelineLogger,
|
||||
scope: CoroutineScope,
|
||||
@@ -141,14 +144,27 @@ class MobileConnectionRepositoryImpl(
|
||||
override fun onDisplayInfoChanged(
|
||||
telephonyDisplayInfo: TelephonyDisplayInfo
|
||||
) {
|
||||
|
||||
val networkType =
|
||||
if (
|
||||
if (telephonyDisplayInfo.networkType == NETWORK_TYPE_UNKNOWN) {
|
||||
UnknownNetworkType
|
||||
} else if (
|
||||
telephonyDisplayInfo.overrideNetworkType ==
|
||||
OVERRIDE_NETWORK_TYPE_NONE
|
||||
) {
|
||||
DefaultNetworkType(telephonyDisplayInfo.networkType)
|
||||
DefaultNetworkType(
|
||||
telephonyDisplayInfo.networkType,
|
||||
mobileMappingsProxy.toIconKey(
|
||||
telephonyDisplayInfo.networkType
|
||||
)
|
||||
)
|
||||
} else {
|
||||
OverrideNetworkType(telephonyDisplayInfo.overrideNetworkType)
|
||||
OverrideNetworkType(
|
||||
telephonyDisplayInfo.overrideNetworkType,
|
||||
mobileMappingsProxy.toIconKeyOverride(
|
||||
telephonyDisplayInfo.overrideNetworkType
|
||||
)
|
||||
)
|
||||
}
|
||||
state = state.copy(resolvedNetworkType = networkType)
|
||||
trySend(state)
|
||||
@@ -211,6 +227,7 @@ class MobileConnectionRepositoryImpl(
|
||||
private val telephonyManager: TelephonyManager,
|
||||
private val logger: ConnectivityPipelineLogger,
|
||||
private val globalSettings: GlobalSettings,
|
||||
private val mobileMappingsProxy: MobileMappingsProxy,
|
||||
@Background private val bgDispatcher: CoroutineDispatcher,
|
||||
@Application private val scope: CoroutineScope,
|
||||
) {
|
||||
@@ -226,6 +243,7 @@ class MobileConnectionRepositoryImpl(
|
||||
globalSettings,
|
||||
defaultDataSubId,
|
||||
globalMobileDataSettingChangedEvent,
|
||||
mobileMappingsProxy,
|
||||
bgDispatcher,
|
||||
logger,
|
||||
scope,
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener
|
||||
import android.telephony.TelephonyManager
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.android.internal.telephony.PhoneConstants
|
||||
import com.android.settingslib.SignalIcon.MobileIconGroup
|
||||
import com.android.settingslib.mobile.MobileMappings
|
||||
import com.android.settingslib.mobile.MobileMappings.Config
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||
@@ -46,6 +47,7 @@ import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
||||
import com.android.systemui.util.settings.GlobalSettings
|
||||
import javax.inject.Inject
|
||||
@@ -59,6 +61,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -75,6 +78,7 @@ constructor(
|
||||
private val subscriptionManager: SubscriptionManager,
|
||||
private val telephonyManager: TelephonyManager,
|
||||
private val logger: ConnectivityPipelineLogger,
|
||||
mobileMappingsProxy: MobileMappingsProxy,
|
||||
broadcastDispatcher: BroadcastDispatcher,
|
||||
private val globalSettings: GlobalSettings,
|
||||
private val context: Context,
|
||||
@@ -157,7 +161,7 @@ constructor(
|
||||
*
|
||||
* This flow will produce whenever the default data subscription or the carrier config changes.
|
||||
*/
|
||||
override val defaultDataSubRatConfig: StateFlow<Config> =
|
||||
private val defaultDataSubRatConfig: StateFlow<Config> =
|
||||
merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent)
|
||||
.mapLatest { Config.readConfig(context) }
|
||||
.stateIn(
|
||||
@@ -166,6 +170,12 @@ constructor(
|
||||
initialValue = Config.readConfig(context)
|
||||
)
|
||||
|
||||
override val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>> =
|
||||
defaultDataSubRatConfig.map { mobileMappingsProxy.mapIconSets(it) }
|
||||
|
||||
override val defaultMobileIconGroup: Flow<MobileIconGroup> =
|
||||
defaultDataSubRatConfig.map { mobileMappingsProxy.getDefaultIcons(it) }
|
||||
|
||||
override fun getRepoForSubId(subId: Int): MobileConnectionRepository {
|
||||
if (!isValidSubId(subId)) {
|
||||
throw IllegalArgumentException(
|
||||
|
||||
@@ -20,10 +20,7 @@ import android.telephony.CarrierConfigManager
|
||||
import com.android.settingslib.SignalIcon.MobileIconGroup
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Connected
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DefaultNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.OverrideNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
|
||||
import com.android.systemui.util.CarrierConfigTracker
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -70,7 +67,6 @@ class MobileIconInteractorImpl(
|
||||
defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>,
|
||||
defaultMobileIconGroup: StateFlow<MobileIconGroup>,
|
||||
override val isDefaultConnectionFailed: StateFlow<Boolean>,
|
||||
mobileMappingsProxy: MobileMappingsProxy,
|
||||
connectionRepository: MobileConnectionRepository,
|
||||
) : MobileIconInteractor {
|
||||
private val mobileStatusInfo = connectionRepository.subscriptionModelFlow
|
||||
@@ -86,13 +82,7 @@ class MobileIconInteractorImpl(
|
||||
defaultMobileIconMapping,
|
||||
defaultMobileIconGroup,
|
||||
) { info, mapping, defaultGroup ->
|
||||
val lookupKey =
|
||||
when (val resolved = info.resolvedNetworkType) {
|
||||
is DefaultNetworkType -> mobileMappingsProxy.toIconKey(resolved.type)
|
||||
is OverrideNetworkType ->
|
||||
mobileMappingsProxy.toIconKeyOverride(resolved.type)
|
||||
}
|
||||
mapping[lookupKey] ?: defaultGroup
|
||||
mapping[info.resolvedNetworkType.lookupKey] ?: defaultGroup
|
||||
}
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), defaultMobileIconGroup.value)
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
|
||||
import com.android.systemui.util.CarrierConfigTracker
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -79,7 +78,6 @@ class MobileIconsInteractorImpl
|
||||
constructor(
|
||||
private val mobileConnectionsRepo: MobileConnectionsRepository,
|
||||
private val carrierConfigTracker: CarrierConfigTracker,
|
||||
private val mobileMappingsProxy: MobileMappingsProxy,
|
||||
userSetupRepo: UserSetupRepository,
|
||||
@Application private val scope: CoroutineScope,
|
||||
) : MobileIconsInteractor {
|
||||
@@ -154,15 +152,19 @@ constructor(
|
||||
* subscription Id. This mapping is the same for every subscription.
|
||||
*/
|
||||
override val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>> =
|
||||
mobileConnectionsRepo.defaultDataSubRatConfig
|
||||
.mapLatest { mobileMappingsProxy.mapIconSets(it) }
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = mapOf())
|
||||
mobileConnectionsRepo.defaultMobileIconMapping.stateIn(
|
||||
scope,
|
||||
SharingStarted.WhileSubscribed(),
|
||||
initialValue = mapOf()
|
||||
)
|
||||
|
||||
/** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */
|
||||
override val defaultMobileIconGroup: StateFlow<MobileIconGroup> =
|
||||
mobileConnectionsRepo.defaultDataSubRatConfig
|
||||
.mapLatest { mobileMappingsProxy.getDefaultIcons(it) }
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = TelephonyIcons.G)
|
||||
mobileConnectionsRepo.defaultMobileIconGroup.stateIn(
|
||||
scope,
|
||||
SharingStarted.WhileSubscribed(),
|
||||
initialValue = TelephonyIcons.G
|
||||
)
|
||||
|
||||
/**
|
||||
* We want to show an error state when cellular has actually failed to validate, but not if some
|
||||
@@ -189,7 +191,6 @@ constructor(
|
||||
defaultMobileIconMapping,
|
||||
defaultMobileIconGroup,
|
||||
isDefaultConnectionFailed,
|
||||
mobileMappingsProxy,
|
||||
mobileConnectionsRepo.getRepoForSubId(subId),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileSubscriptionModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
// TODO(b/261632894): remove this in favor of the real impl or DemoMobileConnectionRepository
|
||||
class FakeMobileConnectionRepository(override val subId: Int) : MobileConnectionRepository {
|
||||
private val _subscriptionsModelFlow = MutableStateFlow(MobileSubscriptionModel())
|
||||
override val subscriptionModelFlow = _subscriptionsModelFlow
|
||||
|
||||
@@ -18,20 +18,41 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository
|
||||
|
||||
import android.telephony.SubscriptionInfo
|
||||
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||
import com.android.settingslib.mobile.MobileMappings.Config
|
||||
import android.telephony.TelephonyDisplayInfo
|
||||
import android.telephony.TelephonyManager
|
||||
import com.android.settingslib.SignalIcon
|
||||
import com.android.settingslib.mobile.TelephonyIcons
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class FakeMobileConnectionsRepository : MobileConnectionsRepository {
|
||||
// TODO(b/261632894): remove this in favor of the real impl or DemoMobileConnectionsRepository
|
||||
class FakeMobileConnectionsRepository(mobileMappings: MobileMappingsProxy) :
|
||||
MobileConnectionsRepository {
|
||||
val GSM_KEY = mobileMappings.toIconKey(GSM)
|
||||
val LTE_KEY = mobileMappings.toIconKey(LTE)
|
||||
val UMTS_KEY = mobileMappings.toIconKey(UMTS)
|
||||
val LTE_ADVANCED_KEY = mobileMappings.toIconKeyOverride(LTE_ADVANCED_PRO)
|
||||
|
||||
/**
|
||||
* To avoid a reliance on [MobileMappings], we'll build a simpler map from network type to
|
||||
* mobile icon. See TelephonyManager.NETWORK_TYPES for a list of types and [TelephonyIcons] for
|
||||
* the exhaustive set of icons
|
||||
*/
|
||||
val TEST_MAPPING: Map<String, SignalIcon.MobileIconGroup> =
|
||||
mapOf(
|
||||
GSM_KEY to TelephonyIcons.THREE_G,
|
||||
LTE_KEY to TelephonyIcons.LTE,
|
||||
UMTS_KEY to TelephonyIcons.FOUR_G,
|
||||
LTE_ADVANCED_KEY to TelephonyIcons.NR_5G,
|
||||
)
|
||||
|
||||
private val _subscriptionsFlow = MutableStateFlow<List<SubscriptionInfo>>(listOf())
|
||||
override val subscriptionsFlow = _subscriptionsFlow
|
||||
|
||||
private val _activeMobileDataSubscriptionId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
|
||||
override val activeMobileDataSubscriptionId = _activeMobileDataSubscriptionId
|
||||
|
||||
private val _defaultDataSubRatConfig = MutableStateFlow(Config())
|
||||
override val defaultDataSubRatConfig = _defaultDataSubRatConfig
|
||||
|
||||
private val _defaultDataSubId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
|
||||
override val defaultDataSubId = _defaultDataSubId
|
||||
|
||||
@@ -47,14 +68,16 @@ class FakeMobileConnectionsRepository : MobileConnectionsRepository {
|
||||
private val _globalMobileDataSettingChangedEvent = MutableStateFlow(Unit)
|
||||
override val globalMobileDataSettingChangedEvent = _globalMobileDataSettingChangedEvent
|
||||
|
||||
private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING)
|
||||
override val defaultMobileIconMapping = _defaultMobileIconMapping
|
||||
|
||||
private val _defaultMobileIconGroup = MutableStateFlow(DEFAULT_ICON)
|
||||
override val defaultMobileIconGroup = _defaultMobileIconGroup
|
||||
|
||||
fun setSubscriptions(subs: List<SubscriptionInfo>) {
|
||||
_subscriptionsFlow.value = subs
|
||||
}
|
||||
|
||||
fun setDefaultDataSubRatConfig(config: Config) {
|
||||
_defaultDataSubRatConfig.value = config
|
||||
}
|
||||
|
||||
fun setDefaultDataSubId(id: Int) {
|
||||
_defaultDataSubId.value = id
|
||||
}
|
||||
@@ -74,4 +97,14 @@ class FakeMobileConnectionsRepository : MobileConnectionsRepository {
|
||||
fun setMobileConnectionRepositoryMap(connections: Map<Int, MobileConnectionRepository>) {
|
||||
connections.forEach { entry -> subIdRepos[entry.key] = entry.value }
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DEFAULT_ICON = TelephonyIcons.G
|
||||
|
||||
// Use [MobileMappings] to define some simple definitions
|
||||
const val GSM = TelephonyManager.NETWORK_TYPE_GSM
|
||||
const val LTE = TelephonyManager.NETWORK_TYPE_LTE
|
||||
const val UMTS = TelephonyManager.NETWORK_TYPE_UMTS
|
||||
const val LTE_ADVANCED_PRO = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoM
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.validMobileEvent
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.kotlinArgumentCaptor
|
||||
@@ -76,6 +77,7 @@ class MobileRepositorySwitcherTest : SysuiTestCase() {
|
||||
|
||||
private val globalSettings = FakeSettings()
|
||||
private val fakeNetworkEventsFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
|
||||
private val mobileMappings = FakeMobileMappingsProxy()
|
||||
|
||||
private val scope = CoroutineScope(IMMEDIATE)
|
||||
|
||||
@@ -97,6 +99,7 @@ class MobileRepositorySwitcherTest : SysuiTestCase() {
|
||||
subscriptionManager,
|
||||
telephonyManager,
|
||||
logger,
|
||||
mobileMappings,
|
||||
fakeBroadcastDispatcher,
|
||||
globalSettings,
|
||||
context,
|
||||
|
||||
@@ -37,10 +37,12 @@ import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DefaultNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileSubscriptionModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.OverrideNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.argumentCaptor
|
||||
@@ -72,8 +74,9 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
@Mock private lateinit var logger: ConnectivityPipelineLogger
|
||||
|
||||
private val scope = CoroutineScope(IMMEDIATE)
|
||||
private val mobileMappings = FakeMobileMappingsProxy()
|
||||
private val globalSettings = FakeSettings()
|
||||
private val connectionsRepo = FakeMobileConnectionsRepository()
|
||||
private val connectionsRepo = FakeMobileConnectionsRepository(mobileMappings)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
@@ -89,6 +92,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
globalSettings,
|
||||
connectionsRepo.defaultDataSubId,
|
||||
connectionsRepo.globalMobileDataSettingChangedEvent,
|
||||
mobileMappings,
|
||||
IMMEDIATE,
|
||||
logger,
|
||||
scope,
|
||||
@@ -272,7 +276,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
val job = underTest.subscriptionModelFlow.onEach { latest = it }.launchIn(this)
|
||||
|
||||
val type = NETWORK_TYPE_UNKNOWN
|
||||
val expected = DefaultNetworkType(type)
|
||||
val expected = UnknownNetworkType
|
||||
|
||||
assertThat(latest?.resolvedNetworkType).isEqualTo(expected)
|
||||
|
||||
@@ -287,7 +291,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
|
||||
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
|
||||
val type = NETWORK_TYPE_LTE
|
||||
val expected = DefaultNetworkType(type)
|
||||
val expected = DefaultNetworkType(type, mobileMappings.toIconKey(type))
|
||||
val ti = mock<TelephonyDisplayInfo>().also { whenever(it.networkType).thenReturn(type) }
|
||||
callback.onDisplayInfoChanged(ti)
|
||||
|
||||
@@ -304,9 +308,10 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
|
||||
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
|
||||
val type = OVERRIDE_NETWORK_TYPE_LTE_CA
|
||||
val expected = OverrideNetworkType(type)
|
||||
val expected = OverrideNetworkType(type, mobileMappings.toIconKeyOverride(type))
|
||||
val ti =
|
||||
mock<TelephonyDisplayInfo>().also {
|
||||
whenever(it.networkType).thenReturn(type)
|
||||
whenever(it.overrideNetworkType).thenReturn(type)
|
||||
}
|
||||
callback.onDisplayInfoChanged(ti)
|
||||
|
||||
@@ -32,6 +32,7 @@ import androidx.test.filters.SmallTest
|
||||
import com.android.internal.telephony.PhoneConstants
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.argumentCaptor
|
||||
@@ -65,6 +66,8 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
|
||||
@Mock private lateinit var telephonyManager: TelephonyManager
|
||||
@Mock private lateinit var logger: ConnectivityPipelineLogger
|
||||
|
||||
private val mobileMappings = FakeMobileMappingsProxy()
|
||||
|
||||
private val scope = CoroutineScope(IMMEDIATE)
|
||||
private val globalSettings = FakeSettings()
|
||||
|
||||
@@ -78,6 +81,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
|
||||
subscriptionManager,
|
||||
telephonyManager,
|
||||
logger,
|
||||
mobileMappings,
|
||||
fakeBroadcastDispatcher,
|
||||
globalSettings,
|
||||
context,
|
||||
|
||||
@@ -24,9 +24,9 @@ import com.android.settingslib.SignalIcon.MobileIconGroup
|
||||
import com.android.settingslib.mobile.TelephonyIcons
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DefaultNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileSubscriptionModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.OverrideNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor.Companion.FIVE_G_OVERRIDE
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor.Companion.FOUR_G
|
||||
@@ -62,7 +62,6 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
mobileIconsInteractor.defaultMobileIconMapping,
|
||||
mobileIconsInteractor.defaultMobileIconGroup,
|
||||
mobileIconsInteractor.isDefaultConnectionFailed,
|
||||
mobileMappingsProxy,
|
||||
connectionRepository,
|
||||
)
|
||||
}
|
||||
@@ -138,7 +137,10 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
fun iconGroup_three_g() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
connectionRepository.setMobileSubscriptionModel(
|
||||
MobileSubscriptionModel(resolvedNetworkType = DefaultNetworkType(THREE_G)),
|
||||
MobileSubscriptionModel(
|
||||
resolvedNetworkType =
|
||||
DefaultNetworkType(THREE_G, mobileMappingsProxy.toIconKey(THREE_G))
|
||||
),
|
||||
)
|
||||
|
||||
var latest: MobileIconGroup? = null
|
||||
@@ -153,7 +155,10 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
fun iconGroup_updates_on_change() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
connectionRepository.setMobileSubscriptionModel(
|
||||
MobileSubscriptionModel(resolvedNetworkType = DefaultNetworkType(THREE_G)),
|
||||
MobileSubscriptionModel(
|
||||
resolvedNetworkType =
|
||||
DefaultNetworkType(THREE_G, mobileMappingsProxy.toIconKey(THREE_G))
|
||||
),
|
||||
)
|
||||
|
||||
var latest: MobileIconGroup? = null
|
||||
@@ -161,7 +166,11 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
connectionRepository.setMobileSubscriptionModel(
|
||||
MobileSubscriptionModel(
|
||||
resolvedNetworkType = DefaultNetworkType(FOUR_G),
|
||||
resolvedNetworkType =
|
||||
DefaultNetworkType(
|
||||
FOUR_G,
|
||||
mobileMappingsProxy.toIconKey(FOUR_G),
|
||||
),
|
||||
),
|
||||
)
|
||||
yield()
|
||||
@@ -175,7 +184,13 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
fun iconGroup_5g_override_type() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
connectionRepository.setMobileSubscriptionModel(
|
||||
MobileSubscriptionModel(resolvedNetworkType = OverrideNetworkType(FIVE_G_OVERRIDE)),
|
||||
MobileSubscriptionModel(
|
||||
resolvedNetworkType =
|
||||
OverrideNetworkType(
|
||||
FIVE_G_OVERRIDE,
|
||||
mobileMappingsProxy.toIconKeyOverride(FIVE_G_OVERRIDE)
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
var latest: MobileIconGroup? = null
|
||||
@@ -191,7 +206,11 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
runBlocking(IMMEDIATE) {
|
||||
connectionRepository.setMobileSubscriptionModel(
|
||||
MobileSubscriptionModel(
|
||||
resolvedNetworkType = DefaultNetworkType(NETWORK_TYPE_UNKNOWN),
|
||||
resolvedNetworkType =
|
||||
DefaultNetworkType(
|
||||
NETWORK_TYPE_UNKNOWN,
|
||||
mobileMappingsProxy.toIconKey(NETWORK_TYPE_UNKNOWN)
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -45,8 +45,8 @@ import org.mockito.MockitoAnnotations
|
||||
class MobileIconsInteractorTest : SysuiTestCase() {
|
||||
private lateinit var underTest: MobileIconsInteractor
|
||||
private val userSetupRepository = FakeUserSetupRepository()
|
||||
private val connectionsRepository = FakeMobileConnectionsRepository()
|
||||
private val mobileMappingsProxy = FakeMobileMappingsProxy()
|
||||
private val connectionsRepository = FakeMobileConnectionsRepository(mobileMappingsProxy)
|
||||
private val scope = CoroutineScope(IMMEDIATE)
|
||||
|
||||
@Mock private lateinit var carrierConfigTracker: CarrierConfigTracker
|
||||
@@ -69,7 +69,6 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
||||
MobileIconsInteractorImpl(
|
||||
connectionsRepository,
|
||||
carrierConfigTracker,
|
||||
mobileMappingsProxy,
|
||||
userSetupRepository,
|
||||
scope
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user