diff --git a/Cronet/tests/cts/src/org/chromium/net/test/CronetApiTest.java b/Cronet/tests/cts/src/org/chromium/net/test/CronetApiTest.java
deleted file mode 100644
index 6465006..0000000
--- a/Cronet/tests/cts/src/org/chromium/net/test/CronetApiTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2019 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 org.chromium.net.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.os.Handler;
-import android.os.Looper;
-
-import androidx.annotation.NonNull;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.chromium.net.CronetEngine;
-import org.chromium.net.CronetException;
-import org.chromium.net.UrlRequest;
-import org.chromium.net.UrlResponseInfo;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.nio.ByteBuffer;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-public class CronetApiTest {
-    private static final String TAG = CronetApiTest.class.getSimpleName();
-    private static final String HTTPS_PREFIX = "https://";
-    private static final int TIMEOUT_MS = 12_000;
-
-    private final String[] mTestDomains = {"www.google.com", "www.android.com"};
-    @NonNull private CronetEngine mCronetEngine;
-    @NonNull private ConnectivityManager mCm;
-    @NonNull private Executor mExecutor;
-
-    @Before
-    public void setUp() throws Exception {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-        CronetEngine.Builder builder = new CronetEngine.Builder(context);
-        builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024)
-                .enableHttp2(true)
-                // .enableBrotli(true)
-                .enableQuic(true);
-        mCronetEngine = builder.build();
-        mExecutor = new Handler(Looper.getMainLooper())::post;
-    }
-
-    private static void assertGreaterThan(String msg, int first, int second) {
-        assertTrue(msg + " Excepted " + first + " to be greater than " + second, first > second);
-    }
-
-    private void assertHasTestableNetworks() {
-        assertNotNull("This test requires a working Internet connection", mCm.getActiveNetwork());
-    }
-
-    private String getRandomDomain() {
-        int index = (new Random()).nextInt(mTestDomains.length);
-        return mTestDomains[index];
-    }
-
-    private static class TestUrlRequestCallback extends UrlRequest.Callback {
-        private final CountDownLatch mLatch = new CountDownLatch(1);
-        private final String mUrl;
-
-        TestUrlRequestCallback(@NonNull String url) {
-            this.mUrl = url;
-        }
-
-        public boolean waitForAnswer() throws InterruptedException {
-            return mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-
-        @Override
-        public void onRedirectReceived(
-                UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
-            request.followRedirect();
-        }
-
-        @Override
-        public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
-            request.read(ByteBuffer.allocateDirect(32 * 1024));
-        }
-
-        @Override
-        public void onReadCompleted(
-                UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
-            byteBuffer.clear();
-            request.read(byteBuffer);
-        }
-
-        @Override
-        public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
-            assertEquals(
-                    "Unexpected http status code from " + mUrl + ".",
-                    200,
-                    info.getHttpStatusCode());
-            assertGreaterThan(
-                    "Received byte from " + mUrl + " is 0.", (int) info.getReceivedByteCount(), 0);
-            mLatch.countDown();
-        }
-
-        @Override
-        public void onFailed(UrlRequest request, UrlResponseInfo info, CronetException error) {
-            fail(mUrl + error.getMessage());
-        }
-    }
-
-    @Test
-    public void testUrlRequestGet_CompletesSuccessfully() throws Exception {
-        assertHasTestableNetworks();
-        String url = HTTPS_PREFIX + getRandomDomain();
-        TestUrlRequestCallback callback = new TestUrlRequestCallback(url);
-        UrlRequest.Builder builder = mCronetEngine.newUrlRequestBuilder(url, callback, mExecutor);
-        builder.build().start();
-        assertTrue(url + " but not complete after " + TIMEOUT_MS + "ms.", callback.waitForAnswer());
-    }
-}
diff --git a/Cronet/tests/cts/src/org/chromium/net/test/CronetUrlRequestTest.java b/Cronet/tests/cts/src/org/chromium/net/test/CronetUrlRequestTest.java
new file mode 100644
index 0000000..7dd9a9a
--- /dev/null
+++ b/Cronet/tests/cts/src/org/chromium/net/test/CronetUrlRequestTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2019 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 org.chromium.net.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+
+import androidx.annotation.NonNull;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.chromium.net.CronetEngine;
+import org.chromium.net.UrlRequest;
+import org.chromium.net.UrlResponseInfo;
+import org.chromium.net.test.util.TestUrlRequestCallback;
+import org.chromium.net.test.util.TestUrlRequestCallback.ResponseStep;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Random;
+
+@RunWith(AndroidJUnit4.class)
+public class CronetUrlRequestTest {
+    private static final String TAG = CronetUrlRequestTest.class.getSimpleName();
+    private static final String HTTPS_PREFIX = "https://";
+
+    private final String[] mTestDomains = {"www.google.com", "www.android.com"};
+    @NonNull private CronetEngine mCronetEngine;
+    @NonNull private ConnectivityManager mCm;
+
+    @Before
+    public void setUp() throws Exception {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        CronetEngine.Builder builder = new CronetEngine.Builder(context);
+        builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024)
+                .enableHttp2(true)
+                // .enableBrotli(true)
+                .enableQuic(true);
+        mCronetEngine = builder.build();
+    }
+
+    private static void assertGreaterThan(String msg, int first, int second) {
+        assertTrue(msg + " Excepted " + first + " to be greater than " + second, first > second);
+    }
+
+    private void assertHasTestableNetworks() {
+        assertNotNull("This test requires a working Internet connection", mCm.getActiveNetwork());
+    }
+
+    private String getRandomDomain() {
+        int index = (new Random()).nextInt(mTestDomains.length);
+        return mTestDomains[index];
+    }
+
+    @Test
+    public void testUrlRequestGet_CompletesSuccessfully() throws Exception {
+        assertHasTestableNetworks();
+        String url = HTTPS_PREFIX + getRandomDomain();
+        TestUrlRequestCallback callback = new TestUrlRequestCallback();
+        UrlRequest.Builder builder = mCronetEngine.newUrlRequestBuilder(url, callback,
+                callback.getExecutor());
+        builder.build().start();
+
+        callback.expectCallback(ResponseStep.ON_SUCCEEDED);
+
+        UrlResponseInfo info = callback.mResponseInfo;
+        assertEquals("Unexpected http status code from " + url + ".", 200,
+                info.getHttpStatusCode());
+        assertGreaterThan(
+                "Received byte from " + url + " is 0.", (int) info.getReceivedByteCount(), 0);
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index fbb342d..846abcb 100644
--- a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -295,8 +295,7 @@
                 NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
         if (h1 == null) return false;
 
-        sendIpv4NfGenMsg(h1, (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
-                           (short) (NLM_F_REQUEST | NLM_F_DUMP));
+        requestSocketDump(h1);
 
         final NativeHandle h2 = mDeps.createConntrackSocket(
                 NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
@@ -325,7 +324,7 @@
     }
 
     @VisibleForTesting
-    public void sendIpv4NfGenMsg(@NonNull NativeHandle handle, short type, short flags) {
+    void sendIpv4NfGenMsg(@NonNull NativeHandle handle, short type, short flags) {
         final int length = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE;
         final byte[] msg = new byte[length];
         final ByteBuffer byteBuffer = ByteBuffer.wrap(msg);
@@ -350,6 +349,12 @@
         }
     }
 
+    @VisibleForTesting
+    void requestSocketDump(NativeHandle handle) {
+        sendIpv4NfGenMsg(handle, (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
+                (short) (NLM_F_REQUEST | NLM_F_DUMP));
+    }
+
     private void closeFdInNativeHandle(final NativeHandle h) {
         try {
             h.close();
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index da69a8d..97a255f 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -16,27 +16,16 @@
 
 package android.net;
 
-import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
 import static android.Manifest.permission.DUMP;
-import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
-import static android.Manifest.permission.NETWORK_SETTINGS;
-import static android.Manifest.permission.TETHER_PRIVILEGED;
-import static android.content.pm.PackageManager.FEATURE_WIFI;
 import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
 import static android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL;
 import static android.net.TetheringManager.TETHERING_ETHERNET;
 import static android.net.TetheringTester.TestDnsPacket;
 import static android.net.TetheringTester.isExpectedIcmpPacket;
-import static android.net.TetheringTester.isExpectedTcpPacket;
 import static android.net.TetheringTester.isExpectedUdpDnsPacket;
-import static android.net.TetheringTester.isExpectedUdpPacket;
 import static android.system.OsConstants.ICMP_ECHO;
 import static android.system.OsConstants.ICMP_ECHOREPLY;
 import static android.system.OsConstants.IPPROTO_ICMP;
-import static android.system.OsConstants.IPPROTO_IP;
-import static android.system.OsConstants.IPPROTO_IPV6;
-import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
 
 import static com.android.net.module.util.ConnectivityUtils.isIPv6ULA;
@@ -44,39 +33,27 @@
 import static com.android.net.module.util.IpUtils.icmpChecksum;
 import static com.android.net.module.util.IpUtils.ipChecksum;
 import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV4;
-import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV6;
 import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ECHO_REPLY_TYPE;
 import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
-import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
 import static com.android.net.module.util.NetworkStackConstants.ICMP_CHECKSUM_OFFSET;
 import static com.android.net.module.util.NetworkStackConstants.IPV4_CHECKSUM_OFFSET;
 import static com.android.net.module.util.NetworkStackConstants.IPV4_HEADER_MIN_LEN;
 import static com.android.net.module.util.NetworkStackConstants.IPV4_LENGTH_OFFSET;
-import static com.android.net.module.util.NetworkStackConstants.TCPHDR_ACK;
-import static com.android.net.module.util.NetworkStackConstants.TCPHDR_SYN;
 import static com.android.testutils.DeviceInfoUtils.KVersion;
-import static com.android.testutils.TestNetworkTrackerKt.initTestNetwork;
 import static com.android.testutils.TestPermissionUtil.runAsShell;
 
 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.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
 import android.content.Context;
-import android.net.EthernetManager.TetheredInterfaceCallback;
-import android.net.EthernetManager.TetheredInterfaceRequest;
-import android.net.TetheringManager.StartTetheringCallback;
-import android.net.TetheringManager.TetheringEventCallback;
 import android.net.TetheringManager.TetheringRequest;
 import android.net.TetheringTester.TetheredDevice;
 import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.VintfRuntimeInfo;
@@ -88,10 +65,8 @@
 import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.modules.utils.build.SdkLevel;
 import com.android.net.module.util.BpfDump;
 import com.android.net.module.util.Ipv6Utils;
-import com.android.net.module.util.PacketBuilder;
 import com.android.net.module.util.Struct;
 import com.android.net.module.util.bpf.Tether4Key;
 import com.android.net.module.util.bpf.Tether4Value;
@@ -106,12 +81,8 @@
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 import com.android.testutils.DeviceInfoUtils;
 import com.android.testutils.DumpTestUtils;
-import com.android.testutils.HandlerUtils;
 import com.android.testutils.TapPacketReader;
-import com.android.testutils.TestNetworkTracker;
 
-import org.junit.After;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -122,18 +93,14 @@
 import java.net.InetAddress;
 import java.net.InterfaceAddress;
 import java.net.NetworkInterface;
-import java.net.SocketException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Random;
-import java.util.Set;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
@@ -231,137 +198,6 @@
             (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04  /* Address: 1.2.3.4 */
     };
 
-    private TetheredInterfaceRequester mTetheredInterfaceRequester;
-    private MyTetheringEventCallback mTetheringEventCallback;
-
-    @Before
-    public void setUp() throws Exception {
-        mHandlerThread = new HandlerThread(getClass().getSimpleName());
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-
-        mRunTests = runAsShell(NETWORK_SETTINGS, TETHER_PRIVILEGED, () ->
-                mTm.isTetheringSupported());
-        assumeTrue(mRunTests);
-
-        mTetheredInterfaceRequester = new TetheredInterfaceRequester(mHandler, mEm);
-    }
-
-    private void maybeStopTapPacketReader(final TapPacketReader tapPacketReader)
-            throws Exception {
-        if (tapPacketReader != null) {
-            TapPacketReader reader = tapPacketReader;
-            mHandler.post(() -> reader.stop());
-        }
-    }
-
-    private void maybeCloseTestInterface(final TestNetworkInterface testInterface)
-            throws Exception {
-        if (testInterface != null) {
-            testInterface.getFileDescriptor().close();
-            Log.d(TAG, "Deleted test interface " + testInterface.getInterfaceName());
-        }
-    }
-
-    private void maybeUnregisterTetheringEventCallback(final MyTetheringEventCallback callback)
-            throws Exception {
-        if (callback != null) {
-            callback.awaitInterfaceUntethered();
-            callback.unregister();
-        }
-    }
-
-    private void cleanUp() throws Exception {
-        setPreferTestNetworks(false);
-
-        if (mUpstreamTracker != null) {
-            runAsShell(MANAGE_TEST_NETWORKS, () -> {
-                mUpstreamTracker.teardown();
-                mUpstreamTracker = null;
-            });
-        }
-        if (mUpstreamReader != null) {
-            TapPacketReader reader = mUpstreamReader;
-            mHandler.post(() -> reader.stop());
-            mUpstreamReader = null;
-        }
-
-        maybeStopTapPacketReader(mDownstreamReader);
-        mDownstreamReader = null;
-        // To avoid flaky which caused by the next test started but the previous interface is not
-        // untracked from EthernetTracker yet. Just delete the test interface without explicitly
-        // calling TetheringManager#stopTethering could let EthernetTracker untrack the test
-        // interface from server mode before tethering stopped. Thus, awaitInterfaceUntethered
-        // could not only make sure tethering is stopped but also guarantee the test interface is
-        // untracked from EthernetTracker.
-        maybeCloseTestInterface(mDownstreamIface);
-        mDownstreamIface = null;
-        maybeUnregisterTetheringEventCallback(mTetheringEventCallback);
-        mTetheringEventCallback = null;
-
-        runAsShell(NETWORK_SETTINGS, () -> mTetheredInterfaceRequester.release());
-        setIncludeTestInterfaces(false);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        try {
-            if (mRunTests) cleanUp();
-        } finally {
-            mHandlerThread.quitSafely();
-            mUiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    private boolean isInterfaceForTetheringAvailable() throws Exception {
-        // Before T, all ethernet interfaces could be used for server mode. Instead of
-        // waiting timeout, just checking whether the system currently has any
-        // ethernet interface is more reliable.
-        if (!SdkLevel.isAtLeastT()) {
-            return runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS, () -> mEm.isAvailable());
-        }
-
-        // If previous test case doesn't release tethering interface successfully, the other tests
-        // after that test may be skipped as unexcepted.
-        // TODO: figure out a better way to check default tethering interface existenion.
-        final TetheredInterfaceRequester requester = new TetheredInterfaceRequester(mHandler, mEm);
-        try {
-            // Use short timeout (200ms) for requesting an existing interface, if any, because
-            // it should reurn faster than requesting a new tethering interface. Using default
-            // timeout (5000ms, TIMEOUT_MS) may make that total testing time is over 1 minute
-            // test module timeout on internal testing.
-            // TODO: if this becomes flaky, consider using default timeout (5000ms) and moving
-            // this check into #setUpOnce.
-            return requester.getInterface(AVAILABLE_TETHER_IFACE_REQUEST_TIMEOUT_MS) != null;
-        } catch (TimeoutException e) {
-            return false;
-        } finally {
-            runAsShell(NETWORK_SETTINGS, () -> {
-                requester.release();
-            });
-        }
-    }
-
-    private void setIncludeTestInterfaces(boolean include) {
-        runAsShell(NETWORK_SETTINGS, () -> {
-            mEm.setIncludeTestInterfaces(include);
-        });
-    }
-
-    private void setPreferTestNetworks(boolean prefer) {
-        runAsShell(NETWORK_SETTINGS, () -> {
-            mTm.setPreferTestNetworks(prefer);
-        });
-    }
-
-    private String getTetheredInterface() throws Exception {
-        return mTetheredInterfaceRequester.getInterface();
-    }
-
-    private CompletableFuture<String> requestTetheredInterface() throws Exception {
-        return mTetheredInterfaceRequester.requestInterface();
-    }
-
     @Test
     public void testVirtualEthernetAlreadyExists() throws Exception {
         // This test requires manipulating packets. Skip if there is a physical Ethernet connected.
@@ -486,22 +322,6 @@
         }
     }
 
-    private static void waitForRouterAdvertisement(TapPacketReader reader, String iface,
-            long timeoutMs) {
-        final long deadline = SystemClock.uptimeMillis() + timeoutMs;
-        do {
-            byte[] pkt = reader.popPacket(timeoutMs);
-            if (isExpectedIcmpPacket(pkt, true /* hasEth */, false /* isIpv4 */,
-                    ICMPV6_ROUTER_ADVERTISEMENT)) {
-                return;
-            }
-
-            timeoutMs = deadline - SystemClock.uptimeMillis();
-        } while (timeoutMs > 0);
-        fail("Did not receive router advertisement on " + iface + " after "
-                +  timeoutMs + "ms idle");
-    }
-
     private static void expectLocalOnlyAddresses(String iface) throws Exception {
         final List<InterfaceAddress> interfaceAddresses =
                 NetworkInterface.getByName(iface).getInterfaceAddresses();
@@ -589,260 +409,6 @@
         // client, which is not possible in this test.
     }
 
-    private static final class MyTetheringEventCallback implements TetheringEventCallback {
-        private final TetheringManager mTm;
-        private final CountDownLatch mTetheringStartedLatch = new CountDownLatch(1);
-        private final CountDownLatch mTetheringStoppedLatch = new CountDownLatch(1);
-        private final CountDownLatch mLocalOnlyStartedLatch = new CountDownLatch(1);
-        private final CountDownLatch mLocalOnlyStoppedLatch = new CountDownLatch(1);
-        private final CountDownLatch mClientConnectedLatch = new CountDownLatch(1);
-        private final CountDownLatch mUpstreamLatch = new CountDownLatch(1);
-        private final CountDownLatch mCallbackRegisteredLatch = new CountDownLatch(1);
-        private final TetheringInterface mIface;
-        private final Network mExpectedUpstream;
-
-        private boolean mAcceptAnyUpstream = false;
-
-        private volatile boolean mInterfaceWasTethered = false;
-        private volatile boolean mInterfaceWasLocalOnly = false;
-        private volatile boolean mUnregistered = false;
-        private volatile Collection<TetheredClient> mClients = null;
-        private volatile Network mUpstream = null;
-
-        MyTetheringEventCallback(TetheringManager tm, String iface) {
-            this(tm, iface, null);
-            mAcceptAnyUpstream = true;
-        }
-
-        MyTetheringEventCallback(TetheringManager tm, String iface, Network expectedUpstream) {
-            mTm = tm;
-            mIface = new TetheringInterface(TETHERING_ETHERNET, iface);
-            mExpectedUpstream = expectedUpstream;
-        }
-
-        public void unregister() {
-            mTm.unregisterTetheringEventCallback(this);
-            mUnregistered = true;
-        }
-        @Override
-        public void onTetheredInterfacesChanged(List<String> interfaces) {
-            fail("Should only call callback that takes a Set<TetheringInterface>");
-        }
-
-        @Override
-        public void onTetheredInterfacesChanged(Set<TetheringInterface> interfaces) {
-            // Ignore stale callbacks registered by previous test cases.
-            if (mUnregistered) return;
-
-            if (!mInterfaceWasTethered && interfaces.contains(mIface)) {
-                // This interface is being tethered for the first time.
-                Log.d(TAG, "Tethering started: " + interfaces);
-                mInterfaceWasTethered = true;
-                mTetheringStartedLatch.countDown();
-            } else if (mInterfaceWasTethered && !interfaces.contains(mIface)) {
-                Log.d(TAG, "Tethering stopped: " + interfaces);
-                mTetheringStoppedLatch.countDown();
-            }
-        }
-
-        @Override
-        public void onLocalOnlyInterfacesChanged(List<String> interfaces) {
-            fail("Should only call callback that takes a Set<TetheringInterface>");
-        }
-
-        @Override
-        public void onLocalOnlyInterfacesChanged(Set<TetheringInterface> interfaces) {
-            // Ignore stale callbacks registered by previous test cases.
-            if (mUnregistered) return;
-
-            if (!mInterfaceWasLocalOnly && interfaces.contains(mIface)) {
-                // This interface is being put into local-only mode for the first time.
-                Log.d(TAG, "Local-only started: " + interfaces);
-                mInterfaceWasLocalOnly = true;
-                mLocalOnlyStartedLatch.countDown();
-            } else if (mInterfaceWasLocalOnly && !interfaces.contains(mIface)) {
-                Log.d(TAG, "Local-only stopped: " + interfaces);
-                mLocalOnlyStoppedLatch.countDown();
-            }
-        }
-
-        public void awaitInterfaceTethered() throws Exception {
-            assertTrue("Ethernet not tethered after " + TIMEOUT_MS + "ms",
-                    mTetheringStartedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-
-        public void awaitInterfaceLocalOnly() throws Exception {
-            assertTrue("Ethernet not local-only after " + TIMEOUT_MS + "ms",
-                    mLocalOnlyStartedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-
-        // Used to check if the callback has registered. When the callback is registered,
-        // onSupportedTetheringTypes is celled in onCallbackStarted(). After
-        // onSupportedTetheringTypes called, drop the permission for registering callback.
-        // See MyTetheringEventCallback#register, TetheringManager#onCallbackStarted.
-        @Override
-        public void onSupportedTetheringTypes(Set<Integer> supportedTypes) {
-            // Used to check callback registered.
-            mCallbackRegisteredLatch.countDown();
-        }
-
-        public void awaitCallbackRegistered() throws Exception {
-            if (!mCallbackRegisteredLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
-                fail("Did not receive callback registered signal after " + TIMEOUT_MS + "ms");
-            }
-        }
-
-        public void awaitInterfaceUntethered() throws Exception {
-            // Don't block teardown if the interface was never tethered.
-            // This is racy because the interface might become tethered right after this check, but
-            // that can only happen in tearDown if startTethering timed out, which likely means
-            // the test has already failed.
-            if (!mInterfaceWasTethered && !mInterfaceWasLocalOnly) return;
-
-            if (mInterfaceWasTethered) {
-                assertTrue(mIface + " not untethered after " + TIMEOUT_MS + "ms",
-                        mTetheringStoppedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            } else if (mInterfaceWasLocalOnly) {
-                assertTrue(mIface + " not untethered after " + TIMEOUT_MS + "ms",
-                        mLocalOnlyStoppedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            } else {
-                fail(mIface + " cannot be both tethered and local-only. Update this test class.");
-            }
-        }
-
-        @Override
-        public void onError(String ifName, int error) {
-            // Ignore stale callbacks registered by previous test cases.
-            if (mUnregistered) return;
-
-            fail("TetheringEventCallback got error:" + error + " on iface " + ifName);
-        }
-
-        @Override
-        public void onClientsChanged(Collection<TetheredClient> clients) {
-            // Ignore stale callbacks registered by previous test cases.
-            if (mUnregistered) return;
-
-            Log.d(TAG, "Got clients changed: " + clients);
-            mClients = clients;
-            if (clients.size() > 0) {
-                mClientConnectedLatch.countDown();
-            }
-        }
-
-        public Collection<TetheredClient> awaitClientConnected() throws Exception {
-            assertTrue("Did not receive client connected callback after " + TIMEOUT_MS + "ms",
-                    mClientConnectedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            return mClients;
-        }
-
-        @Override
-        public void onUpstreamChanged(Network network) {
-            // Ignore stale callbacks registered by previous test cases.
-            if (mUnregistered) return;
-
-            Log.d(TAG, "Got upstream changed: " + network);
-            mUpstream = network;
-            if (mAcceptAnyUpstream || Objects.equals(mUpstream, mExpectedUpstream)) {
-                mUpstreamLatch.countDown();
-            }
-        }
-
-        public Network awaitUpstreamChanged(boolean throwTimeoutException) throws Exception {
-            if (!mUpstreamLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
-                final String errorMessage = "Did not receive upstream "
-                            + (mAcceptAnyUpstream ? "any" : mExpectedUpstream)
-                            + " callback after " + TIMEOUT_MS + "ms";
-
-                if (throwTimeoutException) {
-                    throw new TimeoutException(errorMessage);
-                } else {
-                    fail(errorMessage);
-                }
-            }
-            return mUpstream;
-        }
-    }
-
-    private MyTetheringEventCallback enableEthernetTethering(String iface,
-            TetheringRequest request, Network expectedUpstream) throws Exception {
-        // Enable ethernet tethering with null expectedUpstream means the test accept any upstream
-        // after etherent tethering started.
-        final MyTetheringEventCallback callback;
-        if (expectedUpstream != null) {
-            callback = new MyTetheringEventCallback(mTm, iface, expectedUpstream);
-        } else {
-            callback = new MyTetheringEventCallback(mTm, iface);
-        }
-        runAsShell(NETWORK_SETTINGS, () -> {
-            mTm.registerTetheringEventCallback(mHandler::post, callback);
-            // Need to hold the shell permission until callback is registered. This helps to avoid
-            // the test become flaky.
-            callback.awaitCallbackRegistered();
-        });
-        final CountDownLatch tetheringStartedLatch = new CountDownLatch(1);
-        StartTetheringCallback startTetheringCallback = new StartTetheringCallback() {
-            @Override
-            public void onTetheringStarted() {
-                Log.d(TAG, "Ethernet tethering started");
-                tetheringStartedLatch.countDown();
-            }
-
-            @Override
-            public void onTetheringFailed(int resultCode) {
-                fail("Unexpectedly got onTetheringFailed");
-            }
-        };
-        Log.d(TAG, "Starting Ethernet tethering");
-        runAsShell(TETHER_PRIVILEGED, () -> {
-            mTm.startTethering(request, mHandler::post /* executor */, startTetheringCallback);
-            // Binder call is an async call. Need to hold the shell permission until tethering
-            // started. This helps to avoid the test become flaky.
-            if (!tetheringStartedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
-                fail("Did not receive tethering started callback after " + TIMEOUT_MS + "ms");
-            }
-        });
-
-        final int connectivityType = request.getConnectivityScope();
-        switch (connectivityType) {
-            case CONNECTIVITY_SCOPE_GLOBAL:
-                callback.awaitInterfaceTethered();
-                break;
-            case CONNECTIVITY_SCOPE_LOCAL:
-                callback.awaitInterfaceLocalOnly();
-                break;
-            default:
-                fail("Unexpected connectivity type requested: " + connectivityType);
-        }
-
-        return callback;
-    }
-
-    private MyTetheringEventCallback enableEthernetTethering(String iface, Network expectedUpstream)
-            throws Exception {
-        return enableEthernetTethering(iface,
-                new TetheringRequest.Builder(TETHERING_ETHERNET)
-                .setShouldShowEntitlementUi(false).build(), expectedUpstream);
-    }
-
-    private int getMTU(TestNetworkInterface iface) throws SocketException {
-        NetworkInterface nif = NetworkInterface.getByName(iface.getInterfaceName());
-        assertNotNull("Can't get NetworkInterface object for " + iface.getInterfaceName(), nif);
-        return nif.getMTU();
-    }
-
-    private TapPacketReader makePacketReader(final TestNetworkInterface iface) throws Exception {
-        FileDescriptor fd = iface.getFileDescriptor().getFileDescriptor();
-        return makePacketReader(fd, getMTU(iface));
-    }
-
-    private TapPacketReader makePacketReader(FileDescriptor fd, int mtu) {
-        final TapPacketReader reader = new TapPacketReader(mHandler, fd, mtu);
-        mHandler.post(() -> reader.start());
-        HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS);
-        return reader;
-    }
-
     private void checkTetheredClientCallbacks(final TapPacketReader packetReader,
             final MyTetheringEventCallback tetheringEventCallback) throws Exception {
         // Create a fake client.
@@ -876,54 +442,6 @@
         assertTrue(msg, Math.abs(dhcpResults.leaseDuration - actualLeaseDuration) < 10);
     }
 
-    private static final class TetheredInterfaceRequester implements TetheredInterfaceCallback {
-        private final Handler mHandler;
-        private final EthernetManager mEm;
-
-        private TetheredInterfaceRequest mRequest;
-        private final CompletableFuture<String> mFuture = new CompletableFuture<>();
-
-        TetheredInterfaceRequester(Handler handler, EthernetManager em) {
-            mHandler = handler;
-            mEm = em;
-        }
-
-        @Override
-        public void onAvailable(String iface) {
-            Log.d(TAG, "Ethernet interface available: " + iface);
-            mFuture.complete(iface);
-        }
-
-        @Override
-        public void onUnavailable() {
-            mFuture.completeExceptionally(new IllegalStateException("onUnavailable received"));
-        }
-
-        public CompletableFuture<String> requestInterface() {
-            assertNull("BUG: more than one tethered interface request", mRequest);
-            Log.d(TAG, "Requesting tethered interface");
-            mRequest = runAsShell(NETWORK_SETTINGS, () ->
-                    mEm.requestTetheredInterface(mHandler::post, this));
-            return mFuture;
-        }
-
-        public String getInterface(int timeout) throws Exception {
-            return requestInterface().get(timeout, TimeUnit.MILLISECONDS);
-        }
-
-        public String getInterface() throws Exception {
-            return getInterface(TIMEOUT_MS);
-        }
-
-        public void release() {
-            if (mRequest != null) {
-                mFuture.obtrudeException(new IllegalStateException("Request already released"));
-                mRequest.release();
-                mRequest = null;
-            }
-        }
-    }
-
     public void assertLinkAddressMatches(LinkAddress l1, LinkAddress l2) {
         // Check all fields except the deprecation and expiry times.
         String msg = String.format("LinkAddresses do not match. expected: %s actual: %s", l1, l2);
@@ -962,27 +480,6 @@
                 + nif.getInterfaceAddresses());
     }
 
-    private TestNetworkInterface createTestInterface() throws Exception {
-        TestNetworkManager tnm = runAsShell(MANAGE_TEST_NETWORKS, () ->
-                mContext.getSystemService(TestNetworkManager.class));
-        TestNetworkInterface iface = runAsShell(MANAGE_TEST_NETWORKS, () ->
-                tnm.createTapInterface());
-        Log.d(TAG, "Created test interface " + iface.getInterfaceName());
-        return iface;
-    }
-
-    private TestNetworkTracker createTestUpstream(final List<LinkAddress> addresses,
-            final List<InetAddress> dnses) throws Exception {
-        setPreferTestNetworks(true);
-
-        final LinkProperties lp = new LinkProperties();
-        lp.setLinkAddresses(addresses);
-        lp.setDnsServers(dnses);
-        lp.setNat64Prefix(TEST_NAT64PREFIX);
-
-        return runAsShell(MANAGE_TEST_NETWORKS, () -> initTestNetwork(mContext, lp, TIMEOUT_MS));
-    }
-
     @Test
     public void testIcmpv6Echo() throws Exception {
         runPing6Test(initTetheringTester(toList(TEST_IP4_ADDR, TEST_IP6_ADDR),
@@ -1010,124 +507,6 @@
         });
     }
 
-    // Test network topology:
-    //
-    //         public network (rawip)                 private network
-    //                   |                 UE                |
-    // +------------+    V    +------------+------------+    V    +------------+
-    // |   Sever    +---------+  Upstream  | Downstream +---------+   Client   |
-    // +------------+         +------------+------------+         +------------+
-    // remote ip              public ip                           private ip
-    // 8.8.8.8:443            <Upstream ip>:9876                  <TetheredDevice ip>:9876
-    //
-
-    private short getEthType(@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp) {
-        return isAddressIpv4(srcIp, dstIp) ? (short) ETHER_TYPE_IPV4 : (short) ETHER_TYPE_IPV6;
-    }
-
-    private int getIpProto(@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp) {
-        return isAddressIpv4(srcIp, dstIp) ? IPPROTO_IP : IPPROTO_IPV6;
-    }
-
-    @NonNull
-    private ByteBuffer buildUdpPacket(
-            @Nullable final MacAddress srcMac, @Nullable final MacAddress dstMac,
-            @NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp,
-            short srcPort, short dstPort, @Nullable final ByteBuffer payload)
-            throws Exception {
-        final int ipProto = getIpProto(srcIp, dstIp);
-        final boolean hasEther = (srcMac != null && dstMac != null);
-        final int payloadLen = (payload == null) ? 0 : payload.limit();
-        final ByteBuffer buffer = PacketBuilder.allocate(hasEther, ipProto, IPPROTO_UDP,
-                payloadLen);
-        final PacketBuilder packetBuilder = new PacketBuilder(buffer);
-
-        // [1] Ethernet header
-        if (hasEther) {
-            packetBuilder.writeL2Header(srcMac, dstMac, getEthType(srcIp, dstIp));
-        }
-
-        // [2] IP header
-        if (ipProto == IPPROTO_IP) {
-            packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET,
-                    TIME_TO_LIVE, (byte) IPPROTO_UDP, (Inet4Address) srcIp, (Inet4Address) dstIp);
-        } else {
-            packetBuilder.writeIpv6Header(VERSION_TRAFFICCLASS_FLOWLABEL, (byte) IPPROTO_UDP,
-                    HOP_LIMIT, (Inet6Address) srcIp, (Inet6Address) dstIp);
-        }
-
-        // [3] UDP header
-        packetBuilder.writeUdpHeader(srcPort, dstPort);
-
-        // [4] Payload
-        if (payload != null) {
-            buffer.put(payload);
-            // in case data might be reused by caller, restore the position and
-            // limit of bytebuffer.
-            payload.clear();
-        }
-
-        return packetBuilder.finalizePacket();
-    }
-
-    @NonNull
-    private ByteBuffer buildUdpPacket(@NonNull final InetAddress srcIp,
-            @NonNull final InetAddress dstIp, short srcPort, short dstPort,
-            @Nullable final ByteBuffer payload) throws Exception {
-        return buildUdpPacket(null /* srcMac */, null /* dstMac */, srcIp, dstIp, srcPort,
-                dstPort, payload);
-    }
-
-    private boolean isAddressIpv4(@NonNull final  InetAddress srcIp,
-            @NonNull final InetAddress dstIp) {
-        if (srcIp instanceof Inet4Address && dstIp instanceof Inet4Address) return true;
-        if (srcIp instanceof Inet6Address && dstIp instanceof Inet6Address) return false;
-
-        fail("Unsupported conditions: srcIp " + srcIp + ", dstIp " + dstIp);
-        return false;  // unreachable
-    }
-
-    private void sendDownloadPacketUdp(@NonNull final InetAddress srcIp,
-            @NonNull final InetAddress dstIp, @NonNull final TetheringTester tester,
-            boolean is6To4) throws Exception {
-        if (is6To4) {
-            assertFalse("CLAT download test must sends IPv6 packet", isAddressIpv4(srcIp, dstIp));
-        }
-
-        // Expected received UDP packet IP protocol. While testing CLAT (is6To4 = true), the packet
-        // on downstream must be IPv4. Otherwise, the IP protocol of test packet is the same on
-        // both downstream and upstream.
-        final boolean isIpv4 = is6To4 ? true : isAddressIpv4(srcIp, dstIp);
-
-        final ByteBuffer testPacket = buildUdpPacket(srcIp, dstIp, REMOTE_PORT /* srcPort */,
-                LOCAL_PORT /* dstPort */, RX_PAYLOAD);
-        tester.verifyDownload(testPacket, p -> {
-            Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
-            return isExpectedUdpPacket(p, true /* hasEther */, isIpv4, RX_PAYLOAD);
-        });
-    }
-
-    private void sendUploadPacketUdp(@NonNull final MacAddress srcMac,
-            @NonNull final MacAddress dstMac, @NonNull final InetAddress srcIp,
-            @NonNull final InetAddress dstIp, @NonNull final TetheringTester tester,
-            boolean is4To6) throws Exception {
-        if (is4To6) {
-            assertTrue("CLAT upload test must sends IPv4 packet", isAddressIpv4(srcIp, dstIp));
-        }
-
-        // Expected received UDP packet IP protocol. While testing CLAT (is4To6 = true), the packet
-        // on upstream must be IPv6. Otherwise, the IP protocol of test packet is the same on
-        // both downstream and upstream.
-        final boolean isIpv4 = is4To6 ? false : isAddressIpv4(srcIp, dstIp);
-
-        final ByteBuffer testPacket = buildUdpPacket(srcMac, dstMac, srcIp, dstIp,
-                LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */, TX_PAYLOAD);
-        tester.verifyUpload(testPacket, p -> {
-            Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
-            return isExpectedUdpPacket(p, false /* hasEther */, isIpv4, TX_PAYLOAD);
-        });
-    }
-
     @Test
     public void testTetherUdpV6() throws Exception {
         final TetheringTester tester = initTetheringTester(toList(TEST_IP6_ADDR),
@@ -1140,37 +519,16 @@
         // TODO: test BPF offload maps {rule, stats}.
     }
 
-    // TODO: remove ipv4 verification (is4To6 = false) once upstream connected notification race is
-    // fixed. See #runUdp4Test.
+    // Test network topology:
     //
-    // This function sends a probe packet to downstream interface and exam the result from upstream
-    // interface to make sure ipv4 tethering is ready. Return the entire packet which received from
-    // upstream interface.
-    @NonNull
-    private byte[] probeV4TetheringConnectivity(TetheringTester tester, TetheredDevice tethered,
-            boolean is4To6) throws Exception {
-        final ByteBuffer probePacket = buildUdpPacket(tethered.macAddr,
-                tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
-                REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */,
-                TEST_REACHABILITY_PAYLOAD);
-
-        // Send a UDP packet from client and check the packet can be found on upstream interface.
-        for (int i = 0; i < TETHER_REACHABILITY_ATTEMPTS; i++) {
-            byte[] expectedPacket = tester.testUpload(probePacket, p -> {
-                Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
-                // If is4To6 is true, the ipv4 probe packet would be translated to ipv6 by Clat and
-                // would see this translated ipv6 packet in upstream interface.
-                return isExpectedUdpPacket(p, false /* hasEther */, !is4To6 /* isIpv4 */,
-                        TEST_REACHABILITY_PAYLOAD);
-            });
-            if (expectedPacket != null) return expectedPacket;
-        }
-
-        fail("Can't verify " + (is4To6 ? "ipv4 to ipv6" : "ipv4") + " tethering connectivity after "
-                + TETHER_REACHABILITY_ATTEMPTS + " attempts");
-        return null;
-    }
-
+    //         public network (rawip)                 private network
+    //                   |                 UE                |
+    // +------------+    V    +------------+------------+    V    +------------+
+    // |   Sever    +---------+  Upstream  | Downstream +---------+   Client   |
+    // +------------+         +------------+------------+         +------------+
+    // remote ip              public ip                           private ip
+    // 8.8.8.8:443            <Upstream ip>:9876                  <TetheredDevice ip>:9876
+    //
     private void runUdp4Test(boolean verifyBpf) throws Exception {
         final TetheringTester tester = initTetheringTester(toList(TEST_IP4_ADDR),
                 toList(TEST_IP4_DNS));
@@ -1268,96 +626,6 @@
         }
     }
 
-    // TODO: remove triggering upstream reselection once test network can replace selected upstream
-    // network in Tethering module.
-    private void maybeRetryTestedUpstreamChanged(final Network expectedUpstream,
-            final TimeoutException fallbackException) throws Exception {
-        // Fall back original exception because no way to reselect if there is no WIFI feature.
-        assertTrue(fallbackException.toString(), mPackageManager.hasSystemFeature(FEATURE_WIFI));
-
-        // Try to toggle wifi network, if any, to reselect upstream network via default network
-        // switching. Because test network has higher priority than internet network, this can
-        // help selecting test network to be upstream network for testing. This tries to avoid
-        // the flaky upstream selection under multinetwork environment. Internet and test network
-        // upstream changed event order is not guaranteed. Once tethering selects non-test
-        // upstream {wifi, ..}, test network won't be selected anymore. If too many test cases
-        // trigger the reselection, the total test time may over test suite 1 minmute timeout.
-        // Probably need to disable/restore all internet networks in a common place of test
-        // process. Currently, EthernetTetheringTest is part of CTS test which needs wifi network
-        // connection if device has wifi feature. CtsNetUtils#toggleWifi() checks wifi connection
-        // during the toggling process.
-        // See Tethering#chooseUpstreamType, CtsNetUtils#toggleWifi.
-        // TODO: toggle cellular network if the device has no WIFI feature.
-        Log.d(TAG, "Toggle WIFI to retry upstream selection");
-        mCtsNetUtils.toggleWifi();
-
-        // Wait for expected upstream.
-        final CompletableFuture<Network> future = new CompletableFuture<>();
-        final TetheringEventCallback callback = new TetheringEventCallback() {
-            @Override
-            public void onUpstreamChanged(Network network) {
-                Log.d(TAG, "Got upstream changed: " + network);
-                if (Objects.equals(expectedUpstream, network)) {
-                    future.complete(network);
-                }
-            }
-        };
-        try {
-            mTm.registerTetheringEventCallback(mHandler::post, callback);
-            assertEquals("onUpstreamChanged for unexpected network", expectedUpstream,
-                    future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        } catch (TimeoutException e) {
-            throw new AssertionError("Did not receive upstream " + expectedUpstream
-                    + " callback after " + TIMEOUT_MS + "ms");
-        } finally {
-            mTm.unregisterTetheringEventCallback(callback);
-        }
-    }
-
-    private TetheringTester initTetheringTester(List<LinkAddress> upstreamAddresses,
-            List<InetAddress> upstreamDnses) throws Exception {
-        assumeFalse(isInterfaceForTetheringAvailable());
-
-        // MyTetheringEventCallback currently only support await first available upstream. Tethering
-        // may select internet network as upstream if test network is not available and not be
-        // preferred yet. Create test upstream network before enable tethering.
-        mUpstreamTracker = createTestUpstream(upstreamAddresses, upstreamDnses);
-
-        mDownstreamIface = createTestInterface();
-        setIncludeTestInterfaces(true);
-
-        // Make sure EtherentTracker use "mDownstreamIface" as server mode interface.
-        assertEquals("TetheredInterfaceCallback for unexpected interface",
-                mDownstreamIface.getInterfaceName(), mTetheredInterfaceRequester.getInterface());
-
-        mTetheringEventCallback = enableEthernetTethering(mDownstreamIface.getInterfaceName(),
-                mUpstreamTracker.getNetwork());
-
-        try {
-            assertEquals("onUpstreamChanged for test network", mUpstreamTracker.getNetwork(),
-                    mTetheringEventCallback.awaitUpstreamChanged(
-                            true /* throwTimeoutException */));
-        } catch (TimeoutException e) {
-            // Due to race condition inside tethering module, test network may not be selected as
-            // tethering upstream. Force tethering retry upstream if possible. If it is not
-            // possible to retry, fail the test with the original timeout exception.
-            maybeRetryTestedUpstreamChanged(mUpstreamTracker.getNetwork(), e);
-        }
-
-        mDownstreamReader = makePacketReader(mDownstreamIface);
-        mUpstreamReader = makePacketReader(mUpstreamTracker.getTestIface());
-
-        final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
-        // Currently tethering don't have API to tell when ipv6 tethering is available. Thus, make
-        // sure tethering already have ipv6 connectivity before testing.
-        if (cm.getLinkProperties(mUpstreamTracker.getNetwork()).hasGlobalIpv6Address()) {
-            waitForRouterAdvertisement(mDownstreamReader, mDownstreamIface.getInterfaceName(),
-                    WAIT_RA_TIMEOUT_MS);
-        }
-
-        return new TetheringTester(mDownstreamReader, mUpstreamReader);
-    }
-
     private static boolean isUdpOffloadSupportedByKernel(final String kernelVersion) {
         final KVersion current = DeviceInfoUtils.getMajorMinorSubminorVersion(kernelVersion);
         return current.isInRange(new KVersion(4, 14, 222), new KVersion(4, 19, 0))
@@ -1760,146 +1028,6 @@
                 (short) udpHeader.srcPort, (short) dnsQuery.getHeader().getId(), tester);
     }
 
-    @NonNull
-    private ByteBuffer buildTcpPacket(
-            @Nullable final MacAddress srcMac, @Nullable final MacAddress dstMac,
-            @NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp,
-            short srcPort, short dstPort, final short seq, final short ack,
-            final byte tcpFlags, @NonNull final ByteBuffer payload) throws Exception {
-        final int ipProto = getIpProto(srcIp, dstIp);
-        final boolean hasEther = (srcMac != null && dstMac != null);
-        final ByteBuffer buffer = PacketBuilder.allocate(hasEther, ipProto, IPPROTO_TCP,
-                payload.limit());
-        final PacketBuilder packetBuilder = new PacketBuilder(buffer);
-
-        // [1] Ethernet header
-        if (hasEther) {
-            packetBuilder.writeL2Header(srcMac, dstMac, getEthType(srcIp, dstIp));
-        }
-
-        // [2] IP header
-        if (ipProto == IPPROTO_IP) {
-            packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET,
-                    TIME_TO_LIVE, (byte) IPPROTO_TCP, (Inet4Address) srcIp, (Inet4Address) dstIp);
-        } else {
-            packetBuilder.writeIpv6Header(VERSION_TRAFFICCLASS_FLOWLABEL, (byte) IPPROTO_TCP,
-                    HOP_LIMIT, (Inet6Address) srcIp, (Inet6Address) dstIp);
-        }
-
-        // [3] TCP header
-        packetBuilder.writeTcpHeader(srcPort, dstPort, seq, ack, tcpFlags, WINDOW, URGENT_POINTER);
-
-        // [4] Payload
-        buffer.put(payload);
-        // in case data might be reused by caller, restore the position and
-        // limit of bytebuffer.
-        payload.clear();
-
-        return packetBuilder.finalizePacket();
-    }
-
-    private void sendDownloadPacketTcp(@NonNull final InetAddress srcIp,
-            @NonNull final InetAddress dstIp, short seq, short ack, byte tcpFlags,
-            @NonNull final ByteBuffer payload, @NonNull final TetheringTester tester,
-            boolean is6To4) throws Exception {
-        if (is6To4) {
-            assertFalse("CLAT download test must sends IPv6 packet", isAddressIpv4(srcIp, dstIp));
-        }
-
-        // Expected received TCP packet IP protocol. While testing CLAT (is6To4 = true), the packet
-        // on downstream must be IPv4. Otherwise, the IP protocol of test packet is the same on
-        // both downstream and upstream.
-        final boolean isIpv4 = is6To4 ? true : isAddressIpv4(srcIp, dstIp);
-
-        final ByteBuffer testPacket = buildTcpPacket(null /* srcMac */, null /* dstMac */,
-                srcIp, dstIp, REMOTE_PORT /* srcPort */, LOCAL_PORT /* dstPort */, seq, ack,
-                tcpFlags, payload);
-        tester.verifyDownload(testPacket, p -> {
-            Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
-
-            return isExpectedTcpPacket(p, true /* hasEther */, isIpv4, seq, payload);
-        });
-    }
-
-    private void sendUploadPacketTcp(@NonNull final MacAddress srcMac,
-            @NonNull final MacAddress dstMac, @NonNull final InetAddress srcIp,
-            @NonNull final InetAddress dstIp, short seq, short ack, byte tcpFlags,
-            @NonNull final ByteBuffer payload, @NonNull final TetheringTester tester,
-            boolean is4To6) throws Exception {
-        if (is4To6) {
-            assertTrue("CLAT upload test must sends IPv4 packet", isAddressIpv4(srcIp, dstIp));
-        }
-
-        // Expected received TCP packet IP protocol. While testing CLAT (is4To6 = true), the packet
-        // on upstream must be IPv6. Otherwise, the IP protocol of test packet is the same on
-        // both downstream and upstream.
-        final boolean isIpv4 = is4To6 ? false : isAddressIpv4(srcIp, dstIp);
-
-        final ByteBuffer testPacket = buildTcpPacket(srcMac, dstMac, srcIp, dstIp,
-                LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */, seq, ack, tcpFlags,
-                payload);
-        tester.verifyUpload(testPacket, p -> {
-            Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
-
-            return isExpectedTcpPacket(p, false /* hasEther */, isIpv4, seq, payload);
-        });
-    }
-
-    void runTcpTest(
-            @NonNull final MacAddress uploadSrcMac, @NonNull final MacAddress uploadDstMac,
-            @NonNull final InetAddress uploadSrcIp, @NonNull final InetAddress uploadDstIp,
-            @NonNull final InetAddress downloadSrcIp, @NonNull final InetAddress downloadDstIp,
-            @NonNull final TetheringTester tester, boolean isClat) throws Exception {
-        // Three way handshake and data transfer.
-        //
-        // Server (base seq = 2000)                                  Client (base seq = 1000)
-        //   |                                                          |
-        //   |    [1] [SYN] SEQ = 1000                                  |
-        //   |<---------------------------------------------------------|  -
-        //   |                                                          |  ^
-        //   |    [2] [SYN + ACK] SEQ = 2000, ACK = 1000+1              |  |
-        //   |--------------------------------------------------------->|  three way handshake
-        //   |                                                          |  |
-        //   |    [3] [ACK] SEQ = 1001, ACK = 2000+1                    |  v
-        //   |<---------------------------------------------------------|  -
-        //   |                                                          |  ^
-        //   |    [4] [ACK] SEQ = 1001, ACK = 2001, 2 byte payload      |  |
-        //   |<---------------------------------------------------------|  data transfer
-        //   |                                                          |  |
-        //   |    [5] [ACK] SEQ = 2001, ACK = 1001+2, 2 byte payload    |  v
-        //   |--------------------------------------------------------->|  -
-        //   |                                                          |
-        //
-
-        // This test can only verify the packets are transferred end to end but TCP state.
-        // TODO: verify TCP state change via /proc/net/nf_conntrack or netlink conntrack event.
-        // [1] [UPLOAD] [SYN]: SEQ = 1000
-        sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
-                (short) 1000 /* seq */, (short) 0 /* ack */, TCPHDR_SYN, EMPTY_PAYLOAD,
-                tester, isClat /* is4To6 */);
-
-        // [2] [DONWLOAD] [SYN + ACK]: SEQ = 2000, ACK = 1001
-        sendDownloadPacketTcp(downloadSrcIp, downloadDstIp, (short) 2000 /* seq */,
-                (short) 1001 /* ack */, (byte) ((TCPHDR_SYN | TCPHDR_ACK) & 0xff), EMPTY_PAYLOAD,
-                tester, isClat /* is6To4 */);
-
-        // [3] [UPLOAD] [ACK]: SEQ = 1001, ACK = 2001
-        sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
-                (short) 1001 /* seq */, (short) 2001 /* ack */, TCPHDR_ACK, EMPTY_PAYLOAD, tester,
-                isClat /* is4To6 */);
-
-        // [4] [UPLOAD] [ACK]: SEQ = 1001, ACK = 2001, 2 byte payload
-        sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
-                (short) 1001 /* seq */, (short) 2001 /* ack */, TCPHDR_ACK, TX_PAYLOAD,
-                tester, isClat /* is4To6 */);
-
-        // [5] [DONWLOAD] [ACK]: SEQ = 2001, ACK = 1003, 2 byte payload
-        sendDownloadPacketTcp(downloadSrcIp, downloadDstIp, (short) 2001 /* seq */,
-                (short) 1003 /* ack */, TCPHDR_ACK, RX_PAYLOAD, tester, isClat /* is6To4 */);
-
-        // TODO: test BPF offload maps.
-    }
-
     @Test
     public void testTetherTcpV4() throws Exception {
         final TetheringTester tester = initTetheringTester(toList(TEST_IP4_ADDR),
@@ -1945,8 +1073,4 @@
                 REMOTE_NAT64_ADDR /* downloadSrcIp */, clatIp6 /* downloadDstIp */,
                 tester, true /* isClat */);
     }
-
-    private <T> List<T> toList(T... array) {
-        return Arrays.asList(array);
-    }
 }
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTestBase.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTestBase.java
index d58a60c..7685981 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTestBase.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTestBase.java
@@ -16,24 +16,85 @@
 
 package android.net;
 
+import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
+import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
+import static android.Manifest.permission.NETWORK_SETTINGS;
+import static android.Manifest.permission.TETHER_PRIVILEGED;
+import static android.content.pm.PackageManager.FEATURE_WIFI;
 import static android.net.InetAddresses.parseNumericAddress;
+import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
+import static android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL;
+import static android.net.TetheringManager.TETHERING_ETHERNET;
+import static android.net.TetheringTester.isExpectedIcmpPacket;
+import static android.net.TetheringTester.isExpectedTcpPacket;
+import static android.net.TetheringTester.isExpectedUdpPacket;
+import static android.system.OsConstants.IPPROTO_IP;
+import static android.system.OsConstants.IPPROTO_IPV6;
+import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.IPPROTO_UDP;
+
+import static com.android.net.module.util.HexDump.dumpHexString;
+import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV4;
+import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV6;
+import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
+import static com.android.net.module.util.NetworkStackConstants.TCPHDR_ACK;
+import static com.android.net.module.util.NetworkStackConstants.TCPHDR_SYN;
+import static com.android.testutils.TestNetworkTrackerKt.initTestNetwork;
+import static com.android.testutils.TestPermissionUtil.runAsShell;
+
+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.assumeFalse;
+import static org.junit.Assume.assumeTrue;
 
 import android.app.UiAutomation;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.net.EthernetManager.TetheredInterfaceCallback;
+import android.net.EthernetManager.TetheredInterfaceRequest;
+import android.net.TetheringManager.StartTetheringCallback;
+import android.net.TetheringManager.TetheringEventCallback;
+import android.net.TetheringManager.TetheringRequest;
+import android.net.TetheringTester.TetheredDevice;
 import android.net.cts.util.CtsNetUtils;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.SystemClock;
+import android.util.Log;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.PacketBuilder;
+import com.android.testutils.HandlerUtils;
 import com.android.testutils.TapPacketReader;
 import com.android.testutils.TestNetworkTracker;
 
+import org.junit.After;
+import org.junit.Before;
+
+import java.io.FileDescriptor;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
 import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /**
  * TODO: Common variables or methods shared between CtsEthernetTetheringTest and
@@ -46,8 +107,8 @@
     // Used to check if any tethering interface is available. Choose 200ms to be request timeout
     // because the average interface requested time on cuttlefish@acloud is around 10ms.
     // See TetheredInterfaceRequester.getInterface, isInterfaceForTetheringAvailable.
-    protected static final int AVAILABLE_TETHER_IFACE_REQUEST_TIMEOUT_MS = 200;
-    protected static final int TETHER_REACHABILITY_ATTEMPTS = 20;
+    private static final int AVAILABLE_TETHER_IFACE_REQUEST_TIMEOUT_MS = 200;
+    private static final int TETHER_REACHABILITY_ATTEMPTS = 20;
     protected static final long WAIT_RA_TIMEOUT_MS = 2000;
 
     // Address and NAT prefix definition.
@@ -72,9 +133,9 @@
     protected static final byte TYPE_OF_SERVICE = 0;
 
     // IPv6 header definition.
-    protected static final short HOP_LIMIT = 0x40;
+    private static final short HOP_LIMIT = 0x40;
     // version=6, traffic class=0x0, flowlabel=0x0;
-    protected static final int VERSION_TRAFFICCLASS_FLOWLABEL = 0x60000000;
+    private static final int VERSION_TRAFFICCLASS_FLOWLABEL = 0x60000000;
 
     // UDP and TCP header definition.
     // LOCAL_PORT is used by public port and private port. Assume port 9876 has not been used yet
@@ -82,34 +143,877 @@
     // NAT port forwarding could be different between private port and public port.
     protected static final short LOCAL_PORT = 9876;
     protected static final short REMOTE_PORT = 433;
-    protected static final short WINDOW = (short) 0x2000;
-    protected static final short URGENT_POINTER = 0;
+    private static final short WINDOW = (short) 0x2000;
+    private static final short URGENT_POINTER = 0;
 
     // Payload definition.
     protected static final ByteBuffer EMPTY_PAYLOAD = ByteBuffer.wrap(new byte[0]);
-    protected static final ByteBuffer TEST_REACHABILITY_PAYLOAD =
+    private static final ByteBuffer TEST_REACHABILITY_PAYLOAD =
             ByteBuffer.wrap(new byte[] { (byte) 0x55, (byte) 0xaa });
     protected static final ByteBuffer RX_PAYLOAD =
             ByteBuffer.wrap(new byte[] { (byte) 0x12, (byte) 0x34 });
     protected static final ByteBuffer TX_PAYLOAD =
             ByteBuffer.wrap(new byte[] { (byte) 0x56, (byte) 0x78 });
 
-    protected final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
-    protected final EthernetManager mEm = mContext.getSystemService(EthernetManager.class);
-    protected final TetheringManager mTm = mContext.getSystemService(TetheringManager.class);
-    protected final PackageManager mPackageManager = mContext.getPackageManager();
-    protected final CtsNetUtils mCtsNetUtils = new CtsNetUtils(mContext);
-    protected final UiAutomation mUiAutomation =
+    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
+    private final EthernetManager mEm = mContext.getSystemService(EthernetManager.class);
+    private final TetheringManager mTm = mContext.getSystemService(TetheringManager.class);
+    private final PackageManager mPackageManager = mContext.getPackageManager();
+    private final CtsNetUtils mCtsNetUtils = new CtsNetUtils(mContext);
+    private final UiAutomation mUiAutomation =
             InstrumentationRegistry.getInstrumentation().getUiAutomation();
 
     // Late initialization in setUp()
-    protected boolean mRunTests;
-    protected HandlerThread mHandlerThread;
-    protected Handler mHandler;
+    private boolean mRunTests;
+    private HandlerThread mHandlerThread;
+    private Handler mHandler;
+    private TetheredInterfaceRequester mTetheredInterfaceRequester;
 
     // Late initialization in initTetheringTester().
-    protected TapPacketReader mUpstreamReader;
-    protected TestNetworkTracker mUpstreamTracker;
-    protected TestNetworkInterface mDownstreamIface;
-    protected TapPacketReader mDownstreamReader;
+    private TapPacketReader mUpstreamReader;
+    private TestNetworkTracker mUpstreamTracker;
+    private TestNetworkInterface mDownstreamIface;
+    private TapPacketReader mDownstreamReader;
+    private MyTetheringEventCallback mTetheringEventCallback;
+
+    @Before
+    public void setUp() throws Exception {
+        mHandlerThread = new HandlerThread(getClass().getSimpleName());
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+
+        mRunTests = runAsShell(NETWORK_SETTINGS, TETHER_PRIVILEGED, () ->
+                mTm.isTetheringSupported());
+        assumeTrue(mRunTests);
+
+        mTetheredInterfaceRequester = new TetheredInterfaceRequester(mHandler, mEm);
+    }
+
+    protected void maybeStopTapPacketReader(final TapPacketReader tapPacketReader)
+            throws Exception {
+        if (tapPacketReader != null) {
+            TapPacketReader reader = tapPacketReader;
+            mHandler.post(() -> reader.stop());
+        }
+    }
+
+    protected void maybeCloseTestInterface(final TestNetworkInterface testInterface)
+            throws Exception {
+        if (testInterface != null) {
+            testInterface.getFileDescriptor().close();
+            Log.d(TAG, "Deleted test interface " + testInterface.getInterfaceName());
+        }
+    }
+
+    protected void maybeUnregisterTetheringEventCallback(final MyTetheringEventCallback callback)
+            throws Exception {
+        if (callback != null) {
+            callback.awaitInterfaceUntethered();
+            callback.unregister();
+        }
+    }
+
+    protected void cleanUp() throws Exception {
+        setPreferTestNetworks(false);
+
+        if (mUpstreamTracker != null) {
+            runAsShell(MANAGE_TEST_NETWORKS, () -> {
+                mUpstreamTracker.teardown();
+                mUpstreamTracker = null;
+            });
+        }
+        if (mUpstreamReader != null) {
+            TapPacketReader reader = mUpstreamReader;
+            mHandler.post(() -> reader.stop());
+            mUpstreamReader = null;
+        }
+
+        maybeStopTapPacketReader(mDownstreamReader);
+        mDownstreamReader = null;
+        // To avoid flaky which caused by the next test started but the previous interface is not
+        // untracked from EthernetTracker yet. Just delete the test interface without explicitly
+        // calling TetheringManager#stopTethering could let EthernetTracker untrack the test
+        // interface from server mode before tethering stopped. Thus, awaitInterfaceUntethered
+        // could not only make sure tethering is stopped but also guarantee the test interface is
+        // untracked from EthernetTracker.
+        maybeCloseTestInterface(mDownstreamIface);
+        mDownstreamIface = null;
+        maybeUnregisterTetheringEventCallback(mTetheringEventCallback);
+        mTetheringEventCallback = null;
+
+        runAsShell(NETWORK_SETTINGS, () -> mTetheredInterfaceRequester.release());
+        setIncludeTestInterfaces(false);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        try {
+            if (mRunTests) cleanUp();
+        } finally {
+            mHandlerThread.quitSafely();
+            mUiAutomation.dropShellPermissionIdentity();
+        }
+    }
+
+    protected boolean isInterfaceForTetheringAvailable() throws Exception {
+        // Before T, all ethernet interfaces could be used for server mode. Instead of
+        // waiting timeout, just checking whether the system currently has any
+        // ethernet interface is more reliable.
+        if (!SdkLevel.isAtLeastT()) {
+            return runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS, () -> mEm.isAvailable());
+        }
+
+        // If previous test case doesn't release tethering interface successfully, the other tests
+        // after that test may be skipped as unexcepted.
+        // TODO: figure out a better way to check default tethering interface existenion.
+        final TetheredInterfaceRequester requester = new TetheredInterfaceRequester(mHandler, mEm);
+        try {
+            // Use short timeout (200ms) for requesting an existing interface, if any, because
+            // it should reurn faster than requesting a new tethering interface. Using default
+            // timeout (5000ms, TIMEOUT_MS) may make that total testing time is over 1 minute
+            // test module timeout on internal testing.
+            // TODO: if this becomes flaky, consider using default timeout (5000ms) and moving
+            // this check into #setUpOnce.
+            return requester.getInterface(AVAILABLE_TETHER_IFACE_REQUEST_TIMEOUT_MS) != null;
+        } catch (TimeoutException e) {
+            return false;
+        } finally {
+            runAsShell(NETWORK_SETTINGS, () -> {
+                requester.release();
+            });
+        }
+    }
+
+    protected void setIncludeTestInterfaces(boolean include) {
+        runAsShell(NETWORK_SETTINGS, () -> {
+            mEm.setIncludeTestInterfaces(include);
+        });
+    }
+
+    protected void setPreferTestNetworks(boolean prefer) {
+        runAsShell(NETWORK_SETTINGS, () -> {
+            mTm.setPreferTestNetworks(prefer);
+        });
+    }
+
+    protected String getTetheredInterface() throws Exception {
+        return mTetheredInterfaceRequester.getInterface();
+    }
+
+    protected CompletableFuture<String> requestTetheredInterface() throws Exception {
+        return mTetheredInterfaceRequester.requestInterface();
+    }
+
+    protected static void waitForRouterAdvertisement(TapPacketReader reader, String iface,
+            long timeoutMs) {
+        final long deadline = SystemClock.uptimeMillis() + timeoutMs;
+        do {
+            byte[] pkt = reader.popPacket(timeoutMs);
+            if (isExpectedIcmpPacket(pkt, true /* hasEth */, false /* isIpv4 */,
+                    ICMPV6_ROUTER_ADVERTISEMENT)) {
+                return;
+            }
+
+            timeoutMs = deadline - SystemClock.uptimeMillis();
+        } while (timeoutMs > 0);
+        fail("Did not receive router advertisement on " + iface + " after "
+                +  timeoutMs + "ms idle");
+    }
+
+
+    protected static final class MyTetheringEventCallback implements TetheringEventCallback {
+        private final TetheringManager mTm;
+        private final CountDownLatch mTetheringStartedLatch = new CountDownLatch(1);
+        private final CountDownLatch mTetheringStoppedLatch = new CountDownLatch(1);
+        private final CountDownLatch mLocalOnlyStartedLatch = new CountDownLatch(1);
+        private final CountDownLatch mLocalOnlyStoppedLatch = new CountDownLatch(1);
+        private final CountDownLatch mClientConnectedLatch = new CountDownLatch(1);
+        private final CountDownLatch mUpstreamLatch = new CountDownLatch(1);
+        private final CountDownLatch mCallbackRegisteredLatch = new CountDownLatch(1);
+        private final TetheringInterface mIface;
+        private final Network mExpectedUpstream;
+
+        private boolean mAcceptAnyUpstream = false;
+
+        private volatile boolean mInterfaceWasTethered = false;
+        private volatile boolean mInterfaceWasLocalOnly = false;
+        private volatile boolean mUnregistered = false;
+        private volatile Collection<TetheredClient> mClients = null;
+        private volatile Network mUpstream = null;
+
+        MyTetheringEventCallback(TetheringManager tm, String iface) {
+            this(tm, iface, null);
+            mAcceptAnyUpstream = true;
+        }
+
+        MyTetheringEventCallback(TetheringManager tm, String iface, Network expectedUpstream) {
+            mTm = tm;
+            mIface = new TetheringInterface(TETHERING_ETHERNET, iface);
+            mExpectedUpstream = expectedUpstream;
+        }
+
+        public void unregister() {
+            mTm.unregisterTetheringEventCallback(this);
+            mUnregistered = true;
+        }
+        @Override
+        public void onTetheredInterfacesChanged(List<String> interfaces) {
+            fail("Should only call callback that takes a Set<TetheringInterface>");
+        }
+
+        @Override
+        public void onTetheredInterfacesChanged(Set<TetheringInterface> interfaces) {
+            // Ignore stale callbacks registered by previous test cases.
+            if (mUnregistered) return;
+
+            if (!mInterfaceWasTethered && interfaces.contains(mIface)) {
+                // This interface is being tethered for the first time.
+                Log.d(TAG, "Tethering started: " + interfaces);
+                mInterfaceWasTethered = true;
+                mTetheringStartedLatch.countDown();
+            } else if (mInterfaceWasTethered && !interfaces.contains(mIface)) {
+                Log.d(TAG, "Tethering stopped: " + interfaces);
+                mTetheringStoppedLatch.countDown();
+            }
+        }
+
+        @Override
+        public void onLocalOnlyInterfacesChanged(List<String> interfaces) {
+            fail("Should only call callback that takes a Set<TetheringInterface>");
+        }
+
+        @Override
+        public void onLocalOnlyInterfacesChanged(Set<TetheringInterface> interfaces) {
+            // Ignore stale callbacks registered by previous test cases.
+            if (mUnregistered) return;
+
+            if (!mInterfaceWasLocalOnly && interfaces.contains(mIface)) {
+                // This interface is being put into local-only mode for the first time.
+                Log.d(TAG, "Local-only started: " + interfaces);
+                mInterfaceWasLocalOnly = true;
+                mLocalOnlyStartedLatch.countDown();
+            } else if (mInterfaceWasLocalOnly && !interfaces.contains(mIface)) {
+                Log.d(TAG, "Local-only stopped: " + interfaces);
+                mLocalOnlyStoppedLatch.countDown();
+            }
+        }
+
+        public void awaitInterfaceTethered() throws Exception {
+            assertTrue("Ethernet not tethered after " + TIMEOUT_MS + "ms",
+                    mTetheringStartedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        }
+
+        public void awaitInterfaceLocalOnly() throws Exception {
+            assertTrue("Ethernet not local-only after " + TIMEOUT_MS + "ms",
+                    mLocalOnlyStartedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        }
+
+        // Used to check if the callback has registered. When the callback is registered,
+        // onSupportedTetheringTypes is celled in onCallbackStarted(). After
+        // onSupportedTetheringTypes called, drop the permission for registering callback.
+        // See MyTetheringEventCallback#register, TetheringManager#onCallbackStarted.
+        @Override
+        public void onSupportedTetheringTypes(Set<Integer> supportedTypes) {
+            // Used to check callback registered.
+            mCallbackRegisteredLatch.countDown();
+        }
+
+        public void awaitCallbackRegistered() throws Exception {
+            if (!mCallbackRegisteredLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+                fail("Did not receive callback registered signal after " + TIMEOUT_MS + "ms");
+            }
+        }
+
+        public void awaitInterfaceUntethered() throws Exception {
+            // Don't block teardown if the interface was never tethered.
+            // This is racy because the interface might become tethered right after this check, but
+            // that can only happen in tearDown if startTethering timed out, which likely means
+            // the test has already failed.
+            if (!mInterfaceWasTethered && !mInterfaceWasLocalOnly) return;
+
+            if (mInterfaceWasTethered) {
+                assertTrue(mIface + " not untethered after " + TIMEOUT_MS + "ms",
+                        mTetheringStoppedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            } else if (mInterfaceWasLocalOnly) {
+                assertTrue(mIface + " not untethered after " + TIMEOUT_MS + "ms",
+                        mLocalOnlyStoppedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            } else {
+                fail(mIface + " cannot be both tethered and local-only. Update this test class.");
+            }
+        }
+
+        @Override
+        public void onError(String ifName, int error) {
+            // Ignore stale callbacks registered by previous test cases.
+            if (mUnregistered) return;
+
+            fail("TetheringEventCallback got error:" + error + " on iface " + ifName);
+        }
+
+        @Override
+        public void onClientsChanged(Collection<TetheredClient> clients) {
+            // Ignore stale callbacks registered by previous test cases.
+            if (mUnregistered) return;
+
+            Log.d(TAG, "Got clients changed: " + clients);
+            mClients = clients;
+            if (clients.size() > 0) {
+                mClientConnectedLatch.countDown();
+            }
+        }
+
+        public Collection<TetheredClient> awaitClientConnected() throws Exception {
+            assertTrue("Did not receive client connected callback after " + TIMEOUT_MS + "ms",
+                    mClientConnectedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            return mClients;
+        }
+
+        @Override
+        public void onUpstreamChanged(Network network) {
+            // Ignore stale callbacks registered by previous test cases.
+            if (mUnregistered) return;
+
+            Log.d(TAG, "Got upstream changed: " + network);
+            mUpstream = network;
+            if (mAcceptAnyUpstream || Objects.equals(mUpstream, mExpectedUpstream)) {
+                mUpstreamLatch.countDown();
+            }
+        }
+
+        public Network awaitUpstreamChanged(boolean throwTimeoutException) throws Exception {
+            if (!mUpstreamLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+                final String errorMessage = "Did not receive upstream "
+                            + (mAcceptAnyUpstream ? "any" : mExpectedUpstream)
+                            + " callback after " + TIMEOUT_MS + "ms";
+
+                if (throwTimeoutException) {
+                    throw new TimeoutException(errorMessage);
+                } else {
+                    fail(errorMessage);
+                }
+            }
+            return mUpstream;
+        }
+    }
+
+    protected MyTetheringEventCallback enableEthernetTethering(String iface,
+            TetheringRequest request, Network expectedUpstream) throws Exception {
+        // Enable ethernet tethering with null expectedUpstream means the test accept any upstream
+        // after etherent tethering started.
+        final MyTetheringEventCallback callback;
+        if (expectedUpstream != null) {
+            callback = new MyTetheringEventCallback(mTm, iface, expectedUpstream);
+        } else {
+            callback = new MyTetheringEventCallback(mTm, iface);
+        }
+        runAsShell(NETWORK_SETTINGS, () -> {
+            mTm.registerTetheringEventCallback(mHandler::post, callback);
+            // Need to hold the shell permission until callback is registered. This helps to avoid
+            // the test become flaky.
+            callback.awaitCallbackRegistered();
+        });
+        final CountDownLatch tetheringStartedLatch = new CountDownLatch(1);
+        StartTetheringCallback startTetheringCallback = new StartTetheringCallback() {
+            @Override
+            public void onTetheringStarted() {
+                Log.d(TAG, "Ethernet tethering started");
+                tetheringStartedLatch.countDown();
+            }
+
+            @Override
+            public void onTetheringFailed(int resultCode) {
+                fail("Unexpectedly got onTetheringFailed");
+            }
+        };
+        Log.d(TAG, "Starting Ethernet tethering");
+        runAsShell(TETHER_PRIVILEGED, () -> {
+            mTm.startTethering(request, mHandler::post /* executor */, startTetheringCallback);
+            // Binder call is an async call. Need to hold the shell permission until tethering
+            // started. This helps to avoid the test become flaky.
+            if (!tetheringStartedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+                fail("Did not receive tethering started callback after " + TIMEOUT_MS + "ms");
+            }
+        });
+
+        final int connectivityType = request.getConnectivityScope();
+        switch (connectivityType) {
+            case CONNECTIVITY_SCOPE_GLOBAL:
+                callback.awaitInterfaceTethered();
+                break;
+            case CONNECTIVITY_SCOPE_LOCAL:
+                callback.awaitInterfaceLocalOnly();
+                break;
+            default:
+                fail("Unexpected connectivity type requested: " + connectivityType);
+        }
+
+        return callback;
+    }
+
+    protected MyTetheringEventCallback enableEthernetTethering(String iface,
+            Network expectedUpstream) throws Exception {
+        return enableEthernetTethering(iface,
+                new TetheringRequest.Builder(TETHERING_ETHERNET)
+                .setShouldShowEntitlementUi(false).build(), expectedUpstream);
+    }
+
+    protected int getMTU(TestNetworkInterface iface) throws SocketException {
+        NetworkInterface nif = NetworkInterface.getByName(iface.getInterfaceName());
+        assertNotNull("Can't get NetworkInterface object for " + iface.getInterfaceName(), nif);
+        return nif.getMTU();
+    }
+
+    protected TapPacketReader makePacketReader(final TestNetworkInterface iface) throws Exception {
+        FileDescriptor fd = iface.getFileDescriptor().getFileDescriptor();
+        return makePacketReader(fd, getMTU(iface));
+    }
+
+    protected TapPacketReader makePacketReader(FileDescriptor fd, int mtu) {
+        final TapPacketReader reader = new TapPacketReader(mHandler, fd, mtu);
+        mHandler.post(() -> reader.start());
+        HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS);
+        return reader;
+    }
+
+    protected static final class TetheredInterfaceRequester implements TetheredInterfaceCallback {
+        private final Handler mHandler;
+        private final EthernetManager mEm;
+
+        private TetheredInterfaceRequest mRequest;
+        private final CompletableFuture<String> mFuture = new CompletableFuture<>();
+
+        TetheredInterfaceRequester(Handler handler, EthernetManager em) {
+            mHandler = handler;
+            mEm = em;
+        }
+
+        @Override
+        public void onAvailable(String iface) {
+            Log.d(TAG, "Ethernet interface available: " + iface);
+            mFuture.complete(iface);
+        }
+
+        @Override
+        public void onUnavailable() {
+            mFuture.completeExceptionally(new IllegalStateException("onUnavailable received"));
+        }
+
+        public CompletableFuture<String> requestInterface() {
+            assertNull("BUG: more than one tethered interface request", mRequest);
+            Log.d(TAG, "Requesting tethered interface");
+            mRequest = runAsShell(NETWORK_SETTINGS, () ->
+                    mEm.requestTetheredInterface(mHandler::post, this));
+            return mFuture;
+        }
+
+        public String getInterface(int timeout) throws Exception {
+            return requestInterface().get(timeout, TimeUnit.MILLISECONDS);
+        }
+
+        public String getInterface() throws Exception {
+            return getInterface(TIMEOUT_MS);
+        }
+
+        public void release() {
+            if (mRequest != null) {
+                mFuture.obtrudeException(new IllegalStateException("Request already released"));
+                mRequest.release();
+                mRequest = null;
+            }
+        }
+    }
+
+    protected TestNetworkInterface createTestInterface() throws Exception {
+        TestNetworkManager tnm = runAsShell(MANAGE_TEST_NETWORKS, () ->
+                mContext.getSystemService(TestNetworkManager.class));
+        TestNetworkInterface iface = runAsShell(MANAGE_TEST_NETWORKS, () ->
+                tnm.createTapInterface());
+        Log.d(TAG, "Created test interface " + iface.getInterfaceName());
+        return iface;
+    }
+
+    protected TestNetworkTracker createTestUpstream(final List<LinkAddress> addresses,
+            final List<InetAddress> dnses) throws Exception {
+        setPreferTestNetworks(true);
+
+        final LinkProperties lp = new LinkProperties();
+        lp.setLinkAddresses(addresses);
+        lp.setDnsServers(dnses);
+        lp.setNat64Prefix(TEST_NAT64PREFIX);
+
+        return runAsShell(MANAGE_TEST_NETWORKS, () -> initTestNetwork(mContext, lp, TIMEOUT_MS));
+    }
+
+    private short getEthType(@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp) {
+        return isAddressIpv4(srcIp, dstIp) ? (short) ETHER_TYPE_IPV4 : (short) ETHER_TYPE_IPV6;
+    }
+
+    private int getIpProto(@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp) {
+        return isAddressIpv4(srcIp, dstIp) ? IPPROTO_IP : IPPROTO_IPV6;
+    }
+
+    @NonNull
+    protected ByteBuffer buildUdpPacket(
+            @Nullable final MacAddress srcMac, @Nullable final MacAddress dstMac,
+            @NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp,
+            short srcPort, short dstPort, @Nullable final ByteBuffer payload)
+            throws Exception {
+        final int ipProto = getIpProto(srcIp, dstIp);
+        final boolean hasEther = (srcMac != null && dstMac != null);
+        final int payloadLen = (payload == null) ? 0 : payload.limit();
+        final ByteBuffer buffer = PacketBuilder.allocate(hasEther, ipProto, IPPROTO_UDP,
+                payloadLen);
+        final PacketBuilder packetBuilder = new PacketBuilder(buffer);
+
+        // [1] Ethernet header
+        if (hasEther) {
+            packetBuilder.writeL2Header(srcMac, dstMac, getEthType(srcIp, dstIp));
+        }
+
+        // [2] IP header
+        if (ipProto == IPPROTO_IP) {
+            packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET,
+                    TIME_TO_LIVE, (byte) IPPROTO_UDP, (Inet4Address) srcIp, (Inet4Address) dstIp);
+        } else {
+            packetBuilder.writeIpv6Header(VERSION_TRAFFICCLASS_FLOWLABEL, (byte) IPPROTO_UDP,
+                    HOP_LIMIT, (Inet6Address) srcIp, (Inet6Address) dstIp);
+        }
+
+        // [3] UDP header
+        packetBuilder.writeUdpHeader(srcPort, dstPort);
+
+        // [4] Payload
+        if (payload != null) {
+            buffer.put(payload);
+            // in case data might be reused by caller, restore the position and
+            // limit of bytebuffer.
+            payload.clear();
+        }
+
+        return packetBuilder.finalizePacket();
+    }
+
+    @NonNull
+    protected ByteBuffer buildUdpPacket(@NonNull final InetAddress srcIp,
+            @NonNull final InetAddress dstIp, short srcPort, short dstPort,
+            @Nullable final ByteBuffer payload) throws Exception {
+        return buildUdpPacket(null /* srcMac */, null /* dstMac */, srcIp, dstIp, srcPort,
+                dstPort, payload);
+    }
+
+    private boolean isAddressIpv4(@NonNull final  InetAddress srcIp,
+            @NonNull final InetAddress dstIp) {
+        if (srcIp instanceof Inet4Address && dstIp instanceof Inet4Address) return true;
+        if (srcIp instanceof Inet6Address && dstIp instanceof Inet6Address) return false;
+
+        fail("Unsupported conditions: srcIp " + srcIp + ", dstIp " + dstIp);
+        return false;  // unreachable
+    }
+
+    protected void sendDownloadPacketUdp(@NonNull final InetAddress srcIp,
+            @NonNull final InetAddress dstIp, @NonNull final TetheringTester tester,
+            boolean is6To4) throws Exception {
+        if (is6To4) {
+            assertFalse("CLAT download test must sends IPv6 packet", isAddressIpv4(srcIp, dstIp));
+        }
+
+        // Expected received UDP packet IP protocol. While testing CLAT (is6To4 = true), the packet
+        // on downstream must be IPv4. Otherwise, the IP protocol of test packet is the same on
+        // both downstream and upstream.
+        final boolean isIpv4 = is6To4 ? true : isAddressIpv4(srcIp, dstIp);
+
+        final ByteBuffer testPacket = buildUdpPacket(srcIp, dstIp, REMOTE_PORT /* srcPort */,
+                LOCAL_PORT /* dstPort */, RX_PAYLOAD);
+        tester.verifyDownload(testPacket, p -> {
+            Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
+            return isExpectedUdpPacket(p, true /* hasEther */, isIpv4, RX_PAYLOAD);
+        });
+    }
+
+    protected void sendUploadPacketUdp(@NonNull final MacAddress srcMac,
+            @NonNull final MacAddress dstMac, @NonNull final InetAddress srcIp,
+            @NonNull final InetAddress dstIp, @NonNull final TetheringTester tester,
+            boolean is4To6) throws Exception {
+        if (is4To6) {
+            assertTrue("CLAT upload test must sends IPv4 packet", isAddressIpv4(srcIp, dstIp));
+        }
+
+        // Expected received UDP packet IP protocol. While testing CLAT (is4To6 = true), the packet
+        // on upstream must be IPv6. Otherwise, the IP protocol of test packet is the same on
+        // both downstream and upstream.
+        final boolean isIpv4 = is4To6 ? false : isAddressIpv4(srcIp, dstIp);
+
+        final ByteBuffer testPacket = buildUdpPacket(srcMac, dstMac, srcIp, dstIp,
+                LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */, TX_PAYLOAD);
+        tester.verifyUpload(testPacket, p -> {
+            Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
+            return isExpectedUdpPacket(p, false /* hasEther */, isIpv4, TX_PAYLOAD);
+        });
+    }
+
+
+    @NonNull
+    private ByteBuffer buildTcpPacket(
+            @Nullable final MacAddress srcMac, @Nullable final MacAddress dstMac,
+            @NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp,
+            short srcPort, short dstPort, final short seq, final short ack,
+            final byte tcpFlags, @NonNull final ByteBuffer payload) throws Exception {
+        final int ipProto = getIpProto(srcIp, dstIp);
+        final boolean hasEther = (srcMac != null && dstMac != null);
+        final ByteBuffer buffer = PacketBuilder.allocate(hasEther, ipProto, IPPROTO_TCP,
+                payload.limit());
+        final PacketBuilder packetBuilder = new PacketBuilder(buffer);
+
+        // [1] Ethernet header
+        if (hasEther) {
+            packetBuilder.writeL2Header(srcMac, dstMac, getEthType(srcIp, dstIp));
+        }
+
+        // [2] IP header
+        if (ipProto == IPPROTO_IP) {
+            packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET,
+                    TIME_TO_LIVE, (byte) IPPROTO_TCP, (Inet4Address) srcIp, (Inet4Address) dstIp);
+        } else {
+            packetBuilder.writeIpv6Header(VERSION_TRAFFICCLASS_FLOWLABEL, (byte) IPPROTO_TCP,
+                    HOP_LIMIT, (Inet6Address) srcIp, (Inet6Address) dstIp);
+        }
+
+        // [3] TCP header
+        packetBuilder.writeTcpHeader(srcPort, dstPort, seq, ack, tcpFlags, WINDOW, URGENT_POINTER);
+
+        // [4] Payload
+        buffer.put(payload);
+        // in case data might be reused by caller, restore the position and
+        // limit of bytebuffer.
+        payload.clear();
+
+        return packetBuilder.finalizePacket();
+    }
+
+    protected void sendDownloadPacketTcp(@NonNull final InetAddress srcIp,
+            @NonNull final InetAddress dstIp, short seq, short ack, byte tcpFlags,
+            @NonNull final ByteBuffer payload, @NonNull final TetheringTester tester,
+            boolean is6To4) throws Exception {
+        if (is6To4) {
+            assertFalse("CLAT download test must sends IPv6 packet", isAddressIpv4(srcIp, dstIp));
+        }
+
+        // Expected received TCP packet IP protocol. While testing CLAT (is6To4 = true), the packet
+        // on downstream must be IPv4. Otherwise, the IP protocol of test packet is the same on
+        // both downstream and upstream.
+        final boolean isIpv4 = is6To4 ? true : isAddressIpv4(srcIp, dstIp);
+
+        final ByteBuffer testPacket = buildTcpPacket(null /* srcMac */, null /* dstMac */,
+                srcIp, dstIp, REMOTE_PORT /* srcPort */, LOCAL_PORT /* dstPort */, seq, ack,
+                tcpFlags, payload);
+        tester.verifyDownload(testPacket, p -> {
+            Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
+
+            return isExpectedTcpPacket(p, true /* hasEther */, isIpv4, seq, payload);
+        });
+    }
+
+    protected void sendUploadPacketTcp(@NonNull final MacAddress srcMac,
+            @NonNull final MacAddress dstMac, @NonNull final InetAddress srcIp,
+            @NonNull final InetAddress dstIp, short seq, short ack, byte tcpFlags,
+            @NonNull final ByteBuffer payload, @NonNull final TetheringTester tester,
+            boolean is4To6) throws Exception {
+        if (is4To6) {
+            assertTrue("CLAT upload test must sends IPv4 packet", isAddressIpv4(srcIp, dstIp));
+        }
+
+        // Expected received TCP packet IP protocol. While testing CLAT (is4To6 = true), the packet
+        // on upstream must be IPv6. Otherwise, the IP protocol of test packet is the same on
+        // both downstream and upstream.
+        final boolean isIpv4 = is4To6 ? false : isAddressIpv4(srcIp, dstIp);
+
+        final ByteBuffer testPacket = buildTcpPacket(srcMac, dstMac, srcIp, dstIp,
+                LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */, seq, ack, tcpFlags,
+                payload);
+        tester.verifyUpload(testPacket, p -> {
+            Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
+
+            return isExpectedTcpPacket(p, false /* hasEther */, isIpv4, seq, payload);
+        });
+    }
+
+    protected void runTcpTest(
+            @NonNull final MacAddress uploadSrcMac, @NonNull final MacAddress uploadDstMac,
+            @NonNull final InetAddress uploadSrcIp, @NonNull final InetAddress uploadDstIp,
+            @NonNull final InetAddress downloadSrcIp, @NonNull final InetAddress downloadDstIp,
+            @NonNull final TetheringTester tester, boolean isClat) throws Exception {
+        // Three way handshake and data transfer.
+        //
+        // Server (base seq = 2000)                                  Client (base seq = 1000)
+        //   |                                                          |
+        //   |    [1] [SYN] SEQ = 1000                                  |
+        //   |<---------------------------------------------------------|  -
+        //   |                                                          |  ^
+        //   |    [2] [SYN + ACK] SEQ = 2000, ACK = 1000+1              |  |
+        //   |--------------------------------------------------------->|  three way handshake
+        //   |                                                          |  |
+        //   |    [3] [ACK] SEQ = 1001, ACK = 2000+1                    |  v
+        //   |<---------------------------------------------------------|  -
+        //   |                                                          |  ^
+        //   |    [4] [ACK] SEQ = 1001, ACK = 2001, 2 byte payload      |  |
+        //   |<---------------------------------------------------------|  data transfer
+        //   |                                                          |  |
+        //   |    [5] [ACK] SEQ = 2001, ACK = 1001+2, 2 byte payload    |  v
+        //   |--------------------------------------------------------->|  -
+        //   |                                                          |
+        //
+
+        // This test can only verify the packets are transferred end to end but TCP state.
+        // TODO: verify TCP state change via /proc/net/nf_conntrack or netlink conntrack event.
+        // [1] [UPLOAD] [SYN]: SEQ = 1000
+        sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
+                (short) 1000 /* seq */, (short) 0 /* ack */, TCPHDR_SYN, EMPTY_PAYLOAD,
+                tester, isClat /* is4To6 */);
+
+        // [2] [DONWLOAD] [SYN + ACK]: SEQ = 2000, ACK = 1001
+        sendDownloadPacketTcp(downloadSrcIp, downloadDstIp, (short) 2000 /* seq */,
+                (short) 1001 /* ack */, (byte) ((TCPHDR_SYN | TCPHDR_ACK) & 0xff), EMPTY_PAYLOAD,
+                tester, isClat /* is6To4 */);
+
+        // [3] [UPLOAD] [ACK]: SEQ = 1001, ACK = 2001
+        sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
+                (short) 1001 /* seq */, (short) 2001 /* ack */, TCPHDR_ACK, EMPTY_PAYLOAD, tester,
+                isClat /* is4To6 */);
+
+        // [4] [UPLOAD] [ACK]: SEQ = 1001, ACK = 2001, 2 byte payload
+        sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
+                (short) 1001 /* seq */, (short) 2001 /* ack */, TCPHDR_ACK, TX_PAYLOAD,
+                tester, isClat /* is4To6 */);
+
+        // [5] [DONWLOAD] [ACK]: SEQ = 2001, ACK = 1003, 2 byte payload
+        sendDownloadPacketTcp(downloadSrcIp, downloadDstIp, (short) 2001 /* seq */,
+                (short) 1003 /* ack */, TCPHDR_ACK, RX_PAYLOAD, tester, isClat /* is6To4 */);
+
+        // TODO: test BPF offload maps.
+    }
+
+    // TODO: remove ipv4 verification (is4To6 = false) once upstream connected notification race is
+    // fixed. See #runUdp4Test.
+    //
+    // This function sends a probe packet to downstream interface and exam the result from upstream
+    // interface to make sure ipv4 tethering is ready. Return the entire packet which received from
+    // upstream interface.
+    @NonNull
+    protected byte[] probeV4TetheringConnectivity(TetheringTester tester, TetheredDevice tethered,
+            boolean is4To6) throws Exception {
+        final ByteBuffer probePacket = buildUdpPacket(tethered.macAddr,
+                tethered.routerMacAddr, tethered.ipv4Addr /* srcIp */,
+                REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */,
+                TEST_REACHABILITY_PAYLOAD);
+
+        // Send a UDP packet from client and check the packet can be found on upstream interface.
+        for (int i = 0; i < TETHER_REACHABILITY_ATTEMPTS; i++) {
+            byte[] expectedPacket = tester.testUpload(probePacket, p -> {
+                Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
+                // If is4To6 is true, the ipv4 probe packet would be translated to ipv6 by Clat and
+                // would see this translated ipv6 packet in upstream interface.
+                return isExpectedUdpPacket(p, false /* hasEther */, !is4To6 /* isIpv4 */,
+                        TEST_REACHABILITY_PAYLOAD);
+            });
+            if (expectedPacket != null) return expectedPacket;
+        }
+
+        fail("Can't verify " + (is4To6 ? "ipv4 to ipv6" : "ipv4") + " tethering connectivity after "
+                + TETHER_REACHABILITY_ATTEMPTS + " attempts");
+        return null;
+    }
+
+    // TODO: remove triggering upstream reselection once test network can replace selected upstream
+    // network in Tethering module.
+    private void maybeRetryTestedUpstreamChanged(final Network expectedUpstream,
+            final TimeoutException fallbackException) throws Exception {
+        // Fall back original exception because no way to reselect if there is no WIFI feature.
+        assertTrue(fallbackException.toString(), mPackageManager.hasSystemFeature(FEATURE_WIFI));
+
+        // Try to toggle wifi network, if any, to reselect upstream network via default network
+        // switching. Because test network has higher priority than internet network, this can
+        // help selecting test network to be upstream network for testing. This tries to avoid
+        // the flaky upstream selection under multinetwork environment. Internet and test network
+        // upstream changed event order is not guaranteed. Once tethering selects non-test
+        // upstream {wifi, ..}, test network won't be selected anymore. If too many test cases
+        // trigger the reselection, the total test time may over test suite 1 minmute timeout.
+        // Probably need to disable/restore all internet networks in a common place of test
+        // process. Currently, EthernetTetheringTest is part of CTS test which needs wifi network
+        // connection if device has wifi feature. CtsNetUtils#toggleWifi() checks wifi connection
+        // during the toggling process.
+        // See Tethering#chooseUpstreamType, CtsNetUtils#toggleWifi.
+        // TODO: toggle cellular network if the device has no WIFI feature.
+        Log.d(TAG, "Toggle WIFI to retry upstream selection");
+        mCtsNetUtils.toggleWifi();
+
+        // Wait for expected upstream.
+        final CompletableFuture<Network> future = new CompletableFuture<>();
+        final TetheringEventCallback callback = new TetheringEventCallback() {
+            @Override
+            public void onUpstreamChanged(Network network) {
+                Log.d(TAG, "Got upstream changed: " + network);
+                if (Objects.equals(expectedUpstream, network)) {
+                    future.complete(network);
+                }
+            }
+        };
+        try {
+            mTm.registerTetheringEventCallback(mHandler::post, callback);
+            assertEquals("onUpstreamChanged for unexpected network", expectedUpstream,
+                    future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        } catch (TimeoutException e) {
+            throw new AssertionError("Did not receive upstream " + expectedUpstream
+                    + " callback after " + TIMEOUT_MS + "ms");
+        } finally {
+            mTm.unregisterTetheringEventCallback(callback);
+        }
+    }
+
+    protected TetheringTester initTetheringTester(List<LinkAddress> upstreamAddresses,
+            List<InetAddress> upstreamDnses) throws Exception {
+        assumeFalse(isInterfaceForTetheringAvailable());
+
+        // MyTetheringEventCallback currently only support await first available upstream. Tethering
+        // may select internet network as upstream if test network is not available and not be
+        // preferred yet. Create test upstream network before enable tethering.
+        mUpstreamTracker = createTestUpstream(upstreamAddresses, upstreamDnses);
+
+        mDownstreamIface = createTestInterface();
+        setIncludeTestInterfaces(true);
+
+        // Make sure EtherentTracker use "mDownstreamIface" as server mode interface.
+        assertEquals("TetheredInterfaceCallback for unexpected interface",
+                mDownstreamIface.getInterfaceName(), mTetheredInterfaceRequester.getInterface());
+
+        mTetheringEventCallback = enableEthernetTethering(mDownstreamIface.getInterfaceName(),
+                mUpstreamTracker.getNetwork());
+
+        try {
+            assertEquals("onUpstreamChanged for test network", mUpstreamTracker.getNetwork(),
+                    mTetheringEventCallback.awaitUpstreamChanged(
+                            true /* throwTimeoutException */));
+        } catch (TimeoutException e) {
+            // Due to race condition inside tethering module, test network may not be selected as
+            // tethering upstream. Force tethering retry upstream if possible. If it is not
+            // possible to retry, fail the test with the original timeout exception.
+            maybeRetryTestedUpstreamChanged(mUpstreamTracker.getNetwork(), e);
+        }
+
+        mDownstreamReader = makePacketReader(mDownstreamIface);
+        mUpstreamReader = makePacketReader(mUpstreamTracker.getTestIface());
+
+        final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
+        // Currently tethering don't have API to tell when ipv6 tethering is available. Thus, make
+        // sure tethering already have ipv6 connectivity before testing.
+        if (cm.getLinkProperties(mUpstreamTracker.getNetwork()).hasGlobalIpv6Address()) {
+            waitForRouterAdvertisement(mDownstreamReader, mDownstreamIface.getInterfaceName(),
+                    WAIT_RA_TIMEOUT_MS);
+        }
+
+        return new TetheringTester(mDownstreamReader, mUpstreamReader);
+    }
+
+    protected <T> List<T> toList(T... array) {
+        return Arrays.asList(array);
+    }
 }
diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
index d38a7c3..23fb60c 100644
--- a/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
+++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
@@ -16,28 +16,32 @@
 
 package com.android.networkstack.tethering;
 
+import static android.system.OsConstants.EAGAIN;
+import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.NETLINK_NETFILTER;
+
 import static com.android.net.module.util.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE;
-import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_DUMP;
-import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
-import static com.android.networkstack.tethering.OffloadHardwareInterface.IPCTNL_MSG_CT_GET;
 import static com.android.networkstack.tethering.OffloadHardwareInterface.IPCTNL_MSG_CT_NEW;
 import static com.android.networkstack.tethering.OffloadHardwareInterface.NFNL_SUBSYS_CTNETLINK;
 import static com.android.networkstack.tethering.OffloadHardwareInterface.NF_NETLINK_CONNTRACK_DESTROY;
 import static com.android.networkstack.tethering.OffloadHardwareInterface.NF_NETLINK_CONNTRACK_NEW;
 
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.NativeHandle;
-import android.system.Os;
+import android.system.ErrnoException;
+import android.util.Log;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.net.module.util.SharedLog;
+import com.android.net.module.util.netlink.ConntrackMessage;
+import com.android.net.module.util.netlink.NetlinkMessage;
+import com.android.net.module.util.netlink.NetlinkSocket;
 import com.android.net.module.util.netlink.StructNlMsgHdr;
 
 import org.junit.Before;
