[Status bar refactor] Add Roaming to the mobile pipeline am: 2856487c83

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

Change-Id: I38f9be6bf523783a8e76d615f66f0a654054ca20
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Evan Laird
2022-12-20 23:14:06 +00:00
committed by Automerger Merge Worker
16 changed files with 247 additions and 5 deletions

View File

@@ -41,6 +41,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionS
data class MobileConnectionModel( data class MobileConnectionModel(
/** From [ServiceStateListener.onServiceStateChanged] */ /** From [ServiceStateListener.onServiceStateChanged] */
val isEmergencyOnly: Boolean = false, val isEmergencyOnly: Boolean = false,
val isRoaming: Boolean = false,
/** From [SignalStrengthsListener.onSignalStrengthsChanged] */ /** From [SignalStrengthsListener.onSignalStrengthsChanged] */
val isGsm: Boolean = false, val isGsm: Boolean = false,

View File

@@ -50,4 +50,12 @@ interface MobileConnectionRepository {
* [SubscriptionManager.getDefaultDataSubscriptionId] * [SubscriptionManager.getDefaultDataSubscriptionId]
*/ */
val isDefaultDataSubscription: StateFlow<Boolean> val isDefaultDataSubscription: StateFlow<Boolean>
/**
* See [TelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber]. This bit only matters if
* the connection type is CDMA.
*
* True if the Enhanced Roaming Indicator (ERI) display number is not [TelephonyManager.ERI_OFF]
*/
val cdmaRoaming: StateFlow<Boolean>
} }

View File

@@ -186,6 +186,7 @@ constructor(
connection.dataEnabled.value = true connection.dataEnabled.value = true
connection.isDefaultDataSubscription.value = state.dataType != null connection.isDefaultDataSubscription.value = state.dataType != null
connection.cdmaRoaming.value = state.roaming
connection.connectionInfo.value = state.toMobileConnectionModel() connection.connectionInfo.value = state.toMobileConnectionModel()
} }
@@ -229,6 +230,7 @@ constructor(
private fun Mobile.toMobileConnectionModel(): MobileConnectionModel { private fun Mobile.toMobileConnectionModel(): MobileConnectionModel {
return MobileConnectionModel( return MobileConnectionModel(
isEmergencyOnly = false, // TODO(b/261029387): not yet supported isEmergencyOnly = false, // TODO(b/261029387): not yet supported
isRoaming = roaming,
isGsm = false, // TODO(b/261029387): not yet supported isGsm = false, // TODO(b/261029387): not yet supported
cdmaLevel = level ?: 0, cdmaLevel = level ?: 0,
primaryLevel = level ?: 0, primaryLevel = level ?: 0,
@@ -260,4 +262,6 @@ class DemoMobileConnectionRepository(override val subId: Int) : MobileConnection
override val dataEnabled = MutableStateFlow(true) override val dataEnabled = MutableStateFlow(true)
override val isDefaultDataSubscription = MutableStateFlow(true) override val isDefaultDataSubscription = MutableStateFlow(true)
override val cdmaRoaming = MutableStateFlow(false)
} }

View File

@@ -98,6 +98,7 @@ constructor(
val inflateStrength = getString("inflate")?.toBoolean() val inflateStrength = getString("inflate")?.toBoolean()
val activity = getString("activity")?.toActivity() val activity = getString("activity")?.toActivity()
val carrierNetworkChange = getString("carriernetworkchange") == "show" val carrierNetworkChange = getString("carriernetworkchange") == "show"
val roaming = getString("roam") == "show"
return Mobile( return Mobile(
level = level, level = level,
@@ -107,6 +108,7 @@ constructor(
inflateStrength = inflateStrength, inflateStrength = inflateStrength,
activity = activity, activity = activity,
carrierNetworkChange = carrierNetworkChange, carrierNetworkChange = carrierNetworkChange,
roaming = roaming,
) )
} }
} }

View File

@@ -34,6 +34,7 @@ sealed interface FakeNetworkEventModel {
val inflateStrength: Boolean?, val inflateStrength: Boolean?,
@DataActivityType val activity: Int?, @DataActivityType val activity: Int?,
val carrierNetworkChange: Boolean, val carrierNetworkChange: Boolean,
val roaming: Boolean,
) : FakeNetworkEventModel ) : FakeNetworkEventModel
data class MobileDisabled( data class MobileDisabled(

View File

@@ -27,6 +27,7 @@ import android.telephony.TelephonyCallback
import android.telephony.TelephonyDisplayInfo import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import android.telephony.TelephonyManager.ERI_OFF
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
@@ -95,7 +96,11 @@ class MobileConnectionRepositoryImpl(
TelephonyCallback.CarrierNetworkListener, TelephonyCallback.CarrierNetworkListener,
TelephonyCallback.DisplayInfoListener { TelephonyCallback.DisplayInfoListener {
override fun onServiceStateChanged(serviceState: ServiceState) { override fun onServiceStateChanged(serviceState: ServiceState) {
state = state.copy(isEmergencyOnly = serviceState.isEmergencyOnly) state =
state.copy(
isEmergencyOnly = serviceState.isEmergencyOnly,
isRoaming = serviceState.roaming,
)
trySend(state) trySend(state)
} }
@@ -208,6 +213,11 @@ class MobileConnectionRepositoryImpl(
globalMobileDataSettingChangedEvent, globalMobileDataSettingChangedEvent,
) )
override val cdmaRoaming: StateFlow<Boolean> =
telephonyPollingEvent
.mapLatest { telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber != ERI_OFF }
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
override val dataEnabled: StateFlow<Boolean> = override val dataEnabled: StateFlow<Boolean> =
telephonyPollingEvent telephonyPollingEvent
.mapLatest { dataConnectionAllowed() } .mapLatest { dataConnectionAllowed() }

View File

@@ -54,6 +54,13 @@ interface MobileIconInteractor {
/** True if this line of service is emergency-only */ /** True if this line of service is emergency-only */
val isEmergencyOnly: StateFlow<Boolean> val isEmergencyOnly: StateFlow<Boolean>
/**
* True if this connection is considered roaming. The roaming bit can come from [ServiceState],
* or directly from the telephony manager's CDMA ERI number value. Note that we don't consider a
* connection to be roaming while carrier network change is active
*/
val isRoaming: StateFlow<Boolean>
/** Int describing the connection strength. 0-4 OR 1-5. See [numberOfLevels] */ /** Int describing the connection strength. 0-4 OR 1-5. See [numberOfLevels] */
val level: StateFlow<Int> val level: StateFlow<Int>
@@ -95,6 +102,18 @@ class MobileIconInteractorImpl(
.mapLatest { it.isEmergencyOnly } .mapLatest { it.isEmergencyOnly }
.stateIn(scope, SharingStarted.WhileSubscribed(), false) .stateIn(scope, SharingStarted.WhileSubscribed(), false)
override val isRoaming: StateFlow<Boolean> =
combine(connectionInfo, connectionRepository.cdmaRoaming) { connection, cdmaRoaming ->
if (connection.carrierNetworkChangeActive) {
false
} else if (connection.isGsm) {
connection.isRoaming
} else {
cdmaRoaming
}
}
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
override val level: StateFlow<Int> = override val level: StateFlow<Int> =
connectionInfo connectionInfo
.mapLatest { connection -> .mapLatest { connection ->

View File

@@ -21,6 +21,7 @@ import android.view.View.GONE
import android.view.View.VISIBLE import android.view.View.VISIBLE
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.Space
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
@@ -29,7 +30,6 @@ import com.android.systemui.R
import com.android.systemui.common.ui.binder.IconViewBinder import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModel import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -43,6 +43,8 @@ object MobileIconBinder {
val networkTypeView = view.requireViewById<ImageView>(R.id.mobile_type) val networkTypeView = view.requireViewById<ImageView>(R.id.mobile_type)
val iconView = view.requireViewById<ImageView>(R.id.mobile_signal) val iconView = view.requireViewById<ImageView>(R.id.mobile_signal)
val mobileDrawable = SignalDrawable(view.context).also { iconView.setImageDrawable(it) } val mobileDrawable = SignalDrawable(view.context).also { iconView.setImageDrawable(it) }
val roamingView = view.requireViewById<ImageView>(R.id.mobile_roaming)
val roamingSpace = view.requireViewById<Space>(R.id.mobile_roaming_space)
view.isVisible = true view.isVisible = true
iconView.isVisible = true iconView.isVisible = true
@@ -64,12 +66,21 @@ object MobileIconBinder {
} }
} }
// Set the roaming indicator
launch {
viewModel.roaming.distinctUntilChanged().collect { isRoaming ->
roamingView.isVisible = isRoaming
roamingSpace.isVisible = isRoaming
}
}
// Set the tint // Set the tint
launch { launch {
viewModel.tint.collect { tint -> viewModel.tint.collect { tint ->
val tintList = ColorStateList.valueOf(tint) val tintList = ColorStateList.valueOf(tint)
iconView.imageTintList = tintList iconView.imageTintList = tintList
networkTypeView.imageTintList = tintList networkTypeView.imageTintList = tintList
roamingView.imageTintList = tintList
} }
} }
} }

View File

@@ -87,5 +87,7 @@ constructor(
} }
} }
val roaming: Flow<Boolean> = iconInteractor.isRoaming
val tint: Flow<Int> = flowOf(Color.CYAN) val tint: Flow<Int> = flowOf(Color.CYAN)
} }

