Merge "Clear UIDs when sharing NetworkCapabilties for ConnectivityDiagnostics." into rvc-dev
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 6e0f520..ecf1f13 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -273,9 +273,6 @@
     // connect anyway?" dialog after the user selects a network that doesn't validate.
     private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000;
 
-    // How long to dismiss network notification.
-    private static final int TIMEOUT_NOTIFICATION_DELAY_MS = 20 * 1000;
-
     // Default to 30s linger time-out. Modifiable only for testing.
     private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
     private static final int DEFAULT_LINGER_DELAY_MS = 30_000;
@@ -523,18 +520,13 @@
     private static final int EVENT_PROVISIONING_NOTIFICATION = 43;
 
     /**
-     * This event can handle dismissing notification by given network id.
-     */
-    private static final int EVENT_TIMEOUT_NOTIFICATION = 44;
-
-    /**
      * Used to specify whether a network should be used even if connectivity is partial.
      * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for
      * false)
      * arg2 = whether to remember this choice in the future (1 for true or 0 for false)
      * obj  = network
      */
-    private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 45;
+    private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44;
 
     /**
      * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed.
@@ -543,7 +535,7 @@
      * arg1 = A bitmask to describe which probes are completed.
      * arg2 = A bitmask to describe which probes are successful.
      */
-    public static final int EVENT_PROBE_STATUS_CHANGED = 46;
+    public static final int EVENT_PROBE_STATUS_CHANGED = 45;
 
     /**
      * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed.
@@ -551,7 +543,7 @@
      * arg2 = netId
      * obj = captive portal data
      */
