Merge "Add Intdef annotation for eventId in logEvent" am: 91b05f7f58 am: fc7a1308cd am: 82ec7bcf4e

Change-Id: I7caa207fb35e8088e50de0651a72a6d9628e7ce2
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 94eda01..a305948 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1782,7 +1782,6 @@
         @UnsupportedAppUsage
         public PacketKeepaliveCallback() {
         }
-
         /** The requested keepalive was successfully started. */
         @UnsupportedAppUsage
         public void onStarted() {}
@@ -2424,14 +2423,14 @@
     /**
      * Get the set of tethered dhcp ranges.
      *
-     * @return an array of 0 or more {@code String} of tethered dhcp ranges.
-     * @deprecated This API just return the default value which is not used in DhcpServer.
+     * @deprecated This method is not supported.
+     * TODO: remove this function when all of clients are removed.
      * {@hide}
      */
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     @Deprecated
     public String[] getTetheredDhcpRanges() {
-        return getTetheringManager().getTetheredDhcpRanges();
+        throw new UnsupportedOperationException("getTetheredDhcpRanges is not supported");
     }
 
     /**
@@ -3229,6 +3228,7 @@
      * @hide
      */
     @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_AIRPLANE_MODE,
             android.Manifest.permission.NETWORK_SETTINGS,
             android.Manifest.permission.NETWORK_SETUP_WIZARD,
             android.Manifest.permission.NETWORK_STACK})
@@ -3322,15 +3322,19 @@
     // of dependent changes that would conflict throughout the automerger graph. Having this
     // temporarily helps with the process of going through with all these dependent changes across
     // the entire tree.
+    // STOPSHIP (b/148055573) : remove this before R is released.
     /**
      * @hide
      * Register a NetworkAgent with ConnectivityService.
      * @return Network corresponding to NetworkAgent.
+     * @deprecated use the version that takes a NetworkScore and a provider ID.
      */
     @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+    @Deprecated
     public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
             NetworkCapabilities nc, int score, NetworkAgentConfig config) {
-        return registerNetworkAgent(messenger, ni, lp, nc, score, config, NetworkProvider.ID_NONE);
+        final NetworkScore ns = new NetworkScore.Builder().setLegacyScore(score).build();
+        return registerNetworkAgent(messenger, ni, lp, nc, ns, config, NetworkProvider.ID_NONE);
     }
 
     /**
@@ -3340,8 +3344,7 @@
      */
     @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
     public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
-            NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) {
-
+            NetworkCapabilities nc, NetworkScore score, NetworkAgentConfig config, int providerId) {
         try {
             return mService.registerNetworkAgent(messenger, ni, lp, nc, score, config, providerId);
         } catch (RemoteException e) {
@@ -3747,6 +3750,7 @@
         checkCallbackNotNull(callback);
         Preconditions.checkArgument(action == REQUEST || need != null, "null NetworkCapabilities");
         final NetworkRequest request;
+        final String callingPackageName = mContext.getOpPackageName();
         try {
             synchronized(sCallbacks) {
                 if (callback.networkRequest != null
@@ -3758,10 +3762,11 @@
                 Messenger messenger = new Messenger(handler);
                 Binder binder = new Binder();
                 if (action == LISTEN) {
-                    request = mService.listenForNetwork(need, messenger, binder);
+                    request = mService.listenForNetwork(
+                            need, messenger, binder, callingPackageName);
                 } else {
                     request = mService.requestNetwork(
-                            need, messenger, timeoutMs, binder, legacyType);
+                            need, messenger, timeoutMs, binder, legacyType, callingPackageName);
                 }
                 if (request != null) {
                     sCallbacks.put(request, callback);
@@ -4034,8 +4039,10 @@
             @NonNull PendingIntent operation) {
         printStackTrace();
         checkPendingIntentNotNull(operation);
+        final String callingPackageName = mContext.getOpPackageName();
         try {
-            mService.pendingRequestForNetwork(request.networkCapabilities, operation);
+            mService.pendingRequestForNetwork(
+                    request.networkCapabilities, operation, callingPackageName);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
@@ -4147,8 +4154,10 @@
             @NonNull PendingIntent operation) {
         printStackTrace();
         checkPendingIntentNotNull(operation);
+        final String callingPackageName = mContext.getOpPackageName();
         try {
-            mService.pendingListenForNetwork(request.networkCapabilities, operation);
+            mService.pendingListenForNetwork(
+                    request.networkCapabilities, operation, callingPackageName);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index c871c45..1c7628f 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -26,6 +26,7 @@
 import android.net.NetworkInfo;
 import android.net.NetworkQuotaInfo;
 import android.net.NetworkRequest;
+import android.net.NetworkScore;
 import android.net.NetworkState;
 import android.net.ISocketKeepaliveCallback;
 import android.net.ProxyInfo;
@@ -162,22 +163,23 @@
     void declareNetworkRequestUnfulfillable(in NetworkRequest request);
 
     Network registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp,
-            in NetworkCapabilities nc, int score, in NetworkAgentConfig config,
+            in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config,
             in int factorySerialNumber);
 
     NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
-            in Messenger messenger, int timeoutSec, in IBinder binder, int legacy);
+            in Messenger messenger, int timeoutSec, in IBinder binder, int legacy,
+            String callingPackageName);
 
     NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
-            in PendingIntent operation);
+            in PendingIntent operation, String callingPackageName);
 
     void releasePendingNetworkRequest(in PendingIntent operation);
 
     NetworkRequest listenForNetwork(in NetworkCapabilities networkCapabilities,
-            in Messenger messenger, in IBinder binder);
+            in Messenger messenger, in IBinder binder, String callingPackageName);
 
     void pendingListenForNetwork(in NetworkCapabilities networkCapabilities,
-            in PendingIntent operation);
+            in PendingIntent operation, String callingPackageName);
 
     void releaseNetworkRequest(in NetworkRequest networkRequest);
 
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index d25ee0e..732ceb5 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -21,6 +21,8 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.net.util.LinkPropertiesUtils;
+import android.net.util.LinkPropertiesUtils.CompareResult;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -93,36 +95,6 @@
     /**
      * @hide
      */
-    public static class CompareResult<T> {
-        public final List<T> removed = new ArrayList<>();
-        public final List<T> added = new ArrayList<>();
-
-        public CompareResult() {}
-
-        public CompareResult(Collection<T> oldItems, Collection<T> newItems) {
-            if (oldItems != null) {
-                removed.addAll(oldItems);
-            }
-            if (newItems != null) {
-                for (T newItem : newItems) {
-                    if (!removed.remove(newItem)) {
-                        added.add(newItem);
-                    }
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "removed=[" + TextUtils.join(",", removed)
-                    + "] added=[" + TextUtils.join(",", added)
-                    + "]";
-        }
-    }
-
-    /**
-     * @hide
-     */
     @UnsupportedAppUsage(implicitMember =
             "values()[Landroid/net/LinkProperties$ProvisioningChange;")
     public enum ProvisioningChange {
@@ -1326,7 +1298,7 @@
      */
     @UnsupportedAppUsage
     public boolean isIdenticalInterfaceName(@NonNull LinkProperties target) {
-        return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
+        return LinkPropertiesUtils.isIdenticalInterfaceName(target, this);
     }
 
     /**
@@ -1349,10 +1321,7 @@
      */
     @UnsupportedAppUsage
     public boolean isIdenticalAddresses(@NonNull LinkProperties target) {
-        Collection<InetAddress> targetAddresses = target.getAddresses();
-        Collection<InetAddress> sourceAddresses = getAddresses();
-        return (sourceAddresses.size() == targetAddresses.size()) ?
-                    sourceAddresses.containsAll(targetAddresses) : false;
+        return LinkPropertiesUtils.isIdenticalAddresses(target, this);
     }
 
     /**
@@ -1364,15 +1333,7 @@
      */
     @UnsupportedAppUsage
     public boolean isIdenticalDnses(@NonNull LinkProperties target) {
-        Collection<InetAddress> targetDnses = target.getDnsServers();
-        String targetDomains = target.getDomains();
-        if (mDomains == null) {
-            if (targetDomains != null) return false;
-        } else {
-            if (!mDomains.equals(targetDomains)) return false;
-        }
-        return (mDnses.size() == targetDnses.size()) ?
-                mDnses.containsAll(targetDnses) : false;
+        return LinkPropertiesUtils.isIdenticalDnses(target, this);
     }
 
     /**
@@ -1425,9 +1386,7 @@
      */
     @UnsupportedAppUsage
     public boolean isIdenticalRoutes(@NonNull LinkProperties target) {
-        Collection<RouteInfo> targetRoutes = target.getRoutes();
-        return (mRoutes.size() == targetRoutes.size()) ?
-                mRoutes.containsAll(targetRoutes) : false;
+        return LinkPropertiesUtils.isIdenticalRoutes(target, this);
     }
 
     /**
@@ -1439,8 +1398,7 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public boolean isIdenticalHttpProxy(@NonNull LinkProperties target) {
-        return getHttpProxy() == null ? target.getHttpProxy() == null :
-                getHttpProxy().equals(target.getHttpProxy());
+        return LinkPropertiesUtils.isIdenticalHttpProxy(target, this);
     }
 
     /**
@@ -1663,26 +1621,6 @@
     }
 
     /**
-     * Compares the addresses in this LinkProperties with another
-     * LinkProperties, examining only addresses on the base link.
-     *
-     * @param target a LinkProperties with the new list of addresses
-     * @return the differences between the addresses.
-     * @hide
-     */
-    public @NonNull CompareResult<LinkAddress> compareAddresses(@Nullable LinkProperties target) {
-        /*
-         * Duplicate the LinkAddresses into removed, we will be removing
-         * address which are common between mLinkAddresses and target
-         * leaving the addresses that are different. And address which
-         * are in target but not in mLinkAddresses are placed in the
-         * addedAddresses.
-         */
-        return new CompareResult<>(mLinkAddresses,
-                target != null ? target.getLinkAddresses() : null);
-    }
-
-    /**
      * Compares the DNS addresses in this LinkProperties with another
      * LinkProperties, examining only DNS addresses on the base link.
      *
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index 74c9aac..0e10c42 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -20,11 +20,11 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.net.util.MacAddressUtils;
 import android.net.wifi.WifiInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import com.android.internal.util.BitUtils;
 import com.android.internal.util.Preconditions;
 
 import java.lang.annotation.Retention;
@@ -33,7 +33,6 @@
 import java.net.UnknownHostException;
 import java.security.SecureRandom;
 import java.util.Arrays;
-import java.util.Random;
 
 /**
  * Representation of a MAC address.
@@ -109,21 +108,13 @@
         if (equals(BROADCAST_ADDRESS)) {
             return TYPE_BROADCAST;
         }
-        if (isMulticastAddress()) {
+        if ((mAddr & MULTICAST_MASK) != 0) {
             return TYPE_MULTICAST;
         }
         return TYPE_UNICAST;
     }
 
     /**
-     * @return true if this MacAddress is a multicast address.
-     * @hide
-     */
-    public boolean isMulticastAddress() {
-        return (mAddr & MULTICAST_MASK) != 0;
-    }
-
-    /**
      * @return true if this MacAddress is a locally assigned address.
      */
     public boolean isLocallyAssigned() {
@@ -192,7 +183,7 @@
      * @hide
      */
     public static boolean isMacAddress(byte[] addr) {
-        return addr != null && addr.length == ETHER_ADDR_LEN;
+        return MacAddressUtils.isMacAddress(addr);
     }
 
     /**
@@ -261,26 +252,11 @@
     }
 
     private static byte[] byteAddrFromLongAddr(long addr) {
-        byte[] bytes = new byte[ETHER_ADDR_LEN];
-        int index = ETHER_ADDR_LEN;
-        while (index-- > 0) {
-            bytes[index] = (byte) addr;
-            addr = addr >> 8;
-        }
-        return bytes;
+        return MacAddressUtils.byteAddrFromLongAddr(addr);
     }
 
     private static long longAddrFromByteAddr(byte[] addr) {
-        Preconditions.checkNotNull(addr);
-        if (!isMacAddress(addr)) {
-            throw new IllegalArgumentException(
-                    Arrays.toString(addr) + " was not a valid MAC address");
-        }
-        long longAddr = 0;
-        for (byte b : addr) {
-            longAddr = (longAddr << 8) + BitUtils.uint8(b);
-        }
-        return longAddr;
+        return MacAddressUtils.longAddrFromByteAddr(addr);
     }
 
     // Internal conversion function equivalent to longAddrFromByteAddr(byteAddrFromStringAddr(addr))
@@ -350,50 +326,7 @@
      * @hide
      */
     public static @NonNull MacAddress createRandomUnicastAddressWithGoogleBase() {
-        return createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom());
-    }
-
-    /**
-     * Returns a generated MAC address whose 46 bits, excluding the locally assigned bit and the
-     * unicast bit, are randomly selected.
-     *
-     * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
-     *
-     * @return a random locally assigned, unicast MacAddress.
-     *
-     * @hide
-     */
-    public static @NonNull MacAddress createRandomUnicastAddress() {
-        return createRandomUnicastAddress(null, new SecureRandom());
-    }
-
-    /**
-     * Returns a randomly generated MAC address using the given Random object and the same
-     * OUI values as the given MacAddress.
-     *
-     * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
-     *
-     * @param base a base MacAddress whose OUI is used for generating the random address.
-     *             If base == null then the OUI will also be randomized.
-     * @param r a standard Java Random object used for generating the random address.
-     * @return a random locally assigned MacAddress.
-     *
-     * @hide
-     */
-    public static @NonNull MacAddress createRandomUnicastAddress(MacAddress base, Random r) {
-        long addr;
-        if (base == null) {
-            addr = r.nextLong() & VALID_LONG_MASK;
-        } else {
-            addr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong());
-        }
-        addr |= LOCALLY_ASSIGNED_MASK;
-        addr &= ~MULTICAST_MASK;
-        MacAddress mac = new MacAddress(addr);
-        if (mac.equals(DEFAULT_MAC_ADDRESS)) {
-            return createRandomUnicastAddress(base, r);
-        }
-        return mac;
+        return MacAddressUtils.createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom());
     }
 
     // Convenience function for working around the lack of byte literals.
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 8d1ab33..c5681cb 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -502,7 +502,7 @@
     }
 
     /** @hide */
