Merge "Add ServiceConnectivityResources to tethering" into sc-dev
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index 320ba8f..4eafc2a 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -25,7 +25,7 @@
srcs: [
"apishim/**/*.java",
"src/**/*.java",
- ":framework-tethering-shared-srcs",
+ ":framework-connectivity-shared-srcs",
":tethering-module-utils-srcs",
":services-tethering-shared-srcs",
],
diff --git a/Tethering/bpf_progs/offload.c b/Tethering/bpf_progs/offload.c
index bfa1e3a..7f9754d 100644
--- a/Tethering/bpf_progs/offload.c
+++ b/Tethering/bpf_progs/offload.c
@@ -600,13 +600,7 @@
return bpf_redirect(v->oif, 0 /* this is effectively BPF_F_EGRESS */);
}
-// Full featured (required) implementations for 5.8+ kernels
-
-DEFINE_BPF_PROG_KVER("schedcls/tether_downstream4_ether$5_8", AID_ROOT, AID_NETWORK_STACK,
- sched_cls_tether_downstream4_ether_5_8, KVER(5, 8, 0))
-(struct __sk_buff* skb) {
- return do_forward4(skb, /* is_ethernet */ true, /* downstream */ true, /* updatetime */ true);
-}
+// Full featured (required) implementations for 5.8+ kernels (these are S+ by definition)
DEFINE_BPF_PROG_KVER("schedcls/tether_downstream4_rawip$5_8", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_rawip_5_8, KVER(5, 8, 0))
@@ -614,28 +608,27 @@
return do_forward4(skb, /* is_ethernet */ false, /* downstream */ true, /* updatetime */ true);
}
-DEFINE_BPF_PROG_KVER("schedcls/tether_upstream4_ether$5_8", AID_ROOT, AID_NETWORK_STACK,
- sched_cls_tether_upstream4_ether_5_8, KVER(5, 8, 0))
-(struct __sk_buff* skb) {
- return do_forward4(skb, /* is_ethernet */ true, /* downstream */ false, /* updatetime */ true);
-}
-
DEFINE_BPF_PROG_KVER("schedcls/tether_upstream4_rawip$5_8", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_rawip_5_8, KVER(5, 8, 0))
(struct __sk_buff* skb) {
return do_forward4(skb, /* is_ethernet */ false, /* downstream */ false, /* updatetime */ true);
}
-// Full featured (optional) implementations for [4.14..5.8) kernels
-
-DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$opt",
- AID_ROOT, AID_NETWORK_STACK,
- sched_cls_tether_downstream4_ether_opt,
- KVER(4, 14, 0), KVER(5, 8, 0))
+DEFINE_BPF_PROG_KVER("schedcls/tether_downstream4_ether$5_8", AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_downstream4_ether_5_8, KVER(5, 8, 0))
(struct __sk_buff* skb) {
return do_forward4(skb, /* is_ethernet */ true, /* downstream */ true, /* updatetime */ true);
}
+DEFINE_BPF_PROG_KVER("schedcls/tether_upstream4_ether$5_8", AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_upstream4_ether_5_8, KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+ return do_forward4(skb, /* is_ethernet */ true, /* downstream */ false, /* updatetime */ true);
+}
+
+// Full featured (optional) implementations for 4.14-S, 4.19-S & 5.4-S kernels
+// (optional, because we need to be able to fallback for 4.14/4.19/5.4 pre-S kernels)
+
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$opt",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_rawip_opt,
@@ -644,14 +637,6 @@
return do_forward4(skb, /* is_ethernet */ false, /* downstream */ true, /* updatetime */ true);
}
-DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_ether$opt",
- AID_ROOT, AID_NETWORK_STACK,
- sched_cls_tether_upstream4_ether_opt,
- KVER(4, 14, 0), KVER(5, 8, 0))
-(struct __sk_buff* skb) {
- return do_forward4(skb, /* is_ethernet */ true, /* downstream */ false, /* updatetime */ true);
-}
-
DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$opt",
AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_rawip_opt,
@@ -660,8 +645,25 @@
return do_forward4(skb, /* is_ethernet */ false, /* downstream */ false, /* updatetime */ true);
}
+DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$opt",
+ AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_downstream4_ether_opt,
+ KVER(4, 14, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+ return do_forward4(skb, /* is_ethernet */ true, /* downstream */ true, /* updatetime */ true);
+}
+
+DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_ether$opt",
+ AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_upstream4_ether_opt,
+ KVER(4, 14, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+ return do_forward4(skb, /* is_ethernet */ true, /* downstream */ false, /* updatetime */ true);
+}
+
// Partial (TCP-only: will not update 'last_used' field) implementations for 4.14+ kernels.
-// These will be loaded only if the above optional ones failed (loading of *these* must succeed).
+// These will be loaded only if the above optional ones failed (loading of *these* must succeed
+// for 5.4+, since that is always an R patched kernel).
//
// [Note: as a result TCP connections will not have their conntrack timeout refreshed, however,
// since /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established defaults to 432000 (seconds),
@@ -671,40 +673,73 @@
// which enforces and documents the required kernel cherrypicks will make it pretty unlikely that
// many devices upgrading to S will end up relying on these fallback programs.
+// RAWIP: Required for 5.4-R kernels -- which always support bpf_skb_change_head().
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$5_4", AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_downstream4_rawip_5_4, KVER(5, 4, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+ return do_forward4(skb, /* is_ethernet */ false, /* downstream */ true, /* updatetime */ false);
+}
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$5_4", AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_upstream4_rawip_5_4, KVER(5, 4, 0), KVER(5, 8, 0))
+(struct __sk_buff* skb) {
+ return do_forward4(skb, /* is_ethernet */ false, /* downstream */ false, /* updatetime */ false);
+}
+
+// RAWIP: Optional for 4.14/4.19 (R) kernels -- which support bpf_skb_change_head().
+// [Note: fallback for 4.14/4.19 (P/Q) kernels is below in stub section]
+
+DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$4_14",
+ AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_downstream4_rawip_4_14,
+ KVER(4, 14, 0), KVER(5, 4, 0))
+(struct __sk_buff* skb) {
+ return do_forward4(skb, /* is_ethernet */ false, /* downstream */ true, /* updatetime */ false);
+}
+
+DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$4_14",
+ AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_upstream4_rawip_4_14,
+ KVER(4, 14, 0), KVER(5, 4, 0))
+(struct __sk_buff* skb) {
+ return do_forward4(skb, /* is_ethernet */ false, /* downstream */ false, /* updatetime */ false);
+}
+
+// ETHER: Required for 4.14-Q/R, 4.19-Q/R & 5.4-R kernels.
+
DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$4_14", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_downstream4_ether_4_14, KVER(4, 14, 0), KVER(5, 8, 0))
(struct __sk_buff* skb) {
return do_forward4(skb, /* is_ethernet */ true, /* downstream */ true, /* updatetime */ false);
}
-DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$4_14", AID_ROOT, AID_NETWORK_STACK,
- sched_cls_tether_downstream4_rawip_4_14, KVER(4, 14, 0), KVER(5, 8, 0))
-(struct __sk_buff* skb) {
- return do_forward4(skb, /* is_ethernet */ false, /* downstream */ true, /* updatetime */ false);
-}
-
DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_ether$4_14", AID_ROOT, AID_NETWORK_STACK,
sched_cls_tether_upstream4_ether_4_14, KVER(4, 14, 0), KVER(5, 8, 0))
(struct __sk_buff* skb) {
return do_forward4(skb, /* is_ethernet */ true, /* downstream */ false, /* updatetime */ false);
}
-DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$4_14", AID_ROOT, AID_NETWORK_STACK,
- sched_cls_tether_upstream4_rawip_4_14, KVER(4, 14, 0), KVER(5, 8, 0))
-(struct __sk_buff* skb) {
- return do_forward4(skb, /* is_ethernet */ false, /* downstream */ false, /* updatetime */ false);
-}
+// Placeholder (no-op) implementations for older Q kernels
-// Placeholder (no-op) implementations for older pre-4.14 kernels
+// RAWIP: 4.9-P/Q, 4.14-P/Q & 4.19-Q kernels -- without bpf_skb_change_head() for tc programs
-DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$stub", AID_ROOT, AID_NETWORK_STACK,
- sched_cls_tether_downstream4_ether_stub, KVER_NONE, KVER(4, 14, 0))
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_downstream4_rawip_stub, KVER_NONE, KVER(5, 4, 0))
(struct __sk_buff* skb) {
return TC_ACT_OK;
}
-DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
- sched_cls_tether_downstream4_rawip_stub, KVER_NONE, KVER(4, 14, 0))
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_upstream4_rawip_stub, KVER_NONE, KVER(5, 4, 0))
+(struct __sk_buff* skb) {
+ return TC_ACT_OK;
+}
+
+// ETHER: 4.9-P/Q kernel
+
+DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_downstream4_ether$stub", AID_ROOT, AID_NETWORK_STACK,
+ sched_cls_tether_downstream4_ether_stub, KVER_NONE, KVER(4, 14, 0))
(struct __sk_buff* skb) {
return TC_ACT_OK;
}
@@ -715,38 +750,74 @@
return TC_ACT_OK;
}
-DEFINE_BPF_PROG_KVER_RANGE("schedcls/tether_upstream4_rawip$stub", AID_ROOT, AID_NETWORK_STACK,
- sched_cls_tether_upstream4_rawip_stub, KVER_NONE, KVER(4, 14, 0))
-(struct __sk_buff* skb) {
- return TC_ACT_OK;
-}
-
// ----- XDP Support -----
DEFINE_BPF_MAP_GRW(tether_xdp_devmap, DEVMAP_HASH, uint32_t, uint32_t, 64,
AID_NETWORK_STACK)
+static inline __always_inline int do_xdp_forward6(struct xdp_md *ctx, const bool is_ethernet,
+ const bool downstream) {
+ return XDP_PASS;
+}
+
+static inline __always_inline int do_xdp_forward4(struct xdp_md *ctx, const bool is_ethernet,
+ const bool downstream) {
+ return XDP_PASS;
+}
+
+static inline __always_inline int do_xdp_forward_ether(struct xdp_md *ctx, const bool downstream) {
+ const void* data = (void*)(long)ctx->data;
+ const void* data_end = (void*)(long)ctx->data_end;
+ const struct ethhdr* eth = data;
+
+ // Make sure we actually have an ethernet header
+ if ((void*)(eth + 1) > data_end) return XDP_PASS;
+
+ if (eth->h_proto == htons(ETH_P_IPV6))
+ return do_xdp_forward6(ctx, /* is_ethernet */ true, downstream);
+ if (eth->h_proto == htons(ETH_P_IP))
+ return do_xdp_forward4(ctx, /* is_ethernet */ true, downstream);
+
+ // Anything else we don't know how to handle...
+ return XDP_PASS;
+}
+
+static inline __always_inline int do_xdp_forward_rawip(struct xdp_md *ctx, const bool downstream) {
+ const void* data = (void*)(long)ctx->data;
+ const void* data_end = (void*)(long)ctx->data_end;
+
+ // The top nibble of both IPv4 and IPv6 headers is the IP version.
+ if (data_end - data < 1) return XDP_PASS;
+ const uint8_t v = (*(uint8_t*)data) >> 4;
+
+ if (v == 6) return do_xdp_forward6(ctx, /* is_ethernet */ false, downstream);
+ if (v == 4) return do_xdp_forward4(ctx, /* is_ethernet */ false, downstream);
+
+ // Anything else we don't know how to handle...
+ return XDP_PASS;
+}
+
#define DEFINE_XDP_PROG(str, func) \
DEFINE_BPF_PROG_KVER(str, AID_ROOT, AID_NETWORK_STACK, func, KVER(5, 9, 0))(struct xdp_md *ctx)
DEFINE_XDP_PROG("xdp/tether_downstream_ether",
xdp_tether_downstream_ether) {
- return XDP_PASS;
+ return do_xdp_forward_ether(ctx, /* downstream */ true);
}
DEFINE_XDP_PROG("xdp/tether_downstream_rawip",
xdp_tether_downstream_rawip) {
- return XDP_PASS;
+ return do_xdp_forward_rawip(ctx, /* downstream */ true);
}
DEFINE_XDP_PROG("xdp/tether_upstream_ether",
xdp_tether_upstream_ether) {
- return XDP_PASS;
+ return do_xdp_forward_ether(ctx, /* downstream */ false);
}
DEFINE_XDP_PROG("xdp/tether_upstream_rawip",
xdp_tether_upstream_rawip) {
- return XDP_PASS;
+ return do_xdp_forward_rawip(ctx, /* downstream */ false);
}
LICENSE("Apache 2.0");
diff --git a/Tethering/jarjar-rules.txt b/Tethering/jarjar-rules.txt
index d1ad569..5de4b97 100644
--- a/Tethering/jarjar-rules.txt
+++ b/Tethering/jarjar-rules.txt
@@ -1,5 +1,5 @@
-# These must be kept in sync with the framework-tethering-shared-srcs filegroup.
-# Classes from the framework-tethering-shared-srcs filegroup.
+# These must be kept in sync with the framework-connectivity-shared-srcs filegroup.
+# Classes from the framework-connectivity-shared-srcs filegroup.
# If there are files in that filegroup that are not covered below, the classes in the
# module will be overwritten by the ones in the framework.
rule com.android.internal.util.** com.android.networkstack.tethering.util.@1
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java
index 3a6350c..3636b03 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java
@@ -16,19 +16,20 @@
package com.android.networkstack.tethering;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
import android.content.Context;
+import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
+import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.os.Handler;
+import android.os.UserHandle;
import java.util.HashMap;
import java.util.HashSet;
@@ -39,6 +40,10 @@
/**
* Simulates upstream switching and sending NetworkCallbacks and CONNECTIVITY_ACTION broadcasts.
*
+ * Unlike any real networking code, this class is single-threaded and entirely synchronous.
+ * The effects of all method calls (including sending fake broadcasts, sending callbacks, etc.) are
+ * performed immediately on the caller's thread before returning.
+ *
* TODO: this duplicates a fair amount of code from ConnectivityManager and ConnectivityService.
* Consider using a ConnectivityService object instead, as used in ConnectivityServiceTest.
*
@@ -63,11 +68,21 @@
public Map<NetworkCallback, Integer> legacyTypeMap = new HashMap<>();
private final NetworkRequest mDefaultRequest;
+ private final Context mContext;
+
private int mNetworkId = 100;
+ /**
+ * Constructs a TestConnectivityManager.
+ * @param ctx the context to use. Must be a fake or a mock because otherwise the test will
+ * attempt to send real broadcasts and resulting in permission denials.
+ * @param svc an IConnectivityManager. Should be a fake or a mock.
+ * @param defaultRequest the default NetworkRequest that will be used by Tethering.
+ */
public TestConnectivityManager(Context ctx, IConnectivityManager svc,
NetworkRequest defaultRequest) {
super(ctx, svc);
+ mContext = ctx;
mDefaultRequest = defaultRequest;
}
@@ -109,6 +124,13 @@
final TestNetworkAgent formerDefault = defaultNetwork;
defaultNetwork = agent;
+ if (formerDefault != null) {
+ sendConnectivityAction(formerDefault.legacyType, false /* connected */);
+ }
+ if (defaultNetwork != null) {
+ sendConnectivityAction(defaultNetwork.legacyType, true /* connected */);
+ }
+
for (NetworkCallback cb : trackingDefault) {
if (defaultNetwork != null) {
cb.onAvailable(defaultNetwork.networkId);
@@ -194,24 +216,72 @@
assertFalse(requested.containsKey(cb));
}
+ private void sendConnectivityAction(int type, boolean connected) {
+ NetworkInfo ni = new NetworkInfo(type, 0 /* subtype */, getNetworkTypeName(type),
+ "" /* subtypeName */);
+ NetworkInfo.DetailedState state = connected
+ ? NetworkInfo.DetailedState.CONNECTED
+ : NetworkInfo.DetailedState.DISCONNECTED;
+ ni.setDetailedState(state, "" /* reason */, "" /* extraInfo */);
+ Intent intent = new Intent(CONNECTIVITY_ACTION);
+ intent.putExtra(EXTRA_NETWORK_INFO, ni);
+ mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ }
+
public static class TestNetworkAgent {
public final TestConnectivityManager cm;
public final Network networkId;
- public final int transportType;
public final NetworkCapabilities networkCapabilities;
public final LinkProperties linkProperties;
+ // TODO: delete when tethering no longer uses CONNECTIVITY_ACTION.
+ public final int legacyType;
- public TestNetworkAgent(TestConnectivityManager cm, int transportType) {
+ public TestNetworkAgent(TestConnectivityManager cm, NetworkCapabilities nc) {
this.cm = cm;
this.networkId = new Network(cm.getNetworkId());
- this.transportType = transportType;
- networkCapabilities = new NetworkCapabilities();
- networkCapabilities.addTransportType(transportType);
- networkCapabilities.addCapability(NET_CAPABILITY_INTERNET);
+ networkCapabilities = copy(nc);
linkProperties = new LinkProperties();
+ legacyType = toLegacyType(nc);
+ }
+
+ public TestNetworkAgent(TestConnectivityManager cm, UpstreamNetworkState state) {
+ this.cm = cm;
+ networkId = state.network;
+ networkCapabilities = state.networkCapabilities;
+ linkProperties = state.linkProperties;
+ this.legacyType = toLegacyType(networkCapabilities);
+ }
+
+ private static int toLegacyType(NetworkCapabilities nc) {
+ for (int type = 0; type < ConnectivityManager.TYPE_TEST; type++) {
+ if (matchesLegacyType(nc, type)) return type;
+ }
+ throw new IllegalArgumentException(("Can't determine legacy type for: ") + nc);
+ }
+
+ private static boolean matchesLegacyType(NetworkCapabilities nc, int legacyType) {
+ final NetworkCapabilities typeNc;
+ try {
+ typeNc = ConnectivityManager.networkCapabilitiesForType(legacyType);
+ } catch (IllegalArgumentException e) {
+ // networkCapabilitiesForType does not support all legacy types.
+ return false;
+ }
+ return typeNc.satisfiedByNetworkCapabilities(nc);
+ }
+
+ private boolean matchesLegacyType(int legacyType) {
+ return matchesLegacyType(networkCapabilities, legacyType);
}
public void fakeConnect() {
+ for (NetworkRequest request : cm.requested.values()) {
+ if (matchesLegacyType(request.legacyType)) {
+ cm.sendConnectivityAction(legacyType, true /* connected */);
+ // In practice, a given network can match only one legacy type.
+ break;
+ }
+ }
for (NetworkCallback cb : cm.listening.keySet()) {
cb.onAvailable(networkId);
cb.onCapabilitiesChanged(networkId, copy(networkCapabilities));
@@ -220,6 +290,12 @@
}
public void fakeDisconnect() {
+ for (NetworkRequest request : cm.requested.values()) {
+ if (matchesLegacyType(request.legacyType)) {
+ cm.sendConnectivityAction(legacyType, false /* connected */);
+ break;
+ }
+ }
for (NetworkCallback cb : cm.listening.keySet()) {
cb.onLost(networkId);
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
index e358f5a..7d735fc 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
@@ -85,6 +85,13 @@
// any specific TRANSPORT_* is sufficient to identify this request.
private static final NetworkRequest sDefaultRequest = new NetworkRequest.Builder().build();
+ private static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_INTERNET).build();
+ private static final NetworkCapabilities DUN_CAPABILITIES = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_DUN).build();
+ private static final NetworkCapabilities WIFI_CAPABILITIES = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_WIFI).addCapability(NET_CAPABILITY_INTERNET).build();
+
@Mock private Context mContext;
@Mock private EntitlementManager mEntitleMgr;
@Mock private IConnectivityManager mCS;
@@ -288,7 +295,7 @@
// There are no networks, so there is nothing to select.
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
- final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
+ final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, WIFI_CAPABILITIES);
wifiAgent.fakeConnect();
// WiFi is up, we should prefer it.
assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
@@ -296,7 +303,7 @@
// There are no networks, so there is nothing to select.
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
- final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
+ final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
cellAgent.fakeConnect();
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
@@ -337,8 +344,7 @@
mUNM.updateMobileRequiresDun(true);
assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
- final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
- dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
+ final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, DUN_CAPABILITIES);
dunAgent.fakeConnect();
// WiFi is still preferred.
@@ -370,7 +376,7 @@
mUNM.updateMobileRequiresDun(false);
// [0] Mobile connects, DUN not required -> mobile selected.
- final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
+ final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
cellAgent.fakeConnect();
mCM.makeDefaultNetwork(cellAgent);
assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
@@ -381,7 +387,7 @@
when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
// [2] WiFi connects but not validated/promoted to default -> mobile selected.
- final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
+ final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, WIFI_CAPABILITIES);
wifiAgent.fakeConnect();
assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
@@ -401,7 +407,7 @@
// into UNM we should test for this here.
// [6] DUN network arrives -> DUN selected
- final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
+ final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
dunAgent.fakeConnect();
@@ -424,7 +430,7 @@
final Set<String> alreadySeen = new HashSet<>();
// [1] Pretend Wi-Fi connects.
- final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
+ final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, WIFI_CAPABILITIES);
final LinkProperties wifiLp = wifiAgent.linkProperties;
wifiLp.setInterfaceName("wlan0");
final String[] wifi_addrs = {
@@ -451,7 +457,7 @@
assertEquals(alreadySeen.size(), local.size());
// [2] Pretend mobile connects.
- final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
+ final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
final LinkProperties cellLp = cellAgent.linkProperties;
cellLp.setInterfaceName("rmnet_data0");
final String[] cell_addrs = {
@@ -472,9 +478,7 @@
assertEquals(alreadySeen.size(), local.size());
// [3] Pretend DUN connects.
- final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
- dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
- dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
+ final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, DUN_CAPABILITIES);
final LinkProperties dunLp = dunAgent.linkProperties;
dunLp.setInterfaceName("rmnet_data1");
final String[] dun_addrs = {
@@ -524,11 +528,11 @@
mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
// Setup wifi and make wifi as default network.
- final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
+ final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, WIFI_CAPABILITIES);
wifiAgent.fakeConnect();
mCM.makeDefaultNetwork(wifiAgent);
// Setup mobile network.
- final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
+ final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
cellAgent.fakeConnect();
assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
index 9f03af9..89c79d3 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
@@ -152,8 +152,10 @@
// build a meaningful error message
StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
for (Map.Entry<TestDescription, TestResult> resultEntry :
- result.getTestResults().entrySet()) {
- if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
+ result.getTestResults().entrySet()) {
+ final TestStatus testStatus = resultEntry.getValue().getStatus();
+ if (!TestStatus.PASSED.equals(testStatus)
+ && !TestStatus.ASSUMPTION_FAILURE.equals(testStatus)) {
errorBuilder.append(resultEntry.getKey().toString());
errorBuilder.append(":\n");
errorBuilder.append(resultEntry.getValue().getStackTrace());
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 2e273ee..e3208e7 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -85,7 +85,6 @@
import android.net.NetworkRequest;
import android.net.NetworkUtils;
import android.net.SocketKeepalive;
-import android.net.StringNetworkSpecifier;
import android.net.TestNetworkInterface;
import android.net.TestNetworkManager;
import android.net.cts.util.CtsNetUtils;
@@ -113,6 +112,7 @@
import com.android.networkstack.apishim.ConnectivityManagerShimImpl;
import com.android.networkstack.apishim.ConstantsShim;
import com.android.networkstack.apishim.common.ConnectivityManagerShim;
+import com.android.testutils.CompatUtil;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.RecorderCallback.CallbackEntry;
@@ -1597,8 +1597,8 @@
// Test networks do not have NOT_VPN or TRUSTED capabilities by default
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .setNetworkSpecifier(
- new StringNetworkSpecifier(testNetworkInterface.getInterfaceName()))
+ .setNetworkSpecifier(CompatUtil.makeTestNetworkSpecifier(
+ testNetworkInterface.getInterfaceName()))
.build();
// Verify background network cannot be requested without NETWORK_SETTINGS permission.
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 1046b50..827a05e 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -46,7 +46,6 @@
import android.net.NetworkRequest
import android.net.RouteInfo
import android.net.SocketKeepalive
-import android.net.StringNetworkSpecifier
import android.net.Uri
import android.net.VpnManager
import android.net.VpnTransportInfo
@@ -70,6 +69,7 @@
import com.android.connectivity.aidl.INetworkAgentRegistry
import com.android.modules.utils.build.SdkLevel
import com.android.net.module.util.ArrayTrackRecord
+import com.android.testutils.CompatUtil
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
import com.android.testutils.RecorderCallback.CallbackEntry.Available
@@ -218,8 +218,6 @@
data class OnSignalStrengthThresholdsUpdated(val thresholds: IntArray) : CallbackEntry()
}
- fun getName(): String? = (nc.getNetworkSpecifier() as? StringNetworkSpecifier)?.specifier
-
override fun onBandwidthUpdateRequested() {
history.add(OnBandwidthUpdateRequested)
}
@@ -327,7 +325,7 @@
addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
}
if (null != name) {
- setNetworkSpecifier(StringNetworkSpecifier(name))
+ setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name))
}
}
val lp = initialLp ?: LinkProperties().apply {
@@ -503,12 +501,12 @@
val request1 = NetworkRequest.Builder()
.clearCapabilities()
.addTransportType(TRANSPORT_TEST)
- .setNetworkSpecifier(StringNetworkSpecifier(name1))
+ .setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name1))
.build()
val request2 = NetworkRequest.Builder()
.clearCapabilities()
.addTransportType(TRANSPORT_TEST)
- .setNetworkSpecifier(StringNetworkSpecifier(name2))
+ .setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(name2))
.build()
val callback1 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
val callback2 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
index 31dc64d..30c4e72 100644
--- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
+++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
@@ -21,7 +21,6 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
@@ -50,6 +49,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.modules.utils.build.SdkLevel;
+import com.android.networkstack.apishim.ConstantsShim;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -161,7 +161,7 @@
private void addNotVcnManagedCapability(@NonNull NetworkCapabilities nc) {
if (SdkLevel.isAtLeastS()) {
- nc.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
+ nc.addCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED);
}
}
@@ -303,68 +303,73 @@
public void testBypassingVcnForNonInternetRequest() {
// Make an empty request. Verify the NOT_VCN_MANAGED is added.
final NetworkRequest emptyRequest = new NetworkRequest.Builder().build();
- assertTrue(emptyRequest.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ assertTrue(emptyRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
// Make a request explicitly add NOT_VCN_MANAGED. Verify the NOT_VCN_MANAGED is preserved.
final NetworkRequest mmsAddNotVcnRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_MMS)
- .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ .addCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED)
.build();
- assertTrue(mmsAddNotVcnRequest.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ assertTrue(mmsAddNotVcnRequest.hasCapability(
+ ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
// Similar to above, but the opposite order.
final NetworkRequest mmsAddNotVcnRequest2 = new NetworkRequest.Builder()
- .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ .addCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED)
.addCapability(NET_CAPABILITY_MMS)
.build();
- assertTrue(mmsAddNotVcnRequest2.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ assertTrue(mmsAddNotVcnRequest2.hasCapability(
+ ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
// Make a request explicitly remove NOT_VCN_MANAGED. Verify the NOT_VCN_MANAGED is removed.
final NetworkRequest removeNotVcnRequest = new NetworkRequest.Builder()
- .removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED).build();
- assertFalse(removeNotVcnRequest.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ .removeCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED).build();
+ assertFalse(removeNotVcnRequest.hasCapability(
+ ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
// Make a request add some capability inside VCN supported capabilities.
// Verify the NOT_VCN_MANAGED is added.
final NetworkRequest notRoamRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_NOT_ROAMING).build();
- assertTrue(notRoamRequest.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ assertTrue(notRoamRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
// Make a internet request. Verify the NOT_VCN_MANAGED is added.
final NetworkRequest internetRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_INTERNET).build();
- assertTrue(internetRequest.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ assertTrue(internetRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
// Make a internet request which explicitly removed NOT_VCN_MANAGED.
// Verify the NOT_VCN_MANAGED is removed.
final NetworkRequest internetRemoveNotVcnRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_INTERNET)
- .removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED).build();
- assertFalse(internetRemoveNotVcnRequest.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ .removeCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED).build();
+ assertFalse(internetRemoveNotVcnRequest.hasCapability(
+ ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
// Make a normal MMS request. Verify the request could bypass VCN.
final NetworkRequest mmsRequest =
new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build();
- assertFalse(mmsRequest.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ assertFalse(mmsRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
// Make a SUPL request along with internet. Verify NOT_VCN_MANAGED is not added since
// SUPL is not in the supported list.
final NetworkRequest suplWithInternetRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_SUPL)
.addCapability(NET_CAPABILITY_INTERNET).build();
- assertFalse(suplWithInternetRequest.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ assertFalse(suplWithInternetRequest.hasCapability(
+ ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
// Make a FOTA request with explicitly add NOT_VCN_MANAGED capability. Verify
// NOT_VCN_MANAGED is preserved.
final NetworkRequest fotaRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_FOTA)
- .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED).build();
- assertTrue(fotaRequest.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ .addCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED).build();
+ assertTrue(fotaRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
// Make a DUN request, which is in {@code VCN_SUPPORTED_CAPABILITIES}.
// Verify NOT_VCN_MANAGED is preserved.
final NetworkRequest dunRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_DUN).build();
- assertTrue(dunRequest.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED));
+ assertTrue(dunRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
}
}