Merge changes I508a87e5,Ia71831d4 into udc-dev am: 1d14d28160

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22322303

Change-Id: I0bba26a70c44ed500227f2045fa67bcf5295559e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Evan Laird
2023-04-05 20:52:01 +00:00
committed by Automerger Merge Worker
21 changed files with 356 additions and 165 deletions

View File

@@ -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);
}

View File

@@ -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]"

View File

@@ -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

View File

@@ -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()

View File

@@ -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"
}
}

View File

@@ -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.

View File

@@ -16,15 +16,21 @@
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.TelephonyIcons.NOT_DEFAULT_DATA
import com.android.settingslib.mobile.MobileIconCarrierIdOverrides
import com.android.settingslib.mobile.MobileIconCarrierIdOverridesImpl
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
@@ -34,8 +40,6 @@ import kotlinx.coroutines.flow.StateFlow
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 +80,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:
@@ -119,10 +123,11 @@ class MobileIconInteractorImpl(
override val mobileIsDefault: StateFlow<Boolean>,
defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>,
defaultMobileIconGroup: StateFlow<MobileIconGroup>,
defaultDataSubId: StateFlow<Int>,
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
@@ -130,14 +135,14 @@ class MobileIconInteractorImpl(
override val isDataEnabled: StateFlow<Boolean> = connectionRepository.dataEnabled
private val isDefault =
defaultDataSubId
.mapLatest { connectionRepository.subId == it }
.stateIn(
scope,
SharingStarted.WhileSubscribed(),
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
@@ -157,35 +162,56 @@ 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,
defaultMobileIconGroup,
isDefault,
) { resolvedNetworkType, mapping, defaultGroup, isDefault ->
if (!isDefault) {
return@combine NOT_DEFAULT_DATA
}
) { resolvedNetworkType, mapping, defaultGroup ->
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

View File

@@ -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
@@ -75,9 +76,6 @@ interface MobileIconsInteractor {
/** True if the CDMA level should be preferred over the primary level. */
val alwaysUseCdmaLevel: StateFlow<Boolean>
/** Tracks the subscriptionId set as the default for data connections */
val defaultDataSubId: StateFlow<Int>
/** The icon mapping from network type to [MobileIconGroup] for the default subscription */
val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>
@@ -112,6 +110,7 @@ constructor(
connectivityRepository: ConnectivityRepository,
userSetupRepo: UserSetupRepository,
@Application private val scope: CoroutineScope,
private val context: Context,
) : MobileIconsInteractor {
override val mobileIsDefault = mobileConnectionsRepo.mobileIsDefault
@@ -184,8 +183,6 @@ constructor(
)
.stateIn(scope, SharingStarted.WhileSubscribed(), listOf())
override val defaultDataSubId = mobileConnectionsRepo.defaultDataSubId
/**
* Copied from the old pipeline. We maintain a 2s period of time where we will keep the
* validated bit from the old active network (A) while data is changing to the new one (B).
@@ -282,10 +279,10 @@ constructor(
mobileIsDefault,
defaultMobileIconMapping,
defaultMobileIconGroup,
defaultDataSubId,
isDefaultConnectionFailed,
isForceHidden,
mobileConnectionsRepo.getRepoForSubId(subId),
context,
)
companion object {

View File

@@ -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"
}
}

View File

@@ -146,11 +146,10 @@ constructor(
combine(
iconInteractor.isDataConnected,
iconInteractor.isDataEnabled,
iconInteractor.isDefaultConnectionFailed,
iconInteractor.alwaysShowDataRatIcon,
iconInteractor.mobileIsDefault,
) { dataConnected, dataEnabled, failedConnection, alwaysShow, mobileIsDefault ->
alwaysShow || (dataConnected && dataEnabled && !failedConnection && mobileIsDefault)
) { dataConnected, dataEnabled, alwaysShow, mobileIsDefault ->
alwaysShow || (dataEnabled && dataConnected && mobileIsDefault)
}
.distinctUntilChanged()
.logDiffsForTable(
@@ -167,12 +166,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

View File

@@ -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)

View File

@@ -593,7 +593,6 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
val realRepo =
MobileConnectionRepositoryImpl(
context,
SUB_ID,
defaultNetworkName = NetworkNameModel.Default("default"),
networkNameSeparator = SEP,

View File

@@ -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,

View File

@@ -117,7 +117,6 @@ class MobileConnectionTelephonySmokeTests : SysuiTestCase() {
underTest =
MobileConnectionRepositoryImpl(
context,
SUB_1_ID,
DEFAULT_NAME,
SEP,

View File

@@ -155,7 +155,6 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
connectionFactory =
MobileConnectionRepositoryImpl.Factory(
fakeBroadcastDispatcher,
context = context,
telephonyManager = telephonyManager,
bgDispatcher = IMMEDIATE,
logger = logger,

View File

@@ -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
}

View File

@@ -59,7 +59,6 @@ class FakeMobileIconsInteractor(
override val alwaysShowDataRatIcon = MutableStateFlow(false)
override val alwaysUseCdmaLevel = MutableStateFlow(false)
override val defaultDataSubId = MutableStateFlow(DEFAULT_DATA_SUB_ID)
override val mobileIsDefault = MutableStateFlow(false)

View File

@@ -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,106 @@ 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) {
mobileIconsInteractor.defaultDataSubId.value = SUB_1_ID
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)
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)
// Default data sub id changes to something else
mobileIconsInteractor.defaultDataSubId.value = 123
yield()
assertThat(latest).isEqualTo(TelephonyIcons.NOT_DEFAULT_DATA)
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 +284,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 +299,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 +314,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 +328,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 +341,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 +354,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 +371,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 +390,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 +411,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 +419,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 +432,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 +441,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 +460,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 +473,25 @@ 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.isDefaultConnectionFailed,
mobileIconsInteractor.isForceHidden,
connectionRepository,
context,
overrides,
)
companion object {
private const val GSM_LEVEL = 1
private const val CDMA_LEVEL = 2

View File

@@ -88,6 +88,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
connectivityRepository,
userSetupRepository,
testScope.backgroundScope,
context,
)
}

View File

@@ -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 =

View File

@@ -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)
@@ -267,10 +268,11 @@ class MobileIconViewModelTest : SysuiTestCase() {
}
@Test
fun networkType_nullWhenDisabled() =
fun networkType_null_whenDisabled() =
testScope.runTest {
interactor.setIconGroup(THREE_G)
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
interactor.setIsDataEnabled(false)
interactor.mobileIsDefault.value = true
var latest: Icon? = null
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
@@ -280,15 +282,21 @@ class MobileIconViewModelTest : SysuiTestCase() {
}
@Test
fun networkType_nullWhenFailedConnection() =
fun networkTypeIcon_notNull_whenEnabled() =
testScope.runTest {
interactor.setIconGroup(THREE_G)
val expected =
Icon.Resource(
THREE_G.dataType,
ContentDescription.Resource(THREE_G.dataContentDescription)
)
interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
interactor.setIsDataEnabled(true)
interactor.setIsFailedConnection(true)
interactor.isDataConnected.value = true
interactor.mobileIsDefault.value = true
var latest: Icon? = null
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
assertThat(latest).isNull()
assertThat(latest).isEqualTo(expected)
job.cancel()
}
@@ -302,11 +310,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 +333,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 +351,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 +371,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 +391,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 +412,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 +426,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 +446,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