-    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         proto.write(NetworkProto.NET_ID, netId);
         proto.end(token);
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 61a1484..ddf8dbb 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -33,6 +33,7 @@
 import com.android.internal.util.Protocol;
 
 import java.util.ArrayList;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -50,20 +51,29 @@
     /**
      * The {@link Network} corresponding to this object.
      */
-    @NonNull
-    public final Network network;
+    @Nullable
+    private volatile Network mNetwork;
+
+    // Whether this NetworkAgent is using the legacy (never unhidden) API. The difference is
+    // that the legacy API uses NetworkInfo to convey the state, while the current API is
+    // exposing methods to manage it and generate it internally instead.
+    // TODO : remove this as soon as all agents have been converted.
+    private final boolean mIsLegacy;
 
     private final Handler mHandler;
     private volatile AsyncChannel mAsyncChannel;
     private final String LOG_TAG;
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
-    private final Context mContext;
     private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>();
     private volatile long mLastBwRefreshTime = 0;
     private static final long BW_REFRESH_MIN_WIN_MS = 500;
     private boolean mBandwidthUpdateScheduled = false;
     private AtomicBoolean mBandwidthUpdatePending = new AtomicBoolean(false);
+    // Not used by legacy agents. Non-legacy agents use this to convert the NetworkAgent system API
+    // into the internal API of ConnectivityService.
+    @NonNull
+    private NetworkInfo mNetworkInfo;
 
     /**
      * The ID of the {@link NetworkProvider} that created this object, or
@@ -107,13 +117,6 @@
     public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3;
 
     /**
-     * Centralize the place where base network score, and network score scaling, will be
-     * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE
-     * @hide
-     */
-    public static final int WIFI_BASE_SCORE = 60;
-
-    /**
      * Sent by the NetworkAgent to ConnectivityService to pass the current
      * network score.
      * obj = network score Integer
@@ -262,35 +265,52 @@
      */
     public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17;
 
+    // STOPSHIP (b/148055573) : remove this before R is released.
+    private static NetworkScore makeNetworkScore(int score) {
+        return new NetworkScore.Builder().setLegacyScore(score).build();
+    }
+
     /** @hide TODO: remove and replace usage with the public constructor. */
+    // STOPSHIP (b/148055573) : remove this before R is released.
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score) {
         this(looper, context, logTag, ni, nc, lp, score, null, NetworkProvider.ID_NONE);
+        // Register done by the constructor called in the previous line
     }
 
     /** @hide TODO: remove and replace usage with the public constructor. */
+    // STOPSHIP (b/148055573) : remove this before R is released.
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config) {
         this(looper, context, logTag, ni, nc, lp, score, config, NetworkProvider.ID_NONE);
+        // Register done by the constructor called in the previous line
     }
 
     /** @hide TODO: remove and replace usage with the public constructor. */
+    // STOPSHIP (b/148055573) : remove this before R is released.
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, int providerId) {
         this(looper, context, logTag, ni, nc, lp, score, null, providerId);
+        // Register done by the constructor called in the previous line
     }
 
     /** @hide TODO: remove and replace usage with the public constructor. */
+    // STOPSHIP (b/148055573) : remove this before R is released.
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config,
             int providerId) {
-        this(looper, context, logTag, nc, lp, score, config, providerId, ni);
+        this(looper, context, logTag, nc, lp, makeNetworkScore(score), config, providerId, ni,
+                true /* legacy */);
+        register();
     }
 
     private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
         // The subtype can be changed with (TODO) setLegacySubtype, but it starts
         // with the type and an empty description.
-        return new NetworkInfo(config.legacyType, config.legacyType, config.legacyTypeName, "");
+        final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacyType,
+                config.legacyTypeName, "");
+        ni.setIsAvailable(true);
+        return ni;
     }
 
     /**
@@ -306,30 +326,49 @@
      * @param provider the {@link NetworkProvider} managing this agent.
      */
     public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
-            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
-            @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) {
+            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp,
+            @NonNull NetworkScore score, @NonNull NetworkAgentConfig config,
+            @Nullable NetworkProvider provider) {
         this(looper, context, logTag, nc, lp, score, config,
                 provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(),
-                getLegacyNetworkInfo(config));
+                getLegacyNetworkInfo(config), false /* legacy */);
     }
 
-    private NetworkAgent(Looper looper, Context context, String logTag, NetworkCapabilities nc,
-            LinkProperties lp, int score, NetworkAgentConfig config, int providerId,
-            NetworkInfo ni) {
+    private static class InitialConfiguration {
+        public final Context context;
+        public final NetworkCapabilities capabilities;
+        public final LinkProperties properties;
+        public final NetworkScore score;
+        public final NetworkAgentConfig config;
+        public final NetworkInfo info;
+        InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities,
+                @NonNull LinkProperties properties, @NonNull NetworkScore score,
+                @NonNull NetworkAgentConfig config, @NonNull NetworkInfo info) {
+            this.context = context;
+            this.capabilities = capabilities;
+            this.properties = properties;
+            this.score = score;
+            this.config = config;
+            this.info = info;
+        }
+    }
+    private volatile InitialConfiguration mInitialConfiguration;
+
+    private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag,
+            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, NetworkScore score,
+            @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni,
+            boolean legacy) {
         mHandler = new NetworkAgentHandler(looper);
         LOG_TAG = logTag;
-        mContext = context;
+        mIsLegacy = legacy;
+        mNetworkInfo = new NetworkInfo(ni);
         this.providerId = providerId;
         if (ni == null || nc == null || lp == null) {
             throw new IllegalArgumentException();
         }
 
-        if (VDBG) log("Registering NetworkAgent");
-        ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
-                Context.CONNECTIVITY_SERVICE);
-        network = cm.registerNetworkAgent(new Messenger(mHandler), new NetworkInfo(ni),
-                new LinkProperties(lp), new NetworkCapabilities(nc), score, config,
-                providerId);
+        mInitialConfiguration = new InitialConfiguration(context, new NetworkCapabilities(nc),
+                new LinkProperties(lp), score, config, ni);
     }
 
     private class NetworkAgentHandler extends Handler {
@@ -451,6 +490,32 @@
         }
     }
 
+    /**
+     * Register this network agent with ConnectivityService.
+     * @return the Network associated with this network agent (which can also be obtained later
+     *         by calling getNetwork() on this agent).
+     */
+    @NonNull
+    public Network register() {
+        if (VDBG) log("Registering NetworkAgent");
+        final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context
+                .getSystemService(Context.CONNECTIVITY_SERVICE);
+        mNetwork = cm.registerNetworkAgent(new Messenger(mHandler),
+                new NetworkInfo(mInitialConfiguration.info),
+                mInitialConfiguration.properties, mInitialConfiguration.capabilities,
+                mInitialConfiguration.score, mInitialConfiguration.config, providerId);
+        mInitialConfiguration = null; // All this memory can now be GC'd
+        return mNetwork;
+    }
+
+    /**
+     * @return The Network associated with this agent, or null if it's not registered yet.
+     */
+    @Nullable
+    public Network getNetwork() {
+        return mNetwork;
+    }
+
     private void queueOrSendMessage(int what, Object obj) {
         queueOrSendMessage(what, 0, 0, obj);
     }
@@ -483,15 +548,89 @@
      * @param linkProperties the new LinkProperties.
      */
     public void sendLinkProperties(@NonNull LinkProperties linkProperties) {
+        Objects.requireNonNull(linkProperties);
         queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties));
     }
 
     /**
+     * Inform ConnectivityService that this agent has now connected.
+     */
+    public void setConnected() {
+        if (mIsLegacy) {
+            throw new UnsupportedOperationException(
+                    "Legacy agents can't call setConnected.");
+        }
+        mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
+        queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+    }
+
+    /**
+     * Unregister this network agent.
+     *
+     * This signals the network has disconnected and ends its lifecycle. After this is called,
+     * the network is torn down and this agent can no longer be used.
+     */
+    public void unregister() {
+        if (mIsLegacy) {
+            throw new UnsupportedOperationException(
+                    "Legacy agents can't call unregister.");
+        }
+        mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
+        queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+    }
+
+    /**
+     * Change the legacy subtype of this network agent.
+     *
+     * This is only for backward compatibility and should not be used by non-legacy network agents,
+     * or agents that did not use to set a subtype. As such, only TYPE_MOBILE type agents can use
+     * this and others will be thrown an exception if they try.
+     *
+     * @deprecated this is for backward compatibility only.
+     * @param legacySubtype the legacy subtype.
+     */
+    @Deprecated
+    public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) {
+        if (mIsLegacy) {
+            throw new UnsupportedOperationException("Legacy agents can't call setLegacySubtype.");
+        }
+        mNetworkInfo.setSubtype(legacySubtype, legacySubtypeName);
+        queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+    }
+
+    /**
+     * Set the ExtraInfo of this network agent.
+     *
+     * This sets the ExtraInfo field inside the NetworkInfo returned by legacy public API and the
+     * broadcasts about the corresponding Network.
+     * This is only for backward compatibility and should not be used by non-legacy network agents,
+     * who will be thrown an exception if they try. The extra info should only be :
+     * <ul>
+     *   <li>For cellular agents, the APN name.</li>
+     *   <li>For ethernet agents, the interface name.</li>
+     * </ul>
+     *
+     * @deprecated this is for backward compatibility only.
+     * @param extraInfo the ExtraInfo.
+     */
+    @Deprecated
+    public void setLegacyExtraInfo(@Nullable final String extraInfo) {
+        if (mIsLegacy) {
+            throw new UnsupportedOperationException("Legacy agents can't call setLegacyExtraInfo.");
+        }
+        mNetworkInfo.setExtraInfo(extraInfo);
+        queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+    }
+
+    /**
      * Must be called by the agent when it has a new NetworkInfo object.
      * @hide TODO: expose something better.
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public void sendNetworkInfo(NetworkInfo networkInfo) {
+        if (!mIsLegacy) {
+            throw new UnsupportedOperationException("Only legacy agents can call sendNetworkInfo.");
+        }
         queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo));
     }
 
@@ -500,6 +639,7 @@
      * @param networkCapabilities the new NetworkCapabilities.
      */
     public void sendNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