@@ -45,18 +49,18 @@
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
 
+import java.io.FileDescriptor;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
-import java.net.SocketAddress;
 import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class ConntrackSocketTest {
     private static final long TIMEOUT = 500;
+    private static final String TAG = ConntrackSocketTest.class.getSimpleName();
 
     private HandlerThread mHandlerThread;
     private Handler mHandler;
@@ -80,51 +84,72 @@
         mOffloadHw = new OffloadHardwareInterface(mHandler, mLog, mDeps);
     }
 
+    void findConnectionOrThrow(FileDescriptor fd, InetSocketAddress local, InetSocketAddress remote)
+            throws Exception {
+        Log.d(TAG, "Looking for socket " + local + " -> " + remote);
+
+        // Loop until the socket is found (and return) or recvMessage throws an exception.
+        while (true) {
+            final ByteBuffer buffer = NetlinkSocket.recvMessage(fd, DEFAULT_RECV_BUFSIZE, TIMEOUT);
+
+            // Parse all the netlink messages in the dump.
+            // NetlinkMessage#parse returns null if the message is truncated or invalid.
+            while (buffer.remaining() > 0) {
+                NetlinkMessage nlmsg = NetlinkMessage.parse(buffer, NETLINK_NETFILTER);
+                Log.d(TAG, "Got netlink message: " + nlmsg);
+                if (!(nlmsg instanceof ConntrackMessage)) {
+                    continue;
+                }
+
+                StructNlMsgHdr nlmsghdr = nlmsg.getHeader();
+                ConntrackMessage ctmsg = (ConntrackMessage) nlmsg;
+                ConntrackMessage.Tuple tuple = ctmsg.tupleOrig;
+
+                if (nlmsghdr.nlmsg_type == (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_NEW)
+                        && tuple.protoNum == IPPROTO_TCP
+                        && tuple.srcIp.equals(local.getAddress())
+                        && tuple.dstIp.equals(remote.getAddress())
+                        && tuple.srcPort == (short) local.getPort()
+                        && tuple.dstPort == (short) remote.getPort()) {
+                    return;
+                }
+            }
+        }
+    }
+
     @Test
     public void testIpv4ConntrackSocket() throws Exception {
         // Set up server and connect.
-        final InetSocketAddress anyAddress = new InetSocketAddress(
-                InetAddress.getByName("127.0.0.1"), 0);
+        final InetAddress localhost = InetAddress.getByName("127.0.0.1");
+        final InetSocketAddress anyAddress = new InetSocketAddress(localhost, 0);
         final ServerSocket serverSocket = new ServerSocket();
         serverSocket.bind(anyAddress);
-        final SocketAddress theAddress = serverSocket.getLocalSocketAddress();
+        final InetSocketAddress theAddress =
+                (InetSocketAddress) serverSocket.getLocalSocketAddress();
 
         // Make a connection to the server.
         final Socket socket = new Socket();
         socket.connect(theAddress);
+        final InetSocketAddress localAddress = (InetSocketAddress) socket.getLocalSocketAddress();
         final Socket acceptedSocket = serverSocket.accept();
 
         final NativeHandle handle = mDeps.createConntrackSocket(
                 NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
-        mOffloadHw.sendIpv4NfGenMsg(handle,
-                (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
-                (short) (NLM_F_REQUEST | NLM_F_DUMP));
-
-        boolean foundConntrackEntry = false;
-        ByteBuffer buffer = ByteBuffer.allocate(DEFAULT_RECV_BUFSIZE);
-        buffer.order(ByteOrder.nativeOrder());
+        mOffloadHw.requestSocketDump(handle);
 
         try {
-            while (Os.read(handle.getFileDescriptor(), buffer) > 0) {
-                buffer.flip();
-
-                // TODO: ConntrackMessage should get a parse API like StructNlMsgHdr
-                // so we can confirm that the conntrack added is for the TCP connection above.
-                final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(buffer);
-                assertNotNull(nlmsghdr);
-
-                // As long as 1 conntrack entry is found test case will pass, even if it's not
-                // the from the TCP connection above.
-                if (nlmsghdr.nlmsg_type == ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW)) {
-                    foundConntrackEntry = true;
-                    break;
-                }
+            findConnectionOrThrow(handle.getFileDescriptor(), localAddress, theAddress);
+            // No exceptions? Socket was found, test passes.
+        } catch (ErrnoException e) {
+            if (e.errno == EAGAIN) {
+                fail("Did not find socket " + localAddress + "->" + theAddress + " in dump");
+            } else {
+                throw e;
             }
         } finally {
             socket.close();
             serverSocket.close();
+            acceptedSocket.close();
         }
-        assertTrue("Did not receive any NFNL_SUBSYS_CTNETLINK/IPCTNL_MSG_CT_NEW message",
-                foundConntrackEntry);
     }
 }
diff --git a/nearby/halfsheet/res/values-en-rCA/strings.xml b/nearby/halfsheet/res/values-en-rCA/strings.xml
index d4ed675..6094199 100644
--- a/nearby/halfsheet/res/values-en-rCA/strings.xml
+++ b/nearby/halfsheet/res/values-en-rCA/strings.xml
@@ -17,7 +17,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="fast_pair_setup_in_progress" msgid="4158762239172829807">"Starting setup…"</string>
+    <string name="fast_pair_setup_in_progress" msgid="4158762239172829807">"Starting Setup…"</string>
     <string name="fast_pair_title_setup" msgid="2894360355540593246">"Set up device"</string>
     <string name="fast_pair_device_ready" msgid="2903490346082833101">"Device connected"</string>
     <string name="fast_pair_title_fail" msgid="5677174346601290232">"Couldn\'t connect"</string>
diff --git a/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml b/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
index c490cf8..9827f4e 100644
--- a/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
@@ -17,20 +17,20 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="connectivityResourcesAppLabel" msgid="2476261877900882974">"System connectivity resources"</string>
-    <string name="wifi_available_sign_in" msgid="8041178343789805553">"Sign in to a Wi-Fi network"</string>
+    <string name="connectivityResourcesAppLabel" msgid="2476261877900882974">"System Connectivity Resources"</string>
+    <string name="wifi_available_sign_in" msgid="8041178343789805553">"Sign in to Wi-Fi network"</string>
     <string name="network_available_sign_in" msgid="2622520134876355561">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8439369644697866359) -->
     <skip />
