Snap for 8417617 from 2ff0ecbd424e422fe317f94ba501d22d1e4b08eb to mainline-wifi-release

Change-Id: I170975ca76841867e5182170576b24469ce87f19
diff --git a/Android.bp b/Android.bp
index d11bf8a..ef43047 100644
--- a/Android.bp
+++ b/Android.bp
@@ -61,7 +61,13 @@
 java_defaults {
     name: "NetworkStackDevApiLevel",
     min_sdk_version: "29",
-    sdk_version: "system_current",
+    sdk_version: "module_current",
+    libs: [
+        "framework-connectivity",
+        "framework-connectivity-t",
+        "framework-statsd",
+        "framework-wifi",
+    ]
 }
 
 java_defaults {
@@ -165,6 +171,9 @@
     srcs: [
         "apishim/33/**/*.java",
     ],
+    static_libs: [
+        "net-utils-framework-common",
+    ],
     libs: [
         "NetworkStackShimsCommon",
         "NetworkStackApi29Shims",
@@ -174,6 +183,7 @@
         "framework-connectivity",
         "framework-connectivity-t.stubs.module_lib",
         "framework-tethering",
+        "android.net.ipsec.ike.stubs.module_lib",
     ],
     sdk_version: "module_current",
     visibility: ["//visibility:private"],
diff --git a/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java b/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java
index a6ca1f1..3e7eb16 100644
--- a/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java
+++ b/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java
@@ -16,6 +16,11 @@
 
 package com.android.networkstack.apishim.api29;
 
+import android.os.Build;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
+
+import androidx.annotation.RequiresApi;
 import androidx.annotation.VisibleForTesting;
 
 /**
@@ -44,4 +49,16 @@
 
     // Constants defined in android.content.Context
     public static final String NEARBY_SERVICE = "nearby";
+
+    /** Compatibility class for {@link CarrierConfigManager}. */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    /** See {@link CarrierManager#KEY_CARRIER_SUPPORTS_TETHERING_BOOL} */
+    public static final String KEY_CARRIER_SUPPORTS_TETHERING_BOOL =
+            "carrier_supports_tethering_bool";
+
+    /** Compatibility class for {@link Settings}. */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    /** @see android.provider.Settings#ACTION_TETHER_UNSUPPORTED_CARRIER_UI */
+    public static final  String ACTION_TETHER_UNSUPPORTED_CARRIER_UI =
+            "android.settings.TETHER_UNSUPPORTED_CARRIER_UI";
 }
diff --git a/apishim/29/com/android/networkstack/apishim/api29/EthernetManagerShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/EthernetManagerShimImpl.java
new file mode 100644
index 0000000..2f5fb7d
--- /dev/null
+++ b/apishim/29/com/android/networkstack/apishim/api29/EthernetManagerShimImpl.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.api29;
+
+import android.content.Context;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.EthernetManagerShim;
+
+/**
+ * Implementation of {@link EthernetManagerShim} for API 29.
+ *
+ * Cannot actually import EthernetManager because that only became @SystemApi in API 30.
+ */
+@RequiresApi(Build.VERSION_CODES.Q)
+public class EthernetManagerShimImpl implements EthernetManagerShim {
+    /**
+     * Get a new instance of {@link EthernetManagerShim}.
+     */
+    public static EthernetManagerShim newInstance(Context context) {
+        return new EthernetManagerShimImpl();
+    }
+}
diff --git a/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileBuilderShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileBuilderShimImpl.java
index 754933a..ecf3f15 100644
--- a/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileBuilderShimImpl.java
+++ b/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileBuilderShimImpl.java
@@ -16,8 +16,11 @@
 
 package com.android.networkstack.apishim.api29;
 
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
 import com.android.networkstack.apishim.common.Ikev2VpnProfileBuilderShim;
-import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
 
 /**
  * Implementation of Ikev2VpnProfileBuilderShim for API 29.
@@ -29,13 +32,6 @@
 // NOTE : the trick with the formal parameter only works because when this shim was introduced,
 // the stable API already contained the class that the caller needs to pass in; this won't
 // work for a class added in the latest API level.
+@RequiresApi(Build.VERSION_CODES.Q)
 public class Ikev2VpnProfileBuilderShimImpl<T> implements Ikev2VpnProfileBuilderShim<T> {
-    /**
-     * @see Ikev2VpnProfile.Builder#setRequiresInternetValidation(boolean)
-     */
-    @Override
-    public T setRequiresInternetValidation(T builder,
-            boolean requiresInternetValidation) throws UnsupportedApiLevelException {
-        throw new UnsupportedApiLevelException("Only supported from API level 33.");
-    }
 }
diff --git a/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileShimImpl.java
index b3f5f43..0f8dae5 100644
--- a/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileShimImpl.java
+++ b/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileShimImpl.java
@@ -17,19 +17,10 @@
 package com.android.networkstack.apishim.api29;
 
 import com.android.networkstack.apishim.common.Ikev2VpnProfileShim;
-import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
 
 /**
  * Implementation of Ikev2VpnProfileShim for API 29.
  * @param <T> type of profile, typically Ikev2VpnProfile
  */
 public class Ikev2VpnProfileShimImpl<T> implements Ikev2VpnProfileShim<T> {
-    /**
-     * @see Ikev2VpnProfile#isInternetValidationRequired(boolean)
-     */
-    @Override
-    public boolean isInternetValidationRequired(T profile)
-            throws UnsupportedApiLevelException {
-        throw new UnsupportedApiLevelException("Only supported from API level 33.");
-    }
 }
diff --git a/apishim/29/com/android/networkstack/apishim/api29/NsdShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/NsdShimImpl.java
index b54746a..51cb2ba 100644
--- a/apishim/29/com/android/networkstack/apishim/api29/NsdShimImpl.java
+++ b/apishim/29/com/android/networkstack/apishim/api29/NsdShimImpl.java
@@ -29,6 +29,8 @@
 import com.android.networkstack.apishim.common.NsdShim;
 import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
 
+import java.util.concurrent.Executor;
+
 /**
  * Implementation of {@link NsdShim}.
  */
@@ -55,17 +57,33 @@
     }
 
     @Override
+    public void registerService(@NonNull NsdManager nsdManager, @NonNull NsdServiceInfo serviceInfo,
+            int protocolType, @NonNull Executor executor,
+            @NonNull NsdManager.RegistrationListener listener) throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Register with an executor is only supported on T+");
+    }
+
+    @Override
     public void discoverServices(@NonNull NsdManager nsdManager, @NonNull String serviceType,
             int protocolType, @Nullable Network network,
-            @NonNull NsdManager.DiscoveryListener listener) throws UnsupportedApiLevelException {
+            @NonNull Executor executor, @NonNull NsdManager.DiscoveryListener listener)
+            throws UnsupportedApiLevelException {
         throw new UnsupportedApiLevelException("Discover on network is only supported on T+");
     }
 
     @Override
     public void discoverServices(@NonNull NsdManager nsdManager, @NonNull String serviceType,
             int protocolType, @Nullable NetworkRequest request,
-            @NonNull NsdManager.DiscoveryListener listener) throws UnsupportedApiLevelException {
+            @NonNull Executor executor, @NonNull NsdManager.DiscoveryListener listener)
+            throws UnsupportedApiLevelException {
         throw new UnsupportedApiLevelException(
                 "Discover with NetworkRequest is only supported on T+");
     }
+
+    @Override
+    public void resolveService(@NonNull NsdManager nsdManager, @NonNull NsdServiceInfo serviceInfo,
+            @NonNull Executor executor, @NonNull NsdManager.ResolveListener resolveListener)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Resolve with executor is only supported on T+");
+    }
 }
diff --git a/apishim/29/com/android/networkstack/apishim/api29/ProcessShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/ProcessShimImpl.java
new file mode 100644
index 0000000..51fc06c
--- /dev/null
+++ b/apishim/29/com/android/networkstack/apishim/api29/ProcessShimImpl.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.networkstack.apishim.api29;
+
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.ProcessShim;
+
+/** Implementation of {@link ProcessShim} for API 29. */
+@RequiresApi(Build.VERSION_CODES.Q)
+public class ProcessShimImpl implements ProcessShim {
+
+    /** Get a new instance of {@link ProcessShim}. */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static ProcessShim newInstance() {
+        return new ProcessShimImpl();
+    }
+}
diff --git a/apishim/29/com/android/networkstack/apishim/api29/VpnManagerShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/VpnManagerShimImpl.java
new file mode 100644
index 0000000..fc7d052
--- /dev/null
+++ b/apishim/29/com/android/networkstack/apishim/api29/VpnManagerShimImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.api29;
+
+import android.content.Context;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+import com.android.networkstack.apishim.common.VpnManagerShim;
+
+/**
+ * Implementation of {@link VpnManagerShim} for API 29.
+ */
+@RequiresApi(Build.VERSION_CODES.Q)
+public class VpnManagerShimImpl implements VpnManagerShim {
+    protected VpnManagerShimImpl(Context context) {}
+
+    /**
+     * Get a new instance of {@link VpnManagerShim}.
+     */
+    public static VpnManagerShim newInstance(Context context) throws UnsupportedApiLevelException {
+        return new VpnManagerShimImpl(context);
+    }
+
+    /**
+     * See android.net.VpnManager#startProvisionedVpnProfileSession
+     */
+    @Override
+    public String startProvisionedVpnProfileSession() throws UnsupportedApiLevelException {
+        // Not supported for API 29.
+        throw new UnsupportedApiLevelException("Not supported in API 29.");
+    }
+}
diff --git a/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileBuilderShimImpl.java b/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileBuilderShimImpl.java
index a8310ce..7c126a3 100644
--- a/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileBuilderShimImpl.java
+++ b/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileBuilderShimImpl.java
@@ -17,21 +17,105 @@
 package com.android.networkstack.apishim.api30;
 
 import android.net.Ikev2VpnProfile;
+import android.net.ProxyInfo;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
 
 import com.android.networkstack.apishim.common.Ikev2VpnProfileBuilderShim;
+import com.android.networkstack.apishim.common.Ikev2VpnProfileShim;
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.util.List;
 
 /**
  * Implementation of Ikev2VpnProfileBuilderShim for API 30.
  */
 // TODO : when API29 is no longer supported, remove the type argument
+@RequiresApi(Build.VERSION_CODES.R)
 public class Ikev2VpnProfileBuilderShimImpl
         extends com.android.networkstack.apishim.api29.Ikev2VpnProfileBuilderShimImpl<
