Merge "LockAgent: Refactor violation data"
diff --git a/Android.bp b/Android.bp
index 78509ed..0d2caff 100644
--- a/Android.bp
+++ b/Android.bp
@@ -678,7 +678,7 @@
         "core/java/android/content/pm/AndroidTestBaseUpdater.java",
     ],
 
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     libs: [
         "ext",
     ],
@@ -865,7 +865,7 @@
 java_library {
     name: "ext",
     installable: true,
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     static_libs: [
         "libphonenumber-platform",
         "nist-sip",
@@ -1024,7 +1024,7 @@
 // updated to use hwbinder.stubs.
 java_library {
     name: "hwbinder",
-    no_framework_libs: true,
+    sdk_version: "core_platform",
 
     srcs: [
         "core/java/android/os/HidlSupport.java",
@@ -1557,7 +1557,7 @@
         "core/java/android/util/AndroidException.java",
     ],
     installable: false,
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     annotations_enabled: true,
     previous_api: ":last-released-public-api",
     merge_annotations_dirs: [
diff --git a/cmds/app_process/Android.bp b/cmds/app_process/Android.bp
index d541169..f925023 100644
--- a/cmds/app_process/Android.bp
+++ b/cmds/app_process/Android.bp
@@ -21,6 +21,7 @@
         "libbinder",
         "libcutils",
         "libdl",
+        "libhidlbase",
         "libhwbinder",
         "liblog",
         "libnativeloader",
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index f178fa2..20493e7 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -301,7 +301,7 @@
 // ====  java proto device library (for test only)  ==============================
 java_library {
     name: "statsdprotolite",
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     proto: {
         type: "lite",
         include_dirs: ["external/protobuf/src"],
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 31bbd16..39d63de 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1028,7 +1028,8 @@
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     @AdapterState
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link #getState()} instead to determine "
+            + "whether you can use BLE & BT classic.")
     public int getLeState() {
         int state = BluetoothAdapter.STATE_OFF;
 
@@ -1484,7 +1485,8 @@
      * @return true if the scan mode was set, false otherwise
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link #ACTION_REQUEST_DISCOVERABLE}, which "
+            + "shows UI that confirms the user wants to go into discoverable mode.")
     public boolean setScanMode(@ScanMode int mode, int duration) {
         if (getState() != STATE_ON) {
             return false;
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 34c7372..ee33103 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1051,7 +1051,7 @@
      * @return the Bluetooth alias, or null if no alias or there was a problem
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link #getName()} instead.")
     public String getAlias() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1100,7 +1100,7 @@
      * @see #getAlias()
      * @see #getName()
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link #getName()} instead.")
     public String getAliasName() {
         String name = getAlias();
         if (name == null) {
@@ -1975,7 +1975,8 @@
      * permissions.
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use "
+            + "{@link #createInsecureRfcommSocketToServiceRecord} instead.")
     public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
         if (!isBluetoothEnabled()) {
             Log.e(TAG, "Bluetooth is not enabled");
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index c06b837..3a23808 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -77,7 +77,8 @@
 
     private static final String TAG = "BluetoothServerSocket";
     private static final boolean DBG = false;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use public {@link BluetoothServerSocket} API "
+            + "instead.")
     /*package*/ final BluetoothSocket mSocket;
     private Handler mHandler;
     private int mMessage;
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 3a1e2f5..a6e3153 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -131,7 +131,7 @@
     private boolean mExcludeSdp = false; /* when true no SPP SDP record will be created */
     private boolean mAuthMitm = false;   /* when true Man-in-the-middle protection will be enabled*/
     private boolean mMin16DigitPin = false; /* Minimum 16 digit pin for sec mode 2 connections */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link BluetoothSocket} public API instead.")
     private ParcelFileDescriptor mPfd;
     @UnsupportedAppUsage
     private LocalSocket mSocket;
diff --git a/core/java/android/net/IpSecConfig.java b/core/java/android/net/IpSecConfig.java
index 3552655..43c8ff2 100644
--- a/core/java/android/net/IpSecConfig.java
+++ b/core/java/android/net/IpSecConfig.java
@@ -15,6 +15,7 @@
  */
 package android.net;
 
+import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -333,25 +334,25 @@
                 }
             };
 
-    @VisibleForTesting
-    /** Equals method used for testing */
-    public static boolean equals(IpSecConfig lhs, IpSecConfig rhs) {
-        if (lhs == null || rhs == null) return (lhs == rhs);
-        return (lhs.mMode == rhs.mMode
-                && lhs.mSourceAddress.equals(rhs.mSourceAddress)
-                && lhs.mDestinationAddress.equals(rhs.mDestinationAddress)
-                && ((lhs.mNetwork != null && lhs.mNetwork.equals(rhs.mNetwork))
-                        || (lhs.mNetwork == rhs.mNetwork))
-                && lhs.mEncapType == rhs.mEncapType
-                && lhs.mEncapSocketResourceId == rhs.mEncapSocketResourceId
-                && lhs.mEncapRemotePort == rhs.mEncapRemotePort
-                && lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
-                && lhs.mSpiResourceId == rhs.mSpiResourceId
-                && IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption)
-                && IpSecAlgorithm.equals(lhs.mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
-                && IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication)
-                && lhs.mMarkValue == rhs.mMarkValue
-                && lhs.mMarkMask == rhs.mMarkMask
-                && lhs.mXfrmInterfaceId == rhs.mXfrmInterfaceId);
+    @Override
+    public boolean equals(@Nullable Object other) {
+        if (!(other instanceof IpSecConfig)) return false;
+        final IpSecConfig rhs = (IpSecConfig) other;
+        return (mMode == rhs.mMode
+                && mSourceAddress.equals(rhs.mSourceAddress)
+                && mDestinationAddress.equals(rhs.mDestinationAddress)
+                && ((mNetwork != null && mNetwork.equals(rhs.mNetwork))
+                        || (mNetwork == rhs.mNetwork))
+                && mEncapType == rhs.mEncapType
+                && mEncapSocketResourceId == rhs.mEncapSocketResourceId
+                && mEncapRemotePort == rhs.mEncapRemotePort
+                && mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
+                && mSpiResourceId == rhs.mSpiResourceId
+                && IpSecAlgorithm.equals(mEncryption, rhs.mEncryption)
+                && IpSecAlgorithm.equals(mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
+                && IpSecAlgorithm.equals(mAuthentication, rhs.mAuthentication)
+                && mMarkValue == rhs.mMarkValue
+                && mMarkMask == rhs.mMarkMask
+                && mXfrmInterfaceId == rhs.mXfrmInterfaceId);
     }
 }
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index a12df28..93ae4f1 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -148,15 +148,13 @@
     }
 
     /**
-     * Equals method used for testing
-     *
-     * @hide
+     * Standard equals.
      */
-    @VisibleForTesting
-    public static boolean equals(IpSecTransform lhs, IpSecTransform rhs) {
-        if (lhs == null || rhs == null) return (lhs == rhs);
-        return IpSecConfig.equals(lhs.getConfig(), rhs.getConfig())
-                && lhs.mResourceId == rhs.mResourceId;
+    public boolean equals(Object other) {
+        if (this == other) return true;
+        if (!(other instanceof IpSecTransform)) return false;
+        final IpSecTransform rhs = (IpSecTransform) other;
+        return getConfig().equals(rhs.getConfig()) && mResourceId == rhs.mResourceId;
     }
 
     /**
diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java
index 46eddde..ec73866 100644
--- a/core/java/android/net/SocketKeepalive.java
+++ b/core/java/android/net/SocketKeepalive.java
@@ -44,9 +44,11 @@
  * {@link SocketKeepalive.Callback#onStopped} if the operation was successful or
  * {@link SocketKeepalive.Callback#onError} if an error occurred.
  *
- * The device SHOULD support keepalive offload. If it does not, it MUST reply with
+ * For cellular, the device MUST support at least 1 keepalive slot.
+ *
+ * For WiFi, the device SHOULD support keepalive offload. If it does not, it MUST reply with
  * {@link SocketKeepalive.Callback#onError} with {@code ERROR_UNSUPPORTED} to any keepalive offload
- * request. If it does, it MUST support at least 3 concurrent keepalive slots per transport.
+ * request. If it does, it MUST support at least 3 concurrent keepalive slots.
  */
 public abstract class SocketKeepalive implements AutoCloseable {
     static final String TAG = "SocketKeepalive";
diff --git a/core/java/android/net/util/KeepaliveUtils.java b/core/java/android/net/util/KeepaliveUtils.java
index 569fed1..bfc4563 100644
--- a/core/java/android/net/util/KeepaliveUtils.java
+++ b/core/java/android/net/util/KeepaliveUtils.java
@@ -34,9 +34,6 @@
 
     public static final String TAG = "KeepaliveUtils";
 
-    // Minimum supported keepalive count per transport if the network supports keepalive.
-    public static final int MIN_SUPPORTED_KEEPALIVE_COUNT = 3;
-
     public static class KeepaliveDeviceConfigurationException extends AndroidRuntimeException {
         public KeepaliveDeviceConfigurationException(final String msg) {
             super(msg);
@@ -84,10 +81,7 @@
                 throw new KeepaliveDeviceConfigurationException("Invalid transport " + transport);
             }
 
-            // Customized values should be either 0 to indicate the network doesn't support
-            // keepalive offload, or a positive value that is at least
-            // MIN_SUPPORTED_KEEPALIVE_COUNT if supported.
-            if (supported != 0 && supported < MIN_SUPPORTED_KEEPALIVE_COUNT) {
+            if (supported < 0) {
                 throw new KeepaliveDeviceConfigurationException(
                         "Invalid supported count " + supported + " for "
                                 + NetworkCapabilities.transportNameOf(transport));
diff --git a/core/java/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java
index 1364d8c..d9bcb3c 100644
--- a/core/java/android/net/util/SocketUtils.java
+++ b/core/java/android/net/util/SocketUtils.java
@@ -69,7 +69,10 @@
      */
     @NonNull
     public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex) {
-        return new PacketSocketAddress((short) protocol, ifIndex);
+        return new PacketSocketAddress(
+                (short) protocol /* sll_protocol */,
+                ifIndex /* sll_ifindex */,
+                null /* sll_addr */);
     }
 
     /**
@@ -77,7 +80,10 @@
      */
     @NonNull
     public static SocketAddress makePacketSocketAddress(int ifIndex, @NonNull byte[] hwAddr) {
-        return new PacketSocketAddress(ifIndex, hwAddr);
+        return new PacketSocketAddress(
+                (short) 0 /* sll_protocol */,
+                ifIndex /* sll_ifindex */,
+                hwAddr /* sll_addr */);
     }
 
     /**
diff --git a/core/java/com/android/internal/http/HttpDateTime.java b/core/java/com/android/internal/http/HttpDateTime.java
deleted file mode 100644
index f7706e3..0000000
--- a/core/java/com/android/internal/http/HttpDateTime.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2007 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.internal.http;
-
-import android.annotation.UnsupportedAppUsage;
-import android.text.format.Time;
-
-import java.util.Calendar;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Helper for parsing an HTTP date.
- */
-public final class HttpDateTime {
-
-    /*
-     * Regular expression for parsing HTTP-date.
-     *
-     * Wdy, DD Mon YYYY HH:MM:SS GMT
-     * RFC 822, updated by RFC 1123
-     *
-     * Weekday, DD-Mon-YY HH:MM:SS GMT
-     * RFC 850, obsoleted by RFC 1036
-     *
-     * Wdy Mon DD HH:MM:SS YYYY
-     * ANSI C's asctime() format
-     *
-     * with following variations
-     *
-     * Wdy, DD-Mon-YYYY HH:MM:SS GMT
-     * Wdy, (SP)D Mon YYYY HH:MM:SS GMT
-     * Wdy,DD Mon YYYY HH:MM:SS GMT
-     * Wdy, DD-Mon-YY HH:MM:SS GMT
-     * Wdy, DD Mon YYYY HH:MM:SS -HHMM
-     * Wdy, DD Mon YYYY HH:MM:SS
-     * Wdy Mon (SP)D HH:MM:SS YYYY
-     * Wdy Mon DD HH:MM:SS YYYY GMT
-     * 
-     * HH can be H if the first digit is zero.
-     * 
-     * Mon can be the full name of the month.
-     */
-    private static final String HTTP_DATE_RFC_REGEXP =
-            "([0-9]{1,2})[- ]([A-Za-z]{3,9})[- ]([0-9]{2,4})[ ]"
-            + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])";
-
-    private static final String HTTP_DATE_ANSIC_REGEXP =
-            "[ ]([A-Za-z]{3,9})[ ]+([0-9]{1,2})[ ]"
-            + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])[ ]([0-9]{2,4})";
-
-    /**
-     * The compiled version of the HTTP-date regular expressions.
-     */
-    private static final Pattern HTTP_DATE_RFC_PATTERN =
-            Pattern.compile(HTTP_DATE_RFC_REGEXP);
-    private static final Pattern HTTP_DATE_ANSIC_PATTERN =
-            Pattern.compile(HTTP_DATE_ANSIC_REGEXP);
-
-    private static class TimeOfDay {
-        TimeOfDay(int h, int m, int s) {
-            this.hour = h;
-            this.minute = m;
-            this.second = s;
-        }
-        
-        int hour;
-        int minute;
-        int second;
-    }
-
-    @UnsupportedAppUsage
-    public static long parse(String timeString)
-            throws IllegalArgumentException {
-
-        int date = 1;
-        int month = Calendar.JANUARY;
-        int year = 1970;
-        TimeOfDay timeOfDay;
-
-        Matcher rfcMatcher = HTTP_DATE_RFC_PATTERN.matcher(timeString);
-        if (rfcMatcher.find()) {
-            date = getDate(rfcMatcher.group(1));
-            month = getMonth(rfcMatcher.group(2));
-            year = getYear(rfcMatcher.group(3));
-            timeOfDay = getTime(rfcMatcher.group(4));
-        } else {
-            Matcher ansicMatcher = HTTP_DATE_ANSIC_PATTERN.matcher(timeString);
-            if (ansicMatcher.find()) {
-                month = getMonth(ansicMatcher.group(1));
-                date = getDate(ansicMatcher.group(2));
-                timeOfDay = getTime(ansicMatcher.group(3));
-                year = getYear(ansicMatcher.group(4));
-            } else {
-                throw new IllegalArgumentException();
-            }
-        }
-
-        // FIXME: Y2038 BUG!
-        if (year >= 2038) {
-            year = 2038;
-            month = Calendar.JANUARY;
-            date = 1;
-        }
-
-        Time time = new Time(Time.TIMEZONE_UTC);
-        time.set(timeOfDay.second, timeOfDay.minute, timeOfDay.hour, date,
-                month, year);
-        return time.toMillis(false /* use isDst */);
-    }
-
-    private static int getDate(String dateString) {
-        if (dateString.length() == 2) {
-            return (dateString.charAt(0) - '0') * 10
-                    + (dateString.charAt(1) - '0');
-        } else {
-            return (dateString.charAt(0) - '0');
-        }
-    }
-
-    /*
-     * jan = 9 + 0 + 13 = 22
-     * feb = 5 + 4 + 1 = 10
-     * mar = 12 + 0 + 17 = 29
-     * apr = 0 + 15 + 17 = 32
-     * may = 12 + 0 + 24 = 36
-     * jun = 9 + 20 + 13 = 42
-     * jul = 9 + 20 + 11 = 40
-     * aug = 0 + 20 + 6 = 26
-     * sep = 18 + 4 + 15 = 37
-     * oct = 14 + 2 + 19 = 35
-     * nov = 13 + 14 + 21 = 48
-     * dec = 3 + 4 + 2 = 9
-     */
-    private static int getMonth(String monthString) {
-        int hash = Character.toLowerCase(monthString.charAt(0)) +
-                Character.toLowerCase(monthString.charAt(1)) +
-                Character.toLowerCase(monthString.charAt(2)) - 3 * 'a';
-        switch (hash) {
-            case 22:
-                return Calendar.JANUARY;
-            case 10:
-                return Calendar.FEBRUARY;
-            case 29:
-                return Calendar.MARCH;
-            case 32:
-                return Calendar.APRIL;
-            case 36:
-                return Calendar.MAY;
-            case 42:
-                return Calendar.JUNE;
-            case 40:
-                return Calendar.JULY;
-            case 26:
-                return Calendar.AUGUST;
-            case 37:
-                return Calendar.SEPTEMBER;
-            case 35:
-                return Calendar.OCTOBER;
-            case 48:
-                return Calendar.NOVEMBER;
-            case 9:
-                return Calendar.DECEMBER;
-            default:
-                throw new IllegalArgumentException();
-        }
-    }
-
-    private static int getYear(String yearString) {
-        if (yearString.length() == 2) {
-            int year = (yearString.charAt(0) - '0') * 10
-                    + (yearString.charAt(1) - '0');
-            if (year >= 70) {
-                return year + 1900;
-            } else {
-                return year + 2000;
-            }
-        } else if (yearString.length() == 3) {
-            // According to RFC 2822, three digit years should be added to 1900.
-            int year = (yearString.charAt(0) - '0') * 100
-                    + (yearString.charAt(1) - '0') * 10
-                    + (yearString.charAt(2) - '0');
-            return year + 1900;
-        } else if (yearString.length() == 4) {
-             return (yearString.charAt(0) - '0') * 1000
-                    + (yearString.charAt(1) - '0') * 100
-                    + (yearString.charAt(2) - '0') * 10
-                    + (yearString.charAt(3) - '0');
-        } else {
-             return 1970;
-        }
-    }
-
-    private static TimeOfDay getTime(String timeString) {
-        // HH might be H
-        int i = 0;
-        int hour = timeString.charAt(i++) - '0';
-        if (timeString.charAt(i) != ':')
-            hour = hour * 10 + (timeString.charAt(i++) - '0');
-        // Skip ':'
-        i++;
-        
-        int minute = (timeString.charAt(i++) - '0') * 10
-                    + (timeString.charAt(i++) - '0');
-        // Skip ':'
-        i++;
-        
-        int second = (timeString.charAt(i++) - '0') * 10
-                  + (timeString.charAt(i++) - '0');
-
-        return new TimeOfDay(hour, minute, second);        
-    }
-}
diff --git a/core/proto/android/server/connectivity/Android.bp b/core/proto/android/server/connectivity/Android.bp
index c0ac2cb..4136239 100644
--- a/core/proto/android/server/connectivity/Android.bp
+++ b/core/proto/android/server/connectivity/Android.bp
@@ -21,5 +21,4 @@
         "data_stall_event.proto",
     ],
     sdk_version: "system_current",
-    no_framework_libs: true,
-}
\ No newline at end of file
+}
diff --git a/core/proto/android/stats/connectivity/Android.bp b/core/proto/android/stats/connectivity/Android.bp
index 5aa4ddb..5d642d38 100644
--- a/core/proto/android/stats/connectivity/Android.bp
+++ b/core/proto/android/stats/connectivity/Android.bp
@@ -21,5 +21,4 @@
         "network_stack.proto",
     ],
     sdk_version: "system_current",