+        Objects.requireNonNull(networkCapabilities);
         mBandwidthUpdatePending.set(false);
         mLastBwRefreshTime = System.currentTimeMillis();
         queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED,
@@ -510,22 +650,8 @@
      * Must be called by the agent to update the score of this network.
      * @param score the new score.
      */
-    public void sendNetworkScore(int score) {
-        if (score < 0) {
-            throw new IllegalArgumentException("Score must be >= 0");
-        }
-        final NetworkScore ns = new NetworkScore();
-        ns.putIntExtension(NetworkScore.LEGACY_SCORE, score);
-        updateScore(ns);
-    }
-
-    /**
-     * Must be called by the agent when it has a new {@link NetworkScore} for this network.
-     * @param ns the new score.
-     * @hide TODO: unhide the NetworkScore class, and rename to sendNetworkScore.
-     */
-    public void updateScore(@NonNull NetworkScore ns) {
-        queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new NetworkScore(ns));
+    public void sendNetworkScore(@NonNull final NetworkScore score) {
+        queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, score);
     }
 
     /**
diff --git a/core/java/android/net/NetworkAgentConfig.java b/core/java/android/net/NetworkAgentConfig.java
index 2c5a113..7e2db4a 100644
--- a/core/java/android/net/NetworkAgentConfig.java
+++ b/core/java/android/net/NetworkAgentConfig.java
@@ -22,6 +22,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.Objects;
+
 /**
  * Allows a network transport to provide the system with policy and configuration information about
  * a particular network when registering a {@link NetworkAgent}. This information cannot change once the agent is registered.
@@ -52,23 +54,47 @@
     public boolean explicitlySelected;
 
     /**
+     * @return whether this network was explicitly selected by the user.
+     */
+    public boolean isExplicitlySelected() {
+        return explicitlySelected;
+    }
+
+    /**
      * Set if the user desires to use this network even if it is unvalidated. This field has meaning
      * only if {@link explicitlySelected} is true. If it is, this field must also be set to the
      * appropriate value based on previous user choice.
      *
+     * TODO : rename this field to match its accessor
      * @hide
      */
     public boolean acceptUnvalidated;
 
     /**
+     * @return whether the system should accept this network even if it doesn't validate.
+     */
+    public boolean isUnvalidatedConnectivityAcceptable() {
+        return acceptUnvalidated;
+    }
+
+    /**
      * Whether the user explicitly set that this network should be validated even if presence of
      * only partial internet connectivity.
      *
+     * TODO : rename this field to match its accessor
      * @hide
      */
     public boolean acceptPartialConnectivity;
 
     /**
+     * @return whether the system should validate this network even if it only offers partial
+     *     Internet connectivity.
+     */
+    public boolean isPartialConnectivityAcceptable() {
+        return acceptPartialConnectivity;
+    }
+
+    /**
      * Set to avoid surfacing the "Sign in to network" notification.
      * if carrier receivers/apps are registered to handle the carrier-specific provisioning
      * procedure, a carrier specific provisioning notification will be placed.
@@ -134,9 +160,11 @@
      * Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network.
      * Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode.
      *
+     * This is not parceled, because it would not make sense.
+     *
      * @hide
      */
-    public boolean hasShownBroken;
+    public transient boolean hasShownBroken;
 
     /**
      * The name of the legacy network type. It's a free-form string used in logging.
@@ -163,6 +191,7 @@
             allowBypass = nac.allowBypass;
             explicitlySelected = nac.explicitlySelected;
             acceptUnvalidated = nac.acceptUnvalidated;
+            acceptPartialConnectivity = nac.acceptPartialConnectivity;
             subscriberId = nac.subscriberId;
             provisioningNotificationDisabled = nac.provisioningNotificationDisabled;
             skip464xlat = nac.skip464xlat;
@@ -178,6 +207,43 @@
         private final NetworkAgentConfig mConfig = new NetworkAgentConfig();
 
         /**
+         * Sets whether the network was explicitly selected by the user.
+         *
+         * @return this builder, to facilitate chaining.
+         */
+        @NonNull
+        public Builder setExplicitlySelected(final boolean explicitlySelected) {
+            mConfig.explicitlySelected = explicitlySelected;
+            return this;
+        }
+
+        /**
+         * Sets whether the system should validate this network even if it is found not to offer
+         * Internet connectivity.
+         *
+         * @return this builder, to facilitate chaining.
+         */
+        @NonNull
+        public Builder setUnvalidatedConnectivityAcceptable(
+                final boolean unvalidatedConnectivityAcceptable) {
+            mConfig.acceptUnvalidated = unvalidatedConnectivityAcceptable;
+            return this;
+        }
+
+        /**
+         * Sets whether the system should validate this network even if it is found to only offer
+         * partial Internet connectivity.
+         *
+         * @return this builder, to facilitate chaining.
+         */
+        @NonNull
+        public Builder setPartialConnectivityAcceptable(
+                final boolean partialConnectivityAcceptable) {
+            mConfig.acceptPartialConnectivity = partialConnectivityAcceptable;
+            return this;
+        }
+
+        /**
          * Sets the subscriber ID for this network.
          *
          * @return this builder, to facilitate chaining.
@@ -245,6 +311,45 @@
     }
 
     @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        final NetworkAgentConfig that = (NetworkAgentConfig) o;
+        return allowBypass == that.allowBypass
+                && explicitlySelected == that.explicitlySelected
+                && acceptUnvalidated == that.acceptUnvalidated
+                && acceptPartialConnectivity == that.acceptPartialConnectivity
+                && provisioningNotificationDisabled == that.provisioningNotificationDisabled
+                && skip464xlat == that.skip464xlat
+                && legacyType == that.legacyType
+                && Objects.equals(subscriberId, that.subscriberId)
+                && Objects.equals(legacyTypeName, that.legacyTypeName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated,
+                acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId,
+                skip464xlat, legacyType, legacyTypeName);
+    }
+
+    @Override
+    public String toString() {
+        return "NetworkAgentConfig {"
+                + " allowBypass = " + allowBypass
+                + ", explicitlySelected = " + explicitlySelected
+                + ", acceptUnvalidated = " + acceptUnvalidated
+                + ", acceptPartialConnectivity = " + acceptPartialConnectivity
+                + ", provisioningNotificationDisabled = " + provisioningNotificationDisabled
+                + ", subscriberId = '" + subscriberId + '\''
+                + ", skip464xlat = " + skip464xlat
+                + ", legacyType = " + legacyType
+                + ", hasShownBroken = " + hasShownBroken
+                + ", legacyTypeName = '" + legacyTypeName + '\''
+                + "}";
+    }
+
+    @Override
     public int describeContents() {
         return 0;
     }
@@ -254,9 +359,12 @@
         out.writeInt(allowBypass ? 1 : 0);
         out.writeInt(explicitlySelected ? 1 : 0);
         out.writeInt(acceptUnvalidated ? 1 : 0);
+        out.writeInt(acceptPartialConnectivity ? 1 : 0);
         out.writeString(subscriberId);
         out.writeInt(provisioningNotificationDisabled ? 1 : 0);
         out.writeInt(skip464xlat ? 1 : 0);
+        out.writeInt(legacyType);
+        out.writeString(legacyTypeName);
     }
 
     public static final @NonNull Creator<NetworkAgentConfig> CREATOR =
@@ -267,9 +375,12 @@
             networkAgentConfig.allowBypass = in.readInt() != 0;
             networkAgentConfig.explicitlySelected = in.readInt() != 0;
             networkAgentConfig.acceptUnvalidated = in.readInt() != 0;
+            networkAgentConfig.acceptPartialConnectivity = in.readInt() != 0;
             networkAgentConfig.subscriberId = in.readString();
             networkAgentConfig.provisioningNotificationDisabled = in.readInt() != 0;
             networkAgentConfig.skip464xlat = in.readInt() != 0;
+            networkAgentConfig.legacyType = in.readInt();
+            networkAgentConfig.legacyTypeName = in.readString();
             return networkAgentConfig;
         }
 
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 38f7390..f8b51dd 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -27,6 +27,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Process;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.proto.ProtoOutputStream;
 
@@ -63,6 +64,16 @@
     // Set to true when private DNS is broken.
     private boolean mPrivateDnsBroken;
 
+    /**
+     * Uid of the app making the request.
+     */
+    private int mRequestorUid;
+
+    /**
+     * Package name of the app making the request.
+     */
+    private String mRequestorPackageName;
+
     public NetworkCapabilities() {
         clearAll();
         mNetworkCapabilities = DEFAULT_CAPABILITIES;
@@ -89,6 +100,8 @@
         mOwnerUid = Process.INVALID_UID;
         mSSID = null;
         mPrivateDnsBroken = false;
+        mRequestorUid = Process.INVALID_UID;
+        mRequestorPackageName = null;
     }
 
     /**
@@ -109,6 +122,8 @@
         mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities;
         mSSID = nc.mSSID;
         mPrivateDnsBroken = nc.mPrivateDnsBroken;
+        mRequestorUid = nc.mRequestorUid;
+        mRequestorPackageName = nc.mRequestorPackageName;
     }
 
     /**
@@ -810,7 +825,7 @@
     }
 
     /**
-     * UID of the app that owns this network, or INVALID_UID if none/unknown.
+     * UID of the app that owns this network, or Process#INVALID_UID if none/unknown.
      *
      * <p>This field keeps track of the UID of the app that created this network and is in charge of
      * its lifecycle. This could be the UID of apps such as the Wifi network suggestor, the running
@@ -821,8 +836,9 @@
     /**
      * Set the UID of the owner app.
      */
