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 19d0d5f..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",
@@ -134,7 +135,7 @@
         "-Wthread-safety",
     ],
 
-    ldflags: ["-Wl,--exclude-libs=ALL,-error-limit=0"],
+    ldflags: ["-Wl,--exclude-libs=ALL,--error-limit=0"],
 }
 
 // Common defaults for compiling the actual APK.
@@ -231,4 +232,4 @@
     cmd: "$(location stats-log-api-gen) --java $(out) --module network_tethering" +
          " --javaPackage com.android.networkstack.tethering.metrics --javaClass TetheringStatsLog",
     out: ["com/android/networkstack/tethering/metrics/TetheringStatsLog.java"],
-}
\ No newline at end of file
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 47de640..ca4071f 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -941,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
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 c49cf1e..ef4f052 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -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/bpf_progs/netd.c b/bpf_progs/netd.c
index 17c18c9..44f76de 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -53,15 +53,18 @@
 
 // For maps netd does not need to access
 #define DEFINE_BPF_MAP_NO_NETD(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries) \
-    DEFINE_BPF_MAP_UGM(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries, AID_ROOT, AID_NET_BW_ACCT, 0060)
+    DEFINE_BPF_MAP_EXT(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries, \
+                       AID_ROOT, AID_NET_BW_ACCT, 0060, "fs_bpf_net_shared", "", false)
 
 // For maps netd only needs read only access to
 #define DEFINE_BPF_MAP_RO_NETD(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries) \
-    DEFINE_BPF_MAP_UGM(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries, AID_ROOT, AID_NET_BW_ACCT, 0460)
+    DEFINE_BPF_MAP_EXT(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries, \
+                       AID_ROOT, AID_NET_BW_ACCT, 0460, "fs_bpf_netd_readonly", "", false)
 
 // For maps netd needs to be able to read and write
 #define DEFINE_BPF_MAP_RW_NETD(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries) \
-    DEFINE_BPF_MAP_UGM(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries, AID_ROOT, AID_NET_BW_ACCT, 0660)
+    DEFINE_BPF_MAP_UGM(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries, \
+                       AID_ROOT, AID_NET_BW_ACCT, 0660)
 
 // Bpf map arrays on creation are preinitialized to 0 and do not support deletion of a key,
 // see: kernel/bpf/arraymap.c array_map_delete_elem() returns -EINVAL (from both syscall and ebpf)
@@ -81,6 +84,20 @@
 /* never actually used from ebpf */
 DEFINE_BPF_MAP_NO_NETD(iface_index_name_map, HASH, uint32_t, IfaceValue, IFACE_INDEX_NAME_MAP_SIZE)
 
+// iptables xt_bpf programs need to be usable by both netd and netutils_wrappers
+#define DEFINE_XTBPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
+    DEFINE_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog)
+
+// programs that need to be usable by netd, but not by netutils_wrappers
+#define DEFINE_NETD_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
+    DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, \
+                        KVER_NONE, KVER_INF, false, "fs_bpf_netd_readonly", "")
+
+// programs that only need to be usable by the system server
+#define DEFINE_SYS_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
+    DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, \
+                        KVER_NONE, KVER_INF, false, "fs_bpf_net_shared", "")
+
 static __always_inline int is_system_uid(uint32_t uid) {
     // MIN_SYSTEM_UID is AID_ROOT == 0, so uint32_t is *always* >= 0
     // MAX_SYSTEM_UID is AID_NOBODY == 9999, while AID_APP_START == 10000
@@ -313,18 +330,18 @@
     return match;
 }
 
-DEFINE_BPF_PROG("cgroupskb/ingress/stats", AID_ROOT, AID_SYSTEM, bpf_cgroup_ingress)
+DEFINE_NETD_BPF_PROG("cgroupskb/ingress/stats", AID_ROOT, AID_SYSTEM, bpf_cgroup_ingress)
 (struct __sk_buff* skb) {
     return bpf_traffic_account(skb, BPF_INGRESS);
 }
 
-DEFINE_BPF_PROG("cgroupskb/egress/stats", AID_ROOT, AID_SYSTEM, bpf_cgroup_egress)
+DEFINE_NETD_BPF_PROG("cgroupskb/egress/stats", AID_ROOT, AID_SYSTEM, bpf_cgroup_egress)
 (struct __sk_buff* skb) {
     return bpf_traffic_account(skb, BPF_EGRESS);
 }
 
 // WARNING: Android T's non-updatable netd depends on the name of this program.