-    <string name="wifi_no_internet" msgid="1326348603404555475">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
+    <string name="wifi_no_internet" msgid="1326348603404555475">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no internet access"</string>
     <string name="wifi_no_internet_detailed" msgid="1746921096565304090">"Tap for options"</string>
-    <string name="mobile_no_internet" msgid="4087718456753201450">"Mobile network has no Internet access"</string>
-    <string name="other_networks_no_internet" msgid="5693932964749676542">"Network has no Internet access"</string>
+    <string name="mobile_no_internet" msgid="4087718456753201450">"Mobile network has no internet access"</string>
+    <string name="other_networks_no_internet" msgid="5693932964749676542">"Network has no internet access"</string>
     <string name="private_dns_broken_detailed" msgid="2677123850463207823">"Private DNS server cannot be accessed"</string>
     <string name="network_partial_connectivity" msgid="5549503845834993258">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
     <string name="network_partial_connectivity_detailed" msgid="4732435946300249845">"Tap to connect anyway"</string>
     <string name="network_switch_metered" msgid="5016937523571166319">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="1257300152739542096">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+    <string name="network_switch_metered_detail" msgid="1257300152739542096">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no internet access. Charges may apply."</string>
     <string name="network_switch_metered_toast" msgid="70691146054130335">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3004933964374161223">"mobile data"</item>