-    no_framework_libs: true,
-}
\ No newline at end of file
+}
diff --git a/core/proto/android/stats/dnsresolver/Android.bp b/core/proto/android/stats/dnsresolver/Android.bp
index 0b5aa86..1e8c763 100644
--- a/core/proto/android/stats/dnsresolver/Android.bp
+++ b/core/proto/android/stats/dnsresolver/Android.bp
@@ -21,5 +21,4 @@
         "dns_resolver.proto",
     ],
     sdk_version: "system_current",
-    no_framework_libs: true,
 }
diff --git a/core/res/Android.bp b/core/res/Android.bp
index 4e60f8c..3402033 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -16,7 +16,7 @@
 
 android_app {
     name: "framework-res",
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     certificate: "platform",
 
     // Soong special-cases framework-res to install this alongside
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f94a5bd..1fce5be 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -353,7 +353,7 @@
          overridden by the device to present the capability of creating socket keepalives. -->
     <!-- An Array of "[NetworkCapabilities.TRANSPORT_*],[supported keepalives] -->
     <string-array translatable="false" name="config_networkSupportedKeepaliveCount">
-        <item>0,3</item>
+        <item>0,1</item>
         <item>1,3</item>
     </string-array>
 
diff --git a/graphics/proto/Android.bp b/graphics/proto/Android.bp
index 1d06348..ddced59 100644
--- a/graphics/proto/Android.bp
+++ b/graphics/proto/Android.bp
@@ -5,7 +5,6 @@
         type: "lite",
     },
     srcs: ["game_driver.proto"],
-    no_framework_libs: true,
     jarjar_rules: "jarjar-rules.txt",
     sdk_version: "28",
 }
diff --git a/proto/Android.bp b/proto/Android.bp
index e924a4d..ad4e04c 100644
--- a/proto/Android.bp
+++ b/proto/Android.bp
@@ -5,7 +5,7 @@
         type: "nano",
     },
     srcs: ["src/**/*.proto"],
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     // Pin java_version until jarjar is certified to support later versions. http://b/72703434
     java_version: "1.8",
     target: {
@@ -25,6 +25,5 @@
         type: "nano",
     },
     srcs: ["src/metrics_constants.proto"],
