Merge "Add more NsdService tests"
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 299a88e..770c092 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -122,6 +122,12 @@
     certificate: "com.android.tethering",
 }
 
+filegroup {
+    name: "connectivity-hiddenapi-files",
+    srcs: ["hiddenapi/*.txt"],
+    visibility: ["//packages/modules/Connectivity:__subpackages__"],
+}
+
 // Encapsulate the contributions made by the com.android.tethering to the bootclasspath.
 bootclasspath_fragment {
     name: "com.android.tethering-bootclasspath-fragment",
diff --git a/bpf_progs/dscp_policy.c b/bpf_progs/dscp_policy.c
index 92ea0e2..e45c1d4 100644
--- a/bpf_progs/dscp_policy.c
+++ b/bpf_progs/dscp_policy.c
@@ -64,10 +64,10 @@
 
     int zero = 0;
     int hdr_size = 0;
-    uint64_t* selectedMap = bpf_switch_comp_map_lookup_elem(&zero);
+    uint64_t* selected_map = bpf_switch_comp_map_lookup_elem(&zero);
 
     // use this with HASH map so map lookup only happens once policies have been added?
-    if (!selectedMap) {
+    if (!selected_map) {
         return;
     }
 
@@ -78,8 +78,8 @@
     uint16_t sport = 0;
     uint16_t dport = 0;
     uint8_t protocol = 0;  // TODO: Use are reserved value? Or int (-1) and cast to uint below?
-    struct in6_addr srcIp = {};
-    struct in6_addr dstIp = {};
+    struct in6_addr src_ip = {};
+    struct in6_addr dst_ip = {};
     uint8_t tos = 0;       // Only used for IPv4
     uint8_t priority = 0;  // Only used for IPv6
     uint8_t flow_lbl = 0;  // Only used for IPv6
@@ -96,12 +96,12 @@
         if (iph->ihl != 5) return;
 
         // V4 mapped address in in6_addr sets 10/11 position to 0xff.
-        srcIp.s6_addr32[2] = htonl(0x0000ffff);
-        dstIp.s6_addr32[2] = htonl(0x0000ffff);
+        src_ip.s6_addr32[2] = htonl(0x0000ffff);
+        dst_ip.s6_addr32[2] = htonl(0x0000ffff);
 
         // Copy IPv4 address into in6_addr for easy comparison below.
-        srcIp.s6_addr32[3] = iph->saddr;
-        dstIp.s6_addr32[3] = iph->daddr;
+        src_ip.s6_addr32[3] = iph->saddr;
+        dst_ip.s6_addr32[3] = iph->daddr;
         protocol = iph->protocol;
         tos = iph->tos;
     } else {
@@ -112,8 +112,8 @@
 
         if (ip6h->version != 6) return;
 
-        srcIp = ip6h->saddr;
-        dstIp = ip6h->daddr;
+        src_ip = ip6h->saddr;
+        dst_ip = ip6h->daddr;
         protocol = ip6h->nexthdr;
         priority = ip6h->priority;
         flow_lbl = ip6h->flow_lbl[0];
@@ -139,33 +139,33 @@
             return;
     }
 
-    RuleEntry* existingRule;
+    RuleEntry* existing_rule;
     if (ipv4) {
-        if (*selectedMap == MAP_A) {
-            existingRule = bpf_ipv4_socket_to_policies_map_A_lookup_elem(&cookie);
+        if (*selected_map == MAP_A) {
+            existing_rule = bpf_ipv4_socket_to_policies_map_A_lookup_elem(&cookie);
         } else {
-            existingRule = bpf_ipv4_socket_to_policies_map_B_lookup_elem(&cookie);
+            existing_rule = bpf_ipv4_socket_to_policies_map_B_lookup_elem(&cookie);
         }
     } else {
-        if (*selectedMap == MAP_A) {
-            existingRule = bpf_ipv6_socket_to_policies_map_A_lookup_elem(&cookie);
+        if (*selected_map == MAP_A) {
+            existing_rule = bpf_ipv6_socket_to_policies_map_A_lookup_elem(&cookie);
         } else {
-            existingRule = bpf_ipv6_socket_to_policies_map_B_lookup_elem(&cookie);
+            existing_rule = bpf_ipv6_socket_to_policies_map_B_lookup_elem(&cookie);
         }
     }
 
-    if (existingRule && v6_equal(srcIp, existingRule->srcIp) &&
-        v6_equal(dstIp, existingRule->dstIp) && skb->ifindex == existingRule->ifindex &&
-        ntohs(sport) == htons(existingRule->srcPort) &&
-        ntohs(dport) == htons(existingRule->dstPort) && protocol == existingRule->proto) {
+    if (existing_rule && v6_equal(src_ip, existing_rule->src_ip) &&
+            v6_equal(dst_ip, existing_rule->dst_ip) && skb->ifindex == existing_rule->ifindex &&
+        ntohs(sport) == htons(existing_rule->src_port) &&
+        ntohs(dport) == htons(existing_rule->dst_port) && protocol == existing_rule->proto) {
         if (ipv4) {
-            uint8_t newTos = UPDATE_TOS(existingRule->dscpVal, tos);
+            uint8_t newTos = UPDATE_TOS(existing_rule->dscp_val, tos);
             bpf_l3_csum_replace(skb, IP4_OFFSET(check, l2_header_size), htons(tos), htons(newTos),
                                 sizeof(uint16_t));
             bpf_skb_store_bytes(skb, IP4_OFFSET(tos, l2_header_size), &newTos, sizeof(newTos), 0);
         } else {
-            uint8_t new_priority = UPDATE_PRIORITY(existingRule->dscpVal);
-            uint8_t new_flow_label = UPDATE_FLOW_LABEL(existingRule->dscpVal, flow_lbl);
+            uint8_t new_priority = UPDATE_PRIORITY(existing_rule->dscp_val);
+            uint8_t new_flow_label = UPDATE_FLOW_LABEL(existing_rule->dscp_val, flow_lbl);
             bpf_skb_store_bytes(skb, 0 + l2_header_size, &new_priority, sizeof(uint8_t), 0);
             bpf_skb_store_bytes(skb, 1 + l2_header_size, &new_flow_label, sizeof(uint8_t), 0);
         }
@@ -173,12 +173,12 @@
     }
 
     // Linear scan ipv4_dscp_policies_map since no stored params match skb.
-    int bestScore = -1;
-    uint32_t bestMatch = 0;
+    int best_score = -1;
+    uint32_t best_match = 0;
 
     for (register uint64_t i = 0; i < MAX_POLICIES; i++) {
         int score = 0;
-        uint8_t tempMask = 0;
+        uint8_t temp_mask = 0;
         // Using a uint64 in for loop prevents infinite loop during BPF load,
         // but the key is uint32, so convert back.
         uint32_t key = i;
@@ -190,40 +190,40 @@
             policy = bpf_ipv6_dscp_policies_map_lookup_elem(&key);
         }
 
-        // If the policy lookup failed, presentFields is 0, or iface index does not match
+        // If the policy lookup failed, present_fields is 0, or iface index does not match
         // index on skb buff, then we can continue to next policy.
-        if (!policy || policy->presentFields == 0 || policy->ifindex != skb->ifindex) continue;
+        if (!policy || policy->present_fields == 0 || policy->ifindex != skb->ifindex) continue;
 
-        if ((policy->presentFields & SRC_IP_MASK_FLAG) == SRC_IP_MASK_FLAG &&
-            v6_equal(srcIp, policy->srcIp)) {
+        if ((policy->present_fields & SRC_IP_MASK_FLAG) == SRC_IP_MASK_FLAG &&
+            v6_equal(src_ip, policy->src_ip)) {
             score++;
-            tempMask |= SRC_IP_MASK_FLAG;
+            temp_mask |= SRC_IP_MASK_FLAG;
         }
-        if ((policy->presentFields & DST_IP_MASK_FLAG) == DST_IP_MASK_FLAG &&
-            v6_equal(dstIp, policy->dstIp)) {
+        if ((policy->present_fields & DST_IP_MASK_FLAG) == DST_IP_MASK_FLAG &&
+            v6_equal(dst_ip, policy->dst_ip)) {
             score++;
-            tempMask |= DST_IP_MASK_FLAG;
+            temp_mask |= DST_IP_MASK_FLAG;
         }
-        if ((policy->presentFields & SRC_PORT_MASK_FLAG) == SRC_PORT_MASK_FLAG &&
-            ntohs(sport) == htons(policy->srcPort)) {
+        if ((policy->present_fields & SRC_PORT_MASK_FLAG) == SRC_PORT_MASK_FLAG &&
+            ntohs(sport) == htons(policy->src_port)) {
             score++;
-            tempMask |= SRC_PORT_MASK_FLAG;
+            temp_mask |= SRC_PORT_MASK_FLAG;
         }
-        if ((policy->presentFields & DST_PORT_MASK_FLAG) == DST_PORT_MASK_FLAG &&
-            ntohs(dport) >= htons(policy->dstPortStart) &&
-            ntohs(dport) <= htons(policy->dstPortEnd)) {
+        if ((policy->present_fields & DST_PORT_MASK_FLAG) == DST_PORT_MASK_FLAG &&
+            ntohs(dport) >= htons(policy->dst_port_start) &&
+            ntohs(dport) <= htons(policy->dst_port_end)) {
             score++;
-            tempMask |= DST_PORT_MASK_FLAG;
+            temp_mask |= DST_PORT_MASK_FLAG;
         }
-        if ((policy->presentFields & PROTO_MASK_FLAG) == PROTO_MASK_FLAG &&
+        if ((policy->present_fields & PROTO_MASK_FLAG) == PROTO_MASK_FLAG &&
             protocol == policy->proto) {
             score++;
-            tempMask |= PROTO_MASK_FLAG;
+            temp_mask |= PROTO_MASK_FLAG;
         }
 
-        if (score > bestScore && tempMask == policy->presentFields) {
-            bestMatch = i;
-            bestScore = score;
+        if (score > best_score && temp_mask == policy->present_fields) {
+            best_match = i;
+            best_score = score;
         }
     }
 
@@ -231,16 +231,16 @@
     uint8_t new_dscp = 0;
     uint8_t new_priority = 0;
     uint8_t new_flow_lbl = 0;
-    if (bestScore > 0) {
+    if (best_score > 0) {
         DscpPolicy* policy;
         if (ipv4) {
-            policy = bpf_ipv4_dscp_policies_map_lookup_elem(&bestMatch);
+            policy = bpf_ipv4_dscp_policies_map_lookup_elem(&best_match);
         } else {
-            policy = bpf_ipv6_dscp_policies_map_lookup_elem(&bestMatch);
+            policy = bpf_ipv6_dscp_policies_map_lookup_elem(&best_match);
         }
 
         if (policy) {
-            new_dscp = policy->dscpVal;
+            new_dscp = policy->dscp_val;
             if (ipv4) {
                 new_tos = UPDATE_TOS(new_dscp, tos);
             } else {
@@ -252,24 +252,24 @@
         return;
 
     RuleEntry value = {
-        .srcIp = srcIp,
-        .dstIp = dstIp,
+        .src_ip = src_ip,
+        .dst_ip = dst_ip,
         .ifindex = skb->ifindex,
-        .srcPort = sport,
-        .dstPort = dport,
+        .src_port = sport,
+        .dst_port = dport,
         .proto = protocol,
-        .dscpVal = new_dscp,
+        .dscp_val = new_dscp,
     };
 
     // Update map with new policy.
     if (ipv4) {
-        if (*selectedMap == MAP_A) {
+        if (*selected_map == MAP_A) {
             bpf_ipv4_socket_to_policies_map_A_update_elem(&cookie, &value, BPF_ANY);
         } else {
             bpf_ipv4_socket_to_policies_map_B_update_elem(&cookie, &value, BPF_ANY);
         }
     } else {
-        if (*selectedMap == MAP_A) {
+        if (*selected_map == MAP_A) {
             bpf_ipv6_socket_to_policies_map_A_update_elem(&cookie, &value, BPF_ANY);
         } else {
             bpf_ipv6_socket_to_policies_map_B_update_elem(&cookie, &value, BPF_ANY);
diff --git a/bpf_progs/dscp_policy.h b/bpf_progs/dscp_policy.h
index 1637f7a..455a121 100644
--- a/bpf_progs/dscp_policy.h
+++ b/bpf_progs/dscp_policy.h
@@ -44,27 +44,27 @@
         (void*)BPF_FUNC_skb_ecn_set_ce;
 
 typedef struct {
-    struct in6_addr srcIp;
-    struct in6_addr dstIp;
+    struct in6_addr src_ip;
+    struct in6_addr dst_ip;
     uint32_t ifindex;
-    __be16 srcPort;
-    __be16 dstPortStart;
-    __be16 dstPortEnd;
+    __be16 src_port;
+    __be16 dst_port_start;
+    __be16 dst_port_end;
     uint8_t proto;
-    uint8_t dscpVal;
-    uint8_t presentFields;
+    uint8_t dscp_val;
+    uint8_t present_fields;
     uint8_t pad[3];
 } DscpPolicy;
 STRUCT_SIZE(DscpPolicy, 2 * 16 + 4 + 3 * 2 + 3 * 1 + 3);  // 48
 
 typedef struct {
-    struct in6_addr srcIp;
-    struct in6_addr dstIp;
+    struct in6_addr src_ip;
+    struct in6_addr dst_ip;
     __u32 ifindex;
-    __be16 srcPort;
-    __be16 dstPort;
+    __be16 src_port;
+    __be16 dst_port;
     __u8 proto;
-    __u8 dscpVal;
+    __u8 dscp_val;
     __u8 pad[2];
 } RuleEntry;
 STRUCT_SIZE(RuleEntry, 2 * 16 + 1 * 4 + 2 * 2 + 2 * 1 + 2);  // 44
\ No newline at end of file
diff --git a/framework-t/Android.bp b/framework-t/Android.bp
index 1e508a0..8c32ded 100644
--- a/framework-t/Android.bp
+++ b/framework-t/Android.bp
@@ -103,7 +103,7 @@
     // Do not add static_libs to this library: put them in framework-connectivity instead.
     // The jarjar rules are only so that references to jarjared utils in
     // framework-connectivity-pre-jarjar match at runtime.
-    jarjar_rules: ":connectivity-jarjar-rules",
+    jarjar_rules: ":framework-connectivity-jarjar-rules",
     permitted_packages: [
         "android.app.usage",
         "android.net",
diff --git a/framework-t/Sources.bp b/framework-t/Sources.bp
index b30ee80..391a562 100644
--- a/framework-t/Sources.bp
+++ b/framework-t/Sources.bp
@@ -14,125 +14,13 @@
 // limitations under the License.
 //
 
-// NetworkStats related libraries.
-
-filegroup {
-    name: "framework-connectivity-netstats-internal-sources",
-    srcs: [
-        "src/android/app/usage/*.java",
-        "src/android/net/DataUsageRequest.*",
-        "src/android/net/INetworkStatsService.aidl",
-        "src/android/net/INetworkStatsSession.aidl",
-        "src/android/net/NetworkIdentity.java",
-        "src/android/net/NetworkIdentitySet.java",
-        "src/android/net/NetworkStateSnapshot.*",
-        "src/android/net/NetworkStats.*",
-        "src/android/net/NetworkStatsAccess.*",
-        "src/android/net/NetworkStatsCollection.*",
-        "src/android/net/NetworkStatsHistory.*",
-        "src/android/net/NetworkTemplate.*",
-        "src/android/net/TrafficStats.java",
-        "src/android/net/UnderlyingNetworkInfo.*",
-        "src/android/net/netstats/**/*.*",
-    ],
-    path: "src",
-    visibility: [
-        "//visibility:private",
-    ],
-}
-
-filegroup {
-    name: "framework-connectivity-netstats-sources",
-    srcs: [
-        ":framework-connectivity-netstats-internal-sources",
-    ],
-    visibility: [
-        "//visibility:private",
-    ],
-}
-
-// Nsd related libraries.
-
-filegroup {
-    name: "framework-connectivity-nsd-internal-sources",
-    srcs: [
-        "src/android/net/nsd/*.aidl",
-        "src/android/net/nsd/*.java",
-    ],
-    path: "src",
-    visibility: [
-        "//visibility:private",
-    ],
-}
-
-filegroup {
-    name: "framework-connectivity-nsd-sources",
-    srcs: [
-        ":framework-connectivity-nsd-internal-sources",
-    ],
-    visibility: [
-        "//visibility:private",
-    ],
-}
-
-// IpSec related libraries.
-
-filegroup {
-    name: "framework-connectivity-ipsec-sources",
-    srcs: [
-        "src/android/net/IIpSecService.aidl",
-        "src/android/net/IpSec*.*",
-    ],
-    path: "src",
-    visibility: [
-        "//visibility:private",
-    ],
-}
-
-// Ethernet related libraries.
-
-filegroup {
-    name: "framework-connectivity-ethernet-sources",
-    srcs: [
-        "src/android/net/EthernetManager.java",
-        "src/android/net/EthernetNetworkManagementException.java",
-        "src/android/net/EthernetNetworkManagementException.aidl",
-        "src/android/net/EthernetNetworkSpecifier.java",
-        "src/android/net/EthernetNetworkUpdateRequest.java",
-        "src/android/net/EthernetNetworkUpdateRequest.aidl",
-        "src/android/net/IEthernetManager.aidl",
-        "src/android/net/IEthernetServiceListener.aidl",
-        "src/android/net/INetworkInterfaceOutcomeReceiver.aidl",
-        "src/android/net/ITetheredInterfaceCallback.aidl",
-    ],
-    path: "src",
-    visibility: [
-        "//visibility:private",
-    ],
-}
-
-// Connectivity-T common libraries.
-
-filegroup {
-    name: "framework-connectivity-tiramisu-internal-sources",
-    srcs: [
-        "src/android/net/ConnectivityFrameworkInitializerTiramisu.java",
-    ],
-    path: "src",
-    visibility: [
-        "//visibility:private",
-    ],
-}
-
 filegroup {
     name: "framework-connectivity-tiramisu-updatable-sources",
     srcs: [
-        ":framework-connectivity-ethernet-sources",
-        ":framework-connectivity-ipsec-sources",
-        ":framework-connectivity-netstats-sources",
-        ":framework-connectivity-nsd-sources",
-        ":framework-connectivity-tiramisu-internal-sources",
+        "src/**/*.java",
+        "src/**/*.aidl",
     ],
+    path: "src",
     visibility: [
         "//frameworks/base",
         "//packages/modules/Connectivity:__subpackages__",
diff --git a/framework-t/src/android/app/usage/NetworkStats.java b/framework-t/src/android/app/usage/NetworkStats.java
index 74fe4bd..26841de 100644
--- a/framework-t/src/android/app/usage/NetworkStats.java
+++ b/framework-t/src/android/app/usage/NetworkStats.java
@@ -1,17 +1,17 @@
 /**
  * Copyright (C) 2015 The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package android.app.usage;
@@ -36,11 +36,11 @@
 import java.util.ArrayList;
 
 /**
- * Class providing enumeration over buckets of network usage statistics. {@link NetworkStats} objects
- * are returned as results to various queries in {@link NetworkStatsManager}.
+ * Class providing enumeration over buckets of network usage statistics. {@link NetworkStats}
+ * objects are returned as results to various queries in {@link NetworkStatsManager}.
  */
 public final class NetworkStats implements AutoCloseable {
-    private final static String TAG = "NetworkStats";
+    private static final String TAG = "NetworkStats";
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
@@ -616,7 +616,7 @@
     /**
      * Steps to next uid in enumeration and collects history for that.
      */
-    private void stepHistory(){
+    private void stepHistory() {
         if (hasNextUid()) {
             stepUid();
             mHistory = null;
@@ -692,8 +692,8 @@
                 bucketOut.mMetered = Bucket.METERED_ALL;
                 bucketOut.mRoaming = Bucket.ROAMING_ALL;
                 bucketOut.mBeginTimeStamp = mRecycledHistoryEntry.bucketStart;
-                bucketOut.mEndTimeStamp = mRecycledHistoryEntry.bucketStart +
-                        mRecycledHistoryEntry.bucketDuration;
+                bucketOut.mEndTimeStamp = mRecycledHistoryEntry.bucketStart
+                        + mRecycledHistoryEntry.bucketDuration;
                 bucketOut.mRxBytes = mRecycledHistoryEntry.rxBytes;
                 bucketOut.mRxPackets = mRecycledHistoryEntry.rxPackets;
                 bucketOut.mTxBytes = mRecycledHistoryEntry.txBytes;
diff --git a/framework-t/src/android/net/NetworkStats.java b/framework-t/src/android/net/NetworkStats.java
index 0bb98f8..a655a9b 100644
--- a/framework-t/src/android/net/NetworkStats.java
+++ b/framework-t/src/android/net/NetworkStats.java
@@ -1041,7 +1041,7 @@
      */
     public long getTotalPackets() {
         long total = 0;
-        for (int i = size-1; i >= 0; i--) {
+        for (int i = size - 1; i >= 0; i--) {
             total += rxPackets[i] + txPackets[i];
         }
         return total;
diff --git a/framework/Android.bp b/framework/Android.bp
index 6350e14..fcce7a5 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -112,6 +112,7 @@
         // because the tethering stubs depend on the connectivity stubs (e.g.,
         // TetheringRequest depends on LinkAddress).
         "framework-tethering.stubs.module_lib",
+        "framework-wifi.stubs.module_lib",
     ],
     visibility: ["//packages/modules/Connectivity:__subpackages__"]
 }
@@ -120,7 +121,7 @@
     name: "framework-connectivity",
     defaults: ["framework-connectivity-defaults"],
     installable: true,
-    jarjar_rules: ":connectivity-jarjar-rules",
+    jarjar_rules: ":framework-connectivity-jarjar-rules",
     permitted_packages: ["android.net"],
     impl_library_visibility: [
         "//packages/modules/Connectivity/Tethering/apex",
@@ -211,3 +212,33 @@
         "com.android.tethering",
     ],
 }
+
+java_genrule {
+    name: "framework-connectivity-jarjar-rules",
+    tool_files: [
+        ":connectivity-hiddenapi-files",
+        ":framework-connectivity-pre-jarjar{.jar}",
+        ":framework-connectivity-t-pre-jarjar{.jar}",
+        ":framework-connectivity.stubs.module_lib{.jar}",
+        ":framework-connectivity-t.stubs.module_lib{.jar}",
+        "jarjar-excludes.txt",
+    ],
+    tools: [
+        "jarjar-rules-generator",
+    ],
+    out: ["framework_connectivity_jarjar_rules.txt"],
+    cmd: "$(location jarjar-rules-generator) " +
+        "--jars $(location :framework-connectivity-pre-jarjar{.jar}) " +
+        "$(location :framework-connectivity-t-pre-jarjar{.jar}) " +
+        "--prefix android.net.connectivity " +
+        "--apistubs $(location :framework-connectivity.stubs.module_lib{.jar}) " +
+        "$(location :framework-connectivity-t.stubs.module_lib{.jar}) " +
+        "--unsupportedapi $(locations :connectivity-hiddenapi-files) " +
+        "--excludes $(location jarjar-excludes.txt) " +
+        "--output $(out)",
+    visibility: [
+        "//packages/modules/Connectivity/framework:__subpackages__",
+        "//packages/modules/Connectivity/framework-t:__subpackages__",
+        "//packages/modules/Connectivity/service",
+    ],
+}
diff --git a/framework/jni/android_net_NetworkUtils.cpp b/framework/jni/android_net_NetworkUtils.cpp
index 7478b3e..857ece5 100644
--- a/framework/jni/android_net_NetworkUtils.cpp
+++ b/framework/jni/android_net_NetworkUtils.cpp
@@ -232,7 +232,8 @@
         return NULL;
     }
 
-    jclass class_TcpRepairWindow = env->FindClass("android/net/TcpRepairWindow");
+    jclass class_TcpRepairWindow = env->FindClass(
+        "android/net/connectivity/android/net/TcpRepairWindow");
     jmethodID ctor = env->GetMethodID(class_TcpRepairWindow, "<init>", "(IIIIII)V");
 
     return env->NewObject(class_TcpRepairWindow, ctor, trw.snd_wl1, trw.snd_wnd, trw.max_window,
@@ -253,7 +254,7 @@
     { "bindSocketToNetworkHandle", "(Ljava/io/FileDescriptor;J)I", (void*) android_net_utils_bindSocketToNetworkHandle },
     { "attachDropAllBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDropAllBPFFilter },
     { "detachBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_detachBPFFilter },
-    { "getTcpRepairWindow", "(Ljava/io/FileDescriptor;)Landroid/net/TcpRepairWindow;", (void*) android_net_utils_getTcpRepairWindow },
+    { "getTcpRepairWindow", "(Ljava/io/FileDescriptor;)Landroid/net/connectivity/android/net/TcpRepairWindow;", (void*) android_net_utils_getTcpRepairWindow },
     { "resNetworkSend", "(J[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend },
     { "resNetworkQuery", "(JLjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery },
     { "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult },
diff --git a/framework/src/android/net/DnsResolverServiceManager.java b/framework/src/android/net/DnsResolverServiceManager.java
index 79009e8..e64d2ae 100644
--- a/framework/src/android/net/DnsResolverServiceManager.java
+++ b/framework/src/android/net/DnsResolverServiceManager.java
@@ -29,7 +29,7 @@
 
     private final IBinder mResolver;
 
-    DnsResolverServiceManager(IBinder resolver) {
+    public DnsResolverServiceManager(IBinder resolver) {
         mResolver = resolver;
     }
 
diff --git a/framework/src/android/net/ITestNetworkManager.aidl b/framework/src/android/net/ITestNetworkManager.aidl
index d18b931..9432acb 100644
--- a/framework/src/android/net/ITestNetworkManager.aidl
+++ b/framework/src/android/net/ITestNetworkManager.aidl
@@ -30,7 +30,8 @@
 interface ITestNetworkManager
 {
     TestNetworkInterface createInterface(boolean isTun, boolean hasCarrier, boolean bringUp,
-            in LinkAddress[] addrs, in @nullable String iface);
+            boolean disableIpv6ProvisioningDelay, in LinkAddress[] addrs,
+            in @nullable String iface);
 
     void setCarrierEnabled(in TestNetworkInterface iface, boolean enabled);
 
diff --git a/framework/src/android/net/NattSocketKeepalive.java b/framework/src/android/net/NattSocketKeepalive.java
index a15d165..56cc923 100644
--- a/framework/src/android/net/NattSocketKeepalive.java
+++ b/framework/src/android/net/NattSocketKeepalive.java
@@ -33,7 +33,7 @@
     @NonNull private final InetAddress mDestination;
     private final int mResourceId;
 
-    NattSocketKeepalive(@NonNull IConnectivityManager service,
+    public NattSocketKeepalive(@NonNull IConnectivityManager service,
             @NonNull Network network,
             @NonNull ParcelFileDescriptor pfd,
             int resourceId,
@@ -48,7 +48,7 @@
     }
 
     @Override
-    void startImpl(int intervalSec) {
+    protected void startImpl(int intervalSec) {
         mExecutor.execute(() -> {
             try {
                 mService.startNattKeepaliveWithFd(mNetwork, mPfd, mResourceId,
@@ -62,7 +62,7 @@
     }
 
     @Override
-    void stopImpl() {
+    protected void stopImpl() {
         mExecutor.execute(() -> {
             try {
                 if (mSlot != null) {
diff --git a/framework/src/android/net/QosCallbackConnection.java b/framework/src/android/net/QosCallbackConnection.java
index de0fc24..cfceddd 100644
--- a/framework/src/android/net/QosCallbackConnection.java
+++ b/framework/src/android/net/QosCallbackConnection.java
@@ -35,7 +35,7 @@
  *
  * @hide
  */
-class QosCallbackConnection extends android.net.IQosCallback.Stub {
+public class QosCallbackConnection extends android.net.IQosCallback.Stub {
 
     @NonNull private final ConnectivityManager mConnectivityManager;
     @Nullable private volatile QosCallback mCallback;
@@ -56,7 +56,7 @@
      *                 {@link Executor} must run callback sequentially, otherwise the order of
      *                 callbacks cannot be guaranteed.
      */
-    QosCallbackConnection(@NonNull final ConnectivityManager connectivityManager,
+    public QosCallbackConnection(@NonNull final ConnectivityManager connectivityManager,
             @NonNull final QosCallback callback,
             @NonNull final Executor executor) {
         mConnectivityManager = Objects.requireNonNull(connectivityManager,
@@ -142,7 +142,7 @@
      * There are no synchronization guarantees on exactly when the callback will stop receiving
      * messages.
      */
-    void stopReceivingMessages() {
+    public void stopReceivingMessages() {
         mCallback = null;
     }
 }
diff --git a/framework/src/android/net/QosCallbackException.java b/framework/src/android/net/QosCallbackException.java
index 72430d2..7de3dd1 100644
--- a/framework/src/android/net/QosCallbackException.java
+++ b/framework/src/android/net/QosCallbackException.java
@@ -88,7 +88,7 @@
      * {@hide}
      */
     @NonNull
-    static QosCallbackException createException(@ExceptionType final int type) {
+    public static QosCallbackException createException(@ExceptionType final int type) {
         switch (type) {
             case EX_TYPE_FILTER_NETWORK_RELEASED:
                 return new QosCallbackException(new NetworkReleasedException());
diff --git a/framework/src/android/net/QosFilter.java b/framework/src/android/net/QosFilter.java
index b432644..01dc4bb 100644
--- a/framework/src/android/net/QosFilter.java
+++ b/framework/src/android/net/QosFilter.java
@@ -33,13 +33,15 @@
 @SystemApi
 public abstract class QosFilter {
 
-    /**
-     * The constructor is kept hidden from outside this package to ensure that all derived types
-     * are known and properly handled when being passed to and from {@link NetworkAgent}.
-     *
-     * @hide
-     */
-    QosFilter() {
+    /** @hide */
+    protected QosFilter() {
+        // Ensure that all derived types are known, and known to be properly handled when being
+        // passed to and from NetworkAgent.
+        // For now the only known derived type is QosSocketFilter.
+        if (!(this instanceof QosSocketFilter)) {
+            throw new UnsupportedOperationException(
+                    "Unsupported QosFilter type: " + this.getClass().getName());
+        }
     }
 
     /**
diff --git a/framework/src/android/net/QosSocketInfo.java b/framework/src/android/net/QosSocketInfo.java
index 49ac22b..da9b356 100644
--- a/framework/src/android/net/QosSocketInfo.java
+++ b/framework/src/android/net/QosSocketInfo.java
@@ -73,9 +73,10 @@
      * The parcel file descriptor wrapped around the socket's file descriptor.
      *
      * @return the parcel file descriptor of the socket
+     * @hide
      */
     @NonNull
-    ParcelFileDescriptor getParcelFileDescriptor() {
+    public ParcelFileDescriptor getParcelFileDescriptor() {
         return mParcelFileDescriptor;
     }
 
diff --git a/framework/src/android/net/SocketKeepalive.java b/framework/src/android/net/SocketKeepalive.java
index f6cae72..57cf5e3 100644
--- a/framework/src/android/net/SocketKeepalive.java
+++ b/framework/src/android/net/SocketKeepalive.java
@@ -52,7 +52,8 @@
  * request. If it does, it MUST support at least 3 concurrent keepalive slots.
  */
 public abstract class SocketKeepalive implements AutoCloseable {
-    static final String TAG = "SocketKeepalive";
+    /** @hide */
+    protected static final String TAG = "SocketKeepalive";
 
     /**
      * Success. It indicates there is no error.
@@ -215,15 +216,22 @@
         }
     }
 
-    @NonNull final IConnectivityManager mService;
-    @NonNull final Network mNetwork;
-    @NonNull final ParcelFileDescriptor mPfd;
-    @NonNull final Executor mExecutor;
-    @NonNull final ISocketKeepaliveCallback mCallback;
+    /** @hide */
+    @NonNull protected final IConnectivityManager mService;
+    /** @hide */
+    @NonNull protected final Network mNetwork;
+    /** @hide */
+    @NonNull protected final ParcelFileDescriptor mPfd;
+    /** @hide */
+    @NonNull protected final Executor mExecutor;
+    /** @hide */
+    @NonNull protected final ISocketKeepaliveCallback mCallback;
     // TODO: remove slot since mCallback could be used to identify which keepalive to stop.
-    @Nullable Integer mSlot;
+    /** @hide */
+    @Nullable protected Integer mSlot;
 
-    SocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network,
+    /** @hide */
+    public SocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network,
             @NonNull ParcelFileDescriptor pfd,
             @NonNull Executor executor, @NonNull Callback callback) {
         mService = service;
@@ -303,7 +311,8 @@
         startImpl(intervalSec);
     }
 
-    abstract void startImpl(int intervalSec);
+    /** @hide */
+    protected abstract void startImpl(int intervalSec);
 
     /**
      * Requests that keepalive be stopped. The application must wait for {@link Callback#onStopped}
@@ -313,7 +322,8 @@
         stopImpl();
     }
 
-    abstract void stopImpl();
+    /** @hide */
+    protected abstract void stopImpl();
 
     /**
      * Deactivate this {@link SocketKeepalive} and free allocated resources. The instance won't be
diff --git a/framework/src/android/net/TcpSocketKeepalive.java b/framework/src/android/net/TcpSocketKeepalive.java
index d89814d..7131784 100644
--- a/framework/src/android/net/TcpSocketKeepalive.java
+++ b/framework/src/android/net/TcpSocketKeepalive.java
@@ -24,9 +24,9 @@
 import java.util.concurrent.Executor;
 
 /** @hide */
-final class TcpSocketKeepalive extends SocketKeepalive {
+public final class TcpSocketKeepalive extends SocketKeepalive {
 
-    TcpSocketKeepalive(@NonNull IConnectivityManager service,
+    public TcpSocketKeepalive(@NonNull IConnectivityManager service,
             @NonNull Network network,
             @NonNull ParcelFileDescriptor pfd,
             @NonNull Executor executor,
@@ -50,7 +50,7 @@
      *   acknowledgement.
      */
     @Override
-    void startImpl(int intervalSec) {
+    protected void startImpl(int intervalSec) {
         mExecutor.execute(() -> {
             try {
                 mService.startTcpKeepalive(mNetwork, mPfd, intervalSec, mCallback);
@@ -62,7 +62,7 @@
     }
 
     @Override
-    void stopImpl() {
+    protected void stopImpl() {
         mExecutor.execute(() -> {
             try {
                 if (mSlot != null) {
diff --git a/framework/src/android/net/TestNetworkManager.java b/framework/src/android/net/TestNetworkManager.java
index 788834a..b64299f 100644
--- a/framework/src/android/net/TestNetworkManager.java
+++ b/framework/src/android/net/TestNetworkManager.java
@@ -59,6 +59,8 @@
     private static final boolean TUN = true;
     private static final boolean BRING_UP = true;
     private static final boolean CARRIER_UP = true;
+    // sets disableIpv6ProvisioningDelay to false.
+    private static final boolean USE_IPV6_PROV_DELAY = false;
     private static final LinkAddress[] NO_ADDRS = new LinkAddress[0];
 
     /** @hide */
@@ -167,8 +169,8 @@
     public TestNetworkInterface createTunInterface(@NonNull Collection<LinkAddress> linkAddrs) {
         try {
             final LinkAddress[] arr = new LinkAddress[linkAddrs.size()];
-            return mService.createInterface(TUN, CARRIER_UP, BRING_UP, linkAddrs.toArray(arr),
-                    null /* iface */);
+            return mService.createInterface(TUN, CARRIER_UP, BRING_UP, USE_IPV6_PROV_DELAY,
+                    linkAddrs.toArray(arr), null /* iface */);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -186,7 +188,8 @@
     @NonNull
     public TestNetworkInterface createTapInterface() {
         try {
-            return mService.createInterface(TAP, CARRIER_UP, BRING_UP, NO_ADDRS, null /* iface */);
+            return mService.createInterface(TAP, CARRIER_UP, BRING_UP, USE_IPV6_PROV_DELAY,
+                    NO_ADDRS, null /* iface */);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -204,7 +207,8 @@
     @NonNull
     public TestNetworkInterface createTapInterface(@NonNull LinkAddress[] linkAddrs) {
         try {
-            return mService.createInterface(TAP, CARRIER_UP, BRING_UP, linkAddrs, null /* iface */);
+            return mService.createInterface(TAP, CARRIER_UP, BRING_UP, USE_IPV6_PROV_DELAY,
+                    linkAddrs, null /* iface */);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -223,7 +227,8 @@
     @NonNull
     public TestNetworkInterface createTapInterface(boolean bringUp) {
         try {
-            return mService.createInterface(TAP, CARRIER_UP, bringUp, NO_ADDRS, null /* iface */);
+            return mService.createInterface(TAP, CARRIER_UP, bringUp, USE_IPV6_PROV_DELAY,
+                    NO_ADDRS, null /* iface */);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -245,7 +250,8 @@
     @NonNull
     public TestNetworkInterface createTapInterface(boolean bringUp, @NonNull String iface) {
         try {
-            return mService.createInterface(TAP, CARRIER_UP, bringUp, NO_ADDRS, iface);
+            return mService.createInterface(TAP, CARRIER_UP, bringUp, USE_IPV6_PROV_DELAY,
+                    NO_ADDRS, iface);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -264,7 +270,49 @@
     @NonNull
     public TestNetworkInterface createTapInterface(boolean carrierUp, boolean bringUp) {
         try {
-            return mService.createInterface(TAP, carrierUp, bringUp, NO_ADDRS, null /* iface */);
+            return mService.createInterface(TAP, carrierUp, bringUp, USE_IPV6_PROV_DELAY, NO_ADDRS,
+                    null /* iface */);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Create a tap interface for testing purposes.
+     *
+     * @param carrierUp whether the created interface has a carrier or not.
+     * @param bringUp whether to bring up the interface before returning it.
+     * @param disableIpv6ProvisioningDelay whether to disable DAD and RS delay.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
+    @NonNull
+    public TestNetworkInterface createTapInterface(boolean carrierUp, boolean bringUp,
+            boolean disableIpv6ProvisioningDelay) {
+        try {
+            return mService.createInterface(TAP, carrierUp, bringUp, disableIpv6ProvisioningDelay,
+                    NO_ADDRS, null /* iface */);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Create a tap interface for testing purposes.
+     *
+     * @param disableIpv6ProvisioningDelay whether to disable DAD and RS delay.
+     * @param linkAddrs an array of LinkAddresses to assign to the TAP interface
+     * @return A TestNetworkInterface representing the underlying TAP interface. Close the contained
+     *     ParcelFileDescriptor to tear down the TAP interface.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
+    @NonNull
+    public TestNetworkInterface createTapInterface(boolean disableIpv6ProvisioningDelay,
+            @NonNull LinkAddress[] linkAddrs) {
+        try {
+            return mService.createInterface(TAP, CARRIER_UP, BRING_UP, disableIpv6ProvisioningDelay,
+                    linkAddrs, null /* iface */);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/nearby/OWNERS b/nearby/OWNERS
index 980c221..844ef06 100644
--- a/nearby/OWNERS
+++ b/nearby/OWNERS
@@ -1,4 +1,6 @@
+chenw@google.com
 chunzhang@google.com
 weiwa@google.com
 weiwu@google.com
+xinhe@google.com
 xlythe@google.com
diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java
index fef6afb..08d2a3c 100644
--- a/service-t/src/com/android/server/net/NetworkStatsService.java
+++ b/service-t/src/com/android/server/net/NetworkStatsService.java
@@ -2809,7 +2809,7 @@
                     throw new IllegalStateException("invalid tethering stats " + e);
                 }
             }
-        } catch (IllegalStateException e) {
+        } catch (IllegalStateException | ServiceSpecificException e) {
             Log.wtf(TAG, "problem reading network stats", e);
         }
         return stats;
diff --git a/service/Android.bp b/service/Android.bp
index 7a4fb33..499af25 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -261,9 +261,15 @@
     installable: true,
 }
 
-filegroup {
+genrule {
     name: "connectivity-jarjar-rules",
-    srcs: ["jarjar-rules.txt"],
+    defaults: ["jarjar-rules-combine-defaults"],
+    srcs: [
+        ":framework-connectivity-jarjar-rules",
+        ":service-connectivity-jarjar-gen",
+        ":service-nearby-jarjar-gen",
+    ],
+    out: ["connectivity-jarjar-rules.txt"],
     visibility: ["//packages/modules/Connectivity:__subpackages__"],
 }
 
@@ -274,3 +280,41 @@
     srcs: ["src/com/android/server/BpfNetMaps.java"],
     visibility: ["//packages/modules/Connectivity:__subpackages__"],
 }
+
+java_genrule {
+    name: "service-connectivity-jarjar-gen",
+    tool_files: [
+        ":service-connectivity-pre-jarjar{.jar}",
+        ":service-connectivity-tiramisu-pre-jarjar{.jar}",
+        "jarjar-excludes.txt",
+    ],
+    tools: [
+        "jarjar-rules-generator",
+    ],
+    out: ["service_connectivity_jarjar_rules.txt"],
+    cmd: "$(location jarjar-rules-generator) " +
+        "--jars $(location :service-connectivity-pre-jarjar{.jar}) " +
+        "$(location :service-connectivity-tiramisu-pre-jarjar{.jar}) " +
+        "--prefix android.net.connectivity " +
+        "--excludes $(location jarjar-excludes.txt) " +
+        "--output $(out)",
+    visibility: ["//visibility:private"],
+}
+
+java_genrule {
+    name: "service-nearby-jarjar-gen",
+    tool_files: [
+        ":service-nearby-pre-jarjar{.jar}",
+        "jarjar-excludes.txt",
+    ],
+    tools: [
+        "jarjar-rules-generator",
+    ],
+    out: ["service_nearby_jarjar_rules.txt"],
+    cmd: "$(location jarjar-rules-generator) " +
+        "--jars $(location :service-nearby-pre-jarjar{.jar}) " +
+        "--prefix com.android.server.nearby " +
+        "--excludes $(location jarjar-excludes.txt) " +
+        "--output $(out)",
+    visibility: ["//visibility:private"],
+}
diff --git a/service/jarjar-rules.txt b/service/jarjar-rules.txt
deleted file mode 100644
index 1ad75e3..0000000
--- a/service/jarjar-rules.txt
+++ /dev/null
@@ -1,123 +0,0 @@
-# Classes in framework-connectivity are restricted to the android.net package.
-# This cannot be changed because it is harcoded in ART in S.
-# Any missing jarjar rule for framework-connectivity would be caught by the
-# build as an unexpected class outside of the android.net package.
-rule com.android.net.module.util.** android.net.connectivity.@0
-rule com.android.modules.utils.** android.net.connectivity.@0
-rule android.net.NetworkFactory* android.net.connectivity.@0
-
-# From modules-utils-preconditions
-rule com.android.internal.util.Preconditions* android.net.connectivity.@0
-
-# From framework-connectivity-shared-srcs
-rule android.util.LocalLog* android.net.connectivity.@0
-rule android.util.IndentingPrintWriter* android.net.connectivity.@0
-rule com.android.internal.util.IndentingPrintWriter* android.net.connectivity.@0
-rule com.android.internal.util.MessageUtils* android.net.connectivity.@0
-rule com.android.internal.util.WakeupMessage* android.net.connectivity.@0
-rule com.android.internal.util.FileRotator* android.net.connectivity.@0
-rule com.android.internal.util.ProcFileReader* android.net.connectivity.@0
-
-# From framework-connectivity-protos
-rule com.google.protobuf.** android.net.connectivity.@0
-rule android.service.** android.net.connectivity.@0
-
-rule android.sysprop.** com.android.connectivity.@0
-
-rule com.android.internal.messages.** com.android.connectivity.@0
-
-# From dnsresolver_aidl_interface (newer AIDLs should go to android.net.resolv.aidl)
-rule android.net.resolv.aidl.** com.android.connectivity.@0
-rule android.net.IDnsResolver* com.android.connectivity.@0
-rule android.net.ResolverHostsParcel* com.android.connectivity.@0
-rule android.net.ResolverOptionsParcel* com.android.connectivity.@0
-rule android.net.ResolverParamsParcel* com.android.connectivity.@0
-rule android.net.ResolverParamsParcel* com.android.connectivity.@0
-# Also includes netd event listener AIDL, but this is handled by netd-client rules
-
-# From netd-client (newer AIDLs should go to android.net.netd.aidl)
-rule android.net.netd.aidl.** com.android.connectivity.@0
-# Avoid including android.net.INetdEventCallback, used in tests but not part of the module
-rule android.net.INetd com.android.connectivity.@0
-rule android.net.INetd$* com.android.connectivity.@0
-rule android.net.INetdUnsolicitedEventListener* com.android.connectivity.@0
-rule android.net.InterfaceConfigurationParcel* com.android.connectivity.@0
-rule android.net.MarkMaskParcel* com.android.connectivity.@0
-rule android.net.NativeNetworkConfig* com.android.connectivity.@0
-rule android.net.NativeNetworkType* com.android.connectivity.@0
-rule android.net.NativeVpnType* com.android.connectivity.@0
-rule android.net.RouteInfoParcel* com.android.connectivity.@0
-rule android.net.TetherConfigParcel* com.android.connectivity.@0
-rule android.net.TetherOffloadRuleParcel* com.android.connectivity.@0
-rule android.net.TetherStatsParcel* com.android.connectivity.@0
-rule android.net.UidRangeParcel* com.android.connectivity.@0
-rule android.net.metrics.INetdEventListener* com.android.connectivity.@0
-
-# From netlink-client
-rule android.net.netlink.** com.android.connectivity.@0
-
-# From networkstack-client (newer AIDLs should go to android.net.[networkstack|ipmemorystore].aidl)
-rule android.net.networkstack.aidl.** com.android.connectivity.@0
-rule android.net.ipmemorystore.aidl.** com.android.connectivity.@0
-rule android.net.ipmemorystore.aidl.** com.android.connectivity.@0
-rule android.net.DataStallReportParcelable* com.android.connectivity.@0
-rule android.net.DhcpResultsParcelable* com.android.connectivity.@0
-rule android.net.IIpMemoryStore* com.android.connectivity.@0
-rule android.net.INetworkMonitor* com.android.connectivity.@0
-rule android.net.INetworkStackConnector* com.android.connectivity.@0
-rule android.net.INetworkStackStatusCallback* com.android.connectivity.@0
-rule android.net.InformationElementParcelable* com.android.connectivity.@0
-rule android.net.InitialConfigurationParcelable* com.android.connectivity.@0
-rule android.net.IpMemoryStore* com.android.connectivity.@0
-rule android.net.Layer2InformationParcelable* com.android.connectivity.@0
-rule android.net.Layer2PacketParcelable* com.android.connectivity.@0
-rule android.net.NattKeepalivePacketDataParcelable* com.android.connectivity.@0
-rule android.net.NetworkMonitorManager* com.android.connectivity.@0
-rule android.net.NetworkTestResultParcelable* com.android.connectivity.@0
-rule android.net.PrivateDnsConfigParcel* com.android.connectivity.@0
-rule android.net.ProvisioningConfigurationParcelable* com.android.connectivity.@0
-rule android.net.ScanResultInfoParcelable* com.android.connectivity.@0
-rule android.net.TcpKeepalivePacketDataParcelable* com.android.connectivity.@0
-rule android.net.dhcp.DhcpLeaseParcelable* com.android.connectivity.@0
-rule android.net.dhcp.DhcpServingParamsParcel* com.android.connectivity.@0
-rule android.net.dhcp.IDhcpEventCallbacks* com.android.connectivity.@0
-rule android.net.dhcp.IDhcpServer* com.android.connectivity.@0
-rule android.net.ip.IIpClient* com.android.connectivity.@0
-rule android.net.ip.IpClientCallbacks* com.android.connectivity.@0
-rule android.net.ip.IpClientManager* com.android.connectivity.@0
-rule android.net.ip.IpClientUtil* com.android.connectivity.@0
-rule android.net.ipmemorystore.** com.android.connectivity.@0
-rule android.net.networkstack.** com.android.connectivity.@0
-rule android.net.shared.** com.android.connectivity.@0
-rule android.net.util.KeepalivePacketDataUtil* com.android.connectivity.@0
-
-# From connectivity-module-utils
-rule android.net.shared.** com.android.connectivity.@0
-
-# From services-connectivity-shared-srcs
-rule android.net.util.NetworkConstants* com.android.connectivity.@0
-
-# From modules-utils-statemachine
-rule com.android.internal.util.IState* com.android.connectivity.@0
-rule com.android.internal.util.State* com.android.connectivity.@0
-
-# From the API shims
-rule com.android.networkstack.apishim.** com.android.connectivity.@0
-
-# From filegroup framework-connectivity-protos
-rule android.service.*Proto com.android.connectivity.@0
-
-# From mdns-aidl-interface
-rule android.net.mdns.aidl.** android.net.connectivity.@0
-
-# From nearby-service, including proto
-rule service.proto.** com.android.server.nearby.@0
-rule androidx.annotation.Keep* com.android.server.nearby.@0
-rule androidx.collection.** com.android.server.nearby.@0
-rule androidx.core.** com.android.server.nearby.@0
-rule androidx.versionedparcelable.** com.android.server.nearby.@0
-rule com.google.common.** com.android.server.nearby.@0
-rule android.support.v4.** com.android.server.nearby.@0
-
-# Remaining are connectivity sources in com.android.server and com.android.server.connectivity:
-# TODO: move to a subpackage of com.android.connectivity (such as com.android.connectivity.server)
diff --git a/service/jni/com_android_server_TestNetworkService.cpp b/service/jni/com_android_server_TestNetworkService.cpp
index 9c7a761..a6efbc6 100644
--- a/service/jni/com_android_server_TestNetworkService.cpp
+++ b/service/jni/com_android_server_TestNetworkService.cpp
@@ -97,6 +97,7 @@
     ScopedUtfChars iface(env, jIface);
     if (!iface.c_str()) {
         jniThrowNullPointerException(env, "iface");
+        return;
     }
     setTunTapCarrierEnabledImpl(env, iface.c_str(), tunFd, enabled);
 }
diff --git a/service/proguard.flags b/service/proguard.flags
index cffa490..f546e82 100644
--- a/service/proguard.flags
+++ b/service/proguard.flags
@@ -2,8 +2,6 @@
 # TODO: instead of keeping everything, consider listing only "entry points"
 # (service loader, JNI registered methods, etc) and letting the optimizer do its job
 -keep class android.net.** { *; }
--keep class com.android.connectivity.** { *; }
--keep class com.android.net.** { *; }
 -keep class !com.android.server.nearby.**,com.android.server.** { *; }
 
 # Prevent proguard from stripping out any nearby-service and fast-pair-lite-protos fields.
@@ -13,5 +11,5 @@
 # the schema, keep all the fields.
 # This replicates the base proguard rule used by the build by default
 # (proguard_basic_keeps.flags), but needs to be specified here because the
-# com.google.protobuf package is jarjared to the below package.
--keepclassmembers class * extends android.net.connectivity.com.google.protobuf.MessageLite { <fields>; }
+# com.google.protobuf package is jarjared to use a package prefix.
+-keepclassmembers class * extends **.com.google.protobuf.MessageLite { <fields>; }
diff --git a/service/src/com/android/server/TestNetworkService.java b/service/src/com/android/server/TestNetworkService.java
index 1209579..dc922f4 100644
--- a/service/src/com/android/server/TestNetworkService.java
+++ b/service/src/com/android/server/TestNetworkService.java
@@ -120,7 +120,7 @@
      */
     @Override
     public TestNetworkInterface createInterface(boolean isTun, boolean hasCarrier, boolean bringUp,
-            LinkAddress[] linkAddrs, @Nullable String iface) {
+            boolean disableIpv6ProvisioningDelay, LinkAddress[] linkAddrs, @Nullable String iface) {
         enforceTestNetworkPermissions(mContext);
 
         Objects.requireNonNull(linkAddrs, "missing linkAddrs");
@@ -137,6 +137,14 @@
         try {
             ParcelFileDescriptor tunIntf = ParcelFileDescriptor.adoptFd(
                     nativeCreateTunTap(isTun, hasCarrier, interfaceName));
+
+            // Disable DAD and remove router_solicitation_delay before assigning link addresses.
+            if (disableIpv6ProvisioningDelay) {
+                mNetd.setProcSysNet(
+                        INetd.IPV6, INetd.CONF, interfaceName, "router_solicitation_delay", "0");
+                mNetd.setProcSysNet(INetd.IPV6, INetd.CONF, interfaceName, "dad_transmits", "0");
+            }
+
             for (LinkAddress addr : linkAddrs) {
                 mNetd.interfaceAddAddress(
                         interfaceName,
diff --git a/tests/common/Android.bp b/tests/common/Android.bp
index 58731e0..efea0f9 100644
--- a/tests/common/Android.bp
+++ b/tests/common/Android.bp
@@ -23,7 +23,7 @@
 
 java_library {
     name: "FrameworksNetCommonTests",
-    defaults: ["framework-connectivity-test-defaults"],
+    defaults: ["framework-connectivity-internal-test-defaults"],
     srcs: [
         "java/**/*.java",
         "java/**/*.kt",
@@ -49,6 +49,7 @@
 // jarjar stops at the first matching rule, so order of concatenation affects the output.
 genrule {
     name: "ConnectivityCoverageJarJarRules",
+    defaults: ["jarjar-rules-combine-defaults"],
     srcs: [
         "tethering-jni-jarjar-rules.txt",
         ":connectivity-jarjar-rules",
@@ -56,8 +57,6 @@
         ":NetworkStackJarJarRules",
     ],
     out: ["jarjar-rules-connectivity-coverage.txt"],
-    // Concat files with a line break in the middle
-    cmd: "for src in $(in); do cat $${src}; echo; done > $(out)",
     visibility: ["//visibility:private"],
 }
 
@@ -84,7 +83,7 @@
     target_sdk_version: "31",
     test_suites: ["general-tests", "mts-tethering"],
     defaults: [
-        "framework-connectivity-test-defaults",
+        "framework-connectivity-internal-test-defaults",
         "FrameworksNetTests-jni-defaults",
         "libnetworkstackutilsjni_deps",
     ],
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index a6ed762..75dc50e 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -72,9 +72,9 @@
 android_test {
     name: "CtsNetTestCases",
     defaults: ["CtsNetTestCasesDefaults", "ConnectivityNextEnableDefaults"],
-    // TODO: CTS should not depend on the entirety of the networkstack code.
     static_libs: [
-        "NetworkStackApiCurrentLib",
+        "DhcpPacketLib",
+        "NetworkStackApiCurrentShims",
     ],
     test_suites: [
         "cts",
@@ -86,7 +86,8 @@
     name: "CtsNetTestCasesApiStableDefaults",
     // TODO: CTS should not depend on the entirety of the networkstack code.
     static_libs: [
-        "NetworkStackApiStableLib",
+        "DhcpPacketLib",
+        "NetworkStackApiStableShims",
     ],
     jni_uses_sdk_apis: true,
     min_sdk_version: "29",
diff --git a/tests/cts/net/native/src/BpfCompatTest.cpp b/tests/cts/net/native/src/BpfCompatTest.cpp
index e52533b..5c02b0d 100644
--- a/tests/cts/net/native/src/BpfCompatTest.cpp
+++ b/tests/cts/net/native/src/BpfCompatTest.cpp
@@ -31,7 +31,10 @@
   std::ifstream elfFile(elfPath, std::ios::in | std::ios::binary);
   ASSERT_TRUE(elfFile.is_open());
 
-  if (android::modules::sdklevel::IsAtLeastT()) {
+  if (android::modules::sdklevel::IsAtLeastU()) {
+    EXPECT_EQ(120, readSectionUint("size_of_bpf_map_def", elfFile, 0));
+    EXPECT_EQ(92, readSectionUint("size_of_bpf_prog_def", elfFile, 0));
+  } else if (android::modules::sdklevel::IsAtLeastT()) {
     EXPECT_EQ(116, readSectionUint("size_of_bpf_map_def", elfFile, 0));
     EXPECT_EQ(92, readSectionUint("size_of_bpf_prog_def", elfFile, 0));
   } else {
@@ -47,8 +50,13 @@
 }
 
 TEST(BpfTest, bpfStructSizeTest) {
-  doBpfStructSizeTest("/system/etc/bpf/gpu_mem.o");
-  doBpfStructSizeTest("/system/etc/bpf/time_in_state.o");
+  if (android::modules::sdklevel::IsAtLeastU()) {
+      doBpfStructSizeTest("/system/etc/bpf/gpuMem.o");
+      doBpfStructSizeTest("/system/etc/bpf/timeInState.o");
+  } else {
+      doBpfStructSizeTest("/system/etc/bpf/gpu_mem.o");
+      doBpfStructSizeTest("/system/etc/bpf/time_in_state.o");
+  }
 }
 
 int main(int argc, char **argv) {
diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
index 1b77d5f..b5d2a52 100644
--- a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
+++ b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
@@ -37,8 +37,8 @@
 import android.net.cts.NetworkValidationTestUtil.setHttpsUrlDeviceConfig
 import android.net.cts.NetworkValidationTestUtil.setUrlExpirationDeviceConfig
 import android.net.cts.util.CtsNetUtils
-import android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL
-import android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL
+import com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTPS_URL
+import com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTP_URL
 import android.os.Build
 import android.platform.test.annotations.AppModeFull
 import android.provider.DeviceConfig
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 766d62f..bb92a23 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -75,8 +75,6 @@
 import static android.net.cts.util.CtsNetUtils.TEST_HOST;
 import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
 import static android.net.cts.util.CtsTetheringUtils.TestTetheringEventCallback;
-import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL;
-import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL;
 import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
 import static android.os.Process.INVALID_UID;
 import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
@@ -88,6 +86,8 @@
 import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
 import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
+import static com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTPS_URL;
+import static com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTP_URL;
 import static com.android.networkstack.apishim.ConstantsShim.BLOCKED_REASON_LOCKDOWN_VPN;
 import static com.android.networkstack.apishim.ConstantsShim.BLOCKED_REASON_NONE;
 import static com.android.testutils.Cleanup.testAndCleanup;
@@ -2092,25 +2092,15 @@
 
         try {
             // Verify we cannot set Airplane Mode without correct permission:
-            try {
-                setAndVerifyAirplaneMode(true);
-                fail("SecurityException should have been thrown when setAirplaneMode was called"
-                        + "without holding permission NETWORK_AIRPLANE_MODE.");
-            } catch (SecurityException expected) {}
+            assertThrows(SecurityException.class, () -> setAndVerifyAirplaneMode(true));
 
             // disable airplane mode again to reach a known state
             runShellCommand("cmd connectivity airplane-mode disable");
 
-            // adopt shell permission which holds NETWORK_AIRPLANE_MODE
-            mUiAutomation.adoptShellPermissionIdentity();
+            // Verify we can enable Airplane Mode with correct permission.
+            // TODO: test that NETWORK_AIRPLANE_MODE works as well, once the shell has it.
+            runAsShell(NETWORK_SETTINGS, () -> setAndVerifyAirplaneMode(true));
 
-            // Verify we can enable Airplane Mode with correct permission:
-            try {
-                setAndVerifyAirplaneMode(true);
-            } catch (SecurityException e) {
-                fail("SecurityException should not have been thrown when setAirplaneMode(true) was"
-                        + "called whilst holding the NETWORK_AIRPLANE_MODE permission.");
-            }
             // Verify that the enabling airplane mode takes effect as expected to prevent flakiness
             // caused by fast airplane mode switches. Ensure network lost before turning off
             // airplane mode.
@@ -2118,12 +2108,8 @@
             if (supportTelephony) waitForLost(telephonyCb);
 
             // Verify we can disable Airplane Mode with correct permission:
-            try {
-                setAndVerifyAirplaneMode(false);
-            } catch (SecurityException e) {
-                fail("SecurityException should not have been thrown when setAirplaneMode(false) was"
-                        + "called whilst holding the NETWORK_AIRPLANE_MODE permission.");
-            }
+            runAsShell(NETWORK_SETTINGS, () -> setAndVerifyAirplaneMode(false));
+
             // Verify that turning airplane mode off takes effect as expected.
             // connectToCell only registers a request, it cannot / does not need to be called twice
             mCtsNetUtils.ensureWifiConnected();
@@ -2133,7 +2119,6 @@
             // Restore the previous state of airplane mode and permissions:
             runShellCommand("cmd connectivity airplane-mode "
                     + (isAirplaneModeEnabled ? "enable" : "disable"));
-            mUiAutomation.dropShellPermissionIdentity();
         }
     }
 
diff --git a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
index 1748612..1a3b01e 100644
--- a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
@@ -22,6 +22,8 @@
 import android.net.ConnectivityManager
 import android.net.EthernetManager
 import android.net.EthernetManager.InterfaceStateListener
+import android.net.EthernetManager.ETHERNET_STATE_DISABLED
+import android.net.EthernetManager.ETHERNET_STATE_ENABLED
 import android.net.EthernetManager.ROLE_CLIENT
 import android.net.EthernetManager.ROLE_NONE
 import android.net.EthernetManager.ROLE_SERVER
@@ -44,6 +46,7 @@
 import android.net.NetworkRequest
 import android.net.TestNetworkInterface
 import android.net.TestNetworkManager
+import android.net.cts.EthernetManagerTest.EthernetStateListener.CallbackEntry.EthernetStateChanged
 import android.net.cts.EthernetManagerTest.EthernetStateListener.CallbackEntry.InterfaceStateChanged
 import android.os.Build
 import android.os.Handler
@@ -76,6 +79,7 @@
 import java.util.concurrent.ExecutionException
 import java.util.concurrent.TimeoutException
 import java.util.concurrent.TimeUnit
+import java.util.function.IntConsumer
 import kotlin.test.assertEquals
 import kotlin.test.assertFailsWith
 import kotlin.test.assertFalse
@@ -161,7 +165,7 @@
 
     private open class EthernetStateListener private constructor(
         private val history: ArrayTrackRecord<CallbackEntry>
-    ) : InterfaceStateListener,
+    ) : InterfaceStateListener, IntConsumer,
                 TrackRecord<EthernetStateListener.CallbackEntry> by history {
         constructor() : this(ArrayTrackRecord())
 
@@ -174,6 +178,8 @@
                 val role: Int,
                 val configuration: IpConfiguration?
             ) : CallbackEntry()
+
+            data class EthernetStateChanged(val state: Int) : CallbackEntry()
         }
 
         override fun onInterfaceStateChanged(
@@ -185,6 +191,10 @@
             add(InterfaceStateChanged(iface, state, role, cfg))
         }
 
+        override fun accept(state: Int) {
+            add(EthernetStateChanged(state))
+        }
+
         fun <T : CallbackEntry> expectCallback(expected: T): T {
             val event = pollForNextCallback()
             assertEquals(expected, event)
@@ -195,6 +205,10 @@
             expectCallback(createChangeEvent(iface.name, state, role))
         }
 
+        fun expectCallback(state: Int) {
+            expectCallback(EthernetStateChanged(state))
+        }
+
         fun createChangeEvent(iface: String, state: Int, role: Int) =
                 InterfaceStateChanged(iface, state, role,
                         if (state != STATE_ABSENT) DEFAULT_IP_CONFIGURATION else null)
@@ -209,6 +223,10 @@
             assertNotNull(eventuallyExpect(createChangeEvent(iface.name, state, role)))
         }
 
+        fun eventuallyExpect(state: Int) {
+            assertNotNull(eventuallyExpect(EthernetStateChanged(state)))
+        }
+
         fun assertNoCallback() {
             val cb = events.poll(NO_CALLBACK_TIMEOUT_MS)
             assertNull(cb, "Expected no callback but got $cb")
@@ -280,11 +298,17 @@
 
     @After
     fun tearDown() {
-        setIncludeTestInterfaces(false)
+        // Reenable ethernet, so ABSENT callbacks are received.
+        setEthernetEnabled(true)
+
         for (iface in createdIfaces) {
             iface.destroy()
             ifaceListener.eventuallyExpect(iface, STATE_ABSENT, ROLE_NONE)
         }
+
+        // After test interfaces are removed, disable tracking.
+        setIncludeTestInterfaces(false)
+
         for (listener in addedListeners) {
             em.removeInterfaceStateListener(listener)
         }
@@ -391,6 +415,19 @@
         }
     }
 
+    private fun setEthernetEnabled(enabled: Boolean) {
+        runAsShell(NETWORK_SETTINGS) { em.setEthernetEnabled(enabled) }
+
+        val listener = EthernetStateListener()
+        em.addEthernetStateListener(handler::post, listener)
+        try {
+            listener.eventuallyExpect(
+                    if (enabled) ETHERNET_STATE_ENABLED else ETHERNET_STATE_DISABLED)
+        } finally {
+            em.removeEthernetStateListener(listener)
+        }
+    }
+
     // NetworkRequest.Builder does not create a copy of the passed NetworkRequest, so in order to
     // keep ETH_REQUEST as it is, a defensive copy is created here.
     private fun NetworkRequest.createCopyWithEthernetSpecifier(ifaceName: String) =
diff --git a/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt b/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
index 462c8a3..375bfb8 100644
--- a/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
@@ -17,9 +17,9 @@
 package android.net.cts
 
 import android.Manifest.permission.WRITE_DEVICE_CONFIG
-import android.net.util.NetworkStackUtils
 import android.provider.DeviceConfig
 import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY
+import com.android.net.module.util.NetworkStackConstants
 import com.android.testutils.runAsShell
 
 /**
@@ -35,41 +35,41 @@
     @JvmStatic fun clearValidationTestUrlsDeviceConfig() {
         runAsShell(WRITE_DEVICE_CONFIG) {
             DeviceConfig.setProperty(NAMESPACE_CONNECTIVITY,
-                    NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL, null, false)
+                    NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTPS_URL, null, false)
             DeviceConfig.setProperty(NAMESPACE_CONNECTIVITY,
-                    NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL, null, false)
+                    NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTP_URL, null, false)
             DeviceConfig.setProperty(NAMESPACE_CONNECTIVITY,
-                    NetworkStackUtils.TEST_URL_EXPIRATION_TIME, null, false)
+                    NetworkStackConstants.TEST_URL_EXPIRATION_TIME, null, false)
         }
     }
 
     /**
      * Set the test validation HTTPS URL.
      *
-     * @see NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL
+     * @see NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTPS_URL
      */
     @JvmStatic
     fun setHttpsUrlDeviceConfig(rule: DeviceConfigRule, url: String?) =
             rule.setConfig(NAMESPACE_CONNECTIVITY,
-                NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL, url)
+                NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTPS_URL, url)
 
     /**
      * Set the test validation HTTP URL.
      *
-     * @see NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL
+     * @see NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTP_URL
      */
     @JvmStatic
     fun setHttpUrlDeviceConfig(rule: DeviceConfigRule, url: String?) =
             rule.setConfig(NAMESPACE_CONNECTIVITY,
-                NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL, url)
+                NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTP_URL, url)
 
     /**
      * Set the test validation URL expiration.
      *
-     * @see NetworkStackUtils.TEST_URL_EXPIRATION_TIME
+     * @see NetworkStackConstants.TEST_URL_EXPIRATION_TIME
      */
     @JvmStatic
     fun setUrlExpirationDeviceConfig(rule: DeviceConfigRule, timestamp: Long?) =
             rule.setConfig(NAMESPACE_CONNECTIVITY,
-                NetworkStackUtils.TEST_URL_EXPIRATION_TIME, timestamp?.toString())
+                NetworkStackConstants.TEST_URL_EXPIRATION_TIME, timestamp?.toString())
 }
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
index b3684ac..e3d80a0 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -21,7 +21,7 @@
 
 android_test {
     name: "FrameworksNetIntegrationTests",
-    defaults: ["framework-connectivity-test-defaults"],
+    defaults: ["framework-connectivity-internal-test-defaults"],
     platform_apis: true,
     certificate: "platform",
     srcs: [
@@ -71,8 +71,12 @@
         "net-tests-utils",
     ],
     libs: [
-        "service-connectivity-for-tests",
+        "service-connectivity-pre-jarjar",
         "services.core",
         "services.net",
     ],
+    visibility: [
+        "//packages/modules/Connectivity/tests/integration",
+        "//packages/modules/Connectivity/tests/unit",
+    ],
 }
diff --git a/tests/unit/java/com/android/server/connectivity/VpnTest.java b/tests/unit/java/com/android/server/connectivity/VpnTest.java
index 5c1992d..6f25d1b 100644
--- a/tests/unit/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/unit/java/com/android/server/connectivity/VpnTest.java
@@ -969,6 +969,31 @@
                 AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, AppOpsManager.OPSTR_ACTIVATE_VPN);
     }
 
+    private void setAppOpsPermission() {
+        doAnswer(invocation -> {
+            when(mAppOps.noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN,
+                    Process.myUid(), TEST_VPN_PKG,
+                    null /* attributionTag */, null /* message */))
+                    .thenReturn(AppOpsManager.MODE_ALLOWED);
+            return null;
+        }).when(mAppOps).setMode(
+                eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
+                eq(Process.myUid()),
+                eq(TEST_VPN_PKG),
+                eq(AppOpsManager.MODE_ALLOWED));
+    }
+
+    @Test
+    public void testProvisionVpnProfileNotPreconsented_withControlVpnPermission() throws Exception {
+        setAppOpsPermission();
+        doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks();
+
+        // ACTIVATE_PLATFORM_VPN will be granted if VPN app has CONTROL_VPN permission.
+        checkProvisionVpnProfile(vpn, true /* expectedResult */,
+                AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
+    }
+
     @Test
     public void testProvisionVpnProfileVpnServicePreconsented() throws Exception {
         final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_VPN);
@@ -1589,6 +1614,30 @@
         assertEquals(LegacyVpnInfo.STATE_FAILED, vpn.getLegacyVpnInfo().state);
     }
 
+    @Test
+    public void testVpnManagerEventWillNotBeSentToSettingsVpn() throws Exception {
+        startLegacyVpn(createVpn(PRIMARY_USER.id), mVpnProfile);
+        triggerOnAvailableAndGetCallback();
+
+        verifyInterfaceSetCfgWithFlags(IF_STATE_UP);
+
+        final IkeNonProtocolException exception = mock(IkeNonProtocolException.class);
+        final IkeTimeoutException ikeTimeoutException =
+                new IkeTimeoutException("IkeTimeoutException");
+        when(exception.getCause()).thenReturn(ikeTimeoutException);
+
+        final ArgumentCaptor<IkeSessionCallback> captor =
+                ArgumentCaptor.forClass(IkeSessionCallback.class);
+        verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS))
+                .createIkeSession(any(), any(), any(), any(), captor.capture(), any());
+        final IkeSessionCallback ikeCb = captor.getValue();
+        ikeCb.onClosedWithException(exception);
+
+        final Context userContext =
+                mContext.createContextAsUser(UserHandle.of(PRIMARY_USER.id), 0 /* flags */);
+        verify(userContext, never()).startService(any());
+    }
+
     private void setAndVerifyAlwaysOnPackage(Vpn vpn, int uid, boolean lockdownEnabled) {
         assertTrue(vpn.setAlwaysOnPackage(TEST_VPN_PKG, lockdownEnabled, null));