Merge "SyncSM11.1 make some functions inline" into main
diff --git a/OWNERS b/OWNERS
index b2176cc..988af41 100644
--- a/OWNERS
+++ b/OWNERS
@@ -3,3 +3,4 @@
 file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
 
 per-file **IpSec* = file:platform/frameworks/base:main:/services/core/java/com/android/server/vcn/OWNERS
+per-file **Xfrm* = file:platform/frameworks/base:main:/services/core/java/com/android/server/vcn/OWNERS
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 4bd7e6a..9f542f4 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -90,7 +90,6 @@
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -1258,12 +1257,18 @@
         pw.decreaseIndent();
     }
 
-    private IpPrefix longToPrefix(long ip64) {
-        final ByteBuffer prefixBuffer = ByteBuffer.allocate(IPV6_ADDR_LEN);
-        prefixBuffer.putLong(ip64);
+    /**
+     * Returns a /64 IpPrefix corresponding to the passed in byte array
+     *
+     * @param ip64 byte array to convert format
+     * @return the converted IpPrefix
+     */
+    @VisibleForTesting
+    public static IpPrefix bytesToPrefix(final byte[] ip64) {
         IpPrefix sourcePrefix;
+        byte[] prefixBytes = Arrays.copyOf(ip64, IPV6_ADDR_LEN);
         try {
-            sourcePrefix = new IpPrefix(InetAddress.getByAddress(prefixBuffer.array()), 64);
+            sourcePrefix = new IpPrefix(InetAddress.getByAddress(prefixBytes), 64);
         } catch (UnknownHostException e) {
             // Cannot happen. InetAddress.getByAddress can only throw an exception if the byte array
             // is the wrong length, but we allocate it with fixed length IPV6_ADDR_LEN.
@@ -1274,7 +1279,7 @@
 
     private String ipv6UpstreamRuleToString(TetherUpstream6Key key, Tether6Value value) {
         return String.format("%d(%s) [%s] [%s] -> %d(%s) %04x [%s] [%s]",
-                key.iif, getIfName(key.iif), key.dstMac, longToPrefix(key.src64), value.oif,
+                key.iif, getIfName(key.iif), key.dstMac, bytesToPrefix(key.src64), value.oif,
                 getIfName(value.oif), value.ethProto, value.ethSrcMac, value.ethDstMac);
     }
 
@@ -1570,7 +1575,7 @@
          */
         @NonNull
         public TetherUpstream6Key makeTetherUpstream6Key() {
-            long prefix64 = ByteBuffer.wrap(sourcePrefix.getRawAddress()).getLong();
+            final byte[] prefix64 = Arrays.copyOf(sourcePrefix.getRawAddress(), 8);
             return new TetherUpstream6Key(downstreamIfindex, inDstMac, prefix64);
         }
 
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java b/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
index 36a1c3c..0cc3dd9 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
@@ -32,10 +32,10 @@
     @Field(order = 1, type = Type.EUI48, padding = 6)
     public final MacAddress dstMac; // Destination ethernet mac address (zeroed iff rawip ingress).
 
-    @Field(order = 2, type = Type.S64)
-    public final long src64; // The top 64-bits of the source ip.
+    @Field(order = 2, type = Type.ByteArray, arraysize = 8)
+    public final byte[] src64; // The top 64-bits of the source ip.
 
-    public TetherUpstream6Key(int iif, @NonNull final MacAddress dstMac, long src64) {
+    public TetherUpstream6Key(int iif, @NonNull final MacAddress dstMac, final byte[] src64) {
         Objects.requireNonNull(dstMac);
 
         this.iif = iif;
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index 6c1721e..01600b8 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -64,6 +64,7 @@
 import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
 import static com.android.testutils.MiscAsserts.assertSameElements;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -166,7 +167,6 @@
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
-import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -794,7 +794,7 @@
         if (!mDeps.isAtLeastS()) return;
         ArrayMap<TetherUpstream6Key, Tether6Value> expected = new ArrayMap<>();
         for (IpPrefix upstreamPrefix : upstreamPrefixes) {
-            long prefix64 = prefixToLong(upstreamPrefix);
+            final byte[] prefix64 = prefixToIp64(upstreamPrefix);
             final TetherUpstream6Key key = new TetherUpstream6Key(DOWNSTREAM_IFACE_PARAMS.index,
                     DOWNSTREAM_IFACE_PARAMS.macAddr, prefix64);
             final Tether6Value value = new Tether6Value(upstreamIfindex,
@@ -822,7 +822,7 @@
         if (!mDeps.isAtLeastS()) return;
         Set<TetherUpstream6Key> expected = new ArraySet<>();
         for (IpPrefix upstreamPrefix : upstreamPrefixes) {
-            long prefix64 = prefixToLong(upstreamPrefix);
+            final byte[] prefix64 = prefixToIp64(upstreamPrefix);
             final TetherUpstream6Key key = new TetherUpstream6Key(DOWNSTREAM_IFACE_PARAMS.index,
                     DOWNSTREAM_IFACE_PARAMS.macAddr, prefix64);
             expected.add(key);
@@ -1275,7 +1275,7 @@
     }
 
     @Test
-    public void testRuleMakeTetherDownstream6Key() throws Exception {
+    public void testIpv6DownstreamRuleMakeTetherDownstream6Key() throws Exception {
         final int mobileIfIndex = 100;
         final Ipv6DownstreamRule rule = buildTestDownstreamRule(mobileIfIndex, NEIGH_A, MAC_A);
 
@@ -1288,7 +1288,7 @@
     }
 
     @Test
-    public void testRuleMakeTether6Value() throws Exception {
+    public void testIpv6DownstreamRuleMakeTether6Value() throws Exception {
         final int mobileIfIndex = 100;
         final Ipv6DownstreamRule rule = buildTestDownstreamRule(mobileIfIndex, NEIGH_A, MAC_A);
 
@@ -1303,6 +1303,46 @@
     }
 
     @Test
+    public void testIpv6UpstreamRuleMakeTetherUpstream6Key() {
+        final byte[] bytes = new byte[]{(byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8,
+                (byte) 0xab, (byte) 0xcd, (byte) 0xfe, (byte) 0x00};
+        final IpPrefix prefix = new IpPrefix("2001:db8:abcd:fe00::/64");
+        final Ipv6UpstreamRule rule = buildTestUpstreamRule(UPSTREAM_IFINDEX,
+                DOWNSTREAM_IFINDEX, prefix, DOWNSTREAM_MAC);
+
+        final TetherUpstream6Key key = rule.makeTetherUpstream6Key();
+        assertEquals(DOWNSTREAM_IFINDEX, key.iif);
+        assertEquals(DOWNSTREAM_MAC, key.dstMac);
+        assertArrayEquals(bytes, key.src64);
+        // iif (4) + dstMac (6) + padding (6) + src64 (8) = 24
+        assertEquals(24, key.writeToBytes().length);
+    }
+
+    @Test
+    public void testIpv6UpstreamRuleMakeTether6Value() {
+        final IpPrefix prefix = new IpPrefix("2001:db8:abcd:fe00::/64");
+        final Ipv6UpstreamRule rule = buildTestUpstreamRule(UPSTREAM_IFINDEX,
+                DOWNSTREAM_IFINDEX, prefix, DOWNSTREAM_MAC);
+
+        final Tether6Value value = rule.makeTether6Value();
+        assertEquals(UPSTREAM_IFINDEX, value.oif);
+        assertEquals(MAC_NULL, value.ethDstMac);
+        assertEquals(MAC_NULL, value.ethSrcMac);
+        assertEquals(ETH_P_IPV6, value.ethProto);
+        assertEquals(NetworkStackConstants.ETHER_MTU, value.pmtu);
+        // oif (4) + ethDstMac (6) + ethSrcMac (6) + ethProto (2) + pmtu (2) = 20
+        assertEquals(20, value.writeToBytes().length);
+    }
+
+    @Test
+    public void testBytesToPrefix() {
+        final byte[] bytes = new byte[]{(byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8,
+                (byte) 0x00, (byte) 0x00, (byte) 0x12, (byte) 0x34};
+        final IpPrefix prefix = new IpPrefix("2001:db8:0:1234::/64");
+        assertEquals(prefix, BpfCoordinator.bytesToPrefix(bytes));
+    }
+
+    @Test
     public void testSetDataLimit() throws Exception {
         setupFunctioningNetdInterface();
 
@@ -2269,8 +2309,8 @@
                 100 /* nonzero, CT_NEW */);
     }
 
-    private static long prefixToLong(IpPrefix prefix) {
-        return ByteBuffer.wrap(prefix.getRawAddress()).getLong();
+    private static byte[] prefixToIp64(IpPrefix prefix) {
+        return Arrays.copyOf(prefix.getRawAddress(), 8);
     }
 
     void checkRule4ExistInUpstreamDownstreamMap() throws Exception {
@@ -2515,7 +2555,7 @@
         final Ipv6DownstreamRule rule = buildTestDownstreamRule(UPSTREAM_IFINDEX, NEIGH_A, MAC_A);
         mBpfDownstream6Map.insertEntry(rule.makeTetherDownstream6Key(), rule.makeTether6Value());
 
-        final long prefix64 = prefixToLong(UPSTREAM_PREFIX);
+        final byte[] prefix64 = prefixToIp64(UPSTREAM_PREFIX);
         final TetherUpstream6Key upstream6Key = new TetherUpstream6Key(DOWNSTREAM_IFINDEX,
                 DOWNSTREAM_MAC, prefix64);
         final Tether6Value upstream6Value = new Tether6Value(UPSTREAM_IFINDEX,
diff --git a/framework-t/src/android/net/nsd/MDnsManager.java b/framework-t/src/android/net/nsd/MDnsManager.java
index c11e60c..c7ded25 100644
--- a/framework-t/src/android/net/nsd/MDnsManager.java
+++ b/framework-t/src/android/net/nsd/MDnsManager.java
@@ -51,7 +51,7 @@
     public void startDaemon() {
         try {
             mMdns.startDaemon();
-        } catch (RemoteException | ServiceSpecificException e) {
+        } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) {
             Log.e(TAG, "Start mdns failed.", e);
         }
     }
@@ -62,7 +62,7 @@
     public void stopDaemon() {
         try {
             mMdns.stopDaemon();
-        } catch (RemoteException | ServiceSpecificException e) {
+        } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) {
             Log.e(TAG, "Stop mdns failed.", e);
         }
     }
@@ -85,7 +85,7 @@
                 registrationType, port, txtRecord, interfaceIdx);
         try {
             mMdns.registerService(info);
-        } catch (RemoteException | ServiceSpecificException e) {
+        } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) {
             Log.e(TAG, "Register service failed.", e);
             return false;
         }
@@ -105,7 +105,7 @@
                 registrationType, "" /* domainName */, interfaceIdx, NETID_UNSET);
         try {
             mMdns.discover(info);
-        } catch (RemoteException | ServiceSpecificException e) {
+        } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) {
             Log.e(TAG, "Discover service failed.", e);
             return false;
         }
@@ -129,7 +129,7 @@
                 new byte[0] /* txtRecord */, interfaceIdx);
         try {
             mMdns.resolve(info);
-        } catch (RemoteException | ServiceSpecificException e) {
+        } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) {
             Log.e(TAG, "Resolve service failed.", e);
             return false;
         }
@@ -149,7 +149,7 @@
                 "" /* address */, interfaceIdx, NETID_UNSET);
         try {
             mMdns.getServiceAddress(info);
-        } catch (RemoteException | ServiceSpecificException e) {
+        } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) {
             Log.e(TAG, "Get service address failed.", e);
             return false;
         }
@@ -165,7 +165,7 @@
     public boolean stopOperation(int id) {
         try {
             mMdns.stopOperation(id);
-        } catch (RemoteException | ServiceSpecificException e) {
+        } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) {
             Log.e(TAG, "Stop operation failed.", e);
             return false;
         }
@@ -180,7 +180,7 @@
     public void registerEventListener(@NonNull IMDnsEventListener listener) {
         try {
             mMdns.registerEventListener(listener);
-        } catch (RemoteException | ServiceSpecificException e) {
+        } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) {
             Log.e(TAG, "Register listener failed.", e);
         }
     }
@@ -193,7 +193,7 @@
     public void unregisterEventListener(@NonNull IMDnsEventListener listener) {
         try {
             mMdns.unregisterEventListener(listener);
-        } catch (RemoteException | ServiceSpecificException e) {
+        } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) {
             Log.e(TAG, "Unregister listener failed.", e);
         }
     }
diff --git a/framework-t/src/android/net/nsd/NsdManager.java b/framework-t/src/android/net/nsd/NsdManager.java
index ef0e34b..dae8914 100644
--- a/framework-t/src/android/net/nsd/NsdManager.java
+++ b/framework-t/src/android/net/nsd/NsdManager.java
@@ -34,10 +34,10 @@
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
+import android.net.ConnectivityThread;
 import android.net.Network;
 import android.net.NetworkRequest;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
@@ -632,10 +632,9 @@
      */
     public NsdManager(Context context, INsdManager service) {
         mContext = context;
-
-        HandlerThread t = new HandlerThread("NsdManager");
-        t.start();
-        mHandler = new ServiceHandler(t.getLooper());
+        // Use a common singleton thread ConnectivityThread to be shared among all nsd tasks.
+        // Instead of launching separate threads to handle tasks from the various instances.
+        mHandler = new ServiceHandler(ConnectivityThread.getInstanceLooper());
 
         try {
             mService = service.connect(new NsdCallbackImpl(mHandler), CompatChanges.isChangeEnabled(
diff --git a/framework/Android.bp b/framework/Android.bp
index fab37e9..73a1ed0 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -94,7 +94,9 @@
         "framework-wifi.stubs.module_lib",
     ],
     static_libs: [
-        "mdns_aidl_interface-lateststable-java",
+        // Not using the latest stable version because all functions in the latest version of
+        // mdns_aidl_interface are deprecated.
+        "mdns_aidl_interface-V1-java",
         "modules-utils-backgroundthread",
         "modules-utils-build",
         "modules-utils-preconditions",
diff --git a/service/Android.bp b/service/Android.bp
index 76741bc..e2dab9e 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -185,7 +185,7 @@
         "androidx.annotation_annotation",
         "connectivity-net-module-utils-bpf",
         "connectivity_native_aidl_interface-lateststable-java",
-        "dnsresolver_aidl_interface-V12-java",
+        "dnsresolver_aidl_interface-V13-java",
         "modules-utils-shell-command-handler",
         "net-utils-device-common",
         "net-utils-device-common-ip",
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index a8d925f..8f29078 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -5263,7 +5263,7 @@
     private boolean hasCarrierPrivilegeForNetworkCaps(final int callingUid,
             @NonNull final NetworkCapabilities caps) {
         if (mCarrierPrivilegeAuthenticator != null) {
-            return mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+            return mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                     callingUid, caps);
         }
         return false;
diff --git a/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java b/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
index a39345e..5705ebe 100644
--- a/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
+++ b/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
@@ -17,6 +17,7 @@
 package com.android.server.connectivity;
 
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
 import static com.android.server.connectivity.ConnectivityFlags.CARRIER_SERVICE_CHANGED_USE_CALLBACK;
 
@@ -31,6 +32,8 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkSpecifier;
 import android.net.TelephonyNetworkSpecifier;
+import android.net.TransportInfo;
+import android.net.wifi.WifiInfo;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Process;
@@ -211,12 +214,13 @@
      *
      * This returns whether the passed UID is the carrier service package for the subscription ID
      * stored in the telephony network specifier in the passed network capabilities.
-     * If the capabilities don't code for a cellular network, or if they don't have the
+     * If the capabilities don't code for a cellular or Wi-Fi network, or if they don't have the
      * subscription ID in their specifier, this returns false.
      *
-     * This method can be used to check that a network request for {@link NET_CAPABILITY_CBS} is
-     * allowed for the UID of a caller, which must hold carrier privilege and provide the carrier
-     * config.
+     * This method can be used to check that a network request that requires the UID to be
+     * the carrier service UID is indeed called by such a UID. An example of such a network could
+     * be a network with the  {@link android.net.NetworkCapabilities#NET_CAPABILITY_CBS}
+     * capability.
      * It can also be used to check that a factory is entitled to grant access to a given network
      * to a given UID on grounds that it is the carrier service package.
      *
@@ -224,13 +228,28 @@
      * @param networkCapabilities the network capabilities for which carrier privilege is checked.
      * @return true if uid provides the relevant carrier config else false.
      */
-    public boolean hasCarrierPrivilegeForNetworkCapabilities(int callingUid,
+    public boolean isCarrierServiceUidForNetworkCapabilities(int callingUid,
             @NonNull NetworkCapabilities networkCapabilities) {
         if (callingUid == Process.INVALID_UID) return false;
-        if (!networkCapabilities.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR)) {
-            return false;
+        final int subId;
+        if (networkCapabilities.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR)) {
+            subId = getSubIdFromTelephonySpecifier(networkCapabilities.getNetworkSpecifier());
+        } else if (networkCapabilities.hasSingleTransportBesidesTest(TRANSPORT_WIFI)) {
+            subId = getSubIdFromWifiTransportInfo(networkCapabilities.getTransportInfo());
+        } else {
+            subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         }
-        final int subId = getSubIdFromNetworkSpecifier(networkCapabilities.getNetworkSpecifier());
+        if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+                && !networkCapabilities.getSubscriptionIds().contains(subId)) {
+            // Ideally, the code above should just use networkCapabilities.getSubscriptionIds()
+            // for simplicity and future-proofing. However, this is not the historical behavior,
+            // and there is no enforcement that they do not differ, so log a terrible failure if
+            // they do not match to gain confidence this never happens.
+            // TODO : when there is confidence that this never happens, rewrite the code above
+            // with NetworkCapabilities#getSubscriptionIds.
+            Log.wtf(TAG, "NetworkCapabilities subIds are inconsistent between "
+                    + "specifier/transportInfo and mSubIds : " + networkCapabilities);
+        }
         if (SubscriptionManager.INVALID_SUBSCRIPTION_ID == subId) return false;
         return callingUid == getCarrierServiceUidForSubId(subId);
     }
@@ -259,14 +278,6 @@
     }
 
     @VisibleForTesting
-    int getSubIdFromNetworkSpecifier(NetworkSpecifier specifier) {
-        if (specifier instanceof TelephonyNetworkSpecifier) {
-            return ((TelephonyNetworkSpecifier) specifier).getSubscriptionId();
-        }
-        return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-    }
-
-    @VisibleForTesting
     int getUidForPackage(String pkgName) {
         if (pkgName == null) {
             return Process.INVALID_UID;
@@ -291,8 +302,22 @@
         return getUidForPackage(getCarrierServicePackageNameForLogicalSlot(slotId));
     }
 
-    // Helper methods to avoid having to deal with UnsupportedApiLevelException.
+    @VisibleForTesting
+    int getSubIdFromTelephonySpecifier(@Nullable final NetworkSpecifier specifier) {
+        if (specifier instanceof TelephonyNetworkSpecifier) {
+            return ((TelephonyNetworkSpecifier) specifier).getSubscriptionId();
+        }
+        return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    }
 
+    int getSubIdFromWifiTransportInfo(@Nullable final TransportInfo info) {
+        if (info instanceof WifiInfo) {
+            return ((WifiInfo) info).getSubscriptionId();
+        }
+        return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    }
+
+    // Helper methods to avoid having to deal with UnsupportedApiLevelException.
     private void addCarrierPrivilegesListener(@NonNull final Executor executor,
             @NonNull final PrivilegeListener listener) {
         try {
diff --git a/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
index 567fd41..50cad45 100644
--- a/service/src/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
@@ -23,6 +23,7 @@
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.transportNamesOf;
 
 import android.annotation.NonNull;
@@ -1591,12 +1592,13 @@
             return false;
         }
 
-        // Factories that make cell networks can allow the UID for the carrier service package.
+        // Factories that make cell/wifi networks can allow the UID for the carrier service package.
         // This can only work in T where there is support for CarrierPrivilegeAuthenticator
         if (null != carrierPrivilegeAuthenticator
-                && nc.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR)
+                && (nc.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR)
+                        || nc.hasSingleTransportBesidesTest(TRANSPORT_WIFI))
                 && (1 == nc.getAllowedUidsNoCopy().size())
-                && (carrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+                && (carrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                         nc.getAllowedUidsNoCopy().valueAt(0), nc))) {
             return true;
         }
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index 6325b46..9f1debc 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -191,7 +191,7 @@
 java_library {
     name: "net-utils-device-common-netlink",
     srcs: [
-        "device/com/android/net/module/util/netlink/*.java",
+        "device/com/android/net/module/util/netlink/**/*.java",
     ],
     sdk_version: "module_current",
     min_sdk_version: "30",
diff --git a/staticlibs/device/com/android/net/module/util/netlink/IpSecStructXfrmAddressT.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmAddressT.java
similarity index 86%
rename from staticlibs/device/com/android/net/module/util/netlink/IpSecStructXfrmAddressT.java
rename to staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmAddressT.java
index 4c19887..cef1f56 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/IpSecStructXfrmAddressT.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmAddressT.java
@@ -13,7 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.net.module.util.netlink;
+package com.android.net.module.util.netlink.xfrm;
+
+import static com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_LEN;
 
 import android.system.OsConstants;
 
@@ -41,21 +43,19 @@
  *
  * @hide
  */
-public class IpSecStructXfrmAddressT extends Struct {
-    private static final int IPV4_ADDRESS_LEN = 4;
-
+public class StructXfrmAddressT extends Struct {
     public static final int STRUCT_SIZE = 16;
 
     @Field(order = 0, type = Type.ByteArray, arraysize = STRUCT_SIZE)
     public final byte[] address;
 
     // Constructor that allows Strutc.parse(Class<T>, ByteBuffer) to work
-    public IpSecStructXfrmAddressT(@NonNull byte[] address) {
+    public StructXfrmAddressT(@NonNull final byte[] address) {
         this.address = address.clone();
     }
 
     // Constructor to build a new message
-    public IpSecStructXfrmAddressT(@NonNull InetAddress inetAddress) {
+    public StructXfrmAddressT(@NonNull final InetAddress inetAddress) {
         this.address = new byte[STRUCT_SIZE];
         final byte[] addressBytes = inetAddress.getAddress();
         System.arraycopy(addressBytes, 0, address, 0, addressBytes.length);
@@ -67,7 +67,7 @@
         if (family == OsConstants.AF_INET6) {
             addressBytes = this.address;
         } else if (family == OsConstants.AF_INET) {
-            addressBytes = new byte[IPV4_ADDRESS_LEN];
+            addressBytes = new byte[IPV4_ADDR_LEN];
             System.arraycopy(this.address, 0, addressBytes, 0, addressBytes.length);
         } else {
             throw new IllegalArgumentException("Invalid IP family " + family);
diff --git a/staticlibs/device/com/android/net/module/util/netlink/IpSecStructXfrmUsersaId.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmUsersaId.java
similarity index 76%
rename from staticlibs/device/com/android/net/module/util/netlink/IpSecStructXfrmUsersaId.java
rename to staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmUsersaId.java
index 6f7b656..5ebc69c 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/IpSecStructXfrmUsersaId.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmUsersaId.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.net.module.util.netlink;
+package com.android.net.module.util.netlink.xfrm;
 
 import androidx.annotation.NonNull;
 
@@ -40,7 +40,7 @@
  *
  * @hide
  */
-public class IpSecStructXfrmUsersaId extends Struct {
+public class StructXfrmUsersaId extends Struct {
     public static final int STRUCT_SIZE = 24;
 
     @Field(order = 0, type = Type.ByteArray, arraysize = 16)
@@ -55,23 +55,23 @@
     @Field(order = 3, type = Type.U8, padding = 1)
     public final short proto;
 
-    @Computed private final IpSecStructXfrmAddressT mDestXfrmAddressT;
+    @Computed private final StructXfrmAddressT mDestXfrmAddressT;
 
     // Constructor that allows Strutc.parse(Class<T>, ByteBuffer) to work
-    public IpSecStructXfrmUsersaId(
-            @NonNull byte[] nestedStructDAddr, long spi, int family, short proto) {
+    public StructXfrmUsersaId(
+            @NonNull final byte[] nestedStructDAddr, long spi, int family, short proto) {
         this.nestedStructDAddr = nestedStructDAddr.clone();
         this.spi = spi;
         this.family = family;
         this.proto = proto;
 
-        mDestXfrmAddressT = new IpSecStructXfrmAddressT(this.nestedStructDAddr);
+        mDestXfrmAddressT = new StructXfrmAddressT(this.nestedStructDAddr);
     }
 
     // Constructor to build a new message
-    public IpSecStructXfrmUsersaId(
-            @NonNull InetAddress destAddress, long spi, int family, short proto) {
-        this(new IpSecStructXfrmAddressT(destAddress).writeToBytes(), spi, family, proto);
+    public StructXfrmUsersaId(
+            @NonNull final InetAddress destAddress, long spi, int family, short proto) {
+        this(new StructXfrmAddressT(destAddress).writeToBytes(), spi, family, proto);
     }
 
     /** Return the destination address */
diff --git a/staticlibs/device/com/android/net/module/util/netlink/IpSecXfrmNetlinkMessage.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java
similarity index 81%
rename from staticlibs/device/com/android/net/module/util/netlink/IpSecXfrmNetlinkMessage.java
rename to staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java
index 8ad784b..ee34e57 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/IpSecXfrmNetlinkMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java
@@ -14,21 +14,24 @@
  * limitations under the License.
  */
 
-package com.android.net.module.util.netlink;
+package com.android.net.module.util.netlink.xfrm;
 
 import androidx.annotation.NonNull;
 
+import com.android.net.module.util.netlink.NetlinkMessage;
+import com.android.net.module.util.netlink.StructNlMsgHdr;
+
 /** Base calss for XFRM netlink messages */
 // Developer notes: The Linux kernel includes a number of XFRM structs that are not standard netlink
 // attributes (e.g., xfrm_usersa_id). These structs are unlikely to change size, so this XFRM
 // netlink message implementation assumes their sizes will remain stable. If any non-attribute
 // struct size changes, it should be caught by CTS and then developers should add
 // kernel-version-based behvaiours.
-public abstract class IpSecXfrmNetlinkMessage extends NetlinkMessage {
+public abstract class XfrmNetlinkMessage extends NetlinkMessage {
     // TODO: STOPSHIP: b/308011229 Remove it when OsConstants.IPPROTO_ESP is exposed
     public static final int IPPROTO_ESP = 50;
 
-    public IpSecXfrmNetlinkMessage(@NonNull StructNlMsgHdr header) {
+    public XfrmNetlinkMessage(@NonNull final StructNlMsgHdr header) {
         super(header);
     }
 
diff --git a/staticlibs/netd/Android.bp b/staticlibs/netd/Android.bp
index 56565ed..637a938 100644
--- a/staticlibs/netd/Android.bp
+++ b/staticlibs/netd/Android.bp
@@ -225,19 +225,6 @@
 
 }
 
-java_library {
-    name: "mdns_aidl_interface-lateststable-java",
-    sdk_version: "module_current",
-    min_sdk_version: "30",
-    static_libs: [
-        "mdns_aidl_interface-V1-java",
-    ],
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.tethering",
-    ],
-}
-
 aidl_interface {
     name: "mdns_aidl_interface",
     local_include_dir: "binder",
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/IpSecStructXfrmUsersaIdTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmUsersaIdTest.java
similarity index 84%
rename from staticlibs/tests/unit/src/com/android/net/module/util/netlink/IpSecStructXfrmUsersaIdTest.java
rename to staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmUsersaIdTest.java
index 4266f68..52fd591 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/IpSecStructXfrmUsersaIdTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmUsersaIdTest.java
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.net.module.util.netlink;
+package com.android.net.module.util.netlink.xfrm;
 
-import static com.android.net.module.util.netlink.IpSecXfrmNetlinkMessage.IPPROTO_ESP;
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.IPPROTO_ESP;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -38,7 +38,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-public class IpSecStructXfrmUsersaIdTest {
+public class StructXfrmUsersaIdTest {
     private static final String EXPECTED_HEX_STRING =
             "C0000201000000000000000000000000" + "7768440002003200";
     private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
@@ -50,8 +50,7 @@
 
     @Test
     public void testEncode() throws Exception {
-        final IpSecStructXfrmUsersaId struct =
-                new IpSecStructXfrmUsersaId(DEST_ADDRESS, SPI, FAMILY, PROTO);
+        final StructXfrmUsersaId struct = new StructXfrmUsersaId(DEST_ADDRESS, SPI, FAMILY, PROTO);
 
         ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
         buffer.order(ByteOrder.nativeOrder());
@@ -65,8 +64,8 @@
         final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
         buffer.order(ByteOrder.nativeOrder());
 
-        final IpSecStructXfrmUsersaId struct =
-                IpSecStructXfrmUsersaId.parse(IpSecStructXfrmUsersaId.class, buffer);
+        final StructXfrmUsersaId struct =
+                StructXfrmUsersaId.parse(StructXfrmUsersaId.class, buffer);
 
         assertEquals(DEST_ADDRESS, struct.getDestAddress());
         assertEquals(SPI, struct.spi);
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 3b6607f..225408c 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -757,8 +757,8 @@
             val timeout = SystemClock.elapsedRealtime() + DEFAULT_TIMEOUT_MS
             while (true) {
                 if (SystemClock.elapsedRealtime() > timeout) {
-                    fail("Couldn't make $servicePackage the service package for $defaultSubId: "
-                            + "dumpsys connectivity".execute().split("\n")
+                    fail("Couldn't make $servicePackage the service package for $defaultSubId: " +
+                            "dumpsys connectivity".execute().split("\n")
                                     .filter { it.contains("Logical slot = $defaultSlotIndex.*") })
                 }
                 if ("dumpsys connectivity"
@@ -772,10 +772,14 @@
                 Thread.sleep(500)
             }
 
-            // Cell is allowed to set UIDs, but not WIFI/BLUETOOTH or agents with multiple
+            // Cell and WiFi are allowed to set UIDs, but not Bluetooth or agents with multiple
             // transports.
             doTestAllowedUids(defaultSubId, TRANSPORT_CELLULAR, uid, expectUidsPresent = true)
-            doTestAllowedUids(defaultSubId, TRANSPORT_WIFI, uid, expectUidsPresent = false)
+            if (SdkLevel.isAtLeastV()) {
+                // Cannot be tested before V because WifiInfo.Builder#setSubscriptionId doesn't
+                // exist
+                doTestAllowedUids(defaultSubId, TRANSPORT_WIFI, uid, expectUidsPresent = true)
+            }
             doTestAllowedUids(defaultSubId, TRANSPORT_BLUETOOTH, uid, expectUidsPresent = false)
             doTestAllowedUids(defaultSubId, intArrayOf(TRANSPORT_CELLULAR, TRANSPORT_WIFI), uid,
                     expectUidsPresent = false)
diff --git a/tests/unit/java/android/net/nsd/NsdManagerTest.java b/tests/unit/java/android/net/nsd/NsdManagerTest.java
index 0965193..550a9ee 100644
--- a/tests/unit/java/android/net/nsd/NsdManagerTest.java
+++ b/tests/unit/java/android/net/nsd/NsdManagerTest.java
@@ -51,6 +51,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+@DevSdkIgnoreRunner.MonitorThreadLeak
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 9470a08..9fad766 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -79,7 +79,6 @@
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
-import static android.net.ConnectivityManager.TYPE_NONE;
 import static android.net.ConnectivityManager.TYPE_VPN;
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF;
@@ -17531,7 +17530,7 @@
 
         // In this test TEST_PACKAGE_UID will be the UID of the carrier service UID.
         doReturn(true).when(mCarrierPrivilegeAuthenticator)
-                .hasCarrierPrivilegeForNetworkCapabilities(eq(TEST_PACKAGE_UID), any());
+                .isCarrierServiceUidForNetworkCapabilities(eq(TEST_PACKAGE_UID), any());
 
         // Simulate a restricted telephony network. The telephony factory is entitled to set
         // the access UID to the service package on any of its restricted networks.
@@ -17596,17 +17595,18 @@
         // TODO : fix the builder
         ncb.setNetworkSpecifier(null);
         ncb.removeTransportType(TRANSPORT_CELLULAR);
-        ncb.addTransportType(TRANSPORT_WIFI);
+        ncb.addTransportType(TRANSPORT_BLUETOOTH);
         // Wifi does not get to set access UID, even to the correct UID
         mCm.requestNetwork(new NetworkRequest.Builder()
-                .addTransportType(TRANSPORT_WIFI)
+                .addTransportType(TRANSPORT_BLUETOOTH)
                 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
                 .build(), cb);
-        mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), ncb.build());
-        mWiFiAgent.connect(true);
-        cb.expectAvailableThenValidatedCallbacks(mWiFiAgent);
+        final TestNetworkAgentWrapper bluetoothAgent = new TestNetworkAgentWrapper(
+                TRANSPORT_BLUETOOTH, new LinkProperties(), ncb.build());
+        bluetoothAgent.connect(true);
+        cb.expectAvailableThenValidatedCallbacks(bluetoothAgent);
         ncb.setAllowedUids(serviceUidSet);
-        mWiFiAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
+        bluetoothAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
         cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS);
         mCm.unregisterNetworkCallback(cb);
     }
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index 771edb2..ffc8aa1 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -145,6 +145,7 @@
 // TODOs:
 //  - test client can send requests and receive replies
 //  - test NSD_ON ENABLE/DISABLED listening
+@DevSdkIgnoreRunner.MonitorThreadLeak
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
diff --git a/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java b/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java
index 12324d8..f07593e 100644
--- a/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java
@@ -174,9 +174,9 @@
                 .addTransportType(TRANSPORT_CELLULAR)
                 .setNetworkSpecifier(new TelephonyNetworkSpecifier(0));
 
-        assertTrue(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+        assertTrue(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                 mCarrierConfigPkgUid, ncBuilder.build()));
-        assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+        assertFalse(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                 mCarrierConfigPkgUid + 1, ncBuilder.build()));
     }
 
@@ -213,9 +213,9 @@
                 .addTransportType(TRANSPORT_CELLULAR)
                 .setNetworkSpecifier(specifier)
                 .build();
-        assertTrue(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+        assertTrue(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                 mCarrierConfigPkgUid, nc));
-        assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+        assertFalse(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                 mCarrierConfigPkgUid + 1, nc));
     }
 
@@ -235,9 +235,9 @@
         listener.onCarrierPrivilegesChanged(Collections.emptyList(), new int[] {});
         listener.onCarrierServiceChanged(null, applicationInfo.uid);
 
-        assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+        assertFalse(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                 mCarrierConfigPkgUid, nc));
-        assertTrue(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+        assertTrue(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                 mCarrierConfigPkgUid + 1, nc));
     }
 
@@ -248,11 +248,11 @@
 
         final NetworkCapabilities.Builder ncBuilder = new NetworkCapabilities.Builder();
         ncBuilder.addTransportType(TRANSPORT_CELLULAR);
-        assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+        assertFalse(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                 mCarrierConfigPkgUid, ncBuilder.build()));
 
         ncBuilder.setNetworkSpecifier(new TelephonyNetworkSpecifier(0));
-        assertTrue(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+        assertTrue(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                 mCarrierConfigPkgUid, ncBuilder.build()));
 
         // The builder for NetworkCapabilities doesn't allow removing the transport as long as a
@@ -261,7 +261,7 @@
         ncBuilder.removeTransportType(TRANSPORT_CELLULAR);
         ncBuilder.addTransportType(TRANSPORT_WIFI);
         ncBuilder.setNetworkSpecifier(new TelephonyNetworkSpecifier(0));
-        assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+        assertFalse(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
                 mCarrierConfigPkgUid, ncBuilder.build()));
     }
 }
diff --git a/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java b/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
index 545ed16..afb9abd 100644
--- a/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
@@ -140,7 +140,8 @@
         assertResolverOptionsEquals(actual.resolverOptions, expected.resolverOptions);
         assertContainsExactly(actual.transportTypes, expected.transportTypes);
         assertEquals(actual.meteredNetwork, expected.meteredNetwork);
-        assertFieldCountEquals(17, ResolverParamsParcel.class);
+        assertEquals(actual.dohParams, expected.dohParams);
+        assertFieldCountEquals(18, ResolverParamsParcel.class);
     }
 
     @Before
@@ -381,6 +382,7 @@
         expectedParams.transportTypes = TEST_TRANSPORT_TYPES;
         expectedParams.resolverOptions = null;
         expectedParams.meteredNetwork = true;
+        expectedParams.dohParams = null;
         assertResolverParamsEquals(actualParams, expectedParams);
     }