Merge "Revert "Tweak NetworkWatchListTests.""
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 5a0c5b0..2c91d10 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -1080,8 +1080,13 @@
     }
 
     @VisibleForTesting
+    SparseArray<TetheringRequestParcel> getActiveTetheringRequests() {
+        return mActiveTetheringRequests;
+    }
+
+    @VisibleForTesting
     boolean isTetheringActive() {
-        return mActiveTetheringRequests.size() > 0;
+        return getTetheredIfaces().length > 0;
     }
 
     @VisibleForTesting
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 114cb7c..0a37f54 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -52,6 +52,7 @@
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.networkstack.tethering.Tethering.UserRestrictionActionListener;
 import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
 import static com.android.networkstack.tethering.UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES;
 
@@ -125,6 +126,7 @@
 import android.net.wifi.p2p.WifiP2pGroup;
 import android.net.wifi.p2p.WifiP2pInfo;
 import android.net.wifi.p2p.WifiP2pManager;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -734,9 +736,12 @@
         initTetheringUpstream(upstreamState);
 
         // Emulate pressing the USB tethering button in Settings UI.
-        mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null);
+        final TetheringRequestParcel request = createTetheringRequestParcel(TETHERING_USB);
+        mTethering.startTethering(request, null);
         mLooper.dispatchAll();
         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
+        assertEquals(1, mTethering.getActiveTetheringRequests().size());
+        assertEquals(request, mTethering.getActiveTetheringRequests().get(TETHERING_USB));
 
         mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
     }
@@ -844,6 +849,14 @@
         mLooper.dispatchAll();
     }
 
+    private void assertSetIfaceToDadProxy(final int numOfCalls, final String ifaceName) {
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R || "S".equals(Build.VERSION.CODENAME)
+                    || "T".equals(Build.VERSION.CODENAME)) {
+            verify(mDadProxy, times(numOfCalls)).setUpstreamIface(
+                     argThat(ifaceParams  -> ifaceName.equals(ifaceParams.name)));
+        }
+    }
+
     @Test
     public void workingMobileUsbTethering_IPv4() throws Exception {
         UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
@@ -853,7 +866,7 @@
         verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
 
         sendIPv6TetherUpdates(upstreamState);
-        verify(mDadProxy, never()).setUpstreamIface(notNull());
+        assertSetIfaceToDadProxy(0 /* numOfCalls */, "" /* ifaceName */);
         verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
                 any(), any());
@@ -881,7 +894,7 @@
 
         sendIPv6TetherUpdates(upstreamState);
         // TODO: add interfaceParams to compare in verify.
-        verify(mDadProxy, times(1)).setUpstreamIface(notNull());
+        assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
         verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
     }
@@ -898,7 +911,7 @@
                 any(), any());
 
         sendIPv6TetherUpdates(upstreamState);
-        verify(mDadProxy, times(1)).setUpstreamIface(notNull());
+        assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
         verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
     }
@@ -916,7 +929,7 @@
         verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
 
         sendIPv6TetherUpdates(upstreamState);
-        verify(mDadProxy, times(1)).setUpstreamIface(notNull());
+        assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
         verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
     }
@@ -1165,20 +1178,26 @@
         verifyNoMoreInteractions(mNetd);
     }
 
+    private UserRestrictionActionListener makeUserRestrictionActionListener(
+            final Tethering tethering, final boolean currentDisallow, final boolean nextDisallow) {
+        final Bundle newRestrictions = new Bundle();
+        newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
+        when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
+
+        final UserRestrictionActionListener ural =
+                new UserRestrictionActionListener(mUserManager, tethering, mNotificationUpdater);
+        ural.mDisallowTethering = currentDisallow;
+        return ural;
+    }
+
     private void runUserRestrictionsChange(
             boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive,
             int expectedInteractionsWithShowNotification) throws  Exception {
-        final Bundle newRestrictions = new Bundle();
-        newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
         final Tethering mockTethering = mock(Tethering.class);
         when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive);
-        when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
 