diff --git a/service/ServiceConnectivityResources/res/values-eu/strings.xml b/service/ServiceConnectivityResources/res/values-eu/strings.xml
index 2c4e431..9b39fd3 100644
--- a/service/ServiceConnectivityResources/res/values-eu/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-eu/strings.xml
@@ -35,7 +35,7 @@
   <string-array name="network_switch_type_name">
     <item msgid="3004933964374161223">"datu-konexioa"</item>
     <item msgid="5624324321165953608">"Wifia"</item>
-    <item msgid="5667906231066981731">"Bluetooth-a"</item>
+    <item msgid="5667906231066981731">"Bluetootha"</item>
     <item msgid="346574747471703768">"Ethernet-a"</item>
     <item msgid="5734728378097476003">"VPNa"</item>
   </string-array>
diff --git a/service/ServiceConnectivityResources/res/values-nb/strings.xml b/service/ServiceConnectivityResources/res/values-nb/strings.xml
index 4439048..fff6530 100644
--- a/service/ServiceConnectivityResources/res/values-nb/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-nb/strings.xml
@@ -18,7 +18,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="connectivityResourcesAppLabel" msgid="2476261877900882974">"Ressurser for systemtilkobling"</string>
-    <string name="wifi_available_sign_in" msgid="8041178343789805553">"Logg på Wi-Fi-nettverket"</string>
+    <string name="wifi_available_sign_in" msgid="8041178343789805553">"Logg på Wifi-nettverket"</string>
     <string name="network_available_sign_in" msgid="2622520134876355561">"Logg på nettverk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8439369644697866359) -->
     <skip />
diff --git a/service/ServiceConnectivityResources/res/values-ro/strings.xml b/service/ServiceConnectivityResources/res/values-ro/strings.xml
index 4ff5290..bf4479a 100644
--- a/service/ServiceConnectivityResources/res/values-ro/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-ro/strings.xml
@@ -28,7 +28,7 @@
     <string name="other_networks_no_internet" msgid="5693932964749676542">"Rețeaua nu are acces la internet"</string>
     <string name="private_dns_broken_detailed" msgid="2677123850463207823">"Serverul DNS privat nu poate fi accesat"</string>
     <string name="network_partial_connectivity" msgid="5549503845834993258">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> are conectivitate limitată"</string>
-    <string name="network_partial_connectivity_detailed" msgid="4732435946300249845">"Atingeți pentru a vă conecta oricum"</string>
+    <string name="network_partial_connectivity_detailed" msgid="4732435946300249845">"Atinge pentru a te conecta oricum"</string>
     <string name="network_switch_metered" msgid="5016937523571166319">"S-a comutat la <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
     <string name="network_switch_metered_detail" msgid="1257300152739542096">"Dispozitivul folosește <xliff:g id="NEW_NETWORK">%1$s</xliff:g> când <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nu are acces la internet. Se pot aplica taxe."</string>
     <string name="network_switch_metered_toast" msgid="70691146054130335">"S-a comutat de la <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> la <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceBrowserListener.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceBrowserListener.java