View File

@@ -30,6 +30,8 @@ class FakeMobileConnectionRepository(override val subId: Int) : MobileConnection
private val _isDefaultDataSubscription = MutableStateFlow(true) private val _isDefaultDataSubscription = MutableStateFlow(true)
override val isDefaultDataSubscription = _isDefaultDataSubscription override val isDefaultDataSubscription = _isDefaultDataSubscription
override val cdmaRoaming = MutableStateFlow(false)
fun setConnectionInfo(model: MobileConnectionModel) { fun setConnectionInfo(model: MobileConnectionModel) {
_connectionInfo.value = model _connectionInfo.value = model
} }

View File

@@ -95,6 +95,7 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
inflateStrength = testCase.inflateStrength, inflateStrength = testCase.inflateStrength,
activity = testCase.activity, activity = testCase.activity,
carrierNetworkChange = testCase.carrierNetworkChange, carrierNetworkChange = testCase.carrierNetworkChange,
roaming = testCase.roaming,
) )
fakeNetworkEventFlow.value = networkModel fakeNetworkEventFlow.value = networkModel
@@ -116,6 +117,7 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
assertThat(connectionInfo.dataActivityDirection).isEqualTo(model.activity) assertThat(connectionInfo.dataActivityDirection).isEqualTo(model.activity)
assertThat(connectionInfo.carrierNetworkChangeActive) assertThat(connectionInfo.carrierNetworkChangeActive)
.isEqualTo(model.carrierNetworkChange) .isEqualTo(model.carrierNetworkChange)
assertThat(connectionInfo.isRoaming).isEqualTo(model.roaming)
// TODO(b/261029387): check these once we start handling them // TODO(b/261029387): check these once we start handling them
assertThat(connectionInfo.isEmergencyOnly).isFalse() assertThat(connectionInfo.isEmergencyOnly).isFalse()
@@ -138,6 +140,7 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
val inflateStrength: Boolean, val inflateStrength: Boolean,
@Annotation.DataActivityType val activity: Int, @Annotation.DataActivityType val activity: Int,
val carrierNetworkChange: Boolean, val carrierNetworkChange: Boolean,
val roaming: Boolean,
) { ) {
override fun toString(): String { override fun toString(): String {
return "INPUT(level=$level, " + return "INPUT(level=$level, " +
@@ -146,7 +149,8 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
"carrierId=$carrierId, " + "carrierId=$carrierId, " +
"inflateStrength=$inflateStrength, " + "inflateStrength=$inflateStrength, " +
"activity=$activity, " + "activity=$activity, " +
"carrierNetworkChange=$carrierNetworkChange)" "carrierNetworkChange=$carrierNetworkChange, " +
"roaming=$roaming)"
} }
// Convenience for iterating test data and creating new cases // Convenience for iterating test data and creating new cases
@@ -158,6 +162,7 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
inflateStrength: Boolean? = null, inflateStrength: Boolean? = null,
@Annotation.DataActivityType activity: Int? = null, @Annotation.DataActivityType activity: Int? = null,
carrierNetworkChange: Boolean? = null, carrierNetworkChange: Boolean? = null,
roaming: Boolean? = null,
): TestCase = ): TestCase =
TestCase( TestCase(
level = level ?: this.level, level = level ?: this.level,
@@ -166,7 +171,8 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
carrierId = carrierId ?: this.carrierId, carrierId = carrierId ?: this.carrierId,
inflateStrength = inflateStrength ?: this.inflateStrength, inflateStrength = inflateStrength ?: this.inflateStrength,
activity = activity ?: this.activity, activity = activity ?: this.activity,
carrierNetworkChange = carrierNetworkChange ?: this.carrierNetworkChange carrierNetworkChange = carrierNetworkChange ?: this.carrierNetworkChange,
roaming = roaming ?: this.roaming,
) )
} }
@@ -193,6 +199,8 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
TelephonyManager.DATA_ACTIVITY_INOUT TelephonyManager.DATA_ACTIVITY_INOUT
) )
private val carrierNetworkChange = booleanList private val carrierNetworkChange = booleanList
// false first so the base case doesn't have roaming set (more common)
private val roaming = listOf(false, true)
@Parameters(name = "{0}") @JvmStatic fun data() = testData() @Parameters(name = "{0}") @JvmStatic fun data() = testData()
@@ -226,7 +234,8 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
carrierIds.first(), carrierIds.first(),
inflateStrength.first(), inflateStrength.first(),
activity.first(), activity.first(),
carrierNetworkChange.first() carrierNetworkChange.first(),
roaming.first(),
) )
val tail = val tail =
@@ -237,6 +246,7 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
inflateStrength.map { baseCase.modifiedBy(inflateStrength = it) }, inflateStrength.map { baseCase.modifiedBy(inflateStrength = it) },
activity.map { baseCase.modifiedBy(activity = it) }, activity.map { baseCase.modifiedBy(activity = it) },
carrierNetworkChange.map { baseCase.modifiedBy(carrierNetworkChange = it) }, carrierNetworkChange.map { baseCase.modifiedBy(carrierNetworkChange = it) },
roaming.map { baseCase.modifiedBy(roaming = it) }
) )
.flatten() .flatten()