-        final Tethering.UserRestrictionActionListener ural =
-                new Tethering.UserRestrictionActionListener(
-                        mUserManager, mockTethering, mNotificationUpdater);
-        ural.mDisallowTethering = currentDisallow;
-
+        final UserRestrictionActionListener ural =
+                makeUserRestrictionActionListener(mockTethering, currentDisallow, nextDisallow);
         ural.onUserRestrictionsChanged();
 
         verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification))
@@ -1247,6 +1266,27 @@
                 expectedInteractionsWithShowNotification);
     }
 
+    @Test
+    public void testUntetherUsbWhenRestrictionIsOn() {
+        // Start usb tethering and check that usb interface is tethered.
+        final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
+        runUsbTethering(upstreamState);
+        assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
+        assertTrue(mTethering.isTetheringActive());
+        assertEquals(0, mTethering.getActiveTetheringRequests().size());
+
+        final Tethering.UserRestrictionActionListener ural = makeUserRestrictionActionListener(
+                mTethering, false /* currentDisallow */, true /* nextDisallow */);
+
+        ural.onUserRestrictionsChanged();
+        mLooper.dispatchAll();
+
+        // Verify that restriction notification has showed to user.
+        verify(mNotificationUpdater, times(1)).notifyTetheringDisabledByRestriction();
+        // Verify that usb tethering has been disabled.
+        verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
+    }
+
     private class TestTetheringEventCallback extends ITetheringEventCallback.Stub {
         private final ArrayList<Network> mActualUpstreams = new ArrayList<>();
         private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs =
diff --git a/tests/cts/net/OWNERS b/tests/cts/net/OWNERS
index d558556..7722bb3 100644
--- a/tests/cts/net/OWNERS
+++ b/tests/cts/net/OWNERS
@@ -1,3 +1,5 @@
 # Bug component: 31808
 lorenzo@google.com
 satk@google.com
+
+per-file src/android/net/cts/NetworkWatchlistTest.java=alanstokes@google.com
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
index 54509cd..ccbdbd3 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
@@ -129,6 +129,12 @@
 
     private static final IBinder BINDER = new Binder();
 
+    // Lock for accessing Shell Permissions. Use of this lock around adoptShellPermissionIdentity,
+    // runWithShellPermissionIdentity, and callWithShellPermissionIdentity ensures Shell Permission
+    // is not interrupted by another operation (which would drop all previously adopted
+    // permissions).
+    private Object mShellPermissionsIdentityLock = new Object();
+
     private Context mContext;
     private ConnectivityManager mConnectivityManager;
     private ConnectivityDiagnosticsManager mCdm;
@@ -244,20 +250,24 @@
                 CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
                 new String[] {getCertHashForThisPackage()});
 
-        runWithShellPermissionIdentity(
-                () -> {
-                    mCarrierConfigManager.overrideConfig(subId, carrierConfigs);
-                    mCarrierConfigManager.notifyConfigChangedForSubId(subId);
-                },
-                android.Manifest.permission.MODIFY_PHONE_STATE);
+        synchronized (mShellPermissionsIdentityLock) {
+            runWithShellPermissionIdentity(
+                    () -> {
+                        mCarrierConfigManager.overrideConfig(subId, carrierConfigs);
+                        mCarrierConfigManager.notifyConfigChangedForSubId(subId);
+                    },
+                    android.Manifest.permission.MODIFY_PHONE_STATE);
+        }
 
         // TODO(b/157779832): This should use android.permission.CHANGE_NETWORK_STATE. However, the
         // shell does not have CHANGE_NETWORK_STATE, so use CONNECTIVITY_INTERNAL until the shell
         // permissions are updated.
-        runWithShellPermissionIdentity(
-                () -> mConnectivityManager.requestNetwork(
-                        CELLULAR_NETWORK_REQUEST, testNetworkCallback),
-                android.Manifest.permission.CONNECTIVITY_INTERNAL);
+        synchronized (mShellPermissionsIdentityLock) {
+            runWithShellPermissionIdentity(
+                    () -> mConnectivityManager.requestNetwork(
+                            CELLULAR_NETWORK_REQUEST, testNetworkCallback),
+                    android.Manifest.permission.CONNECTIVITY_INTERNAL);
+        }
 
         final Network network = testNetworkCallback.waitForAvailable();
         assertNotNull(network);
