Merge changes I627dcd0f,I81abc174,Id7948d21 am: 75090fb64e
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/1731450 Change-Id: I3662e70034b16721e4ad1711654cb9f7eda45d35
This commit is contained in:
@@ -18,6 +18,7 @@ package android.net
|
|||||||
|
|
||||||
import android.app.Instrumentation
|
import android.app.Instrumentation
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
|
||||||
import android.net.NetworkCapabilities.TRANSPORT_TEST
|
import android.net.NetworkCapabilities.TRANSPORT_TEST
|
||||||
import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable
|
import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable
|
||||||
import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn
|
import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn
|
||||||
@@ -25,14 +26,18 @@ import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetwo
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.HandlerThread
|
import android.os.HandlerThread
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.util.Log
|
||||||
import androidx.test.InstrumentationRegistry
|
import androidx.test.InstrumentationRegistry
|
||||||
import com.android.net.module.util.ArrayTrackRecord
|
import com.android.net.module.util.ArrayTrackRecord
|
||||||
import com.android.testutils.CompatUtil
|
import com.android.testutils.CompatUtil
|
||||||
|
import com.android.testutils.DevSdkIgnoreRule
|
||||||
|
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter
|
||||||
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
|
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
|
||||||
import com.android.testutils.DevSdkIgnoreRunner
|
import com.android.testutils.DevSdkIgnoreRunner
|
||||||
import com.android.testutils.isDevSdkInRange
|
import com.android.testutils.isDevSdkInRange
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mockito.doReturn
|
import org.mockito.Mockito.doReturn
|
||||||
@@ -41,6 +46,7 @@ import org.mockito.Mockito.verifyNoMoreInteractions
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
|
import kotlin.test.fail
|
||||||
|
|
||||||
private const val DEFAULT_TIMEOUT_MS = 5000L
|
private const val DEFAULT_TIMEOUT_MS = 5000L
|
||||||
private val instrumentation: Instrumentation
|
private val instrumentation: Instrumentation
|
||||||
@@ -51,6 +57,8 @@ private val PROVIDER_NAME = "NetworkProviderTest"
|
|||||||
@RunWith(DevSdkIgnoreRunner::class)
|
@RunWith(DevSdkIgnoreRunner::class)
|
||||||
@IgnoreUpTo(Build.VERSION_CODES.Q)
|
@IgnoreUpTo(Build.VERSION_CODES.Q)
|
||||||
class NetworkProviderTest {
|
class NetworkProviderTest {
|
||||||
|
@Rule @JvmField
|
||||||
|
val mIgnoreRule = DevSdkIgnoreRule()
|
||||||
private val mCm = context.getSystemService(ConnectivityManager::class.java)
|
private val mCm = context.getSystemService(ConnectivityManager::class.java)
|
||||||
private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread")
|
private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread")
|
||||||
|
|
||||||
@@ -68,6 +76,7 @@ class NetworkProviderTest {
|
|||||||
|
|
||||||
private class TestNetworkProvider(context: Context, looper: Looper) :
|
private class TestNetworkProvider(context: Context, looper: Looper) :
|
||||||
NetworkProvider(context, looper, PROVIDER_NAME) {
|
NetworkProvider(context, looper, PROVIDER_NAME) {
|
||||||
|
private val TAG = this::class.simpleName
|
||||||
private val seenEvents = ArrayTrackRecord<CallbackEntry>().newReadHead()
|
private val seenEvents = ArrayTrackRecord<CallbackEntry>().newReadHead()
|
||||||
|
|
||||||
sealed class CallbackEntry {
|
sealed class CallbackEntry {
|
||||||
@@ -80,22 +89,30 @@ class NetworkProviderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onNetworkRequested(request: NetworkRequest, score: Int, id: Int) {
|
override fun onNetworkRequested(request: NetworkRequest, score: Int, id: Int) {
|
||||||
|
Log.d(TAG, "onNetworkRequested $request, $score, $id")
|
||||||
seenEvents.add(OnNetworkRequested(request, score, id))
|
seenEvents.add(OnNetworkRequested(request, score, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNetworkRequestWithdrawn(request: NetworkRequest) {
|
override fun onNetworkRequestWithdrawn(request: NetworkRequest) {
|
||||||
|
Log.d(TAG, "onNetworkRequestWithdrawn $request")
|
||||||
seenEvents.add(OnNetworkRequestWithdrawn(request))
|
seenEvents.add(OnNetworkRequestWithdrawn(request))
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : CallbackEntry> expectCallback(
|
inline fun <reified T : CallbackEntry> eventuallyExpectCallbackThat(
|
||||||
crossinline predicate: (T) -> Boolean
|
crossinline predicate: (T) -> Boolean
|
||||||
) = seenEvents.poll(DEFAULT_TIMEOUT_MS) { it is T && predicate(it) }
|
) = seenEvents.poll(DEFAULT_TIMEOUT_MS) { it is T && predicate(it) }
|
||||||
|
?: fail("Did not receive callback after ${DEFAULT_TIMEOUT_MS}ms")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createNetworkProvider(ctx: Context = context): TestNetworkProvider {
|
private fun createNetworkProvider(ctx: Context = context): TestNetworkProvider {
|
||||||
return TestNetworkProvider(ctx, mHandlerThread.looper)
|
return TestNetworkProvider(ctx, mHandlerThread.looper)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In S+ framework, do not run this test, since the provider will no longer receive
|
||||||
|
// onNetworkRequested for every request. Instead, provider needs to
|
||||||
|
// call {@code registerNetworkOffer} with the description of networks they
|
||||||
|
// might have ability to setup, and expects {@link NetworkOfferCallback#onNetworkNeeded}.
|
||||||
|
@IgnoreAfter(Build.VERSION_CODES.R)
|
||||||
@Test
|
@Test
|
||||||
fun testOnNetworkRequested() {
|
fun testOnNetworkRequested() {
|
||||||
val provider = createNetworkProvider()
|
val provider = createNetworkProvider()
|
||||||
@@ -105,13 +122,15 @@ class NetworkProviderTest {
|
|||||||
|
|
||||||
val specifier = CompatUtil.makeTestNetworkSpecifier(
|
val specifier = CompatUtil.makeTestNetworkSpecifier(
|
||||||
UUID.randomUUID().toString())
|
UUID.randomUUID().toString())
|
||||||
|
// Test network is not allowed to be trusted.
|
||||||
val nr: NetworkRequest = NetworkRequest.Builder()
|
val nr: NetworkRequest = NetworkRequest.Builder()
|
||||||
.addTransportType(TRANSPORT_TEST)
|
.addTransportType(TRANSPORT_TEST)
|
||||||
|
.removeCapability(NET_CAPABILITY_TRUSTED)
|
||||||
.setNetworkSpecifier(specifier)
|
.setNetworkSpecifier(specifier)
|
||||||
.build()
|
.build()
|
||||||
val cb = ConnectivityManager.NetworkCallback()
|
val cb = ConnectivityManager.NetworkCallback()
|
||||||
mCm.requestNetwork(nr, cb)
|
mCm.requestNetwork(nr, cb)
|
||||||
provider.expectCallback<OnNetworkRequested>() { callback ->
|
provider.eventuallyExpectCallbackThat<OnNetworkRequested>() { callback ->
|
||||||
callback.request.getNetworkSpecifier() == specifier &&
|
callback.request.getNetworkSpecifier() == specifier &&
|
||||||
callback.request.hasTransport(TRANSPORT_TEST)
|
callback.request.hasTransport(TRANSPORT_TEST)
|
||||||
}
|
}
|
||||||
@@ -131,22 +150,24 @@ class NetworkProviderTest {
|
|||||||
val config = NetworkAgentConfig.Builder().build()
|
val config = NetworkAgentConfig.Builder().build()
|
||||||
val agent = object : NetworkAgent(context, mHandlerThread.looper, "TestAgent", nc, lp,
|
val agent = object : NetworkAgent(context, mHandlerThread.looper, "TestAgent", nc, lp,
|
||||||
initialScore, config, provider) {}
|
initialScore, config, provider) {}
|
||||||
|
agent.register()
|
||||||
|
agent.markConnected()
|
||||||
|
|
||||||
provider.expectCallback<OnNetworkRequested>() { callback ->
|
provider.eventuallyExpectCallbackThat<OnNetworkRequested>() { callback ->
|
||||||
callback.request.getNetworkSpecifier() == specifier &&
|
callback.request.getNetworkSpecifier() == specifier &&
|
||||||
callback.score == initialScore &&
|
callback.score == initialScore &&
|
||||||
callback.id == agent.providerId
|
callback.id == agent.providerId
|
||||||
}
|
}
|
||||||
|
|
||||||
agent.sendNetworkScore(updatedScore)
|
agent.sendNetworkScore(updatedScore)
|
||||||
provider.expectCallback<OnNetworkRequested>() { callback ->
|
provider.eventuallyExpectCallbackThat<OnNetworkRequested>() { callback ->
|
||||||
callback.request.getNetworkSpecifier() == specifier &&
|
callback.request.getNetworkSpecifier() == specifier &&
|
||||||
callback.score == updatedScore &&
|
callback.score == updatedScore &&
|
||||||
callback.id == agent.providerId
|
callback.id == agent.providerId
|
||||||
}
|
}
|
||||||
|
|
||||||
mCm.unregisterNetworkCallback(cb)
|
mCm.unregisterNetworkCallback(cb)
|
||||||
provider.expectCallback<OnNetworkRequestWithdrawn>() { callback ->
|
provider.eventuallyExpectCallbackThat<OnNetworkRequestWithdrawn>() { callback ->
|
||||||
callback.request.getNetworkSpecifier() == specifier &&
|
callback.request.getNetworkSpecifier() == specifier &&
|
||||||
callback.request.hasTransport(TRANSPORT_TEST)
|
callback.request.hasTransport(TRANSPORT_TEST)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -650,6 +650,18 @@ public class ConnectivityManagerTest {
|
|||||||
mCm.getBackgroundDataSetting();
|
mCm.getBackgroundDataSetting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NetworkRequest makeDefaultRequest() {
|
||||||
|
// Make a request that is similar to the way framework tracks the system
|
||||||
|
// default network.
|
||||||
|
return new NetworkRequest.Builder()
|
||||||
|
.clearCapabilities()
|
||||||
|
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
|
||||||
|
.addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
|
||||||
|
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
|
||||||
|
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private NetworkRequest makeWifiNetworkRequest() {
|
private NetworkRequest makeWifiNetworkRequest() {
|
||||||
return new NetworkRequest.Builder()
|
return new NetworkRequest.Builder()
|
||||||
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
||||||
@@ -710,12 +722,14 @@ public class ConnectivityManagerTest {
|
|||||||
|
|
||||||
final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback();
|
final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback();
|
||||||
final TestNetworkCallback perUidCallback = new TestNetworkCallback();
|
final TestNetworkCallback perUidCallback = new TestNetworkCallback();
|
||||||
|
final TestNetworkCallback bestMatchingCallback = new TestNetworkCallback();
|
||||||
final Handler h = new Handler(Looper.getMainLooper());
|
final Handler h = new Handler(Looper.getMainLooper());
|
||||||
if (TestUtils.shouldTestSApis()) {
|
if (TestUtils.shouldTestSApis()) {
|
||||||
runWithShellPermissionIdentity(() -> {
|
runWithShellPermissionIdentity(() -> {
|
||||||
mCmShim.registerSystemDefaultNetworkCallback(systemDefaultCallback, h);
|
mCmShim.registerSystemDefaultNetworkCallback(systemDefaultCallback, h);
|
||||||
mCmShim.registerDefaultNetworkCallbackForUid(Process.myUid(), perUidCallback, h);
|
mCmShim.registerDefaultNetworkCallbackForUid(Process.myUid(), perUidCallback, h);
|
||||||
}, NETWORK_SETTINGS);
|
}, NETWORK_SETTINGS);
|
||||||
|
mCm.registerBestMatchingNetworkCallback(makeDefaultRequest(), bestMatchingCallback, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
Network wifiNetwork = null;
|
Network wifiNetwork = null;
|
||||||
@@ -741,6 +755,10 @@ public class ConnectivityManagerTest {
|
|||||||
assertNotNull("Did not receive onAvailable on per-UID default network callback",
|
assertNotNull("Did not receive onAvailable on per-UID default network callback",
|
||||||
perUidNetwork);
|
perUidNetwork);
|
||||||
assertEquals(defaultNetwork, perUidNetwork);
|
assertEquals(defaultNetwork, perUidNetwork);
|
||||||
|
final Network bestMatchingNetwork = bestMatchingCallback.waitForAvailable();
|
||||||
|
assertNotNull("Did not receive onAvailable on best matching network callback",
|
||||||
|
bestMatchingNetwork);
|
||||||
|
assertEquals(defaultNetwork, bestMatchingNetwork);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@@ -751,6 +769,7 @@ public class ConnectivityManagerTest {
|
|||||||
if (TestUtils.shouldTestSApis()) {
|
if (TestUtils.shouldTestSApis()) {
|
||||||
mCm.unregisterNetworkCallback(systemDefaultCallback);
|
mCm.unregisterNetworkCallback(systemDefaultCallback);
|
||||||
mCm.unregisterNetworkCallback(perUidCallback);
|
mCm.unregisterNetworkCallback(perUidCallback);
|
||||||
|
mCm.unregisterNetworkCallback(bestMatchingCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSta
|
|||||||
import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive
|
import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive
|
||||||
import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus
|
import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.Handler
|
||||||
import android.os.HandlerThread
|
import android.os.HandlerThread
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.os.Message
|
import android.os.Message
|
||||||
@@ -269,10 +270,9 @@ class NetworkAgentTest {
|
|||||||
history.add(OnSignalStrengthThresholdsUpdated(thresholds))
|
history.add(OnSignalStrengthThresholdsUpdated(thresholds))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun expectEmptySignalStrengths() {
|
fun expectSignalStrengths(thresholds: IntArray? = intArrayOf()) {
|
||||||
expectCallback<OnSignalStrengthThresholdsUpdated>().let {
|
expectCallback<OnSignalStrengthThresholdsUpdated>().let {
|
||||||
// intArrayOf() without arguments makes an empty array
|
assertArrayEquals(thresholds, it.thresholds)
|
||||||
assertArrayEquals(intArrayOf(), it.thresholds)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,7 +292,7 @@ class NetworkAgentTest {
|
|||||||
// a NetworkAgent whose network does not require validation (which test networks do
|
// a NetworkAgent whose network does not require validation (which test networks do
|
||||||
// not, since they lack the INTERNET capability). It always contains the default argument
|
// not, since they lack the INTERNET capability). It always contains the default argument
|
||||||
// for the URI.
|
// for the URI.
|
||||||
fun expectNoInternetValidationStatus() = expectCallback<OnValidationStatus>().let {
|
fun expectValidationBypassedStatus() = expectCallback<OnValidationStatus>().let {
|
||||||
assertEquals(it.status, VALID_NETWORK)
|
assertEquals(it.status, VALID_NETWORK)
|
||||||
// The returned Uri is parsed from the empty string, which means it's an
|
// The returned Uri is parsed from the empty string, which means it's an
|
||||||
// instance of the (private) Uri.StringUri. There are no real good ways
|
// instance of the (private) Uri.StringUri. There are no real good ways
|
||||||
@@ -332,9 +332,30 @@ class NetworkAgentTest {
|
|||||||
callbacksToCleanUp.add(callback)
|
callbacksToCleanUp.add(callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun registerBestMatchingNetworkCallback(
|
||||||
|
request: NetworkRequest,
|
||||||
|
callback: TestableNetworkCallback,
|
||||||
|
handler: Handler
|
||||||
|
) {
|
||||||
|
mCM!!.registerBestMatchingNetworkCallback(request, callback, handler)
|
||||||
|
callbacksToCleanUp.add(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeTestNetworkRequest(specifier: String? = null): NetworkRequest {
|
||||||
|
return NetworkRequest.Builder()
|
||||||
|
.clearCapabilities()
|
||||||
|
.addTransportType(TRANSPORT_TEST)
|
||||||
|
.also {
|
||||||
|
if (specifier != null) {
|
||||||
|
it.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifier))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
private fun createNetworkAgent(
|
private fun createNetworkAgent(
|
||||||
context: Context = realContext,
|
context: Context = realContext,
|
||||||
name: String? = null,
|
specifier: String? = null,
|
||||||
initialNc: NetworkCapabilities? = null,
|
initialNc: NetworkCapabilities? = null,
|
||||||
initialLp: LinkProperties? = null,
|
initialLp: LinkProperties? = null,
|
||||||
initialConfig: NetworkAgentConfig? = null
|
initialConfig: NetworkAgentConfig? = null
|
||||||
@@ -349,8 +370,8 @@ class NetworkAgentTest {
|
|||||||
if (SdkLevel.isAtLeastS()) {
|
if (SdkLevel.isAtLeastS()) {
|
||||||
addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
|
addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
|
||||||
}
|
}
|
||||||
if (null != name) {
|
if (null != specifier) {
|
||||||
setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name))
|
setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifier))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val lp = initialLp ?: LinkProperties().apply {
|
val lp = initialLp ?: LinkProperties().apply {
|
||||||
@@ -365,21 +386,22 @@ class NetworkAgentTest {
|
|||||||
|
|
||||||
private fun createConnectedNetworkAgent(
|
private fun createConnectedNetworkAgent(
|
||||||
context: Context = realContext,
|
context: Context = realContext,
|
||||||
name: String? = null,
|
specifier: String? = UUID.randomUUID().toString(),
|
||||||
initialConfig: NetworkAgentConfig? = null
|
initialConfig: NetworkAgentConfig? = null,
|
||||||
|
expectedInitSignalStrengthThresholds: IntArray? = intArrayOf()
|
||||||
): Pair<TestableNetworkAgent, TestableNetworkCallback> {
|
): Pair<TestableNetworkAgent, TestableNetworkCallback> {
|
||||||
val request: NetworkRequest = NetworkRequest.Builder()
|
|
||||||
.clearCapabilities()
|
|
||||||
.addTransportType(TRANSPORT_TEST)
|
|
||||||
.build()
|
|
||||||
val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
||||||
requestNetwork(request, callback)
|
// Ensure this NetworkAgent is never unneeded by filing a request with its specifier.
|
||||||
val config = initialConfig ?: NetworkAgentConfig.Builder().build()
|
requestNetwork(makeTestNetworkRequest(specifier = specifier), callback)
|
||||||
val agent = createNetworkAgent(context, name, initialConfig = config)
|
val agent = createNetworkAgent(context, specifier, initialConfig = initialConfig)
|
||||||
agent.setTeardownDelayMillis(0)
|
agent.setTeardownDelayMillis(0)
|
||||||
|
// Connect the agent and verify initial status callbacks.
|
||||||
agent.register()
|
agent.register()
|
||||||
agent.markConnected()
|
agent.markConnected()
|
||||||
agent.expectCallback<OnNetworkCreated>()
|
agent.expectCallback<OnNetworkCreated>()
|
||||||
|
agent.expectSignalStrengths(expectedInitSignalStrengthThresholds)
|
||||||
|
agent.expectValidationBypassedStatus()
|
||||||
|
callback.expectAvailableThenValidatedCallbacks(agent.network!!)
|
||||||
return agent to callback
|
return agent to callback
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +435,6 @@ class NetworkAgentTest {
|
|||||||
.setLegacySubType(subtypeLTE)
|
.setLegacySubType(subtypeLTE)
|
||||||
.setLegacySubTypeName(subtypeNameLTE).build()
|
.setLegacySubTypeName(subtypeNameLTE).build()
|
||||||
val (agent, callback) = createConnectedNetworkAgent(initialConfig = config)
|
val (agent, callback) = createConnectedNetworkAgent(initialConfig = config)
|
||||||
callback.expectAvailableThenValidatedCallbacks(agent.network)
|
|
||||||
agent.setLegacySubtype(subtypeUMTS, subtypeNameUMTS)
|
agent.setLegacySubtype(subtypeUMTS, subtypeNameUMTS)
|
||||||
|
|
||||||
// There is no callback when networkInfo changes,
|
// There is no callback when networkInfo changes,
|
||||||
@@ -433,12 +454,8 @@ class NetworkAgentTest {
|
|||||||
@Test
|
@Test
|
||||||
fun testConnectAndUnregister() {
|
fun testConnectAndUnregister() {
|
||||||
val (agent, callback) = createConnectedNetworkAgent()
|
val (agent, callback) = createConnectedNetworkAgent()
|
||||||
callback.expectAvailableThenValidatedCallbacks(agent.network)
|
|
||||||
agent.expectEmptySignalStrengths()
|
|
||||||
agent.expectNoInternetValidationStatus()
|
|
||||||
|
|
||||||
unregister(agent)
|
unregister(agent)
|
||||||
callback.expectCallback<Lost>(agent.network)
|
callback.expectCallback<Lost>(agent.network!!)
|
||||||
assertFailsWith<IllegalStateException>("Must not be able to register an agent twice") {
|
assertFailsWith<IllegalStateException>("Must not be able to register an agent twice") {
|
||||||
agent.register()
|
agent.register()
|
||||||
}
|
}
|
||||||
@@ -446,11 +463,8 @@ class NetworkAgentTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testOnBandwidthUpdateRequested() {
|
fun testOnBandwidthUpdateRequested() {
|
||||||
val (agent, callback) = createConnectedNetworkAgent()
|
val (agent, _) = createConnectedNetworkAgent()
|
||||||
callback.expectAvailableThenValidatedCallbacks(agent.network)
|
mCM.requestBandwidthUpdate(agent.network!!)
|
||||||
agent.expectEmptySignalStrengths()
|
|
||||||
agent.expectNoInternetValidationStatus()
|
|
||||||
mCM.requestBandwidthUpdate(agent.network)
|
|
||||||
agent.expectCallback<OnBandwidthUpdateRequested>()
|
agent.expectCallback<OnBandwidthUpdateRequested>()
|
||||||
unregister(agent)
|
unregister(agent)
|
||||||
}
|
}
|
||||||
@@ -468,13 +482,8 @@ class NetworkAgentTest {
|
|||||||
registerNetworkCallback(request, it)
|
registerNetworkCallback(request, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createConnectedNetworkAgent().let { (agent, callback) ->
|
createConnectedNetworkAgent(expectedInitSignalStrengthThresholds = thresholds).let {
|
||||||
callback.expectAvailableThenValidatedCallbacks(agent.network)
|
(agent, callback) ->
|
||||||
agent.expectCallback<OnSignalStrengthThresholdsUpdated>().let {
|
|
||||||
assertArrayEquals(it.thresholds, thresholds)
|
|
||||||
}
|
|
||||||
agent.expectNoInternetValidationStatus()
|
|
||||||
|
|
||||||
// Send signal strength and check that the callbacks are called appropriately.
|
// Send signal strength and check that the callbacks are called appropriately.
|
||||||
val nc = NetworkCapabilities(agent.nc)
|
val nc = NetworkCapabilities(agent.nc)
|
||||||
nc.setSignalStrength(20)
|
nc.setSignalStrength(20)
|
||||||
@@ -483,21 +492,21 @@ class NetworkAgentTest {
|
|||||||
|
|
||||||
nc.setSignalStrength(40)
|
nc.setSignalStrength(40)
|
||||||
agent.sendNetworkCapabilities(nc)
|
agent.sendNetworkCapabilities(nc)
|
||||||
callbacks[0].expectAvailableCallbacks(agent.network)
|
callbacks[0].expectAvailableCallbacks(agent.network!!)
|
||||||
callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT)
|
callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT)
|
||||||
callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT)
|
callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT)
|
||||||
|
|
||||||
nc.setSignalStrength(80)
|
nc.setSignalStrength(80)
|
||||||
agent.sendNetworkCapabilities(nc)
|
agent.sendNetworkCapabilities(nc)
|
||||||
callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 80 }
|
callbacks[0].expectCapabilitiesThat(agent.network!!) { it.signalStrength == 80 }
|
||||||
callbacks[1].expectAvailableCallbacks(agent.network)
|
callbacks[1].expectAvailableCallbacks(agent.network!!)
|
||||||
callbacks[2].expectAvailableCallbacks(agent.network)
|
callbacks[2].expectAvailableCallbacks(agent.network!!)
|
||||||
|
|
||||||
nc.setSignalStrength(55)
|
nc.setSignalStrength(55)
|
||||||
agent.sendNetworkCapabilities(nc)
|
agent.sendNetworkCapabilities(nc)
|
||||||
callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 }
|
callbacks[0].expectCapabilitiesThat(agent.network!!) { it.signalStrength == 55 }
|
||||||
callbacks[1].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 }
|
callbacks[1].expectCapabilitiesThat(agent.network!!) { it.signalStrength == 55 }
|
||||||
callbacks[2].expectCallback<Lost>(agent.network)
|
callbacks[2].expectCallback<Lost>(agent.network!!)
|
||||||
}
|
}
|
||||||
callbacks.forEach {
|
callbacks.forEach {
|
||||||
mCM.unregisterNetworkCallback(it)
|
mCM.unregisterNetworkCallback(it)
|
||||||
@@ -546,20 +555,17 @@ class NetworkAgentTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) ->
|
fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) ->
|
||||||
callback.expectAvailableThenValidatedCallbacks(agent.network)
|
|
||||||
agent.expectEmptySignalStrengths()
|
|
||||||
agent.expectNoInternetValidationStatus()
|
|
||||||
val ifaceName = "adhocIface"
|
val ifaceName = "adhocIface"
|
||||||
val lp = LinkProperties(agent.lp)
|
val lp = LinkProperties(agent.lp)
|
||||||
lp.setInterfaceName(ifaceName)
|
lp.setInterfaceName(ifaceName)
|
||||||
agent.sendLinkProperties(lp)
|
agent.sendLinkProperties(lp)
|
||||||
callback.expectLinkPropertiesThat(agent.network) {
|
callback.expectLinkPropertiesThat(agent.network!!) {
|
||||||
it.getInterfaceName() == ifaceName
|
it.getInterfaceName() == ifaceName
|
||||||
}
|
}
|
||||||
val nc = NetworkCapabilities(agent.nc)
|
val nc = NetworkCapabilities(agent.nc)
|
||||||
nc.addCapability(NET_CAPABILITY_NOT_METERED)
|
nc.addCapability(NET_CAPABILITY_NOT_METERED)
|
||||||
agent.sendNetworkCapabilities(nc)
|
agent.sendNetworkCapabilities(nc)
|
||||||
callback.expectCapabilitiesThat(agent.network) {
|
callback.expectCapabilitiesThat(agent.network!!) {
|
||||||
it.hasCapability(NET_CAPABILITY_NOT_METERED)
|
it.hasCapability(NET_CAPABILITY_NOT_METERED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -568,56 +574,32 @@ class NetworkAgentTest {
|
|||||||
fun testSendScore() {
|
fun testSendScore() {
|
||||||
// This test will create two networks and check that the one with the stronger
|
// This test will create two networks and check that the one with the stronger
|
||||||
// score wins out for a request that matches them both.
|
// score wins out for a request that matches them both.
|
||||||
// First create requests to make sure both networks are kept up, using the
|
|
||||||
// specifier so they are specific to each network
|
|
||||||
val name1 = UUID.randomUUID().toString()
|
|
||||||
val name2 = UUID.randomUUID().toString()
|
|
||||||
val request1 = NetworkRequest.Builder()
|
|
||||||
.clearCapabilities()
|
|
||||||
.addTransportType(TRANSPORT_TEST)
|
|
||||||
.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name1))
|
|
||||||
.build()
|
|
||||||
val request2 = NetworkRequest.Builder()
|
|
||||||
.clearCapabilities()
|
|
||||||
.addTransportType(TRANSPORT_TEST)
|
|
||||||
.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name2))
|
|
||||||
.build()
|
|
||||||
val callback1 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
|
||||||
val callback2 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
|
||||||
requestNetwork(request1, callback1)
|
|
||||||
requestNetwork(request2, callback2)
|
|
||||||
|
|
||||||
// Then file the interesting request
|
// File the interesting request
|
||||||
val request = NetworkRequest.Builder()
|
|
||||||
.clearCapabilities()
|
|
||||||
.addTransportType(TRANSPORT_TEST)
|
|
||||||
.build()
|
|
||||||
val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
||||||
requestNetwork(request, callback)
|
requestNetwork(makeTestNetworkRequest(), callback)
|
||||||
|
|
||||||
// Connect the first Network
|
// Connect the first Network, with an unused callback that kept the network up.
|
||||||
createConnectedNetworkAgent(name = name1).let { (agent1, _) ->
|
val (agent1, _) = createConnectedNetworkAgent()
|
||||||
callback.expectAvailableThenValidatedCallbacks(agent1.network)
|
callback.expectAvailableThenValidatedCallbacks(agent1.network!!)
|
||||||
// If using the int ranking, agent1 must be upgraded to a better score so that there is
|
// If using the int ranking, agent1 must be upgraded to a better score so that there is
|
||||||
// no ambiguity when agent2 connects that agent1 is still better. If using policy
|
// no ambiguity when agent2 connects that agent1 is still better. If using policy
|
||||||
// ranking, this is not necessary.
|
// ranking, this is not necessary.
|
||||||
agent1.sendNetworkScore(NetworkScore.Builder().setLegacyInt(BETTER_NETWORK_SCORE)
|
agent1.sendNetworkScore(NetworkScore.Builder().setLegacyInt(BETTER_NETWORK_SCORE)
|
||||||
.build())
|
.build())
|
||||||
// Connect the second agent
|
|
||||||
createConnectedNetworkAgent(name = name2).let { (agent2, _) ->
|
// Connect the second agent.
|
||||||
agent2.markConnected()
|
val (agent2, _) = createConnectedNetworkAgent()
|
||||||
// The callback should not see anything yet. With int ranking, agent1 was upgraded
|
// The callback should not see anything yet. With int ranking, agent1 was upgraded
|
||||||
// to a stronger score beforehand. With policy ranking, agent1 is preferred by
|
// to a stronger score beforehand. With policy ranking, agent1 is preferred by
|
||||||
// virtue of already satisfying the request.
|
// virtue of already satisfying the request.
|
||||||
callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
|
callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
|
||||||
// Now downgrade the score and expect the callback now prefers agent2
|
// Now downgrade the score and expect the callback now prefers agent2
|
||||||
agent1.sendNetworkScore(NetworkScore.Builder()
|
agent1.sendNetworkScore(NetworkScore.Builder()
|
||||||
.setLegacyInt(WORSE_NETWORK_SCORE)
|
.setLegacyInt(WORSE_NETWORK_SCORE)
|
||||||
.setExiting(true)
|
.setExiting(true)
|
||||||
.build())
|
.build())
|
||||||
callback.expectCallback<Available>(agent2.network)
|
callback.expectCallback<Available>(agent2.network!!)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// tearDown() will unregister the requests and agents
|
// tearDown() will unregister the requests and agents
|
||||||
}
|
}
|
||||||
@@ -658,7 +640,7 @@ class NetworkAgentTest {
|
|||||||
callback.expectAvailableThenValidatedCallbacks(agent.network!!)
|
callback.expectAvailableThenValidatedCallbacks(agent.network!!)
|
||||||
|
|
||||||
// Check that the default network's transport is propagated to the VPN.
|
// Check that the default network's transport is propagated to the VPN.
|
||||||
var vpnNc = mCM.getNetworkCapabilities(agent.network)
|
var vpnNc = mCM.getNetworkCapabilities(agent.network!!)
|
||||||
assertNotNull(vpnNc)
|
assertNotNull(vpnNc)
|
||||||
assertEquals(VpnManager.TYPE_VPN_SERVICE,
|
assertEquals(VpnManager.TYPE_VPN_SERVICE,
|
||||||
(vpnNc.transportInfo as VpnTransportInfo).type)
|
(vpnNc.transportInfo as VpnTransportInfo).type)
|
||||||
@@ -690,7 +672,7 @@ class NetworkAgentTest {
|
|||||||
// This is not very accurate because the test does not control the capabilities of the
|
// This is not very accurate because the test does not control the capabilities of the
|
||||||
// underlying networks, and because not congested, not roaming, and not suspended are the
|
// underlying networks, and because not congested, not roaming, and not suspended are the
|
||||||
// default anyway. It's still useful as an extra check though.
|
// default anyway. It's still useful as an extra check though.
|
||||||
vpnNc = mCM.getNetworkCapabilities(agent.network)
|
vpnNc = mCM.getNetworkCapabilities(agent.network!!)
|
||||||
for (cap in listOf(NET_CAPABILITY_NOT_CONGESTED,
|
for (cap in listOf(NET_CAPABILITY_NOT_CONGESTED,
|
||||||
NET_CAPABILITY_NOT_ROAMING,
|
NET_CAPABILITY_NOT_ROAMING,
|
||||||
NET_CAPABILITY_NOT_SUSPENDED)) {
|
NET_CAPABILITY_NOT_SUSPENDED)) {
|
||||||
@@ -701,7 +683,7 @@ class NetworkAgentTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unregister(agent)
|
unregister(agent)
|
||||||
callback.expectCallback<Lost>(agent.network)
|
callback.expectCallback<Lost>(agent.network!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unregister(agent: TestableNetworkAgent) {
|
private fun unregister(agent: TestableNetworkAgent) {
|
||||||
@@ -789,43 +771,24 @@ class NetworkAgentTest {
|
|||||||
fun testTemporarilyUnmeteredCapability() {
|
fun testTemporarilyUnmeteredCapability() {
|
||||||
// This test will create a networks with/without NET_CAPABILITY_TEMPORARILY_NOT_METERED
|
// This test will create a networks with/without NET_CAPABILITY_TEMPORARILY_NOT_METERED
|
||||||
// and check that the callback reflects the capability changes.
|
// and check that the callback reflects the capability changes.
|
||||||
// First create a request to make sure the network is kept up
|
|
||||||
val request1 = NetworkRequest.Builder()
|
|
||||||
.clearCapabilities()
|
|
||||||
.addTransportType(TRANSPORT_TEST)
|
|
||||||
.build()
|
|
||||||
val callback1 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS).also {
|
|
||||||
registerNetworkCallback(request1, it)
|
|
||||||
}
|
|
||||||
requestNetwork(request1, callback1)
|
|
||||||
|
|
||||||
// Then file the interesting request
|
|
||||||
val request = NetworkRequest.Builder()
|
|
||||||
.clearCapabilities()
|
|
||||||
.addTransportType(TRANSPORT_TEST)
|
|
||||||
.build()
|
|
||||||
val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
|
||||||
requestNetwork(request, callback)
|
|
||||||
|
|
||||||
// Connect the network
|
// Connect the network
|
||||||
createConnectedNetworkAgent().let { (agent, _) ->
|
val (agent, callback) = createConnectedNetworkAgent()
|
||||||
callback.expectAvailableThenValidatedCallbacks(agent.network)
|
|
||||||
|
|
||||||
// Send TEMP_NOT_METERED and check that the callback is called appropriately.
|
// Send TEMP_NOT_METERED and check that the callback is called appropriately.
|
||||||
val nc1 = NetworkCapabilities(agent.nc)
|
val nc1 = NetworkCapabilities(agent.nc)
|
||||||
.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
|
.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
|
||||||
agent.sendNetworkCapabilities(nc1)
|
agent.sendNetworkCapabilities(nc1)
|
||||||
callback.expectCapabilitiesThat(agent.network) {
|
callback.expectCapabilitiesThat(agent.network!!) {
|
||||||
it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
|
it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove TEMP_NOT_METERED and check that the callback is called appropriately.
|
// Remove TEMP_NOT_METERED and check that the callback is called appropriately.
|
||||||
val nc2 = NetworkCapabilities(agent.nc)
|
val nc2 = NetworkCapabilities(agent.nc)
|
||||||
.removeCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
|
.removeCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
|
||||||
agent.sendNetworkCapabilities(nc2)
|
agent.sendNetworkCapabilities(nc2)
|
||||||
callback.expectCapabilitiesThat(agent.network) {
|
callback.expectCapabilitiesThat(agent.network!!) {
|
||||||
!it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
|
!it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// tearDown() will unregister the requests and agents
|
// tearDown() will unregister the requests and agents
|
||||||
@@ -838,88 +801,137 @@ class NetworkAgentTest {
|
|||||||
// score wins out for a request that matches them both. And the weaker agent will
|
// score wins out for a request that matches them both. And the weaker agent will
|
||||||
// be disconnected after customized linger duration.
|
// be disconnected after customized linger duration.
|
||||||
|
|
||||||
// Connect the first Network
|
// Request the first Network, with a request that could moved to agentStronger in order to
|
||||||
val name1 = UUID.randomUUID().toString()
|
// make agentWeaker linger later.
|
||||||
val name2 = UUID.randomUUID().toString()
|
val specifierWeaker = UUID.randomUUID().toString()
|
||||||
val (agent1, callback) = createConnectedNetworkAgent(name = name1)
|
val specifierStronger = UUID.randomUUID().toString()
|
||||||
callback.expectAvailableThenValidatedCallbacks(agent1.network!!)
|
val commonCallback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
||||||
// Downgrade agent1 to a worse score so that there is no ambiguity when
|
requestNetwork(makeTestNetworkRequest(), commonCallback)
|
||||||
// agent2 connects.
|
val agentWeaker = createNetworkAgent(specifier = specifierWeaker)
|
||||||
agent1.sendNetworkScore(NetworkScore.Builder().setLegacyInt(WORSE_NETWORK_SCORE)
|
agentWeaker.register()
|
||||||
|
agentWeaker.markConnected()
|
||||||
|
commonCallback.expectAvailableThenValidatedCallbacks(agentWeaker.network!!)
|
||||||
|
// Downgrade agentWeaker to a worse score so that there is no ambiguity when
|
||||||
|
// agentStronger connects.
|
||||||
|
agentWeaker.sendNetworkScore(NetworkScore.Builder().setLegacyInt(WORSE_NETWORK_SCORE)
|
||||||
.setExiting(true).build())
|
.setExiting(true).build())
|
||||||
|
|
||||||
// Verify invalid linger duration cannot be set.
|
// Verify invalid linger duration cannot be set.
|
||||||
assertFailsWith<IllegalArgumentException> {
|
assertFailsWith<IllegalArgumentException> {
|
||||||
agent1.setLingerDuration(Duration.ofMillis(-1))
|
agentWeaker.setLingerDuration(Duration.ofMillis(-1))
|
||||||
}
|
}
|
||||||
assertFailsWith<IllegalArgumentException> { agent1.setLingerDuration(Duration.ZERO) }
|
assertFailsWith<IllegalArgumentException> { agentWeaker.setLingerDuration(Duration.ZERO) }
|
||||||
assertFailsWith<IllegalArgumentException> {
|
assertFailsWith<IllegalArgumentException> {
|
||||||
agent1.setLingerDuration(Duration.ofMillis(Integer.MIN_VALUE.toLong()))
|
agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MIN_VALUE.toLong()))
|
||||||
}
|
}
|
||||||
assertFailsWith<IllegalArgumentException> {
|
assertFailsWith<IllegalArgumentException> {
|
||||||
agent1.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong() + 1))
|
agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong() + 1))
|
||||||
}
|
}
|
||||||
assertFailsWith<IllegalArgumentException> {
|
assertFailsWith<IllegalArgumentException> {
|
||||||
agent1.setLingerDuration(Duration.ofMillis(
|
agentWeaker.setLingerDuration(Duration.ofMillis(
|
||||||
NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - 1))
|
NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - 1))
|
||||||
}
|
}
|
||||||
// Verify valid linger timer can be set, but it should not take effect since the network
|
// Verify valid linger timer can be set, but it should not take effect since the network
|
||||||
// is still needed.
|
// is still needed.
|
||||||
agent1.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong()))
|
agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong()))
|
||||||
callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
|
commonCallback.assertNoCallback(NO_CALLBACK_TIMEOUT)
|
||||||
// Set to the value we want to verify the functionality.
|
// Set to the value we want to verify the functionality.
|
||||||
agent1.setLingerDuration(Duration.ofMillis(NetworkAgent.MIN_LINGER_TIMER_MS.toLong()))
|
agentWeaker.setLingerDuration(Duration.ofMillis(NetworkAgent.MIN_LINGER_TIMER_MS.toLong()))
|
||||||
// Make a listener which can observe agent1 lost later.
|
// Make a listener which can observe agentWeaker lost later.
|
||||||
val callbackWeaker = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
val callbackWeaker = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
||||||
registerNetworkCallback(NetworkRequest.Builder()
|
registerNetworkCallback(NetworkRequest.Builder()
|
||||||
.clearCapabilities()
|
.clearCapabilities()
|
||||||
.addTransportType(TRANSPORT_TEST)
|
.addTransportType(TRANSPORT_TEST)
|
||||||
.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name1))
|
.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifierWeaker))
|
||||||
.build(), callbackWeaker)
|
.build(), callbackWeaker)
|
||||||
callbackWeaker.expectAvailableCallbacks(agent1.network!!)
|
callbackWeaker.expectAvailableCallbacks(agentWeaker.network!!)
|
||||||
|
|
||||||
// Connect the second agent with a score better than agent1. Verify the callback for
|
// Connect the agentStronger with a score better than agentWeaker. Verify the callback for
|
||||||
// agent1 sees the linger expiry while the callback for both sees the winner.
|
// agentWeaker sees the linger expiry while the callback for both sees the winner.
|
||||||
// Record linger start timestamp prior to send score to prevent possible race, the actual
|
// Record linger start timestamp prior to send score to prevent possible race, the actual
|
||||||
// timestamp should be slightly late than this since the service handles update
|
// timestamp should be slightly late than this since the service handles update
|
||||||
// network score asynchronously.
|
// network score asynchronously.
|
||||||
val lingerStart = SystemClock.elapsedRealtime()
|
val lingerStart = SystemClock.elapsedRealtime()
|
||||||
val agent2 = createNetworkAgent(name = name2)
|
val agentStronger = createNetworkAgent(specifier = specifierStronger)
|
||||||
agent2.register()
|
agentStronger.register()
|
||||||
agent2.markConnected()
|
agentStronger.markConnected()
|
||||||
callback.expectAvailableCallbacks(agent2.network!!)
|
commonCallback.expectAvailableCallbacks(agentStronger.network!!)
|
||||||
callbackWeaker.expectCallback<Losing>(agent1.network!!)
|
callbackWeaker.expectCallback<Losing>(agentWeaker.network!!)
|
||||||
val expectedRemainingLingerDuration = lingerStart +
|
val expectedRemainingLingerDuration = lingerStart +
|
||||||
NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - SystemClock.elapsedRealtime()
|
NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - SystemClock.elapsedRealtime()
|
||||||
// If the available callback is too late. The remaining duration will be reduced.
|
// If the available callback is too late. The remaining duration will be reduced.
|
||||||
assertTrue(expectedRemainingLingerDuration > 0,
|
assertTrue(expectedRemainingLingerDuration > 0,
|
||||||
"expected remaining linger duration is $expectedRemainingLingerDuration")
|
"expected remaining linger duration is $expectedRemainingLingerDuration")
|
||||||
callbackWeaker.assertNoCallback(expectedRemainingLingerDuration)
|
callbackWeaker.assertNoCallback(expectedRemainingLingerDuration)
|
||||||
callbackWeaker.expectCallback<Lost>(agent1.network!!)
|
callbackWeaker.expectCallback<Lost>(agentWeaker.network!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@IgnoreUpTo(Build.VERSION_CODES.R)
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
fun testSetSubscriberId() {
|
fun testSetSubscriberId() {
|
||||||
val name = "TEST-AGENT"
|
|
||||||
val imsi = UUID.randomUUID().toString()
|
val imsi = UUID.randomUUID().toString()
|
||||||
val config = NetworkAgentConfig.Builder().setSubscriberId(imsi).build()
|
val config = NetworkAgentConfig.Builder().setSubscriberId(imsi).build()
|
||||||
|
|
||||||
val request: NetworkRequest = NetworkRequest.Builder()
|
val (agent, _) = createConnectedNetworkAgent(initialConfig = config)
|
||||||
.clearCapabilities()
|
|
||||||
.addTransportType(TRANSPORT_TEST)
|
|
||||||
.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name))
|
|
||||||
.build()
|
|
||||||
val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
|
||||||
requestNetwork(request, callback)
|
|
||||||
|
|
||||||
val agent = createNetworkAgent(name = name, initialConfig = config)
|
|
||||||
agent.register()
|
|
||||||
agent.markConnected()
|
|
||||||
callback.expectAvailableThenValidatedCallbacks(agent.network!!)
|
|
||||||
val snapshots = runWithShellPermissionIdentity(ThrowingSupplier {
|
val snapshots = runWithShellPermissionIdentity(ThrowingSupplier {
|
||||||
mCM!!.allNetworkStateSnapshots }, NETWORK_SETTINGS)
|
mCM!!.allNetworkStateSnapshots }, NETWORK_SETTINGS)
|
||||||
val testNetworkSnapshot = snapshots.findLast { it.network == agent.network }
|
val testNetworkSnapshot = snapshots.findLast { it.network == agent.network }
|
||||||
assertEquals(imsi, testNetworkSnapshot!!.subscriberId)
|
assertEquals(imsi, testNetworkSnapshot!!.subscriberId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
// TODO: Refactor helper functions to util class and move this test case to
|
||||||
|
// {@link android.net.cts.ConnectivityManagerTest}.
|
||||||
|
fun testRegisterBestMatchingNetworkCallback() {
|
||||||
|
// Register best matching network callback with additional condition that will be
|
||||||
|
// exercised later. This assumes the test network agent has NOT_VCN_MANAGED in it and
|
||||||
|
// does not have NET_CAPABILITY_TEMPORARILY_NOT_METERED.
|
||||||
|
val bestMatchingCb = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
|
||||||
|
registerBestMatchingNetworkCallback(NetworkRequest.Builder()
|
||||||
|
.clearCapabilities()
|
||||||
|
.addTransportType(TRANSPORT_TEST)
|
||||||
|
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
|
||||||
|
.build(), bestMatchingCb, mHandlerThread.threadHandler)
|
||||||
|
|
||||||
|
val (agent1, _) = createConnectedNetworkAgent(specifier = "AGENT-1")
|
||||||
|
bestMatchingCb.expectAvailableThenValidatedCallbacks(agent1.network!!)
|
||||||
|
// Make agent1 worse so when agent2 shows up, the callback will see that.
|
||||||
|
agent1.sendNetworkScore(NetworkScore.Builder().setExiting(true).build())
|
||||||
|
bestMatchingCb.assertNoCallback(NO_CALLBACK_TIMEOUT)
|
||||||
|
|
||||||
|
val (agent2, _) = createConnectedNetworkAgent(specifier = "AGENT-2")
|
||||||
|
bestMatchingCb.expectAvailableDoubleValidatedCallbacks(agent2.network!!)
|
||||||
|
|
||||||
|
// Change something on agent1 to trigger capabilities changed, since the callback
|
||||||
|
// only cares about the best network, verify it received nothing from agent1.
|
||||||
|
val ncAgent1 = agent1.nc
|
||||||
|
ncAgent1.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
|
||||||
|
agent1.sendNetworkCapabilities(ncAgent1)
|
||||||
|
bestMatchingCb.assertNoCallback(NO_CALLBACK_TIMEOUT)
|
||||||
|
|
||||||
|
// Make agent1 the best network again, verify the callback now tracks agent1.
|
||||||
|
agent1.sendNetworkScore(NetworkScore.Builder()
|
||||||
|
.setExiting(false).setTransportPrimary(true).build())
|
||||||
|
bestMatchingCb.expectAvailableCallbacks(agent1.network!!)
|
||||||
|
|
||||||
|
// Make agent1 temporary vcn managed, which will not satisfying the request.
|
||||||
|
// Verify the callback switch from/to the other network accordingly.
|
||||||
|
ncAgent1.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
|
||||||
|
agent1.sendNetworkCapabilities(ncAgent1)
|
||||||
|
bestMatchingCb.expectAvailableCallbacks(agent2.network!!)
|
||||||
|
ncAgent1.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
|
||||||
|
agent1.sendNetworkCapabilities(ncAgent1)
|
||||||
|
bestMatchingCb.expectAvailableDoubleValidatedCallbacks(agent1.network!!)
|
||||||
|
|
||||||
|
// Verify the callback doesn't care about agent2 disconnect.
|
||||||
|
agent2.unregister()
|
||||||
|
agentsToCleanUp.remove(agent2)
|
||||||
|
bestMatchingCb.assertNoCallback()
|
||||||
|
agent1.unregister()
|
||||||
|
agentsToCleanUp.remove(agent1)
|
||||||
|
bestMatchingCb.expectCallback<Lost>(agent1.network!!)
|
||||||
|
|
||||||
|
// tearDown() will unregister the requests and agents
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user