diff --git a/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java b/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
index 11fc6df..fef085d 100644
--- a/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
@@ -41,6 +41,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.annotation.NonNull;
 import android.app.AppOpsManager;
 import android.app.Instrumentation;
 import android.app.usage.NetworkStats;
@@ -68,13 +69,16 @@
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.android.compatibility.common.util.ShellIdentityUtils;
 import com.android.compatibility.common.util.SystemUtil;
 import com.android.modules.utils.build.SdkLevel;
+import com.android.testutils.AutoReleaseNetworkCallbackRule;
 import com.android.testutils.ConnectivityModuleTest;
 import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+import com.android.testutils.RecorderCallback.CallbackEntry;
+import com.android.testutils.TestableNetworkCallback;
 
 import org.junit.After;
 import org.junit.Before;
@@ -95,12 +99,18 @@
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
-@ConnectivityModuleTest
+// TODO: Fix thread leaks in testCallback and annotating with @MonitorThreadLeak.
 @AppModeFull(reason = "instant apps cannot be granted USAGE_STATS")
-@RunWith(AndroidJUnit4.class)
+@ConnectivityModuleTest
+@DevSdkIgnoreRunner.RestoreDefaultNetwork
+@RunWith(DevSdkIgnoreRunner.class)
 public class NetworkStatsManagerTest {
-    @Rule
+    @Rule(order = 1)
     public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(Build.VERSION_CODES.Q);
+    @Rule(order = 2)
+    public final AutoReleaseNetworkCallbackRule
+            networkCallbackRule = new AutoReleaseNetworkCallbackRule();
+
 
     private static final String LOG_TAG = "NetworkStatsManagerTest";
     private static final String APPOPS_SET_SHELL_COMMAND = "appops set {0} {1} {2}";
@@ -119,12 +129,19 @@
     private static final long LONG_TOLERANCE = MINUTE * 120;
 
     private abstract class NetworkInterfaceToTest {
+
+        final TestableNetworkCallback mRequestNetworkCb = new TestableNetworkCallback();
         private boolean mMetered;
         private boolean mRoaming;
         private boolean mIsDefault;
 
         abstract int getNetworkType();
-        abstract int getTransportType();
+
+        abstract Network requestNetwork();
+
+        void unrequestNetwork() {
+            networkCallbackRule.unregisterNetworkCallback(mRequestNetworkCb);
+        }
 
         public boolean getMetered() {
             return mMetered;
@@ -151,7 +168,13 @@
         }
 
         abstract String getSystemFeature();
-        abstract String getErrorMessage();
+
+        @NonNull NetworkRequest buildRequestForTransport(int transport) {
+            return new NetworkRequest.Builder()
+                    .addTransportType(transport)
+                    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                    .build();
+        }
     }
 
     private final NetworkInterfaceToTest[] mNetworkInterfacesToTest =
@@ -163,19 +186,20 @@
                         }
 
                         @Override
-                        public int getTransportType() {
-                            return NetworkCapabilities.TRANSPORT_WIFI;
+                        public Network requestNetwork() {
+                            networkCallbackRule.requestNetwork(buildRequestForTransport(
+                                    NetworkCapabilities.TRANSPORT_WIFI),
+                                    mRequestNetworkCb, TIMEOUT_MILLIS);
+                            return mRequestNetworkCb.expect(CallbackEntry.AVAILABLE,
+                                    "Wifi network not available. "
+                                            + "Please ensure the device has working wifi."
+                            ).getNetwork();
                         }
 
                         @Override
                         public String getSystemFeature() {
                             return PackageManager.FEATURE_WIFI;
                         }
-
-                        @Override
-                        public String getErrorMessage() {
-                            return " Please make sure you are connected to a WiFi access point.";
-                        }
                     },
                     new NetworkInterfaceToTest() {
                         @Override
@@ -184,22 +208,20 @@
                         }
 
                         @Override
-                        public int getTransportType() {
-                            return NetworkCapabilities.TRANSPORT_CELLULAR;
+                        public Network requestNetwork() {
+                            networkCallbackRule.requestNetwork(buildRequestForTransport(
+                                            NetworkCapabilities.TRANSPORT_CELLULAR),
+                                    mRequestNetworkCb, TIMEOUT_MILLIS);
+                            return mRequestNetworkCb.expect(CallbackEntry.AVAILABLE,
+                                    "Cell network not available. "
+                                            + "Please ensure the device has working mobile data."
+                            ).getNetwork();
                         }
 
                         @Override
                         public String getSystemFeature() {
                             return PackageManager.FEATURE_TELEPHONY;
                         }
-
-                        @Override
-                        public String getErrorMessage() {
-                            return " Please make sure you have added a SIM card with data plan to"
-                                    + " your phone, have enabled data over cellular and in case of"
-                                    + " dual SIM devices, have selected the right SIM "
-                                    + "for data connection.";
-                        }
                     }
             };
 
@@ -215,7 +237,22 @@
     private String mWriteSettingsMode;
     private String mUsageStatsMode;
 