-    private static final int EVENT_CAPPORT_DATA_CHANGED = 47;
+    private static final int EVENT_CAPPORT_DATA_CHANGED = 46;
 
     /**
      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
@@ -2877,13 +2869,6 @@
             final boolean valid = ((testResult & NETWORK_VALIDATION_RESULT_VALID) != 0);
             final boolean wasValidated = nai.lastValidated;
             final boolean wasDefault = isDefaultNetwork(nai);
-            // Only show a connected notification if the network is pending validation
-            // after the captive portal app was open, and it has now validated.
-            if (nai.captivePortalValidationPending && valid) {
-                // User is now logged in, network validated.
-                nai.captivePortalValidationPending = false;
-                showNetworkNotification(nai, NotificationType.LOGGED_IN);
-            }
 
             if (DBG) {
                 final String logMsg = !TextUtils.isEmpty(redirectUrl)
@@ -3764,12 +3749,6 @@
                 new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
         appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
 
-        // This runs on a random binder thread, but getNetworkAgentInfoForNetwork is thread-safe,
-        // and captivePortalValidationPending is volatile.
-        final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
-        if (nai != null) {
-            nai.captivePortalValidationPending = true;
-        }
         Binder.withCleanCallingIdentity(() ->
                 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT));
     }
@@ -3888,14 +3867,6 @@
         final String action;
         final boolean highPriority;
         switch (type) {
-            case LOGGED_IN:
-                action = Settings.ACTION_WIFI_SETTINGS;
-                mHandler.removeMessages(EVENT_TIMEOUT_NOTIFICATION);
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NOTIFICATION,
-                        nai.network.netId, 0), TIMEOUT_NOTIFICATION_DELAY_MS);
-                // High priority because it is a direct result of the user logging in to a portal.
-                highPriority = true;
-                break;
             case NO_INTERNET:
                 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
                 // High priority because it is only displayed for explicitly selected networks.
@@ -3923,7 +3894,7 @@
         }
 
         Intent intent = new Intent(action);
-        if (type != NotificationType.LOGGED_IN && type != NotificationType.PRIVATE_DNS_BROKEN) {
+        if (type != NotificationType.PRIVATE_DNS_BROKEN) {
             intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.netId), null));
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             intent.setClassName("com.android.settings",
@@ -4139,9 +4110,6 @@
                 case EVENT_DATA_SAVER_CHANGED:
                     handleRestrictBackgroundChanged(toBool(msg.arg1));
                     break;
-                case EVENT_TIMEOUT_NOTIFICATION:
-                    mNotifier.clearNotification(msg.arg1, NotificationType.LOGGED_IN);
-                    break;
             }
         }
     }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 23b954c..2f04715 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -160,10 +160,6 @@
     // Whether a captive portal was found during the last network validation attempt.
     public boolean lastCaptivePortalDetected;
 
-    // Indicates the captive portal app was opened to show a login UI to the user, but the network
-    // has not validated yet.
-    public volatile boolean captivePortalValidationPending;
-
     // Set to true when partial connectivity was detected.
     public boolean partialConnectivity;
 
@@ -638,7 +634,6 @@
                 + "acceptUnvalidated{" + networkAgentConfig.acceptUnvalidated + "} "
                 + "everCaptivePortalDetected{" + everCaptivePortalDetected + "} "
                 + "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} "
-                + "captivePortalValidationPending{" + captivePortalValidationPending + "} "
                 + "partialConnectivity{" + partialConnectivity + "} "
                 + "acceptPartialConnectivity{" + networkAgentConfig.acceptPartialConnectivity + "} "
                 + "clat{" + clatd + "} "
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 25c761a..0925de8 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -51,7 +51,6 @@
         LOST_INTERNET(SystemMessage.NOTE_NETWORK_LOST_INTERNET),
         NETWORK_SWITCH(SystemMessage.NOTE_NETWORK_SWITCH),
         NO_INTERNET(SystemMessage.NOTE_NETWORK_NO_INTERNET),
-        LOGGED_IN(SystemMessage.NOTE_NETWORK_LOGGED_IN),
         PARTIAL_CONNECTIVITY(SystemMessage.NOTE_NETWORK_PARTIAL_CONNECTIVITY),
         SIGN_IN(SystemMessage.NOTE_NETWORK_SIGN_IN),
         PRIVATE_DNS_BROKEN(SystemMessage.NOTE_NETWORK_PRIVATE_DNS_BROKEN);
@@ -114,14 +113,10 @@
         }
     }
 
-    private static int getIcon(int transportType, NotificationType notifyType) {
-        if (transportType != TRANSPORT_WIFI) {
-            return R.drawable.stat_notify_rssi_in_range;
-        }
-
-        return notifyType == NotificationType.LOGGED_IN
-            ? R.drawable.ic_wifi_signal_4
-            : R.drawable.stat_notify_wifi_in_range;  // TODO: Distinguish ! from ?.
+    private static int getIcon(int transportType) {
+        return (transportType == TRANSPORT_WIFI)
+                ? R.drawable.stat_notify_wifi_in_range :  // TODO: Distinguish ! from ?.
+                R.drawable.stat_notify_rssi_in_range;
     }
 
     /**
@@ -185,7 +180,7 @@
         Resources r = mContext.getResources();
         final CharSequence title;
         final CharSequence details;
-        int icon = getIcon(transportType, notifyType);
+        int icon = getIcon(transportType);
         if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) {
             title = r.getString(R.string.wifi_no_internet,
                     WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
@@ -235,9 +230,6 @@
                     details = r.getString(R.string.network_available_sign_in_detailed, name);
                     break;
             }
-        } else if (notifyType == NotificationType.LOGGED_IN) {
-            title = WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID());
-            details = r.getString(R.string.captive_portal_logged_in_detailed);
         } else if (notifyType == NotificationType.NETWORK_SWITCH) {
             String fromTransport = getTransportName(transportType);
             String toTransport = getTransportName(approximateTransportType(switchToNai));
@@ -379,7 +371,6 @@
             case NETWORK_SWITCH:
                 return 2;
             case LOST_INTERNET:
-            case LOGGED_IN:
                 return 1;
             default:
                 return 0;
diff --git a/tests/net/common/java/android/net/CaptivePortalTest.java b/tests/net/common/java/android/net/CaptivePortalTest.java
index ca4ba63..7a60cc1 100644
--- a/tests/net/common/java/android/net/CaptivePortalTest.java
+++ b/tests/net/common/java/android/net/CaptivePortalTest.java
@@ -18,19 +18,26 @@
 
 import static org.junit.Assert.assertEquals;
 
+import android.os.Build;
 import android.os.RemoteException;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class CaptivePortalTest {
+    @Rule
+    public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
+
     private static final int DEFAULT_TIMEOUT_MS = 5000;
     private static final String TEST_PACKAGE_NAME = "com.google.android.test";
 
@@ -84,6 +91,7 @@
         assertEquals(result.mCode, CaptivePortal.APP_RETURN_WANTED_AS_IS);
     }
 
+    @IgnoreUpTo(Build.VERSION_CODES.Q)
     @Test
     public void testReevaluateNetwork() {
         final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.reevaluateNetwork());
diff --git a/tests/net/common/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java
index 06c6301..99dac14 100644
--- a/tests/net/common/java/android/net/LinkAddressTest.java
+++ b/tests/net/common/java/android/net/LinkAddressTest.java
@@ -28,8 +28,8 @@
 import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 
 import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
 import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
 import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
 
 import static org.junit.Assert.assertEquals;
@@ -38,11 +38,17 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.os.Build;
 import android.os.SystemClock;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -57,6 +63,8 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class LinkAddressTest {
+    @Rule
+    public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
 
     private static final String V4 = "192.0.2.1";
     private static final String V6 = "2001:db8::1";
@@ -318,15 +326,29 @@
 
         l = new LinkAddress(V6_ADDRESS, 64, 123, 456);
         assertParcelingIsLossless(l);
-        l = new LinkAddress(V6_ADDRESS, 64, 123, 456,
-                1L, 3600000L);
-        assertParcelingIsLossless(l);
 
         l = new LinkAddress(V4 + "/28", IFA_F_PERMANENT, RT_SCOPE_LINK);
-        assertParcelSane(l, 6);
+        assertParcelingIsLossless(l);
     }
 
-    @Test
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testLifetimeParceling() {
+        final LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 123, 456, 1L, 3600000L);
+        assertParcelingIsLossless(l);
+    }
+
+    @Test @IgnoreAfter(Build.VERSION_CODES.Q)
+    public void testFieldCount_Q() {
+        assertFieldCountEquals(4, LinkAddress.class);
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testFieldCount() {
+        // Make sure any new field is covered by the above parceling tests when changing this number
+        assertFieldCountEquals(6, LinkAddress.class);
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testDeprecationTime() {
         try {
             new LinkAddress(V6_ADDRESS, 64, 0, 456,
@@ -347,7 +369,7 @@
         } catch (IllegalArgumentException expected) { }
     }
 
-    @Test
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testExpirationTime() {
         try {
             new LinkAddress(V6_ADDRESS, 64, 0, 456,
@@ -366,10 +388,13 @@
     public void testGetFlags() {
         LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 123, RT_SCOPE_HOST);
         assertEquals(123, l.getFlags());
+    }
 
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testGetFlags_Deprecation() {
         // Test if deprecated bit was added/remove automatically based on the provided deprecation
         // time
-        l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_HOST,
+        LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_HOST,
                 1L, LinkAddress.LIFETIME_PERMANENT);
         // Check if the flag is added automatically.
         assertTrue((l.getFlags() & IFA_F_DEPRECATED) != 0);
@@ -458,8 +483,11 @@
                             (IFA_F_TEMPORARY|IFA_F_TENTATIVE|IFA_F_OPTIMISTIC),
                             RT_SCOPE_UNIVERSE);
         assertGlobalPreferred(l, "v6,global,tempaddr+optimistic");
+    }
 
-        l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED,
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testIsGlobalPreferred_DeprecatedInFuture() {
+        final LinkAddress l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED,
                 RT_SCOPE_UNIVERSE, SystemClock.elapsedRealtime() + 100000,
                 SystemClock.elapsedRealtime() + 200000);
         // Although the deprecated bit is set, but the deprecation time is in the future, test
diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
index d250ad3..173dbd1 100644
--- a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
+++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
@@ -16,16 +16,23 @@
 
 package android.net
 
+import android.os.Build
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
 import com.android.testutils.assertParcelSane
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class NetworkAgentConfigTest {
-    @Test
+    @Rule @JvmField
+    val ignoreRule = DevSdkIgnoreRule()
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     fun testParcelNetworkAgentConfig() {
         val config = NetworkAgentConfig.Builder().apply {
             setExplicitlySelected(true)
diff --git a/tests/net/common/java/android/net/RouteInfoTest.java b/tests/net/common/java/android/net/RouteInfoTest.java
index fe51b3a..1658262 100644
--- a/tests/net/common/java/android/net/RouteInfoTest.java
+++ b/tests/net/common/java/android/net/RouteInfoTest.java
@@ -19,19 +19,40 @@
 import static android.net.RouteInfo.RTN_UNREACHABLE;
 
 import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
 import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
 import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
 
-import android.test.suitebuilder.annotation.SmallTest;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
-import junit.framework.TestCase;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 
-public class RouteInfoTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RouteInfoTest {
+    @Rule
+    public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
+
+    private static final int INVALID_ROUTE_TYPE = -1;
 
     private InetAddress Address(String addr) {
         return InetAddress.parseNumericAddress(addr);
@@ -41,15 +62,32 @@
         return new IpPrefix(prefix);
     }
 
-    @SmallTest
+    @Test
     public void testConstructor() {
         RouteInfo r;
-
         // Invalid input.
         try {
             r = new RouteInfo((IpPrefix) null, null, "rmnet0");
             fail("Expected RuntimeException:  destination and gateway null");
-        } catch(RuntimeException e) {}
+        } catch (RuntimeException e) { }
+
+        try {
+            r = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("2001:db8::1"), "rmnet0",
+                    INVALID_ROUTE_TYPE);
+            fail("Invalid route type should cause exception");
+        } catch (IllegalArgumentException e) { }
+
+        try {
+            r = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("192.0.2.1"), "rmnet0",
+                    RTN_UNREACHABLE);
+            fail("Address family mismatch should cause exception");
+        } catch (IllegalArgumentException e) { }
+
+        try {
+            r = new RouteInfo(Prefix("0.0.0.0/0"), Address("2001:db8::1"), "rmnet0",
+                    RTN_UNREACHABLE);
+            fail("Address family mismatch should cause exception");
+        } catch (IllegalArgumentException e) { }
 
         // Null destination is default route.
         r = new RouteInfo((IpPrefix) null, Address("2001:db8::1"), null);
@@ -74,6 +112,7 @@
         assertNull(r.getInterface());
     }
 
+    @Test
     public void testMatches() {
         class PatchedRouteInfo {
             private final RouteInfo mRouteInfo;
@@ -113,6 +152,7 @@
         assertFalse(ipv4Default.matches(Address("2001:db8::f00")));
     }
 
+    @Test
     public void testEquals() {
         // IPv4
         RouteInfo r1 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0");
@@ -146,6 +186,7 @@
         assertNotEqualEitherWay(r1, r3);
     }
 
+    @Test
     public void testHostAndDefaultRoutes() {
         RouteInfo r;
 
@@ -228,6 +269,7 @@
         assertFalse(r.isIPv6Default());
     }
 
+    @Test
     public void testTruncation() {
       LinkAddress l;
       RouteInfo r;
@@ -244,6 +286,7 @@
     // Make sure that creating routes to multicast addresses doesn't throw an exception. Even though
     // there's nothing we can do with them, we don't want to crash if, e.g., someone calls
     // requestRouteToHostAddress("230.0.0.0", MOBILE_HIPRI);
+    @Test
     public void testMulticastRoute() {
       RouteInfo r;
       r = new RouteInfo(Prefix("230.0.0.0/32"), Address("192.0.2.1"), "wlan0");
@@ -251,16 +294,36 @@
       // No exceptions? Good.
     }
 
+    @Test
     public void testParceling() {
         RouteInfo r;
-
-        r = new RouteInfo(Prefix("::/0"), Address("2001:db8::"), null);
+        r = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), null);
         assertParcelingIsLossless(r);
-
         r = new RouteInfo(Prefix("192.0.2.0/24"), null, "wlan0");
-        assertParcelSane(r, 7);
+        assertParcelingIsLossless(r);
+        r = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0", RTN_UNREACHABLE);
+        assertParcelingIsLossless(r);
     }
 
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testMtuParceling() {
+        final RouteInfo r = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::"), "testiface",
+                RTN_UNREACHABLE, 1450 /* mtu */);
+        assertParcelingIsLossless(r);
+    }
+
+    @Test @IgnoreAfter(Build.VERSION_CODES.Q)
+    public void testFieldCount_Q() {
+        assertFieldCountEquals(6, RouteInfo.class);
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testFieldCount() {
+        // Make sure any new field is covered by the above parceling tests when changing this number
+        assertFieldCountEquals(7, RouteInfo.class);
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testMtu() {
         RouteInfo r;
         r = new RouteInfo(Prefix("0.0.0.0/0"), Address("0.0.0.0"), "wlan0",
diff --git a/tests/net/common/java/android/net/util/SocketUtilsTest.kt b/tests/net/common/java/android/net/util/SocketUtilsTest.kt
index 9c7cfb0..aaf97f3 100644
--- a/tests/net/common/java/android/net/util/SocketUtilsTest.kt
+++ b/tests/net/common/java/android/net/util/SocketUtilsTest.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package android.net.util;
+package android.net.util
 
+import android.os.Build
 import android.system.NetlinkSocketAddress
 import android.system.Os
 import android.system.OsConstants.AF_INET
@@ -26,18 +27,26 @@
 import android.system.PacketSocketAddress
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Assert.fail
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
 private const val TEST_INDEX = 123
 private const val TEST_PORT = 555
+private const val FF_BYTE = 0xff.toByte()
+
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class SocketUtilsTest {
+    @Rule @JvmField
+    val ignoreRule = DevSdkIgnoreRule()
+
     @Test
     fun testMakeNetlinkSocketAddress() {
         val nlAddress = SocketUtils.makeNetlinkSocketAddress(TEST_PORT, RTMGRP_NEIGH)
@@ -50,16 +59,21 @@
     }
 
     @Test
-    fun testMakePacketSocketAddress() {
+    fun testMakePacketSocketAddress_Q() {
         val pkAddress = SocketUtils.makePacketSocketAddress(ETH_P_ALL, TEST_INDEX)
         assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress)
 
-        val ff = 0xff.toByte()
-        val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX,
-                byteArrayOf(ff, ff, ff, ff, ff, ff))
+        val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX, ByteArray(6) { FF_BYTE })
         assertTrue("Not PacketSocketAddress object", pkAddress2 is PacketSocketAddress)
     }
 
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testMakePacketSocketAddress() {
+        val pkAddress = SocketUtils.makePacketSocketAddress(
+                ETH_P_ALL, TEST_INDEX, ByteArray(6) { FF_BYTE })
+        assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress)
+    }
+
     @Test
     fun testCloseSocket() {
         // Expect no exception happening with null object.
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index c1999db..6985415 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -2750,9 +2750,6 @@
 
         // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
         validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
-        // Expect no notification to be shown when captive portal disappears by itself
-        verify(mNotificationManager, never()).notifyAsUser(
-                anyString(), eq(NotificationType.LOGGED_IN.eventId), any(), any());
 
         // Break network connectivity.
         // Expect NET_CAPABILITY_VALIDATED onLost callback.
@@ -2814,8 +2811,6 @@
         mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
         validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
         captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
-        verify(mNotificationManager, times(1)).notifyAsUser(anyString(),
-                eq(NotificationType.LOGGED_IN.eventId), any(), eq(UserHandle.ALL));
 
         mCm.unregisterNetworkCallback(validatedCallback);
         mCm.unregisterNetworkCallback(captivePortalCallback);
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index d57f225..47db5d4 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -238,20 +238,6 @@
     }
 
     @Test
-    public void testSameLevelNotifications() {
-        final int id = 101;
-        final String tag = NetworkNotificationManager.tagFor(id);
-
-        mManager.showNotification(id, LOGGED_IN, mWifiNai, mCellNai, null, false);
-        verify(mNotificationManager, times(1))
-                .notifyAsUser(eq(tag), eq(LOGGED_IN.eventId), any(), any());
-
-        mManager.showNotification(id, LOST_INTERNET, mWifiNai, mCellNai, null, false);
-        verify(mNotificationManager, times(1))
-                .notifyAsUser(eq(tag), eq(LOST_INTERNET.eventId), any(), any());
-    }
-
-    @Test
     public void testClearNotificationByType() {
         final int id = 101;
         final String tag = NetworkNotificationManager.tagFor(id);
@@ -259,31 +245,25 @@
         // clearNotification(int id, NotificationType notifyType) will check if given type is equal
         // to previous type or not. If they are equal then clear the notification; if they are not
         // equal then return.
-
-        mManager.showNotification(id, LOGGED_IN, mWifiNai, mCellNai, null, false);
+        mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false);
         verify(mNotificationManager, times(1))
-                .notifyAsUser(eq(tag), eq(LOGGED_IN.eventId), any(), any());
+                .notifyAsUser(eq(tag), eq(NO_INTERNET.eventId), any(), any());
 
-        // Previous notification is LOGGED_IN and given type is LOGGED_IN too. The notification
+        // Previous notification is NO_INTERNET and given type is NO_INTERNET too. The notification
         // should be cleared.
-        mManager.clearNotification(id, LOGGED_IN);
+        mManager.clearNotification(id, NO_INTERNET);
         verify(mNotificationManager, times(1))
-                .cancelAsUser(eq(tag), eq(LOGGED_IN.eventId), any());
+                .cancelAsUser(eq(tag), eq(NO_INTERNET.eventId), any());
 
-        mManager.showNotification(id, LOGGED_IN, mWifiNai, mCellNai, null, false);
-        verify(mNotificationManager, times(2))
-                .notifyAsUser(eq(tag), eq(LOGGED_IN.eventId), any(), any());
-
-        // LOST_INTERNET notification popup after LOGGED_IN notification.
-        mManager.showNotification(id, LOST_INTERNET, mWifiNai, mCellNai, null, false);
+        // SIGN_IN is popped-up.
+        mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false);
         verify(mNotificationManager, times(1))
-                .notifyAsUser(eq(tag), eq(LOST_INTERNET.eventId), any(), any());
+                .notifyAsUser(eq(tag), eq(SIGN_IN.eventId), any(), any());
 
-        // Previous notification is LOST_INTERNET and given type is LOGGED_IN. The notification
-        // shouldn't be cleared.
-        mManager.clearNotification(id, LOGGED_IN);
-        // LOST_INTERNET shouldn't be cleared.
+        // The notification type is not matching previous one, PARTIAL_CONNECTIVITY won't be
+        // cleared.
+        mManager.clearNotification(id, PARTIAL_CONNECTIVITY);
         verify(mNotificationManager, never())
-                .cancelAsUser(eq(tag), eq(LOST_INTERNET.eventId), any());
+                .cancelAsUser(eq(tag), eq(PARTIAL_CONNECTIVITY.eventId), any());
     }
 }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index a9e0b9a..36deca3 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -64,6 +64,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.annotation.NonNull;
 import android.app.AlarmManager;
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
@@ -163,7 +164,6 @@
     private @Mock IBinder mBinder;
     private @Mock AlarmManager mAlarmManager;
     private HandlerThread mHandlerThread;