-DEFINE_BPF_PROG("skfilter/egress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_egress_prog)
+DEFINE_XTBPF_PROG("skfilter/egress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_egress_prog)
 (struct __sk_buff* skb) {
     // Clat daemon does not generate new traffic, all its traffic is accounted for already
     // on the v4-* interfaces (except for the 20 (or 28) extra bytes of IPv6 vs IPv4 overhead,
@@ -344,7 +361,7 @@
 }
 
 // WARNING: Android T's non-updatable netd depends on the name of this program.
-DEFINE_BPF_PROG("skfilter/ingress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_ingress_prog)
+DEFINE_XTBPF_PROG("skfilter/ingress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_ingress_prog)
 (struct __sk_buff* skb) {
     // Clat daemon traffic is not accounted by virtue of iptables raw prerouting drop rule
     // (in clat_raw_PREROUTING chain), which triggers before this (in bw_raw_PREROUTING chain).
@@ -356,7 +373,8 @@
     return BPF_MATCH;
 }
 
-DEFINE_BPF_PROG("schedact/ingress/account", AID_ROOT, AID_NET_ADMIN, tc_bpf_ingress_account_prog)
+DEFINE_SYS_BPF_PROG("schedact/ingress/account", AID_ROOT, AID_NET_ADMIN,
+                    tc_bpf_ingress_account_prog)
 (struct __sk_buff* skb) {
     if (is_received_skb(skb)) {
         // Account for ingress traffic before tc drops it.
@@ -367,7 +385,7 @@
 }
 
 // WARNING: Android T's non-updatable netd depends on the name of this program.
-DEFINE_BPF_PROG("skfilter/allowlist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_allowlist_prog)
+DEFINE_XTBPF_PROG("skfilter/allowlist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_allowlist_prog)
 (struct __sk_buff* skb) {
     uint32_t sock_uid = bpf_get_socket_uid(skb);
     if (is_system_uid(sock_uid)) return BPF_MATCH;
@@ -385,7 +403,7 @@
 }
 
 // WARNING: Android T's non-updatable netd depends on the name of this program.
-DEFINE_BPF_PROG("skfilter/denylist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_denylist_prog)
+DEFINE_XTBPF_PROG("skfilter/denylist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_denylist_prog)
 (struct __sk_buff* skb) {
     uint32_t sock_uid = bpf_get_socket_uid(skb);
     UidOwnerValue* denylistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
@@ -393,7 +411,7 @@
     return BPF_NOMATCH;
 }
 
-DEFINE_BPF_PROG("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_create)
+DEFINE_NETD_BPF_PROG("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_create)
 (struct bpf_sock* sk) {
     uint64_t gid_uid = bpf_get_current_uid_gid();
     /*
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-t/src/com/android/server/ethernet/EthernetServiceImpl.java b/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
index 71d3e4f..f058f94 100644
--- a/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
+++ b/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
@@ -16,12 +16,14 @@
 
 package com.android.server.ethernet;
 
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.net.EthernetNetworkSpecifier;
 import android.net.EthernetNetworkUpdateRequest;
 import android.net.IEthernetManager;
 import android.net.IEthernetServiceListener;
@@ -29,6 +31,7 @@
 import android.net.ITetheredInterfaceCallback;
 import android.net.IpConfiguration;
 import android.net.NetworkCapabilities;
+import android.net.NetworkSpecifier;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.RemoteException;
@@ -216,19 +219,39 @@
                 "EthernetServiceImpl");
     }
 
-    private void maybeValidateTestCapabilities(final String iface,
-            @Nullable final NetworkCapabilities nc) {
+    private void validateOrSetNetworkSpecifier(String iface, NetworkCapabilities nc) {
+        final NetworkSpecifier spec = nc.getNetworkSpecifier();
+        if (spec == null) {
+            nc.setNetworkSpecifier(new EthernetNetworkSpecifier(iface));
+            return;
+        }
+        if (!(spec instanceof EthernetNetworkSpecifier)) {
+            throw new IllegalArgumentException("Invalid specifier type for request.");
+        }
+        if (!((EthernetNetworkSpecifier) spec).getInterfaceName().matches(iface)) {
+            throw new IllegalArgumentException("Invalid interface name set on specifier.");
+        }
+    }
+
+    private void maybeValidateTestCapabilities(String iface, NetworkCapabilities nc) {
         if (!mTracker.isValidTestInterface(iface)) {
             return;
         }
-        // For test interfaces, only null or capabilities that include TRANSPORT_TEST are
-        // allowed.
-        if (nc != null && !nc.hasTransport(TRANSPORT_TEST)) {
+        if (!nc.hasTransport(TRANSPORT_TEST)) {
             throw new IllegalArgumentException(
                     "Updates to test interfaces must have NetworkCapabilities.TRANSPORT_TEST.");
         }
     }
 
+    private void maybeValidateEthernetTransport(String iface, NetworkCapabilities nc) {
+        if (mTracker.isValidTestInterface(iface)) {
+            return;
+        }
+        if (!nc.hasSingleTransport(TRANSPORT_ETHERNET)) {
+            throw new IllegalArgumentException("Invalid transport type for request.");
+        }
+    }
+
     private void enforceAdminPermission(final String iface, boolean enforceAutomotive,
             final String logMessage) {
         if (mTracker.isValidTestInterface(iface)) {
@@ -251,12 +274,17 @@
 
         // TODO: validate that iface is listed in overlay config_ethernet_interfaces
         // only automotive devices are allowed to set the NetworkCapabilities using this API
-        enforceAdminPermission(iface, request.getNetworkCapabilities() != null,
-                "updateConfiguration() with non-null capabilities");
-        maybeValidateTestCapabilities(iface, request.getNetworkCapabilities());
+        final NetworkCapabilities nc = request.getNetworkCapabilities();
+        enforceAdminPermission(
+                iface, nc != null, "updateConfiguration() with non-null capabilities");
+        if (nc != null) {
+            validateOrSetNetworkSpecifier(iface, nc);
+            maybeValidateTestCapabilities(iface, nc);
+            maybeValidateEthernetTransport(iface, nc);
+        }
 
         mTracker.updateConfiguration(
-                iface, request.getIpConfiguration(), request.getNetworkCapabilities(), listener);
+                iface, request.getIpConfiguration(), nc, listener);
     }
 
     @Override
diff --git a/service-t/src/com/android/server/net/NetworkStatsRecorder.java b/service-t/src/com/android/server/net/NetworkStatsRecorder.java
index d99e164..7c801d7 100644
--- a/service-t/src/com/android/server/net/NetworkStatsRecorder.java
+++ b/service-t/src/com/android/server/net/NetworkStatsRecorder.java
@@ -78,6 +78,7 @@
 
     private final long mBucketDuration;
     private final boolean mOnlyTags;
+    private final boolean mWipeOnError;
 
     private long mPersistThresholdBytes = 2 * MB_IN_BYTES;
     private NetworkStats mLastSnapshot;
@@ -102,6 +103,7 @@
         // slack to avoid overflow
         mBucketDuration = YEAR_IN_MILLIS;
         mOnlyTags = false;
+        mWipeOnError = true;
 
         mPending = null;
         mSinceBoot = new NetworkStatsCollection(mBucketDuration);
@@ -113,7 +115,8 @@
      * Persisted recorder.
      */
     public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
-            DropBoxManager dropBox, String cookie, long bucketDuration, boolean onlyTags) {
+            DropBoxManager dropBox, String cookie, long bucketDuration, boolean onlyTags,
+            boolean wipeOnError) {
         mRotator = Objects.requireNonNull(rotator, "missing FileRotator");
         mObserver = Objects.requireNonNull(observer, "missing NonMonotonicObserver");
         mDropBox = Objects.requireNonNull(dropBox, "missing DropBoxManager");
@@ -121,6 +124,7 @@
 
         mBucketDuration = bucketDuration;
         mOnlyTags = onlyTags;
+        mWipeOnError = wipeOnError;
 
         mPending = new NetworkStatsCollection(bucketDuration);
         mSinceBoot = new NetworkStatsCollection(bucketDuration);
@@ -552,7 +556,9 @@
             }
             mDropBox.addData(TAG_NETSTATS_DUMP, os.toByteArray(), 0);
         }
-
-        mRotator.deleteAll();
+        // Delete all files if this recorder is set wipe on error.
+        if (mWipeOnError) {
+            mRotator.deleteAll();
+        }
     }
 }
diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java
index ff6e45d..424dcd9 100644
--- a/service-t/src/com/android/server/net/NetworkStatsService.java
+++ b/service-t/src/com/android/server/net/NetworkStatsService.java
@@ -76,8 +76,10 @@
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.net.ConnectivityManager;
+import android.net.ConnectivityResources;
 import android.net.DataUsageRequest;
 import android.net.INetd;
 import android.net.INetworkStatsService;
@@ -140,6 +142,7 @@
 import android.util.SparseIntArray;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.connectivity.resources.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FileRotator;
@@ -255,7 +258,8 @@
             "netstats_import_legacy_target_attempts";
     static final int DEFAULT_NETSTATS_IMPORT_LEGACY_TARGET_ATTEMPTS = 1;
     static final String NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME = "import.attempts";
-    static final String NETSTATS_IMPORT_SUCCESS_COUNTER_NAME = "import.successes";
+    static final String NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME = "import.successes";
+    static final String NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME = "import.fallbacks";
 
     private final Context mContext;
     private final NetworkStatsFactory mStatsFactory;
@@ -275,10 +279,11 @@
     private final AlertObserver mAlertObserver = new AlertObserver();
 
     // Persistent counters that backed by AtomicFile which stored in the data directory as a file,
-    // to track attempts/successes count across reboot. Note that these counter values will be
-    // rollback as the module rollbacks.
+    // to track attempts/successes/fallbacks count across reboot. Note that these counter values
+    // will be rollback as the module rollbacks.
     private PersistentInt mImportLegacyAttemptsCounter = null;
     private PersistentInt mImportLegacySuccessesCounter = null;
+    private PersistentInt mImportLegacyFallbacksCounter = null;
 
     @VisibleForTesting
     public static final String ACTION_NETWORK_STATS_POLL =
@@ -626,21 +631,14 @@
         }
 
         /**
-         * Create the persistent counter that counts total import legacy stats attempts.
+         * Create a persistent counter for given directory and name.
          */
-        public PersistentInt createImportLegacyAttemptsCounter(@NonNull Path path)
+        public PersistentInt createPersistentCounter(@NonNull Path dir, @NonNull String name)
                 throws IOException {
             // TODO: Modify PersistentInt to call setStartTime every time a write is made.
             //  Create and pass a real logger here.
-            return new PersistentInt(path.toString(), null /* logger */);
-        }
-
-        /**
-         * Create the persistent counter that counts total import legacy stats successes.
-         */
-        public PersistentInt createImportLegacySuccessesCounter(@NonNull Path path)
-                throws IOException {
-            return new PersistentInt(path.toString(), null /* logger */);
+            final String path = dir.resolve(name).toString();
+            return new PersistentInt(path, null /* logger */);
         }
 
         /**
@@ -770,6 +768,11 @@
                 return null;
             }
         }
+
+        /** Gets whether the build is userdebug. */
+        public boolean isDebuggable() {
+            return Build.isDebuggable();
+        }
     }
 
     /**
@@ -797,11 +800,14 @@
             mSystemReady = true;
 
             // create data recorders along with historical rotators
-            mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false, mStatsDir);
-            mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false, mStatsDir);
-            mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false, mStatsDir);
+            mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false, mStatsDir,
+                    true /* wipeOnError */);
+            mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false, mStatsDir,
+                    true /* wipeOnError */);
+            mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false, mStatsDir,
+                    true /* wipeOnError */);
             mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true,
-                    mStatsDir);
+                    mStatsDir, true /* wipeOnError */);
 
             updatePersistThresholdsLocked();
 
@@ -866,12 +872,13 @@
 
     private NetworkStatsRecorder buildRecorder(
             String prefix, NetworkStatsSettings.Config config, boolean includeTags,
-            File baseDir) {
+            File baseDir, boolean wipeOnError) {
         final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
                 Context.DROPBOX_SERVICE);
         return new NetworkStatsRecorder(new FileRotator(
                 baseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
-                mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
+                mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags,
+                wipeOnError);
     }
 
     @GuardedBy("mStatsLock")
@@ -918,10 +925,12 @@
             return;
         }
         try {
-            mImportLegacyAttemptsCounter = mDeps.createImportLegacyAttemptsCounter(
-                    mStatsDir.toPath().resolve(NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME));
-            mImportLegacySuccessesCounter = mDeps.createImportLegacySuccessesCounter(
-                    mStatsDir.toPath().resolve(NETSTATS_IMPORT_SUCCESS_COUNTER_NAME));
+            mImportLegacyAttemptsCounter = mDeps.createPersistentCounter(mStatsDir.toPath(),
+                    NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME);
+            mImportLegacySuccessesCounter = mDeps.createPersistentCounter(mStatsDir.toPath(),
+                    NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME);
+            mImportLegacyFallbacksCounter = mDeps.createPersistentCounter(mStatsDir.toPath(),
+                    NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME);
         } catch (IOException e) {
             Log.wtf(TAG, "Failed to create persistent counters, skip.", e);
             return;
@@ -929,15 +938,33 @@
 
         final int targetAttempts = mDeps.getImportLegacyTargetAttempts();
         final int attempts;
+        final int fallbacks;
+        final boolean runComparison;
         try {
             attempts = mImportLegacyAttemptsCounter.get();
+            // Fallbacks counter would be set to non-zero value to indicate the migration was
+            // not successful.
+            fallbacks = mImportLegacyFallbacksCounter.get();
+            runComparison = shouldRunComparison();
         } catch (IOException e) {
-            Log.wtf(TAG, "Failed to read attempts counter, skip.", e);
+            Log.wtf(TAG, "Failed to read counters, skip.", e);
             return;
         }
-        if (attempts >= targetAttempts) return;
 
-        Log.i(TAG, "Starting import : attempts " + attempts + "/" + targetAttempts);
+        // If the target number of attempts are reached, don't import any data.
+        // However, if comparison is requested, still read the legacy data and compare
+        // it to the importer output. This allows OEMs to debug issues with the
+        // importer code and to collect signals from the field.
+        final boolean dryRunImportOnly =
+                fallbacks != 0 && runComparison && (attempts >= targetAttempts);
+        // Return if target attempts are reached and there is no need to dry run.
+        if (attempts >= targetAttempts && !dryRunImportOnly) return;
+
+        if (dryRunImportOnly) {
+            Log.i(TAG, "Starting import : only perform read");
+        } else {
+            Log.i(TAG, "Starting import : attempts " + attempts + "/" + targetAttempts);
+        }
 
         final MigrationInfo[] migrations = new MigrationInfo[]{
                 new MigrationInfo(mDevRecorder), new MigrationInfo(mXtRecorder),
@@ -945,68 +972,62 @@
         };
 
         // Legacy directories will be created by recorders if they do not exist
-        final File legacyBaseDir = mDeps.getLegacyStatsDir();
-        final NetworkStatsRecorder[] legacyRecorders = new NetworkStatsRecorder[]{
-                buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false, legacyBaseDir),
-                buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false, legacyBaseDir),
-                buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false, legacyBaseDir),
-                buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true, legacyBaseDir)
-        };
+        final NetworkStatsRecorder[] legacyRecorders;
+        if (runComparison) {
+            final File legacyBaseDir = mDeps.getLegacyStatsDir();
+            // Set wipeOnError flag false so the recorder won't damage persistent data if reads
+            // failed and calling deleteAll.
+            legacyRecorders = new NetworkStatsRecorder[]{
+                buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false, legacyBaseDir,
+                        false /* wipeOnError */),
+                buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false, legacyBaseDir,
+                        false /* wipeOnError */),
+                buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false, legacyBaseDir,
+                        false /* wipeOnError */),
+                buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true, legacyBaseDir,
+                        false /* wipeOnError */)};
+        } else {
+            legacyRecorders = null;
+        }
 
         long migrationEndTime = Long.MIN_VALUE;