-    private void exerciseRemoteHost(Network network, URL url) throws Exception {
+    // The test host only has IPv4. So on a dual-stack network where IPv6 connects before IPv4,
+    // we need to wait until IPv4 is available or the test will spuriously fail.
+    private static void waitForHostResolution(@NonNull Network network, @NonNull URL url) {
+        for (int i = 0; i < HOST_RESOLUTION_RETRIES; i++) {
+            try {
+                network.getAllByName(url.getHost());
+                return;
+            } catch (UnknownHostException e) {
+                SystemClock.sleep(HOST_RESOLUTION_INTERVAL_MS);
+            }
+        }
+        fail(String.format("%s could not be resolved on network %s (%d attempts %dms apart)",
+                url.getHost(), network, HOST_RESOLUTION_RETRIES, HOST_RESOLUTION_INTERVAL_MS));
+    }
+
+    private void exerciseRemoteHost(@NonNull Network network, @NonNull URL url) throws Exception {
         NetworkInfo networkInfo = mCm.getNetworkInfo(network);
         if (networkInfo == null) {
             Log.w(LOG_TAG, "Network info is null");
@@ -311,97 +348,44 @@
         return result.contains("FOREGROUND");
     }
 
-    private class NetworkCallback extends ConnectivityManager.NetworkCallback {
-        private long mTolerance;
-        private URL mUrl;
-        public boolean success;
-        public boolean metered;
-        public boolean roaming;
-        public boolean isDefault;
-
-        NetworkCallback(long tolerance, URL url) {
-            mTolerance = tolerance;
-            mUrl = url;
-            success = false;
-            metered = false;
-            roaming = false;
-            isDefault = false;
-        }
-
-        // The test host only has IPv4. So on a dual-stack network where IPv6 connects before IPv4,
-        // we need to wait until IPv4 is available or the test will spuriously fail.
-        private void waitForHostResolution(Network network) {
-            for (int i = 0; i < HOST_RESOLUTION_RETRIES; i++) {
-                try {
-                    network.getAllByName(mUrl.getHost());
-                    return;
-                } catch (UnknownHostException e) {
-                    SystemClock.sleep(HOST_RESOLUTION_INTERVAL_MS);
-                }
-            }
-            fail(String.format("%s could not be resolved on network %s (%d attempts %dms apart)",
-                    mUrl.getHost(), network, HOST_RESOLUTION_RETRIES, HOST_RESOLUTION_INTERVAL_MS));
-        }
-
-        @Override
-        public void onAvailable(Network network) {
-            try {
-                mStartTime = System.currentTimeMillis() - mTolerance;
-                isDefault = network.equals(mCm.getActiveNetwork());
-                waitForHostResolution(network);
-                exerciseRemoteHost(network, mUrl);
-                mEndTime = System.currentTimeMillis() + mTolerance;
-                success = true;
-                metered = !mCm.getNetworkCapabilities(network)
-                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
-                roaming = !mCm.getNetworkCapabilities(network)
-                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
-                synchronized (NetworkStatsManagerTest.this) {
-                    NetworkStatsManagerTest.this.notify();
-                }
-            } catch (Exception e) {
-                Log.w(LOG_TAG, "exercising remote host failed.", e);
-                success = false;
-            }
-        }
-    }
-
     private boolean shouldTestThisNetworkType(int networkTypeIndex) {
         return mPm.hasSystemFeature(mNetworkInterfacesToTest[networkTypeIndex].getSystemFeature());
     }
 
+    @NonNull
+    private Network requestNetworkAndSetAttributes(
+            @NonNull NetworkInterfaceToTest networkInterface) {
+        final Network network = networkInterface.requestNetwork();
+
+        // These attributes are needed when performing NetworkStats queries.
+        // Fetch caps from the first capabilities changed event since the
+        // interested attributes are not mutable, and not expected to be
+        // changed during the test.
+        final NetworkCapabilities caps = networkInterface.mRequestNetworkCb.expect(
+                CallbackEntry.NETWORK_CAPS_UPDATED, network).getCaps();
+        networkInterface.setMetered(!caps.hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_NOT_METERED));
+        networkInterface.setRoaming(!caps.hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING));
+        networkInterface.setIsDefault(network.equals(mCm.getActiveNetwork()));
+
+        return network;
+    }
+
     private void requestNetworkAndGenerateTraffic(int networkTypeIndex, final long tolerance)
             throws Exception {
         final NetworkInterfaceToTest networkInterface = mNetworkInterfacesToTest[networkTypeIndex];
-        final NetworkCallback callback = new NetworkCallback(tolerance,
-                new URL(CHECK_CONNECTIVITY_URL));
-        mCm.requestNetwork(new NetworkRequest.Builder()
-                .addTransportType(networkInterface.getTransportType())
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), callback);
-        synchronized (this) {
-            long now = System.currentTimeMillis();
-            final long deadline = (long) (now + TIMEOUT_MILLIS * 2.4);
-            while (!callback.success && now < deadline) {
-                try {
-                    wait(deadline - now);
-                } catch (InterruptedException e) {
-                }
-                now = System.currentTimeMillis();
-            }
-        }
-        mCm.unregisterNetworkCallback(callback);
-        if (!callback.success) {
-            fail(networkInterface.getSystemFeature()
-                    + " is a reported system feature, however no corresponding "
-                    + "connected network interface was found or the attempt "
-                    + "to connect and read has timed out (timeout = " + (TIMEOUT_MILLIS * 2.4)
-                    + "ms)." + networkInterface.getErrorMessage());
-        }
+        final Network network = requestNetworkAndSetAttributes(networkInterface);
 
-        networkInterface.setMetered(callback.metered);
-        networkInterface.setRoaming(callback.roaming);
-        networkInterface.setIsDefault(callback.isDefault);
+        mStartTime = System.currentTimeMillis() - tolerance;
+        waitForHostResolution(network, new URL(CHECK_CONNECTIVITY_URL));
+        exerciseRemoteHost(network, new URL(CHECK_CONNECTIVITY_URL));
+        mEndTime = System.currentTimeMillis() + tolerance;
+
+        // It is fine if the test fails and this line is not reached.
+        // The AutoReleaseNetworkCallbackRule will eventually release
+        // all unwanted callbacks.
+        networkInterface.unrequestNetwork();
     }
 
     private String getSubscriberId(int networkIndex) {