@@ -536,9 +546,18 @@
     }
 
     private class CarrierConfigReceiver extends BroadcastReceiver {
+        // CountDownLatch used to wait for this BroadcastReceiver to be notified of a CarrierConfig
+        // change. This latch will be counted down if a broadcast indicates this package has carrier
+        // configs, or if an Exception occurs in #onReceive.
         private final CountDownLatch mLatch = new CountDownLatch(1);
         private final int mSubId;
 
+        // #onReceive may encounter Exceptions while running on the Process' main Thread and
+        // #waitForCarrierConfigChanged checks the cached Exception from the test Thread. These
+        // Exceptions must be cached and thrown later, as throwing on the Process' main Thread will
+        // crash the process and cause other tests to fail.
+        private Exception mOnReceiveException;
+
         CarrierConfigReceiver(int subId) {
             mSubId = subId;
         }
@@ -546,6 +565,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (!CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
+                // Received an incorrect broadcast - ignore
                 return;
             }
 
@@ -553,24 +573,64 @@
                     intent.getIntExtra(
                             CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
                             SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-            if (mSubId != subId) return;
+            if (mSubId != subId) {
+                // Received a broadcast for the wrong subId - ignore
+                return;
+            }
 
-            final PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
-            if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) return;
+            final PersistableBundle carrierConfigs;
+            try {
+                synchronized (mShellPermissionsIdentityLock) {
+                    carrierConfigs = callWithShellPermissionIdentity(
+                            () -> mCarrierConfigManager.getConfigForSubId(subId),
+                            android.Manifest.permission.READ_PHONE_STATE);
+                }
+            } catch (Exception exception) {
+                // callWithShellPermissionIdentity() threw an Exception - cache it and allow
+                // waitForCarrierConfigChanged() to throw it
+                mOnReceiveException = exception;
+                mLatch.countDown();
+                return;
+            }
 
-            final String[] certs =
-                    carrierConfigs.getStringArray(
-                            CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
+            if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) {
+                // Configs are not for an identified carrier (meaning they are defaults) - ignore
+                return;
+            }
+
+            final String[] certs = carrierConfigs.getStringArray(
+                    CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
             try {
                 if (ArrayUtils.contains(certs, getCertHashForThisPackage())) {
+                    // Received an update for this package's cert hash - countdown and exit
                     mLatch.countDown();
                 }
-            } catch (Exception e) {
+                // Broadcast is for the right subId, but does not show this package as Carrier
+                // Privileged. Keep waiting for a broadcast that indicates Carrier Privileges.
+            } catch (Exception exception) {
+                // getCertHashForThisPackage() threw an Exception - cache it and allow
+                // waitForCarrierConfigChanged() to throw it
+                mOnReceiveException = exception;
+                mLatch.countDown();
             }
         }
 
+        /**
+         * Waits for the CarrierConfig changed broadcast to reach this CarrierConfigReceiver.
+         *
+         * <p>Must be called from the Test Thread.
+         *
+         * @throws Exception if an Exception occurred during any #onReceive invocation
+         */
         boolean waitForCarrierConfigChanged() throws Exception {
-            return mLatch.await(CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT, TimeUnit.MILLISECONDS);
+            final boolean result = mLatch.await(CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT,
+                    TimeUnit.MILLISECONDS);
+
+            if (mOnReceiveException != null) {
+                throw mOnReceiveException;
+            }
+
+            return result;
         }
     }
 }
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index db4e3e7..cbf43e7 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -16,6 +16,7 @@
 
 package android.net.cts;
 
+import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
 import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
 import static android.Manifest.permission.NETWORK_SETTINGS;
 import static android.content.pm.PackageManager.FEATURE_ETHERNET;