-                Ikev2VpnProfile.Builder
-        > {
+                Ikev2VpnProfile.Builder> {
+    protected Ikev2VpnProfile.Builder mBuilder;
+
+    protected Ikev2VpnProfileBuilderShimImpl(@Nullable String serverAddr,
+            @Nullable String identity, @Nullable Object params) {
+        if (serverAddr != null && identity != null) {
+            mBuilder = new Ikev2VpnProfile.Builder(serverAddr, identity);
+        }
+    }
     /**
      * Returns a new instance of this shim impl.
      */
-    public static Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> newInstance() {
-        return new Ikev2VpnProfileBuilderShimImpl();
+    public static Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> newInstance(
+            @Nullable String serverAddr, @Nullable String identity, @Nullable Object params) {
+        return new Ikev2VpnProfileBuilderShimImpl(serverAddr, identity, params);
+    }
+
+    @Override
+    public Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> setAuthPsk(@NonNull byte[] psk) {
+        mBuilder.setAuthPsk(psk);
+        return this;
+    }
+
+    @Override
+    public Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> setAuthUsernamePassword(
+            @NonNull String user, @NonNull String pass, @Nullable X509Certificate serverRootCa)
+            throws UnsupportedApiLevelException {
+        mBuilder.setAuthUsernamePassword(user, pass, serverRootCa);
+        return this;
+    }
+
+    @Override
+    public Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> setAuthDigitalSignature(
+            @NonNull X509Certificate userCert, @NonNull PrivateKey key,
+            @Nullable X509Certificate serverRootCa) {
+        mBuilder.setAuthDigitalSignature(userCert, key, serverRootCa);
+        return this;
+    }
+
+    @Override
+    public Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> setBypassable(boolean isBypassable) {
+        mBuilder.setBypassable(true);
+        return this;
+    }
+
+    @Override
+    public Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> setProxy(@Nullable ProxyInfo proxy) {
+        mBuilder.setProxy(proxy);
+        return this;
+    }
+
+    @Override
+    public Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> setMaxMtu(int mtu) {
+        mBuilder.setMaxMtu(mtu);
+        return this;
+    }
+
+    @Override
+    public Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> setMetered(boolean isMetered) {
+        mBuilder.setMetered(isMetered);
+        return this;
+    }
+
+    @Override
+    public Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> setAllowedAlgorithms(
+            @NonNull List<String> algorithmNames) {
+        mBuilder.setAllowedAlgorithms(algorithmNames);
+        return this;
+    }
+
+    @Override
+    public Ikev2VpnProfile.Builder getBuilder() {
+        return mBuilder;
+    }
+
+    @Override
+    public Ikev2VpnProfileShim build() {
+        return new Ikev2VpnProfileShimImpl(mBuilder.build());
     }
 }
diff --git a/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileShimImpl.java b/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileShimImpl.java
index cd7938f..71d68ab 100644
--- a/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileShimImpl.java
+++ b/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileShimImpl.java
@@ -18,18 +18,19 @@
 
 import android.net.Ikev2VpnProfile;
 
-import com.android.networkstack.apishim.common.Ikev2VpnProfileShim;
-
 /**
  * Implementation of Ikev2VpnProfileShim for API 30.
  */
 // TODO : when API29 is no longer supported, remove the type argument
 public class Ikev2VpnProfileShimImpl extends
         com.android.networkstack.apishim.api29.Ikev2VpnProfileShimImpl<Ikev2VpnProfile> {
-    /**
-     * Returns a new instance of this shim impl.
-     */
-    public static Ikev2VpnProfileShim<Ikev2VpnProfile> newInstance() {
-        return new Ikev2VpnProfileShimImpl();
+    protected Ikev2VpnProfile mProfile;
+
+    public Ikev2VpnProfileShimImpl(Ikev2VpnProfile profile) {
+        mProfile = profile;
+    }
+
+    public Ikev2VpnProfile getProfile() {
+        return mProfile;
     }
 }
diff --git a/apishim/30/com/android/networkstack/apishim/api30/VpnManagerShimImpl.java b/apishim/30/com/android/networkstack/apishim/api30/VpnManagerShimImpl.java
new file mode 100644
index 0000000..f52b5a8
--- /dev/null
+++ b/apishim/30/com/android/networkstack/apishim/api30/VpnManagerShimImpl.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.api30;
+
+import static com.android.modules.utils.build.SdkLevel.isAtLeastR;
+
+import android.content.Context;
+import android.net.VpnManager;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+import com.android.networkstack.apishim.common.VpnManagerShim;
+
+/**
+ * Implementation of {@link VpnManagerShim} for API 30.
+ */
+@RequiresApi(Build.VERSION_CODES.R)
+public class VpnManagerShimImpl extends com.android.networkstack.apishim.api29.VpnManagerShimImpl {
+    protected final VpnManager mVm;
+    protected VpnManagerShimImpl(Context context) {
+        super(context);
+        mVm = context.getSystemService(VpnManager.class);
+    }
+
+    /**
+     * Get a new instance of {@link VpnManagerShimImpl}.
+     */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static VpnManagerShim newInstance(Context context) throws UnsupportedApiLevelException {
+        if (!isAtLeastR()) {
+            return com.android.networkstack.apishim.api29.VpnManagerShimImpl.newInstance(context);
+        }
+        return new VpnManagerShimImpl(context);
+    }
+
+    /**
+     * See android.net.VpnManager#startProvisionedVpnProfileSession
+     */
+    @Override
+    public String startProvisionedVpnProfileSession() throws UnsupportedApiLevelException {
+        // Not supported for API 30.
+        throw new UnsupportedApiLevelException("Not supported in API 30.");
+    }
+}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/EthernetManagerShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/EthernetManagerShimImpl.java
new file mode 100644
index 0000000..2c93d7c
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/EthernetManagerShimImpl.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.api31;
+
+import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
+
+import android.content.Context;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.EthernetManagerShim;
+
+/**
+ * Implementation of {@link EthernetManagerShim} for API 31.
+ *
+ * Doesn't have any methods, but must exist because the stable shim API level is currently 31.
+ * TODO: delete when the stable shim API level becomes 33.
+ */
+@RequiresApi(Build.VERSION_CODES.S)
+public class EthernetManagerShimImpl
+        extends com.android.networkstack.apishim.api29.EthernetManagerShimImpl {
+    /**
+     * Get a new instance of {@link EthernetManagerShim}.
+     */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static EthernetManagerShim newInstance(Context context) {
+        if (!isAtLeastS()) {
+            return com.android.networkstack.apishim.api29.EthernetManagerShimImpl
+                    .newInstance(context);
+        }
+        return new EthernetManagerShimImpl();
+    }
+}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileBuilderShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileBuilderShimImpl.java
index d4f25d6..de60ff3 100644
--- a/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileBuilderShimImpl.java
+++ b/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileBuilderShimImpl.java
@@ -16,9 +16,19 @@
 
 package com.android.networkstack.apishim.api31;
 
+import android.os.Build;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
 /**
  * Implementation of Ikev2VpnProfileBuilderShim for API 31.
  */
+@RequiresApi(Build.VERSION_CODES.S)
 public class Ikev2VpnProfileBuilderShimImpl
         extends com.android.networkstack.apishim.api30.Ikev2VpnProfileBuilderShimImpl {
+    protected Ikev2VpnProfileBuilderShimImpl(@Nullable String serverAddr,
+            @Nullable String identity, @Nullable Object params) {
+        super(serverAddr, identity, params);
+    }
 }
diff --git a/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileShimImpl.java
index e2d8b59..1a9e332 100644
--- a/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileShimImpl.java
+++ b/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileShimImpl.java
@@ -16,9 +16,14 @@
 
 package com.android.networkstack.apishim.api31;
 
+import android.net.Ikev2VpnProfile;
+
 /**
  * Implementation of Ikev2VpnProfileShim for API 31.
  */
 public class Ikev2VpnProfileShimImpl extends
         com.android.networkstack.apishim.api30.Ikev2VpnProfileShimImpl {
+    public Ikev2VpnProfileShimImpl(Ikev2VpnProfile profile) {
+        super(profile);
+    }
 }
diff --git a/apishim/31/com/android/networkstack/apishim/api31/NetworkAgentConfigShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/NetworkAgentConfigShimImpl.java
index 908cc1d..ac97c60 100644
--- a/apishim/31/com/android/networkstack/apishim/api31/NetworkAgentConfigShimImpl.java
+++ b/apishim/31/com/android/networkstack/apishim/api31/NetworkAgentConfigShimImpl.java
@@ -20,6 +20,7 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.modules.utils.build.SdkLevel;
 import com.android.networkstack.apishim.common.NetworkAgentConfigShim;
 
 /**
@@ -42,6 +43,14 @@
      * Returns a new instance of this shim impl.
      */
     public static NetworkAgentConfigShim newInstance(@Nullable final NetworkAgentConfig config) {
-        return new NetworkAgentConfigShimImpl(config);
+        if (!SdkLevel.isAtLeastS()) {
+            return new NetworkAgentConfigShimImpl(null);
+        }
+        return new NetworkAgentConfigShimImpl(
+                (config != null) ? config : new NetworkAgentConfig.Builder().build());
+    }
+
+    public NetworkAgentConfig getConfig() {
+        return mNetworkAgentConfig;
     }
 }
diff --git a/apishim/31/com/android/networkstack/apishim/api31/ProcessShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/ProcessShimImpl.java
new file mode 100644
index 0000000..e5f2622
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/ProcessShimImpl.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.networkstack.apishim.api31;
+
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.networkstack.apishim.common.ProcessShim;
+
+/** Implementation of {@link ProcessShim} for API 31. */
+@RequiresApi(Build.VERSION_CODES.S)
+public class ProcessShimImpl implements ProcessShim {
+
+    /** Get a new instance of {@link ProcessShim}. */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static ProcessShim newInstance() {
+        if (!SdkLevel.isAtLeastS()) {
+            return com.android.networkstack.apishim.api29.ProcessShimImpl.newInstance();
+        } else {
+            return new ProcessShimImpl();
+        }
+    }
+}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/VpnManagerShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/VpnManagerShimImpl.java
new file mode 100644
index 0000000..91aedd7
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/VpnManagerShimImpl.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.api31;
+
+import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
+
+import android.content.Context;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+import com.android.networkstack.apishim.common.VpnManagerShim;
+
+/**
+ * Implementation of {@link VpnManagerShim} for API 31.
+ */
+@RequiresApi(Build.VERSION_CODES.S)
+public class VpnManagerShimImpl extends com.android.networkstack.apishim.api30.VpnManagerShimImpl {
+    protected VpnManagerShimImpl(Context context) {
+        super(context);
+    }
+
+    /**
+     * Get a new instance of {@link com.android.networkstack.apishim.api30.VpnManagerShimImpl}.
+     */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static VpnManagerShim newInstance(Context context) throws UnsupportedApiLevelException {
+        if (!isAtLeastS()) {
+            return com.android.networkstack.apishim.api30.VpnManagerShimImpl.newInstance(context);
+        }
+        return new VpnManagerShimImpl(context);
+    }
+
+    /**
+     * See android.net.VpnManager#startProvisionedVpnProfileSession
+     */
+    @Override
+    public String startProvisionedVpnProfileSession() throws UnsupportedApiLevelException {
+        // Not supported for API 31.
+        throw new UnsupportedApiLevelException("Not supported in API 31.");
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/EthernetManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/EthernetManagerShimImpl.java
new file mode 100644
index 0000000..82a8f35
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/EthernetManagerShimImpl.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim;
+
+import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
+
+import android.content.Context;
+import android.net.EthernetManager;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.EthernetManagerShim;
+
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+
+/**
+ * Implementation of {@link EthernetManagerShim} for API 33.
+ */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class EthernetManagerShimImpl
+        extends com.android.networkstack.apishim.api31.EthernetManagerShimImpl {
+
+    protected final EthernetManager mEm;
+
+    // This is needed because callers of the shim cannot use EthernetManager.InterfaceStateListener,
+    // they need to use EthernetManagerShim.InterfaceStateListener instead. But when actually
+    // registering a callback, the callback type passed to EthernetManager must be a real
+    // listener, not a shim. This map keeps track of the mapping between the two objects so that
+    // when a caller calls removeInterfaceStateListener with a shim listener, this class knows what
+    // real listener to pass to EthernetManager.
+    private final ConcurrentHashMap<InterfaceStateListener, EthernetManager.InterfaceStateListener>
+            mListeners = new ConcurrentHashMap<>();
+
+    protected EthernetManagerShimImpl(Context context) {
+        mEm = context.getSystemService(EthernetManager.class);
+    }
+
+    /**
+     * Get a new instance of {@link EthernetManagerShim}.
+     */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static EthernetManagerShim newInstance(Context context) {
+        if (!isAtLeastT()) {
+            return com.android.networkstack.apishim.api31.EthernetManagerShimImpl
+                    .newInstance(context);
+        }
+        return new EthernetManagerShimImpl(context);
+    }
+
+    @Override
+    public void addInterfaceStateListener(@NonNull Executor executor,
+            @NonNull InterfaceStateListener listener) {
+        final EthernetManager.InterfaceStateListener wrapper = (a, b, c, d) -> {
+            listener.onInterfaceStateChanged(a, b, c, d);
+        };
+        // EthernetManager#addInterfaceStateListener will allow registering the same listener twice,
+        // but this does not seem very useful and is difficult to support with the wrapper scheme
+        // used by this shim. Don't allow it.
+        final EthernetManager.InterfaceStateListener existing =
+                mListeners.putIfAbsent(listener, wrapper);
+        if (existing != null) {
+            throw new IllegalStateException("Attempt to register duplicate listener");
+        }
+        mEm.addInterfaceStateListener(executor, wrapper);
+    }
+
+    @Override
+    public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) {
+        final EthernetManager.InterfaceStateListener wrapper = mListeners.remove(listener);
+        if (wrapper != null) {
+            mEm.removeInterfaceStateListener(wrapper);
+        }
+    }
+
+    @Override
+    // This method existed in R and S, but as @TestApi, so should not appear in the shims before T
+    // because otherwise it could be used by production code on R and S.
+    public void setIncludeTestInterfaces(boolean include) {
+        mEm.setIncludeTestInterfaces(include);
+    }
+
+    @Override
+    @NonNull
+    public List<String> getInterfaceList() {
+        return mEm.getInterfaceList();
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java b/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java
index d3315a2..634b6b5 100644
--- a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java
@@ -17,9 +17,10 @@
 package com.android.networkstack.apishim;
 
 import android.net.Ikev2VpnProfile;
+import android.net.ipsec.ike.IkeTunnelConnectionParams;
 import android.os.Build;
 
-import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 
 import com.android.modules.utils.build.SdkLevel;
@@ -31,16 +32,36 @@
 @RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class Ikev2VpnProfileBuilderShimImpl
         extends com.android.networkstack.apishim.api31.Ikev2VpnProfileBuilderShimImpl {
+    private Ikev2VpnProfileBuilderShimImpl(@Nullable String serverAddr,
+            @Nullable String identity, @Nullable Object params) {
+        super(serverAddr, identity, params);
+
+        if (serverAddr == null && identity == null && params == null) {
+            throw new IllegalArgumentException(
+                    "serverAddr, identity and params should not be all null");
+        }
+        // Support building the Builder with an IkeTunnelConnectionParams from API 33.
+        if (params != null) {
+            if (!(params instanceof IkeTunnelConnectionParams)) {
+                throw new IllegalArgumentException("params should be an IkeTunnelConnectionParams");
+            }
+            mBuilder = new Ikev2VpnProfile.Builder((IkeTunnelConnectionParams) params);
+        } else {
+            mBuilder = new Ikev2VpnProfile.Builder(serverAddr, identity);
+        }
+    }
+
     /**
      * Returns a new instance of this shim impl.
      */
     @RequiresApi(Build.VERSION_CODES.R)
-    public static Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> newInstance() {
+    public static Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> newInstance(
+            @Nullable String serverAddr, @Nullable String identity, @Nullable Object params) {
         if (SdkLevel.isAtLeastT()) {
-            return new Ikev2VpnProfileBuilderShimImpl();
+            return new Ikev2VpnProfileBuilderShimImpl(serverAddr, identity, params);
         } else {
             return com.android.networkstack.apishim.api31.Ikev2VpnProfileBuilderShimImpl
-                    .newInstance();
+                    .newInstance(serverAddr, identity, params);
         }
     }
 
@@ -48,9 +69,19 @@
      * @see Ikev2VpnProfile.Builder#setRequiresInternetValidation(boolean)
      */
     @Override
-    public Ikev2VpnProfile.Builder setRequiresInternetValidation(
-            @NonNull final Ikev2VpnProfile.Builder builder, boolean requiresInternetValidation) {
-        builder.setRequiresInternetValidation(requiresInternetValidation);
-        return builder;
+    public Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> setRequiresInternetValidation(
+            boolean requiresInternetValidation) {
+        mBuilder.setRequiresInternetValidation(requiresInternetValidation);
+        return this;
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setLocalRoutesExcluded(boolean)
+     */
+    @Override
+    public Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> setLocalRoutesExcluded(
+            boolean excludeLocalRoutes) {
+        mBuilder.setLocalRoutesExcluded(excludeLocalRoutes);
+        return this;
     }
 }
diff --git a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java b/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
index ccaf497..c3e35d3 100644
--- a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
@@ -19,35 +19,31 @@
 import android.net.Ikev2VpnProfile;
 import android.os.Build;
 
-import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 
-import com.android.modules.utils.build.SdkLevel;
-import com.android.networkstack.apishim.common.Ikev2VpnProfileShim;
-
 /**
  * A shim for Ikev2VpnProfile
  */
 @RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class Ikev2VpnProfileShimImpl
         extends com.android.networkstack.apishim.api31.Ikev2VpnProfileShimImpl {
-    /**
-     * Returns a new instance of this shim impl.
-     */
-    @RequiresApi(Build.VERSION_CODES.R)
-    public static Ikev2VpnProfileShim<Ikev2VpnProfile> newInstance() {
-        if (SdkLevel.isAtLeastT()) {
-            return new Ikev2VpnProfileShimImpl();
-        } else {
-            return com.android.networkstack.apishim.api31.Ikev2VpnProfileShimImpl.newInstance();
-        }
+    public Ikev2VpnProfileShimImpl(Ikev2VpnProfile profile) {
+       super(profile);
     }
 
     /**
      * @see Ikev2VpnProfile#isInternetValidationRequired()
      */
     @Override
-    public boolean isInternetValidationRequired(@NonNull final Ikev2VpnProfile profile) {
-        return profile.isInternetValidationRequired();
+    public boolean isInternetValidationRequired() {
+        return mProfile.isInternetValidationRequired();
+    }
+
+    /**
+     * @see Ikev2VpnProfile#getIkeTunnelConnectionParams()
+     */
+    @Override
+    public Object getIkeTunnelConnectionParams() {
+        return mProfile.getIkeTunnelConnectionParams();
     }
 }
diff --git a/apishim/33/com/android/networkstack/apishim/NsdShimImpl.java b/apishim/33/com/android/networkstack/apishim/NsdShimImpl.java
index bee56d3..2f13397 100644
--- a/apishim/33/com/android/networkstack/apishim/NsdShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/NsdShimImpl.java
@@ -30,6 +30,8 @@
 import com.android.networkstack.apishim.common.NsdShim;
 import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
 
+import java.util.concurrent.Executor;
+
 /**
  * Implementation of {@link com.android.networkstack.apishim.common.NsdShim}.
  */
@@ -60,16 +62,32 @@
     }
 
     @Override
+    public void registerService(@NonNull NsdManager nsdManager, @NonNull NsdServiceInfo serviceInfo,
+            int protocolType, @NonNull Executor executor,
+            @NonNull NsdManager.RegistrationListener listener) {
+        nsdManager.registerService(serviceInfo, protocolType, executor, listener);
+    }
+
+    @Override
     public void discoverServices(@NonNull NsdManager nsdManager, @NonNull String serviceType,
             int protocolType, @Nullable Network network,
-            @NonNull NsdManager.DiscoveryListener listener) throws UnsupportedApiLevelException {
-        nsdManager.discoverServices(serviceType, protocolType, network, listener);
+            @NonNull Executor executor, @NonNull NsdManager.DiscoveryListener listener)
+            throws UnsupportedApiLevelException {
+        nsdManager.discoverServices(serviceType, protocolType, network, executor, listener);
     }
 
     @Override
     public void discoverServices(@NonNull NsdManager nsdManager, @NonNull String serviceType,
             int protocolType, @Nullable NetworkRequest request,
-            @NonNull NsdManager.DiscoveryListener listener) throws UnsupportedApiLevelException {
-        nsdManager.discoverServices(serviceType, protocolType, request, listener);
+            @NonNull Executor executor, @NonNull NsdManager.DiscoveryListener listener)
+            throws UnsupportedApiLevelException {
+        nsdManager.discoverServices(serviceType, protocolType, request, executor, listener);
+    }
+
+    @Override
+    public void resolveService(@NonNull NsdManager nsdManager, @NonNull NsdServiceInfo serviceInfo,
+            @NonNull Executor executor, @NonNull NsdManager.ResolveListener resolveListener)
+            throws UnsupportedApiLevelException {
+        nsdManager.resolveService(serviceInfo, executor, resolveListener);
     }
 }
diff --git a/apishim/33/com/android/networkstack/apishim/ProcessShimImpl.java b/apishim/33/com/android/networkstack/apishim/ProcessShimImpl.java
new file mode 100644
index 0000000..882dfbf
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/ProcessShimImpl.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.networkstack.apishim;
+
+import android.os.Build;
+import android.os.Process;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.networkstack.apishim.common.ProcessShim;
+
+/** Implementation of {@link ProcessShim} for API 33. */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class ProcessShimImpl implements ProcessShim {
+
+    /** Get a new instance of {@link ProcessShim}. */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static ProcessShim newInstance() {
+        if (!SdkLevel.isAtLeastT()) {
+            return com.android.networkstack.apishim.api31.ProcessShimImpl.newInstance();
+        } else {
+            return new ProcessShimImpl();
+        }
+    }
+
+    /**
+     * @see Process#toSdkSandboxUid(int)
+     */
+    @Override
+    public int toSdkSandboxUid(int applicationUid) {
+        return Process.toSdkSandboxUid(applicationUid);
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/TelephonyManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/TelephonyManagerShimImpl.java
index 98e061d..3912616 100644
--- a/apishim/33/com/android/networkstack/apishim/TelephonyManagerShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/TelephonyManagerShimImpl.java
@@ -16,9 +16,11 @@
 
 package com.android.networkstack.apishim;
 
+import static com.android.net.module.util.CollectionUtils.toIntArray;
+
 import android.os.Build;
 import android.telephony.TelephonyManager;
-import android.telephony.TelephonyManager.CarrierPrivilegesListener;
+import android.telephony.TelephonyManager.CarrierPrivilegesCallback;
 
 import androidx.annotation.RequiresApi;
 
@@ -27,6 +29,7 @@
 
 import java.util.HashMap;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.Executor;
 
 /**
@@ -35,34 +38,41 @@
 @RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class TelephonyManagerShimImpl extends
         com.android.networkstack.apishim.api31.TelephonyManagerShimImpl {
-    private HashMap<CarrierPrivilegesListenerShim, CarrierPrivilegesListener> mListenerMap =
+    private HashMap<CarrierPrivilegesListenerShim, CarrierPrivilegesCallback> mListenerMap =
             new HashMap<>();
     public TelephonyManagerShimImpl(TelephonyManager telephonyManager) {
         super(telephonyManager);
     }
 
-    /** See android.telephony.TelephonyManager#addCarrierPrivilegesListener */
+    /** See android.telephony.TelephonyManager#registerCarrierPrivilegesCallback */
     public void addCarrierPrivilegesListener(
             int logicalSlotIndex,
             Executor executor,
             CarrierPrivilegesListenerShim listener)
             throws UnsupportedApiLevelException {
-        CarrierPrivilegesListener carrierPrivilegesListener = new CarrierPrivilegesListener() {
+        CarrierPrivilegesCallback carrierPrivilegesCallback = new CarrierPrivilegesCallback() {
             public void onCarrierPrivilegesChanged(
-                    List<String> privilegedPackageNames,
-                    int[] privilegedUids) {
-                listener.onCarrierPrivilegesChanged(privilegedPackageNames, privilegedUids);
+                    Set<String> privilegedPackageNames,
+                    Set<Integer> privilegedUids) {
+                // TODO(b/221306368): Rebuild thoroughly based on onCarrierServiceChanged interface
+                // This is the minimum change to remove the dependency on the obsoleted API in
+                // CarrierPrivilegesListener. A follow-up CL should refactor Connectivity modules
+                // with carrier service change API instead.
+                List<String> pkgNames = List.copyOf(privilegedPackageNames);
+                int[] pkgUids = toIntArray(privilegedUids);
+                listener.onCarrierPrivilegesChanged(pkgNames, pkgUids);
             }
         };
-        mTm.addCarrierPrivilegesListener(logicalSlotIndex, executor, carrierPrivilegesListener);
-        mListenerMap.put(listener, carrierPrivilegesListener);
+        mTm.registerCarrierPrivilegesCallback(logicalSlotIndex, executor,
+                carrierPrivilegesCallback);
+        mListenerMap.put(listener, carrierPrivilegesCallback);
     }
 
-    /** See android.telephony.TelephonyManager#addCarrierPrivilegesListener */
+    /** See android.telephony.TelephonyManager#unregisterCarrierPrivilegesCallback */
     public void removeCarrierPrivilegesListener(
             CarrierPrivilegesListenerShim listener)
             throws UnsupportedApiLevelException {
-        mTm.removeCarrierPrivilegesListener(mListenerMap.get(listener));
+        mTm.unregisterCarrierPrivilegesCallback(mListenerMap.get(listener));
         mListenerMap.remove(listener);
     }
 
diff --git a/apishim/33/com/android/networkstack/apishim/VpnManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/VpnManagerShimImpl.java
new file mode 100644
index 0000000..c1a879e
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/VpnManagerShimImpl.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim;
+
+import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
+
+import android.content.Context;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+import com.android.networkstack.apishim.common.VpnManagerShim;
+
+/**
+ * Compatibility implementation of {@link VpnManagerShim}.
+ */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class VpnManagerShimImpl extends com.android.networkstack.apishim.api31.VpnManagerShimImpl {
+
+    protected VpnManagerShimImpl(Context context) {
+        super(context);
+    }
+
+    /**
+     * Get a new instance of {@link VpnManagerShimImpl}.
+     */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static VpnManagerShim newInstance(Context context) throws UnsupportedApiLevelException {
+        if (!isAtLeastT()) {
+            return com.android.networkstack.apishim.api31.VpnManagerShimImpl.newInstance(context);
+        }
+        return new VpnManagerShimImpl(context);
+    }
+
+    /**
+     * See android.net.VpnManager#startProvisionedVpnProfileSession
+     */
+    @Override
+    public String startProvisionedVpnProfileSession() {
+        return mVm.startProvisionedVpnProfileSession();
+    }
+}
diff --git a/apishim/common/com/android/networkstack/apishim/common/EthernetManagerShim.java b/apishim/common/com/android/networkstack/apishim/common/EthernetManagerShim.java
new file mode 100644
index 0000000..02a08de
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/EthernetManagerShim.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.common;
+
+import android.net.IpConfiguration;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/** API shim for EthernetManager */
+public interface EthernetManagerShim {
+    int STATE_ABSENT = 0;
+    int STATE_LINK_DOWN = 1;
+    int STATE_LINK_UP = 2;
+    int ROLE_NONE = 0;
+    int ROLE_CLIENT = 1;
+    int ROLE_SERVER = 2;
+
+    /** Shim for EthernetManager#InterfaceStateListener. */
+    interface InterfaceStateListener {
+        void onInterfaceStateChanged(@NonNull String iface, int state, int role,
+                @Nullable IpConfiguration configuration);
+    }
+
+    /** Shim for EthernetManager#addInterfaceStateListener */
+    default void addInterfaceStateListener(@NonNull Executor executor,
+            @NonNull InterfaceStateListener listener) throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException();
+    }
+
+    /** Shim for EthernetManager#removeInterfaceStateListener */
+    default void removeInterfaceStateListener(@NonNull InterfaceStateListener listener)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Not supported until API 33");
+    }
+
+    /** Shim for EthernetManager#setIncludeTestInterfaces */
+    default void setIncludeTestInterfaces(boolean include) throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Not supported until API 30");
+    }
+
+    /** Shim for EthernetManager#getInterfaceList */
+    default List<String> getInterfaceList() throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Not supported until API 33");
+    }
+}
diff --git a/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileBuilderShim.java b/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileBuilderShim.java
index b2483e3..0ad989e 100644
--- a/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileBuilderShim.java
+++ b/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileBuilderShim.java
@@ -16,6 +16,16 @@
 
 package com.android.networkstack.apishim.common;
 
+import android.net.ProxyInfo;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+
 /**
  * A shim for Ikev2VpnProfile.Builder.
  *
@@ -28,6 +38,96 @@
     /**
      * @see Ikev2VpnProfile.Builder#setRequiresInternetValidation(boolean)
      */
-    T setRequiresInternetValidation(T builder, boolean requiresInternetValidation)
-            throws UnsupportedApiLevelException;
+    default Ikev2VpnProfileBuilderShim<T> setRequiresInternetValidation(
+            boolean requiresInternetValidation) throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 33");
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setAuthPsk(byte[])
+     */
+    default Ikev2VpnProfileBuilderShim<T> setAuthPsk(@NonNull byte[] psk)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 30");
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setAuthUsernamePassword(String, String, X509Certificate)
+     */
+    default Ikev2VpnProfileBuilderShim<T> setAuthUsernamePassword(@NonNull String user,
+            @NonNull String pass, @Nullable X509Certificate serverRootCa)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 30");
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setAuthDigitalSignature(X509Certificate, PrivateKey,
+     *      X509Certificate)
+     */
+    default Ikev2VpnProfileBuilderShim<T> setAuthDigitalSignature(@NonNull X509Certificate userCert,
+            @NonNull PrivateKey key, @Nullable X509Certificate serverRootCa)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 30");
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setBypassable(boolean)
+     */
+    default Ikev2VpnProfileBuilderShim<T> setBypassable(boolean isBypassable)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 30");
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setProxy(ProxyInfo)
+     */
+    default Ikev2VpnProfileBuilderShim<T> setProxy(@Nullable ProxyInfo proxy)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 30");
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setMaxMtu(int)
+     */
+    default Ikev2VpnProfileBuilderShim<T> setMaxMtu(int mtu) throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 30");
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setMetered(boolean)
+     */
+    default Ikev2VpnProfileBuilderShim<T> setMetered(boolean isMetered)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 30");
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setAllowedAlgorithms(List<String>)
+     */
+    default Ikev2VpnProfileBuilderShim<T> setAllowedAlgorithms(@NonNull List<String> algorithmNames)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 30");
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setLocalRoutesExcluded(boolean)
+     */
+    default Ikev2VpnProfileBuilderShim<T> setLocalRoutesExcluded(boolean excludeLocalRoutes)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 33");
+    }
+
+    /**
+     * Get <T> type of builder, typically Ikev2VpnProfile.Builder
+     */
+    default T getBuilder() throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 30");
+    }
+
+    /**
+     * Build an Ikev2VpnProfileShim
+     */
+    default Ikev2VpnProfileShim build() throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 30");
+    }
 }
diff --git a/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileShim.java b/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileShim.java
index 4a79c43..a29c5bf 100644
--- a/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileShim.java
+++ b/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileShim.java
@@ -28,5 +28,21 @@
     /**
      * @see Ikev2VpnProfile#isInternetValidationRequired()
      */
-    boolean isInternetValidationRequired(T profile) throws UnsupportedApiLevelException;
+    default boolean isInternetValidationRequired() throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API level 33.");
+    }
+
+    /**
+     * @see Ikev2VpnProfile#getIkeTunnelConnectionParams()
+     */
+    default Object getIkeTunnelConnectionParams() throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API level 33.");
+    }
+
+    /**
+     * Return the <T> type of profile.
+     */
+    default T getProfile() throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API level 30.");
+    }
 }
