Merge changes I91b545e9,Iac6ce358 into udc-qpr-dev
* changes: [Status Bar][Wifi] Flip WIFI_TRACKER_LIB_FOR_WIFI_ICON to teamfood. [Status Bar][Wifi] Track secondary networks in TrackerLibRepo.
This commit is contained in:
committed by
Android (Google) Code Review
commit
776e8d0527
@@ -369,7 +369,7 @@ object Flags {
|
||||
|
||||
// TODO(b/292533677): Tracking Bug
|
||||
val WIFI_TRACKER_LIB_FOR_WIFI_ICON =
|
||||
unreleasedFlag(613, "wifi_tracker_lib_for_wifi_icon")
|
||||
unreleasedFlag(613, "wifi_tracker_lib_for_wifi_icon", teamfood = true)
|
||||
|
||||
// TODO(b/293863612): Tracking Bug
|
||||
@JvmField val INCOMPATIBLE_CHARGING_BATTERY_ICON =
|
||||
@@ -378,6 +378,9 @@ object Flags {
|
||||
// TODO(b/293585143): Tracking Bug
|
||||
val INSTANT_TETHER = unreleasedFlag(615, "instant_tether")
|
||||
|
||||
// TODO(b/294588085): Tracking Bug
|
||||
val WIFI_SECONDARY_NETWORKS = unreleasedFlag(617, "wifi_secondary_networks")
|
||||
|
||||
// 700 - dialer/calls
|
||||
// TODO(b/254512734): Tracking Bug
|
||||
val ONGOING_CALL_STATUS_BAR_CHIP = releasedFlag(700, "ongoing_call_status_bar_chip")
|
||||
|
||||
@@ -29,9 +29,18 @@ interface WifiRepository {
|
||||
/** Observable for the current wifi default status. */
|
||||
val isWifiDefault: StateFlow<Boolean>
|
||||
|
||||
/** Observable for the current wifi network. */
|
||||
/** Observable for the current primary wifi network. */
|
||||
val wifiNetwork: StateFlow<WifiNetworkModel>
|
||||
|
||||
/**
|
||||
* Observable for secondary wifi networks (if any). Should specifically exclude the primary
|
||||
* network emitted by [wifiNetwork].
|
||||
*
|
||||
* This isn't used by phones/tablets, which only display the primary network, but may be used by
|
||||
* other variants like Car.
|
||||
*/
|
||||
val secondaryNetworks: StateFlow<List<WifiNetworkModel>>
|
||||
|
||||
/** Observable for the current wifi network activity. */
|
||||
val wifiActivity: StateFlow<DataActivityModel>
|
||||
|
||||
|
||||
@@ -115,6 +115,11 @@ constructor(
|
||||
.flatMapLatest { it.wifiNetwork }
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.wifiNetwork.value)
|
||||
|
||||
override val secondaryNetworks: StateFlow<List<WifiNetworkModel>> =
|
||||
activeRepo
|
||||
.flatMapLatest { it.secondaryNetworks }
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.secondaryNetworks.value)
|
||||
|
||||
override val wifiActivity: StateFlow<DataActivityModel> =
|
||||
activeRepo
|
||||
.flatMapLatest { it.wifiActivity }
|
||||
|
||||
@@ -48,6 +48,9 @@ constructor(
|
||||
private val _wifiNetwork = MutableStateFlow<WifiNetworkModel>(WifiNetworkModel.Inactive)
|
||||
override val wifiNetwork: StateFlow<WifiNetworkModel> = _wifiNetwork
|
||||
|
||||
private val _secondaryNetworks = MutableStateFlow<List<WifiNetworkModel>>(emptyList())
|
||||
override val secondaryNetworks: StateFlow<List<WifiNetworkModel>> = _secondaryNetworks
|
||||
|
||||
private val _wifiActivity =
|
||||
MutableStateFlow(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
|
||||
override val wifiActivity: StateFlow<DataActivityModel> = _wifiActivity
|
||||
|
||||
@@ -43,6 +43,9 @@ class DisabledWifiRepository @Inject constructor() :
|
||||
|
||||
override val wifiNetwork: StateFlow<WifiNetworkModel> = MutableStateFlow(NETWORK).asStateFlow()
|
||||
|
||||
override val secondaryNetworks: StateFlow<List<WifiNetworkModel>> =
|
||||
MutableStateFlow(emptyList<WifiNetworkModel>()).asStateFlow()
|
||||
|
||||
override val wifiActivity: StateFlow<DataActivityModel> =
|
||||
MutableStateFlow(ACTIVITY).asStateFlow()
|
||||
|
||||
|
||||
@@ -56,8 +56,10 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
@@ -216,6 +218,10 @@ constructor(
|
||||
initialValue = WIFI_NETWORK_DEFAULT,
|
||||
)
|
||||
|
||||
// Secondary networks can only be supported by [WifiRepositoryViaTrackerLib].
|
||||
override val secondaryNetworks: StateFlow<List<WifiNetworkModel>> =
|
||||
MutableStateFlow(emptyList<WifiNetworkModel>()).asStateFlow()
|
||||
|
||||
override val wifiActivity: StateFlow<DataActivityModel> =
|
||||
WifiRepositoryHelper.createActivityFlow(
|
||||
wifiManager,
|
||||
|
||||
@@ -93,7 +93,8 @@ constructor(
|
||||
WifiPickerTrackerInfo(
|
||||
state = WIFI_STATE_DEFAULT,
|
||||
isDefault = false,
|
||||
network = WIFI_NETWORK_DEFAULT,
|
||||
primaryNetwork = WIFI_NETWORK_DEFAULT,
|
||||
secondaryNetworks = emptyList(),
|
||||
)
|
||||
callbackFlow {
|
||||
val callback =
|
||||
@@ -102,6 +103,17 @@ constructor(
|
||||
val connectedEntry = wifiPickerTracker?.connectedWifiEntry
|
||||
logOnWifiEntriesChanged(connectedEntry)
|
||||
|
||||
val secondaryNetworks =
|
||||
if (featureFlags.isEnabled(Flags.WIFI_SECONDARY_NETWORKS)) {
|
||||
val activeNetworks =
|
||||
wifiPickerTracker?.activeWifiEntries ?: emptyList()
|
||||
activeNetworks
|
||||
.filter { it != connectedEntry && !it.isPrimaryNetwork }
|
||||
.map { it.toWifiNetworkModel() }
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
// [WifiPickerTracker.connectedWifiEntry] will return the same instance
|
||||
// but with updated internals. For example, when its validation status
|
||||
// changes from false to true, the same instance is re-used but with the
|
||||
@@ -112,8 +124,9 @@ constructor(
|
||||
// into our internal model immediately. [toWifiNetworkModel] always
|
||||
// returns a new instance, so the flow is guaranteed to emit.
|
||||
send(
|
||||
newNetwork = connectedEntry?.toWifiNetworkModel()
|
||||
newPrimaryNetwork = connectedEntry?.toPrimaryWifiNetworkModel()
|
||||
?: WIFI_NETWORK_DEFAULT,
|
||||
newSecondaryNetworks = secondaryNetworks,
|
||||
newIsDefault = connectedEntry?.isDefaultNetwork ?: false,
|
||||
)
|
||||
}
|
||||
@@ -131,9 +144,17 @@ constructor(
|
||||
private fun send(
|
||||
newState: Int = current.state,
|
||||
newIsDefault: Boolean = current.isDefault,
|
||||
newNetwork: WifiNetworkModel = current.network,
|
||||
newPrimaryNetwork: WifiNetworkModel = current.primaryNetwork,
|
||||
newSecondaryNetworks: List<WifiNetworkModel> =
|
||||
current.secondaryNetworks,
|
||||
) {
|
||||
val new = WifiPickerTrackerInfo(newState, newIsDefault, newNetwork)
|
||||
val new =
|
||||
WifiPickerTrackerInfo(
|
||||
newState,
|
||||
newIsDefault,
|
||||
newPrimaryNetwork,
|
||||
newSecondaryNetworks,
|
||||
)
|
||||
current = new
|
||||
trySend(new)
|
||||
}
|
||||
@@ -170,7 +191,7 @@ constructor(
|
||||
|
||||
override val wifiNetwork: StateFlow<WifiNetworkModel> =
|
||||
wifiPickerTrackerInfo
|
||||
.map { it.network }
|
||||
.map { it.primaryNetwork }
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTrackerLibTableLogBuffer,
|
||||
@@ -179,11 +200,32 @@ constructor(
|
||||
)
|
||||
.stateIn(scope, SharingStarted.Eagerly, WIFI_NETWORK_DEFAULT)
|
||||
|
||||
override val secondaryNetworks: StateFlow<List<WifiNetworkModel>> =
|
||||
wifiPickerTrackerInfo
|
||||
.map { it.secondaryNetworks }
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTrackerLibTableLogBuffer,
|
||||
columnPrefix = "",
|
||||
columnName = "secondaryNetworks",
|
||||
initialValue = emptyList(),
|
||||
)
|
||||
.stateIn(scope, SharingStarted.Eagerly, emptyList())
|
||||
|
||||
/**
|
||||
* Converts WifiTrackerLib's [WifiEntry] into our internal model only if the entry is the
|
||||
* primary network. Returns an inactive network if it's not primary.
|
||||
*/
|
||||
private fun WifiEntry.toPrimaryWifiNetworkModel(): WifiNetworkModel {
|
||||
return if (!this.isPrimaryNetwork) {
|
||||
WIFI_NETWORK_DEFAULT
|
||||
} else {
|
||||
this.toWifiNetworkModel()
|
||||
}
|
||||
}
|
||||
|
||||
/** Converts WifiTrackerLib's [WifiEntry] into our internal model. */
|
||||
private fun WifiEntry.toWifiNetworkModel(): WifiNetworkModel {
|
||||
if (!this.isPrimaryNetwork) {
|
||||
return WIFI_NETWORK_DEFAULT
|
||||
}
|
||||
return if (this is MergedCarrierEntry) {
|
||||
this.convertCarrierMergedToModel()
|
||||
} else {
|
||||
@@ -291,7 +333,9 @@ constructor(
|
||||
/** True if wifi is currently the default connection and false otherwise. */
|
||||
val isDefault: Boolean,
|
||||
/** The currently primary wifi network. */
|
||||
val network: WifiNetworkModel,
|
||||
val primaryNetwork: WifiNetworkModel,
|
||||
/** The current secondary network(s), if any. Specifically excludes the primary network. */
|
||||
val secondaryNetworks: List<WifiNetworkModel>
|
||||
)
|
||||
|
||||
@SysUISingleton
|
||||
|
||||
@@ -34,6 +34,8 @@ class FakeWifiRepository : WifiRepository {
|
||||
MutableStateFlow(WifiNetworkModel.Inactive)
|
||||
override val wifiNetwork: StateFlow<WifiNetworkModel> = _wifiNetwork
|
||||
|
||||
override val secondaryNetworks = MutableStateFlow<List<WifiNetworkModel>>(emptyList())
|
||||
|
||||
private val _wifiActivity = MutableStateFlow(ACTIVITY_DEFAULT)
|
||||
override val wifiActivity: StateFlow<DataActivityModel> = _wifiActivity
|
||||
|
||||
|
||||
@@ -1003,6 +1003,27 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
assertThat(latest2Active.ssid).isEqualTo(SSID)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_alwaysEmpty() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
// Even WHEN we do have non-primary wifi info
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
whenever(this.ssid).thenReturn(SSID)
|
||||
whenever(this.isPrimary).thenReturn(false)
|
||||
}
|
||||
val network = mock<Network>().apply { whenever(this.getNetId()).thenReturn(NETWORK_ID) }
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(network, createWifiNetworkCapabilities(wifiInfo))
|
||||
|
||||
// THEN the secondary networks list is empty because this repo doesn't support it
|
||||
assertThat(latest).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_inactiveNetwork_false() =
|
||||
testScope.runTest {
|
||||
|
||||
@@ -101,6 +101,7 @@ class WifiRepositoryViaTrackerLibTest : SysuiTestCase() {
|
||||
@Before
|
||||
fun setUp() {
|
||||
featureFlags.set(Flags.INSTANT_TETHER, false)
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, false)
|
||||
whenever(wifiPickerTrackerFactory.create(any(), capture(callbackCaptor)))
|
||||
.thenReturn(wifiPickerTracker)
|
||||
}
|
||||
@@ -762,6 +763,197 @@ class WifiRepositoryViaTrackerLibTest : SysuiTestCase() {
|
||||
assertThat(latest2Active.ssid).isEqualTo(TITLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_activeEntriesEmpty_isEmpty() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf())
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_oneActiveEntry_hasOne() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
val wifiEntry = mock<WifiEntry>()
|
||||
whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(wifiEntry))
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).hasSize(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_multipleActiveEntries_hasMultiple() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
val wifiEntry1 = mock<WifiEntry>()
|
||||
val wifiEntry2 = mock<WifiEntry>()
|
||||
whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(wifiEntry1, wifiEntry2))
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).hasSize(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_mapsToInactive() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
val inactiveEntry =
|
||||
mock<WifiEntry>().apply { whenever(this.level).thenReturn(WIFI_LEVEL_UNREACHABLE) }
|
||||
whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(inactiveEntry))
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).hasSize(1)
|
||||
assertThat(latest!![0]).isInstanceOf(WifiNetworkModel.Inactive::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_mapsToActive() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
val activeEntry = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
|
||||
whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(activeEntry))
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).hasSize(1)
|
||||
assertThat(latest!![0]).isInstanceOf(WifiNetworkModel.Active::class.java)
|
||||
assertThat((latest!![0] as WifiNetworkModel.Active).level).isEqualTo(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_mapsToCarrierMerged() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
val carrierMergedEntry =
|
||||
mock<MergedCarrierEntry>().apply { whenever(this.level).thenReturn(3) }
|
||||
whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(carrierMergedEntry))
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).hasSize(1)
|
||||
assertThat(latest!![0]).isInstanceOf(WifiNetworkModel.CarrierMerged::class.java)
|
||||
assertThat((latest!![0] as WifiNetworkModel.CarrierMerged).level).isEqualTo(3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_mapsMultipleInOrder() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
val activeEntry = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
|
||||
val carrierMergedEntry =
|
||||
mock<MergedCarrierEntry>().apply { whenever(this.level).thenReturn(3) }
|
||||
whenever(wifiPickerTracker.activeWifiEntries)
|
||||
.thenReturn(listOf(activeEntry, carrierMergedEntry))
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest!![0]).isInstanceOf(WifiNetworkModel.Active::class.java)
|
||||
assertThat((latest!![0] as WifiNetworkModel.Active).level).isEqualTo(2)
|
||||
assertThat(latest!![1]).isInstanceOf(WifiNetworkModel.CarrierMerged::class.java)
|
||||
assertThat((latest!![1] as WifiNetworkModel.CarrierMerged).level).isEqualTo(3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_filtersOutConnectedEntry() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
val connectedEntry = mock<WifiEntry>().apply { whenever(this.level).thenReturn(1) }
|
||||
val secondaryEntry1 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
|
||||
val secondaryEntry2 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(3) }
|
||||
// WHEN the active list has both a primary and secondary networks
|
||||
whenever(wifiPickerTracker.activeWifiEntries)
|
||||
.thenReturn(listOf(connectedEntry, secondaryEntry1, secondaryEntry2))
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(connectedEntry)
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
// THEN only the secondary networks are included
|
||||
assertThat(latest).hasSize(2)
|
||||
assertThat((latest!![0] as WifiNetworkModel.Active).level).isEqualTo(2)
|
||||
assertThat((latest!![1] as WifiNetworkModel.Active).level).isEqualTo(3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_noConnectedEntry_hasAllActiveEntries() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
val secondaryEntry1 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
|
||||
val secondaryEntry2 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(3) }
|
||||
whenever(wifiPickerTracker.activeWifiEntries)
|
||||
.thenReturn(listOf(secondaryEntry1, secondaryEntry2))
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).hasSize(2)
|
||||
assertThat((latest!![0] as WifiNetworkModel.Active).level).isEqualTo(2)
|
||||
assertThat((latest!![1] as WifiNetworkModel.Active).level).isEqualTo(3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_filtersOutPrimaryNetwork() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
val primaryEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.level).thenReturn(1)
|
||||
}
|
||||
val secondaryEntry1 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
|
||||
val secondaryEntry2 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(3) }
|
||||
// WHEN the active list has both a primary and secondary networks
|
||||
whenever(wifiPickerTracker.activeWifiEntries)
|
||||
.thenReturn(listOf(secondaryEntry1, primaryEntry, secondaryEntry2))
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
// THEN only the secondary networks are included
|
||||
assertThat(latest).hasSize(2)
|
||||
assertThat((latest!![0] as WifiNetworkModel.Active).level).isEqualTo(2)
|
||||
assertThat((latest!![1] as WifiNetworkModel.Active).level).isEqualTo(3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secondaryNetworks_flagOff_noNetworks() =
|
||||
testScope.runTest {
|
||||
featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, false)
|
||||
val latest by collectLastValue(underTest.secondaryNetworks)
|
||||
|
||||
val wifiEntry = mock<WifiEntry>()
|
||||
whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(wifiEntry))
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_inactiveNetwork_false() =
|
||||
testScope.runTest {
|
||||
|
||||
Reference in New Issue
Block a user