Merge "Add to owners"
diff --git a/core/api/current.txt b/core/api/current.txt
index c4bd134..b0d659a 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -24875,6 +24875,7 @@
     method @NonNull public static java.util.Set<java.lang.String> getSupportedAlgorithms();
     method public int getTruncationLengthBits();
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final String AUTH_AES_CMAC = "cmac(aes)";
     field public static final String AUTH_AES_XCBC = "xcbc(aes)";
     field public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
     field public static final String AUTH_CRYPT_CHACHA20_POLY1305 = "rfc7539esp(chacha20,poly1305)";
@@ -25016,6 +25017,16 @@
     field public static final int TYPE_IKEV2_IPSEC_USER_PASS = 6; // 0x6
   }
 
+  public final class Proxy {
+    ctor public Proxy();
+    method @Deprecated public static String getDefaultHost();
+    method @Deprecated public static int getDefaultPort();
+    method @Deprecated public static String getHost(android.content.Context);
+    method @Deprecated public static int getPort(android.content.Context);
+    field @Deprecated public static final String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO";
+    field public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE";
+  }
+
   @Deprecated public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
     ctor @Deprecated public SSLCertificateSocketFactory(int);
     method @Deprecated public java.net.Socket createSocket(java.net.Socket, String, int, boolean) throws java.io.IOException;
@@ -38706,7 +38717,7 @@
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String, android.telecom.PhoneAccountHandle);
-    method public boolean hasCompanionInCallServiceAccess();
+    method public boolean hasManageOngoingCallsPermission();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInCall();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInManagedCall();
     method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle);
@@ -40151,7 +40162,6 @@
     method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
     method @Nullable public android.telephony.CellIdentity getCellIdentity();
     method public int getDomain();
-    method public int getNrState();
     method @Nullable public String getRegisteredPlmn();
     method public int getTransportType();
     method public boolean isRegistered();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index c0e79f6..24adb7d 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -14,10 +14,26 @@
     method public int getResourceId();
   }
 
+  public final class NetworkStateSnapshot implements android.os.Parcelable {
+    ctor public NetworkStateSnapshot(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @Nullable String, int);
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStateSnapshot> CREATOR;
+    field public final int legacyType;
+    field @NonNull public final android.net.LinkProperties linkProperties;
+    field @NonNull public final android.net.Network network;
+    field @NonNull public final android.net.NetworkCapabilities networkCapabilities;
+    field @Nullable public final String subscriberId;
+  }
+
   public class NetworkWatchlistManager {
     method @Nullable public byte[] getWatchlistConfigHash();
   }
 
+  public final class Proxy {
+    method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo);
+  }
+
   public final class UnderlyingNetworkInfo implements android.os.Parcelable {
     ctor public UnderlyingNetworkInfo(int, @NonNull String, @NonNull java.util.List<java.lang.String>);
     method public int describeContents();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index afdf335..d214be3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6056,9 +6056,6 @@
     method public abstract void onRequestScores(android.net.NetworkKey[]);
   }
 
-  public class NetworkReleasedException extends java.lang.Exception {
-  }
-
   public class NetworkScoreManager {
     method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, android.Manifest.permission.REQUEST_NETWORK_SCORES}) public boolean clearScores() throws java.lang.SecurityException;
     method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, android.Manifest.permission.REQUEST_NETWORK_SCORES}) public void disableScoring() throws java.lang.SecurityException;
@@ -6142,47 +6139,6 @@
     method @NonNull public android.net.OemNetworkPreferences.Builder clearNetworkPreference(@NonNull String);
   }
 
-  public abstract class QosCallback {
-    ctor public QosCallback();
-    method public void onError(@NonNull android.net.QosCallbackException);
-    method public void onQosSessionAvailable(@NonNull android.net.QosSession, @NonNull android.net.QosSessionAttributes);
-    method public void onQosSessionLost(@NonNull android.net.QosSession);
-  }
-
-  public static class QosCallback.QosCallbackRegistrationException extends java.lang.RuntimeException {
-  }
-
-  public final class QosCallbackException extends java.lang.Exception {
-  }
-
-  public abstract class QosFilter {
-    method @NonNull public abstract android.net.Network getNetwork();
-    method public abstract boolean matchesLocalAddress(@NonNull java.net.InetAddress, int, int);
-  }
-
-  public final class QosSession implements android.os.Parcelable {
-    ctor public QosSession(int, int);
-    method public int describeContents();
-    method public int getSessionId();
-    method public int getSessionType();
-    method public long getUniqueId();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSession> CREATOR;
-    field public static final int TYPE_EPS_BEARER = 1; // 0x1
-  }
-
-  public interface QosSessionAttributes {
-  }
-
-  public final class QosSocketInfo implements android.os.Parcelable {
-    ctor public QosSocketInfo(@NonNull android.net.Network, @NonNull java.net.Socket) throws java.io.IOException;
-    method public int describeContents();
-    method @NonNull public java.net.InetSocketAddress getLocalSocketAddress();
-    method @NonNull public android.net.Network getNetwork();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSocketInfo> CREATOR;
-  }
-
   public class RssiCurve implements android.os.Parcelable {
     ctor public RssiCurve(int, int, byte[]);
     ctor public RssiCurve(int, int, byte[], int);
@@ -6214,12 +6170,6 @@
     field public final android.net.RssiCurve rssiCurve;
   }
 
-  public class SocketLocalAddressChangedException extends java.lang.Exception {
-  }
-
-  public class SocketNotBoundException extends java.lang.Exception {
-  }
-
   public class TrafficStats {
     method public static void setThreadStatsTagApp();
     method public static void setThreadStatsTagBackup();
@@ -6449,6 +6399,19 @@
 
 }
 