-    no_framework_libs: true,
     sdk_version: "system_current",
 }
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 626d724..9bae902 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -562,7 +562,7 @@
         if (KeepaliveInfo.STARTING == ki.mStartedState) {
             if (SUCCESS == reason) {
                 // Keepalive successfully started.
-                if (DBG) Log.d(TAG, "Started keepalive " + slot + " on " + nai.name());
+                Log.d(TAG, "Started keepalive " + slot + " on " + nai.name());
                 ki.mStartedState = KeepaliveInfo.STARTED;
                 try {
                     ki.mCallback.onStarted(slot);
diff --git a/services/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java
index cf52574..787fda3 100644
--- a/services/net/java/android/net/NetworkStackClient.java
+++ b/services/net/java/android/net/NetworkStackClient.java
@@ -488,7 +488,9 @@
     private void requestConnector(@NonNull NetworkStackCallback request) {
         // TODO: PID check.
         final int caller = Binder.getCallingUid();
-        if (caller != Process.SYSTEM_UID && !UserHandle.isSameApp(caller, Process.BLUETOOTH_UID)
+        if (caller != Process.SYSTEM_UID
+                && caller != Process.NETWORK_STACK_UID
+                && !UserHandle.isSameApp(caller, Process.BLUETOOTH_UID)
                 && !UserHandle.isSameApp(caller, Process.PHONE_UID)) {
             // Don't even attempt to obtain the connector and give a nice error message
             throw new SecurityException(
diff --git a/tests/net/util/Android.bp b/startop/apps/test/Android.bp
similarity index 64%
rename from tests/net/util/Android.bp
rename to startop/apps/test/Android.bp
index d8c502d..3adc05e 100644
--- a/tests/net/util/Android.bp
+++ b/startop/apps/test/Android.bp
@@ -14,17 +14,10 @@
 // limitations under the License.
 //
 
-// Common utilities for network tests.
-java_library {
-    name: "frameworks-net-testutils",
-    srcs: ["java/**/*.java"],
-    // test_current to be also appropriate for CTS tests
-    sdk_version: "test_current",
-    static_libs: [
-        "androidx.annotation_annotation",
-        "junit",
+android_app {
+    name: "startop_test_app",
+    srcs: [
+        "src/EmptyActivity.java",
+        "src/LayoutInflation.java",
     ],
-    libs: [
-        "android.test.base.stubs",
-    ],
-}
\ No newline at end of file
+}
diff --git a/startop/apps/test/AndroidManifest.xml b/startop/apps/test/AndroidManifest.xml
new file mode 100644
index 0000000..6b08118
--- /dev/null
+++ b/startop/apps/test/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.startop.test">
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true">
+        <activity android:name=".EmptyActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".LayoutInflation" android:exported="true" />
+    </application>
+
+</manifest>
diff --git a/startop/apps/test/README.md b/startop/apps/test/README.md
new file mode 100644
index 0000000..53c184b
--- /dev/null
+++ b/startop/apps/test/README.md
@@ -0,0 +1,26 @@
+This directory contains a simple Android app that is meant to help in doing
+controlled startup performance experiments.
+
+This app is structured as a number of activities that each are useful for a
+different aspect of startup testing.
+
+# Activities
+
+## EmptyActivity
+
+This is the simplest possible Android activity. Starting this exercises only the
+system parts of startup without any app-specific behavior.
+
+    adb shell am start -n com.android.startop.test/.EmptyActivity
+
+## LayoutInflation
+
+This activity inflates a reasonably complex layout to see the impact of layout
+inflation. The layout is supported by the viewcompiler, so this can be used for
+testing precompiled layout performance.
+
+The activity adds an `inflate#activity_main` slice to atrace around the time
+spent in view inflation to make it easier to focus on the time spent in view
+inflation.
+
+    adb shell am start -n com.android.startop.test/.LayoutInflation
diff --git a/startop/apps/test/res/drawable-v24/ic_launcher_foreground.xml b/startop/apps/test/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..c7bd21d
--- /dev/null
+++ b/startop/apps/test/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportHeight="108"
+    android:viewportWidth="108">
+    <path
+        android:fillType="evenOdd"
+        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
+        android:strokeColor="#00000000"
+        android:strokeWidth="1">
+        <aapt:attr name="android:fillColor">
+            <gradient
+                android:endX="78.5885"
+                android:endY="90.9159"
+                android:startX="48.7653"
+                android:startY="61.0927"
+                android:type="linear">
+                <item
+                    android:color="#44000000"
+                    android:offset="0.0" />
+                <item
+                    android:color="#00000000"
+                    android:offset="1.0" />
+            </gradient>
+        </aapt:attr>
+    </path>
+    <path
+        android:fillColor="#FFFFFF"
+        android:fillType="nonZero"
+        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
+        android:strokeColor="#00000000"
+        android:strokeWidth="1" />
+</vector>
diff --git a/startop/apps/test/res/drawable/ic_launcher_background.xml b/startop/apps/test/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..d5fccc5
--- /dev/null
+++ b/startop/apps/test/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportHeight="108"
+    android:viewportWidth="108">
+    <path
+        android:fillColor="#26A69A"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+</vector>
diff --git a/startop/apps/test/res/layout/activity_main.xml b/startop/apps/test/res/layout/activity_main.xml
new file mode 100644
index 0000000..16f5641f2
--- /dev/null
+++ b/startop/apps/test/res/layout/activity_main.xml
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity" >
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_weight="0.5"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <CheckBox
+            android:id="@+id/checkBox5"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckBox" />
+
+        <EditText
+            android:id="@+id/myEditText"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="EditText" />
+
+        <EditText
+            android:id="@+id/myEditText2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="EditText" />
+
+        <Button
+            android:id="@+id/myButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <Button
+            android:id="@+id/myButton2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <ProgressBar
+            android:id="@+id/progressBar"
+            style="?android:attr/progressBarStyle"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <CheckBox
+            android:id="@+id/checkBox2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckBox" />
+
+        <RadioButton
+            android:id="@+id/radioButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="RadioButton" />
+
+        <CheckedTextView
+            android:id="@+id/checkedTextView2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckedTextView" />
+
+        <TextView
+            android:id="@+id/textView"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <Switch
+            android:id="@+id/switch1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Switch" />
+
+        <CheckBox
+            android:id="@+id/checkBox3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckBox" />
+
+        <CheckBox
+            android:id="@+id/checkBox4"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckBox" />
+
+        <EditText
+            android:id="@+id/editText2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:ems="10"
+            android:inputType="textPassword" />
+
+        <RadioButton
+            android:id="@+id/radioButton2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="RadioButton" />
+
+        <EditText
+            android:id="@+id/editText3"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:ems="10"
+            android:inputType="numberDecimal" />
+
+        <SearchView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" >
+
+        </SearchView>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_weight="0.5"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <Button
+            android:id="@+id/myButton3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <Button
+            android:id="@+id/myButton4"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <Button
+            android:id="@+id/button14"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <EditText
+            android:id="@+id/myEditText3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="EditText" />
+
+        <Button
+            android:id="@+id/button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <EditText
+            android:id="@+id/myEditText4"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="EditText" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton5"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton4"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <ProgressBar
+            android:id="@+id/progressBar2"
+            style="?android:attr/progressBarStyleHorizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <EditText
+            android:id="@+id/editText"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:ems="10"
+            android:inputType="date" />
+
+        <CheckedTextView
+            android:id="@+id/checkedTextView"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckedTextView" />
+
+        <SeekBar
+            android:id="@+id/seekBar"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton6"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton7"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+    </LinearLayout>
+</LinearLayout>
diff --git a/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher.xml b/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
\ No newline at end of file
diff --git a/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher_round.xml b/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
\ No newline at end of file
diff --git a/startop/apps/test/res/mipmap-hdpi/ic_launcher.png b/startop/apps/test/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a2f5908
--- /dev/null
+++ b/startop/apps/test/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-hdpi/ic_launcher_round.png b/startop/apps/test/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..1b52399
--- /dev/null
+++ b/startop/apps/test/res/mipmap-hdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-mdpi/ic_launcher.png b/startop/apps/test/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..ff10afd
--- /dev/null
+++ b/startop/apps/test/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-mdpi/ic_launcher_round.png b/startop/apps/test/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..115a4c7
--- /dev/null
+++ b/startop/apps/test/res/mipmap-mdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xhdpi/ic_launcher.png b/startop/apps/test/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..dcd3cd8
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xhdpi/ic_launcher_round.png b/startop/apps/test/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..459ca60
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xhdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xxhdpi/ic_launcher.png b/startop/apps/test/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..8ca12fe
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xxhdpi/ic_launcher_round.png b/startop/apps/test/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8e19b41
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher.png b/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b824ebd
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher_round.png b/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4c19a13
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/test/res/values/colors.xml b/startop/apps/test/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/startop/apps/test/res/values/colors.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+</resources>
diff --git a/startop/apps/test/res/values/strings.xml b/startop/apps/test/res/values/strings.xml
new file mode 100644
index 0000000..18419b5
--- /dev/null
+++ b/startop/apps/test/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">Startup Testing Swiss Army Knife</string>
+</resources>
diff --git a/tests/net/util/Android.bp b/startop/apps/test/src/EmptyActivity.java
similarity index 63%
copy from tests/net/util/Android.bp
copy to startop/apps/test/src/EmptyActivity.java
index d8c502d..5202938 100644
--- a/tests/net/util/Android.bp
+++ b/startop/apps/test/src/EmptyActivity.java
@@ -14,17 +14,13 @@
 // limitations under the License.
 //
 
-// Common utilities for network tests.
-java_library {
-    name: "frameworks-net-testutils",
-    srcs: ["java/**/*.java"],
-    // test_current to be also appropriate for CTS tests
-    sdk_version: "test_current",
-    static_libs: [
-        "androidx.annotation_annotation",
-        "junit",
-    ],
-    libs: [
-        "android.test.base.stubs",
-    ],
-}
\ No newline at end of file
+package com.android.startop.test;
+
+import android.app.Activity;
+
+/**
+ * The simplest possible Android activity, for testing startup with no
+ * app-specific behavior.
+ */
+public class EmptyActivity extends Activity {
+}
diff --git a/startop/apps/test/src/LayoutInflation.java b/startop/apps/test/src/LayoutInflation.java
new file mode 100644
index 0000000..daa4e45
--- /dev/null
+++ b/startop/apps/test/src/LayoutInflation.java
@@ -0,0 +1,39 @@
+//
+// 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 com.android.startop.test;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Trace;
+import android.view.LayoutInflater;
+import android.view.View;
+
+/**
+ * This activity inflates a reasonably complex layout to see the impact of
+ * layout inflation. The layout is supported by the viewcompiler, so this can be
+ * used for testing precompiled layout performance.
+ */
+public class LayoutInflation extends Activity {
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        LayoutInflater inflater = LayoutInflater.from(this);
+        Trace.beginSection("inflate layout:activity_main");
+        View view = inflater.inflate(R.layout.activity_main, /*root=*/null);
+        Trace.endSection();
+        setContentView(view);
+    }
+}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 44a135d..e9af8a8 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -16,6 +16,8 @@
 
 package android.telephony;
 
+import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -1605,6 +1607,12 @@
         }
     }
 
+    /** @hide */
+    public static int networkTypeToAccessNetworkType(@TelephonyManager.NetworkType
+            int networkType) {
+        return rilRadioTechnologyToAccessNetworkType(networkTypeToRilRadioTechnology(networkType));
+    }
+
     /**
      * Get current data network type.
      *
@@ -1730,6 +1738,36 @@
         return false;
     }
 
+    /**
+     *
+     * Returns whether the bearerBitmask includes a networkType that matches the accessNetworkType.
+     *
+     * The NetworkType refers to NetworkType in TelephonyManager. For example
+     * {@link TelephonyManager#NETWORK_TYPE_GPRS}.
+     *
+     * The accessNetworkType refers to {@link AccessNetworkType}.
+     *
+     * @hide
+     * */
+    public static boolean networkBitmaskHasAccessNetworkType(
+            @TelephonyManager.NetworkTypeBitMask int networkBitmask, int accessNetworkType) {
+        if (networkBitmask == NETWORK_TYPE_BITMASK_UNKNOWN) return true;
+        if (accessNetworkType == AccessNetworkType.UNKNOWN) return false;
+
+        int networkType = 1;
+        while (networkBitmask != 0) {
+            if ((networkBitmask & 1) != 0) {
+                if (networkTypeToAccessNetworkType(networkType) == accessNetworkType) {
+                    return true;
+                }
+            }
+            networkBitmask = networkBitmask >> 1;
+            networkType++;
+        }
+
+        return false;
+    }
+
     /** @hide */
     public static int getBitmaskForTech(int radioTech) {
         if (radioTech >= 1) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c955efb..a88434d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -93,6 +93,8 @@
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.TelephonyProperties;
 
+import dalvik.system.VMRuntime;
+
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.lang.annotation.Retention;
@@ -1485,6 +1487,48 @@
      */
     public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4;
 
+    /**
+     * Integer intent extra to be used with {@link #ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED}
+     * to indicate if the SIM combination in DSDS has limitation or compatible issue.
+     * e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios.
+     *
+     * @hide
+     */
+    public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE =
+            "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
+
+    /** @hide */
+    @IntDef({
+            EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE,
+            EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SimCombinationWarningType{}
+
+    /**
+     * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
+     * to indicate there's no SIM combination warning.
+     * @hide
+     */
+    public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0;
+
+    /**
+     * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
+     * to indicate two active SIMs are both CDMA hence there might be functional limitation.
+     * @hide
+     */
+    public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1;
+
+    /**
+     * String intent extra to be used with {@link #ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED}
+     * to indicate what's the name of SIM combination it has limitation or compatible issue.
+     * e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios, and the
+     * name will be "operator1 & operator2".
+     *
+     * @hide
+     */
+    public static final String EXTRA_SIM_COMBINATION_NAMES =
+            "android.telephony.extra.SIM_COMBINATION_NAMES";
     //
     //
     // Device Info
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index eb25acf..135bf90 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -6,7 +6,6 @@
     static_libs: [
         "FrameworksNetCommonTests",
         "frameworks-base-testutils",
-        "frameworks-net-testutils",
         "framework-protos",
         "androidx.test.rules",
         "mockito-target-minus-junit4",
diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp
index db1ccb4..e44d460 100644
--- a/tests/net/common/Android.bp
+++ b/tests/net/common/Android.bp
@@ -21,12 +21,12 @@
     srcs: ["java/**/*.java", "java/**/*.kt"],
     static_libs: [
         "androidx.test.rules",
-        "frameworks-net-testutils",
         "junit",
         "mockito-target-minus-junit4",
+        "net-tests-utils",
         "platform-test-annotations",
     ],
     libs: [
         "android.test.base.stubs",
     ],
-}
\ No newline at end of file
+}
diff --git a/tests/net/common/java/android/net/IpPrefixTest.java b/tests/net/common/java/android/net/IpPrefixTest.java
index 719960d..985e10d 100644
--- a/tests/net/common/java/android/net/IpPrefixTest.java
+++ b/tests/net/common/java/android/net/IpPrefixTest.java
@@ -16,16 +16,18 @@
 
 package android.net;
 
+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.assertParcelingIsLossless;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.os.Parcel;
-
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -171,56 +173,46 @@
 
     }
 
-    private void assertAreEqual(Object o1, Object o2) {
-        assertTrue(o1.equals(o2));
-        assertTrue(o2.equals(o1));
-    }
-
-    private void assertAreNotEqual(Object o1, Object o2) {
-        assertFalse(o1.equals(o2));
-        assertFalse(o2.equals(o1));
-    }
-
     @Test
     public void testEquals() {
         IpPrefix p1, p2;
 
         p1 = new IpPrefix("192.0.2.251/23");
         p2 = new IpPrefix(new byte[]{(byte) 192, (byte) 0, (byte) 2, (byte) 251}, 23);
-        assertAreEqual(p1, p2);
+        assertEqualBothWays(p1, p2);
 
         p1 = new IpPrefix("192.0.2.5/23");
-        assertAreEqual(p1, p2);
+        assertEqualBothWays(p1, p2);
 
         p1 = new IpPrefix("192.0.2.5/24");
-        assertAreNotEqual(p1, p2);
+        assertNotEqualEitherWay(p1, p2);
 
         p1 = new IpPrefix("192.0.4.5/23");
-        assertAreNotEqual(p1, p2);
+        assertNotEqualEitherWay(p1, p2);
 
 
         p1 = new IpPrefix("2001:db8:dead:beef:f00::80/122");
         p2 = new IpPrefix(IPV6_BYTES, 122);
         assertEquals("2001:db8:dead:beef:f00::80/122", p2.toString());
-        assertAreEqual(p1, p2);
+        assertEqualBothWays(p1, p2);
 
         p1 = new IpPrefix("2001:db8:dead:beef:f00::bf/122");
-        assertAreEqual(p1, p2);
+        assertEqualBothWays(p1, p2);
 
         p1 = new IpPrefix("2001:db8:dead:beef:f00::8:0/123");
-        assertAreNotEqual(p1, p2);
+        assertNotEqualEitherWay(p1, p2);
 
         p1 = new IpPrefix("2001:db8:dead:beef::/122");
-        assertAreNotEqual(p1, p2);
+        assertNotEqualEitherWay(p1, p2);
 
         // 192.0.2.4/32 != c000:0204::/32.
         byte[] ipv6bytes = new byte[16];
         System.arraycopy(IPV4_BYTES, 0, ipv6bytes, 0, IPV4_BYTES.length);
         p1 = new IpPrefix(ipv6bytes, 32);
-        assertAreEqual(p1, new IpPrefix("c000:0204::/32"));
+        assertEqualBothWays(p1, new IpPrefix("c000:0204::/32"));
 
         p2 = new IpPrefix(IPV4_BYTES, 32);
-        assertAreNotEqual(p1, p2);
+        assertNotEqualEitherWay(p1, p2);
     }
 
     @Test
@@ -356,25 +348,6 @@
         assertEquals(InetAddress.parseNumericAddress("192.0.2.0"), p.getAddress());
     }
 
-    public IpPrefix passThroughParcel(IpPrefix p) {
-        Parcel parcel = Parcel.obtain();
-        IpPrefix p2 = null;
-        try {
-            p.writeToParcel(parcel, 0);
-            parcel.setDataPosition(0);
-            p2 = IpPrefix.CREATOR.createFromParcel(parcel);
-        } finally {
-            parcel.recycle();
-        }
-        assertNotNull(p2);
-        return p2;
-    }
-
-    public void assertParcelingIsLossless(IpPrefix p) {
-        IpPrefix p2 = passThroughParcel(p);
-        assertEquals(p, p2);
-    }
-
     @Test
     public void testParceling() {
         IpPrefix p;
@@ -386,5 +359,7 @@
         p = new IpPrefix("192.0.2.0/25");
         assertParcelingIsLossless(p);
         assertTrue(p.isIPv4());
+
+        assertFieldCountEquals(2, IpPrefix.class);
     }
 }
diff --git a/tests/net/common/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java
index d462441b..b2e573b 100644
--- a/tests/net/common/java/android/net/LinkAddressTest.java
+++ b/tests/net/common/java/android/net/LinkAddressTest.java
@@ -27,15 +27,17 @@
 import static android.system.OsConstants.RT_SCOPE_SITE;
 import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 
+import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
+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;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.os.Parcel;
-
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -217,67 +219,56 @@
                 l1.isSameAddressAs(l2));
     }
 
-    private void assertLinkAddressesEqual(LinkAddress l1, LinkAddress l2) {
-        assertTrue(l1 + " unexpectedly not equal to " + l2, l1.equals(l2));
-        assertTrue(l2 + " unexpectedly not equal to " + l1, l2.equals(l1));
-        assertEquals(l1.hashCode(), l2.hashCode());
-    }
-
-    private void assertLinkAddressesNotEqual(LinkAddress l1, LinkAddress l2) {
-        assertFalse(l1 + " unexpectedly equal to " + l2, l1.equals(l2));
-        assertFalse(l2 + " unexpectedly equal to " + l1, l2.equals(l1));
-    }
-
     @Test
     public void testEqualsAndSameAddressAs() {
         LinkAddress l1, l2, l3;
 
         l1 = new LinkAddress("2001:db8::1/64");
         l2 = new LinkAddress("2001:db8::1/64");
-        assertLinkAddressesEqual(l1, l2);
+        assertEqualBothWays(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         l2 = new LinkAddress("2001:db8::1/65");
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsNotSameAddressAs(l1, l2);
 
         l2 = new LinkAddress("2001:db8::2/64");
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsNotSameAddressAs(l1, l2);
 
 
         l1 = new LinkAddress("192.0.2.1/24");
         l2 = new LinkAddress("192.0.2.1/24");
-        assertLinkAddressesEqual(l1, l2);
+        assertEqualBothWays(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         l2 = new LinkAddress("192.0.2.1/23");
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsNotSameAddressAs(l1, l2);
 
         l2 = new LinkAddress("192.0.2.2/24");
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsNotSameAddressAs(l1, l2);
 
 
         // Check equals() and isSameAddressAs() on identical addresses with different flags.
         l1 = new LinkAddress(V6_ADDRESS, 64);
         l2 = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_UNIVERSE);
-        assertLinkAddressesEqual(l1, l2);
+        assertEqualBothWays(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         l2 = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_UNIVERSE);
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         // Check equals() and isSameAddressAs() on identical addresses with different scope.
         l1 = new LinkAddress(V4_ADDRESS, 24);
         l2 = new LinkAddress(V4_ADDRESS, 24, 0, RT_SCOPE_UNIVERSE);
-        assertLinkAddressesEqual(l1, l2);
+        assertEqualBothWays(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         l2 = new LinkAddress(V4_ADDRESS, 24, 0, RT_SCOPE_HOST);
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         // Addresses with the same start or end bytes aren't equal between families.
@@ -291,10 +282,10 @@
         assertTrue(Arrays.equals(ipv4Bytes, l2FirstIPv6Bytes));
         assertTrue(Arrays.equals(ipv4Bytes, l3LastIPv6Bytes));
 
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsNotSameAddressAs(l1, l2);
 
-        assertLinkAddressesNotEqual(l1, l3);
+        assertNotEqualEitherWay(l1, l3);
         assertIsNotSameAddressAs(l1, l3);
 
         // Because we use InetAddress, an IPv4 address is equal to its IPv4-mapped address.
@@ -302,7 +293,7 @@
         String addressString = V4 + "/24";
         l1 = new LinkAddress(addressString);
         l2 = new LinkAddress("::ffff:" + addressString);
-        assertLinkAddressesEqual(l1, l2);
+        assertEqualBothWays(l1, l2);
         assertIsSameAddressAs(l1, l2);
     }
 
@@ -319,25 +310,6 @@
         assertNotEquals(l1.hashCode(), l2.hashCode());
     }
 
-    private LinkAddress passThroughParcel(LinkAddress l) {
-        Parcel p = Parcel.obtain();
-        LinkAddress l2 = null;
-        try {
-            l.writeToParcel(p, 0);
-            p.setDataPosition(0);
-            l2 = LinkAddress.CREATOR.createFromParcel(p);
-        } finally {
-            p.recycle();
-        }
-        assertNotNull(l2);
-        return l2;
-    }
-
-    private void assertParcelingIsLossless(LinkAddress l) {
-      LinkAddress l2 = passThroughParcel(l);
-      assertEquals(l, l2);
-    }
-
     @Test
     public void testParceling() {
         LinkAddress l;
@@ -346,7 +318,7 @@
         assertParcelingIsLossless(l);
 
         l = new LinkAddress(V4 + "/28", IFA_F_PERMANENT, RT_SCOPE_LINK);
-        assertParcelingIsLossless(l);
+        assertParcelSane(l, 4);
     }
 
     private void assertGlobalPreferred(LinkAddress l, String msg) {
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index e1c4238..b0464d9 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -31,8 +33,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.util.TestUtils;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -942,13 +942,13 @@
 
         source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
 
-        TestUtils.assertParcelingIsLossless(source);
+        assertParcelingIsLossless(source);
     }
 
     @Test
     public void testParcelUninitialized() throws Exception {
         LinkProperties empty = new LinkProperties();
-        TestUtils.assertParcelingIsLossless(empty);
+        assertParcelingIsLossless(empty);
     }
 
     @Test
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 6bc7c1b..2ca0d1a8 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -38,6 +38,9 @@
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
 
+import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -45,7 +48,6 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.os.Parcel;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArraySet;
 
@@ -267,9 +269,9 @@
             .setUids(uids)
             .addCapability(NET_CAPABILITY_EIMS)
             .addCapability(NET_CAPABILITY_NOT_METERED);
-        assertEqualsThroughMarshalling(netCap);
+        assertParcelingIsLossless(netCap);
         netCap.setSSID(TEST_SSID);
-        assertEqualsThroughMarshalling(netCap);
+        assertParcelSane(netCap, 11);
     }
 
     @Test
@@ -542,18 +544,6 @@
         nc1.combineCapabilities(nc3);
     }
 
-    private void assertEqualsThroughMarshalling(NetworkCapabilities netCap) {
-        Parcel p = Parcel.obtain();
-        netCap.writeToParcel(p, /* flags */ 0);
-        p.setDataPosition(0);
-        byte[] marshalledData = p.marshall();
-
-        p = Parcel.obtain();
-        p.unmarshall(marshalledData, 0, marshalledData.length);
-        p.setDataPosition(0);
-        assertEquals(NetworkCapabilities.CREATOR.createFromParcel(p), netCap);
-    }
-
     @Test
     public void testSet() {
         NetworkCapabilities nc1 = new NetworkCapabilities();
diff --git a/tests/net/common/java/android/net/NetworkTest.java b/tests/net/common/java/android/net/NetworkTest.java
index 38bc744..11d44b8 100644
--- a/tests/net/common/java/android/net/NetworkTest.java
+++ b/tests/net/common/java/android/net/NetworkTest.java
@@ -18,13 +18,10 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.net.LocalServerSocket;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.net.Network;
 import android.platform.test.annotations.AppModeFull;
 
 import androidx.test.filters.SmallTest;
@@ -40,7 +37,6 @@
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.SocketException;
-import java.util.Objects;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -123,29 +119,29 @@
         Network three = new Network(3);
 
         // None of the hashcodes are zero.
-        assertNotEqual(0, one.hashCode());
-        assertNotEqual(0, two.hashCode());
-        assertNotEqual(0, three.hashCode());
+        assertNotEquals(0, one.hashCode());
+        assertNotEquals(0, two.hashCode());
+        assertNotEquals(0, three.hashCode());
 
         // All the hashcodes are distinct.
-        assertNotEqual(one.hashCode(), two.hashCode());
-        assertNotEqual(one.hashCode(), three.hashCode());
-        assertNotEqual(two.hashCode(), three.hashCode());
+        assertNotEquals(one.hashCode(), two.hashCode());
+        assertNotEquals(one.hashCode(), three.hashCode());
+        assertNotEquals(two.hashCode(), three.hashCode());
 
         // None of the handles are zero.
-        assertNotEqual(0, one.getNetworkHandle());
-        assertNotEqual(0, two.getNetworkHandle());
-        assertNotEqual(0, three.getNetworkHandle());
+        assertNotEquals(0, one.getNetworkHandle());
+        assertNotEquals(0, two.getNetworkHandle());
+        assertNotEquals(0, three.getNetworkHandle());
 
         // All the handles are distinct.
-        assertNotEqual(one.getNetworkHandle(), two.getNetworkHandle());
-        assertNotEqual(one.getNetworkHandle(), three.getNetworkHandle());
-        assertNotEqual(two.getNetworkHandle(), three.getNetworkHandle());
+        assertNotEquals(one.getNetworkHandle(), two.getNetworkHandle());
+        assertNotEquals(one.getNetworkHandle(), three.getNetworkHandle());
+        assertNotEquals(two.getNetworkHandle(), three.getNetworkHandle());
 
         // The handles are not equal to the hashcodes.
-        assertNotEqual(one.hashCode(), one.getNetworkHandle());
-        assertNotEqual(two.hashCode(), two.getNetworkHandle());
-        assertNotEqual(three.hashCode(), three.getNetworkHandle());
+        assertNotEquals(one.hashCode(), one.getNetworkHandle());
+        assertNotEquals(two.hashCode(), two.getNetworkHandle());
+        assertNotEquals(three.hashCode(), three.getNetworkHandle());
 
         // Adjust as necessary to test an implementation's specific constants.
         // When running with runtest, "adb logcat -s TestRunner" can be useful.
@@ -154,15 +150,11 @@
         assertEquals(16290598925L, three.getNetworkHandle());
     }
 
-    private static <T> void assertNotEqual(T t1, T t2) {
-        assertFalse(Objects.equals(t1, t2));
-    }
-
     @Test
     public void testGetPrivateDnsBypassingCopy() {
         final Network copy = mNetwork.getPrivateDnsBypassingCopy();
         assertEquals(mNetwork.netId, copy.netId);
-        assertNotEqual(copy.netId, copy.getNetIdForResolv());
-        assertNotEqual(mNetwork.getNetIdForResolv(), copy.getNetIdForResolv());
+        assertNotEquals(copy.netId, copy.getNetIdForResolv());
+        assertNotEquals(mNetwork.getNetIdForResolv(), copy.getNetIdForResolv());
     }
 }