-    public void setOwnerUid(final int uid) {
+    public @NonNull NetworkCapabilities setOwnerUid(final int uid) {
         mOwnerUid = uid;
+        return this;
     }
 
     /**
@@ -865,9 +881,11 @@
      * @hide
      */
     @SystemApi
-    public void setAdministratorUids(@NonNull final List<Integer> administratorUids) {
+    public @NonNull NetworkCapabilities setAdministratorUids(
+            @NonNull final List<Integer> administratorUids) {
         mAdministratorUids.clear();
         mAdministratorUids.addAll(administratorUids);
+        return this;
     }
 
     /**
@@ -1385,6 +1403,7 @@
         combineSignalStrength(nc);
         combineUids(nc);
         combineSSIDs(nc);
+        combineRequestor(nc);
     }
 
     /**
@@ -1404,7 +1423,8 @@
                 && satisfiedBySpecifier(nc)
                 && (onlyImmutable || satisfiedBySignalStrength(nc))
                 && (onlyImmutable || satisfiedByUids(nc))
-                && (onlyImmutable || satisfiedBySSID(nc)));
+                && (onlyImmutable || satisfiedBySSID(nc)))
+                && (onlyImmutable || satisfiedByRequestor(nc));
     }
 
     /**
@@ -1488,7 +1508,7 @@
     public boolean equals(@Nullable Object obj) {
         if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
         NetworkCapabilities that = (NetworkCapabilities) obj;
-        return (equalsNetCapabilities(that)
+        return equalsNetCapabilities(that)
                 && equalsTransportTypes(that)
                 && equalsLinkBandwidths(that)
                 && equalsSignalStrength(that)
@@ -1496,7 +1516,8 @@
                 && equalsTransportInfo(that)
                 && equalsUids(that)
                 && equalsSSID(that)
-                && equalsPrivateDnsBroken(that));
+                && equalsPrivateDnsBroken(that)
+                && equalsRequestor(that);
     }
 
     @Override
@@ -1514,7 +1535,9 @@
                 + Objects.hashCode(mUids) * 31
                 + Objects.hashCode(mSSID) * 37
                 + Objects.hashCode(mTransportInfo) * 41
-                + Objects.hashCode(mPrivateDnsBroken) * 43;
+                + Objects.hashCode(mPrivateDnsBroken) * 43
+                + Objects.hashCode(mRequestorUid) * 47
+                + Objects.hashCode(mRequestorPackageName) * 53;
     }
 
     @Override
@@ -1537,6 +1560,8 @@
         dest.writeBoolean(mPrivateDnsBroken);
         dest.writeList(mAdministratorUids);
         dest.writeInt(mOwnerUid);
+        dest.writeInt(mRequestorUid);
+        dest.writeString(mRequestorPackageName);
     }
 
     public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
@@ -1559,6 +1584,8 @@
                 netCap.mPrivateDnsBroken = in.readBoolean();
                 netCap.setAdministratorUids(in.readArrayList(null));
                 netCap.mOwnerUid = in.readInt();
+                netCap.mRequestorUid = in.readInt();
+                netCap.mRequestorPackageName = in.readString();
                 return netCap;
             }
             @Override
@@ -1624,6 +1651,9 @@
             sb.append(" Private DNS is broken");
         }
 
+        sb.append(" RequestorUid: ").append(mRequestorUid);
+        sb.append(" RequestorPackageName: ").append(mRequestorPackageName);
+
         sb.append("]");
         return sb.toString();
     }
@@ -1632,6 +1662,7 @@
     private interface NameOf {
         String nameOf(int value);
     }
+
     /**
      * @hide
      */
@@ -1654,7 +1685,7 @@
     }
 
     /** @hide */
-    public void writeToProto(@NonNull ProtoOutputStream proto, long fieldId) {
+    public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
 
         for (int transport : getTransportTypes()) {
@@ -1799,4 +1830,120 @@
     private boolean equalsPrivateDnsBroken(NetworkCapabilities nc) {
         return mPrivateDnsBroken == nc.mPrivateDnsBroken;
     }
+
+    /**
+     * Set the uid of the app making the request.
+     *
+     * Note: This works only for {@link NetworkAgent} instances. Any capabilities passed in
+     * via the public {@link ConnectivityManager} API's will have this field overwritten.
+     *
+     * @param uid UID of the app.
+     * @hide
+     */
+    @SystemApi
+    public @NonNull NetworkCapabilities setRequestorUid(int uid) {
+        mRequestorUid = uid;
+        return this;
+    }
+
+    /**
+     * @return the uid of the app making the request.
+     *
+     * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest}
+     * object was not obtained from {@link ConnectivityManager}.
+     * @hide
+     */
+    public int getRequestorUid() {
+        return mRequestorUid;
+    }
+
+    /**
+     * Set the package name of the app making the request.
+     *
+     * Note: This works only for {@link NetworkAgent} instances. Any capabilities passed in
+     * via the public {@link ConnectivityManager} API's will have this field overwritten.
+     *
+     * @param packageName package name of the app.
+     * @hide
+     */
+    @SystemApi
+    public @NonNull NetworkCapabilities setRequestorPackageName(@NonNull String packageName) {
+        mRequestorPackageName = packageName;
+        return this;
+    }
+
+    /**
+     * @return the package name of the app making the request.
+     *
+     * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained
+     * from {@link ConnectivityManager}.
+     * @hide
+     */
+    @Nullable
+    public String getRequestorPackageName() {
+        return mRequestorPackageName;
+    }
+
+    /**
+     * Set the uid and package name of the app making the request.
+     *
+     * Note: This is intended to be only invoked from within connectivitiy service.
+     *
+     * @param uid UID of the app.
+     * @param packageName package name of the app.
+     * @hide
+     */
+    public @NonNull NetworkCapabilities setRequestorUidAndPackageName(
+            int uid, @NonNull String packageName) {
+        return setRequestorUid(uid).setRequestorPackageName(packageName);
+    }
+
+    /**
+     * Test whether the passed NetworkCapabilities satisfies the requestor restrictions of this
+     * capabilities.
+     *
+     * This method is called on the NetworkCapabilities embedded in a request with the
+     * capabilities of an available network. If the available network, sets a specific
+     * requestor (by uid and optionally package name), then this will only match a request from the
+     * same app. If either of the capabilities have an unset uid or package name, then it matches
+     * everything.
+     * <p>
+     * nc is assumed nonnull. Else, NPE.
+     */
+    private boolean satisfiedByRequestor(NetworkCapabilities nc) {
+        // No uid set, matches everything.
+        if (mRequestorUid == Process.INVALID_UID || nc.mRequestorUid == Process.INVALID_UID) {
+            return true;
+        }
+        // uids don't match.
+        if (mRequestorUid != nc.mRequestorUid) return false;
+        // No package names set, matches everything
+        if (null == nc.mRequestorPackageName || null == mRequestorPackageName) return true;
+        // check for package name match.
+        return TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName);
+    }
+
+    /**
+     * Combine requestor info of the capabilities.
+     * <p>
+     * This is only legal if either the requestor info of this object is reset, or both info are
+     * equal.
+     * nc is assumed nonnull.
+     */
+    private void combineRequestor(@NonNull NetworkCapabilities nc) {
+        if (mRequestorUid != Process.INVALID_UID && mRequestorUid != nc.mOwnerUid) {
+            throw new IllegalStateException("Can't combine two uids");
+        }
+        if (mRequestorPackageName != null
+                && !mRequestorPackageName.equals(nc.mRequestorPackageName)) {
+            throw new IllegalStateException("Can't combine two package names");
+        }
+        setRequestorUid(nc.mRequestorUid);
+        setRequestorPackageName(nc.mRequestorPackageName);
+    }
+
+    private boolean equalsRequestor(NetworkCapabilities nc) {
+        return mRequestorUid == nc.mRequestorUid
+                && TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName);
+    }
 }
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index d0c5363..08fe159 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -17,9 +17,11 @@
 package android.net;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telephony.Annotation.NetworkType;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -150,10 +152,19 @@
     private boolean mIsRoaming;
 
     /**
-     * @hide
+     * Create a new instance of NetworkInfo.
+     *
+     * This may be useful for apps to write unit tests.
+     *
+     * @param type the legacy type of the network, as one of the ConnectivityManager.TYPE_*
+     *             constants.
+     * @param subtype the subtype if applicable, as one of the TelephonyManager.NETWORK_TYPE_*
+     *                constants.
+     * @param typeName a human-readable string for the network type, or an empty string or null.
+     * @param subtypeName a human-readable string for the subtype, or an empty string or null.
      */