diff --git a/apishim/common/com/android/networkstack/apishim/common/NetworkAgentConfigShim.java b/apishim/common/com/android/networkstack/apishim/common/NetworkAgentConfigShim.java
index fb0e545..da60300 100644
--- a/apishim/common/com/android/networkstack/apishim/common/NetworkAgentConfigShim.java
+++ b/apishim/common/com/android/networkstack/apishim/common/NetworkAgentConfigShim.java
@@ -26,4 +26,11 @@
      * @see NetworkAgentConfig#isVpnValidationRequired()
      */
     boolean isVpnValidationRequired();
+
+    /**
+     * Return the config.
+     */
+    default NetworkAgentConfig getConfig() throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported from API 31");
+    }
 }
diff --git a/apishim/common/com/android/networkstack/apishim/common/NsdShim.java b/apishim/common/com/android/networkstack/apishim/common/NsdShim.java
index ff5209e..9e067ee 100644
--- a/apishim/common/com/android/networkstack/apishim/common/NsdShim.java
+++ b/apishim/common/com/android/networkstack/apishim/common/NsdShim.java
@@ -19,11 +19,16 @@
 import android.net.Network;
 import android.net.NetworkRequest;
 import android.net.nsd.NsdManager;
+import android.net.nsd.NsdManager.DiscoveryListener;
+import android.net.nsd.NsdManager.RegistrationListener;
+import android.net.nsd.NsdManager.ResolveListener;
 import android.net.nsd.NsdServiceInfo;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import java.util.concurrent.Executor;