-        boolean endedWithFallback = false;
         try {
             // First, read all legacy collections. This is OEM code and it can throw. Don't
             // commit any data to disk until all are read.
             for (int i = 0; i < migrations.length; i++) {
-                String errMsg = null;
-                Throwable exception = null;
                 final MigrationInfo migration = migrations[i];
 
-                // Read the collection from platform code, and using fallback method if throws.
+                // Read the collection from platform code, and set fallbacks counter if throws
+                // for better debugging.
                 try {
                     migration.collection = readPlatformCollectionForRecorder(migration.recorder);
                 } catch (Throwable e) {
-                    errMsg = "Failed to read stats from platform";
-                    exception = e;
-                }
-
-                // Also read the collection with legacy method
-                final NetworkStatsRecorder legacyRecorder = legacyRecorders[i];
-
-                final NetworkStatsCollection legacyStats;
-                try {
-                    legacyStats = legacyRecorder.getOrLoadCompleteLocked();
-                } catch (Throwable e) {
-                    Log.wtf(TAG, "Failed to read stats with legacy method for recorder " + i, e);
-                    if (exception != null) {
-                        throw exception;
+                    if (dryRunImportOnly) {
+                        Log.wtf(TAG, "Platform data read failed. ", e);
+                        return;
                     } else {
-                        // Use newer stats, since that's all that is available
-                        continue;
+                        // Data is not imported successfully, set fallbacks counter to non-zero
+                        // value to trigger dry run every later boot when the runComparison is
+                        // true, in order to make it easier to debug issues.
+                        tryIncrementLegacyFallbacksCounter();
+                        // Re-throw for error handling. This will increase attempts counter.
+                        throw e;
                     }
                 }
 
-                if (errMsg == null) {
-                    try {
-                        errMsg = compareStats(migration.collection, legacyStats);
-                    } catch (Throwable e) {
-                        errMsg = "Failed to compare migrated stats with all stats";
-                        exception = e;
+                if (runComparison) {
+                    final boolean success =
+                            compareImportedToLegacyStats(migration, legacyRecorders[i]);
+                    if (!success && !dryRunImportOnly) {
+                        tryIncrementLegacyFallbacksCounter();
                     }
                 }
-
-                if (errMsg != null) {
-                    Log.wtf(TAG, "NetworkStats import for migration " + i
-                            + " returned invalid data: " + errMsg, exception);
-                    // Fall back to legacy stats for this boot. The stats for old data will be
-                    // re-imported again on next boot until they succeed the import. This is fine
-                    // since every import clears the previous stats for the imported timespan.
-                    migration.collection = legacyStats;
-                    endedWithFallback = true;
-                }
             }
 
+            // For cases where the fallbacks are not zero but target attempts counts reached,
+            // only perform reads above and return here.
+            if (dryRunImportOnly) return;
+
             // Find the latest end time.
             for (final MigrationInfo migration : migrations) {
                 final long migrationEnd = migration.collection.getEndMillis();
@@ -1029,11 +1050,7 @@
                 migration.recorder.importCollectionLocked(migration.collection);
             }
 
-            if (endedWithFallback) {
-                Log.wtf(TAG, "Imported platform collections with legacy fallback");
-            } else {
-                Log.i(TAG, "Successfully imported platform collections");
-            }
+            // Success normally or uses fallback method.
         } catch (Throwable e) {
             // The code above calls OEM code that may behave differently across devices.
             // It can throw any exception including RuntimeExceptions and
@@ -1073,8 +1090,9 @@
         // Success ! No need to import again next time.
         try {
             mImportLegacyAttemptsCounter.set(targetAttempts);
+            Log.i(TAG, "Successfully imported platform collections");
             // The successes counter is only for debugging. Hence, the synchronization
-            // between these two counters are not very critical.
+            // between successes counter and attempts counter are not very critical.
             final int successCount = mImportLegacySuccessesCounter.get();
             mImportLegacySuccessesCounter.set(successCount + 1);
         } catch (IOException e) {
@@ -1082,6 +1100,68 @@
         }
     }
 
+    void tryIncrementLegacyFallbacksCounter() {
+        try {
+            final int fallbacks = mImportLegacyFallbacksCounter.get();
+            mImportLegacyFallbacksCounter.set(fallbacks + 1);
+        } catch (IOException e) {
+            Log.wtf(TAG, "Failed to update fallback counter.", e);
+        }
+    }
+
+    @VisibleForTesting
+    boolean shouldRunComparison() {
+        final ConnectivityResources resources = new ConnectivityResources(mContext);
+        // 0 if id not found.
+        Boolean overlayValue = null;
+        try {
+            switch (resources.get().getInteger(R.integer.config_netstats_validate_import)) {
+                case 1:
+                    overlayValue = Boolean.TRUE;
+                    break;
+                case 0:
+                    overlayValue = Boolean.FALSE;
+                    break;
+            }
+        } catch (Resources.NotFoundException e) {
+            // Overlay value is not defined.
+        }
+        return overlayValue != null ? overlayValue : mDeps.isDebuggable();
+    }
+
+    /**
+     * Compare imported data with the data returned by legacy recorders.
+     *
+     * @return true if the data matches, false if the data does not match or throw with exceptions.
+     */
+    private boolean compareImportedToLegacyStats(@NonNull MigrationInfo migration,
+            @NonNull NetworkStatsRecorder legacyRecorder) {
+        final NetworkStatsCollection legacyStats;
+        try {
+            legacyStats = legacyRecorder.getOrLoadCompleteLocked();
+        } catch (Throwable e) {
+            Log.wtf(TAG, "Failed to read stats with legacy method for recorder "
+                    + legacyRecorder.getCookie(), e);
+            // Cannot read data from legacy method, skip comparison.
+            return false;
+        }
+
+        // The result of comparison is only for logging.
+        try {
+            final String error = compareStats(migration.collection, legacyStats);
+            if (error != null) {
+                Log.wtf(TAG, "Unexpected comparison result for recorder "
+                        + legacyRecorder.getCookie() + ": " + error);
+                return false;
+            }
+        } catch (Throwable e) {
+            Log.wtf(TAG, "Failed to compare migrated stats with legacy stats for recorder "
+                    + legacyRecorder.getCookie(), e);
+            return false;
+        }
+        return true;
+    }
+
     private static String str(NetworkStatsCollection.Key key) {
         StringBuilder sb = new StringBuilder()
                 .append(key.ident.toString())
@@ -2506,6 +2586,9 @@
                     pw.print("platform legacy stats import successes count",
                             mImportLegacySuccessesCounter.get());
                     pw.println();
+                    pw.print("platform legacy stats import fallbacks count",
+                            mImportLegacyFallbacksCounter.get());
+                    pw.println();
                 } catch (IOException e) {
                     pw.println("(failed to dump platform legacy stats import counters)");
                 }
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/ServiceConnectivityResources/res/values/config.xml b/service/ServiceConnectivityResources/res/values/config.xml
index 81782f9..bff6953 100644
--- a/service/ServiceConnectivityResources/res/values/config.xml
+++ b/service/ServiceConnectivityResources/res/values/config.xml
@@ -179,4 +179,13 @@
     Only supported up to S. On T+, the Wi-Fi code should use unregisterAfterReplacement in order
     to ensure that apps see the network disconnect and reconnect. -->
     <integer translatable="false" name="config_validationFailureAfterRoamIgnoreTimeMillis">-1</integer>
+
+    <!-- Whether the network stats service should run compare on the result of
+    {@link NetworkStatsDataMigrationUtils#readPlatformCollection} and the result
+    of reading from legacy recorders. Possible values are:
+      0 = never compare,
+      1 = always compare,
+      2 = compare on debuggable builds (default value)
+      -->
+    <integer translatable="false" name="config_netstats_validate_import">2</integer>
 </resources>
diff --git a/service/ServiceConnectivityResources/res/values/overlayable.xml b/service/ServiceConnectivityResources/res/values/overlayable.xml
index b92dd08..3389d63 100644
--- a/service/ServiceConnectivityResources/res/values/overlayable.xml
+++ b/service/ServiceConnectivityResources/res/values/overlayable.xml
@@ -41,6 +41,7 @@
             <item type="array" name="config_ethernet_interfaces"/>
             <item type="string" name="config_ethernet_iface_regex"/>
             <item type="integer" name="config_validationFailureAfterRoamIgnoreTimeMillis" />
+            <item type="integer" name="config_netstats_validate_import" />
         </policy>
     </overlayable>
 </resources>
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/proguard.flags b/service/proguard.flags
index 94397ab..cffa490 100644
--- a/service/proguard.flags
+++ b/service/proguard.flags
@@ -8,11 +8,10 @@
 
 # Prevent proguard from stripping out any nearby-service and fast-pair-lite-protos fields.
 -keep class com.android.server.nearby.NearbyService { *; }
--keep class com.android.server.nearby.service.proto { *; }
 
 # The lite proto runtime uses reflection to access fields based on the names in
 # the schema, keep all the fields.
 # This replicates the base proguard rule used by the build by default
 # (proguard_basic_keeps.flags), but needs to be specified here because the
 # com.google.protobuf package is jarjared to the below package.
--keepclassmembers class * extends com.android.connectivity.com.google.protobuf.MessageLite { <fields>; }
+-keepclassmembers class * extends android.net.connectivity.com.google.protobuf.MessageLite { <fields>; }
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/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
index dedeb38..34c6d2d 100755
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
@@ -791,7 +791,7 @@
         mAllApps.add(appId);
 
         // Log package added.
-        mPermissionUpdateLogs.log("Package add: name=" + packageName + ", uid=" + uid
+        mPermissionUpdateLogs.log("Package add: uid=" + uid
                 + ", nPerm=(" + permissionToString(permission) + "/"
                 + permissionToString(currentPermission) + ")"
                 + ", tPerm=" + permissionToString(appIdTrafficPerm));
@@ -844,7 +844,7 @@
         final int permission = highestUidNetworkPermission(uid);
 
         // Log package removed.
-        mPermissionUpdateLogs.log("Package remove: name=" + packageName + ", uid=" + uid
+        mPermissionUpdateLogs.log("Package remove: uid=" + uid
                 + ", nPerm=(" + permissionToString(permission) + "/"
                 + permissionToString(currentPermission) + ")"
                 + ", tPerm=" + permissionToString(appIdTrafficPerm));
diff --git a/tests/cts/net/native/src/BpfCompatTest.cpp b/tests/cts/net/native/src/BpfCompatTest.cpp
index 97ecb9e..e52533b 100644
--- a/tests/cts/net/native/src/BpfCompatTest.cpp
+++ b/tests/cts/net/native/src/BpfCompatTest.cpp
@@ -31,8 +31,13 @@
   std::ifstream elfFile(elfPath, std::ios::in | std::ios::binary);
   ASSERT_TRUE(elfFile.is_open());
 
-  EXPECT_EQ(48, readSectionUint("size_of_bpf_map_def", elfFile, 0));
-  EXPECT_EQ(28, readSectionUint("size_of_bpf_prog_def", elfFile, 0));
+  if (android::modules::sdklevel::IsAtLeastT()) {
+    EXPECT_EQ(116, readSectionUint("size_of_bpf_map_def", elfFile, 0));
+    EXPECT_EQ(92, readSectionUint("size_of_bpf_prog_def", elfFile, 0));
+  } else {
+    EXPECT_EQ(48, readSectionUint("size_of_bpf_map_def", elfFile, 0));
+    EXPECT_EQ(28, readSectionUint("size_of_bpf_prog_def", elfFile, 0));
+  }
 }
 
 TEST(BpfTest, bpfStructSizeTestPreT) {
diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
index 0344604..1b77d5f 100644
--- a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
+++ b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
@@ -33,7 +33,6 @@
 import android.net.NetworkCapabilities.TRANSPORT_WIFI
 import android.net.NetworkRequest
 import android.net.Uri
-import android.net.cts.NetworkValidationTestUtil.clearValidationTestUrlsDeviceConfig
 import android.net.cts.NetworkValidationTestUtil.setHttpUrlDeviceConfig
 import android.net.cts.NetworkValidationTestUtil.setHttpsUrlDeviceConfig
 import android.net.cts.NetworkValidationTestUtil.setUrlExpirationDeviceConfig
@@ -60,6 +59,8 @@
 import org.junit.Assume.assumeTrue
 import org.junit.Assume.assumeFalse
 import org.junit.Before
+import org.junit.BeforeClass
+import org.junit.Rule
 import org.junit.runner.RunWith
 import java.util.concurrent.CompletableFuture
 import java.util.concurrent.TimeUnit
@@ -99,34 +100,42 @@
 
     private val server = TestHttpServer("localhost")
 
+    @get:Rule
+    val deviceConfigRule = DeviceConfigRule(retryCountBeforeSIfConfigChanged = 5)
+
+    companion object {
+        @JvmStatic @BeforeClass
+        fun setUpClass() {
+            runAsShell(READ_DEVICE_CONFIG) {
+                // Verify that the test URLs are not normally set on the device, but do not fail if
+                // the test URLs are set to what this test uses (URLs on localhost), in case the
+                // test was interrupted manually and rerun.
+                assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTPS_URL)
+                assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTP_URL)
+            }
+            NetworkValidationTestUtil.clearValidationTestUrlsDeviceConfig()
+        }
+
+        private fun assertEmptyOrLocalhostUrl(urlKey: String) {
+            val url = DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, urlKey)
+            assertTrue(TextUtils.isEmpty(url) || LOCALHOST_HOSTNAME == Uri.parse(url).host,
+                    "$urlKey must not be set in production scenarios (current value: $url)")
+        }
+    }
+
     @Before
     fun setUp() {
-        runAsShell(READ_DEVICE_CONFIG) {
-            // Verify that the test URLs are not normally set on the device, but do not fail if the
-            // test URLs are set to what this test uses (URLs on localhost), in case the test was
-            // interrupted manually and rerun.
-            assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTPS_URL)
-            assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTP_URL)
-        }
-        clearValidationTestUrlsDeviceConfig()
         server.start()
     }
 
     @After
     fun tearDown() {
-        clearValidationTestUrlsDeviceConfig()
         if (pm.hasSystemFeature(FEATURE_WIFI)) {
-            reconnectWifi()
+            deviceConfigRule.runAfterNextCleanup { reconnectWifi() }
         }
         server.stop()
     }
 
-    private fun assertEmptyOrLocalhostUrl(urlKey: String) {
-        val url = DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, urlKey)
-        assertTrue(TextUtils.isEmpty(url) || LOCALHOST_HOSTNAME == Uri.parse(url).host,
-                "$urlKey must not be set in production scenarios (current value: $url)")
-    }
-
     @Test
     fun testCaptivePortalIsNotDefaultNetwork() {
         assumeTrue(pm.hasSystemFeature(FEATURE_TELEPHONY))
@@ -154,12 +163,13 @@
         server.addResponse(Request(TEST_HTTPS_URL_PATH), Status.INTERNAL_ERROR)
         val headers = mapOf("Location" to makeUrl(TEST_PORTAL_URL_PATH))
         server.addResponse(Request(TEST_HTTP_URL_PATH), Status.REDIRECT, headers)
-        setHttpsUrlDeviceConfig(makeUrl(TEST_HTTPS_URL_PATH))
-        setHttpUrlDeviceConfig(makeUrl(TEST_HTTP_URL_PATH))
+        setHttpsUrlDeviceConfig(deviceConfigRule, makeUrl(TEST_HTTPS_URL_PATH))
+        setHttpUrlDeviceConfig(deviceConfigRule, makeUrl(TEST_HTTP_URL_PATH))
         Log.d(TAG, "Set portal URLs to $TEST_HTTPS_URL_PATH and $TEST_HTTP_URL_PATH")
         // URL expiration needs to be in the next 10 minutes
         assertTrue(WIFI_CONNECT_TIMEOUT_MS < TimeUnit.MINUTES.toMillis(10))
-        setUrlExpirationDeviceConfig(System.currentTimeMillis() + WIFI_CONNECT_TIMEOUT_MS)
+        setUrlExpirationDeviceConfig(deviceConfigRule,
+                System.currentTimeMillis() + WIFI_CONNECT_TIMEOUT_MS)
 
         // Wait for a captive portal to be detected on the network
         val wifiNetworkFuture = CompletableFuture<Network>()
@@ -215,4 +225,4 @@
         utils.ensureWifiDisconnected(null /* wifiNetworkToCheck */)
         utils.ensureWifiConnected()
     }
