Merge changes Id598ae1d,I475bd011
* changes:
Fix a possible crash when the listener is null
Straighten AIDL interface for the memory store
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 2906710..0e10de8 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -510,7 +510,7 @@
* The absence of a connection type.
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
public static final int TYPE_NONE = -1;
/**
@@ -627,7 +627,7 @@
* {@hide}
*/
@Deprecated
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
public static final int TYPE_MOBILE_FOTA = 10;
/**
@@ -645,7 +645,7 @@
* {@hide}
*/
@Deprecated
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
public static final int TYPE_MOBILE_CBS = 12;
/**
@@ -655,7 +655,7 @@
* {@hide}
*/
@Deprecated
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
public static final int TYPE_WIFI_P2P = 13;
/**
@@ -674,7 +674,7 @@
* {@hide}
*/
@Deprecated
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
public static final int TYPE_MOBILE_EMERGENCY = 15;
/**
@@ -775,7 +775,7 @@
*/
public static final String PRIVATE_DNS_DEFAULT_MODE_FALLBACK = PRIVATE_DNS_MODE_OPPORTUNISTIC;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
private final IConnectivityManager mService;
/**
* A kludge to facilitate static access where a Context pointer isn't available, like in the
@@ -867,7 +867,7 @@
* {@hide}
*/
@Deprecated
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
public static boolean isNetworkTypeMobile(int networkType) {
switch (networkType) {
case TYPE_MOBILE:
@@ -1304,7 +1304,7 @@
*/
@Deprecated
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
public LinkProperties getLinkProperties(int networkType) {
try {
return mService.getLinkPropertiesForType(networkType);
@@ -3042,7 +3042,7 @@
*/
@Deprecated
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
public boolean isNetworkSupported(int networkType) {
try {
return mService.isNetworkSupported(networkType);
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java
index b6c4fe2..68826cb 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/core/java/android/net/DnsResolver.java
@@ -197,7 +197,7 @@
final FileDescriptor queryfd;
try {
queryfd = resNetworkSend((network != null
- ? network.netId : NETID_UNSET), query, query.length, flags);
+ ? network.getNetIdForResolv() : NETID_UNSET), query, query.length, flags);
} catch (ErrnoException e) {
executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
return;
@@ -238,7 +238,7 @@
final FileDescriptor queryfd;
try {
queryfd = resNetworkQuery((network != null
- ? network.netId : NETID_UNSET), domain, nsClass, nsType, flags);
+ ? network.getNetIdForResolv() : NETID_UNSET), domain, nsClass, nsType, flags);
} catch (ErrnoException e) {
executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
return;
@@ -346,7 +346,8 @@
if (queryIpv6) {
try {
v6fd = resNetworkQuery((network != null
- ? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_AAAA, flags);
+ ? network.getNetIdForResolv() : NETID_UNSET),
+ domain, CLASS_IN, TYPE_AAAA, flags);
} catch (ErrnoException e) {
executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
return;
@@ -365,7 +366,8 @@
if (queryIpv4) {
try {
v4fd = resNetworkQuery((network != null
- ? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_A, flags);
+ ? network.getNetIdForResolv() : NETID_UNSET),
+ domain, CLASS_IN, TYPE_A, flags);
} catch (ErrnoException e) {
if (queryIpv6) resNetworkCancel(v6fd); // Closes fd, marks it invalid.
executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
@@ -423,7 +425,7 @@
final FileDescriptor queryfd;
try {
queryfd = resNetworkQuery((network != null
- ? network.netId : NETID_UNSET), domain, CLASS_IN, nsType, flags);
+ ? network.getNetIdForResolv() : NETID_UNSET), domain, CLASS_IN, nsType, flags);
} catch (ErrnoException e) {
executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
return;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index c1aff75..244fef4 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -634,7 +634,8 @@
* the first network for a given type changes, or if the default network
* changes.
*/
- private class LegacyTypeTracker {
+ @VisibleForTesting
+ static class LegacyTypeTracker {
private static final boolean DBG = true;
private static final boolean VDBG = false;
@@ -660,10 +661,12 @@
* - dump is thread-safe with respect to concurrent add and remove calls.
*/
private final ArrayList<NetworkAgentInfo> mTypeLists[];
+ @NonNull
+ private final ConnectivityService mService;
- public LegacyTypeTracker() {
- mTypeLists = (ArrayList<NetworkAgentInfo>[])
- new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
+ LegacyTypeTracker(@NonNull ConnectivityService service) {
+ mService = service;
+ mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
}
public void addSupportedType(int type) {
@@ -712,10 +715,10 @@
}
// Send a broadcast if this is the first network of its type or if it's the default.
- final boolean isDefaultNetwork = isDefaultNetwork(nai);
+ final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
if ((list.size() == 1) || isDefaultNetwork) {
maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork);
- sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
+ mService.sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
}
}
@@ -737,15 +740,15 @@
if (wasFirstNetwork || wasDefault) {
maybeLogBroadcast(nai, state, type, wasDefault);
- sendLegacyNetworkBroadcast(nai, state, type);
+ mService.sendLegacyNetworkBroadcast(nai, state, type);
}
if (!list.isEmpty() && wasFirstNetwork) {
if (DBG) log("Other network available for type " + type +
", sending connected broadcast");
final NetworkAgentInfo replacement = list.get(0);
- maybeLogBroadcast(replacement, state, type, isDefaultNetwork(replacement));
- sendLegacyNetworkBroadcast(replacement, state, type);
+ maybeLogBroadcast(replacement, state, type, mService.isDefaultNetwork(replacement));
+ mService.sendLegacyNetworkBroadcast(replacement, state, type);
}
}
@@ -760,7 +763,7 @@
// send out another legacy broadcast - currently only used for suspend/unsuspend
// toggle
public void update(NetworkAgentInfo nai) {
- final boolean isDefault = isDefaultNetwork(nai);
+ final boolean isDefault = mService.isDefaultNetwork(nai);
final DetailedState state = nai.networkInfo.getDetailedState();
for (int type = 0; type < mTypeLists.length; type++) {
final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
@@ -768,7 +771,7 @@
final boolean isFirst = contains && (nai == list.get(0));
if (isFirst || contains && isDefault) {
maybeLogBroadcast(nai, state, type, isDefault);
- sendLegacyNetworkBroadcast(nai, state, type);
+ mService.sendLegacyNetworkBroadcast(nai, state, type);
}
}
}
@@ -804,7 +807,7 @@
pw.println();
}
}
- private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker();
+ private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
/**
* Helper class which parses out priority arguments and dumps sections according to their
@@ -5371,7 +5374,8 @@
}
}
- private boolean isDefaultNetwork(NetworkAgentInfo nai) {
+ @VisibleForTesting
+ protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
return nai == getDefaultNetwork();
}
@@ -6671,7 +6675,8 @@
}
}
- private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
+ @VisibleForTesting
+ protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
// The NetworkInfo we actually send out has no bearing on the real
// state of affairs. For example, if the default connection is mobile,
// and a request for HIPRI has just gone away, we need to pretend that
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index 1913635..e33392d 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -34,6 +34,7 @@
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkUtils;
+import android.net.ResolverParamsParcel;
import android.net.Uri;
import android.net.shared.PrivateDnsConfig;
import android.os.Binder;
@@ -311,11 +312,9 @@
public void setDnsConfigurationForNetwork(
int netId, LinkProperties lp, boolean isDefaultNetwork) {
- final String[] assignedServers = NetworkUtils.makeStrings(lp.getDnsServers());
- final String[] domainStrs = getDomainStrings(lp.getDomains());
updateParametersSettings();
- final int[] params = { mSampleValidity, mSuccessThreshold, mMinSamples, mMaxSamples };
+ final ResolverParamsParcel paramsParcel = new ResolverParamsParcel();
// We only use the PrivateDnsConfig data pushed to this class instance
// from ConnectivityService because it works in coordination with
@@ -329,34 +328,44 @@
final boolean useTls = privateDnsCfg.useTls;
final boolean strictMode = privateDnsCfg.inStrictMode();
- final String tlsHostname = strictMode ? privateDnsCfg.hostname : "";
- final String[] tlsServers =
+ paramsParcel.netId = netId;
+ paramsParcel.sampleValiditySeconds = mSampleValidity;
+ paramsParcel.successThreshold = mSuccessThreshold;
+ paramsParcel.minSamples = mMinSamples;
+ paramsParcel.maxSamples = mMaxSamples;
+ paramsParcel.servers = NetworkUtils.makeStrings(lp.getDnsServers());
+ paramsParcel.domains = getDomainStrings(lp.getDomains());
+ paramsParcel.tlsName = strictMode ? privateDnsCfg.hostname : "";
+ paramsParcel.tlsServers =
strictMode ? NetworkUtils.makeStrings(
Arrays.stream(privateDnsCfg.ips)
.filter((ip) -> lp.isReachable(ip))
.collect(Collectors.toList()))
- : useTls ? assignedServers // Opportunistic
+ : useTls ? paramsParcel.servers // Opportunistic
: new String[0]; // Off
-
+ paramsParcel.tlsFingerprints = new String[0];
// Prepare to track the validation status of the DNS servers in the
// resolver config when private DNS is in opportunistic or strict mode.
if (useTls) {
if (!mPrivateDnsValidationMap.containsKey(netId)) {
mPrivateDnsValidationMap.put(netId, new PrivateDnsValidationStatuses());
}
- mPrivateDnsValidationMap.get(netId).updateTrackedDnses(tlsServers, tlsHostname);
+ mPrivateDnsValidationMap.get(netId).updateTrackedDnses(paramsParcel.tlsServers,
+ paramsParcel.tlsName);
} else {
mPrivateDnsValidationMap.remove(netId);
}
- Slog.d(TAG, String.format("setDnsConfigurationForNetwork(%d, %s, %s, %s, %s, %s)",
- netId, Arrays.toString(assignedServers), Arrays.toString(domainStrs),
- Arrays.toString(params), tlsHostname, Arrays.toString(tlsServers)));
- final String[] tlsFingerprints = new String[0];
+ Slog.d(TAG, String.format("setDnsConfigurationForNetwork(%d, %s, %s, %d, %d, %d, %d, "
+ + "%d, %d, %s, %s)", paramsParcel.netId, Arrays.toString(paramsParcel.servers),
+ Arrays.toString(paramsParcel.domains), paramsParcel.sampleValiditySeconds,
+ paramsParcel.successThreshold, paramsParcel.minSamples,
+ paramsParcel.maxSamples, paramsParcel.baseTimeoutMsec,
+ paramsParcel.retryCount, paramsParcel.tlsName,
+ Arrays.toString(paramsParcel.tlsServers)));
+
try {
- mDnsResolver.setResolverConfiguration(
- netId, assignedServers, domainStrs, params,
- tlsHostname, tlsServers, tlsFingerprints);
+ mDnsResolver.setResolverConfiguration(paramsParcel);
} catch (RemoteException | ServiceSpecificException e) {
Slog.e(TAG, "Error setting DNS configuration: " + e);
return;
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 35f7ea3..77a18e2 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -191,6 +191,7 @@
case NOT_STARTED : return "NOT_STARTED";
case STARTING : return "STARTING";
case STARTED : return "STARTED";
+ case STOPPING : return "STOPPING";
}
throw new IllegalArgumentException("Unknown state");
}
@@ -314,18 +315,27 @@
Log.e(TAG, "Cannot stop unowned keepalive " + mSlot + " on " + mNai.network);
}
}
- if (NOT_STARTED != mStartedState) {
- mStartedState = STOPPING;
- Log.d(TAG, "Stopping keepalive " + mSlot + " on " + mNai.name());
- if (mType == TYPE_NATT) {
- mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot);
- } else if (mType == TYPE_TCP) {
- mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot);
- mNai.asyncChannel.sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, mSlot);
- mTcpController.stopSocketMonitor(mSlot);
- } else {
- Log.wtf(TAG, "Stopping keepalive with unknown type: " + mType);
- }
+ Log.d(TAG, "Stopping keepalive " + mSlot + " on " + mNai.name() + ": " + reason);
+ switch (mStartedState) {
+ case NOT_STARTED:
+ // Remove the reference of the keepalive that meet error before starting,
+ // e.g. invalid parameter.
+ cleanupStoppedKeepalive(mNai, mSlot);
+ break;
+ case STOPPING:
+ // Keepalive is already in stopping state, ignore.
+ return;
+ default:
+ mStartedState = STOPPING;
+ if (mType == TYPE_NATT) {
+ mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot);
+ } else if (mType == TYPE_TCP) {
+ mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot);
+ mNai.asyncChannel.sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, mSlot);
+ mTcpController.stopSocketMonitor(mSlot);
+ } else {
+ Log.wtf(TAG, "Stopping keepalive with unknown type: " + mType);
+ }
}
// Close the duplicated fd that maintains the lifecycle of socket whenever
@@ -405,9 +415,9 @@
for (KeepaliveInfo ki : networkKeepalives.values()) {
ki.stop(reason);
}
- networkKeepalives.clear();
- mKeepalives.remove(nai);
}
+ // Clean up keepalives will be done as a result of calling ki.stop() after the slots are
+ // freed.
}
public void handleStopKeepalive(NetworkAgentInfo nai, int slot, int reason) {
@@ -423,8 +433,24 @@
return;
}
ki.stop(reason);
+ // Clean up keepalives will be done as a result of calling ki.stop() after the slots are
+ // freed.
+ }
+
+ private void cleanupStoppedKeepalive(NetworkAgentInfo nai, int slot) {
+ String networkName = (nai == null) ? "(null)" : nai.name();
+ HashMap<Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(nai);
+ if (networkKeepalives == null) {
+ Log.e(TAG, "Attempt to remove keepalive on nonexistent network " + networkName);
+ return;
+ }
+ KeepaliveInfo ki = networkKeepalives.get(slot);
+ if (ki == null) {
+ Log.e(TAG, "Attempt to remove nonexistent keepalive " + slot + " on " + networkName);
+ return;
+ }
networkKeepalives.remove(slot);
- Log.d(TAG, "Stopped keepalive " + slot + " on " + networkName + ", "
+ Log.d(TAG, "Remove keepalive " + slot + " on " + networkName + ", "
+ networkKeepalives.size() + " remains.");
if (networkKeepalives.isEmpty()) {
mKeepalives.remove(nai);
@@ -495,10 +521,11 @@
handleStopKeepalive(nai, slot, reason);
}
} else if (KeepaliveInfo.STOPPING == ki.mStartedState) {
- // The message indicated result of stopping : don't call handleStopKeepalive.
+ // The message indicated result of stopping : clean up keepalive slots.
Log.d(TAG, "Stopped keepalive " + slot + " on " + nai.name()
+ " stopped: " + reason);
ki.mStartedState = KeepaliveInfo.NOT_STARTED;
+ cleanupStoppedKeepalive(nai, slot);
} else {
Log.wtf(TAG, "Event " + message.what + "," + slot + "," + reason
+ " for keepalive in wrong state: " + ki.toString());
diff --git a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
index 948c690..a1a8e35 100644
--- a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
+++ b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
@@ -33,6 +33,7 @@
import android.util.Pair;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.TrafficStatsConstants;
import libcore.io.IoUtils;
@@ -381,7 +382,8 @@
protected void setupSocket(
int sockType, int protocol, long writeTimeout, long readTimeout, int dstPort)
throws ErrnoException, IOException {
- final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_PROBE);
+ final int oldTag = TrafficStats.getAndSetThreadStatsTag(
+ TrafficStatsConstants.TAG_SYSTEM_PROBE);
try {
mFileDescriptor = Os.socket(mAddressFamily, sockType, protocol);
} finally {
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 9098f90..689abed 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -63,7 +63,7 @@
android_test {
name: "FrameworksNetTests",
defaults: ["FrameworksNetTests-jni-defaults"],
- srcs: ["java/**/*.java"],
+ srcs: ["java/**/*.java", "java/**/*.kt"],
platform_apis: true,
test_suites: ["device-tests"],
certificate: "platform",
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index ee9d785..e3c6c41 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -16,8 +16,6 @@
package com.android.server;
-import static android.content.pm.PackageManager.GET_PERMISSIONS;
-import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.NETID_UNSET;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
@@ -105,7 +103,6 @@
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.net.ConnectivityManager;
@@ -141,6 +138,7 @@
import android.net.NetworkState;
import android.net.NetworkUtils;
import android.net.ProxyInfo;
+import android.net.ResolverParamsParcel;
import android.net.RouteInfo;
import android.net.SocketKeepalive;
import android.net.UidRange;
@@ -274,10 +272,10 @@
@Mock IDnsResolver mMockDnsResolver;
@Mock INetd mMockNetd;
@Mock NetworkStackClient mNetworkStack;
- @Mock PackageManager mPackageManager;
@Mock UserManager mUserManager;
- private ArgumentCaptor<String[]> mStringArrayCaptor = ArgumentCaptor.forClass(String[].class);
+ private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor =
+ ArgumentCaptor.forClass(ResolverParamsParcel.class);
// This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
// do not go through ConnectivityService but talk to netd directly, so they don't automatically
@@ -359,11 +357,6 @@
public Resources getResources() {
return mResources;
}
-
- @Override
- public PackageManager getPackageManager() {
- return mPackageManager;
- }
}
public void waitForIdle(int timeoutMsAsInt) {
@@ -1233,12 +1226,6 @@
Arrays.asList(new UserInfo[] {
new UserInfo(VPN_USER, "", 0),
}));
- when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
- Arrays.asList(new PackageInfo[] {
- buildPackageInfo(/* SYSTEM */ false, APP1_UID),
- buildPackageInfo(/* SYSTEM */ false, APP2_UID),
- buildPackageInfo(/* SYSTEM */ false, VPN_UID)
- }));
// InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
// http://b/25897652 .
@@ -4307,8 +4294,9 @@
}
// Check that there is no port leaked after all keepalives and sockets are closed.
- assertFalse(isUdpPortInUse(srcPort));
- assertFalse(isUdpPortInUse(srcPort2));
+ // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7.
+ // assertFalse(isUdpPortInUse(srcPort));
+ // assertFalse(isUdpPortInUse(srcPort2));
mWiFiNetworkAgent.disconnect();
waitFor(mWiFiNetworkAgent.getDisconnectedCV());
@@ -4436,7 +4424,8 @@
assertEquals(anyIPv4, sa.getAddress());
testPfd.close();
- assertFalse(isUdpPortInUse(srcPort));
+ // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7.
+ // assertFalse(isUdpPortInUse(srcPort));
mWiFiNetworkAgent.disconnect();
waitFor(mWiFiNetworkAgent.getDisconnectedCV());
@@ -4856,16 +4845,13 @@
@Test
public void testBasicDnsConfigurationPushed() throws Exception {
setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
- ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class);
// Clear any interactions that occur as a result of CS starting up.
reset(mMockDnsResolver);
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
waitForIdle();
- verify(mMockDnsResolver, never()).setResolverConfiguration(
- anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
- eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+ verify(mMockDnsResolver, never()).setResolverConfiguration(any());
verifyNoMoreInteractions(mMockDnsResolver);
final LinkProperties cellLp = new LinkProperties();
@@ -4883,35 +4869,33 @@
mCellNetworkAgent.connect(false);
waitForIdle();
// CS tells netd about the empty DNS config for this network.
- verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
- anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
- eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+ verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any());
reset(mMockDnsResolver);
cellLp.addDnsServer(InetAddress.getByName("2001:db8::1"));
mCellNetworkAgent.sendLinkProperties(cellLp);
waitForIdle();
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
- anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
- assertEquals(1, mStringArrayCaptor.getValue().length);
- assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "2001:db8::1"));
+ mResolverParamsParcelCaptor.capture());
+ ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue();
+ assertEquals(1, resolvrParams.servers.length);
+ assertTrue(ArrayUtils.contains(resolvrParams.servers, "2001:db8::1"));
// Opportunistic mode.
- assertTrue(ArrayUtils.contains(tlsServers.getValue(), "2001:db8::1"));
+ assertTrue(ArrayUtils.contains(resolvrParams.tlsServers, "2001:db8::1"));
reset(mMockDnsResolver);
cellLp.addDnsServer(InetAddress.getByName("192.0.2.1"));
mCellNetworkAgent.sendLinkProperties(cellLp);
waitForIdle();
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
- anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
- assertEquals(2, mStringArrayCaptor.getValue().length);
- assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
+ mResolverParamsParcelCaptor.capture());
+ resolvrParams = mResolverParamsParcelCaptor.getValue();
+ assertEquals(2, resolvrParams.servers.length);
+ assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
new String[]{"2001:db8::1", "192.0.2.1"}));
// Opportunistic mode.
- assertEquals(2, tlsServers.getValue().length);
- assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
+ assertEquals(2, resolvrParams.tlsServers.length);
+ assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
new String[]{"2001:db8::1", "192.0.2.1"}));
reset(mMockDnsResolver);
@@ -4924,18 +4908,16 @@
waitForIdle();
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
- anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(TLS_SPECIFIER), eq(TLS_SERVERS), eq(EMPTY_STRING_ARRAY));
- assertEquals(2, mStringArrayCaptor.getValue().length);
- assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
+ mResolverParamsParcelCaptor.capture());
+ resolvrParams = mResolverParamsParcelCaptor.getValue();
+ assertEquals(2, resolvrParams.servers.length);
+ assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
new String[]{"2001:db8::1", "192.0.2.1"}));
reset(mMockDnsResolver);
}
@Test
public void testPrivateDnsSettingsChange() throws Exception {
- ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class);
-
// Clear any interactions that occur as a result of CS starting up.
reset(mMockDnsResolver);
@@ -4950,9 +4932,7 @@
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
waitForIdle();
// CS tells netd about the empty DNS config for this network.
- verify(mMockDnsResolver, never()).setResolverConfiguration(
- anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
- eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+ verify(mMockDnsResolver, never()).setResolverConfiguration(any());
verifyNoMoreInteractions(mMockDnsResolver);
final LinkProperties cellLp = new LinkProperties();
@@ -4973,14 +4953,14 @@
mCellNetworkAgent.connect(false);
waitForIdle();
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
- anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
- assertEquals(2, mStringArrayCaptor.getValue().length);
- assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
+ mResolverParamsParcelCaptor.capture());
+ ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue();
+ assertEquals(2, resolvrParams.tlsServers.length);
+ assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
new String[]{"2001:db8::1", "192.0.2.1"}));
// Opportunistic mode.
- assertEquals(2, tlsServers.getValue().length);
- assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
+ assertEquals(2, resolvrParams.tlsServers.length);
+ assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
new String[]{"2001:db8::1", "192.0.2.1"}));
reset(mMockDnsResolver);
cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
@@ -4995,23 +4975,23 @@
setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com");
verify(mMockDnsResolver, times(1)).setResolverConfiguration(
- anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
- assertEquals(2, mStringArrayCaptor.getValue().length);
- assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
+ mResolverParamsParcelCaptor.capture());
+ resolvrParams = mResolverParamsParcelCaptor.getValue();
+ assertEquals(2, resolvrParams.servers.length);
+ assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
new String[]{"2001:db8::1", "192.0.2.1"}));
reset(mMockDnsResolver);
cellNetworkCallback.assertNoCallback();
setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
- anyInt(), mStringArrayCaptor.capture(), any(), any(),
- eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
- assertEquals(2, mStringArrayCaptor.getValue().length);
- assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
+ mResolverParamsParcelCaptor.capture());
+ resolvrParams = mResolverParamsParcelCaptor.getValue();
+ assertEquals(2, resolvrParams.servers.length);
+ assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
new String[]{"2001:db8::1", "192.0.2.1"}));
- assertEquals(2, tlsServers.getValue().length);
- assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
+ assertEquals(2, resolvrParams.tlsServers.length);
+ assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
new String[]{"2001:db8::1", "192.0.2.1"}));
reset(mMockDnsResolver);
cellNetworkCallback.assertNoCallback();
@@ -5863,9 +5843,7 @@
mCellNetworkAgent.sendLinkProperties(cellLp);
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
- verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
- eq(cellNetId), eq(EMPTY_STRING_ARRAY), any(), any(),
- eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+ verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any());
verifyNoMoreInteractions(mMockNetd);
verifyNoMoreInteractions(mMockDnsResolver);
@@ -5908,10 +5886,10 @@
assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0));
verify(mMockDnsResolver, times(1)).setResolverConfiguration(
- eq(cellNetId), mStringArrayCaptor.capture(), any(), any(),
- eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
- assertEquals(1, mStringArrayCaptor.getValue().length);
- assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "8.8.8.8"));
+ mResolverParamsParcelCaptor.capture());
+ ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue();
+ assertEquals(1, resolvrParams.servers.length);
+ assertTrue(ArrayUtils.contains(resolvrParams.servers, "8.8.8.8"));
// Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked
// linkproperties are cleaned up.
@@ -6168,6 +6146,7 @@
}
@Test
+ @Ignore
public void testFullyRoutedVpnResultsInInterfaceFilteringRules() throws Exception {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName("tun0");
@@ -6194,6 +6173,7 @@
}
@Test
+ @Ignore
public void testLegacyVpnDoesNotResultInInterfaceFilteringRule() throws Exception {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName("tun0");
@@ -6206,6 +6186,8 @@
verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any());
}
+ @Test
+ @Ignore
public void testLocalIpv4OnlyVpnDoesNotResultInInterfaceFilteringRule()
throws Exception {
LinkProperties lp = new LinkProperties();
@@ -6221,6 +6203,7 @@
}
@Test
+ @Ignore
public void testVpnHandoverChangesInterfaceFilteringRule() throws Exception {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName("tun0");
@@ -6270,6 +6253,7 @@
}
@Test
+ @Ignore
public void testUidUpdateChangesInterfaceFilteringRule() throws Exception {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName("tun0");
diff --git a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
new file mode 100644
index 0000000..d983b65
--- /dev/null
+++ b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server
+
+import android.net.ConnectivityManager.TYPE_ETHERNET
+import android.net.ConnectivityManager.TYPE_MOBILE
+import android.net.ConnectivityManager.TYPE_WIFI
+import android.net.ConnectivityManager.TYPE_WIMAX
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.server.ConnectivityService.LegacyTypeTracker
+import com.android.server.connectivity.NetworkAgentInfo
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertSame
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+
+const val UNSUPPORTED_TYPE = TYPE_WIMAX
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class LegacyTypeTrackerTest {
+ private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET)
+
+ private val mMockService = mock(ConnectivityService::class.java).apply {
+ doReturn(false).`when`(this).isDefaultNetwork(any())
+ }
+ private val mTracker = LegacyTypeTracker(mMockService).apply {
+ supportedTypes.forEach {
+ addSupportedType(it)
+ }
+ }
+
+ @Test
+ fun testSupportedTypes() {
+ try {
+ mTracker.addSupportedType(supportedTypes[0])
+ fail("Expected IllegalStateException")
+ } catch (expected: IllegalStateException) {}
+ supportedTypes.forEach {
+ assertTrue(mTracker.isTypeSupported(it))
+ }
+ assertFalse(mTracker.isTypeSupported(UNSUPPORTED_TYPE))
+ }
+
+ @Test
+ fun testAddNetwork() {
+ val mobileNai = mock(NetworkAgentInfo::class.java)
+ val wifiNai = mock(NetworkAgentInfo::class.java)
+ mTracker.add(TYPE_MOBILE, mobileNai)
+ mTracker.add(TYPE_WIFI, wifiNai)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), mobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Make sure adding a second NAI does not change the results.
+ val secondMobileNai = mock(NetworkAgentInfo::class.java)
+ mTracker.add(TYPE_MOBILE, secondMobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), mobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Make sure removing a network that wasn't added for this type is a no-op.
+ mTracker.remove(TYPE_MOBILE, wifiNai, false /* wasDefault */)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), mobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Remove the top network for mobile and make sure the second one becomes the network
+ // of record for this type.
+ mTracker.remove(TYPE_MOBILE, mobileNai, false /* wasDefault */)
+ assertSame(mTracker.getNetworkForType(TYPE_MOBILE), secondMobileNai)
+ assertSame(mTracker.getNetworkForType(TYPE_WIFI), wifiNai)
+ // Make sure adding a network for an unsupported type does not register it.
+ mTracker.add(UNSUPPORTED_TYPE, mobileNai)
+ assertNull(mTracker.getNetworkForType(UNSUPPORTED_TYPE))
+ }
+}