+
 /** Shim for NSD APIs, including {@link android.net.nsd.NsdManager} and
  * {@link android.net.nsd.NsdServiceInfo}. */
 public interface NsdShim {
@@ -39,16 +44,32 @@
     void setNetwork(@NonNull NsdServiceInfo serviceInfo, @Nullable Network network);
 
     /**
-     * @see NsdManager#discoverServices(String, int, Network, NsdManager.DiscoveryListener)
+     * @see NsdManager#registerService(NsdServiceInfo, int, Executor, RegistrationListener)
+     */
+    void registerService(@NonNull NsdManager nsdManager, @NonNull NsdServiceInfo serviceInfo,
+            int protocolType, @NonNull Executor executor, @NonNull RegistrationListener listener)
+            throws UnsupportedApiLevelException;
+
+    /**
+     * @see NsdManager#discoverServices(String, int, Network, Executor, DiscoveryListener)
      */
     void discoverServices(@NonNull NsdManager nsdManager, @NonNull String serviceType,
             int protocolType, @Nullable Network network,
-            @NonNull NsdManager.DiscoveryListener listener) throws UnsupportedApiLevelException;
+            @NonNull Executor executor, @NonNull DiscoveryListener listener)
+            throws UnsupportedApiLevelException;
 
     /**
-     * @see NsdManager#discoverServices(String, int, NetworkRequest, NsdManager.DiscoveryListener)
+     * @see NsdManager#resolveService(NsdServiceInfo, Executor, ResolveListener)
+     */
+    void resolveService(@NonNull NsdManager nsdManager, @NonNull NsdServiceInfo serviceInfo,
+            @NonNull Executor executor, @NonNull ResolveListener resolveListener)
+            throws UnsupportedApiLevelException;
+
+    /**
+     * @see NsdManager#discoverServices(String, int, NetworkRequest, Executor, DiscoveryListener)
      */
     void discoverServices(@NonNull NsdManager nsdManager, @NonNull String serviceType,
             int protocolType, @Nullable NetworkRequest request,
-            @NonNull NsdManager.DiscoveryListener listener) throws UnsupportedApiLevelException;
+            @NonNull Executor executor, @NonNull DiscoveryListener listener)
+            throws UnsupportedApiLevelException;
 }
diff --git a/apishim/common/com/android/networkstack/apishim/common/ProcessShim.java b/apishim/common/com/android/networkstack/apishim/common/ProcessShim.java
new file mode 100644
index 0000000..5922ac7
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/ProcessShim.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.networkstack.apishim.common;
+
+import android.os.Process;
+
+/** API shim for Process. */
+public interface ProcessShim {
+    /**
+     * @see Process#toSdkSandboxUid(int)
+     */
+    default int toSdkSandboxUid(int applicationUid) {
+        return Process.INVALID_UID;
+    }
+}
diff --git a/apishim/common/com/android/networkstack/apishim/common/VpnManagerShim.java b/apishim/common/com/android/networkstack/apishim/common/VpnManagerShim.java
new file mode 100644
index 0000000..7ef0270
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/VpnManagerShim.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.common;
+
+/**
+ * Interface used to access API methods in {@link android.net.VpnManager}, with
+ * appropriate fallbacks if the methods are not yet part of the released API.
+ */
+public interface VpnManagerShim {
+    /** See android.net.VpnManager#startProvisionedVpnProfileSession */
+    String startProvisionedVpnProfileSession() throws UnsupportedApiLevelException;
+}
diff --git a/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java b/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java
index b151cb9..583a356 100644
--- a/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java
+++ b/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java
@@ -26,9 +26,11 @@
 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
+import android.annotation.NonNull;
 import android.net.NetworkCapabilities;
 
 import com.android.modules.utils.build.SdkLevel;