-}
\ No newline at end of file
+}
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/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 08cf0d7..766d62f 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -249,6 +249,10 @@
     @Rule
     public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
 
+    @Rule
+    public final DeviceConfigRule mTestValidationConfigRule = new DeviceConfigRule(
+            5 /* retryCountBeforeSIfConfigChanged */);
+
     private static final String TAG = ConnectivityManagerTest.class.getSimpleName();
 
     public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE;
@@ -2765,9 +2769,8 @@
             // Accept partial connectivity network should result in a validated network
             expectNetworkHasCapability(network, NET_CAPABILITY_VALIDATED, WIFI_CONNECT_TIMEOUT_MS);
         } finally {
-            resetValidationConfig();
-            // Reconnect wifi to reset the wifi status
-            reconnectWifi();
+            mHttpServer.stop();
+            mTestValidationConfigRule.runAfterNextCleanup(this::reconnectWifi);
         }
     }
 
@@ -2792,11 +2795,13 @@
             // Reject partial connectivity network should cause the network being torn down
             assertEquals(network, cb.waitForLost());
         } finally {
-            resetValidationConfig();
+            mHttpServer.stop();
             // Wifi will not automatically reconnect to the network. ensureWifiDisconnected cannot
             // apply here. Thus, turn off wifi first and restart to restore.
-            runShellCommand("svc wifi disable");
-            mCtsNetUtils.ensureWifiConnected();
+            mTestValidationConfigRule.runAfterNextCleanup(() -> {
+                runShellCommand("svc wifi disable");
+                mCtsNetUtils.ensureWifiConnected();
+            });
         }
     }
 
@@ -2832,11 +2837,13 @@
             });
             waitForLost(wifiCb);
         } finally {
-            resetValidationConfig();
+            mHttpServer.stop();
             /// Wifi will not automatically reconnect to the network. ensureWifiDisconnected cannot
             // apply here. Thus, turn off wifi first and restart to restore.
-            runShellCommand("svc wifi disable");
-            mCtsNetUtils.ensureWifiConnected();
+            mTestValidationConfigRule.runAfterNextCleanup(() -> {
+                runShellCommand("svc wifi disable");
+                mCtsNetUtils.ensureWifiConnected();
+            });
         }
     }
 
@@ -2896,9 +2903,8 @@
             wifiCb.assertNoCallbackThat(NO_CALLBACK_TIMEOUT_MS, c -> isValidatedCaps(c));
         } finally {
             resetAvoidBadWifi(previousAvoidBadWifi);
-            resetValidationConfig();
-            // Reconnect wifi to reset the wifi status
-            reconnectWifi();
+            mHttpServer.stop();
+            mTestValidationConfigRule.runAfterNextCleanup(this::reconnectWifi);
         }
     }
 
@@ -2942,11 +2948,6 @@
         return future.get(timeout, TimeUnit.MILLISECONDS);
     }
 
