Snap for 10620181 from 4c0e9c0cf7dd067497cfec2f9774b4cfa5e67e81 to mainline-art-release Change-Id: If2f5de8cc4464056dcd6a955344719fc790e8f8a
diff --git a/Android.bp b/Android.bp index 40bf3ce..15b4235 100644 --- a/Android.bp +++ b/Android.bp
@@ -506,6 +506,9 @@ srcs: [ "jni/network_stack_utils_jni.cpp" ], + header_libs: [ + "bpf_headers", + ], sdk_version: "30", min_sdk_version: "30", shared_libs: [
diff --git a/OWNERS b/OWNERS index 62c5737..c24680e 100644 --- a/OWNERS +++ b/OWNERS
@@ -1,2 +1,2 @@ set noparent -file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking +file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
diff --git a/TEST_MAPPING b/TEST_MAPPING index 3869fc9..46ade58 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING
@@ -7,7 +7,12 @@ "name": "NetworkStackNextTests" }, { - "name": "NetworkStackIntegrationTests" + "name": "NetworkStackIntegrationTests", + "options": [ + { + "exclude-annotation": "com.android.testutils.SkipPresubmit" + } + ] }, { "name": "NetworkStackRootTests" @@ -32,6 +37,11 @@ "name": "NetworkStackRootTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk]" } ], + "postsubmit": [ + { + "name": "NetworkStackIntegrationTests" + } + ], "imports": [ { "path": "packages/modules/Connectivity"
diff --git a/jni/network_stack_utils_jni.cpp b/jni/network_stack_utils_jni.cpp index 5d84f57..b5d97be 100644 --- a/jni/network_stack_utils_jni.cpp +++ b/jni/network_stack_utils_jni.cpp
@@ -36,6 +36,7 @@ #include <netjniutils/netjniutils.h> #include <android/log.h> +#include <bpf/BpfClassic.h> namespace android { constexpr const char NETWORKSTACKUTILS_PKG_NAME[] = @@ -102,25 +103,22 @@ static void network_stack_utils_attachDhcpFilter(JNIEnv *env, jclass clazz, jobject javaFd) { static sock_filter filter_code[] = { // Check the protocol is UDP. - BPF_STMT(BPF_LD | BPF_B | BPF_ABS, kIPv4Protocol), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, IPPROTO_UDP, 0, 6), + BPF_LOAD_IPV4_U8(protocol), + BPF2_REJECT_IF_NOT_EQUAL(IPPROTO_UDP), // Check this is not a fragment. - BPF_STMT(BPF_LD | BPF_H | BPF_ABS, kIPv4FlagsOffset), - BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, IP_MF | IP_OFFMASK, 4, 0), + BPF_LOAD_IPV4_BE16(frag_off), + BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, IP_MF | IP_OFFMASK, 0, 1), + BPF_REJECT, // Get the IP header length. BPF_STMT(BPF_LDX | BPF_B | BPF_MSH, kEtherHeaderLen), // Check the destination port. BPF_STMT(BPF_LD | BPF_H | BPF_IND, kUDPDstPortIndirectOffset), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, kDhcpClientPort, 0, 1), + BPF2_REJECT_IF_NOT_EQUAL(kDhcpClientPort), - // Accept. - BPF_STMT(BPF_RET | BPF_K, 0xffff), - - // Reject. - BPF_STMT(BPF_RET | BPF_K, 0) + BPF_ACCEPT, }; const sock_fprog filter = { sizeof(filter_code) / sizeof(filter_code[0]), @@ -133,28 +131,17 @@ } } -static void network_stack_utils_attachRaFilter(JNIEnv *env, jclass clazz, jobject javaFd, - jint hardwareAddressType) { - if (hardwareAddressType != ARPHRD_ETHER) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "attachRaFilter only supports ARPHRD_ETHER"); - return; - } - +static void network_stack_utils_attachRaFilter(JNIEnv *env, jclass clazz, jobject javaFd) { static sock_filter filter_code[] = { // Check IPv6 Next Header is ICMPv6. - BPF_STMT(BPF_LD | BPF_B | BPF_ABS, kIPv6NextHeader), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, IPPROTO_ICMPV6, 0, 3), + BPF_LOAD_IPV6_U8(nexthdr), + BPF2_REJECT_IF_NOT_EQUAL(IPPROTO_ICMPV6), // Check ICMPv6 type is Router Advertisement. - BPF_STMT(BPF_LD | BPF_B | BPF_ABS, kICMPv6TypeOffset), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_ROUTER_ADVERT, 0, 1), + BPF_LOAD_NET_RELATIVE_U8(sizeof(ipv6hdr) + offsetof(icmp6_hdr, icmp6_type)), + BPF2_REJECT_IF_NOT_EQUAL(ND_ROUTER_ADVERT), - // Accept. - BPF_STMT(BPF_RET | BPF_K, 0xffff), - - // Reject. - BPF_STMT(BPF_RET | BPF_K, 0) + BPF_ACCEPT, }; static const sock_fprog filter = { sizeof(filter_code) / sizeof(filter_code[0]), @@ -227,11 +214,9 @@ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, ND_ROUTER_SOLICIT, 0, 2), BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, ND_NEIGHBOR_ADVERT, 1, 0), - // Accept. - BPF_STMT(BPF_RET | BPF_K, 0xffff), + BPF_ACCEPT, - // Reject. - BPF_STMT(BPF_RET | BPF_K, 0) + BPF_REJECT, }; static const sock_fprog filter = { sizeof(filter_code) / sizeof(filter_code[0]), @@ -252,7 +237,7 @@ /* name, signature, funcPtr */ { "addArpEntry", "([B[BLjava/lang/String;Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_addArpEntry }, { "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_attachDhcpFilter }, - { "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) network_stack_utils_attachRaFilter }, + { "attachRaFilter", "(Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_attachRaFilter }, { "attachControlPacketFilter", "(Ljava/io/FileDescriptor;I)V", (void*) network_stack_utils_attachControlPacketFilter }, };
diff --git a/src/android/net/apf/ApfFilter.java b/src/android/net/apf/ApfFilter.java index 1bc3b41..5c8ff49 100644 --- a/src/android/net/apf/ApfFilter.java +++ b/src/android/net/apf/ApfFilter.java
@@ -537,7 +537,7 @@ socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6); SocketAddress addr = makePacketSocketAddress(ETH_P_IPV6, mInterfaceParams.index); Os.bind(socket, addr); - NetworkStackUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat); + NetworkStackUtils.attachRaFilter(socket); } catch(SocketException|ErrnoException e) { Log.e(TAG, "Error starting filter", e); return;
diff --git a/src/android/net/dhcp6/Dhcp6AdvertisePacket.java b/src/android/net/dhcp6/Dhcp6AdvertisePacket.java index a9fac83..263ab5f 100644 --- a/src/android/net/dhcp6/Dhcp6AdvertisePacket.java +++ b/src/android/net/dhcp6/Dhcp6AdvertisePacket.java
@@ -34,7 +34,7 @@ */ Dhcp6AdvertisePacket(int transId, @NonNull final byte[] clientDuid, @NonNull final byte[] serverDuid, final byte[] iapd) { - super(transId, (short) 0 /* secs */, clientDuid, serverDuid, iapd); + super(transId, 0 /* elapsedTime */, clientDuid, serverDuid, iapd); } /**
diff --git a/src/android/net/dhcp6/Dhcp6Client.java b/src/android/net/dhcp6/Dhcp6Client.java index 975c2c5..d4b4a21 100644 --- a/src/android/net/dhcp6/Dhcp6Client.java +++ b/src/android/net/dhcp6/Dhcp6Client.java
@@ -292,37 +292,35 @@ mTransStartMillis = SystemClock.elapsedRealtime(); } - private short getHundredthsOfSec() { - return (short) ((SystemClock.elapsedRealtime() - mTransStartMillis) / 10); + private long getElapsedTimeMs() { + return SystemClock.elapsedRealtime() - mTransStartMillis; } @SuppressWarnings("ByteBufferBackingArray") private boolean sendSolicitPacket(final ByteBuffer iapd) { final ByteBuffer packet = Dhcp6Packet.buildSolicitPacket(mTransId, - getHundredthsOfSec() /* elapsed time */, iapd.array(), mClientDuid, - true /* rapidCommit */); + getElapsedTimeMs(), iapd.array(), mClientDuid, true /* rapidCommit */); return transmitPacket(packet, "solicit"); } @SuppressWarnings("ByteBufferBackingArray") private boolean sendRequestPacket(final ByteBuffer iapd) { - final ByteBuffer packet = Dhcp6Packet.buildRequestPacket(mTransId, - getHundredthsOfSec() /* elapsed time */, iapd.array(), mClientDuid, - mServerDuid); + final ByteBuffer packet = Dhcp6Packet.buildRequestPacket(mTransId, getElapsedTimeMs(), + iapd.array(), mClientDuid, mServerDuid); return transmitPacket(packet, "request"); } @SuppressWarnings("ByteBufferBackingArray") private boolean sendRenewPacket(final ByteBuffer iapd) { - final ByteBuffer packet = Dhcp6Packet.buildRenewPacket(mTransId, - getHundredthsOfSec() /* elapsed time*/, iapd.array(), mClientDuid, mServerDuid); + final ByteBuffer packet = Dhcp6Packet.buildRenewPacket(mTransId, getElapsedTimeMs(), + iapd.array(), mClientDuid, mServerDuid); return transmitPacket(packet, "renew"); } @SuppressWarnings("ByteBufferBackingArray") private boolean sendRebindPacket(final ByteBuffer iapd) { - final ByteBuffer packet = Dhcp6Packet.buildRebindPacket(mTransId, - getHundredthsOfSec() /* elapsed time */, iapd.array(), mClientDuid); + final ByteBuffer packet = Dhcp6Packet.buildRebindPacket(mTransId, getElapsedTimeMs(), + iapd.array(), mClientDuid); return transmitPacket(packet, "rebind"); } @@ -632,7 +630,7 @@ @Override protected void handlePacket(byte[] recvbuf, int length) { try { - final Dhcp6Packet packet = Dhcp6Packet.decodePacket(recvbuf, length); + final Dhcp6Packet packet = Dhcp6Packet.decode(recvbuf, length); if (DBG) Log.d(TAG, "Received packet: " + packet); sendMessage(CMD_RECEIVED_PACKET, packet); } catch (Dhcp6Packet.ParseException e) {
diff --git a/src/android/net/dhcp6/Dhcp6Packet.java b/src/android/net/dhcp6/Dhcp6Packet.java index 9682556..8a11547 100644 --- a/src/android/net/dhcp6/Dhcp6Packet.java +++ b/src/android/net/dhcp6/Dhcp6Packet.java
@@ -80,7 +80,7 @@ * This time is expressed in hundredths of a second. */ public static final byte DHCP6_ELAPSED_TIME = 8; - protected final short mSecs; + protected final int mElapsedTime; /** * DHCPv6 Optional Type: Status Code. @@ -123,10 +123,10 @@ */ protected int mIaId; - Dhcp6Packet(int transId, short secs, @NonNull final byte[] clientDuid, final byte[] serverDuid, - @NonNull final byte[] iapd) { + Dhcp6Packet(int transId, int elapsedTime, @NonNull final byte[] clientDuid, + final byte[] serverDuid, @NonNull final byte[] iapd) { mTransId = transId; - mSecs = secs; + mElapsedTime = elapsedTime; mClientDuid = clientDuid; mServerDuid = serverDuid; mIaPd = iapd; @@ -249,8 +249,8 @@ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ @VisibleForTesting - static Dhcp6Packet decodePacket(@NonNull final ByteBuffer packet) throws ParseException { - short secs = 0; + static Dhcp6Packet decode(@NonNull final ByteBuffer packet) throws ParseException { + int elapsedTime = 0; byte[] iapd = null; byte[] serverDuid = null; byte[] clientDuid = null; @@ -308,7 +308,7 @@ break; case DHCP6_ELAPSED_TIME: expectedLen = 2; - secs = packet.getShort(); + elapsedTime = (int) (packet.getShort() & 0xFFFF); break; case DHCP6_STATUS_CODE: expectedLen = optionLen; @@ -335,23 +335,26 @@ switch(messageType) { case DHCP6_MESSAGE_TYPE_SOLICIT: - newPacket = new Dhcp6SolicitPacket(transId, secs, clientDuid, iapd, rapidCommit); + newPacket = new Dhcp6SolicitPacket(transId, elapsedTime, clientDuid, iapd, + rapidCommit); break; case DHCP6_MESSAGE_TYPE_ADVERTISE: newPacket = new Dhcp6AdvertisePacket(transId, clientDuid, serverDuid, iapd); break; case DHCP6_MESSAGE_TYPE_REQUEST: - newPacket = new Dhcp6RequestPacket(transId, secs, clientDuid, serverDuid, iapd); + newPacket = new Dhcp6RequestPacket(transId, elapsedTime, clientDuid, serverDuid, + iapd); break; case DHCP6_MESSAGE_TYPE_REPLY: newPacket = new Dhcp6ReplyPacket(transId, clientDuid, serverDuid, iapd, rapidCommit); break; case DHCP6_MESSAGE_TYPE_RENEW: - newPacket = new Dhcp6RenewPacket(transId, secs, clientDuid, serverDuid, iapd); + newPacket = new Dhcp6RenewPacket(transId, elapsedTime, clientDuid, serverDuid, + iapd); break; case DHCP6_MESSAGE_TYPE_REBIND: - newPacket = new Dhcp6RebindPacket(transId, secs, clientDuid, iapd); + newPacket = new Dhcp6RebindPacket(transId, elapsedTime, clientDuid, iapd); break; default: throw new ParseException("Unimplemented DHCP6 message type %d" + messageType); @@ -376,10 +379,10 @@ /** * Parse a packet from an array of bytes, stopping at the given length. */ - public static Dhcp6Packet decodePacket(@NonNull final byte[] packet, int length) + public static Dhcp6Packet decode(@NonNull final byte[] packet, int length) throws ParseException { final ByteBuffer buffer = ByteBuffer.wrap(packet, 0, length).order(ByteOrder.BIG_ENDIAN); - return decodePacket(buffer); + return decode(buffer); } /** @@ -524,10 +527,11 @@ /** * Builds a DHCPv6 SOLICIT packet from the required specified parameters. */ - public static ByteBuffer buildSolicitPacket(int transId, short secs, @NonNull final byte[] iapd, - @NonNull final byte[] clientDuid, boolean rapidCommit) { + public static ByteBuffer buildSolicitPacket(int transId, long millisecs, + @NonNull final byte[] iapd, @NonNull final byte[] clientDuid, boolean rapidCommit) { final Dhcp6SolicitPacket pkt = - new Dhcp6SolicitPacket(transId, secs, clientDuid, iapd, rapidCommit); + new Dhcp6SolicitPacket(transId, (int) (millisecs / 10) /* elapsed time */, + clientDuid, iapd, rapidCommit); return pkt.buildPacket(); } @@ -555,29 +559,34 @@ /** * Builds a DHCPv6 REQUEST packet from the required specified parameters. */ - public static ByteBuffer buildRequestPacket(int transId, short secs, @NonNull final byte[] iapd, - @NonNull final byte[] clientDuid, @NonNull final byte[] serverDuid) { + public static ByteBuffer buildRequestPacket(int transId, long millisecs, + @NonNull final byte[] iapd, @NonNull final byte[] clientDuid, + @NonNull final byte[] serverDuid) { final Dhcp6RequestPacket pkt = - new Dhcp6RequestPacket(transId, secs, clientDuid, serverDuid, iapd); + new Dhcp6RequestPacket(transId, (int) (millisecs / 10) /* elapsed time */, + clientDuid, serverDuid, iapd); return pkt.buildPacket(); } /** * Builds a DHCPv6 RENEW packet from the required specified parameters. */ - public static ByteBuffer buildRenewPacket(int transId, short secs, @NonNull final byte[] iapd, - @NonNull final byte[] clientDuid, @NonNull final byte[] serverDuid) { + public static ByteBuffer buildRenewPacket(int transId, long millisecs, + @NonNull final byte[] iapd, @NonNull final byte[] clientDuid, + @NonNull final byte[] serverDuid) { final Dhcp6RenewPacket pkt = - new Dhcp6RenewPacket(transId, secs, clientDuid, serverDuid, iapd); + new Dhcp6RenewPacket(transId, (int) (millisecs / 10) /* elapsed time */, clientDuid, + serverDuid, iapd); return pkt.buildPacket(); } /** * Builds a DHCPv6 REBIND packet from the required specified parameters. */ - public static ByteBuffer buildRebindPacket(int transId, short secs, @NonNull final byte[] iapd, - @NonNull final byte[] clientDuid) { - final Dhcp6RebindPacket pkt = new Dhcp6RebindPacket(transId, secs, clientDuid, iapd); + public static ByteBuffer buildRebindPacket(int transId, long millisecs, + @NonNull final byte[] iapd, @NonNull final byte[] clientDuid) { + final Dhcp6RebindPacket pkt = new Dhcp6RebindPacket(transId, + (int) (millisecs / 10) /* elapsed time */, clientDuid, iapd); return pkt.buildPacket(); } }
diff --git a/src/android/net/dhcp6/Dhcp6RebindPacket.java b/src/android/net/dhcp6/Dhcp6RebindPacket.java index 33a9fc1..87f2f45 100644 --- a/src/android/net/dhcp6/Dhcp6RebindPacket.java +++ b/src/android/net/dhcp6/Dhcp6RebindPacket.java
@@ -33,9 +33,9 @@ /** * Generates a rebind packet with the specified parameters. */ - Dhcp6RebindPacket(int transId, short secs, @NonNull final byte[] clientDuid, + Dhcp6RebindPacket(int transId, int elapsedTime, @NonNull final byte[] clientDuid, @NonNull final byte[] iapd) { - super(transId, secs, clientDuid, null /* serverDuid */, iapd); + super(transId, elapsedTime, clientDuid, null /* serverDuid */, iapd); } /** @@ -47,7 +47,7 @@ packet.putInt(msgTypeAndTransId); addTlv(packet, DHCP6_CLIENT_IDENTIFIER, getClientDuid()); - addTlv(packet, DHCP6_ELAPSED_TIME, mSecs); + addTlv(packet, DHCP6_ELAPSED_TIME, (short) (mElapsedTime & 0xFFFF)); addTlv(packet, DHCP6_IA_PD, mIaPd); packet.flip();
diff --git a/src/android/net/dhcp6/Dhcp6RenewPacket.java b/src/android/net/dhcp6/Dhcp6RenewPacket.java index 3de73df..8c6686c 100644 --- a/src/android/net/dhcp6/Dhcp6RenewPacket.java +++ b/src/android/net/dhcp6/Dhcp6RenewPacket.java
@@ -33,9 +33,9 @@ /** * Generates a renew packet with the specified parameters. */ - Dhcp6RenewPacket(int transId, short secs, @NonNull final byte[] clientDuid, + Dhcp6RenewPacket(int transId, int elapsedTime, @NonNull final byte[] clientDuid, @NonNull final byte[] serverDuid, final byte[] iapd) { - super(transId, secs, clientDuid, serverDuid, iapd); + super(transId, elapsedTime, clientDuid, serverDuid, iapd); } /** @@ -48,7 +48,7 @@ addTlv(packet, DHCP6_SERVER_IDENTIFIER, mServerDuid); addTlv(packet, DHCP6_CLIENT_IDENTIFIER, mClientDuid); - addTlv(packet, DHCP6_ELAPSED_TIME, mSecs); + addTlv(packet, DHCP6_ELAPSED_TIME, (short) (mElapsedTime & 0xFFFF)); addTlv(packet, DHCP6_IA_PD, mIaPd); packet.flip();
diff --git a/src/android/net/dhcp6/Dhcp6ReplyPacket.java b/src/android/net/dhcp6/Dhcp6ReplyPacket.java index 15f748b..d68fbdb 100644 --- a/src/android/net/dhcp6/Dhcp6ReplyPacket.java +++ b/src/android/net/dhcp6/Dhcp6ReplyPacket.java
@@ -35,7 +35,7 @@ */ Dhcp6ReplyPacket(int transId, @NonNull final byte[] clientDuid, @NonNull final byte[] serverDuid, final byte[] iapd, boolean rapidCommit) { - super(transId, (short) 0 /* secs */, clientDuid, serverDuid, iapd); + super(transId, 0 /* elapsedTime */, clientDuid, serverDuid, iapd); mRapidCommit = rapidCommit; }
diff --git a/src/android/net/dhcp6/Dhcp6RequestPacket.java b/src/android/net/dhcp6/Dhcp6RequestPacket.java index 5671502..0c65f17 100644 --- a/src/android/net/dhcp6/Dhcp6RequestPacket.java +++ b/src/android/net/dhcp6/Dhcp6RequestPacket.java
@@ -32,9 +32,9 @@ /** * Generates a request packet with the specified parameters. */ - Dhcp6RequestPacket(int transId, short secs, @NonNull final byte[] clientDuid, + Dhcp6RequestPacket(int transId, int elapsedTime, @NonNull final byte[] clientDuid, @NonNull final byte[] serverDuid, final byte[] iapd) { - super(transId, secs, clientDuid, serverDuid, iapd); + super(transId, elapsedTime, clientDuid, serverDuid, iapd); } /** @@ -47,7 +47,7 @@ addTlv(packet, DHCP6_SERVER_IDENTIFIER, mServerDuid); addTlv(packet, DHCP6_CLIENT_IDENTIFIER, mClientDuid); - addTlv(packet, DHCP6_ELAPSED_TIME, mSecs); + addTlv(packet, DHCP6_ELAPSED_TIME, (short) (mElapsedTime & 0xFFFF)); addTlv(packet, DHCP6_IA_PD, mIaPd); packet.flip();
diff --git a/src/android/net/dhcp6/Dhcp6SolicitPacket.java b/src/android/net/dhcp6/Dhcp6SolicitPacket.java index 69dc81e..4916c1e 100644 --- a/src/android/net/dhcp6/Dhcp6SolicitPacket.java +++ b/src/android/net/dhcp6/Dhcp6SolicitPacket.java
@@ -31,9 +31,9 @@ /** * Generates a solicit packet with the specified parameters. */ - Dhcp6SolicitPacket(int transId, short secs, @NonNull final byte[] clientDuid, + Dhcp6SolicitPacket(int transId, int elapsedTime, @NonNull final byte[] clientDuid, final byte[] iapd, boolean rapidCommit) { - super(transId, secs, clientDuid, null /* serverDuid */, iapd); + super(transId, elapsedTime, clientDuid, null /* serverDuid */, iapd); mRapidCommit = rapidCommit; } @@ -45,7 +45,7 @@ final int msgTypeAndTransId = (DHCP6_MESSAGE_TYPE_SOLICIT << 24) | mTransId; packet.putInt(msgTypeAndTransId); - addTlv(packet, DHCP6_ELAPSED_TIME, mSecs); + addTlv(packet, DHCP6_ELAPSED_TIME, (short) (mElapsedTime & 0xFFFF)); addTlv(packet, DHCP6_CLIENT_IDENTIFIER, mClientDuid); addTlv(packet, DHCP6_IA_PD, mIaPd); if (mRapidCommit) {
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java index b3a0652..c169ad5 100644 --- a/src/android/net/ip/IpClient.java +++ b/src/android/net/ip/IpClient.java
@@ -2814,11 +2814,10 @@ // Delete the global IPv6 address based on delegated prefix from interface. for (LinkAddress la : mLinkProperties.getLinkAddresses()) { - if (!la.isIpv6()) continue; - final Inet6Address address = (Inet6Address) la.getAddress(); - if (la.isIpv6() && prefix.contains(address)) { - NetlinkUtils.sendRtmDelAddressRequest(mInterfaceParams.index, address, - (short) la.getPrefixLength()); + final InetAddress address = la.getAddress(); + if (prefix.contains(address)) { + NetlinkUtils.sendRtmDelAddressRequest(mInterfaceParams.index, + (Inet6Address) address, (short) la.getPrefixLength()); } } }
diff --git a/src/android/net/ip/IpReachabilityMonitor.java b/src/android/net/ip/IpReachabilityMonitor.java index ff6d65e..4d40c4f 100644 --- a/src/android/net/ip/IpReachabilityMonitor.java +++ b/src/android/net/ip/IpReachabilityMonitor.java
@@ -262,7 +262,7 @@ IP_REACHABILITY_MCAST_RESOLICIT_VERSION, true /* defaultEnabled */); mIgnoreIncompleteIpv6DnsServerEnabled = dependencies.isFeatureEnabled(context, IP_REACHABILITY_IGNORE_INCOMPLETE_IPV6_DNS_SERVER_VERSION, - false /* defaultEnabled */); + true /* defaultEnabled */); mIgnoreIncompleteIpv6DefaultRouterEnabled = dependencies.isFeatureEnabled(context, IP_REACHABILITY_IGNORE_INCOMPLETE_IPV6_DEFAULT_ROUTER_VERSION, false /* defaultEnabled */);
diff --git a/src/com/android/networkstack/util/NetworkStackUtils.java b/src/com/android/networkstack/util/NetworkStackUtils.java index 8559a26..8fb157c 100755 --- a/src/com/android/networkstack/util/NetworkStackUtils.java +++ b/src/com/android/networkstack/util/NetworkStackUtils.java
@@ -385,9 +385,8 @@ /** * Attaches a socket filter that accepts ICMPv6 router advertisements to the given socket. * @param fd the socket's {@link FileDescriptor}. - * @param packetType the hardware address type, one of ARPHRD_*. */ - public static native void attachRaFilter(FileDescriptor fd, int packetType) + public static native void attachRaFilter(FileDescriptor fd) throws SocketException; /**
diff --git a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java index dfc8c1a..6f30d4c 100644 --- a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java +++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -218,6 +218,7 @@ import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; import com.android.testutils.HandlerUtils; +import com.android.testutils.SkipPresubmit; import com.android.testutils.TapPacketReader; import com.android.testutils.TestableNetworkAgent; import com.android.testutils.TestableNetworkCallback; @@ -1289,7 +1290,7 @@ // Strip the Ethernet/IPv6/UDP headers, only keep DHCPv6 message payload for decode. final byte[] payload = Arrays.copyOfRange(packet, DHCP6_HEADER_OFFSET, packet.length); - final Dhcp6Packet dhcp6Packet = Dhcp6Packet.decodePacket(payload, payload.length); + final Dhcp6Packet dhcp6Packet = Dhcp6Packet.decode(payload, payload.length); if (dhcp6Packet != null) return dhcp6Packet; } return null; @@ -4851,6 +4852,8 @@ x -> x.isIpv6Provisioned() && hasIpv6AddressPrefixedWith(x, prefix) && hasRouteTo(x, "2001:db8:1::/64", RTN_UNREACHABLE) + // IPv4 address, IPv6 link-local, two global delegated IPv6 addresses + && x.getLinkAddresses().size() == 4 )); } @@ -4886,8 +4889,9 @@ assertTrue(packet instanceof Dhcp6RebindPacket); } - @Test @SignatureRequiredTest(reason = "Need to mock the DHCP6 renew/rebind alarms") + @SkipPresubmit(reason = "Out of SLO flakiness") + @Test public void testDhcp6Pd_prefixMismatchOnRenew() throws Exception { prepareDhcp6PdRenewTest();
diff --git a/tests/integration/signature/android/net/NetworkStatsIntegrationTest.kt b/tests/integration/signature/android/net/NetworkStatsIntegrationTest.kt index dcc0b1f..0f860a8 100644 --- a/tests/integration/signature/android/net/NetworkStatsIntegrationTest.kt +++ b/tests/integration/signature/android/net/NetworkStatsIntegrationTest.kt
@@ -34,6 +34,7 @@ import com.android.testutils.DevSdkIgnoreRunner import com.android.testutils.PacketBridge import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged +import com.android.testutils.SkipPresubmit import com.android.testutils.TestDnsServer import com.android.testutils.TestHttpServer import com.android.testutils.TestableNetworkCallback @@ -178,6 +179,7 @@ * While the packets are being forwarded to the external interface, the servers will see * the packets originated from the mocked v6 address, and destined to a local v6 address. */ + @SkipPresubmit(reason = "Out of SLO flakiness") @Test fun test464XlatTcpStats() { // Wait for 464Xlat to be ready.
diff --git a/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt b/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt index cf514e9..2377ffa 100644 --- a/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt +++ b/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt
@@ -176,7 +176,7 @@ echo.rewind() assertNextPacketEquals(socket, echo.readAsArray(), "ICMPv6 echo") - NetworkStackUtils.attachRaFilter(socket, ARPHRD_ETHER) + NetworkStackUtils.attachRaFilter(socket) // Send another echo, then an RA. After setting the filter expect only the RA. echo.rewind() reader.sendResponse(echo)
diff --git a/tests/unit/src/android/net/dhcp6/Dhcp6PacketTest.kt b/tests/unit/src/android/net/dhcp6/Dhcp6PacketTest.kt index 2d093f7..de97ed4 100644 --- a/tests/unit/src/android/net/dhcp6/Dhcp6PacketTest.kt +++ b/tests/unit/src/android/net/dhcp6/Dhcp6PacketTest.kt
@@ -42,7 +42,7 @@ // IA prefix option(option_len=25) "001A001900000000000000004000000000000000000000000000000000" val bytes = HexDump.hexStringToByteArray(solicitHex) - val packet = Dhcp6Packet.decodePacket(ByteBuffer.wrap(bytes)) + val packet = Dhcp6Packet.decode(ByteBuffer.wrap(bytes)) assertTrue(packet is Dhcp6SolicitPacket) } @@ -61,7 +61,7 @@ "001A001900000000000000004000000000000000000000000000000000" val bytes = HexDump.hexStringToByteArray(solicitHex) assertThrows(Dhcp6Packet.ParseException::class.java) { - Dhcp6Packet.decodePacket(ByteBuffer.wrap(bytes)) + Dhcp6Packet.decode(ByteBuffer.wrap(bytes)) } } @@ -80,7 +80,7 @@ "001A0019000000000000000040000000000000000000000000000000" val bytes = HexDump.hexStringToByteArray(solicitHex) assertThrows(Dhcp6Packet.ParseException::class.java) { - Dhcp6Packet.decodePacket(ByteBuffer.wrap(bytes)) + Dhcp6Packet.decode(ByteBuffer.wrap(bytes)) } } @@ -99,7 +99,7 @@ "001A001900000000000000004000000000000000000000000000000000" val bytes = HexDump.hexStringToByteArray(solicitHex) assertThrows(Dhcp6Packet.ParseException::class.java) { - Dhcp6Packet.decodePacket(ByteBuffer.wrap(bytes)) + Dhcp6Packet.decode(ByteBuffer.wrap(bytes)) } } @@ -119,7 +119,7 @@ // IA prefix option(option_len=25, prefix="fdfd:9ed6:7950:2::/64") "001A00190000019F0000A8C040FDFD9ED6795000010000000000000000" val bytes = HexDump.hexStringToByteArray(advertiseHex) - val packet = Dhcp6Packet.decodePacket(ByteBuffer.wrap(bytes)) + val packet = Dhcp6Packet.decode(ByteBuffer.wrap(bytes)) assertTrue(packet is Dhcp6AdvertisePacket) } @@ -142,7 +142,7 @@ "001A00190000019F0000A8C040FDFD9ED6795000010000000000000000" val bytes = HexDump.hexStringToByteArray(advertiseHex) // The unsupported option will be skipped normally and won't throw ParseException. - val packet = Dhcp6Packet.decodePacket(ByteBuffer.wrap(bytes)) + val packet = Dhcp6Packet.decode(ByteBuffer.wrap(bytes)) assertTrue(packet is Dhcp6AdvertisePacket) } }
diff --git a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java index 19c9e5e..4cf6f34 100644 --- a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java +++ b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -90,7 +90,6 @@ import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; @@ -578,7 +577,7 @@ return null; }).when(mContext).unregisterReceiver(any()); - resetCallbacks(); + initCallbacks(11 /* interfaceVersion */); setMinDataStallEvaluateInterval(TEST_MIN_STALL_EVALUATE_INTERVAL_MS); setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS); @@ -609,12 +608,7 @@ } } - private void resetCallbacks() throws Exception { - resetCallbacks(11); - } - - private void resetCallbacks(int interfaceVersion) throws Exception { - reset(mCallbacks); + private void initCallbacks(int interfaceVersion) throws Exception { try { doReturn(interfaceVersion).when(mCallbacks).getInterfaceVersion(); } catch (RemoteException e) { @@ -1025,7 +1019,6 @@ verify(mContext, times(1)).registerReceiver(receiverCaptor.capture(), argThat(receiver -> ACTION_CONFIGURATION_CHANGED.equals(receiver.getAction(0)))); - resetCallbacks(); // New URLs with partial connectivity doReturn(TEST_HTTPS_OTHER_URL1).when(mResources).getString( R.string.config_captive_portal_https_url); @@ -1039,7 +1032,8 @@ HandlerUtils.waitForIdle(nm.getHandler(), HANDLER_TIMEOUT_MS); verifyNetworkTested(NETWORK_VALIDATION_RESULT_PARTIAL, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP); + NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP, + 1 /* interactions */); verify(mOtherHttpsConnection1, times(1)).getResponseCode(); verify(mOtherHttpConnection1, times(1)).getResponseCode(); } @@ -1311,7 +1305,7 @@ assertTrue(INITIAL_REEVALUATE_DELAY_MS < 2000); verify(mOtherFallbackConnection, timeout(INITIAL_REEVALUATE_DELAY_MS + HANDLER_TIMEOUT_MS)) .getResponseCode(); - verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL); + verifyNetworkTestedPortal(TEST_LOGIN_URL, 1 /* interactions */); } @Test @@ -1403,8 +1397,7 @@ + "'user-portal-url': '" + TEST_LOGIN_URL + "'}"); nm.notifyLinkPropertiesChanged(makeCapportLPs()); - verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, - TEST_LOGIN_URL); + verifyNetworkTestedPortal(TEST_LOGIN_URL, 1 /* interactions */); final ArgumentCaptor<CaptivePortalData> capportCaptor = ArgumentCaptor.forClass( CaptivePortalData.class); verify(mCallbacks).notifyCaptivePortalDataChanged(capportCaptor.capture()); @@ -1435,7 +1428,7 @@ // After notifyNetworkConnected, validation uses the capport API contents notifyNetworkConnected(nm, lp, CELL_METERED_CAPABILITIES); - verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL); + verifyNetworkTestedPortal(TEST_LOGIN_URL, 1 /* interactions */); verify(mHttpConnection, never()).getResponseCode(); verify(mCapportApiConnection).getResponseCode(); @@ -1555,25 +1548,19 @@ NETWORK_VALIDATION_RESULT_VALID, NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS, null); - resetCallbacks(); // Underlying network changed. notifyUnderlyingNetworkChange(nm, nc , List.of(new Network(TEST_NETID))); // The underlying network change should cause a re-validation - verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS); + verifyNetworkTestedValidFromHttps(1 /* interactions */); - resetCallbacks(); notifyUnderlyingNetworkChange(nm, nc , List.of(new Network(TEST_NETID))); - // Identical networks should not cause revalidation. - verify(mCallbacks, never()).notifyNetworkTestedWithExtras(matchNetworkTestResultParcelable( - NETWORK_VALIDATION_RESULT_VALID, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS)); + // Identical networks should not cause revalidation. The interaction stays in 1 time which + // is verified in runNetworkTest. + verifyNetworkTestedValidFromHttps(1 /* interactions */); - resetCallbacks(); // Change to another network notifyUnderlyingNetworkChange(nm, nc , List.of(new Network(TEST_NETID2))); - verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS); + verifyNetworkTestedValidFromHttps(2 /* interactions */); } private void notifyUnderlyingNetworkChange(NetworkMonitor nm, NetworkCapabilities nc, @@ -1974,7 +1961,7 @@ @Test public void testNoInternetCapabilityValidated_OlderPlatform() throws Exception { // Before callbacks version 11, NETWORK_VALIDATION_RESULT_SKIPPED is not sent - resetCallbacks(10); + initCallbacks(10); doValidationSkippedTest(CELL_NO_INTERNET_CAPABILITIES, NETWORK_VALIDATION_RESULT_VALID); } @@ -2127,8 +2114,6 @@ // Portal URL should be detection URL. final String redirectUrl = bundle.getString(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL); assertEquals(expectedUrl, redirectUrl); - - resetCallbacks(); } @@ -2206,29 +2191,25 @@ wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns6.google", new InetAddress[0])); notifyNetworkConnected(wnm, CELL_NOT_METERED_CAPABILITIES); - verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID); - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged( - eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID)); + verifyNetworkTestedValidFromPrivateDns(1 /* interactions */); + verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */); // Verify dns query only get v4 address. - resetCallbacks(); mFakeDns.setAnswer("dns4.google", new String[]{"192.0.2.1"}, TYPE_A); wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns4.google", new InetAddress[0])); - verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID); + verifyNetworkTestedValidFromPrivateDns(2 /* interactions */); // NetworkMonitor will check if the probes has changed or not, if the probes has not - // changed, the callback won't be fired. - verify(mCallbacks, never()).notifyProbeStatusChanged( - eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID)); + // changed, the callback won't be fired. The interaction stays in 1 time. + verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */); // Verify dns query get both v4 and v6 address. - resetCallbacks(); mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::54"}, TYPE_AAAA); mFakeDns.setAnswer("dns.google", new String[]{"192.0.2.3"}, TYPE_A); wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0])); - verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID); - verify(mCallbacks, never()).notifyProbeStatusChanged( - eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID)); + verifyNetworkTestedValidFromPrivateDns(3 /* interactions */); + // Verify no further interaction. + verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */); } @Test @@ -2240,22 +2221,18 @@ WrappedNetworkMonitor wnm = makeCellNotMeteredNetworkMonitor(); wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0])); notifyNetworkConnected(wnm, CELL_NOT_METERED_CAPABILITIES); - verifyNetworkTested(VALIDATION_RESULT_INVALID, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS); - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyProbeStatusChanged( - eq(PROBES_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS - | NETWORK_VALIDATION_PROBE_HTTPS)); + verifyNetworkTestedInvalidFromHttps(1 /* interactions */); + verifyProbeStatusChangedPrivateDnsCompleteAndHttpsSucceeded(1 /* interaction */); + // Fix DNS and retry, expect validation to succeed. - resetCallbacks(); mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::1"}, TYPE_AAAA); wnm.forceReevaluation(Process.myUid()); // ProbeCompleted should be reset to 0 HandlerUtils.waitForIdle(wnm.getHandler(), HANDLER_TIMEOUT_MS); assertEquals(wnm.getEvaluationState().getProbeCompletedResult(), 0); - verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID); - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyProbeStatusChanged( - eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID)); + verifyNetworkTestedValidFromPrivateDns(1 /* interactions */); + verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */); } @Test @@ -2267,57 +2244,40 @@ WrappedNetworkMonitor wnm = makeCellNotMeteredNetworkMonitor(); wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0])); notifyNetworkConnected(wnm, CELL_NOT_METERED_CAPABILITIES); - verifyNetworkTested(VALIDATION_RESULT_INVALID, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS); - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged( - eq(PROBES_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS - | NETWORK_VALIDATION_PROBE_HTTPS)); + verifyNetworkTestedInvalidFromHttps(1 /* interactions */); + verifyProbeStatusChangedPrivateDnsCompleteAndHttpsSucceeded(1 /* interactions */); // Fix DNS and retry, expect validation to succeed. - resetCallbacks(); mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::1"}, TYPE_AAAA); wnm.forceReevaluation(Process.myUid()); - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce()) - .notifyNetworkTestedWithExtras(matchNetworkTestResultParcelable( - NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID)); - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged( - eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID)); + verifyNetworkTestedValidFromPrivateDns(1 /* interactions */); + verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */); // Change configuration to an invalid DNS name, expect validation to fail. - resetCallbacks(); mFakeDns.setAnswer("dns.bad", new String[0], TYPE_A); mFakeDns.setAnswer("dns.bad", new String[0], TYPE_AAAA); wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.bad", new InetAddress[0])); // Strict mode hostname resolve fail. Expect only notification for evaluation fail. No probe // notification. - verifyNetworkTested(VALIDATION_RESULT_INVALID, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS); - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged( - eq(PROBES_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS - | NETWORK_VALIDATION_PROBE_HTTPS)); + verifyNetworkTestedInvalidFromHttps(2 /* interactions */); + verifyProbeStatusChangedPrivateDnsCompleteAndHttpsSucceeded(2 /* interaction */); // Change configuration back to working again, but make private DNS not work. // Expect validation to fail. - resetCallbacks(); mFakeDns.setNonBypassPrivateDnsWorking(false); wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0])); - verifyNetworkTested(VALIDATION_RESULT_INVALID, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS); + verifyNetworkTestedInvalidFromHttps(3 /* interactions */); // NetworkMonitor will check if the probes has changed or not, if the probes has not - // changed, the callback won't be fired. - verify(mCallbacks, never()).notifyProbeStatusChanged( - eq(PROBES_PRIVDNS_VALID), eq(NETWORK_VALIDATION_PROBE_DNS - | NETWORK_VALIDATION_PROBE_HTTPS)); + // changed, the callback won't be fired. No further interaction. + verifyProbeStatusChangedPrivateDnsCompleteAndHttpsSucceeded(2 /* interaction */); // Make private DNS work again. Expect validation to succeed. - resetCallbacks(); mFakeDns.setNonBypassPrivateDnsWorking(true); wnm.forceReevaluation(Process.myUid()); - verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID); - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged( - eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID)); + verifyNetworkTestedValidFromPrivateDns(1 /* interactions */); + verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(1 /* interaction */); } @Test @@ -2423,8 +2383,7 @@ fail("Undefined transport type"); } notifyNetworkConnected(nm, nc); - verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS); + verifyNetworkTestedValidFromHttps(1 /* interactions */); nm.setLastProbeTime(SystemClock.elapsedRealtime() - STALL_EXPECTED_LAST_PROBE_TIME_MS); return nm; } @@ -2633,11 +2592,11 @@ NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP, null /* redirectUrl */); - resetCallbacks(); nm.setAcceptPartialConnectivity(); // Expect to update evaluation result notifications to CS. verifyNetworkTested(NETWORK_VALIDATION_RESULT_PARTIAL | NETWORK_VALIDATION_RESULT_VALID, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP); + NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP, + 1 /* interactions */); } @Test @@ -2710,7 +2669,6 @@ final NetworkMonitor nm = runValidatedNetworkTest(); // Verify forceReevaluation will not reset the validation result but only probe result until // getting the validation result. - resetCallbacks(); setSslException(mHttpsConnection); setStatus(mHttpConnection, 500); setStatus(mFallbackConnection, 204); @@ -2718,7 +2676,7 @@ // Expect to send HTTP, HTTPs, FALLBACK and evaluation results. verifyNetworkTested(VALIDATION_RESULT_INVALID, NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_FALLBACK, - null /* redirectUrl */); + 1 /* interactions */); HandlerUtils.waitForIdle(nm.getHandler(), HANDLER_TIMEOUT_MS); } @@ -2726,7 +2684,7 @@ public void testNotifyNetwork_NotifyNetworkTestedOldInterfaceVersion() throws Exception { // Use old interface version so notifyNetworkTested is used over // notifyNetworkTestedWithExtras - resetCallbacks(4); + initCallbacks(4); // Trigger Network validation setStatus(mHttpsConnection, 204); @@ -2813,8 +2771,6 @@ setValidProbes(); final NetworkMonitor nm = runValidatedNetworkTest(); - resetCallbacks(); - nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, CaptivePortalProbeResult.success(1 << PROBE_HTTP)); // Verify result should be appended and notifyNetworkTestedWithExtras callback is triggered @@ -2842,20 +2798,22 @@ nm.getEvaluationState().reportEvaluationResult(NETWORK_VALIDATION_RESULT_VALID, null /* redirectUrl */); verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP); + NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP, + 1 /* interactions */); nm.getEvaluationState().reportEvaluationResult( NETWORK_VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL, null /* redirectUrl */); verifyNetworkTested( NETWORK_VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL, - NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP); + NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP, + 1 /* interactions */); nm.getEvaluationState().reportEvaluationResult(VALIDATION_RESULT_INVALID, TEST_REDIRECT_URL); verifyNetworkTested(VALIDATION_RESULT_INVALID, NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP, - TEST_REDIRECT_URL); + TEST_REDIRECT_URL, 1 /* interactions */); } @Test @@ -2997,14 +2955,13 @@ verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)) .showProvisioningNotification(any(), any()); assertCaptivePortalAppReceiverRegistered(true /* isPortal */); - verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL); + verifyNetworkTestedPortal(TEST_LOGIN_URL, 1 /* interactions */); // Force reevaluation and confirm that the network is still captive HandlerUtils.waitForIdle(monitor.getHandler(), HANDLER_TIMEOUT_MS); - resetCallbacks(); monitor.forceReevaluation(Process.myUid()); assertEquals(monitor.getEvaluationState().getProbeCompletedResult(), 0); - verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL); + verifyNetworkTestedPortal(TEST_LOGIN_URL, 2 /* interactions */); // Check that startCaptivePortalApp sends the expected intent. monitor.launchCaptivePortalApp(); @@ -3197,21 +3154,59 @@ int testResult, int probesSucceeded, String redirectUrl) throws Exception { final NetworkMonitor monitor = makeMonitor(nc); notifyNetworkConnected(monitor, config, lp, nc); - verifyNetworkTested(testResult, probesSucceeded, redirectUrl); + verifyNetworkTested(testResult, probesSucceeded, redirectUrl, 1 /* interactions */); HandlerUtils.waitForIdle(monitor.getHandler(), HANDLER_TIMEOUT_MS); return monitor; } - private void verifyNetworkTested(int testResult, int probesSucceeded) throws Exception { - verifyNetworkTested(testResult, probesSucceeded, null /* redirectUrl */); + private void verifyProbeStatusChangedPrivateDnsCompleteAndSucceeded(int interactions) + throws Exception { + verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(interactions)) + .notifyProbeStatusChanged(eq(PROBES_PRIVDNS_VALID), eq(PROBES_PRIVDNS_VALID)); } - private void verifyNetworkTested(int testResult, int probesSucceeded, String redirectUrl) - throws RemoteException { + private void verifyProbeStatusChangedPrivateDnsCompleteAndHttpsSucceeded(int interactions) + throws Exception { + verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(interactions)) + .notifyProbeStatusChanged( + eq(PROBES_PRIVDNS_VALID), + eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS)); + } + + private void verifyNetworkTestedInvalidFromHttps(int interactions) throws Exception { + verifyNetworkTested(VALIDATION_RESULT_INVALID, + NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS, + interactions); + } + + private void verifyNetworkTestedPortal(String redirectUrl, int interactions) throws Exception { + verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, redirectUrl, + interactions); + } + + private void verifyNetworkTestedValidFromHttps(int interactions) throws Exception { + verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, + NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS, + interactions); + } + + private void verifyNetworkTestedValidFromPrivateDns(int interactions) throws Exception { + verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID, PROBES_PRIVDNS_VALID, interactions); + } + + private void verifyNetworkTested(int testResult, int probesSucceeded, int interactions) + throws Exception { + verifyNetworkTested(testResult, probesSucceeded, null /* redirectUrl */, interactions); + } + + private void verifyNetworkTested(int testResult, int probesSucceeded, String redirectUrl, + int interactions) throws RemoteException { try { - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyNetworkTestedWithExtras( - matchNetworkTestResultParcelable(testResult, probesSucceeded, redirectUrl)); + verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(interactions)) + .notifyNetworkTestedWithExtras( + matchNetworkTestResultParcelable( + testResult, probesSucceeded, redirectUrl)); } catch (AssertionFailedError e) { // Capture the callbacks up to now to give a better error message final ArgumentCaptor<NetworkTestResultParcelable> captor = @@ -3221,14 +3216,15 @@ // call which failed, but this time use a captor to log the exact parcel sent by // NetworkMonitor. // This assertion will fail if notifyNetworkTested was not called at all. - verify(mCallbacks).notifyNetworkTestedWithExtras(captor.capture()); + verify(mCallbacks, times(interactions)).notifyNetworkTestedWithExtras(captor.capture()); - final NetworkTestResultParcelable lastResult = captor.getValue(); - fail(String.format("notifyNetworkTestedWithExtras was not called with the " + final List<NetworkTestResultParcelable> results = captor.getAllValues(); + final NetworkTestResultParcelable lastResult = results.get(results.size() - 1); + fail(String.format("notifyNetworkTestedWithExtras was not called %d times with the " + "expected result within timeout. " + "Expected result %d, probes succeeded %d, redirect URL %s, " + "last result was (%d, %d, %s).", - testResult, probesSucceeded, redirectUrl, + interactions, testResult, probesSucceeded, redirectUrl, lastResult.result, lastResult.probesSucceeded, lastResult.redirectUrl)); } }