index 7a8fcc0..7c19359 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceBrowserListener.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceBrowserListener.java
@@ -28,21 +28,24 @@
 public interface MdnsServiceBrowserListener {
 
     /**
-     * Called when an mDNS service instance is found.
+     * Called when an mDNS service instance is found. This method would be called only if all
+     * service records (PTR, SRV, TXT, A or AAAA) are received .
      *
      * @param serviceInfo The found mDNS service instance.
      */
     void onServiceFound(@NonNull MdnsServiceInfo serviceInfo);
 
     /**
-     * Called when an mDNS service instance is updated.
+     * Called when an mDNS service instance is updated. This method would be called only if all
+     * service records (PTR, SRV, TXT, A or AAAA) are received before.
      *
      * @param serviceInfo The updated mDNS service instance.
      */
     void onServiceUpdated(@NonNull MdnsServiceInfo serviceInfo);
 
     /**
-     * Called when an mDNS service instance is no longer valid and removed.
+     * Called when a mDNS service instance is no longer valid and removed. This method would be
+     * called only if all service records (PTR, SRV, TXT, A or AAAA) are received before.
      *
      * @param serviceInfo The service instance of the removed mDNS service.
      */
@@ -75,4 +78,19 @@
      * @param errorCode            The error code, defined in {@link MdnsResponseErrorCode}.
      */
     void onFailedToParseMdnsResponse(int receivedPacketNumber, int errorCode);
+
+    /**
+     * Called when a mDNS service instance is discovered. This method would be called if the PTR
+     * record has been received.
+     *
+     * @param serviceInfo The discovered mDNS service instance.
+     */
+    void onServiceNameDiscovered(@NonNull MdnsServiceInfo serviceInfo);
+
+    /**
+     * Called when a discovered mDNS service instance is no longer valid and removed.
+     *
+     * @param serviceInfo The service instance of the removed mDNS service.
+     */
+    void onServiceNameRemoved(@NonNull MdnsServiceInfo serviceInfo);
 }
\ 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
index f1b2def..9683bc9 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java
@@ -270,7 +270,8 @@
     public Map<String, String> getAttributes() {
         Map<String, String> map = new HashMap<>(attributes.size());
         for (Map.Entry<String, byte[]> kv : attributes.entrySet()) {
-            map.put(kv.getKey(), new String(kv.getValue(), UTF_8));
+            final byte[] value = kv.getValue();
+            map.put(kv.getKey(), value == null ? null : new String(value, UTF_8));
         }
         return Collections.unmodifiableMap(map);
     }
@@ -342,7 +343,7 @@
             // 2. If there is no '=' in a DNS-SD TXT record string, then it is a
             // boolean attribute, simply identified as being present, with no value.
             if (delimitPos < 0) {
-                return new TextEntry(new String(textBytes, US_ASCII), "");
+                return new TextEntry(new String(textBytes, US_ASCII), (byte[]) null);
             } else if (delimitPos == 0) {
                 return null;
             }
@@ -353,13 +354,13 @@
 
         /** Creates a new {@link TextEntry} with given key and value of a UTF-8 string. */
         public TextEntry(String key, String value) {
-            this(key, value.getBytes(UTF_8));
+            this(key, value == null ? null : value.getBytes(UTF_8));
         }
 
         /** Creates a new {@link TextEntry} with given key and value of a byte array. */
         public TextEntry(String key, byte[] value) {
             this.key = key;
-            this.value = value.clone();
+            this.value = value == null ? null : value.clone();
         }
 
         private TextEntry(Parcel in) {
@@ -372,17 +373,24 @@
         }
 
         public byte[] getValue() {
-            return value.clone();
+            return value == null ? null : value.clone();
         }
 
         /** Converts this {@link TextEntry} instance to '=' separated byte array. */
         public byte[] toBytes() {
-            return ByteUtils.concat(key.getBytes(US_ASCII), new byte[]{'='}, value);
+            final byte[] keyBytes = key.getBytes(US_ASCII);
+            if (value == null) {
+                return keyBytes;
+            }
+            return ByteUtils.concat(keyBytes, new byte[]{'='}, value);
         }
 
         /** Converts this {@link TextEntry} instance to '=' separated string. */
         @Override
         public String toString() {
+            if (value == null) {
+                return key;
+            }
             return key + "=" + new String(value, UTF_8);
         }
 
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
index 0fd6025..dd4ff9b 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
@@ -148,10 +148,11 @@
             this.searchOptions = searchOptions;
             if (listeners.add(listener)) {
                 for (MdnsResponse existingResponse : instanceNameToResponse.values()) {
+                    final MdnsServiceInfo info =
+                            buildMdnsServiceInfoFromResponse(existingResponse, serviceTypeLabels);
+                    listener.onServiceNameDiscovered(info);
                     if (existingResponse.isComplete()) {
-                        listener.onServiceFound(
-                                buildMdnsServiceInfoFromResponse(existingResponse,
-                                        serviceTypeLabels));
+                        listener.onServiceFound(info);
                     }
                 }
             }
@@ -226,6 +227,7 @@
 
         boolean newServiceFound = false;
         boolean existingServiceChanged = false;
+        boolean serviceBecomesComplete = false;
         if (currentResponse == null) {
             newServiceFound = true;
             currentResponse = response;
@@ -233,10 +235,13 @@
             if (serviceInstanceName != null) {
                 instanceNameToResponse.put(serviceInstanceName, currentResponse);
             }
-        } else if (currentResponse.mergeRecordsFrom(response)) {
-            existingServiceChanged = true;
+        } else {
+            boolean before = currentResponse.isComplete();
+            existingServiceChanged = currentResponse.mergeRecordsFrom(response);
+            boolean after = currentResponse.isComplete();
+            serviceBecomesComplete = !before && after;
         }
-        if (!currentResponse.isComplete() || (!newServiceFound && !existingServiceChanged)) {
+        if (!newServiceFound && !existingServiceChanged) {
             return;
         }
         MdnsServiceInfo serviceInfo =
@@ -244,9 +249,15 @@
 
         for (MdnsServiceBrowserListener listener : listeners) {
             if (newServiceFound) {
-                listener.onServiceFound(serviceInfo);
-            } else {
-                listener.onServiceUpdated(serviceInfo);
+                listener.onServiceNameDiscovered(serviceInfo);
+            }
+
+            if (currentResponse.isComplete()) {
+                if (newServiceFound || serviceBecomesComplete) {
+                    listener.onServiceFound(serviceInfo);
+                } else {
+                    listener.onServiceUpdated(serviceInfo);
+                }
             }
         }
     }
@@ -259,7 +270,10 @@
         for (MdnsServiceBrowserListener listener : listeners) {
             final MdnsServiceInfo serviceInfo =
                     buildMdnsServiceInfoFromResponse(response, serviceTypeLabels);
-            listener.onServiceRemoved(serviceInfo);
+            if (response.isComplete()) {
+                listener.onServiceRemoved(serviceInfo);
+            }
+            listener.onServiceNameRemoved(serviceInfo);
         }
     }
 
@@ -423,7 +437,7 @@
                     Iterator<MdnsResponse> iter = instanceNameToResponse.values().iterator();
                     while (iter.hasNext()) {
                         MdnsResponse existingResponse = iter.next();
-                        if (existingResponse.isComplete()
+                        if (existingResponse.hasServiceRecord()
                                 && existingResponse
                                 .getServiceRecord()
                                 .getRemainingTTL(SystemClock.elapsedRealtime())
@@ -436,7 +450,10 @@
                                     final MdnsServiceInfo serviceInfo =
                                             buildMdnsServiceInfoFromResponse(
                                                     existingResponse, serviceTypeLabels);
-                                    listener.onServiceRemoved(serviceInfo);
+                                    if (existingResponse.isComplete()) {
+                                        listener.onServiceRemoved(serviceInfo);
+                                    }
+                                    listener.onServiceNameRemoved(serviceInfo);
                                 }
                             }
                         }
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index aea2103..b8a8fb4 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -281,7 +281,7 @@
         if (sEnableJavaBpfMap == null) {
             sEnableJavaBpfMap = DeviceConfigUtils.isFeatureEnabled(context,
                     DeviceConfig.NAMESPACE_TETHERING, BPF_NET_MAPS_ENABLE_JAVA_BPF_MAP,
-                    SdkLevel.isAtLeastU() /* defaultValue */);
+                    false /* defaultValue */) || SdkLevel.isAtLeastU();
         }
         Log.d(TAG, "BpfNetMaps is initialized with sEnableJavaBpfMap=" + sEnableJavaBpfMap);
 
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 316f9e5..4c9e3a3 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -250,6 +250,7 @@
 import com.android.modules.utils.BasicShellCommandHandler;
 import com.android.modules.utils.build.SdkLevel;
 import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
+import com.android.net.module.util.BinderUtils;
 import com.android.net.module.util.BitUtils;
 import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.DeviceConfigUtils;
@@ -5161,7 +5162,9 @@
             description = settingValue + " (?)";
         }
         pw.println("Avoid bad wifi setting:        " + description);
-        final Boolean configValue = mMultinetworkPolicyTracker.deviceConfigActivelyPreferBadWifi();
+
+        final Boolean configValue = BinderUtils.withCleanCallingIdentity(
+                () -> mMultinetworkPolicyTracker.deviceConfigActivelyPreferBadWifi());
         if (null == configValue) {
             description = "unset";
         } else if (configValue) {
diff --git a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
index e2821cb..3c71c90 100644
--- a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
@@ -155,6 +155,13 @@
         // removing data activity tracking.
         mCtsNetUtils.ensureWifiConnected();
 
+        // There's rate limit to update mobile battery so if ConnectivityService calls
+        // BatteryStatsManager.reportMobileRadioPowerState when default network changed,
+        // the mobile stats might not be updated. But if the mobile update due to other
+        // reasons (plug/unplug, battery level change, etc) will be unaffected. Thus here
+        // dumps the battery stats to trigger a full sync of data.
+        executeShellCommand("dumpsys batterystats");
+
         // Check cellular battery stats are updated.
         runAsShell(UPDATE_DEVICE_STATS,
                 () -> assertStatsEventually(mBsm::getCellularBatteryStats,
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 437622b..8ed735a 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -66,7 +66,6 @@
         "java/android/net/netstats/NetworkStatsDataMigrationUtilsTest.kt",
         "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",
diff --git a/tests/unit/java/android/net/ConnectivityManagerTest.java b/tests/unit/java/android/net/ConnectivityManagerTest.java
index c327868..45a9dbc 100644
--- a/tests/unit/java/android/net/ConnectivityManagerTest.java
+++ b/tests/unit/java/android/net/ConnectivityManagerTest.java
@@ -498,7 +498,7 @@
     public void testConnectivityManagerDoesNotLeakContext() throws Exception {
         final WeakReference<Context> ref = makeConnectivityManagerAndReturnContext();
 
-        final int attempts = 100;
+        final int attempts = 600;
         final long waitIntervalMs = 50;
         for (int i = 0; i < attempts; i++) {
             forceGC();
diff --git a/tests/unit/java/com/android/server/NetworkManagementServiceTest.java b/tests/unit/java/com/android/server/NetworkManagementServiceTest.java
deleted file mode 100644
index 7688a6b..0000000
--- a/tests/unit/java/com/android/server/NetworkManagementServiceTest.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (C) 2012 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.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
-import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
-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.util.DebugUtils.valueToString;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.INetd;
-import android.net.INetdUnsolicitedEventListener;
-import android.net.LinkAddress;
-import android.net.NetworkPolicyManager;
-import android.os.BatteryStats;
-import android.os.Binder;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.Process;
-import android.os.RemoteException;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.ArrayMap;
-
-import com.android.internal.app.IBatteryStats;
-import com.android.server.NetworkManagementService.Dependencies;
-import com.android.server.net.BaseNetworkObserver;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.function.BiFunction;
-
-/**
- * Tests for {@link NetworkManagementService}.
- */
-@RunWith(DevSdkIgnoreRunner.class)
-@SmallTest
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
-public class NetworkManagementServiceTest {
-    private NetworkManagementService mNMService;
-    @Mock private Context mContext;
-    @Mock private ConnectivityManager mCm;
-    @Mock private IBatteryStats.Stub mBatteryStatsService;
-    @Mock private INetd.Stub mNetdService;
-
-    private static final int TEST_UID = 111;
-
-    @NonNull
-    @Captor
-    private ArgumentCaptor<INetdUnsolicitedEventListener> mUnsolListenerCaptor;
-
-    private final MockDependencies mDeps = new MockDependencies();
-
-    private final class MockDependencies extends Dependencies {
-        @Override
-        public IBinder getService(String name) {
-            switch (name) {
-                case BatteryStats.SERVICE_NAME:
-                    return mBatteryStatsService;
-                default:
-                    throw new UnsupportedOperationException("Unknown service " + name);
-            }
-        }
-
-        @Override
-        public void registerLocalService(NetworkManagementInternal nmi) {
-        }
-
-        @Override
-        public INetd getNetd() {
-            return mNetdService;
-        }
-
-        @Override
-        public int getCallingUid() {
-            return Process.SYSTEM_UID;
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        doNothing().when(mNetdService)
-                .registerUnsolicitedEventListener(mUnsolListenerCaptor.capture());
-        doReturn(Context.CONNECTIVITY_SERVICE).when(mContext).getSystemServiceName(
-                eq(ConnectivityManager.class));
-        doReturn(mCm).when(mContext).getSystemService(eq(Context.CONNECTIVITY_SERVICE));
-        // Start the service and wait until it connects to our socket.
-        mNMService = NetworkManagementService.create(mContext, mDeps);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mNMService.shutdown();
-    }
-
-    private static <T> T expectSoon(T mock) {
-        return verify(mock, timeout(200));
-    }
-
-    /**
-     * Tests that network observers work properly.
-     */
-    @Test
-    public void testNetworkObservers() throws Exception {
-        BaseNetworkObserver observer = mock(BaseNetworkObserver.class);
-        doReturn(new Binder()).when(observer).asBinder();  // Used by registerObserver.
-        mNMService.registerObserver(observer);
-
-        // Forget everything that happened to the mock so far, so we can explicitly verify
-        // everything that happens and does not happen to it from now on.
-
-        INetdUnsolicitedEventListener unsolListener = mUnsolListenerCaptor.getValue();
-        reset(observer);
-        // Now call unsolListener methods and ensure that the observer methods are
-        // called. After every method we expect a callback soon after; to ensure that
-        // invalid messages don't cause any callbacks, we call verifyNoMoreInteractions at the end.
-
-        /**
-         * Interface changes.
-         */
-        unsolListener.onInterfaceAdded("rmnet12");
-        expectSoon(observer).interfaceAdded("rmnet12");
-
-        unsolListener.onInterfaceRemoved("eth1");
-        expectSoon(observer).interfaceRemoved("eth1");
-
-        unsolListener.onInterfaceChanged("clat4", true);
-        expectSoon(observer).interfaceStatusChanged("clat4", true);
-
-        unsolListener.onInterfaceLinkStateChanged("rmnet0", false);
-        expectSoon(observer).interfaceLinkStateChanged("rmnet0", false);
-
-        /**
-         * Bandwidth control events.
-         */
-        unsolListener.onQuotaLimitReached("data", "rmnet_usb0");
-        expectSoon(observer).limitReached("data", "rmnet_usb0");
-
-        /**
-         * Interface class activity.
-         */
-        unsolListener.onInterfaceClassActivityChanged(true, 1, 1234, TEST_UID);
-        expectSoon(observer).interfaceClassDataActivityChanged(1, true, 1234, TEST_UID);
-
-        unsolListener.onInterfaceClassActivityChanged(false, 9, 5678, TEST_UID);
-        expectSoon(observer).interfaceClassDataActivityChanged(9, false, 5678, TEST_UID);
-
-        unsolListener.onInterfaceClassActivityChanged(false, 9, 4321, TEST_UID);
-        expectSoon(observer).interfaceClassDataActivityChanged(9, false, 4321, TEST_UID);
-
-        /**
-         * IP address changes.
-         */
-        unsolListener.onInterfaceAddressUpdated("fe80::1/64", "wlan0", 128, 253);
-        expectSoon(observer).addressUpdated("wlan0", new LinkAddress("fe80::1/64", 128, 253));
-
-        unsolListener.onInterfaceAddressRemoved("fe80::1/64", "wlan0", 128, 253);
-        expectSoon(observer).addressRemoved("wlan0", new LinkAddress("fe80::1/64", 128, 253));
-
-        unsolListener.onInterfaceAddressRemoved("2001:db8::1/64", "wlan0", 1, 0);
-        expectSoon(observer).addressRemoved("wlan0", new LinkAddress("2001:db8::1/64", 1, 0));
-
-        /**
-         * DNS information broadcasts.
-         */
-        unsolListener.onInterfaceDnsServerInfo("rmnet_usb0", 3600, new String[]{"2001:db8::1"});
-        expectSoon(observer).interfaceDnsServerInfo("rmnet_usb0", 3600,
-                new String[]{"2001:db8::1"});
-
-        unsolListener.onInterfaceDnsServerInfo("wlan0", 14400,
-                new String[]{"2001:db8::1", "2001:db8::2"});
-        expectSoon(observer).interfaceDnsServerInfo("wlan0", 14400,
-                new String[]{"2001:db8::1", "2001:db8::2"});
-
-        // We don't check for negative lifetimes, only for parse errors.
-        unsolListener.onInterfaceDnsServerInfo("wlan0", -3600, new String[]{"::1"});
-        expectSoon(observer).interfaceDnsServerInfo("wlan0", -3600,
-                new String[]{"::1"});
-
-        // No syntax checking on the addresses.
-        unsolListener.onInterfaceDnsServerInfo("wlan0", 600,
-                new String[]{"", "::", "", "foo", "::1"});
-        expectSoon(observer).interfaceDnsServerInfo("wlan0", 600,
-                new String[]{"", "::", "", "foo", "::1"});
-
-        // Make sure nothing else was called.
-        verifyNoMoreInteractions(observer);
-    }
-
-    @Test
-    public void testFirewallEnabled() {
-        mNMService.setFirewallEnabled(true);
-        assertTrue(mNMService.isFirewallEnabled());
-
-        mNMService.setFirewallEnabled(false);
-        assertFalse(mNMService.isFirewallEnabled());
-    }
-
-    @Test
-    public void testNetworkRestrictedDefault() {
-        assertFalse(mNMService.isNetworkRestricted(TEST_UID));
-    }
-
-    @Test
-    public void testMeteredNetworkRestrictions() throws RemoteException {
-        // Make sure the mocked netd method returns true.
-        doReturn(true).when(mNetdService).bandwidthEnableDataSaver(anyBoolean());
-
-        // Restrict usage of mobile data in background
-        mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, true);
-        assertTrue("Should be true since mobile data usage is restricted",
-                mNMService.isNetworkRestricted(TEST_UID));
-        verify(mCm).addUidToMeteredNetworkDenyList(TEST_UID);
-
-        mNMService.setDataSaverModeEnabled(true);
-        verify(mNetdService).bandwidthEnableDataSaver(true);
-
-        mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, false);
-        assertTrue("Should be true since data saver is on and the uid is not allowlisted",
-                mNMService.isNetworkRestricted(TEST_UID));
-        verify(mCm).removeUidFromMeteredNetworkDenyList(TEST_UID);
-
-        mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, true);
-        assertFalse("Should be false since data saver is on and the uid is allowlisted",
-                mNMService.isNetworkRestricted(TEST_UID));
-        verify(mCm).addUidToMeteredNetworkAllowList(TEST_UID);
-
-        // remove uid from allowlist and turn datasaver off again
-        mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, false);
-        verify(mCm).removeUidFromMeteredNetworkAllowList(TEST_UID);
-        mNMService.setDataSaverModeEnabled(false);
-        verify(mNetdService).bandwidthEnableDataSaver(false);
-        assertFalse("Network should not be restricted when data saver is off",
-                mNMService.isNetworkRestricted(TEST_UID));
-    }
-
-    @Test
-    public void testFirewallChains() {
-        final ArrayMap<Integer, ArrayMap<Integer, Boolean>> expected = new ArrayMap<>();
-        // Dozable chain
-        final ArrayMap<Integer, Boolean> isRestrictedForDozable = new ArrayMap<>();
-        isRestrictedForDozable.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true);
-        isRestrictedForDozable.put(INetd.FIREWALL_RULE_ALLOW, false);
-        isRestrictedForDozable.put(INetd.FIREWALL_RULE_DENY, true);
-        expected.put(FIREWALL_CHAIN_DOZABLE, isRestrictedForDozable);
-        // Powersaver chain
-        final ArrayMap<Integer, Boolean> isRestrictedForPowerSave = new ArrayMap<>();
-        isRestrictedForPowerSave.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true);
-        isRestrictedForPowerSave.put(INetd.FIREWALL_RULE_ALLOW, false);
-        isRestrictedForPowerSave.put(INetd.FIREWALL_RULE_DENY, true);
-        expected.put(FIREWALL_CHAIN_POWERSAVE, isRestrictedForPowerSave);
-        // Standby chain
-        final ArrayMap<Integer, Boolean> isRestrictedForStandby = new ArrayMap<>();
-        isRestrictedForStandby.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, false);
-        isRestrictedForStandby.put(INetd.FIREWALL_RULE_ALLOW, false);
-        isRestrictedForStandby.put(INetd.FIREWALL_RULE_DENY, true);
-        expected.put(FIREWALL_CHAIN_STANDBY, isRestrictedForStandby);
-        // Restricted mode chain
-        final ArrayMap<Integer, Boolean> isRestrictedForRestrictedMode = new ArrayMap<>();
-        isRestrictedForRestrictedMode.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true);
-        isRestrictedForRestrictedMode.put(INetd.FIREWALL_RULE_ALLOW, false);
-        isRestrictedForRestrictedMode.put(INetd.FIREWALL_RULE_DENY, true);
-        expected.put(FIREWALL_CHAIN_RESTRICTED, isRestrictedForRestrictedMode);
-        // Low Power Standby chain
-        final ArrayMap<Integer, Boolean> isRestrictedForLowPowerStandby = new ArrayMap<>();
-        isRestrictedForLowPowerStandby.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true);
-        isRestrictedForLowPowerStandby.put(INetd.FIREWALL_RULE_ALLOW, false);
-        isRestrictedForLowPowerStandby.put(INetd.FIREWALL_RULE_DENY, true);
-        expected.put(FIREWALL_CHAIN_LOW_POWER_STANDBY, isRestrictedForLowPowerStandby);
-
-        final int[] chains = {
-                FIREWALL_CHAIN_STANDBY,
-                FIREWALL_CHAIN_POWERSAVE,
-                FIREWALL_CHAIN_DOZABLE,
-                FIREWALL_CHAIN_RESTRICTED,
-                FIREWALL_CHAIN_LOW_POWER_STANDBY
-        };
-        final int[] states = {
-                INetd.FIREWALL_RULE_ALLOW,
-                INetd.FIREWALL_RULE_DENY,
-                NetworkPolicyManager.FIREWALL_RULE_DEFAULT
-        };
-        BiFunction<Integer, Integer, String> errorMsg = (chain, state) -> {
-            return String.format("Unexpected value for chain: %s and state: %s",
-                    valueToString(INetd.class, "FIREWALL_CHAIN_", chain),
-                    valueToString(INetd.class, "FIREWALL_RULE_", state));
-        };
-        for (int chain : chains) {
-            final ArrayMap<Integer, Boolean> expectedValues = expected.get(chain);
-            mNMService.setFirewallChainEnabled(chain, true);
-            verify(mCm).setFirewallChainEnabled(chain, true /* enabled */);
-            for (int state : states) {
-                mNMService.setFirewallUidRule(chain, TEST_UID, state);
-                assertEquals(errorMsg.apply(chain, state),
-                        expectedValues.get(state), mNMService.isNetworkRestricted(TEST_UID));
-            }
-            mNMService.setFirewallChainEnabled(chain, false);
-            verify(mCm).setFirewallChainEnabled(chain, false /* enabled */);
-        }
-    }
-}
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
index d3934c2..ebdb73f 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
@@ -164,7 +164,8 @@
                         List.of("vn=Alphabet Inc.", "mn=Google Nest Hub Max", "id=12345"),
                         List.of(
                                 MdnsServiceInfo.TextEntry.fromString("vn=Google Inc."),
-                                MdnsServiceInfo.TextEntry.fromString("mn=Google Nest Hub Max")));
+                                MdnsServiceInfo.TextEntry.fromString("mn=Google Nest Hub Max"),
+                                MdnsServiceInfo.TextEntry.fromString("test=")));
 
         beforeParcel.writeToParcel(parcel, 0);
         parcel.setDataPosition(0);