+package android.net.util {
+
+  public final class SocketUtils {
+    method public static void bindSocketToInterface(@NonNull java.io.FileDescriptor, @NonNull String) throws android.system.ErrnoException;
+    method public static void closeSocket(@Nullable java.io.FileDescriptor) throws java.io.IOException;
+    method @NonNull public static java.net.SocketAddress makeNetlinkSocketAddress(int, int);
+    method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int);
+    method @Deprecated @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
+    method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int, @NonNull byte[]);
+  }
+
+}
+
 package android.net.vcn {
 
   public class VcnManager {
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index 0baf11e..dc3b88a 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -19,7 +19,7 @@
 import android.net.DataUsageRequest;
 import android.net.INetworkStatsSession;
 import android.net.Network;
-import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
 import android.net.NetworkStats;
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
@@ -68,7 +68,7 @@
     /** Force update of ifaces. */
     void forceUpdateIfaces(
          in Network[] defaultNetworks,
-         in NetworkState[] networkStates,
+         in NetworkStateSnapshot[] snapshots,
          in String activeIface,
          in UnderlyingNetworkInfo[] underlyingNetworkInfos);
     /** Force update of statistics. */
diff --git a/core/java/android/net/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java
index e89451e..8f1e2de 100644
--- a/core/java/android/net/IpSecAlgorithm.java
+++ b/core/java/android/net/IpSecAlgorithm.java
@@ -146,6 +146,25 @@
     public static final String AUTH_AES_XCBC = "xcbc(aes)";
 
     /**
+     * AES-CMAC Authentication/Integrity Algorithm.
+     *
+     * <p>Keys for this algorithm must be 128 bits in length.
+     *
+     * <p>The only valid truncation length is 96 bits.
+     *
+     * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
+     * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
+     * included in the returned algorithm set. The returned algorithm set will not change unless the
+     * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
+     * requested on an unsupported device.
+     *
+     * <p>@see {@link #getSupportedAlgorithms()}
+     */
+    // This algorithm may be available on devices released before Android 12, and is guaranteed
+    // to be available on devices first shipped with Android 12 or later.
+    public static final String AUTH_AES_CMAC = "cmac(aes)";
+
+    /**
      * AES-GCM Authentication/Integrity + Encryption/Ciphering Algorithm.
      *
      * <p>Valid lengths for keying material are {160, 224, 288}.
@@ -191,6 +210,7 @@
         AUTH_HMAC_SHA384,
         AUTH_HMAC_SHA512,
         AUTH_AES_XCBC,
+        AUTH_AES_CMAC,
         AUTH_CRYPT_AES_GCM,
         AUTH_CRYPT_CHACHA20_POLY1305
     })
@@ -215,6 +235,7 @@
         // STOPSHIP: b/170424293 Use Build.VERSION_CODES.S when it is defined
         ALGO_TO_REQUIRED_FIRST_SDK.put(CRYPT_AES_CTR, Build.VERSION_CODES.R + 1);
         ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_XCBC, Build.VERSION_CODES.R + 1);
+        ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_CMAC, Build.VERSION_CODES.R + 1);
         ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_CRYPT_CHACHA20_POLY1305, Build.VERSION_CODES.R + 1);
     }
 
@@ -383,6 +404,10 @@
                 isValidLen = keyLen == 128;
                 isValidTruncLen = truncLen == 96;
                 break;
+            case AUTH_AES_CMAC:
+                isValidLen = keyLen == 128;
+                isValidTruncLen = truncLen == 96;
+                break;
             case AUTH_CRYPT_AES_GCM:
                 // The keying material for GCM is a key plus a 32-bit salt
                 isValidLen = keyLen == 128 + 32 || keyLen == 192 + 32 || keyLen == 256 + 32;
@@ -416,6 +441,7 @@
             case AUTH_HMAC_SHA384:
             case AUTH_HMAC_SHA512:
             case AUTH_AES_XCBC:
+            case AUTH_AES_CMAC:
                 return true;
             default:
                 return false;
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index 303a407..a5ece7b 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -18,7 +18,6 @@
 
 import static android.net.ConnectivityManager.TYPE_WIFI;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.net.wifi.WifiInfo;
@@ -180,29 +179,42 @@
     }
 
     /**
-     * Build a {@link NetworkIdentity} from the given {@link NetworkState} and {@code subType},
-     * assuming that any mobile networks are using the current IMSI. The subType if applicable,
-     * should be set as one of the TelephonyManager.NETWORK_TYPE_* constants, or
-     * {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
+     * Build a {@link NetworkIdentity} from the given {@link NetworkState} and
+     * {@code subType}, assuming that any mobile networks are using the current IMSI.
+     * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
+     * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
      */
-    public static NetworkIdentity buildNetworkIdentity(Context context, NetworkState state,
-            boolean defaultNetwork, @NetworkType int subType) {
-        final int legacyType = state.legacyNetworkType;
+    // TODO: Delete this function after NetworkPolicyManagerService finishes the migration.
+    public static NetworkIdentity buildNetworkIdentity(Context context,
+            NetworkState state, boolean defaultNetwork, @NetworkType int subType) {
+        final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network,
+                state.networkCapabilities, state.linkProperties, state.subscriberId,
+                state.legacyNetworkType);
+        return buildNetworkIdentity(context, snapshot, defaultNetwork, subType);
+    }
 
-        String subscriberId = null;
+    /**
+     * Build a {@link NetworkIdentity} from the given {@link NetworkStateSnapshot} and
+     * {@code subType}, assuming that any mobile networks are using the current IMSI.
+     * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
+     * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
+     */
+    public static NetworkIdentity buildNetworkIdentity(Context context,
+            NetworkStateSnapshot snapshot, boolean defaultNetwork, @NetworkType int subType) {
+        final int legacyType = snapshot.legacyType;
+
+        final String subscriberId = snapshot.subscriberId;
         String networkId = null;
-        boolean roaming = !state.networkCapabilities.hasCapability(
+        boolean roaming = !snapshot.networkCapabilities.hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
-        boolean metered = !state.networkCapabilities.hasCapability(
+        boolean metered = !snapshot.networkCapabilities.hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
 
-        subscriberId = state.subscriberId;
-
-        final int oemManaged = getOemBitfield(state.networkCapabilities);
+        final int oemManaged = getOemBitfield(snapshot.networkCapabilities);
 
         if (legacyType == TYPE_WIFI) {
-            if (state.networkCapabilities.getSsid() != null) {
-                networkId = state.networkCapabilities.getSsid();
+            if (snapshot.networkCapabilities.getSsid() != null) {
+                networkId = snapshot.networkCapabilities.getSsid();
                 if (networkId == null) {
                     // TODO: Figure out if this code path never runs. If so, remove them.
                     final WifiManager wifi = (WifiManager) context.getSystemService(
diff --git a/core/java/android/net/NetworkStateSnapshot.java b/core/java/android/net/NetworkStateSnapshot.java
index 881b373..b3d8d4e 100644
--- a/core/java/android/net/NetworkStateSnapshot.java
+++ b/core/java/android/net/NetworkStateSnapshot.java
@@ -16,8 +16,11 @@
 
 package android.net;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -28,31 +31,49 @@
  *
  * @hide
  */
+@SystemApi(client = MODULE_LIBRARIES)
 public final class NetworkStateSnapshot implements Parcelable {
-    @NonNull
-    public final LinkProperties linkProperties;
-    @NonNull
-    public final NetworkCapabilities networkCapabilities;
+    /** The network associated with this snapshot. */
     @NonNull
     public final Network network;
+
+    /** The {@link NetworkCapabilities} of the network associated with this snapshot. */
+    @NonNull
+    public final NetworkCapabilities networkCapabilities;
+
+    /** The {@link LinkProperties} of the network associated with this snapshot. */
+    @NonNull
+    public final LinkProperties linkProperties;
+
+    /**
+     * The Subscriber Id of the network associated with this snapshot. See
+     * {@link android.telephony.TelephonyManager#getSubscriberId()}.
+     */
     @Nullable
     public final String subscriberId;
+
+    /**
+     * The legacy type of the network associated with this snapshot. See
+     * {@code ConnectivityManager#TYPE_*}.
+     */
     public final int legacyType;
 
-    public NetworkStateSnapshot(@NonNull LinkProperties linkProperties,
-            @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network,
+    public NetworkStateSnapshot(@NonNull Network network,
+            @NonNull NetworkCapabilities networkCapabilities,
+            @NonNull LinkProperties linkProperties,
             @Nullable String subscriberId, int legacyType) {
-        this.linkProperties = Objects.requireNonNull(linkProperties);
-        this.networkCapabilities = Objects.requireNonNull(networkCapabilities);
         this.network = Objects.requireNonNull(network);
+        this.networkCapabilities = Objects.requireNonNull(networkCapabilities);
+        this.linkProperties = Objects.requireNonNull(linkProperties);
         this.subscriberId = subscriberId;
         this.legacyType = legacyType;
     }
 
+    /** @hide */
     public NetworkStateSnapshot(@NonNull Parcel in) {
-        linkProperties = in.readParcelable(null);
-        networkCapabilities = in.readParcelable(null);
         network = in.readParcelable(null);
+        networkCapabilities = in.readParcelable(null);
+        linkProperties = in.readParcelable(null);
         subscriberId = in.readString();
         legacyType = in.readInt();
     }
@@ -64,9 +85,9 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel out, int flags) {
-        out.writeParcelable(linkProperties, flags);
-        out.writeParcelable(networkCapabilities, flags);
         out.writeParcelable(network, flags);
+        out.writeParcelable(networkCapabilities, flags);
+        out.writeParcelable(linkProperties, flags);
         out.writeString(subscriberId);
         out.writeInt(legacyType);
     }
@@ -93,14 +114,14 @@
         if (!(o instanceof NetworkStateSnapshot)) return false;
         NetworkStateSnapshot that = (NetworkStateSnapshot) o;
         return legacyType == that.legacyType
-                && Objects.equals(linkProperties, that.linkProperties)
-                && Objects.equals(networkCapabilities, that.networkCapabilities)
                 && Objects.equals(network, that.network)
+                && Objects.equals(networkCapabilities, that.networkCapabilities)
+                && Objects.equals(linkProperties, that.linkProperties)
                 && Objects.equals(subscriberId, that.subscriberId);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(linkProperties, networkCapabilities, network, subscriberId, legacyType);
+        return Objects.hash(network, networkCapabilities, linkProperties, subscriberId, legacyType);
     }
 }
diff --git a/packages/Connectivity/framework/src/android/net/PacProxySelector.java b/core/java/android/net/PacProxySelector.java
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/PacProxySelector.java
rename to core/java/android/net/PacProxySelector.java
diff --git a/packages/Connectivity/framework/src/android/net/Proxy.java b/core/java/android/net/Proxy.java
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/Proxy.java
rename to core/java/android/net/Proxy.java
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index f90fbaf..fa3ff8a 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -41,6 +41,7 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 
+import com.android.internal.net.NetworkUtilsInternal;
 import com.android.internal.net.VpnConfig;
 
 import java.net.DatagramSocket;
@@ -254,7 +255,7 @@
      * @return {@code true} on success.
      */
     public boolean protect(int socket) {
-        return NetworkUtils.protectFromVpn(socket);
+        return NetworkUtilsInternal.protectFromVpn(socket);
     }
 
     /**
diff --git a/packages/Connectivity/framework/src/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java
similarity index 97%
rename from packages/Connectivity/framework/src/android/net/util/SocketUtils.java
rename to core/java/android/net/util/SocketUtils.java
index e64060f..69edc75 100644
--- a/packages/Connectivity/framework/src/android/net/util/SocketUtils.java
+++ b/core/java/android/net/util/SocketUtils.java
@@ -22,12 +22,13 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
-import android.net.NetworkUtils;
 import android.system.ErrnoException;
 import android.system.NetlinkSocketAddress;
 import android.system.Os;
 import android.system.PacketSocketAddress;
 
+import com.android.internal.net.NetworkUtilsInternal;
+
 import libcore.io.IoBridge;
 
 import java.io.FileDescriptor;
@@ -51,7 +52,7 @@
         // of struct ifreq is a NULL-terminated interface name.
         // TODO: add a setsockoptString()
         Os.setsockoptIfreq(socket, SOL_SOCKET, SO_BINDTODEVICE, iface);
-        NetworkUtils.protectFromVpn(socket);
+        NetworkUtilsInternal.protectFromVpn(socket);
     }
 
     /**
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java b/core/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java
new file mode 100644
index 0000000..6bbc6b1
--- /dev/null
+++ b/core/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2021 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.vcn.persistablebundleutils;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility;
+
+import android.annotation.NonNull;
+import android.net.InetAddresses;
+import android.net.ipsec.ike.IkeTrafficSelector;
+import android.os.PersistableBundle;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Objects;
+
+/**
+ * Provides utility methods to convert IkeTrafficSelector to/from PersistableBundle.
+ *
+ * @hide
+ */
+@VisibleForTesting(visibility = Visibility.PRIVATE)
+public final class IkeTrafficSelectorUtils {
+    private static final String START_PORT_KEY = "START_PORT_KEY";
+    private static final String END_PORT_KEY = "END_PORT_KEY";
+    private static final String START_ADDRESS_KEY = "START_ADDRESS_KEY";
+    private static final String END_ADDRESS_KEY = "END_ADDRESS_KEY";
+
+    /** Constructs an IkeTrafficSelector by deserializing a PersistableBundle. */
+    @NonNull
+    public static IkeTrafficSelector fromPersistableBundle(@NonNull PersistableBundle in) {
+        Objects.requireNonNull(in, "PersistableBundle was null");
+
+        final int startPort = in.getInt(START_PORT_KEY);
+        final int endPort = in.getInt(END_PORT_KEY);
+
+        final String startingAddress = in.getString(START_ADDRESS_KEY);
+        final String endingAddress = in.getString(END_ADDRESS_KEY);
+        Objects.requireNonNull(startingAddress, "startAddress was null");
+        Objects.requireNonNull(startingAddress, "endAddress was null");
+
+        return new IkeTrafficSelector(
+                startPort,
+                endPort,
+                InetAddresses.parseNumericAddress(startingAddress),
+                InetAddresses.parseNumericAddress(endingAddress));
+    }
+
+    /** Serializes an IkeTrafficSelector to a PersistableBundle. */
+    @NonNull
+    public static PersistableBundle toPersistableBundle(@NonNull IkeTrafficSelector ts) {
+        final PersistableBundle result = new PersistableBundle();
+
+        result.putInt(START_PORT_KEY, ts.startPort);
+        result.putInt(END_PORT_KEY, ts.endPort);
+        result.putString(START_ADDRESS_KEY, ts.startingAddress.getHostAddress());
+        result.putString(END_ADDRESS_KEY, ts.endingAddress.getHostAddress());
+
+        return result;
+    }
+}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 874add5..91d6a9b 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -23,7 +23,6 @@
 import android.net.Network;
 import android.net.NetworkStats;
 import android.net.RouteInfo;
-import android.net.UidRange;
 
 /**
  * @hide
@@ -182,11 +181,6 @@
     String[] listTetheredInterfaces();
 
     /**
-     * Sets the list of DNS forwarders (in order of priority)
-     */
-    void setDnsForwarders(in Network network, in String[] dns);
-
-    /**
      * Returns the list of DNS forwarders (in order of priority)
      */
     String[] getDnsForwarders();
@@ -300,8 +294,6 @@
     void setFirewallUidRules(int chain, in int[] uids, in int[] rules);
     void setFirewallChainEnabled(int chain, boolean enable);
 
-    void addLegacyRouteForNetId(int netId, in RouteInfo routeInfo, int uid);
-
     /**
      * Allow UID to call protect().
      */
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index c9da641..9ffc5aa0 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -657,16 +657,8 @@
         argsForZygote.add("--runtime-flags=" + runtimeFlags);
         if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
             argsForZygote.add("--mount-external-default");
-        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
-            argsForZygote.add("--mount-external-read");
-        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
-            argsForZygote.add("--mount-external-write");
-        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {
-            argsForZygote.add("--mount-external-full");
         } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
             argsForZygote.add("--mount-external-installer");
-        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
-            argsForZygote.add("--mount-external-legacy");
         } else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
             argsForZygote.add("--mount-external-pass-through");
         } else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index c43c410..a86984f 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -57,6 +57,7 @@
 per-file ViewRootImpl.java = file:/services/core/java/com/android/server/input/OWNERS
 per-file ViewRootImpl.java = file:/services/core/java/com/android/server/wm/OWNERS
 per-file ViewRootImpl.java = file:/core/java/android/view/inputmethod/OWNERS
+per-file AccessibilityInteractionController.java = file:/services/accessibility/OWNERS
 
 # WindowManager
 per-file DisplayCutout.aidl = file:/services/core/java/com/android/server/wm/OWNERS
diff --git a/core/java/com/android/internal/net/NetworkUtilsInternal.java b/core/java/com/android/internal/net/NetworkUtilsInternal.java
index 571d7e7..052959a 100644
--- a/core/java/com/android/internal/net/NetworkUtilsInternal.java
+++ b/core/java/com/android/internal/net/NetworkUtilsInternal.java
@@ -22,6 +22,8 @@
 import android.annotation.NonNull;
 import android.system.Os;
 
+import java.io.FileDescriptor;
+
 /** @hide */
 public class NetworkUtilsInternal {
 
@@ -36,6 +38,20 @@
     public static native void setAllowNetworkingForProcess(boolean allowNetworking);
 
     /**
+     * Protect {@code fd} from VPN connections.  After protecting, data sent through
+     * this socket will go directly to the underlying network, so its traffic will not be
+     * forwarded through the VPN.
+     */
+    public static native boolean protectFromVpn(FileDescriptor fd);
+
+    /**
+     * Protect {@code socketfd} from VPN connections.  After protecting, data sent through
+     * this socket will go directly to the underlying network, so its traffic will not be
+     * forwarded through the VPN.
+     */
+    public static native boolean protectFromVpn(int socketfd);
+
+    /**
      * Returns true if the hostname is weakly validated.
      * @param hostname Name of host to validate.
      * @return True if it's a valid-ish hostname.
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index d99f305..1c4e4a2 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -179,23 +179,11 @@
     public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
     /** Default external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_DEFAULT = IVold.REMOUNT_MODE_DEFAULT;
-    /** Read-only external storage should be mounted. */
-    public static final int MOUNT_EXTERNAL_READ = IVold.REMOUNT_MODE_READ;
-    /** Read-write external storage should be mounted. */
-    public static final int MOUNT_EXTERNAL_WRITE = IVold.REMOUNT_MODE_WRITE;
-    /**
-     * Mount mode for apps that are already installed on the device before the isolated_storage
-     * feature is enabled.
-     */
-    public static final int MOUNT_EXTERNAL_LEGACY = IVold.REMOUNT_MODE_LEGACY;
     /**
      * Mount mode for package installers which should give them access to
      * all obb dirs in addition to their package sandboxes
      */
     public static final int MOUNT_EXTERNAL_INSTALLER = IVold.REMOUNT_MODE_INSTALLER;
-    /** Read-write external storage should be mounted instead of package sandbox */
-    public static final int MOUNT_EXTERNAL_FULL = IVold.REMOUNT_MODE_FULL;
-
     /** The lower file system should be bind mounted directly on external storage */
     public static final int MOUNT_EXTERNAL_PASS_THROUGH = IVold.REMOUNT_MODE_PASS_THROUGH;
 
diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java
index 5a1c171..65b454d 100644
--- a/core/java/com/android/internal/os/ZygoteArguments.java
+++ b/core/java/com/android/internal/os/ZygoteArguments.java
@@ -395,16 +395,8 @@
                 mNiceName = getAssignmentValue(arg);
             } else if (arg.equals("--mount-external-default")) {
                 mMountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
-            } else if (arg.equals("--mount-external-read")) {
-                mMountExternal = Zygote.MOUNT_EXTERNAL_READ;
-            } else if (arg.equals("--mount-external-write")) {
-                mMountExternal = Zygote.MOUNT_EXTERNAL_WRITE;
-            } else if (arg.equals("--mount-external-full")) {
-                mMountExternal = Zygote.MOUNT_EXTERNAL_FULL;
-            }  else if (arg.equals("--mount-external-installer")) {
+            } else if (arg.equals("--mount-external-installer")) {
                 mMountExternal = Zygote.MOUNT_EXTERNAL_INSTALLER;
-            }  else if (arg.equals("--mount-external-legacy")) {
-                mMountExternal = Zygote.MOUNT_EXTERNAL_LEGACY;
             } else if (arg.equals("--mount-external-pass-through")) {
                 mMountExternal = Zygote.MOUNT_EXTERNAL_PASS_THROUGH;
             } else if (arg.equals("--mount-external-android-writable")) {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index e58ad79..afd19b6 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -149,7 +149,7 @@
                 "android_os_VintfRuntimeInfo.cpp",
                 "android_os_incremental_IncrementalManager.cpp",
                 "android_net_LocalSocketImpl.cpp",
-                "android_net_NetUtils.cpp",
+                "android_net_NetworkUtils.cpp",
                 "android_service_DataLoaderService.cpp",
                 "android_util_AssetManager.cpp",
                 "android_util_Binder.cpp",
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetworkUtils.cpp
similarity index 94%
rename from core/jni/android_net_NetUtils.cpp
rename to core/jni/android_net_NetworkUtils.cpp
index e2af87e..7508108 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetworkUtils.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "NetUtils"
+#define LOG_TAG "NetworkUtils"
 
 #include <vector>
 
@@ -123,15 +123,6 @@
     return setNetworkForSocket(netId, AFileDescriptor_getFD(env, javaFd));
 }
 
-static jboolean android_net_utils_protectFromVpn(JNIEnv *env, jobject thiz, jint socket)
-{
-    return (jboolean) !protectFromVpn(socket);
-}
-
-static jboolean android_net_utils_protectFromVpnWithFd(JNIEnv *env, jobject thiz, jobject javaFd) {
-    return android_net_utils_protectFromVpn(env, thiz, AFileDescriptor_getFD(env, javaFd));
-}
-
 static jboolean android_net_utils_queryUserAccess(JNIEnv *env, jobject thiz, jint uid, jint netId)
 {
     return (jboolean) !queryUserAccess(uid, netId);
@@ -276,8 +267,6 @@
     { "getBoundNetworkForProcess", "()I", (void*) android_net_utils_getBoundNetworkForProcess },
     { "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
     { "bindSocketToNetwork", "(Ljava/io/FileDescriptor;I)I", (void*) android_net_utils_bindSocketToNetwork },
-    { "protectFromVpn", "(I)Z", (void*) android_net_utils_protectFromVpn },
-    { "protectFromVpn", "(Ljava/io/FileDescriptor;)Z", (void*) android_net_utils_protectFromVpnWithFd },
     { "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess },
     { "attachDropAllBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDropAllBPFFilter },
     { "detachBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_detachBPFFilter },
diff --git a/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp b/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
index 10fc18d..980e12d 100644
--- a/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
+++ b/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <android/file_descriptor_jni.h>
+
 #include "NetdClient.h"
 #include "core_jni_helpers.h"
 #include "jni.h"
@@ -24,9 +26,20 @@
     setAllowNetworkingForProcess(hasConnectivity == JNI_TRUE);
 }
 
+static jboolean android_net_utils_protectFromVpn(JNIEnv *env, jobject thiz, jint socket) {
+    return (jboolean)!protectFromVpn(socket);
+}
+
+static jboolean android_net_utils_protectFromVpnWithFd(JNIEnv *env, jobject thiz, jobject javaFd) {
+    return android_net_utils_protectFromVpn(env, thiz, AFileDescriptor_getFD(env, javaFd));
+}
+
 static const JNINativeMethod gNetworkUtilMethods[] = {
         {"setAllowNetworkingForProcess", "(Z)V",
          (void *)android_net_utils_setAllowNetworkingForProcess},
+        {"protectFromVpn", "(I)Z", (void *)android_net_utils_protectFromVpn},
+        {"protectFromVpn", "(Ljava/io/FileDescriptor;)Z",
+         (void *)android_net_utils_protectFromVpnWithFd},
 };
 
 int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv *env) {
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index bcd203b..c9062d8 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -115,7 +115,6 @@
 static pid_t gSystemServerPid = 0;
 
 static constexpr const char* kVoldAppDataIsolation = "persist.sys.vold_app_data_isolation_enabled";
-static constexpr const char* kPropFuse = "persist.sys.fuse";
 static const char kZygoteClassName[] = "com/android/internal/os/Zygote";
 static jclass gZygoteClass;
 static jmethodID gCallPostForkSystemServerHooks;
@@ -305,31 +304,15 @@
 static FileDescriptorTable* gOpenFdTable = nullptr;
 
 // Must match values in com.android.internal.os.Zygote.
-// The order of entries here must be kept in sync with ExternalStorageViews array values.
+// Note that there are gaps in the constants:
+// This is to further keep the values consistent with IVold.aidl
 enum MountExternalKind {
-  MOUNT_EXTERNAL_NONE = 0,
-  MOUNT_EXTERNAL_DEFAULT = 1,
-  MOUNT_EXTERNAL_READ = 2,
-  MOUNT_EXTERNAL_WRITE = 3,
-  MOUNT_EXTERNAL_LEGACY = 4,
-  MOUNT_EXTERNAL_INSTALLER = 5,
-  MOUNT_EXTERNAL_FULL = 6,
-  MOUNT_EXTERNAL_PASS_THROUGH = 7,
-  MOUNT_EXTERNAL_ANDROID_WRITABLE = 8,
-  MOUNT_EXTERNAL_COUNT = 9
-};
-
-// The order of entries here must be kept in sync with MountExternalKind enum values.
-static const std::array<const std::string, MOUNT_EXTERNAL_COUNT> ExternalStorageViews = {
-  "",                     // MOUNT_EXTERNAL_NONE
-  "/mnt/runtime/default", // MOUNT_EXTERNAL_DEFAULT
-  "/mnt/runtime/read",    // MOUNT_EXTERNAL_READ
-  "/mnt/runtime/write",   // MOUNT_EXTERNAL_WRITE
-  "/mnt/runtime/write",   // MOUNT_EXTERNAL_LEGACY
-  "/mnt/runtime/write",   // MOUNT_EXTERNAL_INSTALLER
-  "/mnt/runtime/full",    // MOUNT_EXTERNAL_FULL
-  "/mnt/runtime/full",    // MOUNT_EXTERNAL_PASS_THROUGH (only used w/ FUSE)
-  "/mnt/runtime/full",    // MOUNT_EXTERNAL_ANDROID_WRITABLE (only used w/ FUSE)
+    MOUNT_EXTERNAL_NONE = 0,
+    MOUNT_EXTERNAL_DEFAULT = 1,
+    MOUNT_EXTERNAL_INSTALLER = 5,
+    MOUNT_EXTERNAL_PASS_THROUGH = 7,
+    MOUNT_EXTERNAL_ANDROID_WRITABLE = 8,
+    MOUNT_EXTERNAL_COUNT = 9
 };
 
 // Must match values in com.android.internal.os.Zygote.
@@ -832,29 +815,20 @@
   PrepareDir(user_source, 0710, user_id ? AID_ROOT : AID_SHELL,
              multiuser_get_uid(user_id, AID_EVERYBODY), fail_fn);
 
-  bool isFuse = GetBoolProperty(kPropFuse, false);
   bool isAppDataIsolationEnabled = GetBoolProperty(kVoldAppDataIsolation, false);
 
-  if (isFuse) {
-    if (mount_mode == MOUNT_EXTERNAL_PASS_THROUGH) {
+  if (mount_mode == MOUNT_EXTERNAL_PASS_THROUGH) {
       const std::string pass_through_source = StringPrintf("/mnt/pass_through/%d", user_id);
       PrepareDir(pass_through_source, 0710, AID_ROOT, AID_MEDIA_RW, fail_fn);
       BindMount(pass_through_source, "/storage", fail_fn);
-    } else if (mount_mode == MOUNT_EXTERNAL_INSTALLER) {
+  } else if (mount_mode == MOUNT_EXTERNAL_INSTALLER) {
       const std::string installer_source = StringPrintf("/mnt/installer/%d", user_id);
       BindMount(installer_source, "/storage", fail_fn);
-    } else if (isAppDataIsolationEnabled && mount_mode == MOUNT_EXTERNAL_ANDROID_WRITABLE) {
+  } else if (isAppDataIsolationEnabled && mount_mode == MOUNT_EXTERNAL_ANDROID_WRITABLE) {
       const std::string writable_source = StringPrintf("/mnt/androidwritable/%d", user_id);
       BindMount(writable_source, "/storage", fail_fn);
-    } else {
-      BindMount(user_source, "/storage", fail_fn);
-    }
   } else {
-    const std::string& storage_source = ExternalStorageViews[mount_mode];
-    BindMount(storage_source, "/storage", fail_fn);
-
-    // Mount user-specific symlink helper into place
-    BindMount(user_source, "/storage/self", fail_fn);
+      BindMount(user_source, "/storage", fail_fn);
   }
 }
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 93758b6..22a79ed 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1691,7 +1691,7 @@
              * SDK level 28 makes the following algorithms mandatory : "cbc(aes)", "hmac(md5)",
                "hmac(sha1)", "hmac(sha256)", "hmac(sha384)", "hmac(sha512)", "rfc4106(gcm(aes))"
              * SDK level 31 makes the following algorithms mandatory : "rfc3686(ctr(aes))",
-               "xcbc(aes)", "rfc7539esp(chacha20,poly1305)"
+               "xcbc(aes)", "cmac(aes)", "rfc7539esp(chacha20,poly1305)"
      -->
     <string-array name="config_optionalIpSecAlgorithms" translatable="false">
         <!-- Add algorithm here -->
diff --git a/core/tests/coretests/src/android/view/accessibility/OWNERS b/core/tests/coretests/src/android/view/accessibility/OWNERS
new file mode 100644
index 0000000..b74281e
--- /dev/null
+++ b/core/tests/coretests/src/android/view/accessibility/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/accessibility/OWNERS
diff --git a/core/java/android/net/QosFilterParcelable.aidl b/packages/Connectivity/framework/aidl-export/android/net/QosFilterParcelable.aidl
similarity index 100%
rename from core/java/android/net/QosFilterParcelable.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/QosFilterParcelable.aidl
diff --git a/core/java/android/net/QosSession.aidl b/packages/Connectivity/framework/aidl-export/android/net/QosSession.aidl
similarity index 100%
rename from core/java/android/net/QosSession.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/QosSession.aidl
diff --git a/core/java/android/net/QosSocketInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/QosSocketInfo.aidl
similarity index 100%
rename from core/java/android/net/QosSocketInfo.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/QosSocketInfo.aidl
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
index d4262a8..4bfcda3 100644
--- a/packages/Connectivity/framework/api/current.txt
+++ b/packages/Connectivity/framework/api/current.txt
@@ -400,16 +400,6 @@
     method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
   }
 
-  public final class Proxy {
-    ctor public Proxy();
-    method @Deprecated public static String getDefaultHost();
-    method @Deprecated public static int getDefaultPort();
-    method @Deprecated public static String getHost(android.content.Context);
-    method @Deprecated public static int getPort(android.content.Context);
-    field @Deprecated public static final String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO";
-    field public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE";
-  }
-
   public class ProxyInfo implements android.os.Parcelable {
     ctor public ProxyInfo(@Nullable android.net.ProxyInfo);
     method public static android.net.ProxyInfo buildDirectProxy(String, int);
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index 3af855e..a9fd6f2 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -23,10 +23,6 @@
     field public static final int TRANSPORT_TEST = 7; // 0x7
   }
 
-  public final class Proxy {
-    method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo);
-  }
-
   public final class TcpRepairWindow {
     ctor public TcpRepairWindow(int, int, int, int, int, int);
     field public final int maxWindow;
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index 41ebc57..373fa3c 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -308,6 +308,9 @@
     field public static final int ID_NONE = -1; // 0xffffffff
   }
 
+  public class NetworkReleasedException extends java.lang.Exception {
+  }
+
   public class NetworkRequest implements android.os.Parcelable {
     method @Nullable public String getRequestorPackageName();
     method public int getRequestorUid();
@@ -317,6 +320,47 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
   }
 
+  public abstract class QosCallback {
+    ctor public QosCallback();
+    method public void onError(@NonNull android.net.QosCallbackException);
+    method public void onQosSessionAvailable(@NonNull android.net.QosSession, @NonNull android.net.QosSessionAttributes);
+    method public void onQosSessionLost(@NonNull android.net.QosSession);
+  }
+
+  public static class QosCallback.QosCallbackRegistrationException extends java.lang.RuntimeException {
+  }
+
+  public final class QosCallbackException extends java.lang.Exception {
+  }
+
+  public abstract class QosFilter {
+    method @NonNull public abstract android.net.Network getNetwork();
+    method public abstract boolean matchesLocalAddress(@NonNull java.net.InetAddress, int, int);
+  }
+
+  public final class QosSession implements android.os.Parcelable {
+    ctor public QosSession(int, int);
+    method public int describeContents();
+    method public int getSessionId();
+    method public int getSessionType();
+    method public long getUniqueId();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSession> CREATOR;
+    field public static final int TYPE_EPS_BEARER = 1; // 0x1
+  }
+
+  public interface QosSessionAttributes {
+  }
+
+  public final class QosSocketInfo implements android.os.Parcelable {
+    ctor public QosSocketInfo(@NonNull android.net.Network, @NonNull java.net.Socket) throws java.io.IOException;
+    method public int describeContents();
+    method @NonNull public java.net.InetSocketAddress getLocalSocketAddress();
+    method @NonNull public android.net.Network getNetwork();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSocketInfo> CREATOR;
+  }
+
   public final class RouteInfo implements android.os.Parcelable {
     ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int);
     ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int, int);
@@ -331,6 +375,12 @@
     field public static final int SUCCESS = 0; // 0x0
   }
 
+  public class SocketLocalAddressChangedException extends java.lang.Exception {
+  }
+
+  public class SocketNotBoundException extends java.lang.Exception {
+  }
+
   public final class StaticIpConfiguration implements android.os.Parcelable {
     ctor public StaticIpConfiguration();
     ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
@@ -392,16 +442,3 @@
 
 }
 
-package android.net.util {
-
-  public final class SocketUtils {
-    method public static void bindSocketToInterface(@NonNull java.io.FileDescriptor, @NonNull String) throws android.system.ErrnoException;
-    method public static void closeSocket(@Nullable java.io.FileDescriptor) throws java.io.IOException;
-    method @NonNull public static java.net.SocketAddress makeNetlinkSocketAddress(int, int);
-    method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int);
-    method @Deprecated @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
-    method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int, @NonNull byte[]);
-  }
-
-}
-
diff --git a/core/java/android/net/IOnSetOemNetworkPreferenceListener.aidl b/packages/Connectivity/framework/src/android/net/IOnSetOemNetworkPreferenceListener.aidl
similarity index 100%
rename from core/java/android/net/IOnSetOemNetworkPreferenceListener.aidl
rename to packages/Connectivity/framework/src/android/net/IOnSetOemNetworkPreferenceListener.aidl
diff --git a/core/java/android/net/IQosCallback.aidl b/packages/Connectivity/framework/src/android/net/IQosCallback.aidl
similarity index 100%
rename from core/java/android/net/IQosCallback.aidl
rename to packages/Connectivity/framework/src/android/net/IQosCallback.aidl
diff --git a/core/java/android/net/NetworkReleasedException.java b/packages/Connectivity/framework/src/android/net/NetworkReleasedException.java
similarity index 100%
rename from core/java/android/net/NetworkReleasedException.java
rename to packages/Connectivity/framework/src/android/net/NetworkReleasedException.java
diff --git a/packages/Connectivity/framework/src/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
index b5e8a61..9e42bbe 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkUtils.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
@@ -87,22 +87,6 @@
     public static native int bindSocketToNetwork(FileDescriptor fd, int netId);
 
     /**
-     * Protect {@code fd} from VPN connections.  After protecting, data sent through
-     * this socket will go directly to the underlying network, so its traffic will not be
-     * forwarded through the VPN.
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553,
-            publicAlternatives = "Use {@link android.net.VpnService#protect} instead.")
-    public static native boolean protectFromVpn(FileDescriptor fd);
-
-    /**
-     * Protect {@code socketfd} from VPN connections.  After protecting, data sent through
-     * this socket will go directly to the underlying network, so its traffic will not be
-     * forwarded through the VPN.
-     */
-    public native static boolean protectFromVpn(int socketfd);
-
-    /**
      * Determine if {@code uid} can access network designated by {@code netId}.
      * @return {@code true} if {@code uid} can access network, {@code false} otherwise.
      */
diff --git a/core/java/android/net/QosCallback.java b/packages/Connectivity/framework/src/android/net/QosCallback.java
similarity index 100%
rename from core/java/android/net/QosCallback.java
rename to packages/Connectivity/framework/src/android/net/QosCallback.java
diff --git a/core/java/android/net/QosCallbackConnection.java b/packages/Connectivity/framework/src/android/net/QosCallbackConnection.java
similarity index 100%
rename from core/java/android/net/QosCallbackConnection.java
rename to packages/Connectivity/framework/src/android/net/QosCallbackConnection.java
diff --git a/core/java/android/net/QosCallbackException.java b/packages/Connectivity/framework/src/android/net/QosCallbackException.java
similarity index 100%
rename from core/java/android/net/QosCallbackException.java
rename to packages/Connectivity/framework/src/android/net/QosCallbackException.java
diff --git a/core/java/android/net/QosFilter.java b/packages/Connectivity/framework/src/android/net/QosFilter.java
similarity index 100%
rename from core/java/android/net/QosFilter.java
rename to packages/Connectivity/framework/src/android/net/QosFilter.java
diff --git a/core/java/android/net/QosFilterParcelable.java b/packages/Connectivity/framework/src/android/net/QosFilterParcelable.java
similarity index 100%
rename from core/java/android/net/QosFilterParcelable.java
rename to packages/Connectivity/framework/src/android/net/QosFilterParcelable.java
diff --git a/core/java/android/net/QosSession.java b/packages/Connectivity/framework/src/android/net/QosSession.java
similarity index 100%
rename from core/java/android/net/QosSession.java
rename to packages/Connectivity/framework/src/android/net/QosSession.java
diff --git a/core/java/android/net/QosSessionAttributes.java b/packages/Connectivity/framework/src/android/net/QosSessionAttributes.java
similarity index 100%
rename from core/java/android/net/QosSessionAttributes.java
rename to packages/Connectivity/framework/src/android/net/QosSessionAttributes.java
diff --git a/core/java/android/net/QosSocketFilter.java b/packages/Connectivity/framework/src/android/net/QosSocketFilter.java
similarity index 100%
rename from core/java/android/net/QosSocketFilter.java
rename to packages/Connectivity/framework/src/android/net/QosSocketFilter.java
diff --git a/core/java/android/net/QosSocketInfo.java b/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
similarity index 100%
rename from core/java/android/net/QosSocketInfo.java
rename to packages/Connectivity/framework/src/android/net/QosSocketInfo.java
diff --git a/core/java/android/net/SocketLocalAddressChangedException.java b/packages/Connectivity/framework/src/android/net/SocketLocalAddressChangedException.java
similarity index 100%
rename from core/java/android/net/SocketLocalAddressChangedException.java
rename to packages/Connectivity/framework/src/android/net/SocketLocalAddressChangedException.java
diff --git a/core/java/android/net/SocketNotBoundException.java b/packages/Connectivity/framework/src/android/net/SocketNotBoundException.java
similarity index 100%
rename from core/java/android/net/SocketNotBoundException.java
rename to packages/Connectivity/framework/src/android/net/SocketNotBoundException.java
diff --git a/core/java/android/net/UidRange.aidl b/packages/Connectivity/framework/src/android/net/UidRange.aidl
similarity index 100%
rename from core/java/android/net/UidRange.aidl
rename to packages/Connectivity/framework/src/android/net/UidRange.aidl
diff --git a/core/java/android/net/UidRange.java b/packages/Connectivity/framework/src/android/net/UidRange.java
similarity index 86%
rename from core/java/android/net/UidRange.java
rename to packages/Connectivity/framework/src/android/net/UidRange.java
index f0e7da7..26518d3 100644
--- a/core/java/android/net/UidRange.java
+++ b/packages/Connectivity/framework/src/android/net/UidRange.java
@@ -16,8 +16,6 @@
 
 package android.net;
 
-import static android.os.UserHandle.PER_USER_RANGE;
-
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -52,14 +50,15 @@
 
     /** Returns the smallest user Id which is contained in this UidRange */
     public int getStartUser() {
-        return start / PER_USER_RANGE;
+        return UserHandle.getUserHandleForUid(start).getIdentifier();
     }
 
     /** Returns the largest user Id which is contained in this UidRange */
     public int getEndUser() {
-        return stop / PER_USER_RANGE;
+        return UserHandle.getUserHandleForUid(stop).getIdentifier();
     }
 
+    /** Returns whether the UidRange contains the specified UID. */
     public boolean contains(int uid) {
         return start <= uid && uid <= stop;
     }
@@ -72,7 +71,7 @@
     }
 
     /**
-     * @return {@code true} if this range contains every UID contained by the {@param other} range.
+     * @return {@code true} if this range contains every UID contained by the {@code other} range.
      */
     public boolean containsRange(UidRange other) {
         return start <= other.start && other.stop <= stop;
@@ -118,18 +117,18 @@
     }
 
     public static final @android.annotation.NonNull Creator<UidRange> CREATOR =
-        new Creator<UidRange>() {
-            @Override
-            public UidRange createFromParcel(Parcel in) {
-                int start = in.readInt();
-                int stop = in.readInt();
+            new Creator<UidRange>() {
+        @Override
+        public UidRange createFromParcel(Parcel in) {
+            int start = in.readInt();
+            int stop = in.readInt();
 
-                return new UidRange(start, stop);
-            }
-            @Override
-            public UidRange[] newArray(int size) {
-                return new UidRange[size];
-            }
+            return new UidRange(start, stop);
+        }
+        @Override
+        public UidRange[] newArray(int size) {
+            return new UidRange[size];
+        }
     };
 
     /**
diff --git a/packages/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp
index f20b89f..e65b7b4 100644
--- a/packages/Connectivity/service/Android.bp
+++ b/packages/Connectivity/service/Android.bp
@@ -63,6 +63,7 @@
         "unsupportedappusage",
     ],
     static_libs: [
+        "modules-utils-os",
         "net-utils-device-common",
         "net-utils-framework-common",
         "netd-client",
diff --git a/packages/Connectivity/service/jarjar-rules.txt b/packages/Connectivity/service/jarjar-rules.txt
index ef53ebb..d8205bf 100644
--- a/packages/Connectivity/service/jarjar-rules.txt
+++ b/packages/Connectivity/service/jarjar-rules.txt
@@ -1 +1,2 @@
-rule com.android.net.module.util.** com.android.connectivity.util.@1
\ No newline at end of file
+rule com.android.net.module.util.** com.android.connectivity.net-utils.@1
+rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1
\ No newline at end of file
diff --git a/services/api/Android.bp b/services/api/Android.bp
index b8ca548..bbc8c72 100644
--- a/services/api/Android.bp
+++ b/services/api/Android.bp
@@ -14,6 +14,12 @@
 
 package {
     default_visibility: ["//visibility:private"],
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
 }
 
 filegroup {
@@ -26,4 +32,4 @@
     name: "non-updatable-system-server-removed.txt",
     srcs: ["non-updatable-removed.txt"],
     visibility: ["//frameworks/base/api"],
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 542d527..82d6065 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -120,6 +120,7 @@
 import android.net.NetworkStack;
 import android.net.NetworkStackClient;
 import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
 import android.net.NetworkTestResultParcelable;
 import android.net.NetworkUtils;
 import android.net.NetworkWatchlistManager;
@@ -155,7 +156,6 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
@@ -324,7 +324,6 @@
     // 0 is full bad, 100 is full good
     private int mDefaultInetConditionPublished = 0;
 
-    private INetworkManagementService mNMS;
     @VisibleForTesting
     protected IDnsResolver mDnsResolver;
     @VisibleForTesting
@@ -1040,15 +1039,14 @@
         }
     }
 
-    public ConnectivityService(Context context, INetworkManagementService netManager,
-            INetworkStatsService statsService) {
-        this(context, netManager, statsService, getDnsResolver(context), new IpConnectivityLog(),
+    public ConnectivityService(Context context, INetworkStatsService statsService) {
+        this(context, statsService, getDnsResolver(context), new IpConnectivityLog(),
                 NetdService.getInstance(), new Dependencies());
     }
 
     @VisibleForTesting
-    protected ConnectivityService(Context context, INetworkManagementService netManager,
-            INetworkStatsService statsService, IDnsResolver dnsresolver, IpConnectivityLog logger,
+    protected ConnectivityService(Context context, INetworkStatsService statsService,
+            IDnsResolver dnsresolver, IpConnectivityLog logger,
             INetd netd, Dependencies deps) {
         if (DBG) log("ConnectivityService starting up");
 
@@ -1095,7 +1093,6 @@
         // TODO: Consider making the timer customizable.
         mNascentDelayMs = DEFAULT_NASCENT_DELAY_MS;
 
-        mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
         mStatsService = Objects.requireNonNull(statsService, "missing INetworkStatsService");
         mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
         mPolicyManagerInternal = Objects.requireNonNull(
@@ -1203,7 +1200,7 @@
         mUserAllContext.registerReceiver(mIntentReceiver, intentFilter,
                 null /* broadcastPermission */, mHandler);
 
-        mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNMS, mNetd);
+        mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNetd);
 
         mNetdCallback = new NetdCallback();
         try {
@@ -1237,12 +1234,12 @@
         mDnsManager = new DnsManager(mContext, mDnsResolver);
         registerPrivateDnsSettingsCallbacks();
 
-        mNoServiceNetwork =  new NetworkAgentInfo(null,
+        mNoServiceNetwork = new NetworkAgentInfo(null,
                 new Network(NO_SERVICE_NET_ID),
                 new NetworkInfo(TYPE_NONE, 0, "", ""),
                 new LinkProperties(), new NetworkCapabilities(), 0, mContext,
                 null, new NetworkAgentConfig(), this, null,
-                null, null, 0, INVALID_UID,
+                null, 0, INVALID_UID,
                 mQosCallbackTracker);
     }
 
@@ -6030,7 +6027,7 @@
         final NetworkAgentInfo nai = new NetworkAgentInfo(na,
                 new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
                 currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
-                this, mNetd, mDnsResolver, mNMS, providerId, uid, mQosCallbackTracker);
+                this, mNetd, mDnsResolver, providerId, uid, mQosCallbackTracker);
 
         // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
         processCapabilitiesFromAgent(nai, nc);
@@ -7952,8 +7949,16 @@
 
         final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo();
         try {
-            mStatsService.forceUpdateIfaces(getDefaultNetworks(), getAllNetworkState(), activeIface,
-                    underlyingNetworkInfos);
+            final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>();
+            // TODO: Directly use NetworkStateSnapshot when feasible.
+            for (final NetworkState state : getAllNetworkState()) {
+                final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network,
+                        state.networkCapabilities, state.linkProperties, state.subscriberId,
+                        state.legacyNetworkType);
+                snapshots.add(snapshot);
+            }
+            mStatsService.forceUpdateIfaces(getDefaultNetworks(), snapshots.toArray(
+                    new NetworkStateSnapshot[0]), activeIface, underlyingNetworkInfos);
         } catch (Exception ignored) {
         }
     }
