Merge "Immediately create native networks when NetworkAgents register."
This commit is contained in:
@@ -2653,7 +2653,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
final ArrayList<NetworkStateSnapshot> result = new ArrayList<>();
|
||||
for (Network network : getAllNetworks()) {
|
||||
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
|
||||
if (nai != null && nai.everConnected()) {
|
||||
final boolean includeNetwork = (nai != null) && nai.isCreated();
|
||||
if (includeNetwork) {
|
||||
// TODO (b/73321673) : NetworkStateSnapshot contains a copy of the
|
||||
// NetworkCapabilities, which may contain UIDs of apps to which the
|
||||
// network applies. Should the UIDs be cleared so as not to leak or
|
||||
@@ -3879,9 +3880,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
break;
|
||||
}
|
||||
case NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT: {
|
||||
if (!nai.isCreated()) {
|
||||
Log.d(TAG, "unregisterAfterReplacement on uncreated " + nai.toShortString()
|
||||
+ ", tearing down instead");
|
||||
if (!nai.everConnected()) {
|
||||
Log.d(TAG, "unregisterAfterReplacement on never-connected "
|
||||
+ nai.toShortString() + ", tearing down instead");
|
||||
teardownUnneededNetwork(nai);
|
||||
break;
|
||||
}
|
||||
@@ -4466,6 +4467,25 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected static boolean shouldCreateNetworksImmediately() {
|
||||
// Before U, physical networks are only created when the agent advances to CONNECTED.
|
||||
// In U and above, all networks are immediately created when the agent is registered.
|
||||
return SdkLevel.isAtLeastU();
|
||||
}
|
||||
|
||||
private static boolean shouldCreateNativeNetwork(@NonNull NetworkAgentInfo nai,
|
||||
@NonNull NetworkInfo.State state) {
|
||||
if (nai.isCreated()) return false;
|
||||
if (state == NetworkInfo.State.CONNECTED) return true;
|
||||
if (state != NetworkInfo.State.CONNECTING) {
|
||||
// TODO: throw if no WTFs are observed in the field.
|
||||
Log.wtf(TAG, "Uncreated network in invalid state: " + state);
|
||||
return false;
|
||||
}
|
||||
return nai.isVPN() || shouldCreateNetworksImmediately();
|
||||
}
|
||||
|
||||
private static boolean shouldDestroyNativeNetwork(@NonNull NetworkAgentInfo nai) {
|
||||
return nai.isCreated() && !nai.isDestroyed();
|
||||
}
|
||||
@@ -7908,7 +7928,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
if (isDefaultNetwork(networkAgent)) {
|
||||
handleApplyDefaultProxy(newLp.getHttpProxy());
|
||||
} else {
|
||||
} else if (networkAgent.everConnected()) {
|
||||
updateProxy(newLp, oldLp);
|
||||
}
|
||||
|
||||
@@ -7942,6 +7962,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
|
||||
}
|
||||
|
||||
private void applyInitialLinkProperties(@NonNull NetworkAgentInfo nai) {
|
||||
updateLinkProperties(nai, new LinkProperties(nai.linkProperties), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param naData captive portal data from NetworkAgent
|
||||
* @param apiData captive portal data from capport API
|
||||
@@ -9704,21 +9728,32 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
+ oldInfo.getState() + " to " + state);
|
||||
}
|
||||
|
||||
if (!networkAgent.isCreated()
|
||||
&& (state == NetworkInfo.State.CONNECTED
|
||||
|| (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
|
||||
|
||||
if (shouldCreateNativeNetwork(networkAgent, state)) {
|
||||
// A network that has just connected has zero requests and is thus a foreground network.
|
||||
networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
|
||||
|
||||
if (!createNativeNetwork(networkAgent)) return;
|
||||
|
||||
networkAgent.setCreated();
|
||||
|
||||
// If the network is created immediately on register, then apply the LinkProperties now.
|
||||
// Otherwise, this is done further down when the network goes into connected state.
|
||||
// Applying the LinkProperties means that the network is ready to carry traffic -
|
||||
// interfaces and routing rules have been added, DNS servers programmed, etc.
|
||||
// For VPNs, this must be done before the capabilities are updated, because as soon as
|
||||
// that happens, UIDs are routed to the network.
|
||||
if (shouldCreateNetworksImmediately()) {
|
||||
applyInitialLinkProperties(networkAgent);
|
||||
}
|
||||
|
||||
// TODO: should this move earlier? It doesn't seem to have anything to do with whether
|
||||
// a network is created or not.
|
||||
if (networkAgent.propagateUnderlyingCapabilities()) {
|
||||
// Initialize the network's capabilities to their starting values according to the
|
||||
// underlying networks. This ensures that the capabilities are correct before
|
||||
// anything happens to the network.
|
||||
updateCapabilitiesForNetwork(networkAgent);
|
||||
}
|
||||
networkAgent.setCreated();
|
||||
networkAgent.onNetworkCreated();
|
||||
updateAllowedUids(networkAgent, null, networkAgent.networkCapabilities);
|
||||
updateProfileAllowedNetworks();
|
||||
@@ -9732,8 +9767,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities);
|
||||
|
||||
handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig());
|
||||
updateLinkProperties(networkAgent, new LinkProperties(networkAgent.linkProperties),
|
||||
null);
|
||||
if (!shouldCreateNetworksImmediately()) {
|
||||
applyInitialLinkProperties(networkAgent);
|
||||
} else {
|
||||
// The network was created when the agent registered, and the LinkProperties are
|
||||
// already up-to-date. However, updateLinkProperties also makes some changes only
|
||||
// when the network connects. Apply those changes here. On T and below these are
|
||||
// handled by the applyInitialLinkProperties call just above.
|
||||
// TODO: stop relying on updateLinkProperties(..., null) to do this.
|
||||
// If something depends on both LinkProperties and connected state, it should be in
|
||||
// this method as well.
|
||||
networkAgent.clatd.update();
|
||||
updateProxy(networkAgent.linkProperties, null);
|
||||
}
|
||||
|
||||
// If a rate limit has been configured and is applicable to this network (network
|
||||
// provides internet connectivity), apply it. The tc police filter cannot be attached
|
||||
|
||||
@@ -29,9 +29,9 @@ import android.net.LinkProperties
|
||||
import android.net.NattKeepalivePacketData
|
||||
import android.net.Network
|
||||
import android.net.NetworkAgent
|
||||
import android.net.NetworkAgentConfig
|
||||
import android.net.NetworkAgent.INVALID_NETWORK
|
||||
import android.net.NetworkAgent.VALID_NETWORK
|
||||
import android.net.NetworkAgentConfig
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED
|
||||
@@ -46,21 +46,23 @@ import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
|
||||
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
|
||||
import android.net.NetworkCapabilities.TRANSPORT_TEST
|
||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||
import android.net.NetworkCapabilities.TRANSPORT_VPN
|
||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||
import android.net.NetworkInfo
|
||||
import android.net.NetworkProvider
|
||||
import android.net.NetworkReleasedException
|
||||
import android.net.NetworkRequest
|
||||
import android.net.NetworkScore
|
||||
import android.net.RouteInfo
|
||||
import android.net.QosCallback
|
||||
import android.net.QosCallbackException
|
||||
import android.net.QosCallback.QosCallbackRegistrationException
|
||||
import android.net.QosCallbackException
|
||||
import android.net.QosSession
|
||||
import android.net.QosSessionAttributes
|
||||
import android.net.QosSocketInfo
|
||||
import android.net.RouteInfo
|
||||
import android.net.SocketKeepalive
|
||||
import android.net.TestNetworkInterface
|
||||
import android.net.TestNetworkManager
|
||||
import android.net.Uri
|
||||
import android.net.VpnManager
|
||||
import android.net.VpnTransportInfo
|
||||
@@ -71,6 +73,7 @@ import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.Message
|
||||
import android.os.Process
|
||||
import android.os.SystemClock
|
||||
import android.platform.test.annotations.AppModeFull
|
||||
import android.system.OsConstants.IPPROTO_TCP
|
||||
@@ -89,6 +92,7 @@ import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
|
||||
import com.android.testutils.DevSdkIgnoreRunner
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.Available
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatus
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.Losing
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry.Lost
|
||||
@@ -178,6 +182,7 @@ class NetworkAgentTest {
|
||||
private val agentsToCleanUp = mutableListOf<NetworkAgent>()
|
||||
private val callbacksToCleanUp = mutableListOf<TestableNetworkCallback>()
|
||||
private var qosTestSocket: Closeable? = null // either Socket or DatagramSocket
|
||||
private val ifacesToCleanUp = mutableListOf<TestNetworkInterface>()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
@@ -189,6 +194,7 @@ class NetworkAgentTest {
|
||||
fun tearDown() {
|
||||
agentsToCleanUp.forEach { it.unregister() }
|
||||
callbacksToCleanUp.forEach { mCM.unregisterNetworkCallback(it) }
|
||||
ifacesToCleanUp.forEach { it.fileDescriptor.close() }
|
||||
qosTestSocket?.close()
|
||||
mHandlerThread.quitSafely()
|
||||
mHandlerThread.join()
|
||||
@@ -269,7 +275,7 @@ class NetworkAgentTest {
|
||||
removeCapability(NET_CAPABILITY_INTERNET)
|
||||
addCapability(NET_CAPABILITY_NOT_SUSPENDED)
|
||||
addCapability(NET_CAPABILITY_NOT_ROAMING)
|
||||
addCapability(NET_CAPABILITY_NOT_VPN)
|
||||
if (!transports.contains(TRANSPORT_VPN)) addCapability(NET_CAPABILITY_NOT_VPN)
|
||||
if (SdkLevel.isAtLeastS()) {
|
||||
addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
|
||||
}
|
||||
@@ -304,7 +310,7 @@ class NetworkAgentTest {
|
||||
context: Context = realContext,
|
||||
specifier: String? = UUID.randomUUID().toString(),
|
||||
initialConfig: NetworkAgentConfig? = null,
|
||||
expectedInitSignalStrengthThresholds: IntArray? = intArrayOf(),
|
||||
expectedInitSignalStrengthThresholds: IntArray = intArrayOf(),
|
||||
transports: IntArray = intArrayOf()
|
||||
): Pair<TestableNetworkAgent, TestableNetworkCallback> {
|
||||
val callback = TestableNetworkCallback()
|
||||
@@ -317,8 +323,7 @@ class NetworkAgentTest {
|
||||
agent.register()
|
||||
agent.markConnected()
|
||||
agent.expectCallback<OnNetworkCreated>()
|
||||
agent.expectSignalStrengths(expectedInitSignalStrengthThresholds)
|
||||
agent.expectValidationBypassedStatus()
|
||||
agent.expectPostConnectionCallbacks(expectedInitSignalStrengthThresholds)
|
||||
callback.expectAvailableThenValidatedCallbacks(agent.network!!)
|
||||
return agent to callback
|
||||
}
|
||||
@@ -336,6 +341,19 @@ class NetworkAgentTest {
|
||||
mFakeConnectivityService.connect(it.registerForTest(Network(FAKE_NET_ID)))
|
||||
}
|
||||
|
||||
private fun TestableNetworkAgent.expectPostConnectionCallbacks(
|
||||
thresholds: IntArray = intArrayOf()
|
||||
) {
|
||||
expectSignalStrengths(thresholds)
|
||||
expectValidationBypassedStatus()
|
||||
assertNoCallback()
|
||||
}
|
||||
|
||||
private fun createTunInterface(): TestNetworkInterface = realContext.getSystemService(
|
||||
TestNetworkManager::class.java)!!.createTunInterface(emptyList()).also {
|
||||
ifacesToCleanUp.add(it)
|
||||
}
|
||||
|
||||
fun assertLinkPropertiesEventually(
|
||||
n: Network,
|
||||
description: String,
|
||||
@@ -1291,8 +1309,12 @@ class NetworkAgentTest {
|
||||
requestNetwork(makeTestNetworkRequest(specifier = specifier6), callback)
|
||||
val agent6 = createNetworkAgent(specifier = specifier6)
|
||||
val network6 = agent6.register()
|
||||
// No callbacks are sent, so check the LinkProperties to see if the network has connected.
|
||||
assertLinkPropertiesEventuallyNotNull(agent6.network!!)
|
||||
if (SdkLevel.isAtLeastU()) {
|
||||
agent6.expectCallback<OnNetworkCreated>()
|
||||
} else {
|
||||
// No callbacks are sent, so check LinkProperties to wait for the network to be created.
|
||||
assertLinkPropertiesEventuallyNotNull(agent6.network!!)
|
||||
}
|
||||
|
||||
// unregisterAfterReplacement tears down the network immediately.
|
||||
// Approximately check that this is the case by picking an unregister timeout that's longer
|
||||
@@ -1301,8 +1323,9 @@ class NetworkAgentTest {
|
||||
val timeoutMs = agent6.DEFAULT_TIMEOUT_MS.toInt() + 1_000
|
||||
agent6.unregisterAfterReplacement(timeoutMs)
|
||||
agent6.expectCallback<OnNetworkUnwanted>()
|
||||
if (!SdkLevel.isAtLeastT()) {
|
||||
if (!SdkLevel.isAtLeastT() || SdkLevel.isAtLeastU()) {
|
||||
// Before T, onNetworkDestroyed is called even if the network was never created.
|
||||
// On U+, the network was created by register(). Destroying it sends onNetworkDestroyed.
|
||||
agent6.expectCallback<OnNetworkDestroyed>()
|
||||
}
|
||||
// Poll for LinkProperties becoming null, because when onNetworkUnwanted is called, the
|
||||
@@ -1375,4 +1398,101 @@ class NetworkAgentTest {
|
||||
callback.expect<Available>(agent.network!!)
|
||||
callback.eventuallyExpect<Lost> { it.network == agent.network }
|
||||
}
|
||||
|
||||
fun doTestNativeNetworkCreation(expectCreatedImmediately: Boolean, transports: IntArray) {
|
||||
val iface = createTunInterface()
|
||||
val ifName = iface.interfaceName
|
||||
val nc = makeTestNetworkCapabilities(ifName, transports).also {
|
||||
if (transports.contains(TRANSPORT_VPN)) {
|
||||
val sessionId = "NetworkAgentTest-${Process.myPid()}"
|
||||
it.transportInfo = VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, sessionId,
|
||||
/*bypassable=*/ false, /*longLivedTcpConnectionsExpensive=*/ false)
|
||||
it.underlyingNetworks = listOf()
|
||||
}
|
||||
}
|
||||
val lp = LinkProperties().apply {
|
||||
interfaceName = ifName
|
||||
addLinkAddress(LinkAddress("2001:db8::1/64"))
|
||||
addRoute(RouteInfo(IpPrefix("2001:db8::/64"), null /* nextHop */, ifName))
|
||||
addRoute(RouteInfo(IpPrefix("::/0"),
|
||||
InetAddresses.parseNumericAddress("fe80::abcd"),
|
||||
ifName))
|
||||
}
|
||||
|
||||
// File a request containing the agent's specifier to receive callbacks and to ensure that
|
||||
// the agent is not torn down due to being unneeded.
|
||||
val request = makeTestNetworkRequest(specifier = ifName)
|
||||
val requestCallback = TestableNetworkCallback()
|
||||
requestNetwork(request, requestCallback)
|
||||
|
||||
val listenCallback = TestableNetworkCallback()
|
||||
registerNetworkCallback(request, listenCallback)
|
||||
|
||||
// Register the NetworkAgent...
|
||||
val agent = createNetworkAgent(realContext, initialNc = nc, initialLp = lp)
|
||||
val network = agent.register()
|
||||
|
||||
// ... and then change the NetworkCapabilities and LinkProperties.
|
||||
nc.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
|
||||
agent.sendNetworkCapabilities(nc)
|
||||
lp.addLinkAddress(LinkAddress("192.0.2.2/25"))
|
||||
lp.addRoute(RouteInfo(IpPrefix("192.0.2.0/25"), null /* nextHop */, ifName))
|
||||
agent.sendLinkProperties(lp)
|
||||
|
||||
requestCallback.assertNoCallback()
|
||||
listenCallback.assertNoCallback()
|
||||
if (!expectCreatedImmediately) {
|
||||
agent.assertNoCallback()
|
||||
agent.markConnected()
|
||||
agent.expectCallback<OnNetworkCreated>()
|
||||
} else {
|
||||
agent.expectCallback<OnNetworkCreated>()
|
||||
agent.markConnected()
|
||||
}
|
||||
agent.expectPostConnectionCallbacks()
|
||||
|
||||
// onAvailable must be called only when the network connects, and no other callbacks may be
|
||||
// called before that happens. The callbacks report the state of the network as it was when
|
||||
// it connected, so they reflect the NC and LP changes made after registration.
|
||||
requestCallback.expect<Available>(network)
|
||||
listenCallback.expect<Available>(network)
|
||||
|
||||
requestCallback.expect<CapabilitiesChanged>(network) { it.caps.hasCapability(
|
||||
NET_CAPABILITY_TEMPORARILY_NOT_METERED) }
|
||||
listenCallback.expect<CapabilitiesChanged>(network) { it.caps.hasCapability(
|
||||
NET_CAPABILITY_TEMPORARILY_NOT_METERED) }
|
||||
|
||||
requestCallback.expect<LinkPropertiesChanged>(network) { it.lp.equals(lp) }
|
||||
listenCallback.expect<LinkPropertiesChanged>(network) { it.lp.equals(lp) }
|
||||
|
||||
requestCallback.expect<BlockedStatus>()
|
||||
listenCallback.expect<BlockedStatus>()
|
||||
|
||||
// Except for network validation, ensure no more callbacks are sent.
|
||||
requestCallback.expectCaps(network) {
|
||||
it.hasCapability(NET_CAPABILITY_VALIDATED)
|
||||
}
|
||||
listenCallback.expectCaps(network) {
|
||||
it.hasCapability(NET_CAPABILITY_VALIDATED)
|
||||
}
|
||||
unregister(agent)
|
||||
// Lost implicitly checks that no further callbacks happened after connect.
|
||||
requestCallback.expect<Lost>(network)
|
||||
listenCallback.expect<Lost>(network)
|
||||
assertNull(mCM.getLinkProperties(network))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNativeNetworkCreation_PhysicalNetwork() {
|
||||
// On T and below, the native network is only created when the agent connects.
|
||||
// Starting in U, the native network is created as soon as the agent is registered.
|
||||
doTestNativeNetworkCreation(expectCreatedImmediately = SdkLevel.isAtLeastU(),
|
||||
intArrayOf(TRANSPORT_CELLULAR))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNativeNetworkCreation_Vpn() {
|
||||
// VPN networks are always created as soon as the agent is registered.
|
||||
doTestNativeNetworkCreation(expectCreatedImmediately = true, intArrayOf(TRANSPORT_VPN))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3810,6 +3810,12 @@ public class ConnectivityServiceTest {
|
||||
|
||||
mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, callbacks);
|
||||
|
||||
if (mService.shouldCreateNetworksImmediately()) {
|
||||
assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
} else {
|
||||
assertNull(eventOrder.poll());
|
||||
}
|
||||
|
||||
// Connect a network, and file a request for it after it has come up, to ensure the nascent
|
||||
// timer is cleared and the test does not have to wait for it. Filing the request after the
|
||||
// network has come up is necessary because ConnectivityService does not appear to clear the
|
||||
@@ -3817,7 +3823,12 @@ public class ConnectivityServiceTest {
|
||||
// connected.
|
||||
// TODO: fix this bug, file the request before connecting, and remove the waitForIdle.
|
||||
mWiFiAgent.connectWithoutInternet();
|
||||
waitForIdle();
|
||||
if (!mService.shouldCreateNetworksImmediately()) {
|
||||
assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
} else {
|
||||
waitForIdle();
|
||||
assertNull(eventOrder.poll());
|
||||
}
|
||||
mCm.requestNetwork(request, callback);
|
||||
callback.expectAvailableCallbacksUnvalidated(mWiFiAgent);
|
||||
|
||||
@@ -3834,7 +3845,6 @@ public class ConnectivityServiceTest {
|
||||
|
||||
// Disconnect the network and check that events happened in the right order.
|
||||
mCm.unregisterNetworkCallback(callback);
|
||||
assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
assertEquals("onNetworkUnwanted", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
assertEquals("timePasses", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
assertEquals("onNetworkDisconnected", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
@@ -7620,7 +7630,9 @@ public class ConnectivityServiceTest {
|
||||
// Simple connection with initial LP should have updated ifaces.
|
||||
mCellAgent.connect(false);
|
||||
waitForIdle();
|
||||
expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME);
|
||||
List<Network> allNetworks = mService.shouldCreateNetworksImmediately()
|
||||
? cellAndWifi() : onlyCell();
|
||||
expectNotifyNetworkStatus(allNetworks, onlyCell(), MOBILE_IFNAME);
|
||||
reset(mStatsManager);
|
||||
|
||||
// Verify change fields other than interfaces does not trigger a notification to NSS.
|
||||
@@ -7929,9 +7941,13 @@ public class ConnectivityServiceTest {
|
||||
setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
|
||||
|
||||
mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
|
||||
final int netId = mCellAgent.getNetwork().netId;
|
||||
waitForIdle();
|
||||
verify(mMockDnsResolver, never()).setResolverConfiguration(any());
|
||||
verifyNoMoreInteractions(mMockDnsResolver);
|
||||
if (mService.shouldCreateNetworksImmediately()) {
|
||||
verify(mMockDnsResolver, times(1)).createNetworkCache(netId);
|
||||
} else {
|
||||
verify(mMockDnsResolver, never()).setResolverConfiguration(any());
|
||||
}
|
||||
|
||||
final LinkProperties cellLp = new LinkProperties();
|
||||
cellLp.setInterfaceName(MOBILE_IFNAME);
|
||||
@@ -7947,10 +7963,13 @@ public class ConnectivityServiceTest {
|
||||
mCellAgent.sendLinkProperties(cellLp);
|
||||
mCellAgent.connect(false);
|
||||
waitForIdle();
|
||||
|
||||
verify(mMockDnsResolver, times(1)).createNetworkCache(eq(mCellAgent.getNetwork().netId));
|
||||
// CS tells dnsresolver about the empty DNS config for this network.
|
||||
if (!mService.shouldCreateNetworksImmediately()) {
|
||||
// CS tells dnsresolver about the empty DNS config for this network.
|
||||
verify(mMockDnsResolver, times(1)).createNetworkCache(netId);
|
||||
}
|
||||
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any());
|
||||
|
||||
verifyNoMoreInteractions(mMockDnsResolver);
|
||||
reset(mMockDnsResolver);
|
||||
|
||||
cellLp.addDnsServer(InetAddress.getByName("2001:db8::1"));
|
||||
@@ -8065,10 +8084,13 @@ public class ConnectivityServiceTest {
|
||||
mCm.requestNetwork(cellRequest, cellNetworkCallback);
|
||||
|
||||
mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
|
||||
final int netId = mCellAgent.getNetwork().netId;
|
||||
waitForIdle();
|
||||
// CS tells netd about the empty DNS config for this network.
|
||||
verify(mMockDnsResolver, never()).setResolverConfiguration(any());
|
||||
verifyNoMoreInteractions(mMockDnsResolver);
|
||||
if (mService.shouldCreateNetworksImmediately()) {
|
||||
verify(mMockDnsResolver, times(1)).createNetworkCache(netId);
|
||||
} else {
|
||||
verify(mMockDnsResolver, never()).setResolverConfiguration(any());
|
||||
}
|
||||
|
||||
final LinkProperties cellLp = new LinkProperties();
|
||||
cellLp.setInterfaceName(MOBILE_IFNAME);
|
||||
@@ -8087,7 +8109,9 @@ public class ConnectivityServiceTest {
|
||||
mCellAgent.sendLinkProperties(cellLp);
|
||||
mCellAgent.connect(false);
|
||||
waitForIdle();
|
||||
verify(mMockDnsResolver, times(1)).createNetworkCache(eq(mCellAgent.getNetwork().netId));
|
||||
if (!mService.shouldCreateNetworksImmediately()) {
|
||||
verify(mMockDnsResolver, times(1)).createNetworkCache(netId);
|
||||
}
|
||||
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
|
||||
mResolverParamsParcelCaptor.capture());
|
||||
ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue();
|
||||
@@ -8098,6 +8122,7 @@ public class ConnectivityServiceTest {
|
||||
assertEquals(2, resolvrParams.tlsServers.length);
|
||||
assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll(
|
||||
asList("2001:db8::1", "192.0.2.1")));
|
||||
verifyNoMoreInteractions(mMockDnsResolver);
|
||||
reset(mMockDnsResolver);
|
||||
cellNetworkCallback.expect(AVAILABLE, mCellAgent);
|
||||
cellNetworkCallback.expect(NETWORK_CAPS_UPDATED, mCellAgent);
|
||||
@@ -10425,7 +10450,8 @@ public class ConnectivityServiceTest {
|
||||
if (inOrder != null) {
|
||||
return inOrder.verify(t);
|
||||
} else {
|
||||
return verify(t);
|
||||
// times(1) for consistency with the above. InOrder#verify always implies times(1).
|
||||
return verify(t, times(1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10474,6 +10500,21 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void expectNativeNetworkCreated(int netId, int permission, String iface,
|
||||
InOrder inOrder) throws Exception {
|
||||
verifyWithOrder(inOrder, mMockNetd).networkCreate(nativeNetworkConfigPhysical(netId,
|
||||
permission));
|
||||
verifyWithOrder(inOrder, mMockDnsResolver).createNetworkCache(eq(netId));
|
||||
if (iface != null) {
|
||||
verifyWithOrder(inOrder, mMockNetd).networkAddInterface(netId, iface);
|
||||
}
|
||||
}
|
||||
|
||||
private void expectNativeNetworkCreated(int netId, int permission, String iface)
|
||||
throws Exception {
|
||||
expectNativeNetworkCreated(netId, permission, iface, null /* inOrder */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackedLinkProperties() throws Exception {
|
||||
final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24");
|
||||
@@ -10511,11 +10552,8 @@ public class ConnectivityServiceTest {
|
||||
int cellNetId = mCellAgent.getNetwork().netId;
|
||||
waitForIdle();
|
||||
|
||||
verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(cellNetId,
|
||||
INetd.PERMISSION_NONE));
|
||||
expectNativeNetworkCreated(cellNetId, INetd.PERMISSION_NONE, MOBILE_IFNAME);
|
||||
assertRoutesAdded(cellNetId, ipv6Subnet, ipv6Default);
|
||||
verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId));
|
||||
verify(mMockNetd, times(1)).networkAddInterface(cellNetId, MOBILE_IFNAME);
|
||||
final ArrayTrackRecord<ReportedInterfaces>.ReadHead readHead =
|
||||
mDeps.mReportedInterfaceHistory.newReadHead();
|
||||
assertNotNull(readHead.poll(TIMEOUT_MS, ri -> ri.contentEquals(mServiceContext,
|
||||
@@ -15062,7 +15100,7 @@ public class ConnectivityServiceTest {
|
||||
UserHandle testHandle,
|
||||
TestNetworkCallback profileDefaultNetworkCallback,
|
||||
TestNetworkCallback disAllowProfileDefaultNetworkCallback) throws Exception {
|
||||
final InOrder inOrder = inOrder(mMockNetd);
|
||||
final InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver);
|
||||
|
||||
mCellAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
|
||||
mCellAgent.connect(true);
|
||||
@@ -15078,8 +15116,16 @@ public class ConnectivityServiceTest {
|
||||
|
||||
final TestNetworkAgentWrapper workAgent =
|
||||
makeEnterpriseNetworkAgent(profileNetworkPreference.getPreferenceEnterpriseId());
|
||||
if (mService.shouldCreateNetworksImmediately()) {
|
||||
expectNativeNetworkCreated(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM,
|
||||
null /* iface */, inOrder);
|
||||
}
|
||||
if (connectWorkProfileAgentAhead) {
|
||||
workAgent.connect(false);
|
||||
if (!mService.shouldCreateNetworksImmediately()) {
|
||||
expectNativeNetworkCreated(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM,
|
||||
null /* iface */, inOrder);
|
||||
}
|
||||
}
|
||||
|
||||
final TestOnCompleteListener listener = new TestOnCompleteListener();
|
||||
@@ -15119,6 +15165,11 @@ public class ConnectivityServiceTest {
|
||||
|
||||
if (!connectWorkProfileAgentAhead) {
|
||||
workAgent.connect(false);
|
||||
if (!mService.shouldCreateNetworksImmediately()) {
|
||||
inOrder.verify(mMockNetd).networkCreate(
|
||||
nativeNetworkConfigPhysical(workAgent.getNetwork().netId,
|
||||
INetd.PERMISSION_SYSTEM));
|
||||
}
|
||||
}
|
||||
|
||||
profileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent);
|
||||
@@ -15127,8 +15178,6 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
mSystemDefaultNetworkCallback.assertNoCallback();
|
||||
mDefaultNetworkCallback.assertNoCallback();
|
||||
inOrder.verify(mMockNetd).networkCreate(
|
||||
nativeNetworkConfigPhysical(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM));
|
||||
inOrder.verify(mMockNetd).networkAddUidRangesParcel(new NativeUidRangeConfig(
|
||||
workAgent.getNetwork().netId,
|
||||
uidRangeFor(testHandle, profileNetworkPreference),
|
||||
@@ -17647,6 +17696,22 @@ public class ConnectivityServiceTest {
|
||||
verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt());
|
||||
}
|
||||
|
||||
private void verifyMtuSetOnWifiInterfaceOnlyUpToT(int mtu) throws Exception {
|
||||
if (!mService.shouldCreateNetworksImmediately()) {
|
||||
verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu);
|
||||
} else {
|
||||
verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt());
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyMtuSetOnWifiInterfaceOnlyStartingFromU(int mtu) throws Exception {
|
||||
if (mService.shouldCreateNetworksImmediately()) {
|
||||
verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu);
|
||||
} else {
|
||||
verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendLinkPropertiesSetInterfaceMtuBeforeConnect() throws Exception {
|
||||
final int mtu = 1281;
|
||||
@@ -17661,8 +17726,8 @@ public class ConnectivityServiceTest {
|
||||
reset(mMockNetd);
|
||||
|
||||
mWiFiAgent.connect(false /* validated */);
|
||||
// The MTU is always (re-)applied when the network connects.
|
||||
verifyMtuSetOnWifiInterface(mtu);
|
||||
// Before U, the MTU is always (re-)applied when the network connects.
|
||||
verifyMtuSetOnWifiInterfaceOnlyUpToT(mtu);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -17672,13 +17737,13 @@ public class ConnectivityServiceTest {
|
||||
lp.setInterfaceName(WIFI_IFNAME);
|
||||
lp.setMtu(mtu);
|
||||
|
||||
// Registering an agent with an MTU doesn't set the MTU...
|
||||
// Registering an agent with an MTU only sets the MTU on U+.
|
||||
mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp);
|
||||
waitForIdle();
|
||||
verifyMtuNeverSetOnWifiInterface();
|
||||
verifyMtuSetOnWifiInterfaceOnlyStartingFromU(mtu);
|
||||
reset(mMockNetd);
|
||||
|
||||
// ... but prevents future updates with the same MTU from setting the MTU.
|
||||
// Future updates with the same MTU don't set the MTU even on T when it's not set initially.
|
||||
mWiFiAgent.sendLinkProperties(lp);
|
||||
waitForIdle();
|
||||
verifyMtuNeverSetOnWifiInterface();
|
||||
@@ -17691,8 +17756,8 @@ public class ConnectivityServiceTest {
|
||||
reset(mMockNetd);
|
||||
|
||||
mWiFiAgent.connect(false /* validated */);
|
||||
// The MTU is always (re-)applied when the network connects.
|
||||
verifyMtuSetOnWifiInterface(mtu + 1);
|
||||
// Before U, the MTU is always (re-)applied when the network connects.
|
||||
verifyMtuSetOnWifiInterfaceOnlyUpToT(mtu + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user