-    private Handler mHandler;
 
     private NetworkStatsService mService;
     private INetworkStatsSession mSession;
@@ -192,15 +192,11 @@
         PowerManager.WakeLock wakeLock =
                 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
 
-        mService = new NetworkStatsService(
-                mServiceContext, mNetManager, mAlarmManager, wakeLock, mClock,
-                mServiceContext.getSystemService(TelephonyManager.class), mSettings,
-                mStatsFactory, new NetworkStatsObservers(),  mStatsDir, getBaseDir(mStatsDir));
         mHandlerThread = new HandlerThread("HandlerThread");
-        mHandlerThread.start();
-        Handler.Callback callback = new NetworkStatsService.HandlerCallback(mService);
-        mHandler = new Handler(mHandlerThread.getLooper(), callback);
-        mService.setHandler(mHandler, callback);
+        final NetworkStatsService.Dependencies deps = makeDependencies();
+        mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock,
+                mClock, mServiceContext.getSystemService(TelephonyManager.class), mSettings,
+                mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir), deps);
 
         mElapsedRealtime = 0L;
 
@@ -217,11 +213,21 @@
 
         // catch INetworkManagementEventObserver during systemReady()
         ArgumentCaptor<INetworkManagementEventObserver> networkObserver =
-              ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
+                ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
         verify(mNetManager).registerObserver(networkObserver.capture());
         mNetworkObserver = networkObserver.getValue();
     }
 