@@ -8186,7 +8191,7 @@
             TestNetworkService.enforceTestNetworkPermissions(mContext);
 
             if (mTNS == null) {
-                mTNS = new TestNetworkService(mContext, mNMS);
+                mTNS = new TestNetworkService(mContext);
             }
 
             return mTNS;
@@ -8661,9 +8666,23 @@
 
     private class NetdCallback extends BaseNetdUnsolicitedEventListener {
         @Override
-        public void onInterfaceClassActivityChanged(boolean isActive, int timerLabel,
+        public void onInterfaceClassActivityChanged(boolean isActive, int transportType,
                 long timestampNs, int uid) {
-            mNetworkActivityTracker.setAndReportNetworkActive(isActive, timerLabel, timestampNs);
+            mNetworkActivityTracker.setAndReportNetworkActive(isActive, transportType, timestampNs);
+        }
+
+        @Override
+        public void onInterfaceLinkStateChanged(String iface, boolean up) {
+            for (NetworkAgentInfo nai : mNetworkAgentInfos) {
+                nai.clatd.interfaceLinkStateChanged(iface, up);
+            }
+        }
+
+        @Override
+        public void onInterfaceRemoved(String iface) {
+            for (NetworkAgentInfo nai : mNetworkAgentInfos) {
+                nai.clatd.interfaceRemoved(iface);
+            }
         }
     }
 
@@ -8697,7 +8716,7 @@
         }
 
         LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler,
