[Sb refactor] Add carrierId to the new pipeline
Adds carrierId to the mobile connection repo, and upgrades the mobile icon group type to a NetworkTypeIconModel so that we can do fancy stuff like override it. We add support for checking MobileIconCarrierIdOverrides for an override entry whenever the carrierId changes. If an override entry exists, then we check for an asset override whenever the network changes. Also can be tested using Demo mode: ``` $ # MCC/MNC 311/480 overrides the icon to use 5GUC -- no carrierId $ # override for 1234 $ adb shell am broadcast -a com.android.systemui.demo -e command network -e mobile show -e level 2 -e datatype 5g+ -e mccmnc 311480 -e carrierid 1234 $ # carrierid 2032 contains an icon override, pointing back to the $ # default 5G+ icon $ adb shell am broadcast -a com.android.systemui.demo -e command network -e mobile show -e level 2 -e datatype 5g+ -e mccmnc 311480 -e carrierid 2032 ``` Test: MobileConnectionsRepositoryTest Test: MobileIconInteractorTest Bug: 272099695 Change-Id: Ia71831d481d84c2508d8cbe08755644eed2f9ff5
This commit is contained in:
@@ -558,8 +558,10 @@ public interface StatusBarIconController {
|
||||
mGroup.addView(view, index, onCreateLayoutParams());
|
||||
|
||||
if (mIsInDemoMode) {
|
||||
Context mobileContext = mMobileContextProvider
|
||||
.getMobileContextForSub(subId, mContext);
|
||||
mDemoStatusIcons.addModernMobileView(
|
||||
mContext,
|
||||
mobileContext,
|
||||
mMobileIconsViewModel.getLogger(),
|
||||
subId);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ interface MobileConnectionRepository {
|
||||
/** The subscriptionId that this connection represents */
|
||||
val subId: Int
|
||||
|
||||
/** The carrierId for this connection. See [TelephonyManager.getSimCarrierId] */
|
||||
val carrierId: StateFlow<Int>
|
||||
|
||||
/**
|
||||
* The table log buffer created for this connection. Will have the name "MobileConnectionLog
|
||||
* [subId]"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui.statusbar.pipeline.mobile.data.repository.demo
|
||||
|
||||
import android.telephony.CellSignalStrength
|
||||
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||
import android.telephony.TelephonyManager
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.log.table.logDiffsForTable
|
||||
@@ -25,6 +26,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameMode
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_CARRIER_ID
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_CARRIER_NETWORK_CHANGE
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_CDMA_LEVEL
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_EMERGENCY
|
||||
@@ -52,6 +54,17 @@ class DemoMobileConnectionRepository(
|
||||
override val tableLogBuffer: TableLogBuffer,
|
||||
val scope: CoroutineScope,
|
||||
) : MobileConnectionRepository {
|
||||
private val _carrierId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
|
||||
override val carrierId =
|
||||
_carrierId
|
||||
.logDiffsForTable(
|
||||
tableLogBuffer,
|
||||
columnPrefix = "",
|
||||
columnName = COL_CARRIER_ID,
|
||||
_carrierId.value,
|
||||
)
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), _carrierId.value)
|
||||
|
||||
private val _isEmergencyOnly = MutableStateFlow(false)
|
||||
override val isEmergencyOnly =
|
||||
_isEmergencyOnly
|
||||
@@ -186,6 +199,8 @@ class DemoMobileConnectionRepository(
|
||||
dataEnabled.value = true
|
||||
networkName.value = NetworkNameModel.IntentDerived(event.name)
|
||||
|
||||
_carrierId.value = event.carrierId ?: INVALID_SUBSCRIPTION_ID
|
||||
|
||||
cdmaRoaming.value = event.roaming
|
||||
_isRoaming.value = event.roaming
|
||||
// TODO(b/261029387): not yet supported
|
||||
@@ -208,6 +223,8 @@ class DemoMobileConnectionRepository(
|
||||
// This is always true here, because we split out disabled states at the data-source level
|
||||
dataEnabled.value = true
|
||||
networkName.value = NetworkNameModel.IntentDerived(CARRIER_MERGED_NAME)
|
||||
// TODO(b/276943904): is carrierId a thing with carrier merged networks?
|
||||
_carrierId.value = INVALID_SUBSCRIPTION_ID
|
||||
numberOfLevels.value = event.numberOfLevels
|
||||
cdmaRoaming.value = false
|
||||
_primaryLevel.value = event.level
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
|
||||
|
||||
import android.telephony.CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN
|
||||
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||
import android.telephony.TelephonyManager
|
||||
import android.util.Log
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
@@ -157,6 +158,7 @@ class CarrierMergedConnectionRepository(
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), DataConnectionState.Disconnected)
|
||||
|
||||
override val isRoaming = MutableStateFlow(false).asStateFlow()
|
||||
override val carrierId = MutableStateFlow(INVALID_SUBSCRIPTION_ID).asStateFlow()
|
||||
override val isEmergencyOnly = MutableStateFlow(false).asStateFlow()
|
||||
override val operatorAlphaShort = MutableStateFlow(null).asStateFlow()
|
||||
override val isInService = MutableStateFlow(true).asStateFlow()
|
||||
|
||||
@@ -109,6 +109,11 @@ class FullMobileConnectionRepository(
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), initial)
|
||||
}
|
||||
|
||||
override val carrierId =
|
||||
activeRepo
|
||||
.flatMapLatest { it.carrierId }
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.carrierId.value)
|
||||
|
||||
override val cdmaRoaming =
|
||||
activeRepo
|
||||
.flatMapLatest { it.cdmaRoaming }
|
||||
@@ -321,13 +326,14 @@ class FullMobileConnectionRepository(
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val COL_EMERGENCY = "emergencyOnly"
|
||||
const val COL_ROAMING = "roaming"
|
||||
const val COL_OPERATOR = "operatorName"
|
||||
const val COL_IS_IN_SERVICE = "isInService"
|
||||
const val COL_IS_GSM = "isGsm"
|
||||
const val COL_CDMA_LEVEL = "cdmaLevel"
|
||||
const val COL_PRIMARY_LEVEL = "primaryLevel"
|
||||
const val COL_CARRIER_ID = "carrierId"
|
||||
const val COL_CARRIER_NETWORK_CHANGE = "carrierNetworkChangeActive"
|
||||
const val COL_CDMA_LEVEL = "cdmaLevel"
|
||||
const val COL_EMERGENCY = "emergencyOnly"
|
||||
const val COL_IS_GSM = "isGsm"
|
||||
const val COL_IS_IN_SERVICE = "isInService"
|
||||
const val COL_OPERATOR = "operatorName"
|
||||
const val COL_PRIMARY_LEVEL = "primaryLevel"
|
||||
const val COL_ROAMING = "roaming"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.telephony.CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN
|
||||
import android.telephony.CellSignalStrengthCdma
|
||||
@@ -31,6 +31,7 @@ import android.telephony.TelephonyManager.ERI_FLASH
|
||||
import android.telephony.TelephonyManager.ERI_ON
|
||||
import android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||||
import android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID
|
||||
import com.android.settingslib.Utils
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
@@ -65,6 +66,7 @@ import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.flow.scan
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
@@ -75,7 +77,6 @@ import kotlinx.coroutines.flow.stateIn
|
||||
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class MobileConnectionRepositoryImpl(
|
||||
private val context: Context,
|
||||
override val subId: Int,
|
||||
defaultNetworkName: NetworkNameModel,
|
||||
networkNameSeparator: String,
|
||||
@@ -293,6 +294,23 @@ class MobileConnectionRepositoryImpl(
|
||||
}
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
|
||||
|
||||
override val carrierId =
|
||||
broadcastDispatcher
|
||||
.broadcastFlow(
|
||||
filter =
|
||||
IntentFilter(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED),
|
||||
map = { intent, _ -> intent },
|
||||
)
|
||||
.filter { intent ->
|
||||
intent.getIntExtra(EXTRA_SUBSCRIPTION_ID, INVALID_SUBSCRIPTION_ID) == subId
|
||||
}
|
||||
.map { it.carrierId() }
|
||||
.onStart {
|
||||
// Make sure we get the initial carrierId
|
||||
emit(telephonyManager.simCarrierId)
|
||||
}
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), telephonyManager.simCarrierId)
|
||||
|
||||
override val networkName: StateFlow<NetworkNameModel> =
|
||||
broadcastDispatcher
|
||||
.broadcastFlow(
|
||||
@@ -317,7 +335,6 @@ class MobileConnectionRepositoryImpl(
|
||||
@Inject
|
||||
constructor(
|
||||
private val broadcastDispatcher: BroadcastDispatcher,
|
||||
private val context: Context,
|
||||
private val telephonyManager: TelephonyManager,
|
||||
private val logger: MobileInputLogger,
|
||||
private val carrierConfigRepository: CarrierConfigRepository,
|
||||
@@ -332,7 +349,6 @@ class MobileConnectionRepositoryImpl(
|
||||
networkNameSeparator: String,
|
||||
): MobileConnectionRepository {
|
||||
return MobileConnectionRepositoryImpl(
|
||||
context,
|
||||
subId,
|
||||
defaultNetworkName,
|
||||
networkNameSeparator,
|
||||
@@ -349,6 +365,9 @@ class MobileConnectionRepositoryImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun Intent.carrierId(): Int =
|
||||
getIntExtra(TelephonyManager.EXTRA_CARRIER_ID, UNKNOWN_CARRIER_ID)
|
||||
|
||||
/**
|
||||
* Wrap every [TelephonyCallback] we care about in a data class so we can accept them in a single
|
||||
* shared flow and then split them back out into other flows.
|
||||
|
||||
@@ -16,15 +16,22 @@
|
||||
|
||||
package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
|
||||
|
||||
import android.content.Context
|
||||
import android.telephony.CarrierConfigManager
|
||||
import com.android.settingslib.SignalIcon.MobileIconGroup
|
||||
import com.android.settingslib.mobile.MobileIconCarrierIdOverrides
|
||||
import com.android.settingslib.mobile.MobileIconCarrierIdOverridesImpl
|
||||
import com.android.settingslib.mobile.TelephonyIcons.NOT_DEFAULT_DATA
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.log.table.logDiffsForTable
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Connected
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.model.NetworkTypeIconModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.model.NetworkTypeIconModel.DefaultIcon
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.model.NetworkTypeIconModel.OverriddenIcon
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -35,7 +42,6 @@ import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
interface MobileIconInteractor {
|
||||
@@ -76,7 +82,7 @@ interface MobileIconInteractor {
|
||||
val alwaysUseCdmaLevel: StateFlow<Boolean>
|
||||
|
||||
/** Observable for RAT type (network type) indicator */
|
||||
val networkTypeIconGroup: StateFlow<MobileIconGroup>
|
||||
val networkTypeIconGroup: StateFlow<NetworkTypeIconModel>
|
||||
|
||||
/**
|
||||
* Provider name for this network connection. The name can be one of 3 values:
|
||||
@@ -123,6 +129,8 @@ class MobileIconInteractorImpl(
|
||||
override val isDefaultConnectionFailed: StateFlow<Boolean>,
|
||||
override val isForceHidden: Flow<Boolean>,
|
||||
connectionRepository: MobileConnectionRepository,
|
||||
private val context: Context,
|
||||
val carrierIdOverrides: MobileIconCarrierIdOverrides = MobileIconCarrierIdOverridesImpl()
|
||||
) : MobileIconInteractor {
|
||||
override val tableLogBuffer: TableLogBuffer = connectionRepository.tableLogBuffer
|
||||
|
||||
@@ -139,6 +147,15 @@ class MobileIconInteractorImpl(
|
||||
connectionRepository.subId == defaultDataSubId.value
|
||||
)
|
||||
|
||||
// True if there exists _any_ icon override for this carrierId. Note that overrides can include
|
||||
// any or none of the icon groups defined in MobileMappings, so we still need to check on a
|
||||
// per-network-type basis whether or not the given icon group is overridden
|
||||
private val carrierIdIconOverrideExists =
|
||||
connectionRepository.carrierId
|
||||
.map { carrierIdOverrides.carrierIdEntryExists(it) }
|
||||
.distinctUntilChanged()
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
|
||||
|
||||
override val isDefaultDataEnabled = defaultSubscriptionHasDataEnabled
|
||||
|
||||
override val networkName =
|
||||
@@ -157,8 +174,8 @@ class MobileIconInteractorImpl(
|
||||
connectionRepository.networkName.value
|
||||
)
|
||||
|
||||
/** Observable for the current RAT indicator icon ([MobileIconGroup]) */
|
||||
override val networkTypeIconGroup: StateFlow<MobileIconGroup> =
|
||||
/** What the mobile icon would be before carrierId overrides */
|
||||
private val defaultNetworkType: StateFlow<MobileIconGroup> =
|
||||
combine(
|
||||
connectionRepository.resolvedNetworkType,
|
||||
defaultMobileIconMapping,
|
||||
@@ -172,20 +189,46 @@ class MobileIconInteractorImpl(
|
||||
when (resolvedNetworkType) {
|
||||
is ResolvedNetworkType.CarrierMergedNetworkType ->
|
||||
resolvedNetworkType.iconGroupOverride
|
||||
else -> mapping[resolvedNetworkType.lookupKey] ?: defaultGroup
|
||||
else -> {
|
||||
mapping[resolvedNetworkType.lookupKey] ?: defaultGroup
|
||||
}
|
||||
}
|
||||
}
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), defaultMobileIconGroup.value)
|
||||
|
||||
override val networkTypeIconGroup =
|
||||
combine(
|
||||
defaultNetworkType,
|
||||
carrierIdIconOverrideExists,
|
||||
) { networkType, overrideExists ->
|
||||
// DefaultIcon comes out of the icongroup lookup, we check for overrides here
|
||||
if (overrideExists) {
|
||||
val iconOverride =
|
||||
carrierIdOverrides.getOverrideFor(
|
||||
connectionRepository.carrierId.value,
|
||||
networkType.name,
|
||||
context.resources,
|
||||
)
|
||||
if (iconOverride > 0) {
|
||||
OverriddenIcon(networkType, iconOverride)
|
||||
} else {
|
||||
DefaultIcon(networkType)
|
||||
}
|
||||
} else {
|
||||
DefaultIcon(networkType)
|
||||
}
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.onEach {
|
||||
// Doesn't use [logDiffsForTable] because [MobileIconGroup] can't implement the
|
||||
// [Diffable] interface.
|
||||
tableLogBuffer.logChange(
|
||||
prefix = "",
|
||||
columnName = "networkTypeIcon",
|
||||
value = it.name
|
||||
)
|
||||
}
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), defaultMobileIconGroup.value)
|
||||
.logDiffsForTable(
|
||||
tableLogBuffer = tableLogBuffer,
|
||||
columnPrefix = "",
|
||||
initialValue = DefaultIcon(defaultMobileIconGroup.value),
|
||||
)
|
||||
.stateIn(
|
||||
scope,
|
||||
SharingStarted.WhileSubscribed(),
|
||||
DefaultIcon(defaultMobileIconGroup.value),
|
||||
)
|
||||
|
||||
override val isEmergencyOnly = connectionRepository.isEmergencyOnly
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
|
||||
|
||||
import android.content.Context
|
||||
import android.telephony.CarrierConfigManager
|
||||
import android.telephony.SubscriptionManager
|
||||
import com.android.settingslib.SignalIcon.MobileIconGroup
|
||||
@@ -112,6 +113,7 @@ constructor(
|
||||
connectivityRepository: ConnectivityRepository,
|
||||
userSetupRepo: UserSetupRepository,
|
||||
@Application private val scope: CoroutineScope,
|
||||
private val context: Context,
|
||||
) : MobileIconsInteractor {
|
||||
|
||||
override val mobileIsDefault = mobileConnectionsRepo.mobileIsDefault
|
||||
@@ -286,6 +288,7 @@ constructor(
|
||||
isDefaultConnectionFailed,
|
||||
isForceHidden,
|
||||
mobileConnectionsRepo.getRepoForSubId(subId),
|
||||
context,
|
||||
)
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.domain.model
|
||||
|
||||
import com.android.settingslib.SignalIcon.MobileIconGroup
|
||||
import com.android.systemui.log.table.Diffable
|
||||
import com.android.systemui.log.table.TableRowLogger
|
||||
|
||||
/**
|
||||
* A data wrapper class for [MobileIconGroup]. One lingering nuance of this pipeline is its
|
||||
* dependency on MobileMappings for its lookup from NetworkType -> NetworkTypeIcon. And because
|
||||
* MobileMappings is a static map of (netType, icon) that knows nothing of `carrierId`, we need the
|
||||
* concept of a "default" or "overridden" icon type.
|
||||
*
|
||||
* Until we can remove that dependency on MobileMappings, we should just allow for the composition
|
||||
* of overriding an icon id using the lookup defined in [MobileIconCarrierIdOverrides]. By using the
|
||||
* [overrideIcon] method defined below, we can create any arbitrarily overridden network type icon.
|
||||
*/
|
||||
sealed interface NetworkTypeIconModel : Diffable<NetworkTypeIconModel> {
|
||||
val contentDescription: Int
|
||||
val iconId: Int
|
||||
val name: String
|
||||
|
||||
data class DefaultIcon(
|
||||
val iconGroup: MobileIconGroup,
|
||||
) : NetworkTypeIconModel {
|
||||
override val contentDescription = iconGroup.dataContentDescription
|
||||
override val iconId = iconGroup.dataType
|
||||
override val name = iconGroup.name
|
||||
|
||||
override fun logDiffs(prevVal: NetworkTypeIconModel, row: TableRowLogger) {
|
||||
if (prevVal !is DefaultIcon || prevVal.name != name) {
|
||||
row.logChange(COL_NETWORK_ICON, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class OverriddenIcon(
|
||||
val iconGroup: MobileIconGroup,
|
||||
override val iconId: Int,
|
||||
) : NetworkTypeIconModel {
|
||||
override val contentDescription = iconGroup.dataContentDescription
|
||||
override val name = iconGroup.name
|
||||
|
||||
override fun logDiffs(prevVal: NetworkTypeIconModel, row: TableRowLogger) {
|
||||
if (prevVal !is OverriddenIcon || prevVal.name != name || prevVal.iconId != iconId) {
|
||||
row.logChange(COL_NETWORK_ICON, "Ovrd($name)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val COL_NETWORK_ICON = "networkTypeIcon"
|
||||
}
|
||||
}
|
||||
@@ -167,12 +167,12 @@ constructor(
|
||||
showNetworkTypeIcon,
|
||||
) { networkTypeIconGroup, shouldShow ->
|
||||
val desc =
|
||||
if (networkTypeIconGroup.dataContentDescription != 0)
|
||||
ContentDescription.Resource(networkTypeIconGroup.dataContentDescription)
|
||||
if (networkTypeIconGroup.contentDescription != 0)
|
||||
ContentDescription.Resource(networkTypeIconGroup.contentDescription)
|
||||
else null
|
||||
val icon =
|
||||
if (networkTypeIconGroup.dataType != 0)
|
||||
Icon.Resource(networkTypeIconGroup.dataType, desc)
|
||||
if (networkTypeIconGroup.iconId != 0)
|
||||
Icon.Resource(networkTypeIconGroup.iconId, desc)
|
||||
else null
|
||||
return@combine when {
|
||||
!shouldShow -> null
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.pipeline.mobile.data.repository
|
||||
|
||||
import android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
|
||||
@@ -29,6 +30,7 @@ class FakeMobileConnectionRepository(
|
||||
override val subId: Int,
|
||||
override val tableLogBuffer: TableLogBuffer,
|
||||
) : MobileConnectionRepository {
|
||||
override val carrierId = MutableStateFlow(UNKNOWN_CARRIER_ID)
|
||||
override val isEmergencyOnly = MutableStateFlow(false)
|
||||
override val isRoaming = MutableStateFlow(false)
|
||||
override val operatorAlphaShort: MutableStateFlow<String?> = MutableStateFlow(null)
|
||||
|
||||
@@ -593,7 +593,6 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
|
||||
val realRepo =
|
||||
MobileConnectionRepositoryImpl(
|
||||
context,
|
||||
SUB_ID,
|
||||
defaultNetworkName = NetworkNameModel.Default("default"),
|
||||
networkNameSeparator = SEP,
|
||||
|
||||
@@ -42,6 +42,7 @@ import android.telephony.TelephonyManager.DATA_SUSPENDED
|
||||
import android.telephony.TelephonyManager.DATA_UNKNOWN
|
||||
import android.telephony.TelephonyManager.ERI_OFF
|
||||
import android.telephony.TelephonyManager.ERI_ON
|
||||
import android.telephony.TelephonyManager.EXTRA_CARRIER_ID
|
||||
import android.telephony.TelephonyManager.EXTRA_PLMN
|
||||
import android.telephony.TelephonyManager.EXTRA_SHOW_PLMN
|
||||
import android.telephony.TelephonyManager.EXTRA_SHOW_SPN
|
||||
@@ -116,7 +117,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
|
||||
underTest =
|
||||
MobileConnectionRepositoryImpl(
|
||||
context,
|
||||
SUB_1_ID,
|
||||
DEFAULT_NAME,
|
||||
SEP,
|
||||
@@ -358,6 +358,36 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun carrierId_initialValueCaptured() =
|
||||
testScope.runTest {
|
||||
whenever(telephonyManager.simCarrierId).thenReturn(1234)
|
||||
|
||||
var latest: Int? = null
|
||||
val job = underTest.carrierId.onEach { latest = it }.launchIn(this)
|
||||
|
||||
assertThat(latest).isEqualTo(1234)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun carrierId_updatesOnBroadcast() =
|
||||
testScope.runTest {
|
||||
whenever(telephonyManager.simCarrierId).thenReturn(1234)
|
||||
|
||||
var latest: Int? = null
|
||||
val job = underTest.carrierId.onEach { latest = it }.launchIn(this)
|
||||
|
||||
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
|
||||
receiver.onReceive(context, carrierIdIntent(carrierId = 4321))
|
||||
}
|
||||
|
||||
assertThat(latest).isEqualTo(4321)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun carrierNetworkChange() =
|
||||
testScope.runTest {
|
||||
@@ -796,6 +826,15 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
return MobileTelephonyHelpers.getTelephonyCallbackForType(telephonyManager)
|
||||
}
|
||||
|
||||
private fun carrierIdIntent(
|
||||
subId: Int = SUB_1_ID,
|
||||
carrierId: Int,
|
||||
): Intent =
|
||||
Intent(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED).apply {
|
||||
putExtra(EXTRA_SUBSCRIPTION_ID, subId)
|
||||
putExtra(EXTRA_CARRIER_ID, carrierId)
|
||||
}
|
||||
|
||||
private fun spnIntent(
|
||||
subId: Int = SUB_1_ID,
|
||||
showSpn: Boolean = true,
|
||||
|
||||
@@ -117,7 +117,6 @@ class MobileConnectionTelephonySmokeTests : SysuiTestCase() {
|
||||
|
||||
underTest =
|
||||
MobileConnectionRepositoryImpl(
|
||||
context,
|
||||
SUB_1_ID,
|
||||
DEFAULT_NAME,
|
||||
SEP,
|
||||
|
||||
@@ -155,7 +155,6 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
|
||||
connectionFactory =
|
||||
MobileConnectionRepositoryImpl.Factory(
|
||||
fakeBroadcastDispatcher,
|
||||
context = context,
|
||||
telephonyManager = telephonyManager,
|
||||
bgDispatcher = IMMEDIATE,
|
||||
logger = logger,
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
|
||||
|
||||
import android.telephony.CellSignalStrength
|
||||
import com.android.settingslib.SignalIcon
|
||||
import com.android.settingslib.mobile.TelephonyIcons
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.model.NetworkTypeIconModel
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
@@ -42,8 +42,10 @@ class FakeMobileIconInteractor(
|
||||
|
||||
override val mobileIsDefault = MutableStateFlow(true)
|
||||
|
||||
private val _iconGroup = MutableStateFlow<SignalIcon.MobileIconGroup>(TelephonyIcons.THREE_G)
|
||||
override val networkTypeIconGroup = _iconGroup
|
||||
override val networkTypeIconGroup =
|
||||
MutableStateFlow<NetworkTypeIconModel>(
|
||||
NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
|
||||
)
|
||||
|
||||
override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived("demo mode"))
|
||||
|
||||
@@ -73,10 +75,6 @@ class FakeMobileIconInteractor(
|
||||
|
||||
override val isForceHidden = MutableStateFlow(false)
|
||||
|
||||
fun setIconGroup(group: SignalIcon.MobileIconGroup) {
|
||||
_iconGroup.value = group
|
||||
}
|
||||
|
||||
fun setIsEmergencyOnly(emergency: Boolean) {
|
||||
_isEmergencyOnly.value = emergency
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@ package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
|
||||
import android.telephony.CellSignalStrength
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.settingslib.SignalIcon.MobileIconGroup
|
||||
import com.android.settingslib.mobile.MobileIconCarrierIdOverrides
|
||||
import com.android.settingslib.mobile.MobileIconCarrierIdOverridesImpl
|
||||
import com.android.settingslib.mobile.TelephonyIcons
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
|
||||
@@ -31,18 +32,24 @@ import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobile
|
||||
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
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor.Companion.THREE_G
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.model.NetworkTypeIconModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.yield
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.ArgumentMatchers.anyString
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@SmallTest
|
||||
class MobileIconInteractorTest : SysuiTestCase() {
|
||||
private lateinit var underTest: MobileIconInteractor
|
||||
@@ -50,29 +57,17 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
private val mobileIconsInteractor = FakeMobileIconsInteractor(mobileMappingsProxy, mock())
|
||||
private val connectionRepository = FakeMobileConnectionRepository(SUB_1_ID, mock())
|
||||
|
||||
private val scope = CoroutineScope(IMMEDIATE)
|
||||
private val testDispatcher = UnconfinedTestDispatcher()
|
||||
private val testScope = TestScope(testDispatcher)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
underTest =
|
||||
MobileIconInteractorImpl(
|
||||
scope,
|
||||
mobileIconsInteractor.activeDataConnectionHasDataEnabled,
|
||||
mobileIconsInteractor.alwaysShowDataRatIcon,
|
||||
mobileIconsInteractor.alwaysUseCdmaLevel,
|
||||
mobileIconsInteractor.mobileIsDefault,
|
||||
mobileIconsInteractor.defaultMobileIconMapping,
|
||||
mobileIconsInteractor.defaultMobileIconGroup,
|
||||
mobileIconsInteractor.defaultDataSubId,
|
||||
mobileIconsInteractor.isDefaultConnectionFailed,
|
||||
mobileIconsInteractor.isForceHidden,
|
||||
connectionRepository,
|
||||
)
|
||||
underTest = createInteractor()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun gsm_level_default_unknown() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.isGsm.value = true
|
||||
|
||||
var latest: Int? = null
|
||||
@@ -85,7 +80,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun gsm_usesGsmLevel() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.isGsm.value = true
|
||||
connectionRepository.primaryLevel.value = GSM_LEVEL
|
||||
connectionRepository.cdmaLevel.value = CDMA_LEVEL
|
||||
@@ -100,7 +95,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun gsm_alwaysShowCdmaTrue_stillUsesGsmLevel() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.isGsm.value = true
|
||||
connectionRepository.primaryLevel.value = GSM_LEVEL
|
||||
connectionRepository.cdmaLevel.value = CDMA_LEVEL
|
||||
@@ -116,7 +111,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun notGsm_level_default_unknown() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.isGsm.value = false
|
||||
|
||||
var latest: Int? = null
|
||||
@@ -128,7 +123,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun notGsm_alwaysShowCdmaTrue_usesCdmaLevel() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.isGsm.value = false
|
||||
connectionRepository.primaryLevel.value = GSM_LEVEL
|
||||
connectionRepository.cdmaLevel.value = CDMA_LEVEL
|
||||
@@ -144,7 +139,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun notGsm_alwaysShowCdmaFalse_usesPrimaryLevel() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.isGsm.value = false
|
||||
connectionRepository.primaryLevel.value = GSM_LEVEL
|
||||
connectionRepository.cdmaLevel.value = CDMA_LEVEL
|
||||
@@ -160,7 +155,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun numberOfLevels_comesFromRepo() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Int? = null
|
||||
val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -175,101 +170,128 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun iconGroup_three_g() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.resolvedNetworkType.value =
|
||||
DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
|
||||
|
||||
var latest: MobileIconGroup? = null
|
||||
var latest: NetworkTypeIconModel? = null
|
||||
val job = underTest.networkTypeIconGroup.onEach { latest = it }.launchIn(this)
|
||||
|
||||
assertThat(latest).isEqualTo(TelephonyIcons.THREE_G)
|
||||
assertThat(latest).isEqualTo(NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G))
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun iconGroup_updates_on_change() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.resolvedNetworkType.value =
|
||||
DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
|
||||
|
||||
var latest: MobileIconGroup? = null
|
||||
var latest: NetworkTypeIconModel? = null
|
||||
val job = underTest.networkTypeIconGroup.onEach { latest = it }.launchIn(this)
|
||||
|
||||
connectionRepository.resolvedNetworkType.value =
|
||||
DefaultNetworkType(mobileMappingsProxy.toIconKey(FOUR_G))
|
||||
yield()
|
||||
|
||||
assertThat(latest).isEqualTo(TelephonyIcons.FOUR_G)
|
||||
assertThat(latest).isEqualTo(NetworkTypeIconModel.DefaultIcon(TelephonyIcons.FOUR_G))
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun iconGroup_5g_override_type() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.resolvedNetworkType.value =
|
||||
OverrideNetworkType(mobileMappingsProxy.toIconKeyOverride(FIVE_G_OVERRIDE))
|
||||
|
||||
var latest: MobileIconGroup? = null
|
||||
var latest: NetworkTypeIconModel? = null
|
||||
val job = underTest.networkTypeIconGroup.onEach { latest = it }.launchIn(this)
|
||||
|
||||
assertThat(latest).isEqualTo(TelephonyIcons.NR_5G)
|
||||
assertThat(latest).isEqualTo(NetworkTypeIconModel.DefaultIcon(TelephonyIcons.NR_5G))
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun iconGroup_default_if_no_lookup() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.resolvedNetworkType.value =
|
||||
DefaultNetworkType(mobileMappingsProxy.toIconKey(NETWORK_TYPE_UNKNOWN))
|
||||
|
||||
var latest: MobileIconGroup? = null
|
||||
var latest: NetworkTypeIconModel? = null
|
||||
val job = underTest.networkTypeIconGroup.onEach { latest = it }.launchIn(this)
|
||||
|
||||
assertThat(latest).isEqualTo(FakeMobileIconsInteractor.DEFAULT_ICON)
|
||||
assertThat(latest)
|
||||
.isEqualTo(NetworkTypeIconModel.DefaultIcon(FakeMobileIconsInteractor.DEFAULT_ICON))
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun iconGroup_carrierMerged_usesOverride() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
connectionRepository.resolvedNetworkType.value = CarrierMergedNetworkType
|
||||
|
||||
var latest: MobileIconGroup? = null
|
||||
var latest: NetworkTypeIconModel? = null
|
||||
val job = underTest.networkTypeIconGroup.onEach { latest = it }.launchIn(this)
|
||||
|
||||
assertThat(latest).isEqualTo(CarrierMergedNetworkType.iconGroupOverride)
|
||||
assertThat(latest)
|
||||
.isEqualTo(
|
||||
NetworkTypeIconModel.DefaultIcon(CarrierMergedNetworkType.iconGroupOverride)
|
||||
)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `icon group - checks default data`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
mobileIconsInteractor.defaultDataSubId.value = SUB_1_ID
|
||||
connectionRepository.resolvedNetworkType.value =
|
||||
DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
|
||||
|
||||
var latest: MobileIconGroup? = null
|
||||
var latest: NetworkTypeIconModel? = null
|
||||
val job = underTest.networkTypeIconGroup.onEach { latest = it }.launchIn(this)
|
||||
|
||||
assertThat(latest).isEqualTo(TelephonyIcons.THREE_G)
|
||||
assertThat(latest).isEqualTo(NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G))
|
||||
|
||||
// Default data sub id changes to something else
|
||||
mobileIconsInteractor.defaultDataSubId.value = 123
|
||||
yield()
|
||||
|
||||
assertThat(latest).isEqualTo(TelephonyIcons.NOT_DEFAULT_DATA)
|
||||
assertThat(latest)
|
||||
.isEqualTo(NetworkTypeIconModel.DefaultIcon(TelephonyIcons.NOT_DEFAULT_DATA))
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun overrideIcon_usesCarrierIdOverride() =
|
||||
testScope.runTest {
|
||||
val overrides =
|
||||
mock<MobileIconCarrierIdOverrides>().also {
|
||||
whenever(it.carrierIdEntryExists(anyInt())).thenReturn(true)
|
||||
whenever(it.getOverrideFor(anyInt(), anyString(), any())).thenReturn(1234)
|
||||
}
|
||||
|
||||
underTest = createInteractor(overrides)
|
||||
|
||||
mobileIconsInteractor.defaultDataSubId.value = SUB_1_ID
|
||||
connectionRepository.resolvedNetworkType.value =
|
||||
DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
|
||||
|
||||
var latest: NetworkTypeIconModel? = null
|
||||
val job = underTest.networkTypeIconGroup.onEach { latest = it }.launchIn(this)
|
||||
|
||||
assertThat(latest)
|
||||
.isEqualTo(NetworkTypeIconModel.OverriddenIcon(TelephonyIcons.THREE_G, 1234))
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun alwaysShowDataRatIcon_matchesParent() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -284,7 +306,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun alwaysUseCdmaLevel_matchesParent() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -299,7 +321,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun test_isDefaultDataEnabled_matchesParent() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.isDefaultDataEnabled.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -314,7 +336,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun test_isDefaultConnectionFailed_matchedParent() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
val job = underTest.isDefaultConnectionFailed.launchIn(this)
|
||||
|
||||
mobileIconsInteractor.isDefaultConnectionFailed.value = false
|
||||
@@ -328,12 +350,11 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun dataState_connected() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.isDataConnected.onEach { latest = it }.launchIn(this)
|
||||
|
||||
connectionRepository.dataConnectionState.value = DataConnectionState.Connected
|
||||
yield()
|
||||
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
@@ -342,7 +363,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun dataState_notConnected() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.isDataConnected.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -355,7 +376,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `isInService - uses repository value`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.isInService.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -372,19 +393,17 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `roaming - is gsm - uses connection model`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
|
||||
|
||||
connectionRepository.cdmaRoaming.value = true
|
||||
connectionRepository.isGsm.value = true
|
||||
connectionRepository.isRoaming.value = false
|
||||
yield()
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
|
||||
connectionRepository.isRoaming.value = true
|
||||
yield()
|
||||
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
@@ -393,21 +412,19 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `roaming - is cdma - uses cdma roaming bit`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
|
||||
|
||||
connectionRepository.cdmaRoaming.value = false
|
||||
connectionRepository.isGsm.value = false
|
||||
connectionRepository.isRoaming.value = true
|
||||
yield()
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
|
||||
connectionRepository.cdmaRoaming.value = true
|
||||
connectionRepository.isGsm.value = false
|
||||
connectionRepository.isRoaming.value = false
|
||||
yield()
|
||||
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
@@ -416,7 +433,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `roaming - false while carrierNetworkChangeActive`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -424,13 +441,11 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
connectionRepository.isGsm.value = false
|
||||
connectionRepository.isRoaming.value = true
|
||||
connectionRepository.carrierNetworkChangeActive.value = true
|
||||
yield()
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
|
||||
connectionRepository.cdmaRoaming.value = true
|
||||
connectionRepository.isGsm.value = true
|
||||
yield()
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
|
||||
@@ -439,7 +454,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `network name - uses operatorAlphaShot when non null and repo is default`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: NetworkNameModel? = null
|
||||
val job = underTest.networkName.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -448,20 +463,17 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
// Default network name, operator name is non-null, uses the operator name
|
||||
connectionRepository.networkName.value = DEFAULT_NAME
|
||||
connectionRepository.operatorAlphaShort.value = testOperatorName
|
||||
yield()
|
||||
|
||||
assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived(testOperatorName))
|
||||
|
||||
// Default network name, operator name is null, uses the default
|
||||
connectionRepository.operatorAlphaShort.value = null
|
||||
yield()
|
||||
|
||||
assertThat(latest).isEqualTo(DEFAULT_NAME)
|
||||
|
||||
// Derived network name, operator name non-null, uses the derived name
|
||||
connectionRepository.networkName.value = DERIVED_NAME
|
||||
connectionRepository.operatorAlphaShort.value = testOperatorName
|
||||
yield()
|
||||
|
||||
assertThat(latest).isEqualTo(DERIVED_NAME)
|
||||
|
||||
@@ -470,7 +482,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun isForceHidden_matchesParent() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
testScope.runTest {
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -483,9 +495,26 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val IMMEDIATE = Dispatchers.Main.immediate
|
||||
private fun createInteractor(
|
||||
overrides: MobileIconCarrierIdOverrides = MobileIconCarrierIdOverridesImpl()
|
||||
) =
|
||||
MobileIconInteractorImpl(
|
||||
testScope.backgroundScope,
|
||||
mobileIconsInteractor.activeDataConnectionHasDataEnabled,
|
||||
mobileIconsInteractor.alwaysShowDataRatIcon,
|
||||
mobileIconsInteractor.alwaysUseCdmaLevel,
|
||||
mobileIconsInteractor.mobileIsDefault,
|
||||
mobileIconsInteractor.defaultMobileIconMapping,
|
||||
mobileIconsInteractor.defaultMobileIconGroup,
|
||||
mobileIconsInteractor.defaultDataSubId,
|
||||
mobileIconsInteractor.isDefaultConnectionFailed,
|
||||
mobileIconsInteractor.isForceHidden,
|
||||
connectionRepository,
|
||||
context,
|
||||
overrides,
|
||||
)
|
||||
|
||||
companion object {
|
||||
private const val GSM_LEVEL = 1
|
||||
private const val CDMA_LEVEL = 2
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
||||
connectivityRepository,
|
||||
userSetupRepository,
|
||||
testScope.backgroundScope,
|
||||
context,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
|
||||
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.domain.interactor.FakeMobileIconInteractor
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.model.NetworkTypeIconModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModelTest.Companion.defaultSignal
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
|
||||
@@ -71,9 +72,9 @@ class LocationBasedMobileIconViewModelTest : SysuiTestCase() {
|
||||
setLevel(1)
|
||||
setIsDefaultDataEnabled(true)
|
||||
setIsFailedConnection(false)
|
||||
setIconGroup(TelephonyIcons.THREE_G)
|
||||
setIsEmergencyOnly(false)
|
||||
setNumberOfLevels(4)
|
||||
networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
|
||||
isDataConnected.value = true
|
||||
}
|
||||
commonImpl =
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.android.systemui.log.table.TableLogBuffer
|
||||
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.domain.interactor.FakeMobileIconInteractor
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.model.NetworkTypeIconModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
|
||||
@@ -77,9 +78,9 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
setLevel(1)
|
||||
setIsDefaultDataEnabled(true)
|
||||
setIsFailedConnection(false)
|
||||
setIconGroup(THREE_G)
|
||||
setIsEmergencyOnly(false)
|
||||
setNumberOfLevels(4)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
isDataConnected.value = true
|
||||
}
|
||||
createAndSetViewModel()
|
||||
@@ -256,7 +257,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
THREE_G.dataType,
|
||||
ContentDescription.Resource(THREE_G.dataContentDescription)
|
||||
)
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
|
||||
var latest: Icon? = null
|
||||
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
|
||||
@@ -269,7 +270,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun networkType_nullWhenDisabled() =
|
||||
testScope.runTest {
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
interactor.setIsDataEnabled(false)
|
||||
var latest: Icon? = null
|
||||
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
|
||||
@@ -282,7 +283,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun networkType_nullWhenFailedConnection() =
|
||||
testScope.runTest {
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
interactor.setIsDataEnabled(true)
|
||||
interactor.setIsFailedConnection(true)
|
||||
var latest: Icon? = null
|
||||
@@ -302,11 +303,11 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
ContentDescription.Resource(THREE_G.dataContentDescription)
|
||||
)
|
||||
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
var latest: Icon? = null
|
||||
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
|
||||
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
assertThat(latest).isEqualTo(initial)
|
||||
|
||||
interactor.isDataConnected.value = false
|
||||
@@ -325,7 +326,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
THREE_G.dataType,
|
||||
ContentDescription.Resource(THREE_G.dataContentDescription)
|
||||
)
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
interactor.setIsDataEnabled(true)
|
||||
var latest: Icon? = null
|
||||
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
|
||||
@@ -343,7 +344,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun networkType_alwaysShow_shownEvenWhenDisabled() =
|
||||
testScope.runTest {
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
interactor.setIsDataEnabled(false)
|
||||
interactor.alwaysShowDataRatIcon.value = true
|
||||
|
||||
@@ -363,7 +364,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun networkType_alwaysShow_shownEvenWhenDisconnected() =
|
||||
testScope.runTest {
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
interactor.isDataConnected.value = false
|
||||
interactor.alwaysShowDataRatIcon.value = true
|
||||
|
||||
@@ -383,7 +384,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun networkType_alwaysShow_shownEvenWhenFailedConnection() =
|
||||
testScope.runTest {
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
interactor.setIsFailedConnection(true)
|
||||
interactor.alwaysShowDataRatIcon.value = true
|
||||
|
||||
@@ -404,7 +405,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
fun networkType_alwaysShow_notShownWhenInvalidDataTypeIcon() =
|
||||
testScope.runTest {
|
||||
// The UNKNOWN icon group doesn't have a valid data type icon ID
|
||||
interactor.setIconGroup(UNKNOWN)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(UNKNOWN)
|
||||
interactor.alwaysShowDataRatIcon.value = true
|
||||
|
||||
var latest: Icon? = null
|
||||
@@ -418,7 +419,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun `network type - alwaysShow - shown when not default`() =
|
||||
testScope.runTest {
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
interactor.mobileIsDefault.value = false
|
||||
interactor.alwaysShowDataRatIcon.value = true
|
||||
|
||||
@@ -438,7 +439,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun `network type - not shown when not default`() =
|
||||
testScope.runTest {
|
||||
interactor.setIconGroup(THREE_G)
|
||||
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
|
||||
interactor.isDataConnected.value = true
|
||||
interactor.mobileIsDefault.value = false
|
||||
|
||||
|
||||
Reference in New Issue
Block a user