Merge "[MS25.2] Remove AppOpsManager.OP_GET_USAGE_STATS dependency"
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index 15f07f2..8bf1a2b 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -25,9 +25,14 @@
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.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.IPPROTO_IP;
+import static android.system.OsConstants.IPPROTO_UDP;
import static com.android.net.module.util.ConnectivityUtils.isIPv6ULA;
+import static com.android.net.module.util.HexDump.dumpHexString;
+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_ROUTER_ADVERTISEMENT;
import static com.android.testutils.TestNetworkTrackerKt.initTestNetwork;
@@ -47,20 +52,26 @@
import android.net.TetheringManager.StartTetheringCallback;
import android.net.TetheringManager.TetheringEventCallback;
import android.net.TetheringManager.TetheringRequest;
+import android.net.TetheringTester.TetheredDevice;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.net.module.util.PacketBuilder;
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.UdpHeader;
import com.android.testutils.HandlerUtils;
import com.android.testutils.TapPacketReader;
import com.android.testutils.TestNetworkTracker;
@@ -71,6 +82,7 @@
import org.junit.runner.RunWith;
import java.io.FileDescriptor;
+import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
@@ -92,10 +104,13 @@
private static final String TAG = EthernetTetheringTest.class.getSimpleName();
private static final int TIMEOUT_MS = 5000;
+ private static final int TETHER_REACHABILITY_ATTEMPTS = 20;
private static final LinkAddress TEST_IP4_ADDR = new LinkAddress("10.0.0.1/8");
private static final LinkAddress TEST_IP6_ADDR = new LinkAddress("2001:db8:1::101/64");
private static final InetAddress TEST_IP4_DNS = parseNumericAddress("8.8.8.8");
private static final InetAddress TEST_IP6_DNS = parseNumericAddress("2001:db8:1::888");
+ private static final ByteBuffer TEST_REACHABILITY_PAYLOAD =
+ ByteBuffer.wrap(new byte[] { (byte) 0x55, (byte) 0xaa });
private final Context mContext = InstrumentationRegistry.getContext();
private final EthernetManager mEm = mContext.getSystemService(EthernetManager.class);
@@ -105,6 +120,7 @@
private HandlerThread mHandlerThread;
private Handler mHandler;
private TapPacketReader mDownstreamReader;
+ private TapPacketReader mUpstreamReader;
private TetheredInterfaceRequester mTetheredInterfaceRequester;
private MyTetheringEventCallback mTetheringEventCallback;
@@ -140,6 +156,11 @@
mUpstreamTracker.teardown();
mUpstreamTracker = null;
}
+ if (mUpstreamReader != null) {
+ TapPacketReader reader = mUpstreamReader;
+ mHandler.post(() -> reader.stop());
+ mUpstreamReader = null;
+ }
mTm.stopTethering(TETHERING_ETHERNET);
if (mTetheringEventCallback != null) {
@@ -706,6 +727,168 @@
// TODO: do basic forwarding test here.
}
+ // Test network topology:
+ //
+ // public network (rawip) private network
+ // | UE |
+ // +------------+ V +------------+------------+ V +------------+
+ // | Sever +---------+ Upstream | Downstream +---------+ Client |
+ // +------------+ +------------+------------+ +------------+
+ // remote ip public ip private ip
+ // 8.8.8.8:443 <Upstream ip>:9876 <TetheredDevice ip>:9876
+ //
+ private static final Inet4Address REMOTE_IP4_ADDR =
+ (Inet4Address) parseNumericAddress("8.8.8.8");
+ // Used by public port and private port. Assume port 9876 has not been used yet before the
+ // testing that public port and private port are the same in the testing. Note that NAT port
+ // forwarding could be different between private port and public port.
+ private static final short LOCAL_PORT = 9876;
+ private static final short REMOTE_PORT = 433;
+ private static final byte TYPE_OF_SERVICE = 0;
+ private static final short ID = 27149;
+ private static final short ID2 = 27150;
+ private static final short FLAGS_AND_FRAGMENT_OFFSET = (short) 0x4000; // flags=DF, offset=0
+ private static final byte TIME_TO_LIVE = (byte) 0x40;
+ private static final ByteBuffer PAYLOAD =
+ ByteBuffer.wrap(new byte[] { (byte) 0x12, (byte) 0x34 });
+ private static final ByteBuffer PAYLOAD2 =
+ ByteBuffer.wrap(new byte[] { (byte) 0x56, (byte) 0x78 });
+
+ private boolean isExpectedUdpPacket(@NonNull final byte[] rawPacket, boolean hasEther,
+ @NonNull final ByteBuffer payload) {
+ final ByteBuffer buf = ByteBuffer.wrap(rawPacket);
+
+ if (hasEther) {
+ final EthernetHeader etherHeader = Struct.parse(EthernetHeader.class, buf);
+ if (etherHeader == null) return false;
+ }
+
+ final Ipv4Header ipv4Header = Struct.parse(Ipv4Header.class, buf);
+ if (ipv4Header == null) return false;
+
+ final UdpHeader udpHeader = Struct.parse(UdpHeader.class, buf);
+ if (udpHeader == 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 buildUdpv4Packet(@Nullable final MacAddress srcMac,
+ @Nullable final MacAddress dstMac, short id,
+ @NonNull final Inet4Address srcIp, @NonNull final Inet4Address dstIp,
+ short srcPort, short dstPort, @Nullable final ByteBuffer payload)
+ throws Exception {
+ final boolean hasEther = (srcMac != null && dstMac != null);
+ final int payloadLen = (payload == null) ? 0 : payload.limit();
+ final ByteBuffer buffer = PacketBuilder.allocate(hasEther, IPPROTO_IP, IPPROTO_UDP,
+ payloadLen);
+ final PacketBuilder packetBuilder = new PacketBuilder(buffer);
+
+ if (hasEther) packetBuilder.writeL2Header(srcMac, dstMac, (short) ETHER_TYPE_IPV4);
+ packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET,
+ TIME_TO_LIVE, (byte) IPPROTO_UDP, srcIp, dstIp);
+ packetBuilder.writeUdpHeader(srcPort, dstPort);
+ if (payload != null) {
+ buffer.put(payload);
+ // in case data might be reused by caller, restore the position and
+ // limit of bytebuffer.
+ payload.clear();
+ }
+
+ return packetBuilder.finalizePacket();
+ }
+
+ @NonNull
+ private ByteBuffer buildUdpv4Packet(short id, @NonNull final Inet4Address srcIp,
+ @NonNull final Inet4Address dstIp, short srcPort, short dstPort,
+ @Nullable final ByteBuffer payload) throws Exception {
+ return buildUdpv4Packet(null /* srcMac */, null /* dstMac */, id, srcIp, dstIp, srcPort,
+ dstPort, payload);
+ }
+
+ // TODO: remove this verification once upstream connected notification race is fixed.
+ // See #runUdp4Test.
+ private boolean isIpv4TetherConnectivityVerified(TetheringTester tester,
+ RemoteResponder remote, TetheredDevice tethered) throws Exception {
+ final ByteBuffer probePacket = buildUdpv4Packet(tethered.macAddr,
+ tethered.routerMacAddr, ID, tethered.ipv4Addr /* srcIp */,
+ REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /*dstPort */,
+ TEST_REACHABILITY_PAYLOAD);
+
+ // 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 -> {
+ Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
+ return isExpectedUdpPacket(p, false /* hasEther */, TEST_REACHABILITY_PAYLOAD);
+ });
+ if (expectedPacket != null) return true;
+ }
+ return false;
+ }
+
+ private void runUdp4Test(TetheringTester tester, RemoteResponder remote) throws Exception {
+ final TetheredDevice tethered = tester.createTetheredDevice(MacAddress.fromString(
+ "1:2:3:4:5:6"));
+
+ // TODO: remove the connectivity verification for upstream connected notification race.
+ // Because async upstream connected notification can't guarantee the tethering routing is
+ // ready to use. Need to test tethering connectivity before testing.
+ // 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));
+
+ // Send a UDP packet in original direction.
+ final ByteBuffer originalPacket = buildUdpv4Packet(tethered.macAddr,
+ tethered.routerMacAddr, ID, tethered.ipv4Addr /* srcIp */,
+ REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /*dstPort */,
+ PAYLOAD /* payload */);
+ tester.verifyUpload(remote, originalPacket, p -> {
+ Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
+ return isExpectedUdpPacket(p, false /* hasEther */, PAYLOAD);
+ });
+
+ // Send a UDP packet in reply direction.
+ final Inet4Address publicIp4Addr = (Inet4Address) TEST_IP4_ADDR.getAddress();
+ final ByteBuffer replyPacket = buildUdpv4Packet(ID2, REMOTE_IP4_ADDR /* srcIp */,
+ publicIp4Addr /* dstIp */, REMOTE_PORT /* srcPort */, LOCAL_PORT /*dstPort */,
+ PAYLOAD2 /* payload */);
+ remote.verifyDownload(tester, replyPacket, p -> {
+ Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
+ return isExpectedUdpPacket(p, true/* hasEther */, PAYLOAD2);
+ });
+ }
+
+ @Test
+ public void testUdpV4() 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));
+
+ mDownstreamIface = createTestInterface();
+ mEm.setIncludeTestInterfaces(true);
+
+ final String iface = mTetheredInterfaceRequester.getInterface();
+ assertEquals("TetheredInterfaceCallback for unexpected interface",
+ mDownstreamIface.getInterfaceName(), iface);
+
+ mTetheringEventCallback = enableEthernetTethering(mDownstreamIface.getInterfaceName());
+ assertEquals("onUpstreamChanged for unexpected network", mUpstreamTracker.getNetwork(),
+ mTetheringEventCallback.awaitFirstUpstreamConnected());
+
+ mDownstreamReader = makePacketReader(mDownstreamIface);
+ mUpstreamReader = makePacketReader(mUpstreamTracker.getTestIface());
+
+ runUdp4Test(new TetheringTester(mDownstreamReader), new RemoteResponder(mUpstreamReader));
+ }
+
private <T> List<T> toList(T... array) {
return Arrays.asList(array);
}
diff --git a/Tethering/tests/integration/src/android/net/TetheringTester.java b/Tethering/tests/integration/src/android/net/TetheringTester.java
index d61bbb3..d24661a 100644
--- a/Tethering/tests/integration/src/android/net/TetheringTester.java
+++ b/Tethering/tests/integration/src/android/net/TetheringTester.java
@@ -16,6 +16,12 @@
package android.net;
+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 org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import android.net.dhcp.DhcpAckPacket;
@@ -24,6 +30,9 @@
import android.util.ArrayMap;
import android.util.Log;
+import androidx.annotation.Nullable;
+
+import com.android.networkstack.arp.ArpPacket;
import com.android.testutils.TapPacketReader;
import java.net.Inet4Address;
@@ -72,15 +81,17 @@
}
public class TetheredDevice {
- private final MacAddress mMacAddr;
-
- public final Inet4Address mIpv4Addr;
+ public final MacAddress macAddr;
+ public final MacAddress routerMacAddr;
+ public final Inet4Address ipv4Addr;
private TetheredDevice(MacAddress mac) throws Exception {
- mMacAddr = mac;
+ macAddr = mac;
- DhcpResults dhcpResults = runDhcp(mMacAddr.toByteArray());
- mIpv4Addr = (Inet4Address) dhcpResults.ipAddress.getAddress();
+ DhcpResults dhcpResults = runDhcp(macAddr.toByteArray());
+ ipv4Addr = (Inet4Address) dhcpResults.ipAddress.getAddress();
+ routerMacAddr = getRouterMacAddressFromArp(ipv4Addr, macAddr,
+ dhcpResults.serverAddress);
}
}
@@ -146,12 +157,84 @@
DhcpPacket.decodeFullPacket(packet, packet.length, DhcpPacket.ENCAP_L2);
}
+ @Nullable
+ private ArpPacket parseArpPacket(final byte[] packet) {
+ try {
+ return ArpPacket.parseArpPacket(packet, packet.length);
+ } catch (ArpPacket.ParseException e) {
+ return null;
+ }
+ }
+
+ private void maybeReplyArp(byte[] packet) {
+ ByteBuffer buf = ByteBuffer.wrap(packet);
+
+ final ArpPacket arpPacket = parseArpPacket(packet);
+ if (arpPacket == null || arpPacket.opCode != ARP_REQUEST) return;
+
+ for (int i = 0; i < mTetheredDevices.size(); i++) {
+ TetheredDevice tethered = mTetheredDevices.valueAt(i);
+ if (!arpPacket.targetIp.equals(tethered.ipv4Addr)) continue;
+
+ final ByteBuffer arpReply = ArpPacket.buildArpPacket(
+ arpPacket.senderHwAddress.toByteArray() /* dst */,
+ tethered.macAddr.toByteArray() /* srcMac */,
+ arpPacket.senderIp.getAddress() /* target IP */,
+ arpPacket.senderHwAddress.toByteArray() /* target HW address */,
+ tethered.ipv4Addr.getAddress() /* sender IP */,
+ (short) ARP_REPLY);
+ try {
+ sendPacket(arpReply);
+ } catch (Exception e) {
+ fail("Failed to reply ARP for " + tethered.ipv4Addr);
+ }
+ return;
+ }
+ }
+
+ private MacAddress getRouterMacAddressFromArp(final Inet4Address tetherIp,
+ final MacAddress tetherMac, final Inet4Address routerIp) throws Exception {
+ final ByteBuffer arpProbe = ArpPacket.buildArpPacket(ETHER_BROADCAST /* dst */,
+ tetherMac.toByteArray() /* srcMac */, routerIp.getAddress() /* target IP */,
+ new byte[ETHER_ADDR_LEN] /* target HW address */,
+ tetherIp.getAddress() /* sender IP */, (short) ARP_REQUEST);
+ sendPacket(arpProbe);
+
+ final byte[] packet = getNextMatchedPacket((p) -> {
+ final ArpPacket arpPacket = parseArpPacket(p);
+ if (arpPacket == null || arpPacket.opCode != ARP_REPLY) return false;
+ return arpPacket.targetIp.equals(tetherIp);
+ });
+
+ if (packet != null) {
+ Log.d(TAG, "Get Mac address from ARP");
+ final ArpPacket arpReply = ArpPacket.parseArpPacket(packet, packet.length);
+ return arpReply.senderHwAddress;
+ }
+
+ fail("Could not get ARP packet");
+ return null;
+ }
+
public void sendPacket(ByteBuffer packet) throws Exception {
mDownstreamReader.sendResponse(packet);
}
public byte[] getNextMatchedPacket(Predicate<byte[]> filter) {
- return mDownstreamReader.poll(PACKET_READ_TIMEOUT_MS, filter);
+ byte[] packet;
+ while ((packet = mDownstreamReader.poll(PACKET_READ_TIMEOUT_MS)) != null) {
+ if (filter.test(packet)) return packet;
+
+ maybeReplyArp(packet);
+ }
+
+ 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));
}
public static class RemoteResponder {
@@ -167,5 +250,11 @@
public byte[] getNextMatchedPacket(Predicate<byte[]> filter) throws Exception {
return mUpstreamReader.poll(PACKET_READ_TIMEOUT_MS, filter);
}
+
+ public void verifyDownload(final TetheringTester dst, final ByteBuffer packet,
+ final Predicate<byte[]> filter) throws Exception {
+ sendPacket(packet);
+ assertNotNull("Download fail", dst.getNextMatchedPacket(filter));
+ }
}
}
diff --git a/bpf_progs/Android.bp b/bpf_progs/Android.bp
index 17eebe0..d015ef6 100644
--- a/bpf_progs/Android.bp
+++ b/bpf_progs/Android.bp
@@ -25,6 +25,8 @@
name: "bpf_connectivity_headers",
vendor_available: false,
host_supported: false,
+ header_libs: ["bpf_headers"],
+ export_header_lib_headers: ["bpf_headers"],
export_include_dirs: ["."],
cflags: [
"-Wall",
diff --git a/framework/src/android/net/NetworkAgentConfig.java b/framework/src/android/net/NetworkAgentConfig.java
index ad8396b..93fc379 100644
--- a/framework/src/android/net/NetworkAgentConfig.java
+++ b/framework/src/android/net/NetworkAgentConfig.java
@@ -232,6 +232,20 @@
return mLegacyExtraInfo;
}
+ /**
+ * If the {@link Network} is a VPN, whether the local traffic is exempted from the VPN.
+ * @hide
+ */
+ public boolean excludeLocalRouteVpn = false;
+
+ /**
+ * @return whether local traffic is excluded from the VPN network.
+ * @hide
+ */
+ public boolean getExcludeLocalRouteVpn() {
+ return excludeLocalRouteVpn;
+ }
+
/** @hide */
public NetworkAgentConfig() {
}
@@ -251,6 +265,7 @@
legacySubType = nac.legacySubType;
legacySubTypeName = nac.legacySubTypeName;
mLegacyExtraInfo = nac.mLegacyExtraInfo;
+ excludeLocalRouteVpn = nac.excludeLocalRouteVpn;
}
}
@@ -407,6 +422,17 @@
}
/**
+ * Sets whether the local traffic is exempted from VPN.
+ *
+ * @return this builder, to facilitate chaining.
+ * @hide TODO(184750836): Unhide once the implementation is completed.
+ */
+ public Builder setExcludeLocalRoutesVpn(boolean excludeLocalRoutes) {
+ mConfig.excludeLocalRouteVpn = excludeLocalRoutes;
+ return this;
+ }
+
+ /**
* Returns the constructed {@link NetworkAgentConfig} object.
*/
@NonNull
@@ -429,14 +455,15 @@
&& legacyType == that.legacyType
&& Objects.equals(subscriberId, that.subscriberId)
&& Objects.equals(legacyTypeName, that.legacyTypeName)
- && Objects.equals(mLegacyExtraInfo, that.mLegacyExtraInfo);
+ && Objects.equals(mLegacyExtraInfo, that.mLegacyExtraInfo)
+ && excludeLocalRouteVpn == that.excludeLocalRouteVpn;
}
@Override
public int hashCode() {
return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated,
acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId,
- skip464xlat, legacyType, legacyTypeName, mLegacyExtraInfo);
+ skip464xlat, legacyType, legacyTypeName, mLegacyExtraInfo, excludeLocalRouteVpn);
}
@Override
@@ -453,6 +480,7 @@
+ ", hasShownBroken = " + hasShownBroken
+ ", legacyTypeName = '" + legacyTypeName + '\''
+ ", legacyExtraInfo = '" + mLegacyExtraInfo + '\''
+ + ", excludeLocalRouteVpn = '" + excludeLocalRouteVpn + '\''
+ "}";
}
@@ -475,6 +503,7 @@
out.writeInt(legacySubType);
out.writeString(legacySubTypeName);
out.writeString(mLegacyExtraInfo);
+ out.writeInt(excludeLocalRouteVpn ? 1 : 0);
}
public static final @NonNull Creator<NetworkAgentConfig> CREATOR =
@@ -494,6 +523,7 @@
networkAgentConfig.legacySubType = in.readInt();
networkAgentConfig.legacySubTypeName = in.readString();
networkAgentConfig.mLegacyExtraInfo = in.readString();
+ networkAgentConfig.excludeLocalRouteVpn = in.readInt() != 0;
return networkAgentConfig;
}
diff --git a/tests/common/Android.bp b/tests/common/Android.bp
index f47f6b0..c533dab 100644
--- a/tests/common/Android.bp
+++ b/tests/common/Android.bp
@@ -64,8 +64,7 @@
name: "ConnectivityCoverageTests",
// Tethering started on SDK 30
min_sdk_version: "30",
- // TODO: change to 31 as soon as it is available
- target_sdk_version: "30",
+ target_sdk_version: "31",
test_suites: ["general-tests", "mts-tethering"],
defaults: [
"framework-connectivity-test-defaults",
diff --git a/tests/common/java/android/net/NetworkAgentConfigTest.kt b/tests/common/java/android/net/NetworkAgentConfigTest.kt
index afaae1c..ed9995c 100644
--- a/tests/common/java/android/net/NetworkAgentConfigTest.kt
+++ b/tests/common/java/android/net/NetworkAgentConfigTest.kt
@@ -48,9 +48,16 @@
setBypassableVpn(true)
}
}.build()
+ // This test can be run as unit test against the latest system image, as CTS to verify
+ // an Android release that is as recent as the test, or as MTS to verify the
+ // Connectivity module. In the first two cases NetworkAgentConfig will be as recent
+ // as the test. In the last case, starting from S NetworkAgentConfig is updated as part
+ // of Connectivity, so it is also as recent as the test. For MTS on Q and R,
+ // NetworkAgentConfig is not updatable, so it may have a different number of fields.
if (isAtLeastS()) {
- // From S, the config will have 12 items
- assertParcelSane(config, 12)
+ // When this test is run on S+, NetworkAgentConfig is as recent as the test,
+ // so this should be the most recent known number of fields.
+ assertParcelSane(config, 13)
} else {
// For R or below, the config will have 10 items
assertParcelSane(config, 10)
diff --git a/tests/common/java/android/net/NetworkProviderTest.kt b/tests/common/java/android/net/NetworkProviderTest.kt
index 626a344..ff5de1d 100644
--- a/tests/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/common/java/android/net/NetworkProviderTest.kt
@@ -40,7 +40,6 @@
import com.android.testutils.isDevSdkInRange
import org.junit.After
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -205,7 +204,6 @@
}
}
- @Ignore("Temporarily disable the test since prebuilt Connectivity module is not updated.")
@IgnoreUpTo(Build.VERSION_CODES.R)
@Test
fun testRegisterNetworkOffer() {
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
index c9fed44..232114e 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
@@ -85,7 +85,6 @@
import com.android.net.module.util.ArrayTrackRecord;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.DevSdkIgnoreRunner;
-import com.android.testutils.SkipPresubmit;
import org.junit.After;
import org.junit.Before;
@@ -207,7 +206,6 @@
cb.assertNoCallback();
}
- @SkipPresubmit(reason = "Flaky: b/159718782; add to presubmit after fixing")
@Test
public void testRegisterCallbackWithCarrierPrivileges() throws Exception {
assumeTrue(mPackageManager.hasSystemFeature(FEATURE_TELEPHONY));
diff --git a/tests/unit/java/android/net/NetworkTemplateTest.kt b/tests/unit/java/android/net/NetworkTemplateTest.kt
index 5d6e6dd..15db45c 100644
--- a/tests/unit/java/android/net/NetworkTemplateTest.kt
+++ b/tests/unit/java/android/net/NetworkTemplateTest.kt
@@ -50,6 +50,7 @@
import android.net.NetworkTemplate.buildTemplateWifi
import android.net.NetworkTemplate.buildTemplateWifiWildcard
import android.net.NetworkTemplate.normalize
+import android.net.wifi.WifiInfo
import android.os.Build
import android.telephony.TelephonyManager
import com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
@@ -61,6 +62,7 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
@@ -71,35 +73,38 @@
private const val TEST_IMSI1 = "imsi1"
private const val TEST_IMSI2 = "imsi2"
private const val TEST_IMSI3 = "imsi3"
-private const val TEST_SSID1 = "ssid1"
-private const val TEST_SSID2 = "ssid2"
+private const val TEST_WIFI_KEY1 = "wifiKey1"
+private const val TEST_WIFI_KEY2 = "wifiKey2"
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class NetworkTemplateTest {
private val mockContext = mock(Context::class.java)
+ private val mockWifiInfo = mock(WifiInfo::class.java)
private fun buildMobileNetworkState(subscriberId: String): NetworkStateSnapshot =
buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId)
- private fun buildWifiNetworkState(subscriberId: String?, ssid: String?): NetworkStateSnapshot =
- buildNetworkState(TYPE_WIFI, subscriberId = subscriberId, ssid = ssid)
+ private fun buildWifiNetworkState(subscriberId: String?, wifiKey: String?):
+ NetworkStateSnapshot = buildNetworkState(TYPE_WIFI,
+ subscriberId = subscriberId, wifiKey = wifiKey)
private fun buildNetworkState(
type: Int,
subscriberId: String? = null,
- ssid: String? = null,
+ wifiKey: String? = null,
oemManaged: Int = OEM_NONE,
metered: Boolean = true
): NetworkStateSnapshot {
+ `when`(mockWifiInfo.getCurrentNetworkKey()).thenReturn(wifiKey)
val lp = LinkProperties()
val caps = NetworkCapabilities().apply {
setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !metered)
setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true)
- setSSID(ssid)
setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID,
(oemManaged and OEM_PAID) == OEM_PAID)
setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
(oemManaged and OEM_PRIVATE) == OEM_PRIVATE)
+ setTransportInfo(mockWifiInfo)
}
return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type)
}
@@ -122,64 +127,65 @@
val identMobileImsi1 = buildNetworkIdentity(mockContext,
buildMobileNetworkState(TEST_IMSI1),
false, TelephonyManager.NETWORK_TYPE_UMTS)
- val identWifiImsiNullSsid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
- val identWifiImsi1Ssid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
+ val identWifiImsiNullKey1 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(null, TEST_WIFI_KEY1), true, 0)
+ val identWifiImsi1Key1 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
templateWifiWildcard.assertDoesNotMatch(identMobileImsi1)
- templateWifiWildcard.assertMatches(identWifiImsiNullSsid1)
- templateWifiWildcard.assertMatches(identWifiImsi1Ssid1)
+ templateWifiWildcard.assertMatches(identWifiImsiNullKey1)
+ templateWifiWildcard.assertMatches(identWifiImsi1Key1)
}
@Test
fun testWifiMatches() {
- val templateWifiSsid1 = buildTemplateWifi(TEST_SSID1)
- val templateWifiSsid1ImsiNull = buildTemplateWifi(TEST_SSID1, null)
- val templateWifiSsid1Imsi1 = buildTemplateWifi(TEST_SSID1, TEST_IMSI1)
- val templateWifiSsidAllImsi1 = buildTemplateWifi(WIFI_NETWORK_KEY_ALL, TEST_IMSI1)
+ val templateWifiKey1 = buildTemplateWifi(TEST_WIFI_KEY1)
+ val templateWifiKey1ImsiNull = buildTemplateWifi(TEST_WIFI_KEY1, null)
+ val templateWifiKey1Imsi1 = buildTemplateWifi(TEST_WIFI_KEY1, TEST_IMSI1)
+ val templateWifiKeyAllImsi1 = buildTemplateWifi(WIFI_NETWORK_KEY_ALL, TEST_IMSI1)
val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1),
false, TelephonyManager.NETWORK_TYPE_UMTS)
- val identWifiImsiNullSsid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
- val identWifiImsi1Ssid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
- val identWifiImsi2Ssid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_SSID1), true, 0)
- val identWifiImsi1Ssid2 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID2), true, 0)
+ val identWifiImsiNullKey1 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(null, TEST_WIFI_KEY1), true, 0)
+ val identWifiImsi1Key1 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
+ val identWifiImsi2Key1 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_WIFI_KEY1), true, 0)
+ val identWifiImsi1Key2 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY2), true, 0)
- // Verify that template with SSID only matches any subscriberId and specific SSID.
- templateWifiSsid1.assertDoesNotMatch(identMobile1)
- templateWifiSsid1.assertMatches(identWifiImsiNullSsid1)
- templateWifiSsid1.assertMatches(identWifiImsi1Ssid1)
- templateWifiSsid1.assertMatches(identWifiImsi2Ssid1)
- templateWifiSsid1.assertDoesNotMatch(identWifiImsi1Ssid2)
+ // Verify that template with WiFi Network Key only matches any subscriberId and
+ // specific WiFi Network Key.
+ templateWifiKey1.assertDoesNotMatch(identMobile1)
+ templateWifiKey1.assertMatches(identWifiImsiNullKey1)
+ templateWifiKey1.assertMatches(identWifiImsi1Key1)
+ templateWifiKey1.assertMatches(identWifiImsi2Key1)
+ templateWifiKey1.assertDoesNotMatch(identWifiImsi1Key2)
- // Verify that template with SSID1 and null imsi matches any network with
- // SSID1 and null imsi.
- templateWifiSsid1ImsiNull.assertDoesNotMatch(identMobile1)
- templateWifiSsid1ImsiNull.assertMatches(identWifiImsiNullSsid1)
- templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi1Ssid1)
- templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi2Ssid1)
- templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi1Ssid2)
+ // Verify that template with WiFi Network Key1 and null imsi matches any network with
+ // WiFi Network Key1 and null imsi.
+ templateWifiKey1ImsiNull.assertDoesNotMatch(identMobile1)
+ templateWifiKey1ImsiNull.assertMatches(identWifiImsiNullKey1)
+ templateWifiKey1ImsiNull.assertDoesNotMatch(identWifiImsi1Key1)
+ templateWifiKey1ImsiNull.assertDoesNotMatch(identWifiImsi2Key1)
+ templateWifiKey1ImsiNull.assertDoesNotMatch(identWifiImsi1Key2)
- // Verify that template with SSID1 and imsi1 matches any network with
- // SSID1 and imsi1.
- templateWifiSsid1Imsi1.assertDoesNotMatch(identMobile1)
- templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsiNullSsid1)
- templateWifiSsid1Imsi1.assertMatches(identWifiImsi1Ssid1)
- templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsi2Ssid1)
- templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsi1Ssid2)
+ // Verify that template with WiFi Network Key1 and imsi1 matches any network with
+ // WiFi Network Key1 and imsi1.
+ templateWifiKey1Imsi1.assertDoesNotMatch(identMobile1)
+ templateWifiKey1Imsi1.assertDoesNotMatch(identWifiImsiNullKey1)
+ templateWifiKey1Imsi1.assertMatches(identWifiImsi1Key1)
+ templateWifiKey1Imsi1.assertDoesNotMatch(identWifiImsi2Key1)
+ templateWifiKey1Imsi1.assertDoesNotMatch(identWifiImsi1Key2)
- // Verify that template with SSID all and imsi1 matches any network with
- // any SSID and imsi1.
- templateWifiSsidAllImsi1.assertDoesNotMatch(identMobile1)
- templateWifiSsidAllImsi1.assertDoesNotMatch(identWifiImsiNullSsid1)
- templateWifiSsidAllImsi1.assertMatches(identWifiImsi1Ssid1)
- templateWifiSsidAllImsi1.assertDoesNotMatch(identWifiImsi2Ssid1)
- templateWifiSsidAllImsi1.assertMatches(identWifiImsi1Ssid2)
+ // Verify that template with WiFi Network Key all and imsi1 matches any network with
+ // any WiFi Network Key and imsi1.
+ templateWifiKeyAllImsi1.assertDoesNotMatch(identMobile1)
+ templateWifiKeyAllImsi1.assertDoesNotMatch(identWifiImsiNullKey1)
+ templateWifiKeyAllImsi1.assertMatches(identWifiImsi1Key1)
+ templateWifiKeyAllImsi1.assertDoesNotMatch(identWifiImsi2Key1)
+ templateWifiKeyAllImsi1.assertMatches(identWifiImsi1Key2)
}
@Test
@@ -188,7 +194,7 @@
val templateMobileImsi2WithRatType = buildTemplateMobileWithRatType(TEST_IMSI2,
TelephonyManager.NETWORK_TYPE_UMTS, METERED_YES)
- val mobileImsi1 = buildNetworkState(TYPE_MOBILE, TEST_IMSI1, null /* ssid */,
+ val mobileImsi1 = buildNetworkState(TYPE_MOBILE, TEST_IMSI1, null /* wifiKey */,
OEM_NONE, true /* metered */)
val identMobile1 = buildNetworkIdentity(mockContext, mobileImsi1,
false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
@@ -196,8 +202,8 @@
val identMobile2Umts = buildNetworkIdentity(mockContext, mobileImsi2,
false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
- val identWifiImsi1Ssid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
+ val identWifiImsi1Key1 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
// Verify that the template matches type and the subscriberId.
templateMobileImsi1.assertMatches(identMobile1)
@@ -208,7 +214,7 @@
templateMobileImsi2WithRatType.assertDoesNotMatch(identMobile1)
// Verify that the different type does not match.
- templateMobileImsi1.assertDoesNotMatch(identWifiImsi1Ssid1)
+ templateMobileImsi1.assertDoesNotMatch(identWifiImsi1Key1)
}
@Test
@@ -225,12 +231,12 @@
templateMobileWildcard.assertMatches(identMobile1)
templateMobileNullImsiWithRatType.assertMatches(identMobile1)
- val identWifiImsi1Ssid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
+ val identWifiImsi1Key1 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
// Verify that the different type does not match.
- templateMobileWildcard.assertDoesNotMatch(identWifiImsi1Ssid1)
- templateMobileNullImsiWithRatType.assertDoesNotMatch(identWifiImsi1Ssid1)
+ templateMobileWildcard.assertDoesNotMatch(identWifiImsi1Key1)
+ templateMobileNullImsiWithRatType.assertDoesNotMatch(identWifiImsi1Key1)
}
@Test
@@ -238,13 +244,14 @@
val templateCarrierImsi1Metered = buildTemplateCarrierMetered(TEST_IMSI1)
val mobileImsi1 = buildMobileNetworkState(TEST_IMSI1)
- val mobileImsi1Unmetered = buildNetworkState(TYPE_MOBILE, TEST_IMSI1, null /* ssid */,
- OEM_NONE, false /* metered */)
+ val mobileImsi1Unmetered = buildNetworkState(TYPE_MOBILE, TEST_IMSI1,
+ null /* wifiKey */, OEM_NONE, false /* metered */)
val mobileImsi2 = buildMobileNetworkState(TEST_IMSI2)
- val wifiSsid1 = buildWifiNetworkState(null /* subscriberId */, TEST_SSID1)
- val wifiImsi1Ssid1 = buildWifiNetworkState(TEST_IMSI1, TEST_SSID1)
- val wifiImsi1Ssid1Unmetered = buildNetworkState(TYPE_WIFI, TEST_IMSI1, TEST_SSID1,
- OEM_NONE, false /* metered */)
+ val wifiKey1 = buildWifiNetworkState(null /* subscriberId */,
+ TEST_WIFI_KEY1)
+ val wifiImsi1Key1 = buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1)
+ val wifiImsi1Key1Unmetered = buildNetworkState(TYPE_WIFI, TEST_IMSI1,
+ TEST_WIFI_KEY1, OEM_NONE, false /* metered */)
val identMobileImsi1Metered = buildNetworkIdentity(mockContext,
mobileImsi1, false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
@@ -253,17 +260,17 @@
TelephonyManager.NETWORK_TYPE_UMTS)
val identMobileImsi2Metered = buildNetworkIdentity(mockContext,
mobileImsi2, false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
- val identWifiSsid1Metered = buildNetworkIdentity(
- mockContext, wifiSsid1, true /* defaultNetwork */, 0 /* subType */)
+ val identWifiKey1Metered = buildNetworkIdentity(
+ mockContext, wifiKey1, true /* defaultNetwork */, 0 /* subType */)
val identCarrierWifiImsi1Metered = buildNetworkIdentity(
- mockContext, wifiImsi1Ssid1, true /* defaultNetwork */, 0 /* subType */)
+ mockContext, wifiImsi1Key1, true /* defaultNetwork */, 0 /* subType */)
val identCarrierWifiImsi1NonMetered = buildNetworkIdentity(mockContext,
- wifiImsi1Ssid1Unmetered, true /* defaultNetwork */, 0 /* subType */)
+ wifiImsi1Key1Unmetered, true /* defaultNetwork */, 0 /* subType */)
templateCarrierImsi1Metered.assertMatches(identMobileImsi1Metered)
templateCarrierImsi1Metered.assertDoesNotMatch(identMobileImsi1Unmetered)
templateCarrierImsi1Metered.assertDoesNotMatch(identMobileImsi2Metered)
- templateCarrierImsi1Metered.assertDoesNotMatch(identWifiSsid1Metered)
+ templateCarrierImsi1Metered.assertDoesNotMatch(identWifiKey1Metered)
templateCarrierImsi1Metered.assertMatches(identCarrierWifiImsi1Metered)
templateCarrierImsi1Metered.assertDoesNotMatch(identCarrierWifiImsi1NonMetered)
}
@@ -273,9 +280,9 @@
fun testRatTypeGroupMatches() {
val stateMobileImsi1Metered = buildMobileNetworkState(TEST_IMSI1)
val stateMobileImsi1NonMetered = buildNetworkState(TYPE_MOBILE, TEST_IMSI1,
- null /* ssid */, OEM_NONE, false /* metered */)
+ null /* wifiKey */, OEM_NONE, false /* metered */)
val stateMobileImsi2NonMetered = buildNetworkState(TYPE_MOBILE, TEST_IMSI2,
- null /* ssid */, OEM_NONE, false /* metered */)
+ null /* wifiKey */, OEM_NONE, false /* metered */)
// Build UMTS template that matches mobile identities with RAT in the same
// group with any IMSI. See {@link NetworkTemplate#getCollapsedRatType}.
@@ -309,7 +316,7 @@
val identImsi2UmtsMetered = buildNetworkIdentity(mockContext,
buildMobileNetworkState(TEST_IMSI2), false, TelephonyManager.NETWORK_TYPE_UMTS)
val identWifi = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
+ mockContext, buildWifiNetworkState(null, TEST_WIFI_KEY1), true, 0)
val identUmtsNonMetered = buildNetworkIdentity(
mockContext, stateMobileImsi1NonMetered, false, TelephonyManager.NETWORK_TYPE_UMTS)
@@ -397,15 +404,16 @@
@Test
fun testParcelUnparcel() {
- val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL,
- ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE,
+ val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null,
+ arrayOf<String>(), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
+ TelephonyManager.NETWORK_TYPE_LTE, OEM_MANAGED_ALL,
+ SUBSCRIBER_ID_MATCH_RULE_EXACT)
+ val templateWifi = NetworkTemplate(MATCH_WIFI, null, null,
+ arrayOf(TEST_WIFI_KEY1), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, 0,
OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
- val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL,
- ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL,
- SUBSCRIBER_ID_MATCH_RULE_EXACT)
- val templateOem = NetworkTemplate(MATCH_MOBILE, null, null, null, METERED_ALL,
- ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES,
- SUBSCRIBER_ID_MATCH_RULE_EXACT)
+ val templateOem = NetworkTemplate(MATCH_MOBILE, null, null,
+ arrayOf<String>(), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, 0,
+ OEM_MANAGED_YES, SUBSCRIBER_ID_MATCH_RULE_EXACT)
assertParcelSane(templateMobile, 10)
assertParcelSane(templateWifi, 10)
assertParcelSane(templateOem, 10)
@@ -443,39 +451,43 @@
* @param subscriberId To be populated with {@code TEST_IMSI*} only if networkType is
* {@code TYPE_MOBILE}. May be left as null when matchType is
* {@link NetworkTemplate.MATCH_MOBILE_WILDCARD}.
- * @param templateSsid Top be populated with {@code TEST_SSID*} only if networkType is
+ * @param templateWifiKey Top be populated with {@code TEST_WIFI_KEY*} only if networkType is
* {@code TYPE_WIFI}. May be left as null when matchType is
* {@link NetworkTemplate.MATCH_WIFI_WILDCARD}.
- * @param identSsid If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide
- * one of {@code TEST_SSID*}.
+ * @param identWifiKey If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide
+ * one of {@code TEST_WIFI_KEY*}.
*/
private fun matchOemManagedIdent(
networkType: Int,
matchType: Int,
subscriberId: String? = null,
- templateSsid: String? = null,
- identSsid: String? = null
+ templateWifiKey: String? = null,
+ identWifiKey: String? = null
) {
val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
val matchSubscriberIds = arrayOf(subscriberId)
+ val matchWifiNetworkKeys = arrayOf(templateWifiKey)
val templateOemYes = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
- templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_MANAGED_YES, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+ matchWifiNetworkKeys, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES,
+ SUBSCRIBER_ID_MATCH_RULE_EXACT)
val templateOemAll = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
- templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+ matchWifiNetworkKeys, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
+ SUBSCRIBER_ID_MATCH_RULE_EXACT)
for (identityOemManagedState in oemManagedStates) {
val ident = buildNetworkIdentity(mockContext, buildNetworkState(networkType,
- subscriberId, identSsid, identityOemManagedState), /*defaultNetwork=*/false,
- /*subType=*/0)
+ subscriberId, identWifiKey, identityOemManagedState),
+ /*defaultNetwork=*/false, /*subType=*/0)
// Create a template with each OEM managed type and match it against the NetworkIdentity
for (templateOemManagedState in oemManagedStates) {
val template = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
- templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
- NETWORK_TYPE_ALL, templateOemManagedState, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+ matchWifiNetworkKeys, METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, templateOemManagedState,
+ SUBSCRIBER_ID_MATCH_RULE_EXACT)
if (identityOemManagedState == templateOemManagedState) {
template.assertMatches(ident)
} else {
@@ -497,9 +509,10 @@
fun testOemManagedMatchesIdent() {
matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE, subscriberId = TEST_IMSI1)
matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE_WILDCARD)
- matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, templateSsid = TEST_SSID1,
- identSsid = TEST_SSID1)
- matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI_WILDCARD, identSsid = TEST_SSID1)
+ matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, templateWifiKey = TEST_WIFI_KEY1,
+ identWifiKey = TEST_WIFI_KEY1)
+ matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI_WILDCARD,
+ identWifiKey = TEST_WIFI_KEY1)
}
@Test
@@ -514,12 +527,12 @@
val identMobileImsi3 = buildNetworkIdentity(mockContext,
buildMobileNetworkState(TEST_IMSI3), false /* defaultNetwork */,
TelephonyManager.NETWORK_TYPE_UMTS)
- val identWifiImsi1Ssid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
- val identWifiImsi2Ssid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_SSID1), true, 0)
- val identWifiImsi3Ssid1 = buildNetworkIdentity(
- mockContext, buildWifiNetworkState(TEST_IMSI3, TEST_SSID1), true, 0)
+ val identWifiImsi1Key1 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
+ val identWifiImsi2Key1 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_WIFI_KEY1), true, 0)
+ val identWifiImsi3WifiKey1 = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(TEST_IMSI3, TEST_WIFI_KEY1), true, 0)
normalize(buildTemplateMobileAll(TEST_IMSI1), mergedImsiList).also {
it.assertMatches(identMobileImsi1)
@@ -531,10 +544,10 @@
it.assertMatches(identMobileImsi2)
it.assertDoesNotMatch(identMobileImsi3)
}
- normalize(buildTemplateWifi(TEST_SSID1, TEST_IMSI1), mergedImsiList).also {
- it.assertMatches(identWifiImsi1Ssid1)
- it.assertMatches(identWifiImsi2Ssid1)
- it.assertDoesNotMatch(identWifiImsi3Ssid1)
+ normalize(buildTemplateWifi(TEST_WIFI_KEY1, TEST_IMSI1), mergedImsiList).also {
+ it.assertMatches(identWifiImsi1Key1)
+ it.assertMatches(identWifiImsi2Key1)
+ it.assertDoesNotMatch(identWifiImsi3WifiKey1)
}
normalize(buildTemplateMobileWildcard(), mergedImsiList).also {
it.assertMatches(identMobileImsi1)
@@ -566,7 +579,7 @@
NetworkTemplate.Builder(matchRule).setSubscriberIds(setOf(TEST_IMSI1))
.setMeteredness(METERED_YES).build().let {
val expectedTemplate = NetworkTemplate(matchRule, TEST_IMSI1,
- arrayOf(TEST_IMSI1), null, METERED_YES,
+ arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
assertEquals(expectedTemplate, it)
@@ -582,7 +595,7 @@
// regardless of IMSI. See buildTemplateMobileWildcard.
NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES).build().let {
val expectedTemplate = NetworkTemplate(MATCH_MOBILE_WILDCARD, null /*subscriberId*/,
- null /*subscriberIds*/, null /*wifiNetworkKey*/,
+ null /*subscriberIds*/, arrayOf<String>(),
METERED_YES, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
assertEquals(expectedTemplate, it)
@@ -594,7 +607,7 @@
.setMeteredness(METERED_YES).setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
.build().let {
val expectedTemplate = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1,
- arrayOf(TEST_IMSI1), null, METERED_YES,
+ arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_UMTS,
OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
assertEquals(expectedTemplate, it)
@@ -604,7 +617,7 @@
// regardless of Wifi Network Key. See buildTemplateWifiWildcard and buildTemplateWifi.
NetworkTemplate.Builder(MATCH_WIFI).build().let {
val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
- null /*subscriberIds*/, null /*wifiNetworkKey*/,
+ null /*subscriberIds*/, arrayOf<String>(),
METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
assertEquals(expectedTemplate, it)
@@ -612,9 +625,9 @@
// Verify template which matches wifi networks with the given Wifi Network Key.
// See buildTemplateWifi(wifiNetworkKey).
- NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKey(TEST_SSID1).build().let {
+ NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
val expectedTemplate = NetworkTemplate(MATCH_WIFI, null /*subscriberId*/,
- null /*subscriberIds*/, TEST_SSID1,
+ null /*subscriberIds*/, arrayOf(TEST_WIFI_KEY1),
METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
assertEquals(expectedTemplate, it)
@@ -623,9 +636,9 @@
// Verify template which matches all wifi networks with the
// given Wifi Network Key, and IMSI. See buildTemplateWifi(wifiNetworkKey, subscriberId).
NetworkTemplate.Builder(MATCH_WIFI).setSubscriberIds(setOf(TEST_IMSI1))
- .setWifiNetworkKey(TEST_SSID1).build().let {
+ .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
val expectedTemplate = NetworkTemplate(MATCH_WIFI, TEST_IMSI1,
- arrayOf(TEST_IMSI1), TEST_SSID1,
+ arrayOf(TEST_IMSI1), arrayOf(TEST_WIFI_KEY1),
METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
assertEquals(expectedTemplate, it)
@@ -636,11 +649,46 @@
listOf(MATCH_ETHERNET, MATCH_BLUETOOTH).forEach { matchRule ->
NetworkTemplate.Builder(matchRule).build().let {
val expectedTemplate = NetworkTemplate(matchRule, null /*subscriberId*/,
- null /*subscriberIds*/, null /*wifiNetworkKey*/,
+ null /*subscriberIds*/, arrayOf<String>(),
METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
assertEquals(expectedTemplate, it)
}
}
}
+
+ @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S)
+ @Test
+ fun testBuilderWifiNetworkKeys() {
+ // Verify template builder which generates same template with the given different
+ // sequence keys.
+ NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(
+ setOf(TEST_WIFI_KEY1, TEST_WIFI_KEY2)).build().let {
+ val expectedTemplate = NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(
+ setOf(TEST_WIFI_KEY2, TEST_WIFI_KEY1)).build()
+ assertEquals(expectedTemplate, it)
+ }
+
+ // Verify template which matches non-wifi networks with the given key is invalid.
+ listOf(MATCH_MOBILE, MATCH_CARRIER, MATCH_ETHERNET, MATCH_BLUETOOTH, -1,
+ Integer.MAX_VALUE).forEach { matchRule ->
+ assertFailsWith<IllegalArgumentException> {
+ NetworkTemplate.Builder(matchRule).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
+ }
+ }
+
+ // Verify template which matches wifi networks with the given null key is invalid.
+ assertFailsWith<IllegalArgumentException> {
+ NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(null)).build()
+ }
+
+ // Verify template which matches wifi wildcard with the given empty key set.
+ NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf<String>()).build().let {
+ val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
+ arrayOf<String>() /*subscriberIds*/, arrayOf<String>(),
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+ assertEquals(expectedTemplate, it)
+ }
+ }
}
diff --git a/tests/unit/java/com/android/internal/net/VpnProfileTest.java b/tests/unit/java/com/android/internal/net/VpnProfileTest.java
index a945a1f..960a9f1 100644
--- a/tests/unit/java/com/android/internal/net/VpnProfileTest.java
+++ b/tests/unit/java/com/android/internal/net/VpnProfileTest.java
@@ -16,6 +16,7 @@
package com.android.internal.net;
+import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
import static com.android.testutils.ParcelUtils.assertParcelSane;
import static org.junit.Assert.assertEquals;
@@ -48,6 +49,7 @@
private static final int ENCODED_INDEX_AUTH_PARAMS_INLINE = 23;
private static final int ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS = 24;
+ private static final int ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE = 25;
@Test
public void testDefaults() throws Exception {
@@ -126,7 +128,12 @@
@Test
public void testParcelUnparcel() {
- assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 23);
+ if (isAtLeastT()) {
+ // excludeLocalRoutes is added in T.
+ assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 24);
+ } else {
+ assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 23);
+ }
}
@Test
@@ -166,7 +173,8 @@
final String tooFewValues =
getEncodedDecodedIkev2ProfileMissingValues(
ENCODED_INDEX_AUTH_PARAMS_INLINE,
- ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS /* missingIndices */);
+ ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS,
+ ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE /* missingIndices */);
assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes()));
}
@@ -183,6 +191,17 @@
}
@Test
+ public void testEncodeDecodeMissingExcludeLocalRoutes() {
+ final String tooFewValues =
+ getEncodedDecodedIkev2ProfileMissingValues(
+ ENCODED_INDEX_EXCLUDE_LOCAL_ROUTE /* missingIndices */);
+
+ // Verify decoding without isRestrictedToTestNetworks defaults to false
+ final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes());
+ assertFalse(decoded.excludeLocalRoutes);
+ }
+
+ @Test
public void testEncodeDecodeLoginsNotSaved() {
final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY);
profile.saveLogin = false;
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index dd92f3a..6416808 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -98,6 +98,7 @@
import android.net.TelephonyNetworkSpecifier;
import android.net.UnderlyingNetworkInfo;
import android.net.netstats.provider.INetworkStatsProviderCallback;
+import android.net.wifi.WifiInfo;
import android.os.Build;
import android.os.ConditionVariable;
import android.os.Handler;
@@ -158,9 +159,9 @@
private static final String IMSI_1 = "310004";
private static final String IMSI_2 = "310260";
- private static final String TEST_SSID = "AndroidAP";
+ private static final String TEST_WIFI_NETWORK_KEY = "WifiNetworkKey";
- private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID);
+ private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_WIFI_NETWORK_KEY);
private static NetworkTemplate sTemplateCarrierWifi1 =
buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL, IMSI_1);
private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
@@ -181,6 +182,7 @@
private File mStatsDir;
private MockContext mServiceContext;
private @Mock TelephonyManager mTelephonyManager;
+ private static @Mock WifiInfo sWifiInfo;
private @Mock INetworkManagementService mNetManager;
private @Mock NetworkStatsFactory mStatsFactory;
private @Mock NetworkStatsSettings mSettings;
@@ -242,6 +244,7 @@
MockitoAnnotations.initMocks(this);
final Context context = InstrumentationRegistry.getContext();
mServiceContext = new MockContext(context);
+ when(sWifiInfo.getCurrentNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY);
mStatsDir = TestIoUtils.createTemporaryDirectory(getClass().getSimpleName());
PowerManager powerManager = (PowerManager) mServiceContext.getSystemService(
@@ -358,7 +361,7 @@
// verify service recorded history
assertNetworkTotal(sTemplateCarrierWifi1, 1024L, 1L, 2048L, 2L, 0);
- // verify service recorded history for wifi with SSID filter
+ // verify service recorded history for wifi with WiFi Network Key filter
assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
@@ -368,7 +371,7 @@
// verify service recorded history
assertNetworkTotal(sTemplateCarrierWifi1, 4096L, 4L, 8192L, 8L, 0);
- // verify service recorded history for wifi with SSID filter
+ // verify service recorded history for wifi with WiFi Network Key filter
assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
}
@@ -774,28 +777,31 @@
@Test
public void testMobileStatsOemManaged() throws Exception {
final NetworkTemplate templateOemPaid = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
- /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID,
- SUBSCRIBER_ID_MATCH_RULE_EXACT);
+ /*subscriberId=*/null, /*matchSubscriberIds=*/null,
+ /*matchWifiNetworkKeys=*/new String[0], METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID, SUBSCRIBER_ID_MATCH_RULE_EXACT);
final NetworkTemplate templateOemPrivate = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
- /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE,
- SUBSCRIBER_ID_MATCH_RULE_EXACT);
+ /*subscriberId=*/null, /*matchSubscriberIds=*/null,
+ /*matchWifiNetworkKeys=*/new String[0], METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE, SUBSCRIBER_ID_MATCH_RULE_EXACT);
final NetworkTemplate templateOemAll = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
- /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_PAID | OEM_PRIVATE, SUBSCRIBER_ID_MATCH_RULE_EXACT);
+ /*subscriberId=*/null, /*matchSubscriberIds=*/null,
+ /*matchWifiNetworkKeys=*/new String[0], METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID | OEM_PRIVATE,
+ SUBSCRIBER_ID_MATCH_RULE_EXACT);
final NetworkTemplate templateOemYes = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
- /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES,
+ /*subscriberId=*/null, /*matchSubscriberIds=*/null,
+ /*matchWifiNetworkKeys=*/new String[0], METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES,
SUBSCRIBER_ID_MATCH_RULE_EXACT);
final NetworkTemplate templateOemNone = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
- /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO,
+ /*subscriberId=*/null, /*matchSubscriberIds=*/null,
+ /*matchWifiNetworkKeys=*/new String[0], METERED_ALL, ROAMING_ALL,
+ DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO,
SUBSCRIBER_ID_MATCH_RULE_EXACT);
// OEM_PAID network comes online.
@@ -1787,7 +1793,7 @@
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered);
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
- capabilities.setSSID(TEST_SSID);
+ capabilities.setTransportInfo(sWifiInfo);
return new NetworkStateSnapshot(WIFI_NETWORK, capabilities, prop, subscriberId, TYPE_WIFI);
}