-                @NonNull INetworkManagementService nms, @NonNull INetd netd) {
+                @NonNull INetd netd) {
             mContext = context;
             mNetd = netd;
             mHandler = handler;
diff --git a/services/core/java/com/android/server/ConnectivityServiceInitializer.java b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
index 0779f71..097441f 100644
--- a/services/core/java/com/android/server/ConnectivityServiceInitializer.java
+++ b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
@@ -21,7 +21,6 @@
 
 import android.content.Context;
 import android.net.INetworkStatsService;
-import android.os.INetworkManagementService;
 import android.os.ServiceManager;
 import android.util.Log;
 
@@ -38,8 +37,7 @@
         // Load JNI libraries used by ConnectivityService and its dependencies
         System.loadLibrary("service-connectivity");
         // TODO: Define formal APIs to get the needed services.
-        mConnectivity = new ConnectivityService(context, getNetworkManagementService(),
-                getNetworkStatsService());
+        mConnectivity = new ConnectivityService(context, getNetworkStatsService());
     }
 
     @Override
@@ -49,11 +47,6 @@
                 /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
     }
 
-    private INetworkManagementService getNetworkManagementService() {
-        return INetworkManagementService.Stub.asInterface(
-               ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
-    }
-
     private INetworkStatsService getNetworkStatsService() {
         return INetworkStatsService.Stub.asInterface(
                 ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 4405408..10d6570 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -44,7 +44,6 @@
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.content.Context;
-import android.net.ConnectivityManager;
 import android.net.INetd;
 import android.net.INetdUnsolicitedEventListener;
 import android.net.INetworkManagementEventObserver;
@@ -54,7 +53,6 @@
 import android.net.InterfaceConfigurationParcel;
 import android.net.IpPrefix;
 import android.net.LinkAddress;
-import android.net.Network;
 import android.net.NetworkPolicyManager;
 import android.net.NetworkStack;
 import android.net.NetworkStats;
@@ -974,19 +972,6 @@
     }
 
     @Override
-    public void setDnsForwarders(Network network, String[] dns) {
-        NetworkStack.checkNetworkStackPermission(mContext);
-
-        int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
-
-        try {
-            mNetdService.tetherDnsSet(netId, dns);
-        } catch (RemoteException | ServiceSpecificException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    @Override
     public String[] getDnsForwarders() {
         NetworkStack.checkNetworkStackPermission(mContext);
         try {
@@ -1775,27 +1760,6 @@
     }
 
     @Override
-    public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
-        NetworkStack.checkNetworkStackPermission(mContext);
-
-        final LinkAddress la = routeInfo.getDestinationLinkAddress();
-        final String ifName = routeInfo.getInterface();
-        final String dst = la.toString();
-        final String nextHop;
-
-        if (routeInfo.hasGateway()) {
-            nextHop = routeInfo.getGateway().getHostAddress();
-        } else {
-            nextHop = "";
-        }
-        try {
-            mNetdService.networkAddLegacyRoute(netId, ifName, dst, nextHop, uid);
-        } catch (RemoteException | ServiceSpecificException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    @Override
     public void allowProtect(int uid) {
         NetworkStack.checkNetworkStackPermission(mContext);
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 4e2519b..c65b8e5 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -18,9 +18,7 @@
 
 import static android.Manifest.permission.ACCESS_MTP;
 import static android.Manifest.permission.INSTALL_PACKAGES;
-import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
-import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
@@ -4328,19 +4326,9 @@
             }
 
             // Determine if caller is holding runtime permission
-            final boolean hasRead = StorageManager.checkPermissionAndCheckOp(mContext, false, 0,
-                    uid, packageName, READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE);
             final boolean hasWrite = StorageManager.checkPermissionAndCheckOp(mContext, false, 0,
                     uid, packageName, WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE);
 
-            // We're only willing to give out broad access if they also hold
-            // runtime permission; this is a firm CDD requirement
-            final boolean hasFull = mIPackageManager.checkUidPermission(WRITE_MEDIA_STORAGE,
-                    uid) == PERMISSION_GRANTED;
-            if (hasFull && hasWrite) {
-                return Zygote.MOUNT_EXTERNAL_FULL;
-            }
-
             // We're only willing to give out installer access if they also hold
             // runtime permission; this is a firm CDD requirement
             final boolean hasInstall = mIPackageManager.checkUidPermission(INSTALL_PACKAGES,
@@ -4360,19 +4348,7 @@
             if ((hasInstall || hasInstallOp) && hasWrite) {
                 return Zygote.MOUNT_EXTERNAL_INSTALLER;
             }
-
-            // Otherwise we're willing to give out sandboxed or non-sandboxed if
-            // they hold the runtime permission
-            boolean hasLegacy = mIAppOpsService.checkOperation(OP_LEGACY_STORAGE,
-                    uid, packageName) == MODE_ALLOWED;
-
-            if (hasLegacy && hasWrite) {
-                return Zygote.MOUNT_EXTERNAL_WRITE;
-            } else if (hasLegacy && hasRead) {
-                return Zygote.MOUNT_EXTERNAL_READ;
-            } else {
-                return Zygote.MOUNT_EXTERNAL_DEFAULT;
-            }
+            return Zygote.MOUNT_EXTERNAL_DEFAULT;
         } catch (RemoteException e) {
             // Should not happen
         }
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index 96f832d..55408ea 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -32,7 +32,6 @@
 import android.net.NetworkAgentConfig;
 import android.net.NetworkCapabilities;
 import android.net.NetworkProvider;
-import android.net.NetworkStack;
 import android.net.RouteInfo;
 import android.net.StringNetworkSpecifier;
 import android.net.TestNetworkInterface;
@@ -41,7 +40,6 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
@@ -51,6 +49,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.net.module.util.NetdUtils;
 import com.android.net.module.util.NetworkStackConstants;
+import com.android.net.module.util.PermissionUtils;
 
 import java.io.UncheckedIOException;
 import java.net.Inet4Address;
@@ -69,7 +68,6 @@
     @NonNull private static final AtomicInteger sTestTunIndex = new AtomicInteger();
 
     @NonNull private final Context mContext;
-    @NonNull private final INetworkManagementService mNMS;
     @NonNull private final INetd mNetd;
 
     @NonNull private final HandlerThread mHandlerThread;
@@ -82,14 +80,12 @@
     private static native int jniCreateTunTap(boolean isTun, @NonNull String iface);
 
     @VisibleForTesting
-    protected TestNetworkService(
-            @NonNull Context context, @NonNull INetworkManagementService netManager) {
+    protected TestNetworkService(@NonNull Context context) {
         mHandlerThread = new HandlerThread("TestNetworkServiceThread");
         mHandlerThread.start();
         mHandler = new Handler(mHandlerThread.getLooper());
 
         mContext = Objects.requireNonNull(context, "missing Context");
-        mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
         mNetd = Objects.requireNonNull(NetdService.getInstance(), "could not get netd instance");
         mCm = mContext.getSystemService(ConnectivityManager.class);
         mNetworkProvider = new NetworkProvider(mContext, mHandler.getLooper(),
@@ -324,7 +320,7 @@
         try {
             final long token = Binder.clearCallingIdentity();
             try {
-                NetworkStack.checkNetworkStackPermission(mContext);
+                PermissionUtils.enforceNetworkStackPermission(mContext);
                 NetdUtils.setInterfaceUp(mNetd, iface);
             } finally {
                 Binder.restoreCallingIdentity(token);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e4d2382..fd8e1bc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -19834,7 +19834,7 @@
         @Override
         public int getStorageMountMode(int pid, int uid) {
             if (uid == SHELL_UID || uid == ROOT_UID) {
-                return Zygote.MOUNT_EXTERNAL_FULL;
+                return Zygote.MOUNT_EXTERNAL_DEFAULT;
             }
             synchronized (mPidsSelfLocked) {
                 final ProcessRecord pr = mPidsSelfLocked.get(pid);
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index c5a6e7b..45cf95d 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -92,7 +92,6 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
-import android.os.storage.StorageManager;
 import android.os.storage.StorageManagerInternal;
 import android.system.Os;
 import android.text.TextUtils;
@@ -1854,14 +1853,10 @@
                     final IPackageManager pm = AppGlobals.getPackageManager();
                     permGids = pm.getPackageGids(app.info.packageName,
                             MATCH_DIRECT_BOOT_AUTO, app.userId);
-                    if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) {
-                        mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
-                    } else {
-                        StorageManagerInternal storageManagerInternal = LocalServices.getService(
-                                StorageManagerInternal.class);
-                        mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
-                                app.info.packageName);
-                    }
+                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
+                            StorageManagerInternal.class);
+                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
+                            app.info.packageName);
                 } catch (RemoteException e) {
                     throw e.rethrowAsRuntimeException();
                 }
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 640d99f..cb631e0 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1725,24 +1725,13 @@
                             if (Process.isIsolated(uid)) {
                                 return Zygote.MOUNT_EXTERNAL_NONE;
                             }
-                            if (noteOperation(AppOpsManager.OP_READ_EXTERNAL_STORAGE, uid,
-                                    packageName, null, true, "External storage policy", true)
-                                    != AppOpsManager.MODE_ALLOWED) {
-                                return Zygote.MOUNT_EXTERNAL_NONE;
-                            }
-                            if (noteOperation(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, uid,
-                                    packageName, null, true, "External storage policy", true)
-                                    != AppOpsManager.MODE_ALLOWED) {
-                                return Zygote.MOUNT_EXTERNAL_READ;
-                            }
-                            return Zygote.MOUNT_EXTERNAL_WRITE;
+                            return Zygote.MOUNT_EXTERNAL_DEFAULT;
                         }
 
                         @Override
                         public boolean hasExternalStorage(int uid, String packageName) {
                             final int mountMode = getMountMode(uid, packageName);
-                            return mountMode == Zygote.MOUNT_EXTERNAL_READ
-                                    || mountMode == Zygote.MOUNT_EXTERNAL_WRITE;
+                            return mountMode != Zygote.MOUNT_EXTERNAL_NONE;
                         }
                     });
         }
diff --git a/services/core/java/com/android/server/connectivity/DataConnectionStats.java b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
index fbd089c..15f43a0 100644
--- a/services/core/java/com/android/server/connectivity/DataConnectionStats.java
+++ b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
@@ -52,6 +52,7 @@
     private SignalStrength mSignalStrength;
     private ServiceState mServiceState;
     private int mDataState = TelephonyManager.DATA_DISCONNECTED;
+    private int mNrState = NetworkRegistrationInfo.NR_STATE_NONE;
 
     public DataConnectionStats(Context context, Handler listenerHandler) {
         mContext = context;
@@ -99,7 +100,7 @@
                 : regInfo.getAccessNetworkTechnology();
         // If the device is in NSA NR connection the networkType will report as LTE.
         // For cell dwell rate metrics, this should report NR instead.
-        if (regInfo != null && regInfo.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
+        if (mNrState == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
             networkType = TelephonyManager.NETWORK_TYPE_NR;
         }
         if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible",
@@ -171,6 +172,7 @@
         @Override
         public void onServiceStateChanged(ServiceState state) {
             mServiceState = state;
+            mNrState = state.getNrState();
             notePhoneDataConnectionState();
         }
 
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 34d9ccc..7b20ded 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -57,8 +57,8 @@
 import android.util.Pair;
 
 import com.android.internal.R;
-import com.android.internal.util.HexDump;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.net.module.util.HexDump;
 import com.android.net.module.util.IpUtils;
 
 import java.io.FileDescriptor;
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 641287f..fa80b25 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -29,14 +29,12 @@
 import android.net.LinkProperties;
 import android.net.NetworkInfo;
 import android.net.RouteInfo;
-import android.os.INetworkManagementService;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.net.module.util.NetworkStackConstants;
-import com.android.server.net.BaseNetworkObserver;
 
 import java.net.Inet6Address;
 import java.util.Objects;
@@ -48,7 +46,7 @@
  *
  * @hide
  */
-public class Nat464Xlat extends BaseNetworkObserver {
+public class Nat464Xlat {
     private static final String TAG = Nat464Xlat.class.getSimpleName();
 
     // This must match the interface prefix in clatd.c.
@@ -70,7 +68,6 @@
 
     private final IDnsResolver mDnsResolver;
     private final INetd mNetd;
-    private final INetworkManagementService mNMService;
 
     // The network we're running on, and its type.
     private final NetworkAgentInfo mNetwork;
@@ -99,11 +96,9 @@
 
     private boolean mPrefixDiscoveryRunning;
 
-    public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
-            INetworkManagementService nmService) {
+    public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver) {
         mDnsResolver = dnsResolver;
         mNetd = netd;
-        mNMService = nmService;
         mNetwork = nai;
     }
 
@@ -174,13 +169,6 @@
      * and set internal state.
      */
     private void enterStartingState(String baseIface) {
-        try {
-            mNMService.registerObserver(this);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Can't register iface observer for clat on " + mNetwork.toShortString());
-            return;
-        }
-
         mNat64PrefixInUse = selectNat64Prefix();
         String addrStr = null;
         try {
@@ -216,11 +204,6 @@
      * Unregister as a base observer for the stacked interface, and clear internal state.
      */
     private void leaveStartedState() {
-        try {
-            mNMService.unregisterObserver(this);
-        } catch (RemoteException | IllegalStateException e) {
-            Log.e(TAG, "Error unregistering clatd observer on " + mBaseIface + ": " + e);
-        }
         mNat64PrefixInUse = null;
         mIface = null;
         mBaseIface = null;
@@ -507,12 +490,10 @@
         stop();
     }
 
-    @Override
     public void interfaceLinkStateChanged(String iface, boolean up) {
         mNetwork.handler().post(() -> { handleInterfaceLinkStateChanged(iface, up); });
     }
 
-    @Override
     public void interfaceRemoved(String iface) {
         mNetwork.handler().post(() -> handleInterfaceRemoved(iface));
     }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 4cf5274..cac6cab 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -43,7 +43,6 @@
 import android.net.TcpKeepalivePacketData;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.INetworkManagementService;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.telephony.data.EpsBearerQosSessionAttributes;
@@ -341,8 +340,8 @@
     public NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info,
             @NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, int score, Context context,
             Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
-            IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber,
-            int creatorUid, QosCallbackTracker qosCallbackTracker) {
+            IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid,
+            QosCallbackTracker qosCallbackTracker) {
         Objects.requireNonNull(net);
         Objects.requireNonNull(info);
         Objects.requireNonNull(lp);
@@ -356,7 +355,7 @@
         linkProperties = lp;
         networkCapabilities = nc;
         mScore = score;
-        clatd = new Nat464Xlat(this, netd, dnsResolver, nms);
+        clatd = new Nat464Xlat(this, netd, dnsResolver);
         mConnService = connService;
         mContext = context;
         mHandler = handler;
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 5b9a11b..3a5e10e 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -97,7 +97,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkIdentity;
 import android.net.NetworkStack;
-import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
 import android.net.NetworkStats;
 import android.net.NetworkStats.NonMonotonicObserver;
 import android.net.NetworkStatsHistory;
@@ -296,7 +296,7 @@
     /** Last states of all networks sent from ConnectivityService. */
     @GuardedBy("mStatsLock")
     @Nullable
-    private NetworkState[] mLastNetworkStates = null;
+    private NetworkStateSnapshot[] mLastNetworkStateSnapshots = null;
 
     private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
             new DropBoxNonMonotonicObserver();
@@ -378,8 +378,8 @@
                 }
                 case MSG_UPDATE_IFACES: {
                     // If no cached states, ignore.
-                    if (mLastNetworkStates == null) break;
-                    updateIfaces(mDefaultNetworks, mLastNetworkStates, mActiveIface);
+                    if (mLastNetworkStateSnapshots == null) break;
+                    updateIfaces(mDefaultNetworks, mLastNetworkStateSnapshots, mActiveIface);
                     break;
                 }
                 case MSG_PERFORM_POLL_REGISTER_ALERT: {
@@ -967,10 +967,9 @@
         }
     }
 
-    @Override
     public void forceUpdateIfaces(
             Network[] defaultNetworks,
-            NetworkState[] networkStates,
+            NetworkStateSnapshot[] networkStates,
             String activeIface,
             UnderlyingNetworkInfo[] underlyingNetworkInfos) {
         checkNetworkStackPermission(mContext);
@@ -1248,13 +1247,13 @@
 
     private void updateIfaces(
             Network[] defaultNetworks,
-            NetworkState[] networkStates,
+            NetworkStateSnapshot[] snapshots,
             String activeIface) {
         synchronized (mStatsLock) {
             mWakeLock.acquire();
             try {
                 mActiveIface = activeIface;
-                updateIfacesLocked(defaultNetworks, networkStates);
+                updateIfacesLocked(defaultNetworks, snapshots);
             } finally {
                 mWakeLock.release();
             }
@@ -1262,13 +1261,13 @@
     }
 
     /**
-     * Inspect all current {@link NetworkState} to derive mapping from {@code iface} to {@link
-     * NetworkStatsHistory}. When multiple networks are active on a single {@code iface},
+     * Inspect all current {@link NetworkStateSnapshot}s to derive mapping from {@code iface} to
+     * {@link NetworkStatsHistory}. When multiple networks are active on a single {@code iface},
      * they are combined under a single {@link NetworkIdentitySet}.
      */
     @GuardedBy("mStatsLock")
     private void updateIfacesLocked(@Nullable Network[] defaultNetworks,
-            @NonNull NetworkState[] states) {
+            @NonNull NetworkStateSnapshot[] snapshots) {
         if (!mSystemReady) return;
         if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
 
@@ -1288,21 +1287,21 @@
             mDefaultNetworks = defaultNetworks;
         }
 
-        mLastNetworkStates = states;
+        mLastNetworkStateSnapshots = snapshots;
 
         final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled();
         final ArraySet<String> mobileIfaces = new ArraySet<>();
-        for (NetworkState state : states) {
-            final boolean isMobile = isNetworkTypeMobile(state.legacyNetworkType);
-            final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
+        for (NetworkStateSnapshot snapshot : snapshots) {
+            final boolean isMobile = isNetworkTypeMobile(snapshot.legacyType);
+            final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, snapshot.network);
             final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED
-                    : getSubTypeForState(state);
-            final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
+                    : getSubTypeForStateSnapshot(snapshot);
+            final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot,
                     isDefault, subType);
 
             // Traffic occurring on the base interface is always counted for
             // both total usage and UID details.
-            final String baseIface = state.linkProperties.getInterfaceName();
+            final String baseIface = snapshot.linkProperties.getInterfaceName();
             if (baseIface != null) {
                 findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
                 findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
@@ -1312,7 +1311,7 @@
                 // If IMS is metered, then the IMS network usage has already included VT usage.
                 // VT is considered always metered in framework's layer. If VT is not metered
                 // per carrier's policy, modem will report 0 usage for VT calls.
-                if (state.networkCapabilities.hasCapability(
+                if (snapshot.networkCapabilities.hasCapability(
                         NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
 
                     // Copy the identify from IMS one but mark it as metered.
@@ -1358,7 +1357,7 @@
             // (or non eBPF offloaded) TX they would appear on both, however egress interface
             // accounting is explicitly bypassed for traffic from the clat uid.
             //
-            final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
+            final List<LinkProperties> stackedLinks = snapshot.linkProperties.getStackedLinks();
             for (LinkProperties stackedLink : stackedLinks) {
                 final String stackedIface = stackedLink.getInterfaceName();
                 if (stackedIface != null) {
@@ -1381,7 +1380,7 @@
      * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different
      * transport types do not actually fill this value.
      */
-    private int getSubTypeForState(@NonNull NetworkState state) {
+    private int getSubTypeForStateSnapshot(@NonNull NetworkStateSnapshot state) {
         if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
             return 0;
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4896fd9..5607167 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -20,10 +20,8 @@
 import static android.Manifest.permission.INSTALL_PACKAGES;
 import static android.Manifest.permission.MANAGE_DEVICE_ADMINS;
 import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
-import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
 import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
 import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
-import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_DEFAULT;
 import static android.app.AppOpsManager.MODE_IGNORED;
@@ -92,7 +90,6 @@
 import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
-import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.pm.PackageManager.RESTRICTION_NONE;
 import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
@@ -21603,24 +21600,18 @@
 
         mInjector.getStorageManagerInternal().addExternalStoragePolicy(
                 new StorageManagerInternal.ExternalStorageMountPolicy() {
-            @Override
-            public int getMountMode(int uid, String packageName) {
-                if (Process.isIsolated(uid)) {
-                    return Zygote.MOUNT_EXTERNAL_NONE;
-                }
-                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
-                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
-                }
-                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
-                    return Zygote.MOUNT_EXTERNAL_READ;
-                }
-                return Zygote.MOUNT_EXTERNAL_WRITE;
-            }
+                    @Override
+                    public int getMountMode(int uid, String packageName) {
+                        if (Process.isIsolated(uid)) {
+                            return Zygote.MOUNT_EXTERNAL_NONE;
+                        }
+                        return Zygote.MOUNT_EXTERNAL_DEFAULT;
+                    }
 
-            @Override
-            public boolean hasExternalStorage(int uid, String packageName) {
-                return true;
-            }
+                    @Override
+                    public boolean hasExternalStorage(int uid, String packageName) {
+                        return true;
+                    }
         });
 
         // Now that we're mostly running, clean up stale users and apps
diff --git a/services/core/java/com/android/server/servicewatcher/OWNERS b/services/core/java/com/android/server/servicewatcher/OWNERS
new file mode 100644
index 0000000..ced619f
--- /dev/null
+++ b/services/core/java/com/android/server/servicewatcher/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 25692
+
+sooniln@google.com
+wyattriley@google.com
+
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 7d7af03..752da31 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -2043,7 +2043,8 @@
         final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
         networkCapabilities.addTransportType(TRANSPORT_WIFI);
         networkCapabilities.setSSID(TEST_SSID);
-        return new NetworkState(TYPE_WIFI, prop, networkCapabilities, null, null);
+        return new NetworkState(TYPE_WIFI, prop, networkCapabilities, new Network(TEST_NET_ID),
+                null);
     }
 
     private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception {
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 07de617..0ff288b 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -138,6 +138,24 @@
  *     }
  * }
  * }
+ *
+ * </pre>
+ * <p id="companionInCallService">
+ * <h3>Access to InCallService for Wearable Devices</h3>
+ * <ol>
+ * If your app is a third-party companion app and wants to access InCallService APIs, what your
+ * app could do are:
+ * <p>
+ *   <ol>
+ *     <li> Declare MANAGE_ONGOING_CALLS permission in your manifest
+ *     <li> Associate with a physical wearable device via the
+ *          {@link android.companion.CompanionDeviceManager} API as a companion app. See:
+ *          https://developer.android.com/guide/topics/connectivity/companion-device-pairing
+ *     <li> Implement this InCallService with BIND_INCALL_SERVICE permission
+ *   </ol>
+ * </ol>
+ * <p>
+ *
  * </pre>
  * <p id="incomingCallNotification">
  * <h3>Showing the Incoming Call Notification</h3>
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 3f8b683..b0b5ba7 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1649,24 +1649,25 @@
     }
 
     /**
-     * Returns whether the caller has {@link InCallService} access for companion apps.
-     *
-     * A companion app is an app associated with a physical wearable device via the
-     * {@link android.companion.CompanionDeviceManager} API.
+     * Returns whether the caller has {@link android.Manifest.permission#MANAGE_ONGOING_CALLS}
+     * permission. The permission can be obtained by associating with a physical wearable device
+     * via the {@link android.companion.CompanionDeviceManager} API as a companion app. If the
+     * caller app has the permission, it has {@link InCallService} access to manage ongoing calls.
      *
      * @return {@code true} if the caller has {@link InCallService} access for
      *      companion app; {@code false} otherwise.
      */
-    public boolean hasCompanionInCallServiceAccess() {
-        try {
-            if (isServiceConnected()) {
-                return getTelecomService().hasCompanionInCallServiceAccess(
+    public boolean hasManageOngoingCallsPermission() {
+        ITelecomService service = getTelecomService();
+        if (service != null) {
+            try {
+                return service.hasManageOngoingCallsPermission(
                         mContext.getOpPackageName());
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException calling hasCompanionInCallServiceAccess().", e);
-            if (!isSystemProcess()) {
-                e.rethrowAsRuntimeException();
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException calling hasManageOngoingCallsPermission().", e);
+                if (!isSystemProcess()) {
+                    e.rethrowAsRuntimeException();
+                }
             }
         }
         return false;
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 6dc096d..5afac2e 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -179,9 +179,9 @@
     boolean isInCall(String callingPackage, String callingFeatureId);
 
     /**
-     * @see TelecomServiceImpl#hasCompanionInCallServiceAccess
+     * @see TelecomServiceImpl#hasManageOngoingCallsPermission
      */
-    boolean hasCompanionInCallServiceAccess(String callingPackage);
+    boolean hasManageOngoingCallsPermission(String callingPackage);
 
     /**
      * @see TelecomServiceImpl#isInManagedCall
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 706e3cb..a78f813 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -371,6 +371,7 @@
      * Get the 5G NR connection state.
      *
      * @return the 5G NR connection state.
+     * @hide
      */
     public @NRState int getNrState() {
         return mNrState;
diff --git a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt
index 56b56ef..0ca4d95 100644
--- a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt
+++ b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt
@@ -63,10 +63,10 @@
 
     @Test
     fun testParcelUnparcel() {
-        val emptySnapshot = NetworkStateSnapshot(LinkProperties(), NetworkCapabilities(),
-                Network(TEST_NETID), null, TYPE_NONE)
+        val emptySnapshot = NetworkStateSnapshot(Network(TEST_NETID), NetworkCapabilities(),
+                LinkProperties(), null, TYPE_NONE)
         val snapshot = NetworkStateSnapshot(
-                TEST_LINK_PROPERTIES, TEST_CAPABILITIES, Network(TEST_NETID), TEST_IMSI, TYPE_WIFI)
+                Network(TEST_NETID), TEST_CAPABILITIES, TEST_LINK_PROPERTIES, TEST_IMSI, TYPE_WIFI)
         assertParcelSane(emptySnapshot, 5)
         assertParcelSane(snapshot, 5)
     }
diff --git a/tests/net/common/java/android/net/UidRangeTest.java b/tests/net/common/java/android/net/UidRangeTest.java
new file mode 100644
index 0000000..1b1c954
--- /dev/null
+++ b/tests/net/common/java/android/net/UidRangeTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2016 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 static android.os.UserHandle.MIN_SECONDARY_USER_ID;
+import static android.os.UserHandle.SYSTEM;
+import static android.os.UserHandle.USER_SYSTEM;
+import static android.os.UserHandle.getUid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.os.Build;
+import android.os.UserHandle;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UidRangeTest {
+
+    /*
+     * UidRange is no longer passed to netd. UID ranges between the framework and netd are passed as
+     * UidRangeParcel objects.
+     */
+
+    @Rule
+    public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
+
+    @Test
+    public void testSingleItemUidRangeAllowed() {
+        new UidRange(123, 123);
+        new UidRange(0, 0);
+        new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE);
+    }
+
+    @Test
+    public void testNegativeUidsDisallowed() {
+        try {
+            new UidRange(-2, 100);
+            fail("Exception not thrown for negative start UID");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            new UidRange(-200, -100);
+            fail("Exception not thrown for negative stop UID");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testStopLessThanStartDisallowed() {
+        final int x = 4195000;
+        try {
+            new UidRange(x, x - 1);
+            fail("Exception not thrown for negative-length UID range");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testGetStartAndEndUser() throws Exception {
+        final UidRange uidRangeOfPrimaryUser = new UidRange(
+                getUid(USER_SYSTEM, 10000), getUid(USER_SYSTEM, 10100));
+        final UidRange uidRangeOfSecondaryUser = new UidRange(
+                getUid(MIN_SECONDARY_USER_ID, 10000), getUid(MIN_SECONDARY_USER_ID, 10100));
+        assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser());
+        assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getEndUser());
+        assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getStartUser());
+        assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getEndUser());
+
+        final UidRange uidRangeForDifferentUsers = new UidRange(
+                getUid(USER_SYSTEM, 10000), getUid(MIN_SECONDARY_USER_ID, 10100));
+        assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser());
+        assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getEndUser());
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testCreateForUser() throws Exception {
+        final UidRange uidRangeOfPrimaryUser = UidRange.createForUser(SYSTEM);
+        final UidRange uidRangeOfSecondaryUser = UidRange.createForUser(
+                UserHandle.of(USER_SYSTEM + 1));
+        assertTrue(uidRangeOfPrimaryUser.stop < uidRangeOfSecondaryUser.start);
+        assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser());
+        assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getEndUser());
+        assertEquals(USER_SYSTEM + 1, uidRangeOfSecondaryUser.getStartUser());
+        assertEquals(USER_SYSTEM + 1, uidRangeOfSecondaryUser.getEndUser());
+    }
+}
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 9ed55f0..c10c573 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -177,7 +177,7 @@
     }
 
     private inner class TestConnectivityService(deps: Dependencies) : ConnectivityService(
-            context, netManager, statsService, dnsResolver, log, netd, deps)
+            context, statsService, dnsResolver, log, netd, deps)
 
     private fun makeDependencies(): ConnectivityService.Dependencies {
         val deps = spy(ConnectivityService.Dependencies())
diff --git a/tests/net/java/android/net/IpSecAlgorithmTest.java b/tests/net/java/android/net/IpSecAlgorithmTest.java
index 2e1c29a..3a8d600 100644
--- a/tests/net/java/android/net/IpSecAlgorithmTest.java
+++ b/tests/net/java/android/net/IpSecAlgorithmTest.java
@@ -129,6 +129,7 @@
             checkCryptKeyLenValidation(IpSecAlgorithm.CRYPT_AES_CTR, len);
         }
         checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_AES_XCBC, 128, 96);
+        checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_AES_CMAC, 128, 96);
         checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305, 288, 128);
     }
 
diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt
index 27224c2..64b774c 100644
--- a/tests/net/java/android/net/NetworkTemplateTest.kt
+++ b/tests/net/java/android/net/NetworkTemplateTest.kt
@@ -20,14 +20,13 @@
 import android.net.ConnectivityManager.TYPE_MOBILE
 import android.net.ConnectivityManager.TYPE_WIFI
 import android.net.NetworkIdentity.SUBTYPE_COMBINED
-import android.net.NetworkIdentity.OEM_NONE;
-import android.net.NetworkIdentity.OEM_PAID;
-import android.net.NetworkIdentity.OEM_PRIVATE;
+import android.net.NetworkIdentity.OEM_NONE
+import android.net.NetworkIdentity.OEM_PAID
+import android.net.NetworkIdentity.OEM_PRIVATE
 import android.net.NetworkIdentity.buildNetworkIdentity
 import android.net.NetworkStats.DEFAULT_NETWORK_ALL
 import android.net.NetworkStats.METERED_ALL
 import android.net.NetworkStats.ROAMING_ALL
-import android.net.NetworkTemplate.MATCH_ETHERNET
 import android.net.NetworkTemplate.MATCH_MOBILE
 import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
 import android.net.NetworkTemplate.MATCH_WIFI
@@ -50,7 +49,6 @@
 import kotlin.test.assertFalse
 import kotlin.test.assertNotEquals
 import kotlin.test.assertTrue
-import kotlin.test.fail
 
 private const val TEST_IMSI1 = "imsi1"
 private const val TEST_IMSI2 = "imsi2"
@@ -60,17 +58,17 @@
 class NetworkTemplateTest {
     private val mockContext = mock(Context::class.java)
 
-    private fun buildMobileNetworkState(subscriberId: String): NetworkState =
+    private fun buildMobileNetworkState(subscriberId: String): NetworkStateSnapshot =
             buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId)
-    private fun buildWifiNetworkState(ssid: String): NetworkState =
+    private fun buildWifiNetworkState(ssid: String): NetworkStateSnapshot =
             buildNetworkState(TYPE_WIFI, ssid = ssid)
 
     private fun buildNetworkState(
         type: Int,
         subscriberId: String? = null,
         ssid: String? = null,
-        oemManaged: Int = OEM_NONE,
-    ): NetworkState {
+        oemManaged: Int = OEM_NONE
+    ): NetworkStateSnapshot {
         val lp = LinkProperties()
         val caps = NetworkCapabilities().apply {
             setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false)
@@ -81,7 +79,7 @@
             setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
                     (oemManaged and OEM_PRIVATE) == OEM_PRIVATE)
         }
-        return NetworkState(type, lp, caps, mock(Network::class.java), subscriberId)
+        return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type)
     }
 
     private fun NetworkTemplate.assertMatches(ident: NetworkIdentity) =
@@ -179,7 +177,7 @@
                 OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
 
         // Verify that "not OEM managed network" constants are equal.
-        assertEquals(OEM_MANAGED_NO, OEM_NONE);
+        assertEquals(OEM_MANAGED_NO, OEM_NONE)
 
         // Verify the constants don't conflict.
         assertEquals(constantValues.size, constantValues.distinct().count())
@@ -201,8 +199,13 @@
      * @param identSsid If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide
      *         one of {@code TEST_SSID*}.
      */
-    private fun matchOemManagedIdent(networkType: Int, matchType:Int, subscriberId: String? = null,
-            templateSsid: String? = null, identSsid: String? = null) {
+    private fun matchOemManagedIdent(
+        networkType: Int,
+        matchType: Int,
+        subscriberId: String? = null,
+        templateSsid: String? = null,
+        identSsid: String? = null
+    ) {
         val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
         // A null subscriberId needs a null matchSubscriberIds argument as well.
         val matchSubscriberIds = if (subscriberId == null) null else arrayOf(subscriberId)
diff --git a/tests/net/java/android/net/UidRangeTest.java b/tests/net/java/android/net/UidRangeTest.java
deleted file mode 100644
index ea1df09..0000000
--- a/tests/net/java/android/net/UidRangeTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 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 static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class UidRangeTest {
-
-  /*
-   * UidRange is no longer passed to netd. UID ranges between the framework and netd are passed as
-   * UidRangeParcel objects.
-   */
-
-    @Test
-    public void testSingleItemUidRangeAllowed() {
-        new UidRange(123, 123);
-        new UidRange(0, 0);
-        new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE);
-    }
-
-    @Test
-    public void testNegativeUidsDisallowed() {
-        try {
-            new UidRange(-2, 100);
-            fail("Exception not thrown for negative start UID");
-        } catch (IllegalArgumentException expected) {
-        }
-
-        try {
-            new UidRange(-200, -100);
-            fail("Exception not thrown for negative stop UID");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testStopLessThanStartDisallowed() {
-        final int x = 4195000;
-        try {
-            new UidRange(x, x - 1);
-            fail("Exception not thrown for negative-length UID range");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index bb822d8..e43770f 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -198,7 +198,7 @@
 import android.net.NetworkSpecifier;
 import android.net.NetworkStack;
 import android.net.NetworkStackClient;
-import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
 import android.net.NetworkTestResultParcelable;
 import android.net.OemNetworkPreferences;
 import android.net.ProxyInfo;
@@ -1463,7 +1463,6 @@
         mDeps = makeDependencies();
         returnRealCallingUid();
         mService = new ConnectivityService(mServiceContext,
-                mNetworkManagementService,
                 mStatsService,
                 mMockDnsResolver,
                 mock(IpConnectivityLog.class),
@@ -5485,7 +5484,7 @@
                 UnderlyingNetworkInfo[].class);
 
         verify(mStatsService, atLeastOnce()).forceUpdateIfaces(networksCaptor.capture(),
-                any(NetworkState[].class), eq(defaultIface), vpnInfosCaptor.capture());
+                any(NetworkStateSnapshot[].class), eq(defaultIface), vpnInfosCaptor.capture());
 
         assertSameElementsNoDuplicates(networksCaptor.getValue(), networks);
 
@@ -5555,9 +5554,8 @@
         // Temp metered change shouldn't update ifaces
         mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
         waitForIdle();
-        verify(mStatsService, never())
-                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
-                        eq(new UnderlyingNetworkInfo[0]));
+        verify(mStatsService, never()).forceUpdateIfaces(eq(onlyCell), any(
+                NetworkStateSnapshot[].class), eq(MOBILE_IFNAME), eq(new UnderlyingNetworkInfo[0]));
         reset(mStatsService);
 
         // Roaming change should update ifaces
@@ -5639,7 +5637,7 @@
         // Confirm that we never tell NetworkStatsService that cell is no longer the underlying
         // network for the VPN...
         verify(mStatsService, never()).forceUpdateIfaces(any(Network[].class),
-                any(NetworkState[].class), any() /* anyString() doesn't match null */,
+                any(NetworkStateSnapshot[].class), any() /* anyString() doesn't match null */,
                 argThat(infos -> infos[0].underlyingIfaces.size() == 1
                         && WIFI_IFNAME.equals(infos[0].underlyingIfaces.get(0))));
         verifyNoMoreInteractions(mStatsService);
@@ -5653,7 +5651,7 @@
         mEthernetNetworkAgent.connect(false);
         waitForIdle();
         verify(mStatsService).forceUpdateIfaces(any(Network[].class),
-                any(NetworkState[].class), any() /* anyString() doesn't match null */,
+                any(NetworkStateSnapshot[].class), any() /* anyString() doesn't match null */,
                 argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.size() == 1
                         && WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces.get(0))));
         mEthernetNetworkAgent.disconnect();
@@ -7856,7 +7854,6 @@
         cellLp.addRoute(defaultRoute);
         cellLp.addRoute(ipv6Subnet);
         mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
-        reset(mNetworkManagementService);
         reset(mMockDnsResolver);
         reset(mMockNetd);
         reset(mBatteryStatsService);
@@ -7896,7 +7893,6 @@
 
         verifyNoMoreInteractions(mMockNetd);
         verifyNoMoreInteractions(mMockDnsResolver);
-        reset(mNetworkManagementService);
         reset(mMockNetd);
         reset(mMockDnsResolver);
         when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME))
@@ -7996,7 +7992,6 @@
         verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME);
         verifyNoMoreInteractions(mMockNetd);
         verifyNoMoreInteractions(mMockDnsResolver);
-        reset(mNetworkManagementService);
         reset(mMockNetd);
         reset(mMockDnsResolver);
         when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME))
@@ -8233,7 +8228,6 @@
         final LinkProperties cellLp = new LinkProperties();
         cellLp.setInterfaceName(MOBILE_IFNAME);
         mCellNetworkAgent.sendLinkProperties(cellLp);
-        reset(mNetworkManagementService);
         mCellNetworkAgent.connect(true);
         networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(),
@@ -8927,8 +8921,8 @@
                 ConnectivityManager.getNetworkTypeName(TYPE_MOBILE),
                 TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE));
         return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(),