-    @UnsupportedAppUsage
-    public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
+    public NetworkInfo(int type, @NetworkType int subtype,
+            @Nullable String typeName, @Nullable String subtypeName) {
         if (!ConnectivityManager.isNetworkTypeValid(type)
                 && type != ConnectivityManager.TYPE_NONE) {
             throw new IllegalArgumentException("Invalid network type: " + type);
@@ -462,17 +473,19 @@
 
     /**
      * Sets the fine-grained state of the network.
+     *
+     * This is only useful for testing.
+     *
      * @param detailedState the {@link DetailedState}.
      * @param reason a {@code String} indicating the reason for the state change,
      * if one was supplied. May be {@code null}.
      * @param extraInfo an optional {@code String} providing addditional network state
      * information passed up from the lower networking layers.
      * @deprecated Use {@link NetworkCapabilities} instead.
-     * @hide
      */
     @Deprecated
-    @UnsupportedAppUsage
-    public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
+    public void setDetailedState(@NonNull DetailedState detailedState, @Nullable String reason,
+            @Nullable String extraInfo) {
         synchronized (this) {
             this.mDetailedState = detailedState;
             this.mState = stateMap.get(detailedState);
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index ee4379a..964f13f 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -380,6 +380,7 @@
         dest.writeInt(requestId);
         dest.writeString(type.name());
     }
+
     public static final @android.annotation.NonNull Creator<NetworkRequest> CREATOR =
         new Creator<NetworkRequest>() {
             public NetworkRequest createFromParcel(Parcel in) {
@@ -494,6 +495,31 @@
         return networkCapabilities.getNetworkSpecifier();
     }
 
+    /**
+     * @return the uid of the app making the request.
+     *
+     * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest} object was
+     * not obtained from {@link ConnectivityManager}.
+     * @hide
+     */
+    @SystemApi
+    public int getRequestorUid() {
+        return networkCapabilities.getRequestorUid();
+    }
+
+    /**
+     * @return the package name of the app making the request.
+     *
+     * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained
+     * from {@link ConnectivityManager}.
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getRequestorPackageName() {
+        return networkCapabilities.getRequestorPackageName();
+    }
+
     public String toString() {
         return "NetworkRequest [ " + type + " id=" + requestId +
                 (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") +
@@ -518,13 +544,13 @@
     }
 
     /** @hide */
-    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
 
         proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type));
         proto.write(NetworkRequestProto.REQUEST_ID, requestId);
         proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType);
-        networkCapabilities.writeToProto(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
+        networkCapabilities.dumpDebug(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
 
         proto.end(token);
     }
diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java
index 13f2994..ae17378 100644
--- a/core/java/android/net/NetworkScore.java
+++ b/core/java/android/net/NetworkScore.java
@@ -15,12 +15,18 @@
  */
 package android.net;
 
+import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
@@ -28,57 +34,392 @@
  *
  * A NetworkScore object represents the characteristics of a network that affects how good the
  * network is considered for a particular use.
+ *
+ * This class is not thread-safe.
  * @hide
  */
+@TestApi
+@SystemApi
 public final class NetworkScore implements Parcelable {
+    /** An object containing scoring-relevant metrics for a network. */
+    public static class Metrics {
+        /** Value meaning the latency is unknown. */
+        public static final int LATENCY_UNKNOWN = -1;
 
-    // The key of bundle which is used to get the legacy network score of NetworkAgentInfo.
-    // TODO: Remove this when the transition to NetworkScore is over.
-    public static final String LEGACY_SCORE = "LEGACY_SCORE";
+        /** Value meaning the bandwidth is unknown. */
+        public static final int BANDWIDTH_UNKNOWN = -1;
+
+        /**
+         * Round-trip delay in milliseconds to the relevant destination for this Metrics object.
+         *
+         * LATENCY_UNKNOWN if unknown.
+         */
+        @IntRange(from = LATENCY_UNKNOWN)
+        public final int latencyMs;
+
+        /**
+         * Downlink in kB/s with the relevant destination for this Metrics object.
+         *
+         * BANDWIDTH_UNKNOWN if unknown. If directional bandwidth is unknown, up and downlink
+         * bandwidth can have the same value.
+         */
+        @IntRange(from = BANDWIDTH_UNKNOWN)
+        public final int downlinkBandwidthKBps;
+
+        /**
+         * Uplink in kB/s with the relevant destination for this Metrics object.
+         *
+         * BANDWIDTH_UNKNOWN if unknown. If directional bandwidth is unknown, up and downlink
+         * bandwidth can have the same value.
+         */
+        @IntRange(from = BANDWIDTH_UNKNOWN)
+        public final int uplinkBandwidthKBps;
+
+        /** Constructor */
+        public Metrics(@IntRange(from = LATENCY_UNKNOWN) final int latency,
+                @IntRange(from = BANDWIDTH_UNKNOWN) final int downlinkBandwidth,
+                @IntRange(from = BANDWIDTH_UNKNOWN) final int uplinkBandwidth) {
+            latencyMs = latency;
+            downlinkBandwidthKBps = downlinkBandwidth;
+            uplinkBandwidthKBps = uplinkBandwidth;
+        }
+
+        /** toString */
+        public String toString() {
+            return "latency = " + latencyMs + " downlinkBandwidth = " + downlinkBandwidthKBps
+                    + "uplinkBandwidth = " + uplinkBandwidthKBps;
+        }
+
+        @NonNull
+        public static final Metrics EMPTY =
+                new Metrics(LATENCY_UNKNOWN, BANDWIDTH_UNKNOWN, BANDWIDTH_UNKNOWN);
+    }
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, prefix = "POLICY_", value = {
+            POLICY_LOCKDOWN_VPN,
+            POLICY_VPN,
+            POLICY_IGNORE_ON_WIFI,
+            POLICY_DEFAULT_SUBSCRIPTION
+    })
+    public @interface Policy {
+    }
+
+    /**
+     * This network is a VPN with lockdown enabled.
+     *
+     * If a network with this bit is present in the list of candidates and not connected,
+     * no network can satisfy the request.
+     */
+    public static final int POLICY_LOCKDOWN_VPN = 1 << 0;
+
+    /**
+     * This network is a VPN.
+     *
+     * If a network with this bit is present and the request UID is included in the UID ranges
+     * of this network, it outscores all other networks without this bit.
+     */
+    public static final int POLICY_VPN = 1 << 1;
+
+    /**
+     * This network should not be used if a previously validated WiFi network is available.
+     *
+     * If a network with this bit is present and a previously validated WiFi is present too, the
+     * network with this bit is outscored by it. This stays true if the WiFi network
+     * becomes unvalidated : this network will not be considered.
+     */
+    public static final int POLICY_IGNORE_ON_WIFI = 1 << 2;
+
+    /**
+     * This network is the default subscription for this transport.
+     *
+     * If a network with this bit is present, other networks of the same transport without this
+     * bit are outscored by it. A device with two active subscriptions and a setting
+     * to decide the default one would have this policy bit on the network for the default
+     * subscription so that when both are active at the same time, the device chooses the
+     * network associated with the default subscription rather than the one with the best link
+     * quality (which will happen if policy doesn't dictate otherwise).
+     */
+    public static final int POLICY_DEFAULT_SUBSCRIPTION = 1 << 3;
+
+    /**
+     * Policy bits for this network. Filled in by the NetworkAgent.
+     */
+    private final int mPolicy;
+
+    /**
+     * Predicted metrics to the gateway (it contains latency and bandwidth to the gateway).
+     * This is filled by the NetworkAgent with the theoretical values of the link if available,
+     * although they may fill it with predictions from historical data if available.
+     * Note that while this member cannot be null, any and all of its members can be unknown.
+     */
     @NonNull
-    private final Bundle mExtensions;
+    private final Metrics mLinkLayerMetrics;
 
-    public NetworkScore() {
-        mExtensions = new Bundle();
-    }
+    /**
+     * Predicted metrics to representative servers.
+     * This is filled by connectivity with (if available) a best-effort estimate of the performance
+     * information to servers the user connects to in similar circumstances, and predicted from
+     * actual measurements if possible.
+     * Note that while this member cannot be null, any and all of its members can be unknown.
+     */
+    @NonNull
+    private final Metrics mEndToEndMetrics;
 
-    public NetworkScore(@NonNull NetworkScore source) {
-        mExtensions = new Bundle(source.mExtensions);
+    /** Value meaning the signal strength is unknown. */
+    public static final int UNKNOWN_SIGNAL_STRENGTH = -1;
+
+    /** The smallest meaningful signal strength. */
+    public static final int MIN_SIGNAL_STRENGTH = 0;
+
+    /** The largest meaningful signal strength. */
+    public static final int MAX_SIGNAL_STRENGTH = 1000;
+
+    /**
+     * User-visible measure of the strength of the signal normalized 1~1000.
+     * This represents a measure of the signal strength for this network.
+     * If unknown, this has value UNKNOWN_SIGNAL_STRENGTH.
+     */
+    // A good way to populate this value is to fill it with the number of bars displayed in
+    // the system UI, scaled 0 to 1000. This is what the user sees and it makes sense to them.
+    // Cellular for example could quantize the ASU value (see SignalStrength#getAsuValue) into
+    // this, while WiFi could scale the RSSI (see WifiManager#calculateSignalLevel).
+    @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH)
+    private final int mSignalStrength;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, prefix = "RANGE_", value = {
+            RANGE_UNKNOWN, RANGE_CLOSE, RANGE_SHORT, RANGE_MEDIUM, RANGE_LONG
+    })
+    public @interface Range {
     }
 
     /**
-     * Put the value of parcelable inside the bundle by key.
+     * The range of this network is not known.
+     * This can be used by VPN the range of which depends on the range of the underlying network.
      */
-    public void putExtension(@Nullable String key, @Nullable Parcelable value) {
-        mExtensions.putParcelable(key, value);
+    public static final int RANGE_UNKNOWN = 0;
+
+    /**
+     * This network typically only operates at close range, like an NFC beacon.
+     */
+    public static final int RANGE_CLOSE = 1;
+
+    /**
+     * This network typically operates at a range of a few meters to a few dozen meters, like WiFi.
+     */
+    public static final int RANGE_SHORT = 2;
+
+    /**
+     * This network typically operates at a range of a few dozen to a few hundred meters, like CBRS.
+     */
+    public static final int RANGE_MEDIUM = 3;
+
+    /**
+     * This network typically offers continuous connectivity up to many kilometers away, like LTE.
+     */
+    public static final int RANGE_LONG = 4;
+
+    /**
+     * The typical range of this networking technology.
+     *
+     * This is one of the RANGE_* constants and is filled by the NetworkAgent.
+     * This may be useful when evaluating how desirable a network is, because for two networks that
+     * have equivalent performance and cost, the one that won't lose IP continuity when the user
+     * moves is probably preferable.
+     * Agents should fill this with the largest typical range this technology provides. See the
+     * descriptions of the individual constants for guidance.
+     *
+     * If unknown, this is set to RANGE_UNKNOWN.
+     */
+    @Range private final int mRange;
+
+    /**
+     * A prediction of whether this network is likely to be unusable in a few seconds.
+     *
+     * NetworkAgents set this to true to mean they are aware that usability is limited due to
+     * low signal strength, congestion, or other reasons, and indicates that the system should
+     * only use this network as a last resort. An example would be a WiFi network when the device
+     * is about to move outside of range.
+     *
+     * This is filled by the NetworkAgent. Agents that don't know whether this network is likely
+     * to be unusable soon should set this to false.
+     */
+    private final boolean mExiting;
+
+    /**
+     * The legacy score, as a migration strategy from Q to R.
+     * STOPSHIP : remove this before R ships.
+     */
+    private final int mLegacyScore;
+
+    /**
+     * Create a new NetworkScore object.
+     */
+    private NetworkScore(@Policy final int policy, @Nullable final Metrics l2Perf,
+            @Nullable final Metrics e2ePerf,
+            @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH)
+            final int signalStrength,
+            @Range final int range, final boolean exiting, final int legacyScore) {
+        mPolicy = policy;
+        mLinkLayerMetrics = null != l2Perf ? l2Perf : Metrics.EMPTY;
+        mEndToEndMetrics = null != e2ePerf ? e2ePerf : Metrics.EMPTY;
+        mSignalStrength = signalStrength;
+        mRange = range;
+        mExiting = exiting;
+        mLegacyScore = legacyScore;
     }
 
     /**
-     * Put the value of int inside the bundle by key.
+     * Utility function to return a copy of this with a different exiting value.
      */
-    public void putIntExtension(@Nullable String key, int value) {
-        mExtensions.putInt(key, value);
+    @NonNull public NetworkScore withExiting(final boolean exiting) {
+        return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToEndMetrics,
+                mSignalStrength, mRange, exiting, mLegacyScore);
     }
 
     /**
-     * Get the value of non primitive type by key.
+     * Utility function to return a copy of this with a different signal strength.
      */
-    public <T extends Parcelable> T getExtension(@Nullable String key) {
-        return mExtensions.getParcelable(key);
+    @NonNull public NetworkScore withSignalStrength(
+            @IntRange(from = UNKNOWN_SIGNAL_STRENGTH) final int signalStrength) {
+        return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToEndMetrics,
+                signalStrength, mRange, mExiting, mLegacyScore);
     }
 
     /**
-     * Get the value of int by key.
+     * Returns whether this network has a particular policy flag.
+     * @param policy the policy, as one of the POLICY_* constants.
      */
-    public int getIntExtension(@Nullable String key) {
-        return mExtensions.getInt(key);
+    public boolean hasPolicy(@Policy final int policy) {
+        return 0 != (mPolicy & policy);
     }
 
     /**
-     * Remove the entry by given key.
+     * Returns the Metrics representing the performance of the link layer.
+     *
+     * This contains the theoretical performance of the link, if available.
+     * Note that while this function cannot return null, any and/or all of the members of the
+     * returned object can be null if unknown.
      */
-    public void removeExtension(@Nullable String key) {
-        mExtensions.remove(key);
+    @NonNull public Metrics getLinkLayerMetrics() {
+        return mLinkLayerMetrics;
+    }
+
+    /**
+     * Returns the Metrics representing the end-to-end performance of the network.
+     *
+     * This contains the end-to-end performance of the link, if available.
+     * Note that while this function cannot return null, any and/or all of the members of the
+     * returned object can be null if unknown.
+     */
+    @NonNull public Metrics getEndToEndMetrics() {
+        return mEndToEndMetrics;
+    }
+
+    /**
+     * Returns the signal strength of this network normalized 0~1000, or UNKNOWN_SIGNAL_STRENGTH.
+     */
+    @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH)
+    public int getSignalStrength() {
+        return mSignalStrength;
+    }
+
+    /**
+     * Returns the typical range of this network technology as one of the RANGE_* constants.
+     */
+    @Range public int getRange() {
+        return mRange;
+    }
+
+    /** Returns a prediction of whether this network is likely to be unusable in a few seconds. */
+    public boolean isExiting() {
+        return mExiting;
+    }
+
+    /**
+     * Get the legacy score.
+     * @hide
+     */
+    public int getLegacyScore() {
+        return mLegacyScore;
+    }
+
+    /** Builder for NetworkScore. */
+    public static class Builder {
+        private int mPolicy = 0;
+        @NonNull
+        private Metrics mLinkLayerMetrics = new Metrics(Metrics.LATENCY_UNKNOWN,
+                Metrics.BANDWIDTH_UNKNOWN, Metrics.BANDWIDTH_UNKNOWN);
+        @NonNull
+        private Metrics mEndToMetrics = new Metrics(Metrics.LATENCY_UNKNOWN,
+                Metrics.BANDWIDTH_UNKNOWN, Metrics.BANDWIDTH_UNKNOWN);
+        private int mSignalStrength = UNKNOWN_SIGNAL_STRENGTH;
+        private int mRange = RANGE_UNKNOWN;
+        private boolean mExiting = false;
+        private int mLegacyScore = 0;
+        @NonNull private Bundle mExtensions = new Bundle();
+
+        /** Create a new builder. */
+        public Builder() { }
+
+        /** Add a policy flag. */
+        @NonNull public Builder addPolicy(@Policy final int policy) {
+            mPolicy |= policy;
+            return this;
+        }
+
+        /** Clear a policy flag */
+        @NonNull public Builder clearPolicy(@Policy final int policy) {
+            mPolicy &= ~policy;
+            return this;
+        }
+
+        /** Set the link layer metrics. */
+        @NonNull public Builder setLinkLayerMetrics(@NonNull final Metrics linkLayerMetrics) {
+            mLinkLayerMetrics = linkLayerMetrics;
+            return this;
+        }
+
+        /** Set the end-to-end metrics. */
+        @NonNull public Builder setEndToEndMetrics(@NonNull final Metrics endToEndMetrics) {
+            mEndToMetrics = endToEndMetrics;
+            return this;
+        }
+
+        /** Set the signal strength. */
+        @NonNull public Builder setSignalStrength(
+                @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH)
+                        final int signalStrength) {
+            mSignalStrength = signalStrength;
+            return this;
+        }
+
+        /** Set the range. */
+        @NonNull public Builder setRange(@Range final int range) {
+            mRange = range;
+            return this;
+        }
+
+        /** Set whether this network is exiting. */
+        @NonNull public Builder setExiting(final boolean exiting) {
+            mExiting = exiting;
+            return this;
+        }
+
+        /** Add a parcelable extension. */
+        @NonNull public Builder setLegacyScore(final int legacyScore) {
+            mLegacyScore = legacyScore;
+            return this;
+        }
+
+        /** Build the NetworkScore object represented by this builder. */
+        @NonNull public NetworkScore build() {
+            return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToMetrics,
+                    mSignalStrength, mRange, mExiting, mLegacyScore);
+        }
     }
 
     @Override