-    private void resetValidationConfig() {
-        NetworkValidationTestUtil.clearValidationTestUrlsDeviceConfig();
-        mHttpServer.stop();
-    }
-
     private void prepareHttpServer() throws Exception {
         runAsShell(READ_DEVICE_CONFIG, () -> {
             // Verify that the test URLs are not normally set on the device, but do not fail if the
@@ -3019,9 +3020,11 @@
         mHttpServer.addResponse(new TestHttpServer.Request(
                 TEST_HTTP_URL_PATH, Method.GET, "" /* queryParameters */),
                 httpStatusCode, null /* locationHeader */, "" /* content */);
-        NetworkValidationTestUtil.setHttpsUrlDeviceConfig(makeUrl(TEST_HTTPS_URL_PATH));
-        NetworkValidationTestUtil.setHttpUrlDeviceConfig(makeUrl(TEST_HTTP_URL_PATH));
-        NetworkValidationTestUtil.setUrlExpirationDeviceConfig(
+        NetworkValidationTestUtil.setHttpsUrlDeviceConfig(mTestValidationConfigRule,
+                makeUrl(TEST_HTTPS_URL_PATH));
+        NetworkValidationTestUtil.setHttpUrlDeviceConfig(mTestValidationConfigRule,
+                makeUrl(TEST_HTTP_URL_PATH));
+        NetworkValidationTestUtil.setUrlExpirationDeviceConfig(mTestValidationConfigRule,
                 System.currentTimeMillis() + WIFI_CONNECT_TIMEOUT_MS);
     }
 
@@ -3374,6 +3377,7 @@
     }
 
     @Test @IgnoreUpTo(SC_V2)
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
     public void testFirewallBlocking() {
         // Following tests affect the actual state of networking on the device after the test.
         // This might cause unexpected behaviour of the device. So, we skip them for now.
diff --git a/tests/cts/net/src/android/net/cts/DeviceConfigRule.kt b/tests/cts/net/src/android/net/cts/DeviceConfigRule.kt
new file mode 100644
index 0000000..d31a4e0
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/DeviceConfigRule.kt
@@ -0,0 +1,124 @@
+/*
+ * 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 android.net.cts
+
+import android.Manifest.permission.READ_DEVICE_CONFIG
+import android.Manifest.permission.WRITE_DEVICE_CONFIG
+import android.provider.DeviceConfig
+import android.util.Log
+import com.android.modules.utils.build.SdkLevel
+import com.android.testutils.runAsShell
+import com.android.testutils.tryTest
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+private val TAG = DeviceConfigRule::class.simpleName
+
+/**
+ * A [TestRule] that helps set [DeviceConfig] for tests and clean up the test configuration
+ * automatically on teardown.
+ *
+ * The rule can also optionally retry tests when they fail following an external change of
+ * DeviceConfig before S; this typically happens because device config flags are synced while the
+ * test is running, and DisableConfigSyncTargetPreparer is only usable starting from S.
+ *
+ * @param retryCountBeforeSIfConfigChanged if > 0, when the test fails before S, check if
+ *        the configs that were set through this rule were changed, and retry the test
+ *        up to the specified number of times if yes.
+ */
+class DeviceConfigRule @JvmOverloads constructor(
+    val retryCountBeforeSIfConfigChanged: Int = 0
+) : TestRule {
+    // Maps (namespace, key) -> value
+    private val originalConfig = mutableMapOf<Pair<String, String>, String?>()
+    private val usedConfig = mutableMapOf<Pair<String, String>, String?>()
+
+    /**
+     * Actions to be run after cleanup of the config, for the current test only.
+     */
+    private val currentTestCleanupActions = mutableListOf<Runnable>()
+
+    override fun apply(base: Statement, description: Description): Statement {
+        return TestValidationUrlStatement(base, description)
+    }
+
+    private inner class TestValidationUrlStatement(
+        private val base: Statement,
+        private val description: Description
+    ) : Statement() {
+        override fun evaluate() {
+            var retryCount = if (SdkLevel.isAtLeastS()) 1 else retryCountBeforeSIfConfigChanged + 1
+            while (retryCount > 0) {
+                retryCount--
+                tryTest {
+                    base.evaluate()
+                    // Can't use break/return out of a loop here because this is a tryTest lambda,
+                    // so set retryCount to exit instead
+                    retryCount = 0
+                }.catch<Throwable> { e -> // junit AssertionFailedError does not extend Exception
+                    if (retryCount == 0) throw e
+                    usedConfig.forEach { (key, value) ->
+                        val currentValue = runAsShell(READ_DEVICE_CONFIG) {
+                            DeviceConfig.getProperty(key.first, key.second)
+                        }
+                        if (currentValue != value) {
+                            Log.w(TAG, "Test failed with unexpected device config change, retrying")
+                            return@catch
+                        }
+                    }
+                    throw e
+                } cleanupStep {
+                    runAsShell(WRITE_DEVICE_CONFIG) {
+                        originalConfig.forEach { (key, value) ->
+                            DeviceConfig.setProperty(
+                                    key.first, key.second, value, false /* makeDefault */)
+                        }
+                    }
+                } cleanupStep {
+                    originalConfig.clear()
+                    usedConfig.clear()
+                } cleanup {
+                    currentTestCleanupActions.forEach { it.run() }
+                    currentTestCleanupActions.clear()
+                }
+            }
+        }
+    }
+
+    /**
+     * Set a configuration key/value. After the test case ends, it will be restored to the value it
+     * had when this method was first called.
+     */
+    fun setConfig(namespace: String, key: String, value: String?) {
+        runAsShell(READ_DEVICE_CONFIG, WRITE_DEVICE_CONFIG) {
+            val keyPair = Pair(namespace, key)
+            if (!originalConfig.containsKey(keyPair)) {
+                originalConfig[keyPair] = DeviceConfig.getProperty(namespace, key)
+            }
+            usedConfig[keyPair] = value
+            DeviceConfig.setProperty(namespace, key, value, false /* makeDefault */)
+        }
+    }
+
+    /**
+     * Add an action to be run after config cleanup when the current test case ends.
+     */
+    fun runAfterNextCleanup(action: Runnable) {
+        currentTestCleanupActions.add(action)
+    }
+}
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 d0d44dc..1748612 100644
--- a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
@@ -49,13 +49,14 @@
 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
 import com.android.net.module.util.ArrayTrackRecord
 import com.android.net.module.util.TrackRecord
 import com.android.testutils.anyNetwork
+import com.android.testutils.ConnectivityModuleTest
+import com.android.testutils.DeviceInfoUtils.isKernelVersionAtLeast
 import com.android.testutils.DevSdkIgnoreRule
 import com.android.testutils.DevSdkIgnoreRunner
 import com.android.testutils.RecorderCallback.CallbackEntry.Available
@@ -66,13 +67,14 @@
 import com.android.testutils.runAsShell
 import com.android.testutils.waitForIdle
 import org.junit.After
-import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
 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
@@ -97,6 +99,8 @@
 @AppModeFull(reason = "Instant apps can't access EthernetManager")
 // EthernetManager is not updatable before T, so tests do not need to be backwards compatible.
 @RunWith(DevSdkIgnoreRunner::class)
+// This test depends on behavior introduced post-T as part of connectivity module updates
+@ConnectivityModuleTest
 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
 class EthernetManagerTest {
 
@@ -140,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)
@@ -199,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() {
@@ -290,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)
@@ -297,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,
@@ -446,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)
     }
 
     /**
@@ -626,6 +646,8 @@
 
     @Test
     fun testNetworkRequest_forInterfaceWhileTogglingCarrier() {
+        assumeChangingCarrierSupported()
+
         val iface = createInterface(false /* hasCarrier */)
 
         val cb = requestNetwork(ETH_REQUEST)
@@ -637,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/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt b/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
index 391d03a..462c8a3 100644
--- a/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
@@ -16,16 +16,11 @@
 
 package android.net.cts
 
-import android.Manifest
+import android.Manifest.permission.WRITE_DEVICE_CONFIG
 import android.net.util.NetworkStackUtils
 import android.provider.DeviceConfig
 import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY
-import android.util.Log
 import com.android.testutils.runAsShell
-import com.android.testutils.tryTest
-import java.util.concurrent.CompletableFuture
-import java.util.concurrent.Executor
-import java.util.concurrent.TimeUnit
 
 /**
  * Collection of utility methods for configuring network validation.
@@ -38,9 +33,14 @@
      * Clear the test network validation URLs.
      */
     @JvmStatic fun clearValidationTestUrlsDeviceConfig() {
-        setHttpsUrlDeviceConfig(null)
-        setHttpUrlDeviceConfig(null)
-        setUrlExpirationDeviceConfig(null)
+        runAsShell(WRITE_DEVICE_CONFIG) {
+            DeviceConfig.setProperty(NAMESPACE_CONNECTIVITY,
+                    NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL, null, false)
+            DeviceConfig.setProperty(NAMESPACE_CONNECTIVITY,
+                    NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL, null, false)
+            DeviceConfig.setProperty(NAMESPACE_CONNECTIVITY,
+                    NetworkStackUtils.TEST_URL_EXPIRATION_TIME, null, false)
+        }
     }
 
     /**
@@ -48,71 +48,28 @@
      *
      * @see NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL
      */
-    @JvmStatic fun setHttpsUrlDeviceConfig(url: String?) =
-            setConfig(NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL, url)
+    @JvmStatic
+    fun setHttpsUrlDeviceConfig(rule: DeviceConfigRule, url: String?) =
+            rule.setConfig(NAMESPACE_CONNECTIVITY,
+                NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL, url)
 
     /**
      * Set the test validation HTTP URL.
      *
      * @see NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL
      */
-    @JvmStatic fun setHttpUrlDeviceConfig(url: String?) =
-            setConfig(NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL, url)
+    @JvmStatic
+    fun setHttpUrlDeviceConfig(rule: DeviceConfigRule, url: String?) =
+            rule.setConfig(NAMESPACE_CONNECTIVITY,
+                NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL, url)
 
     /**
      * Set the test validation URL expiration.
      *
      * @see NetworkStackUtils.TEST_URL_EXPIRATION_TIME
      */