-                nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, null,
-                0, INVALID_UID, mQosCallbackTracker);
+                nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0,
+                INVALID_UID, mQosCallbackTracker);
     }
 
     @Test
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 52cb836..a913673 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -41,7 +41,6 @@
 import android.net.NetworkInfo;
 import android.net.NetworkProvider;
 import android.os.Binder;
-import android.os.INetworkManagementService;
 import android.text.format.DateUtils;
 
 import androidx.test.filters.SmallTest;
@@ -74,7 +73,6 @@
     @Mock ConnectivityService mConnService;
     @Mock IDnsResolver mDnsResolver;
     @Mock INetd mNetd;
-    @Mock INetworkManagementService mNMS;
     @Mock Context mCtx;
     @Mock NetworkNotificationManager mNotifier;
     @Mock Resources mResources;
@@ -358,8 +356,8 @@
         caps.addTransportType(transport);
         NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info,
                 new LinkProperties(), caps, 50, mCtx, null, new NetworkAgentConfig() /* config */,
-                mConnService, mNetd, mDnsResolver, mNMS, NetworkProvider.ID_NONE,
-                Binder.getCallingUid(), mQosCallbackTracker);
+                mConnService, mNetd, mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(),
+                mQosCallbackTracker);
         nai.everValidated = true;
         return nai;
     }
diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
index 4f65b67..5f56e25 100644
--- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
+++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
@@ -36,7 +36,6 @@
 import android.net.NetworkAgentConfig;
 import android.net.NetworkInfo;
 import android.os.Handler;
-import android.os.INetworkManagementService;
 import android.os.test.TestLooper;
 
 import androidx.test.filters.SmallTest;
@@ -67,7 +66,6 @@
     @Mock ConnectivityService mConnectivity;
     @Mock IDnsResolver mDnsResolver;
     @Mock INetd mNetd;
-    @Mock INetworkManagementService mNms;
     @Mock NetworkAgentInfo mNai;
 
     TestLooper mLooper;
@@ -75,7 +73,7 @@
     NetworkAgentConfig mAgentConfig = new NetworkAgentConfig();
 
     Nat464Xlat makeNat464Xlat() {
-        return new Nat464Xlat(mNai, mNetd, mDnsResolver, mNms) {
+        return new Nat464Xlat(mNai, mNetd, mDnsResolver) {
             @Override protected int getNetId() {
                 return NETID;
             }
@@ -206,7 +204,6 @@
         // Start clat.
         nat.start();
 
-        verify(mNms).registerObserver(eq(nat));
         verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
 
         // Stacked interface up notification arrives.
@@ -225,7 +222,6 @@
 
         verify(mNetd).clatdStop(eq(BASE_IFACE));
         verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
-        verify(mNms).unregisterObserver(eq(nat));
         assertTrue(c.getValue().getStackedLinks().isEmpty());
         assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
         verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
@@ -235,7 +231,7 @@
         nat.interfaceRemoved(STACKED_IFACE);
         mLooper.dispatchNext();
 
-        verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+        verifyNoMoreInteractions(mNetd, mConnectivity);
     }
 
     @Test
@@ -346,7 +342,6 @@
 
         nat.start();
 
-        verify(mNms).registerObserver(eq(nat));
         verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
 
         // Stacked interface up notification arrives.
@@ -365,7 +360,6 @@
 
         verify(mNetd).clatdStop(eq(BASE_IFACE));
         verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
-        verify(mNms).unregisterObserver(eq(nat));
         verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
         assertTrue(c.getValue().getStackedLinks().isEmpty());
         assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
@@ -374,7 +368,7 @@
         // ConnectivityService stops clat: no-op.
         nat.stop();
 
-        verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+        verifyNoMoreInteractions(mNetd, mConnectivity);
     }
 
     private void checkStopBeforeClatdStarts(boolean dueToDisconnect) throws Exception {
@@ -386,7 +380,6 @@
 
         nat.start();
 
-        verify(mNms).registerObserver(eq(nat));
         verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
 
         // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
@@ -394,7 +387,6 @@
         nat.stop();
 
         verify(mNetd).clatdStop(eq(BASE_IFACE));
-        verify(mNms).unregisterObserver(eq(nat));
         verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
         assertIdle(nat);
 
@@ -408,7 +400,7 @@
 
         assertIdle(nat);
 
-        verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+        verifyNoMoreInteractions(mNetd, mConnectivity);
     }
 
     @Test
@@ -430,7 +422,6 @@
 
         nat.start();
 
-        verify(mNms).registerObserver(eq(nat));
         verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
 
         // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
@@ -438,11 +429,10 @@
         nat.stop();
 
         verify(mNetd).clatdStop(eq(BASE_IFACE));
-        verify(mNms).unregisterObserver(eq(nat));
         verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
         assertIdle(nat);
 
-        verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+        verifyNoMoreInteractions(mNetd, mConnectivity);
     }
 
     @Test
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 54d6fb9..9334e2c 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -19,9 +19,7 @@
 import static android.content.Intent.ACTION_UID_REMOVED;
 import static android.content.Intent.EXTRA_UID;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_VPN;
 import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.NetworkIdentity.OEM_NONE;
 import static android.net.NetworkIdentity.OEM_PAID;
 import static android.net.NetworkIdentity.OEM_PRIVATE;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