+import com.android.networkstack.apishim.common.NetworkAgentConfigShim;
 
 /** @hide */
 public class NetworkMonitorUtils {
@@ -67,9 +69,7 @@
      * Return whether validation is required for private DNS in strict mode.
      * @param nc Network capabilities of the network to test.
      */
-    public static boolean isPrivateDnsValidationRequired(NetworkCapabilities nc) {
-        if (nc == null) return false;
-
+    public static boolean isPrivateDnsValidationRequired(@NonNull final NetworkCapabilities nc) {
         final boolean isVcnManaged = SdkLevel.isAtLeastS()
                 && !nc.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         final boolean isOemPaid = nc.hasCapability(NET_CAPABILITY_OEM_PAID)
@@ -100,10 +100,15 @@
 
     /**
      * Return whether validation is required for a network.
+     * @param config Configuration of the network to test.
      * @param nc Network capabilities of the network to test.
      */
-    public static boolean isValidationRequired(NetworkCapabilities nc) {
+    public static boolean isValidationRequired(@NonNull final NetworkAgentConfigShim config,
+            @NonNull final NetworkCapabilities nc) {
         // TODO: Consider requiring validation for DUN networks.
-        return isPrivateDnsValidationRequired(nc) && nc.hasCapability(NET_CAPABILITY_NOT_VPN);
+        if (!nc.hasCapability(NET_CAPABILITY_NOT_VPN)) {
+            return config.isVpnValidationRequired();
+        }
+        return isPrivateDnsValidationRequired(nc);
     }
 }
diff --git a/common/networkstackclient/Android.bp b/common/networkstackclient/Android.bp
index 6e44450..53477ac 100644
--- a/common/networkstackclient/Android.bp
+++ b/common/networkstackclient/Android.bp
@@ -143,6 +143,7 @@
         "12",
         "13",
         "14",
+        "15",
     ],
     // TODO: have tethering depend on networkstack-client and set visibility to private
     visibility: [
@@ -158,7 +159,7 @@
     min_sdk_version: "29",
     static_libs: [
         "ipmemorystore-aidl-interfaces-V10-java",
-        "networkstack-aidl-interfaces-V14-java",
+        "networkstack-aidl-interfaces-V15-java",
     ],
     visibility: ["//packages/modules/NetworkStack:__subpackages__"],
     apex_available: [
@@ -207,6 +208,7 @@
     ],
     apex_available: [
         "//apex_available:platform",
+        "com.android.bluetooth",
         "com.android.tethering",
     ],
 }
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/.hash b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/.hash
new file mode 100644
index 0000000..1355b3f
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/.hash
@@ -0,0 +1 @@
+c7a085b65072b36dc02239895cac021b6daee530
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/DataStallReportParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/DataStallReportParcelable.aidl
new file mode 100644
index 0000000..771deda
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/DataStallReportParcelable.aidl
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2020, 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 perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable DataStallReportParcelable {
+  long timestampMillis = 0;
+  int detectionMethod = 1;
+  int tcpPacketFailRate = 2;
+  int tcpMetricsCollectionPeriodMillis = 3;
+  int dnsConsecutiveTimeouts = 4;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/DhcpResultsParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/DhcpResultsParcelable.aidl
new file mode 100644
index 0000000..31f2194
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/DhcpResultsParcelable.aidl
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable DhcpResultsParcelable {
+  android.net.StaticIpConfiguration baseConfiguration;
+  int leaseDuration;
+  int mtu;
+  String serverAddress;
+  String vendorInfo;
+  @nullable String serverHostName;
+  @nullable String captivePortalApiUrl;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkMonitor.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkMonitor.aidl
new file mode 100644
index 0000000..fc6a70e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkMonitor.aidl
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2018, 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 perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetworkMonitor {
+  oneway void start();
+  oneway void launchCaptivePortalApp();
+  oneway void notifyCaptivePortalAppFinished(int response);
+  oneway void setAcceptPartialConnectivity();
+  oneway void forceReevaluation(int uid);
+  oneway void notifyPrivateDnsChanged(in android.net.PrivateDnsConfigParcel config);
+  oneway void notifyDnsResponse(int returnCode);
+  oneway void notifyNetworkConnected(in android.net.LinkProperties lp, in android.net.NetworkCapabilities nc);
+  oneway void notifyNetworkDisconnected();
+  oneway void notifyLinkPropertiesChanged(in android.net.LinkProperties lp);
+  oneway void notifyNetworkCapabilitiesChanged(in android.net.NetworkCapabilities nc);
+  oneway void notifyNetworkConnectedParcel(in android.net.networkstack.aidl.NetworkMonitorParameters params);
+  const int NETWORK_TEST_RESULT_VALID = 0;
+  const int NETWORK_TEST_RESULT_INVALID = 1;
+  const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
+  const int NETWORK_VALIDATION_RESULT_VALID = 1;
+  const int NETWORK_VALIDATION_RESULT_PARTIAL = 2;
+  const int NETWORK_VALIDATION_RESULT_SKIPPED = 4;
+  const int NETWORK_VALIDATION_PROBE_DNS = 4;
+  const int NETWORK_VALIDATION_PROBE_HTTP = 8;
+  const int NETWORK_VALIDATION_PROBE_HTTPS = 16;
+  const int NETWORK_VALIDATION_PROBE_FALLBACK = 32;
+  const int NETWORK_VALIDATION_PROBE_PRIVDNS = 64;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkMonitorCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkMonitorCallbacks.aidl
new file mode 100644
index 0000000..36eda8e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkMonitorCallbacks.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetworkMonitorCallbacks {
+  oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor) = 0;
+  oneway void notifyNetworkTested(int testResult, @nullable String redirectUrl) = 1;
+  oneway void notifyPrivateDnsConfigResolved(in android.net.PrivateDnsConfigParcel config) = 2;
+  oneway void showProvisioningNotification(String action, String packageName) = 3;
+  oneway void hideProvisioningNotification() = 4;
+  oneway void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) = 5;
+  oneway void notifyNetworkTestedWithExtras(in android.net.NetworkTestResultParcelable result) = 6;
+  oneway void notifyDataStallSuspected(in android.net.DataStallReportParcelable report) = 7;
+  oneway void notifyCaptivePortalDataChanged(in android.net.CaptivePortalData data) = 8;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkStackConnector.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkStackConnector.aidl
new file mode 100644
index 0000000..8120ffc
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkStackConnector.aidl
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2018, 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 perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetworkStackConnector {
+  oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
+  oneway void makeNetworkMonitor(in android.net.Network network, String name, in android.net.INetworkMonitorCallbacks cb);
+  oneway void makeIpClient(in String ifName, in android.net.ip.IIpClientCallbacks callbacks);
+  oneway void fetchIpMemoryStore(in android.net.IIpMemoryStoreCallbacks cb);
+  oneway void allowTestUid(int uid, in android.net.INetworkStackStatusCallback cb);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkStackStatusCallback.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkStackStatusCallback.aidl
new file mode 100644
index 0000000..0b6b778
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/INetworkStackStatusCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetworkStackStatusCallback {
+  oneway void onStatusAvailable(int statusCode);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/InformationElementParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/InformationElementParcelable.aidl
new file mode 100644
index 0000000..6103774
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/InformationElementParcelable.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable InformationElementParcelable {
+  int id;
+  byte[] payload;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/InitialConfigurationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/InitialConfigurationParcelable.aidl
new file mode 100644
index 0000000..6a597e6
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/InitialConfigurationParcelable.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable InitialConfigurationParcelable {
+  android.net.LinkAddress[] ipAddresses;
+  android.net.IpPrefix[] directlyConnectedRoutes;
+  String[] dnsServers;
+  String gateway;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/Layer2InformationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/Layer2InformationParcelable.aidl
new file mode 100644
index 0000000..83796ee
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/Layer2InformationParcelable.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable Layer2InformationParcelable {
+  String l2Key;
+  String cluster;
+  android.net.MacAddress bssid;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/Layer2PacketParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/Layer2PacketParcelable.aidl
new file mode 100644
index 0000000..4b3fff5
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/Layer2PacketParcelable.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable Layer2PacketParcelable {
+  android.net.MacAddress dstMacAddress;
+  byte[] payload;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/NattKeepalivePacketDataParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/NattKeepalivePacketDataParcelable.aidl
new file mode 100644
index 0000000..18cf954
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/NattKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable NattKeepalivePacketDataParcelable {
+  byte[] srcAddress;
+  int srcPort;
+  byte[] dstAddress;
+  int dstPort;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/NetworkTestResultParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/NetworkTestResultParcelable.aidl
new file mode 100644
index 0000000..4d6d5a2
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/NetworkTestResultParcelable.aidl
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2020, 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 perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable NetworkTestResultParcelable {
+  long timestampMillis;
+  int result;
+  int probesSucceeded;
+  int probesAttempted;
+  String redirectUrl;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/PrivateDnsConfigParcel.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/PrivateDnsConfigParcel.aidl
new file mode 100644
index 0000000..1457caf
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/PrivateDnsConfigParcel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable PrivateDnsConfigParcel {
+  String hostname;
+  String[] ips;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ProvisioningConfigurationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ProvisioningConfigurationParcelable.aidl
new file mode 100644
index 0000000..9ecd110
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ProvisioningConfigurationParcelable.aidl
@@ -0,0 +1,62 @@
+/*
+**
+** Copyright (C) 2019 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable ProvisioningConfigurationParcelable {
+  /**
+   * @deprecated use ipv4ProvisioningMode instead.
+   */
+  boolean enableIPv4;
+  /**
+   * @deprecated use ipv6ProvisioningMode instead.
+   */
+  boolean enableIPv6;
+  boolean usingMultinetworkPolicyTracker;
+  boolean usingIpReachabilityMonitor;
+  int requestedPreDhcpActionMs;
+  android.net.InitialConfigurationParcelable initialConfig;
+  android.net.StaticIpConfiguration staticIpConfig;
+  android.net.apf.ApfCapabilities apfCapabilities;
+  int provisioningTimeoutMs;
+  int ipv6AddrGenMode;
+  android.net.Network network;
+  String displayName;
+  boolean enablePreconnection;
+  @nullable android.net.ScanResultInfoParcelable scanResultInfo;
+  @nullable android.net.Layer2InformationParcelable layer2Info;
+  @nullable List<android.net.networkstack.aidl.dhcp.DhcpOption> options;
+  int ipv4ProvisioningMode;
+  int ipv6ProvisioningMode;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ScanResultInfoParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ScanResultInfoParcelable.aidl
new file mode 100644
index 0000000..94fc27f
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ScanResultInfoParcelable.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable ScanResultInfoParcelable {
+  String ssid;
+  String bssid;
+  android.net.InformationElementParcelable[] informationElements;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/TcpKeepalivePacketDataParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/TcpKeepalivePacketDataParcelable.aidl
new file mode 100644
index 0000000..0e1c21c
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@JavaDerive(toString=true)
+parcelable TcpKeepalivePacketDataParcelable {
+  byte[] srcAddress;
+  int srcPort;
+  byte[] dstAddress;
+  int dstPort;
+  int seq;
+  int ack;
+  int rcvWnd;
+  int rcvWndScale;
+  int tos;
+  int ttl;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/DhcpLeaseParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/DhcpLeaseParcelable.aidl
new file mode 100644
index 0000000..3cd8860
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/DhcpLeaseParcelable.aidl
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2020, 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 perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.dhcp;
+@JavaDerive(toString=true)
+parcelable DhcpLeaseParcelable {
+  byte[] clientId;
+  byte[] hwAddr;
+  int netAddr;
+  int prefixLength;
+  long expTime;
+  String hostname;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/DhcpServingParamsParcel.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/DhcpServingParamsParcel.aidl
new file mode 100644
index 0000000..7997936
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -0,0 +1,49 @@
+/**
+ *
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.dhcp;
+@JavaDerive(toString=true)
+parcelable DhcpServingParamsParcel {
+  int serverAddr;
+  int serverAddrPrefixLength;
+  int[] defaultRouters;
+  int[] dnsServers;
+  int[] excludedAddrs;
+  long dhcpLeaseTimeSecs;
+  int linkMtu;
+  boolean metered;
+  int singleClientAddr = 0;
+  boolean changePrefixOnDecline = false;
+  int leasesSubnetPrefixLength = 0;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/IDhcpEventCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/IDhcpEventCallbacks.aidl
new file mode 100644
index 0000000..9312f47
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/IDhcpEventCallbacks.aidl
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2020, 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 perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.dhcp;
+interface IDhcpEventCallbacks {
+  oneway void onLeasesChanged(in List<android.net.dhcp.DhcpLeaseParcelable> newLeases);
+  oneway void onNewPrefixRequest(in android.net.IpPrefix currentPrefix);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/IDhcpServer.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/IDhcpServer.aidl
new file mode 100644
index 0000000..1109f35
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/IDhcpServer.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2018, 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 perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.dhcp;
+/* @hide */
+interface IDhcpServer {
+  oneway void start(in android.net.INetworkStackStatusCallback cb) = 0;
+  oneway void startWithCallbacks(in android.net.INetworkStackStatusCallback statusCb, in android.net.dhcp.IDhcpEventCallbacks eventCb) = 3;
+  oneway void updateParams(in android.net.dhcp.DhcpServingParamsParcel params, in android.net.INetworkStackStatusCallback cb) = 1;
+  oneway void stop(in android.net.INetworkStackStatusCallback cb) = 2;
+  const int STATUS_UNKNOWN = 0;
+  const int STATUS_SUCCESS = 1;
+  const int STATUS_INVALID_ARGUMENT = 2;
+  const int STATUS_UNKNOWN_ERROR = 3;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/IDhcpServerCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/IDhcpServerCallbacks.aidl
new file mode 100644
index 0000000..ab8577c
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/dhcp/IDhcpServerCallbacks.aidl
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2018, 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 perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.dhcp;
+/* @hide */
+interface IDhcpServerCallbacks {
+  oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ip/IIpClient.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ip/IIpClient.aidl
new file mode 100644
index 0000000..a97511e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ip/IIpClient.aidl
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ip;
+/* @hide */
+interface IIpClient {
+  oneway void completedPreDhcpAction();
+  oneway void confirmConfiguration();
+  oneway void readPacketFilterComplete(in byte[] data);
+  oneway void shutdown();
+  oneway void startProvisioning(in android.net.ProvisioningConfigurationParcelable req);
+  oneway void stop();
+  oneway void setTcpBufferSizes(in String tcpBufferSizes);
+  oneway void setHttpProxy(in android.net.ProxyInfo proxyInfo);
+  oneway void setMulticastFilter(boolean enabled);
+  oneway void addKeepalivePacketFilter(int slot, in android.net.TcpKeepalivePacketDataParcelable pkt);
+  oneway void removeKeepalivePacketFilter(int slot);
+  oneway void setL2KeyAndGroupHint(in String l2Key, in String cluster);
+  oneway void addNattKeepalivePacketFilter(int slot, in android.net.NattKeepalivePacketDataParcelable pkt);
+  oneway void notifyPreconnectionComplete(boolean success);
+  oneway void updateLayer2Information(in android.net.Layer2InformationParcelable info);
+  const int PROV_IPV4_DISABLED = 0;
+  const int PROV_IPV4_STATIC = 1;
+  const int PROV_IPV4_DHCP = 2;
+  const int PROV_IPV6_DISABLED = 0;
+  const int PROV_IPV6_SLAAC = 1;
+  const int PROV_IPV6_LINKLOCAL = 2;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ip/IIpClientCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ip/IIpClientCallbacks.aidl
new file mode 100644
index 0000000..24bbf64
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/ip/IIpClientCallbacks.aidl
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ip;
+/* @hide */
+interface IIpClientCallbacks {
+  oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
+  oneway void onPreDhcpAction();
+  oneway void onPostDhcpAction();
+  oneway void onNewDhcpResults(in android.net.DhcpResultsParcelable dhcpResults);
+  oneway void onProvisioningSuccess(in android.net.LinkProperties newLp);
+  oneway void onProvisioningFailure(in android.net.LinkProperties newLp);
+  oneway void onLinkPropertiesChange(in android.net.LinkProperties newLp);
+  oneway void onReachabilityLost(in String logMsg);
+  oneway void onQuit();
+  oneway void installPacketFilter(in byte[] filter);
+  oneway void startReadPacketFilter();
+  oneway void setFallbackMulticastFilter(boolean enabled);
+  oneway void setNeighborDiscoveryOffload(boolean enable);
+  oneway void onPreconnectionStart(in List<android.net.Layer2PacketParcelable> packets);
+  oneway void onReachabilityFailure(in android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable lossInfo);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/NetworkMonitorParameters.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/NetworkMonitorParameters.aidl
new file mode 100644
index 0000000..2ab9db0
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/NetworkMonitorParameters.aidl
@@ -0,0 +1,41 @@
+/**
+ *
+ * Copyright (C) 2022 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.networkstack.aidl;
+@JavaDerive(equals=true, toString=true)
+parcelable NetworkMonitorParameters {
+  android.net.NetworkAgentConfig networkAgentConfig;
+  android.net.NetworkCapabilities networkCapabilities;
+  android.net.LinkProperties linkProperties;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/dhcp/DhcpOption.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/dhcp/DhcpOption.aidl
new file mode 100644
index 0000000..eea3e0d
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/dhcp/DhcpOption.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2020, 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 perNmissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.networkstack.aidl.dhcp;
+@JavaDerive(toString=true)
+parcelable DhcpOption {
+  byte type;
+  @nullable byte[] value;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl
new file mode 100644
index 0000000..bb88434
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.networkstack.aidl.ip;
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable ReachabilityLossInfoParcelable {
+  String message;
+  android.net.networkstack.aidl.ip.ReachabilityLossReason reason;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl
new file mode 100644
index 0000000..70a7db2
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/15/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.networkstack.aidl.ip;
+@Backing(type="int")
+enum ReachabilityLossReason {
+  ROAM = 0,
+  CONFIRM = 1,
+  ORGANIC = 2,
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/dhcp/DhcpServingParamsParcel.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/dhcp/DhcpServingParamsParcel.aidl
index fa412cb..7997936 100644
--- a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/dhcp/DhcpServingParamsParcel.aidl
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -45,4 +45,5 @@
   boolean metered;
   int singleClientAddr = 0;
   boolean changePrefixOnDecline = false;
+  int leasesSubnetPrefixLength = 0;
 }
diff --git a/common/networkstackclient/src/android/net/dhcp/DhcpServingParamsParcel.aidl b/common/networkstackclient/src/android/net/dhcp/DhcpServingParamsParcel.aidl
index 7154c55..03e58da 100644
--- a/common/networkstackclient/src/android/net/dhcp/DhcpServingParamsParcel.aidl
+++ b/common/networkstackclient/src/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -30,4 +30,10 @@
     /** IP address to assign to a single client. 0.0.0.0 means support multiple clients.. */
     int singleClientAddr = 0;
     boolean changePrefixOnDecline = false;
+    /**
+     * This is used to restrict the range of addresses offered by the server to a subset of its
+     * prefix. The acceptable value is  >= serverAddrPrefixLength and <= 30, "0" means ignore this
+     * configuration in which case serverAddrPrefixLength is used instead.
+     */
+    int leasesSubnetPrefixLength = 0;
 }
diff --git a/common/networkstackclient/src/android/net/shared/InitialConfiguration.java b/common/networkstackclient/src/android/net/shared/InitialConfiguration.java
index 007c8ca..c61c674 100644
--- a/common/networkstackclient/src/android/net/shared/InitialConfiguration.java
+++ b/common/networkstackclient/src/android/net/shared/InitialConfiguration.java
@@ -178,7 +178,9 @@
     }
 
     private static boolean isDirectlyConnectedRoute(RouteInfo route, IpPrefix prefix) {
-        return !route.hasGateway() && prefix.equals(route.getDestination());
+        return !route.hasGateway()
+                && route.getType() == RouteInfo.RTN_UNICAST
+                && prefix.equals(route.getDestination());
     }
 
     private static boolean isPrefixLengthCompliant(LinkAddress addr) {
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index e54f11c..706f174 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -19,7 +19,7 @@
     <string name="notification_channel_name_connected" msgid="1795068343200033922">"Godkendelse til loginportal"</string>
     <string name="notification_channel_description_connected" msgid="7239184168268014518">"De notifikationer, der vises, når enheden er blevet godkendt til et netværk via en loginportal"</string>
     <string name="notification_channel_name_network_venue_info" msgid="6526543187249265733">"Oplysninger om netværksplacering"</string>
-    <string name="notification_channel_description_network_venue_info" msgid="5131499595382733605">"Notifikationer, der vises for at indikere, at netværket har en side med oplysninger om placeringen"</string>
+    <string name="notification_channel_description_network_venue_info" msgid="5131499595382733605">"Notifikationer, der vises for at indikere, at netværket har en side med oplysninger om lokationen"</string>
     <string name="connected" msgid="4563643884927480998">"Der er oprettet forbindelse"</string>
     <string name="tap_for_info" msgid="6849746325626883711">"Der er oprettet forbindelse/tryk for at se website"</string>
     <string name="application_label" msgid="1322847171305285454">"Netværksadministrator"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 9aec881..bed0ea7 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -17,9 +17,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="notification_channel_name_connected" msgid="1795068343200033922">"Кирүү бетинин аутентификациясы"</string>
-    <string name="notification_channel_description_connected" msgid="7239184168268014518">"Түзмөк тармактын кирүү бети аркылуу аутентификациядан ийгиликтүү өткөндө билдирмелер көрсөтүлөт"</string>
+    <string name="notification_channel_description_connected" msgid="7239184168268014518">"Түзмөк тармактын кирүү бети аркылуу аутентификациядан ийгиликтүү өткөндө билдирмелер көрүнөт"</string>
     <string name="notification_channel_name_network_venue_info" msgid="6526543187249265733">"Тармактын жайгашуусу жөнүндө маалымат"</string>
-    <string name="notification_channel_description_network_venue_info" msgid="5131499595382733605">"Тармак маалымат барагына киргенде билдирме көрсөтүлөт"</string>
+    <string name="notification_channel_description_network_venue_info" msgid="5131499595382733605">"Тармак маалымат барагына киргенде билдирме көрүнөт"</string>
     <string name="connected" msgid="4563643884927480998">"Туташты"</string>
     <string name="tap_for_info" msgid="6849746325626883711">"Туташты / Вебсайтты көрүү үчүн таптаңыз"</string>
     <string name="application_label" msgid="1322847171305285454">"Тармактарды башкаргыч"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index e3b7121..b5a08ec 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -21,6 +21,6 @@
     <string name="notification_channel_name_network_venue_info" msgid="6526543187249265733">"Maklumat tempat rangkaian"</string>
     <string name="notification_channel_description_network_venue_info" msgid="5131499595382733605">"Pemberitahuan dipaparkan untuk menunjukkan rangkaian mempunyai halaman maklumat tempat"</string>
     <string name="connected" msgid="4563643884927480998">"Disambungkan"</string>
-    <string name="tap_for_info" msgid="6849746325626883711">"Disambungkan / Ketik untuk melihat tapak web"</string>
+    <string name="tap_for_info" msgid="6849746325626883711">"Disambungkan / Ketik untuk melihat laman web"</string>
     <string name="application_label" msgid="1322847171305285454">"Pengurus rangkaian"</string>
 </resources>
diff --git a/src/android/net/dhcp/DhcpLeaseRepository.java b/src/android/net/dhcp/DhcpLeaseRepository.java
index 562d36c..b404296 100644
--- a/src/android/net/dhcp/DhcpLeaseRepository.java
+++ b/src/android/net/dhcp/DhcpLeaseRepository.java
@@ -76,9 +76,9 @@
     private IpPrefix mPrefix;
     @NonNull
     private Set<Inet4Address> mReservedAddrs;
-    private int mSubnetAddr;
+    private int mLeasesSubnetAddr;
     private int mPrefixLength;
-    private int mSubnetMask;
+    private int mLeasesSubnetMask;
     private int mNumAddresses;
     private long mLeaseTimeMs;
     @Nullable
@@ -131,22 +131,25 @@
     private final LinkedHashMap<Inet4Address, Long> mDeclinedAddrs = new LinkedHashMap<>();
 
     DhcpLeaseRepository(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs,
-            long leaseTimeMs, @Nullable Inet4Address clientAddr, @NonNull SharedLog log,
-            @NonNull Clock clock) {
+            long leaseTimeMs, @Nullable Inet4Address clientAddr, int leasesSubnetPrefixLength,
+            @NonNull SharedLog log, @NonNull Clock clock) {
         mLog = log;
         mClock = clock;
         mClientAddr = clientAddr;
-        updateParams(prefix, reservedAddrs, leaseTimeMs, clientAddr);
+        updateParams(prefix, reservedAddrs, leaseTimeMs, clientAddr, leasesSubnetPrefixLength);
     }
 
     public void updateParams(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs,
-            long leaseTimeMs, @Nullable Inet4Address clientAddr) {
+            long leaseTimeMs, @Nullable Inet4Address clientAddr, int leasesSubnetPrefixLength) {
         mPrefix = prefix;
         mReservedAddrs = Collections.unmodifiableSet(new HashSet<>(reservedAddrs));
         mPrefixLength = prefix.getPrefixLength();
-        mSubnetMask = prefixLengthToV4NetmaskIntHTH(mPrefixLength);
-        mSubnetAddr = inet4AddressToIntHTH((Inet4Address) prefix.getAddress()) & mSubnetMask;
-        mNumAddresses = clientAddr != null ? 1 : 1 << (IPV4_ADDR_BITS - prefix.getPrefixLength());
+        int subnetPrefixLength = mPrefixLength > leasesSubnetPrefixLength
+                ? mPrefixLength : leasesSubnetPrefixLength;
+        mLeasesSubnetMask = prefixLengthToV4NetmaskIntHTH(subnetPrefixLength);
+        mLeasesSubnetAddr =
+                inet4AddressToIntHTH((Inet4Address) prefix.getAddress()) & mLeasesSubnetMask;
+        mNumAddresses = clientAddr != null ? 1 : 1 << (IPV4_ADDR_BITS - subnetPrefixLength);
         mLeaseTimeMs = leaseTimeMs;
         mClientAddr = clientAddr;
 
@@ -519,11 +522,11 @@
      *
      */
     private int getAddrIndex(int addr) {
-        return addr & ~mSubnetMask;
+        return addr & ~mLeasesSubnetMask;
     }
 
     private int getAddrByIndex(int index) {
-        return mSubnetAddr | index;
+        return mLeasesSubnetAddr | index;
     }
 
     /**
diff --git a/src/android/net/dhcp/DhcpServer.java b/src/android/net/dhcp/DhcpServer.java
index 3465e72..dbd85a4 100644
--- a/src/android/net/dhcp/DhcpServer.java
+++ b/src/android/net/dhcp/DhcpServer.java
@@ -211,7 +211,8 @@
             return new DhcpLeaseRepository(
                     DhcpServingParams.makeIpPrefix(servingParams.serverAddr),
                     servingParams.excludedAddrs, servingParams.dhcpLeaseTimeSecs * 1000,
-                    servingParams.singleClientAddr, log.forSubComponent(REPO_TAG), clock);
+                    servingParams.singleClientAddr, servingParams.leasesSubnetPrefixLength,
+                    log.forSubComponent(REPO_TAG), clock);
         }
 
         @Override
@@ -388,7 +389,8 @@
                 DhcpServingParams.makeIpPrefix(params.serverAddr),
                 params.excludedAddrs,
                 params.dhcpLeaseTimeSecs * 1000,
-                params.singleClientAddr);
+                params.singleClientAddr,
+                params.leasesSubnetPrefixLength);
         maybeNotifyStatus(cb, STATUS_SUCCESS);
     }
 
diff --git a/src/android/net/dhcp/DhcpServingParams.java b/src/android/net/dhcp/DhcpServingParams.java
index 9d395f7..0f443a2 100644
--- a/src/android/net/dhcp/DhcpServingParams.java
+++ b/src/android/net/dhcp/DhcpServingParams.java
@@ -49,6 +49,8 @@
 public class DhcpServingParams {
     public static final int MTU_UNSET = 0;
     public static final int MIN_PREFIX_LENGTH = 16;
+    // DhcpLeaseRepository ignores the first and last addresses of the range so it needs
+    // MAX_PREFIX_LENGTH to be <= 30.
     public static final int MAX_PREFIX_LENGTH = 30;
 
     /** Server inet address and prefix to serve */
@@ -99,6 +101,12 @@
     public final boolean changePrefixOnDecline;
 
     /**
+     * Indicate the leases dhcp serving range. leasesSubnetPrefixLength should be larger than
+     * the length of server address prefix and smaller than MAX_PREFIX_LENGTH.
+     */
+    public final int leasesSubnetPrefixLength;
+
+    /**
      * Checked exception thrown when some parameters used to build {@link DhcpServingParams} are
      * missing or invalid.
      */
@@ -112,7 +120,7 @@
             @NonNull Set<Inet4Address> defaultRouters,
             @NonNull Set<Inet4Address> dnsServers, @NonNull Set<Inet4Address> excludedAddrs,
             long dhcpLeaseTimeSecs, int linkMtu, boolean metered, Inet4Address singleClientAddr,
-            boolean changePrefixOnDecline) {
+            boolean changePrefixOnDecline, int leasesSubnetPrefixLength) {
         this.serverAddr = serverAddr;
         this.defaultRouters = defaultRouters;
         this.dnsServers = dnsServers;
@@ -122,6 +130,7 @@
         this.metered = metered;
         this.singleClientAddr = singleClientAddr;
         this.changePrefixOnDecline = changePrefixOnDecline;
+        this.leasesSubnetPrefixLength = leasesSubnetPrefixLength;
     }
 
     /**
@@ -151,6 +160,7 @@
                 .setMetered(parcel.metered)
                 .setSingleClientAddr(clientAddr)
                 .setChangePrefixOnDecline(parcel.changePrefixOnDecline)
+                .setLeasesSubnetPrefixLength(parcel.leasesSubnetPrefixLength)
                 .build();
     }
 
@@ -207,6 +217,7 @@
         private boolean mMetered;
         private Inet4Address mClientAddr;
         private boolean mChangePrefixOnDecline;
+        private int mLeasesSubnetPrefixLength;
 
         /**
          * Set the server address and served prefix for the DHCP server.
@@ -352,6 +363,16 @@
         }
 
         /**
+         * Set leases subnet prefix length.
+         *
+         * <p>If not set, the default value is the server prefix length.
+         */
+        public Builder setLeasesSubnetPrefixLength(int leasesSubnetPrefixLength) {
+            this.mLeasesSubnetPrefixLength = leasesSubnetPrefixLength;
+            return this;
+        }
+
+        /**
          * Create a new {@link DhcpServingParams} instance based on parameters set in the builder.
          *
          * <p>This method has no side-effects. If it does not throw, a valid
@@ -372,7 +393,8 @@
                 throw new InvalidParameterException("Missing dnsServers");
             }
             if (mDhcpLeaseTimeSecs <= 0 || mDhcpLeaseTimeSecs > toUnsignedLong(INFINITE_LEASE)) {
-                throw new InvalidParameterException("Invalid lease time: " + mDhcpLeaseTimeSecs);
+                throw new InvalidParameterException(
+                        "Invalid lease time: " + mDhcpLeaseTimeSecs);
             }
             if (mLinkMtu != MTU_UNSET && (mLinkMtu < IPV4_MIN_MTU || mLinkMtu > IPV4_MAX_MTU)) {
                 throw new InvalidParameterException("Invalid link MTU: " + mLinkMtu);
@@ -393,6 +415,14 @@
                 }
             }
 
+            if (mLeasesSubnetPrefixLength == 0) {
+                mLeasesSubnetPrefixLength = mServerAddr.getPrefixLength();
+            } else if (mLeasesSubnetPrefixLength < mServerAddr.getPrefixLength()
+                    || mLeasesSubnetPrefixLength > MAX_PREFIX_LENGTH) {
+                throw new InvalidParameterException(
+                         "LeasesSubnetPrefix " + mLeasesSubnetPrefixLength + " is out of range");
+            }
+
             final Set<Inet4Address> excl = new HashSet<>();
             if (mExcludedAddrs != null) {
                 excl.addAll(mExcludedAddrs);
@@ -405,7 +435,8 @@
                     Collections.unmodifiableSet(new HashSet<>(mDefaultRouters)),
                     Collections.unmodifiableSet(new HashSet<>(mDnsServers)),
                     Collections.unmodifiableSet(excl),
-                    mDhcpLeaseTimeSecs, mLinkMtu, mMetered, mClientAddr, mChangePrefixOnDecline);
+                    mDhcpLeaseTimeSecs, mLinkMtu, mMetered, mClientAddr, mChangePrefixOnDecline,
+                    mLeasesSubnetPrefixLength);
         }
     }
 
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index a94e4cc..3ed6c0c 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -1354,8 +1354,7 @@
 
     private void restartIpv6WithAcceptRaDisabled() {
         mInterfaceCtrl.disableIPv6();
-        setIpv6AcceptRa(0 /* accept_ra */);
-        startIPv6();
+        startIPv6(0 /* acceptRa */);
     }
 
     // TODO: Investigate folding all this into the existing static function
@@ -1893,8 +1892,8 @@
         return true;
     }
 
-    private boolean startIPv6() {
-        setIpv6AcceptRa(mConfiguration.mIPv6ProvisioningMode == PROV_IPV6_LINKLOCAL ? 0 : 2);
+    private boolean startIPv6(int acceptRa) {
+        setIpv6AcceptRa(acceptRa);
         return mInterfaceCtrl.setIPv6PrivacyExtensions(true)
                 && mInterfaceCtrl.setIPv6AddrGenModeIfSupported(mConfiguration.mIPv6AddrGenMode)
                 && mInterfaceCtrl.enableIPv6();
@@ -2390,7 +2389,9 @@
             mPacketTracker = createPacketTracker();
             if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName);
 
-            if (isIpv6Enabled() && !startIPv6()) {
+            final int acceptRa =
+                    mConfiguration.mIPv6ProvisioningMode == PROV_IPV6_LINKLOCAL ? 0 : 2;
+            if (isIpv6Enabled() && !startIPv6(acceptRa)) {
                 doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
                 enqueueJumpToStoppingState(DisconnectCode.DC_ERROR_STARTING_IPV6);
                 return;
diff --git a/src/com/android/server/connectivity/NetworkMonitor.java b/src/com/android/server/connectivity/NetworkMonitor.java
index 301462f..fd566c8 100755
--- a/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/src/com/android/server/connectivity/NetworkMonitor.java
@@ -164,9 +164,11 @@
 import com.android.networkstack.NetworkStackNotifier;
 import com.android.networkstack.R;
 import com.android.networkstack.apishim.CaptivePortalDataShimImpl;
+import com.android.networkstack.apishim.NetworkAgentConfigShimImpl;
 import com.android.networkstack.apishim.NetworkInformationShimImpl;
 import com.android.networkstack.apishim.api29.ConstantsShim;
 import com.android.networkstack.apishim.common.CaptivePortalDataShim;
+import com.android.networkstack.apishim.common.NetworkAgentConfigShim;
 import com.android.networkstack.apishim.common.NetworkInformationShim;
 import com.android.networkstack.apishim.common.ShimUtils;
 import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
@@ -427,6 +429,7 @@
     private final INetworkMonitorCallbacks mCallback;
     private final int mCallbackVersion;
     private final Network mCleartextDnsNetwork;
+    @NonNull
     private final Network mNetwork;
     private final TelephonyManager mTelephonyManager;
     private final WifiManager mWifiManager;
@@ -460,7 +463,11 @@
     private final int mEvaluatingBandwidthTimeoutMs;
     private final AtomicInteger mNextEvaluatingBandwidthThreadId = new AtomicInteger(1);
 
+    @NonNull
+    private NetworkAgentConfigShim mNetworkAgentConfig;
+    @NonNull
     private NetworkCapabilities mNetworkCapabilities;
+    @NonNull
     private LinkProperties mLinkProperties;
 
     @VisibleForTesting
@@ -647,6 +654,7 @@
         // even before notifyNetworkConnected.
         mLinkProperties = new LinkProperties();
         mNetworkCapabilities = new NetworkCapabilities(null);
+        mNetworkAgentConfig = NetworkAgentConfigShimImpl.newInstance(null);
     }
 
     /**
@@ -712,7 +720,7 @@
 
     private void updateConnectedNetworkAttributes(Message connectedMsg) {
         final NetworkMonitorParameters params = (NetworkMonitorParameters) connectedMsg.obj;
-        // TODO : also read the NetworkAgentConfig
+        mNetworkAgentConfig = NetworkAgentConfigShimImpl.newInstance(params.networkAgentConfig);
         mLinkProperties = params.linkProperties;
         mNetworkCapabilities = params.networkCapabilities;
         suppressNotificationIfNetworkRestricted();
@@ -773,7 +781,7 @@
     }
 
     private boolean isValidationRequired() {
-        return NetworkMonitorUtils.isValidationRequired(mNetworkCapabilities);
+        return NetworkMonitorUtils.isValidationRequired(mNetworkAgentConfig, mNetworkCapabilities);
     }
 
     private boolean isPrivateDnsValidationRequired() {
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
index 4d2a860..da4fb5e 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
@@ -358,6 +358,9 @@
     private static final Inet4Address NETMASK = getPrefixMaskAsInet4Address(PREFIX_LENGTH);
     private static final Inet4Address BROADCAST_ADDR = getBroadcastAddress(
             SERVER_ADDR, PREFIX_LENGTH);
+    private static final String IPV6_LINK_LOCAL_PREFIX = "fe80::/64";
+    private static final String IPV4_TEST_SUBNET_PREFIX = "192.168.1.0/24";
+    private static final String IPV4_ANY_ADDRESS_PREFIX = "0.0.0.0/0";
     private static final String HOSTNAME = "testhostname";
     private static final int TEST_DEFAULT_MTU = 1500;
     private static final int TEST_MIN_MTU = 1280;
@@ -1402,7 +1405,7 @@
         assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime, TEST_DEFAULT_MTU);
     }
 
-    @Test
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testRollbackFromRapidCommitOption() throws Exception {
         startIpClientProvisioning(false /* isDhcpLeaseCacheEnabled */,
                 true /* isDhcpRapidCommitEnabled */, false /* isPreConnectionEnabled */,
@@ -2692,6 +2695,13 @@
                 (long) NetworkQuirkEvent.QE_IPV6_PROVISIONING_ROUTER_LOST.ordinal());
     }
 
+    private boolean hasRouteTo(@NonNull final LinkProperties lp, @NonNull final String prefix) {
+        for (RouteInfo r : lp.getRoutes()) {
+            if (r.getDestination().equals(new IpPrefix(prefix))) return true;
+        }
+        return false;
+    }
+
     @Test @SignatureRequiredTest(reason = "signature perms are required due to mocked callabck")
     public void testIgnoreIpv6ProvisioningLoss_disableAcceptRa() throws Exception {
         doDualStackProvisioning(true /* shouldDisableAcceptRa */);
@@ -2707,6 +2717,8 @@
                     // Only IPv4 provisioned and IPv6 link-local address
                     final boolean isIPv6LinkLocalAndIPv4OnlyProvisioned =
                             (x.getLinkAddresses().size() == 2
+                                    // fe80::/64, IPv4 default route, IPv4 subnet route
+                                    && x.getRoutes().size() == 3
                                     && x.getDnsServers().size() == 1
                                     && x.getAddresses().get(0) instanceof Inet4Address
                                     && x.getDnsServers().get(0) instanceof Inet4Address);
@@ -2719,6 +2731,10 @@
         assertNotNull(lp);
         assertEquals(lp.getAddresses().get(0), CLIENT_ADDR);
         assertEquals(lp.getDnsServers().get(0), SERVER_ADDR);
+        assertEquals(3, lp.getRoutes().size());
+        assertTrue(hasRouteTo(lp, IPV6_LINK_LOCAL_PREFIX)); // fe80::/64
+        assertTrue(hasRouteTo(lp, IPV4_TEST_SUBNET_PREFIX)); // IPv4 directly-connected route
+        assertTrue(hasRouteTo(lp, IPV4_ANY_ADDRESS_PREFIX)); // IPv4 default route
         assertTrue(lp.getAddresses().get(1).isLinkLocalAddress());
 
         reset(mCb);
diff --git a/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java b/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
index b9b1652..243bf63 100644
--- a/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
+++ b/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
@@ -92,6 +92,7 @@
     private static final Set<Inet4Address> TEST_EXCL_SET =
             Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
                 TEST_SERVER_ADDR, TEST_DEF_ROUTER, TEST_RESERVED_ADDR)));
+    private static final int DEFAULT_TARGET_PREFIX_LENGTH = 0;
 
     @NonNull
     private SharedLog mLog;
@@ -122,7 +123,9 @@
         // Use a non-null Binder for linkToDeath
         when(mCallbacks.asBinder()).thenReturn(mCallbacksBinder);
         mRepo = new DhcpLeaseRepository(
-                TEST_IP_PREFIX, TEST_EXCL_SET, TEST_LEASE_TIME_MS, clientAddr, mLog, mClock);
+                TEST_IP_PREFIX, TEST_EXCL_SET, TEST_LEASE_TIME_MS, clientAddr,
+                DEFAULT_TARGET_PREFIX_LENGTH,
+                mLog, mClock);
         mRepo.addLeaseCallbacks(mCallbacks);
         verify(mCallbacks, atLeastOnce()).asBinder();
     }
@@ -131,7 +134,7 @@
      * Request a number of addresses through offer/request. Useful to test address exhaustion.
      * @param nAddr Number of addresses to request.
      */
-    private void requestAddresses(byte nAddr) throws Exception {
+    private Set<Inet4Address> requestAddresses(byte nAddr) throws Exception {
         final HashSet<Inet4Address> addrs = new HashSet<>();
         byte[] hwAddrBytes = new byte[] { 8, 4, 3, 2, 1, 0 };
         for (byte i = 0; i < nAddr; i++) {
@@ -149,6 +152,8 @@
 
             requestLeaseSelecting(newMac, lease.getNetAddr(), hostname);
         }
+
+        return addrs;
     }
 
     @SuppressLint("NewApi")
@@ -156,7 +161,7 @@
     public void testAddressExhaustion() throws Exception {
         // Use a /28 to quickly run out of addresses
         mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS,
-                null /* clientAddr */);
+                null /* clientAddr */, DEFAULT_TARGET_PREFIX_LENGTH);
 
         // /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
         requestAddresses((byte) 11);
@@ -204,7 +209,7 @@
         Set<Inet4Address> newReserved = new HashSet<>(TEST_EXCL_SET);
         newReserved.add(reservedAddr);
         mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), newReserved, TEST_LEASE_TIME_MS,
-                null /* clientAddr */);
+                null /* clientAddr */, DEFAULT_TARGET_PREFIX_LENGTH);
         // Callback is called for the second time with just this lease
         verifyLeasesChangedCallback(2 /* times */, reqAddrIn28Lease);
         verifyNoMoreInteractions(mCallbacks);
@@ -237,7 +242,8 @@
     @Test
     public void testUpdateParams_UsesNewPrefix() throws Exception {
         final IpPrefix newPrefix = new IpPrefix(parseAddr4("192.168.123.0"), 24);
-        mRepo.updateParams(newPrefix, TEST_EXCL_SET, TEST_LEASE_TIME_MS, null /* clientAddr */);
+        mRepo.updateParams(newPrefix, TEST_EXCL_SET, TEST_LEASE_TIME_MS, null /* clientAddr */,
+                DEFAULT_TARGET_PREFIX_LENGTH);
 
         DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
                 IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
@@ -548,7 +554,7 @@
     public void testMarkLeaseDeclined_UsedIfOutOfAddresses() throws Exception {
         // Use a /28 to quickly run out of addresses
         mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS,
-                null /* clientAddr */);
+                null /* clientAddr */, DEFAULT_TARGET_PREFIX_LENGTH);
 
         mRepo.markLeaseDeclined(TEST_INETADDR_1);
         mRepo.markLeaseDeclined(TEST_INETADDR_2);
@@ -578,6 +584,35 @@
         assertEquals(TEST_HOSTNAME_2, secondLease.getHostname());
     }
 
+    // Android Lint doesn't handle API change from @SystemApi to public API correctly
+    // (see b/193460475). Suppresses NewApi warnings for IpPrefix(InetAddress, int).
+    @SuppressLint("NewApi")
+    @Test
+    public void testSetTargetPrefixLength() throws Exception {
+        final Inet4Address p2pStaticAddr = parseAddr4("192.168.49.1");
+        final Set<Inet4Address> excludedAddrs = new HashSet<>(Arrays.asList(p2pStaticAddr));
+        // Set leasesSubnetPrefixLength to /29.
+        mRepo.updateParams(new IpPrefix(p2pStaticAddr, 24), excludedAddrs, TEST_LEASE_TIME_MS,
+                null /* clientAddr */, 29);
+
+        // /29 should have 8 addresses (192.168.49.0 ~ 192.168.49.7),
+        // 6 w/o the first and last addresses, 5 w/o server addresses: 192.168.49.2 ~ 192.168.49.6.
+        final Set<Inet4Address> offerAddresses = requestAddresses((byte) 5);
+        assertTrue(offerAddresses.contains(parseAddr4("192.168.49.2")));
+        assertTrue(offerAddresses.contains(parseAddr4("192.168.49.3")));
+        assertTrue(offerAddresses.contains(parseAddr4("192.168.49.4")));
+        assertTrue(offerAddresses.contains(parseAddr4("192.168.49.5")));
+        assertTrue(offerAddresses.contains(parseAddr4("192.168.49.6")));
+
+        try {
+            mRepo.getOffer(null, TEST_MAC_2,
+                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
+            fail("Should be out of addresses");
+        } catch (DhcpLeaseRepository.OutOfAddressesException e) {
+            // Expected
+        }
+    }
+
     private DhcpLease requestLease(@NonNull MacAddress macAddr, @NonNull Inet4Address clientAddr,
             @Nullable Inet4Address reqAddr, @Nullable String hostname, boolean sidSet)
             throws DhcpLeaseRepository.DhcpLeaseException {
diff --git a/tests/unit/src/android/net/dhcp/DhcpResultsParcelableUtilTest.java b/tests/unit/src/android/net/dhcp/DhcpResultsParcelableUtilTest.java
index 8ab7404..126f6c2 100644
--- a/tests/unit/src/android/net/dhcp/DhcpResultsParcelableUtilTest.java
+++ b/tests/unit/src/android/net/dhcp/DhcpResultsParcelableUtilTest.java
@@ -25,6 +25,7 @@
 import static org.junit.Assert.assertEquals;
 
 import android.net.DhcpResults;
+import android.net.DhcpResultsParcelable;
 import android.net.LinkAddress;
 import android.net.shared.IpConfigurationParcelableUtil;
 
@@ -124,7 +125,8 @@
     @Test
     public void testToString() {
         final String expected = ""
-                + "android.net.DhcpResultsParcelable{baseConfiguration: IP address 192.168.42.19/25"
+                + DhcpResultsParcelable.class.getName()
+                + "{baseConfiguration: IP address 192.168.42.19/25"
                 + " Gateway 192.168.42.42  DNS servers: [ 8.8.8.8 192.168.43.43 ]"
                 + " Domains example.com, leaseDuration: 3600, mtu: 1450,"
                 + " serverAddress: 192.168.44.44, vendorInfo: TEST_VENDOR_INFO,"
diff --git a/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java b/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
index 290fd69..732fce2 100644
--- a/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
+++ b/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
@@ -65,6 +65,7 @@
             Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201")));
     private static final boolean TEST_METERED = true;
     private static final boolean TEST_CHANGE_PREFIX_ON_DECLINE = true;
+    private static final int LEASES_SUBNET_PREFIX_LENGTH = 25;
 
     @Before
     public void setUp() {
@@ -77,7 +78,8 @@
                 .setExcludedAddrs(TEST_EXCLUDED_ADDRS)
                 .setMetered(TEST_METERED)
                 .setSingleClientAddr(TEST_CLIENT_ADDR)
-                .setChangePrefixOnDecline(TEST_CHANGE_PREFIX_ON_DECLINE);
+                .setChangePrefixOnDecline(TEST_CHANGE_PREFIX_ON_DECLINE)
+                .setLeasesSubnetPrefixLength(LEASES_SUBNET_PREFIX_LENGTH);
     }
 
     @Test
@@ -174,6 +176,25 @@
     }
 
     @Test
+    public void testBuild_LeasesSubnetPrefixLengthDefault() throws InvalidParameterException {
+        final DhcpServingParams params = mBuilder.setLeasesSubnetPrefixLength(0).build();
+        // Same as server address prefix length (20).
+        assertEquals(20, params.leasesSubnetPrefixLength);
+    }
+
+    @Test(expected = InvalidParameterException.class)
+    public void testBuild_LeasesSubnetPrefixLengthTooSmall() throws InvalidParameterException {
+        // Smaller than server address prefix length (20).
+        mBuilder.setLeasesSubnetPrefixLength(2).build();
+    }
+
+    @Test(expected = InvalidParameterException.class)
+    public void testBuild_LeasesSubnetPrefixLengthTooLarge() throws InvalidParameterException {
+        // Larger than max prefix length (30).
+        mBuilder.setLeasesSubnetPrefixLength(31).build();
+    }
+
+    @Test
     public void testFromParcelableObject() throws InvalidParameterException {
         final DhcpServingParams params = mBuilder.build();
         final DhcpServingParamsParcel parcel = new DhcpServingParamsParcel();
@@ -187,6 +208,7 @@
         parcel.metered = TEST_METERED;
         parcel.singleClientAddr = inet4AddressToIntHTH(TEST_CLIENT_ADDR);
         parcel.changePrefixOnDecline = TEST_CHANGE_PREFIX_ON_DECLINE;
+        parcel.leasesSubnetPrefixLength = LEASES_SUBNET_PREFIX_LENGTH;
         final DhcpServingParams parceled = DhcpServingParams.fromParcelableObject(parcel);
 
         assertEquals(params.defaultRouters, parceled.defaultRouters);
@@ -198,8 +220,9 @@
         assertEquals(params.metered, parceled.metered);
         assertEquals(params.singleClientAddr, parceled.singleClientAddr);
         assertEquals(params.changePrefixOnDecline, parceled.changePrefixOnDecline);
+        assertEquals(params.leasesSubnetPrefixLength, parceled.leasesSubnetPrefixLength);
 
-        MiscAsserts.assertFieldCountEquals(10, DhcpServingParamsParcel.class);
+        MiscAsserts.assertFieldCountEquals(11, DhcpServingParamsParcel.class);
     }
 
     @Test(expected = InvalidParameterException.class)
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java
index 481a957..b88317a 100644
--- a/tests/unit/src/android/net/ip/IpClientTest.java
+++ b/tests/unit/src/android/net/ip/IpClientTest.java
@@ -465,7 +465,17 @@
                     routes("fe80::/64", "fd2c:4e57:8e3c::/64"),
                     dns(),
                     conf(links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                        prefixes( "fe80::/64", "fd2c:4e57:8e3c::/64"), ips()))
+                        prefixes("fe80::/64", "fd2c:4e57:8e3c::/64"), ips())),
+
+            // Test case with excluded route
+            notProvisionedCase(
+                    links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
+                    routes(
+                            routes("fe80::/64"),
+                            excludedRoutes("fd2c:4e57:8e3c::/64")),
+                    dns(),
+                    conf(links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
+                            prefixes("fe80::/64", "fd2c:4e57:8e3c::/64"), ips()))
         };
 
         for (IsProvisionedTestCase testcase : testcases) {
@@ -627,6 +637,20 @@
                 TEST_IFNAME));
     }
 
+    static Set<RouteInfo> excludedRoutes(String... excludedRoutes) {
+        return mapIntoSet(excludedRoutes, (r) -> new RouteInfo(new IpPrefix(r), null /* gateway */,
+                TEST_IFNAME, RouteInfo.RTN_THROW));
+    }
+
+    static Set<RouteInfo> routes(Set<RouteInfo> includedRoutes, Set<RouteInfo> excludedRoutes) {
+        Set<RouteInfo> result = new HashSet<>(includedRoutes.size() + excludedRoutes.size());
+
+        result.addAll(includedRoutes);
+        result.addAll(excludedRoutes);
+
+        return result;
+    }
+
     @SuppressLint("NewApi")
     static RouteInfo defaultIPV6Route(String gateway) {
         return new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
diff --git a/tests/unit/src/android/net/networkstack/ModuleNetworkStackClientTest.kt b/tests/unit/src/android/net/networkstack/ModuleNetworkStackClientTest.kt
index d8864e6..0753b29 100644
--- a/tests/unit/src/android/net/networkstack/ModuleNetworkStackClientTest.kt
+++ b/tests/unit/src/android/net/networkstack/ModuleNetworkStackClientTest.kt
@@ -73,8 +73,10 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        // Use DESCRIPTOR and not class name, as the descriptor is the original class name before
+        // jarjar, and is always what is used to query the interface.
         doReturn(mConnector).`when`(mConnectorBinder).queryLocalInterface(
-                INetworkStackConnector::class.qualifiedName!!)
+                INetworkStackConnector.DESCRIPTOR)
     }
 
     @After
diff --git a/tests/unit/src/android/net/shared/ProvisioningConfigurationTest.java b/tests/unit/src/android/net/shared/ProvisioningConfigurationTest.java
index 716abaa..2734fd2 100644
--- a/tests/unit/src/android/net/shared/ProvisioningConfigurationTest.java
+++ b/tests/unit/src/android/net/shared/ProvisioningConfigurationTest.java
@@ -34,10 +34,14 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
+import android.net.InformationElementParcelable;
+import android.net.InitialConfigurationParcelable;
+import android.net.Layer2InformationParcelable;
 import android.net.LinkAddress;
 import android.net.MacAddress;
 import android.net.Network;
 import android.net.ProvisioningConfigurationParcelable;
+import android.net.ScanResultInfoParcelable;
 import android.net.StaticIpConfiguration;
 import android.net.apf.ApfCapabilities;
 import android.net.networkstack.aidl.dhcp.DhcpOption;
@@ -288,21 +292,28 @@
     }
 
     private static final String TEMPLATE = ""
-            + "android.net.ProvisioningConfigurationParcelable{enableIPv4: true, enableIPv6: true,"
+            + ProvisioningConfigurationParcelable.class.getName()
+            + "{enableIPv4: true, enableIPv6: true,"
             + " usingMultinetworkPolicyTracker: true,"
             + " usingIpReachabilityMonitor: true, requestedPreDhcpActionMs: 42,"
-            + " initialConfig: android.net.InitialConfigurationParcelable{ipAddresses:"
-            + " [192.168.42.42/24], directlyConnectedRoutes: [], dnsServers: [], gateway: null},"
+            + " initialConfig: "
+            + InitialConfigurationParcelable.class.getName()
+            + "{ipAddresses: [192.168.42.42/24],"
+            + " directlyConnectedRoutes: [], dnsServers: [], gateway: null},"
             + " staticIpConfig: IP address 2001:db8::42/90 Gateway  DNS servers: [ ] Domains ,"
             + " apfCapabilities: ApfCapabilities{version: 1, maxSize: 2, format: 3},"
             + " provisioningTimeoutMs: 4200, ipv6AddrGenMode: 123, network: 321,"
-            + " displayName: test_config, enablePreconnection: false, scanResultInfo:"
-            + " android.net.ScanResultInfoParcelable{ssid: ssid, bssid: 01:02:03:04:05:06,"
-            + " informationElements: [android.net.InformationElementParcelable{id: 221,"
-            + " payload: [0, 23, -14, 6, 1, 1, 3, 1, 0, 0]}]}, layer2Info:"
-            + " android.net.Layer2InformationParcelable{l2Key: some l2key,"
-            + " cluster: some cluster, bssid: %s},"
-            + " options: [android.net.networkstack.aidl.dhcp.DhcpOption{type: 60,"
+            + " displayName: test_config, enablePreconnection: false, scanResultInfo: "
+            + ScanResultInfoParcelable.class.getName()
+            + "{ssid: ssid, bssid: 01:02:03:04:05:06,"
+            + " informationElements: ["
+            + InformationElementParcelable.class.getName()
+            + "{id: 221, payload: [0, 23, -14, 6, 1, 1, 3, 1, 0, 0]}]}, layer2Info: "
+            + Layer2InformationParcelable.class.getName()
+            + "{l2Key: some l2key, cluster: some cluster, bssid: %s},"
+            + " options: ["
+            + DhcpOption.class.getName()
+            + "{type: 60,"
             + " value: [97, 110, 100, 114, 111, 105, 100, 45, 100, 104, 99, 112, 45, 49, 49]}],"
             + " ipv4ProvisioningMode: 2, ipv6ProvisioningMode: 1}";
 
diff --git a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
index 01daf67..ddc1aba 100644
--- a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -148,12 +148,15 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.modules.utils.build.SdkLevel;
 import com.android.networkstack.NetworkStackNotifier;
 import com.android.networkstack.R;
 import com.android.networkstack.apishim.CaptivePortalDataShimImpl;
 import com.android.networkstack.apishim.ConstantsShim;
+import com.android.networkstack.apishim.NetworkAgentConfigShimImpl;
 import com.android.networkstack.apishim.NetworkInformationShimImpl;
 import com.android.networkstack.apishim.common.CaptivePortalDataShim;
+import com.android.networkstack.apishim.common.NetworkAgentConfigShim;
 import com.android.networkstack.apishim.common.NetworkInformationShim;
 import com.android.networkstack.apishim.common.ShimUtils;
 import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
@@ -298,8 +301,8 @@
     private static final int TEST_MIN_STALL_EVALUATE_INTERVAL_MS = 500;
     private static final int STALL_EXPECTED_LAST_PROBE_TIME_MS =
             TEST_MIN_STALL_EVALUATE_INTERVAL_MS + HANDLER_TIMEOUT_MS;
-    private static final NetworkAgentConfig TEST_AGENT_CONFIG =
-            new NetworkAgentConfig.Builder().build();
+    private static final NetworkAgentConfigShim TEST_AGENT_CONFIG =
+            NetworkAgentConfigShimImpl.newInstance(null);
     private static final LinkProperties TEST_LINK_PROPERTIES = new LinkProperties();
 
     // Cannot have a static member for the LinkProperties with captive portal API information, as
@@ -1396,8 +1399,7 @@
                 + "'user-portal-url': '" + TEST_LOGIN_URL + "'}");
 
         // After notifyNetworkConnected, validation uses the capport API contents
-        nm.notifyNetworkConnectedParcel(
-                makeParams(TEST_AGENT_CONFIG, lp, CELL_METERED_CAPABILITIES));
+        notifyNetworkConnected(nm, lp, CELL_METERED_CAPABILITIES);
         verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL);
 
         verify(mHttpConnection, never()).getResponseCode();