diff --git a/tests/net/common/java/android/net/RouteInfoTest.java b/tests/net/common/java/android/net/RouteInfoTest.java
index 2edbd40..5ce8436 100644
--- a/tests/net/common/java/android/net/RouteInfoTest.java
+++ b/tests/net/common/java/android/net/RouteInfoTest.java
@@ -18,7 +18,11 @@
 
 import static android.net.RouteInfo.RTN_UNREACHABLE;
 
-import android.os.Parcel;
+import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
+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 junit.framework.TestCase;
@@ -109,47 +113,37 @@
         assertFalse(ipv4Default.matches(Address("2001:db8::f00")));
     }
 
-    private void assertAreEqual(Object o1, Object o2) {
-        assertTrue(o1.equals(o2));
-        assertTrue(o2.equals(o1));
-    }
-
-    private void assertAreNotEqual(Object o1, Object o2) {
-        assertFalse(o1.equals(o2));
-        assertFalse(o2.equals(o1));
-    }
-
     public void testEquals() {
         // IPv4
         RouteInfo r1 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0");
         RouteInfo r2 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0");
-        assertAreEqual(r1, r2);
+        assertEqualBothWays(r1, r2);
 
         RouteInfo r3 = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("2001:db8::1"), "wlan0");
         RouteInfo r4 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::2"), "wlan0");
         RouteInfo r5 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "rmnet0");