@@ -86,7 +84,7 @@
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
 import android.net.NetworkStats;
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
@@ -286,7 +284,7 @@
         // pretend that wifi network comes online; service should ask about full
         // network state, and poll any existing interfaces before updating.
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[] {buildWifiState()};
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -329,7 +327,7 @@
         // pretend that wifi network comes online; service should ask about full
         // network state, and poll any existing interfaces before updating.
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[] {buildWifiState()};
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -403,7 +401,7 @@
         // pretend that wifi network comes online; service should ask about full
         // network state, and poll any existing interfaces before updating.
         expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
-        NetworkState[] states = new NetworkState[] {buildWifiState()};
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -444,7 +442,7 @@
     public void testUidStatsAcrossNetworks() throws Exception {
         // pretend first mobile network comes online
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildMobile3gState(IMSI_1)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -475,7 +473,7 @@
         // disappearing, to verify we don't count backwards.
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
-        states = new NetworkState[] {buildMobile3gState(IMSI_2)};
+        states = new NetworkStateSnapshot[] {buildMobile3gState(IMSI_2)};
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
                 .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
@@ -519,7 +517,7 @@
     public void testUidRemovedIsMoved() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[] {buildWifiState()};
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -583,7 +581,8 @@
                 buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_LTE);
         final NetworkTemplate template5g =
                 buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_NR);
