Merge "[SB Refactor] Fix handling of network transports in wifi repo." into tm-qpr-dev am: 63321fc0a6

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

Change-Id: If36b5e0567892bf52d7b99bf65bf63af8b02aa1c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Caitlin Shkuratov
2023-01-26 21:28:07 +00:00
committed by Automerger Merge Worker
5 changed files with 157 additions and 13 deletions

View File

@@ -501,7 +501,7 @@ public interface StatusBarIconController {
@VisibleForTesting @VisibleForTesting
protected StatusIconDisplayable addWifiIcon(int index, String slot, WifiIconState state) { protected StatusIconDisplayable addWifiIcon(int index, String slot, WifiIconState state) {
if (mStatusBarPipelineFlags.useNewWifiIcon()) { if (mStatusBarPipelineFlags.useNewWifiIcon()) {
throw new IllegalStateException("Attempting to add a mobile icon while the new " throw new IllegalStateException("Attempting to add a wifi icon while the new "
+ "icons are enabled is not supported"); + "icons are enabled is not supported");
} }

View File

@@ -97,15 +97,20 @@ constructor(
) )
} }
fun logOnCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { fun logOnCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities,
isDefaultNetworkCallback: Boolean,
) {
buffer.log( buffer.log(
SB_LOGGING_TAG, SB_LOGGING_TAG,
LogLevel.INFO, LogLevel.INFO,
{ {
bool1 = isDefaultNetworkCallback
int1 = network.getNetId() int1 = network.getNetId()
str1 = networkCapabilities.toString() str1 = networkCapabilities.toString()
}, },
{ "onCapabilitiesChanged: net=$int1 capabilities=$str1" } { "onCapabilitiesChanged[default=$bool1]: net=$int1 capabilities=$str1" }
) )
} }

View File