-        assertAreNotEqual(r1, r3);
-        assertAreNotEqual(r1, r4);
-        assertAreNotEqual(r1, r5);
+        assertNotEqualEitherWay(r1, r3);
+        assertNotEqualEitherWay(r1, r4);
+        assertNotEqualEitherWay(r1, r5);
 
         // IPv6
         r1 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "wlan0");
         r2 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "wlan0");
-        assertAreEqual(r1, r2);
+        assertEqualBothWays(r1, r2);
 
         r3 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0");
         r4 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.2"), "wlan0");
         r5 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "rmnet0");
-        assertAreNotEqual(r1, r3);
-        assertAreNotEqual(r1, r4);
-        assertAreNotEqual(r1, r5);
+        assertNotEqualEitherWay(r1, r3);
+        assertNotEqualEitherWay(r1, r4);
+        assertNotEqualEitherWay(r1, r5);
 
         // Interfaces (but not destinations or gateways) can be null.
         r1 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), null);
         r2 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), null);
         r3 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0");
-        assertAreEqual(r1, r2);
-        assertAreNotEqual(r1, r3);
+        assertEqualBothWays(r1, r2);
+        assertNotEqualEitherWay(r1, r3);
     }
 
     public void testHostAndDefaultRoutes() {
@@ -257,25 +251,6 @@
       // No exceptions? Good.
     }
 
-    public RouteInfo passThroughParcel(RouteInfo r) {
-        Parcel p = Parcel.obtain();
-        RouteInfo r2 = null;
-        try {
-            r.writeToParcel(p, 0);
-            p.setDataPosition(0);
-            r2 = RouteInfo.CREATOR.createFromParcel(p);
-        } finally {
-            p.recycle();
-        }
-        assertNotNull(r2);
-        return r2;
-    }
-
-    public void assertParcelingIsLossless(RouteInfo r) {
-      RouteInfo r2 = passThroughParcel(r);
-      assertEquals(r, r2);
-    }
-
     public void testParceling() {
         RouteInfo r;
 
@@ -283,6 +258,6 @@
         assertParcelingIsLossless(r);
 
         r = new RouteInfo(Prefix("192.0.2.0/24"), null, "wlan0");
-        assertParcelingIsLossless(r);
+        assertParcelSane(r, 6);
     }
 }
diff --git a/tests/net/common/java/android/net/StaticIpConfigurationTest.java b/tests/net/common/java/android/net/StaticIpConfigurationTest.java
index 5096be2..b5f23bf 100644
--- a/tests/net/common/java/android/net/StaticIpConfigurationTest.java
+++ b/tests/net/common/java/android/net/StaticIpConfigurationTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -34,7 +35,6 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Objects;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -61,10 +61,6 @@
         assertEquals(0, s.dnsServers.size());
     }
 
-    private static <T> void assertNotEquals(T t1, T t2) {
-        assertFalse(Objects.equals(t1, t2));
-    }
-
     private StaticIpConfiguration makeTestObject() {
         StaticIpConfiguration s = new StaticIpConfiguration();
         s.ipAddress = ADDR;
diff --git a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
index 0ce7c91..f4f804a 100644
--- a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
@@ -16,6 +16,8 @@
 
 package android.net.apf;
 
+import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -24,9 +26,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.util.ParcelableTestUtil;
-import com.android.internal.util.TestUtils;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -40,9 +39,7 @@
         assertEquals(456, caps.maximumApfProgramSize);
         assertEquals(789, caps.apfPacketFormat);
 
-        ParcelableTestUtil.assertFieldCountEquals(3, ApfCapabilities.class);
-
-        TestUtils.assertParcelingIsLossless(caps);
+        assertParcelSane(caps, 3);
     }
 
     @Test