@@ -208,11 +209,11 @@
     }
 
     @Test
-    public void textEntry_fromStringWithoutAssignPunc_valueisEmpty() {
+    public void textEntry_fromStringWithoutAssignPunc_noValue() {
         TextEntry entry = TextEntry.fromString("AA");
 
         assertEquals("AA", entry.getKey());
-        assertArrayEquals(new byte[] {}, entry.getValue());
+        assertNull(entry.getValue());
     }
 
     @Test
@@ -241,11 +242,11 @@
     }
 
     @Test
-    public void textEntry_fromBytesWithoutAssignPunc_valueisEmpty() {
+    public void textEntry_fromBytesWithoutAssignPunc_noValue() {
         TextEntry entry = TextEntry.fromBytes(new byte[] {'A', 'A'});
 
         assertEquals("AA", entry.getKey());
-        assertArrayEquals(new byte[] {}, entry.getValue());
+        assertNull(entry.getValue());
     }
 
     @Test
@@ -270,4 +271,12 @@
         assertEquals(new TextEntry("BB", "xxyyzz"), new TextEntry("BB", "xxyyzz"));
         assertEquals(new TextEntry("AA", "XXYYZZ"), new TextEntry("AA", "XXYYZZ"));
     }
+
+    @Test
+    public void textEntry_fromString_valueIsEmpty() {
+        TextEntry entry = TextEntry.fromString("AA=");
+
+        assertEquals("AA", entry.getKey());
+        assertArrayEquals(new byte[] {}, entry.getValue());
+    }
 }
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
index 6f8b85a..462685a 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
@@ -18,6 +18,7 @@
 
 import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
@@ -26,16 +27,18 @@
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
 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 static java.nio.charset.StandardCharsets.UTF_8;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.InetAddresses;
 import android.text.TextUtils;
 
 import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry;
@@ -49,6 +52,7 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
+import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
@@ -72,7 +76,7 @@
 @RunWith(DevSdkIgnoreRunner.class)
 @DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
 public class MdnsServiceTypeClientTests {
-
+    private static final int INTERFACE_INDEX = 999;
     private static final String SERVICE_TYPE = "_googlecast._tcp.local";
     private static final String[] SERVICE_TYPE_LABELS = TextUtils.split(SERVICE_TYPE, "\\.");
 
@@ -379,15 +383,41 @@
         assertNull(currentThreadExecutor.getAndClearLastScheduledRunnable());
     }
 
+    private static void verifyServiceInfo(MdnsServiceInfo serviceInfo, String serviceName,
+            String[] serviceType, String ipv4Address, String ipv6Address, int port,
+            List<String> subTypes, Map<String, String> attributes, int interfaceIndex) {
+        assertEquals(serviceName, serviceInfo.getServiceInstanceName());
+        assertArrayEquals(serviceType, serviceInfo.getServiceType());
+        assertEquals(ipv4Address, serviceInfo.getIpv4Address());
+        assertEquals(ipv6Address, serviceInfo.getIpv6Address());
+        assertEquals(port, serviceInfo.getPort());
+        assertEquals(subTypes, serviceInfo.getSubtypes());
+        for (String key : attributes.keySet()) {
+            assertEquals(attributes.get(key), serviceInfo.getAttributeByKey(key));
+        }
+        assertEquals(interfaceIndex, serviceInfo.getInterfaceIndex());
+    }
+
     @Test
     public void processResponse_incompleteResponse() {
         client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
 
         MdnsResponse response = mock(MdnsResponse.class);
         when(response.getServiceInstanceName()).thenReturn("service-instance-1");
+        doReturn(INTERFACE_INDEX).when(response).getInterfaceIndex();
         when(response.isComplete()).thenReturn(false);
 
         client.processResponse(response);
+        verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
+        verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
+                "service-instance-1",
+                SERVICE_TYPE_LABELS,
+                null /* ipv4Address */,
+                null /* ipv6Address */,
+                0 /* port */,
+                List.of() /* subTypes */,
+                Collections.singletonMap("key", null) /* attributes */,
+                INTERFACE_INDEX);
 
         verify(mockListenerOne, never()).onServiceFound(any(MdnsServiceInfo.class));
         verify(mockListenerOne, never()).onServiceUpdated(any(MdnsServiceInfo.class));
@@ -404,7 +434,7 @@
                         "service-instance-1",
                         ipV4Address,
                         5353,
-                        Collections.singletonList("ABCDE"),
+                        /* subtype= */ "ABCDE",
                         Collections.emptyMap(),
                         /* interfaceIndex= */ 20);
         client.processResponse(initialResponse);
@@ -415,14 +445,26 @@
                         "service-instance-1",
                         ipV4Address,
                         5354,
-                        Collections.singletonList("ABCDE"),
+                        /* subtype= */ "ABCDE",
                         Collections.singletonMap("key", "value"),
                         /* interfaceIndex= */ 20);
         client.processResponse(secondResponse);
 
+        // Verify onServiceNameDiscovered was called once for the initial response.
+        verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
+        verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
+                "service-instance-1",
+                SERVICE_TYPE_LABELS,
+                ipV4Address /* ipv4Address */,
+                null /* ipv6Address */,
+                5353 /* port */,
+                Collections.singletonList("ABCDE") /* subTypes */,
+                Collections.singletonMap("key", null) /* attributes */,
+                20 /* interfaceIndex */);
+
         // Verify onServiceFound was called once for the initial response.
         verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
-        MdnsServiceInfo initialServiceInfo = serviceInfoCaptor.getAllValues().get(0);
+        MdnsServiceInfo initialServiceInfo = serviceInfoCaptor.getAllValues().get(1);
         assertEquals(initialServiceInfo.getServiceInstanceName(), "service-instance-1");
         assertEquals(initialServiceInfo.getIpv4Address(), ipV4Address);
         assertEquals(initialServiceInfo.getPort(), 5353);
@@ -432,7 +474,7 @@
 
         // Verify onServiceUpdated was called once for the second response.
         verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
-        MdnsServiceInfo updatedServiceInfo = serviceInfoCaptor.getAllValues().get(1);
+        MdnsServiceInfo updatedServiceInfo = serviceInfoCaptor.getAllValues().get(2);
         assertEquals(updatedServiceInfo.getServiceInstanceName(), "service-instance-1");
         assertEquals(updatedServiceInfo.getIpv4Address(), ipV4Address);
         assertEquals(updatedServiceInfo.getPort(), 5354);
@@ -453,7 +495,7 @@
                         "service-instance-1",
                         ipV6Address,
                         5353,
-                        Collections.singletonList("ABCDE"),
+                        /* subtype= */ "ABCDE",
                         Collections.emptyMap(),
                         /* interfaceIndex= */ 20);
         client.processResponse(initialResponse);
@@ -464,7 +506,7 @@
                         "service-instance-1",
                         ipV6Address,
                         5354,
-                        Collections.singletonList("ABCDE"),
+                        /* subtype= */ "ABCDE",
                         Collections.singletonMap("key", "value"),
                         /* interfaceIndex= */ 20);
         client.processResponse(secondResponse);
@@ -472,9 +514,21 @@
         System.out.println("secondResponses ip"
                 + secondResponse.getInet6AddressRecord().getInet6Address().getHostAddress());
 
+        // Verify onServiceNameDiscovered was called once for the initial response.
+        verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
+        verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
+                "service-instance-1",
+                SERVICE_TYPE_LABELS,
+                null /* ipv4Address */,
+                ipV6Address /* ipv6Address */,
+                5353 /* port */,
+                Collections.singletonList("ABCDE") /* subTypes */,
+                Collections.singletonMap("key", null) /* attributes */,
+                20 /* interfaceIndex */);
+
         // Verify onServiceFound was called once for the initial response.
         verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
-        MdnsServiceInfo initialServiceInfo = serviceInfoCaptor.getAllValues().get(0);
+        MdnsServiceInfo initialServiceInfo = serviceInfoCaptor.getAllValues().get(1);
         assertEquals(initialServiceInfo.getServiceInstanceName(), "service-instance-1");
         assertEquals(initialServiceInfo.getIpv6Address(), ipV6Address);
         assertEquals(initialServiceInfo.getPort(), 5353);
@@ -484,7 +538,7 @@
 
         // Verify onServiceUpdated was called once for the second response.
         verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
-        MdnsServiceInfo updatedServiceInfo = serviceInfoCaptor.getAllValues().get(1);
+        MdnsServiceInfo updatedServiceInfo = serviceInfoCaptor.getAllValues().get(2);
         assertEquals(updatedServiceInfo.getServiceInstanceName(), "service-instance-1");
         assertEquals(updatedServiceInfo.getIpv6Address(), ipV6Address);
         assertEquals(updatedServiceInfo.getPort(), 5354);
@@ -494,6 +548,23 @@
         assertEquals(updatedServiceInfo.getInterfaceIndex(), 20);
     }
 
+    private void verifyServiceRemovedNoCallback(MdnsServiceBrowserListener listener) {
+        verify(listener, never()).onServiceRemoved(any());
+        verify(listener, never()).onServiceNameRemoved(any());
+    }
+
+    private void verifyServiceRemovedCallback(MdnsServiceBrowserListener listener,
+            String serviceName, String[] serviceType, int interfaceIndex) {
+        verify(listener).onServiceRemoved(argThat(
+                info -> serviceName.equals(info.getServiceInstanceName())
+                        && Arrays.equals(serviceType, info.getServiceType())
+                        && info.getInterfaceIndex() == interfaceIndex));
+        verify(listener).onServiceNameRemoved(argThat(
+                info -> serviceName.equals(info.getServiceInstanceName())
+                        && Arrays.equals(serviceType, info.getServiceType())
+                        && info.getInterfaceIndex() == interfaceIndex));
+    }
+
     @Test
     public void processResponse_goodBye() throws Exception {
         client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
@@ -501,37 +572,32 @@
 
         final String serviceName = "service-instance-1";
         final String ipV6Address = "2000:3333::da6c:63ff:fe7c:7483";
-        final int interfaceIndex = 999;
         // Process the initial response.
         final MdnsResponse initialResponse =
                 createResponse(
                         serviceName,
                         ipV6Address,
                         5353 /* port */,
-                        Collections.singletonList("ABCDE"),
+                        /* subtype= */ "ABCDE",
                         Collections.emptyMap(),
-                        interfaceIndex);
+                        INTERFACE_INDEX);
         client.processResponse(initialResponse);
         MdnsResponse response = mock(MdnsResponse.class);
         doReturn("goodbye-service").when(response).getServiceInstanceName();
-        doReturn(interfaceIndex).when(response).getInterfaceIndex();
+        doReturn(INTERFACE_INDEX).when(response).getInterfaceIndex();
         doReturn(true).when(response).isGoodbye();
         client.processResponse(response);
-        // Verify onServiceRemoved won't be called if the service is not existed.
-        verify(mockListenerOne, never()).onServiceRemoved(any());
-        verify(mockListenerTwo, never()).onServiceRemoved(any());
+        // Verify removed callback won't be called if the service is not existed.
+        verifyServiceRemovedNoCallback(mockListenerOne);
+        verifyServiceRemovedNoCallback(mockListenerTwo);
 
-        // Verify onServiceRemoved would be called.
+        // Verify removed callback would be called.
         doReturn(serviceName).when(response).getServiceInstanceName();
         client.processResponse(response);
-        verify(mockListenerOne).onServiceRemoved(argThat(
-                info -> serviceName.equals(info.getServiceInstanceName())
-                        && Arrays.equals(SERVICE_TYPE_LABELS, info.getServiceType())
-                        && info.getInterfaceIndex() == interfaceIndex));
-        verify(mockListenerTwo).onServiceRemoved(argThat(
-                info -> serviceName.equals(info.getServiceInstanceName())
-                        && Arrays.equals(SERVICE_TYPE_LABELS, info.getServiceType())
-                        && info.getInterfaceIndex() == interfaceIndex));
+        verifyServiceRemovedCallback(
+                mockListenerOne, serviceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX);
+        verifyServiceRemovedCallback(
+                mockListenerTwo, serviceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX);
     }
 
     @Test
@@ -542,15 +608,28 @@
                         "service-instance-1",
                         "192.168.1.1",
                         5353,
-                        Collections.singletonList("ABCDE"),
-                        Collections.emptyMap());
+                        /* subtype= */ "ABCDE",
+                        Collections.emptyMap(),
+                        INTERFACE_INDEX);
         client.processResponse(initialResponse);
 
         client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
 
+        // Verify onServiceNameDiscovered was called once for the existing response.
+        verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
+        verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
+                "service-instance-1",
+                SERVICE_TYPE_LABELS,
+                "192.168.1.1" /* ipv4Address */,
+                null /* ipv6Address */,
+                5353 /* port */,
+                Collections.singletonList("ABCDE") /* subTypes */,
+                Collections.singletonMap("key", null) /* attributes */,
+                INTERFACE_INDEX);
+
         // Verify onServiceFound was called once for the existing response.
         verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
-        MdnsServiceInfo existingServiceInfo = serviceInfoCaptor.getAllValues().get(0);
+        MdnsServiceInfo existingServiceInfo = serviceInfoCaptor.getAllValues().get(1);
         assertEquals(existingServiceInfo.getServiceInstanceName(), "service-instance-1");
         assertEquals(existingServiceInfo.getIpv4Address(), "192.168.1.1");
         assertEquals(existingServiceInfo.getPort(), 5353);
@@ -567,6 +646,7 @@
 
         // Verify onServiceFound was not called on the newly registered listener after the existing
         // response is gone.
+        verify(mockListenerTwo, never()).onServiceNameDiscovered(any(MdnsServiceInfo.class));
         verify(mockListenerTwo, never()).onServiceFound(any(MdnsServiceInfo.class));
     }
 
@@ -580,9 +660,9 @@
 
         // Process the initial response.
         MdnsResponse initialResponse =
-                createResponse(
+                createMockResponse(
                         serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
-                        Map.of());
+                        Map.of(), INTERFACE_INDEX);
         client.processResponse(initialResponse);
 
         // Clear the scheduled runnable.
@@ -592,8 +672,8 @@
         when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
         firstMdnsTask.run();
 
-        // Verify onServiceRemoved was not called.
-        verify(mockListenerOne, never()).onServiceRemoved(any());
+        // Verify removed callback was not called.
+        verifyServiceRemovedNoCallback(mockListenerOne);
     }
 
     @Test
@@ -614,9 +694,9 @@
 
         // Process the initial response.
         MdnsResponse initialResponse =
-                createResponse(
+                createMockResponse(
                         serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
-                        Map.of(), 999 /* interfaceIndex */);
+                        Map.of(), INTERFACE_INDEX);
         client.processResponse(initialResponse);
 
         // Clear the scheduled runnable.
@@ -626,18 +706,16 @@
         when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 1000);
         firstMdnsTask.run();
 
-        // Verify onServiceRemoved was not called.
-        verify(mockListenerOne, never()).onServiceRemoved(any());
+        // Verify removed callback was not called.
+        verifyServiceRemovedNoCallback(mockListenerOne);
 
         // 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(argThat(
-                info -> serviceInstanceName.equals(info.getServiceInstanceName())
-                        && Arrays.equals(SERVICE_TYPE_LABELS, info.getServiceType())
-                        && info.getInterfaceIndex() == 999));
+        // Verify removed callback was called.
+        verifyServiceRemovedCallback(
+                mockListenerOne, serviceInstanceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX);
     }
 
     @Test
@@ -656,9 +734,9 @@
 
         // Process the initial response.
         MdnsResponse initialResponse =
-                createResponse(
+                createMockResponse(
                         serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
-                        Map.of());
+                        Map.of(), INTERFACE_INDEX);
         client.processResponse(initialResponse);
 
         // Clear the scheduled runnable.
@@ -668,8 +746,8 @@
         when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
         firstMdnsTask.run();
 
-        // Verify onServiceRemoved was not called.
-        verify(mockListenerOne, never()).onServiceRemoved(any());
+        // Verify removed callback was not called.
+        verifyServiceRemovedNoCallback(mockListenerOne);
     }
 
     @Test
@@ -690,9 +768,9 @@
 
         // Process the initial response.
         MdnsResponse initialResponse =
-                createResponse(
+                createMockResponse(
                         serviceInstanceName, "192.168.1.1", 5353, List.of("ABCDE"),
-                        Map.of(), 999 /* interfaceIndex */);
+                        Map.of(), INTERFACE_INDEX);
         client.processResponse(initialResponse);
 
         // Clear the scheduled runnable.
@@ -702,11 +780,117 @@
         when(initialResponse.getServiceRecord().getRemainingTTL(anyLong())).thenReturn((long) 0);
         firstMdnsTask.run();
 
-        // Verify onServiceRemoved was called.
-        verify(mockListenerOne, times(1)).onServiceRemoved(argThat(
-                info -> serviceInstanceName.equals(info.getServiceInstanceName())
-                        && Arrays.equals(SERVICE_TYPE_LABELS, info.getServiceType())
-                        && info.getInterfaceIndex() == 999));
+        // Verify removed callback was called.
+        verifyServiceRemovedCallback(
+                mockListenerOne, serviceInstanceName, SERVICE_TYPE_LABELS, INTERFACE_INDEX);
+    }
+
+    @Test
+    public void testProcessResponse_InOrder() throws Exception {
+        final String serviceName = "service-instance";
+        final String ipV4Address = "192.0.2.0";
+        final String ipV6Address = "2001:db8::";
+        client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+        InOrder inOrder = inOrder(mockListenerOne);
+
+        // Process the initial response which is incomplete.
+        final MdnsResponse initialResponse =
+                createResponse(
+                        serviceName,
+                        null,
+                        5353,
+                        "ABCDE" /* subtype */,
+                        Collections.emptyMap(),
+                        INTERFACE_INDEX);
+        client.processResponse(initialResponse);
+
+        // Process a second response which has ip address to make response become complete.
+        final MdnsResponse secondResponse =
+                createResponse(
+                        serviceName,
+                        ipV4Address,
+                        5353,
+                        "ABCDE" /* subtype */,
+                        Collections.emptyMap(),
+                        INTERFACE_INDEX);
+        client.processResponse(secondResponse);
+
+        // Process a third response with a different ip address, port and updated text attributes.
+        final MdnsResponse thirdResponse =
+                createResponse(
+                        serviceName,
+                        ipV6Address,
+                        5354,
+                        "ABCDE" /* subtype */,
+                        Collections.singletonMap("key", "value"),
+                        INTERFACE_INDEX);
+        client.processResponse(thirdResponse);
+
+        // Process the last response which is goodbye message.
+        final MdnsResponse lastResponse = mock(MdnsResponse.class);
+        doReturn(serviceName).when(lastResponse).getServiceInstanceName();
+        doReturn(true).when(lastResponse).isGoodbye();
+        client.processResponse(lastResponse);
+
+        // Verify onServiceNameDiscovered was first called for the initial response.
+        inOrder.verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
+        verifyServiceInfo(serviceInfoCaptor.getAllValues().get(0),
+                serviceName,
+                SERVICE_TYPE_LABELS,
+                null /* ipv4Address */,
+                null /* ipv6Address */,
+                5353 /* port */,
+                Collections.singletonList("ABCDE") /* subTypes */,
+                Collections.singletonMap("key", null) /* attributes */,
+                INTERFACE_INDEX);
+
+        // Verify onServiceFound was second called for the second response.
+        inOrder.verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
+        verifyServiceInfo(serviceInfoCaptor.getAllValues().get(1),
+                serviceName,
+                SERVICE_TYPE_LABELS,
+                ipV4Address /* ipv4Address */,
+                null /* ipv6Address */,
+                5353 /* port */,
+                Collections.singletonList("ABCDE") /* subTypes */,
+                Collections.singletonMap("key", null) /* attributes */,
+                INTERFACE_INDEX);
+
+        // Verify onServiceUpdated was third called for the third response.
+        inOrder.verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
+        verifyServiceInfo(serviceInfoCaptor.getAllValues().get(2),
+                serviceName,
+                SERVICE_TYPE_LABELS,
+                ipV4Address /* ipv4Address */,
+                ipV6Address /* ipv6Address */,
+                5354 /* port */,
+                Collections.singletonList("ABCDE") /* subTypes */,
+                Collections.singletonMap("key", "value") /* attributes */,
+                INTERFACE_INDEX);
+
+        // Verify onServiceRemoved was called for the last response.
+        inOrder.verify(mockListenerOne).onServiceRemoved(serviceInfoCaptor.capture());
+        verifyServiceInfo(serviceInfoCaptor.getAllValues().get(3),
+                serviceName,
+                SERVICE_TYPE_LABELS,
+                ipV4Address /* ipv4Address */,
+                ipV6Address /* ipv6Address */,
+                5354 /* port */,
+                Collections.singletonList("ABCDE") /* subTypes */,
+                Collections.singletonMap("key", "value") /* attributes */,
+                INTERFACE_INDEX);
+
+        // Verify onServiceNameRemoved was called for the last response.
+        inOrder.verify(mockListenerOne).onServiceNameRemoved(serviceInfoCaptor.capture());
+        verifyServiceInfo(serviceInfoCaptor.getAllValues().get(4),
+                serviceName,
+                SERVICE_TYPE_LABELS,
+                ipV4Address /* ipv4Address */,
+                ipV6Address /* ipv6Address */,
+                5354 /* port */,
+                Collections.singletonList("ABCDE") /* subTypes */,
+                Collections.singletonMap("key", "value") /* attributes */,
+                INTERFACE_INDEX);
     }
 
     // verifies that the right query was enqueued with the right delay, and send query by executing