@@ -114,13 +114,17 @@ constructor(
network: Network, network: Network,
networkCapabilities: NetworkCapabilities networkCapabilities: NetworkCapabilities
) { ) {
logger.logOnCapabilitiesChanged(
network,
networkCapabilities,
isDefaultNetworkCallback = true,
)
// This method will always be called immediately after the network // This method will always be called immediately after the network
// becomes the default, in addition to any time the capabilities change // becomes the default, in addition to any time the capabilities change
// while the network is the default. // while the network is the default.
// If this network contains valid wifi info, then wifi is the default // If this network is a wifi network, then wifi is the default network.
// network. trySend(isWifiNetwork(networkCapabilities))
val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
trySend(wifiInfo != null)
} }
override fun onLost(network: Network) { override fun onLost(network: Network) {
@@ -152,7 +156,11 @@ constructor(
network: Network, network: Network,
networkCapabilities: NetworkCapabilities networkCapabilities: NetworkCapabilities
) { ) {
logger.logOnCapabilitiesChanged(network, networkCapabilities) logger.logOnCapabilitiesChanged(
network,
networkCapabilities,
isDefaultNetworkCallback = false,
)
wifiNetworkChangeEvents.tryEmit(Unit) wifiNetworkChangeEvents.tryEmit(Unit)
@@ -253,16 +261,30 @@ constructor(
networkCapabilities: NetworkCapabilities networkCapabilities: NetworkCapabilities
): WifiInfo? { ): WifiInfo? {
return when { return when {
networkCapabilities.hasTransport(TRANSPORT_WIFI) ->
networkCapabilities.transportInfo as WifiInfo?
networkCapabilities.hasTransport(TRANSPORT_CELLULAR) -> networkCapabilities.hasTransport(TRANSPORT_CELLULAR) ->
// Sometimes, cellular networks can act as wifi networks (known as VCN -- // Sometimes, cellular networks can act as wifi networks (known as VCN --
// virtual carrier network). So, see if this cellular network has wifi info. // virtual carrier network). So, see if this cellular network has wifi info.
Utils.tryGetWifiInfoForVcn(networkCapabilities) Utils.tryGetWifiInfoForVcn(networkCapabilities)
networkCapabilities.hasTransport(TRANSPORT_WIFI) ->
if (networkCapabilities.transportInfo is WifiInfo) {
networkCapabilities.transportInfo as WifiInfo
} else {
null
}
else -> null else -> null
} }
} }
/** True if these capabilities represent a wifi network. */
private fun isWifiNetwork(networkCapabilities: NetworkCapabilities): Boolean {
return when {
networkCapabilities.hasTransport(TRANSPORT_WIFI) -> true
networkCapabilities.hasTransport(TRANSPORT_CELLULAR) ->
Utils.tryGetWifiInfoForVcn(networkCapabilities) != null
else -> false
}
}
private fun createWifiNetworkModel( private fun createWifiNetworkModel(
wifiInfo: WifiInfo, wifiInfo: WifiInfo,
network: Network, network: Network,

View File

@@ -45,7 +45,7 @@ class ConnectivityPipelineLoggerTest : SysuiTestCase() {
@Test @Test
fun testLogNetworkCapsChange_bufferHasInfo() { fun testLogNetworkCapsChange_bufferHasInfo() {
logger.logOnCapabilitiesChanged(NET_1, NET_1_CAPS) logger.logOnCapabilitiesChanged(NET_1, NET_1_CAPS, isDefaultNetworkCallback = true)
val stringWriter = StringWriter() val stringWriter = StringWriter()
buffer.dump(PrintWriter(stringWriter), tailLength = 0) buffer.dump(PrintWriter(stringWriter), tailLength = 0)
@@ -54,6 +54,7 @@ class ConnectivityPipelineLoggerTest : SysuiTestCase() {
val expectedNetId = NET_1_ID.toString() val expectedNetId = NET_1_ID.toString()
val expectedCaps = NET_1_CAPS.toString() val expectedCaps = NET_1_CAPS.toString()
assertThat(actualString).contains("true")
assertThat(actualString).contains(expectedNetId) assertThat(actualString).contains(expectedNetId)
assertThat(actualString).contains(expectedCaps) assertThat(actualString).contains(expectedCaps)
} }

View File

@@ -21,7 +21,10 @@ import android.net.Network
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.NetworkCapabilities.TRANSPORT_VPN
import android.net.NetworkCapabilities.TRANSPORT_WIFI import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.net.TransportInfo
import android.net.VpnTransportInfo
import android.net.vcn.VcnTransportInfo import android.net.vcn.VcnTransportInfo
import android.net.wifi.WifiInfo import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager import android.net.wifi.WifiManager
@@ -243,6 +246,54 @@ class WifiRepositoryImplTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
/** Regression test for b/266628069. */
@Test
fun isWifiDefault_transportInfoIsNotWifi_andNoWifiTransport_false() =
runBlocking(IMMEDIATE) {
val job = underTest.isWifiDefault.launchIn(this)
val transportInfo = VpnTransportInfo(
/* type= */ 0,
/* sessionId= */ "sessionId",
)
val networkCapabilities = mock<NetworkCapabilities>().also {
whenever(it.hasTransport(TRANSPORT_VPN)).thenReturn(true)
whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(false)
whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(false)
whenever(it.transportInfo).thenReturn(transportInfo)
}
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, networkCapabilities)
assertThat(underTest.isWifiDefault.value).isFalse()
job.cancel()
}
/** Regression test for b/266628069. */
@Test
fun isWifiDefault_transportInfoIsNotWifi_butHasWifiTransport_true() =
runBlocking(IMMEDIATE) {
val job = underTest.isWifiDefault.launchIn(this)
val transportInfo = VpnTransportInfo(
/* type= */ 0,
/* sessionId= */ "sessionId",
)
val networkCapabilities = mock<NetworkCapabilities>().also {
whenever(it.hasTransport(TRANSPORT_VPN)).thenReturn(true)
whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(false)
whenever(it.transportInfo).thenReturn(transportInfo)
}
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, networkCapabilities)
assertThat(underTest.isWifiDefault.value).isTrue()
job.cancel()
}
@Test @Test
fun isWifiDefault_cellularVcnNetwork_isTrue() = runBlocking(IMMEDIATE) { fun isWifiDefault_cellularVcnNetwork_isTrue() = runBlocking(IMMEDIATE) {
val job = underTest.isWifiDefault.launchIn(this) val job = underTest.isWifiDefault.launchIn(this)
@@ -259,6 +310,24 @@ class WifiRepositoryImplTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun wifiNetwork_cellularAndWifiTransports_usesCellular_isTrue() =
runBlocking(IMMEDIATE) {
val job = underTest.isWifiDefault.launchIn(this)
val capabilities = mock<NetworkCapabilities>().apply {
whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
whenever(this.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO))
}
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
assertThat(underTest.isWifiDefault.value).isTrue()
job.cancel()
}
@Test @Test
fun isWifiDefault_cellularNotVcnNetwork_isFalse() = runBlocking(IMMEDIATE) { fun isWifiDefault_cellularNotVcnNetwork_isFalse() = runBlocking(IMMEDIATE) {
val job = underTest.isWifiDefault.launchIn(this) val job = underTest.isWifiDefault.launchIn(this)
@@ -467,6 +536,28 @@ class WifiRepositoryImplTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
/** Regression test for b/266628069. */
@Test
fun wifiNetwork_transportInfoIsNotWifi_flowHasNoNetwork() =
runBlocking(IMMEDIATE) {
var latest: WifiNetworkModel? = null
val job = underTest
.wifiNetwork
.onEach { latest = it }
.launchIn(this)
val transportInfo = VpnTransportInfo(
/* type= */ 0,
/* sessionId= */ "sessionId",
)
getNetworkCallback()
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(transportInfo))
assertThat(latest is WifiNetworkModel.Inactive).isTrue()
job.cancel()
}
@Test @Test
fun wifiNetwork_cellularVcnNetworkAdded_flowHasNetwork() = runBlocking(IMMEDIATE) { fun wifiNetwork_cellularVcnNetworkAdded_flowHasNetwork() = runBlocking(IMMEDIATE) {
var latest: WifiNetworkModel? = null var latest: WifiNetworkModel? = null
@@ -534,6 +625,31 @@ class WifiRepositoryImplTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun wifiNetwork_cellularAndWifiTransports_usesCellular() =
runBlocking(IMMEDIATE) {
var latest: WifiNetworkModel? = null
val job = underTest
.wifiNetwork
.onEach { latest = it }
.launchIn(this)
val capabilities = mock<NetworkCapabilities>().apply {
whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
whenever(this.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO))
}
getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
assertThat(latest is WifiNetworkModel.Active).isTrue()
val latestActive = latest as WifiNetworkModel.Active
assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
assertThat(latestActive.ssid).isEqualTo(SSID)
job.cancel()
}
@Test @Test
fun wifiNetwork_newPrimaryWifiNetwork_flowHasNewNetwork() = runBlocking(IMMEDIATE) { fun wifiNetwork_newPrimaryWifiNetwork_flowHasNewNetwork() = runBlocking(IMMEDIATE) {
var latest: WifiNetworkModel? = null var latest: WifiNetworkModel? = null
@@ -870,12 +986,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
} }
private fun createWifiNetworkCapabilities( private fun createWifiNetworkCapabilities(
wifiInfo: WifiInfo, transportInfo: TransportInfo,
isValidated: Boolean = true, isValidated: Boolean = true,
): NetworkCapabilities { ): NetworkCapabilities {
return mock<NetworkCapabilities>().also { return mock<NetworkCapabilities>().also {
whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true) whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
whenever(it.transportInfo).thenReturn(wifiInfo) whenever(it.transportInfo).thenReturn(transportInfo)
whenever(it.hasCapability(NET_CAPABILITY_VALIDATED)).thenReturn(isValidated) whenever(it.hasCapability(NET_CAPABILITY_VALIDATED)).thenReturn(isValidated)
} }
} }