diff --git a/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt b/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt
index 8d055c9..0b7b740 100644
--- a/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics;
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
@@ -30,11 +28,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class ApfProgramEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     private infix fun Int.hasFlag(flag: Int) = (this and (1 shl flag)) != 0
 
     @Test
@@ -55,7 +48,7 @@
         assertEquals(5, apfProgramEvent.programLength)
         assertEquals(ApfProgramEvent.flagsFor(true, true), apfProgramEvent.flags)
 
-        testParcel(apfProgramEvent, 6)
+        assertParcelSane(apfProgramEvent, 6)
     }
 
     @Test
diff --git a/tests/net/common/java/android/net/metrics/ApfStatsTest.kt b/tests/net/common/java/android/net/metrics/ApfStatsTest.kt
index f8eb40c..46a8c8e 100644
--- a/tests/net/common/java/android/net/metrics/ApfStatsTest.kt
+++ b/tests/net/common/java/android/net/metrics/ApfStatsTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -28,11 +26,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class ApfStatsTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testBuilderAndParcel() {
         val apfStats = ApfStats.Builder()
@@ -59,6 +52,6 @@
         assertEquals(8, apfStats.programUpdatesAllowingMulticast)
         assertEquals(9, apfStats.maxProgramSize)
 
-        testParcel(apfStats, 10)
+        assertParcelSane(apfStats, 10)
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt b/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt
index 36e9f8c..8d7a9c4 100644
--- a/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -30,11 +28,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class DhcpClientEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testBuilderAndParcel() {
         val dhcpClientEvent = DhcpClientEvent.Builder()
@@ -45,6 +38,6 @@
         assertEquals(FAKE_MESSAGE, dhcpClientEvent.msg)
         assertEquals(Integer.MAX_VALUE, dhcpClientEvent.durationMs)
 
-        testParcel(dhcpClientEvent, 2)
+        assertParcelSane(dhcpClientEvent, 2)
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt b/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt
index e9d5e6d..236f72e 100644
--- a/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt
@@ -1,10 +1,10 @@
 package android.net.metrics
 
-import android.net.metrics.DhcpErrorEvent.errorCodeWithOption
 import android.net.metrics.DhcpErrorEvent.DHCP_INVALID_OPTION_LENGTH
+import android.net.metrics.DhcpErrorEvent.errorCodeWithOption
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.TestUtils.parcelingRoundTrip
+import com.android.testutils.parcelingRoundTrip
 import java.lang.reflect.Modifier
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotNull
@@ -62,4 +62,4 @@
     fun testToString_InvalidErrorCode() {
         assertNotNull(DhcpErrorEvent(TEST_ERROR_CODE).toString())
     }
-}
\ No newline at end of file
+}
diff --git a/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt b/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt
index 5144ca5..64be508 100644
--- a/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -28,11 +26,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class IpManagerEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testConstructorAndParcel() {
         (IpManagerEvent.PROVISIONING_OK..IpManagerEvent.ERROR_INTERFACE_NOT_FOUND).forEach {
@@ -40,7 +33,7 @@
             assertEquals(it, ipManagerEvent.eventType)
             assertEquals(Long.MAX_VALUE, ipManagerEvent.durationMs)
 
-            testParcel(ipManagerEvent, 2)
+            assertParcelSane(ipManagerEvent, 2)
         }
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt b/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt
index d76ebf6..55b5e49 100644
--- a/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -28,18 +26,13 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class IpReachabilityEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testConstructorAndParcel() {
         (IpReachabilityEvent.PROBE..IpReachabilityEvent.PROVISIONING_LOST_ORGANIC).forEach {
             val ipReachabilityEvent = IpReachabilityEvent(it)
             assertEquals(it, ipReachabilityEvent.eventType)
 
-            testParcel(ipReachabilityEvent, 1)
+            assertParcelSane(ipReachabilityEvent, 1)
         }
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/NetworkEventTest.kt b/tests/net/common/java/android/net/metrics/NetworkEventTest.kt
index 8b52e81..41430b0 100644
--- a/tests/net/common/java/android/net/metrics/NetworkEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/NetworkEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -28,11 +26,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class NetworkEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testConstructorAndParcel() {
         (NetworkEvent.NETWORK_CONNECTED..NetworkEvent.NETWORK_PARTIAL_CONNECTIVITY).forEach {
@@ -44,7 +37,7 @@
             assertEquals(it, networkEvent.eventType)
             assertEquals(Long.MAX_VALUE, networkEvent.durationMs)
 
-            testParcel(networkEvent, 2)
+            assertParcelSane(networkEvent, 2)
         }
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/RaEventTest.kt b/tests/net/common/java/android/net/metrics/RaEventTest.kt
index f38d328..d9b7203 100644
--- a/tests/net/common/java/android/net/metrics/RaEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/RaEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -30,11 +28,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class RaEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testConstructorAndParcel() {
         var raEvent = RaEvent.Builder().build()
@@ -74,6 +67,6 @@
         assertEquals(5, raEvent.rdnssLifetime)
         assertEquals(6, raEvent.dnsslLifetime)
 
-        testParcel(raEvent, 6)
+        assertParcelSane(raEvent, 6)
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt b/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt
index c0cef8f..51c0d41 100644
--- a/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import java.lang.reflect.Modifier
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertTrue
@@ -33,11 +31,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class ValidationProbeEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     private infix fun Int.hasType(type: Int) = (type and this) == type
 
     @Test
@@ -58,7 +51,7 @@
         assertTrue(validationProbeEvent.probeType hasType FIRST_VALIDATION)
         assertEquals(ValidationProbeEvent.DNS_SUCCESS, validationProbeEvent.returnCode)
 
-        testParcel(validationProbeEvent, 3)
+        assertParcelSane(validationProbeEvent, 3)
     }
 
     @Test
diff --git a/tests/net/java/android/app/usage/NetworkStatsManagerTest.java b/tests/net/java/android/app/usage/NetworkStatsManagerTest.java
index fd555c1..899295a 100644
--- a/tests/net/java/android/app/usage/NetworkStatsManagerTest.java
+++ b/tests/net/java/android/app/usage/NetworkStatsManagerTest.java
@@ -202,8 +202,7 @@
         assertFalse(stats.hasNextBucket());
     }
 
-    private void assertBucketMatches(Entry expected,
-            NetworkStats.Bucket actual) {
+    private void assertBucketMatches(Entry expected, NetworkStats.Bucket actual) {
         assertEquals(expected.uid, actual.getUid());
         assertEquals(expected.rxBytes, actual.getRxBytes());
         assertEquals(expected.rxPackets, actual.getRxPackets());
diff --git a/tests/net/java/android/net/IpSecConfigTest.java b/tests/net/java/android/net/IpSecConfigTest.java
index 215506c..c9888b2 100644
--- a/tests/net/java/android/net/IpSecConfigTest.java
+++ b/tests/net/java/android/net/IpSecConfigTest.java
@@ -16,12 +16,12 @@
 
 package android.net;
 
-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 com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
 
-import android.os.Parcel;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
 
 import androidx.test.filters.SmallTest;
 
@@ -89,23 +89,15 @@
         IpSecConfig original = getSampleConfig();
         IpSecConfig copy = new IpSecConfig(original);
 
-        assertTrue(IpSecConfig.equals(original, copy));
-        assertFalse(original == copy);
+        assertEquals(original, copy);
+        assertNotSame(original, copy);
     }
 
     @Test
-    public void testParcelUnparcel() throws Exception {
+    public void testParcelUnparcel() {
         assertParcelingIsLossless(new IpSecConfig());
 
         IpSecConfig c = getSampleConfig();
-        assertParcelingIsLossless(c);
-    }
-
-    private void assertParcelingIsLossless(IpSecConfig ci) throws Exception {
-        Parcel p = Parcel.obtain();
-        ci.writeToParcel(p, 0);
-        p.setDataPosition(0);
-        IpSecConfig co = IpSecConfig.CREATOR.createFromParcel(p);
-        assertTrue(IpSecConfig.equals(co, ci));
+        assertParcelSane(c, 15);
     }
 }
diff --git a/tests/net/java/android/net/IpSecTransformTest.java b/tests/net/java/android/net/IpSecTransformTest.java
index 2308a3c..424f23d 100644
--- a/tests/net/java/android/net/IpSecTransformTest.java
+++ b/tests/net/java/android/net/IpSecTransformTest.java
@@ -16,8 +16,8 @@
 
 package android.net;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 
 import androidx.test.filters.SmallTest;
 
@@ -43,7 +43,7 @@
         config.setSpiResourceId(1985);
         IpSecTransform postModification = new IpSecTransform(null, config);
 
-        assertFalse(IpSecTransform.equals(preModification, postModification));
+        assertNotEquals(preModification, postModification);
     }
 
     @Test
@@ -57,6 +57,6 @@
         IpSecTransform config1 = new IpSecTransform(null, config);
         IpSecTransform config2 = new IpSecTransform(null, config);
 
-        assertTrue(IpSecTransform.equals(config1, config2));
+        assertEquals(config1, config2);
     }
 }
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index 583d3fd..5cb0d7e 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -16,14 +16,14 @@
 
 package android.net;
 
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
 import android.net.SocketKeepalive.InvalidPacketException;
 
-import com.android.internal.util.TestUtils;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -79,7 +79,7 @@
         assertEquals(testInfo.tos, resultData.ipTos);
         assertEquals(testInfo.ttl, resultData.ipTtl);
 
-        TestUtils.assertParcelingIsLossless(resultData);
+        assertParcelingIsLossless(resultData);
 
         final byte[] packet = resultData.getPacket();
         // IP version and IHL
diff --git a/tests/net/java/android/net/shared/InitialConfigurationTest.java b/tests/net/java/android/net/shared/InitialConfigurationTest.java
index 2fb8b19..17f8324 100644
--- a/tests/net/java/android/net/shared/InitialConfigurationTest.java
+++ b/tests/net/java/android/net/shared/InitialConfigurationTest.java
@@ -18,7 +18,7 @@
 
 import static android.net.InetAddresses.parseNumericAddress;
 
-import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
diff --git a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
index f9dbdc7..f987389 100644
--- a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
+++ b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
@@ -20,7 +20,7 @@
 import static android.net.shared.IpConfigurationParcelableUtil.fromStableParcelable;
 import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
 
-import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
 
 import static org.junit.Assert.assertEquals;
 
diff --git a/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java b/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
index 382afe0..7079a28 100644
--- a/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
+++ b/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
@@ -19,7 +19,7 @@
 import static android.net.InetAddresses.parseNumericAddress;
 import static android.net.shared.ProvisioningConfiguration.fromStableParcelable;
 
-import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
diff --git a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
index 814e06e..8ea226d 100644
--- a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
+++ b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
@@ -78,7 +78,6 @@
         assertRunWithException(arrayOf("5"))
 
         // Check resource with invalid slots value.