-    @JvmStatic fun setUrlExpirationDeviceConfig(timestamp: Long?) =
-            setConfig(NetworkStackUtils.TEST_URL_EXPIRATION_TIME, timestamp?.toString())
-
-    private fun setConfig(configKey: String, value: String?): String? {
-        Log.i(TAG, "Setting config \"$configKey\" to \"$value\"")
-        val readWritePermissions = arrayOf(
-                Manifest.permission.READ_DEVICE_CONFIG,
-                Manifest.permission.WRITE_DEVICE_CONFIG)
-
-        val existingValue = runAsShell(*readWritePermissions) {
-            DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, configKey)
-        }
-        if (existingValue == value) {
-            // Already the correct value. There may be a race if a change is already in flight,
-            // but if multiple threads update the config there is no way to fix that anyway.
-            Log.i(TAG, "\$configKey\" already had value \"$value\"")
-            return value
-        }
-
-        val future = CompletableFuture<String>()
-        val listener = DeviceConfig.OnPropertiesChangedListener {
-            // The listener receives updates for any change to any key, so don't react to
-            // changes that do not affect the relevant key
-            if (!it.keyset.contains(configKey)) return@OnPropertiesChangedListener
-            if (it.getString(configKey, null) == value) {
-                future.complete(value)
-            }
-        }
-
-        return tryTest {
-            runAsShell(*readWritePermissions) {
-                DeviceConfig.addOnPropertiesChangedListener(
-                        NAMESPACE_CONNECTIVITY,
-                        inlineExecutor,
-                        listener)
-                DeviceConfig.setProperty(
-                        NAMESPACE_CONNECTIVITY,
-                        configKey,
-                        value,
-                        false /* makeDefault */)
-                // Don't drop the permission until the config is applied, just in case
-                future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS)
-            }.also {
-                Log.i(TAG, "Config \"$configKey\" successfully set to \"$value\"")
-            }
-        } cleanup {
-            DeviceConfig.removeOnPropertiesChangedListener(listener)
-        }
-    }
-
-    private val inlineExecutor get() = Executor { r -> r.run() }
+    @JvmStatic
+    fun setUrlExpirationDeviceConfig(rule: DeviceConfigRule, timestamp: Long?) =
+            rule.setConfig(NAMESPACE_CONNECTIVITY,
+                NetworkStackUtils.TEST_URL_EXPIRATION_TIME, timestamp?.toString())
 }
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/android/net/NetworkStatsRecorderTest.java b/tests/unit/java/android/net/NetworkStatsRecorderTest.java
new file mode 100644
index 0000000..fad11a3
--- /dev/null
+++ b/tests/unit/java/android/net/NetworkStatsRecorderTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *i
+ * 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.net;
+
+import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.net.NetworkStats;
+import android.os.DropBoxManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.util.FileRotator;
+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;
+
+@RunWith(DevSdkIgnoreRunner.class)
+@SmallTest
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public final class NetworkStatsRecorderTest {
+    private static final String TAG = NetworkStatsRecorderTest.class.getSimpleName();
+
+    private static final String TEST_PREFIX = "test";
+
+    @Mock private DropBoxManager mDropBox;
+    @Mock private NetworkStats.NonMonotonicObserver mObserver;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    private NetworkStatsRecorder buildRecorder(FileRotator rotator, boolean wipeOnError) {
+        return new NetworkStatsRecorder(rotator, mObserver, mDropBox, TEST_PREFIX,
+                    HOUR_IN_MILLIS, false /* includeTags */, wipeOnError);
+    }
+
+    @Test
+    public void testWipeOnError() throws Exception {
+        final FileRotator rotator = mock(FileRotator.class);
+        final NetworkStatsRecorder wipeOnErrorRecorder = buildRecorder(rotator, true);
+
+        // Assuming that the rotator gets an exception happened when read data.
+        doThrow(new IOException()).when(rotator).readMatching(any(), anyLong(), anyLong());
+        wipeOnErrorRecorder.getOrLoadPartialLocked(Long.MIN_VALUE, Long.MAX_VALUE);
+        // Verify that the files will be deleted.
+        verify(rotator, times(1)).deleteAll();
+        reset(rotator);
+
+        final NetworkStatsRecorder noWipeOnErrorRecorder = buildRecorder(rotator, false);
+        doThrow(new IOException()).when(rotator).readMatching(any(), anyLong(), anyLong());
+        noWipeOnErrorRecorder.getOrLoadPartialLocked(Long.MIN_VALUE, Long.MAX_VALUE);
+        // Verify that the rotator won't delete files.
+        verify(rotator, never()).deleteAll();
+    }
+}
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 5899fd0..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;
 
@@ -41,6 +38,7 @@
 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.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
@@ -95,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;
@@ -120,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;
@@ -144,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;
@@ -176,7 +172,10 @@
 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;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Stream;
@@ -189,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";
@@ -247,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;
@@ -279,6 +250,8 @@
     @Mock private ConnectivityManager mConnectivityManager;
     @Mock private IpSecService mIpSecService;
     @Mock private VpnProfileStore mVpnProfileStore;
+    @Mock private ScheduledThreadPoolExecutor mExecutor;
+    @Mock private ScheduledFuture mScheduledFuture;
     @Mock DeviceIdleInternal mDeviceIdleInternal;
     private final VpnProfile mVpnProfile;
 
@@ -303,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);
@@ -342,7 +315,9 @@
         // PERMISSION_DENIED.
         doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(any());
 
+        // Set up mIkev2SessionCreator and mExecutor
         resetIkev2SessionCreator(mIkeSessionWrapper);
+        resetExecutor(mScheduledFuture);
     }
 
     private void resetIkev2SessionCreator(Vpn.IkeSessionWrapper ikeSession) {
@@ -351,6 +326,18 @@
                 .thenReturn(ikeSession);
     }
 
+    private void resetExecutor(ScheduledFuture scheduledFuture) {
+        doAnswer(
+                (invocation) -> {
+                    ((Runnable) invocation.getArgument(0)).run();
+                    return null;
+                })
+            .when(mExecutor)
+            .execute(any());
+        when(mExecutor.schedule(
+                any(Runnable.class), anyLong(), any())).thenReturn(mScheduledFuture);
+    }
+
     @After
     public void tearDown() throws Exception {
         doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
@@ -394,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]),
@@ -450,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),
@@ -472,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());
@@ -496,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.
@@ -530,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.
@@ -641,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,
@@ -674,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),
@@ -726,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
@@ -760,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);
 
@@ -795,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 {
@@ -860,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());
@@ -876,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<>()));
@@ -935,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);
@@ -958,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);
@@ -1081,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);
@@ -1094,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);
@@ -1165,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;
@@ -1232,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 */));
@@ -1372,10 +1431,6 @@
         final ArgumentCaptor<IkeSessionCallback> captor =
                 ArgumentCaptor.forClass(IkeSessionCallback.class);
 
-        // This test depends on a real ScheduledThreadPoolExecutor
-        doReturn(new ScheduledThreadPoolExecutor(1)).when(mTestDeps)
-                .newScheduledThreadPoolExecutor();
-
         final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
         when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
                 .thenReturn(mVpnProfile.encode());
@@ -1400,25 +1455,38 @@
             verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS))
                     .unregisterNetworkCallback(eq(cb));
         } else if (errorType == VpnManager.ERROR_CLASS_RECOVERABLE) {
-            // To prevent spending much time to test the retry function, only retry 2 times here.
             int retryIndex = 0;
-            verify(mIkev2SessionCreator,
-                    timeout(((TestDeps) vpn.mDeps).getNextRetryDelaySeconds(retryIndex++) * 1000
-                            + TEST_TIMEOUT_MS))
-                    .createIkeSession(any(), any(), any(), any(), captor.capture(), any());
+            final IkeSessionCallback ikeCb2 = verifyRetryAndGetNewIkeCb(retryIndex++);
 
-            // Capture a new IkeSessionCallback to get the latest token.
-            reset(mIkev2SessionCreator);
-            final IkeSessionCallback ikeCb2 = captor.getValue();
             ikeCb2.onClosedWithException(exception);
-            verify(mIkev2SessionCreator,
-                    timeout(((TestDeps) vpn.mDeps).getNextRetryDelaySeconds(retryIndex++) * 1000
-                            + TEST_TIMEOUT_MS))
-                    .createIkeSession(any(), any(), any(), any(), captor.capture(), any());
-            reset(mIkev2SessionCreator);
+            verifyRetryAndGetNewIkeCb(retryIndex++);
         }
     }
 
+    private IkeSessionCallback verifyRetryAndGetNewIkeCb(int retryIndex) {
+        final ArgumentCaptor<Runnable> runnableCaptor =
+                ArgumentCaptor.forClass(Runnable.class);
+        final ArgumentCaptor<IkeSessionCallback> ikeCbCaptor =
+                ArgumentCaptor.forClass(IkeSessionCallback.class);
+
+        // Verify retry is scheduled
+        final long expectedDelay = mTestDeps.getNextRetryDelaySeconds(retryIndex);
+        verify(mExecutor).schedule(runnableCaptor.capture(), eq(expectedDelay), any());
+
+        // Mock the event of firing the retry task
+        runnableCaptor.getValue().run();
+
+        verify(mIkev2SessionCreator)
+                .createIkeSession(any(), any(), any(), any(), ikeCbCaptor.capture(), any());
+
+        // Forget the mIkev2SessionCreator#createIkeSession call and mExecutor#schedule call
+        // for the next retry verification
+        resetIkev2SessionCreator(mIkeSessionWrapper);
+        resetExecutor(mScheduledFuture);
+
+        return ikeCbCaptor.getValue();
+    }
+
     @Test
     public void testStartPlatformVpnAuthenticationFailed() throws Exception {
         final IkeProtocolException exception = mock(IkeProtocolException.class);
@@ -1485,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);
@@ -1505,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;
@@ -1533,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();
@@ -1685,9 +1753,13 @@
         final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
                 createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */));
 
-        // Mock network switch
+        // Mock network loss and verify a cleanup task is scheduled
         vpnSnapShot.nwCb.onLost(TEST_NETWORK);
+        verify(mExecutor).schedule(any(Runnable.class), anyLong(), any());
+
+        // Mock new network comes up and the cleanup task is cancelled
         vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2);
+        verify(mScheduledFuture).cancel(anyBoolean());
 
         // Verify MOBIKE is triggered
         verify(mIkeSessionWrapper).setNetwork(TEST_NETWORK_2);
@@ -1755,7 +1827,55 @@
         vpnSnapShot.vpn.mVpnRunner.exitVpnRunner();
     }
 