View File

@@ -292,6 +292,7 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
assertThat(connectionInfo.dataActivityDirection).isEqualTo(model.activity) assertThat(connectionInfo.dataActivityDirection).isEqualTo(model.activity)
assertThat(connectionInfo.carrierNetworkChangeActive) assertThat(connectionInfo.carrierNetworkChangeActive)
.isEqualTo(model.carrierNetworkChange) .isEqualTo(model.carrierNetworkChange)
assertThat(connectionInfo.isRoaming).isEqualTo(model.roaming)
// TODO(b/261029387) check these once we start handling them // TODO(b/261029387) check these once we start handling them
assertThat(connectionInfo.isEmergencyOnly).isFalse() assertThat(connectionInfo.isEmergencyOnly).isFalse()
@@ -313,6 +314,7 @@ fun validMobileEvent(
inflateStrength: Boolean? = false, inflateStrength: Boolean? = false,
activity: Int? = null, activity: Int? = null,
carrierNetworkChange: Boolean = false, carrierNetworkChange: Boolean = false,
roaming: Boolean = false,
): FakeNetworkEventModel = ): FakeNetworkEventModel =
FakeNetworkEventModel.Mobile( FakeNetworkEventModel.Mobile(
level = level, level = level,
@@ -322,4 +324,5 @@ fun validMobileEvent(
inflateStrength = inflateStrength, inflateStrength = inflateStrength,
activity = activity, activity = activity,
carrierNetworkChange = carrierNetworkChange, carrierNetworkChange = carrierNetworkChange,
roaming = roaming,
) )

View File

@@ -32,6 +32,8 @@ import android.telephony.TelephonyManager.DATA_CONNECTING
import android.telephony.TelephonyManager.DATA_DISCONNECTED import android.telephony.TelephonyManager.DATA_DISCONNECTED
import android.telephony.TelephonyManager.DATA_DISCONNECTING import android.telephony.TelephonyManager.DATA_DISCONNECTING
import android.telephony.TelephonyManager.DATA_UNKNOWN import android.telephony.TelephonyManager.DATA_UNKNOWN
import android.telephony.TelephonyManager.ERI_OFF
import android.telephony.TelephonyManager.ERI_ON
import android.telephony.TelephonyManager.NETWORK_TYPE_LTE import android.telephony.TelephonyManager.NETWORK_TYPE_LTE
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
@@ -402,6 +404,61 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun `roaming - cdma - queries telephony manager`() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
// Start the telephony collection job so that cdmaRoaming starts updating
val telephonyJob = underTest.connectionInfo.launchIn(this)
val job = underTest.cdmaRoaming.onEach { latest = it }.launchIn(this)
val cb = getTelephonyCallbackForType<ServiceStateListener>()
val serviceState = ServiceState()
serviceState.roaming = false
// CDMA roaming is off, GSM roaming is off
whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF)
cb.onServiceStateChanged(serviceState)
assertThat(latest).isFalse()
// CDMA roaming is off, GSM roaming is on
whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_ON)
cb.onServiceStateChanged(serviceState)
assertThat(latest).isTrue()
telephonyJob.cancel()
job.cancel()
}
@Test
fun `roaming - gsm - queries service state`() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
val job = underTest.connectionInfo.onEach { latest = it.isRoaming }.launchIn(this)
val serviceState = ServiceState()
serviceState.roaming = false
val cb = getTelephonyCallbackForType<ServiceStateListener>()
// CDMA roaming is off, GSM roaming is off
whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF)
cb.onServiceStateChanged(serviceState)
assertThat(latest).isFalse()
// CDMA roaming is off, GSM roaming is on
serviceState.roaming = true
cb.onServiceStateChanged(serviceState)
assertThat(latest).isTrue()
job.cancel()
}
private fun getTelephonyCallbacks(): List<TelephonyCallback> { private fun getTelephonyCallbacks(): List<TelephonyCallback> {
val callbackCaptor = argumentCaptor<TelephonyCallback>() val callbackCaptor = argumentCaptor<TelephonyCallback>()
Mockito.verify(telephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture()) Mockito.verify(telephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture())

View File

@@ -30,6 +30,8 @@ class FakeMobileIconInteractor : MobileIconInteractor {
private val _isEmergencyOnly = MutableStateFlow(false) private val _isEmergencyOnly = MutableStateFlow(false)
override val isEmergencyOnly = _isEmergencyOnly override val isEmergencyOnly = _isEmergencyOnly
override val isRoaming = MutableStateFlow(false)
private val _isFailedConnection = MutableStateFlow(false) private val _isFailedConnection = MutableStateFlow(false)
override val isDefaultConnectionFailed = _isFailedConnection override val isDefaultConnectionFailed = _isFailedConnection

View File

@@ -298,6 +298,100 @@ class MobileIconInteractorTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun `roaming - is gsm - uses connection model`() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
connectionRepository.cdmaRoaming.value = true
connectionRepository.setConnectionInfo(
MobileConnectionModel(
isGsm = true,
isRoaming = false,
)
)
yield()
assertThat(latest).isFalse()
connectionRepository.setConnectionInfo(
MobileConnectionModel(
isGsm = true,
isRoaming = true,
)
)
yield()
assertThat(latest).isTrue()
job.cancel()
}
@Test
fun `roaming - is cdma - uses cdma roaming bit`() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
connectionRepository.cdmaRoaming.value = false
connectionRepository.setConnectionInfo(
MobileConnectionModel(
isGsm = false,
isRoaming = true,
)
)
yield()
assertThat(latest).isFalse()
connectionRepository.cdmaRoaming.value = true
connectionRepository.setConnectionInfo(
MobileConnectionModel(
isGsm = false,
isRoaming = false,
)
)
yield()
assertThat(latest).isTrue()
job.cancel()
}
@Test
fun `roaming - false while carrierNetworkChangeActive`() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
connectionRepository.cdmaRoaming.value = true
connectionRepository.setConnectionInfo(
MobileConnectionModel(
isGsm = false,
isRoaming = true,
carrierNetworkChangeActive = true,
)
)
yield()
assertThat(latest).isFalse()
connectionRepository.cdmaRoaming.value = true
connectionRepository.setConnectionInfo(
MobileConnectionModel(
isGsm = true,
isRoaming = true,
carrierNetworkChangeActive = true,
)
)
yield()
assertThat(latest).isFalse()
job.cancel()
}
companion object { companion object {
private val IMMEDIATE = Dispatchers.Main.immediate private val IMMEDIATE = Dispatchers.Main.immediate

View File

@@ -234,6 +234,22 @@ class MobileIconViewModelTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun roaming() =
runBlocking(IMMEDIATE) {
interactor.isRoaming.value = true
var latest: Boolean? = null
val job = underTest.roaming.onEach { latest = it }.launchIn(this)
assertThat(latest).isTrue()
interactor.isRoaming.value = false
assertThat(latest).isFalse()
job.cancel()
}
/** Convenience constructor for these tests */ /** Convenience constructor for these tests */
private fun defaultSignal( private fun defaultSignal(
level: Int = 1, level: Int = 1,