-        assertRunWithException(arrayOf("2,2"))
         assertRunWithException(arrayOf("3,-1"))
 
         // Check resource with invalid transport type.
diff --git a/tests/net/java/com/android/internal/util/RingBufferTest.java b/tests/net/java/com/android/internal/util/RingBufferTest.java
index eff334f..d06095a 100644
--- a/tests/net/java/com/android/internal/util/RingBufferTest.java
+++ b/tests/net/java/com/android/internal/util/RingBufferTest.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.util;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
@@ -25,9 +26,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.Arrays;
-import java.util.Objects;
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class RingBufferTest {
@@ -36,7 +34,7 @@
     public void testEmptyRingBuffer() {
         RingBuffer<String> buffer = new RingBuffer<>(String.class, 100);
 
-        assertArraysEqual(new String[0], buffer.toArray());
+        assertArrayEquals(new String[0], buffer.toArray());
     }
 
     @Test
@@ -65,7 +63,7 @@
         buffer.append("e");
 
         String[] expected = {"a", "b", "c", "d", "e"};
-        assertArraysEqual(expected, buffer.toArray());
+        assertArrayEquals(expected, buffer.toArray());
     }
 
     @Test
@@ -73,19 +71,19 @@
         RingBuffer<String> buffer = new RingBuffer<>(String.class, 1);
 
         buffer.append("a");
-        assertArraysEqual(new String[]{"a"}, buffer.toArray());
+        assertArrayEquals(new String[]{"a"}, buffer.toArray());
 
         buffer.append("b");
-        assertArraysEqual(new String[]{"b"}, buffer.toArray());
+        assertArrayEquals(new String[]{"b"}, buffer.toArray());
 
         buffer.append("c");
-        assertArraysEqual(new String[]{"c"}, buffer.toArray());
+        assertArrayEquals(new String[]{"c"}, buffer.toArray());
 
         buffer.append("d");
-        assertArraysEqual(new String[]{"d"}, buffer.toArray());
+        assertArrayEquals(new String[]{"d"}, buffer.toArray());
 
         buffer.append("e");
-        assertArraysEqual(new String[]{"e"}, buffer.toArray());
+        assertArrayEquals(new String[]{"e"}, buffer.toArray());
     }
 
     @Test
@@ -100,7 +98,7 @@
         buffer.append("e");
 
         String[] expected1 = {"a", "b", "c", "d", "e"};
-        assertArraysEqual(expected1, buffer.toArray());
+        assertArrayEquals(expected1, buffer.toArray());
 
         String[] expected2 = new String[capacity];
         int firstIndex = 0;
@@ -111,22 +109,22 @@
             buffer.append("x");
             expected2[i] = "x";
         }
-        assertArraysEqual(expected2, buffer.toArray());
+        assertArrayEquals(expected2, buffer.toArray());
 
         buffer.append("x");
         expected2[firstIndex] = "x";
-        assertArraysEqual(expected2, buffer.toArray());
+        assertArrayEquals(expected2, buffer.toArray());
 
         for (int i = 0; i < 10; i++) {
             for (String s : expected2) {
                 buffer.append(s);
             }
         }
-        assertArraysEqual(expected2, buffer.toArray());
+        assertArrayEquals(expected2, buffer.toArray());
 
         buffer.append("a");
         expected2[lastIndex] = "a";
-        assertArraysEqual(expected2, buffer.toArray());
+        assertArrayEquals(expected2, buffer.toArray());
     }
 
     @Test
@@ -143,7 +141,7 @@
             expected[i] = new DummyClass1();
             expected[i].x = capacity * i;
         }
-        assertArraysEqual(expected, buffer.toArray());
+        assertArrayEquals(expected, buffer.toArray());
 
         for (int i = 0; i < capacity; ++i) {
             if (actual[i] != buffer.getNextSlot()) {
@@ -177,18 +175,4 @@
     }
 
     private static final class DummyClass3 {}
-
-    static <T> void assertArraysEqual(T[] expected, T[] got) {
-        if (expected.length != got.length) {
-            fail(Arrays.toString(expected) + " and " + Arrays.toString(got)
-                    + " did not have the same length");
-        }
-
-        for (int i = 0; i < expected.length; i++) {
-            if (!Objects.equals(expected[i], got[i])) {
-                fail(Arrays.toString(expected) + " and " + Arrays.toString(got)
-                        + " were not equal");
-            }
-        }
-    }
 }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index f14eced..7317d62 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -68,7 +68,15 @@
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
 import static android.net.RouteInfo.RTN_UNREACHABLE;
 
-import static org.junit.Assert.assertArrayEquals;
+import static com.android.testutils.ConcurrentUtilsKt.await;
+import static com.android.testutils.ConcurrentUtilsKt.durationOf;
+import static com.android.testutils.HandlerUtilsKt.waitForIdleSerialExecutor;
+import static com.android.testutils.MiscAssertsKt.assertContainsExactly;
+import static com.android.testutils.MiscAssertsKt.assertEmpty;
+import static com.android.testutils.MiscAssertsKt.assertLength;
+import static com.android.testutils.MiscAssertsKt.assertRunsInAtMost;
+import static com.android.testutils.MiscAssertsKt.assertThrows;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -194,6 +202,7 @@
 import com.android.server.net.NetworkPolicyManagerInternal;
 import com.android.server.net.NetworkStatsFactory;
 import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.ThrowingConsumer;
 
 import org.junit.After;
 import org.junit.Before;
@@ -2567,10 +2576,10 @@
                 .build();
 
         Class<IllegalArgumentException> expected = IllegalArgumentException.class;
-        assertException(() -> { mCm.requestNetwork(request1, new NetworkCallback()); }, expected);
-        assertException(() -> { mCm.requestNetwork(request1, pendingIntent); }, expected);
-        assertException(() -> { mCm.requestNetwork(request2, new NetworkCallback()); }, expected);
-        assertException(() -> { mCm.requestNetwork(request2, pendingIntent); }, expected);
+        assertThrows(expected, () -> mCm.requestNetwork(request1, new NetworkCallback()));
+        assertThrows(expected, () -> mCm.requestNetwork(request1, pendingIntent));
+        assertThrows(expected, () -> mCm.requestNetwork(request2, new NetworkCallback()));
+        assertThrows(expected, () -> mCm.requestNetwork(request2, pendingIntent));
     }
 
     @Test
@@ -3482,7 +3491,7 @@
             };
         }
 
-        assertTimeLimit("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> {
+        assertRunsInAtMost("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> {
             for (NetworkCallback cb : callbacks) {
                 mCm.registerNetworkCallback(request, cb);
             }
@@ -3495,7 +3504,7 @@
         mCellNetworkAgent.connect(false);
 
         long onAvailableDispatchingDuration = durationOf(() -> {
-            awaitLatch(availableLatch, 10 * CONNECT_TIME_LIMIT_MS);
+            await(availableLatch, 10 * CONNECT_TIME_LIMIT_MS);
         });
         Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms",
                 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS,
@@ -3510,7 +3519,7 @@
         mWiFiNetworkAgent.connect(false);
 
         long onLostDispatchingDuration = durationOf(() -> {
-            awaitLatch(losingLatch, 10 * SWITCH_TIME_LIMIT_MS);
+            await(losingLatch, 10 * SWITCH_TIME_LIMIT_MS);
         });
         Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms",
                 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration));
@@ -3518,33 +3527,13 @@
                 NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS),
                 onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS);
 
-        assertTimeLimit("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> {
+        assertRunsInAtMost("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> {
             for (NetworkCallback cb : callbacks) {
                 mCm.unregisterNetworkCallback(cb);
             }
         });
     }
 
-    private long durationOf(Runnable fn) {
-        long startTime = SystemClock.elapsedRealtime();
-        fn.run();
-        return SystemClock.elapsedRealtime() - startTime;
-    }
-
-    private void assertTimeLimit(String descr, long timeLimit, Runnable fn) {
-        long timeTaken = durationOf(fn);
-        String msg = String.format("%s: took %dms, limit was %dms", descr, timeTaken, timeLimit);
-        Log.d(TAG, msg);
-        assertTrue(msg, timeTaken <= timeLimit);
-    }
-
-    private boolean awaitLatch(CountDownLatch l, long timeoutMs) {
-        try {
-            return l.await(timeoutMs, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {}
-        return false;
-    }
-
     @Test
     public void testMobileDataAlwaysOn() throws Exception {
         final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
@@ -4105,7 +4094,7 @@
         }
 
         public void assertNoCallback() {
-            HandlerUtilsKt.waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS);
+            waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS);
             CallbackValue cv = mCallbacks.peek();
             assertNull("Unexpected callback: " + cv, cv);
         }
@@ -4244,11 +4233,6 @@
         callback3.expectStopped();
     }
 
-    @FunctionalInterface
-    private interface ThrowingConsumer<T> {
-        void accept(T t) throws Exception;
-    }
-
     // Helper method to prepare the executor and run test
     private void runTestWithSerialExecutors(ThrowingConsumer<Executor> functor) throws Exception {
         final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor();
@@ -4823,17 +4807,17 @@
         assertNull(mCm.getLinkProperties(TYPE_NONE));
         assertFalse(mCm.isNetworkSupported(TYPE_NONE));
 
-        assertException(() -> { mCm.networkCapabilitiesForType(TYPE_NONE); },
-                IllegalArgumentException.class);
+        assertThrows(IllegalArgumentException.class,
+                () -> { mCm.networkCapabilitiesForType(TYPE_NONE); });
 
         Class<UnsupportedOperationException> unsupported = UnsupportedOperationException.class;
-        assertException(() -> { mCm.startUsingNetworkFeature(TYPE_WIFI, ""); }, unsupported);
-        assertException(() -> { mCm.stopUsingNetworkFeature(TYPE_WIFI, ""); }, unsupported);
+        assertThrows(unsupported, () -> { mCm.startUsingNetworkFeature(TYPE_WIFI, ""); });
+        assertThrows(unsupported, () -> { mCm.stopUsingNetworkFeature(TYPE_WIFI, ""); });
         // TODO: let test context have configuration application target sdk version
         // and test that pre-M requesting for TYPE_NONE sends back APN_REQUEST_FAILED
-        assertException(() -> { mCm.startUsingNetworkFeature(TYPE_NONE, ""); }, unsupported);
-        assertException(() -> { mCm.stopUsingNetworkFeature(TYPE_NONE, ""); }, unsupported);
-        assertException(() -> { mCm.requestRouteToHostAddress(TYPE_NONE, null); }, unsupported);
+        assertThrows(unsupported, () -> { mCm.startUsingNetworkFeature(TYPE_NONE, ""); });
+        assertThrows(unsupported, () -> { mCm.stopUsingNetworkFeature(TYPE_NONE, ""); });
+        assertThrows(unsupported, () -> { mCm.requestRouteToHostAddress(TYPE_NONE, null); });
     }
 
     @Test
@@ -5095,11 +5079,11 @@
         ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue();
         assertEquals(2, resolvrParams.tlsServers.length);
         assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