@@ -88,9 +429,17 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        synchronized (this) {
-            dest.writeBundle(mExtensions);
-        }
+        dest.writeInt(mPolicy);
+        dest.writeInt(mLinkLayerMetrics.latencyMs);
+        dest.writeInt(mLinkLayerMetrics.downlinkBandwidthKBps);
+        dest.writeInt(mLinkLayerMetrics.uplinkBandwidthKBps);
+        dest.writeInt(mEndToEndMetrics.latencyMs);
+        dest.writeInt(mEndToEndMetrics.downlinkBandwidthKBps);
+        dest.writeInt(mEndToEndMetrics.uplinkBandwidthKBps);
+        dest.writeInt(mSignalStrength);
+        dest.writeInt(mRange);
+        dest.writeBoolean(mExiting);
+        dest.writeInt(mLegacyScore);
     }
 
     public static final @NonNull Creator<NetworkScore> CREATOR = new Creator<NetworkScore>() {
@@ -106,57 +455,52 @@
     };
 
     private NetworkScore(@NonNull Parcel in) {
-        mExtensions = in.readBundle();
+        mPolicy = in.readInt();
+        mLinkLayerMetrics = new Metrics(in.readInt(), in.readInt(), in.readInt());
+        mEndToEndMetrics = new Metrics(in.readInt(), in.readInt(), in.readInt());
+        mSignalStrength = in.readInt();
+        mRange = in.readInt();
+        mExiting = in.readBoolean();
+        mLegacyScore = in.readInt();
     }
 
-    // TODO: Modify this method once new fields are added into this class.
     @Override
     public boolean equals(@Nullable Object obj) {
         if (!(obj instanceof NetworkScore)) {
             return false;
         }
         final NetworkScore other = (NetworkScore) obj;
-        return bundlesEqual(mExtensions, other.mExtensions);
+        return mPolicy == other.mPolicy
+                && mLinkLayerMetrics.latencyMs == other.mLinkLayerMetrics.latencyMs
+                && mLinkLayerMetrics.uplinkBandwidthKBps
+                == other.mLinkLayerMetrics.uplinkBandwidthKBps
+                && mEndToEndMetrics.latencyMs == other.mEndToEndMetrics.latencyMs
+                && mEndToEndMetrics.uplinkBandwidthKBps
+                == other.mEndToEndMetrics.uplinkBandwidthKBps
+                && mSignalStrength == other.mSignalStrength
+                && mRange == other.mRange
+                && mExiting == other.mExiting
+                && mLegacyScore == other.mLegacyScore;
     }
 
     @Override
     public int hashCode() {
-        int result = 29;
-        for (String key : mExtensions.keySet()) {
-            final Object value = mExtensions.get(key);
-            // The key may be null, so call Objects.hash() is safer.
-            result += 31 * value.hashCode() + 37 * Objects.hash(key);
-        }
-        return result;
-    }
-
-    // mExtensions won't be null since the constructor will create it.
-    private boolean bundlesEqual(@NonNull Bundle bundle1, @NonNull Bundle bundle2) {
-        if (bundle1 == bundle2) {
-            return true;
-        }
-
-        // This is unlikely but it's fine to add this clause here.
-        if (null == bundle1 || null == bundle2) {
-            return false;
-        }
-
-        if (bundle1.size() != bundle2.size()) {
-            return false;
-        }
-
-        for (String key : bundle1.keySet()) {
-            final Object value1 = bundle1.get(key);
-            final Object value2 = bundle2.get(key);
-            if (!Objects.equals(value1, value2)) {
-                return false;
-            }
-        }
-        return true;
+        return Objects.hash(mPolicy,
+                mLinkLayerMetrics.latencyMs, mLinkLayerMetrics.uplinkBandwidthKBps,
+                mEndToEndMetrics.latencyMs, mEndToEndMetrics.uplinkBandwidthKBps,
+                mSignalStrength, mRange, mExiting, mLegacyScore);
     }
 
     /** Convert to a string */
     public String toString() {
-        return "NetworkScore[" + mExtensions.toString() + "]";
+        return "NetworkScore ["
+                + "Policy = " + mPolicy
+                + " LinkLayerMetrics = " + mLinkLayerMetrics
+                + " EndToEndMetrics = " + mEndToEndMetrics
+                + " SignalStrength = " + mSignalStrength
+                + " Range = " + mRange
+                + " Exiting = " + mExiting
+                + " LegacyScore = " + mLegacyScore
+                + "]";
     }
 }
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 08cc4e2..779f7bc 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -31,7 +31,6 @@
 import java.io.FileDescriptor;
 import java.math.BigInteger;
 import java.net.Inet4Address;
-import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.SocketException;
 import java.net.UnknownHostException;
@@ -313,15 +312,6 @@
     }
 
     /**
-     * Check if IP address type is consistent between two InetAddress.
-     * @return true if both are the same type.  False otherwise.
-     */
-    public static boolean addressTypeMatches(InetAddress left, InetAddress right) {
-        return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) ||
-                ((left instanceof Inet6Address) && (right instanceof Inet6Address)));
-    }
-
-    /**
      * Convert a 32 char hex string into a Inet6Address.
      * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be
      * made into an Inet6Address
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index 67bad53..2b9e9fe 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -22,6 +22,7 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.net.util.NetUtils;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -483,21 +484,7 @@
     @UnsupportedAppUsage
     @Nullable
     public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
-        if ((routes == null) || (dest == null)) return null;
-
-        RouteInfo bestRoute = null;
-        // pick a longest prefix match under same address type
-        for (RouteInfo route : routes) {
-            if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) {
-                if ((bestRoute != null) &&
-                        (bestRoute.mDestination.getPrefixLength() >=
-                        route.mDestination.getPrefixLength())) {
-                    continue;
-                }
-                if (route.matches(dest)) bestRoute = route;
-            }
-        }
-        return bestRoute;
+        return NetUtils.selectBestRoute(routes, dest);
     }
 
     /**
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index e2b8ad9..b334b26 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -48,8 +48,6 @@
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
-
 import static java.util.Map.Entry;
 
 import android.annotation.NonNull;
@@ -88,7 +86,6 @@
 import android.net.IpMemoryStore;
 import android.net.IpPrefix;
 import android.net.LinkProperties;
-import android.net.LinkProperties.CompareResult;
 import android.net.MatchAllNetworkSpecifier;
 import android.net.NattSocketKeepalive;
 import android.net.Network;
@@ -123,6 +120,7 @@
 import android.net.metrics.NetworkEvent;
 import android.net.netlink.InetDiagMessage;
 import android.net.shared.PrivateDnsConfig;
+import android.net.util.LinkPropertiesUtils.CompareResult;
 import android.net.util.MultinetworkPolicyTracker;
 import android.net.util.NetdService;
 import android.os.Binder;
@@ -606,7 +604,7 @@
 
     private Set<String> mWolSupportedInterfaces;
 
-    private TelephonyManager mTelephonyManager;
+    private final TelephonyManager mTelephonyManager;
     private final AppOpsManager mAppOpsManager;
 
     private final LocationPermissionChecker mLocationPermissionChecker;
@@ -925,7 +923,7 @@
          * @see IpConnectivityMetrics.Logger
          */
         public IpConnectivityMetrics.Logger getMetricsLogger() {
-            return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
+            return Objects.requireNonNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
                     "no IpConnectivityMetrics service");
         }
 
