diff --git a/TEST_MAPPING b/TEST_MAPPING
index 4eeaf51..4774866 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -171,23 +171,6 @@
       ]
     }
   ],
-  "auto-postsubmit": [
-    // Test tag for automotive targets. These are only running in postsubmit so as to harden the
-    // automotive targets to avoid introducing additional test flake and build time. The plan for
-    // presubmit testing for auto is to augment the existing tests to cover auto use cases as well.
-    // Additionally, this tag is used in targeted test suites to limit resource usage on the test
-    // infra during the hardening phase.
-    // TODO: this tag to be removed once the above is no longer an issue.
-    {
-      "name": "FrameworksNetTests"
-    },
-    {
-      "name": "FrameworksNetIntegrationTests"
-    },
-    {
-      "name": "FrameworksNetDeflakeTest"
-    }
-  ],
   "imports": [
     {
       "path": "frameworks/base/core/java/android/net"
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index 28edc8a..bfba5cd 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -37,6 +37,7 @@
     ],
     static_libs: [
         "androidx.annotation_annotation",
+        "connectivity-net-module-utils-bpf",
         "modules-utils-build",
         "modules-utils-statemachine",
         "networkstack-client",
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index c403548..ca4071f 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -51,7 +51,6 @@
 import android.system.OsConstants;
 import android.text.TextUtils;
 import android.util.ArraySet;
-import android.util.Base64;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -61,6 +60,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.BpfDump;
 import com.android.net.module.util.BpfMap;
 import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.InterfaceParams;
@@ -125,9 +125,6 @@
     private static final String DUMPSYS_RAWMAP_ARG_STATS = "--stats";
     private static final String DUMPSYS_RAWMAP_ARG_UPSTREAM4 = "--upstream4";
 
-    // Using "," as a separator is safe because base64 characters are [0-9a-zA-Z/=+].
-    private static final String DUMP_BASE64_DELIMITER = ",";
-
     /** The names of all the BPF counters defined in bpf_tethering.h. */
     public static final String[] sBpfCounterNames = getBpfCounterNames();
 
@@ -944,6 +941,8 @@
      * be allowed to be accessed on the handler thread.
      */
     public void dump(@NonNull IndentingPrintWriter pw) {
+        // Note that EthernetTetheringTest#isTetherConfigBpfOffloadEnabled relies on
+        // "mIsBpfEnabled" to check tethering config via dumpsys. Beware of the change if any.
         pw.println("mIsBpfEnabled: " + mIsBpfEnabled);
         pw.println("Polling " + (mPollingStarted ? "started" : "not started"));
         pw.println("Stats provider " + (mStatsProvider != null
@@ -1078,18 +1077,6 @@
         }
     }
 
-    private <K extends Struct, V extends Struct> String bpfMapEntryToBase64String(
-            final K key, final V value) {
-        final byte[] keyBytes = key.writeToBytes();
-        final String keyBase64Str = Base64.encodeToString(keyBytes, Base64.DEFAULT)
-                .replace("\n", "");
-        final byte[] valueBytes = value.writeToBytes();
-        final String valueBase64Str = Base64.encodeToString(valueBytes, Base64.DEFAULT)
-                .replace("\n", "");
-
-        return keyBase64Str + DUMP_BASE64_DELIMITER + valueBase64Str;
-    }
-
     private <K extends Struct, V extends Struct> void dumpRawMap(BpfMap<K, V> map,
             IndentingPrintWriter pw) throws ErrnoException {
         if (map == null) {
@@ -1100,14 +1087,20 @@
             pw.println("No entries");
             return;
         }
-        map.forEach((k, v) -> pw.println(bpfMapEntryToBase64String(k, v)));
+        map.forEach((k, v) -> pw.println(BpfDump.toBase64EncodedString(k, v)));
     }
 
     /**
-     * Dump raw BPF map in base64 encoded strings. For test only.
-     * Only allow to dump one map path once.
-     * Format:
+     * Dump raw BPF map into the base64 encoded strings "<base64 key>,<base64 value>".
+     * Allow to dump only one map path once. For test only.
+     *
+     * Usage:
      * $ dumpsys tethering bpfRawMap --<map name>
+     *
+     * Output:
+     * <base64 encoded key #1>,<base64 encoded value #1>
+     * <base64 encoded key #2>,<base64 encoded value #2>
+     * ..
      */
     public void dumpRawMap(@NonNull IndentingPrintWriter pw, @Nullable String[] args) {
         // TODO: consider checking the arg order that <map name> is after "bpfRawMap". Probably
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index af017f3..f613b73 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -1406,7 +1406,9 @@
     private void enableIpServing(int tetheringType, String ifname, int ipServingMode,
             boolean isNcm) {
         ensureIpServerStarted(ifname, tetheringType, isNcm);
-        changeInterfaceState(ifname, ipServingMode);
+        if (tether(ifname, ipServingMode) != TETHER_ERROR_NO_ERROR) {
+            Log.e(TAG, "unable start tethering on iface " + ifname);
+        }
     }
 
     private void disableWifiIpServingCommon(int tetheringType, String ifname) {
@@ -1551,27 +1553,6 @@
         }
     }
 
-    private void changeInterfaceState(String ifname, int requestedState) {
-        final int result;
-        switch (requestedState) {
-            case IpServer.STATE_UNAVAILABLE:
-            case IpServer.STATE_AVAILABLE:
-                result = untether(ifname);
-                break;
-            case IpServer.STATE_TETHERED:
-            case IpServer.STATE_LOCAL_ONLY:
-                result = tether(ifname, requestedState);
-                break;
-            default:
-                Log.wtf(TAG, "Unknown interface state: " + requestedState);
-                return;
-        }
-        if (result != TETHER_ERROR_NO_ERROR) {
-            Log.e(TAG, "unable start or stop tethering on iface " + ifname);
-            return;
-        }
-    }
-
     TetheringConfiguration getTetheringConfiguration() {
         return mConfig;
     }
diff --git a/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java b/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java
index e25f2ae..d8e631e 100644
--- a/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java
+++ b/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java
@@ -69,7 +69,6 @@
 
     /** Update Tethering stats about caller's package name and downstream type. */
     public void createBuilder(final int downstreamType, final String callerPkg) {
-        mBuilderMap.clear();
         NetworkTetheringReported.Builder statsBuilder =
                     NetworkTetheringReported.newBuilder();
         statsBuilder.setDownstreamType(downstreamTypeToEnum(downstreamType))
diff --git a/Tethering/tests/integration/Android.bp b/Tethering/tests/integration/Android.bp
index 31c3df3..ca8d3de 100644
--- a/Tethering/tests/integration/Android.bp
+++ b/Tethering/tests/integration/Android.bp
@@ -32,6 +32,7 @@
         "net-tests-utils",
         "net-utils-device-common-bpf",
         "testables",
+        "connectivity-net-module-utils-bpf",
     ],
     libs: [
         "android.test.runner",
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index 819936d..ef4f052 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -32,6 +32,7 @@
 import static android.system.OsConstants.IPPROTO_IPV6;
 import static android.system.OsConstants.IPPROTO_UDP;
 
+import static com.android.net.module.util.BpfDump.BASE64_DELIMITER;
 import static com.android.net.module.util.ConnectivityUtils.isIPv6ULA;
 import static com.android.net.module.util.HexDump.dumpHexString;
 import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV4;
@@ -156,7 +157,6 @@
     private static final String DUMPSYS_TETHERING_RAWMAP_ARG = "bpfRawMap";
     private static final String DUMPSYS_RAWMAP_ARG_STATS = "--stats";
     private static final String DUMPSYS_RAWMAP_ARG_UPSTREAM4 = "--upstream4";
-    private static final String BASE64_DELIMITER = ",";
     private static final String LINE_DELIMITER = "\\n";
 
     // version=6, traffic class=0x0, flowlabel=0x0;
@@ -1125,12 +1125,18 @@
     @IgnoreUpTo(Build.VERSION_CODES.R)
     public void testTetherUdpV4AfterR() throws Exception {
         final String kernelVersion = VintfRuntimeInfo.getKernelVersion();
-        boolean usingBpf = isUdpOffloadSupportedByKernel(kernelVersion);
-        if (!usingBpf) {
+        final boolean isUdpOffloadSupported = isUdpOffloadSupportedByKernel(kernelVersion);
+        if (!isUdpOffloadSupported) {
             Log.i(TAG, "testTetherUdpV4AfterR will skip BPF offload test for kernel "
                     + kernelVersion);
         }
-        runUdp4Test(initTetheringTester(toList(TEST_IP4_ADDR), toList(TEST_IP4_DNS)), usingBpf);
+        final boolean isTetherConfigBpfOffloadEnabled = isTetherConfigBpfOffloadEnabled();
+        if (!isTetherConfigBpfOffloadEnabled) {
+            Log.i(TAG, "testTetherUdpV4AfterR will skip BPF offload test "
+                    + "because tethering config doesn't enable BPF offload.");
+        }
+        runUdp4Test(initTetheringTester(toList(TEST_IP4_ADDR), toList(TEST_IP4_DNS)),
+                isUdpOffloadSupported && isTetherConfigBpfOffloadEnabled);
     }
 
     @Nullable
@@ -1189,6 +1195,21 @@
         return null;
     }
 
+    private boolean isTetherConfigBpfOffloadEnabled() throws Exception {
+        final String dumpStr = DumpTestUtils.dumpService(Context.TETHERING_SERVICE, "--short");
+
+        // BPF offload tether config can be overridden by "config_tether_enable_bpf_offload" in
+        // packages/modules/Connectivity/Tethering/res/values/config.xml. OEM may disable config by
+        // RRO to override the enabled default value. Get the tethering config via dumpsys.
+        // $ dumpsys tethering
+        //   mIsBpfEnabled: true
+        boolean enabled = dumpStr.contains("mIsBpfEnabled: true");
+        if (!enabled) {
+            Log.d(TAG, "BPF offload tether config not enabled: " + dumpStr);
+        }
+        return enabled;
+    }
+
     @NonNull
     private Inet6Address getClatIpv6Address(TetheringTester tester, TetheredDevice tethered)
             throws Exception {
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/metrics/TetheringMetricsTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/metrics/TetheringMetricsTest.java
index c34cf5f..6a85718 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/metrics/TetheringMetricsTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/metrics/TetheringMetricsTest.java
@@ -81,6 +81,22 @@
         mTetheringMetrics = spy(new MockTetheringMetrics());
     }
 
+    private void verifyReport(DownstreamType downstream, ErrorCode error, UserType user)
+            throws Exception {
+        final NetworkTetheringReported expectedReport =
+                mStatsBuilder.setDownstreamType(downstream)
+                .setUserType(user)
+                .setUpstreamType(UpstreamType.UT_UNKNOWN)
+                .setErrorCode(error)
+                .build();
+        verify(mTetheringMetrics).write(expectedReport);
+    }
+
+    private void updateErrorAndSendReport(int downstream, int error) {
+        mTetheringMetrics.updateErrorCode(downstream, error);
+        mTetheringMetrics.sendReport(downstream);
+    }
+
     private void runDownstreamTypesTest(final Pair<Integer, DownstreamType>... testPairs)
             throws Exception {
         for (Pair<Integer, DownstreamType> testPair : testPairs) {
@@ -88,15 +104,8 @@
             final DownstreamType expectedResult = testPair.second;
 
             mTetheringMetrics.createBuilder(type, TEST_CALLER_PKG);
-            mTetheringMetrics.updateErrorCode(type, TETHER_ERROR_NO_ERROR);
-            mTetheringMetrics.sendReport(type);
-            NetworkTetheringReported expectedReport =
-                    mStatsBuilder.setDownstreamType(expectedResult)
-                    .setUserType(UserType.USER_UNKNOWN)
-                    .setUpstreamType(UpstreamType.UT_UNKNOWN)
-                    .setErrorCode(ErrorCode.EC_NO_ERROR)
-                    .build();
-            verify(mTetheringMetrics).write(expectedReport);
+            updateErrorAndSendReport(type, TETHER_ERROR_NO_ERROR);
+            verifyReport(expectedResult, ErrorCode.EC_NO_ERROR, UserType.USER_UNKNOWN);
             reset(mTetheringMetrics);
         }
     }
@@ -118,15 +127,8 @@
             final ErrorCode expectedResult = testPair.second;
 
             mTetheringMetrics.createBuilder(TETHERING_WIFI, TEST_CALLER_PKG);
-            mTetheringMetrics.updateErrorCode(TETHERING_WIFI, errorCode);
-            mTetheringMetrics.sendReport(TETHERING_WIFI);
-            NetworkTetheringReported expectedReport =
-                    mStatsBuilder.setDownstreamType(DownstreamType.DS_TETHERING_WIFI)
-                    .setUserType(UserType.USER_UNKNOWN)
-                    .setUpstreamType(UpstreamType.UT_UNKNOWN)
-                    .setErrorCode(expectedResult)
-                    .build();
-            verify(mTetheringMetrics).write(expectedReport);
+            updateErrorAndSendReport(TETHERING_WIFI, errorCode);
+            verifyReport(DownstreamType.DS_TETHERING_WIFI, expectedResult, UserType.USER_UNKNOWN);
             reset(mTetheringMetrics);
         }
     }
@@ -163,15 +165,8 @@
             final UserType expectedResult = testPair.second;
 
             mTetheringMetrics.createBuilder(TETHERING_WIFI, callerPkg);
-            mTetheringMetrics.updateErrorCode(TETHERING_WIFI, TETHER_ERROR_NO_ERROR);
-            mTetheringMetrics.sendReport(TETHERING_WIFI);
-            NetworkTetheringReported expectedReport =
-                    mStatsBuilder.setDownstreamType(DownstreamType.DS_TETHERING_WIFI)
-                    .setUserType(expectedResult)
-                    .setUpstreamType(UpstreamType.UT_UNKNOWN)
-                    .setErrorCode(ErrorCode.EC_NO_ERROR)
-                    .build();
-            verify(mTetheringMetrics).write(expectedReport);
+            updateErrorAndSendReport(TETHERING_WIFI, TETHER_ERROR_NO_ERROR);
+            verifyReport(DownstreamType.DS_TETHERING_WIFI, ErrorCode.EC_NO_ERROR, expectedResult);
             reset(mTetheringMetrics);
         }
     }
@@ -183,4 +178,23 @@
                 new Pair<>(SYSTEMUI_PKG, UserType.USER_SYSTEMUI),
                 new Pair<>(GMS_PKG, UserType.USER_GMS));
     }
+
+    @Test
+    public void testMultiBuildersCreatedBeforeSendReport() throws Exception {
+        mTetheringMetrics.createBuilder(TETHERING_WIFI, SETTINGS_PKG);
+        mTetheringMetrics.createBuilder(TETHERING_USB, SYSTEMUI_PKG);
+        mTetheringMetrics.createBuilder(TETHERING_BLUETOOTH, GMS_PKG);
+
+        updateErrorAndSendReport(TETHERING_WIFI, TETHER_ERROR_DHCPSERVER_ERROR);
+        verifyReport(DownstreamType.DS_TETHERING_WIFI, ErrorCode.EC_DHCPSERVER_ERROR,
+                UserType.USER_SETTINGS);
+
+        updateErrorAndSendReport(TETHERING_USB, TETHER_ERROR_ENABLE_FORWARDING_ERROR);
+        verifyReport(DownstreamType.DS_TETHERING_USB, ErrorCode.EC_ENABLE_FORWARDING_ERROR,
+                UserType.USER_SYSTEMUI);
+
+        updateErrorAndSendReport(TETHERING_BLUETOOTH, TETHER_ERROR_TETHER_IFACE_ERROR);
+        verifyReport(DownstreamType.DS_TETHERING_BLUETOOTH, ErrorCode.EC_TETHER_IFACE_ERROR,
+                UserType.USER_GMS);
+    }
 }
diff --git a/bpf_progs/bpf_shared.h b/bpf_progs/bpf_shared.h
index fd449a3..85b9f86 100644
--- a/bpf_progs/bpf_shared.h
+++ b/bpf_progs/bpf_shared.h
@@ -148,6 +148,7 @@
 
 #endif // __cplusplus
 
+// LINT.IfChange(match_type)
 enum UidOwnerMatchType {
     NO_MATCH = 0,
     HAPPY_BOX_MATCH = (1 << 0),
@@ -163,6 +164,7 @@
     OEM_DENY_2_MATCH = (1 << 10),
     OEM_DENY_3_MATCH = (1 << 11),
 };
+// LINT.ThenChange(packages/modules/Connectivity/service/src/com/android/server/BpfNetMaps.java)
 
 enum BpfPermissionMatch {
     BPF_PERMISSION_INTERNET = 1 << 2,
diff --git a/bpf_progs/dscp_policy.c b/bpf_progs/dscp_policy.c
index 538a9e4..38e1050 100644
--- a/bpf_progs/dscp_policy.c
+++ b/bpf_progs/dscp_policy.c
@@ -297,7 +297,7 @@
 }
 
 DEFINE_BPF_PROG_KVER("schedcls/set_dscp_ether", AID_ROOT, AID_SYSTEM,
-                     schedcls_set_dscp_ether, KVER(5, 4, 0))
+                     schedcls_set_dscp_ether, KVER(5, 15, 0))
 (struct __sk_buff* skb) {
 
     if (skb->pkt_type != PACKET_HOST) return TC_ACT_PIPE;
@@ -313,7 +313,7 @@
 }
 
 DEFINE_BPF_PROG_KVER("schedcls/set_dscp_raw_ip", AID_ROOT, AID_SYSTEM,
-                     schedcls_set_dscp_raw_ip, KVER(5, 4, 0))
+                     schedcls_set_dscp_raw_ip, KVER(5, 15, 0))
 (struct __sk_buff* skb) {
     if (skb->protocol == htons(ETH_P_IP)) {
         match_policy(skb, true, false);
diff --git a/common/Android.bp b/common/Android.bp
new file mode 100644
index 0000000..729ef32
--- /dev/null
+++ b/common/Android.bp
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2022 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
+//
+//      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.
+//
+
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+    name: "connectivity-net-module-utils-bpf",
+    srcs: [
+        "src/com/android/net/module/util/bpf/*.java",
+    ],
+    sdk_version: "module_current",
+    min_sdk_version: "29",
+    visibility: [
+        // Do not add any lib. This library is only shared inside connectivity module
+        // and its tests.
+        "//packages/modules/Connectivity:__subpackages__",
+    ],
+    libs: [
+        "androidx.annotation_annotation",
+        "framework-connectivity.stubs.module_lib",
+    ],
+    static_libs: [
+        "net-utils-device-common-struct",
+    ],
+    apex_available: [
+        "com.android.tethering",
+    ],
+    lint: { strict_updatability_linting: true },
+}
diff --git a/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java b/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java
new file mode 100644
index 0000000..12200ec
--- /dev/null
+++ b/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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
+ *
+ *      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.
+ */
+
+package com.android.net.module.util.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet4Address;
+
+/** Key type for clat egress IPv4 maps. */
+public class ClatEgress4Key extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long iif; // The input interface index
+
+    @Field(order = 1, type = Type.Ipv4Address)
+    public final Inet4Address local4; // The source IPv4 address
+
+    public ClatEgress4Key(final long iif, final Inet4Address local4) {
+        this.iif = iif;
+        this.local4 = local4;
+    }
+}
diff --git a/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java b/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java
new file mode 100644
index 0000000..c10cb4d
--- /dev/null
+++ b/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 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
+ *
+ *      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.
+ */
+
+package com.android.net.module.util.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet6Address;
+
+/** Value type for clat egress IPv4 maps. */
+public class ClatEgress4Value extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long oif; // The output interface to redirect to
+
+    @Field(order = 1, type = Type.Ipv6Address)
+    public final Inet6Address local6; // The full 128-bits of the source IPv6 address
+
+    @Field(order = 2, type = Type.Ipv6Address)
+    public final Inet6Address pfx96; // The destination /96 nat64 prefix, bottom 32 bits must be 0
+
+    @Field(order = 3, type = Type.U8, padding = 3)
+    public final short oifIsEthernet; // Whether the output interface requires ethernet header
+
+    public ClatEgress4Value(final long oif, final Inet6Address local6, final Inet6Address pfx96,
+            final short oifIsEthernet) {
+        this.oif = oif;
+        this.local6 = local6;
+        this.pfx96 = pfx96;
+        this.oifIsEthernet = oifIsEthernet;
+    }
+}
diff --git a/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java b/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java
new file mode 100644
index 0000000..1e2f4e0
--- /dev/null
+++ b/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 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
+ *
+ *      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.
+ */
+
+package com.android.net.module.util.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet6Address;
+
+/** Key type for clat ingress IPv6 maps. */
+public class ClatIngress6Key extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long iif; // The input interface index
+
+    @Field(order = 1, type = Type.Ipv6Address)
+    public final Inet6Address pfx96; // The source /96 nat64 prefix, bottom 32 bits must be 0
+
+    @Field(order = 2, type = Type.Ipv6Address)
+    public final Inet6Address local6; // The full 128-bits of the destination IPv6 address
+
+    public ClatIngress6Key(final long iif, final Inet6Address pfx96, final Inet6Address local6) {
+        this.iif = iif;
+        this.pfx96 = pfx96;
+        this.local6 = local6;
+    }
+}
diff --git a/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java b/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java
new file mode 100644
index 0000000..bfec44f
--- /dev/null
+++ b/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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
+ *
+ *      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.
+ */
+
+package com.android.net.module.util.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet4Address;
+
+/** Value type for clat ingress IPv6 maps. */
+public class ClatIngress6Value extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long oif; // The output interface to redirect to (0 means don't redirect)
+
+    @Field(order = 1, type = Type.Ipv4Address)
+    public final Inet4Address local4; // The destination IPv4 address
+
+    public ClatIngress6Value(final long oif, final Inet4Address local4) {
+        this.oif = oif;
+        this.local4 = local4;
+    }
+}
diff --git a/common/src/com/android/net/module/util/bpf/Tether4Key.java b/common/src/com/android/net/module/util/bpf/Tether4Key.java
new file mode 100644
index 0000000..638576f
--- /dev/null
+++ b/common/src/com/android/net/module/util/bpf/Tether4Key.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 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
+ *
+ *      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.
+ */
+
+package com.android.net.module.util.bpf;
+
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet4Address;
+import java.net.UnknownHostException;
+import java.util.Objects;
+
+/** Key type for downstream & upstream IPv4 forwarding maps. */
+public class Tether4Key extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long iif;
+
+    @Field(order = 1, type = Type.EUI48)
+    public final MacAddress dstMac;
+
+    @Field(order = 2, type = Type.U8, padding = 1)
+    public final short l4proto;
+
+    @Field(order = 3, type = Type.ByteArray, arraysize = 4)
+    public final byte[] src4;
+
+    @Field(order = 4, type = Type.ByteArray, arraysize = 4)
+    public final byte[] dst4;
+
+    @Field(order = 5, type = Type.UBE16)
+    public final int srcPort;
+
+    @Field(order = 6, type = Type.UBE16)
+    public final int dstPort;
+
+    public Tether4Key(final long iif, @NonNull final MacAddress dstMac, final short l4proto,
+            final byte[] src4, final byte[] dst4, final int srcPort,
+            final int dstPort) {
+        Objects.requireNonNull(dstMac);
+
+        this.iif = iif;
+        this.dstMac = dstMac;
+        this.l4proto = l4proto;
+        this.src4 = src4;
+        this.dst4 = dst4;
+        this.srcPort = srcPort;
+        this.dstPort = dstPort;
+    }
+
+    @Override
+    public String toString() {
+        try {
+            return String.format(
+                    "iif: %d, dstMac: %s, l4proto: %d, src4: %s, dst4: %s, "
+                            + "srcPort: %d, dstPort: %d",
+                    iif, dstMac, l4proto,
+                    Inet4Address.getByAddress(src4), Inet4Address.getByAddress(dst4),
+                    Short.toUnsignedInt((short) srcPort), Short.toUnsignedInt((short) dstPort));
+        } catch (UnknownHostException | IllegalArgumentException e) {
+            return String.format("Invalid IP address", e);
+        }
+    }
+}
diff --git a/common/src/com/android/net/module/util/bpf/Tether4Value.java b/common/src/com/android/net/module/util/bpf/Tether4Value.java
new file mode 100644
index 0000000..de98766
--- /dev/null
+++ b/common/src/com/android/net/module/util/bpf/Tether4Value.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 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
+ *
+ *      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.
+ */
+
+package com.android.net.module.util.bpf;
+
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Objects;
+
+/** Value type for downstream & upstream IPv4 forwarding maps. */
+public class Tether4Value extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long oif;
+
+    // The ethhdr struct which is defined in uapi/linux/if_ether.h
+    @Field(order = 1, type = Type.EUI48)
+    public final MacAddress ethDstMac;
+    @Field(order = 2, type = Type.EUI48)
+    public final MacAddress ethSrcMac;
+    @Field(order = 3, type = Type.UBE16)
+    public final int ethProto;  // Packet type ID field.
+
+    @Field(order = 4, type = Type.U16)
+    public final int pmtu;
+
+    @Field(order = 5, type = Type.ByteArray, arraysize = 16)
+    public final byte[] src46;
+
+    @Field(order = 6, type = Type.ByteArray, arraysize = 16)
+    public final byte[] dst46;
+
+    @Field(order = 7, type = Type.UBE16)
+    public final int srcPort;
+
+    @Field(order = 8, type = Type.UBE16)
+    public final int dstPort;
+
+    // TODO: consider using U64.
+    @Field(order = 9, type = Type.U63)
+    public final long lastUsed;
+
+    public Tether4Value(final long oif, @NonNull final MacAddress ethDstMac,
+            @NonNull final MacAddress ethSrcMac, final int ethProto, final int pmtu,
+            final byte[] src46, final byte[] dst46, final int srcPort,
+            final int dstPort, final long lastUsed) {
+        Objects.requireNonNull(ethDstMac);
+        Objects.requireNonNull(ethSrcMac);
+
+        this.oif = oif;
+        this.ethDstMac = ethDstMac;
+        this.ethSrcMac = ethSrcMac;
+        this.ethProto = ethProto;
+        this.pmtu = pmtu;
+        this.src46 = src46;
+        this.dst46 = dst46;
+        this.srcPort = srcPort;
+        this.dstPort = dstPort;
+        this.lastUsed = lastUsed;
+    }
+
+    @Override
+    public String toString() {
+        try {
+            return String.format(
+                    "oif: %d, ethDstMac: %s, ethSrcMac: %s, ethProto: %d, pmtu: %d, "
+                            + "src46: %s, dst46: %s, srcPort: %d, dstPort: %d, "
+                            + "lastUsed: %d",
+                    oif, ethDstMac, ethSrcMac, ethProto, pmtu,
+                    InetAddress.getByAddress(src46), InetAddress.getByAddress(dst46),
+                    Short.toUnsignedInt((short) srcPort), Short.toUnsignedInt((short) dstPort),
+                    lastUsed);
+        } catch (UnknownHostException | IllegalArgumentException e) {
+            return String.format("Invalid IP address", e);
+        }
+    }
+}
diff --git a/common/src/com/android/net/module/util/bpf/TetherStatsKey.java b/common/src/com/android/net/module/util/bpf/TetherStatsKey.java
new file mode 100644
index 0000000..c6d595b
--- /dev/null
+++ b/common/src/com/android/net/module/util/bpf/TetherStatsKey.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 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
+ *
+ *      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.
+ */
+
+package com.android.net.module.util.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/** The key of BpfMap which is used for tethering stats. */
+public class TetherStatsKey extends Struct {
+    @Field(order = 0, type = Type.U32)
+    public final long ifindex;  // upstream interface index
+
+    public TetherStatsKey(final long ifindex) {
+        this.ifindex = ifindex;
+    }
+
+    // TODO: remove equals, hashCode and toString once aosp/1536721 is merged.
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherStatsKey)) return false;
+
+        final TetherStatsKey that = (TetherStatsKey) obj;
+
+        return ifindex == that.ifindex;
+    }
+
+    @Override
+    public int hashCode() {
+        return Long.hashCode(ifindex);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("ifindex: %d", ifindex);
+    }
+}
diff --git a/common/src/com/android/net/module/util/bpf/TetherStatsValue.java b/common/src/com/android/net/module/util/bpf/TetherStatsValue.java
new file mode 100644
index 0000000..028d217
--- /dev/null
+++ b/common/src/com/android/net/module/util/bpf/TetherStatsValue.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 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
+ *
+ *      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.
+ */
+
+package com.android.net.module.util.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/** The key of BpfMap which is used for tethering stats. */
+public class TetherStatsValue extends Struct {
+    // Use the signed long variable to store the uint64 stats from stats BPF map.
+    // U63 is enough for each data element even at 5Gbps for ~468 years.
+    // 2^63 / (5 * 1000 * 1000 * 1000) * 8 / 86400 / 365 = 468.
+    @Field(order = 0, type = Type.U63)
+    public final long rxPackets;
+    @Field(order = 1, type = Type.U63)
+    public final long rxBytes;
+    @Field(order = 2, type = Type.U63)
+    public final long rxErrors;
+    @Field(order = 3, type = Type.U63)
+    public final long txPackets;
+    @Field(order = 4, type = Type.U63)
+    public final long txBytes;
+    @Field(order = 5, type = Type.U63)
+    public final long txErrors;
+
+    public TetherStatsValue(final long rxPackets, final long rxBytes, final long rxErrors,
+            final long txPackets, final long txBytes, final long txErrors) {
+        this.rxPackets = rxPackets;
+        this.rxBytes = rxBytes;
+        this.rxErrors = rxErrors;
+        this.txPackets = txPackets;
+        this.txBytes = txBytes;
+        this.txErrors = txErrors;
+    }
+
+    // TODO: remove equals, hashCode and toString once aosp/1536721 is merged.
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof TetherStatsValue)) return false;
+
+        final TetherStatsValue that = (TetherStatsValue) obj;
+
+        return rxPackets == that.rxPackets
+                && rxBytes == that.rxBytes
+                && rxErrors == that.rxErrors
+                && txPackets == that.txPackets
+                && txBytes == that.txBytes
+                && txErrors == that.txErrors;
+    }
+
+    @Override
+    public int hashCode() {
+        return Long.hashCode(rxPackets) ^ Long.hashCode(rxBytes) ^ Long.hashCode(rxErrors)
+                ^ Long.hashCode(txPackets) ^ Long.hashCode(txBytes) ^ Long.hashCode(txErrors);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("rxPackets: %s, rxBytes: %s, rxErrors: %s, txPackets: %s, "
+                + "txBytes: %s, txErrors: %s", rxPackets, rxBytes, rxErrors, txPackets,
+                txBytes, txErrors);
+    }
+}
diff --git a/framework/Android.bp b/framework/Android.bp
index 24d8cca..6350e14 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -92,6 +92,7 @@
         "framework-connectivity-javastream-protos",
     ],
     libs: [
+        "androidx.annotation_annotation",
         "app-compat-annotations",
         "framework-connectivity-t.stubs.module_lib",
         "unsupportedappusage",
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 39cd7f3..eeedfd1 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -5903,6 +5903,7 @@
      *
      * @param chain target chain.
      * @param enable whether the chain should be enabled.
+     * @throws UnsupportedOperationException if called on pre-T devices.
      * @throws IllegalStateException if enabling or disabling the firewall chain failed.
      * @hide
      */
@@ -5921,6 +5922,29 @@
     }
 
     /**
+     * Get the specified firewall chain's status.
+     *
+     * @param chain target chain.
+     * @return {@code true} if chain is enabled, {@code false} if chain is disabled.
+     * @throws UnsupportedOperationException if called on pre-T devices.
+     * @throws ServiceSpecificException in case of failure, with an error code indicating the
+     *                                  cause of the failure.
+     * @hide
+     */
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_STACK,
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
+    })
+    public boolean getFirewallChainEnabled(@FirewallChain final int chain) {
+        try {
+            return mService.getFirewallChainEnabled(chain);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Replaces the contents of the specified UID-based firewall chain.
      *
      * @param chain target chain to replace.
diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl
index bc73769..29fea00 100644
--- a/framework/src/android/net/IConnectivityManager.aidl
+++ b/framework/src/android/net/IConnectivityManager.aidl
@@ -244,5 +244,7 @@
 
     void setFirewallChainEnabled(int chain, boolean enable);
 
+    boolean getFirewallChainEnabled(int chain);
+
     void replaceFirewallChain(int chain, in int[] uids);
 }
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index 97b1f32..dbb05a9 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -3043,7 +3043,7 @@
          * <p>
          * This list cannot be null, but it can be empty to mean that no UID without the
          * {@link android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS} permission
-         * gets to access this network.
+         * can access this network.
          *
          * @param uids the list of UIDs that can always access this network
          * @return this builder
diff --git a/framework/src/android/net/TestNetworkManager.java b/framework/src/android/net/TestNetworkManager.java
index 7b18765..9cae9e6 100644
--- a/framework/src/android/net/TestNetworkManager.java
+++ b/framework/src/android/net/TestNetworkManager.java
@@ -236,6 +236,8 @@
     /**
      * Create a tap interface with or without carrier for testing purposes.
      *
+     * Note: setting carrierUp = false is not supported until kernel version 5.0.
+     *
      * @param carrierUp whether the created interface has a carrier or not.
      * @param bringUp whether to bring up the interface before returning it.
      * @hide
@@ -254,7 +256,6 @@
      * Enable / disable carrier on TestNetworkInterface
      *
      * Note: TUNSETCARRIER is not supported until kernel version 5.0.
-     * TODO: add RequiresApi annotation.
      *
      * @param iface the interface to configure.
      * @param enabled true to turn carrier on, false to turn carrier off.
diff --git a/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java b/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
index c4ea9ae..cedffe1 100644
--- a/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
+++ b/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
@@ -60,7 +60,9 @@
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * {@link NetworkProvider} that manages NetworkOffers for Ethernet networks.
+ * Class that manages NetworkOffers for Ethernet networks.
+ *
+ * TODO: this class should be merged into EthernetTracker.
  */
 public class EthernetNetworkFactory {
     private final static String TAG = EthernetNetworkFactory.class.getSimpleName();
@@ -221,11 +223,17 @@
     }
 
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    protected void removeInterface(String interfaceName) {
+    protected boolean removeInterface(String interfaceName) {
         NetworkInterfaceState iface = mTrackingInterfaces.remove(interfaceName);
         if (iface != null) {
-            iface.destroy();
+            iface.unregisterNetworkOfferAndStop();
+            return true;
         }
+        // TODO(b/236892130): if an interface is currently in server mode, it may not be properly
+        // removed.
+        // TODO: when false is returned, do not send a STATE_ABSENT callback.
+        Log.w(TAG, interfaceName + " is not tracked and cannot be removed");
+        return false;
     }
 
     /** Returns true if state has been modified */
@@ -292,7 +300,7 @@
         private boolean mLinkUp;
         private int mLegacyType;
         private LinkProperties mLinkProperties = new LinkProperties();
-        private Set<NetworkRequest> mRequests = new ArraySet<>();
+        private final Set<Integer> mRequestIds = new ArraySet<>();
 
         private volatile @Nullable IpClientManager mIpClient;
         private @NonNull NetworkCapabilities mCapabilities;
@@ -401,7 +409,7 @@
                 // existing requests.
                 // ConnectivityService filters requests for us based on the NetworkCapabilities
                 // passed in the registerNetworkOffer() call.
-                mRequests.add(request);
+                mRequestIds.add(request.requestId);
                 // if the network is already started, this is a no-op.
                 start();
             }
@@ -412,8 +420,12 @@
                     Log.d(TAG,
                             String.format("%s: onNetworkUnneeded for request: %s", name, request));
                 }
-                mRequests.remove(request);
-                if (mRequests.isEmpty()) {
+                if (!mRequestIds.remove(request.requestId)) {
+                    // This can only happen if onNetworkNeeded was not called for a request or if
+                    // the requestId changed. Both should *never* happen.
+                    Log.wtf(TAG, "onNetworkUnneeded called for unknown request");
+                }
+                if (mRequestIds.isEmpty()) {
                     // not currently serving any requests, stop the network.
                     stop();
                 }
@@ -454,7 +466,7 @@
                     + "transport type.");
         }
 
-        private static NetworkScore getBestNetworkScore() {
+        private static NetworkScore getNetworkScore() {
             return new NetworkScore.Builder().build();
         }
 
@@ -465,9 +477,7 @@
             if (mLinkUp) {
                 // registering a new network offer will update the existing one, not install a
                 // new one.
-                mNetworkProvider.registerNetworkOffer(getBestNetworkScore(),
-                        new NetworkCapabilities(capabilities), cmd -> mHandler.post(cmd),
-                        mNetworkOfferCallback);
+                registerNetworkOffer();
             }
         }
 
@@ -629,14 +639,12 @@
 
             if (!up) { // was up, goes down
                 // retract network offer and stop IpClient.
-                destroy();
+                unregisterNetworkOfferAndStop();
                 // If only setting the interface down, send a callback to signal completion.
                 EthernetNetworkFactory.maybeSendNetworkManagementCallback(listener, name, null);
             } else { // was down, goes up
                 // register network offer
-                mNetworkProvider.registerNetworkOffer(getBestNetworkScore(),
-                        new NetworkCapabilities(mCapabilities), (cmd) -> mHandler.post(cmd),
-                        mNetworkOfferCallback);
+                registerNetworkOffer();
             }
 
             return true;
@@ -660,10 +668,16 @@
             mLinkProperties.clear();
         }
 
-        public void destroy() {
+        private void registerNetworkOffer() {
+            mNetworkProvider.registerNetworkOffer(getNetworkScore(),
+                    new NetworkCapabilities(mCapabilities), cmd -> mHandler.post(cmd),
+                    mNetworkOfferCallback);
+        }
+
+        public void unregisterNetworkOfferAndStop() {
             mNetworkProvider.unregisterNetworkOffer(mNetworkOfferCallback);
             stop();
-            mRequests.clear();
+            mRequestIds.clear();
         }
 
         private static void provisionIpClient(@NonNull final IpClientManager ipClient,
diff --git a/service/Android.bp b/service/Android.bp
index 45e43bc..7a4fb33 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -158,6 +158,7 @@
     static_libs: [
         // Do not add libs here if they are already included
         // in framework-connectivity
+        "connectivity-net-module-utils-bpf",
         "connectivity_native_aidl_interface-lateststable-java",
         "dnsresolver_aidl_interface-V9-java",
         "modules-utils-shell-command-handler",
@@ -181,6 +182,25 @@
     ],
 }
 
+// TODO: Remove this temporary library and put code into module when test coverage is enough.
+java_library {
+    name: "service-mdns",
+    sdk_version: "system_server_current",
+    min_sdk_version: "30",
+    srcs: [
+        "mdns/**/*.java",
+    ],
+    libs: [
+        "framework-annotations-lib",
+        "framework-connectivity-pre-jarjar",
+        "framework-wifi.stubs.module_lib",
+        "service-connectivity-pre-jarjar",
+    ],
+    visibility: [
+        "//packages/modules/Connectivity/tests:__subpackages__",
+    ],
+}
+
 java_library {
     name: "service-connectivity-protos",
     sdk_version: "system_current",
diff --git a/service/jni/com_android_server_BpfNetMaps.cpp b/service/jni/com_android_server_BpfNetMaps.cpp
index 2780044..49392e0 100644
--- a/service/jni/com_android_server_BpfNetMaps.cpp
+++ b/service/jni/com_android_server_BpfNetMaps.cpp
@@ -82,13 +82,6 @@
   return (jint)status.code();
 }
 
-static jint native_setChildChain(JNIEnv* env, jobject self, jint childChain, jboolean enable) {
-  auto chain = static_cast<ChildChain>(childChain);
-  int res = mTc.toggleUidOwnerMap(chain, enable);
-  if (res) ALOGE("%s failed, error code = %d", __func__, res);
-  return (jint)res;
-}
-
 static jint native_replaceUidChain(JNIEnv* env, jobject self, jstring name, jboolean isAllowlist,
                                    jintArray jUids) {
     const ScopedUtfChars chainNameUtf8(env, name);
@@ -199,8 +192,6 @@
     (void*)native_addNiceApp},
     {"native_removeNiceApp", "(I)I",
     (void*)native_removeNiceApp},
-    {"native_setChildChain", "(IZ)I",
-    (void*)native_setChildChain},
     {"native_replaceUidChain", "(Ljava/lang/String;Z[I)I",
     (void*)native_replaceUidChain},
     {"native_setUidRule", "(III)I",
diff --git a/service/mdns/com/android/server/connectivity/mdns/ConnectivityMonitor.java b/service/mdns/com/android/server/connectivity/mdns/ConnectivityMonitor.java
new file mode 100644
index 0000000..2b99d0a
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/ConnectivityMonitor.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+/** Interface for monitoring connectivity changes. */
+public interface ConnectivityMonitor {
+    /**
+     * Starts monitoring changes of connectivity of this device, which may indicate that the list of
+     * network interfaces available for multi-cast messaging has changed.
+     */
+    void startWatchingConnectivityChanges();
+
+    /** Stops monitoring changes of connectivity. */
+    void stopWatchingConnectivityChanges();
+
+    void notifyConnectivityChange();
+
+    /** Listener interface for receiving connectivity changes. */
+    interface Listener {
+        void onConnectivityChanged();
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/ConnectivityMonitorWithConnectivityManager.java b/service/mdns/com/android/server/connectivity/mdns/ConnectivityMonitorWithConnectivityManager.java
new file mode 100644
index 0000000..3563d61
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/ConnectivityMonitorWithConnectivityManager.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.os.Build;
+
+import com.android.server.connectivity.mdns.util.MdnsLogger;
+
+/** Class for monitoring connectivity changes using {@link ConnectivityManager}. */
+public class ConnectivityMonitorWithConnectivityManager implements ConnectivityMonitor {
+    private static final String TAG = "ConnMntrWConnMgr";
+    private static final MdnsLogger LOGGER = new MdnsLogger(TAG);
+
+    private final Listener listener;
+    private final ConnectivityManager.NetworkCallback networkCallback;
+    private final ConnectivityManager connectivityManager;
+    // TODO(b/71901993): Ideally we shouldn't need this flag. However we still don't have clues why
+    // the receiver is unregistered twice yet.
+    private boolean isCallbackRegistered = false;
+
+    @SuppressWarnings({"nullness:assignment", "nullness:method.invocation"})
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    public ConnectivityMonitorWithConnectivityManager(Context context, Listener listener) {
+        this.listener = listener;
+
+        connectivityManager =
+                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        networkCallback =
+                new ConnectivityManager.NetworkCallback() {
+                    @Override
+                    public void onAvailable(Network network) {
+                        LOGGER.log("network available.");
+                        notifyConnectivityChange();
+                    }
+
+                    @Override
+                    public void onLost(Network network) {
+                        LOGGER.log("network lost.");
+                        notifyConnectivityChange();
+                    }
+
+                    @Override
+                    public void onUnavailable() {
+                        LOGGER.log("network unavailable.");
+                        notifyConnectivityChange();
+                    }
+                };
+    }
+
+    @Override
+    public void notifyConnectivityChange() {
+        listener.onConnectivityChanged();
+    }
+
+    /**
+     * Starts monitoring changes of connectivity of this device, which may indicate that the list of
+     * network interfaces available for multi-cast messaging has changed.
+     */
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    @Override
+    public void startWatchingConnectivityChanges() {
+        LOGGER.log("Start watching connectivity changes");
+        if (isCallbackRegistered) {
+            return;
+        }
+
+        connectivityManager.registerNetworkCallback(
+                new NetworkRequest.Builder().addTransportType(
+                        NetworkCapabilities.TRANSPORT_WIFI).build(),
+                networkCallback);
+        isCallbackRegistered = true;
+    }
+
+    /** Stops monitoring changes of connectivity. */
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    @Override
+    public void stopWatchingConnectivityChanges() {
+        LOGGER.log("Stop watching connectivity changes");
+        if (!isCallbackRegistered) {
+            return;
+        }
+
+        connectivityManager.unregisterNetworkCallback(networkCallback);
+        isCallbackRegistered = false;
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java b/service/mdns/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java
new file mode 100644
index 0000000..3db1b22
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/EnqueueMdnsQueryCallable.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.annotation.NonNull;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import com.android.server.connectivity.mdns.util.MdnsLogger;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * A {@link Callable} that builds and enqueues a mDNS query to send over the multicast socket. If a
+ * query is built and enqueued successfully, then call to {@link #call()} returns the transaction ID
+ * and the list of the subtypes in the query as a {@link Pair}. If a query is failed to build, or if
+ * it can not be enqueued, then call to {@link #call()} returns {@code null}.
+ */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+public class EnqueueMdnsQueryCallable implements Callable<Pair<Integer, List<String>>> {
+
+    private static final String TAG = "MdnsQueryCallable";
+    private static final MdnsLogger LOGGER = new MdnsLogger(TAG);
+    private static final List<Integer> castShellEmulatorMdnsPorts;
+
+    static {
+        castShellEmulatorMdnsPorts = new ArrayList<>();
+        String[] stringPorts = MdnsConfigs.castShellEmulatorMdnsPorts();
+
+        for (String port : stringPorts) {
+            try {
+                castShellEmulatorMdnsPorts.add(Integer.parseInt(port));
+            } catch (NumberFormatException e) {
+                // Ignore.
+            }
+        }
+    }
+
+    private final WeakReference<MdnsSocketClient> weakRequestSender;
+    private final MdnsPacketWriter packetWriter;
+    private final String[] serviceTypeLabels;
+    private final List<String> subtypes;
+    private final boolean expectUnicastResponse;
+    private final int transactionId;
+
+    EnqueueMdnsQueryCallable(
+            @NonNull MdnsSocketClient requestSender,
+            @NonNull MdnsPacketWriter packetWriter,
+            @NonNull String serviceType,
+            @NonNull Collection<String> subtypes,
+            boolean expectUnicastResponse,
+            int transactionId) {
+        weakRequestSender = new WeakReference<>(requestSender);
+        this.packetWriter = packetWriter;
+        serviceTypeLabels = TextUtils.split(serviceType, "\\.");
+        this.subtypes = new ArrayList<>(subtypes);
+        this.expectUnicastResponse = expectUnicastResponse;
+        this.transactionId = transactionId;
+    }
+
+    @Override
+    public Pair<Integer, List<String>> call() {
+        try {
+            MdnsSocketClient requestSender = weakRequestSender.get();
+            if (requestSender == null) {
+                return null;
+            }
+
+            int numQuestions = 1;
+            if (!subtypes.isEmpty()) {
+                numQuestions += subtypes.size();
+            }
+
+            // Header.
+            packetWriter.writeUInt16(transactionId); // transaction ID
+            packetWriter.writeUInt16(MdnsConstants.FLAGS_QUERY); // flags
+            packetWriter.writeUInt16(numQuestions); // number of questions
+            packetWriter.writeUInt16(0); // number of answers (not yet known; will be written later)
+            packetWriter.writeUInt16(0); // number of authority entries
+            packetWriter.writeUInt16(0); // number of additional records
+
+            // Question(s). There will be one question for each (fqdn+subtype, recordType)
+          // combination,
+            // as well as one for each (fqdn, recordType) combination.
+
+            for (String subtype : subtypes) {
+                String[] labels = new String[serviceTypeLabels.length + 2];
+                labels[0] = MdnsConstants.SUBTYPE_PREFIX + subtype;
+                labels[1] = MdnsConstants.SUBTYPE_LABEL;
+                System.arraycopy(serviceTypeLabels, 0, labels, 2, serviceTypeLabels.length);
+
+                packetWriter.writeLabels(labels);
+                packetWriter.writeUInt16(MdnsRecord.TYPE_PTR);
+                packetWriter.writeUInt16(
+                        MdnsConstants.QCLASS_INTERNET
+                                | (expectUnicastResponse ? MdnsConstants.QCLASS_UNICAST : 0));
+            }
+
+            packetWriter.writeLabels(serviceTypeLabels);
+            packetWriter.writeUInt16(MdnsRecord.TYPE_PTR);
+            packetWriter.writeUInt16(
+                    MdnsConstants.QCLASS_INTERNET
+                            | (expectUnicastResponse ? MdnsConstants.QCLASS_UNICAST : 0));
+
+            InetAddress mdnsAddress = MdnsConstants.getMdnsIPv4Address();
+            if (requestSender.isOnIPv6OnlyNetwork()) {
+                mdnsAddress = MdnsConstants.getMdnsIPv6Address();
+            }
+
+            sendPacketTo(requestSender,
+                    new InetSocketAddress(mdnsAddress, MdnsConstants.MDNS_PORT));
+            for (Integer emulatorPort : castShellEmulatorMdnsPorts) {
+                sendPacketTo(requestSender, new InetSocketAddress(mdnsAddress, emulatorPort));
+            }
+            return Pair.create(transactionId, subtypes);
+        } catch (IOException e) {
+            LOGGER.e(String.format("Failed to create mDNS packet for subtype: %s.",
+                    TextUtils.join(",", subtypes)), e);
+            return null;
+        }
+    }
+
+    private void sendPacketTo(MdnsSocketClient requestSender, InetSocketAddress address)
+            throws IOException {
+        DatagramPacket packet = packetWriter.getPacket(address);
+        if (expectUnicastResponse) {
+            requestSender.sendUnicastPacket(packet);
+        } else {
+            requestSender.sendMulticastPacket(packet);
+        }
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/ExecutorProvider.java b/service/mdns/com/android/server/connectivity/mdns/ExecutorProvider.java
new file mode 100644
index 0000000..72b65e0
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/ExecutorProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.util.ArraySet;
+
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+
+/**
+ * This class provides {@link ScheduledExecutorService} instances to {@link MdnsServiceTypeClient}
+ * instances, and provides method to shutdown all the created executors.
+ */
+public class ExecutorProvider {
+
+    private final Set<ScheduledExecutorService> serviceTypeClientSchedulerExecutors =
+            new ArraySet<>();
+
+    /** Returns a new {@link ScheduledExecutorService} instance. */
+    public ScheduledExecutorService newServiceTypeClientSchedulerExecutor() {
+        // TODO: actually use a pool ?
+        ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1);
+        serviceTypeClientSchedulerExecutors.add(executor);
+        return executor;
+    }
+
+    /** Shuts down all the created {@link ScheduledExecutorService} instances. */
+    public void shutdownAll() {
+        for (ScheduledExecutorService executor : serviceTypeClientSchedulerExecutors) {
+            executor.shutdownNow();
+        }
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java b/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java
new file mode 100644
index 0000000..922037b
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+/**
+ * mDNS configuration values.
+ *
+ * TODO: consider making some of these adjustable via flags.
+ */
+public class MdnsConfigs {
+    public static String[] castShellEmulatorMdnsPorts() {
+        return new String[0];
+    }
+
+    public static long initialTimeBetweenBurstsMs() {
+        return 5000L;
+    }
+
+    public static long timeBetweenBurstsMs() {
+        return 20_000L;
+    }
+
+    public static int queriesPerBurst() {
+        return 3;
+    }
+
+    public static long timeBetweenQueriesInBurstMs() {
+        return 1000L;
+    }
+
+    public static int queriesPerBurstPassive() {
+        return 1;
+    }
+
+    public static boolean alwaysAskForUnicastResponseInEachBurst() {
+        return false;
+    }
+
+    public static boolean useSessionIdToScheduleMdnsTask() {
+        return false;
+    }
+
+    public static boolean shouldCancelScanTaskWhenFutureIsNull() {
+        return false;
+    }
+
+    public static long sleepTimeForSocketThreadMs() {
+        return 20_000L;
+    }
+
+    public static boolean checkMulticastResponse() {
+        return false;
+    }
+
+    public static boolean useSeparateSocketToSendUnicastQuery() {
+        return false;
+    }
+
+    public static long checkMulticastResponseIntervalMs() {
+        return 10_000L;
+    }
+
+    public static boolean clearMdnsPacketQueueAfterDiscoveryStops() {
+        return true;
+    }
+
+    public static boolean allowAddMdnsPacketAfterDiscoveryStops() {
+        return false;
+    }
+
+    public static int mdnsPacketQueueMaxSize() {
+        return Integer.MAX_VALUE;
+    }
+
+    public static boolean preferIpv6() {
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsConstants.java b/service/mdns/com/android/server/connectivity/mdns/MdnsConstants.java
new file mode 100644
index 0000000..ed28700
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsConstants.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+/** mDNS-related constants. */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+@VisibleForTesting
+public final class MdnsConstants {
+    public static final int MDNS_PORT = 5353;
+    // Flags word format is:
+    // 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+    // QR [ Opcode  ] AA TC RD RA  Z AD CD [  Rcode  ]
+    // See http://www.networksorcery.com/enp/protocol/dns.htm
+    // For responses, QR bit should be 1, AA - CD bits should be ignored, and all other bits
+    // should be 0.
+    public static final int FLAGS_QUERY = 0x0000;
+    public static final int FLAGS_RESPONSE_MASK = 0xF80F;
+    public static final int FLAGS_RESPONSE = 0x8000;
+    public static final int QCLASS_INTERNET = 0x0001;
+    public static final int QCLASS_UNICAST = 0x8000;
+    public static final String SUBTYPE_LABEL = "_sub";
+    public static final String SUBTYPE_PREFIX = "_";
+    private static final String MDNS_IPV4_HOST_ADDRESS = "224.0.0.251";
+    private static final String MDNS_IPV6_HOST_ADDRESS = "FF02::FB";
+    private static InetAddress mdnsAddress;
+    private static Charset utf8Charset;
+    private MdnsConstants() {
+    }
+
+    public static InetAddress getMdnsIPv4Address() {
+        synchronized (MdnsConstants.class) {
+            InetAddress addr = null;
+            try {
+                addr = InetAddress.getByName(MDNS_IPV4_HOST_ADDRESS);
+            } catch (UnknownHostException e) {
+                /* won't happen */
+            }
+            mdnsAddress = addr;
+            return mdnsAddress;
+        }
+    }
+
+    public static InetAddress getMdnsIPv6Address() {
+        synchronized (MdnsConstants.class) {
+            InetAddress addr = null;
+            try {
+                addr = InetAddress.getByName(MDNS_IPV6_HOST_ADDRESS);
+            } catch (UnknownHostException e) {
+                /* won't happen */
+            }
+            mdnsAddress = addr;
+            return mdnsAddress;
+        }
+    }
+
+    public static Charset getUtf8Charset() {
+        synchronized (MdnsConstants.class) {
+            if (utf8Charset == null) {
+                utf8Charset = getUtf8CharsetOnKitKat();
+            }
+            return utf8Charset;
+        }
+    }
+
+    @TargetApi(Build.VERSION_CODES.KITKAT)
+    private static Charset getUtf8CharsetOnKitKat() {
+        return StandardCharsets.UTF_8;
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java b/service/mdns/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
new file mode 100644
index 0000000..1faa6ce
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.Manifest.permission;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.connectivity.mdns.util.MdnsLogger;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ * This class keeps tracking the set of registered {@link MdnsServiceBrowserListener} instances, and
+ * notify them when a mDNS service instance is found, updated, or removed?
+ */
+public class MdnsDiscoveryManager implements MdnsSocketClient.Callback {
+
+    private static final MdnsLogger LOGGER = new MdnsLogger("MdnsDiscoveryManager");
+
+    private final ExecutorProvider executorProvider;
+    private final MdnsSocketClient socketClient;
+
+    private final Map<String, MdnsServiceTypeClient> serviceTypeClients = new ArrayMap<>();
+
+    public MdnsDiscoveryManager(
+            @NonNull ExecutorProvider executorProvider, @NonNull MdnsSocketClient socketClient) {
+        this.executorProvider = executorProvider;
+        this.socketClient = socketClient;
+    }
+
+    /**
+     * Starts (or continue) to discovery mDNS services with given {@code serviceType}, and registers
+     * {@code listener} for receiving mDNS service discovery responses.
+     *
+     * @param serviceType   The type of the service to discover.
+     * @param listener      The {@link MdnsServiceBrowserListener} listener.
+     * @param searchOptions The {@link MdnsSearchOptions} to be used for discovering {@code
+     *                      serviceType}.
+     */
+    @RequiresPermission(permission.CHANGE_WIFI_MULTICAST_STATE)
+    public synchronized void registerListener(
+            @NonNull String serviceType,
+            @NonNull MdnsServiceBrowserListener listener,
+            @NonNull MdnsSearchOptions searchOptions) {
+        LOGGER.log(
+                "Registering listener for subtypes: %s",
+                TextUtils.join(",", searchOptions.getSubtypes()));
+        if (serviceTypeClients.isEmpty()) {
+            // First listener. Starts the socket client.
+            try {
+                socketClient.startDiscovery();
+            } catch (IOException e) {
+                LOGGER.e("Failed to start discover.", e);
+                return;
+            }
+        }
+        // All listeners of the same service types shares the same MdnsServiceTypeClient.
+        MdnsServiceTypeClient serviceTypeClient = serviceTypeClients.get(serviceType);
+        if (serviceTypeClient == null) {
+            serviceTypeClient = createServiceTypeClient(serviceType);
+            serviceTypeClients.put(serviceType, serviceTypeClient);
+        }
+        serviceTypeClient.startSendAndReceive(listener, searchOptions);
+    }
+
+    /**
+     * Unregister {@code listener} for receiving mDNS service discovery responses. IF no listener is
+     * registered for the given service type, stops discovery for the service type.
+     *
+     * @param serviceType The type of the service to discover.
+     * @param listener    The {@link MdnsServiceBrowserListener} listener.
+     */
+    @RequiresPermission(permission.CHANGE_WIFI_MULTICAST_STATE)
+    public synchronized void unregisterListener(
+            @NonNull String serviceType, @NonNull MdnsServiceBrowserListener listener) {
+        LOGGER.log("Unregistering listener for service type: %s", serviceType);
+        MdnsServiceTypeClient serviceTypeClient = serviceTypeClients.get(serviceType);
+        if (serviceTypeClient == null) {
+            return;
+        }
+        if (serviceTypeClient.stopSendAndReceive(listener)) {
+            // No listener is registered for the service type anymore, remove it from the list of
+          // the
+            // service type clients.
+            serviceTypeClients.remove(serviceType);
+            if (serviceTypeClients.isEmpty()) {
+                // No discovery request. Stops the socket client.
+                socketClient.stopDiscovery();
+            }
+        }
+    }
+
+    @Override
+    public synchronized void onResponseReceived(@NonNull MdnsResponse response) {
+        String[] name =
+                response.getPointerRecords().isEmpty()
+                        ? null
+                        : response.getPointerRecords().get(0).getName();
+        if (name != null) {
+            for (MdnsServiceTypeClient serviceTypeClient : serviceTypeClients.values()) {
+                String[] serviceType = serviceTypeClient.getServiceTypeLabels();
+                if ((Arrays.equals(name, serviceType)
+                        || ((name.length == (serviceType.length + 2))
+                        && name[1].equals(MdnsConstants.SUBTYPE_LABEL)
+                        && MdnsRecord.labelsAreSuffix(serviceType, name)))) {
+                    serviceTypeClient.processResponse(response);
+                    return;
+                }
+            }
+        }
+    }
+
+    @Override
+    public synchronized void onFailedToParseMdnsResponse(int receivedPacketNumber, int errorCode) {
+        for (MdnsServiceTypeClient serviceTypeClient : serviceTypeClients.values()) {
+            serviceTypeClient.onFailedToParseMdnsResponse(receivedPacketNumber, errorCode);
+        }
+    }
+
+    @VisibleForTesting
+    MdnsServiceTypeClient createServiceTypeClient(@NonNull String serviceType) {
+        return new MdnsServiceTypeClient(
+                serviceType, socketClient,
+                executorProvider.newServiceTypeClientSchedulerExecutor());
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java
new file mode 100644
index 0000000..e35743c
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Locale;
+import java.util.Objects;
+
+/** An mDNS "AAAA" or "A" record, which holds an IPv6 or IPv4 address. */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+@VisibleForTesting
+public class MdnsInetAddressRecord extends MdnsRecord {
+    private Inet6Address inet6Address;
+    private Inet4Address inet4Address;
+
+    /**
+     * Constructs the {@link MdnsRecord}
+     *
+     * @param name   the service host name
+     * @param type   the type of record (either Type 'AAAA' or Type 'A')
+     * @param reader the reader to read the record from.
+     */
+    public MdnsInetAddressRecord(String[] name, int type, MdnsPacketReader reader)
+            throws IOException {
+        super(name, type, reader);
+    }
+
+    /** Returns the IPv6 address. */
+    public Inet6Address getInet6Address() {
+        return inet6Address;
+    }
+
+    /** Returns the IPv4 address. */
+    public Inet4Address getInet4Address() {
+        return inet4Address;
+    }
+
+    @Override
+    protected void readData(MdnsPacketReader reader) throws IOException {
+        int size = 4;
+        if (super.getType() == MdnsRecord.TYPE_AAAA) {
+            size = 16;
+        }
+        byte[] buf = new byte[size];
+        reader.readBytes(buf);
+        try {
+            InetAddress address = InetAddress.getByAddress(buf);
+            if (address instanceof Inet4Address) {
+                inet4Address = (Inet4Address) address;
+                inet6Address = null;
+            } else if (address instanceof Inet6Address) {
+                inet4Address = null;
+                inet6Address = (Inet6Address) address;
+            } else {
+                inet4Address = null;
+                inet6Address = null;
+            }
+        } catch (UnknownHostException e) {
+            // Ignore exception
+        }
+    }
+
+    @Override
+    protected void writeData(MdnsPacketWriter writer) throws IOException {
+        byte[] buf = null;
+        if (inet4Address != null) {
+            buf = inet4Address.getAddress();
+        } else if (inet6Address != null) {
+            buf = inet6Address.getAddress();
+        }
+        if (buf != null) {
+            writer.writeBytes(buf);
+        }
+    }
+
+    @Override
+    public String toString() {
+        String type = "AAAA";
+        if (super.getType() == MdnsRecord.TYPE_A) {
+            type = "A";
+        }
+        return String.format(
+                Locale.ROOT, "%s: Inet4Address: %s Inet6Address: %s", type, inet4Address,
+                inet6Address);
+    }
+
+    @Override
+    public int hashCode() {
+        return (super.hashCode() * 31)
+                + Objects.hashCode(inet4Address)
+                + Objects.hashCode(inet6Address);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof MdnsInetAddressRecord)) {
+            return false;
+        }
+
+        return super.equals(other)
+                && Objects.equals(inet4Address, ((MdnsInetAddressRecord) other).inet4Address)
+                && Objects.equals(inet6Address, ((MdnsInetAddressRecord) other).inet6Address);
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsPacketReader.java b/service/mdns/com/android/server/connectivity/mdns/MdnsPacketReader.java
new file mode 100644
index 0000000..61c5f5a
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsPacketReader.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.util.SparseArray;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/** Simple decoder for mDNS packets. */
+public class MdnsPacketReader {
+    private final byte[] buf;
+    private final int count;
+    private final SparseArray<LabelEntry> labelDictionary;
+    private int pos;
+    private int limit;
+
+    /** Constructs a reader for the given packet. */
+    public MdnsPacketReader(DatagramPacket packet) {
+        buf = packet.getData();
+        count = packet.getLength();
+        pos = 0;
+        limit = -1;
+        labelDictionary = new SparseArray<>(16);
+    }
+
+    /**
+     * Sets a temporary limit (from the current read position) for subsequent reads. Any attempt to
+     * read past this limit will result in an EOFException.
+     *
+     * @param limit The new limit.
+     * @throws IOException If there is insufficient data for the new limit.
+     */
+    public void setLimit(int limit) throws IOException {
+        if (limit >= 0) {
+            if (pos + limit <= count) {
+                this.limit = pos + limit;
+            } else {
+                throw new IOException(
+                        String.format(
+                                Locale.ROOT,
+                                "attempt to set limit beyond available data: %d exceeds %d",
+                                pos + limit,
+                                count));
+            }
+        }
+    }
+
+    /** Clears the limit set by {@link #setLimit}. */
+    public void clearLimit() {
+        limit = -1;
+    }
+
+    /**
+     * Returns the number of bytes left to read, between the current read position and either the
+     * limit (if set) or the end of the packet.
+     */
+    public int getRemaining() {
+        return (limit >= 0 ? limit : count) - pos;
+    }
+
+    /**
+     * Reads an unsigned 8-bit integer.
+     *
+     * @throws EOFException If there are not enough bytes remaining in the packet to satisfy the
+     *                      read.
+     */
+    public int readUInt8() throws EOFException {
+        checkRemaining(1);
+        byte val = buf[pos++];
+        return val & 0xFF;
+    }
+
+    /**
+     * Reads an unsigned 16-bit integer.
+     *
+     * @throws EOFException If there are not enough bytes remaining in the packet to satisfy the
+     *                      read.
+     */
+    public int readUInt16() throws EOFException {
+        checkRemaining(2);
+        int val = (buf[pos++] & 0xFF) << 8;
+        val |= (buf[pos++]) & 0xFF;
+        return val;
+    }
+
+    /**
+     * Reads an unsigned 32-bit integer.
+     *
+     * @throws EOFException If there are not enough bytes remaining in the packet to satisfy the
+     *                      read.
+     */
+    public long readUInt32() throws EOFException {
+        checkRemaining(4);
+        long val = (long) (buf[pos++] & 0xFF) << 24;
+        val |= (long) (buf[pos++] & 0xFF) << 16;
+        val |= (long) (buf[pos++] & 0xFF) << 8;
+        val |= buf[pos++] & 0xFF;
+        return val;
+    }
+
+    /**
+     * Reads a sequence of labels and returns them as an array of strings. A sequence of labels is
+     * either a sequence of strings terminated by a NUL byte, a sequence of strings terminated by a
+     * pointer, or a pointer.
+     *
+     * @throws EOFException If there are not enough bytes remaining in the packet to satisfy the
+     *                      read.
+     * @throws IOException  If invalid data is read.
+     */
+    public String[] readLabels() throws IOException {
+        List<String> result = new ArrayList<>(5);
+        LabelEntry previousEntry = null;
+
+        while (getRemaining() > 0) {
+            byte nextByte = peekByte();
+
+            if (nextByte == 0) {
+                // A NUL byte terminates a sequence of labels.
+                skip(1);
+                break;
+            }
+
+            int currentOffset = pos;
+
+            boolean isLabelPointer = (nextByte & 0xC0) == 0xC0;
+            if (isLabelPointer) {
+                // A pointer terminates a sequence of labels. Store the pointer value in the
+                // previous label entry.
+                int labelOffset = ((readUInt8() & 0x3F) << 8) | (readUInt8() & 0xFF);
+                if (previousEntry != null) {
+                    previousEntry.nextOffset = labelOffset;
+                }
+
+                // Follow the chain of labels starting at this pointer, adding all of them onto the
+                // result.
+                while (labelOffset != 0) {
+                    LabelEntry entry = labelDictionary.get(labelOffset);
+                    if (entry == null) {
+                        throw new IOException(
+                                String.format(Locale.ROOT, "Invalid label pointer: %04X",
+                                        labelOffset));
+                    }
+                    result.add(entry.label);
+                    labelOffset = entry.nextOffset;
+                }
+                break;
+            } else {
+                // It's an ordinary label. Chain it onto the previous label entry (if any), and add
+                // it onto the result.
+                String val = readString();
+                LabelEntry newEntry = new LabelEntry(val);
+                labelDictionary.put(currentOffset, newEntry);
+
+                if (previousEntry != null) {
+                    previousEntry.nextOffset = currentOffset;
+                }
+                previousEntry = newEntry;
+                result.add(val);
+            }
+        }
+
+        return result.toArray(new String[result.size()]);
+    }
+
+    /**
+     * Reads a length-prefixed string.
+     *
+     * @throws EOFException If there are not enough bytes remaining in the packet to satisfy the
+     *                      read.
+     */
+    public String readString() throws EOFException {
+        int len = readUInt8();
+        checkRemaining(len);
+        String val = new String(buf, pos, len, MdnsConstants.getUtf8Charset());
+        pos += len;
+        return val;
+    }
+
+    /**
+     * Reads a specific number of bytes.
+     *
+     * @param bytes The array to fill.
+     * @throws EOFException If there are not enough bytes remaining in the packet to satisfy the
+     *                      read.
+     */
+    public void readBytes(byte[] bytes) throws EOFException {
+        checkRemaining(bytes.length);
+        System.arraycopy(buf, pos, bytes, 0, bytes.length);
+        pos += bytes.length;
+    }
+
+    /**
+     * Skips over the given number of bytes.
+     *
+     * @param count The number of bytes to read and discard.
+     * @throws EOFException If there are not enough bytes remaining in the packet to satisfy the
+     *                      read.
+     */
+    public void skip(int count) throws EOFException {
+        checkRemaining(count);
+        pos += count;
+    }
+
+    /**
+     * Peeks at and returns the next byte in the packet, without advancing the read position.
+     *
+     * @throws EOFException If there are not enough bytes remaining in the packet to satisfy the
+     *                      read.
+     */
+    public byte peekByte() throws EOFException {
+        checkRemaining(1);
+        return buf[pos];
+    }
+
+    /** Returns the current byte position of the reader for the data packet. */
+    public int getPosition() {
+        return pos;
+    }
+
+    // Checks if the number of remaining bytes to be read in the packet is at least |count|.
+    private void checkRemaining(int count) throws EOFException {
+        if (getRemaining() < count) {
+            throw new EOFException();
+        }
+    }
+
+    private static class LabelEntry {
+        public final String label;
+        public int nextOffset = 0;
+
+        public LabelEntry(String label) {
+            this.label = label;
+        }
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsPacketWriter.java b/service/mdns/com/android/server/connectivity/mdns/MdnsPacketWriter.java
new file mode 100644
index 0000000..2fed36d
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsPacketWriter.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.SocketAddress;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Simple encoder for mDNS packets. */
+public class MdnsPacketWriter {
+    private static final int MDNS_POINTER_MASK = 0xC000;
+    private final byte[] data;
+    private final Map<Integer, String[]> labelDictionary;
+    private int pos = 0;
+    private int savedWritePos = -1;
+
+    /**
+     * Constructs a writer for a new packet.
+     *
+     * @param maxSize The maximum size of a packet.
+     */
+    public MdnsPacketWriter(int maxSize) {
+        if (maxSize <= 0) {
+            throw new IllegalArgumentException("invalid size");
+        }
+
+        data = new byte[maxSize];
+        labelDictionary = new HashMap<>();
+    }
+
+    /** Returns the current write position. */
+    public int getWritePosition() {
+        return pos;
+    }
+
+    /**
+     * Saves the current write position and then rewinds the write position by the given number of
+     * bytes. This is useful for updating length fields earlier in the packet. Rewinds cannot be
+     * nested.
+     *
+     * @param position The position to rewind to.
+     * @throws IOException If the count would go beyond the beginning of the packet, or if there is
+     *                     already a rewind in effect.
+     */
+    public void rewind(int position) throws IOException {
+        if ((savedWritePos != -1) || (position > pos) || (position < 0)) {
+            throw new IOException("invalid rewind");
+        }
+
+        savedWritePos = pos;
+        pos = position;
+    }
+
+    /**
+     * Sets the current write position to what it was prior to the last rewind.
+     *
+     * @throws IOException If there was no rewind in effect.
+     */
+    public void unrewind() throws IOException {
+        if (savedWritePos == -1) {
+            throw new IOException("no rewind is in effect");
+        }
+        pos = savedWritePos;
+        savedWritePos = -1;
+    }
+
+    /** Clears any rewind state. */
+    public void clearRewind() {
+        savedWritePos = -1;
+    }
+
+    /**
+     * Writes an unsigned 8-bit integer.
+     *
+     * @param value The value to write.
+     * @throws IOException If there is not enough space remaining in the packet.
+     */
+    public void writeUInt8(int value) throws IOException {
+        checkRemaining(1);
+        data[pos++] = (byte) (value & 0xFF);
+    }
+
+    /**
+     * Writes an unsigned 16-bit integer.
+     *
+     * @param value The value to write.
+     * @throws IOException If there is not enough space remaining in the packet.
+     */
+    public void writeUInt16(int value) throws IOException {
+        checkRemaining(2);
+        data[pos++] = (byte) ((value >>> 8) & 0xFF);
+        data[pos++] = (byte) (value & 0xFF);
+    }
+
+    /**
+     * Writes an unsigned 32-bit integer.
+     *
+     * @param value The value to write.
+     * @throws IOException If there is not enough space remaining in the packet.
+     */
+    public void writeUInt32(long value) throws IOException {
+        checkRemaining(4);
+        data[pos++] = (byte) ((value >>> 24) & 0xFF);
+        data[pos++] = (byte) ((value >>> 16) & 0xFF);
+        data[pos++] = (byte) ((value >>> 8) & 0xFF);
+        data[pos++] = (byte) (value & 0xFF);
+    }
+
+    /**
+     * Writes a specific number of bytes.
+     *
+     * @param data The array to write.
+     * @throws IOException If there is not enough space remaining in the packet.
+     */
+    public void writeBytes(byte[] data) throws IOException {
+        checkRemaining(data.length);
+        System.arraycopy(data, 0, this.data, pos, data.length);
+        pos += data.length;
+    }
+
+    /**
+     * Writes a string.
+     *
+     * @param value The string to write.
+     * @throws IOException If there is not enough space remaining in the packet.
+     */
+    public void writeString(String value) throws IOException {
+        byte[] utf8 = value.getBytes(MdnsConstants.getUtf8Charset());
+        writeUInt8(utf8.length);
+        writeBytes(utf8);
+    }
+
+    /**
+     * Writes a series of labels. Uses name compression.
+     *
+     * @param labels The labels to write.
+     * @throws IOException If there is not enough space remaining in the packet.
+     */
+    public void writeLabels(String[] labels) throws IOException {
+        // See section 4.1.4 of RFC 1035 (http://tools.ietf.org/html/rfc1035) for a description
+        // of the name compression method used here.
+
+        int suffixLength = 0;
+        int suffixPointer = 0;
+
+        for (Map.Entry<Integer, String[]> entry : labelDictionary.entrySet()) {
+            int existingOffset = entry.getKey();
+            String[] existingLabels = entry.getValue();
+
+            if (Arrays.equals(existingLabels, labels)) {
+                writePointer(existingOffset);
+                return;
+            } else if (MdnsRecord.labelsAreSuffix(existingLabels, labels)) {
+                // Keep track of the longest matching suffix so far.
+                if (existingLabels.length > suffixLength) {
+                    suffixLength = existingLabels.length;
+                    suffixPointer = existingOffset;
+                }
+            }
+        }
+
+        if (suffixLength > 0) {
+            for (int i = 0; i < (labels.length - suffixLength); ++i) {
+                writeString(labels[i]);
+            }
+            writePointer(suffixPointer);
+        } else {
+            int[] offsets = new int[labels.length];
+            for (int i = 0; i < labels.length; ++i) {
+                offsets[i] = getWritePosition();
+                writeString(labels[i]);
+            }
+            writeUInt8(0); // NUL terminator
+
+            // Add entries to the label dictionary for each suffix of the label list, including
+            // the whole list itself.
+            for (int i = 0, len = labels.length; i < labels.length; ++i, --len) {
+                String[] value = new String[len];
+                System.arraycopy(labels, i, value, 0, len);
+                labelDictionary.put(offsets[i], value);
+            }
+        }
+    }
+
+    /** Returns the number of bytes that can still be written. */
+    public int getRemaining() {
+        return data.length - pos;
+    }
+
+    // Writes a pointer to a label.
+    private void writePointer(int offset) throws IOException {
+        writeUInt16(MDNS_POINTER_MASK | offset);
+    }
+
+    // Checks if the remaining space in the packet is at least |count|.
+    private void checkRemaining(int count) throws IOException {
+        if (getRemaining() < count) {
+            throw new IOException();
+        }
+    }
+
+    /** Builds and returns the packet. */
+    public DatagramPacket getPacket(SocketAddress destAddress) throws IOException {
+        return new DatagramPacket(data, pos, destAddress);
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java
new file mode 100644
index 0000000..2b36a3c
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/** An mDNS "PTR" record, which holds a name (the "pointer"). */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+@VisibleForTesting
+public class MdnsPointerRecord extends MdnsRecord {
+    private String[] pointer;
+
+    public MdnsPointerRecord(String[] name, MdnsPacketReader reader) throws IOException {
+        super(name, TYPE_PTR, reader);
+    }
+
+    /** Returns the pointer as an array of labels. */
+    public String[] getPointer() {
+        return pointer;
+    }
+
+    @Override
+    protected void readData(MdnsPacketReader reader) throws IOException {
+        pointer = reader.readLabels();
+    }
+
+    @Override
+    protected void writeData(MdnsPacketWriter writer) throws IOException {
+        writer.writeLabels(pointer);
+    }
+
+    public boolean hasSubtype() {
+        return (name != null) && (name.length > 2) && name[1].equals(MdnsConstants.SUBTYPE_LABEL);
+    }
+
+    public String getSubtype() {
+        return hasSubtype() ? name[0] : null;
+    }
+
+    @Override
+    public String toString() {
+        return "PTR: " + labelsToString(name) + " -> " + labelsToString(pointer);
+    }
+
+    @Override
+    public int hashCode() {
+        return (super.hashCode() * 31) + Arrays.hashCode(pointer);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof MdnsPointerRecord)) {
+            return false;
+        }
+
+        return super.equals(other) && Arrays.equals(pointer, ((MdnsPointerRecord) other).pointer);
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java
new file mode 100644
index 0000000..4bfdb2c
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.os.SystemClock;
+import android.text.TextUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Abstract base class for mDNS records. Stores the header fields and provides methods for reading
+ * the record from and writing it to a packet.
+ */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+public abstract class MdnsRecord {
+    public static final int TYPE_A = 0x0001;
+    public static final int TYPE_AAAA = 0x001C;
+    public static final int TYPE_PTR = 0x000C;
+    public static final int TYPE_SRV = 0x0021;
+    public static final int TYPE_TXT = 0x0010;
+
+    /** Status indicating that the record is current. */
+    public static final int STATUS_OK = 0;
+    /** Status indicating that the record has expired (TTL reached 0). */
+    public static final int STATUS_EXPIRED = 1;
+    /** Status indicating that the record should be refreshed (Less than half of TTL remains.) */
+    public static final int STATUS_NEEDS_REFRESH = 2;
+
+    protected final String[] name;
+    private final int type;
+    private final int cls;
+    private final long receiptTimeMillis;
+    private final long ttlMillis;
+    private Object key;
+
+    /**
+     * Constructs a new record with the given name and type.
+     *
+     * @param reader The reader to read the record from.
+     * @throws IOException If an error occurs while reading the packet.
+     */
+    protected MdnsRecord(String[] name, int type, MdnsPacketReader reader) throws IOException {
+        this.name = name;
+        this.type = type;
+        cls = reader.readUInt16();
+        ttlMillis = TimeUnit.SECONDS.toMillis(reader.readUInt32());
+        int dataLength = reader.readUInt16();
+
+        receiptTimeMillis = SystemClock.elapsedRealtime();
+
+        reader.setLimit(dataLength);
+        readData(reader);
+        reader.clearLimit();
+    }
+
+    /**
+     * Converts an array of labels into their dot-separated string representation. This method
+     * should
+     * be used for logging purposes only.
+     */
+    public static String labelsToString(String[] labels) {
+        if (labels == null) {
+            return null;
+        }
+        return TextUtils.join(".", labels);
+    }
+
+    /** Tests if |list1| is a suffix of |list2|. */
+    public static boolean labelsAreSuffix(String[] list1, String[] list2) {
+        int offset = list2.length - list1.length;
+
+        if (offset < 1) {
+            return false;
+        }
+
+        for (int i = 0; i < list1.length; ++i) {
+            if (!list1[i].equals(list2[i + offset])) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /** Returns the record's receipt (creation) time. */
+    public final long getReceiptTime() {
+        return receiptTimeMillis;
+    }
+
+    /** Returns the record's name. */
+    public String[] getName() {
+        return name;
+    }
+
+    /** Returns the record's original TTL, in milliseconds. */
+    public final long getTtl() {
+        return ttlMillis;
+    }
+
+    /** Returns the record's type. */
+    public final int getType() {
+        return type;
+    }
+
+    /**
+     * Returns the record's remaining TTL.
+     *
+     * @param now The current system time.
+     * @return The remaning TTL, in milliseconds.
+     */
+    public long getRemainingTTL(final long now) {
+        long age = now - receiptTimeMillis;
+        if (age > ttlMillis) {
+            return 0;
+        }
+
+        return ttlMillis - age;
+    }
+
+    /**
+     * Reads the record's payload from a packet.
+     *
+     * @param reader The reader to use.
+     * @throws IOException If an I/O error occurs.
+     */
+    protected abstract void readData(MdnsPacketReader reader) throws IOException;
+
+    /**
+     * Writes the record to a packet.
+     *
+     * @param writer The writer to use.
+     * @param now    The current system time. This is used when writing the updated TTL.
+     */
+    @VisibleForTesting
+    public final void write(MdnsPacketWriter writer, long now) throws IOException {
+        writer.writeLabels(name);
+        writer.writeUInt16(type);
+        writer.writeUInt16(cls);
+
+        writer.writeUInt32(TimeUnit.MILLISECONDS.toSeconds(getRemainingTTL(now)));
+
+        int dataLengthPos = writer.getWritePosition();
+        writer.writeUInt16(0); // data length
+        int dataPos = writer.getWritePosition();
+
+        writeData(writer);
+
+        // Calculate amount of data written, and overwrite the data field earlier in the packet.
+        int endPos = writer.getWritePosition();
+        int dataLength = endPos - dataPos;
+        writer.rewind(dataLengthPos);
+        writer.writeUInt16(dataLength);
+        writer.unrewind();
+    }
+
+    /**
+     * Writes the record's payload to a packet.
+     *
+     * @param writer The writer to use.
+     * @throws IOException If an I/O error occurs.
+     */
+    protected abstract void writeData(MdnsPacketWriter writer) throws IOException;
+
+    /** Gets the status of the record. */
+    public int getStatus(final long now) {
+        final long age = now - receiptTimeMillis;
+        if (age > ttlMillis) {
+            return STATUS_EXPIRED;
+        }
+        if (age > (ttlMillis / 2)) {
+            return STATUS_NEEDS_REFRESH;
+        }
+        return STATUS_OK;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (!(other instanceof MdnsRecord)) {
+            return false;
+        }
+
+        MdnsRecord otherRecord = (MdnsRecord) other;
+
+        return Arrays.equals(name, otherRecord.name) && (type == otherRecord.type);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(Arrays.hashCode(name), type);
+    }
+
+    /**
+     * Returns an opaque object that uniquely identifies this record through a combination of its
+     * type
+     * and name. Suitable for use as a key in caches.
+     */
+    public final Object getKey() {
+        if (key == null) {
+            key = new Key(type, name);
+        }
+        return key;
+    }
+
+    private static final class Key {
+        private final int recordType;
+        private final String[] recordName;
+
+        public Key(int recordType, String[] recordName) {
+            this.recordType = recordType;
+            this.recordName = recordName;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (this == other) {
+                return true;
+            }
+            if (!(other instanceof Key)) {
+                return false;
+            }
+
+            Key otherKey = (Key) other;
+
+            return (recordType == otherKey.recordType) && Arrays.equals(recordName,
+                    otherKey.recordName);
+        }
+
+        @Override
+        public int hashCode() {
+            return (recordType * 31) + Arrays.hashCode(recordName);
+        }
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsResponse.java b/service/mdns/com/android/server/connectivity/mdns/MdnsResponse.java
new file mode 100644
index 0000000..1305e07
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsResponse.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/** An mDNS response. */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+public class MdnsResponse {
+    private final List<MdnsRecord> records;
+    private final List<MdnsPointerRecord> pointerRecords;
+    private MdnsServiceRecord serviceRecord;
+    private MdnsTextRecord textRecord;
+    private MdnsInetAddressRecord inet4AddressRecord;
+    private MdnsInetAddressRecord inet6AddressRecord;
+    private long lastUpdateTime;
+
+    /** Constructs a new, empty response. */
+    public MdnsResponse(long now) {
+        lastUpdateTime = now;
+        records = new LinkedList<>();
+        pointerRecords = new LinkedList<>();
+    }
+
+    // This generic typed helper compares records for equality.
+    // Returns True if records are the same.
+    private <T> boolean recordsAreSame(T a, T b) {
+        return ((a == null) && (b == null)) || ((a != null) && (b != null) && a.equals(b));
+    }
+
+    /**
+     * Adds a pointer record.
+     *
+     * @return <code>true</code> if the record was added, or <code>false</code> if a matching
+     * pointer
+     * record is already present in the response.
+     */
+    public synchronized boolean addPointerRecord(MdnsPointerRecord pointerRecord) {
+        if (!pointerRecords.contains(pointerRecord)) {
+            pointerRecords.add(pointerRecord);
+            records.add(pointerRecord);
+            return true;
+        }
+
+        return false;
+    }
+
+    /** Gets the pointer records. */
+    public synchronized List<MdnsPointerRecord> getPointerRecords() {
+        // Returns a shallow copy.
+        return new LinkedList<>(pointerRecords);
+    }
+
+    public synchronized boolean hasPointerRecords() {
+        return !pointerRecords.isEmpty();
+    }
+
+    @VisibleForTesting
+    /* package */ synchronized void clearPointerRecords() {
+        pointerRecords.clear();
+    }
+
+    public synchronized boolean hasSubtypes() {
+        for (MdnsPointerRecord pointerRecord : pointerRecords) {
+            if (pointerRecord.hasSubtype()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public synchronized List<String> getSubtypes() {
+        List<String> subtypes = null;
+
+        for (MdnsPointerRecord pointerRecord : pointerRecords) {
+            if (pointerRecord.hasSubtype()) {
+                if (subtypes == null) {
+                    subtypes = new LinkedList<>();
+                }
+                subtypes.add(pointerRecord.getSubtype());
+            }
+        }
+
+        return subtypes;
+    }
+
+    @VisibleForTesting
+    public synchronized void removeSubtypes() {
+        Iterator<MdnsPointerRecord> iter = pointerRecords.iterator();
+        while (iter.hasNext()) {
+            MdnsPointerRecord pointerRecord = iter.next();
+            if (pointerRecord.hasSubtype()) {
+                iter.remove();
+            }
+        }
+    }
+
+    /** Sets the service record. */
+    public synchronized boolean setServiceRecord(MdnsServiceRecord serviceRecord) {
+        if (recordsAreSame(this.serviceRecord, serviceRecord)) {
+            return false;
+        }
+        if (this.serviceRecord != null) {
+            records.remove(this.serviceRecord);
+        }
+        this.serviceRecord = serviceRecord;
+        if (this.serviceRecord != null) {
+            records.add(this.serviceRecord);
+        }
+        return true;
+    }
+
+    /** Gets the service record. */
+    public synchronized MdnsServiceRecord getServiceRecord() {
+        return serviceRecord;
+    }
+
+    public synchronized boolean hasServiceRecord() {
+        return serviceRecord != null;
+    }
+
+    /** Sets the text record. */
+    public synchronized boolean setTextRecord(MdnsTextRecord textRecord) {
+        if (recordsAreSame(this.textRecord, textRecord)) {
+            return false;
+        }
+        if (this.textRecord != null) {
+            records.remove(this.textRecord);
+        }
+        this.textRecord = textRecord;
+        if (this.textRecord != null) {
+            records.add(this.textRecord);
+        }
+        return true;
+    }
+
+    /** Gets the text record. */
+    public synchronized MdnsTextRecord getTextRecord() {
+        return textRecord;
+    }
+
+    public synchronized boolean hasTextRecord() {
+        return textRecord != null;
+    }
+
+    /** Sets the IPv4 address record. */
+    public synchronized boolean setInet4AddressRecord(MdnsInetAddressRecord newInet4AddressRecord) {
+        if (recordsAreSame(this.inet4AddressRecord, newInet4AddressRecord)) {
+            return false;
+        }
+        if (this.inet4AddressRecord != null) {
+            records.remove(this.inet4AddressRecord);
+        }
+        if (newInet4AddressRecord != null && newInet4AddressRecord.getInet4Address() != null) {
+            this.inet4AddressRecord = newInet4AddressRecord;
+            records.add(this.inet4AddressRecord);
+        }
+        return true;
+    }
+
+    /** Gets the IPv4 address record. */
+    public synchronized MdnsInetAddressRecord getInet4AddressRecord() {
+        return inet4AddressRecord;
+    }
+
+    public synchronized boolean hasInet4AddressRecord() {
+        return inet4AddressRecord != null;
+    }
+
+    /** Sets the IPv6 address record. */
+    public synchronized boolean setInet6AddressRecord(MdnsInetAddressRecord newInet6AddressRecord) {
+        if (recordsAreSame(this.inet6AddressRecord, newInet6AddressRecord)) {
+            return false;
+        }
+        if (this.inet6AddressRecord != null) {
+            records.remove(this.inet6AddressRecord);
+        }
+        if (newInet6AddressRecord != null && newInet6AddressRecord.getInet6Address() != null) {
+            this.inet6AddressRecord = newInet6AddressRecord;
+            records.add(this.inet6AddressRecord);
+        }
+        return true;
+    }
+
+
+    /** Gets the IPv6 address record. */
+    public synchronized MdnsInetAddressRecord getInet6AddressRecord() {
+        return inet6AddressRecord;
+    }
+
+    public synchronized boolean hasInet6AddressRecord() {
+        return inet6AddressRecord != null;
+    }
+
+    /** Gets all of the records. */
+    public synchronized List<MdnsRecord> getRecords() {
+        return new LinkedList<>(records);
+    }
+
+    /**
+     * Merges any records that are present in another response into this one.
+     *
+     * @return <code>true</code> if any records were added or updated.
+     */
+    public synchronized boolean mergeRecordsFrom(MdnsResponse other) {
+        lastUpdateTime = other.lastUpdateTime;
+
+        boolean updated = false;
+
+        List<MdnsPointerRecord> pointerRecords = other.getPointerRecords();
+        if (pointerRecords != null) {
+            for (MdnsPointerRecord pointerRecord : pointerRecords) {
+                if (addPointerRecord(pointerRecord)) {
+                    updated = true;
+                }
+            }
+        }
+
+        MdnsServiceRecord serviceRecord = other.getServiceRecord();
+        if (serviceRecord != null) {
+            if (setServiceRecord(serviceRecord)) {
+                updated = true;
+            }
+        }
+
+        MdnsTextRecord textRecord = other.getTextRecord();
+        if (textRecord != null) {
+            if (setTextRecord(textRecord)) {
+                updated = true;
+            }
+        }
+
+        MdnsInetAddressRecord otherInet4AddressRecord = other.getInet4AddressRecord();
+        if (otherInet4AddressRecord != null && otherInet4AddressRecord.getInet4Address() != null) {
+            if (setInet4AddressRecord(otherInet4AddressRecord)) {
+                updated = true;
+            }
+        }
+
+        MdnsInetAddressRecord otherInet6AddressRecord = other.getInet6AddressRecord();
+        if (otherInet6AddressRecord != null && otherInet6AddressRecord.getInet6Address() != null) {
+            if (setInet6AddressRecord(otherInet6AddressRecord)) {
+                updated = true;
+            }
+        }
+
+        // If the hostname in the service record no longer matches the hostname in either of the
+        // address records, then drop the address records.
+        if (this.serviceRecord != null) {
+            boolean dropAddressRecords = false;
+
+            if (this.inet4AddressRecord != null) {
+                if (!Arrays.equals(
+                        this.serviceRecord.getServiceHost(), this.inet4AddressRecord.getName())) {
+                    dropAddressRecords = true;
+                }
+            }
+            if (this.inet6AddressRecord != null) {
+                if (!Arrays.equals(
+                        this.serviceRecord.getServiceHost(), this.inet6AddressRecord.getName())) {
+                    dropAddressRecords = true;
+                }
+            }
+
+            if (dropAddressRecords) {
+                setInet4AddressRecord(null);
+                setInet6AddressRecord(null);
+                updated = true;
+            }
+        }
+
+        return updated;
+    }
+
+    /**
+     * Tests if the response is complete. A response is considered complete if it contains PTR, SRV,
+     * TXT, and A (for IPv4) or AAAA (for IPv6) records.
+     */
+    public synchronized boolean isComplete() {
+        return !pointerRecords.isEmpty()
+                && (serviceRecord != null)
+                && (textRecord != null)
+                && (inet4AddressRecord != null || inet6AddressRecord != null);
+    }
+
+    /**
+     * Returns the key for this response. The key uniquely identifies the response by its service
+     * name.
+     */
+    public synchronized String getServiceInstanceName() {
+        if (pointerRecords.isEmpty()) {
+            return null;
+        }
+        String[] pointers = pointerRecords.get(0).getPointer();
+        return ((pointers != null) && (pointers.length > 0)) ? pointers[0] : null;
+    }
+
+    /**
+     * Tests if this response is a goodbye message. This will be true if a service record is present
+     * and any of the records have a TTL of 0.
+     */
+    public synchronized boolean isGoodbye() {
+        if (getServiceInstanceName() != null) {
+            for (MdnsRecord record : records) {
+                // Expiring PTR records with subtypes just signal a change in known supported
+                // criteria, not the device itself going offline, so ignore those.
+                if ((record instanceof MdnsPointerRecord)
+                        && ((MdnsPointerRecord) record).hasSubtype()) {
+                    continue;
+                }
+
+                if (record.getTtl() == 0) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Writes the response to a packet.
+     *
+     * @param writer The writer to use.
+     * @param now    The current time. This is used to write updated TTLs that reflect the remaining
+     *               TTL
+     *               since the response was received.
+     * @return The number of records that were written.
+     * @throws IOException If an error occurred while writing (typically indicating overflow).
+     */
+    public synchronized int write(MdnsPacketWriter writer, long now) throws IOException {
+        int count = 0;
+        for (MdnsPointerRecord pointerRecord : pointerRecords) {
+            pointerRecord.write(writer, now);
+            ++count;
+        }
+
+        if (serviceRecord != null) {
+            serviceRecord.write(writer, now);
+            ++count;
+        }
+
+        if (textRecord != null) {
+            textRecord.write(writer, now);
+            ++count;
+        }
+
+        if (inet4AddressRecord != null) {
+            inet4AddressRecord.write(writer, now);
+            ++count;
+        }
+
+        if (inet6AddressRecord != null) {
+            inet6AddressRecord.write(writer, now);
+            ++count;
+        }
+
+        return count;
+    }
+}
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java b/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
new file mode 100644
index 0000000..72c3156
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.SystemClock;
+
+import com.android.server.connectivity.mdns.util.MdnsLogger;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/** A class that decodes mDNS responses from UDP packets. */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+public class MdnsResponseDecoder {
+
+    public static final int SUCCESS = 0;
+    private static final String TAG = "MdnsResponseDecoder";
+    private static final MdnsLogger LOGGER = new MdnsLogger(TAG);
+    private final String[] serviceType;
+    private final Clock clock;
+
+    /** Constructs a new decoder that will extract responses for the given service type. */
+    public MdnsResponseDecoder(@NonNull Clock clock, @Nullable String[] serviceType) {
+        this.clock = clock;
+        this.serviceType = serviceType;
+    }
+
+    private static void skipMdnsRecord(MdnsPacketReader reader) throws IOException {
+        reader.skip(2 + 4); // skip the class and TTL
+        int dataLength = reader.readUInt16();
+        reader.skip(dataLength);
+    }
+
+    private static MdnsResponse findResponseWithPointer(
+            List<MdnsResponse> responses, String[] pointer) {
+        if (responses != null) {
+            for (MdnsResponse response : responses) {
+                List<MdnsPointerRecord> pointerRecords = response.getPointerRecords();
+                if (pointerRecords == null) {
+                    continue;
+                }
+                for (MdnsPointerRecord pointerRecord : pointerRecords) {
+                    if (Arrays.equals(pointerRecord.getPointer(), pointer)) {
+                        return response;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private static MdnsResponse findResponseWithHostName(
+            List<MdnsResponse> responses, String[] hostName) {
+        if (responses != null) {
+            for (MdnsResponse response : responses) {
+                MdnsServiceRecord serviceRecord = response.getServiceRecord();
+                if (serviceRecord == null) {
+                    continue;
+                }
+                if (Arrays.equals(serviceRecord.getServiceHost(), hostName)) {
+                    return response;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Decodes all mDNS responses for the desired service type from a packet. The class does not
+     * check
+     * the responses for completeness; the caller should do that.
+     *
+     * @param packet The packet to read from.
+     * @return A list of mDNS responses, or null if the packet contained no appropriate responses.
+     */
+    public int decode(@NonNull DatagramPacket packet, @NonNull List<MdnsResponse> responses) {
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+
+        List<MdnsRecord> records;
+        try {
+            reader.readUInt16(); // transaction ID (not used)
+            int flags = reader.readUInt16();
+            if ((flags & MdnsConstants.FLAGS_RESPONSE_MASK) != MdnsConstants.FLAGS_RESPONSE) {
+                return MdnsResponseErrorCode.ERROR_NOT_RESPONSE_MESSAGE;
+            }
+
+            int numQuestions = reader.readUInt16();
+            int numAnswers = reader.readUInt16();
+            int numAuthority = reader.readUInt16();
+            int numRecords = reader.readUInt16();
+
+            LOGGER.log(String.format(
+                    "num questions: %d, num answers: %d, num authority: %d, num records: %d",
+                    numQuestions, numAnswers, numAuthority, numRecords));
+
+            if (numAnswers < 1) {
+                return MdnsResponseErrorCode.ERROR_NO_ANSWERS;
+            }
+
+            records = new LinkedList<>();
+
+            for (int i = 0; i < (numAnswers + numAuthority + numRecords); ++i) {
+                String[] name;
+                try {
+                    name = reader.readLabels();
+                } catch (IOException e) {
+                    LOGGER.e("Failed to read labels from mDNS response.", e);
+                    return MdnsResponseErrorCode.ERROR_READING_RECORD_NAME;
+                }
+                int type = reader.readUInt16();
+
+                switch (type) {
+                    case MdnsRecord.TYPE_A: {
+                        try {
+                            records.add(new MdnsInetAddressRecord(name, MdnsRecord.TYPE_A, reader));
+                        } catch (IOException e) {
+                            LOGGER.e("Failed to read A record from mDNS response.", e);
+                            return MdnsResponseErrorCode.ERROR_READING_A_RDATA;
+                        }
+                        break;
+                    }
+
+                    case MdnsRecord.TYPE_AAAA: {
+                        try {
+                            // AAAA should only contain the IPv6 address.
+                            MdnsInetAddressRecord record =
+                                    new MdnsInetAddressRecord(name, MdnsRecord.TYPE_AAAA, reader);
+                            if (record.getInet6Address() != null) {
+                                records.add(record);
+                            }
+                        } catch (IOException e) {
+                            LOGGER.e("Failed to read AAAA record from mDNS response.", e);
+                            return MdnsResponseErrorCode.ERROR_READING_AAAA_RDATA;
+                        }
+                        break;
+                    }
+
+                    case MdnsRecord.TYPE_PTR: {
+                        try {
+                            records.add(new MdnsPointerRecord(name, reader));
+                        } catch (IOException e) {
+                            LOGGER.e("Failed to read PTR record from mDNS response.", e);
+                            return MdnsResponseErrorCode.ERROR_READING_PTR_RDATA;
+                        }
+                        break;
+                    }
+
+                    case MdnsRecord.TYPE_SRV: {
+                        if (name.length == 4) {
+                            try {
+                                records.add(new MdnsServiceRecord(name, reader));
+                            } catch (IOException e) {
+                                LOGGER.e("Failed to read SRV record from mDNS response.", e);
+                                return MdnsResponseErrorCode.ERROR_READING_SRV_RDATA;
+                            }
+                        } else {
+                            try {
+                                skipMdnsRecord(reader);
+                            } catch (IOException e) {
+                                LOGGER.e("Failed to skip SVR record from mDNS response.", e);
+                                return MdnsResponseErrorCode.ERROR_SKIPPING_SRV_RDATA;
+                            }
+                        }
+                        break;
+                    }
+
+                    case MdnsRecord.TYPE_TXT: {
+                        try {
+                            records.add(new MdnsTextRecord(name, reader));
+                        } catch (IOException e) {
+                            LOGGER.e("Failed to read TXT record from mDNS response.", e);
+                            return MdnsResponseErrorCode.ERROR_READING_TXT_RDATA;
+                        }
+                        break;
+                    }
+
+                    default: {
+                        try {
+                            skipMdnsRecord(reader);
+                        } catch (IOException e) {
+                            LOGGER.e("Failed to skip mDNS record.", e);
+                            return MdnsResponseErrorCode.ERROR_SKIPPING_UNKNOWN_RECORD;
+                        }
+                    }
+                }
+            }
+        } catch (EOFException e) {
+            LOGGER.e("Reached the end of the mDNS response unexpectedly.", e);
+            return MdnsResponseErrorCode.ERROR_END_OF_FILE;
+        }
+
+        // The response records are structured in a hierarchy, where some records reference
+        // others, as follows:
+        //
+        //        PTR
+        //        / \
+        //       /   \
+        //      TXT  SRV
+        //           / \
+        //          /   \
+        //         A   AAAA
+        //
+        // But the order in which these records appear in the response packet is completely
+        // arbitrary. This means that we need to rescan the record list to construct each level of
+        // this hierarchy.
+        //
+        // PTR: service type -> service instance name
+        //
+        // SRV: service instance name -> host name (priority, weight)
+        //
+        // TXT: service instance name -> machine readable txt entries.
+        //
+        // A: host name -> IP address
+
+        // Loop 1: find PTR records, which identify distinct service instances.
+        long now = SystemClock.elapsedRealtime();
+        for (MdnsRecord record : records) {
+            if (record instanceof MdnsPointerRecord) {
+                String[] name = record.getName();
+                if ((serviceType == null)
+                        || Arrays.equals(name, serviceType)
+                        || ((name.length == (serviceType.length + 2))
+                        && name[1].equals(MdnsConstants.SUBTYPE_LABEL)
+                        && MdnsRecord.labelsAreSuffix(serviceType, name))) {
+                    MdnsPointerRecord pointerRecord = (MdnsPointerRecord) record;
+                    // Group PTR records that refer to the same service instance name into a single
+                    // response.
+                    MdnsResponse response = findResponseWithPointer(responses,
+                            pointerRecord.getPointer());
+                    if (response == null) {
+                        response = new MdnsResponse(now);
+                        responses.add(response);
+                    }
+                    response.addPointerRecord((MdnsPointerRecord) record);
+                }
+            }
+        }
+
+        // Loop 2: find SRV and TXT records, which reference the pointer in the PTR record.
+        for (MdnsRecord record : records) {
+            if (record instanceof MdnsServiceRecord) {
+                MdnsServiceRecord serviceRecord = (MdnsServiceRecord) record;
+                MdnsResponse response = findResponseWithPointer(responses, serviceRecord.getName());
+                if (response != null) {
+                    response.setServiceRecord(serviceRecord);
+                }
+            } else if (record instanceof MdnsTextRecord) {
+                MdnsTextRecord textRecord = (MdnsTextRecord) record;
+                MdnsResponse response = findResponseWithPointer(responses, textRecord.getName());
+                if (response != null) {
+                    response.setTextRecord(textRecord);
+                }
+            }
+        }
+
+        // Loop 3: find A and AAAA records, which reference the host name in the SRV record.
+        for (MdnsRecord record : records) {
+            if (record instanceof MdnsInetAddressRecord) {
+                MdnsInetAddressRecord inetRecord = (MdnsInetAddressRecord) record;
+                MdnsResponse response = findResponseWithHostName(responses, inetRecord.getName());
+                if (inetRecord.getInet4Address() != null && response != null) {
+                    response.setInet4AddressRecord(inetRecord);
+                } else if (inetRecord.getInet6Address() != null && response != null) {
+                    response.setInet6AddressRecord(inetRecord);
+                }
+            }
+        }
+
+        return SUCCESS;
+    }
+
+    public static class Clock {
+        public long elapsedRealtime() {
+            return SystemClock.elapsedRealtime();
+        }
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsResponseErrorCode.java b/service/mdns/com/android/server/connectivity/mdns/MdnsResponseErrorCode.java
new file mode 100644
index 0000000..fcf9058
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsResponseErrorCode.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+/**
+ * The list of error code for parsing mDNS response.
+ *
+ * @hide
+ */
+public class MdnsResponseErrorCode {
+    public static final int SUCCESS = 0;
+    public static final int ERROR_NOT_RESPONSE_MESSAGE = 1;
+    public static final int ERROR_NO_ANSWERS = 2;
+    public static final int ERROR_READING_RECORD_NAME = 3;
+    public static final int ERROR_READING_A_RDATA = 4;
+    public static final int ERROR_READING_AAAA_RDATA = 5;
+    public static final int ERROR_READING_PTR_RDATA = 6;
+    public static final int ERROR_SKIPPING_PTR_RDATA = 7;
+    public static final int ERROR_READING_SRV_RDATA = 8;
+    public static final int ERROR_SKIPPING_SRV_RDATA = 9;
+    public static final int ERROR_READING_TXT_RDATA = 10;
+    public static final int ERROR_SKIPPING_UNKNOWN_RECORD = 11;
+    public static final int ERROR_END_OF_FILE = 12;
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsSearchOptions.java b/service/mdns/com/android/server/connectivity/mdns/MdnsSearchOptions.java
new file mode 100644
index 0000000..6e90d2c
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsSearchOptions.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.ArraySet;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * API configuration parameters for searching the mDNS service.
+ *
+ * <p>Use {@link MdnsSearchOptions.Builder} to create {@link MdnsSearchOptions}.
+ *
+ * @hide
+ */
+public class MdnsSearchOptions implements Parcelable {
+
+    /** @hide */
+    public static final Parcelable.Creator<MdnsSearchOptions> CREATOR =
+            new Parcelable.Creator<MdnsSearchOptions>() {
+                @Override
+                public MdnsSearchOptions createFromParcel(Parcel source) {
+                    return new MdnsSearchOptions(source.createStringArrayList(),
+                            source.readBoolean());
+                }
+
+                @Override
+                public MdnsSearchOptions[] newArray(int size) {
+                    return new MdnsSearchOptions[size];
+                }
+            };
+    private static MdnsSearchOptions defaultOptions;
+    private final List<String> subtypes;
+
+    private final boolean isPassiveMode;
+
+    /** Parcelable constructs for a {@link MdnsServiceInfo}. */
+    MdnsSearchOptions(List<String> subtypes, boolean isPassiveMode) {
+        this.subtypes = new ArrayList<>();
+        if (subtypes != null) {
+            this.subtypes.addAll(subtypes);
+        }
+        this.isPassiveMode = isPassiveMode;
+    }
+
+    /** Returns a {@link Builder} for {@link MdnsSearchOptions}. */
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /** Returns a default search options. */
+    public static synchronized MdnsSearchOptions getDefaultOptions() {
+        if (defaultOptions == null) {
+            defaultOptions = newBuilder().build();
+        }
+        return defaultOptions;
+    }
+
+    /** @return the list of subtypes to search. */
+    public List<String> getSubtypes() {
+        return subtypes;
+    }
+
+    /**
+     * @return {@code true} if the passive mode is used. The passive mode scans less frequently in
+     * order to conserve battery and produce less network traffic.
+     */
+    public boolean isPassiveMode() {
+        return isPassiveMode;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeStringList(subtypes);
+        out.writeBoolean(isPassiveMode);
+    }
+
+    /** A builder to create {@link MdnsSearchOptions}. */
+    public static final class Builder {
+        private final Set<String> subtypes;
+        private boolean isPassiveMode = true;
+
+        private Builder() {
+            subtypes = new ArraySet<>();
+        }
+
+        /**
+         * Adds a subtype to search.
+         *
+         * @param subtype the subtype to add.
+         */
+        public Builder addSubtype(@NonNull String subtype) {
+            if (TextUtils.isEmpty(subtype)) {
+                throw new IllegalArgumentException("Empty subtype");
+            }
+            subtypes.add(subtype);
+            return this;
+        }
+
+        /**
+         * Adds a set of subtypes to search.
+         *
+         * @param subtypes The list of subtypes to add.
+         */
+        public Builder addSubtypes(@NonNull Collection<String> subtypes) {
+            this.subtypes.addAll(Objects.requireNonNull(subtypes));
+            return this;
+        }
+
+        /**
+         * Sets if the passive mode scan should be used. The passive mode scans less frequently in
+         * order
+         * to conserve battery and produce less network traffic.
+         *
+         * @param isPassiveMode If set to {@code true}, passive mode will be used. If set to {@code
+         *                      false}, active mode will be used.
+         */
+        public Builder setIsPassiveMode(boolean isPassiveMode) {
+            this.isPassiveMode = isPassiveMode;
+            return this;
+        }
+
+        /** Builds a {@link MdnsSearchOptions} with the arguments supplied to this builder. */
+        public MdnsSearchOptions build() {
+            return new MdnsSearchOptions(new ArrayList<>(subtypes), isPassiveMode);
+        }
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceBrowserListener.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceBrowserListener.java
new file mode 100644
index 0000000..53e58d1
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceBrowserListener.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.annotation.NonNull;
+
+import java.util.List;
+
+/**
+ * Listener interface for mDNS service instance discovery events.
+ *
+ * @hide
+ */
+public interface MdnsServiceBrowserListener {
+
+    /**
+     * Called when an mDNS service instance is found.
+     *
+     * @param serviceInfo The found mDNS service instance.
+     */
+    void onServiceFound(@NonNull MdnsServiceInfo serviceInfo);
+
+    /**
+     * Called when an mDNS service instance is updated.
+     *
+     * @param serviceInfo The updated mDNS service instance.
+     */
+    void onServiceUpdated(@NonNull MdnsServiceInfo serviceInfo);
+
+    /**
+     * Called when an mDNS service instance is no longer valid and removed.
+     *
+     * @param serviceInstanceName The service instance name of the removed mDNS service.
+     */
+    void onServiceRemoved(@NonNull String serviceInstanceName);
+
+    /**
+     * Called when searching for mDNS service has stopped because of an error.
+     *
+     * TODO (changed when importing code): define error constants
+     *
+     * @param error The error code of the stop reason.
+     */
+    void onSearchStoppedWithError(int error);
+
+    /** Called when it failed to start an mDNS service discovery process. */
+    void onSearchFailedToStart();
+
+    /**
+     * Called when a mDNS service discovery query has been sent.
+     *
+     * @param subtypes      The list of subtypes in the discovery query.
+     * @param transactionId The transaction ID of the query.
+     */
+    void onDiscoveryQuerySent(@NonNull List<String> subtypes, int transactionId);
+
+    /**
+     * Called when an error has happened when parsing a received mDNS response packet.
+     *
+     * @param receivedPacketNumber The packet sequence number of the received packet.
+     * @param errorCode            The error code, defined in {@link MdnsResponseErrorCode}.
+     */
+    void onFailedToParseMdnsResponse(int receivedPacketNumber, int errorCode);
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java
new file mode 100644
index 0000000..2e4a4e5
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * A class representing a discovered mDNS service instance.
+ *
+ * @hide
+ */
+public class MdnsServiceInfo implements Parcelable {
+
+    /** @hide */
+    public static final Parcelable.Creator<MdnsServiceInfo> CREATOR =
+            new Parcelable.Creator<MdnsServiceInfo>() {
+
+                @Override
+                public MdnsServiceInfo createFromParcel(Parcel source) {
+                    return new MdnsServiceInfo(
+                            source.readString(),
+                            source.createStringArray(),
+                            source.createStringArrayList(),
+                            source.createStringArray(),
+                            source.readInt(),
+                            source.readString(),
+                            source.readString(),
+                            source.createStringArrayList());
+                }
+
+                @Override
+                public MdnsServiceInfo[] newArray(int size) {
+                    return new MdnsServiceInfo[size];
+                }
+            };
+
+    private final String serviceInstanceName;
+    private final String[] serviceType;
+    private final List<String> subtypes;
+    private final String[] hostName;
+    private final int port;
+    private final String ipv4Address;
+    private final String ipv6Address;
+    private final Map<String, String> attributes = new HashMap<>();
+    List<String> textStrings;
+
+    /**
+     * Constructs a {@link MdnsServiceInfo} object with default values.
+     *
+     * @hide
+     */
+    public MdnsServiceInfo(
+            String serviceInstanceName,
+            String[] serviceType,
+            List<String> subtypes,
+            String[] hostName,
+            int port,
+            String ipv4Address,
+            String ipv6Address,
+            List<String> textStrings) {
+        this.serviceInstanceName = serviceInstanceName;
+        this.serviceType = serviceType;
+        this.subtypes = new ArrayList<>();
+        if (subtypes != null) {
+            this.subtypes.addAll(subtypes);
+        }
+        this.hostName = hostName;
+        this.port = port;
+        this.ipv4Address = ipv4Address;
+        this.ipv6Address = ipv6Address;
+        if (textStrings != null) {
+            for (String text : textStrings) {
+                int pos = text.indexOf('=');
+                if (pos < 1) {
+                    continue;
+                }
+                attributes.put(text.substring(0, pos).toLowerCase(Locale.ENGLISH),
+                        text.substring(++pos));
+            }
+        }
+    }
+
+    /** @return the name of this service instance. */
+    public String getServiceInstanceName() {
+        return serviceInstanceName;
+    }
+
+    /** @return the type of this service instance. */
+    public String[] getServiceType() {
+        return serviceType;
+    }
+
+    /** @return the list of subtypes supported by this service instance. */
+    public List<String> getSubtypes() {
+        return new ArrayList<>(subtypes);
+    }
+
+    /**
+     * @return {@code true} if this service instance supports any subtypes.
+     * @return {@code false} if this service instance does not support any subtypes.
+     */
+    public boolean hasSubtypes() {
+        return !subtypes.isEmpty();
+    }
+
+    /** @return the host name of this service instance. */
+    public String[] getHostName() {
+        return hostName;
+    }
+
+    /** @return the port number of this service instance. */
+    public int getPort() {
+        return port;
+    }
+
+    /** @return the IPV4 address of this service instance. */
+    public String getIpv4Address() {
+        return ipv4Address;
+    }
+
+    /** @return the IPV6 address of this service instance. */
+    public String getIpv6Address() {
+        return ipv6Address;
+    }
+
+    /**
+     * @return the attribute value for {@code key}.
+     * @return {@code null} if no attribute value exists for {@code key}.
+     */
+    public String getAttributeByKey(@NonNull String key) {
+        return attributes.get(key.toLowerCase(Locale.ENGLISH));
+    }
+
+    /** @return an immutable map of all attributes. */
+    public Map<String, String> getAttributes() {
+        return Collections.unmodifiableMap(attributes);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        if (textStrings == null) {
+            // Lazily initialize the parcelable field mTextStrings.
+            textStrings = new ArrayList<>(attributes.size());
+            for (Map.Entry<String, String> kv : attributes.entrySet()) {
+                textStrings.add(String.format(Locale.ROOT, "%s=%s", kv.getKey(), kv.getValue()));
+            }
+        }
+
+        out.writeString(serviceInstanceName);
+        out.writeStringArray(serviceType);
+        out.writeStringList(subtypes);
+        out.writeStringArray(hostName);
+        out.writeInt(port);
+        out.writeString(ipv4Address);
+        out.writeString(ipv6Address);
+        out.writeStringList(textStrings);
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                Locale.ROOT,
+                "Name: %s, subtypes: %s, ip: %s, port: %d",
+                serviceInstanceName,
+                TextUtils.join(",", subtypes),
+                ipv4Address,
+                port);
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java
new file mode 100644
index 0000000..51de3b2
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Objects;
+
+/** An mDNS "SRV" record, which contains service information. */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+@VisibleForTesting
+public class MdnsServiceRecord extends MdnsRecord {
+    public static final int PROTO_NONE = 0;
+    public static final int PROTO_TCP = 1;
+    public static final int PROTO_UDP = 2;
+    private static final String PROTO_TOKEN_TCP = "_tcp";
+    private static final String PROTO_TOKEN_UDP = "_udp";
+    private int servicePriority;
+    private int serviceWeight;
+    private int servicePort;
+    private String[] serviceHost;
+
+    public MdnsServiceRecord(String[] name, MdnsPacketReader reader) throws IOException {
+        super(name, TYPE_SRV, reader);
+    }
+
+    /** Returns the service's port number. */
+    public int getServicePort() {
+        return servicePort;
+    }
+
+    /** Returns the service's host name. */
+    public String[] getServiceHost() {
+        return serviceHost;
+    }
+
+    /** Returns the service's priority. */
+    public int getServicePriority() {
+        return servicePriority;
+    }
+
+    /** Returns the service's weight. */
+    public int getServiceWeight() {
+        return serviceWeight;
+    }
+
+    // Format of name is <instance-name>.<service-name>.<protocol>.<domain>
+
+    /** Returns the service's instance name, which uniquely identifies the service instance. */
+    public String getServiceInstanceName() {
+        if (name.length < 1) {
+            return null;
+        }
+        return name[0];
+    }
+
+    /** Returns the service's name. */
+    public String getServiceName() {
+        if (name.length < 2) {
+            return null;
+        }
+        return name[1];
+    }
+
+    /** Returns the service's protocol. */
+    public int getServiceProtocol() {
+        if (name.length < 3) {
+            return PROTO_NONE;
+        }
+
+        String protocol = name[2];
+        if (protocol.equals(PROTO_TOKEN_TCP)) {
+            return PROTO_TCP;
+        }
+        if (protocol.equals(PROTO_TOKEN_UDP)) {
+            return PROTO_UDP;
+        }
+        return PROTO_NONE;
+    }
+
+    @Override
+    protected void readData(MdnsPacketReader reader) throws IOException {
+        servicePriority = reader.readUInt16();
+        serviceWeight = reader.readUInt16();
+        servicePort = reader.readUInt16();
+        serviceHost = reader.readLabels();
+    }
+
+    @Override
+    protected void writeData(MdnsPacketWriter writer) throws IOException {
+        writer.writeUInt16(servicePriority);
+        writer.writeUInt16(serviceWeight);
+        writer.writeUInt16(servicePort);
+        writer.writeLabels(serviceHost);
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                Locale.ROOT,
+                "SRV: %s:%d (prio=%d, weight=%d)",
+                labelsToString(serviceHost),
+                servicePort,
+                servicePriority,
+                serviceWeight);
+    }
+
+    @Override
+    public int hashCode() {
+        return (super.hashCode() * 31)
+                + Objects.hash(servicePriority, serviceWeight, Arrays.hashCode(serviceHost),
+                servicePort);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof MdnsServiceRecord)) {
+            return false;
+        }
+        MdnsServiceRecord otherRecord = (MdnsServiceRecord) other;
+
+        return super.equals(other)
+                && (servicePriority == otherRecord.servicePriority)
+                && (serviceWeight == otherRecord.serviceWeight)
+                && Objects.equals(serviceHost, otherRecord.serviceHost)
+                && (servicePort == otherRecord.servicePort);
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
new file mode 100644
index 0000000..c3a86e3
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.annotation.NonNull;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Pair;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.connectivity.mdns.util.MdnsLogger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Instance of this class sends and receives mDNS packets of a given service type and invoke
+ * registered {@link MdnsServiceBrowserListener} instances.
+ */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+public class MdnsServiceTypeClient {
+
+    private static final int DEFAULT_MTU = 1500;
+    private static final MdnsLogger LOGGER = new MdnsLogger("MdnsServiceTypeClient");
+
+    private final String serviceType;
+    private final String[] serviceTypeLabels;
+    private final MdnsSocketClient socketClient;
+    private final ScheduledExecutorService executor;
+    private final Object lock = new Object();
+    private final Set<MdnsServiceBrowserListener> listeners = new ArraySet<>();
+    private final Map<String, MdnsResponse> instanceNameToResponse = new HashMap<>();
+
+    // The session ID increases when startSendAndReceive() is called where we schedule a
+    // QueryTask for
+    // new subtypes. It stays the same between packets for same subtypes.
+    private long currentSessionId = 0;
+
+    @GuardedBy("lock")
+    private Future<?> requestTaskFuture;
+
+    /**
+     * Constructor of {@link MdnsServiceTypeClient}.
+     *
+     * @param socketClient Sends and receives mDNS packet.
+     * @param executor     A {@link ScheduledExecutorService} used to schedule query tasks.
+     */
+    public MdnsServiceTypeClient(
+            @NonNull String serviceType,
+            @NonNull MdnsSocketClient socketClient,
+            @NonNull ScheduledExecutorService executor) {
+        this.serviceType = serviceType;
+        this.socketClient = socketClient;
+        this.executor = executor;
+        serviceTypeLabels = TextUtils.split(serviceType, "\\.");
+    }
+
+    private static MdnsServiceInfo buildMdnsServiceInfoFromResponse(
+            @NonNull MdnsResponse response, @NonNull String[] serviceTypeLabels) {
+        String[] hostName = response.getServiceRecord().getServiceHost();
+        int port = response.getServiceRecord().getServicePort();
+
+        String ipv4Address = null;
+        String ipv6Address = null;
+        if (response.hasInet4AddressRecord()) {
+            ipv4Address = response.getInet4AddressRecord().getInet4Address().getHostAddress();
+        }
+        if (response.hasInet6AddressRecord()) {
+            ipv6Address = response.getInet6AddressRecord().getInet6Address().getHostAddress();
+        }
+        // TODO: Throw an error message if response doesn't have Inet6 or Inet4 address.
+        return new MdnsServiceInfo(
+                response.getServiceInstanceName(),
+                serviceTypeLabels,
+                response.getSubtypes(),
+                hostName,
+                port,
+                ipv4Address,
+                ipv6Address,
+                response.getTextRecord().getStrings());
+    }
+
+    /**
+     * Registers {@code listener} for receiving discovery event of mDNS service instances, and
+     * starts
+     * (or continue) to send mDNS queries periodically.
+     *
+     * @param listener      The {@link MdnsServiceBrowserListener} to register.
+     * @param searchOptions {@link MdnsSearchOptions} contains the list of subtypes to discover.
+     */
+    public void startSendAndReceive(
+            @NonNull MdnsServiceBrowserListener listener,
+            @NonNull MdnsSearchOptions searchOptions) {
+        synchronized (lock) {
+            if (!listeners.contains(listener)) {
+                listeners.add(listener);
+                for (MdnsResponse existingResponse : instanceNameToResponse.values()) {
+                    if (existingResponse.isComplete()) {
+                        listener.onServiceFound(
+                                buildMdnsServiceInfoFromResponse(existingResponse,
+                                        serviceTypeLabels));
+                    }
+                }
+            }
+            // Cancel the next scheduled periodical task.
+            if (requestTaskFuture != null) {
+                requestTaskFuture.cancel(true);
+            }
+            // Keep tracking the ScheduledFuture for the task so we can cancel it if caller is not
+            // interested anymore.
+            requestTaskFuture =
+                    executor.submit(
+                            new QueryTask(
+                                    new QueryTaskConfig(
+                                            searchOptions.getSubtypes(),
+                                            searchOptions.isPassiveMode(),
+                                            ++currentSessionId)));
+        }
+    }
+
+    /**
+     * Unregisters {@code listener} from receiving discovery event of mDNS service instances.
+     *
+     * @param listener The {@link MdnsServiceBrowserListener} to unregister.
+     * @return {@code true} if no listener is registered with this client after unregistering {@code
+     * listener}. Otherwise returns {@code false}.
+     */
+    public boolean stopSendAndReceive(@NonNull MdnsServiceBrowserListener listener) {
+        synchronized (lock) {
+            listeners.remove(listener);
+            if (listeners.isEmpty() && requestTaskFuture != null) {
+                requestTaskFuture.cancel(true);
+                requestTaskFuture = null;
+            }
+            return listeners.isEmpty();
+        }
+    }
+
+    public String[] getServiceTypeLabels() {
+        return serviceTypeLabels;
+    }
+
+    public synchronized void processResponse(@NonNull MdnsResponse response) {
+        if (response.isGoodbye()) {
+            onGoodbyeReceived(response.getServiceInstanceName());
+        } else {
+            onResponseReceived(response);
+        }
+    }
+
+    public synchronized void onFailedToParseMdnsResponse(int receivedPacketNumber, int errorCode) {
+        for (MdnsServiceBrowserListener listener : listeners) {
+            listener.onFailedToParseMdnsResponse(receivedPacketNumber, errorCode);
+        }
+    }
+
+    private void onResponseReceived(@NonNull MdnsResponse response) {
+        MdnsResponse currentResponse;
+        currentResponse = instanceNameToResponse.get(response.getServiceInstanceName());
+
+        boolean newServiceFound = false;
+        boolean existingServiceChanged = false;
+        if (currentResponse == null) {
+            newServiceFound = true;
+            currentResponse = response;
+            instanceNameToResponse.put(response.getServiceInstanceName(), currentResponse);
+        } else if (currentResponse.mergeRecordsFrom(response)) {
+            existingServiceChanged = true;
+        }
+        if (!currentResponse.isComplete() || (!newServiceFound && !existingServiceChanged)) {
+            return;
+        }
+        MdnsServiceInfo serviceInfo =
+                buildMdnsServiceInfoFromResponse(currentResponse, serviceTypeLabels);
+
+        for (MdnsServiceBrowserListener listener : listeners) {
+            if (newServiceFound) {
+                listener.onServiceFound(serviceInfo);
+            } else {
+                listener.onServiceUpdated(serviceInfo);
+            }
+        }
+    }
+
+    private void onGoodbyeReceived(@NonNull String serviceInstanceName) {
+        instanceNameToResponse.remove(serviceInstanceName);
+        for (MdnsServiceBrowserListener listener : listeners) {
+            listener.onServiceRemoved(serviceInstanceName);
+        }
+    }
+
+    @VisibleForTesting
+    MdnsPacketWriter createMdnsPacketWriter() {
+        return new MdnsPacketWriter(DEFAULT_MTU);
+    }
+
+    // A configuration for the PeriodicalQueryTask that contains parameters to build a query packet.
+    // Call to getConfigForNextRun returns a config that can be used to build the next query task.
+    @VisibleForTesting
+    static class QueryTaskConfig {
+
+        private static final int INITIAL_TIME_BETWEEN_BURSTS_MS =
+                (int) MdnsConfigs.initialTimeBetweenBurstsMs();
+        private static final int TIME_BETWEEN_BURSTS_MS = (int) MdnsConfigs.timeBetweenBurstsMs();
+        private static final int QUERIES_PER_BURST = (int) MdnsConfigs.queriesPerBurst();
+        private static final int TIME_BETWEEN_QUERIES_IN_BURST_MS =
+                (int) MdnsConfigs.timeBetweenQueriesInBurstMs();
+        private static final int QUERIES_PER_BURST_PASSIVE_MODE =
+                (int) MdnsConfigs.queriesPerBurstPassive();
+        private static final int UNSIGNED_SHORT_MAX_VALUE = 65536;
+        // The following fields are used by QueryTask so we need to test them.
+        @VisibleForTesting
+        final List<String> subtypes;
+        private final boolean alwaysAskForUnicastResponse =
+                MdnsConfigs.alwaysAskForUnicastResponseInEachBurst();
+        private final boolean usePassiveMode;
+        private final long sessionId;
+        @VisibleForTesting
+        int transactionId;
+        @VisibleForTesting
+        boolean expectUnicastResponse;
+        private int queriesPerBurst;
+        private int timeBetweenBurstsInMs;
+        private int burstCounter;
+        private int timeToRunNextTaskInMs;
+        private boolean isFirstBurst;
+
+        QueryTaskConfig(@NonNull Collection<String> subtypes, boolean usePassiveMode,
+                long sessionId) {
+            this.usePassiveMode = usePassiveMode;
+            this.subtypes = new ArrayList<>(subtypes);
+            this.queriesPerBurst = QUERIES_PER_BURST;
+            this.burstCounter = 0;
+            this.transactionId = 1;
+            this.expectUnicastResponse = true;
+            this.isFirstBurst = true;
+            this.sessionId = sessionId;
+            // Config the scan frequency based on the scan mode.
+            if (this.usePassiveMode) {
+                // In passive scan mode, sends a single burst of QUERIES_PER_BURST queries, and then
+                // in each TIME_BETWEEN_BURSTS interval, sends QUERIES_PER_BURST_PASSIVE_MODE
+                // queries.
+                this.timeBetweenBurstsInMs = TIME_BETWEEN_BURSTS_MS;
+            } else {
+                // In active scan mode, sends a burst of QUERIES_PER_BURST queries,
+                // TIME_BETWEEN_QUERIES_IN_BURST_MS apart, then waits for the scan interval, and
+                // then repeats. The scan interval starts as INITIAL_TIME_BETWEEN_BURSTS_MS and
+                // doubles until it maxes out at TIME_BETWEEN_BURSTS_MS.
+                this.timeBetweenBurstsInMs = INITIAL_TIME_BETWEEN_BURSTS_MS;
+            }
+        }
+
+        QueryTaskConfig getConfigForNextRun() {
+            if (++transactionId > UNSIGNED_SHORT_MAX_VALUE) {
+                transactionId = 1;
+            }
+            // Only the first query expects uni-cast response.
+            expectUnicastResponse = false;
+            if (++burstCounter == queriesPerBurst) {
+                burstCounter = 0;
+
+                if (alwaysAskForUnicastResponse) {
+                    expectUnicastResponse = true;
+                }
+                // In passive scan mode, sends a single burst of QUERIES_PER_BURST queries, and
+                // then in each TIME_BETWEEN_BURSTS interval, sends QUERIES_PER_BURST_PASSIVE_MODE
+                // queries.
+                if (isFirstBurst) {
+                    isFirstBurst = false;
+                    if (usePassiveMode) {
+                        queriesPerBurst = QUERIES_PER_BURST_PASSIVE_MODE;
+                    }
+                }
+                // In active scan mode, sends a burst of QUERIES_PER_BURST queries,
+                // TIME_BETWEEN_QUERIES_IN_BURST_MS apart, then waits for the scan interval, and
+                // then repeats. The scan interval starts as INITIAL_TIME_BETWEEN_BURSTS_MS and
+                // doubles until it maxes out at TIME_BETWEEN_BURSTS_MS.
+                timeToRunNextTaskInMs = timeBetweenBurstsInMs;
+                if (timeBetweenBurstsInMs < TIME_BETWEEN_BURSTS_MS) {
+                    timeBetweenBurstsInMs = Math.min(timeBetweenBurstsInMs * 2,
+                            TIME_BETWEEN_BURSTS_MS);
+                }
+            } else {
+                timeToRunNextTaskInMs = TIME_BETWEEN_QUERIES_IN_BURST_MS;
+            }
+            return this;
+        }
+    }
+
+    // A FutureTask that enqueues a single query, and schedule a new FutureTask for the next task.
+    private class QueryTask implements Runnable {
+
+        private final QueryTaskConfig config;
+
+        QueryTask(@NonNull QueryTaskConfig config) {
+            this.config = config;
+        }
+
+        @Override
+        public void run() {
+            Pair<Integer, List<String>> result;
+            try {
+                result =
+                        new EnqueueMdnsQueryCallable(
+                                socketClient,
+                                createMdnsPacketWriter(),
+                                serviceType,
+                                config.subtypes,
+                                config.expectUnicastResponse,
+                                config.transactionId)
+                                .call();
+            } catch (Exception e) {
+                LOGGER.e(String.format("Failed to run EnqueueMdnsQueryCallable for subtype: %s",
+                        TextUtils.join(",", config.subtypes)), e);
+                result = null;
+            }
+            synchronized (lock) {
+                if (MdnsConfigs.useSessionIdToScheduleMdnsTask()) {
+                    // In case that the task is not canceled successfully, use session ID to check
+                    // if this task should continue to schedule more.
+                    if (config.sessionId != currentSessionId) {
+                        return;
+                    }
+                }
+
+                if (MdnsConfigs.shouldCancelScanTaskWhenFutureIsNull()) {
+                    if (requestTaskFuture == null) {
+                        // If requestTaskFuture is set to null, the task is cancelled. We can't use
+                        // isCancelled() here because this QueryTask is different from the future
+                        // that is returned from executor.schedule(). See b/71646910.
+                        return;
+                    }
+                }
+                if ((result != null)) {
+                    for (MdnsServiceBrowserListener listener : listeners) {
+                        listener.onDiscoveryQuerySent(result.second, result.first);
+                    }
+                }
+                QueryTaskConfig config = this.config.getConfigForNextRun();
+                requestTaskFuture =
+                        executor.schedule(
+                                new QueryTask(config), config.timeToRunNextTaskInMs,
+                                TimeUnit.MILLISECONDS);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsSocket.java b/service/mdns/com/android/server/connectivity/mdns/MdnsSocket.java
new file mode 100644
index 0000000..241a52a
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsSocket.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetSocketAddress;
+import java.net.MulticastSocket;
+import java.util.List;
+
+/**
+ * {@link MdnsSocket} provides a similar interface to {@link MulticastSocket} and binds to all
+ * available multi-cast network interfaces.
+ *
+ * @see MulticastSocket for javadoc of each public method.
+ */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+public class MdnsSocket {
+    private static final InetSocketAddress MULTICAST_IPV4_ADDRESS =
+            new InetSocketAddress(MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT);
+    private static final InetSocketAddress MULTICAST_IPV6_ADDRESS =
+            new InetSocketAddress(MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT);
+    private static boolean isOnIPv6OnlyNetwork = false;
+    private final MulticastNetworkInterfaceProvider multicastNetworkInterfaceProvider;
+    private final MulticastSocket multicastSocket;
+
+    public MdnsSocket(
+            @NonNull MulticastNetworkInterfaceProvider multicastNetworkInterfaceProvider, int port)
+            throws IOException {
+        this.multicastNetworkInterfaceProvider = multicastNetworkInterfaceProvider;
+        this.multicastNetworkInterfaceProvider.startWatchingConnectivityChanges();
+        multicastSocket = createMulticastSocket(port);
+        // RFC Spec: https://tools.ietf.org/html/rfc6762
+        // Time to live is set 255, which is similar to the jMDNS implementation.
+        multicastSocket.setTimeToLive(255);
+
+        // TODO (changed when importing code): consider tagging the socket for data usage
+        isOnIPv6OnlyNetwork = false;
+    }
+
+    public void send(DatagramPacket packet) throws IOException {
+        List<NetworkInterfaceWrapper> networkInterfaces =
+                multicastNetworkInterfaceProvider.getMulticastNetworkInterfaces();
+        for (NetworkInterfaceWrapper networkInterface : networkInterfaces) {
+            multicastSocket.setNetworkInterface(networkInterface.getNetworkInterface());
+            multicastSocket.send(packet);
+        }
+    }
+
+    public void receive(DatagramPacket packet) throws IOException {
+        multicastSocket.receive(packet);
+    }
+
+    public void joinGroup() throws IOException {
+        List<NetworkInterfaceWrapper> networkInterfaces =
+                multicastNetworkInterfaceProvider.getMulticastNetworkInterfaces();
+        InetSocketAddress multicastAddress = MULTICAST_IPV4_ADDRESS;
+        if (multicastNetworkInterfaceProvider.isOnIpV6OnlyNetwork(networkInterfaces)) {
+            isOnIPv6OnlyNetwork = true;
+            multicastAddress = MULTICAST_IPV6_ADDRESS;
+        } else {
+            isOnIPv6OnlyNetwork = false;
+        }
+        for (NetworkInterfaceWrapper networkInterface : networkInterfaces) {
+            multicastSocket.joinGroup(multicastAddress, networkInterface.getNetworkInterface());
+        }
+    }
+
+    public void leaveGroup() throws IOException {
+        List<NetworkInterfaceWrapper> networkInterfaces =
+                multicastNetworkInterfaceProvider.getMulticastNetworkInterfaces();
+        InetSocketAddress multicastAddress = MULTICAST_IPV4_ADDRESS;
+        if (multicastNetworkInterfaceProvider.isOnIpV6OnlyNetwork(networkInterfaces)) {
+            multicastAddress = MULTICAST_IPV6_ADDRESS;
+        }
+        for (NetworkInterfaceWrapper networkInterface : networkInterfaces) {
+            multicastSocket.leaveGroup(multicastAddress, networkInterface.getNetworkInterface());
+        }
+    }
+
+    public void close() {
+        // This is a race with the use of the file descriptor (b/27403984).
+        multicastSocket.close();
+        multicastNetworkInterfaceProvider.stopWatchingConnectivityChanges();
+    }
+
+    @VisibleForTesting
+    MulticastSocket createMulticastSocket(int port) throws IOException {
+        return new MulticastSocket(port);
+    }
+
+    public boolean isOnIPv6OnlyNetwork() {
+        return isOnIPv6OnlyNetwork;
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsSocketClient.java b/service/mdns/com/android/server/connectivity/mdns/MdnsSocketClient.java
new file mode 100644
index 0000000..e689d6c
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsSocketClient.java
@@ -0,0 +1,504 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.Manifest.permission;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.content.Context;
+import android.net.wifi.WifiManager.MulticastLock;
+import android.os.SystemClock;
+import android.text.format.DateUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.connectivity.mdns.util.MdnsLogger;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * The {@link MdnsSocketClient} maintains separate threads to send and receive mDNS packets for all
+ * the requested service types.
+ *
+ * <p>See https://tools.ietf.org/html/rfc6763 (namely sections 4 and 5).
+ */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+public class MdnsSocketClient {
+
+    private static final String TAG = "MdnsClient";
+    // TODO: The following values are copied from cast module. We need to think about the
+    // better way to share those.
+    private static final String CAST_SENDER_LOG_SOURCE = "CAST_SENDER_SDK";
+    private static final String CAST_PREFS_NAME = "google_cast";
+    private static final String PREF_CAST_SENDER_ID = "PREF_CAST_SENDER_ID";
+    private static final MdnsLogger LOGGER = new MdnsLogger(TAG);
+    private static final String MULTICAST_TYPE = "multicast";
+    private static final String UNICAST_TYPE = "unicast";
+
+    private static final long SLEEP_TIME_FOR_SOCKET_THREAD_MS =
+            MdnsConfigs.sleepTimeForSocketThreadMs();
+    // A value of 0 leads to an infinite wait.
+    private static final long THREAD_JOIN_TIMEOUT_MS = DateUtils.SECOND_IN_MILLIS;
+    private static final int RECEIVER_BUFFER_SIZE = 2048;
+    @VisibleForTesting
+    final Queue<DatagramPacket> multicastPacketQueue = new ArrayDeque<>();
+    @VisibleForTesting
+    final Queue<DatagramPacket> unicastPacketQueue = new ArrayDeque<>();
+    private final Context context;
+    private final byte[] multicastReceiverBuffer = new byte[RECEIVER_BUFFER_SIZE];
+    private final byte[] unicastReceiverBuffer;
+    private final MdnsResponseDecoder responseDecoder;
+    private final MulticastLock multicastLock;
+    private final boolean useSeparateSocketForUnicast =
+            MdnsConfigs.useSeparateSocketToSendUnicastQuery();
+    private final boolean checkMulticastResponse = MdnsConfigs.checkMulticastResponse();
+    private final long checkMulticastResponseIntervalMs =
+            MdnsConfigs.checkMulticastResponseIntervalMs();
+    private final Object socketLock = new Object();
+    private final Object timerObject = new Object();
+    // If multicast response was received in the current session. The value is reset in the
+    // beginning of each session.
+    @VisibleForTesting
+    boolean receivedMulticastResponse;
+    // If unicast response was received in the current session. The value is reset in the beginning
+    // of each session.
+    @VisibleForTesting
+    boolean receivedUnicastResponse;
+    // If the phone is the bad state where it can't receive any multicast response.
+    @VisibleForTesting
+    AtomicBoolean cannotReceiveMulticastResponse = new AtomicBoolean(false);
+    @VisibleForTesting
+    volatile Thread sendThread;
+    @VisibleForTesting
+    Thread multicastReceiveThread;
+    @VisibleForTesting
+    Thread unicastReceiveThread;
+    private volatile boolean shouldStopSocketLoop;
+    private Callback callback;
+    private MdnsSocket multicastSocket;
+    private MdnsSocket unicastSocket;
+    private int receivedPacketNumber = 0;
+    private Timer logMdnsPacketTimer;
+    private AtomicInteger packetsCount;
+    private Timer checkMulticastResponseTimer;
+
+    public MdnsSocketClient(@NonNull Context context, @NonNull MulticastLock multicastLock) {
+        this.context = context;
+        this.multicastLock = multicastLock;
+        responseDecoder = new MdnsResponseDecoder(new MdnsResponseDecoder.Clock(), null);
+        if (useSeparateSocketForUnicast) {
+            unicastReceiverBuffer = new byte[RECEIVER_BUFFER_SIZE];
+        } else {
+            unicastReceiverBuffer = null;
+        }
+    }
+
+    public synchronized void setCallback(@Nullable Callback callback) {
+        this.callback = callback;
+    }
+
+    @RequiresPermission(permission.CHANGE_WIFI_MULTICAST_STATE)
+    public synchronized void startDiscovery() throws IOException {
+        if (multicastSocket != null) {
+            LOGGER.w("Discovery is already in progress.");
+            return;
+        }
+
+        receivedMulticastResponse = false;
+        receivedUnicastResponse = false;
+        cannotReceiveMulticastResponse.set(false);
+
+        shouldStopSocketLoop = false;
+        try {
+            // TODO (changed when importing code): consider setting thread stats tag
+            multicastSocket = createMdnsSocket(MdnsConstants.MDNS_PORT);
+            multicastSocket.joinGroup();
+            if (useSeparateSocketForUnicast) {
+                // For unicast, use port 0 and the system will assign it with any available port.
+                unicastSocket = createMdnsSocket(0);
+            }
+            multicastLock.acquire();
+        } catch (IOException e) {
+            multicastLock.release();
+            if (multicastSocket != null) {
+                multicastSocket.close();
+                multicastSocket = null;
+            }
+            if (unicastSocket != null) {
+                unicastSocket.close();
+                unicastSocket = null;
+            }
+            throw e;
+        } finally {
+            // TODO (changed when importing code): consider resetting thread stats tag
+        }
+        createAndStartSendThread();
+        createAndStartReceiverThreads();
+    }
+
+    @RequiresPermission(permission.CHANGE_WIFI_MULTICAST_STATE)
+    public void stopDiscovery() {
+        LOGGER.log("Stop discovery.");
+        if (multicastSocket == null && unicastSocket == null) {
+            return;
+        }
+
+        if (MdnsConfigs.clearMdnsPacketQueueAfterDiscoveryStops()) {
+            synchronized (multicastPacketQueue) {
+                multicastPacketQueue.clear();
+            }
+            synchronized (unicastPacketQueue) {
+                unicastPacketQueue.clear();
+            }
+        }
+
+        multicastLock.release();
+
+        shouldStopSocketLoop = true;
+        waitForSendThreadToStop();
+        waitForReceiverThreadsToStop();
+
+        synchronized (socketLock) {
+            multicastSocket = null;
+            unicastSocket = null;
+        }
+
+        synchronized (timerObject) {
+            if (checkMulticastResponseTimer != null) {
+                checkMulticastResponseTimer.cancel();
+                checkMulticastResponseTimer = null;
+            }
+        }
+    }
+
+    /** Sends a mDNS request packet that asks for multicast response. */
+    public void sendMulticastPacket(@NonNull DatagramPacket packet) {
+        sendMdnsPacket(packet, multicastPacketQueue);
+    }
+
+    /** Sends a mDNS request packet that asks for unicast response. */
+    public void sendUnicastPacket(DatagramPacket packet) {
+        if (useSeparateSocketForUnicast) {
+            sendMdnsPacket(packet, unicastPacketQueue);
+        } else {
+            sendMdnsPacket(packet, multicastPacketQueue);
+        }
+    }
+
+    private void sendMdnsPacket(DatagramPacket packet, Queue<DatagramPacket> packetQueueToUse) {
+        if (shouldStopSocketLoop && !MdnsConfigs.allowAddMdnsPacketAfterDiscoveryStops()) {
+            LOGGER.w("sendMdnsPacket() is called after discovery already stopped");
+            return;
+        }
+        synchronized (packetQueueToUse) {
+            while (packetQueueToUse.size() >= MdnsConfigs.mdnsPacketQueueMaxSize()) {
+                packetQueueToUse.remove();
+            }
+            packetQueueToUse.add(packet);
+        }
+        triggerSendThread();
+    }
+
+    private void createAndStartSendThread() {
+        if (sendThread != null) {
+            LOGGER.w("A socket thread already exists.");
+            return;
+        }
+        sendThread = new Thread(this::sendThreadMain);
+        sendThread.setName("mdns-send");
+        sendThread.start();
+    }
+
+    private void createAndStartReceiverThreads() {
+        if (multicastReceiveThread != null) {
+            LOGGER.w("A multicast receiver thread already exists.");
+            return;
+        }
+        multicastReceiveThread =
+                new Thread(() -> receiveThreadMain(multicastReceiverBuffer, multicastSocket));
+        multicastReceiveThread.setName("mdns-multicast-receive");
+        multicastReceiveThread.start();
+
+        if (useSeparateSocketForUnicast) {
+            unicastReceiveThread =
+                    new Thread(() -> receiveThreadMain(unicastReceiverBuffer, unicastSocket));
+            unicastReceiveThread.setName("mdns-unicast-receive");
+            unicastReceiveThread.start();
+        }
+    }
+
+    private void triggerSendThread() {
+        LOGGER.log("Trigger send thread.");
+        Thread sendThread = this.sendThread;
+        if (sendThread != null) {
+            sendThread.interrupt();
+        } else {
+            LOGGER.w("Socket thread is null");
+        }
+    }
+
+    private void waitForReceiverThreadsToStop() {
+        if (multicastReceiveThread != null) {
+            waitForThread(multicastReceiveThread);
+            multicastReceiveThread = null;
+        }
+
+        if (unicastReceiveThread != null) {
+            waitForThread(unicastReceiveThread);
+            unicastReceiveThread = null;
+        }
+    }
+
+    private void waitForSendThreadToStop() {
+        LOGGER.log("wait For Send Thread To Stop");
+        if (sendThread == null) {
+            LOGGER.w("socket thread is already dead.");
+            return;
+        }
+        waitForThread(sendThread);
+        sendThread = null;
+    }
+
+    private void waitForThread(Thread thread) {
+        long startMs = SystemClock.elapsedRealtime();
+        long waitMs = THREAD_JOIN_TIMEOUT_MS;
+        while (thread.isAlive() && (waitMs > 0)) {
+            try {
+                thread.interrupt();
+                thread.join(waitMs);
+                if (thread.isAlive()) {
+                    LOGGER.w("Failed to join thread: " + thread);
+                }
+                break;
+            } catch (InterruptedException e) {
+                // Compute remaining time after at least a single join call, in case the clock
+                // resolution is poor.
+                waitMs = THREAD_JOIN_TIMEOUT_MS - (SystemClock.elapsedRealtime() - startMs);
+            }
+        }
+    }
+
+    private void sendThreadMain() {
+        List<DatagramPacket> multicastPacketsToSend = new ArrayList<>();
+        List<DatagramPacket> unicastPacketsToSend = new ArrayList<>();
+        boolean shouldThreadSleep;
+        try {
+            while (!shouldStopSocketLoop) {
+                try {
+                    // Make a local copy of all packets, and clear the queue.
+                    // Send packets that ask for multicast response.
+                    multicastPacketsToSend.clear();
+                    synchronized (multicastPacketQueue) {
+                        multicastPacketsToSend.addAll(multicastPacketQueue);
+                        multicastPacketQueue.clear();
+                    }
+
+                    // Send packets that ask for unicast response.
+                    if (useSeparateSocketForUnicast) {
+                        unicastPacketsToSend.clear();
+                        synchronized (unicastPacketQueue) {
+                            unicastPacketsToSend.addAll(unicastPacketQueue);
+                            unicastPacketQueue.clear();
+                        }
+                    }
+
+                    // Send all the packets.
+                    sendPackets(multicastPacketsToSend, multicastSocket);
+                    sendPackets(unicastPacketsToSend, unicastSocket);
+
+                    // Sleep ONLY if no more packets have been added to the queue, while packets
+                    // were being sent.
+                    synchronized (multicastPacketQueue) {
+                        synchronized (unicastPacketQueue) {
+                            shouldThreadSleep =
+                                    multicastPacketQueue.isEmpty() && unicastPacketQueue.isEmpty();
+                        }
+                    }
+                    if (shouldThreadSleep) {
+                        Thread.sleep(SLEEP_TIME_FOR_SOCKET_THREAD_MS);
+                    }
+                } catch (InterruptedException e) {
+                    // Don't log the interruption as it's expected.
+                }
+            }
+        } finally {
+            LOGGER.log("Send thread stopped.");
+            try {
+                multicastSocket.leaveGroup();
+            } catch (Exception t) {
+                LOGGER.e("Failed to leave the group.", t);
+            }
+
+            // Close the socket first. This is the only way to interrupt a blocking receive.
+            try {
+                // This is a race with the use of the file descriptor (b/27403984).
+                multicastSocket.close();
+                if (unicastSocket != null) {
+                    unicastSocket.close();
+                }
+            } catch (Exception t) {
+                LOGGER.e("Failed to close the mdns socket.", t);
+            }
+        }
+    }
+
+    private void receiveThreadMain(byte[] receiverBuffer, MdnsSocket socket) {
+        DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length);
+
+        while (!shouldStopSocketLoop) {
+            try {
+                // This is a race with the use of the file descriptor (b/27403984).
+                synchronized (socketLock) {
+                    // This checks is to make sure the socket was not set to null.
+                    if (socket != null && (socket == multicastSocket || socket == unicastSocket)) {
+                        socket.receive(packet);
+                    }
+                }
+
+                if (!shouldStopSocketLoop) {
+                    String responseType = socket == multicastSocket ? MULTICAST_TYPE : UNICAST_TYPE;
+                    processResponsePacket(packet, responseType);
+                }
+            } catch (IOException e) {
+                if (!shouldStopSocketLoop) {
+                    LOGGER.e("Failed to receive mDNS packets.", e);
+                }
+            }
+        }
+        LOGGER.log("Receive thread stopped.");
+    }
+
+    private int processResponsePacket(@NonNull DatagramPacket packet, String responseType)
+            throws IOException {
+        int packetNumber = ++receivedPacketNumber;
+
+        List<MdnsResponse> responses = new LinkedList<>();
+        int errorCode = responseDecoder.decode(packet, responses);
+        if (errorCode == MdnsResponseDecoder.SUCCESS) {
+            if (responseType.equals(MULTICAST_TYPE)) {
+                receivedMulticastResponse = true;
+                if (cannotReceiveMulticastResponse.getAndSet(false)) {
+                    // If we are already in the bad state, receiving a multicast response means
+                    // we are recovered.
+                    LOGGER.e(
+                            "Recovered from the state where the phone can't receive any multicast"
+                                    + " response");
+                }
+            } else {
+                receivedUnicastResponse = true;
+            }
+            for (MdnsResponse response : responses) {
+                String serviceInstanceName = response.getServiceInstanceName();
+                LOGGER.log("mDNS %s response received: %s", responseType, serviceInstanceName);
+                if (callback != null) {
+                    callback.onResponseReceived(response);
+                }
+            }
+        } else if (errorCode != MdnsResponseErrorCode.ERROR_NOT_RESPONSE_MESSAGE) {
+            LOGGER.w(String.format("Error while decoding %s packet (%d): %d",
+                    responseType, packetNumber, errorCode));
+            if (callback != null) {
+                callback.onFailedToParseMdnsResponse(packetNumber, errorCode);
+            }
+        }
+        return errorCode;
+    }
+
+    @VisibleForTesting
+    MdnsSocket createMdnsSocket(int port) throws IOException {
+        return new MdnsSocket(new MulticastNetworkInterfaceProvider(context), port);
+    }
+
+    private void sendPackets(List<DatagramPacket> packets, MdnsSocket socket) {
+        String requestType = socket == multicastSocket ? "multicast" : "unicast";
+        for (DatagramPacket packet : packets) {
+            if (shouldStopSocketLoop) {
+                break;
+            }
+            try {
+                LOGGER.log("Sending a %s mDNS packet...", requestType);
+                socket.send(packet);
+
+                // Start the timer task to monitor the response.
+                synchronized (timerObject) {
+                    if (socket == multicastSocket) {
+                        if (cannotReceiveMulticastResponse.get()) {
+                            // Don't schedule the timer task if we are already in the bad state.
+                            return;
+                        }
+                        if (checkMulticastResponseTimer != null) {
+                            // Don't schedule the timer task if it's already scheduled.
+                            return;
+                        }
+                        if (checkMulticastResponse && useSeparateSocketForUnicast) {
+                            // Only when useSeparateSocketForUnicast is true, we can tell if we
+                            // received a multicast or unicast response.
+                            checkMulticastResponseTimer = new Timer();
+                            checkMulticastResponseTimer.schedule(
+                                    new TimerTask() {
+                                        @Override
+                                        public void run() {
+                                            synchronized (timerObject) {
+                                                if (checkMulticastResponseTimer == null) {
+                                                    // Discovery already stopped.
+                                                    return;
+                                                }
+                                                if ((!receivedMulticastResponse)
+                                                        && receivedUnicastResponse) {
+                                                    LOGGER.e(String.format(
+                                                            "Haven't received multicast response"
+                                                                    + " in the last %d ms.",
+                                                            checkMulticastResponseIntervalMs));
+                                                    cannotReceiveMulticastResponse.set(true);
+                                                }
+                                                checkMulticastResponseTimer = null;
+                                            }
+                                        }
+                                    },
+                                    checkMulticastResponseIntervalMs);
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                LOGGER.e(String.format("Failed to send a %s mDNS packet.", requestType), e);
+            }
+        }
+        packets.clear();
+    }
+
+    public boolean isOnIPv6OnlyNetwork() {
+        return multicastSocket.isOnIPv6OnlyNetwork();
+    }
+
+    /** Callback for {@link MdnsSocketClient}. */
+    public interface Callback {
+        void onResponseReceived(@NonNull MdnsResponse response);
+
+        void onFailedToParseMdnsResponse(int receivedPacketNumber, int errorCode);
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
new file mode 100644
index 0000000..a5b5595
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/** An mDNS "TXT" record, which contains a list of text strings. */
+// TODO(b/177655645): Resolve nullness suppression.
+@SuppressWarnings("nullness")
+@VisibleForTesting
+public class MdnsTextRecord extends MdnsRecord {
+    private List<String> strings;
+
+    public MdnsTextRecord(String[] name, MdnsPacketReader reader) throws IOException {
+        super(name, TYPE_TXT, reader);
+    }
+
+    /** Returns the list of strings. */
+    public List<String> getStrings() {
+        return Collections.unmodifiableList(strings);
+    }
+
+    @Override
+    protected void readData(MdnsPacketReader reader) throws IOException {
+        strings = new ArrayList<>();
+        while (reader.getRemaining() > 0) {
+            strings.add(reader.readString());
+        }
+    }
+
+    @Override
+    protected void writeData(MdnsPacketWriter writer) throws IOException {
+        if (strings != null) {
+            for (String string : strings) {
+                writer.writeString(string);
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("TXT: {");
+        if (strings != null) {
+            for (String string : strings) {
+                sb.append(' ').append(string);
+            }
+        }
+        sb.append("}");
+
+        return sb.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return (super.hashCode() * 31) + Objects.hash(strings);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof MdnsTextRecord)) {
+            return false;
+        }
+
+        return super.equals(other) && Objects.equals(strings, ((MdnsTextRecord) other).strings);
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MulticastNetworkInterfaceProvider.java b/service/mdns/com/android/server/connectivity/mdns/MulticastNetworkInterfaceProvider.java
new file mode 100644
index 0000000..e0d8fa6
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MulticastNetworkInterfaceProvider.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.connectivity.mdns.util.MdnsLogger;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * This class is used by the {@link MdnsSocket} to monitor the list of {@link NetworkInterface}
+ * instances that are currently available for multi-cast messaging.
+ */
+public class MulticastNetworkInterfaceProvider {
+
+    private static final String TAG = "MdnsNIProvider";
+    private static final MdnsLogger LOGGER = new MdnsLogger(TAG);
+    private static final boolean PREFER_IPV6 = MdnsConfigs.preferIpv6();
+
+    private final List<NetworkInterfaceWrapper> multicastNetworkInterfaces = new ArrayList<>();
+    // Only modifiable from tests.
+    @VisibleForTesting
+    ConnectivityMonitor connectivityMonitor;
+    private volatile boolean connectivityChanged = true;
+
+    @SuppressWarnings("nullness:methodref.receiver.bound")
+    public MulticastNetworkInterfaceProvider(@NonNull Context context) {
+        // IMPORT CHANGED
+        this.connectivityMonitor = new ConnectivityMonitorWithConnectivityManager(
+                context, this::onConnectivityChanged);
+    }
+
+    private void onConnectivityChanged() {
+        connectivityChanged = true;
+    }
+
+    /**
+     * Starts monitoring changes of connectivity of this device, which may indicate that the list of
+     * network interfaces available for multi-cast messaging has changed.
+     */
+    public void startWatchingConnectivityChanges() {
+        connectivityMonitor.startWatchingConnectivityChanges();
+    }
+
+    /** Stops monitoring changes of connectivity. */
+    public void stopWatchingConnectivityChanges() {
+        connectivityMonitor.stopWatchingConnectivityChanges();
+    }
+
+    /**
+     * Returns the list of {@link NetworkInterfaceWrapper} instances available for multi-cast
+     * messaging.
+     */
+    public synchronized List<NetworkInterfaceWrapper> getMulticastNetworkInterfaces() {
+        if (connectivityChanged) {
+            connectivityChanged = false;
+            updateMulticastNetworkInterfaces();
+            if (multicastNetworkInterfaces.isEmpty()) {
+                LOGGER.log("No network interface available for mDNS scanning.");
+            }
+        }
+        return new ArrayList<>(multicastNetworkInterfaces);
+    }
+
+    private void updateMulticastNetworkInterfaces() {
+        multicastNetworkInterfaces.clear();
+        List<NetworkInterfaceWrapper> networkInterfaceWrappers = getNetworkInterfaces();
+        for (NetworkInterfaceWrapper interfaceWrapper : networkInterfaceWrappers) {
+            if (canScanOnInterface(interfaceWrapper)) {
+                multicastNetworkInterfaces.add(interfaceWrapper);
+            }
+        }
+    }
+
+    public boolean isOnIpV6OnlyNetwork(List<NetworkInterfaceWrapper> networkInterfaces) {
+        if (networkInterfaces.isEmpty()) {
+            return false;
+        }
+
+        // TODO(b/79866499): Remove this when the bug is resolved.
+        if (PREFER_IPV6) {
+            return true;
+        }
+        boolean hasAtleastOneIPv6Address = false;
+        for (NetworkInterfaceWrapper interfaceWrapper : networkInterfaces) {
+            for (InterfaceAddress ifAddr : interfaceWrapper.getInterfaceAddresses()) {
+                if (!(ifAddr.getAddress() instanceof Inet6Address)) {
+                    return false;
+                } else {
+                    hasAtleastOneIPv6Address = true;
+                }
+            }
+        }
+        return hasAtleastOneIPv6Address;
+    }
+
+    @VisibleForTesting
+    List<NetworkInterfaceWrapper> getNetworkInterfaces() {
+        List<NetworkInterfaceWrapper> networkInterfaceWrappers = new ArrayList<>();
+        try {
+            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+            if (interfaces != null) {
+                while (interfaces.hasMoreElements()) {
+                    networkInterfaceWrappers.add(
+                            new NetworkInterfaceWrapper(interfaces.nextElement()));
+                }
+            }
+        } catch (SocketException e) {
+            LOGGER.e("Failed to get network interfaces.", e);
+        } catch (NullPointerException e) {
+            // Android R has a bug that could lead to a NPE. See b/159277702.
+            LOGGER.e("Failed to call getNetworkInterfaces API", e);
+        }
+
+        return networkInterfaceWrappers;
+    }
+
+    private boolean canScanOnInterface(@Nullable NetworkInterfaceWrapper networkInterface) {
+        try {
+            if ((networkInterface == null)
+                    || networkInterface.isLoopback()
+                    || networkInterface.isPointToPoint()
+                    || networkInterface.isVirtual()
+                    || !networkInterface.isUp()
+                    || !networkInterface.supportsMulticast()) {
+                return false;
+            }
+            return hasInet4Address(networkInterface) || hasInet6Address(networkInterface);
+        } catch (IOException e) {
+            LOGGER.e(String.format("Failed to check interface %s.",
+                    networkInterface.getNetworkInterface().getDisplayName()), e);
+        }
+
+        return false;
+    }
+
+    private boolean hasInet4Address(@NonNull NetworkInterfaceWrapper networkInterface) {
+        for (InterfaceAddress ifAddr : networkInterface.getInterfaceAddresses()) {
+            if (ifAddr.getAddress() instanceof Inet4Address) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean hasInet6Address(@NonNull NetworkInterfaceWrapper networkInterface) {
+        for (InterfaceAddress ifAddr : networkInterface.getInterfaceAddresses()) {
+            if (ifAddr.getAddress() instanceof Inet6Address) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/NetworkInterfaceWrapper.java b/service/mdns/com/android/server/connectivity/mdns/NetworkInterfaceWrapper.java
new file mode 100644
index 0000000..0ecae48
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/NetworkInterfaceWrapper.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns;
+
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.List;
+
+/** A wrapper class of {@link NetworkInterface} to be mocked in unit tests. */
+public class NetworkInterfaceWrapper {
+    private final NetworkInterface networkInterface;
+
+    public NetworkInterfaceWrapper(NetworkInterface networkInterface) {
+        this.networkInterface = networkInterface;
+    }
+
+    public NetworkInterface getNetworkInterface() {
+        return networkInterface;
+    }
+
+    public boolean isUp() throws SocketException {
+        return networkInterface.isUp();
+    }
+
+    public boolean isLoopback() throws SocketException {
+        return networkInterface.isLoopback();
+    }
+
+    public boolean isPointToPoint() throws SocketException {
+        return networkInterface.isPointToPoint();
+    }
+
+    public boolean isVirtual() {
+        return networkInterface.isVirtual();
+    }
+
+    public boolean supportsMulticast() throws SocketException {
+        return networkInterface.supportsMulticast();
+    }
+
+    public List<InterfaceAddress> getInterfaceAddresses() {
+        return networkInterface.getInterfaceAddresses();
+    }
+
+    @Override
+    public String toString() {
+        return networkInterface.toString();
+    }
+}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/util/MdnsLogger.java b/service/mdns/com/android/server/connectivity/mdns/util/MdnsLogger.java
new file mode 100644
index 0000000..31c62f5
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/util/MdnsLogger.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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.
+ */
+
+package com.android.server.connectivity.mdns.util;
+
+import android.net.util.SharedLog;
+import android.text.TextUtils;
+
+/**
+ * The logger used in mDNS.
+ */
+public class MdnsLogger {
+    // Make this logger public for other level logging than dogfood.
+    public final SharedLog mLog;
+
+    /**
+     * Constructs a new {@link MdnsLogger} with the given logging tag.
+     *
+     * @param tag The log tag that will be used by this logger
+     */
+    public MdnsLogger(String tag) {
+        mLog = new SharedLog(tag);
+    }
+
+    public void log(String message) {
+        mLog.log(message);
+    }
+
+    public void log(String message, Object... args) {
+        mLog.log(message + " ; " + TextUtils.join(" ; ", args));
+    }
+
+    public void d(String message) {
+        mLog.log(message);
+    }
+
+    public void e(String message) {
+        mLog.e(message);
+    }
+
+    public void e(String message, Throwable e) {
+        mLog.e(message, e);
+    }
+
+    public void w(String message) {
+        mLog.w(message);
+    }
+}
\ No newline at end of file
diff --git a/service/native/TrafficController.cpp b/service/native/TrafficController.cpp
index 4dc056d..9331548 100644
--- a/service/native/TrafficController.cpp
+++ b/service/native/TrafficController.cpp
@@ -451,53 +451,6 @@
     return 0;
 }
 
-int TrafficController::toggleUidOwnerMap(ChildChain chain, bool enable) {
-    std::lock_guard guard(mMutex);
-    uint32_t key = UID_RULES_CONFIGURATION_KEY;
-    auto oldConfigure = mConfigurationMap.readValue(key);
-    if (!oldConfigure.ok()) {
-        ALOGE("Cannot read the old configuration from map: %s",
-              oldConfigure.error().message().c_str());
-        return -oldConfigure.error().code();
-    }
-    uint32_t match;
-    switch (chain) {
-        case DOZABLE:
-            match = DOZABLE_MATCH;
-            break;
-        case STANDBY:
-            match = STANDBY_MATCH;
-            break;
-        case POWERSAVE:
-            match = POWERSAVE_MATCH;
-            break;
-        case RESTRICTED:
-            match = RESTRICTED_MATCH;
-            break;
-        case LOW_POWER_STANDBY:
-            match = LOW_POWER_STANDBY_MATCH;
-            break;
-        case OEM_DENY_1:
-            match = OEM_DENY_1_MATCH;
-            break;
-        case OEM_DENY_2:
-            match = OEM_DENY_2_MATCH;
-            break;
-        case OEM_DENY_3:
-            match = OEM_DENY_3_MATCH;
-            break;
-        default:
-            return -EINVAL;
-    }
-    BpfConfig newConfiguration =
-            enable ? (oldConfigure.value() | match) : (oldConfigure.value() & ~match);
-    Status res = mConfigurationMap.writeValue(key, newConfiguration, BPF_EXIST);
-    if (!isOk(res)) {
-        ALOGE("Failed to toggleUidOwnerMap(%d): %s", chain, res.msg().c_str());
-    }
-    return -res.code();
-}
-
 Status TrafficController::swapActiveStatsMap() {
     std::lock_guard guard(mMutex);
 
diff --git a/service/native/include/TrafficController.h b/service/native/include/TrafficController.h
index 8512929..14c5eaf 100644
--- a/service/native/include/TrafficController.h
+++ b/service/native/include/TrafficController.h
@@ -71,8 +71,6 @@
     netdutils::Status updateUidOwnerMap(const uint32_t uid,
                                         UidOwnerMatchType matchType, IptOp op) EXCLUDES(mMutex);
 
-    int toggleUidOwnerMap(ChildChain chain, bool enable) EXCLUDES(mMutex);
-
     static netdutils::StatusOr<std::unique_ptr<netdutils::NetlinkListenerInterface>>
     makeSkDestroyListener();
 
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index 151d0e3..6e107c2 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -16,15 +16,29 @@
 
 package com.android.server;
 
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
+import static android.system.OsConstants.EINVAL;
 import static android.system.OsConstants.EOPNOTSUPP;
 
 import android.net.INetd;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
+import android.system.ErrnoException;
 import android.system.Os;
 import android.util.Log;
+import android.util.SparseLongArray;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.BpfMap;
+import com.android.net.module.util.Struct.U32;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -38,40 +52,128 @@
     private static final String TAG = "BpfNetMaps";
     private final INetd mNetd;
     // Use legacy netd for releases before T.
-    private static final boolean USE_NETD = !SdkLevel.isAtLeastT();
+    private static final boolean PRE_T = !SdkLevel.isAtLeastT();
     private static boolean sInitialized = false;
 
+    // Lock for sConfigurationMap entry for UID_RULES_CONFIGURATION_KEY.
+    // This entry is not accessed by others.
+    // BpfNetMaps acquires this lock while sequence of read, modify, and write.
+    private static final Object sUidRulesConfigBpfMapLock = new Object();
+
+    private static final String CONFIGURATION_MAP_PATH =
+            "/sys/fs/bpf/netd_shared/map_netd_configuration_map";
+    private static final U32 UID_RULES_CONFIGURATION_KEY = new U32(0);
+    private static BpfMap<U32, U32> sConfigurationMap = null;
+
+    // LINT.IfChange(match_type)
+    private static final long NO_MATCH = 0;
+    private static final long HAPPY_BOX_MATCH = (1 << 0);
+    private static final long PENALTY_BOX_MATCH = (1 << 1);
+    private static final long DOZABLE_MATCH = (1 << 2);
+    private static final long STANDBY_MATCH = (1 << 3);
+    private static final long POWERSAVE_MATCH = (1 << 4);
+    private static final long RESTRICTED_MATCH = (1 << 5);
+    private static final long LOW_POWER_STANDBY_MATCH = (1 << 6);
+    private static final long IIF_MATCH = (1 << 7);
+    private static final long LOCKDOWN_VPN_MATCH = (1 << 8);
+    private static final long OEM_DENY_1_MATCH = (1 << 9);
+    private static final long OEM_DENY_2_MATCH = (1 << 10);
+    private static final long OEM_DENY_3_MATCH = (1 << 11);
+    // LINT.ThenChange(packages/modules/Connectivity/bpf_progs/bpf_shared.h)
+
+    // TODO: Use Java BpfMap instead of JNI code (TrafficController) for map update.
+    // Currently, BpfNetMaps uses TrafficController for map update and TrafficController
+    // (changeUidOwnerRule and toggleUidOwnerMap) also does conversion from "firewall chain" to
+    // "match". Migrating map update from JNI to Java BpfMap will solve this duplication.
+    private static final SparseLongArray FIREWALL_CHAIN_TO_MATCH = new SparseLongArray();
+    static {
+        FIREWALL_CHAIN_TO_MATCH.put(FIREWALL_CHAIN_DOZABLE, DOZABLE_MATCH);
+        FIREWALL_CHAIN_TO_MATCH.put(FIREWALL_CHAIN_STANDBY, STANDBY_MATCH);
+        FIREWALL_CHAIN_TO_MATCH.put(FIREWALL_CHAIN_POWERSAVE, POWERSAVE_MATCH);
+        FIREWALL_CHAIN_TO_MATCH.put(FIREWALL_CHAIN_RESTRICTED, RESTRICTED_MATCH);
+        FIREWALL_CHAIN_TO_MATCH.put(FIREWALL_CHAIN_LOW_POWER_STANDBY, LOW_POWER_STANDBY_MATCH);
+        FIREWALL_CHAIN_TO_MATCH.put(FIREWALL_CHAIN_OEM_DENY_1, OEM_DENY_1_MATCH);
+        FIREWALL_CHAIN_TO_MATCH.put(FIREWALL_CHAIN_OEM_DENY_2, OEM_DENY_2_MATCH);
+        FIREWALL_CHAIN_TO_MATCH.put(FIREWALL_CHAIN_OEM_DENY_3, OEM_DENY_3_MATCH);
+    }
+
+    /**
+     * Only tests or BpfNetMaps#ensureInitialized can call this function.
+     */
+    @VisibleForTesting
+    public static void initialize(final Dependencies deps) {
+        sConfigurationMap = deps.getConfigurationMap();
+    }
+
     /**
      * Initializes the class if it is not already initialized. This method will open maps but not
      * cause any other effects. This method may be called multiple times on any thread.
      */
     private static synchronized void ensureInitialized() {
         if (sInitialized) return;
-        if (!USE_NETD) {
+        if (!PRE_T) {
             System.loadLibrary("service-connectivity");
             native_init();
+            initialize(new Dependencies());
         }
         sInitialized = true;
     }
 
+    /**
+     * Dependencies of BpfNetMaps, for injection in tests.
+     */
+    @VisibleForTesting
+    public static class Dependencies {
+        /**
+         *  Get configuration BPF map.
+         */
+        public BpfMap<U32, U32> getConfigurationMap() {
+            try {
+                return new BpfMap<>(
+                        CONFIGURATION_MAP_PATH, BpfMap.BPF_F_RDWR, U32.class, U32.class);
+            } catch (ErrnoException e) {
+                Log.e(TAG, "Cannot open netd configuration map: " + e);
+                return null;
+            }
+        }
+    }
+
     /** Constructor used after T that doesn't need to use netd anymore. */
     public BpfNetMaps() {
         this(null);
 
-        if (USE_NETD) throw new IllegalArgumentException("BpfNetMaps need to use netd before T");
+        if (PRE_T) throw new IllegalArgumentException("BpfNetMaps need to use netd before T");
     }
 
-    public BpfNetMaps(INetd netd) {
+    public BpfNetMaps(final INetd netd) {
         ensureInitialized();
         mNetd = netd;
     }
 
+    /**
+     * Get corresponding match from firewall chain.
+     */
+    @VisibleForTesting
+    public long getMatchByFirewallChain(final int chain) {
+        final long match = FIREWALL_CHAIN_TO_MATCH.get(chain, NO_MATCH);
+        if (match == NO_MATCH) {
+            throw new ServiceSpecificException(EINVAL, "Invalid firewall chain: " + chain);
+        }
+        return match;
+    }
+
     private void maybeThrow(final int err, final String msg) {
         if (err != 0) {
             throw new ServiceSpecificException(err, msg + ": " + Os.strerror(err));
         }
     }
 
+    private void throwIfPreT(final String msg) {
+        if (PRE_T) {
+            throw new UnsupportedOperationException(msg);
+        }
+    }
+
     /**
      * Add naughty app bandwidth rule for specific app
      *
@@ -125,12 +227,46 @@
      *
      * @param childChain target chain to enable
      * @param enable     whether to enable or disable child chain.
+     * @throws UnsupportedOperationException if called on pre-T devices.
      * @throws ServiceSpecificException in case of failure, with an error code indicating the
      *                                  cause of the failure.
      */
     public void setChildChain(final int childChain, final boolean enable) {
-        final int err = native_setChildChain(childChain, enable);
-        maybeThrow(err, "Unable to set child chain");
+        throwIfPreT("setChildChain is not available on pre-T devices");
+
+        final long match = getMatchByFirewallChain(childChain);
+        try {
+            synchronized (sUidRulesConfigBpfMapLock) {
+                final U32 config = sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY);
+                final long newConfig = enable ? (config.val | match) : (config.val & ~match);
+                sConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(newConfig));
+            }
+        } catch (ErrnoException e) {
+            throw new ServiceSpecificException(e.errno,
+                    "Unable to set child chain: " + Os.strerror(e.errno));
+        }
+    }
+
+    /**
+     * Get the specified firewall chain's status.
+     *
+     * @param childChain target chain
+     * @return {@code true} if chain is enabled, {@code false} if chain is not enabled.
+     * @throws UnsupportedOperationException if called on pre-T devices.
+     * @throws ServiceSpecificException in case of failure, with an error code indicating the
+     *                                  cause of the failure.
+     */
+    public boolean isChainEnabled(final int childChain) {
+        throwIfPreT("isChainEnabled is not available on pre-T devices");
+
+        final long match = getMatchByFirewallChain(childChain);
+        try {
+            final U32 config = sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY);
+            return (config.val & match) != 0;
+        } catch (ErrnoException e) {
+            throw new ServiceSpecificException(e.errno,
+                    "Unable to get firewall chain status: " + Os.strerror(e.errno));
+        }
     }
 
     /**
@@ -187,7 +323,7 @@
      *                                  cause of the failure.
      */
     public void addUidInterfaceRules(final String ifName, final int[] uids) throws RemoteException {
-        if (USE_NETD) {
+        if (PRE_T) {
             mNetd.firewallAddUidInterfaceRules(ifName, uids);
             return;
         }
@@ -207,7 +343,7 @@
      *                                  cause of the failure.
      */
     public void removeUidInterfaceRules(final int[] uids) throws RemoteException {
-        if (USE_NETD) {
+        if (PRE_T) {
             mNetd.firewallRemoveUidInterfaceRules(uids);
             return;
         }
@@ -250,7 +386,7 @@
      * @throws RemoteException when netd has crashed.
      */
     public void setNetPermForUids(final int permissions, final int[] uids) throws RemoteException {
-        if (USE_NETD) {
+        if (PRE_T) {
             mNetd.trafficSetNetPermForUids(permissions, uids);
             return;
         }
@@ -266,7 +402,7 @@
      */
     public void dump(final FileDescriptor fd, boolean verbose)
             throws IOException, ServiceSpecificException {
-        if (USE_NETD) {
+        if (PRE_T) {
             throw new ServiceSpecificException(
                     EOPNOTSUPP, "dumpsys connectivity trafficcontroller dump not available on pre-T"
                     + " devices, use dumpsys netd trafficcontroller instead.");
@@ -279,7 +415,6 @@
     private native int native_removeNaughtyApp(int uid);
     private native int native_addNiceApp(int uid);
     private native int native_removeNiceApp(int uid);
-    private native int native_setChildChain(int childChain, boolean enable);
     private native int native_replaceUidChain(String name, boolean isAllowlist, int[] uids);
     private native int native_setUidRule(int childChain, int uid, int firewallRule);
     private native int native_addUidInterfaceRules(String ifName, int[] uids);
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 853a1a2..37fc391 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -3422,6 +3422,17 @@
         pw.increaseIndent();
         mNetworkActivityTracker.dump(pw);
         pw.decreaseIndent();
+
+        // pre-T is logged by netd.
+        if (SdkLevel.isAtLeastT()) {
+            pw.println();
+            pw.println("BPF programs & maps:");
+            pw.increaseIndent();
+            // Flush is required. Otherwise, the traces in fd can interleave with traces in pw.
+            pw.flush();
+            dumpTrafficController(pw, fd, /*verbose=*/ true);
+            pw.decreaseIndent();
+        }
     }
 
     private void dumpNetworks(IndentingPrintWriter pw) {
@@ -6352,7 +6363,7 @@
             if (null != satisfier) {
                 // If the old NRI was satisfied by an NAI, then it may have had an active request.
                 // The active request is necessary to figure out what callbacks to send, in
-                // particular then a network updates its capabilities.
+                // particular when a network updates its capabilities.
                 // As this code creates a new NRI with a new set of requests, figure out which of
                 // the list of requests should be the active request. It is always the first
                 // request of the list that can be satisfied by the satisfier since the order of
@@ -11384,6 +11395,13 @@
     }
 
     @Override
+    public boolean getFirewallChainEnabled(final int chain) {
+        enforceNetworkStackOrSettingsPermission();
+
+        return mBpfNetMaps.isChainEnabled(chain);
+    }
+
+    @Override
     public void replaceFirewallChain(final int chain, final int[] uids) {
         enforceNetworkStackOrSettingsPermission();
 
diff --git a/service/src/com/android/server/connectivity/ClatCoordinator.java b/service/src/com/android/server/connectivity/ClatCoordinator.java
index 498cf63..5ea586a 100644
--- a/service/src/com/android/server/connectivity/ClatCoordinator.java
+++ b/service/src/com/android/server/connectivity/ClatCoordinator.java
@@ -347,6 +347,19 @@
                     && this.pid == that.pid
                     && this.cookie == that.cookie;
         }
+
+        @Override
+        public String toString() {
+            return "iface: " + iface
+                    + " (" + ifIndex + ")"
+                    + ", v4iface: " + v4iface
+                    + " (" + v4ifIndex + ")"
+                    + ", v4: " + v4
+                    + ", v6: " + v6
+                    + ", pfx96: " + pfx96
+                    + ", pid: " + pid
+                    + ", cookie: " + cookie;
+        }
     };
 
     @VisibleForTesting
@@ -819,9 +832,9 @@
      * @param pw print writer.
      */
     public void dump(@NonNull IndentingPrintWriter pw) {
-        // TODO: dump ClatdTracker
         // TODO: move map dump to a global place to avoid duplicate dump while there are two or
         // more IPv6 only networks.
+        pw.println("CLAT tracker: " + mClatdTracker.toString());
         pw.println("Forwarding rules:");
         pw.increaseIndent();
         dumpBpfIngress(pw);
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
index 68fa38d..7d1e13f 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
@@ -113,7 +113,7 @@
     private static final int UNKNOWN_DETECTION_METHOD = 4;
     private static final int FILTERED_UNKNOWN_DETECTION_METHOD = 0;
     private static final int CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT = 5000;
-    private static final int DELAY_FOR_ADMIN_UIDS_MILLIS = 2000;
+    private static final int DELAY_FOR_ADMIN_UIDS_MILLIS = 5000;
 
     private static final Executor INLINE_EXECUTOR = x -> x.run();
 
diff --git a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
index bbac09b..621b743 100644
--- a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
+++ b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
@@ -136,8 +136,8 @@
 
     @Before
     fun setUp() {
-        // For BPF support kernel needs to be at least 5.4.
-        assumeTrue(kernelIsAtLeast(5, 4))
+        // For BPF support kernel needs to be at least 5.15.
+        assumeTrue(kernelIsAtLeast(5, 15))
 
         runAsShell(MANAGE_TEST_NETWORKS) {
             val tnm = realContext.getSystemService(TestNetworkManager::class.java)
@@ -158,7 +158,7 @@
 
     @After
     fun tearDown() {
-        if (!kernelIsAtLeast(5, 4)) {
+        if (!kernelIsAtLeast(5, 15)) {
             return;
         }
         agentsToCleanUp.forEach { it.unregister() }
diff --git a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
index cc64239..1748612 100644
--- a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
@@ -49,7 +49,6 @@
 import android.os.Handler
 import android.os.Looper
 import android.os.OutcomeReceiver
-import android.os.SystemProperties
 import android.platform.test.annotations.AppModeFull
 import android.util.ArraySet
 import androidx.test.platform.app.InstrumentationRegistry
@@ -57,7 +56,7 @@
 import com.android.net.module.util.TrackRecord
 import com.android.testutils.anyNetwork
 import com.android.testutils.ConnectivityModuleTest
-import com.android.testutils.DeviceInfoUtils
+import com.android.testutils.DeviceInfoUtils.isKernelVersionAtLeast
 import com.android.testutils.DevSdkIgnoreRule
 import com.android.testutils.DevSdkIgnoreRunner
 import com.android.testutils.RecorderCallback.CallbackEntry.Available
@@ -69,13 +68,13 @@
 import com.android.testutils.waitForIdle
 import org.junit.After
 import org.junit.Assume.assumeTrue
-import org.junit.Assume.assumeFalse
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import java.net.Inet6Address
 import java.util.concurrent.CompletableFuture
 import java.util.concurrent.ExecutionException
+import java.util.concurrent.TimeoutException
 import java.util.concurrent.TimeUnit
 import kotlin.test.assertEquals
 import kotlin.test.assertFailsWith
@@ -145,6 +144,8 @@
             raResponder.start()
         }
 
+        // WARNING: this function requires kernel support. Call assumeChangingCarrierSupported() at
+        // the top of your test.
         fun setCarrierEnabled(enabled: Boolean) {
             runAsShell(MANAGE_TEST_NETWORKS) {
                 tnm.setCarrierEnabled(tapInterface, enabled)
@@ -204,12 +205,8 @@
 
         fun eventuallyExpect(expected: CallbackEntry) = events.poll(TIMEOUT_MS) { it == expected }
 
-        fun eventuallyExpect(interfaceName: String, state: Int, role: Int) {
-            assertNotNull(eventuallyExpect(createChangeEvent(interfaceName, state, role)))
-        }
-
         fun eventuallyExpect(iface: EthernetTestInterface, state: Int, role: Int) {
-            eventuallyExpect(iface.name, state, role)
+            assertNotNull(eventuallyExpect(createChangeEvent(iface.name, state, role)))
         }
 
         fun assertNoCallback() {
@@ -295,6 +292,9 @@
         releaseTetheredInterface()
     }
 
+    // Setting the carrier up / down relies on TUNSETCARRIER which was added in kernel version 5.0.
+    private fun assumeChangingCarrierSupported() = assumeTrue(isKernelVersionAtLeast("5.0.0"))
+
     private fun addInterfaceStateListener(listener: EthernetStateListener) {
         runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS) {
             em.addInterfaceStateListener(handler::post, listener)
@@ -302,6 +302,8 @@
         addedListeners.add(listener)
     }
 
+    // WARNING: setting hasCarrier to false requires kernel support. Call
+    // assumeChangingCarrierSupported() at the top of your test.
     private fun createInterface(hasCarrier: Boolean = true): EthernetTestInterface {
         val iface = EthernetTestInterface(
             context,
@@ -451,32 +453,45 @@
         }
     }
 
-    // TODO: this function is now used in two places (EthernetManagerTest and
-    // EthernetTetheringTest), so it should be moved to testutils.
-    private fun isAdbOverNetwork(): Boolean {
-        // If adb TCP port opened, this test may running by adb over network.
-        return (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1 ||
-                SystemProperties.getInt("service.adb.tcp.port", -1) > -1)
+    private fun assumeNoInterfaceForTetheringAvailable() {
+        // Interfaces that have configured NetworkCapabilities will never be used for tethering,
+        // see aosp/2123900.
+        try {
+            // assumeException does not exist.
+            requestTetheredInterface().expectOnAvailable()
+            // interface used for tethering is available, throw an assumption error.
+            assumeTrue(false)
+        } catch (e: TimeoutException) {
+            // do nothing -- the TimeoutException indicates that no interface is available for
+            // tethering.
+            releaseTetheredInterface()
+        }
     }
 
     @Test
     fun testCallbacks_forServerModeInterfaces() {
-        // do not run this test when adb might be connected over ethernet.
-        assumeFalse(isAdbOverNetwork())
+        // do not run this test if an interface that can be used for tethering already exists.
+        assumeNoInterfaceForTetheringAvailable()
+
+        val iface = createInterface()
+        requestTetheredInterface().expectOnAvailable()
 
         val listener = EthernetStateListener()
         addInterfaceStateListener(listener)
-
-        // it is possible that a physical interface is present, so it is not guaranteed that iface
-        // will be put into server mode. This should not matter for the test though. Calling
-        // createInterface() makes sure we have at least one interface available.
-        val iface = createInterface()
-        val cb = requestTetheredInterface()
-        val ifaceName = cb.expectOnAvailable()
-        listener.eventuallyExpect(ifaceName, STATE_LINK_UP, ROLE_SERVER)
+        // TODO(b/236895792): THIS IS A BUG! Existing server mode interfaces are not reported when
+        // an InterfaceStateListener is registered.
+        // Note: using eventuallyExpect as there may be other interfaces present.
+        // listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_SERVER)
 
         releaseTetheredInterface()
-        listener.eventuallyExpect(ifaceName, STATE_LINK_UP, ROLE_CLIENT)
+        listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_CLIENT)
+
+        requestTetheredInterface().expectOnAvailable()
+        // This should be changed to expectCallback, once b/236895792 is fixed.
+        listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_SERVER)
+
+        releaseTetheredInterface()
+        listener.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
     }
 
     /**
@@ -631,9 +646,7 @@
 
     @Test
     fun testNetworkRequest_forInterfaceWhileTogglingCarrier() {
-        // Notice this test case fails on devices running on an older kernel version(e.g. 4.14)
-        // that might not support ioctl new argument. Only run this test on 4.19 kernel or above.
-        assumeTrue(DeviceInfoUtils.isKernelVersionAtLeast("4.19.0"))
+        assumeChangingCarrierSupported()
 
         val iface = createInterface(false /* hasCarrier */)
 
@@ -646,4 +659,26 @@
         iface.setCarrierEnabled(false)
         cb.eventuallyExpectLost()
     }
+
+    @Test
+    fun testRemoveInterface_whileInServerMode() {
+        assumeNoInterfaceForTetheringAvailable()
+
+        val listener = EthernetStateListener()
+        addInterfaceStateListener(listener)
+
+        val iface = createInterface()
+        val ifaceName = requestTetheredInterface().expectOnAvailable()
+
+        assertEquals(iface.name, ifaceName)
+        listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_SERVER)
+
+        removeInterface(iface)
+
+        // Note: removeInterface already verifies that a STATE_ABSENT, ROLE_NONE callback is
+        // received, but it can't hurt to explicitly check for it.
+        listener.expectCallback(iface, STATE_ABSENT, ROLE_NONE)
+        releaseTetheredInterface()
+        listener.assertNoCallback()
+    }
 }
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 3ea27f7..0908ad2 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -63,12 +63,14 @@
         "java/com/android/internal/net/NetworkUtilsInternalTest.java",
         "java/com/android/internal/net/VpnProfileTest.java",
         "java/com/android/server/NetworkManagementServiceTest.java",
+        "java/com/android/server/VpnManagerServiceTest.java",
         "java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java",
         "java/com/android/server/connectivity/IpConnectivityMetricsTest.java",
         "java/com/android/server/connectivity/MultipathPolicyTrackerTest.java",
         "java/com/android/server/connectivity/NetdEventListenerServiceTest.java",
         "java/com/android/server/connectivity/VpnTest.java",
         "java/com/android/server/net/ipmemorystore/*.java",
+        "java/com/android/server/connectivity/mdns/**/*.java",
     ]
 }
 
@@ -143,6 +145,7 @@
     static_libs: [
         "services.core",
         "services.net",
+        "service-mdns",
     ],
     jni_libs: [
         "libandroid_net_connectivity_com_android_net_module_util_jni",
diff --git a/tests/unit/java/com/android/server/BpfNetMapsTest.java b/tests/unit/java/com/android/server/BpfNetMapsTest.java
index f07a10d..e9fad9b 100644
--- a/tests/unit/java/com/android/server/BpfNetMapsTest.java
+++ b/tests/unit/java/com/android/server/BpfNetMapsTest.java
@@ -16,43 +16,93 @@
 
 package com.android.server;
 
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
 import static android.net.INetd.PERMISSION_INTERNET;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeFalse;
 import static org.mockito.Mockito.verify;
 
 import android.net.INetd;
 import android.os.Build;
+import android.os.ServiceSpecificException;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.BpfMap;
+import com.android.net.module.util.Struct.U32;
 import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 import com.android.testutils.DevSdkIgnoreRunner;
+import com.android.testutils.TestBpfMap;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.List;
+
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
 public final class BpfNetMapsTest {
     private static final String TAG = "BpfNetMapsTest";
+
+    @Rule
+    public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
+
     private static final int TEST_UID = 10086;
     private static final int[] TEST_UIDS = {10002, 10003};
     private static final String IFNAME = "wlan0";
     private static final String CHAINNAME = "fw_dozable";
+    private static final U32 UID_RULES_CONFIGURATION_KEY = new U32(0);
+    private static final List<Integer> FIREWALL_CHAINS = List.of(
+            FIREWALL_CHAIN_DOZABLE,
+            FIREWALL_CHAIN_STANDBY,
+            FIREWALL_CHAIN_POWERSAVE,
+            FIREWALL_CHAIN_RESTRICTED,
+            FIREWALL_CHAIN_LOW_POWER_STANDBY,
+            FIREWALL_CHAIN_OEM_DENY_1,
+            FIREWALL_CHAIN_OEM_DENY_2,
+            FIREWALL_CHAIN_OEM_DENY_3
+    );
+
     private BpfNetMaps mBpfNetMaps;
 
     @Mock INetd mNetd;
+    private static final TestBpfMap<U32, U32> sConfigurationMap =
+            new TestBpfMap<>(U32.class, U32.class);
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mBpfNetMaps = new BpfNetMaps(mNetd);
+        BpfNetMaps.initialize(makeDependencies());
+        sConfigurationMap.clear();
+    }
+
+    private static BpfNetMaps.Dependencies makeDependencies() {
+        return new BpfNetMaps.Dependencies() {
+            @Override
+            public BpfMap<U32, U32> getConfigurationMap() {
+                return sConfigurationMap;
+            }
+        };
     }
 
     @Test
@@ -65,4 +115,138 @@
         mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET, TEST_UIDS);
         verify(mNetd).trafficSetNetPermForUids(PERMISSION_INTERNET, TEST_UIDS);
     }
+
+    private void doTestIsChainEnabled(final List<Integer> enableChains) throws Exception {
+        long match = 0;
+        for (final int chain: enableChains) {
+            match |= mBpfNetMaps.getMatchByFirewallChain(chain);
+        }
+        sConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(match));
+
+        for (final int chain: FIREWALL_CHAINS) {
+            final String testCase = "EnabledChains: " + enableChains + " CheckedChain: " + chain;
+            if (enableChains.contains(chain)) {
+                assertTrue("Expected isChainEnabled returns True, " + testCase,
+                        mBpfNetMaps.isChainEnabled(chain));
+            } else {
+                assertFalse("Expected isChainEnabled returns False, " + testCase,
+                        mBpfNetMaps.isChainEnabled(chain));
+            }
+        }
+    }
+
+    private void doTestIsChainEnabled(final int enableChain) throws Exception {
+        doTestIsChainEnabled(List.of(enableChain));
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testIsChainEnabled() throws Exception {
+        doTestIsChainEnabled(FIREWALL_CHAIN_DOZABLE);
+        doTestIsChainEnabled(FIREWALL_CHAIN_STANDBY);
+        doTestIsChainEnabled(FIREWALL_CHAIN_POWERSAVE);
+        doTestIsChainEnabled(FIREWALL_CHAIN_RESTRICTED);
+        doTestIsChainEnabled(FIREWALL_CHAIN_LOW_POWER_STANDBY);
+        doTestIsChainEnabled(FIREWALL_CHAIN_OEM_DENY_1);
+        doTestIsChainEnabled(FIREWALL_CHAIN_OEM_DENY_2);
+        doTestIsChainEnabled(FIREWALL_CHAIN_OEM_DENY_3);
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testIsChainEnabledMultipleChainEnabled() throws Exception {
+        doTestIsChainEnabled(List.of(
+                FIREWALL_CHAIN_DOZABLE,
+                FIREWALL_CHAIN_STANDBY));
+        doTestIsChainEnabled(List.of(
+                FIREWALL_CHAIN_DOZABLE,
+                FIREWALL_CHAIN_STANDBY,
+                FIREWALL_CHAIN_POWERSAVE,
+                FIREWALL_CHAIN_RESTRICTED));
+        doTestIsChainEnabled(FIREWALL_CHAINS);
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testIsChainEnabledInvalidChain() {
+        final Class<ServiceSpecificException> expected = ServiceSpecificException.class;
+        assertThrows(expected, () -> mBpfNetMaps.isChainEnabled(-1 /* childChain */));
+        assertThrows(expected, () -> mBpfNetMaps.isChainEnabled(1000 /* childChain */));
+    }
+
+    @Test
+    @IgnoreAfter(Build.VERSION_CODES.S_V2)
+    public void testIsChainEnabledBeforeT() {
+        assertThrows(UnsupportedOperationException.class,
+                () -> mBpfNetMaps.isChainEnabled(FIREWALL_CHAIN_DOZABLE));
+    }
+
+    private void doTestSetChildChain(final List<Integer> testChains) throws Exception {
+        long expectedMatch = 0;
+        for (final int chain: testChains) {
+            expectedMatch |= mBpfNetMaps.getMatchByFirewallChain(chain);
+        }
+
+        assertEquals(0, sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val);
+
+        for (final int chain: testChains) {
+            mBpfNetMaps.setChildChain(chain, true /* enable */);
+        }
+        assertEquals(expectedMatch, sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val);
+
+        for (final int chain: testChains) {
+            mBpfNetMaps.setChildChain(chain, false /* enable */);
+        }
+        assertEquals(0, sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val);
+    }
+
+    private void doTestSetChildChain(final int testChain) throws Exception {
+        doTestSetChildChain(List.of(testChain));
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testSetChildChain() throws Exception {
+        sConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0));
+        doTestSetChildChain(FIREWALL_CHAIN_DOZABLE);
+        doTestSetChildChain(FIREWALL_CHAIN_STANDBY);
+        doTestSetChildChain(FIREWALL_CHAIN_POWERSAVE);
+        doTestSetChildChain(FIREWALL_CHAIN_RESTRICTED);
+        doTestSetChildChain(FIREWALL_CHAIN_LOW_POWER_STANDBY);
+        doTestSetChildChain(FIREWALL_CHAIN_OEM_DENY_1);
+        doTestSetChildChain(FIREWALL_CHAIN_OEM_DENY_2);
+        doTestSetChildChain(FIREWALL_CHAIN_OEM_DENY_3);
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testSetChildChainMultipleChain() throws Exception {
+        sConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0));
+        doTestSetChildChain(List.of(
+                FIREWALL_CHAIN_DOZABLE,
+                FIREWALL_CHAIN_STANDBY));
+        doTestSetChildChain(List.of(
+                FIREWALL_CHAIN_DOZABLE,
+                FIREWALL_CHAIN_STANDBY,
+                FIREWALL_CHAIN_POWERSAVE,
+                FIREWALL_CHAIN_RESTRICTED));
+        doTestSetChildChain(FIREWALL_CHAINS);
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testSetChildChainInvalidChain() {
+        final Class<ServiceSpecificException> expected = ServiceSpecificException.class;
+        assertThrows(expected,
+                () -> mBpfNetMaps.setChildChain(-1 /* childChain */, true /* enable */));
+        assertThrows(expected,
+                () -> mBpfNetMaps.setChildChain(1000 /* childChain */, true /* enable */));
+    }
+
+    @Test
+    @IgnoreAfter(Build.VERSION_CODES.S_V2)
+    public void testSetChildChainBeforeT() {
+        assertThrows(UnsupportedOperationException.class,
+                () -> mBpfNetMaps.setChildChain(FIREWALL_CHAIN_DOZABLE, true /* enable */));
+    }
 }
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 900ee5a..0919dfc 100644
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -10633,19 +10633,6 @@
     }
 
     @Test
-    public void testStartVpnProfileFromDiffPackage() throws Exception {
-        final String notMyVpnPkg = "com.not.my.vpn";
-        assertThrows(
-                SecurityException.class, () -> mVpnManagerService.startVpnProfile(notMyVpnPkg));
-    }
-
-    @Test
-    public void testStopVpnProfileFromDiffPackage() throws Exception {
-        final String notMyVpnPkg = "com.not.my.vpn";
-        assertThrows(SecurityException.class, () -> mVpnManagerService.stopVpnProfile(notMyVpnPkg));
-    }
-
-    @Test
     public void testUidUpdateChangesInterfaceFilteringRule() throws Exception {
         LinkProperties lp = new LinkProperties();
         lp.setInterfaceName("tun0");
diff --git a/tests/unit/java/com/android/server/VpnManagerServiceTest.java b/tests/unit/java/com/android/server/VpnManagerServiceTest.java
new file mode 100644
index 0000000..ece13b3
--- /dev/null
+++ b/tests/unit/java/com/android/server/VpnManagerServiceTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2022 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
+ *
+ *      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.
+ */
+
+package com.android.server;
+
+import static android.os.Build.VERSION_CODES.R;
+
+import static com.android.testutils.ContextUtils.mockService;
+import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import static com.android.testutils.MiscAsserts.assertThrows;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.annotation.UserIdInt;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.INetd;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.INetworkManagementService;
+import android.os.Looper;
+import android.os.UserManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.connectivity.Vpn;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+@RunWith(DevSdkIgnoreRunner.class)
+@IgnoreUpTo(R) // VpnManagerService is not available before R
+@SmallTest
+public class VpnManagerServiceTest extends VpnTestBase {
+    @Rule
+    public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
+
+    @Spy Context mContext;
+    private HandlerThread mHandlerThread;
+    @Mock private Handler mHandler;
+    @Mock private Vpn mVpn;
+    @Mock private INetworkManagementService mNms;
+    @Mock private ConnectivityManager mCm;
+    @Mock private UserManager mUserManager;
+    @Mock private INetd mNetd;
+    @Mock private PackageManager mPackageManager;
+    private VpnManagerServiceDependencies mDeps;
+    private VpnManagerService mService;
+
+    private final String mNotMyVpnPkg = "com.not.my.vpn";
+
+    class VpnManagerServiceDependencies extends VpnManagerService.Dependencies {
+        @Override
+        public HandlerThread makeHandlerThread() {
+            return mHandlerThread;
+        }
+
+        @Override
+        public INetworkManagementService getINetworkManagementService() {
+            return mNms;
+        }
+
+        @Override
+        public INetd getNetd() {
+            return mNetd;
+        }
+
+        @Override
+        public Vpn createVpn(Looper looper, Context context, INetworkManagementService nms,
+                INetd netd, @UserIdInt int userId) {
+            return mVpn;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mHandlerThread = new HandlerThread("TestVpnManagerService");
+        mDeps = new VpnManagerServiceDependencies();
+        doReturn(mContext).when(mContext).createContextAsUser(any(), anyInt());
+        doReturn(mPackageManager).when(mContext).getPackageManager();
+        setMockedPackages(mPackageManager, sPackages);
+
+        mockService(mContext, ConnectivityManager.class, Context.CONNECTIVITY_SERVICE, mCm);
+        mockService(mContext, UserManager.class, Context.USER_SERVICE, mUserManager);
+
+        doReturn(new Intent()).when(mContext).registerReceiver(
+                any() /* receiver */,
+                any() /* intentFilter */,
+                any() /* broadcastPermission */,
+                eq(mHandler) /* scheduler */);
+        doReturn(SYSTEM_USER).when(mUserManager).getUserInfo(eq(SYSTEM_USER_ID));
+        mService = new VpnManagerService(mContext, mDeps);
+    }
+
+    @Test
+    public void testUpdateAppExclusionList() {
+        // Add user to create vpn in mVpn
+        mService.onUserStarted(SYSTEM_USER_ID);
+        assertNotNull(mService.mVpns.get(SYSTEM_USER_ID));
+
+        // Start vpn
+        mService.startVpnProfile(TEST_VPN_PKG);
+        verify(mVpn).startVpnProfile(eq(TEST_VPN_PKG));
+
+        // Remove package due to package replaced.
+        mService.onPackageRemoved(PKGS[0], PKG_UIDS[0], true /* isReplacing */);
+        verify(mVpn, never()).refreshPlatformVpnAppExclusionList();
+
+        // Add package due to package replaced.
+        mService.onPackageAdded(PKGS[0], PKG_UIDS[0], true /* isReplacing */);
+        verify(mVpn, never()).refreshPlatformVpnAppExclusionList();
+
+        // Remove package
+        mService.onPackageRemoved(PKGS[0], PKG_UIDS[0], false /* isReplacing */);
+        verify(mVpn).refreshPlatformVpnAppExclusionList();
+
+        // Add the package back
+        mService.onPackageAdded(PKGS[0], PKG_UIDS[0], false /* isReplacing */);
+        verify(mVpn, times(2)).refreshPlatformVpnAppExclusionList();
+    }
+
+    @Test
+    public void testStartVpnProfileFromDiffPackage() {
+        assertThrows(
+                SecurityException.class, () -> mService.startVpnProfile(mNotMyVpnPkg));
+    }
+
+    @Test
+    public void testStopVpnProfileFromDiffPackage() {
+        assertThrows(SecurityException.class, () -> mService.stopVpnProfile(mNotMyVpnPkg));
+    }
+}
diff --git a/tests/unit/java/com/android/server/VpnTestBase.java b/tests/unit/java/com/android/server/VpnTestBase.java
new file mode 100644
index 0000000..6113872
--- /dev/null
+++ b/tests/unit/java/com/android/server/VpnTestBase.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 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
+ *
+ *      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.
+ */
+
+package com.android.server;
+
+import static android.content.pm.UserInfo.FLAG_ADMIN;
+import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
+import static android.content.pm.UserInfo.FLAG_PRIMARY;
+import static android.content.pm.UserInfo.FLAG_RESTRICTED;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.Process;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/** Common variables or methods shared between VpnTest and VpnManagerServiceTest. */
+public class VpnTestBase {
+    protected static final String TEST_VPN_PKG = "com.testvpn.vpn";
+    /**
+     * Names and UIDs for some fake packages. Important points:
+     *  - UID is ordered increasing.
+     *  - One pair of packages have consecutive UIDs.
+     */
+    protected static final String[] PKGS = {"com.example", "org.example", "net.example", "web.vpn"};
+    protected static final int[] PKG_UIDS = {10066, 10077, 10078, 10400};
+    // Mock packages
+    protected static final Map<String, Integer> sPackages = new ArrayMap<>();
+    static {
+        for (int i = 0; i < PKGS.length; i++) {
+            sPackages.put(PKGS[i], PKG_UIDS[i]);
+        }
+        sPackages.put(TEST_VPN_PKG, Process.myUid());
+    }
+
+    // Mock users
+    protected static final int SYSTEM_USER_ID = 0;
+    protected static final UserInfo SYSTEM_USER = new UserInfo(0, "system", UserInfo.FLAG_PRIMARY);
+    protected static final UserInfo PRIMARY_USER = new UserInfo(27, "Primary",
+            FLAG_ADMIN | FLAG_PRIMARY);
+    protected static final UserInfo SECONDARY_USER = new UserInfo(15, "Secondary", FLAG_ADMIN);
+    protected static final UserInfo RESTRICTED_PROFILE_A = new UserInfo(40, "RestrictedA",
+            FLAG_RESTRICTED);
+    protected static final UserInfo RESTRICTED_PROFILE_B = new UserInfo(42, "RestrictedB",
+            FLAG_RESTRICTED);
+    protected static final UserInfo MANAGED_PROFILE_A = new UserInfo(45, "ManagedA",
+            FLAG_MANAGED_PROFILE);
+    static {
+        RESTRICTED_PROFILE_A.restrictedProfileParentId = PRIMARY_USER.id;
+        RESTRICTED_PROFILE_B.restrictedProfileParentId = SECONDARY_USER.id;
+        MANAGED_PROFILE_A.profileGroupId = PRIMARY_USER.id;
+    }
+
+    // Populate a fake packageName-to-UID mapping.
+    protected void setMockedPackages(PackageManager mockPm, final Map<String, Integer> packages) {
+        try {
+            doAnswer(invocation -> {
+                final String appName = (String) invocation.getArguments()[0];
+                final int userId = (int) invocation.getArguments()[1];
+
+                final Integer appId = packages.get(appName);
+                if (appId == null) {
+                    throw new PackageManager.NameNotFoundException(appName);
+                }
+
+                return UserHandle.getUid(userId, appId);
+            }).when(mockPm).getPackageUidAsUser(anyString(), anyInt());
+        } catch (Exception e) {
+        }
+    }
+
+    protected List<Integer> toList(int[] arr) {
+        return Arrays.stream(arr).boxed().collect(Collectors.toList());
+    }
+}
diff --git a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
index 8dfe924..feee293 100644
--- a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
@@ -525,16 +525,19 @@
         coordinator.dump(ipw);
 
         final String[] dumpStrings = stringWriter.toString().split("\n");
-        assertEquals(5, dumpStrings.length);
-        assertEquals("Forwarding rules:", dumpStrings[0].trim());
+        assertEquals(6, dumpStrings.length);
+        assertEquals("CLAT tracker: iface: test0 (1000), v4iface: v4-test0 (1001), "
+                + "v4: /192.0.0.46, v6: /2001:db8:0:b11::464, pfx96: /64:ff9b::, "
+                + "pid: 10483, cookie: 27149", dumpStrings[0].trim());
+        assertEquals("Forwarding rules:", dumpStrings[1].trim());
         assertEquals("BPF ingress map: iif nat64Prefix v6Addr -> v4Addr oif",
-                dumpStrings[1].trim());
-        assertEquals("1000 /64:ff9b::/96 /2001:db8:0:b11::464 -> /192.0.0.46 1001",
                 dumpStrings[2].trim());
-        assertEquals("BPF egress map: iif v4Addr -> v6Addr nat64Prefix oif",
+        assertEquals("1000 /64:ff9b::/96 /2001:db8:0:b11::464 -> /192.0.0.46 1001",
                 dumpStrings[3].trim());
-        assertEquals("1001 /192.0.0.46 -> /2001:db8:0:b11::464 /64:ff9b::/96 1000 ether",
+        assertEquals("BPF egress map: iif v4Addr -> v6Addr nat64Prefix oif",
                 dumpStrings[4].trim());
+        assertEquals("1001 /192.0.0.46 -> /2001:db8:0:b11::464 /64:ff9b::/96 1000 ether",
+                dumpStrings[5].trim());
     }
 
     @Test
diff --git a/tests/unit/java/com/android/server/connectivity/VpnTest.java b/tests/unit/java/com/android/server/connectivity/VpnTest.java
index 8f1d3b8..0891ee3 100644
--- a/tests/unit/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/unit/java/com/android/server/connectivity/VpnTest.java
@@ -20,10 +20,6 @@
 import static android.Manifest.permission.CONTROL_VPN;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.content.pm.UserInfo.FLAG_ADMIN;
-import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
-import static android.content.pm.UserInfo.FLAG_PRIMARY;
-import static android.content.pm.UserInfo.FLAG_RESTRICTED;
 import static android.net.ConnectivityManager.NetworkCallback;
 import static android.net.INetd.IF_STATE_DOWN;
 import static android.net.INetd.IF_STATE_UP;
@@ -34,6 +30,7 @@
 import static android.os.UserHandle.PER_USER_RANGE;
 
 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
+import static com.android.testutils.Cleanup.testAndCleanup;
 import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 import static com.android.testutils.MiscAsserts.assertThrows;
 
@@ -96,10 +93,8 @@
 import android.net.LocalSocket;
 import android.net.Network;
 import android.net.NetworkAgent;
-import android.net.NetworkAgentConfig;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkProvider;
 import android.net.RouteInfo;
 import android.net.UidRangeParcel;
 import android.net.VpnManager;
@@ -121,7 +116,6 @@
 import android.os.Bundle;
 import android.os.ConditionVariable;
 import android.os.INetworkManagementService;
-import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.os.PowerWhitelistManager;
 import android.os.Process;
@@ -145,6 +139,7 @@
 import com.android.modules.utils.build.SdkLevel;
 import com.android.server.DeviceIdleInternal;
 import com.android.server.IpSecService;
+import com.android.server.VpnTestBase;
 import com.android.server.vcn.util.PersistableBundleUtils;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRunner;
@@ -177,6 +172,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -191,28 +188,15 @@
  */
 @RunWith(DevSdkIgnoreRunner.class)
 @SmallTest
-@IgnoreUpTo(VERSION_CODES.S_V2)
-public class VpnTest {
+@IgnoreUpTo(S_V2)
+public class VpnTest extends VpnTestBase {
     private static final String TAG = "VpnTest";
 
     @Rule
     public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
 
-    // Mock users
-    static final UserInfo primaryUser = new UserInfo(27, "Primary", FLAG_ADMIN | FLAG_PRIMARY);
-    static final UserInfo secondaryUser = new UserInfo(15, "Secondary", FLAG_ADMIN);
-    static final UserInfo restrictedProfileA = new UserInfo(40, "RestrictedA", FLAG_RESTRICTED);
-    static final UserInfo restrictedProfileB = new UserInfo(42, "RestrictedB", FLAG_RESTRICTED);
-    static final UserInfo managedProfileA = new UserInfo(45, "ManagedA", FLAG_MANAGED_PROFILE);
-    static {
-        restrictedProfileA.restrictedProfileParentId = primaryUser.id;
-        restrictedProfileB.restrictedProfileParentId = secondaryUser.id;
-        managedProfileA.profileGroupId = primaryUser.id;
-    }
-
     static final Network EGRESS_NETWORK = new Network(101);
     static final String EGRESS_IFACE = "wlan0";
-    static final String TEST_VPN_PKG = "com.testvpn.vpn";
     private static final String TEST_VPN_CLIENT = "2.4.6.8";
     private static final String TEST_VPN_SERVER = "1.2.3.4";
     private static final String TEST_VPN_IDENTITY = "identity";
@@ -249,23 +233,8 @@
     private static final long TEST_TIMEOUT_MS = 500L;
     private static final String PRIMARY_USER_APP_EXCLUDE_KEY =
             "VPN_APP_EXCLUDED_27_com.testvpn.vpn";
-    /**
-     * Names and UIDs for some fake packages. Important points:
-     *  - UID is ordered increasing.
-     *  - One pair of packages have consecutive UIDs.
-     */
-    static final String[] PKGS = {"com.example", "org.example", "net.example", "web.vpn"};
     static final String PKGS_BYTES = getPackageByteString(List.of(PKGS));
-    static final int[] PKG_UIDS = {10066, 10077, 10078, 10400};
-
-    // Mock packages
-    static final Map<String, Integer> mPackages = new ArrayMap<>();
-    static {
-        for (int i = 0; i < PKGS.length; i++) {
-            mPackages.put(PKGS[i], PKG_UIDS[i]);
-        }
-    }
-    private static final Range<Integer> PRI_USER_RANGE = uidRangeForUser(primaryUser.id);
+    private static final Range<Integer> PRIMARY_USER_RANGE = uidRangeForUser(PRIMARY_USER.id);
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
     @Mock private UserManager mUserManager;
@@ -307,7 +276,7 @@
         mTestDeps = spy(new TestDeps());
 
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
-        setMockedPackages(mPackages);
+        setMockedPackages(sPackages);
 
         when(mContext.getPackageName()).thenReturn(TEST_VPN_PKG);
         when(mContext.getOpPackageName()).thenReturn(TEST_VPN_PKG);
@@ -412,50 +381,51 @@
 
     @Test
     public void testRestrictedProfilesAreAddedToVpn() {
-        setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB);
+        setMockedUsers(PRIMARY_USER, SECONDARY_USER, RESTRICTED_PROFILE_A, RESTRICTED_PROFILE_B);
 
-        final Vpn vpn = createVpn(primaryUser.id);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
 
         // Assume the user can have restricted profiles.
         doReturn(true).when(mUserManager).canHaveRestrictedProfile();
         final Set<Range<Integer>> ranges =
-                vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null);
+                vpn.createUserAndRestrictedProfilesRanges(PRIMARY_USER.id, null, null);
 
-        assertEquals(rangeSet(PRI_USER_RANGE, uidRangeForUser(restrictedProfileA.id)), ranges);
+        assertEquals(rangeSet(PRIMARY_USER_RANGE, uidRangeForUser(RESTRICTED_PROFILE_A.id)),
+                 ranges);
     }
 
     @Test
     public void testManagedProfilesAreNotAddedToVpn() {
-        setMockedUsers(primaryUser, managedProfileA);
+        setMockedUsers(PRIMARY_USER, MANAGED_PROFILE_A);
 
-        final Vpn vpn = createVpn(primaryUser.id);
-        final Set<Range<Integer>> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
-                null, null);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
+        final Set<Range<Integer>> ranges = vpn.createUserAndRestrictedProfilesRanges(
+                PRIMARY_USER.id, null, null);
 
-        assertEquals(rangeSet(PRI_USER_RANGE), ranges);
+        assertEquals(rangeSet(PRIMARY_USER_RANGE), ranges);
     }
 
     @Test
     public void testAddUserToVpnOnlyAddsOneUser() {
-        setMockedUsers(primaryUser, restrictedProfileA, managedProfileA);
+        setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A, MANAGED_PROFILE_A);
 
-        final Vpn vpn = createVpn(primaryUser.id);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
         final Set<Range<Integer>> ranges = new ArraySet<>();
-        vpn.addUserToRanges(ranges, primaryUser.id, null, null);
+        vpn.addUserToRanges(ranges, PRIMARY_USER.id, null, null);
 
-        assertEquals(rangeSet(PRI_USER_RANGE), ranges);
+        assertEquals(rangeSet(PRIMARY_USER_RANGE), ranges);
     }
 
     @Test
     public void testUidAllowAndDenylist() throws Exception {
-        final Vpn vpn = createVpn(primaryUser.id);
-        final Range<Integer> user = PRI_USER_RANGE;
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
+        final Range<Integer> user = PRIMARY_USER_RANGE;
         final int userStart = user.getLower();
         final int userStop = user.getUpper();
         final String[] packages = {PKGS[0], PKGS[1], PKGS[2]};
 
         // Allowed list
-        final Set<Range<Integer>> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
+        final Set<Range<Integer>> allow = vpn.createUserAndRestrictedProfilesRanges(PRIMARY_USER.id,
                 Arrays.asList(packages), null /* disallowedApplications */);
         assertEquals(rangeSet(
                 uidRange(userStart + PKG_UIDS[0], userStart + PKG_UIDS[0]),
@@ -468,7 +438,7 @@
 
         // Denied list
         final Set<Range<Integer>> disallow =
-                vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
+                vpn.createUserAndRestrictedProfilesRanges(PRIMARY_USER.id,
                         null /* allowedApplications */, Arrays.asList(packages));
         assertEquals(rangeSet(
                 uidRange(userStart, userStart + PKG_UIDS[0] - 1),
@@ -490,7 +460,7 @@
 
     @Test
     public void testGetAlwaysAndOnGetLockDown() throws Exception {
-        final Vpn vpn = createVpn(primaryUser.id);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
 
         // Default state.
         assertFalse(vpn.getAlwaysOn());
@@ -514,8 +484,8 @@
 
     @Test
     public void testLockdownChangingPackage() throws Exception {
-        final Vpn vpn = createVpn(primaryUser.id);
-        final Range<Integer> user = PRI_USER_RANGE;
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
+        final Range<Integer> user = PRIMARY_USER_RANGE;
         final int userStart = user.getLower();
         final int userStop = user.getUpper();
         // Set always-on without lockdown.
@@ -548,8 +518,8 @@
 
     @Test
     public void testLockdownAllowlist() throws Exception {
-        final Vpn vpn = createVpn(primaryUser.id);
-        final Range<Integer> user = PRI_USER_RANGE;
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
+        final Range<Integer> user = PRIMARY_USER_RANGE;
         final int userStart = user.getLower();
         final int userStop = user.getUpper();
         // Set always-on with lockdown and allow app PKGS[2] from lockdown.
@@ -659,9 +629,9 @@
 
     @Test
     public void testLockdownRuleRepeatability() throws Exception {
-        final Vpn vpn = createVpn(primaryUser.id);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
         final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] {
-                new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper())};
+                new UidRangeParcel(PRIMARY_USER_RANGE.getLower(), PRIMARY_USER_RANGE.getUpper())};
         // Given legacy lockdown is already enabled,
         vpn.setLockdown(true);
         verify(mConnectivityManager, times(1)).setRequireVpnForUids(true,
@@ -692,9 +662,9 @@
     @Test
     public void testLockdownRuleReversibility() throws Exception {
         doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
-        final Vpn vpn = createVpn(primaryUser.id);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
         final UidRangeParcel[] entireUser = {
-            new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper())
+            new UidRangeParcel(PRIMARY_USER_RANGE.getLower(), PRIMARY_USER_RANGE.getUpper())
         };
         final UidRangeParcel[] exceptPkg0 = {
             new UidRangeParcel(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1),
@@ -744,17 +714,17 @@
 
     @Test
     public void testIsAlwaysOnPackageSupported() throws Exception {
-        final Vpn vpn = createVpn(primaryUser.id);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
 
         ApplicationInfo appInfo = new ApplicationInfo();
-        when(mPackageManager.getApplicationInfoAsUser(eq(PKGS[0]), anyInt(), eq(primaryUser.id)))
+        when(mPackageManager.getApplicationInfoAsUser(eq(PKGS[0]), anyInt(), eq(PRIMARY_USER.id)))
                 .thenReturn(appInfo);
 
         ServiceInfo svcInfo = new ServiceInfo();
         ResolveInfo resInfo = new ResolveInfo();
         resInfo.serviceInfo = svcInfo;
         when(mPackageManager.queryIntentServicesAsUser(any(), eq(PackageManager.GET_META_DATA),
-                eq(primaryUser.id)))
+                eq(PRIMARY_USER.id)))
                 .thenReturn(Collections.singletonList(resInfo));
 
         // null package name should return false
@@ -778,9 +748,9 @@
 
     @Test
     public void testNotificationShownForAlwaysOnApp() throws Exception {
-        final UserHandle userHandle = UserHandle.of(primaryUser.id);
-        final Vpn vpn = createVpn(primaryUser.id);
-        setMockedUsers(primaryUser);
+        final UserHandle userHandle = UserHandle.of(PRIMARY_USER.id);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
+        setMockedUsers(PRIMARY_USER);
 
         final InOrder order = inOrder(mNotificationManager);
 
@@ -813,15 +783,15 @@
      */
     @Test
     public void testGetProfileNameForPackage() throws Exception {
-        final Vpn vpn = createVpn(primaryUser.id);
-        setMockedUsers(primaryUser);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
+        setMockedUsers(PRIMARY_USER);
 
-        final String expected = Credentials.PLATFORM_VPN + primaryUser.id + "_" + TEST_VPN_PKG;
+        final String expected = Credentials.PLATFORM_VPN + PRIMARY_USER.id + "_" + TEST_VPN_PKG;
         assertEquals(expected, vpn.getProfileNameForPackage(TEST_VPN_PKG));
     }
 
     private Vpn createVpnAndSetupUidChecks(String... grantedOps) throws Exception {
-        return createVpnAndSetupUidChecks(primaryUser, grantedOps);
+        return createVpnAndSetupUidChecks(PRIMARY_USER, grantedOps);
     }
 
     private Vpn createVpnAndSetupUidChecks(UserInfo user, String... grantedOps) throws Exception {
@@ -878,14 +848,11 @@
 
         vpn.startVpnProfile(TEST_VPN_PKG);
         verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
-        vpn.mNetworkAgent = new NetworkAgent(mContext, Looper.getMainLooper(), TAG,
-                new NetworkCapabilities.Builder().build(), new LinkProperties(), 10 /* score */,
-                new NetworkAgentConfig.Builder().build(),
-                new NetworkProvider(mContext, Looper.getMainLooper(), TAG)) {};
+        vpn.mNetworkAgent = mMockNetworkAgent;
         return vpn;
     }
 
-    @Test @IgnoreUpTo(S_V2)
+    @Test
     public void testSetAndGetAppExclusionList() throws Exception {
         final Vpn vpn = prepareVpnForVerifyAppExclusionList();
         verify(mVpnProfileStore, never()).put(eq(PRIMARY_USER_APP_EXCLUDE_KEY), any());
@@ -894,16 +861,90 @@
                 .put(eq(PRIMARY_USER_APP_EXCLUDE_KEY),
                      eq(HexDump.hexStringToByteArray(PKGS_BYTES)));
         assertEquals(vpn.createUserAndRestrictedProfilesRanges(
-                primaryUser.id, null, Arrays.asList(PKGS)),
+                PRIMARY_USER.id, null, Arrays.asList(PKGS)),
                 vpn.mNetworkCapabilities.getUids());
         assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG));
     }
 
-    @Test @IgnoreUpTo(S_V2)
+    @Test
+    public void testRefreshPlatformVpnAppExclusionList_updatesExcludedUids() throws Exception {
+        final Vpn vpn = prepareVpnForVerifyAppExclusionList();
+        vpn.setAppExclusionList(TEST_VPN_PKG, Arrays.asList(PKGS));
+        verify(mMockNetworkAgent).sendNetworkCapabilities(any());
+        assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG));
+
+        reset(mMockNetworkAgent);
+
+        // Remove one of the package
+        List<Integer> newExcludedUids = toList(PKG_UIDS);
+        newExcludedUids.remove((Integer) PKG_UIDS[0]);
+        sPackages.remove(PKGS[0]);
+        vpn.refreshPlatformVpnAppExclusionList();
+
+        // List in keystore is not changed, but UID for the removed packages is no longer exempted.
+        assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG));
+        assertEquals(makeVpnUidRange(PRIMARY_USER.id, newExcludedUids),
+                vpn.mNetworkCapabilities.getUids());
+        ArgumentCaptor<NetworkCapabilities> ncCaptor =
+                ArgumentCaptor.forClass(NetworkCapabilities.class);
+        verify(mMockNetworkAgent).sendNetworkCapabilities(ncCaptor.capture());
+        assertEquals(makeVpnUidRange(PRIMARY_USER.id, newExcludedUids),
+                ncCaptor.getValue().getUids());
+
+        reset(mMockNetworkAgent);
+
+        // Add the package back
+        newExcludedUids.add(PKG_UIDS[0]);
+        sPackages.put(PKGS[0], PKG_UIDS[0]);
+        vpn.refreshPlatformVpnAppExclusionList();
+
+        // List in keystore is not changed and the uid list should be updated in the net cap.
+        assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG));
+        assertEquals(makeVpnUidRange(PRIMARY_USER.id, newExcludedUids),
+                vpn.mNetworkCapabilities.getUids());
+        verify(mMockNetworkAgent).sendNetworkCapabilities(ncCaptor.capture());
+        assertEquals(makeVpnUidRange(PRIMARY_USER.id, newExcludedUids),
+                ncCaptor.getValue().getUids());
+    }
+
+    private Set<Range<Integer>> makeVpnUidRange(int userId, List<Integer> excludedList) {
+        final SortedSet<Integer> list = new TreeSet<>();
+
+        final int userBase = userId * UserHandle.PER_USER_RANGE;
+        for (int uid : excludedList) {
+            final int applicationUid = UserHandle.getUid(userId, uid);
+            list.add(applicationUid);
+            list.add(Process.toSdkSandboxUid(applicationUid)); // Add Sdk Sandbox UID
+        }
+
+        final int minUid = userBase;
+        final int maxUid = userBase + UserHandle.PER_USER_RANGE - 1;
+        final Set<Range<Integer>> ranges = new ArraySet<>();
+
+        // Iterate the list to create the ranges between each uid.
+        int start = minUid;
+        for (int uid : list) {
+            if (uid == start) {
+                start++;
+            } else {
+                ranges.add(new Range<>(start, uid - 1));
+                start = uid + 1;
+            }
+        }
+
+        // Create the range between last uid and max uid.
+        if (start <= maxUid) {
+            ranges.add(new Range<>(start, maxUid));
+        }
+
+        return ranges;
+    }
+
+    @Test
     public void testSetAndGetAppExclusionListRestrictedUser() throws Exception {
         final Vpn vpn = prepareVpnForVerifyAppExclusionList();
         // Mock it to restricted profile
-        when(mUserManager.getUserInfo(anyInt())).thenReturn(restrictedProfileA);
+        when(mUserManager.getUserInfo(anyInt())).thenReturn(RESTRICTED_PROFILE_A);
         // Restricted users cannot configure VPNs
         assertThrows(SecurityException.class,
                 () -> vpn.setAppExclusionList(TEST_VPN_PKG, new ArrayList<>()));
@@ -953,7 +994,7 @@
     public void testProvisionVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
+                        RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile);
@@ -976,7 +1017,7 @@
     public void testDeleteVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
+                        RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.deleteVpnProfile(TEST_VPN_PKG);
@@ -1099,7 +1140,7 @@
     public void testStartVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
+                        RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.startVpnProfile(TEST_VPN_PKG);
@@ -1112,7 +1153,7 @@
     public void testStopVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
+                        RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.stopVpnProfile(TEST_VPN_PKG);
@@ -1183,7 +1224,7 @@
     private void verifyVpnManagerEvent(String sessionKey, String category, int errorClass,
             int errorCode, VpnProfileState... profileState) {
         final Context userContext =
-                mContext.createContextAsUser(UserHandle.of(primaryUser.id), 0 /* flags */);
+                mContext.createContextAsUser(UserHandle.of(PRIMARY_USER.id), 0 /* flags */);
         final ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
 
         final int verifyTimes = (profileState == null) ? 1 : profileState.length;
@@ -1250,7 +1291,7 @@
         assumeTrue(SdkLevel.isAtLeastT());
         // Calling setAlwaysOnPackage() needs to hold CONTROL_VPN.
         doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
-        final Vpn vpn = createVpn(primaryUser.id);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
         // Enable VPN always-on for PKGS[1].
         assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false /* lockdown */,
                 null /* lockdownAllowlist */));
@@ -1512,7 +1553,7 @@
     public void testStartPlatformVpnIllegalArgumentExceptionInSetup() throws Exception {
         when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any()))
                 .thenThrow(new IllegalArgumentException());
-        final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), mVpnProfile);
+        final Vpn vpn = startLegacyVpn(createVpn(PRIMARY_USER.id), mVpnProfile);
         final NetworkCallback cb = triggerOnAvailableAndGetCallback();
 
         verifyInterfaceSetCfgWithFlags(IF_STATE_UP);
@@ -1532,18 +1573,18 @@
                 eq(AppOpsManager.MODE_ALLOWED));
 
         verify(mSystemServices).settingsSecurePutStringForUser(
-                eq(Settings.Secure.ALWAYS_ON_VPN_APP), eq(TEST_VPN_PKG), eq(primaryUser.id));
+                eq(Settings.Secure.ALWAYS_ON_VPN_APP), eq(TEST_VPN_PKG), eq(PRIMARY_USER.id));
         verify(mSystemServices).settingsSecurePutIntForUser(
                 eq(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN), eq(lockdownEnabled ? 1 : 0),
-                eq(primaryUser.id));
+                eq(PRIMARY_USER.id));
         verify(mSystemServices).settingsSecurePutStringForUser(
-                eq(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST), eq(""), eq(primaryUser.id));
+                eq(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST), eq(""), eq(PRIMARY_USER.id));
     }
 
     @Test
     public void testSetAndStartAlwaysOnVpn() throws Exception {
-        final Vpn vpn = createVpn(primaryUser.id);
-        setMockedUsers(primaryUser);
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
+        setMockedUsers(PRIMARY_USER);
 
         // UID checks must return a different UID; otherwise it'll be treated as already prepared.
         final int uid = Process.myUid() + 1;
@@ -1560,7 +1601,7 @@
     }
 
     private Vpn startLegacyVpn(final Vpn vpn, final VpnProfile vpnProfile) throws Exception {
-        setMockedUsers(primaryUser);
+        setMockedUsers(PRIMARY_USER);
 
         // Dummy egress interface
         final LinkProperties lp = new LinkProperties();
@@ -1876,11 +1917,10 @@
         doReturn(new Network(102)).when(mConnectivityManager).registerNetworkAgent(any(), any(),
                 any(), any(), any(), any(), anyInt());
 
-        final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), profile);
+        final Vpn vpn = startLegacyVpn(createVpn(PRIMARY_USER.id), profile);
         final TestDeps deps = (TestDeps) vpn.mDeps;
 
-        // TODO: use import when this is merged in all branches and there's no merge conflict
-        com.android.testutils.Cleanup.testAndCleanup(() -> {
+        testAndCleanup(() -> {
             final String[] mtpdArgs = deps.mtpdArgs.get(10, TimeUnit.SECONDS);
             final String[] argsPrefix = new String[]{
                     EGRESS_IFACE, "pptp", profile.server, "1723", "name", profile.username,
@@ -1928,7 +1968,7 @@
                     legacyRunnerReady.open();
                     return new Network(102);
                 });
-        final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), profile);
+        final Vpn vpn = startLegacyVpn(createVpn(PRIMARY_USER.id), profile);
         final TestDeps deps = (TestDeps) vpn.mDeps;
         try {
             // udppsk and 1701 are the values for TYPE_L2TP_IPSEC_PSK
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/ConnectivityMonitorWithConnectivityManagerTests.java b/tests/unit/java/com/android/server/connectivity/mdns/ConnectivityMonitorWithConnectivityManagerTests.java
new file mode 100644
index 0000000..f84e2d8
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/ConnectivityMonitorWithConnectivityManagerTests.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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
+ */
+
+package com.android.server.connectivity.mdns;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.net.NetworkRequest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Tests for {@link ConnectivityMonitor}. */
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class ConnectivityMonitorWithConnectivityManagerTests {
+    @Mock private Context mContext;
+    @Mock private ConnectivityMonitor.Listener mockListener;
+    @Mock private ConnectivityManager mConnectivityManager;
+
+    private ConnectivityMonitorWithConnectivityManager monitor;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mConnectivityManager).when(mContext)
+                .getSystemService(Context.CONNECTIVITY_SERVICE);
+        monitor = new ConnectivityMonitorWithConnectivityManager(mContext, mockListener);
+    }
+
+    @Test
+    public void testInitialState_shouldNotRegisterNetworkCallback() {
+        verifyNetworkCallbackRegistered(0 /* time */);
+        verifyNetworkCallbackUnregistered(0 /* time */);
+    }
+
+    @Test
+    public void testStartDiscovery_shouldRegisterNetworkCallback() {
+        monitor.startWatchingConnectivityChanges();
+
+        verifyNetworkCallbackRegistered(1 /* time */);
+        verifyNetworkCallbackUnregistered(0 /* time */);
+    }
+
+    @Test
+    public void testStartDiscoveryTwice_shouldRegisterOneNetworkCallback() {
+        monitor.startWatchingConnectivityChanges();
+        monitor.startWatchingConnectivityChanges();
+
+        verifyNetworkCallbackRegistered(1 /* time */);
+        verifyNetworkCallbackUnregistered(0 /* time */);
+    }
+
+    @Test
+    public void testStopDiscovery_shouldUnregisterNetworkCallback() {
+        monitor.startWatchingConnectivityChanges();
+        monitor.stopWatchingConnectivityChanges();
+
+        verifyNetworkCallbackRegistered(1 /* time */);
+        verifyNetworkCallbackUnregistered(1 /* time */);
+    }
+
+    @Test
+    public void testStopDiscoveryTwice_shouldUnregisterNetworkCallback() {
+        monitor.startWatchingConnectivityChanges();
+        monitor.stopWatchingConnectivityChanges();
+
+        verifyNetworkCallbackRegistered(1 /* time */);
+        verifyNetworkCallbackUnregistered(1 /* time */);
+    }
+
+    @Test
+    public void testIntentFired_shouldNotifyListener() {
+        InOrder inOrder = inOrder(mockListener);
+        monitor.startWatchingConnectivityChanges();
+
+        final ArgumentCaptor<NetworkCallback> callbackCaptor =
+                ArgumentCaptor.forClass(NetworkCallback.class);
+        verify(mConnectivityManager, times(1)).registerNetworkCallback(
+                any(NetworkRequest.class), callbackCaptor.capture());
+
+        final NetworkCallback callback = callbackCaptor.getValue();
+        final Network testNetwork = new Network(1 /* netId */);
+
+        // Simulate network available.
+        callback.onAvailable(testNetwork);
+        inOrder.verify(mockListener).onConnectivityChanged();
+
+        // Simulate network lost.
+        callback.onLost(testNetwork);
+        inOrder.verify(mockListener).onConnectivityChanged();
+
+        // Simulate network unavailable.
+        callback.onUnavailable();
+        inOrder.verify(mockListener).onConnectivityChanged();
+    }
+
+    private void verifyNetworkCallbackRegistered(int time) {
+        verify(mConnectivityManager, times(time)).registerNetworkCallback(
+                any(NetworkRequest.class), any(NetworkCallback.class));
+    }
+
+    private void verifyNetworkCallbackUnregistered(int time) {
+        verify(mConnectivityManager, times(time))
+                .unregisterNetworkCallback(any(NetworkCallback.class));
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsDiscoveryManagerTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsDiscoveryManagerTests.java
new file mode 100644
index 0000000..3e3c3bf
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsDiscoveryManagerTests.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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
+ */
+
+package com.android.server.connectivity.mdns;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.text.TextUtils;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.IOException;
+import java.util.Collections;
+
+/** Tests for {@link MdnsDiscoveryManager}. */
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class MdnsDiscoveryManagerTests {
+
+    private static final String SERVICE_TYPE_1 = "_googlecast._tcp.local";
+    private static final String SERVICE_TYPE_2 = "_test._tcp.local";
+
+    @Mock private ExecutorProvider executorProvider;
+    @Mock private MdnsSocketClient socketClient;
+    @Mock private MdnsServiceTypeClient mockServiceTypeClientOne;
+    @Mock private MdnsServiceTypeClient mockServiceTypeClientTwo;
+
+    @Mock MdnsServiceBrowserListener mockListenerOne;
+    @Mock MdnsServiceBrowserListener mockListenerTwo;
+    private MdnsDiscoveryManager discoveryManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mockServiceTypeClientOne.getServiceTypeLabels())
+                .thenReturn(TextUtils.split(SERVICE_TYPE_1, "\\."));
+        when(mockServiceTypeClientTwo.getServiceTypeLabels())
+                .thenReturn(TextUtils.split(SERVICE_TYPE_2, "\\."));
+
+        discoveryManager = new MdnsDiscoveryManager(executorProvider, socketClient) {
+                    @Override
+                    MdnsServiceTypeClient createServiceTypeClient(@NonNull String serviceType) {
+                        if (serviceType.equals(SERVICE_TYPE_1)) {
+                            return mockServiceTypeClientOne;
+                        } else if (serviceType.equals(SERVICE_TYPE_2)) {
+                            return mockServiceTypeClientTwo;
+                        }
+                        return null;
+                    }
+                };
+    }
+
+    @Test
+    public void registerListener_unregisterListener() throws IOException {
+        discoveryManager.registerListener(
+                SERVICE_TYPE_1, mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+        verify(socketClient).startDiscovery();
+        verify(mockServiceTypeClientOne)
+                .startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+
+        when(mockServiceTypeClientOne.stopSendAndReceive(mockListenerOne)).thenReturn(true);
+        discoveryManager.unregisterListener(SERVICE_TYPE_1, mockListenerOne);
+        verify(mockServiceTypeClientOne).stopSendAndReceive(mockListenerOne);
+        verify(socketClient).stopDiscovery();
+    }
+
+    @Test
+    public void registerMultipleListeners() throws IOException {
+        discoveryManager.registerListener(
+                SERVICE_TYPE_1, mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+        verify(socketClient).startDiscovery();
+        verify(mockServiceTypeClientOne)
+                .startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+
+        discoveryManager.registerListener(
+                SERVICE_TYPE_2, mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
+        verify(mockServiceTypeClientTwo)
+                .startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
+    }
+
+    @Test
+    public void onResponseReceived() {
+        discoveryManager.registerListener(
+                SERVICE_TYPE_1, mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+        discoveryManager.registerListener(
+                SERVICE_TYPE_2, mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
+
+        MdnsResponse responseForServiceTypeOne = createMockResponse(SERVICE_TYPE_1);
+        discoveryManager.onResponseReceived(responseForServiceTypeOne);
+        verify(mockServiceTypeClientOne).processResponse(responseForServiceTypeOne);
+
+        MdnsResponse responseForServiceTypeTwo = createMockResponse(SERVICE_TYPE_2);
+        discoveryManager.onResponseReceived(responseForServiceTypeTwo);
+        verify(mockServiceTypeClientTwo).processResponse(responseForServiceTypeTwo);
+
+        MdnsResponse responseForSubtype = createMockResponse("subtype._sub._googlecast._tcp.local");
+        discoveryManager.onResponseReceived(responseForSubtype);
+        verify(mockServiceTypeClientOne).processResponse(responseForSubtype);
+    }
+
+    private MdnsResponse createMockResponse(String serviceType) {
+        MdnsPointerRecord mockPointerRecord = mock(MdnsPointerRecord.class);
+        MdnsResponse mockResponse = mock(MdnsResponse.class);
+        when(mockResponse.getPointerRecords())
+                .thenReturn(Collections.singletonList(mockPointerRecord));
+        when(mockPointerRecord.getName()).thenReturn(TextUtils.split(serviceType, "\\."));
+        return mockResponse;
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsPacketReaderTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsPacketReaderTests.java
new file mode 100644
index 0000000..19d8a00
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsPacketReaderTests.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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
+ */
+
+package com.android.server.connectivity.mdns;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.util.Locale;
+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class MdnsPacketReaderTests {
+
+    @Test
+    public void testLimits() throws IOException {
+        byte[] data = new byte[25];
+        DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
+
+        // After creating a new reader, confirm that the remaining is equal to the packet length
+        // (or that there is no temporary limit).
+        MdnsPacketReader packetReader = new MdnsPacketReader(datagramPacket);
+        assertEquals(data.length, packetReader.getRemaining());
+
+        // Confirm that we can set the temporary limit to 0.
+        packetReader.setLimit(0);
+        assertEquals(0, packetReader.getRemaining());
+
+        // Confirm that we can clear the temporary limit, and restore to the length of the packet.
+        packetReader.clearLimit();
+        assertEquals(data.length, packetReader.getRemaining());
+
+        // Confirm that we can set the temporary limit to the actual length of the packet.
+        // While parsing packets, it is common to set the limit to the length of the packet.
+        packetReader.setLimit(data.length);
+        assertEquals(data.length, packetReader.getRemaining());
+
+        // Confirm that we ignore negative limits.
+        packetReader.setLimit(-10);
+        assertEquals(data.length, packetReader.getRemaining());
+
+        // Confirm that we can set the temporary limit to something less than the packet length.
+        packetReader.setLimit(data.length / 2);
+        assertEquals(data.length / 2, packetReader.getRemaining());
+
+        // Confirm that we throw an exception if trying to set the temporary limit beyond the
+        // packet length.
+        packetReader.clearLimit();
+        try {
+            packetReader.setLimit(data.length * 2 + 1);
+            fail("Should have thrown an IOException when trying to set the temporary limit beyond "
+                    + "the packet length");
+        } catch (IOException e) {
+            // Expected
+        } catch (Exception e) {
+            fail(String.format(
+                    Locale.ROOT,
+                    "Should not have thrown any other exception except " + "for IOException: %s",
+                    e.getMessage()));
+        }
+        assertEquals(data.length, packetReader.getRemaining());
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
new file mode 100644
index 0000000..fdb4d4a
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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
+ */
+
+package com.android.server.connectivity.mdns;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.util.Log;
+
+import com.android.net.module.util.HexDump;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetSocketAddress;
+import java.util.List;
+
+// The record test data does not use compressed names (label pointers), since that would require
+// additional data to populate the label dictionary accordingly.
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class MdnsRecordTests {
+    private static final String TAG = "MdnsRecordTests";
+    private static final int MAX_PACKET_SIZE = 4096;
+    private static final InetSocketAddress MULTICAST_IPV4_ADDRESS =
+            new InetSocketAddress(MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT);
+    private static final InetSocketAddress MULTICAST_IPV6_ADDRESS =
+            new InetSocketAddress(MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT);
+
+    @Test
+    public void testInet4AddressRecord() throws IOException {
+        final byte[] dataIn = HexDump.hexStringToByteArray(
+                "0474657374000001" + "0001000011940004" + "0A010203");
+        assertNotNull(dataIn);
+        String dataInText = HexDump.dumpHexString(dataIn, 0, dataIn.length);
+
+        // Decode
+        DatagramPacket packet = new DatagramPacket(dataIn, dataIn.length);
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+
+        String[] name = reader.readLabels();
+        assertNotNull(name);
+        assertEquals(1, name.length);
+        assertEquals("test", name[0]);
+        String fqdn = MdnsRecord.labelsToString(name);
+        assertEquals("test", fqdn);
+
+        int type = reader.readUInt16();
+        assertEquals(MdnsRecord.TYPE_A, type);
+
+        MdnsInetAddressRecord record = new MdnsInetAddressRecord(name, MdnsRecord.TYPE_A, reader);
+        Inet4Address addr = record.getInet4Address();
+        assertEquals("/10.1.2.3", addr.toString());
+
+        // Encode
+        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
+        record.write(writer, record.getReceiptTime());
+
+        packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
+        byte[] dataOut = packet.getData();
+
+        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        Log.d(TAG, dataOutText);
+
+        assertEquals(dataInText, dataOutText);
+    }
+
+    @Test
+    public void testTypeAAAInet6AddressRecord() throws IOException {
+        final byte[] dataIn = HexDump.hexStringToByteArray(
+                "047465737400001C"
+                        + "0001000011940010"
+                        + "AABBCCDD11223344"
+                        + "A0B0C0D010203040");
+        assertNotNull(dataIn);
+        String dataInText = HexDump.dumpHexString(dataIn, 0, dataIn.length);
+
+        // Decode
+        DatagramPacket packet = new DatagramPacket(dataIn, dataIn.length);
+        packet.setSocketAddress(
+                new InetSocketAddress(MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT));
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+
+        String[] name = reader.readLabels();
+        assertNotNull(name);
+        assertEquals(1, name.length);
+        String fqdn = MdnsRecord.labelsToString(name);
+        assertEquals("test", fqdn);
+
+        int type = reader.readUInt16();
+        assertEquals(MdnsRecord.TYPE_AAAA, type);
+
+        MdnsInetAddressRecord record = new MdnsInetAddressRecord(name, MdnsRecord.TYPE_AAAA,
+                reader);
+        assertNull(record.getInet4Address());
+        Inet6Address addr = record.getInet6Address();
+        assertEquals("/aabb:ccdd:1122:3344:a0b0:c0d0:1020:3040", addr.toString());
+
+        // Encode
+        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
+        record.write(writer, record.getReceiptTime());
+
+        packet = writer.getPacket(MULTICAST_IPV6_ADDRESS);
+        byte[] dataOut = packet.getData();
+
+        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        Log.d(TAG, dataOutText);
+
+        assertEquals(dataInText, dataOutText);
+    }
+
+    @Test
+    public void testTypeAAAInet4AddressRecord() throws IOException {
+        final byte[] dataIn = HexDump.hexStringToByteArray(
+                "047465737400001C"
+                        + "0001000011940010"
+                        + "0000000000000000"
+                        + "0000FFFF10203040");
+        assertNotNull(dataIn);
+        HexDump.dumpHexString(dataIn, 0, dataIn.length);
+
+        // Decode
+        DatagramPacket packet = new DatagramPacket(dataIn, dataIn.length);
+        packet.setSocketAddress(
+                new InetSocketAddress(MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT));
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+
+        String[] name = reader.readLabels();
+        assertNotNull(name);
+        assertEquals(1, name.length);
+        String fqdn = MdnsRecord.labelsToString(name);
+        assertEquals("test", fqdn);
+
+        int type = reader.readUInt16();
+        assertEquals(MdnsRecord.TYPE_AAAA, type);
+
+        MdnsInetAddressRecord record = new MdnsInetAddressRecord(name, MdnsRecord.TYPE_AAAA,
+                reader);
+        assertNull(record.getInet6Address());
+        Inet4Address addr = record.getInet4Address();
+        assertEquals("/16.32.48.64", addr.toString());
+
+        // Encode
+        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
+        record.write(writer, record.getReceiptTime());
+
+        packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
+        byte[] dataOut = packet.getData();
+
+        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        Log.d(TAG, dataOutText);
+
+        final byte[] expectedDataIn =
+                HexDump.hexStringToByteArray("047465737400001C000100001194000410203040");
+        assertNotNull(expectedDataIn);
+        String expectedDataInText = HexDump.dumpHexString(expectedDataIn, 0, expectedDataIn.length);
+
+        assertEquals(expectedDataInText, dataOutText);
+    }
+
+    @Test
+    public void testPointerRecord() throws IOException {
+        final byte[] dataIn = HexDump.hexStringToByteArray(
+                "047465737400000C"
+                        + "000100001194000E"
+                        + "03666F6F03626172"
+                        + "047175787800");
+        assertNotNull(dataIn);
+        String dataInText = HexDump.dumpHexString(dataIn, 0, dataIn.length);
+
+        // Decode
+        DatagramPacket packet = new DatagramPacket(dataIn, dataIn.length);
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+
+        String[] name = reader.readLabels();
+        assertNotNull(name);
+        assertEquals(1, name.length);
+        String fqdn = MdnsRecord.labelsToString(name);
+        assertEquals("test", fqdn);
+
+        int type = reader.readUInt16();
+        assertEquals(MdnsRecord.TYPE_PTR, type);
+
+        MdnsPointerRecord record = new MdnsPointerRecord(name, reader);
+        String[] pointer = record.getPointer();
+        assertEquals("foo.bar.quxx", MdnsRecord.labelsToString(pointer));
+
+        assertFalse(record.hasSubtype());
+        assertNull(record.getSubtype());
+
+        // Encode
+        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
+        record.write(writer, record.getReceiptTime());
+
+        packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
+        byte[] dataOut = packet.getData();
+
+        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        Log.d(TAG, dataOutText);
+
+        assertEquals(dataInText, dataOutText);
+    }
+
+    @Test
+    public void testServiceRecord() throws IOException {
+        final byte[] dataIn = HexDump.hexStringToByteArray(
+                "0474657374000021"
+                        + "0001000011940014"
+                        + "000100FF1F480366"
+                        + "6F6F036261720471"
+                        + "75787800");
+        assertNotNull(dataIn);
+        String dataInText = HexDump.dumpHexString(dataIn, 0, dataIn.length);
+
+        // Decode
+        DatagramPacket packet = new DatagramPacket(dataIn, dataIn.length);
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+
+        String[] name = reader.readLabels();
+        assertNotNull(name);
+        assertEquals(1, name.length);
+        String fqdn = MdnsRecord.labelsToString(name);
+        assertEquals("test", fqdn);
+
+        int type = reader.readUInt16();
+        assertEquals(MdnsRecord.TYPE_SRV, type);
+
+        MdnsServiceRecord record = new MdnsServiceRecord(name, reader);
+
+        int servicePort = record.getServicePort();
+        assertEquals(8008, servicePort);
+
+        String serviceHost = MdnsRecord.labelsToString(record.getServiceHost());
+        assertEquals("foo.bar.quxx", serviceHost);
+
+        assertEquals(1, record.getServicePriority());
+        assertEquals(255, record.getServiceWeight());
+
+        // Encode
+        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
+        record.write(writer, record.getReceiptTime());
+
+        packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
+        byte[] dataOut = packet.getData();
+
+        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        Log.d(TAG, dataOutText);
+
+        assertEquals(dataInText, dataOutText);
+    }
+
+    @Test
+    public void testTextRecord() throws IOException {
+        final byte[] dataIn = HexDump.hexStringToByteArray(
+                "0474657374000010"
+                        + "0001000011940024"
+                        + "0D613D68656C6C6F"
+                        + "2074686572650C62"
+                        + "3D31323334353637"
+                        + "3839300878797A3D"
+                        + "21402324");
+        assertNotNull(dataIn);
+        String dataInText = HexDump.dumpHexString(dataIn, 0, dataIn.length);
+
+        // Decode
+        DatagramPacket packet = new DatagramPacket(dataIn, dataIn.length);
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+
+        String[] name = reader.readLabels();
+        assertNotNull(name);
+        assertEquals(1, name.length);
+        String fqdn = MdnsRecord.labelsToString(name);
+        assertEquals("test", fqdn);
+
+        int type = reader.readUInt16();
+        assertEquals(MdnsRecord.TYPE_TXT, type);
+
+        MdnsTextRecord record = new MdnsTextRecord(name, reader);
+
+        List<String> strings = record.getStrings();
+        assertNotNull(strings);
+        assertEquals(3, strings.size());
+
+        assertEquals("a=hello there", strings.get(0));
+        assertEquals("b=1234567890", strings.get(1));
+        assertEquals("xyz=!@#$", strings.get(2));
+
+        // Encode
+        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
+        record.write(writer, record.getReceiptTime());
+
+        packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
+        byte[] dataOut = packet.getData();
+
+        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        Log.d(TAG, dataOutText);
+
+        assertEquals(dataInText, dataOutText);
+    }
+}
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
new file mode 100644
index 0000000..ea9156c
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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
+ */
+
+package com.android.server.connectivity.mdns;
+
+import static com.android.server.connectivity.mdns.MdnsResponseDecoder.Clock;
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import com.android.net.module.util.HexDump;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetSocketAddress;
+import java.util.LinkedList;
+import java.util.List;
+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class MdnsResponseDecoderTests {
+    private static final byte[] data = HexDump.hexStringToByteArray(
+            "0000840000000004"
+            + "00000003134A6F68"
+            + "6E6E792773204368"
+            + "726F6D6563617374"
+            + "0B5F676F6F676C65"
+            + "63617374045F7463"
+            + "70056C6F63616C00"
+            + "0010800100001194"
+            + "006C2369643D3937"
+            + "3062663534376237"
+            + "3533666336336332"
+            + "6432613336626238"
+            + "3936616261380576"
+            + "653D30320D6D643D"
+            + "4368726F6D656361"
+            + "73741269633D2F73"
+            + "657475702F69636F"
+            + "6E2E706E6716666E"
+            + "3D4A6F686E6E7927"
+            + "73204368726F6D65"
+            + "636173740463613D"
+            + "350473743D30095F"
+            + "7365727669636573"
+            + "075F646E732D7364"
+            + "045F756470C03100"
+            + "0C00010000119400"
+            + "02C020C020000C00"
+            + "01000011940002C0"
+            + "0CC00C0021800100"
+            + "000078001C000000"
+            + "001F49134A6F686E"
+            + "6E79277320436872"
+            + "6F6D6563617374C0"
+            + "31C0F30001800100"
+            + "0000780004C0A864"
+            + "68C0F3002F800100"
+            + "0000780005C0F300"
+            + "0140C00C002F8001"
+            + "000011940009C00C"
+            + "00050000800040");
+
+    private static final byte[] data6 = HexDump.hexStringToByteArray(
+            "0000840000000001000000030B5F676F6F676C656361737404"
+            + "5F746370056C6F63616C00000C000100000078003330476F6F676C"
+            + "652D486F6D652D4D61782D61363836666331323961366638636265"
+            + "31643636353139343065336164353766C00CC02E00108001000011"
+            + "9400C02369643D6136383666633132396136663863626531643636"
+            + "3531393430653361643537662363643D4133304233303032363546"
+            + "36384341313233353532434639344141353742314613726D3D4335"
+            + "35393134383530383841313638330576653D3035126D643D476F6F"
+            + "676C6520486F6D65204D61781269633D2F73657475702F69636F6E"
+            + "2E706E6710666E3D417474696320737065616B65720863613D3130"
+            + "3234340473743D320F62733D464138464341363734453537046E66"
+            + "3D320372733DC02E0021800100000078002D000000001F49246136"
+            + "3836666331322D396136662D386362652D316436362D3531393430"
+            + "65336164353766C01DC13F001C8001000000780010200033330000"
+            + "0000DA6C63FFFE7C74830109018001000000780004C0A801026C6F"
+            + "63616C0000018001000000780004C0A8010A000001800100000078"
+            + "0004C0A8010A00000000000000");
+
+    private static final String DUMMY_CAST_SERVICE_NAME = "_googlecast";
+    private static final String[] DUMMY_CAST_SERVICE_TYPE =
+            new String[] {DUMMY_CAST_SERVICE_NAME, "_tcp", "local"};
+
+    private final List<MdnsResponse> responses = new LinkedList<>();
+
+    private final Clock mClock = mock(Clock.class);
+
+    @Before
+    public void setUp() {
+        MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, DUMMY_CAST_SERVICE_TYPE);
+        assertNotNull(data);
+        DatagramPacket packet = new DatagramPacket(data, data.length);
+        packet.setSocketAddress(
+                new InetSocketAddress(MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT));
+        responses.clear();
+        int errorCode = decoder.decode(packet, responses);
+        assertEquals(MdnsResponseDecoder.SUCCESS, errorCode);
+        assertEquals(1, responses.size());
+    }
+
+    @Test
+    public void testDecodeWithNullServiceType() {
+        MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, null);
+        assertNotNull(data);
+        DatagramPacket packet = new DatagramPacket(data, data.length);
+        packet.setSocketAddress(
+                new InetSocketAddress(MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT));
+        responses.clear();
+        int errorCode = decoder.decode(packet, responses);
+        assertEquals(MdnsResponseDecoder.SUCCESS, errorCode);
+        assertEquals(2, responses.size());
+    }
+
+    @Test
+    public void testDecodeMultipleAnswerPacket() throws IOException {
+        MdnsResponse response = responses.get(0);
+        assertTrue(response.isComplete());
+
+        MdnsInetAddressRecord inet4AddressRecord = response.getInet4AddressRecord();
+        Inet4Address inet4Addr = inet4AddressRecord.getInet4Address();
+
+        assertNotNull(inet4Addr);
+        assertEquals("/192.168.100.104", inet4Addr.toString());
+
+        MdnsServiceRecord serviceRecord = response.getServiceRecord();
+        String serviceName = serviceRecord.getServiceName();
+        assertEquals(DUMMY_CAST_SERVICE_NAME, serviceName);
+
+        String serviceInstanceName = serviceRecord.getServiceInstanceName();
+        assertEquals("Johnny's Chromecast", serviceInstanceName);
+
+        String serviceHost = MdnsRecord.labelsToString(serviceRecord.getServiceHost());
+        assertEquals("Johnny's Chromecast.local", serviceHost);
+
+        int serviceProto = serviceRecord.getServiceProtocol();
+        assertEquals(MdnsServiceRecord.PROTO_TCP, serviceProto);
+
+        int servicePort = serviceRecord.getServicePort();
+        assertEquals(8009, servicePort);
+
+        int servicePriority = serviceRecord.getServicePriority();
+        assertEquals(0, servicePriority);
+
+        int serviceWeight = serviceRecord.getServiceWeight();
+        assertEquals(0, serviceWeight);
+
+        MdnsTextRecord textRecord = response.getTextRecord();
+        List<String> textStrings = textRecord.getStrings();
+        assertEquals(7, textStrings.size());
+        assertEquals("id=970bf547b753fc63c2d2a36bb896aba8", textStrings.get(0));
+        assertEquals("ve=02", textStrings.get(1));
+        assertEquals("md=Chromecast", textStrings.get(2));
+        assertEquals("ic=/setup/icon.png", textStrings.get(3));
+        assertEquals("fn=Johnny's Chromecast", textStrings.get(4));
+        assertEquals("ca=5", textStrings.get(5));
+        assertEquals("st=0", textStrings.get(6));
+    }
+
+    @Test
+    public void testDecodeIPv6AnswerPacket() throws IOException {
+        MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, DUMMY_CAST_SERVICE_TYPE);
+        assertNotNull(data6);
+        DatagramPacket packet = new DatagramPacket(data6, data6.length);
+        packet.setSocketAddress(
+                new InetSocketAddress(MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT));
+
+        responses.clear();
+        int errorCode = decoder.decode(packet, responses);
+        assertEquals(MdnsResponseDecoder.SUCCESS, errorCode);
+
+        MdnsResponse response = responses.get(0);
+        assertTrue(response.isComplete());
+
+        MdnsInetAddressRecord inet6AddressRecord = response.getInet6AddressRecord();
+        assertNotNull(inet6AddressRecord);
+        Inet4Address inet4Addr = inet6AddressRecord.getInet4Address();
+        assertNull(inet4Addr);
+
+        Inet6Address inet6Addr = inet6AddressRecord.getInet6Address();
+        assertNotNull(inet6Addr);
+        assertEquals(inet6Addr.getHostAddress(), "2000:3333::da6c:63ff:fe7c:7483");
+    }
+
+    @Test
+    public void testIsComplete() {
+        MdnsResponse response = responses.get(0);
+        assertTrue(response.isComplete());
+
+        response.clearPointerRecords();
+        assertFalse(response.isComplete());
+
+        response = responses.get(0);
+        response.setInet4AddressRecord(null);
+        assertFalse(response.isComplete());
+
+        response = responses.get(0);
+        response.setInet6AddressRecord(null);
+        assertFalse(response.isComplete());
+
+        response = responses.get(0);
+        response.setServiceRecord(null);
+        assertFalse(response.isComplete());
+
+        response = responses.get(0);
+        response.setTextRecord(null);
+        assertFalse(response.isComplete());
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
new file mode 100644
index 0000000..ae16f2b
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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
+ */
+
+package com.android.server.connectivity.mdns;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.net.module.util.HexDump;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.util.Arrays;
+import java.util.List;
+
+// The record test data does not use compressed names (label pointers), since that would require
+// additional data to populate the label dictionary accordingly.
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class MdnsResponseTests {
+    private static final String TAG = "MdnsResponseTests";
+    // MDNS response packet for name "test" with an IPv4 address of 10.1.2.3
+    private static final byte[] dataIn_ipv4_1 = HexDump.hexStringToByteArray(
+            "0474657374000001" + "0001000011940004" + "0A010203");
+    // MDNS response packet for name "tess" with an IPv4 address of 10.1.2.4
+    private static final byte[] dataIn_ipv4_2 = HexDump.hexStringToByteArray(
+            "0474657373000001" + "0001000011940004" + "0A010204");
+    // MDNS response w/name "test" & IPv6 address of aabb:ccdd:1122:3344:a0b0:c0d0:1020:3040
+    private static final byte[] dataIn_ipv6_1 = HexDump.hexStringToByteArray(
+            "047465737400001C" + "0001000011940010" + "AABBCCDD11223344" + "A0B0C0D010203040");
+    // MDNS response w/name "test" & IPv6 address of aabb:ccdd:1122:3344:a0b0:c0d0:1020:3030
+    private static final byte[] dataIn_ipv6_2 = HexDump.hexStringToByteArray(
+            "047465737400001C" + "0001000011940010" + "AABBCCDD11223344" + "A0B0C0D010203030");
+    // MDNS response w/name "test" & PTR to foo.bar.quxx
+    private static final byte[] dataIn_ptr_1 = HexDump.hexStringToByteArray(
+            "047465737400000C" + "000100001194000E" + "03666F6F03626172" + "047175787800");
+    // MDNS response w/name "test" & PTR to foo.bar.quxy
+    private static final byte[] dataIn_ptr_2 = HexDump.hexStringToByteArray(
+            "047465737400000C" + "000100001194000E" + "03666F6F03626172" + "047175787900");
+    // MDNS response w/name "test" & Service for host foo.bar.quxx
+    private static final byte[] dataIn_service_1 = HexDump.hexStringToByteArray(
+            "0474657374000021"
+            + "0001000011940014"
+            + "000100FF1F480366"
+            + "6F6F036261720471"
+            + "75787800");
+    // MDNS response w/name "test" & Service for host test
+    private static final byte[] dataIn_service_2 = HexDump.hexStringToByteArray(
+            "0474657374000021" + "000100001194000B" + "000100FF1F480474" + "657374");
+    // MDNS response w/name "test" & the following text strings:
+    // "a=hello there", "b=1234567890", and "xyz=!$$$"
+    private static final byte[] dataIn_text_1 = HexDump.hexStringToByteArray(
+            "0474657374000010"
+            + "0001000011940024"
+            + "0D613D68656C6C6F"
+            + "2074686572650C62"
+            + "3D31323334353637"
+            + "3839300878797A3D"
+            + "21242424");
+    // MDNS response w/name "test" & the following text strings:
+    // "a=hello there", "b=1234567890", and "xyz=!@#$"
+    private static final byte[] dataIn_text_2 = HexDump.hexStringToByteArray(
+            "0474657374000010"
+            + "0001000011940024"
+            + "0D613D68656C6C6F"
+            + "2074686572650C62"
+            + "3D31323334353637"
+            + "3839300878797A3D"
+            + "21402324");
+
+    // The following helper classes act as wrappers so that IPv4 and IPv6 address records can
+    // be explicitly created by type using same constructor signature as all other records.
+    static class MdnsInet4AddressRecord extends MdnsInetAddressRecord {
+        public MdnsInet4AddressRecord(String[] name, MdnsPacketReader reader) throws IOException {
+            super(name, MdnsRecord.TYPE_A, reader);
+        }
+    }
+
+    static class MdnsInet6AddressRecord extends MdnsInetAddressRecord {
+        public MdnsInet6AddressRecord(String[] name, MdnsPacketReader reader) throws IOException {
+            super(name, MdnsRecord.TYPE_AAAA, reader);
+        }
+    }
+
+    // This helper class just wraps the data bytes of a response packet with the contained record
+    // type.
+    // Its only purpose is to make the test code a bit more readable.
+    static class PacketAndRecordClass {
+        public final byte[] packetData;
+        public final Class<?> recordClass;
+
+        public PacketAndRecordClass() {
+            packetData = null;
+            recordClass = null;
+        }
+
+        public PacketAndRecordClass(byte[] data, Class<?> c) {
+            packetData = data;
+            recordClass = c;
+        }
+    }
+
+    // Construct an MdnsResponse with the specified data packets applied.
+    private MdnsResponse makeMdnsResponse(long time, List<PacketAndRecordClass> responseList)
+            throws IOException {
+        MdnsResponse response = new MdnsResponse(time);
+        for (PacketAndRecordClass responseData : responseList) {
+            DatagramPacket packet =
+                    new DatagramPacket(responseData.packetData, responseData.packetData.length);
+            MdnsPacketReader reader = new MdnsPacketReader(packet);
+            String[] name = reader.readLabels();
+            reader.skip(2); // skip record type indication.
+            // Apply the right kind of record to the response.
+            if (responseData.recordClass == MdnsInet4AddressRecord.class) {
+                response.setInet4AddressRecord(new MdnsInet4AddressRecord(name, reader));
+            } else if (responseData.recordClass == MdnsInet6AddressRecord.class) {
+                response.setInet6AddressRecord(new MdnsInet6AddressRecord(name, reader));
+            } else if (responseData.recordClass == MdnsPointerRecord.class) {
+                response.addPointerRecord(new MdnsPointerRecord(name, reader));
+            } else if (responseData.recordClass == MdnsServiceRecord.class) {
+                response.setServiceRecord(new MdnsServiceRecord(name, reader));
+            } else if (responseData.recordClass == MdnsTextRecord.class) {
+                response.setTextRecord(new MdnsTextRecord(name, reader));
+            } else {
+                fail("Unsupported/unexpected MdnsRecord subtype used in test - invalid test!");
+            }
+        }
+        return response;
+    }
+
+    @Test
+    public void getInet4AddressRecord_returnsAddedRecord() throws IOException {
+        DatagramPacket packet = new DatagramPacket(dataIn_ipv4_1, dataIn_ipv4_1.length);
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+        String[] name = reader.readLabels();
+        reader.skip(2); // skip record type indication.
+        MdnsInetAddressRecord record = new MdnsInetAddressRecord(name, MdnsRecord.TYPE_A, reader);
+        MdnsResponse response = new MdnsResponse(0);
+        assertFalse(response.hasInet4AddressRecord());
+        assertTrue(response.setInet4AddressRecord(record));
+        assertEquals(response.getInet4AddressRecord(), record);
+    }
+
+    @Test
+    public void getInet6AddressRecord_returnsAddedRecord() throws IOException {
+        DatagramPacket packet = new DatagramPacket(dataIn_ipv6_1, dataIn_ipv6_1.length);
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+        String[] name = reader.readLabels();
+        reader.skip(2); // skip record type indication.
+        MdnsInetAddressRecord record =
+                new MdnsInetAddressRecord(name, MdnsRecord.TYPE_AAAA, reader);
+        MdnsResponse response = new MdnsResponse(0);
+        assertFalse(response.hasInet6AddressRecord());
+        assertTrue(response.setInet6AddressRecord(record));
+        assertEquals(response.getInet6AddressRecord(), record);
+    }
+
+    @Test
+    public void getPointerRecords_returnsAddedRecord() throws IOException {
+        DatagramPacket packet = new DatagramPacket(dataIn_ptr_1, dataIn_ptr_1.length);
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+        String[] name = reader.readLabels();
+        reader.skip(2); // skip record type indication.
+        MdnsPointerRecord record = new MdnsPointerRecord(name, reader);
+        MdnsResponse response = new MdnsResponse(0);
+        assertFalse(response.hasPointerRecords());
+        assertTrue(response.addPointerRecord(record));
+        List<MdnsPointerRecord> recordList = response.getPointerRecords();
+        assertNotNull(recordList);
+        assertEquals(1, recordList.size());
+        assertEquals(record, recordList.get(0));
+    }
+
+    @Test
+    public void getServiceRecord_returnsAddedRecord() throws IOException {
+        DatagramPacket packet = new DatagramPacket(dataIn_service_1, dataIn_service_1.length);
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+        String[] name = reader.readLabels();
+        reader.skip(2); // skip record type indication.
+        MdnsServiceRecord record = new MdnsServiceRecord(name, reader);
+        MdnsResponse response = new MdnsResponse(0);
+        assertFalse(response.hasServiceRecord());
+        assertTrue(response.setServiceRecord(record));
+        assertEquals(response.getServiceRecord(), record);
+    }
+
+    @Test
+    public void getTextRecord_returnsAddedRecord() throws IOException {
+        DatagramPacket packet = new DatagramPacket(dataIn_text_1, dataIn_text_1.length);
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+        String[] name = reader.readLabels();
+        reader.skip(2); // skip record type indication.
+        MdnsTextRecord record = new MdnsTextRecord(name, reader);
+        MdnsResponse response = new MdnsResponse(0);
+        assertFalse(response.hasTextRecord());
+        assertTrue(response.setTextRecord(record));
+        assertEquals(response.getTextRecord(), record);
+    }
+
+    @Test
+    public void mergeRecordsFrom_indicates_change_on_ipv4_address() throws IOException {
+        MdnsResponse response = makeMdnsResponse(
+                0,
+                Arrays.asList(
+                        new PacketAndRecordClass(dataIn_ipv4_1, MdnsInet4AddressRecord.class)));
+        // Now create a new response that updates the address.
+        MdnsResponse response2 = makeMdnsResponse(
+                100,
+                Arrays.asList(
+                        new PacketAndRecordClass(dataIn_ipv4_2, MdnsInet4AddressRecord.class)));
+        assertTrue(response.mergeRecordsFrom(response2));
+    }
+
+    @Test
+    public void mergeRecordsFrom_indicates_change_on_ipv6_address() throws IOException {
+        MdnsResponse response = makeMdnsResponse(
+                0,
+                Arrays.asList(
+                        new PacketAndRecordClass(dataIn_ipv6_1, MdnsInet6AddressRecord.class)));
+        // Now create a new response that updates the address.
+        MdnsResponse response2 = makeMdnsResponse(
+                100,
+                Arrays.asList(
+                        new PacketAndRecordClass(dataIn_ipv6_2, MdnsInet6AddressRecord.class)));
+        assertTrue(response.mergeRecordsFrom(response2));
+    }
+
+    @Test
+    public void mergeRecordsFrom_indicates_change_on_text() throws IOException {
+        MdnsResponse response = makeMdnsResponse(
+                0,
+                Arrays.asList(new PacketAndRecordClass(dataIn_text_1, MdnsTextRecord.class)));
+        // Now create a new response that updates the address.
+        MdnsResponse response2 = makeMdnsResponse(
+                100,
+                Arrays.asList(new PacketAndRecordClass(dataIn_text_2, MdnsTextRecord.class)));
+        assertTrue(response.mergeRecordsFrom(response2));
+    }
+
+    @Test
+    public void mergeRecordsFrom_indicates_change_on_service() throws IOException {
+        MdnsResponse response = makeMdnsResponse(
+                0,
+                Arrays.asList(new PacketAndRecordClass(dataIn_service_1, MdnsServiceRecord.class)));
+        // Now create a new response that updates the address.
+        MdnsResponse response2 = makeMdnsResponse(
+                100,
+                Arrays.asList(new PacketAndRecordClass(dataIn_service_2, MdnsServiceRecord.class)));
+        assertTrue(response.mergeRecordsFrom(response2));
+    }
+
+    @Test
+    public void mergeRecordsFrom_indicates_change_on_pointer() throws IOException {
+        MdnsResponse response = makeMdnsResponse(
+                0,
+                Arrays.asList(new PacketAndRecordClass(dataIn_ptr_1, MdnsPointerRecord.class)));
+        // Now create a new response that updates the address.
+        MdnsResponse response2 = makeMdnsResponse(
+                100,
+                Arrays.asList(new PacketAndRecordClass(dataIn_ptr_2, MdnsPointerRecord.class)));
+        assertTrue(response.mergeRecordsFrom(response2));
+    }
+
+    @Test
+    @Ignore("MdnsConfigs is not configurable currently.")
+    public void mergeRecordsFrom_indicates_noChange() throws IOException {
+        //MdnsConfigsFlagsImpl.useReducedMergeRecordUpdateEvents.override(true);
+        List<PacketAndRecordClass> recordList =
+                Arrays.asList(
+                        new PacketAndRecordClass(dataIn_ipv4_1, MdnsInet4AddressRecord.class),
+                        new PacketAndRecordClass(dataIn_ipv6_1, MdnsInet6AddressRecord.class),
+                        new PacketAndRecordClass(dataIn_ptr_1, MdnsPointerRecord.class),
+                        new PacketAndRecordClass(dataIn_service_2, MdnsServiceRecord.class),
+                        new PacketAndRecordClass(dataIn_text_1, MdnsTextRecord.class));
+        // Create a two identical responses.
+        MdnsResponse response = makeMdnsResponse(0, recordList);
+        MdnsResponse response2 = makeMdnsResponse(100, recordList);
+        // Merging should not indicate any change.
+        assertFalse(response.mergeRecordsFrom(response2));
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
new file mode 100644
index 0000000..5843fd0
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
@@ -0,0 +1,770 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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
+ */
+
+package com.android.server.connectivity.mdns;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+
+import com.android.server.connectivity.mdns.MdnsServiceTypeClient.QueryTaskConfig;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/** Tests for {@link MdnsServiceTypeClient}. */
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class MdnsServiceTypeClientTests {
+
+    private static final String SERVICE_TYPE = "_googlecast._tcp.local";
+
+    @Mock
+    private MdnsServiceBrowserListener mockListenerOne;
+    @Mock
+    private MdnsServiceBrowserListener mockListenerTwo;
+    @Mock
+    private MdnsPacketWriter mockPacketWriter;
+    @Mock
+    private MdnsSocketClient mockSocketClient;
+    @Captor
+    private ArgumentCaptor<MdnsServiceInfo> serviceInfoCaptor;
+
+    private final byte[] buf = new byte[10];
+
+    private DatagramPacket[] expectedPackets;
+    private ScheduledFuture<?>[] expectedSendFutures;
+    private FakeExecutor currentThreadExecutor = new FakeExecutor();
+
+    private MdnsServiceTypeClient client;
+
+    @Before
+    @SuppressWarnings("DoNotMock")
+    public void setUp() throws IOException {
+        MockitoAnnotations.initMocks(this);
+
+        expectedPackets = new DatagramPacket[16];
+        expectedSendFutures = new ScheduledFuture<?>[16];
+
+        for (int i = 0; i < expectedSendFutures.length; ++i) {
+            expectedPackets[i] = new DatagramPacket(buf, 0, 5);
+            expectedSendFutures[i] = Mockito.mock(ScheduledFuture.class);
+        }
+        when(mockPacketWriter.getPacket(any(SocketAddress.class)))
+                .thenReturn(expectedPackets[0])
+                .thenReturn(expectedPackets[1])
+                .thenReturn(expectedPackets[2])
+                .thenReturn(expectedPackets[3])
+                .thenReturn(expectedPackets[4])
+                .thenReturn(expectedPackets[5])
+                .thenReturn(expectedPackets[6])
+                .thenReturn(expectedPackets[7])
+                .thenReturn(expectedPackets[8])
+                .thenReturn(expectedPackets[9])
+                .thenReturn(expectedPackets[10])
+                .thenReturn(expectedPackets[11])
+                .thenReturn(expectedPackets[12])
+                .thenReturn(expectedPackets[13])
+                .thenReturn(expectedPackets[14])
+                .thenReturn(expectedPackets[15]);
+
+        client =
+                new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor) {
+                    @Override
+                    MdnsPacketWriter createMdnsPacketWriter() {
+                        return mockPacketWriter;
+                    }
+                };
+    }
+
+    @Test
+    public void sendQueries_activeScanMode() {
+        MdnsSearchOptions searchOptions =
+                MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(false).build();
+        client.startSendAndReceive(mockListenerOne, searchOptions);
+
+        // First burst, 3 queries.
+        verifyAndSendQuery(0, 0, /* expectsUnicastResponse= */ true);
+        verifyAndSendQuery(
+                1, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        verifyAndSendQuery(
+                2, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        // Second burst will be sent after initialTimeBetweenBurstsMs, 3 queries.
+        verifyAndSendQuery(
+                3, MdnsConfigs.initialTimeBetweenBurstsMs(), /* expectsUnicastResponse= */ false);
+        verifyAndSendQuery(
+                4, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        verifyAndSendQuery(
+                5, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        // Third burst will be sent after initialTimeBetweenBurstsMs * 2, 3 queries.
+        verifyAndSendQuery(
+                6, MdnsConfigs.initialTimeBetweenBurstsMs() * 2, /* expectsUnicastResponse= */
+                false);
+        verifyAndSendQuery(
+                7, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        verifyAndSendQuery(
+                8, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        // Forth burst will be sent after initialTimeBetweenBurstsMs * 4, 3 queries.
+        verifyAndSendQuery(
+                9, MdnsConfigs.initialTimeBetweenBurstsMs() * 4, /* expectsUnicastResponse= */
+                false);
+        verifyAndSendQuery(
+                10, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        verifyAndSendQuery(
+                11, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        // Fifth burst will be sent after timeBetweenBurstsMs, 3 queries.
+        verifyAndSendQuery(12, MdnsConfigs.timeBetweenBurstsMs(), /* expectsUnicastResponse= */
+                false);
+        verifyAndSendQuery(
+                13, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        verifyAndSendQuery(
+                14, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+
+        // Stop sending packets.
+        client.stopSendAndReceive(mockListenerOne);
+        verify(expectedSendFutures[15]).cancel(true);
+    }
+
+    @Test
+    public void sendQueries_reentry_activeScanMode() {
+        MdnsSearchOptions searchOptions =
+                MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(false).build();
+        client.startSendAndReceive(mockListenerOne, searchOptions);
+
+        // First burst, first query is sent.
+        verifyAndSendQuery(0, 0, /* expectsUnicastResponse= */ true);
+
+        // After the first query is sent, change the subtypes, and restart.
+        searchOptions =
+                MdnsSearchOptions.newBuilder()
+                        .addSubtype("12345")
+                        .addSubtype("abcde")
+                        .setIsPassiveMode(false)
+                        .build();
+        client.startSendAndReceive(mockListenerOne, searchOptions);
+        // The previous scheduled task should be canceled.
+        verify(expectedSendFutures[1]).cancel(true);
+
+        // Queries should continue to be sent.
+        verifyAndSendQuery(1, 0, /* expectsUnicastResponse= */ true);
+        verifyAndSendQuery(
+                2, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        verifyAndSendQuery(
+                3, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+
+        // Stop sending packets.
+        client.stopSendAndReceive(mockListenerOne);
+        verify(expectedSendFutures[5]).cancel(true);
+    }
+
+    @Test
+    public void sendQueries_passiveScanMode() {
+        MdnsSearchOptions searchOptions =
+                MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(true).build();
+        client.startSendAndReceive(mockListenerOne, searchOptions);
+
+        // First burst, 3 query.
+        verifyAndSendQuery(0, 0, /* expectsUnicastResponse= */ true);
+        verifyAndSendQuery(
+                1, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        verifyAndSendQuery(
+                2, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        // Second burst will be sent after timeBetweenBurstsMs, 1 query.
+        verifyAndSendQuery(3, MdnsConfigs.timeBetweenBurstsMs(), /* expectsUnicastResponse= */
+                false);
+        // Third burst will be sent after timeBetweenBurstsMs, 1 query.
+        verifyAndSendQuery(4, MdnsConfigs.timeBetweenBurstsMs(), /* expectsUnicastResponse= */
+                false);
+
+        // Stop sending packets.
+        client.stopSendAndReceive(mockListenerOne);
+        verify(expectedSendFutures[5]).cancel(true);
+    }
+
+    @Test
+    public void sendQueries_reentry_passiveScanMode() {
+        MdnsSearchOptions searchOptions =
+                MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(true).build();
+        client.startSendAndReceive(mockListenerOne, searchOptions);
+
+        // First burst, first query is sent.
+        verifyAndSendQuery(0, 0, /* expectsUnicastResponse= */ true);
+
+        // After the first query is sent, change the subtypes, and restart.
+        searchOptions =
+                MdnsSearchOptions.newBuilder()
+                        .addSubtype("12345")
+                        .addSubtype("abcde")
+                        .setIsPassiveMode(true)
+                        .build();
+        client.startSendAndReceive(mockListenerOne, searchOptions);
+        // The previous scheduled task should be canceled.
+        verify(expectedSendFutures[1]).cancel(true);
+
+        // Queries should continue to be sent.
+        verifyAndSendQuery(1, 0, /* expectsUnicastResponse= */ true);
+        verifyAndSendQuery(
+                2, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+        verifyAndSendQuery(
+                3, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
+
+        // Stop sending packets.
+        client.stopSendAndReceive(mockListenerOne);
+        verify(expectedSendFutures[5]).cancel(true);
+    }
+
+    @Test
+    @Ignore("MdnsConfigs is not configurable currently.")
+    public void testQueryTaskConfig_alwaysAskForUnicastResponse() {
+        //MdnsConfigsFlagsImpl.alwaysAskForUnicastResponseInEachBurst.override(true);
+        MdnsSearchOptions searchOptions =
+                MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(false).build();
+        QueryTaskConfig config =
+                new QueryTaskConfig(searchOptions.getSubtypes(), searchOptions.isPassiveMode(), 1);
+
+        // This is the first query. We will ask for unicast response.
+        assertTrue(config.expectUnicastResponse);
+        assertEquals(config.subtypes, searchOptions.getSubtypes());
+        assertEquals(config.transactionId, 1);
+
+        // For the rest of queries in this burst, we will NOT ask for unicast response.
+        for (int i = 1; i < MdnsConfigs.queriesPerBurst(); i++) {
+            int oldTransactionId = config.transactionId;
+            config = config.getConfigForNextRun();
+            assertFalse(config.expectUnicastResponse);
+            assertEquals(config.subtypes, searchOptions.getSubtypes());
+            assertEquals(config.transactionId, oldTransactionId + 1);
+        }
+
+        // This is the first query of a new burst. We will ask for unicast response.
+        int oldTransactionId = config.transactionId;
+        config = config.getConfigForNextRun();
+        assertTrue(config.expectUnicastResponse);
+        assertEquals(config.subtypes, searchOptions.getSubtypes());
+        assertEquals(config.transactionId, oldTransactionId + 1);
+    }
+
+    @Test
+    public void testQueryTaskConfig_askForUnicastInFirstQuery() {
+        MdnsSearchOptions searchOptions =
+                MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(false).build();
+        QueryTaskConfig config =
+                new QueryTaskConfig(searchOptions.getSubtypes(), searchOptions.isPassiveMode(), 1);
+
+        // This is the first query. We will ask for unicast response.
+        assertTrue(config.expectUnicastResponse);
+        assertEquals(config.subtypes, searchOptions.getSubtypes());
+        assertEquals(config.transactionId, 1);
+
+        // For the rest of queries in this burst, we will NOT ask for unicast response.
+        for (int i = 1; i < MdnsConfigs.queriesPerBurst(); i++) {
+            int oldTransactionId = config.transactionId;
+            config = config.getConfigForNextRun();
+            assertFalse(config.expectUnicastResponse);
+            assertEquals(config.subtypes, searchOptions.getSubtypes());
+            assertEquals(config.transactionId, oldTransactionId + 1);
+        }
+
+        // This is the first query of a new burst. We will NOT ask for unicast response.
+        int oldTransactionId = config.transactionId;
+        config = config.getConfigForNextRun();
+        assertFalse(config.expectUnicastResponse);
+        assertEquals(config.subtypes, searchOptions.getSubtypes());
+        assertEquals(config.transactionId, oldTransactionId + 1);
+    }
+
+    @Test
+    @Ignore("MdnsConfigs is not configurable currently.")
+    public void testIfPreviousTaskIsCanceledWhenNewSessionStarts() {
+        //MdnsConfigsFlagsImpl.useSessionIdToScheduleMdnsTask.override(true);
+        MdnsSearchOptions searchOptions =
+                MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(true).build();
+        client.startSendAndReceive(mockListenerOne, searchOptions);
+        Runnable firstMdnsTask = currentThreadExecutor.getAndClearSubmittedRunnable();
+
+        // Change the sutypes and start a new session.
+        searchOptions =
+                MdnsSearchOptions.newBuilder()
+                        .addSubtype("12345")
+                        .addSubtype("abcde")
+                        .setIsPassiveMode(true)
+                        .build();
+        client.startSendAndReceive(mockListenerOne, searchOptions);
+
+        // Clear the scheduled runnable.
+        currentThreadExecutor.getAndClearLastScheduledRunnable();
+
+        // Simulate the case where the first mdns task is not successful canceled and it gets
+        // executed anyway.
+        firstMdnsTask.run();
+
+        // Although it gets executes, no more task gets scheduled.
+        assertNull(currentThreadExecutor.getAndClearLastScheduledRunnable());
+    }
+
+    @Test
+    @Ignore("MdnsConfigs is not configurable currently.")
+    public void testIfPreviousTaskIsCanceledWhenSessionStops() {
+        //MdnsConfigsFlagsImpl.shouldCancelScanTaskWhenFutureIsNull.override(true);
+        MdnsSearchOptions searchOptions =
+                MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(true).build();
+        client.startSendAndReceive(mockListenerOne, searchOptions);
+        // Change the sutypes and start a new session.
+        client.stopSendAndReceive(mockListenerOne);
+        // Clear the scheduled runnable.
+        currentThreadExecutor.getAndClearLastScheduledRunnable();
+
+        // Simulate the case where the first mdns task is not successful canceled and it gets
+        // executed anyway.
+        currentThreadExecutor.getAndClearSubmittedRunnable().run();
+
+        // Although it gets executes, no more task gets scheduled.
+        assertNull(currentThreadExecutor.getAndClearLastScheduledRunnable());
+    }
+
+    @Test
+    public void processResponse_incompleteResponse() {
+        client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+
+        MdnsResponse response = mock(MdnsResponse.class);
+        when(response.getServiceInstanceName()).thenReturn("service-instance-1");
+        when(response.isComplete()).thenReturn(false);
+
+        client.processResponse(response);
+
+        verify(mockListenerOne, never()).onServiceFound(any(MdnsServiceInfo.class));
+        verify(mockListenerOne, never()).onServiceUpdated(any(MdnsServiceInfo.class));
+    }
+
+    @Test
+    public void processIPv4Response_completeResponseForNewServiceInstance() throws Exception {
+        final String ipV4Address = "192.168.1.1";
+        client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+
+        // Process the initial response.
+        MdnsResponse initialResponse =
+                createResponse(
+                        "service-instance-1",
+                        ipV4Address,
+                        5353,
+                        Collections.singletonList("ABCDE"),
+                        Collections.emptyMap());
+        client.processResponse(initialResponse);
+
+        // Process a second response with a different port and updated text attributes.
+        MdnsResponse secondResponse =
+                createResponse(
+                        "service-instance-1",
+                        ipV4Address,
+                        5354,
+                        Collections.singletonList("ABCDE"),
+                        Collections.singletonMap("key", "value"));
+        client.processResponse(secondResponse);
+
+        // Verify onServiceFound was called once for the initial response.
+        verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
+        MdnsServiceInfo initialServiceInfo = serviceInfoCaptor.getAllValues().get(0);
+        assertEquals(initialServiceInfo.getServiceInstanceName(), "service-instance-1");
+        assertEquals(initialServiceInfo.getIpv4Address(), ipV4Address);
+        assertEquals(initialServiceInfo.getPort(), 5353);
+        assertEquals(initialServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
+        assertNull(initialServiceInfo.getAttributeByKey("key"));
+
+        // Verify onServiceUpdated was called once for the second response.
+        verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
+        MdnsServiceInfo updatedServiceInfo = serviceInfoCaptor.getAllValues().get(1);
+        assertEquals(updatedServiceInfo.getServiceInstanceName(), "service-instance-1");
+        assertEquals(updatedServiceInfo.getIpv4Address(), ipV4Address);
+        assertEquals(updatedServiceInfo.getPort(), 5354);
+        assertTrue(updatedServiceInfo.hasSubtypes());
+        assertEquals(updatedServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
+        assertEquals(updatedServiceInfo.getAttributeByKey("key"), "value");
+    }
+
+    @Test
+    public void processIPv6Response_getCorrectServiceInfo() throws Exception {
+        final String ipV6Address = "2000:3333::da6c:63ff:fe7c:7483";
+        client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+
+        // Process the initial response.
+        MdnsResponse initialResponse =
+                createResponse(
+                        "service-instance-1",
+                        ipV6Address,
+                        5353,
+                        Collections.singletonList("ABCDE"),
+                        Collections.emptyMap());
+        client.processResponse(initialResponse);
+
+        // Process a second response with a different port and updated text attributes.
+        MdnsResponse secondResponse =
+                createResponse(
+                        "service-instance-1",
+                        ipV6Address,
+                        5354,
+                        Collections.singletonList("ABCDE"),
+                        Collections.singletonMap("key", "value"));
+        client.processResponse(secondResponse);
+
+        System.out.println("secondResponses ip"
+                + secondResponse.getInet6AddressRecord().getInet6Address().getHostAddress());
+
+        // Verify onServiceFound was called once for the initial response.
+        verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
+        MdnsServiceInfo initialServiceInfo = serviceInfoCaptor.getAllValues().get(0);
+        assertEquals(initialServiceInfo.getServiceInstanceName(), "service-instance-1");
+        assertEquals(initialServiceInfo.getIpv6Address(), ipV6Address);
+        assertEquals(initialServiceInfo.getPort(), 5353);
+        assertEquals(initialServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
+        assertNull(initialServiceInfo.getAttributeByKey("key"));
+
+        // Verify onServiceUpdated was called once for the second response.
+        verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
+        MdnsServiceInfo updatedServiceInfo = serviceInfoCaptor.getAllValues().get(1);
+        assertEquals(updatedServiceInfo.getServiceInstanceName(), "service-instance-1");
+        assertEquals(updatedServiceInfo.getIpv6Address(), ipV6Address);
+        assertEquals(updatedServiceInfo.getPort(), 5354);
+        assertTrue(updatedServiceInfo.hasSubtypes());
+        assertEquals(updatedServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
+        assertEquals(updatedServiceInfo.getAttributeByKey("key"), "value");
+    }
+
+    @Test
+    public void processResponse_goodBye() {
+        client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+        client.startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
+
+        MdnsResponse response = mock(MdnsResponse.class);
+        when(response.getServiceInstanceName()).thenReturn("goodbye-service-instance-name");
+        when(response.isGoodbye()).thenReturn(true);
+        client.processResponse(response);
+
+        verify(mockListenerOne).onServiceRemoved("goodbye-service-instance-name");
+        verify(mockListenerTwo).onServiceRemoved("goodbye-service-instance-name");
+    }
+
+    @Test
+    public void reportExistingServiceToNewlyRegisteredListeners() throws UnknownHostException {
+        // Process the initial response.
+        MdnsResponse initialResponse =
+                createResponse(
+                        "service-instance-1",
+                        "192.168.1.1",
+                        5353,
+                        Collections.singletonList("ABCDE"),
+                        Collections.emptyMap());
+        client.processResponse(initialResponse);
+
+        client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+
+        // Verify onServiceFound was called once for the existing response.
+        verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
+        MdnsServiceInfo existingServiceInfo = serviceInfoCaptor.getAllValues().get(0);
+        assertEquals(existingServiceInfo.getServiceInstanceName(), "service-instance-1");
+        assertEquals(existingServiceInfo.getIpv4Address(), "192.168.1.1");
+        assertEquals(existingServiceInfo.getPort(), 5353);
+        assertEquals(existingServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
+        assertNull(existingServiceInfo.getAttributeByKey("key"));
+
+        // Process a goodbye message for the existing response.
+        MdnsResponse goodByeResponse = mock(MdnsResponse.class);
+        when(goodByeResponse.getServiceInstanceName()).thenReturn("service-instance-1");
+        when(goodByeResponse.isGoodbye()).thenReturn(true);
+        client.processResponse(goodByeResponse);
+
+        client.startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
+
+        // Verify onServiceFound was not called on the newly registered listener after the existing
+        // response is gone.
+        verify(mockListenerTwo, never()).onServiceFound(any(MdnsServiceInfo.class));
+    }
+
+    @Test
+    public void processResponse_notAllowRemoveSearch_shouldNotRemove() throws Exception {
+        final String serviceInstanceName = "service-instance-1";
+        client.startSendAndReceive(
+                mockListenerOne,
+                MdnsSearchOptions.newBuilder().build());
+        Runnable firstMdnsTask = currentThreadExecutor.getAndClearSubmittedRunnable();
+
+        // Process the initial response.
+        MdnsResponse initialResponse =
+                createResponse(
+                        serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
+                        Map.of());
+        client.processResponse(initialResponse);
+
+        // Clear the scheduled runnable.
+        currentThreadExecutor.getAndClearLastScheduledRunnable();
+
+        // Simulate the case where the response is after TTL.
+        when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
+        firstMdnsTask.run();
+
+        // Verify onServiceRemoved was not called.
+        verify(mockListenerOne, never()).onServiceRemoved(serviceInstanceName);
+    }
+
+    @Test
+    @Ignore("MdnsConfigs is not configurable currently.")
+    public void processResponse_allowSearchOptionsToRemoveExpiredService_shouldRemove()
+            throws Exception {
+        //MdnsConfigsFlagsImpl.allowSearchOptionsToRemoveExpiredService.override(true);
+        final String serviceInstanceName = "service-instance-1";
+        client =
+                new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor) {
+                    @Override
+                    MdnsPacketWriter createMdnsPacketWriter() {
+                        return mockPacketWriter;
+                    }
+                };
+        client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+        Runnable firstMdnsTask = currentThreadExecutor.getAndClearSubmittedRunnable();
+
+        // Process the initial response.
+        MdnsResponse initialResponse =
+                createResponse(
+                        serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
+                        Map.of());
+        client.processResponse(initialResponse);
+
+        // Clear the scheduled runnable.
+        currentThreadExecutor.getAndClearLastScheduledRunnable();
+
+        // Simulate the case where the response is under TTL.
+        when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 1000);
+        firstMdnsTask.run();
+
+        // Verify onServiceRemoved was not called.
+        verify(mockListenerOne, never()).onServiceRemoved(serviceInstanceName);
+
+        // Simulate the case where the response is after TTL.
+        when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
+        firstMdnsTask.run();
+
+        // Verify onServiceRemoved was called.
+        verify(mockListenerOne, times(1)).onServiceRemoved(serviceInstanceName);
+    }
+
+    @Test
+    public void processResponse_searchOptionsNotEnableServiceRemoval_shouldNotRemove()
+            throws Exception {
+        final String serviceInstanceName = "service-instance-1";
+        client =
+                new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor) {
+                    @Override
+                    MdnsPacketWriter createMdnsPacketWriter() {
+                        return mockPacketWriter;
+                    }
+                };
+        client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+        Runnable firstMdnsTask = currentThreadExecutor.getAndClearSubmittedRunnable();
+
+        // Process the initial response.
+        MdnsResponse initialResponse =
+                createResponse(
+                        serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
+                        Map.of());
+        client.processResponse(initialResponse);
+
+        // Clear the scheduled runnable.
+        currentThreadExecutor.getAndClearLastScheduledRunnable();
+
+        // Simulate the case where the response is after TTL.
+        when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
+        firstMdnsTask.run();
+
+        // Verify onServiceRemoved was not called.
+        verify(mockListenerOne, never()).onServiceRemoved(serviceInstanceName);
+    }
+
+    @Test
+    @Ignore("MdnsConfigs is not configurable currently.")
+    public void processResponse_removeServiceAfterTtlExpiresEnabled_shouldRemove()
+            throws Exception {
+        //MdnsConfigsFlagsImpl.removeServiceAfterTtlExpires.override(true);
+        final String serviceInstanceName = "service-instance-1";
+        client =
+                new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor) {
+                    @Override
+                    MdnsPacketWriter createMdnsPacketWriter() {
+                        return mockPacketWriter;
+                    }
+                };
+        client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+        Runnable firstMdnsTask = currentThreadExecutor.getAndClearSubmittedRunnable();
+
+        // Process the initial response.
+        MdnsResponse initialResponse =
+                createResponse(
+                        serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
+                        Map.of());
+        client.processResponse(initialResponse);
+
+        // Clear the scheduled runnable.
+        currentThreadExecutor.getAndClearLastScheduledRunnable();
+
+        // Simulate the case where the response is after TTL.
+        when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
+        firstMdnsTask.run();
+
+        // Verify onServiceRemoved was not called.
+        verify(mockListenerOne, times(1)).onServiceRemoved(serviceInstanceName);
+    }
+
+    // verifies that the right query was enqueued with the right delay, and send query by executing
+    // the runnable.
+    private void verifyAndSendQuery(int index, long timeInMs, boolean expectsUnicastResponse) {
+        assertEquals(currentThreadExecutor.getAndClearLastScheduledDelayInMs(), timeInMs);
+        currentThreadExecutor.getAndClearLastScheduledRunnable().run();
+        if (expectsUnicastResponse) {
+            verify(mockSocketClient).sendUnicastPacket(expectedPackets[index]);
+        } else {
+            verify(mockSocketClient).sendMulticastPacket(expectedPackets[index]);
+        }
+    }
+
+    // A fake ScheduledExecutorService that keeps tracking the last scheduled Runnable and its delay
+    // time.
+    private class FakeExecutor extends ScheduledThreadPoolExecutor {
+        private long lastScheduledDelayInMs;
+        private Runnable lastScheduledRunnable;
+        private Runnable lastSubmittedRunnable;
+        private int futureIndex;
+
+        FakeExecutor() {
+            super(1);
+            lastScheduledDelayInMs = -1;
+        }
+
+        @Override
+        public Future<?> submit(Runnable command) {
+            Future<?> future = super.submit(command);
+            lastSubmittedRunnable = command;
+            return future;
+        }
+
+        // Don't call through the real implementation, just track the scheduled Runnable, and
+        // returns a ScheduledFuture.
+        @Override
+        public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
+            lastScheduledDelayInMs = delay;
+            lastScheduledRunnable = command;
+            return expectedSendFutures[futureIndex++];
+        }
+
+        // Returns the delay of the last scheduled task, and clear it.
+        long getAndClearLastScheduledDelayInMs() {
+            long val = lastScheduledDelayInMs;
+            lastScheduledDelayInMs = -1;
+            return val;
+        }
+
+        // Returns the last scheduled task, and clear it.
+        Runnable getAndClearLastScheduledRunnable() {
+            Runnable val = lastScheduledRunnable;
+            lastScheduledRunnable = null;
+            return val;
+        }
+
+        Runnable getAndClearSubmittedRunnable() {
+            Runnable val = lastSubmittedRunnable;
+            lastSubmittedRunnable = null;
+            return val;
+        }
+    }
+
+    // Creates a complete mDNS response.
+    private MdnsResponse createResponse(
+            @NonNull String serviceInstanceName,
+            @NonNull String host,
+            int port,
+            @NonNull List<String> subtypes,
+            @NonNull Map<String, String> textAttributes)
+            throws UnknownHostException {
+        String[] hostName = new String[]{"hostname"};
+        MdnsServiceRecord serviceRecord = mock(MdnsServiceRecord.class);
+        when(serviceRecord.getServiceHost()).thenReturn(hostName);
+        when(serviceRecord.getServicePort()).thenReturn(port);
+
+        MdnsResponse response = spy(new MdnsResponse(0));
+
+        MdnsInetAddressRecord inetAddressRecord = mock(MdnsInetAddressRecord.class);
+        if (host.contains(":")) {
+            when(inetAddressRecord.getInet6Address())
+                    .thenReturn((Inet6Address) Inet6Address.getByName(host));
+            response.setInet6AddressRecord(inetAddressRecord);
+        } else {
+            when(inetAddressRecord.getInet4Address())
+                    .thenReturn((Inet4Address) Inet4Address.getByName(host));
+            response.setInet4AddressRecord(inetAddressRecord);
+        }
+
+        MdnsTextRecord textRecord = mock(MdnsTextRecord.class);
+        List<String> textStrings = new ArrayList<>();
+        for (Map.Entry<String, String> kv : textAttributes.entrySet()) {
+            textStrings.add(kv.getKey() + "=" + kv.getValue());
+        }
+        when(textRecord.getStrings()).thenReturn(textStrings);
+
+        response.setServiceRecord(serviceRecord);
+        response.setTextRecord(textRecord);
+
+        doReturn(false).when(response).isGoodbye();
+        doReturn(true).when(response).isComplete();
+        doReturn(serviceInstanceName).when(response).getServiceInstanceName();
+        doReturn(new ArrayList<>(subtypes)).when(response).getSubtypes();
+        return response;
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketClientTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketClientTests.java
new file mode 100644
index 0000000..21ed7eb
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketClientTests.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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
+ */
+
+package com.android.server.connectivity.mdns;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.Manifest.permission;
+import android.annotation.RequiresPermission;
+import android.content.Context;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.MulticastLock;
+import android.text.format.DateUtils;
+
+import com.android.net.module.util.HexDump;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/** Tests for {@link MdnsSocketClient} */
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class MdnsSocketClientTests {
+    private static final long TIMEOUT = 500;
+    private final byte[] buf = new byte[10];
+    final AtomicBoolean enableMulticastResponse = new AtomicBoolean(true);
+    final AtomicBoolean enableUnicastResponse = new AtomicBoolean(true);
+
+    @Mock private Context mContext;
+    @Mock private WifiManager mockWifiManager;
+    @Mock private MdnsSocket mockMulticastSocket;
+    @Mock private MdnsSocket mockUnicastSocket;
+    @Mock private MulticastLock mockMulticastLock;
+    @Mock private MdnsSocketClient.Callback mockCallback;
+
+    private MdnsSocketClient mdnsClient;
+
+    @Before
+    public void setup() throws RuntimeException, IOException {
+        MockitoAnnotations.initMocks(this);
+
+        when(mockWifiManager.createMulticastLock(ArgumentMatchers.anyString()))
+                .thenReturn(mockMulticastLock);
+
+        mdnsClient = new MdnsSocketClient(mContext, mockMulticastLock) {
+                    @Override
+                    MdnsSocket createMdnsSocket(int port) throws IOException {
+                        if (port == MdnsConstants.MDNS_PORT) {
+                            return mockMulticastSocket;
+                        }
+                        return mockUnicastSocket;
+                    }
+                };
+        mdnsClient.setCallback(mockCallback);
+
+        doAnswer(
+                (InvocationOnMock invocationOnMock) -> {
+                    final byte[] dataIn = HexDump.hexStringToByteArray(
+                            "0000840000000004"
+                            + "00000003134A6F68"
+                            + "6E6E792773204368"
+                            + "726F6D6563617374"
+                            + "0B5F676F6F676C65"
+                            + "63617374045F7463"
+                            + "70056C6F63616C00"
+                            + "0010800100001194"
+                            + "006C2369643D3937"
+                            + "3062663534376237"
+                            + "3533666336336332"
+                            + "6432613336626238"
+                            + "3936616261380576"
+                            + "653D30320D6D643D"
+                            + "4368726F6D656361"
+                            + "73741269633D2F73"
+                            + "657475702F69636F"
+                            + "6E2E706E6716666E"
+                            + "3D4A6F686E6E7927"
+                            + "73204368726F6D65"
+                            + "636173740463613D"
+                            + "350473743D30095F"
+                            + "7365727669636573"
+                            + "075F646E732D7364"
+                            + "045F756470C03100"
+                            + "0C00010000119400"
+                            + "02C020C020000C00"
+                            + "01000011940002C0"
+                            + "0CC00C0021800100"
+                            + "000078001C000000"
+                            + "001F49134A6F686E"
+                            + "6E79277320436872"
+                            + "6F6D6563617374C0"
+                            + "31C0F30001800100"
+                            + "0000780004C0A864"
+                            + "68C0F3002F800100"
+                            + "0000780005C0F300"
+                            + "0140C00C002F8001"
+                            + "000011940009C00C"
+                            + "00050000800040");
+                    if (enableMulticastResponse.get()) {
+                        DatagramPacket packet = invocationOnMock.getArgument(0);
+                        packet.setData(dataIn);
+                    }
+                    return null;
+                })
+                .when(mockMulticastSocket)
+                .receive(any(DatagramPacket.class));
+        doAnswer(
+                (InvocationOnMock invocationOnMock) -> {
+                    final byte[] dataIn = HexDump.hexStringToByteArray(
+                            "0000840000000004"
+                            + "00000003134A6F68"
+                            + "6E6E792773204368"
+                            + "726F6D6563617374"
+                            + "0B5F676F6F676C65"
+                            + "63617374045F7463"
+                            + "70056C6F63616C00"
+                            + "0010800100001194"
+                            + "006C2369643D3937"
+                            + "3062663534376237"
+                            + "3533666336336332"
+                            + "6432613336626238"
+                            + "3936616261380576"
+                            + "653D30320D6D643D"
+                            + "4368726F6D656361"
+                            + "73741269633D2F73"
+                            + "657475702F69636F"
+                            + "6E2E706E6716666E"
+                            + "3D4A6F686E6E7927"
+                            + "73204368726F6D65"
+                            + "636173740463613D"
+                            + "350473743D30095F"
+                            + "7365727669636573"
+                            + "075F646E732D7364"
+                            + "045F756470C03100"
+                            + "0C00010000119400"
+                            + "02C020C020000C00"
+                            + "01000011940002C0"
+                            + "0CC00C0021800100"
+                            + "000078001C000000"
+                            + "001F49134A6F686E"
+                            + "6E79277320436872"
+                            + "6F6D6563617374C0"
+                            + "31C0F30001800100"
+                            + "0000780004C0A864"
+                            + "68C0F3002F800100"
+                            + "0000780005C0F300"
+                            + "0140C00C002F8001"
+                            + "000011940009C00C"
+                            + "00050000800040");
+                    if (enableUnicastResponse.get()) {
+                        DatagramPacket packet = invocationOnMock.getArgument(0);
+                        packet.setData(dataIn);
+                    }
+                    return null;
+                })
+                .when(mockUnicastSocket)
+                .receive(any(DatagramPacket.class));
+    }
+
+    @After
+    public void tearDown() {
+        mdnsClient.stopDiscovery();
+    }
+
+    @Test
+    @Ignore("MdnsConfigs is not configurable currently.")
+    public void testSendPackets_useSeparateSocketForUnicast()
+            throws InterruptedException, IOException {
+        //MdnsConfigsFlagsImpl.useSeparateSocketToSendUnicastQuery.override(true);
+        //MdnsConfigsFlagsImpl.checkMulticastResponse.override(true);
+        //MdnsConfigsFlagsImpl.checkMulticastResponseIntervalMs
+        //        .override(DateUtils.SECOND_IN_MILLIS);
+        mdnsClient.startDiscovery();
+        Thread multicastReceiverThread = mdnsClient.multicastReceiveThread;
+        Thread unicastReceiverThread = mdnsClient.unicastReceiveThread;
+        Thread sendThread = mdnsClient.sendThread;
+
+        assertTrue(multicastReceiverThread.isAlive());
+        assertTrue(sendThread.isAlive());
+        assertTrue(unicastReceiverThread.isAlive());
+
+        // Sends a packet.
+        DatagramPacket packet = new DatagramPacket(buf, 0, 5);
+        mdnsClient.sendMulticastPacket(packet);
+        // mockMulticastSocket.send() will be called on another thread. If we verify it immediately,
+        // it may not be called yet. So timeout is added.
+        verify(mockMulticastSocket, timeout(TIMEOUT).times(1)).send(packet);
+        verify(mockUnicastSocket, timeout(TIMEOUT).times(0)).send(packet);
+
+        // Verify the packet is sent by the unicast socket.
+        mdnsClient.sendUnicastPacket(packet);
+        verify(mockMulticastSocket, timeout(TIMEOUT).times(1)).send(packet);
+        verify(mockUnicastSocket, timeout(TIMEOUT).times(1)).send(packet);
+
+        // Stop the MdnsClient, and ensure that it stops in a reasonable amount of time.
+        // Run part of the test logic in a background thread, in case stopDiscovery() blocks
+        // for a long time (the foreground thread can fail the test early).
+        final CountDownLatch stopDiscoveryLatch = new CountDownLatch(1);
+        Thread testThread =
+                new Thread(
+                        new Runnable() {
+                            @RequiresPermission(permission.CHANGE_WIFI_MULTICAST_STATE)
+                            @Override
+                            public void run() {
+                                mdnsClient.stopDiscovery();
+                                stopDiscoveryLatch.countDown();
+                            }
+                        });
+        testThread.start();
+        assertTrue(stopDiscoveryLatch.await(DateUtils.SECOND_IN_MILLIS, TimeUnit.MILLISECONDS));
+
+        // We should be able to join in a reasonable amount of time, to prove that the
+        // the MdnsClient exited without sending the large queue of packets.
+        testThread.join(DateUtils.SECOND_IN_MILLIS);
+
+        assertFalse(multicastReceiverThread.isAlive());
+        assertFalse(sendThread.isAlive());
+        assertFalse(unicastReceiverThread.isAlive());
+    }
+
+    @Test
+    public void testSendPackets_useSameSocketForMulticastAndUnicast()
+            throws InterruptedException, IOException {
+        mdnsClient.startDiscovery();
+        Thread multicastReceiverThread = mdnsClient.multicastReceiveThread;
+        Thread unicastReceiverThread = mdnsClient.unicastReceiveThread;
+        Thread sendThread = mdnsClient.sendThread;
+
+        assertTrue(multicastReceiverThread.isAlive());
+        assertTrue(sendThread.isAlive());
+        assertNull(unicastReceiverThread);
+
+        // Sends a packet.
+        DatagramPacket packet = new DatagramPacket(buf, 0, 5);
+        mdnsClient.sendMulticastPacket(packet);
+        // mockMulticastSocket.send() will be called on another thread. If we verify it immediately,
+        // it may not be called yet. So timeout is added.
+        verify(mockMulticastSocket, timeout(TIMEOUT).times(1)).send(packet);
+        verify(mockUnicastSocket, timeout(TIMEOUT).times(0)).send(packet);
+
+        // Verify the packet is sent by the multicast socket as well.
+        mdnsClient.sendUnicastPacket(packet);
+        verify(mockMulticastSocket, timeout(TIMEOUT).times(2)).send(packet);
+        verify(mockUnicastSocket, timeout(TIMEOUT).times(0)).send(packet);
+
+        // Stop the MdnsClient, and ensure that it stops in a reasonable amount of time.
+        // Run part of the test logic in a background thread, in case stopDiscovery() blocks
+        // for a long time (the foreground thread can fail the test early).
+        final CountDownLatch stopDiscoveryLatch = new CountDownLatch(1);
+        Thread testThread =
+                new Thread(
+                        new Runnable() {
+                            @RequiresPermission(permission.CHANGE_WIFI_MULTICAST_STATE)
+                            @Override
+                            public void run() {
+                                mdnsClient.stopDiscovery();
+                                stopDiscoveryLatch.countDown();
+                            }
+                        });
+        testThread.start();
+        assertTrue(stopDiscoveryLatch.await(DateUtils.SECOND_IN_MILLIS, TimeUnit.MILLISECONDS));
+
+        // We should be able to join in a reasonable amount of time, to prove that the
+        // the MdnsClient exited without sending the large queue of packets.
+        testThread.join(DateUtils.SECOND_IN_MILLIS);
+
+        assertFalse(multicastReceiverThread.isAlive());
+        assertFalse(sendThread.isAlive());
+        assertNull(unicastReceiverThread);
+    }
+
+    @Test
+    public void testStartStop() throws IOException {
+        for (int i = 0; i < 5; i++) {
+            mdnsClient.startDiscovery();
+
+            Thread multicastReceiverThread = mdnsClient.multicastReceiveThread;
+            Thread socketThread = mdnsClient.sendThread;
+
+            assertTrue(multicastReceiverThread.isAlive());
+            assertTrue(socketThread.isAlive());
+
+            mdnsClient.stopDiscovery();
+
+            assertFalse(multicastReceiverThread.isAlive());
+            assertFalse(socketThread.isAlive());
+        }
+    }
+
+    @Test
+    public void testStopDiscovery_queueIsCleared() throws IOException {
+        mdnsClient.startDiscovery();
+        mdnsClient.stopDiscovery();
+        mdnsClient.sendMulticastPacket(new DatagramPacket(buf, 0, 5));
+
+        synchronized (mdnsClient.multicastPacketQueue) {
+            assertTrue(mdnsClient.multicastPacketQueue.isEmpty());
+        }
+    }
+
+    @Test
+    public void testSendPacket_afterDiscoveryStops() throws IOException {
+        mdnsClient.startDiscovery();
+        mdnsClient.stopDiscovery();
+        mdnsClient.sendMulticastPacket(new DatagramPacket(buf, 0, 5));
+
+        synchronized (mdnsClient.multicastPacketQueue) {
+            assertTrue(mdnsClient.multicastPacketQueue.isEmpty());
+        }
+    }
+
+    @Test
+    @Ignore("MdnsConfigs is not configurable currently.")
+    public void testSendPacket_queueReachesSizeLimit() throws IOException {
+        //MdnsConfigsFlagsImpl.mdnsPacketQueueMaxSize.override(2L);
+        mdnsClient.startDiscovery();
+        for (int i = 0; i < 100; i++) {
+            mdnsClient.sendMulticastPacket(new DatagramPacket(buf, 0, 5));
+        }
+
+        synchronized (mdnsClient.multicastPacketQueue) {
+            assertTrue(mdnsClient.multicastPacketQueue.size() <= 2);
+        }
+    }
+
+    @Test
+    public void testMulticastResponseReceived_useSeparateSocketForUnicast() throws IOException {
+        mdnsClient.setCallback(mockCallback);
+
+        mdnsClient.startDiscovery();
+
+        verify(mockCallback, timeout(TIMEOUT).atLeast(1))
+                .onResponseReceived(any(MdnsResponse.class));
+    }
+
+    @Test
+    public void testMulticastResponseReceived_useSameSocketForMulticastAndUnicast()
+            throws Exception {
+        mdnsClient.startDiscovery();
+
+        verify(mockCallback, timeout(TIMEOUT).atLeastOnce())
+                .onResponseReceived(any(MdnsResponse.class));
+
+        mdnsClient.stopDiscovery();
+    }
+
+    @Test
+    public void testFailedToParseMdnsResponse_useSeparateSocketForUnicast() throws IOException {
+        mdnsClient.setCallback(mockCallback);
+
+        // Both multicast socket and unicast socket receive malformed responses.
+        byte[] dataIn = HexDump.hexStringToByteArray("0000840000000004");
+        doAnswer(
+                (InvocationOnMock invocationOnMock) -> {
+                    // Malformed data.
+                    DatagramPacket packet = invocationOnMock.getArgument(0);
+                    packet.setData(dataIn);
+                    return null;
+                })
+                .when(mockMulticastSocket)
+                .receive(any(DatagramPacket.class));
+        doAnswer(
+                (InvocationOnMock invocationOnMock) -> {
+                    // Malformed data.
+                    DatagramPacket packet = invocationOnMock.getArgument(0);
+                    packet.setData(dataIn);
+                    return null;
+                })
+                .when(mockUnicastSocket)
+                .receive(any(DatagramPacket.class));
+
+        mdnsClient.startDiscovery();
+
+        verify(mockCallback, timeout(TIMEOUT).atLeast(1))
+                .onFailedToParseMdnsResponse(anyInt(), eq(MdnsResponseErrorCode.ERROR_END_OF_FILE));
+
+        mdnsClient.stopDiscovery();
+    }
+
+    @Test
+    public void testFailedToParseMdnsResponse_useSameSocketForMulticastAndUnicast()
+            throws IOException {
+        doAnswer(
+                (InvocationOnMock invocationOnMock) -> {
+                    final byte[] dataIn = HexDump.hexStringToByteArray("0000840000000004");
+                    DatagramPacket packet = invocationOnMock.getArgument(0);
+                    packet.setData(dataIn);
+                    return null;
+                })
+                .when(mockMulticastSocket)
+                .receive(any(DatagramPacket.class));
+
+        mdnsClient.startDiscovery();
+
+        verify(mockCallback, timeout(TIMEOUT).atLeast(1))
+                .onFailedToParseMdnsResponse(1, MdnsResponseErrorCode.ERROR_END_OF_FILE);
+
+        mdnsClient.stopDiscovery();
+    }
+
+    @Test
+    @Ignore("MdnsConfigs is not configurable currently.")
+    public void testMulticastResponseIsNotReceived() throws IOException, InterruptedException {
+        //MdnsConfigsFlagsImpl.checkMulticastResponse.override(true);
+        //MdnsConfigsFlagsImpl.checkMulticastResponseIntervalMs
+        //        .override(DateUtils.SECOND_IN_MILLIS);
+        //MdnsConfigsFlagsImpl.useSeparateSocketToSendUnicastQuery.override(true);
+        enableMulticastResponse.set(false);
+        enableUnicastResponse.set(true);
+
+        mdnsClient.startDiscovery();
+        DatagramPacket packet = new DatagramPacket(buf, 0, 5);
+        mdnsClient.sendUnicastPacket(packet);
+        mdnsClient.sendMulticastPacket(packet);
+
+        // Wait for the timer to be triggered.
+        Thread.sleep(MdnsConfigs.checkMulticastResponseIntervalMs() * 2);
+
+        assertFalse(mdnsClient.receivedMulticastResponse);
+        assertTrue(mdnsClient.receivedUnicastResponse);
+        assertTrue(mdnsClient.cannotReceiveMulticastResponse.get());
+
+        // Allow multicast response and verify the states again.
+        enableMulticastResponse.set(true);
+        Thread.sleep(DateUtils.SECOND_IN_MILLIS);
+
+        // Verify cannotReceiveMulticastResponse is reset to false.
+        assertTrue(mdnsClient.receivedMulticastResponse);
+        assertTrue(mdnsClient.receivedUnicastResponse);
+        assertFalse(mdnsClient.cannotReceiveMulticastResponse.get());
+
+        // Stop the discovery and start a new session. Don't respond the unicsat query either in
+        // this session.
+        enableMulticastResponse.set(false);
+        enableUnicastResponse.set(false);
+        mdnsClient.stopDiscovery();
+        mdnsClient.startDiscovery();
+
+        // Verify the states are reset.
+        assertFalse(mdnsClient.receivedMulticastResponse);
+        assertFalse(mdnsClient.receivedUnicastResponse);
+        assertFalse(mdnsClient.cannotReceiveMulticastResponse.get());
+
+        mdnsClient.sendUnicastPacket(packet);
+        mdnsClient.sendMulticastPacket(packet);
+        Thread.sleep(MdnsConfigs.checkMulticastResponseIntervalMs() * 2);
+
+        // Verify cannotReceiveMulticastResponse is not set the true because we didn't receive the
+        // unicast response either. This is expected for users who don't have any cast device.
+        assertFalse(mdnsClient.receivedMulticastResponse);
+        assertFalse(mdnsClient.receivedUnicastResponse);
+        assertFalse(mdnsClient.cannotReceiveMulticastResponse.get());
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketTests.java
new file mode 100644
index 0000000..9f11a4b
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketTests.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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
+ */
+
+package com.android.server.connectivity.mdns;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.MulticastSocket;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Collections;
+
+/** Tests for {@link MdnsSocket}. */
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class MdnsSocketTests {
+
+    @Mock private NetworkInterfaceWrapper mockNetworkInterfaceWrapper;
+    @Mock private MulticastSocket mockMulticastSocket;
+    @Mock private MulticastNetworkInterfaceProvider mockMulticastNetworkInterfaceProvider;
+    private SocketAddress socketIPv4Address;
+    private SocketAddress socketIPv6Address;
+
+    private byte[] data = new byte[25];
+    private final DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
+    private NetworkInterface networkInterface;
+
+    private MdnsSocket mdnsSocket;
+
+    @Before
+    public void setUp() throws SocketException, UnknownHostException {
+        MockitoAnnotations.initMocks(this);
+
+        networkInterface = createEmptyNetworkInterface();
+        when(mockNetworkInterfaceWrapper.getNetworkInterface()).thenReturn(networkInterface);
+        when(mockMulticastNetworkInterfaceProvider.getMulticastNetworkInterfaces())
+                .thenReturn(Collections.singletonList(mockNetworkInterfaceWrapper));
+        socketIPv4Address = new InetSocketAddress(
+                InetAddress.getByName("224.0.0.251"), MdnsConstants.MDNS_PORT);
+        socketIPv6Address = new InetSocketAddress(
+                InetAddress.getByName("FF02::FB"), MdnsConstants.MDNS_PORT);
+    }
+
+    @Test
+    public void testMdnsSocket() throws IOException {
+        mdnsSocket =
+                new MdnsSocket(mockMulticastNetworkInterfaceProvider, MdnsConstants.MDNS_PORT) {
+                    @Override
+                    MulticastSocket createMulticastSocket(int port) throws IOException {
+                        return mockMulticastSocket;
+                    }
+                };
+        mdnsSocket.send(datagramPacket);
+        verify(mockMulticastSocket).setNetworkInterface(networkInterface);
+        verify(mockMulticastSocket).send(datagramPacket);
+
+        mdnsSocket.receive(datagramPacket);
+        verify(mockMulticastSocket).receive(datagramPacket);
+
+        mdnsSocket.joinGroup();
+        verify(mockMulticastSocket).joinGroup(socketIPv4Address, networkInterface);
+
+        mdnsSocket.leaveGroup();
+        verify(mockMulticastSocket).leaveGroup(socketIPv4Address, networkInterface);
+
+        mdnsSocket.close();
+        verify(mockMulticastSocket).close();
+    }
+
+    @Test
+    public void testIPv6OnlyNetwork_IPv6Enabled() throws IOException {
+        // Have mockMulticastNetworkInterfaceProvider send back an IPv6Only networkInterfaceWrapper
+        networkInterface = createEmptyNetworkInterface();
+        when(mockNetworkInterfaceWrapper.getNetworkInterface()).thenReturn(networkInterface);
+        when(mockMulticastNetworkInterfaceProvider.getMulticastNetworkInterfaces())
+                .thenReturn(Collections.singletonList(mockNetworkInterfaceWrapper));
+
+        mdnsSocket =
+                new MdnsSocket(mockMulticastNetworkInterfaceProvider, MdnsConstants.MDNS_PORT) {
+                    @Override
+                    MulticastSocket createMulticastSocket(int port) throws IOException {
+                        return mockMulticastSocket;
+                    }
+                };
+
+        when(mockMulticastNetworkInterfaceProvider.isOnIpV6OnlyNetwork(
+                Collections.singletonList(mockNetworkInterfaceWrapper)))
+                .thenReturn(true);
+
+        mdnsSocket.joinGroup();
+        verify(mockMulticastSocket).joinGroup(socketIPv6Address, networkInterface);
+
+        mdnsSocket.leaveGroup();
+        verify(mockMulticastSocket).leaveGroup(socketIPv6Address, networkInterface);
+
+        mdnsSocket.close();
+        verify(mockMulticastSocket).close();
+    }
+
+    @Test
+    public void testIPv6OnlyNetwork_IPv6Toggle() throws IOException {
+        // Have mockMulticastNetworkInterfaceProvider send back a networkInterfaceWrapper
+        networkInterface = createEmptyNetworkInterface();
+        when(mockNetworkInterfaceWrapper.getNetworkInterface()).thenReturn(networkInterface);
+        when(mockMulticastNetworkInterfaceProvider.getMulticastNetworkInterfaces())
+                .thenReturn(Collections.singletonList(mockNetworkInterfaceWrapper));
+
+        mdnsSocket =
+                new MdnsSocket(mockMulticastNetworkInterfaceProvider, MdnsConstants.MDNS_PORT) {
+                    @Override
+                    MulticastSocket createMulticastSocket(int port) throws IOException {
+                        return mockMulticastSocket;
+                    }
+                };
+
+        when(mockMulticastNetworkInterfaceProvider.isOnIpV6OnlyNetwork(
+                Collections.singletonList(mockNetworkInterfaceWrapper)))
+                .thenReturn(true);
+
+        mdnsSocket.joinGroup();
+        verify(mockMulticastSocket).joinGroup(socketIPv6Address, networkInterface);
+
+        mdnsSocket.leaveGroup();
+        verify(mockMulticastSocket).leaveGroup(socketIPv6Address, networkInterface);
+
+        mdnsSocket.close();
+        verify(mockMulticastSocket).close();
+    }
+
+    private NetworkInterface createEmptyNetworkInterface() {
+        try {
+            Constructor<NetworkInterface> constructor =
+                    NetworkInterface.class.getDeclaredConstructor();
+            constructor.setAccessible(true);
+            return constructor.newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MulticastNetworkInterfaceProviderTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MulticastNetworkInterfaceProviderTests.java
new file mode 100644
index 0000000..2268dfe
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MulticastNetworkInterfaceProviderTests.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2021 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
+ *
+ *      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
+ */
+
+package com.android.server.connectivity.mdns;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/** Tests for {@link MulticastNetworkInterfaceProvider}. */
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class MulticastNetworkInterfaceProviderTests {
+
+    @Mock private NetworkInterfaceWrapper loopbackInterface;
+    @Mock private NetworkInterfaceWrapper pointToPointInterface;
+    @Mock private NetworkInterfaceWrapper virtualInterface;
+    @Mock private NetworkInterfaceWrapper inactiveMulticastInterface;
+    @Mock private NetworkInterfaceWrapper activeIpv6MulticastInterface;
+    @Mock private NetworkInterfaceWrapper activeIpv6MulticastInterfaceTwo;
+    @Mock private NetworkInterfaceWrapper nonMulticastInterface;
+    @Mock private NetworkInterfaceWrapper multicastInterfaceOne;
+    @Mock private NetworkInterfaceWrapper multicastInterfaceTwo;
+
+    private final List<NetworkInterfaceWrapper> networkInterfaces = new ArrayList<>();
+    private MulticastNetworkInterfaceProvider provider;
+    private Context context;
+
+    @Before
+    public void setUp() throws SocketException, UnknownHostException {
+        MockitoAnnotations.initMocks(this);
+        context = InstrumentationRegistry.getContext();
+
+        setupNetworkInterface(
+                loopbackInterface,
+                true /* isUp */,
+                true /* isLoopBack */,
+                false /* isPointToPoint */,
+                false /* isVirtual */,
+                true /* supportsMulticast */,
+                false /* isIpv6 */);
+
+        setupNetworkInterface(
+                pointToPointInterface,
+                true /* isUp */,
+                false /* isLoopBack */,
+                true /* isPointToPoint */,
+                false /* isVirtual */,
+                true /* supportsMulticast */,
+                false /* isIpv6 */);
+
+        setupNetworkInterface(
+                virtualInterface,
+                true /* isUp */,
+                false /* isLoopBack */,
+                false /* isPointToPoint */,
+                true /* isVirtual */,
+                true /* supportsMulticast */,
+                false /* isIpv6 */);
+
+        setupNetworkInterface(
+                inactiveMulticastInterface,
+                false /* isUp */,
+                false /* isLoopBack */,
+                false /* isPointToPoint */,
+                false /* isVirtual */,
+                true /* supportsMulticast */,
+                false /* isIpv6 */);
+
+        setupNetworkInterface(
+                nonMulticastInterface,
+                true /* isUp */,
+                false /* isLoopBack */,
+                false /* isPointToPoint */,
+                false /* isVirtual */,
+                false /* supportsMulticast */,
+                false /* isIpv6 */);
+
+        setupNetworkInterface(
+                activeIpv6MulticastInterface,
+                true /* isUp */,
+                false /* isLoopBack */,
+                false /* isPointToPoint */,
+                false /* isVirtual */,
+                true /* supportsMulticast */,
+                true /* isIpv6 */);
+
+        setupNetworkInterface(
+                activeIpv6MulticastInterfaceTwo,
+                true /* isUp */,
+                false /* isLoopBack */,
+                false /* isPointToPoint */,
+                false /* isVirtual */,
+                true /* supportsMulticast */,
+                true /* isIpv6 */);
+
+        setupNetworkInterface(
+                multicastInterfaceOne,
+                true /* isUp */,
+                false /* isLoopBack */,
+                false /* isPointToPoint */,
+                false /* isVirtual */,
+                true /* supportsMulticast */,
+                false /* isIpv6 */);
+
+        setupNetworkInterface(
+                multicastInterfaceTwo,
+                true /* isUp */,
+                false /* isLoopBack */,
+                false /* isPointToPoint */,
+                false /* isVirtual */,
+                true /* supportsMulticast */,
+                false /* isIpv6 */);
+
+        provider =
+                new MulticastNetworkInterfaceProvider(context) {
+                    @Override
+                    List<NetworkInterfaceWrapper> getNetworkInterfaces() {
+                        return networkInterfaces;
+                    }
+                };
+    }
+
+    @Test
+    public void testGetMulticastNetworkInterfaces() {
+        // getNetworkInterfaces returns 1 multicast interface and 5 interfaces that can not be used
+        // to send and receive multicast packets.
+        networkInterfaces.add(loopbackInterface);
+        networkInterfaces.add(pointToPointInterface);
+        networkInterfaces.add(virtualInterface);
+        networkInterfaces.add(inactiveMulticastInterface);
+        networkInterfaces.add(nonMulticastInterface);
+        networkInterfaces.add(multicastInterfaceOne);
+
+        assertEquals(Collections.singletonList(multicastInterfaceOne),
+                provider.getMulticastNetworkInterfaces());
+
+        // getNetworkInterfaces returns 2 multicast interfaces after a connectivity change.
+        networkInterfaces.clear();
+        networkInterfaces.add(multicastInterfaceOne);
+        networkInterfaces.add(multicastInterfaceTwo);
+
+        provider.connectivityMonitor.notifyConnectivityChange();
+
+        assertEquals(networkInterfaces, provider.getMulticastNetworkInterfaces());
+    }
+
+    @Test
+    public void testStartWatchingConnectivityChanges() {
+        ConnectivityMonitor mockMonitor = mock(ConnectivityMonitor.class);
+        provider.connectivityMonitor = mockMonitor;
+
+        InOrder inOrder = inOrder(mockMonitor);
+
+        provider.startWatchingConnectivityChanges();
+        inOrder.verify(mockMonitor).startWatchingConnectivityChanges();
+
+        provider.stopWatchingConnectivityChanges();
+        inOrder.verify(mockMonitor).stopWatchingConnectivityChanges();
+    }
+
+    @Test
+    public void testIpV6OnlyNetwork_EmptyNetwork() {
+        // getNetworkInterfaces returns no network interfaces.
+        assertFalse(provider.isOnIpV6OnlyNetwork(networkInterfaces));
+    }
+
+    @Test
+    public void testIpV6OnlyNetwork_IPv4Only() {
+        // getNetworkInterfaces returns two IPv4 network interface.
+        networkInterfaces.add(multicastInterfaceOne);
+        networkInterfaces.add(multicastInterfaceTwo);
+        assertFalse(provider.isOnIpV6OnlyNetwork(networkInterfaces));
+    }
+
+    @Test
+    public void testIpV6OnlyNetwork_MixedNetwork() {
+        // getNetworkInterfaces returns one IPv6 network interface.
+        networkInterfaces.add(activeIpv6MulticastInterface);
+        networkInterfaces.add(multicastInterfaceOne);
+        networkInterfaces.add(activeIpv6MulticastInterfaceTwo);
+        networkInterfaces.add(multicastInterfaceTwo);
+        assertFalse(provider.isOnIpV6OnlyNetwork(networkInterfaces));
+    }
+
+    @Test
+    public void testIpV6OnlyNetwork_IPv6Only() {
+        // getNetworkInterfaces returns one IPv6 network interface.
+        networkInterfaces.add(activeIpv6MulticastInterface);
+        networkInterfaces.add(activeIpv6MulticastInterfaceTwo);
+        assertTrue(provider.isOnIpV6OnlyNetwork(networkInterfaces));
+    }
+
+    @Test
+    public void testIpV6OnlyNetwork_IPv6Enabled() {
+        // getNetworkInterfaces returns one IPv6 network interface.
+        networkInterfaces.add(activeIpv6MulticastInterface);
+        assertTrue(provider.isOnIpV6OnlyNetwork(networkInterfaces));
+
+        final List<NetworkInterfaceWrapper> interfaces = provider.getMulticastNetworkInterfaces();
+        assertEquals(Collections.singletonList(activeIpv6MulticastInterface), interfaces);
+    }
+
+    private void setupNetworkInterface(
+            @NonNull NetworkInterfaceWrapper networkInterfaceWrapper,
+            boolean isUp,
+            boolean isLoopback,
+            boolean isPointToPoint,
+            boolean isVirtual,
+            boolean supportsMulticast,
+            boolean isIpv6)
+            throws SocketException, UnknownHostException {
+        when(networkInterfaceWrapper.isUp()).thenReturn(isUp);
+        when(networkInterfaceWrapper.isLoopback()).thenReturn(isLoopback);
+        when(networkInterfaceWrapper.isPointToPoint()).thenReturn(isPointToPoint);
+        when(networkInterfaceWrapper.isVirtual()).thenReturn(isVirtual);
+        when(networkInterfaceWrapper.supportsMulticast()).thenReturn(supportsMulticast);
+        if (isIpv6) {
+            InterfaceAddress interfaceAddress = mock(InterfaceAddress.class);
+            InetAddress ip6Address = Inet6Address.getByName("2001:4860:0:1001::68");
+            when(interfaceAddress.getAddress()).thenReturn(ip6Address);
+            when(networkInterfaceWrapper.getInterfaceAddresses())
+                    .thenReturn(Collections.singletonList(interfaceAddress));
+        } else {
+            Inet4Address ip = (Inet4Address) Inet4Address.getByName("192.168.0.1");
+            InterfaceAddress interfaceAddress = mock(InterfaceAddress.class);
+            when(interfaceAddress.getAddress()).thenReturn(ip);
+            when(networkInterfaceWrapper.getInterfaceAddresses())
+                    .thenReturn(Collections.singletonList(interfaceAddress));
+        }
+    }
+}
\ No newline at end of file