-                new String[]{"2001:db8::1", "192.0.2.1"}));
+                new String[] { "2001:db8::1", "192.0.2.1" }));
         // Opportunistic mode.
         assertEquals(2, resolvrParams.tlsServers.length);
         assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
-                new String[]{"2001:db8::1", "192.0.2.1"}));
+                new String[] { "2001:db8::1", "192.0.2.1" }));
         reset(mMockDnsResolver);
         cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
         cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES,
@@ -5117,7 +5101,7 @@
         resolvrParams = mResolverParamsParcelCaptor.getValue();
         assertEquals(2, resolvrParams.servers.length);
         assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
-                new String[]{"2001:db8::1", "192.0.2.1"}));
+                new String[] { "2001:db8::1", "192.0.2.1" }));
         reset(mMockDnsResolver);
         cellNetworkCallback.assertNoCallback();
 
@@ -5127,10 +5111,10 @@
         resolvrParams = mResolverParamsParcelCaptor.getValue();
         assertEquals(2, resolvrParams.servers.length);
         assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
-                new String[]{"2001:db8::1", "192.0.2.1"}));
+                new String[] { "2001:db8::1", "192.0.2.1" }));
         assertEquals(2, resolvrParams.tlsServers.length);
         assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
-                new String[]{"2001:db8::1", "192.0.2.1"}));
+                new String[] { "2001:db8::1", "192.0.2.1" }));
         reset(mMockDnsResolver);
         cellNetworkCallback.assertNoCallback();
 
@@ -5265,29 +5249,6 @@
         assertTrue(lp.getDnsServers().containsAll(dnsServers));
     }
 
-    private static <T> void assertEmpty(T[] ts) {
-        int length = ts.length;
-        assertEquals("expected empty array, but length was " + length, 0, length);
-    }
-
-    private static <T> void assertLength(int expected, T[] got) {
-        int length = got.length;
-        assertEquals(String.format("expected array of length %s, but length was %s for %s",
-                expected, length, Arrays.toString(got)), expected, length);
-    }
-
-    private static <T> void assertException(Runnable block, Class<T> expected) {
-        try {
-            block.run();
-            fail("Expected exception of type " + expected);
-        } catch (Exception got) {
-            if (!got.getClass().equals(expected)) {
-                fail("Expected exception of type " + expected + " but got " + got);
-            }
-            return;
-        }
-    }
-
     @Test
     public void testVpnNetworkActive() {
         final int uid = Process.myUid();
@@ -6484,14 +6445,6 @@
         return vpnNetworkAgent;
     }
 
-    private void assertContainsExactly(int[] actual, int... expected) {
-        int[] sortedActual = Arrays.copyOf(actual, actual.length);
-        int[] sortedExpected = Arrays.copyOf(expected, expected.length);
-        Arrays.sort(sortedActual);
-        Arrays.sort(sortedExpected);
-        assertArrayEquals(sortedExpected, sortedActual);
-    }
-
     private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) {
         final PackageInfo packageInfo = new PackageInfo();
         packageInfo.requestedPermissions = new String[0];
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index e4117b8..aef9386 100644
--- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -19,8 +19,9 @@
 import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
 import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
 
+import static com.android.testutils.MiscAssertsKt.assertStringContains;
+
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -111,15 +112,15 @@
         String[] events2 = remove(listNetdEvent(), baseline);
         int expectedLength2 = uids.length + 1; // +1 for the WakeupStats line
         assertEquals(expectedLength2, events2.length);
-        assertContains(events2[0], "WakeupStats");
-        assertContains(events2[0], "wlan0");
-        assertContains(events2[0], "0x800");
-        assertContains(events2[0], "0x86dd");
+        assertStringContains(events2[0], "WakeupStats");
+        assertStringContains(events2[0], "wlan0");
+        assertStringContains(events2[0], "0x800");
+        assertStringContains(events2[0], "0x86dd");
         for (int i = 0; i < uids.length; i++) {
             String got = events2[i+1];
-            assertContains(got, "WakeupEvent");
-            assertContains(got, "wlan0");
-            assertContains(got, "uid: " + uids[i]);
+            assertStringContains(got, "WakeupEvent");
+            assertStringContains(got, "wlan0");
+            assertStringContains(got, "uid: " + uids[i]);
         }
 
         int uid = 20000;
@@ -131,13 +132,13 @@
         String[] events3 = remove(listNetdEvent(), baseline);
         int expectedLength3 = BUFFER_LENGTH + 1; // +1 for the WakeupStats line
         assertEquals(expectedLength3, events3.length);
-        assertContains(events2[0], "WakeupStats");
-        assertContains(events2[0], "wlan0");
+        assertStringContains(events2[0], "WakeupStats");
+        assertStringContains(events2[0], "wlan0");
         for (int i = 1; i < expectedLength3; i++) {
             String got = events3[i];
-            assertContains(got, "WakeupEvent");
-            assertContains(got, "wlan0");
-            assertContains(got, "uid: " + uid);
+            assertStringContains(got, "WakeupEvent");
+            assertStringContains(got, "wlan0");
+            assertStringContains(got, "uid: " + uid);
         }
 
         uid = 45678;
@@ -145,9 +146,9 @@
 
         String[] events4 = remove(listNetdEvent(), baseline);
         String lastEvent = events4[events4.length - 1];
-        assertContains(lastEvent, "WakeupEvent");
-        assertContains(lastEvent, "wlan0");
-        assertContains(lastEvent, "uid: " + uid);
+        assertStringContains(lastEvent, "WakeupEvent");
+        assertStringContains(lastEvent, "wlan0");
+        assertStringContains(lastEvent, "uid: " + uid);
     }
 
     @Test
@@ -529,10 +530,6 @@
         return buffer.toString().split("\\n");
     }
 
-    static void assertContains(String got, String want) {
-        assertTrue(got + " did not contain \"" + want + "\"", got.contains(want));
-    }
-
     static <T> T[] remove(T[] array, T[] filtered) {
         List<T> c = Arrays.asList(filtered);
         int next = 0;
diff --git a/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java b/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
index 762b76c..9931aec 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
@@ -25,6 +25,7 @@
 import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
 
 import static com.android.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats;
+import static com.android.testutils.MiscAssertsKt.assertContainsAll;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -244,7 +245,7 @@
         inOrder.verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
         ArrayList<String> localPrefixes = mStringArrayCaptor.getValue();
         assertEquals(4, localPrefixes.size());
-        assertArrayListContains(localPrefixes,
+        assertContainsAll(localPrefixes,
                 "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64");
         inOrder.verifyNoMoreInteractions();
 
@@ -360,7 +361,7 @@
         inOrder.verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
         localPrefixes = mStringArrayCaptor.getValue();
         assertEquals(6, localPrefixes.size());
-        assertArrayListContains(localPrefixes,
+        assertContainsAll(localPrefixes,
                 "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64",
                 "2001:db8::6173:7369:676e:6564/128", "2001:db8::7261:6e64:6f6d/128");
         // The relevant parts of the LinkProperties have not changed, but at the
@@ -717,7 +718,7 @@
         verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
         ArrayList<String> localPrefixes = mStringArrayCaptor.getValue();
         assertEquals(4, localPrefixes.size());
-        assertArrayListContains(localPrefixes,
+        assertContainsAll(localPrefixes,
                 // TODO: The logic to find and exclude downstream IP prefixes
                 // is currently in Tethering's OffloadWrapper but must be moved
                 // into OffloadController proper. After this, also check for:
@@ -730,9 +731,4 @@
         verifyNoMoreInteractions(mHardware);
     }
 
-    private static void assertArrayListContains(ArrayList<String> list, String... elems) {
-        for (String element : elems) {
-            assertTrue(element + " not in list", list.contains(element));
-        }
-    }
 }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index 9b4f49c..8f90f13 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -29,6 +29,7 @@
 
 import static com.android.server.net.NetworkStatsCollection.multiplySafe;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
@@ -43,7 +44,6 @@
 import android.os.UserHandle;
 import android.telephony.SubscriptionPlan;
 import android.telephony.TelephonyManager;
-import android.test.MoreAsserts;
 import android.text.format.DateUtils;
 import android.util.RecurrenceRule;
 
@@ -240,11 +240,11 @@
                 60 * MINUTE_IN_MILLIS, entry);
 
         // Verify the set of relevant UIDs for each access level.
-        MoreAsserts.assertEquals(new int[] { myUid },
+        assertArrayEquals(new int[] { myUid },
                 collection.getRelevantUids(NetworkStatsAccess.Level.DEFAULT));
-        MoreAsserts.assertEquals(new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser },
+        assertArrayEquals(new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser },
                 collection.getRelevantUids(NetworkStatsAccess.Level.USER));
-        MoreAsserts.assertEquals(
+        assertArrayEquals(
                 new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser, uidInDifferentUser },
                 collection.getRelevantUids(NetworkStatsAccess.Level.DEVICE));
 
diff --git a/tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java b/tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java
deleted file mode 100644
index 87537b9..0000000
--- a/tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java
+++ /dev/null
@@ -1,41 +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 com.android.internal.util;
-
-import static org.junit.Assert.assertEquals;
-
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-
-/**
- * Utility classes to write tests for stable AIDL parceling/unparceling
- */
-public final class ParcelableTestUtil {
-
-    /**
-     * Verifies that the number of nonstatic fields in a class equals a given count.
-     *
-     * <p>This assertion serves as a reminder to update test code around it if fields are added
-     * after the test is written.
-     * @param count Expected number of nonstatic fields in the class.
-     * @param clazz Class to test.
-     */
-    public static <T> void assertFieldCountEquals(int count, Class<T> clazz) {
-        assertEquals(count, Arrays.stream(clazz.getDeclaredFields())
-                .filter(f -> !Modifier.isStatic(f.getModifiers())).count());
-    }
-}
diff --git a/tests/net/util/java/com/android/internal/util/TestUtils.java b/tests/net/util/java/com/android/internal/util/TestUtils.java
deleted file mode 100644
index daa00d2..0000000
--- a/tests/net/util/java/com/android/internal/util/TestUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2017 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.internal.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public final class TestUtils {
-    private TestUtils() { }
-
-    /**
-     * Return a new instance of {@code T} after being parceled then unparceled.
-     */
-    public static <T extends Parcelable> T parcelingRoundTrip(T source) {
-        final Parcelable.Creator<T> creator;
-        try {
-            creator = (Parcelable.Creator<T>) source.getClass().getField("CREATOR").get(null);
-        } catch (IllegalAccessException | NoSuchFieldException e) {
-            fail("Missing CREATOR field: " + e.getMessage());
-            return null;
-        }
-        Parcel p = Parcel.obtain();
-        source.writeToParcel(p, /* flags */ 0);
-        p.setDataPosition(0);
-        final byte[] marshalled = p.marshall();
-        p = Parcel.obtain();
-        p.unmarshall(marshalled, 0, marshalled.length);
-        p.setDataPosition(0);
-        return creator.createFromParcel(p);
-    }
-
-    /**
-     * Assert that after being parceled then unparceled, {@code source} is equal to the original
-     * object.
-     */
-    public static <T extends Parcelable> void assertParcelingIsLossless(T source) {
-        assertEquals(source, parcelingRoundTrip(source));
-    }
-}