@@ -2072,8 +2074,7 @@
 
         WrappedNetworkMonitor wnm = makeCellNotMeteredNetworkMonitor();
         wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
-        wnm.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES,
-                CELL_NOT_METERED_CAPABILITIES));
+        notifyNetworkConnected(wnm, CELL_NOT_METERED_CAPABILITIES);
         verifyNetworkTested(VALIDATION_RESULT_INVALID,
                 NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
         verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyProbeStatusChanged(
@@ -2100,8 +2101,7 @@
 
         WrappedNetworkMonitor wnm = makeCellNotMeteredNetworkMonitor();
         wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
-        wnm.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES,
-                CELL_NOT_METERED_CAPABILITIES));
+        notifyNetworkConnected(wnm, CELL_NOT_METERED_CAPABILITIES);
         verifyNetworkTested(VALIDATION_RESULT_INVALID,
                 NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
         verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyProbeStatusChanged(
@@ -2232,7 +2232,7 @@
             nm = null;
             fail("Undefined transport type");
         }
-        nm.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, nc));
+        notifyNetworkConnected(nm, nc);
         verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID,
                 NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
         nm.setLastProbeTime(SystemClock.elapsedRealtime() - STALL_EXPECTED_LAST_PROBE_TIME_MS);