-    // TODO: Add a test for network loss without mobility
+    private void verifyHandlingNetworkLoss() throws Exception {
+        final ArgumentCaptor<LinkProperties> lpCaptor =
+                ArgumentCaptor.forClass(LinkProperties.class);
+        verify(mMockNetworkAgent).sendLinkProperties(lpCaptor.capture());
+        final LinkProperties lp = lpCaptor.getValue();
+
+        assertNull(lp.getInterfaceName());
+        final List<RouteInfo> expectedRoutes = Arrays.asList(
+                new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null /*gateway*/,
+                        null /*iface*/, RTN_UNREACHABLE),
+                new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /*gateway*/,
+                        null /*iface*/, RTN_UNREACHABLE));
+        assertEquals(expectedRoutes, lp.getRoutes());
+    }
+
+    @Test
+    public void testStartPlatformVpnHandlesNetworkLoss_mobikeEnabled() throws Exception {
+        final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
+                createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */));
+
+        // Forget the #sendLinkProperties during first setup.
+        reset(mMockNetworkAgent);
+
+        final ArgumentCaptor<Runnable> runnableCaptor =
+                ArgumentCaptor.forClass(Runnable.class);
+
+        // Mock network loss
+        vpnSnapShot.nwCb.onLost(TEST_NETWORK);
+
+        // Mock the grace period expires
+        verify(mExecutor).schedule(runnableCaptor.capture(), anyLong(), any());
+        runnableCaptor.getValue().run();
+
+        verifyHandlingNetworkLoss();
+    }
+
+    @Test
+    public void testStartPlatformVpnHandlesNetworkLoss_mobikeDisabled() throws Exception {
+        final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
+                createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */));
+
+        // Forget the #sendLinkProperties during first setup.
+        reset(mMockNetworkAgent);
+
+        // Mock network loss
+        vpnSnapShot.nwCb.onLost(TEST_NETWORK);
+
+        verifyHandlingNetworkLoss();
+    }
 
     @Test
     public void testStartRacoonNumericAddress() throws Exception {
@@ -1767,6 +1887,16 @@
         startRacoon("hostname", "5.6.7.8"); // address returned by deps.resolve
     }
 
+    @Test
+    public void testStartPptp() throws Exception {
+        startPptp(true /* useMppe */);
+    }
+
+    @Test
+    public void testStartPptp_NoMppe() throws Exception {
+        startPptp(false /* useMppe */);
+    }
+
     private void assertTransportInfoMatches(NetworkCapabilities nc, int type) {
         assertNotNull(nc);
         VpnTransportInfo ti = (VpnTransportInfo) nc.getTransportInfo();
@@ -1774,6 +1904,48 @@
         assertEquals(type, ti.getType());
     }
 
+    private void startPptp(boolean useMppe) throws Exception {
+        final VpnProfile profile = new VpnProfile("testProfile" /* key */);
+        profile.type = VpnProfile.TYPE_PPTP;
+        profile.name = "testProfileName";
+        profile.username = "userName";
+        profile.password = "thePassword";
+        profile.server = "192.0.2.123";
+        profile.mppe = useMppe;
+
+        doReturn(new Network[] { new Network(101) }).when(mConnectivityManager).getAllNetworks();
+        doReturn(new Network(102)).when(mConnectivityManager).registerNetworkAgent(any(), any(),
+                any(), any(), any(), any(), anyInt());
+
+        final Vpn vpn = startLegacyVpn(createVpn(PRIMARY_USER.id), profile);
+        final TestDeps deps = (TestDeps) vpn.mDeps;
+
+        testAndCleanup(() -> {
+            final String[] mtpdArgs = deps.mtpdArgs.get(10, TimeUnit.SECONDS);
+            final String[] argsPrefix = new String[]{
+                    EGRESS_IFACE, "pptp", profile.server, "1723", "name", profile.username,
+                    "password", profile.password, "linkname", "vpn", "refuse-eap", "nodefaultroute",
+                    "usepeerdns", "idle", "1800", "mtu", "1270", "mru", "1270"
+            };
+            assertArrayEquals(argsPrefix, Arrays.copyOf(mtpdArgs, argsPrefix.length));
+            if (useMppe) {
+                assertEquals(argsPrefix.length + 2, mtpdArgs.length);
+                assertEquals("+mppe", mtpdArgs[argsPrefix.length]);
+                assertEquals("-pap", mtpdArgs[argsPrefix.length + 1]);
+            } else {
+                assertEquals(argsPrefix.length + 1, mtpdArgs.length);
+                assertEquals("nomppe", mtpdArgs[argsPrefix.length]);
+            }
+
+            verify(mConnectivityManager, timeout(10_000)).registerNetworkAgent(any(), any(),
+                    any(), any(), any(), any(), anyInt());
+        }, () -> { // Cleanup
+                vpn.mVpnRunner.exitVpnRunner();
+                deps.getStateFile().delete(); // set to delete on exit, but this deletes it earlier
+                vpn.mVpnRunner.join(10_000); // wait for up to 10s for the runner to die and cleanup
+            });
+    }
+
     public void startRacoon(final String serverAddr, final String expectedAddr)
             throws Exception {
         final ConditionVariable legacyRunnerReady = new ConditionVariable();
@@ -1796,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
@@ -1981,16 +2153,7 @@
 
         @Override
         public ScheduledThreadPoolExecutor newScheduledThreadPoolExecutor() {
-            final ScheduledThreadPoolExecutor mockExecutor =
-                    mock(ScheduledThreadPoolExecutor.class);
-            doAnswer(
-                    (invocation) -> {
-                        ((Runnable) invocation.getArgument(0)).run();
-                        return null;
-                    })
-                .when(mockExecutor)
-                .execute(any());
-            return mockExecutor;
+            return mExecutor;
         }
     }
 
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
diff --git a/tests/unit/java/com/android/server/ethernet/EthernetServiceImplTest.java b/tests/unit/java/com/android/server/ethernet/EthernetServiceImplTest.java
index b2b9f2c..a1d93a0 100644
--- a/tests/unit/java/com/android/server/ethernet/EthernetServiceImplTest.java
+++ b/tests/unit/java/com/android/server/ethernet/EthernetServiceImplTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.ethernet;
 
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
 
 import static org.junit.Assert.assertThrows;
@@ -35,10 +36,12 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.net.EthernetNetworkSpecifier;
 import android.net.EthernetNetworkUpdateRequest;
 import android.net.INetworkInterfaceOutcomeReceiver;
 import android.net.IpConfiguration;
 import android.net.NetworkCapabilities;
+import android.net.StringNetworkSpecifier;
 import android.os.Build;
 import android.os.Handler;
 
@@ -56,10 +59,14 @@
 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
 public class EthernetServiceImplTest {
     private static final String TEST_IFACE = "test123";
+    private static final NetworkCapabilities DEFAULT_CAPS = new NetworkCapabilities.Builder()
+            .addTransportType(TRANSPORT_ETHERNET)
+            .setNetworkSpecifier(new EthernetNetworkSpecifier(TEST_IFACE))
+            .build();
     private static final EthernetNetworkUpdateRequest UPDATE_REQUEST =
             new EthernetNetworkUpdateRequest.Builder()
                     .setIpConfiguration(new IpConfiguration())
-                    .setNetworkCapabilities(new NetworkCapabilities.Builder().build())
+                    .setNetworkCapabilities(DEFAULT_CAPS)
                     .build();
     private static final EthernetNetworkUpdateRequest UPDATE_REQUEST_WITHOUT_CAPABILITIES =
             new EthernetNetworkUpdateRequest.Builder()
@@ -67,7 +74,7 @@
                     .build();
     private static final EthernetNetworkUpdateRequest UPDATE_REQUEST_WITHOUT_IP_CONFIG =
             new EthernetNetworkUpdateRequest.Builder()
-                    .setNetworkCapabilities(new NetworkCapabilities.Builder().build())
+                    .setNetworkCapabilities(DEFAULT_CAPS)
                     .build();
     private static final INetworkInterfaceOutcomeReceiver NULL_LISTENER = null;
     private EthernetServiceImpl mEthernetServiceImpl;
@@ -161,6 +168,41 @@
     }
 
     @Test