@@ -771,19 +955,8 @@
         }
     }
 
-    private MdnsResponse createResponse(
-            @NonNull String serviceInstanceName,
-            @NonNull String host,
-            int port,
-            @NonNull List<String> subtypes,
-            @NonNull Map<String, String> textAttributes)
-            throws Exception {
-        return createResponse(serviceInstanceName, host, port, subtypes, textAttributes,
-                /* interfaceIndex= */ -1);
-    }
-
-    // Creates a complete mDNS response.
-    private MdnsResponse createResponse(
+    // Creates a mock mDNS response.
+    private MdnsResponse createMockResponse(
             @NonNull String serviceInstanceName,
             @NonNull String host,
             int port,
@@ -830,4 +1003,73 @@
         doReturn(new ArrayList<>(subtypes)).when(response).getSubtypes();
         return response;
     }
+
+    // Creates a mDNS response.
+    private MdnsResponse createResponse(
+            @NonNull String serviceInstanceName,
+            @Nullable String host,
+            int port,
+            @NonNull String subtype,
+            @NonNull Map<String, String> textAttributes,
+            int interfaceIndex)
+            throws Exception {
+        MdnsResponse response = new MdnsResponse(0);
+        response.setInterfaceIndex(interfaceIndex);
+
+        // Set PTR record
+        final MdnsPointerRecord pointerRecord = new MdnsPointerRecord(
+                new String[]{subtype, MdnsConstants.SUBTYPE_LABEL, "test"} /* name */,
+                0L /* receiptTimeMillis */,
+                false /* cacheFlush */,
+                120000L /* ttlMillis */,
+                new String[]{serviceInstanceName});
+        response.addPointerRecord(pointerRecord);
+
+        // Set SRV record.
+        final MdnsServiceRecord serviceRecord = new MdnsServiceRecord(
+                new String[] {"service"} /* name */,
+                0L /* receiptTimeMillis */,
+                false /* cacheFlush */,
+                120000L /* ttlMillis */,
+                0 /* servicePriority */,
+                0 /* serviceWeight */,
+                port,
+                new String[]{"hostname"});
+        response.setServiceRecord(serviceRecord);
+
+        // Set A/AAAA record.
+        if (host != null) {
+            if (InetAddresses.parseNumericAddress(host) instanceof Inet6Address) {
+                final MdnsInetAddressRecord inetAddressRecord = new MdnsInetAddressRecord(
+                        new String[] {"address"} /* name */,
+                        0L /* receiptTimeMillis */,
+                        false /* cacheFlush */,
+                        120000L /* ttlMillis */,
+                        Inet6Address.getByName(host));
+                response.setInet6AddressRecord(inetAddressRecord);
+            } else {
+                final MdnsInetAddressRecord inetAddressRecord = new MdnsInetAddressRecord(
+                        new String[] {"address"} /* name */,
+                        0L /* receiptTimeMillis */,
+                        false /* cacheFlush */,
+                        120000L /* ttlMillis */,
+                        Inet4Address.getByName(host));
+                response.setInet4AddressRecord(inetAddressRecord);
+            }
+        }
+
+        // Set TXT record.
+        final List<TextEntry> textEntries = new ArrayList<>();
+        for (Map.Entry<String, String> kv : textAttributes.entrySet()) {
+            textEntries.add(new TextEntry(kv.getKey(), kv.getValue().getBytes(UTF_8)));
+        }
+        final MdnsTextRecord textRecord = new MdnsTextRecord(
+                new String[] {"text"} /* name */,
+                0L /* receiptTimeMillis */,
+                false /* cacheFlush */,
+                120000L /* ttlMillis */,
+                textEntries);
+        response.setTextRecord(textRecord);
+        return response;
+    }
 }
\ No newline at end of file
diff --git a/tools/gn2bp/Android.bp.swp b/tools/gn2bp/Android.bp.swp
index e6f3978..f8f2b6a 100644
--- a/tools/gn2bp/Android.bp.swp
+++ b/tools/gn2bp/Android.bp.swp
@@ -2356,31 +2356,10 @@
         "base/metrics/histogram_base.h",
         "base/task/task_traits.h",
         "build/android/gyp/java_cpp_enum.py",
-    ],
-}
-
-// GN: //base:base_java_aidl
-java_genrule {
-    name: "cronet_aml_base_base_java_aidl",
-    cmd: "$(location build/android/gyp/aidl.py) --aidl-path " +
-         "../../third_party/android_sdk/public/build-tools/33.0.0/aidl " +
-         "--imports " +
-         "[\"../../third_party/android_sdk/public/platforms/android-33/framework.aidl\"] " +
-         "--srcjar " +
-         "gen/base/base_java_aidl.srcjar " +
-         "--depfile " +
-         "gen/base/base_java_aidl.d " +
-         "--includes " +
-         "[\"../../base/android/java/src\"] " +
-         "../../base/android/java/src/org/chromium/base/process_launcher/IChildProcessService.aidl " +
-         "../../base/android/java/src/org/chromium/base/process_launcher/IParentProcess.aidl",
-    out: [
-        "base/base_java_aidl.srcjar",
-    ],
-    tool_files: [
-        "base/android/java/src/org/chromium/base/process_launcher/IChildProcessService.aidl",
-        "base/android/java/src/org/chromium/base/process_launcher/IParentProcess.aidl",
-        "build/android/gyp/aidl.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
     ],
 }
 
@@ -4231,18 +4210,22 @@
         "base/task/task_features.cc",
     ],
     cmd: "$(location build/android/gyp/java_cpp_features.py) --srcjar " +
-         "gen/base/java_features_srcjar.srcjar " +
+         "$(out) " +
          "--template " +
-         "../../base/android/java/src/org/chromium/base/BaseFeatures.java.tmpl " +
-         "../../base/android/base_features.cc " +
-         "../../base/features.cc " +
-         "../../base/task/task_features.cc",
+         "$(location base/android/java/src/org/chromium/base/BaseFeatures.java.tmpl) " +
+         "$(location base/android/base_features.cc) " +
+         "$(location base/features.cc) " +
+         "$(location base/task/task_features.cc)",
     out: [
         "base/java_features_srcjar.srcjar",
     ],
     tool_files: [
         "base/android/java/src/org/chromium/base/BaseFeatures.java.tmpl",
         "build/android/gyp/java_cpp_features.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
     ],
 }
 
@@ -4253,16 +4236,20 @@
         "base/base_switches.cc",
     ],
     cmd: "$(location build/android/gyp/java_cpp_strings.py) --srcjar " +
-         "gen/base/java_switches_srcjar.srcjar " +
+         "$(out) " +
          "--template " +
-         "../../base/android/java/src/org/chromium/base/BaseSwitches.java.tmpl " +
-         "../../base/base_switches.cc",
+         "$(location base/android/java/src/org/chromium/base/BaseSwitches.java.tmpl) " +
+         "$(location base/base_switches.cc)",
     out: [
         "base/java_switches_srcjar.srcjar",
     ],
     tool_files: [
         "base/android/java/src/org/chromium/base/BaseSwitches.java.tmpl",
         "build/android/gyp/java_cpp_strings.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
     ],
 }
 
@@ -5698,7 +5685,10 @@
     ],
     tool_files: [
         "build/android/gyp/gcc_preprocess.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
         "build/android/java/templates/BuildConfig.template",
+        "build/gn_helpers.py",
     ],
 }
 
@@ -5706,7 +5696,7 @@
 java_genrule {
     name: "cronet_aml_build_android_native_libraries_gen",
     cmd: "$(location build/android/gyp/write_native_libraries_java.py) --output " +
-         "gen/build/android/native_libraries_gen.srcjar " +
+         "$(out) " +
          "--cpu-family " +
          "CPU_FAMILY_ARM",
     out: [
@@ -7829,6 +7819,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "components/cronet/url_request_context_config.h",
     ],
 }
@@ -7841,7 +7835,7 @@
          "-f " +
          "$(location build/util/LASTCHANGE) " +
          "-e " +
-         "API_LEVEL=20 " +
+         "'API_LEVEL=20' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/android/java/src/org/chromium/net/impl/ImplVersion.template)",
@@ -7870,6 +7864,9 @@
     ],
     tool_files: [
         "build/android/gyp/gcc_preprocess.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/gn_helpers.py",
         "components/cronet/android/java/src/org/chromium/net/impl/IntegratedModeState.template",
     ],
 }
@@ -7882,7 +7879,7 @@
          "-f " +
          "$(location build/util/LASTCHANGE) " +
          "-e " +
-         "API_LEVEL=20 " +
+         "'API_LEVEL=20' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/android/api/src/org/chromium/net/ApiVersion.template)",
@@ -7911,7 +7908,11 @@
     ],
     tool_files: [
         "build/android/gyp/gcc_preprocess.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/gn_helpers.py",
         "components/cronet/android/java/src/org/chromium/net/impl/LoadState.template",
+        "net/base/load_states_list.h",
     ],
 }
 
@@ -7926,6 +7927,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/base/idempotency.h",
     ],
 }
@@ -7941,6 +7946,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/base/request_priority.h",
     ],
 }
@@ -7956,6 +7965,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/nqe/network_quality_observation_source.h",
     ],
 }
@@ -7971,6 +7984,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/nqe/network_quality.h",
     ],
 }
@@ -7986,6 +8003,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "components/cronet/android/url_request_error.h",
     ],
 }
@@ -8261,7 +8282,7 @@
     cmd: "$(location build/util/version.py) -f " +
          "$(location chrome/VERSION) " +
          "-e " +
-         "VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH) " +
+         "'VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/version.h.in)",
@@ -8286,7 +8307,7 @@
     cmd: "$(location build/util/version.py) -f " +
          "$(location chrome/VERSION) " +
          "-e " +
-         "VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH) " +
+         "'VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/version.h.in)",
@@ -8311,7 +8332,7 @@
     cmd: "$(location build/util/version.py) -f " +
          "$(location chrome/VERSION) " +
          "-e " +
-         "VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH) " +
+         "'VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/version.h.in)",
@@ -8336,7 +8357,7 @@
     cmd: "$(location build/util/version.py) -f " +
          "$(location chrome/VERSION) " +
          "-e " +
-         "VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH) " +
+         "'VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)' " +
          "-o " +
          "$(out) " +
          "$(location components/cronet/version.h.in)",
@@ -9601,6 +9622,8 @@
         "base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionFactory.java",
         "base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionImpl.java",
         "base/android/java/src/org/chromium/base/process_launcher/FileDescriptorInfo.java",
+        "base/android/java/src/org/chromium/base/process_launcher/IChildProcessService.aidl",
+        "base/android/java/src/org/chromium/base/process_launcher/IParentProcess.aidl",
         "base/android/java/src/org/chromium/base/supplier/BooleanSupplier.java",
         "base/android/java/src/org/chromium/base/supplier/DestroyableObservableSupplier.java",
         "base/android/java/src/org/chromium/base/supplier/ObservableSupplier.java",
@@ -9765,6 +9788,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/android/cert_verify_result_android.h",
         "net/android/keystore.h",
         "net/base/network_change_notifier.h",
@@ -9784,7 +9811,11 @@
     ],
     tool_files: [
         "build/android/gyp/gcc_preprocess.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/gn_helpers.py",
         "net/android/java/NetError.template",
+        "net/base/net_error_list.h",
     ],
 }
 
@@ -11090,6 +11121,10 @@
     ],
     tool_files: [
         "build/android/gyp/java_cpp_enum.py",
+        "build/android/gyp/util/__init__.py",
+        "build/android/gyp/util/build_utils.py",
+        "build/android/gyp/util/java_cpp_utils.py",
+        "build/gn_helpers.py",
         "net/nqe/effective_connection_type.h",
     ],
 }
diff --git a/tools/gn2bp/gen_android_bp b/tools/gn2bp/gen_android_bp
index ef05126..233e6f8 100755
--- a/tools/gn2bp/gen_android_bp
+++ b/tools/gn2bp/gen_android_bp
@@ -746,6 +746,23 @@
   def get_outputs(self):
     return self.target.outputs
 
+  def get_srcs(self):
+    # gn treats inputs and sources for actions equally.
+    # soong only supports source files inside srcs, non-source files are added as
+    # tool_files dependency.
+    files = self.target.sources.union(self.target.inputs)
+    return {gn_utils.label_to_path(file) for file in files if is_supported_source_file(file)}
+
+  def get_tool_files(self):
+    # gn treats inputs and sources for actions equally.
+    # soong only supports source files inside srcs, non-source files are added as
+    # tool_files dependency.
+    files = self.target.sources.union(self.target.inputs)
+    tool_files = {gn_utils.label_to_path(file)
+                  for file in files if not is_supported_source_file(file)}
+    tool_files.add(gn_utils.label_to_path(self.target.script))
+    return tool_files
+
   def _sanitize_args(self):
     # Handle passing parameters via response file by piping them into the script
     # and reading them from /dev/stdin.
@@ -759,9 +776,13 @@
   def _sanitize_outputs(self):
     pass
 
+  def _sanitize_inputs(self):
+    pass
+
   def sanitize(self):
     self._sanitize_args()
     self._sanitize_outputs()
+    self._sanitize_inputs()
 
   # Whether this target generates header files
   def is_header_generated(self):
@@ -803,7 +824,17 @@
     self.target.outputs = {re.sub('^jni_headers/', '', out) for out in self.target.outputs}
     super()._sanitize_outputs()
 
+  def get_tool_files(self):
+    tool_files = super().get_tool_files()
+    # android_jar.classes should be part of the tools as it list implicit classes
+    # for the script to generate JNI headers.
+    tool_files.add("base/android/jni_generator/android_jar.classes")
+    return tool_files
+
 class JniRegistrationGeneratorSanitizer(BaseActionSanitizer):
+  def _sanitize_inputs(self):
+    self.target.inputs = [file for file in self.target.inputs if not file.startswith('//out/')]
+
   def _sanitize_args(self):
     self._update_value_arg('--depfile', self._sanitize_filepath)
     self._update_value_arg('--srcjar-path', self._sanitize_filepath)
@@ -849,8 +880,15 @@
     # args for the version.py contain file path without leading --arg key. So apply sanitize
     # function for all the args.
     self._update_all_args(self._sanitize_filepath_with_location_tag)
+    self._set_value_arg('-e', "'%s'" % self._get_value_arg('-e'))
     super()._sanitize_args()
 
+  def get_tool_files(self):
+    tool_files = super().get_tool_files()
+    # android_chrome_version.py is not specified in anywhere but version.py imports this file
+    tool_files.add('build/util/android_chrome_version.py')
+    return tool_files
+
 class JavaCppEnumSanitizer(BaseActionSanitizer):
   def _sanitize_args(self):
     self._update_all_args(self._sanitize_filepath_with_location_tag)
@@ -863,6 +901,23 @@
     # (e.g. registry_controlled_domain.cc)
     return True
 
+class JavaCppFeatureSanitizer(BaseActionSanitizer):
+  def _sanitize_args(self):
+    self._update_all_args(self._sanitize_filepath_with_location_tag)
+    self._set_value_arg('--srcjar', '$(out)')
+    super()._sanitize_args()
+
+class JavaCppStringSanitizer(BaseActionSanitizer):
+  def _sanitize_args(self):
+    self._update_all_args(self._sanitize_filepath_with_location_tag)
+    self._set_value_arg('--srcjar', '$(out)')
+    super()._sanitize_args()
+
+class WriteNativeLibrariesJavaSanitizer(BaseActionSanitizer):
+  def _sanitize_args(self):
+    self._set_value_arg('--output', '$(out)')
+    super()._sanitize_args()
+
 def get_action_sanitizer(target, type):
   if target.script == "//build/write_buildflag_header.py":
     return WriteBuildFlagHeaderSanitizer(target)
@@ -881,6 +936,12 @@
     return JavaCppEnumSanitizer(target)
   elif target.script == "//net/tools/dafsa/make_dafsa.py":
     return MakeDafsaSanitizer(target)
+  elif target.script == '//build/android/gyp/java_cpp_features.py':
+    return JavaCppFeatureSanitizer(target)
+  elif target.script == '//build/android/gyp/java_cpp_strings.py':
+    return JavaCppStringSanitizer(target)
+  elif target.script == '//build/android/gyp/write_native_libraries_java.py':
+    return WriteNativeLibrariesJavaSanitizer(target)
   else:
     # TODO: throw exception here once all script hacks have been converted.
     return BaseActionSanitizer(target)
@@ -921,39 +982,14 @@
 def create_action_module(blueprint, target, type):
   sanitizer = get_action_sanitizer(target, type)
   sanitizer.sanitize()
+
   module = Module(type, sanitizer.get_name(), target.name)
   module.cmd = sanitizer.get_cmd()
   module.out = sanitizer.get_outputs()
   if sanitizer.is_header_generated():
     module.genrule_headers.add(module.name)
-
-  if target.script == '//base/android/jni_generator/jni_generator.py':
-    # android_jar.classes should be part of the tools as it list implicit classes
-    # for the script to generate JNI headers.
-    module.tool_files.add("base/android/jni_generator/android_jar.classes")
-
-  elif target.script == '//base/android/jni_generator/jni_registration_generator.py':
-    # jni_registration_generator.py pulls in some config dependencies that we
-    # do not handle. Remove them.
-    # TODO: find a better way to do this.
-    target.deps.clear()
-
-    target.inputs = [file for file in target.inputs if not file.startswith('//out/')]
-  elif target.script == "//build/util/version.py":
-    # android_chrome_version.py is not specified in anywhere but version.py imports this file
-    module.tool_files.add('build/util/android_chrome_version.py')
-
-  script = gn_utils.label_to_path(target.script)
-  module.tool_files.add(script)
-
-  # gn treats inputs and sources for actions equally.
-  # soong only supports source files inside srcs, non-source files are added as
-  # tool_files dependency.
-  for it in target.sources or target.inputs:
-    if is_supported_source_file(it):
-      module.srcs.add(gn_utils.label_to_path(it))
-    else:
-      module.tool_files.add(gn_utils.label_to_path(it))
+  module.srcs = sanitizer.get_srcs()
+  module.tool_files = sanitizer.get_tool_files()
 
   blueprint.add_module(module)
   return module
@@ -1230,7 +1266,8 @@
 
   # TODO: java_sources might not contain all the required java files
   module.srcs.update([gn_utils.label_to_path(source)
-                      for source in gn.java_sources if source not in deny_list])
+                      for source in gn.java_sources
+                      if source.endswith('.java') and source not in deny_list])
 
 def create_blueprint_for_targets(gn, targets):
   """Generate a blueprint for a list of GN targets."""
diff --git a/tools/gn2bp/gn_utils.py b/tools/gn2bp/gn_utils.py
index 0511e8a..130f8ff 100644
--- a/tools/gn2bp/gn_utils.py
+++ b/tools/gn2bp/gn_utils.py
@@ -429,7 +429,13 @@
           java_srcs = [src for src in dep.inputs if _is_java_source(src)]
           self.java_sources.update(java_srcs)
       if dep.type in ["action"] and target.type == "java_group":
-        self.java_actions.add(dep.name)
+        # //base:base_java_aidl generates srcjar from .aidl files. But java_library in soong can
+        # directly have .aidl files in srcs. So adding .aidl files to the java_sources.
+        # TODO: Find a better way/place to do this.
+        if dep.name == '//base:base_java_aidl':
+          self.java_sources.update(dep.arch[arch].sources)
+        else:
+          self.java_actions.add(dep.name)
     return target
 
   def get_proto_exports(self, proto_desc):