-        final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
+        final NetworkStateSnapshot[] states =
+                new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)};
 
         // 3G network comes online.
         expectNetworkStatsSummary(buildEmptyStats());
@@ -673,7 +672,8 @@
                 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO);
 
         // OEM_PAID network comes online.
-        NetworkState[] states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false,
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
+                buildOemManagedMobileState(IMSI_1, false,
                 new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
@@ -688,7 +688,7 @@
         forcePollAndWaitForIdle();
 
         // OEM_PRIVATE network comes online.
-        states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false,
+        states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false,
                 new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE})};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
@@ -703,7 +703,7 @@
         forcePollAndWaitForIdle();
 
         // OEM_PAID + OEM_PRIVATE network comes online.
-        states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false,
+        states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false,
                 new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
                           NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
         expectNetworkStatsSummary(buildEmptyStats());
@@ -719,7 +719,7 @@
         forcePollAndWaitForIdle();
 
         // OEM_NONE network comes online.
-        states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})};
+        states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
         mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
@@ -771,7 +771,7 @@
     public void testSummaryForAllUid() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[] {buildWifiState()};
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -830,7 +830,7 @@
     public void testDetailedUidStats() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[] {buildWifiState()};
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -871,9 +871,9 @@
         final String stackedIface = "stacked-test0";
         final LinkProperties stackedProp = new LinkProperties();
         stackedProp.setInterfaceName(stackedIface);
-        final NetworkState wifiState = buildWifiState();
+        final NetworkStateSnapshot wifiState = buildWifiState();
         wifiState.linkProperties.addStackedLink(stackedProp);
-        NetworkState[] states = new NetworkState[] {wifiState};
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {wifiState};
 
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
@@ -929,7 +929,7 @@
     public void testForegroundBackground() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[] {buildWifiState()};
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -986,8 +986,8 @@
     public void testMetered() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
-        NetworkState[] states =
-                new NetworkState[] {buildWifiState(true /* isMetered */, TEST_IFACE)};
+        NetworkStateSnapshot[] states =
+                new NetworkStateSnapshot[] {buildWifiState(true /* isMetered */, TEST_IFACE)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -1026,8 +1026,8 @@
     public void testRoaming() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
-        NetworkState[] states =
-            new NetworkState[] {buildMobile3gState(IMSI_1, true /* isRoaming */)};
+        NetworkStateSnapshot[] states =
+            new NetworkStateSnapshot[] {buildMobile3gState(IMSI_1, true /* isRoaming */)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -1065,7 +1065,8 @@
     public void testTethering() throws Exception {
         // pretend first mobile network comes online
         expectDefaultSettings();
-        final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
+        final NetworkStateSnapshot[] states =
+                new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -1122,7 +1123,7 @@
         // pretend that wifi network comes online; service should ask about full
         // network state, and poll any existing interfaces before updating.
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[] {buildWifiState()};
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -1220,8 +1221,8 @@
     public void testStatsProviderUpdateStats() throws Exception {
         // Pretend that network comes online.
         expectDefaultSettings();
-        final NetworkState[] states =
-                new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
+        final NetworkStateSnapshot[] states =
+                new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -1282,8 +1283,8 @@
     public void testStatsProviderSetAlert() throws Exception {
         // Pretend that network comes online.
         expectDefaultSettings();
-        NetworkState[] states =
-                new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
+        NetworkStateSnapshot[] states =
+                new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
         mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
                 new UnderlyingNetworkInfo[0]);
 
@@ -1326,7 +1327,8 @@
                 buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UNKNOWN);
         final NetworkTemplate templateAll =
                 buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL);
-        final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
+        final NetworkStateSnapshot[] states =
+                new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)};
 
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1401,7 +1403,7 @@
     public void testOperationCount_nonDefault_traffic() throws Exception {
         // Pretend mobile network comes online, but wifi is the default network.
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[]{
+        NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
                 buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)};
         expectNetworkStatsUidDetail(buildEmptyStats());
         mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
@@ -1489,7 +1491,7 @@
         expectNetworkStatsSummary(buildEmptyStats());
     }
 
-    private String getActiveIface(NetworkState... states) throws Exception {
+    private String getActiveIface(NetworkStateSnapshot... states) throws Exception {
         if (states == null || states.length == 0 || states[0].linkProperties == null) {
             return null;
         }
@@ -1565,11 +1567,11 @@
         assertEquals("unexpected operations", operations, entry.operations);
     }
 
-    private static NetworkState buildWifiState() {
+    private static NetworkStateSnapshot buildWifiState() {
         return buildWifiState(false, TEST_IFACE);
     }
 
-    private static NetworkState buildWifiState(boolean isMetered, @NonNull String iface) {
+    private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface) {
         final LinkProperties prop = new LinkProperties();
         prop.setInterfaceName(iface);
         final NetworkCapabilities capabilities = new NetworkCapabilities();
@@ -1577,35 +1579,30 @@
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
         capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
         capabilities.setSSID(TEST_SSID);
-        return new NetworkState(TYPE_WIFI, prop, capabilities, WIFI_NETWORK, null);
+        return new NetworkStateSnapshot(WIFI_NETWORK, capabilities, prop, null, TYPE_WIFI);
     }
 
-    private static NetworkState buildMobile3gState(String subscriberId) {
+    private static NetworkStateSnapshot buildMobile3gState(String subscriberId) {
         return buildMobile3gState(subscriberId, false /* isRoaming */);
     }
 
-    private static NetworkState buildMobile3gState(String subscriberId, boolean isRoaming) {
+    private static NetworkStateSnapshot buildMobile3gState(String subscriberId, boolean isRoaming) {
         final LinkProperties prop = new LinkProperties();
         prop.setInterfaceName(TEST_IFACE);
         final NetworkCapabilities capabilities = new NetworkCapabilities();
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
         capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-        return new NetworkState(TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId);
+        return new NetworkStateSnapshot(
+                MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE);
     }
 
     private NetworkStats buildEmptyStats() {
         return new NetworkStats(getElapsedRealtime(), 0);
     }
 
-    private static NetworkState buildVpnState() {
-        final LinkProperties prop = new LinkProperties();
-        prop.setInterfaceName(TUN_IFACE);
-        return new NetworkState(TYPE_VPN, prop, new NetworkCapabilities(), VPN_NETWORK, null);
-    }
-
-    private static NetworkState buildOemManagedMobileState(String subscriberId, boolean isRoaming,
-                int[] oemNetCapabilities) {
+    private static NetworkStateSnapshot buildOemManagedMobileState(
+            String subscriberId, boolean isRoaming, int[] oemNetCapabilities) {
         final LinkProperties prop = new LinkProperties();
         prop.setInterfaceName(TEST_IFACE);
         final NetworkCapabilities capabilities = new NetworkCapabilities();
@@ -1615,7 +1612,8 @@
             capabilities.setCapability(nc, true);
         }
         capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-        return new NetworkState(TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId);
+        return new NetworkStateSnapshot(MOBILE_NETWORK, capabilities, prop, subscriberId,
+                TYPE_MOBILE);
     }
 
     private long getElapsedRealtime() {
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
new file mode 100644
index 0000000..28cf38a
--- /dev/null
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 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.vcn.persistablebundleutils;
+
+import static org.junit.Assert.assertEquals;
+
+import android.net.InetAddresses;
+import android.net.ipsec.ike.IkeTrafficSelector;
+import android.os.PersistableBundle;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetAddress;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IkeTrafficSelectorUtilsTest {
+    private static final int START_PORT = 16;
+    private static final int END_PORT = 65520;
+
+    private static final InetAddress IPV4_START_ADDRESS =
+            InetAddresses.parseNumericAddress("192.0.2.100");
+    private static final InetAddress IPV4_END_ADDRESS =
+            InetAddresses.parseNumericAddress("192.0.2.101");
+
+    private static final InetAddress IPV6_START_ADDRESS =
+            InetAddresses.parseNumericAddress("2001:db8:2::100");
+    private static final InetAddress IPV6_END_ADDRESS =
+            InetAddresses.parseNumericAddress("2001:db8:2::101");
+
+    private static void verifyPersistableBundleEncodeDecodeIsLossless(IkeTrafficSelector ts) {
+        final PersistableBundle bundle = IkeTrafficSelectorUtils.toPersistableBundle(ts);
+        final IkeTrafficSelector resultTs = IkeTrafficSelectorUtils.fromPersistableBundle(bundle);
+        assertEquals(ts, resultTs);
+    }
+
+    @Test
+    public void testPersistableBundleEncodeDecodeIsLosslessIpv4Ts() throws Exception {
+        verifyPersistableBundleEncodeDecodeIsLossless(
+                new IkeTrafficSelector(START_PORT, END_PORT, IPV4_START_ADDRESS, IPV4_END_ADDRESS));
+    }
+
+    @Test
+    public void testPersistableBundleEncodeDecodeIsLosslessIpv6Ts() throws Exception {
+        verifyPersistableBundleEncodeDecodeIsLossless(
+                new IkeTrafficSelector(START_PORT, END_PORT, IPV6_START_ADDRESS, IPV6_END_ADDRESS));
+    }
+}