@@ -1517,7 +1518,10 @@
 
     @Test
     public void testGetCaptivePortalServerUrl() {
-        final String url = runAsShell(NETWORK_SETTINGS, mCm::getCaptivePortalServerUrl);
+        final String permission = Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q
+                ? CONNECTIVITY_INTERNAL
+                : NETWORK_SETTINGS;
+        final String url = runAsShell(permission, mCm::getCaptivePortalServerUrl);
         assertNotNull("getCaptivePortalServerUrl must not be null", url);
         try {
             final URL parsedUrl = new URL(url);
diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
index 4acbbcf..4d95fbe 100644
--- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
@@ -28,6 +28,7 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.ContentResolver;
+import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.DnsResolver;
@@ -91,6 +92,7 @@
 
     private ContentResolver mCR;
     private ConnectivityManager mCM;
+    private PackageManager mPackageManager;
     private CtsNetUtils mCtsNetUtils;
     private Executor mExecutor;
     private Executor mExecutorInline;
@@ -109,6 +111,7 @@
         mCR = getContext().getContentResolver();
         mCtsNetUtils = new CtsNetUtils(getContext());
         mCtsNetUtils.storePrivateDnsSetting();
+        mPackageManager = mContext.getPackageManager();
     }
 
     @Override
@@ -128,6 +131,9 @@
     }
 
     private Network[] getTestableNetworks() {
+        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+            mCtsNetUtils.ensureWifiConnected();
+        }
         final ArrayList<Network> testableNetworks = new ArrayList<Network>();
         for (Network network : mCM.getAllNetworks()) {
             final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
@@ -555,6 +561,7 @@
         @Override
         public void onError(@NonNull DnsResolver.DnsException error) {
             mErrorMsg = mMsg + error.getMessage();
+            mLatch.countDown();
         }
     }
 
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 7508228..45a84f8 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -62,6 +62,7 @@
 import com.android.internal.util.AsyncChannel
 import com.android.net.module.util.ArrayTrackRecord
 import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
 import com.android.testutils.RecorderCallback.CallbackEntry.Available
 import com.android.testutils.RecorderCallback.CallbackEntry.Lost
 import com.android.testutils.TestableNetworkCallback
@@ -541,6 +542,7 @@
     }
 
     @Test
+    @IgnoreUpTo(android.os.Build.VERSION_CODES.R)
     fun testAgentStartsInConnecting() {
         val mockContext = mock(Context::class.java)
         val mockCm = mock(ConnectivityManager::class.java)
diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
index 37bdd44..1d9268a 100755
--- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
+++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
@@ -59,9 +59,11 @@
         assertTrue(TrafficStats.getTotalRxBytes() >= 0);
     }
 
