Merge "Revert "Add unit tests for IKEv2 VPN setup and MOBIKE""
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index 237a645..c3a7a6d 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -26,8 +26,8 @@
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL;
import static android.net.TetheringManager.TETHERING_ETHERNET;
-import static android.net.TetheringTester.RemoteResponder;
-import static android.net.TetheringTester.isIcmpv6Type;
+import static android.net.TetheringTester.isExpectedIcmpv6Packet;
+import static android.net.TetheringTester.isExpectedUdpPacket;
import static android.system.OsConstants.IPPROTO_IP;
import static android.system.OsConstants.IPPROTO_IPV6;
import static android.system.OsConstants.IPPROTO_UDP;
@@ -83,10 +83,7 @@
import com.android.net.module.util.bpf.Tether4Value;
import com.android.net.module.util.bpf.TetherStatsKey;
import com.android.net.module.util.bpf.TetherStatsValue;
-import com.android.net.module.util.structs.EthernetHeader;
-import com.android.net.module.util.structs.Ipv4Header;
import com.android.net.module.util.structs.Ipv6Header;
-import com.android.net.module.util.structs.UdpHeader;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -333,7 +330,7 @@
final long deadline = SystemClock.uptimeMillis() + timeoutMs;
do {
byte[] pkt = reader.popPacket(timeoutMs);
- if (isIcmpv6Type(pkt, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT)) return;
+ if (isExpectedIcmpv6Packet(pkt, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT)) return;
timeoutMs = deadline - SystemClock.uptimeMillis();
} while (timeoutMs > 0);
@@ -793,61 +790,28 @@
@Test
public void testIcmpv6Echo() throws Exception {
- assumeFalse(mEm.isAvailable());
-
- // MyTetheringEventCallback currently only support await first available upstream. Tethering
- // may select internet network as upstream if test network is not available and not be
- // preferred yet. Create test upstream network before enable tethering.
- mUpstreamTracker = createTestUpstream(toList(TEST_IP4_ADDR, TEST_IP6_ADDR),
- toList(TEST_IP4_DNS, TEST_IP6_DNS));
-
- mDownstreamIface = createTestInterface();
- mEm.setIncludeTestInterfaces(true);
-
- final String iface = mTetheredInterfaceRequester.getInterface();
- assertEquals("TetheredInterfaceCallback for unexpected interface",
- mDownstreamIface.getInterfaceName(), iface);
-
- mTetheringEventCallback = enableEthernetTethering(mDownstreamIface.getInterfaceName(),
- mUpstreamTracker.getNetwork());
- assertEquals("onUpstreamChanged for unexpected network", mUpstreamTracker.getNetwork(),
- mTetheringEventCallback.awaitUpstreamChanged());
-
- mDownstreamReader = makePacketReader(mDownstreamIface);
- mUpstreamReader = makePacketReader(mUpstreamTracker.getTestIface());
-
- runPing6Test(new TetheringTester(mDownstreamReader), new RemoteResponder(mUpstreamReader));
+ runPing6Test(initTetheringTester(toList(TEST_IP4_ADDR, TEST_IP6_ADDR),
+ toList(TEST_IP4_DNS, TEST_IP6_DNS)));
}
- private void runPing6Test(TetheringTester tester, RemoteResponder remote) throws Exception {
- // Currently tethering don't have API to tell when ipv6 tethering is available. Thus, let
- // TetheringTester test ipv6 tethering connectivity before testing ipv6.
- // TODO: move to a common place to avoid that every IPv6 test needs to call this function.
- tester.waitForIpv6TetherConnectivityVerified();
-
+ private void runPing6Test(TetheringTester tester) throws Exception {
TetheredDevice tethered = tester.createTetheredDevice(MacAddress.fromString("1:2:3:4:5:6"),
true /* hasIpv6 */);
Inet6Address remoteIp6Addr = (Inet6Address) parseNumericAddress("2400:222:222::222");
ByteBuffer request = Ipv6Utils.buildEchoRequestPacket(tethered.macAddr,
tethered.routerMacAddr, tethered.ipv6Addr, remoteIp6Addr);
- tester.sendPacket(request);
-
- final byte[] echoRequest = remote.getNextMatchedPacket((p) -> {
+ tester.verifyUpload(request, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
- return isIcmpv6Type(p, false /* hasEth */, ICMPV6_ECHO_REQUEST_TYPE);
+ return isExpectedIcmpv6Packet(p, false /* hasEth */, ICMPV6_ECHO_REQUEST_TYPE);
});
- assertNotNull("No icmpv6 echo request in upstream", echoRequest);
ByteBuffer reply = Ipv6Utils.buildEchoReplyPacket(remoteIp6Addr, tethered.ipv6Addr);
- remote.sendPacket(reply);
-
- final byte[] echoReply = tester.getNextMatchedPacket((p) -> {
+ tester.verifyDownload(reply, p -> {
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
- return isIcmpv6Type(p, true /* hasEth */, ICMPV6_ECHO_REPLY_TYPE);
+ return isExpectedIcmpv6Packet(p, true /* hasEth */, ICMPV6_ECHO_REPLY_TYPE);
});
- assertNotNull("No icmpv6 echo reply in downstream", echoReply);
}
// Test network topology:
@@ -879,28 +843,6 @@
private static final ByteBuffer PAYLOAD3 =
ByteBuffer.wrap(new byte[] { (byte) 0x9a, (byte) 0xbc });
- private boolean isExpectedUdpPacket(@NonNull final byte[] rawPacket, boolean hasEther,
- boolean isIpv4, @NonNull final ByteBuffer payload) {
- final ByteBuffer buf = ByteBuffer.wrap(rawPacket);
-
- if (hasEther) {
- if (Struct.parse(EthernetHeader.class, buf) == null) return false;
- }
-
- if (isIpv4) {
- if (Struct.parse(Ipv4Header.class, buf) == null) return false;
- } else {
- if (Struct.parse(Ipv6Header.class, buf) == null) return false;
- }
-
- if (Struct.parse(UdpHeader.class, buf) == null) return false;
-
- if (buf.remaining() != payload.limit()) return false;
-
- return Arrays.equals(Arrays.copyOfRange(buf.array(), buf.position(), buf.limit()),
- payload.array());
- }
-
@NonNull
private ByteBuffer buildUdpPacket(
@Nullable final MacAddress srcMac, @Nullable final MacAddress dstMac,
@@ -964,7 +906,7 @@
// TODO: remove this verification once upstream connected notification race is fixed.
// See #runUdp4Test.
private boolean isIpv4TetherConnectivityVerified(TetheringTester tester,
- RemoteResponder remote, TetheredDevice tethered) throws Exception {
+ TetheredDevice tethered) throws Exception {
final ByteBuffer probePacket = buildUdpPacket(tethered.macAddr,
tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */,
@@ -972,8 +914,7 @@
// Send a UDP packet from client and check the packet can be found on upstream interface.
for (int i = 0; i < TETHER_REACHABILITY_ATTEMPTS; i++) {
- tester.sendPacket(probePacket);
- byte[] expectedPacket = remote.getNextMatchedPacket(p -> {
+ byte[] expectedPacket = tester.testUpload(probePacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, true /* isIpv4 */,
TEST_REACHABILITY_PAYLOAD);
@@ -983,8 +924,7 @@
return false;
}
- private void runUdp4Test(TetheringTester tester, RemoteResponder remote, boolean usingBpf)
- throws Exception {
+ private void runUdp4Test(TetheringTester tester, boolean usingBpf) throws Exception {
final TetheredDevice tethered = tester.createTetheredDevice(MacAddress.fromString(
"1:2:3:4:5:6"), false /* hasIpv6 */);
@@ -994,14 +934,14 @@
// For short term plan, consider using IPv6 RA to get MAC address because the prefix comes
// from upstream. That can guarantee that the routing is ready. Long term plan is that
// refactors upstream connected notification from async to sync.
- assertTrue(isIpv4TetherConnectivityVerified(tester, remote, tethered));
+ assertTrue(isIpv4TetherConnectivityVerified(tester, tethered));
// Send a UDP packet in original direction.
final ByteBuffer originalPacket = buildUdpPacket(tethered.macAddr,
tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */,
PAYLOAD /* payload */);
- tester.verifyUpload(remote, originalPacket, p -> {
+ tester.verifyUpload(originalPacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, true /* isIpv4 */, PAYLOAD);
});
@@ -1011,7 +951,7 @@
final ByteBuffer replyPacket = buildUdpPacket(REMOTE_IP4_ADDR /* srcIp */,
publicIp4Addr /* dstIp */, REMOTE_PORT /* srcPort */, LOCAL_PORT /* dstPort */,
PAYLOAD2 /* payload */);
- remote.verifyDownload(tester, replyPacket, p -> {
+ tester.verifyDownload(replyPacket, p -> {
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, true /* hasEther */, true /* isIpv4 */, PAYLOAD2);
});
@@ -1030,7 +970,7 @@
tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */,
REMOTE_PORT /* dstPort */, PAYLOAD3 /* payload */);
- tester.verifyUpload(remote, originalPacket2, p -> {
+ tester.verifyUpload(originalPacket2, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, true /* isIpv4 */, PAYLOAD3);
});
@@ -1066,7 +1006,7 @@
// Send packets on original direction.
for (int i = 0; i < TX_UDP_PACKET_COUNT; i++) {
- tester.verifyUpload(remote, originalPacket, p -> {
+ tester.verifyUpload(originalPacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, true /* isIpv4 */, PAYLOAD);
});
@@ -1074,7 +1014,7 @@
// Send packets on reply direction.
for (int i = 0; i < RX_UDP_PACKET_COUNT; i++) {
- remote.verifyDownload(tester, replyPacket, p -> {
+ tester.verifyDownload(replyPacket, p -> {
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, true /* hasEther */, true /* isIpv4 */, PAYLOAD2);
});
@@ -1101,8 +1041,8 @@
}
}
- void initializeTethering(List<LinkAddress> upstreamAddresses, List<InetAddress> upstreamDnses)
- throws Exception {
+ private TetheringTester initTetheringTester(List<LinkAddress> upstreamAddresses,
+ List<InetAddress> upstreamDnses) throws Exception {
assumeFalse(mEm.isAvailable());
// MyTetheringEventCallback currently only support await first available upstream. Tethering
@@ -1113,9 +1053,9 @@
mDownstreamIface = createTestInterface();
mEm.setIncludeTestInterfaces(true);
- final String iface = mTetheredInterfaceRequester.getInterface();
+ // Make sure EtherentTracker use "mDownstreamIface" as server mode interface.
assertEquals("TetheredInterfaceCallback for unexpected interface",
- mDownstreamIface.getInterfaceName(), iface);
+ mDownstreamIface.getInterfaceName(), mTetheredInterfaceRequester.getInterface());
mTetheringEventCallback = enableEthernetTethering(mDownstreamIface.getInterfaceName(),
mUpstreamTracker.getNetwork());
@@ -1124,13 +1064,22 @@
mDownstreamReader = makePacketReader(mDownstreamIface);
mUpstreamReader = makePacketReader(mUpstreamTracker.getTestIface());
+
+ final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
+ // Currently tethering don't have API to tell when ipv6 tethering is available. Thus, make
+ // sure tethering already have ipv6 connectivity before testing.
+ if (cm.getLinkProperties(mUpstreamTracker.getNetwork()).hasGlobalIpv6Address()) {
+ waitForRouterAdvertisement(mDownstreamReader, mDownstreamIface.getInterfaceName(),
+ WAIT_RA_TIMEOUT_MS);
+ }
+
+ return new TetheringTester(mDownstreamReader, mUpstreamReader);
}
@Test
@IgnoreAfter(Build.VERSION_CODES.R)
public void testTetherUdpV4UpToR() throws Exception {
- initializeTethering(toList(TEST_IP4_ADDR), toList(TEST_IP4_DNS));
- runUdp4Test(new TetheringTester(mDownstreamReader), new RemoteResponder(mUpstreamReader),
+ runUdp4Test(initTetheringTester(toList(TEST_IP4_ADDR), toList(TEST_IP4_DNS)),
false /* usingBpf */);
}
@@ -1165,15 +1114,13 @@
@Test
@IgnoreUpTo(Build.VERSION_CODES.R)
public void testTetherUdpV4AfterR() throws Exception {
- initializeTethering(toList(TEST_IP4_ADDR), toList(TEST_IP4_DNS));
final String kernelVersion = VintfRuntimeInfo.getKernelVersion();
boolean usingBpf = isUdpOffloadSupportedByKernel(kernelVersion);
if (!usingBpf) {
Log.i(TAG, "testTetherUdpV4AfterR will skip BPF offload test for kernel "
+ kernelVersion);
}
- runUdp4Test(new TetheringTester(mDownstreamReader), new RemoteResponder(mUpstreamReader),
- usingBpf);
+ runUdp4Test(initTetheringTester(toList(TEST_IP4_ADDR), toList(TEST_IP4_DNS)), usingBpf);
}
@Nullable
@@ -1233,8 +1180,8 @@
}
@Nullable
- private Inet6Address getClatIpv6Address(TetheringTester tester,
- RemoteResponder remote, TetheredDevice tethered) throws Exception {
+ private Inet6Address getClatIpv6Address(TetheringTester tester, TetheredDevice tethered)
+ throws Exception {
final ByteBuffer probePacket = buildUdpPacket(tethered.macAddr,
tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */,
@@ -1245,8 +1192,7 @@
// packet.
byte[] expectedPacket = null;
for (int i = 0; i < TETHER_REACHABILITY_ATTEMPTS; i++) {
- tester.sendPacket(probePacket);
- expectedPacket = remote.getNextMatchedPacket(p -> {
+ expectedPacket = tester.verifyUpload(probePacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, false /* isIpv4 */,
TEST_REACHABILITY_PAYLOAD);
@@ -1275,18 +1221,12 @@
// sending out an IPv4 packet and extracting the source address from CLAT translated IPv6
// packet.
//
- private void runClatUdpTest(TetheringTester tester, RemoteResponder remote)
- throws Exception {
- // Currently tethering don't have API to tell when ipv6 tethering is available. Thus, let
- // TetheringTester test ipv6 tethering connectivity before testing ipv6.
- // TODO: move to a common place to avoid that every IPv6 test needs to call this function.
- tester.waitForIpv6TetherConnectivityVerified();
-
+ private void runClatUdpTest(TetheringTester tester) throws Exception {
final TetheredDevice tethered = tester.createTetheredDevice(MacAddress.fromString(
"1:2:3:4:5:6"), true /* hasIpv6 */);
// Get CLAT IPv6 address.
- final Inet6Address clatAddr6 = getClatIpv6Address(tester, remote, tethered);
+ final Inet6Address clatAddr6 = getClatIpv6Address(tester, tethered);
assertNotNull(clatAddr6);
// Send an IPv4 UDP packet in original direction.
@@ -1295,7 +1235,7 @@
tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */,
PAYLOAD /* payload */);
- tester.verifyUpload(remote, originalPacket, p -> {
+ tester.verifyUpload(originalPacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, false /* hasEther */, false /* isIpv4 */, PAYLOAD);
});
@@ -1305,7 +1245,7 @@
final ByteBuffer replyPacket = buildUdpPacket(REMOTE_NAT64_ADDR /* srcIp */,
clatAddr6 /* dstIp */, REMOTE_PORT /* srcPort */, LOCAL_PORT /* dstPort */,
PAYLOAD2 /* payload */);
- remote.verifyDownload(tester, replyPacket, p -> {
+ tester.verifyDownload(replyPacket, p -> {
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, true /* hasEther */, true /* isIpv4 */, PAYLOAD2);
});
@@ -1317,9 +1257,7 @@
@IgnoreUpTo(Build.VERSION_CODES.R)
public void testTetherClatUdp() throws Exception {
// CLAT only starts on IPv6 only network.
- initializeTethering(toList(TEST_IP6_ADDR), toList(TEST_IP6_DNS));
- runClatUdpTest(new TetheringTester(mDownstreamReader),
- new RemoteResponder(mUpstreamReader));
+ runClatUdpTest(initTetheringTester(toList(TEST_IP6_ADDR), toList(TEST_IP6_DNS)));
}
private <T> List<T> toList(T... array) {
diff --git a/Tethering/tests/integration/src/android/net/TetheringTester.java b/Tethering/tests/integration/src/android/net/TetheringTester.java
index 458680a..4d90d39 100644
--- a/Tethering/tests/integration/src/android/net/TetheringTester.java
+++ b/Tethering/tests/integration/src/android/net/TetheringTester.java
@@ -18,11 +18,13 @@
import static android.net.InetAddresses.parseNumericAddress;
import static android.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.IPPROTO_UDP;
import static com.android.net.module.util.NetworkStackConstants.ARP_REPLY;
import static com.android.net.module.util.NetworkStackConstants.ARP_REQUEST;
import static com.android.net.module.util.NetworkStackConstants.ETHER_ADDR_LEN;
import static com.android.net.module.util.NetworkStackConstants.ETHER_BROADCAST;
+import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV4;
import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV6;
import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_PIO;
import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA;
@@ -42,17 +44,20 @@
import android.util.ArrayMap;
import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.net.module.util.Ipv6Utils;
import com.android.net.module.util.Struct;
import com.android.net.module.util.structs.EthernetHeader;
import com.android.net.module.util.structs.Icmpv6Header;
+import com.android.net.module.util.structs.Ipv4Header;
import com.android.net.module.util.structs.Ipv6Header;
import com.android.net.module.util.structs.LlaOption;
import com.android.net.module.util.structs.NsHeader;
import com.android.net.module.util.structs.PrefixInformationOption;
import com.android.net.module.util.structs.RaHeader;
+import com.android.net.module.util.structs.UdpHeader;
import com.android.networkstack.arp.ArpPacket;
import com.android.testutils.TapPacketReader;
@@ -61,6 +66,7 @@
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeoutException;
@@ -88,11 +94,17 @@
private final ArrayMap<MacAddress, TetheredDevice> mTetheredDevices;
private final TapPacketReader mDownstreamReader;
+ private final TapPacketReader mUpstreamReader;
public TetheringTester(TapPacketReader downstream) {
+ this(downstream, null);
+ }
+
+ public TetheringTester(TapPacketReader downstream, TapPacketReader upstream) {
if (downstream == null) fail("Downstream reader could not be NULL");
mDownstreamReader = downstream;
+ mUpstreamReader = upstream;
mTetheredDevices = new ArrayMap<>();
}
@@ -170,7 +182,7 @@
}
private DhcpPacket getNextDhcpPacket() throws Exception {
- final byte[] packet = getNextMatchedPacket((p) -> {
+ final byte[] packet = getDownloadPacket((p) -> {
// Test whether this is DHCP packet.
try {
DhcpPacket.decodeFullPacket(p, p.length, DhcpPacket.ENCAP_L2);
@@ -213,7 +225,7 @@
tethered.ipv4Addr.getAddress() /* sender IP */,
(short) ARP_REPLY);
try {
- sendPacket(arpReply);
+ sendUploadPacket(arpReply);
} catch (Exception e) {
fail("Failed to reply ARP for " + tethered.ipv4Addr);
}
@@ -227,9 +239,9 @@
tetherMac.toByteArray() /* srcMac */, routerIp.getAddress() /* target IP */,
new byte[ETHER_ADDR_LEN] /* target HW address */,
tetherIp.getAddress() /* sender IP */, (short) ARP_REQUEST);
- sendPacket(arpProbe);
+ sendUploadPacket(arpProbe);
- final byte[] packet = getNextMatchedPacket((p) -> {
+ final byte[] packet = getDownloadPacket((p) -> {
final ArpPacket arpPacket = parseArpPacket(p);
if (arpPacket == null || arpPacket.opCode != ARP_REPLY) return false;
return arpPacket.targetIp.equals(tetherIp);
@@ -245,25 +257,11 @@
return null;
}
- public void waitForIpv6TetherConnectivityVerified() throws Exception {
- Log.d(TAG, "Waiting RA multicast");
-
- // Wait for RA multicast message from router to confirm that the IPv6 tethering
- // connectivity is ready. We don't extract the router mac address from RA because
- // we get the router mac address from IPv4 ARP packet. See #getRouterMacAddressFromArp.
- for (int i = 0; i < READ_RA_ATTEMPTS; i++) {
- final byte[] raPacket = getNextMatchedPacket((p) -> {
- return isIcmpv6Type(p, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT);
- });
- if (raPacket != null) return;
- }
-
- fail("Could not get RA multicast packet after " + READ_RA_ATTEMPTS + " attempts");
- }
-
private List<PrefixInformationOption> getRaPrefixOptions(byte[] packet) {
ByteBuffer buf = ByteBuffer.wrap(packet);
- if (!isIcmpv6Type(buf, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT)) return null;
+ if (!isExpectedIcmpv6Packet(buf, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT)) {
+ fail("Parsing RA packet fail");
+ }
Struct.parse(RaHeader.class, buf);
final ArrayList<PrefixInformationOption> pioList = new ArrayList<>();
@@ -290,13 +288,10 @@
private Inet6Address runSlaac(MacAddress srcMac, MacAddress dstMac) throws Exception {
sendRsPacket(srcMac, dstMac);
- final byte[] raPacket = getNextMatchedPacket((p) -> {
- return isIcmpv6Type(p, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT);
- });
+ final byte[] raPacket = verifyPacketNotNull("Receive RA fail", getDownloadPacket(p -> {
+ return isExpectedIcmpv6Packet(p, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT);
+ }));
- if (raPacket == null) {
- fail("Could not get ra for prefix options");
- }
final List<PrefixInformationOption> options = getRaPrefixOptions(raPacket);
for (PrefixInformationOption pio : options) {
@@ -312,7 +307,7 @@
}
}
- fail("Could not get ipv6 address");
+ fail("No available ipv6 prefix");
return null;
}
@@ -322,7 +317,7 @@
ByteBuffer rs = Ipv6Utils.buildRsPacket(srcMac, dstMac, (Inet6Address) LINK_LOCAL,
IPV6_ADDR_ALL_NODES_MULTICAST, slla);
- sendPacket(rs);
+ sendUploadPacket(rs);
}
private void maybeReplyNa(byte[] packet) {
@@ -347,7 +342,7 @@
ByteBuffer ns = Ipv6Utils.buildNaPacket(tethered.macAddr, tethered.routerMacAddr,
nsHdr.target, ipv6Hdr.srcIp, flags, nsHdr.target, tlla);
try {
- sendPacket(ns);
+ sendUploadPacket(ns);
} catch (Exception e) {
fail("Failed to reply NA for " + tethered.ipv6Addr);
}
@@ -356,23 +351,18 @@
}
}
- public static boolean isIcmpv6Type(byte[] packet, boolean hasEth, int type) {
+ public static boolean isExpectedIcmpv6Packet(byte[] packet, boolean hasEth, int type) {
final ByteBuffer buf = ByteBuffer.wrap(packet);
- return isIcmpv6Type(buf, hasEth, type);
+ return isExpectedIcmpv6Packet(buf, hasEth, type);
}
- private static boolean isIcmpv6Type(ByteBuffer buf, boolean hasEth, int type) {
+ private static boolean isExpectedIcmpv6Packet(ByteBuffer buf, boolean hasEth, int type) {
try {
- if (hasEth) {
- final EthernetHeader ethHdr = Struct.parse(EthernetHeader.class, buf);
- if (ethHdr.etherType != ETHER_TYPE_IPV6) return false;
- }
+ if (hasEth && !hasExpectedEtherHeader(buf, false /* isIpv4 */)) return false;
- final Ipv6Header ipv6Hdr = Struct.parse(Ipv6Header.class, buf);
- if (ipv6Hdr.nextHeader != (byte) IPPROTO_ICMPV6) return false;
+ if (!hasExpectedIpHeader(buf, false /* isIpv4 */, IPPROTO_ICMPV6)) return false;
- final Icmpv6Header icmpv6Hdr = Struct.parse(Icmpv6Header.class, buf);
- return icmpv6Hdr.type == (short) type;
+ return Struct.parse(Icmpv6Header.class, buf).type == (short) type;
} catch (Exception e) {
// Parsing packet fail means it is not icmpv6 packet.
}
@@ -380,11 +370,53 @@
return false;
}
- public void sendPacket(ByteBuffer packet) throws Exception {
+ private static boolean hasExpectedEtherHeader(@NonNull final ByteBuffer buf, boolean isIpv4)
+ throws Exception {
+ final int expected = isIpv4 ? ETHER_TYPE_IPV4 : ETHER_TYPE_IPV6;
+
+ return Struct.parse(EthernetHeader.class, buf).etherType == expected;
+ }
+
+ private static boolean hasExpectedIpHeader(@NonNull final ByteBuffer buf, boolean isIpv4,
+ int ipProto) throws Exception {
+ if (isIpv4) {
+ return Struct.parse(Ipv4Header.class, buf).protocol == (byte) ipProto;
+ } else {
+ return Struct.parse(Ipv6Header.class, buf).nextHeader == (byte) ipProto;
+ }
+ }
+
+ public static boolean isExpectedUdpPacket(@NonNull final byte[] rawPacket, boolean hasEth,
+ boolean isIpv4, @NonNull final ByteBuffer payload) {
+ final ByteBuffer buf = ByteBuffer.wrap(rawPacket);
+ try {
+ if (hasEth && !hasExpectedEtherHeader(buf, isIpv4)) return false;
+
+ if (!hasExpectedIpHeader(buf, isIpv4, IPPROTO_UDP)) return false;
+
+ if (Struct.parse(UdpHeader.class, buf) == null) return false;
+ } catch (Exception e) {
+ // Parsing packet fail means it is not udp packet.
+ return false;
+ }
+
+ if (buf.remaining() != payload.limit()) return false;
+
+ return Arrays.equals(Arrays.copyOfRange(buf.array(), buf.position(), buf.limit()),
+ payload.array());
+ }
+
+ private void sendUploadPacket(ByteBuffer packet) throws Exception {
mDownstreamReader.sendResponse(packet);
}
- public byte[] getNextMatchedPacket(Predicate<byte[]> filter) {
+ private void sendDownloadPacket(ByteBuffer packet) throws Exception {
+ assertNotNull("Can't deal with upstream interface in local only mode", mUpstreamReader);
+
+ mUpstreamReader.sendResponse(packet);
+ }
+
+ private byte[] getDownloadPacket(Predicate<byte[]> filter) {
byte[] packet;
while ((packet = mDownstreamReader.poll(PACKET_READ_TIMEOUT_MS)) != null) {
if (filter.test(packet)) return packet;
@@ -396,30 +428,34 @@
return null;
}
- public void verifyUpload(final RemoteResponder dst, final ByteBuffer packet,
- final Predicate<byte[]> filter) throws Exception {
- sendPacket(packet);
- assertNotNull("Upload fail", dst.getNextMatchedPacket(filter));
+ private byte[] getUploadPacket(Predicate<byte[]> filter) {
+ assertNotNull("Can't deal with upstream interface in local only mode", mUpstreamReader);
+
+ return mUpstreamReader.poll(PACKET_READ_TIMEOUT_MS, filter);
}
- public static class RemoteResponder {
- final TapPacketReader mUpstreamReader;
- public RemoteResponder(TapPacketReader reader) {
- mUpstreamReader = reader;
- }
+ private @NonNull byte[] verifyPacketNotNull(String message, @Nullable byte[] packet) {
+ assertNotNull(message, packet);
- public void sendPacket(ByteBuffer packet) throws Exception {
- mUpstreamReader.sendResponse(packet);
- }
+ return packet;
+ }
- public byte[] getNextMatchedPacket(Predicate<byte[]> filter) throws Exception {
- return mUpstreamReader.poll(PACKET_READ_TIMEOUT_MS, filter);
- }
+ public byte[] testUpload(final ByteBuffer packet, final Predicate<byte[]> filter)
+ throws Exception {
+ sendUploadPacket(packet);
- public void verifyDownload(final TetheringTester dst, final ByteBuffer packet,
- final Predicate<byte[]> filter) throws Exception {
- sendPacket(packet);
- assertNotNull("Download fail", dst.getNextMatchedPacket(filter));
- }
+ return getUploadPacket(filter);
+ }
+
+ public byte[] verifyUpload(final ByteBuffer packet, final Predicate<byte[]> filter)
+ throws Exception {
+ return verifyPacketNotNull("Upload fail", testUpload(packet, filter));
+ }
+
+ public byte[] verifyDownload(final ByteBuffer packet, final Predicate<byte[]> filter)
+ throws Exception {
+ sendDownloadPacket(packet);
+
+ return verifyPacketNotNull("Download fail", getDownloadPacket(filter));
}
}
diff --git a/framework/Android.bp b/framework/Android.bp
index d7de439..24d8cca 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -64,7 +64,6 @@
":framework-connectivity-sources",
":net-utils-framework-common-srcs",
":framework-connectivity-api-shared-srcs",
- ":framework-connectivity-javastream-protos",
],
aidl: {
generate_get_transaction_name: true,
@@ -90,6 +89,7 @@
"modules-utils-backgroundthread",
"modules-utils-build",
"modules-utils-preconditions",
+ "framework-connectivity-javastream-protos",
],
libs: [
"app-compat-annotations",
@@ -197,28 +197,16 @@
visibility: ["//frameworks/base"],
}
-gensrcs {
+java_library {
name: "framework-connectivity-javastream-protos",
- depfile: true,
-
- tools: [
- "aprotoc",
- "protoc-gen-javastream",
- "soong_zip",
+ proto: {
+ type: "stream",
+ },
+ srcs: [":framework-connectivity-protos"],
+ installable: false,
+ sdk_version: "module_current",
+ min_sdk_version: "30",
+ apex_available: [
+ "com.android.tethering",
],
-
- cmd: "mkdir -p $(genDir)/$(in) " +
- "&& $(location aprotoc) " +
- " --plugin=$(location protoc-gen-javastream) " +
- " --dependency_out=$(depfile) " +
- " --javastream_out=$(genDir)/$(in) " +
- " -Iexternal/protobuf/src " +
- " -I . " +
- " $(in) " +
- "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
-
- srcs: [
- ":framework-connectivity-protos",
- ],
- output_extension: "srcjar",
}
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index ddac19d..4ce6add 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -51,6 +51,9 @@
field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
field public static final int FIREWALL_CHAIN_DOZABLE = 1; // 0x1
field public static final int FIREWALL_CHAIN_LOW_POWER_STANDBY = 5; // 0x5
+ field public static final int FIREWALL_CHAIN_OEM_DENY_1 = 7; // 0x7
+ field public static final int FIREWALL_CHAIN_OEM_DENY_2 = 8; // 0x8
+ field public static final int FIREWALL_CHAIN_OEM_DENY_3 = 9; // 0x9
field public static final int FIREWALL_CHAIN_POWERSAVE = 3; // 0x3
field public static final int FIREWALL_CHAIN_RESTRICTED = 4; // 0x4
field public static final int FIREWALL_CHAIN_STANDBY = 2; // 0x2
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 5769b92..1b0578f 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -997,6 +997,7 @@
* Denylist of apps that will not have network access due to OEM-specific restrictions.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int FIREWALL_CHAIN_OEM_DENY_1 = 7;
/**
@@ -1004,6 +1005,7 @@
* Denylist of apps that will not have network access due to OEM-specific restrictions.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int FIREWALL_CHAIN_OEM_DENY_2 = 8;
/**
@@ -1011,6 +1013,7 @@
* Denylist of apps that will not have network access due to OEM-specific restrictions.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int FIREWALL_CHAIN_OEM_DENY_3 = 9;
/** @hide */
diff --git a/service/native/TrafficControllerTest.cpp b/service/native/TrafficControllerTest.cpp
index 2eabc26..0134dea 100644
--- a/service/native/TrafficControllerTest.cpp
+++ b/service/native/TrafficControllerTest.cpp
@@ -262,37 +262,6 @@
EXPECT_TRUE(mTc.mPrivilegedUser.empty());
}
- void addPrivilegedUid(uid_t uid) {
- std::vector privilegedUid = {uid};
- mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, privilegedUid);
- }
-
- void removePrivilegedUid(uid_t uid) {
- std::vector privilegedUid = {uid};
- mTc.setPermissionForUids(INetd::PERMISSION_NONE, privilegedUid);
- }
-
- void expectFakeStatsUnchanged(uint64_t cookie, uint32_t tag, uint32_t uid,
- StatsKey tagStatsMapKey) {
- Result<UidTagValue> cookieMapResult = mFakeCookieTagMap.readValue(cookie);
- EXPECT_RESULT_OK(cookieMapResult);
- EXPECT_EQ(uid, cookieMapResult.value().uid);
- EXPECT_EQ(tag, cookieMapResult.value().tag);
- Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
- EXPECT_RESULT_OK(statsMapResult);
- EXPECT_EQ((uint64_t)RXPACKETS, statsMapResult.value().rxPackets);
- EXPECT_EQ((uint64_t)RXBYTES, statsMapResult.value().rxBytes);
- tagStatsMapKey.tag = 0;
- statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
- EXPECT_RESULT_OK(statsMapResult);
- EXPECT_EQ((uint64_t)RXPACKETS, statsMapResult.value().rxPackets);
- EXPECT_EQ((uint64_t)RXBYTES, statsMapResult.value().rxBytes);
- auto appStatsResult = mFakeAppUidStatsMap.readValue(uid);
- EXPECT_RESULT_OK(appStatsResult);
- EXPECT_EQ((uint64_t)RXPACKETS, appStatsResult.value().rxPackets);
- EXPECT_EQ((uint64_t)RXBYTES, appStatsResult.value().rxBytes);
- }
-
Status updateUidOwnerMaps(const std::vector<uint32_t>& appUids,
UidOwnerMatchType matchType, TrafficController::IptOp op) {
Status ret(0);
diff --git a/service/src/com/android/server/connectivity/ClatCoordinator.java b/service/src/com/android/server/connectivity/ClatCoordinator.java
index ea89be6..498cf63 100644
--- a/service/src/com/android/server/connectivity/ClatCoordinator.java
+++ b/service/src/com/android/server/connectivity/ClatCoordinator.java
@@ -596,7 +596,6 @@
try {
mNetd.interfaceSetEnableIPv6(tunIface, false /* enabled */);
} catch (RemoteException | ServiceSpecificException e) {
- maybeCleanUp(tunFd, readSock6, writeSock6);
Log.e(TAG, "Disable IPv6 on " + tunIface + " failed: " + e);
}
diff --git a/tests/common/java/android/net/LinkPropertiesTest.java b/tests/common/java/android/net/LinkPropertiesTest.java
index 581ee22..9ed2bb3 100644
--- a/tests/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/common/java/android/net/LinkPropertiesTest.java
@@ -20,7 +20,6 @@
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.RouteInfo.RTN_UNREACHABLE;
-import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
@@ -53,6 +52,7 @@
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
import java.net.Inet4Address;
@@ -68,11 +68,13 @@
@SmallTest
@ConnectivityModuleTest
public class LinkPropertiesTest {
+ // Use a RuleChain to explicitly specify the order of rules. DevSdkIgnoreRule must run before
+ // PlatformCompatChange rule, because otherwise tests with that should be skipped when targeting
+ // target SDK 33 will still attempt to override compat changes (which on user builds will crash)
+ // before being skipped.
@Rule
- public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
-
- @Rule
- public final PlatformCompatChangeRule compatChangeRule = new PlatformCompatChangeRule();
+ public final RuleChain chain = RuleChain.outerRule(
+ new DevSdkIgnoreRule()).around(new PlatformCompatChangeRule());
private static final InetAddress ADDRV4 = address("75.208.6.1");
private static final InetAddress ADDRV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
@@ -1262,7 +1264,8 @@
assertFalse(lp.hasIpv4UnreachableDefaultRoute());
}
- @Test @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ @CtsNetTestCasesMaxTargetSdk31(reason = "Compat change cannot be overridden when targeting T+")
@EnableCompatChanges({LinkProperties.EXCLUDED_ROUTES})
public void testHasExcludeRoute() {
LinkProperties lp = new LinkProperties();
@@ -1274,7 +1277,8 @@
assertTrue(lp.hasExcludeRoute());
}
- @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ @CtsNetTestCasesMaxTargetSdk31(reason = "Compat change cannot be overridden when targeting T+")
@EnableCompatChanges({LinkProperties.EXCLUDED_ROUTES})
public void testRouteAddWithSameKey() throws Exception {
LinkProperties lp = new LinkProperties();
@@ -1291,7 +1295,8 @@
assertEquals(2, lp.getRoutes().size());
}
- @Test @IgnoreUpTo(SC_V2)
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ @CtsNetTestCasesMaxTargetSdk31(reason = "Compat change cannot be overridden when targeting T+")
@EnableCompatChanges({LinkProperties.EXCLUDED_ROUTES})
public void testExcludedRoutesEnabled() {
final LinkProperties lp = new LinkProperties();
@@ -1307,8 +1312,8 @@
assertEquals(3, lp.getRoutes().size());
}
- @Test @IgnoreUpTo(SC_V2)
- @CtsNetTestCasesMaxTargetSdk31(reason = "Compat change cannot be overridden on T or above")
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ @CtsNetTestCasesMaxTargetSdk31(reason = "Compat change cannot be overridden when targeting T+")
@DisableCompatChanges({LinkProperties.EXCLUDED_ROUTES})
public void testExcludedRoutesDisabled() {
final LinkProperties lp = new LinkProperties();
diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
index 6dfadc7..bd1b74a 100644
--- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -26,13 +26,8 @@
import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
import static android.net.cts.util.CtsTetheringUtils.isAnyIfaceMatch;
-import static com.android.networkstack.apishim.ConstantsShim.KEY_CARRIER_SUPPORTS_TETHERING_BOOL;
-import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
-import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -73,19 +68,14 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.TestCarrierConfigReceiver;
-
import org.junit.After;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -94,9 +84,6 @@
@RunWith(AndroidJUnit4.class)
public class TetheringManagerTest {
- @Rule
- public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
-
private Context mContext;
private ConnectivityManager mCm;
@@ -405,7 +392,7 @@
// Override carrier config to ignore entitlement check.
final PersistableBundle bundle = new PersistableBundle();
bundle.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, false);
- overrideCarrierConfig(bundle, CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
+ overrideCarrierConfig(bundle);
// Verify that requestLatestTetheringEntitlementResult() can get entitlement
// result TETHER_ERROR_NO_ERROR due to provisioning bypassed.
@@ -413,112 +400,14 @@
TETHERING_WIFI, false, c -> c.run(), listener), TETHER_ERROR_NO_ERROR);
// Reset carrier config.
- overrideCarrierConfig(null, "");
+ overrideCarrierConfig(null);
}
- @Test
- @IgnoreUpTo(SC_V2)
- public void testEnableTethering_carrierUnsupported_noTetheringActive() throws Exception {
- assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
-
- final TestTetheringEventCallback tetherEventCallback =
- mCtsTetheringUtils.registerTetheringEventCallback();
- boolean previousWifiEnabledState = false;
- try {
- tetherEventCallback.assumeWifiTetheringSupported(mContext);
- // Avoid device connected to Wifi network.
- previousWifiEnabledState = ensureCurrentNetworkIsCellular();
- final PersistableBundle bundle = new PersistableBundle();
- bundle.putBoolean(KEY_CARRIER_SUPPORTS_TETHERING_BOOL, false);
- // Override carrier config to make carrier not support.
- overrideCarrierConfig(bundle, KEY_CARRIER_SUPPORTS_TETHERING_BOOL);
-
- mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
-
- mCtsTetheringUtils.expectSoftApDisabled();
- tetherEventCallback.expectNoTetheringActive();
- } finally {
- overrideCarrierConfig(null, "");
- mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
- if (previousWifiEnabledState) {
- mCtsNetUtils.connectToWifi();
- }
- }
- }
-
- @Test
- @IgnoreUpTo(SC_V2)
- public void testEnableTethering_carrierUnsupportByConfigChange_noTetheringActive()
- throws Exception {
- assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
-
- final TestTetheringEventCallback tetherEventCallback =
- mCtsTetheringUtils.registerTetheringEventCallback();
- boolean previousWifiEnabledState = false;
- try {
- tetherEventCallback.assumeWifiTetheringSupported(mContext);
- // Avoid device connected to Wifi network.
- previousWifiEnabledState = ensureCurrentNetworkIsCellular();
- mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
-
- final PersistableBundle bundle = new PersistableBundle();
- bundle.putBoolean(KEY_CARRIER_SUPPORTS_TETHERING_BOOL, false);
- // Override carrier config to make carrier not support.
- overrideCarrierConfig(bundle, KEY_CARRIER_SUPPORTS_TETHERING_BOOL);
-
- mCtsTetheringUtils.expectSoftApDisabled();
- tetherEventCallback.expectNoTetheringActive();
- } finally {
- overrideCarrierConfig(null, "");
- mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
- if (previousWifiEnabledState) {
- mCtsNetUtils.connectToWifi();
- }
- }
- }
-
- @Test
- @IgnoreUpTo(SC_V2)
- public void testRequestLatestEntitlementResult_carrierUnsupported() throws Exception {
- assumeTrue(mTM.isTetheringSupported());
- assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
-
- final PersistableBundle bundle = new PersistableBundle();
- bundle.putBoolean(KEY_CARRIER_SUPPORTS_TETHERING_BOOL, false);
- try {
- // Override carrier config to make carrier not support.
- overrideCarrierConfig(bundle, KEY_CARRIER_SUPPORTS_TETHERING_BOOL);
-
- // Verify that requestLatestTetheringEntitlementResult() can get entitlement
- // result TETHER_ERROR_PROVISIONING_FAILED due to carrier unsupported
- assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult(
- TETHERING_WIFI,
- false,
- c -> c.run(),
- listener),
- TETHER_ERROR_PROVISIONING_FAILED);
- } finally {
- // Reset carrier config.
- overrideCarrierConfig(null, "");
- }
- }
-
- private void overrideCarrierConfig(PersistableBundle bundle, String configName)
- throws Exception {
- final int timeoutMs = 5_000;
- final int currentSubId = SubscriptionManager.getDefaultSubscriptionId();
- TestCarrierConfigReceiver configListener =
- new TestCarrierConfigReceiver(mContext, currentSubId, timeoutMs, bundle,
- (configs) -> {
- if (bundle == null) {
- // This is to restore carrier config and means no need to do match.
- return true;
- }
- boolean requestConfigValue = bundle.getBoolean(configName);
- boolean receiveConfigValue = configs.getBoolean(configName);
- return Objects.equals(receiveConfigValue, requestConfigValue);
- });
- configListener.overrideCarrierConfigForTest();
+ private void overrideCarrierConfig(PersistableBundle bundle) {
+ final CarrierConfigManager configManager = (CarrierConfigManager) mContext
+ .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ final int subId = SubscriptionManager.getDefaultSubscriptionId();
+ configManager.overrideConfig(subId, bundle);
}
@Test
@@ -532,8 +421,30 @@
try {
tetherEventCallback.assumeWifiTetheringSupported(mContext);
tetherEventCallback.expectNoTetheringActive();
- // Avoid device connected to Wifi network.
- previousWifiEnabledState = ensureCurrentNetworkIsCellular();
+
+ previousWifiEnabledState = mWm.isWifiEnabled();
+ if (previousWifiEnabledState) {
+ mCtsNetUtils.ensureWifiDisconnected(null);
+ }
+
+ final TestNetworkCallback networkCallback = new TestNetworkCallback();
+ Network activeNetwork = null;
+ try {
+ mCm.registerDefaultNetworkCallback(networkCallback);
+ activeNetwork = networkCallback.waitForAvailable();
+ } finally {
+ mCm.unregisterNetworkCallback(networkCallback);
+ }
+
+ assertNotNull("No active network. Please ensure the device has working mobile data.",
+ activeNetwork);
+ final NetworkCapabilities activeNetCap = mCm.getNetworkCapabilities(activeNetwork);
+
+ // If active nework is ETHERNET, tethering may not use cell network as upstream.
+ assumeFalse(activeNetCap.hasTransport(TRANSPORT_ETHERNET));
+
+ assertTrue(activeNetCap.hasTransport(TRANSPORT_CELLULAR));
+
mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
@@ -553,36 +464,4 @@
}
}
}
-
- /**
- * Make sure current network is cellular data.
- * @return true Previous Wifi state is enabled, false is disabled.
- */
- private boolean ensureCurrentNetworkIsCellular() throws Exception {
- final boolean previousWifiEnabledState = mWm.isWifiEnabled();
- if (previousWifiEnabledState) {
- mCtsNetUtils.ensureWifiDisconnected(null);
- }
-
- final TestNetworkCallback networkCallback = new TestNetworkCallback();
- Network activeNetwork = null;
- try {
- mCm.registerDefaultNetworkCallback(networkCallback);
- activeNetwork = networkCallback.waitForAvailable();
- } finally {
- mCm.unregisterNetworkCallback(networkCallback);
- }
-
- assertNotNull("No active network. Please ensure the device has working mobile data.",
- activeNetwork);
-
- final NetworkCapabilities activeNetCap = mCm.getNetworkCapabilities(activeNetwork);
-
- // If active nework is ETHERNET, tethering may not use cell network as upstream.
- assumeFalse(activeNetCap.hasTransport(TRANSPORT_ETHERNET));
-
- assertTrue(activeNetCap.hasTransport(TRANSPORT_CELLULAR));
-
- return previousWifiEnabledState;
- }
}