Merge "Prefer the VCN subscription when filtering for CBRS" into udc-dev am: 541ef6fb00
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22889527 Change-Id: I386a63dc375d58af9a07347ebae7b44d3019e100 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -155,7 +155,8 @@ constructor(
|
|||||||
combine(
|
combine(
|
||||||
unfilteredSubscriptions,
|
unfilteredSubscriptions,
|
||||||
mobileConnectionsRepo.activeMobileDataSubscriptionId,
|
mobileConnectionsRepo.activeMobileDataSubscriptionId,
|
||||||
) { unfilteredSubs, activeId ->
|
connectivityRepository.vcnSubId,
|
||||||
|
) { unfilteredSubs, activeId, vcnSubId ->
|
||||||
// Based on the old logic,
|
// Based on the old logic,
|
||||||
if (unfilteredSubs.size != 2) {
|
if (unfilteredSubs.size != 2) {
|
||||||
return@combine unfilteredSubs
|
return@combine unfilteredSubs
|
||||||
@@ -182,7 +183,13 @@ constructor(
|
|||||||
// return the non-opportunistic info
|
// return the non-opportunistic info
|
||||||
return@combine if (info1.isOpportunistic) listOf(info2) else listOf(info1)
|
return@combine if (info1.isOpportunistic) listOf(info2) else listOf(info1)
|
||||||
} else {
|
} else {
|
||||||
return@combine if (info1.subscriptionId == activeId) {
|
// It's possible for the subId of the VCN to disagree with the active subId in
|
||||||
|
// cases where the system has tried to switch but found no connection. In these
|
||||||
|
// scenarios, VCN will always have the subId that we want to use, so use that
|
||||||
|
// value instead of the activeId reported by telephony
|
||||||
|
val subIdToKeep = vcnSubId ?: activeId
|
||||||
|
|
||||||
|
return@combine if (info1.subscriptionId == subIdToKeep) {
|
||||||
listOf(info1)
|
listOf(info1)
|
||||||
} else {
|
} else {
|
||||||
listOf(info2)
|
listOf(info2)
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ constructor(
|
|||||||
model::messagePrinter,
|
model::messagePrinter,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun logVcnSubscriptionId(subId: Int) {
|
||||||
|
buffer.log(TAG, LogLevel.DEBUG, { int1 = subId }, { "vcnSubId changed: $int1" })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val TAG = "ConnectivityInputLogger"
|
private const val TAG = "ConnectivityInputLogger"
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
|
|||||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||||
import android.net.vcn.VcnTransportInfo
|
import android.net.vcn.VcnTransportInfo
|
||||||
import android.net.wifi.WifiInfo
|
import android.net.wifi.WifiInfo
|
||||||
|
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||||
import androidx.annotation.ArrayRes
|
import androidx.annotation.ArrayRes
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import com.android.systemui.Dumpable
|
import com.android.systemui.Dumpable
|
||||||
@@ -50,10 +51,13 @@ import java.io.PrintWriter
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.flow.shareIn
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +70,16 @@ interface ConnectivityRepository {
|
|||||||
|
|
||||||
/** Observable for which connection(s) are currently default. */
|
/** Observable for which connection(s) are currently default. */
|
||||||
val defaultConnections: StateFlow<DefaultConnectionModel>
|
val defaultConnections: StateFlow<DefaultConnectionModel>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscription ID of the [VcnTransportInfo] for the default connection.
|
||||||
|
*
|
||||||
|
* If the default network has a [VcnTransportInfo], then that transport info contains a subId of
|
||||||
|
* the VCN. When VCN is connected and default, this subId is what SystemUI will care about. In
|
||||||
|
* cases where telephony's activeDataSubscriptionId differs from this value, it is expected to
|
||||||
|
* eventually catch up and reflect what is represented here in the VcnTransportInfo.
|
||||||
|
*/
|
||||||
|
val vcnSubId: StateFlow<Int?>
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
@@ -118,24 +132,13 @@ constructor(
|
|||||||
initialValue = defaultHiddenIcons
|
initialValue = defaultHiddenIcons
|
||||||
)
|
)
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
private val defaultNetworkCapabilities: SharedFlow<NetworkCapabilities?> =
|
||||||
override val defaultConnections: StateFlow<DefaultConnectionModel> =
|
|
||||||
conflatedCallbackFlow {
|
conflatedCallbackFlow {
|
||||||
val callback =
|
val callback =
|
||||||
object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
|
object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
|
||||||
override fun onLost(network: Network) {
|
override fun onLost(network: Network) {
|
||||||
logger.logOnDefaultLost(network)
|
logger.logOnDefaultLost(network)
|
||||||
// The system no longer has a default network, so everything is
|
trySend(null)
|
||||||
// non-default.
|
|
||||||
trySend(
|
|
||||||
DefaultConnectionModel(
|
|
||||||
Wifi(isDefault = false),
|
|
||||||
Mobile(isDefault = false),
|
|
||||||
CarrierMerged(isDefault = false),
|
|
||||||
Ethernet(isDefault = false),
|
|
||||||
isValidated = false,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCapabilitiesChanged(
|
override fun onCapabilitiesChanged(
|
||||||
@@ -143,22 +146,60 @@ constructor(
|
|||||||
networkCapabilities: NetworkCapabilities,
|
networkCapabilities: NetworkCapabilities,
|
||||||
) {
|
) {
|
||||||
logger.logOnDefaultCapabilitiesChanged(network, networkCapabilities)
|
logger.logOnDefaultCapabilitiesChanged(network, networkCapabilities)
|
||||||
|
trySend(networkCapabilities)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connectivityManager.registerDefaultNetworkCallback(callback)
|
||||||
|
|
||||||
|
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
|
||||||
|
}
|
||||||
|
.shareIn(scope, SharingStarted.WhileSubscribed())
|
||||||
|
|
||||||
|
override val vcnSubId: StateFlow<Int?> =
|
||||||
|
defaultNetworkCapabilities
|
||||||
|
.map { networkCapabilities ->
|
||||||
|
networkCapabilities?.run {
|
||||||
|
val subId = (transportInfo as? VcnTransportInfo)?.subId
|
||||||
|
// Never return an INVALID_SUBSCRIPTION_ID (-1)
|
||||||
|
if (subId != INVALID_SUBSCRIPTION_ID) {
|
||||||
|
subId
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.distinctUntilChanged()
|
||||||
|
/* A note for logging: we use -2 here since -1 == INVALID_SUBSCRIPTION_ID */
|
||||||
|
.onEach { logger.logVcnSubscriptionId(it ?: -2) }
|
||||||
|
.stateIn(scope, SharingStarted.Eagerly, null)
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
|
override val defaultConnections: StateFlow<DefaultConnectionModel> =
|
||||||
|
defaultNetworkCapabilities
|
||||||
|
.map { networkCapabilities ->
|
||||||
|
if (networkCapabilities == null) {
|
||||||
|
// The system no longer has a default network, so everything is
|
||||||
|
// non-default.
|
||||||
|
DefaultConnectionModel(
|
||||||
|
Wifi(isDefault = false),
|
||||||
|
Mobile(isDefault = false),
|
||||||
|
CarrierMerged(isDefault = false),
|
||||||
|
Ethernet(isDefault = false),
|
||||||
|
isValidated = false,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
val wifiInfo =
|
val wifiInfo =
|
||||||
networkCapabilities.getMainOrUnderlyingWifiInfo(connectivityManager)
|
networkCapabilities.getMainOrUnderlyingWifiInfo(connectivityManager)
|
||||||
|
|
||||||
val isWifiDefault =
|
val isWifiDefault =
|
||||||
networkCapabilities.hasTransport(TRANSPORT_WIFI) || wifiInfo != null
|
networkCapabilities.hasTransport(TRANSPORT_WIFI) || wifiInfo != null
|
||||||
val isMobileDefault =
|
val isMobileDefault = networkCapabilities.hasTransport(TRANSPORT_CELLULAR)
|
||||||
networkCapabilities.hasTransport(TRANSPORT_CELLULAR)
|
|
||||||
val isCarrierMergedDefault = wifiInfo?.isCarrierMerged == true
|
val isCarrierMergedDefault = wifiInfo?.isCarrierMerged == true
|
||||||
val isEthernetDefault =
|
val isEthernetDefault = networkCapabilities.hasTransport(TRANSPORT_ETHERNET)
|
||||||
networkCapabilities.hasTransport(TRANSPORT_ETHERNET)
|
|
||||||
|
|
||||||
val isValidated =
|
val isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)
|
||||||
networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)
|
|
||||||
|
|
||||||
trySend(
|
|
||||||
DefaultConnectionModel(
|
DefaultConnectionModel(
|
||||||
Wifi(isWifiDefault),
|
Wifi(isWifiDefault),
|
||||||
Mobile(isMobileDefault),
|
Mobile(isMobileDefault),
|
||||||
@@ -166,14 +207,8 @@ constructor(
|
|||||||
Ethernet(isEthernetDefault),
|
Ethernet(isEthernetDefault),
|
||||||
isValidated,
|
isValidated,
|
||||||
)
|
)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connectivityManager.registerDefaultNetworkCallback(callback)
|
|
||||||
|
|
||||||
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
|
|
||||||
}
|
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.onEach { logger.logDefaultConnectionsChanged(it) }
|
.onEach { logger.logDefaultConnectionsChanged(it) }
|
||||||
.stateIn(scope, SharingStarted.Eagerly, DefaultConnectionModel())
|
.stateIn(scope, SharingStarted.Eagerly, DefaultConnectionModel())
|
||||||
|
|||||||
@@ -271,6 +271,52 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun filteredSubscriptions_vcnSubId_agreesWithActiveSubId_usesActiveAkaVcnSub() =
|
||||||
|
testScope.runTest {
|
||||||
|
val (sub1, sub3) =
|
||||||
|
createSubscriptionPair(
|
||||||
|
subscriptionIds = Pair(SUB_1_ID, SUB_3_ID),
|
||||||
|
opportunistic = Pair(true, true),
|
||||||
|
grouped = true,
|
||||||
|
)
|
||||||
|
connectionsRepository.setSubscriptions(listOf(sub1, sub3))
|
||||||
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
||||||
|
connectivityRepository.vcnSubId.value = SUB_3_ID
|
||||||
|
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
||||||
|
.thenReturn(false)
|
||||||
|
|
||||||
|
var latest: List<SubscriptionModel>? = null
|
||||||
|
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(listOf(sub3))
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun filteredSubscriptions_vcnSubId_disagreesWithActiveSubId_usesVcnSub() =
|
||||||
|
testScope.runTest {
|
||||||
|
val (sub1, sub3) =
|
||||||
|
createSubscriptionPair(
|
||||||
|
subscriptionIds = Pair(SUB_1_ID, SUB_3_ID),
|
||||||
|
opportunistic = Pair(true, true),
|
||||||
|
grouped = true,
|
||||||
|
)
|
||||||
|
connectionsRepository.setSubscriptions(listOf(sub1, sub3))
|
||||||
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
||||||
|
connectivityRepository.vcnSubId.value = SUB_1_ID
|
||||||
|
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
||||||
|
.thenReturn(false)
|
||||||
|
|
||||||
|
var latest: List<SubscriptionModel>? = null
|
||||||
|
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(listOf(sub1))
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun activeDataConnection_turnedOn() =
|
fun activeDataConnection_turnedOn() =
|
||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
|
|||||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||||
import android.net.vcn.VcnTransportInfo
|
import android.net.vcn.VcnTransportInfo
|
||||||
import android.net.wifi.WifiInfo
|
import android.net.wifi.WifiInfo
|
||||||
|
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.dump.DumpManager
|
import com.android.systemui.dump.DumpManager
|
||||||
@@ -37,6 +38,7 @@ import com.android.systemui.statusbar.pipeline.shared.data.repository.Connectivi
|
|||||||
import com.android.systemui.tuner.TunerService
|
import com.android.systemui.tuner.TunerService
|
||||||
import com.android.systemui.util.mockito.any
|
import com.android.systemui.util.mockito.any
|
||||||
import com.android.systemui.util.mockito.argumentCaptor
|
import com.android.systemui.util.mockito.argumentCaptor
|
||||||
|
import com.android.systemui.util.mockito.eq
|
||||||
import com.android.systemui.util.mockito.mock
|
import com.android.systemui.util.mockito.mock
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
@@ -654,6 +656,139 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun vcnSubId_initiallyNull() {
|
||||||
|
assertThat(underTest.vcnSubId.value).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun vcnSubId_tracksVcnTransportInfo() =
|
||||||
|
testScope.runTest {
|
||||||
|
val vcnInfo = VcnTransportInfo(SUB_1_ID)
|
||||||
|
|
||||||
|
var latest: Int? = null
|
||||||
|
val job = underTest.vcnSubId.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
val capabilities =
|
||||||
|
mock<NetworkCapabilities>().also {
|
||||||
|
whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
|
||||||
|
whenever(it.transportInfo).thenReturn(vcnInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(SUB_1_ID)
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun vcnSubId_filersOutInvalid() =
|
||||||
|
testScope.runTest {
|
||||||
|
val vcnInfo = VcnTransportInfo(INVALID_SUBSCRIPTION_ID)
|
||||||
|
|
||||||
|
var latest: Int? = null
|
||||||
|
val job = underTest.vcnSubId.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
val capabilities =
|
||||||
|
mock<NetworkCapabilities>().also {
|
||||||
|
whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
|
||||||
|
whenever(it.transportInfo).thenReturn(vcnInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||||
|
|
||||||
|
assertThat(latest).isNull()
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun vcnSubId_nullIfNoTransportInfo() =
|
||||||
|
testScope.runTest {
|
||||||
|
var latest: Int? = null
|
||||||
|
val job = underTest.vcnSubId.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
val capabilities =
|
||||||
|
mock<NetworkCapabilities>().also {
|
||||||
|
whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
|
||||||
|
whenever(it.transportInfo).thenReturn(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||||
|
|
||||||
|
assertThat(latest).isNull()
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun vcnSubId_nullIfVcnInfoIsNotCellular() =
|
||||||
|
testScope.runTest {
|
||||||
|
// If the underlying network of the VCN is a WiFi network, then there is no subId that
|
||||||
|
// could disagree with telephony's active data subscription id.
|
||||||
|
|
||||||
|
var latest: Int? = null
|
||||||
|
val job = underTest.vcnSubId.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
val wifiInfo = mock<WifiInfo>()
|
||||||
|
val vcnInfo = VcnTransportInfo(wifiInfo)
|
||||||
|
val capabilities =
|
||||||
|
mock<NetworkCapabilities>().also {
|
||||||
|
whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
|
||||||
|
whenever(it.transportInfo).thenReturn(vcnInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||||
|
|
||||||
|
assertThat(latest).isNull()
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun vcnSubId_changingVcnInfoIsTracked() =
|
||||||
|
testScope.runTest {
|
||||||
|
var latest: Int? = null
|
||||||
|
val job = underTest.vcnSubId.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
val wifiInfo = mock<WifiInfo>()
|
||||||
|
val wifiVcnInfo = VcnTransportInfo(wifiInfo)
|
||||||
|
val sub1VcnInfo = VcnTransportInfo(SUB_1_ID)
|
||||||
|
val sub2VcnInfo = VcnTransportInfo(SUB_2_ID)
|
||||||
|
|
||||||
|
val capabilities =
|
||||||
|
mock<NetworkCapabilities>().also {
|
||||||
|
whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
|
||||||
|
whenever(it.transportInfo).thenReturn(wifiVcnInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WIFI VCN info
|
||||||
|
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||||
|
|
||||||
|
assertThat(latest).isNull()
|
||||||
|
|
||||||
|
// Cellular VCN info with subId 1
|
||||||
|
whenever(capabilities.hasTransport(eq(TRANSPORT_CELLULAR))).thenReturn(true)
|
||||||
|
whenever(capabilities.transportInfo).thenReturn(sub1VcnInfo)
|
||||||
|
|
||||||
|
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(SUB_1_ID)
|
||||||
|
|
||||||
|
// Cellular VCN info with subId 2
|
||||||
|
whenever(capabilities.transportInfo).thenReturn(sub2VcnInfo)
|
||||||
|
|
||||||
|
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(SUB_2_ID)
|
||||||
|
|
||||||
|
// No VCN anymore
|
||||||
|
whenever(capabilities.transportInfo).thenReturn(null)
|
||||||
|
|
||||||
|
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||||
|
|
||||||
|
assertThat(latest).isNull()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getMainOrUnderlyingWifiInfo_wifi_hasInfo() {
|
fun getMainOrUnderlyingWifiInfo_wifi_hasInfo() {
|
||||||
val wifiInfo = mock<WifiInfo>()
|
val wifiInfo = mock<WifiInfo>()
|
||||||
@@ -964,6 +1099,9 @@ class ConnectivityRepositoryImplTest : SysuiTestCase() {
|
|||||||
private const val SLOT_WIFI = "wifi"
|
private const val SLOT_WIFI = "wifi"
|
||||||
private const val SLOT_MOBILE = "mobile"
|
private const val SLOT_MOBILE = "mobile"
|
||||||
|
|
||||||
|
private const val SUB_1_ID = 1
|
||||||
|
private const val SUB_2_ID = 2
|
||||||
|
|
||||||
const val NETWORK_ID = 45
|
const val NETWORK_ID = 45
|
||||||
val NETWORK = mock<Network>().apply { whenever(this.getNetId()).thenReturn(NETWORK_ID) }
|
val NETWORK = mock<Network>().apply { whenever(this.getNetId()).thenReturn(NETWORK_ID) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ class FakeConnectivityRepository : ConnectivityRepository {
|
|||||||
override val defaultConnections: StateFlow<DefaultConnectionModel> =
|
override val defaultConnections: StateFlow<DefaultConnectionModel> =
|
||||||
MutableStateFlow(DefaultConnectionModel())
|
MutableStateFlow(DefaultConnectionModel())
|
||||||
|
|
||||||
|
override val vcnSubId: MutableStateFlow<Int?> = MutableStateFlow(null)
|
||||||
|
|
||||||
fun setForceHiddenIcons(hiddenIcons: Set<ConnectivitySlot>) {
|
fun setForceHiddenIcons(hiddenIcons: Set<ConnectivitySlot>) {
|
||||||
_forceHiddenIcons.value = hiddenIcons
|
_forceHiddenIcons.value = hiddenIcons
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user