-    public void testValidPacketStats() {
+    public void testValidIfaceStats() {
         assertTrue(TrafficStats.getTxPackets("lo") >= 0);
         assertTrue(TrafficStats.getRxPackets("lo") >= 0);
+        assertTrue(TrafficStats.getTxBytes("lo") >= 0);
+        assertTrue(TrafficStats.getRxBytes("lo") >= 0);
     }
 
     public void testThreadStatsTag() throws Exception {
@@ -109,6 +111,8 @@
         final long uidRxPacketsBefore = TrafficStats.getUidRxPackets(Process.myUid());
         final long ifaceTxPacketsBefore = TrafficStats.getTxPackets("lo");
         final long ifaceRxPacketsBefore = TrafficStats.getRxPackets("lo");
+        final long ifaceTxBytesBefore = TrafficStats.getTxBytes("lo");
+        final long ifaceRxBytesBefore = TrafficStats.getRxBytes("lo");
 
         // Transfer 1MB of data across an explicitly localhost socket.
         final int byteCount = 1024;
@@ -189,8 +193,12 @@
         final long uidRxDeltaPackets = uidRxPacketsAfter - uidRxPacketsBefore;
         final long ifaceTxPacketsAfter = TrafficStats.getTxPackets("lo");
         final long ifaceRxPacketsAfter = TrafficStats.getRxPackets("lo");
+        final long ifaceTxBytesAfter = TrafficStats.getTxBytes("lo");
+        final long ifaceRxBytesAfter = TrafficStats.getRxBytes("lo");
         final long ifaceTxDeltaPackets = ifaceTxPacketsAfter - ifaceTxPacketsBefore;
         final long ifaceRxDeltaPackets = ifaceRxPacketsAfter - ifaceRxPacketsBefore;
+        final long ifaceTxDeltaBytes = ifaceTxBytesAfter - ifaceTxBytesBefore;
+        final long ifaceRxDeltaBytes = ifaceRxBytesAfter - ifaceRxBytesBefore;
 
         // Localhost traffic *does* count against per-UID stats.
         /*
@@ -246,9 +254,13 @@
         assertInRange("uidrxb", uidRxDeltaBytes, pktBytes + minExpExtraPktBytes,
                 pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes + deltaRxOtherPktBytes);
         assertInRange("iftxp", ifaceTxDeltaPackets, packetCount + minExpectedExtraPackets,
-                packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets);
+                packetCount + packetCount + maxExpectedExtraPackets);
         assertInRange("ifrxp", ifaceRxDeltaPackets, packetCount + minExpectedExtraPackets,
-                packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets);
+                packetCount + packetCount + maxExpectedExtraPackets);
+        assertInRange("iftxb", ifaceTxDeltaBytes, pktBytes + minExpExtraPktBytes,
+                pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes);
+        assertInRange("ifrxb", ifaceRxDeltaBytes, pktBytes + minExpExtraPktBytes,
+                pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes);
 
         // Localhost traffic *does* count against total stats.
         // Check the total stats increased after test data transfer over localhost has been made.
@@ -264,6 +276,10 @@
                 totalTxPacketsAfter >= totalTxPacketsBefore + ifaceTxDeltaPackets);
         assertTrue("ifrxp: " + ifaceRxPacketsBefore + " -> " + ifaceRxPacketsAfter,
                 totalRxPacketsAfter >= totalRxPacketsBefore + ifaceRxDeltaPackets);
+        assertTrue("iftxb: " + ifaceTxBytesBefore + " -> " + ifaceTxBytesAfter,
+            totalTxBytesAfter >= totalTxBytesBefore + ifaceTxDeltaBytes);
+        assertTrue("ifrxb: " + ifaceRxBytesBefore + " -> " + ifaceRxBytesAfter,
+            totalRxBytesAfter >= totalRxBytesBefore + ifaceRxDeltaBytes);
 
         // Localhost traffic should *not* count against mobile stats,
         // There might be some other traffic, but nowhere near 1MB.
diff --git a/tests/cts/net/src/android/net/cts/TunUtils.java b/tests/cts/net/src/android/net/cts/TunUtils.java
index adaba9d..7887385 100644
--- a/tests/cts/net/src/android/net/cts/TunUtils.java
+++ b/tests/cts/net/src/android/net/cts/TunUtils.java
@@ -47,7 +47,7 @@
     protected static final int IP6_PROTO_OFFSET = 6;
 
     private static final int DATA_BUFFER_LEN = 4096;
-    private static final int TIMEOUT = 1000;
+    private static final int TIMEOUT = 2000;
 
     private final List<byte[]> mPackets = new ArrayList<>();
     private final ParcelFileDescriptor mTunFd;
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
index be0daae..0527011 100644
--- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -16,6 +16,7 @@
 
 package android.net.cts.util;
 
+import static android.Manifest.permission.ACCESS_WIFI_STATE;
 import static android.Manifest.permission.NETWORK_SETTINGS;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
@@ -84,7 +85,7 @@
     private static final int SOCKET_TIMEOUT_MS = 2000;
     private static final int PRIVATE_DNS_PROBE_MS = 1_000;
 
-    private static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 6_000;
+    private static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 10_000;
     private static final int CONNECTIVITY_CHANGE_TIMEOUT_SECS = 30;
     public static final int HTTP_PORT = 80;
     public static final String TEST_HOST = "connectivitycheck.gstatic.com";
@@ -331,7 +332,7 @@
      * to them.
      */
     private void clearWifiBlacklist() {
-        runAsShell(NETWORK_SETTINGS, () -> {
+        runAsShell(NETWORK_SETTINGS, ACCESS_WIFI_STATE, () -> {
             for (WifiConfiguration cfg : mWifiManager.getConfiguredNetworks()) {
                 assertTrue(mWifiManager.enableNetwork(cfg.networkId, false /* attemptConnect */));
             }