@@ -954,9 +952,10 @@
             IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd, Dependencies deps) {
         if (DBG) log("ConnectivityService starting up");
 
-        mDeps = checkNotNull(deps, "missing Dependencies");
+        mDeps = Objects.requireNonNull(deps, "missing Dependencies");
         mSystemProperties = mDeps.getSystemProperties();
         mNetIdManager = mDeps.makeNetIdManager();
+        mContext = Objects.requireNonNull(context, "missing Context");
 
         mMetricsLog = logger;
         mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
@@ -986,14 +985,13 @@
 
         mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
 
-        mContext = checkNotNull(context, "missing Context");
-        mNMS = checkNotNull(netManager, "missing INetworkManagementService");
-        mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
-        mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
-        mPolicyManagerInternal = checkNotNull(
+        mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
+        mStatsService = Objects.requireNonNull(statsService, "missing INetworkStatsService");
+        mPolicyManager = Objects.requireNonNull(policyManager, "missing INetworkPolicyManager");
+        mPolicyManagerInternal = Objects.requireNonNull(
                 LocalServices.getService(NetworkPolicyManagerInternal.class),
                 "missing NetworkPolicyManagerInternal");
-        mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver");
+        mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
         mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
 
         mNetd = netd;
@@ -1166,6 +1164,7 @@
             int transportType, NetworkRequest.Type type) {
         final NetworkCapabilities netCap = new NetworkCapabilities();
         netCap.addCapability(NET_CAPABILITY_INTERNET);
+        netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
         if (transportType > -1) {
             netCap.addTransportType(transportType);
         }
@@ -1696,10 +1695,12 @@
         return newLp;
     }
 
-    private void restrictRequestUidsForCaller(NetworkCapabilities nc) {
+    private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc,
+            int callerUid, String callerPackageName) {
         if (!checkSettingsPermission()) {
-            nc.setSingleUid(Binder.getCallingUid());
+            nc.setSingleUid(callerUid);
         }
+        nc.setRequestorUidAndPackageName(callerUid, callerPackageName);
         nc.setAdministratorUids(Collections.EMPTY_LIST);
 
         // Clear owner UID; this can never come from an app.
@@ -2095,6 +2096,15 @@
                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
     }
 
+    private void enforceAirplaneModePermission() {
+        enforceAnyPermissionOf(
+                android.Manifest.permission.NETWORK_AIRPLANE_MODE,
+                android.Manifest.permission.NETWORK_SETTINGS,
+                android.Manifest.permission.NETWORK_SETUP_WIZARD,
+                android.Manifest.permission.NETWORK_STACK,
+                NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+    }
+
     private boolean checkNetworkStackPermission() {
         return checkAnyPermissionOf(
                 android.Manifest.permission.NETWORK_STACK,
@@ -4957,7 +4967,7 @@
 
     @Override
     public void setAirplaneMode(boolean enable) {
-        enforceNetworkStackSettingsOrSetup();
+        enforceAirplaneModePermission();
         final long ident = Binder.clearCallingIdentity();
         try {
             final ContentResolver cr = mContext.getContentResolver();
@@ -5305,7 +5315,7 @@
     // This checks that the passed capabilities either do not request a
     // specific SSID/SignalStrength, or the calling app has permission to do so.
     private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
-            int callerPid, int callerUid) {
+            int callerPid, int callerUid, String callerPackageName) {
         if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) {
             throw new SecurityException("Insufficient permissions to request a specific SSID");
         }
@@ -5315,6 +5325,7 @@
             throw new SecurityException(
                     "Insufficient permissions to request a specific signal strength");
         }
+        mAppOpsManager.checkPackage(callerUid, callerPackageName);
     }
 
     private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) {
@@ -5361,7 +5372,6 @@
             return;
         }
         MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns);
-        ns.assertValidFromUid(Binder.getCallingUid());
     }
 
     private void ensureValid(NetworkCapabilities nc) {
@@ -5373,7 +5383,9 @@
 
     @Override
     public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
-            Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
+            Messenger messenger, int timeoutMs, IBinder binder, int legacyType,
+            @NonNull String callingPackageName) {
+        final int callingUid = Binder.getCallingUid();
         final NetworkRequest.Type type = (networkCapabilities == null)
                 ? NetworkRequest.Type.TRACK_DEFAULT
                 : NetworkRequest.Type.REQUEST;
@@ -5381,7 +5393,7 @@
         // the default network request. This allows callers to keep track of
         // the system default network.
         if (type == NetworkRequest.Type.TRACK_DEFAULT) {
-            networkCapabilities = createDefaultNetworkCapabilitiesForUid(Binder.getCallingUid());
+            networkCapabilities = createDefaultNetworkCapabilitiesForUid(callingUid);
             enforceAccessPermission();
         } else {
             networkCapabilities = new NetworkCapabilities(networkCapabilities);
@@ -5393,13 +5405,14 @@
         }
         ensureRequestableCapabilities(networkCapabilities);
         ensureSufficientPermissionsForRequest(networkCapabilities,
-                Binder.getCallingPid(), Binder.getCallingUid());
+                Binder.getCallingPid(), callingUid, callingPackageName);
         // Set the UID range for this request to the single UID of the requester, or to an empty
         // set of UIDs if the caller has the appropriate permission and UIDs have not been set.
         // This will overwrite any allowed UIDs in the requested capabilities. Though there
         // are no visible methods to set the UIDs, an app could use reflection to try and get
         // networks for other apps so it's essential that the UIDs are overwritten.
-        restrictRequestUidsForCaller(networkCapabilities);
+        restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
+                callingUid, callingPackageName);
 
         if (timeoutMs < 0) {
             throw new IllegalArgumentException("Bad timeout specified");
@@ -5474,16 +5487,18 @@
 
     @Override
     public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
-            PendingIntent operation) {
-        checkNotNull(operation, "PendingIntent cannot be null.");
+            PendingIntent operation, @NonNull String callingPackageName) {
+        Objects.requireNonNull(operation, "PendingIntent cannot be null.");
+        final int callingUid = Binder.getCallingUid();
         networkCapabilities = new NetworkCapabilities(networkCapabilities);
         enforceNetworkRequestPermissions(networkCapabilities);
         enforceMeteredApnPolicy(networkCapabilities);
         ensureRequestableCapabilities(networkCapabilities);
         ensureSufficientPermissionsForRequest(networkCapabilities,
-                Binder.getCallingPid(), Binder.getCallingUid());
+                Binder.getCallingPid(), callingUid, callingPackageName);
         ensureValidNetworkSpecifier(networkCapabilities);
-        restrictRequestUidsForCaller(networkCapabilities);
+        restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
+                callingUid, callingPackageName);
 
         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
                 nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
@@ -5502,7 +5517,7 @@
 
     @Override
     public void releasePendingNetworkRequest(PendingIntent operation) {
-        checkNotNull(operation, "PendingIntent cannot be null.");
+        Objects.requireNonNull(operation, "PendingIntent cannot be null.");
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
                 getCallingUid(), 0, operation));
     }
@@ -5531,15 +5546,16 @@
 
     @Override
     public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
-            Messenger messenger, IBinder binder) {
+            Messenger messenger, IBinder binder, @NonNull String callingPackageName) {
+        final int callingUid = Binder.getCallingUid();
         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
             enforceAccessPermission();
         }
 
         NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
         ensureSufficientPermissionsForRequest(networkCapabilities,
-                Binder.getCallingPid(), Binder.getCallingUid());
-        restrictRequestUidsForCaller(nc);
+                Binder.getCallingPid(), callingUid, callingPackageName);
+        restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
         // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
         // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
         // onLost and onAvailable callbacks when networks move in and out of the background.
@@ -5559,17 +5575,17 @@
 
     @Override
     public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
-            PendingIntent operation) {
-        checkNotNull(operation, "PendingIntent cannot be null.");
+            PendingIntent operation, @NonNull String callingPackageName) {
+        Objects.requireNonNull(operation, "PendingIntent cannot be null.");
+        final int callingUid = Binder.getCallingUid();
         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
             enforceAccessPermission();
         }
         ensureValid(networkCapabilities);
         ensureSufficientPermissionsForRequest(networkCapabilities,
-                Binder.getCallingPid(), Binder.getCallingUid());
-
+                Binder.getCallingPid(), callingUid, callingPackageName);
         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
-        restrictRequestUidsForCaller(nc);
+        restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
 
         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
                 NetworkRequest.Type.LISTEN);
@@ -5712,20 +5728,6 @@
         return nri.request.requestId == mDefaultRequest.requestId;
     }
 
-    // TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent
-    // changes that would conflict throughout the automerger graph. Having this method temporarily
-    // helps with the process of going through with all these dependent changes across the entire
-    // tree.
-    /**
-     * Register a new agent. {@see #registerNetworkAgent} below.
-     */
-    public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
-            LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
-            int currentScore, NetworkAgentConfig networkAgentConfig) {
-        return registerNetworkAgent(messenger, networkInfo, linkProperties, networkCapabilities,
-                currentScore, networkAgentConfig, NetworkProvider.ID_NONE);
-    }
-
     /**
      * Register a new agent with ConnectivityService to handle a network.
      *
@@ -5744,7 +5746,7 @@
      */
     public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
-            int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
+            NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
         enforceNetworkFactoryPermission();
 
         LinkProperties lp = new LinkProperties(linkProperties);
@@ -5752,12 +5754,10 @@
         // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
         // satisfies mDefaultRequest.
         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
-        final NetworkScore ns = new NetworkScore();
-        ns.putIntExtension(NetworkScore.LEGACY_SCORE, currentScore);
         final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
                 new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
-                ns, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig), this,
-                mNetd, mDnsResolver, mNMS, providerId);
+                currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
+                this, mNetd, mDnsResolver, mNMS, providerId);
         // Make sure the network capabilities reflect what the agent info says.
         nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
         final String extraInfo = networkInfo.getExtraInfo();
@@ -7848,12 +7848,13 @@
             throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated."
                     + " Please use NetworkCapabilities instead.");
         }
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackageName);
+        final int callingUid = Binder.getCallingUid();
+        mAppOpsManager.checkPackage(callingUid, callingPackageName);
 
         // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid
         // and administrator uids to be safe.
         final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities);