@@ -2542,9 +2542,7 @@
         setStatus(mHttpsConnection, 204);
         setStatus(mHttpConnection, 204);
         final NetworkMonitor nm = makeMonitor(CELL_METERED_CAPABILITIES);
-        nm.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES,
-                CELL_METERED_CAPABILITIES));
-
+        notifyNetworkConnected(nm, CELL_METERED_CAPABILITIES);
         verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS))
                 .notifyNetworkTested(eq(NETWORK_VALIDATION_RESULT_VALID
                         | NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
@@ -2808,8 +2806,7 @@
         monitor.notifyLinkPropertiesChanged(linkProperties);
         final NetworkCapabilities networkCapabilities =
                 new NetworkCapabilities(WIFI_NOT_METERED_CAPABILITIES);
-        monitor.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG,
-                linkProperties, networkCapabilities));
+        notifyNetworkConnected(monitor, linkProperties, networkCapabilities);
         verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
                 .showProvisioningNotification(any(), any());
         assertCaptivePortalAppReceiverRegistered(true /* isPortal */);
@@ -2971,21 +2968,21 @@
                 eq(key), any() /* defaultValue */);
     }
 
-    private NetworkMonitor runPortalNetworkTest() throws RemoteException {
+    private NetworkMonitor runPortalNetworkTest() throws Exception {
         final NetworkMonitor nm = runNetworkTest(VALIDATION_RESULT_PORTAL,
                 0 /* probesSucceeded */, TEST_LOGIN_URL);
         assertCaptivePortalAppReceiverRegistered(true /* isPortal */);
         return nm;
     }
 
-    private NetworkMonitor runNoValidationNetworkTest() throws RemoteException {
+    private NetworkMonitor runNoValidationNetworkTest() throws Exception {
         final NetworkMonitor nm = runNetworkTest(NETWORK_VALIDATION_RESULT_VALID,
                 0 /* probesSucceeded */, null /* redirectUrl */);
         assertCaptivePortalAppReceiverRegistered(false /* isPortal */);
         return nm;
     }
 
-    private NetworkMonitor runFailedNetworkTest() throws RemoteException {
+    private NetworkMonitor runFailedNetworkTest() throws Exception {
         final NetworkMonitor nm = runNetworkTest(
                 VALIDATION_RESULT_INVALID, 0 /* probesSucceeded */, null /* redirectUrl */);
         assertCaptivePortalAppReceiverRegistered(false /* isPortal */);
@@ -2993,14 +2990,14 @@
     }
 
     private NetworkMonitor runPartialConnectivityNetworkTest(int probesSucceeded)
-            throws RemoteException {
+            throws Exception {
         final NetworkMonitor nm = runNetworkTest(NETWORK_VALIDATION_RESULT_PARTIAL,
                 probesSucceeded, null /* redirectUrl */);
         assertCaptivePortalAppReceiverRegistered(false /* isPortal */);
         return nm;
     }
 
-    private NetworkMonitor runValidatedNetworkTest() throws RemoteException {
+    private NetworkMonitor runValidatedNetworkTest() throws Exception {
         // Expect to send HTTPS and evaluation results.
         return runNetworkTest(NETWORK_VALIDATION_RESULT_VALID,
                 NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS,
@@ -3008,23 +3005,23 @@
     }
 
     private NetworkMonitor runNetworkTest(int testResult, int probesSucceeded, String redirectUrl)
-            throws RemoteException {
+            throws Exception {
         return runNetworkTest(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, CELL_METERED_CAPABILITIES,
                 testResult, probesSucceeded, redirectUrl);
     }
 
-    private NetworkMonitor runNetworkTest(NetworkAgentConfig config,
+    private NetworkMonitor runNetworkTest(NetworkAgentConfigShim config,
             LinkProperties lp, NetworkCapabilities nc,
-            int testResult, int probesSucceeded, String redirectUrl) throws RemoteException {
+            int testResult, int probesSucceeded, String redirectUrl) throws Exception {
         final NetworkMonitor monitor = makeMonitor(nc);
-        monitor.notifyNetworkConnectedParcel(makeParams(config, lp, nc));
+        notifyNetworkConnected(monitor, config, lp, nc);
         verifyNetworkTested(testResult, probesSucceeded, redirectUrl);
         HandlerUtils.waitForIdle(monitor.getHandler(), HANDLER_TIMEOUT_MS);
 
         return monitor;
     }
 
-    private void verifyNetworkTested(int testResult, int probesSucceeded) throws RemoteException {
+    private void verifyNetworkTested(int testResult, int probesSucceeded) throws Exception {
         verifyNetworkTested(testResult, probesSucceeded, null /* redirectUrl */);
     }
 
@@ -3054,14 +3051,30 @@
         }
     }
 
-    private void notifyNetworkConnected(NetworkMonitor nm, NetworkCapabilities nc) {
-        nm.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, nc));
+    private void notifyNetworkConnected(NetworkMonitor nm, NetworkAgentConfigShim config,
+            LinkProperties lp, NetworkCapabilities nc) throws Exception {
+        if (SdkLevel.isAtLeastT()) {
+            nm.notifyNetworkConnectedParcel(makeParams(config, lp, nc));
+        } else {
+            nm.notifyNetworkConnected(lp, nc);
+        }
     }
 
-    private NetworkMonitorParameters makeParams(@NonNull final NetworkAgentConfig config,
-            @NonNull final LinkProperties prop, @NonNull final NetworkCapabilities caps) {
+    private void notifyNetworkConnected(NetworkMonitor nm, LinkProperties lp,
+            NetworkCapabilities nc) throws Exception {
+        notifyNetworkConnected(nm, TEST_AGENT_CONFIG, lp, nc);
+    }
+
+    private void notifyNetworkConnected(NetworkMonitor nm, NetworkCapabilities nc)
+            throws Exception {
+        notifyNetworkConnected(nm, TEST_LINK_PROPERTIES, nc);
+    }
+
+    private NetworkMonitorParameters makeParams(@NonNull final NetworkAgentConfigShim config,
+            @NonNull final LinkProperties prop, @NonNull final NetworkCapabilities caps)
+            throws Exception {
         final NetworkMonitorParameters params = new NetworkMonitorParameters();
-        params.networkAgentConfig = config;
+        params.networkAgentConfig = (NetworkAgentConfig) config.getConfig();
         params.linkProperties = prop;
         params.networkCapabilities = caps;
         return params;