+    public void testUpdateConfigurationRejectsWithInvalidSpecifierType() {
+        final StringNetworkSpecifier invalidSpecifierType = new StringNetworkSpecifier("123");
+        final EthernetNetworkUpdateRequest request =
+                new EthernetNetworkUpdateRequest.Builder()
+                        .setNetworkCapabilities(
+                                new NetworkCapabilities.Builder()
+                                        .addTransportType(TRANSPORT_ETHERNET)
+                                        .setNetworkSpecifier(invalidSpecifierType)
+                                        .build()
+                        ).build();
+        assertThrows(IllegalArgumentException.class, () -> {
+            mEthernetServiceImpl.updateConfiguration(
+                    "" /* iface */, request, null /* listener */);
+        });
+    }
+
+    @Test
+    public void testUpdateConfigurationRejectsWithInvalidSpecifierName() {
+        final String ifaceToUpdate = "eth0";
+        final String ifaceOnSpecifier = "wlan0";
+        EthernetNetworkUpdateRequest request =
+                new EthernetNetworkUpdateRequest.Builder()
+                        .setNetworkCapabilities(
+                                new NetworkCapabilities.Builder()
+                                        .addTransportType(TRANSPORT_ETHERNET)
+                                        .setNetworkSpecifier(
+                                                new EthernetNetworkSpecifier(ifaceOnSpecifier))
+                                        .build()
+                        ).build();
+        assertThrows(IllegalArgumentException.class, () -> {
+            mEthernetServiceImpl.updateConfiguration(ifaceToUpdate, request, null /* listener */);
+        });
+    }
+
+    @Test
     public void testUpdateConfigurationWithCapabilitiesWithAutomotiveFeature() {
         toggleAutomotiveFeature(false);
         mEthernetServiceImpl.updateConfiguration(TEST_IFACE, UPDATE_REQUEST_WITHOUT_CAPABILITIES,
@@ -247,6 +289,24 @@
     }
 
     @Test
+    public void testUpdateConfigurationAddsSpecifierWhenNotSet() {
+        final NetworkCapabilities nc = new NetworkCapabilities.Builder()
+                .addTransportType(TRANSPORT_ETHERNET).build();
+        final EthernetNetworkUpdateRequest requestSansSpecifier =
+                new EthernetNetworkUpdateRequest.Builder()
+                        .setNetworkCapabilities(nc)
+                        .build();
+        final NetworkCapabilities ncWithSpecifier = new NetworkCapabilities(nc)
+                .setNetworkSpecifier(new EthernetNetworkSpecifier(TEST_IFACE));
+
+        mEthernetServiceImpl.updateConfiguration(TEST_IFACE, requestSansSpecifier, NULL_LISTENER);
+        verify(mEthernetTracker).updateConfiguration(
+                eq(TEST_IFACE),
+                isNull(),
+                eq(ncWithSpecifier), eq(NULL_LISTENER));
+    }
+
+    @Test
     public void testEnableInterface() {
         mEthernetServiceImpl.enableInterface(TEST_IFACE, NULL_LISTENER);
         verify(mEthernetTracker).enableInterface(eq(TEST_IFACE), eq(NULL_LISTENER));
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index 4fbbc75..f9cbb10 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -67,6 +67,9 @@
 
 import static com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT;
 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
+import static com.android.server.net.NetworkStatsService.NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME;
+import static com.android.server.net.NetworkStatsService.NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME;
+import static com.android.server.net.NetworkStatsService.NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME;
 import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
 
 import static org.junit.Assert.assertEquals;
@@ -92,13 +95,16 @@
 import android.app.AlarmManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
 import android.database.ContentObserver;
+import android.net.ConnectivityResources;
 import android.net.DataUsageRequest;
 import android.net.INetd;
 import android.net.INetworkStatsSession;
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
+import android.net.NetworkIdentity;
 import android.net.NetworkStateSnapshot;
 import android.net.NetworkStats;
 import android.net.NetworkStatsCollection;
@@ -125,6 +131,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
+import com.android.connectivity.resources.R;
 import com.android.internal.util.FileRotator;
 import com.android.internal.util.test.BroadcastInterceptingContext;
 import com.android.net.module.util.IBpfMap;
@@ -152,6 +159,7 @@
 import org.mockito.MockitoAnnotations;
 
 import java.io.File;
+import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.time.Clock;
@@ -161,6 +169,7 @@
 import java.time.temporal.ChronoUnit;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -242,6 +251,9 @@
     private int mImportLegacyTargetAttempts = 0;
     private @Mock PersistentInt mImportLegacyAttemptsCounter;
     private @Mock PersistentInt mImportLegacySuccessesCounter;
+    private @Mock PersistentInt mImportLegacyFallbacksCounter;
+    private @Mock Resources mResources;
+    private Boolean mIsDebuggable;
 
     private class MockContext extends BroadcastInterceptingContext {
         private final Context mBaseContext;
@@ -302,6 +314,12 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+
+        // Setup mock resources.
+        final Context mockResContext = mock(Context.class);
+        doReturn(mResources).when(mockResContext).getResources();
+        ConnectivityResources.setResourcesContextForTest(mockResContext);
+
         final Context context = InstrumentationRegistry.getContext();
         mServiceContext = new MockContext(context);
         when(mLocationPermissionChecker.checkCallersLocationPermission(
@@ -382,15 +400,18 @@
             }
 
             @Override
-            public PersistentInt createImportLegacyAttemptsCounter(
-                    @androidx.annotation.NonNull Path path) {
-                return mImportLegacyAttemptsCounter;
-            }
-
-            @Override
-            public PersistentInt createImportLegacySuccessesCounter(
-                    @androidx.annotation.NonNull Path path) {
-                return mImportLegacySuccessesCounter;
+            public PersistentInt createPersistentCounter(@androidx.annotation.NonNull Path dir,
+                    @androidx.annotation.NonNull String name) throws IOException {
+                switch (name) {
+                    case NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME:
+                        return mImportLegacyAttemptsCounter;
+                    case NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME:
+                        return mImportLegacySuccessesCounter;
+                    case NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME:
+                        return mImportLegacyFallbacksCounter;
+                    default:
+                        throw new IllegalArgumentException("Unknown counter name: " + name);
+                }
             }
 
             @Override
@@ -454,6 +475,11 @@
             public IBpfMap<UidStatsMapKey, StatsMapValue> getAppUidStatsMap() {
                 return mAppUidStatsMap;
             }
+
+            @Override
+            public boolean isDebuggable() {
+                return mIsDebuggable == Boolean.TRUE;
+            }
         };
     }
 
@@ -1890,19 +1916,127 @@
         //  will decrease the retry counter by 1.
     }
 
+    @Test
+    public void testDataMigration_differentFromFallback() throws Exception {
+        assertStatsFilesExist(false);
+        expectDefaultSettings();
+
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{buildWifiState()};
+
+        mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
+                new UnderlyingNetworkInfo[0]);
+
+        // modify some number on wifi, and trigger poll event
+        incrementCurrentTime(HOUR_IN_MILLIS);
+        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+                .insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L));
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
+        forcePollAndWaitForIdle();
+        // Simulate shutdown to force persisting data
+        mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
+        assertStatsFilesExist(true);
+
+        // Move the files to the legacy directory to simulate an import from old data
+        for (File f : mStatsDir.listFiles()) {
+            Files.move(f.toPath(), mLegacyStatsDir.toPath().resolve(f.getName()));
+        }
+        assertStatsFilesExist(false);
+
+        // Prepare some unexpected data.
+        final NetworkIdentity testWifiIdent = new NetworkIdentity.Builder().setType(TYPE_WIFI)
+                .setWifiNetworkKey(TEST_WIFI_NETWORK_KEY).build();
+        final NetworkStatsCollection.Key unexpectedUidAllkey = new NetworkStatsCollection.Key(
+                Set.of(testWifiIdent), UID_ALL, SET_DEFAULT, 0);
+        final NetworkStatsCollection.Key unexpectedUidBluekey = new NetworkStatsCollection.Key(
+                Set.of(testWifiIdent), UID_BLUE, SET_DEFAULT, 0);
+        final NetworkStatsHistory unexpectedHistory = new NetworkStatsHistory
+                .Builder(965L /* bucketDuration */, 1)
+                .addEntry(new NetworkStatsHistory.Entry(TEST_START, 3L, 55L, 4L, 31L, 10L, 5L))
+                .build();
+
+        // Simulate the platform stats collection somehow is different from what is read from
+        // the fallback method. The service should read them as is. This usually happens when an
+        // OEM has changed the implementation of NetworkStatsDataMigrationUtils inside the platform.
+        final NetworkStatsCollection summaryCollection =
+                getLegacyCollection(PREFIX_XT, false /* includeTags */);
+        summaryCollection.recordHistory(unexpectedUidAllkey, unexpectedHistory);
+        final NetworkStatsCollection uidCollection =
+                getLegacyCollection(PREFIX_UID, false /* includeTags */);
+        uidCollection.recordHistory(unexpectedUidBluekey, unexpectedHistory);
+        mPlatformNetworkStatsCollection.put(PREFIX_DEV, summaryCollection);
+        mPlatformNetworkStatsCollection.put(PREFIX_XT, summaryCollection);
+        mPlatformNetworkStatsCollection.put(PREFIX_UID, uidCollection);
+        mPlatformNetworkStatsCollection.put(PREFIX_UID_TAG,
+                getLegacyCollection(PREFIX_UID_TAG, true /* includeTags */));
+
+        // Mock zero usage and boot through serviceReady(), verify there is no imported data.
+        expectDefaultSettings();
+        expectNetworkStatsUidDetail(buildEmptyStats());
+        expectSystemReady();
+        mService.systemReady();
+        assertStatsFilesExist(false);
+
+        // Set the flag and reboot, verify the imported data is not there until next boot.
+        mStoreFilesInApexData = true;
+        mImportLegacyTargetAttempts = 3;
+        mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
+        assertStatsFilesExist(false);
+
+        // Boot through systemReady() again.
+        expectDefaultSettings();
+        expectNetworkStatsUidDetail(buildEmptyStats());
+        expectSystemReady();
+        mService.systemReady();
+
+        // Verify the result read from public API matches the result returned from the importer.
+        assertNetworkTotal(sTemplateWifi, 1024L + 55L, 8L + 4L, 2048L + 31L, 16L + 10L, 0 + 5);
+        assertUidTotal(sTemplateWifi, UID_BLUE,
+                128L + 55L, 1L + 4L, 128L + 31L, 1L + 10L, 0 + 5);
+        assertStatsFilesExist(true);
+        verify(mImportLegacyAttemptsCounter).set(3);
+        verify(mImportLegacySuccessesCounter).set(1);
+    }
+
+    @Test
+    public void testShouldRunComparison() {
+        for (Boolean isDebuggable : Set.of(Boolean.TRUE, Boolean.FALSE)) {
+            mIsDebuggable = isDebuggable;
+            // Verify return false regardless of the device is debuggable.
+            doReturn(0).when(mResources)
+                    .getInteger(R.integer.config_netstats_validate_import);
+            assertShouldRunComparison(false, isDebuggable);
+            // Verify return true regardless of the device is debuggable.
+            doReturn(1).when(mResources)
+                    .getInteger(R.integer.config_netstats_validate_import);
+            assertShouldRunComparison(true, isDebuggable);
+            // Verify return true iff the device is debuggable.
+            for (int testValue : Set.of(-1, 2)) {
+                doReturn(testValue).when(mResources)
+                        .getInteger(R.integer.config_netstats_validate_import);
+                assertShouldRunComparison(isDebuggable, isDebuggable);
+            }
+        }
+    }
+
+    private void assertShouldRunComparison(boolean expected, boolean isDebuggable) {
+        assertEquals("shouldRunComparison (debuggable=" + isDebuggable + "): ",
+                expected, mService.shouldRunComparison());
+    }
+
     private NetworkStatsRecorder makeTestRecorder(File directory, String prefix, Config config,
-            boolean includeTags) {
+            boolean includeTags, boolean wipeOnError) {
         final NetworkStats.NonMonotonicObserver observer =
                 mock(NetworkStats.NonMonotonicObserver.class);
         final DropBoxManager dropBox = mock(DropBoxManager.class);
         return new NetworkStatsRecorder(new FileRotator(
                 directory, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
-                observer, dropBox, prefix, config.bucketDuration, includeTags);
+                observer, dropBox, prefix, config.bucketDuration, includeTags, wipeOnError);
     }
 
     private NetworkStatsCollection getLegacyCollection(String prefix, boolean includeTags) {
-        final NetworkStatsRecorder recorder = makeTestRecorder(mLegacyStatsDir, PREFIX_DEV,
-                mSettings.getDevConfig(), includeTags);
+        final NetworkStatsRecorder recorder = makeTestRecorder(mLegacyStatsDir, prefix,
+                mSettings.getDevConfig(), includeTags, false);
         return recorder.getOrLoadCompleteLocked();
     }
 