+    @NonNull
+    private NetworkStatsService.Dependencies makeDependencies() {
+        return new NetworkStatsService.Dependencies() {
+            @Override
+            public HandlerThread makeHandlerThread() {
+                return mHandlerThread;
+            }
+        };
+    }
+
     @After
     public void tearDown() throws Exception {
         IoUtils.deleteContents(mStatsDir);
@@ -234,6 +240,8 @@
 
         mSession.close();
         mService = null;
+
+        mHandlerThread.quitSafely();
     }
 
     @Test
@@ -939,9 +947,7 @@
         long minThresholdInBytes = 2 * 1024 * 1024; // 2 MB
         assertEquals(minThresholdInBytes, request.thresholdInBytes);
 
-        // Send dummy message to make sure that any previous message has been handled
-        mHandler.sendMessage(mHandler.obtainMessage(-1));
-        HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT);
+        HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
 
         // Make sure that the caller binder gets connected
         verify(mBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
@@ -1077,7 +1083,7 @@
 
         // Simulates alert quota of the provider has been reached.
         cb.onAlertReached();
-        HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT);
+        HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
 
         // Verifies that polling is triggered by alert reached.
         provider.expectStatsUpdate(0 /* unused */);
@@ -1294,9 +1300,7 @@
 
     private void forcePollAndWaitForIdle() {
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
-        // Send dummy message to make sure that any previous message has been handled
-        mHandler.sendMessage(mHandler.obtainMessage(-1));
-        HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT);
+        HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
     }
 
     static class LatchedHandler extends Handler {