-        restrictRequestUidsForCaller(nc);
+        restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
 
         final NetworkRequest requestWithId =
                 new NetworkRequest(
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index a7e36b2..35a9802 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -16,8 +16,6 @@
 
 package com.android.server;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -55,6 +53,7 @@
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.util.ArrayList;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /** @hide */
@@ -82,9 +81,9 @@
         mHandlerThread.start();
         mHandler = new Handler(mHandlerThread.getLooper());
 
-        mContext = checkNotNull(context, "missing Context");
-        mNMS = checkNotNull(netManager, "missing INetworkManagementService");
-        mNetd = checkNotNull(NetdService.getInstance(), "could not get netd instance");
+        mContext = Objects.requireNonNull(context, "missing Context");
+        mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
+        mNetd = Objects.requireNonNull(NetdService.getInstance(), "could not get netd instance");
     }
 
     /**
@@ -96,7 +95,7 @@
     private TestNetworkInterface createInterface(boolean isTun, LinkAddress[] linkAddrs) {
         enforceTestNetworkPermissions(mContext);
 
-        checkNotNull(linkAddrs, "missing linkAddrs");
+        Objects.requireNonNull(linkAddrs, "missing linkAddrs");
 
         String ifacePrefix = isTun ? TEST_TUN_PREFIX : TEST_TAP_PREFIX;
         String iface = ifacePrefix + sTestTunIndex.getAndIncrement();
@@ -219,7 +218,7 @@
             // Has to be in TestNetworkAgent to ensure all teardown codepaths properly clean up
             // resources, even for binder death or unwanted calls.
             synchronized (mTestNetworkTracker) {
-                mTestNetworkTracker.remove(network.netId);
+                mTestNetworkTracker.remove(getNetwork().netId);
             }
         }
     }
@@ -233,8 +232,8 @@
             int callingUid,
             @NonNull IBinder binder)
             throws RemoteException, SocketException {
-        checkNotNull(looper, "missing Looper");
-        checkNotNull(context, "missing Context");
+        Objects.requireNonNull(looper, "missing Looper");
+        Objects.requireNonNull(context, "missing Context");
         // iface and binder validity checked by caller
 
         // Build network info with special testing type
@@ -267,7 +266,7 @@
         // Find the currently assigned addresses, and add them to LinkProperties
         boolean allowIPv4 = false, allowIPv6 = false;
         NetworkInterface netIntf = NetworkInterface.getByName(iface);
-        checkNotNull(netIntf, "No such network interface found: " + netIntf);
+        Objects.requireNonNull(netIntf, "No such network interface found: " + netIntf);
 
         for (InterfaceAddress intfAddr : netIntf.getInterfaceAddresses()) {
             lp.addLinkAddress(
@@ -305,8 +304,8 @@
             @NonNull IBinder binder) {
         enforceTestNetworkPermissions(mContext);
 
-        checkNotNull(iface, "missing Iface");
-        checkNotNull(binder, "missing IBinder");
+        Objects.requireNonNull(iface, "missing Iface");
+        Objects.requireNonNull(binder, "missing IBinder");
 
         if (!(iface.startsWith(INetd.IPSEC_INTERFACE_PREFIX)
                 || iface.startsWith(TEST_TUN_PREFIX))) {
@@ -338,7 +337,7 @@
                                             callingUid,
                                             binder);
 
-                            mTestNetworkTracker.put(agent.network.netId, agent);
+                            mTestNetworkTracker.put(agent.getNetwork().netId, agent);
                         }
                     } catch (SocketException e) {
                         throw new UncheckedIOException(e);
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index d30a320..592be2f 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -486,7 +486,7 @@
             return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE;
         }
 
-        int score = mNetworkScore.getIntExtension(NetworkScore.LEGACY_SCORE);
+        int score = mNetworkScore.getLegacyScore();
         if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) {
             score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY;
         }
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index 3f311c9..f25fd4d 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -27,8 +27,8 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.net.LinkProperties.CompareResult;
 import android.net.LinkProperties.ProvisioningChange;
+import android.net.util.LinkPropertiesUtils.CompareResult;
 import android.system.OsConstants;
 import android.util.ArraySet;
 
diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
new file mode 100644
index 0000000..d250ad3
--- /dev/null
+++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
@@ -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 android.net
+
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.assertParcelSane
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class NetworkAgentConfigTest {
+    @Test
+    fun testParcelNetworkAgentConfig() {
+        val config = NetworkAgentConfig.Builder().apply {
+            setExplicitlySelected(true)
+            setLegacyType(ConnectivityManager.TYPE_ETHERNET)
+            setSubscriberId("MySubId")
+            setPartialConnectivityAcceptable(false)
+            setUnvalidatedConnectivityAcceptable(true)
+        }.build()
+        assertParcelSane(config, 9)
+    }
+}
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 3e4f3d8..efea91a 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -272,10 +272,24 @@
         netCap.setOwnerUid(123);
         assertParcelingIsLossless(netCap);
         netCap.setSSID(TEST_SSID);
-        assertParcelSane(netCap, 13);
+        assertParcelSane(netCap, 15);
     }
 
     @Test
+    public void testParcelNetworkCapabilitiesWithRequestorUidAndPackageName() {
+        final NetworkCapabilities netCap = new NetworkCapabilities()
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .setRequestorUid(9304)
+                .setRequestorPackageName("com.android.test")
+                .addCapability(NET_CAPABILITY_EIMS)
+                .addCapability(NET_CAPABILITY_NOT_METERED);
+        assertParcelingIsLossless(netCap);
+        netCap.setSSID(TEST_SSID);
+        assertParcelSane(netCap, 15);
+    }
+
+
+    @Test
     public void testOemPaid() {
         NetworkCapabilities nc = new NetworkCapabilities();
         // By default OEM_PAID is neither in the unwanted or required lists and the network is not
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index 1c69209..7ae9e95 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -40,6 +40,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkProvider;
+import android.net.NetworkScore;
 import android.net.NetworkSpecifier;
 import android.net.SocketKeepalive;
 import android.net.UidRange;
@@ -155,9 +156,13 @@
         }
     }
 
+    private NetworkScore makeNetworkScore(final int legacyScore) {
+        return new NetworkScore.Builder().setLegacyScore(legacyScore).build();
+    }
+
     public void adjustScore(int change) {
         mScore += change;
-        mNetworkAgent.sendNetworkScore(mScore);
+        mNetworkAgent.sendNetworkScore(makeNetworkScore(mScore));
     }
 
     public int getScore() {
@@ -222,7 +227,7 @@
 
     @Override
     public Network getNetwork() {
-        return mNetworkAgent.network;
+        return mNetworkAgent.getNetwork();
     }
 
     public void expectPreventReconnectReceived(long timeoutMs) {
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 7ede144..d6bf334 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -212,7 +212,8 @@
         ArgumentCaptor<Messenger> captor = ArgumentCaptor.forClass(Messenger.class);
 
         // register callback
-        when(mService.requestNetwork(any(), captor.capture(), anyInt(), any(), anyInt()))
+        when(mService.requestNetwork(
+                any(), captor.capture(), anyInt(), any(), anyInt(), any()))
                 .thenReturn(request);
         manager.requestNetwork(request, callback, handler);
 
@@ -240,7 +241,8 @@
         ArgumentCaptor<Messenger> captor = ArgumentCaptor.forClass(Messenger.class);
 
         // register callback
-        when(mService.requestNetwork(any(), captor.capture(), anyInt(), any(), anyInt()))
+        when(mService.requestNetwork(
+                any(), captor.capture(), anyInt(), any(), anyInt(), any()))
                 .thenReturn(req1);
         manager.requestNetwork(req1, callback, handler);
 
@@ -258,7 +260,8 @@
         verify(callback, timeout(100).times(0)).onLosing(any(), anyInt());
 
         // callback can be registered again
-        when(mService.requestNetwork(any(), captor.capture(), anyInt(), any(), anyInt()))
+        when(mService.requestNetwork(
+                any(), captor.capture(), anyInt(), any(), anyInt(), any()))
                 .thenReturn(req2);
         manager.requestNetwork(req2, callback, handler);
 
@@ -282,7 +285,8 @@
         info.targetSdkVersion = VERSION_CODES.N_MR1 + 1;
 
         when(mCtx.getApplicationInfo()).thenReturn(info);
-        when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt())).thenReturn(request);
+        when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any()))
+                .thenReturn(request);
 
         Handler handler = new Handler(Looper.getMainLooper());
         manager.requestNetwork(request, callback, handler);
diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java
index daf187d..91c9a2a 100644
--- a/tests/net/java/android/net/MacAddressTest.java
+++ b/tests/net/java/android/net/MacAddressTest.java
@@ -22,6 +22,8 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.net.util.MacAddressUtils;
+
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -122,11 +124,11 @@
 
         for (MacAddress mac : multicastAddresses) {
             String msg = mac.toString() + " expected to be a multicast address";
-            assertTrue(msg, mac.isMulticastAddress());
+            assertTrue(msg, MacAddressUtils.isMulticastAddress(mac));
         }
         for (MacAddress mac : unicastAddresses) {
             String msg = mac.toString() + " expected not to be a multicast address";
-            assertFalse(msg, mac.isMulticastAddress());
+            assertFalse(msg, MacAddressUtils.isMulticastAddress(mac));
         }
     }
 
@@ -156,7 +158,7 @@
     public void testMacAddressConversions() {
         final int iterations = 10000;
         for (int i = 0; i < iterations; i++) {
-            MacAddress mac = MacAddress.createRandomUnicastAddress();
+            MacAddress mac = MacAddressUtils.createRandomUnicastAddress();
 
             String stringRepr = mac.toString();
             byte[] bytesRepr = mac.toByteArray();
@@ -188,7 +190,7 @@
         final String expectedLocalOui = "26:5f:78";
         final MacAddress base = MacAddress.fromString(anotherOui + ":0:0:0");
         for (int i = 0; i < iterations; i++) {
-            MacAddress mac = MacAddress.createRandomUnicastAddress(base, r);
+            MacAddress mac = MacAddressUtils.createRandomUnicastAddress(base, r);
             String stringRepr = mac.toString();
 
             assertTrue(stringRepr + " expected to be a locally assigned address",
@@ -199,7 +201,7 @@
         }
 
         for (int i = 0; i < iterations; i++) {
-            MacAddress mac = MacAddress.createRandomUnicastAddress();
+            MacAddress mac = MacAddressUtils.createRandomUnicastAddress();
             String stringRepr = mac.toString();
 
             assertTrue(stringRepr + " expected to be a locally assigned address",
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 8da1a5b..968f552 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -107,6 +107,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -305,6 +306,7 @@
     private static final String MOBILE_IFNAME = "test_rmnet_data0";
     private static final String WIFI_IFNAME = "test_wlan0";
     private static final String WIFI_WOL_IFNAME = "test_wlan_wol";
+    private static final String TEST_PACKAGE_NAME = "com.android.test.package";
     private static final String[] EMPTY_STRING_ARRAY = new String[0];
 
     private MockContext mServiceContext;
@@ -633,7 +635,7 @@
                 }
             };
 
-            assertEquals(na.network.netId, nmNetworkCaptor.getValue().netId);
+            assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId);
             mNmCallbacks = nmCbCaptor.getValue();
 
             mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor);
@@ -654,7 +656,7 @@
 
             if (mNmValidationRedirectUrl != null) {
                 mNmCallbacks.showProvisioningNotification(
-                        "test_provisioning_notif_action", "com.android.test.package");
+                        "test_provisioning_notif_action", TEST_PACKAGE_NAME);
                 mNmProvNotificationRequested = true;
             }
         }
@@ -2972,7 +2974,7 @@
             networkCapabilities.addTransportType(TRANSPORT_WIFI)
                     .setNetworkSpecifier(new MatchAllNetworkSpecifier());
             mService.requestNetwork(networkCapabilities, null, 0, null,
-                    ConnectivityManager.TYPE_WIFI);
+                    ConnectivityManager.TYPE_WIFI, TEST_PACKAGE_NAME);
         });
 
         class NonParcelableSpecifier extends NetworkSpecifier {
@@ -3011,31 +3013,12 @@
     }
 
     @Test
-    public void testNetworkSpecifierUidSpoofSecurityException() throws Exception {
-        class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
-            @Override
-            public boolean satisfiedBy(NetworkSpecifier other) {
-                return true;
-            }
-
-            @Override
-            public void assertValidFromUid(int requestorUid) {
-                throw new SecurityException("failure");
-            }
-
-            @Override
-            public int describeContents() { return 0; }
-            @Override
-            public void writeToParcel(Parcel dest, int flags) {}
-        }
-
+    public void testNetworkRequestUidSpoofSecurityException() throws Exception {
         mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);
-
-        UidAwareNetworkSpecifier networkSpecifier = new UidAwareNetworkSpecifier();
-        NetworkRequest networkRequest = newWifiRequestBuilder().setNetworkSpecifier(
-                networkSpecifier).build();
+        NetworkRequest networkRequest = newWifiRequestBuilder().build();
         TestNetworkCallback networkCallback = new TestNetworkCallback();
+        doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString());
         assertThrows(SecurityException.class, () -> {
             mCm.requestNetwork(networkRequest, networkCallback);
         });
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index e863266..25e9057 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -353,8 +353,7 @@
         NetworkCapabilities caps = new NetworkCapabilities();
         caps.addCapability(0);
         caps.addTransportType(transport);
-        NetworkScore ns = new NetworkScore();
-        ns.putIntExtension(NetworkScore.LEGACY_SCORE, 50);
+        NetworkScore ns = new NetworkScore.Builder().setLegacyScore(50).build();
         NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
                 caps, ns, mCtx, null, null /* config */, mConnService, mNetd, mDnsResolver, mNMS,
                 NetworkProvider.ID_NONE);
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index 76e3e2f..39f849c 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -56,7 +56,6 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
-import android.content.pm.PackageList;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.UserInfo;
@@ -72,6 +71,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.LocalServices;
+import com.android.server.pm.PackageList;
 
 import org.junit.Before;
 import org.junit.Test;