Snap for 8303596 from e52428eb05bfb81414653d24ae4b809b88dac884 to mainline-sdkext-release

Change-Id: I31f087abe33c5cbb936da8f4fbd950b7e9ad2e8a
diff --git a/Android.bp b/Android.bp
index dd7e8c6..d11bf8a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -45,6 +45,8 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+// TODO: remove this default and replace with ConnectivityNextEnableDefaults. This will need to be
+// done separately in each branch due to merge conflicts.
 // Defaults to enable/disable java targets that depend on
 // NetworkStackNext, which uses development APIs. "enabled" may
 // have a different value depending on the branch.
@@ -159,7 +161,7 @@
 // integer so if the next SDK release happens to use that integer, we don't need to rename them.
 java_library {
     name: "NetworkStackApi33Shims",
-    defaults: ["NetworkStackShimsDefaults"],
+    defaults: ["NetworkStackShimsDefaults", "ConnectivityNextEnableDefaults"],
     srcs: [
         "apishim/33/**/*.java",
     ],
@@ -168,7 +170,10 @@
         "NetworkStackApi29Shims",
         "NetworkStackApi30Shims",
         "NetworkStackApi31Shims",
+        "framework-bluetooth",
         "framework-connectivity",
+        "framework-connectivity-t.stubs.module_lib",
+        "framework-tethering",
     ],
     sdk_version: "module_current",
     visibility: ["//visibility:private"],
@@ -179,7 +184,7 @@
 // called directly by the networkstack code.
 java_library {
     name: "NetworkStackApiCurrentShims",
-    defaults: ["NetworkStackShimsDefaults"],
+    defaults: ["NetworkStackShimsDefaults", "ConnectivityNextEnableDefaults"],
     static_libs: [
         "NetworkStackShimsCommon",
         "NetworkStackApi29Shims",
@@ -190,6 +195,8 @@
     sdk_version: "module_current",
     visibility: [
         "//packages/modules/Connectivity/Tethering",
+        "//packages/modules/Connectivity/service",
+        "//packages/modules/Connectivity/service-t",
         "//packages/modules/Connectivity/tests/cts/net",
         "//packages/modules/Connectivity/tests/cts/hostside/app",
     ],
@@ -211,8 +218,9 @@
     sdk_version: "module_31",
     visibility: [
         "//packages/modules/Connectivity/Tethering",
-        "//packages/modules/Connectivity/tests/cts/net",
-        "//packages/modules/Connectivity/tests/cts/hostside/app",
+        "//packages/modules/Connectivity/service",
+        "//packages/modules/Connectivity/service-t",
+        "//packages/modules/Connectivity/tests/cts:__subpackages__",
     ],
 }
 
@@ -249,7 +257,7 @@
     defaults: [
         "NetworkStackDevApiLevel",
         "NetworkStackAndroidLibraryDefaults",
-        "NetworkStackNextEnableDefaults",
+        "ConnectivityNextEnableDefaults",
     ],
     srcs: [
         "src/**/*.java",
@@ -322,7 +330,7 @@
     defaults: [
         "NetworkStackAppDefaults",
         "NetworkStackDevApiLevel",
-        "NetworkStackNextEnableDefaults",
+        "ConnectivityNextEnableDefaults",
     ],
     static_libs: ["NetworkStackApiCurrentLib"],
     certificate: "platform",
@@ -344,7 +352,7 @@
     defaults: [
         "NetworkStackAppDefaults",
         "NetworkStackDevApiLevel",
-        "NetworkStackNextEnableDefaults",
+        "ConnectivityNextEnableDefaults",
     ],
     static_libs: ["NetworkStackApiCurrentLib"],
     manifest: "AndroidManifest.xml"
@@ -356,7 +364,7 @@
     defaults: [
         "NetworkStackAppDefaults",
         "NetworkStackDevApiLevel",
-        "NetworkStackNextEnableDefaults",
+        "ConnectivityNextEnableDefaults",
     ],
     static_libs: ["NetworkStackNextManifestBase"],
     certificate: "networkstack",
diff --git a/apishim/29/com/android/networkstack/apishim/api29/ConnectivityFrameworkInitShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/ConnectivityFrameworkInitShimImpl.java
new file mode 100644
index 0000000..1bbc1e5
--- /dev/null
+++ b/apishim/29/com/android/networkstack/apishim/api29/ConnectivityFrameworkInitShimImpl.java
@@ -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.
+ */
+
+package com.android.networkstack.apishim.api29;
+
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.ConnectivityFrameworkInitShim;
+
+/**
+ * Implementation of {@link ConnectivityFrameworkInitShim}.
+ */
+@RequiresApi(Build.VERSION_CODES.Q)
+public class ConnectivityFrameworkInitShimImpl implements ConnectivityFrameworkInitShim {
+    /**
+     * Get a new instance of {@link NsdShim}.
+     */
+    public static ConnectivityFrameworkInitShim newInstance() {
+        return new ConnectivityFrameworkInitShimImpl();
+    }
+
+    @Override
+    public void registerServiceWrappers() {
+        // No-op: ConnectivityFrameworkInitializer doesn't exist before S
+    }
+}
diff --git a/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java b/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java
index 0b000a9..a6ca1f1 100644
--- a/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java
+++ b/apishim/29/com/android/networkstack/apishim/api29/ConstantsShim.java
@@ -42,4 +42,6 @@
     // Constants defined in android.net.NetworkCapabilities.
     public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28;
 
+    // Constants defined in android.content.Context
+    public static final String NEARBY_SERVICE = "nearby";
 }
diff --git a/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileBuilderShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileBuilderShimImpl.java
new file mode 100644
index 0000000..754933a
--- /dev/null
+++ b/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileBuilderShimImpl.java
@@ -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.
+ */
+
+package com.android.networkstack.apishim.api29;
+
+import com.android.networkstack.apishim.common.Ikev2VpnProfileBuilderShim;
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+
+/**
+ * Implementation of Ikev2VpnProfileBuilderShim for API 29.
+  *
+ * @param <T> type of builder, typically Ikev2VpnProfile.Builder. This is necessary because at
+ *            compile time, shims for older releases will not have access to this class as it
+ *            debuted in SDK30. So the user of the shim has to pass it in.
+ */
+// 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.
+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
new file mode 100644
index 0000000..b3f5f43
--- /dev/null
+++ b/apishim/29/com/android/networkstack/apishim/api29/Ikev2VpnProfileShimImpl.java
@@ -0,0 +1,35 @@
+/*
+ * 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 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/NetworkAgentConfigShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/NetworkAgentConfigShimImpl.java
new file mode 100644
index 0000000..c2260dc
--- /dev/null
+++ b/apishim/29/com/android/networkstack/apishim/api29/NetworkAgentConfigShimImpl.java
@@ -0,0 +1,29 @@
+/*
+ * 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 com.android.networkstack.apishim.common.NetworkAgentConfigShim;
+
+/**
+ * Implementation of NetworkAgentConfigShim for API 29.
+ */
+public class NetworkAgentConfigShimImpl implements NetworkAgentConfigShim {
+    @Override
+    public boolean isVpnValidationRequired() {
+        return false;
+    }
+}
diff --git a/apishim/29/com/android/networkstack/apishim/api29/NsdShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/NsdShimImpl.java
new file mode 100644
index 0000000..b54746a
--- /dev/null
+++ b/apishim/29/com/android/networkstack/apishim/api29/NsdShimImpl.java
@@ -0,0 +1,71 @@
+/*
+ * 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.net.Network;
+import android.net.NetworkRequest;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.NsdShim;
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+
+/**
+ * Implementation of {@link NsdShim}.
+ */
+@RequiresApi(Build.VERSION_CODES.Q)
+public class NsdShimImpl implements NsdShim {
+
+    /**
+     * Get a new instance of {@link NsdShim}.
+     */
+    public static NsdShim newInstance() {
+        return new NsdShimImpl();
+    }
+
+    @Nullable
+    @Override
+    public Network getNetwork(@NonNull NsdServiceInfo serviceInfo) {
+        // NsdServiceInfo has no Network before T
+        return null;
+    }
+
+    @Override
+    public void setNetwork(@NonNull NsdServiceInfo serviceInfo, @Nullable Network network) {
+        // No-op: NsdServiceInfo has no Network before T
+    }
+
+    @Override
+    public void discoverServices(@NonNull NsdManager nsdManager, @NonNull String serviceType,
+            int protocolType, @Nullable Network network,
+            @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 {
+        throw new UnsupportedApiLevelException(
+                "Discover with NetworkRequest is only supported on T+");
+    }
+}
diff --git a/apishim/29/com/android/networkstack/apishim/api29/TelephonyManagerShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/TelephonyManagerShimImpl.java
new file mode 100644
index 0000000..376c4f3
--- /dev/null
+++ b/apishim/29/com/android/networkstack/apishim/api29/TelephonyManagerShimImpl.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.api29;
+
+import android.os.Build;
+import android.telephony.TelephonyManager;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.TelephonyManagerShim;
+
+/**
+ * Implementation of {@link TelephonyManagerShim} for API 29.
+ */
+@RequiresApi(Build.VERSION_CODES.Q)
+public class TelephonyManagerShimImpl implements TelephonyManagerShim {
+    protected final TelephonyManager mTm;
+    public TelephonyManagerShimImpl(TelephonyManager tm) {
+        mTm = tm;
+    }
+}
diff --git a/apishim/30/com/android/networkstack/apishim/api30/BluetoothPanShimImpl.java b/apishim/30/com/android/networkstack/apishim/api30/BluetoothPanShimImpl.java
new file mode 100644
index 0000000..60611c5
--- /dev/null
+++ b/apishim/30/com/android/networkstack/apishim/api30/BluetoothPanShimImpl.java
@@ -0,0 +1,55 @@
+/*
+ * 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 android.bluetooth.BluetoothPan;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.BluetoothPanShim;
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Implementation of {@link BluetoothPanShimImpl} for API 30.
+ */
+@RequiresApi(Build.VERSION_CODES.R)
+public class BluetoothPanShimImpl implements BluetoothPanShim {
+    protected final BluetoothPan mPan;
+    protected BluetoothPanShimImpl(BluetoothPan pan) {
+        mPan = pan;
+    }
+
+    /**
+     * Get a new instance of {@link BluetoothPanShimImpl}.
+     */
+    @RequiresApi(Build.VERSION_CODES.R)
+    public static BluetoothPanShim newInstance(final BluetoothPan pan) {
+        return new BluetoothPanShimImpl(pan);
+    }
+
+    @Override
+    public TetheredInterfaceRequestShim requestTetheredInterface(@NonNull final Executor executor,
+            @NonNull final TetheredInterfaceCallbackShim callback)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException(
+                "requestTetheredInterface does not exist before API 32");
+    }
+}
diff --git a/apishim/30/com/android/networkstack/apishim/api30/ConnectivityFrameworkInitShimImpl.java b/apishim/30/com/android/networkstack/apishim/api30/ConnectivityFrameworkInitShimImpl.java
new file mode 100644
index 0000000..7998c93
--- /dev/null
+++ b/apishim/30/com/android/networkstack/apishim/api30/ConnectivityFrameworkInitShimImpl.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+/**
+ * Implementation of {@link ConnectivityFrameworkInitShim}.
+ */
+public class ConnectivityFrameworkInitShimImpl extends
+        com.android.networkstack.apishim.api29.ConnectivityFrameworkInitShimImpl {
+    // Inherit everything from API29 shim
+}
diff --git a/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileBuilderShimImpl.java b/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileBuilderShimImpl.java
new file mode 100644
index 0000000..a8310ce
--- /dev/null
+++ b/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileBuilderShimImpl.java
@@ -0,0 +1,37 @@
+/*
+ * 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 android.net.Ikev2VpnProfile;
+
+import com.android.networkstack.apishim.common.Ikev2VpnProfileBuilderShim;
+
+/**
+ * Implementation of Ikev2VpnProfileBuilderShim for API 30.
+ */
+// TODO : when API29 is no longer supported, remove the type argument
+public class Ikev2VpnProfileBuilderShimImpl
+        extends com.android.networkstack.apishim.api29.Ikev2VpnProfileBuilderShimImpl<
+                Ikev2VpnProfile.Builder
+        > {
+    /**
+     * Returns a new instance of this shim impl.
+     */
+    public static Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> newInstance() {
+        return new Ikev2VpnProfileBuilderShimImpl();
+    }
+}
diff --git a/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileShimImpl.java b/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileShimImpl.java
new file mode 100644
index 0000000..cd7938f
--- /dev/null
+++ b/apishim/30/com/android/networkstack/apishim/api30/Ikev2VpnProfileShimImpl.java
@@ -0,0 +1,35 @@
+/*
+ * 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 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();
+    }
+}
diff --git a/apishim/30/com/android/networkstack/apishim/api30/TelephonyManagerShimImpl.java b/apishim/30/com/android/networkstack/apishim/api30/TelephonyManagerShimImpl.java
new file mode 100644
index 0000000..67344f5
--- /dev/null
+++ b/apishim/30/com/android/networkstack/apishim/api30/TelephonyManagerShimImpl.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.api30;
+
+import android.os.Build;
+import android.telephony.TelephonyManager;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.TelephonyManagerShim;
+
+/**
+ * Implementation of {@link TelephonyManagerShim} for API 30.
+ */
+@RequiresApi(Build.VERSION_CODES.R)
+public class TelephonyManagerShimImpl
+        extends com.android.networkstack.apishim.api29.TelephonyManagerShimImpl {
+    public TelephonyManagerShimImpl(TelephonyManager telephonyManager) {
+        super(telephonyManager);
+    }
+}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/BluetoothPanShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/BluetoothPanShimImpl.java
new file mode 100644
index 0000000..eb7f719
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/BluetoothPanShimImpl.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.api31;
+
+import android.bluetooth.BluetoothPan;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+/**
+ * Implementation of {@link com.android.networkstack.apishim.common.BluetoothPanShim}.
+ */
+@RequiresApi(Build.VERSION_CODES.S)
+public class BluetoothPanShimImpl extends
+        com.android.networkstack.apishim.api30.BluetoothPanShimImpl {
+    protected BluetoothPanShimImpl(BluetoothPan pan) {
+        super(pan);
+    }
+}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/ConnectivityFrameworkInitShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/ConnectivityFrameworkInitShimImpl.java
new file mode 100644
index 0000000..02d7853
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/ConnectivityFrameworkInitShimImpl.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+/**
+ * Implementation of {@link ConnectivityFrameworkInitShim}.
+ */
+public class ConnectivityFrameworkInitShimImpl extends
+        com.android.networkstack.apishim.api30.ConnectivityFrameworkInitShimImpl {
+    // Inherit everything from API30 shim
+}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/ConstantsShim.java b/apishim/31/com/android/networkstack/apishim/api31/ConstantsShim.java
index 95ff072..5ceb191 100644
--- a/apishim/31/com/android/networkstack/apishim/api31/ConstantsShim.java
+++ b/apishim/31/com/android/networkstack/apishim/api31/ConstantsShim.java
@@ -34,4 +34,17 @@
     // When removing this shim, the version in NetworkMonitorUtils should be removed too.
     // TODO: add TRANSPORT_TEST to system API in API 31 (it is only a test API as of R)
     public static final int TRANSPORT_TEST = 7;
+
+    /**
+     * Flag for {@link #registerReceiver}: The receiver can receive broadcasts from other apps;
+     * has the same behavior as marking a statically registered receiver with "exported=true".
+     */
+    public static final int RECEIVER_EXPORTED = 0x2;
+
+    /**
+     * Flag for {@link android.content.Context#registerReceiver}: The receiver cannot receive
+     * broadcasts from other apps; has the same behavior as marking a statically registered receiver
+     * with "exported=false".
+     */
+    public static final int RECEIVER_NOT_EXPORTED = 0x4;
 }
diff --git a/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileBuilderShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileBuilderShimImpl.java
new file mode 100644
index 0000000..d4f25d6
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileBuilderShimImpl.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+/**
+ * Implementation of Ikev2VpnProfileBuilderShim for API 31.
+ */
+public class Ikev2VpnProfileBuilderShimImpl
+        extends com.android.networkstack.apishim.api30.Ikev2VpnProfileBuilderShimImpl {
+}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileShimImpl.java
new file mode 100644
index 0000000..e2d8b59
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/Ikev2VpnProfileShimImpl.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+/**
+ * Implementation of Ikev2VpnProfileShim for API 31.
+ */
+public class Ikev2VpnProfileShimImpl extends
+        com.android.networkstack.apishim.api30.Ikev2VpnProfileShimImpl {
+}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/NetworkAgentConfigShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/NetworkAgentConfigShimImpl.java
new file mode 100644
index 0000000..908cc1d
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/NetworkAgentConfigShimImpl.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.api31;
+
+import android.net.NetworkAgentConfig;
+
+import androidx.annotation.Nullable;
+
+import com.android.networkstack.apishim.common.NetworkAgentConfigShim;
+
+/**
+ * Implementation of NetworkAgentConfigShim for API 31.
+ *
+ * Compared with API29, NetworkAgentConfig is now API, though the shim currently doesn't
+ * need to implement any of its methods yet.
+ */
+public class NetworkAgentConfigShimImpl
+        extends com.android.networkstack.apishim.api29.NetworkAgentConfigShimImpl {
+    // This can be null when running on a device with an old Connectivity module.
+    @Nullable
+    protected final NetworkAgentConfig mNetworkAgentConfig;
+
+    protected NetworkAgentConfigShimImpl(@Nullable final NetworkAgentConfig config) {
+        mNetworkAgentConfig = config;
+    }
+
+    /**
+     * Returns a new instance of this shim impl.
+     */
+    public static NetworkAgentConfigShim newInstance(@Nullable final NetworkAgentConfig config) {
+        return new NetworkAgentConfigShimImpl(config);
+    }
+}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/NsdShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/NsdShimImpl.java
new file mode 100644
index 0000000..0e89b59
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/NsdShimImpl.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+/**
+ * Implementation of {@link com.android.networkstack.apishim.common.NsdShim}.
+ */
+public class NsdShimImpl extends com.android.networkstack.apishim.api29.NsdShimImpl {
+    // Inherit everything from API29 shim
+}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/TelephonyManagerShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/TelephonyManagerShimImpl.java
new file mode 100644
index 0000000..74d200d
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/TelephonyManagerShimImpl.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.api31;
+
+import android.os.Build;
+import android.telephony.TelephonyManager;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.TelephonyManagerShim;
+
+/**
+ * Implementation of {@link TelephonyManagerShim} for API 31.
+ */
+@RequiresApi(Build.VERSION_CODES.S)
+public class TelephonyManagerShimImpl
+        extends com.android.networkstack.apishim.api30.TelephonyManagerShimImpl {
+    public TelephonyManagerShimImpl(TelephonyManager telephonyManager) {
+        super(telephonyManager);
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/BluetoothPanShimImpl.java b/apishim/33/com/android/networkstack/apishim/BluetoothPanShimImpl.java
new file mode 100644
index 0000000..990a312
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/BluetoothPanShimImpl.java
@@ -0,0 +1,80 @@
+/*
+ * 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.bluetooth.BluetoothPan;
+import android.net.TetheringManager.TetheredInterfaceCallback;
+import android.net.TetheringManager.TetheredInterfaceRequest;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.BluetoothPanShim;
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Implementation of {@link BluetoothPanShimImpl} for API 33.
+ */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class BluetoothPanShimImpl extends
+        com.android.networkstack.apishim.api31.BluetoothPanShimImpl {
+    protected BluetoothPanShimImpl(BluetoothPan pan) {
+        super(pan);
+    }
+
+    /**
+     * Get a new instance of {@link BluetoothPanShimImpl}.
+     */
+    @RequiresApi(Build.VERSION_CODES.R)
+    public static BluetoothPanShim newInstance(final BluetoothPan pan) {
+        if (!isAtLeastT()) {
+            return com.android.networkstack.apishim.api31.BluetoothPanShimImpl
+                    .newInstance(pan);
+        }
+        return new BluetoothPanShimImpl(pan);
+    }
+
+    @Override
+    public TetheredInterfaceRequestShim requestTetheredInterface(@NonNull final Executor executor,
+            @NonNull final TetheredInterfaceCallbackShim callback)
+            throws UnsupportedApiLevelException {
+        TetheredInterfaceRequest request = mPan.requestTetheredInterface(executor,
+                new TetheredInterfaceCallback() {
+                    public void onAvailable(@NonNull String iface) {
+                        callback.onAvailable(iface);
+                    }
+
+                    public void onUnavailable() {
+                        callback.onUnavailable();
+                    }
+                });
+
+        if (request == null) return null;
+
+        return new TetheredInterfaceRequestShim() {
+            @Override
+            public void release() {
+                request.release();
+            }
+        };
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/ConnectivityFrameworkInitShimImpl.java b/apishim/33/com/android/networkstack/apishim/ConnectivityFrameworkInitShimImpl.java
new file mode 100644
index 0000000..2fc4ca1
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/ConnectivityFrameworkInitShimImpl.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;
+
+import android.net.ConnectivityFrameworkInitializerTiramisu;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.networkstack.apishim.common.ConnectivityFrameworkInitShim;
+
+/**
+ * Implementation of {@link ConnectivityFrameworkInitShim}.
+ */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class ConnectivityFrameworkInitShimImpl extends
+        com.android.networkstack.apishim.api31.ConnectivityFrameworkInitShimImpl {
+    /**
+     * Get a new instance of {@link ConnectivityFrameworkInitShimImpl}.
+     */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static ConnectivityFrameworkInitShim newInstance() {
+        if (SdkLevel.isAtLeastT()) {
+            return new ConnectivityFrameworkInitShimImpl();
+        } else {
+            return new com.android.networkstack.apishim.api31.ConnectivityFrameworkInitShimImpl();
+        }
+    }
+
+    @Override
+    public void registerServiceWrappers() {
+        ConnectivityFrameworkInitializerTiramisu.registerServiceWrappers();
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java b/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java
new file mode 100644
index 0000000..d3315a2
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileBuilderShimImpl.java
@@ -0,0 +1,56 @@
+/*
+ * 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.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.Ikev2VpnProfileBuilderShim;
+
+/**
+ * A shim for Ikev2VpnProfile.Builder
+ */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class Ikev2VpnProfileBuilderShimImpl
+        extends com.android.networkstack.apishim.api31.Ikev2VpnProfileBuilderShimImpl {
+    /**
+     * Returns a new instance of this shim impl.
+     */
+    @RequiresApi(Build.VERSION_CODES.R)
+    public static Ikev2VpnProfileBuilderShim<Ikev2VpnProfile.Builder> newInstance() {
+        if (SdkLevel.isAtLeastT()) {
+            return new Ikev2VpnProfileBuilderShimImpl();
+        } else {
+            return com.android.networkstack.apishim.api31.Ikev2VpnProfileBuilderShimImpl
+                    .newInstance();
+        }
+    }
+
+    /**
+     * @see Ikev2VpnProfile.Builder#setRequiresInternetValidation(boolean)
+     */
+    @Override
+    public Ikev2VpnProfile.Builder setRequiresInternetValidation(
+            @NonNull final Ikev2VpnProfile.Builder builder, boolean requiresInternetValidation) {
+        builder.setRequiresInternetValidation(requiresInternetValidation);
+        return builder;
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java b/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
new file mode 100644
index 0000000..ccaf497
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/Ikev2VpnProfileShimImpl.java
@@ -0,0 +1,53 @@
+/*
+ * 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.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();
+        }
+    }
+
+    /**
+     * @see Ikev2VpnProfile#isInternetValidationRequired()
+     */
+    @Override
+    public boolean isInternetValidationRequired(@NonNull final Ikev2VpnProfile profile) {
+        return profile.isInternetValidationRequired();
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/NetworkAgentConfigShimImpl.java b/apishim/33/com/android/networkstack/apishim/NetworkAgentConfigShimImpl.java
new file mode 100644
index 0000000..912b721
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/NetworkAgentConfigShimImpl.java
@@ -0,0 +1,65 @@
+/*
+ * 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.net.NetworkAgentConfig;
+
+import androidx.annotation.Nullable;
+
+import com.android.networkstack.apishim.common.NetworkAgentConfigShim;
+
+/**
+ * A shim for NetworkAgentConfig
+ */
+public class NetworkAgentConfigShimImpl
+        extends com.android.networkstack.apishim.api31.NetworkAgentConfigShimImpl {
+    protected NetworkAgentConfigShimImpl(@Nullable final NetworkAgentConfig config) {
+        super(config);
+    }
+
+    /**
+     * Returns a new instance of this shim impl.
+     */
+    public static NetworkAgentConfigShim newInstance(@Nullable final NetworkAgentConfig config) {
+        if (!isAtLeastT()) {
+            return com.android.networkstack.apishim.api31.NetworkAgentConfigShimImpl
+                    .newInstance(config);
+        } else {
+            return new NetworkAgentConfigShimImpl(config);
+        }
+    }
+
+    @Override
+    public boolean isVpnValidationRequired() {
+        if (null == mNetworkAgentConfig) {
+            return false;
+        } else {
+            return mNetworkAgentConfig.isVpnValidationRequired();
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (null == mNetworkAgentConfig) {
+            return "NetworkAgentConfigShimImpl[null]";
+        } else {
+            return mNetworkAgentConfig.toString();
+        }
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/NsdShimImpl.java b/apishim/33/com/android/networkstack/apishim/NsdShimImpl.java
new file mode 100644
index 0000000..bee56d3
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/NsdShimImpl.java
@@ -0,0 +1,75 @@
+/*
+ * 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.net.Network;
+import android.net.NetworkRequest;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.networkstack.apishim.common.NsdShim;
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+
+/**
+ * Implementation of {@link com.android.networkstack.apishim.common.NsdShim}.
+ */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class NsdShimImpl extends com.android.networkstack.apishim.api31.NsdShimImpl {
+
+    /**
+     * Get a new instance of {@link NsdShim}.
+     */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static NsdShim newInstance() {
+        if (SdkLevel.isAtLeastT()) {
+            return new NsdShimImpl();
+        } else {
+            return new com.android.networkstack.apishim.api31.NsdShimImpl();
+        }
+    }
+
+    @Nullable
+    @Override
+    public Network getNetwork(@NonNull NsdServiceInfo serviceInfo) {
+        return serviceInfo.getNetwork();
+    }
+
+    @Override
+    public void setNetwork(@NonNull NsdServiceInfo serviceInfo, @Nullable Network network) {
+        serviceInfo.setNetwork(network);
+    }
+
+    @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);
+    }
+
+    @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);
+    }
+}
diff --git a/apishim/33/com/android/networkstack/apishim/TelephonyManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/TelephonyManagerShimImpl.java
new file mode 100644
index 0000000..98e061d
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/TelephonyManagerShimImpl.java
@@ -0,0 +1,73 @@
+/*
+ * 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.telephony.TelephonyManager;
+import android.telephony.TelephonyManager.CarrierPrivilegesListener;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.networkstack.apishim.common.TelephonyManagerShim;
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * Implementation of {@link TelephonyManagerShim} for API 33.
+ */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class TelephonyManagerShimImpl extends
+        com.android.networkstack.apishim.api31.TelephonyManagerShimImpl {
+    private HashMap<CarrierPrivilegesListenerShim, CarrierPrivilegesListener> mListenerMap =
+            new HashMap<>();
+    public TelephonyManagerShimImpl(TelephonyManager telephonyManager) {
+        super(telephonyManager);
+    }
+
+    /** See android.telephony.TelephonyManager#addCarrierPrivilegesListener */
+    public void addCarrierPrivilegesListener(
+            int logicalSlotIndex,
+            Executor executor,
+            CarrierPrivilegesListenerShim listener)
+            throws UnsupportedApiLevelException {
+        CarrierPrivilegesListener carrierPrivilegesListener = new CarrierPrivilegesListener() {
+            public void onCarrierPrivilegesChanged(
+                    List<String> privilegedPackageNames,
+                    int[] privilegedUids) {
+                listener.onCarrierPrivilegesChanged(privilegedPackageNames, privilegedUids);
+            }
+        };
+        mTm.addCarrierPrivilegesListener(logicalSlotIndex, executor, carrierPrivilegesListener);
+        mListenerMap.put(listener, carrierPrivilegesListener);
+    }
+
+    /** See android.telephony.TelephonyManager#addCarrierPrivilegesListener */
+    public void removeCarrierPrivilegesListener(
+            CarrierPrivilegesListenerShim listener)
+            throws UnsupportedApiLevelException {
+        mTm.removeCarrierPrivilegesListener(mListenerMap.get(listener));
+        mListenerMap.remove(listener);
+    }
+
+    /** See android.telephony.TelephonyManager#getCarrierServicePackageNameForLogicalSlot */
+    public String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex) {
+        return mTm.getCarrierServicePackageNameForLogicalSlot(logicalSlotIndex);
+    }
+}
diff --git a/apishim/common/com/android/networkstack/apishim/common/BluetoothPanShim.java b/apishim/common/com/android/networkstack/apishim/common/BluetoothPanShim.java
new file mode 100644
index 0000000..801a0e6
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/BluetoothPanShim.java
@@ -0,0 +1,52 @@
+/*
+ * 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 androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Interface for accessing API methods in {@link android.bluetooth.BluetoothPan} by different SDK
+ * level.
+ */
+public interface BluetoothPanShim {
+    /** Use to deal with the TetheringManager#TetheredInterfaceRequest by different sdk version. */
+    public interface TetheredInterfaceRequestShim {
+        /** Release the request to tear down tethered interface */
+        default void release() {}
+    }
+
+    /** Use to deal with the TetheringManager#TetheredInterfaceCallback by different sdk version. */
+    public interface TetheredInterfaceCallbackShim {
+        /** Called when the tethered interface is available. */
+        default void onAvailable(@NonNull String iface) {}
+
+        /** Called when the tethered interface is now unavailable. */
+        default void onUnavailable() {}
+    }
+
+    /**
+     * Use to deal with the BluetoothPan#setBluetoothTethering and
+     * BluetoothPan#requestTetheredInterface by different sdk version. This can return null if the
+     * service is not available.
+     */
+    @Nullable
+    TetheredInterfaceRequestShim requestTetheredInterface(@NonNull Executor executor,
+            @NonNull TetheredInterfaceCallbackShim callback) throws UnsupportedApiLevelException;
+}
diff --git a/apishim/common/com/android/networkstack/apishim/common/ConnectivityFrameworkInitShim.java b/apishim/common/com/android/networkstack/apishim/common/ConnectivityFrameworkInitShim.java
new file mode 100644
index 0000000..e0a763a
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/ConnectivityFrameworkInitShim.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;
+
+
+/** Shim for ConnectivityFrameworkInitializer APIs */
+public interface ConnectivityFrameworkInitShim {
+    /**
+     * @see ConnectivityFrameworkInitializer[Android version]#registerServiceWrappers()
+     */
+    void registerServiceWrappers();
+}
diff --git a/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileBuilderShim.java b/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileBuilderShim.java
new file mode 100644
index 0000000..b2483e3
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileBuilderShim.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.common;
+
+/**
+ * A shim for Ikev2VpnProfile.Builder.
+ *
+ * T should extend Ikev2VpnProfile.Builder, but this can't be written here as that class is not
+ * available in API29.
+ * @param <T> type of builder, typically Ikev2VpnProfile.Builder
+ */
+// TODO : when API29 is no longer supported, remove the type argument
+public interface Ikev2VpnProfileBuilderShim<T> {
+    /**
+     * @see Ikev2VpnProfile.Builder#setRequiresInternetValidation(boolean)
+     */
+    T setRequiresInternetValidation(T builder, boolean requiresInternetValidation)
+            throws UnsupportedApiLevelException;
+}
diff --git a/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileShim.java b/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileShim.java
new file mode 100644
index 0000000..4a79c43
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/Ikev2VpnProfileShim.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * A shim for Ikev2VpnProfile.
+ *
+ * T should extend Ikev2VpnProfile, but this can't be written here as that class is not
+ * available in API29.
+ * @param <T> type of profile, typically Ikev2VpnProfile
+ */
+// TODO : when API29 is no longer supported, remove the type argument
+public interface Ikev2VpnProfileShim<T> {
+    /**
+     * @see Ikev2VpnProfile#isInternetValidationRequired()
+     */
+    boolean isInternetValidationRequired(T profile) throws UnsupportedApiLevelException;
+}
diff --git a/apishim/common/com/android/networkstack/apishim/common/NetworkAgentConfigShim.java b/apishim/common/com/android/networkstack/apishim/common/NetworkAgentConfigShim.java
new file mode 100644
index 0000000..fb0e545
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/NetworkAgentConfigShim.java
@@ -0,0 +1,29 @@
+/*
+ * 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.NetworkAgentConfig;
+
+/**
+ * A shim for NetworkAgentConfig
+ */
+public interface NetworkAgentConfigShim {
+    /**
+     * @see NetworkAgentConfig#isVpnValidationRequired()
+     */
+    boolean isVpnValidationRequired();
+}
diff --git a/apishim/common/com/android/networkstack/apishim/common/NsdShim.java b/apishim/common/com/android/networkstack/apishim/common/NsdShim.java
new file mode 100644
index 0000000..ff5209e
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/NsdShim.java
@@ -0,0 +1,54 @@
+/*
+ * 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.Network;
+import android.net.NetworkRequest;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/** Shim for NSD APIs, including {@link android.net.nsd.NsdManager} and
+ * {@link android.net.nsd.NsdServiceInfo}. */
+public interface NsdShim {
+    /**
+     * @see NsdServiceInfo#getNetwork()
+     */
+    @Nullable
+    Network getNetwork(@NonNull NsdServiceInfo serviceInfo);
+
+    /**
+     * @see NsdServiceInfo#setNetwork(Network)
+     */
+    void setNetwork(@NonNull NsdServiceInfo serviceInfo, @Nullable Network network);
+
+    /**
+     * @see NsdManager#discoverServices(String, int, Network, NsdManager.DiscoveryListener)
+     */
+    void discoverServices(@NonNull NsdManager nsdManager, @NonNull String serviceType,
+            int protocolType, @Nullable Network network,
+            @NonNull NsdManager.DiscoveryListener listener) throws UnsupportedApiLevelException;
+
+    /**
+     * @see NsdManager#discoverServices(String, int, NetworkRequest, NsdManager.DiscoveryListener)
+     */
+    void discoverServices(@NonNull NsdManager nsdManager, @NonNull String serviceType,
+            int protocolType, @Nullable NetworkRequest request,
+            @NonNull NsdManager.DiscoveryListener listener) throws UnsupportedApiLevelException;
+}
diff --git a/apishim/common/com/android/networkstack/apishim/common/TelephonyManagerShim.java b/apishim/common/com/android/networkstack/apishim/common/TelephonyManagerShim.java
new file mode 100644
index 0000000..492624a
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/TelephonyManagerShim.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.apishim.common;
+
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * Interface used to access API methods in {@link android.telephony.TelephonyManager}, with
+ * appropriate fallbacks if the methods are not yet part of the released API.
+ *
+ * <p>This interface makes it easier for callers to use TelephonyManagerShimImpl, as it's more
+ * obvious what methods must be implemented on each API level, and it abstracts from callers the
+ * need to reference classes that have different implementations (which also does not work well
+ * with IDEs).
+ */
+public interface TelephonyManagerShim {
+    /** See android.telephony.TelephonyManager.CarrierPrivilegesListener */
+    public interface CarrierPrivilegesListenerShim {
+        /** See android.telephony.TelephonyManager
+         * .CarrierPrivilegesListener#onCarrierPrivilegesChanged */
+        void onCarrierPrivilegesChanged(
+                List<String> privilegedPackageNames,
+                int[] privilegedUids);
+    }
+
+    /** See android.telephony.TelephonyManager#addCarrierPrivilegesListener */
+    default void addCarrierPrivilegesListener(
+            int logicalSlotIndex,
+            Executor executor,
+            CarrierPrivilegesListenerShim listener)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported starting from API 33");
+    }
+
+    /** See android.telephony.TelephonyManager#addCarrierPrivilegesListener */
+    default void removeCarrierPrivilegesListener(
+            CarrierPrivilegesListenerShim listener)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported starting from API 33");
+    }
+
+    /** See android.telephony.TelephonyManager#getCarrierServicePackageNameForLogicalSlot */
+    default String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported starting from API 33");
+    }
+}
diff --git a/common/moduleutils/Android.bp b/common/moduleutils/Android.bp
index 8e10d29..c0ee3f4 100644
--- a/common/moduleutils/Android.bp
+++ b/common/moduleutils/Android.bp
@@ -26,7 +26,6 @@
     name: "net-module-utils-srcs",
     srcs: [
         "src/android/net/shared/NetdUtils.java",
-        "src/android/net/util/InterfaceParams.java",
         "src/android/net/util/SharedLog.java",
     ],
     visibility: [
@@ -63,7 +62,6 @@
         "src/android/net/ip/IpNeighborMonitor.java",
         "src/android/net/ip/NetlinkMonitor.java",
         "src/android/net/shared/NetdUtils.java",
-        "src/android/net/util/InterfaceParams.java",
         "src/android/net/util/SharedLog.java",
     ],
     visibility: [
diff --git a/common/moduleutils/src/android/net/util/InterfaceParams.java b/common/moduleutils/src/android/net/util/InterfaceParams.java
deleted file mode 100644
index 0982981..0000000
--- a/common/moduleutils/src/android/net/util/InterfaceParams.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import android.net.MacAddress;
-import android.text.TextUtils;
-
-import java.net.NetworkInterface;
-import java.net.SocketException;
-
-
-/**
- * Encapsulate the interface parameters common to IpClient/IpServer components.
- *
- * Basically all java.net.NetworkInterface methods throw Exceptions. IpClient
- * and IpServer (sub)components need most or all of this information at some
- * point during their lifecycles, so pass only this simplified object around
- * which can be created once when IpClient/IpServer are told to start.
- *
- * @hide
- */
-public class InterfaceParams {
-    public final String name;
-    public final int index;
-    public final boolean hasMacAddress;
-    public final MacAddress macAddr;
-    public final int defaultMtu;
-
-    // TODO: move the below to NetworkStackConstants when this class is moved to the NetworkStack.
-    private static final int ETHER_MTU = 1500;
-    private static final int IPV6_MIN_MTU = 1280;
-
-
-    public static InterfaceParams getByName(String name) {
-        final NetworkInterface netif = getNetworkInterfaceByName(name);
-        if (netif == null) return null;
-
-        // Not all interfaces have MAC addresses, e.g. rmnet_data0.
-        final MacAddress macAddr = getMacAddress(netif);
-
-        try {
-            return new InterfaceParams(name, netif.getIndex(), macAddr, netif.getMTU());
-        } catch (IllegalArgumentException|SocketException e) {
-            return null;
-        }
-    }
-
-    public InterfaceParams(String name, int index, MacAddress macAddr) {
-        this(name, index, macAddr, ETHER_MTU);
-    }
-
-    public InterfaceParams(String name, int index, MacAddress macAddr, int defaultMtu) {
-        if (TextUtils.isEmpty(name)) {
-            throw new IllegalArgumentException("impossible interface name");
-        }
-
-        if (index <= 0) throw new IllegalArgumentException("invalid interface index");
-
-        this.name = name;
-        this.index = index;
-        this.hasMacAddress = (macAddr != null);
-        this.macAddr = hasMacAddress ? macAddr : MacAddress.fromBytes(new byte[] {
-                0x02, 0x00, 0x00, 0x00, 0x00, 0x00 });
-        this.defaultMtu = (defaultMtu > IPV6_MIN_MTU) ? defaultMtu : IPV6_MIN_MTU;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("%s/%d/%s/%d", name, index, macAddr, defaultMtu);
-    }
-
-    private static NetworkInterface getNetworkInterfaceByName(String name) {
-        try {
-            return NetworkInterface.getByName(name);
-        } catch (NullPointerException|SocketException e) {
-            return null;
-        }
-    }
-
-    private static MacAddress getMacAddress(NetworkInterface netif) {
-        try {
-            return MacAddress.fromBytes(netif.getHardwareAddress());
-        } catch (IllegalArgumentException|NullPointerException|SocketException e) {
-            return null;
-        }
-    }
-}
diff --git a/common/networkstackclient/Android.bp b/common/networkstackclient/Android.bp
index 3c97dc2..6e44450 100644
--- a/common/networkstackclient/Android.bp
+++ b/common/networkstackclient/Android.bp
@@ -34,6 +34,7 @@
         java: {
             apex_available: [
                 "//apex_available:platform",
+                "com.android.bluetooth",
                 "com.android.wifi",
                 "com.android.tethering",
             ],
@@ -100,6 +101,7 @@
         "src/android/net/ip/IIpClientCallbacks.aidl",
         // New AIDL classes should go into android.net.networkstack.aidl so they can be clearly
         // identified
+        "src/android/net/networkstack/aidl/NetworkMonitorParameters.aidl",
         "src/android/net/networkstack/aidl/dhcp/DhcpOption.aidl",
         "src/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl",
         "src/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl",
@@ -108,11 +110,15 @@
         java: {
             apex_available: [
                 "//apex_available:platform",
+                "com.android.bluetooth",
                 "com.android.wifi",
                 "com.android.tethering",
             ],
             // this is part of updatable modules(NetworkStack) which targets 29(Q)
             min_sdk_version: "29",
+            lint: {
+                enabled: false,
+            },
         },
         ndk: {
             enabled: false,
@@ -136,6 +142,7 @@
         "11",
         "12",
         "13",
+        "14",
     ],
     // TODO: have tethering depend on networkstack-client and set visibility to private
     visibility: [
@@ -151,11 +158,12 @@
     min_sdk_version: "29",
     static_libs: [
         "ipmemorystore-aidl-interfaces-V10-java",
-        "networkstack-aidl-interfaces-V13-java",
+        "networkstack-aidl-interfaces-V14-java",
     ],
     visibility: ["//packages/modules/NetworkStack:__subpackages__"],
     apex_available: [
         "//apex_available:platform",
+        "com.android.bluetooth",
         "com.android.tethering",
         "com.android.wifi",
     ],
@@ -185,6 +193,7 @@
     ],
     static_libs: [
         "networkstack-aidl-latest",
+        "modules-utils-build",
     ],
     visibility: [
         "//frameworks/base/packages/Connectivity/service",
@@ -193,6 +202,7 @@
         "//frameworks/base/services/net",
         "//frameworks/opt/net/wifi/service",
         "//packages/apps/Bluetooth",
+        "//packages/modules/Bluetooth/android/app",
         "//packages/modules/NetworkStack",
     ],
     apex_available: [
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/.hash b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/.hash
new file mode 100644
index 0000000..5f638b6
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/.hash
@@ -0,0 +1 @@
+76b76d8bfc2fdacc6f5989fc9ec18abff61bfa32
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/DataStallReportParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/DataStallReportParcelable.aidl
new file mode 100644
index 0000000..771deda
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/DhcpResultsParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/DhcpResultsParcelable.aidl
new file mode 100644
index 0000000..31f2194
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/INetworkMonitor.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/INetworkMonitor.aidl
new file mode 100644
index 0000000..fc6a70e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/INetworkMonitorCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/INetworkMonitorCallbacks.aidl
new file mode 100644
index 0000000..36eda8e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/INetworkStackConnector.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/INetworkStackConnector.aidl
new file mode 100644
index 0000000..8120ffc
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/INetworkStackStatusCallback.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/INetworkStackStatusCallback.aidl
new file mode 100644
index 0000000..0b6b778
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/InformationElementParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/InformationElementParcelable.aidl
new file mode 100644
index 0000000..6103774
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/InitialConfigurationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/InitialConfigurationParcelable.aidl
new file mode 100644
index 0000000..6a597e6
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/Layer2InformationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/Layer2InformationParcelable.aidl
new file mode 100644
index 0000000..83796ee
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/Layer2PacketParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/Layer2PacketParcelable.aidl
new file mode 100644
index 0000000..4b3fff5
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/NattKeepalivePacketDataParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/NattKeepalivePacketDataParcelable.aidl
new file mode 100644
index 0000000..18cf954
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/NetworkTestResultParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/NetworkTestResultParcelable.aidl
new file mode 100644
index 0000000..4d6d5a2
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/PrivateDnsConfigParcel.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/PrivateDnsConfigParcel.aidl
new file mode 100644
index 0000000..1457caf
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/ProvisioningConfigurationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/ProvisioningConfigurationParcelable.aidl
new file mode 100644
index 0000000..9ecd110
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/ScanResultInfoParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/ScanResultInfoParcelable.aidl
new file mode 100644
index 0000000..94fc27f
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/TcpKeepalivePacketDataParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/TcpKeepalivePacketDataParcelable.aidl
new file mode 100644
index 0000000..0e1c21c
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/dhcp/DhcpLeaseParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/dhcp/DhcpLeaseParcelable.aidl
new file mode 100644
index 0000000..3cd8860
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/dhcp/DhcpServingParamsParcel.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/dhcp/DhcpServingParamsParcel.aidl
new file mode 100644
index 0000000..fa412cb
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -0,0 +1,48 @@
+/**
+ *
+ * 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;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/dhcp/IDhcpEventCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/dhcp/IDhcpEventCallbacks.aidl
new file mode 100644
index 0000000..9312f47
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/dhcp/IDhcpServer.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/dhcp/IDhcpServer.aidl
new file mode 100644
index 0000000..1109f35
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/dhcp/IDhcpServerCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/dhcp/IDhcpServerCallbacks.aidl
new file mode 100644
index 0000000..ab8577c
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/ip/IIpClient.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/ip/IIpClient.aidl
new file mode 100644
index 0000000..a97511e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/ip/IIpClientCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/ip/IIpClientCallbacks.aidl
new file mode 100644
index 0000000..24bbf64
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/networkstack/aidl/NetworkMonitorParameters.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/networkstack/aidl/NetworkMonitorParameters.aidl
new file mode 100644
index 0000000..2ab9db0
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/networkstack/aidl/dhcp/DhcpOption.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/networkstack/aidl/dhcp/DhcpOption.aidl
new file mode 100644
index 0000000..eea3e0d
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl
new file mode 100644
index 0000000..bb88434
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/14/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl
new file mode 100644
index 0000000..70a7db2
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/14/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/INetworkMonitor.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/INetworkMonitor.aidl
index d92196d..fc6a70e 100644
--- a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/INetworkMonitor.aidl
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/INetworkMonitor.aidl
@@ -45,6 +45,7 @@
   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;
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/networkstack/aidl/NetworkMonitorParameters.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/networkstack/aidl/NetworkMonitorParameters.aidl
new file mode 100644
index 0000000..2ab9db0
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/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/src/android/net/INetworkMonitor.aidl b/common/networkstackclient/src/android/net/INetworkMonitor.aidl
index b124734..d6bd999 100644
--- a/common/networkstackclient/src/android/net/INetworkMonitor.aidl
+++ b/common/networkstackclient/src/android/net/INetworkMonitor.aidl
@@ -18,6 +18,7 @@
 import android.net.LinkProperties;
 import android.net.NetworkCapabilities;
 import android.net.PrivateDnsConfigParcel;
+import android.net.networkstack.aidl.NetworkMonitorParameters;
 
 /** @hide */
 oneway interface INetworkMonitor {
@@ -67,8 +68,16 @@
     void forceReevaluation(int uid);
     void notifyPrivateDnsChanged(in PrivateDnsConfigParcel config);
     void notifyDnsResponse(int returnCode);
+    /**
+     * Notify NetworkMonitor that this network connected.
+     * @Deprecated use notifyNetworkConnectedParcel.
+     */
     void notifyNetworkConnected(in LinkProperties lp, in NetworkCapabilities nc);
     void notifyNetworkDisconnected();
     void notifyLinkPropertiesChanged(in LinkProperties lp);
     void notifyNetworkCapabilitiesChanged(in NetworkCapabilities nc);
+    /**
+     * Notify NetworkMonitor that this network connected, version 2
+     */
+    void notifyNetworkConnectedParcel(in NetworkMonitorParameters params);
 }
diff --git a/common/networkstackclient/src/android/net/NetworkMonitorManager.java b/common/networkstackclient/src/android/net/NetworkMonitorManager.java
index 0f66981..98598a1 100644
--- a/common/networkstackclient/src/android/net/NetworkMonitorManager.java
+++ b/common/networkstackclient/src/android/net/NetworkMonitorManager.java
@@ -18,10 +18,13 @@
 
 import android.annotation.Hide;
 import android.annotation.NonNull;
+import android.net.networkstack.aidl.NetworkMonitorParameters;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.modules.utils.build.SdkLevel;
+
 /**
  * A convenience wrapper for INetworkMonitor.
  *
@@ -147,10 +150,15 @@
         }
     }
 
-    public boolean notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
+    public boolean notifyNetworkConnected(NetworkMonitorParameters params) {
         final long token = Binder.clearCallingIdentity();
         try {
-            mNetworkMonitor.notifyNetworkConnected(lp, nc);
+            if (SdkLevel.isAtLeastT()) {
+                mNetworkMonitor.notifyNetworkConnectedParcel(params);
+            } else {
+                mNetworkMonitor.notifyNetworkConnected(params.linkProperties,
+                        params.networkCapabilities);
+            }
             return true;
         } catch (RemoteException e) {
             log("Error in notifyNetworkConnected", e);
diff --git a/common/networkstackclient/src/android/net/networkstack/ModuleNetworkStackClient.java b/common/networkstackclient/src/android/net/networkstack/ModuleNetworkStackClient.java
index cbbae37..c3079fe 100644
--- a/common/networkstackclient/src/android/net/networkstack/ModuleNetworkStackClient.java
+++ b/common/networkstackclient/src/android/net/networkstack/ModuleNetworkStackClient.java
@@ -44,9 +44,7 @@
      */
     @NonNull
     public static synchronized ModuleNetworkStackClient getInstance(Context packageContext) {
-        // TODO(b/149676685): change this check to "< R" once R is defined
-        if (SDK_INT < Build.VERSION_CODES.Q
-                || (SDK_INT == Build.VERSION_CODES.Q && "REL".equals(Build.VERSION.CODENAME))) {
+        if (SDK_INT < Build.VERSION_CODES.R) {
             // The NetworkStack connector is not available through NetworkStack before R
             throw new UnsupportedOperationException(
                     "ModuleNetworkStackClient is not supported on API " + SDK_INT);
diff --git a/common/networkstackclient/src/android/net/networkstack/aidl/NetworkMonitorParameters.aidl b/common/networkstackclient/src/android/net/networkstack/aidl/NetworkMonitorParameters.aidl
new file mode 100644
index 0000000..eb61371
--- /dev/null
+++ b/common/networkstackclient/src/android/net/networkstack/aidl/NetworkMonitorParameters.aidl
@@ -0,0 +1,29 @@
+/**
+ *
+ * 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 android.net.networkstack.aidl;
+
+import android.net.LinkProperties;
+import android.net.NetworkAgentConfig;
+import android.net.NetworkCapabilities;
+
+@JavaDerive(equals=true, toString=true)
+parcelable NetworkMonitorParameters {
+    NetworkAgentConfig networkAgentConfig;
+    NetworkCapabilities networkCapabilities;
+    LinkProperties linkProperties;
+}
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 706f174..e54f11c 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 lokationen"</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="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 bed0ea7..9aec881 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 b5a08ec..e3b7121 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 laman web"</string>
+    <string name="tap_for_info" msgid="6849746325626883711">"Disambungkan / Ketik untuk melihat tapak web"</string>
     <string name="application_label" msgid="1322847171305285454">"Pengurus rangkaian"</string>
 </resources>
diff --git a/src/android/net/DhcpResults.java b/src/android/net/DhcpResults.java
new file mode 100644
index 0000000..ed75282
--- /dev/null
+++ b/src/android/net/DhcpResults.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.net.module.util.InetAddressUtils;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A simple object for retrieving the results of a DHCP request.
+ * Optimized (attempted) for that jni interface
+ * TODO: remove this class and replace with other existing constructs
+ * @hide
+ */
+public final class DhcpResults implements Parcelable {
+    private static final String TAG = "DhcpResults";
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public LinkAddress ipAddress;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public InetAddress gateway;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public final ArrayList<InetAddress> dnsServers = new ArrayList<>();
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public String domains;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public Inet4Address serverAddress;
+
+    /** Vendor specific information (from RFC 2132). */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public String vendorInfo;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public int leaseDuration;
+
+    /** Link MTU option. 0 means unset. */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public int mtu;
+
+    public String serverHostName;
+
+    @Nullable
+    public String captivePortalApiUrl;
+
+    public DhcpResults() {
+        super();
+    }
+
+    /**
+     * Create a {@link StaticIpConfiguration} based on the DhcpResults.
+     */
+    @SuppressLint("NewApi") // TODO: b/193460475 remove once fixed
+    public StaticIpConfiguration toStaticIpConfiguration() {
+        return new StaticIpConfiguration.Builder()
+                .setIpAddress(ipAddress)
+                .setGateway(gateway)
+                .setDnsServers(dnsServers)
+                .setDomains(domains)
+                .build();
+    }
+
+    @SuppressLint("NewApi") // TODO: b/193460475 remove once fixed
+    public DhcpResults(StaticIpConfiguration source) {
+        if (source != null) {
+            ipAddress = source.getIpAddress();
+            gateway = source.getGateway();
+            dnsServers.addAll(source.getDnsServers());
+            domains = source.getDomains();
+        }
+    }
+
+    /** copy constructor */
+    public DhcpResults(DhcpResults source) {
+        this(source == null ? null : source.toStaticIpConfiguration());
+        if (source != null) {
+            serverAddress = source.serverAddress;
+            vendorInfo = source.vendorInfo;
+            leaseDuration = source.leaseDuration;
+            mtu = source.mtu;
+            serverHostName = source.serverHostName;
+            captivePortalApiUrl = source.captivePortalApiUrl;
+        }
+    }
+
+    /**
+     * @see StaticIpConfiguration#getRoutes(String)
+     * @hide
+     */
+    public List<RouteInfo> getRoutes(String iface) {
+        return toStaticIpConfiguration().getRoutes(iface);
+    }
+
+    /**
+     * Test if this DHCP lease includes vendor hint that network link is
+     * metered, and sensitive to heavy data transfers.
+     */
+    public boolean hasMeteredHint() {
+        if (vendorInfo != null) {
+            return vendorInfo.contains("ANDROID_METERED");
+        } else {
+            return false;
+        }
+    }
+
+    /** Clears all data and resets this object to its initial state. */
+    public void clear() {
+        ipAddress = null;
+        gateway = null;
+        dnsServers.clear();
+        domains = null;
+        serverAddress = null;
+        vendorInfo = null;
+        leaseDuration = 0;
+        mtu = 0;
+        serverHostName = null;
+        captivePortalApiUrl = null;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder(super.toString());
+
+        str.append(" DHCP server ").append(serverAddress);
+        str.append(" Vendor info ").append(vendorInfo);
+        str.append(" lease ").append(leaseDuration).append(" seconds");
+        if (mtu != 0) str.append(" MTU ").append(mtu);
+        str.append(" Servername ").append(serverHostName);
+        if (captivePortalApiUrl != null) {
+            str.append(" CaptivePortalApiUrl ").append(captivePortalApiUrl);
+        }
+
+        return str.toString();
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof DhcpResults)) return false;
+
+        DhcpResults target = (DhcpResults) obj;
+
+        return toStaticIpConfiguration().equals(target.toStaticIpConfiguration())
+                && Objects.equals(serverAddress, target.serverAddress)
+                && Objects.equals(vendorInfo, target.vendorInfo)
+                && Objects.equals(serverHostName, target.serverHostName)
+                && leaseDuration == target.leaseDuration
+                && mtu == target.mtu
+                && Objects.equals(captivePortalApiUrl, target.captivePortalApiUrl);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ipAddress, gateway, dnsServers, domains, serverAddress, vendorInfo,
+            serverHostName, captivePortalApiUrl) + 43 *  leaseDuration + 67 * mtu;
+    }
+
+    /**
+     * Implement the Parcelable interface
+     */
+    @SuppressLint("NewApi") // TODO: b/193460475 remove once fixed
+    public static final @android.annotation.NonNull Creator<DhcpResults> CREATOR =
+            new Creator<DhcpResults>() {
+                public DhcpResults createFromParcel(Parcel in) {
+                    return readFromParcel(in);
+                }
+
+                public DhcpResults[] newArray(int size) {
+                    return new DhcpResults[size];
+                }
+            };
+
+    /** Implement the Parcelable interface */
+    public void writeToParcel(Parcel dest, int flags) {
+        toStaticIpConfiguration().writeToParcel(dest, flags);
+        dest.writeInt(leaseDuration);
+        dest.writeInt(mtu);
+        InetAddressUtils.parcelInetAddress(dest, serverAddress, flags);
+        dest.writeString(vendorInfo);
+        dest.writeString(serverHostName);
+        dest.writeString(captivePortalApiUrl);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @SuppressLint("NewApi") // TODO: b/193460475 remove once fixed
+    private static DhcpResults readFromParcel(Parcel in) {
+        final StaticIpConfiguration s = StaticIpConfiguration.CREATOR.createFromParcel(in);
+        final DhcpResults dhcpResults = new DhcpResults(s);
+        dhcpResults.leaseDuration = in.readInt();
+        dhcpResults.mtu = in.readInt();
+        dhcpResults.serverAddress = (Inet4Address) InetAddressUtils.unparcelInetAddress(in);
+        dhcpResults.vendorInfo = in.readString();
+        dhcpResults.serverHostName = in.readString();
+        dhcpResults.captivePortalApiUrl = in.readString();
+        return dhcpResults;
+    }
+
+    /**
+     * Sets the IPv4 address.
+     *
+     * @param addrString the string representation of the IPv4 address
+     * @param prefixLength the prefix length.
+     * @return false on success, true on failure
+     */
+    public boolean setIpAddress(String addrString, int prefixLength) {
+        try {
+            Inet4Address addr = (Inet4Address) InetAddresses.parseNumericAddress(addrString);
+            ipAddress = new LinkAddress(addr, prefixLength);
+        } catch (IllegalArgumentException | ClassCastException e) {
+            Log.e(TAG, "setIpAddress failed with addrString " + addrString + "/" + prefixLength);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sets the gateway IPv4 address.
+     *
+     * @param addrString the string representation of the gateway IPv4 address
+     * @return false on success, true on failure
+     */
+    public boolean setGateway(String addrString) {
+        try {
+            gateway = InetAddresses.parseNumericAddress(addrString);
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "setGateway failed with addrString " + addrString);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Adds a DNS server to the list.
+     *
+     * @param addrString the string representation of the DNS server IPv4 address
+     * @return false on success, true on failure
+     */
+    public boolean addDns(String addrString) {
+        if (TextUtils.isEmpty(addrString)) return false;
+        try {
+            dnsServers.add(InetAddresses.parseNumericAddress(addrString));
+            return false;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "addDns failed with addrString " + addrString);
+            return true;
+        }
+    }
+
+    public LinkAddress getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(LinkAddress ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public InetAddress getGateway() {
+        return gateway;
+    }
+
+    public void setGateway(InetAddress gateway) {
+        this.gateway = gateway;
+    }
+
+    public List<InetAddress> getDnsServers() {
+        return dnsServers;
+    }
+
+    /**
+     * Add a DNS server to this configuration.
+     */
+    public void addDnsServer(InetAddress server) {
+        dnsServers.add(server);
+    }
+
+    public String getDomains() {
+        return domains;
+    }
+
+    public void setDomains(String domains) {
+        this.domains = domains;
+    }
+
+    public Inet4Address getServerAddress() {
+        return serverAddress;
+    }
+
+    public void setServerAddress(Inet4Address addr) {
+        serverAddress = addr;
+    }
+
+    public int getLeaseDuration() {
+        return leaseDuration;
+    }
+
+    public void setLeaseDuration(int duration) {
+        leaseDuration = duration;
+    }
+
+    public String getVendorInfo() {
+        return vendorInfo;
+    }
+
+    public void setVendorInfo(String info) {
+        vendorInfo = info;
+    }
+
+    public int getMtu() {
+        return mtu;
+    }
+
+    public void setMtu(int mtu) {
+        this.mtu = mtu;
+    }
+
+    public String getCaptivePortalApiUrl() {
+        return captivePortalApiUrl;
+    }
+
+    public void setCaptivePortalApiUrl(String url) {
+        captivePortalApiUrl = url;
+    }
+}
diff --git a/src/android/net/apf/ApfFilter.java b/src/android/net/apf/ApfFilter.java
index 7a13392..4d98568 100644
--- a/src/android/net/apf/ApfFilter.java
+++ b/src/android/net/apf/ApfFilter.java
@@ -49,7 +49,6 @@
 import android.net.metrics.ApfStats;
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.RaEvent;
-import android.net.util.InterfaceParams;
 import android.net.util.NetworkStackUtils;
 import android.os.PowerManager;
 import android.os.SystemClock;
@@ -67,6 +66,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.ConnectivityUtils;
+import com.android.net.module.util.InterfaceParams;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
diff --git a/src/android/net/dhcp/DhcpClient.java b/src/android/net/dhcp/DhcpClient.java
index 704ca7d..c88b653 100644
--- a/src/android/net/dhcp/DhcpClient.java
+++ b/src/android/net/dhcp/DhcpClient.java
@@ -73,7 +73,6 @@
 import android.net.metrics.IpConnectivityLog;
 import android.net.networkstack.aidl.dhcp.DhcpOption;
 import android.net.util.HostnameTransliterator;
-import android.net.util.InterfaceParams;
 import android.net.util.NetworkStackUtils;
 import android.net.util.SocketUtils;
 import android.os.Build;
@@ -99,6 +98,7 @@
 import com.android.internal.util.StateMachine;
 import com.android.internal.util.WakeupMessage;
 import com.android.net.module.util.DeviceConfigUtils;
+import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.NetworkStackConstants;
 import com.android.net.module.util.PacketReader;
 import com.android.networkstack.R;
diff --git a/src/android/net/ip/ConnectivityPacketTracker.java b/src/android/net/ip/ConnectivityPacketTracker.java
index c02f7d3..a905315 100644
--- a/src/android/net/ip/ConnectivityPacketTracker.java
+++ b/src/android/net/ip/ConnectivityPacketTracker.java
@@ -24,7 +24,6 @@
 import static android.system.OsConstants.SOCK_RAW;
 
 import android.net.util.ConnectivityPacketSummary;
-import android.net.util.InterfaceParams;
 import android.net.util.NetworkStackUtils;
 import android.os.Handler;
 import android.os.SystemClock;
@@ -36,6 +35,7 @@
 
 import com.android.internal.util.HexDump;
 import com.android.internal.util.TokenBucket;
+import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.PacketReader;
 
 import java.io.FileDescriptor;
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 00aa599..a94e4cc 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -40,6 +40,7 @@
 import static com.android.net.module.util.NetworkStackConstants.VENDOR_SPECIFIC_IE_ID;
 import static com.android.server.util.PermissionUtil.enforceNetworkStackCallingPermission;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
@@ -72,7 +73,6 @@
 import android.net.shared.ProvisioningConfiguration;
 import android.net.shared.ProvisioningConfiguration.ScanResultInfo;
 import android.net.shared.ProvisioningConfiguration.ScanResultInfo.InformationElement;
-import android.net.util.InterfaceParams;
 import android.net.util.NetworkStackUtils;
 import android.net.util.SharedLog;
 import android.os.Build;
@@ -95,6 +95,7 @@
 import android.util.SparseArray;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.HexDump;
@@ -105,6 +106,7 @@
 import com.android.internal.util.StateMachine;
 import com.android.internal.util.WakeupMessage;
 import com.android.net.module.util.DeviceConfigUtils;
+import com.android.net.module.util.InterfaceParams;
 import com.android.networkstack.R;
 import com.android.networkstack.apishim.NetworkInformationShimImpl;
 import com.android.networkstack.apishim.SocketUtilsShimImpl;
@@ -740,9 +742,27 @@
         mLinkObserver = new IpClientLinkObserver(
                 mContext, getHandler(),
                 mInterfaceName,
-                (ifaceUp) -> sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED, ifaceUp
-                        ? ARG_LINKPROP_CHANGED_LINKSTATE_UP
-                        : ARG_LINKPROP_CHANGED_LINKSTATE_DOWN),
+                new IpClientLinkObserver.Callback() {
+                    @Override
+                    public void update(boolean linkState) {
+                        sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED, linkState
+                                ? ARG_LINKPROP_CHANGED_LINKSTATE_UP
+                                : ARG_LINKPROP_CHANGED_LINKSTATE_DOWN);
+                    }
+
+                    @Override
+                    public void onIpv6AddressRemoved(final Inet6Address targetIp) {
+                        // The update of Gratuitous NA target addresses set should be only accessed
+                        // from the handler thread of IpClient StateMachine, keeping the behaviour
+                        // consistent with relying on the non-blocking NetworkObserver callbacks,
+                        // see {@link registerObserverForNonblockingCallback}. This can be done
+                        // by either sending a message to StateMachine or posting a handler.
+                        getHandler().post(() -> {
+                            if (!mGratuitousNaTargetAddresses.contains(targetIp)) return;
+                            updateGratuitousNaTargetSet(targetIp, false /* remove address */);
+                        });
+                    }
+                },
                 config, mLog, mDependencies) {
             @Override
             public void onInterfaceAdded(String iface) {
@@ -775,21 +795,6 @@
                 logMsg(msg);
             }
 
-            @Override
-            public void onInterfaceAddressRemoved(LinkAddress address, String iface) {
-                super.onInterfaceAddressRemoved(address, iface);
-                if (!mInterfaceName.equals(iface)) return;
-                if (!address.isIpv6()) return;
-                final Inet6Address targetIp = (Inet6Address) address.getAddress();
-                if (mGratuitousNaTargetAddresses.contains(targetIp)) {
-                    mGratuitousNaTargetAddresses.remove(targetIp);
-
-                    final String msg = "Global IPv6 address: " + targetIp
-                            + " has removed from the set of gratuitous NA target address.";
-                    logMsg(msg);
-                }
-            }
-
             private void logMsg(String msg) {
                 Log.d(mTag, msg);
                 getHandler().post(() -> mLog.log("OBSERVED " + msg));
@@ -1663,6 +1668,7 @@
         transmitPacket(packet, sockAddress, "Failed to send GARP");
     }
 
+    @Nullable
     private static Inet6Address getIpv6LinkLocalAddress(final LinkProperties newLp) {
         for (LinkAddress la : newLp.getLinkAddresses()) {
             if (!la.isIpv6()) continue;
@@ -1672,6 +1678,16 @@
         return null;
     }
 
+    private void updateGratuitousNaTargetSet(@NonNull final Inet6Address targetIp, boolean add) {
+        if (add) {
+            mGratuitousNaTargetAddresses.add(targetIp);
+        } else {
+            mGratuitousNaTargetAddresses.remove(targetIp);
+        }
+        mLog.log((add ? "Add" : "Remove") + " global IPv6 address " + targetIp
+                + (add ? " to" : " from") + " the set of gratuitous NA target address.");
+    }
+
     private void maybeSendGratuitousNAs(final LinkProperties lp, boolean afterRoaming) {
         if (!lp.hasGlobalIpv6Address()) return;
 
@@ -1692,7 +1708,7 @@
                         + targetIp.getHostAddress() + (afterRoaming ? " after roaming" : ""));
             }
             sendGratuitousNA(srcIp, targetIp);
-            if (!afterRoaming) mGratuitousNaTargetAddresses.add(targetIp);
+            if (!afterRoaming) updateGratuitousNaTargetSet(targetIp, true /* add address */);
         }
     }
 
@@ -1857,6 +1873,7 @@
         mCallback.onProvisioningFailure(mLinkProperties);
     }
 
+    @SuppressLint("NewApi") // TODO: b/193460475 remove once fixed
     private boolean startIPv4() {
         // If we have a StaticIpConfiguration attempt to apply it and
         // handle the result accordingly.
diff --git a/src/android/net/ip/IpClientLinkObserver.java b/src/android/net/ip/IpClientLinkObserver.java
index f8ba367..8a5ed2e 100644
--- a/src/android/net/ip/IpClientLinkObserver.java
+++ b/src/android/net/ip/IpClientLinkObserver.java
@@ -36,12 +36,14 @@
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.RouteInfo;
-import android.net.util.InterfaceParams;
 import android.net.util.SharedLog;
 import android.os.Handler;
 import android.system.OsConstants;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.netlink.NduseroptMessage;
 import com.android.net.module.util.netlink.NetlinkConstants;
 import com.android.net.module.util.netlink.NetlinkMessage;
@@ -56,6 +58,7 @@
 import com.android.networkstack.apishim.common.NetworkInformationShim;
 import com.android.server.NetworkObserver;
 
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -111,6 +114,13 @@
          *                  with {@link #getLinkProperties()} in particular.
          */
         void update(boolean linkState);
+
+        /**
+         * Called when an IPv6 address was removed from the interface.
+         *
+         * @param addr The removed IPv6 address.
+         */
+        void onIpv6AddressRemoved(Inet6Address addr);
     }
 
     /** Configuration parameters for IpClientLinkObserver. */
@@ -262,7 +272,7 @@
         }
     }
 
-    private void updateInterfaceAddress(final LinkAddress address, boolean add) {
+    private void updateInterfaceAddress(@NonNull final LinkAddress address, boolean add) {
         final boolean changed;
         final boolean linkState;
         synchronized (this) {
@@ -275,6 +285,10 @@
         }
         if (changed) {
             mCallback.update(linkState);
+            if (!add && address.isIpv6()) {
+                final Inet6Address addr = (Inet6Address) address.getAddress();
+                mCallback.onIpv6AddressRemoved(addr);
+            }
         }
     }
 
diff --git a/src/android/net/ip/IpReachabilityMonitor.java b/src/android/net/ip/IpReachabilityMonitor.java
index c716fdf..076d73d 100644
--- a/src/android/net/ip/IpReachabilityMonitor.java
+++ b/src/android/net/ip/IpReachabilityMonitor.java
@@ -33,7 +33,6 @@
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.IpReachabilityEvent;
 import android.net.networkstack.aidl.ip.ReachabilityLossReason;
-import android.net.util.InterfaceParams;
 import android.net.util.SharedLog;
 import android.os.ConditionVariable;
 import android.os.Handler;
@@ -54,6 +53,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 import com.android.net.module.util.DeviceConfigUtils;
+import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.netlink.StructNdMsg;
 import com.android.networkstack.R;
 import com.android.networkstack.metrics.IpReachabilityMonitorMetrics;
diff --git a/src/com/android/networkstack/netlink/TcpSocketTracker.java b/src/com/android/networkstack/netlink/TcpSocketTracker.java
index b5eafd6..9cc2d60 100644
--- a/src/com/android/networkstack/netlink/TcpSocketTracker.java
+++ b/src/com/android/networkstack/netlink/TcpSocketTracker.java
@@ -86,8 +86,8 @@
  * This is not thread-safe. This should be only accessed from one thread.
  */
 public class TcpSocketTracker {
-    private static final String TAG = "TcpSocketTracker";
-    private static final boolean DBG = false;
+    private static final String TAG = TcpSocketTracker.class.getSimpleName();
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
     private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET6, AF_INET};
     // Enough for parsing v1 tcp_info for more than 200 sockets per time.
     private static final int DEFAULT_RECV_BUFSIZE = 60_000;
@@ -355,7 +355,7 @@
             stat.lostCount -= previous.tcpInfo.mLost;
             stat.retransmitCount -= previous.tcpInfo.mRetransmits;
         }
-
+        log("calculateLatestPacketsStat, stat:" + stat);
         return stat;
     }
 
@@ -519,6 +519,12 @@
             receivedCount += stat.receivedCount;
             retransmitCount += stat.retransmitCount;
         }
+
+        @Override
+        public String toString() {
+            return "TcpStat {sent=" + sentCount + ", lost=" + lostCount
+                    + ", retransmit=" + retransmitCount + ", received=" + receivedCount + "}";
+        }
     }
 
     /**
diff --git a/src/com/android/server/NetworkStackService.java b/src/com/android/server/NetworkStackService.java
index 903a5a8..64cbc24 100644
--- a/src/com/android/server/NetworkStackService.java
+++ b/src/com/android/server/NetworkStackService.java
@@ -43,6 +43,7 @@
 import android.net.dhcp.IDhcpServerCallbacks;
 import android.net.ip.IIpClientCallbacks;
 import android.net.ip.IpClient;
+import android.net.networkstack.aidl.NetworkMonitorParameters;
 import android.net.shared.PrivateDnsConfig;
 import android.net.util.SharedLog;
 import android.os.Build;
@@ -612,12 +613,25 @@
             mNm.notifyDnsResponse(returnCode);
         }
 
+        /**
+         * Send a notification to NetworkMonitor indicating that the network is now connected.
+         * @Deprecated use notifyNetworkConnectedParcel, which also passes the NetworkAgentConfig.
+         */
         @Override
         public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
             mPermChecker.enforceNetworkStackCallingPermission();
             mNm.notifyNetworkConnected(lp, nc);
         }
 
+        /**
+         * Send a notification to NetworkMonitor indicating that the network is now connected.
+         */
+        @Override
+        public void notifyNetworkConnectedParcel(NetworkMonitorParameters params) {
+            mPermChecker.enforceNetworkStackCallingPermission();
+            mNm.notifyNetworkConnectedParcel(params);
+        }
+
         @Override
         public void notifyNetworkDisconnected() {
             mPermChecker.enforceNetworkStackCallingPermission();
diff --git a/src/com/android/server/connectivity/NetworkMonitor.java b/src/com/android/server/connectivity/NetworkMonitor.java
index 948ce8d..301462f 100755
--- a/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/src/com/android/server/connectivity/NetworkMonitor.java
@@ -83,6 +83,7 @@
 import static com.android.net.module.util.DeviceConfigUtils.getResBooleanConfig;
 import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_DNS_EVENTS;
 import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_TCP_METRICS;
+import static com.android.networkstack.apishim.ConstantsShim.RECEIVER_NOT_EXPORTED;
 import static com.android.networkstack.apishim.ConstantsShim.TRANSPORT_TEST;
 import static com.android.networkstack.util.DnsUtils.PRIVATE_DNS_PROBE_HOST_SUFFIX;
 import static com.android.networkstack.util.DnsUtils.TYPE_ADDRCONFIG;
@@ -112,6 +113,7 @@
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.NetworkEvent;
 import android.net.metrics.ValidationProbeEvent;
+import android.net.networkstack.aidl.NetworkMonitorParameters;
 import android.net.shared.NetworkMonitorUtils;
 import android.net.shared.PrivateDnsConfig;
 import android.net.util.DataStallUtils.EvaluationType;
@@ -143,7 +145,6 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
 import android.util.SparseArray;
 
 import androidx.annotation.ArrayRes;
@@ -157,6 +158,7 @@
 import com.android.internal.util.RingBufferIndices;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.modules.utils.build.SdkLevel;
 import com.android.net.module.util.DeviceConfigUtils;
 import com.android.net.module.util.NetworkStackConstants;
 import com.android.networkstack.NetworkStackNotifier;
@@ -691,17 +693,28 @@
 
     /**
      * Send a notification to NetworkMonitor indicating that the network is now connected.
+     * @Deprecated use notifyNetworkConnectedParcel. This method is called on S-.
      */
     public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
-        sendMessage(CMD_NETWORK_CONNECTED, new Pair<>(
-                new LinkProperties(lp), new NetworkCapabilities(nc)));
+        final NetworkMonitorParameters params = new NetworkMonitorParameters();
+        params.linkProperties = lp;
+        params.networkCapabilities = nc;
+        notifyNetworkConnectedParcel(params);
+    }
+
+    /**
+     * Send a notification to NetworkMonitor indicating that the network is now connected.
+     * Called in S when the Connectivity module is recent enough, or in T+ in all cases.
+     */
+    public void notifyNetworkConnectedParcel(NetworkMonitorParameters params) {
+        sendMessage(CMD_NETWORK_CONNECTED, params);
     }
 
     private void updateConnectedNetworkAttributes(Message connectedMsg) {
-        final Pair<LinkProperties, NetworkCapabilities> attrs =
-                (Pair<LinkProperties, NetworkCapabilities>) connectedMsg.obj;
-        mLinkProperties = attrs.first;
-        mNetworkCapabilities = attrs.second;
+        final NetworkMonitorParameters params = (NetworkMonitorParameters) connectedMsg.obj;
+        // TODO : also read the NetworkAgentConfig
+        mLinkProperties = params.linkProperties;
+        mNetworkCapabilities = params.networkCapabilities;
         suppressNotificationIfNetworkRestricted();
     }
 
@@ -1428,7 +1441,8 @@
             mToken = token;
             mWhat = what;
             mAction = action + "_" + mCleartextDnsNetwork.getNetworkHandle() + "_" + token;
-            mContext.registerReceiver(this, new IntentFilter(mAction));
+            final int flags = SdkLevel.isAtLeastT() ? RECEIVER_NOT_EXPORTED : 0;
+            mContext.registerReceiver(this, new IntentFilter(mAction), flags);
         }
         public PendingIntent getPendingIntent() {
             final Intent intent = new Intent(mAction);
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
index 6056ee5..36c6162 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -81,7 +81,7 @@
     defaults: [
         "NetworkStackIntegrationTestsDefaults",
         "NetworkStackIntegrationTestsJniDefaults",
-        "NetworkStackNextEnableDefaults",
+        "ConnectivityNextEnableDefaults",
     ],
     static_libs: [
         "NetworkStackApiCurrentLib",
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
index 22a4844..7aef0e3 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
@@ -16,6 +16,7 @@
 
 package android.net.ip;
 
+import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
 import static android.net.dhcp.DhcpClient.EXPIRED_LEASE;
 import static android.net.dhcp.DhcpPacket.DHCP_BOOTREQUEST;
 import static android.net.dhcp.DhcpPacket.DHCP_CLIENT;
@@ -58,6 +59,7 @@
 import static com.android.net.module.util.NetworkStackConstants.PIO_FLAG_AUTONOMOUS;
 import static com.android.net.module.util.NetworkStackConstants.PIO_FLAG_ON_LINK;
 import static com.android.testutils.MiscAsserts.assertThrows;
+import static com.android.testutils.TestPermissionUtil.runAsShell;
 
 import static junit.framework.Assert.fail;
 
@@ -130,7 +132,6 @@
 import android.net.shared.Layer2Information;
 import android.net.shared.ProvisioningConfiguration;
 import android.net.shared.ProvisioningConfiguration.ScanResultInfo;
-import android.net.util.InterfaceParams;
 import android.net.util.NetworkStackUtils;
 import android.net.util.SharedLog;
 import android.os.Build;
@@ -154,6 +155,7 @@
 import com.android.internal.util.HexDump;
 import com.android.internal.util.StateMachine;
 import com.android.net.module.util.ArrayTrackRecord;
+import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.Ipv6Utils;
 import com.android.net.module.util.netlink.StructNdOptPref64;
 import com.android.net.module.util.structs.LlaOption;
@@ -641,19 +643,11 @@
 
     private void setUpTapInterface() throws Exception {
         final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
-        // Adopt the shell permission identity to create a test TAP interface.
-        inst.getUiAutomation().adoptShellPermissionIdentity();
-
-        final TestNetworkInterface iface;
-        try {
-            final TestNetworkManager tnm = (TestNetworkManager)
-                    inst.getContext().getSystemService(Context.TEST_NETWORK_SERVICE);
-            iface = tnm.createTapInterface();
-        } finally {
-            // Drop the identity in order to regain the network stack permissions, which the shell
-            // does not have.
-            inst.getUiAutomation().dropShellPermissionIdentity();
-        }
+        final TestNetworkInterface iface = runAsShell(MANAGE_TEST_NETWORKS, () -> {
+            final TestNetworkManager tnm =
+                    inst.getContext().getSystemService(TestNetworkManager.class);
+            return tnm.createTapInterface();
+        });
         mIfaceName = iface.getInterfaceName();
         mClientMac = getIfaceMacAddr(mIfaceName).toByteArray();
         mPacketReaderThread = new HandlerThread(
@@ -1408,7 +1402,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 */,
diff --git a/tests/integration/src/android/net/util/NetworkStackUtilsIntegrationTest.kt b/tests/integration/src/android/net/util/NetworkStackUtilsIntegrationTest.kt
index 0ec43a5..2dd984d 100644
--- a/tests/integration/src/android/net/util/NetworkStackUtilsIntegrationTest.kt
+++ b/tests/integration/src/android/net/util/NetworkStackUtilsIntegrationTest.kt
@@ -38,6 +38,7 @@
 import android.system.OsConstants.SOL_SOCKET
 import android.system.OsConstants.SO_RCVTIMEO
 import android.system.StructTimeval
+import com.android.net.module.util.InterfaceParams
 import com.android.net.module.util.Ipv6Utils
 import com.android.net.module.util.NetworkStackConstants.ETHER_ADDR_LEN
 import com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ANY
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 1dba074..05a3260 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -29,6 +29,7 @@
         "kotlin-reflect",
         "mockito-target-extended-minus-junit4",
         "net-tests-utils",
+        //"net-utils-framework-common",
         "testables",
     ],
     libs: [
@@ -47,6 +48,7 @@
         "libnetworkstackutilsjni",
     ],
     jni_uses_sdk_apis: true,
+    exclude_kotlinc_generated_files: false,
 }
 
 // Tests for NetworkStackNext.
@@ -56,8 +58,11 @@
     min_sdk_version: "29",
     srcs: [], // TODO: tests that only apply to the current, non-stable API can be added here
     test_suites: ["general-tests"],
-    test_mainline_modules: ["CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex"],
-    defaults: ["NetworkStackTestsDefaults", "NetworkStackNextEnableDefaults"],
+    defaults: [
+        "NetworkStackTestsDefaults",
+        "ConnectivityNextEnableDefaults",
+        "connectivity-mainline-presubmit-java-defaults",
+    ],
     static_libs: ["NetworkStackApiCurrentLib"],
     compile_multilib: "both", // Workaround for b/147785146 for mainline-presubmit
     jarjar_rules: ":NetworkStackJarJarRules",
@@ -83,8 +88,10 @@
     min_sdk_version: "29",
     target_sdk_version: "30",
     test_suites: ["general-tests", "mts"],
-    test_mainline_modules: ["CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex"],
-    defaults: ["NetworkStackTestsDefaults"],
+    defaults: [
+        "NetworkStackTestsDefaults",
+        "connectivity-mainline-presubmit-java-defaults",
+    ],
     static_libs: ["NetworkStackApiStableLib"],
     compile_multilib: "both",
     jarjar_rules: ":NetworkStackJarJarRules",
diff --git a/tests/unit/src/android/net/apf/ApfTest.java b/tests/unit/src/android/net/apf/ApfTest.java
index b6de3a1..b2feaf1 100644
--- a/tests/unit/src/android/net/apf/ApfTest.java
+++ b/tests/unit/src/android/net/apf/ApfTest.java
@@ -51,7 +51,6 @@
 import android.net.ip.IpClient.IpClientCallbacksWrapper;
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.RaEvent;
-import android.net.util.InterfaceParams;
 import android.net.util.SharedLog;
 import android.os.ConditionVariable;
 import android.os.Parcelable;
@@ -67,6 +66,7 @@
 
 import com.android.internal.util.HexDump;
 import com.android.net.module.util.Inet4AddressUtils;
+import com.android.net.module.util.InterfaceParams;
 import com.android.net.module.util.NetworkStackConstants;
 import com.android.networkstack.apishim.NetworkInformationShimImpl;
 import com.android.server.networkstack.tests.R;
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java
index 37f12ca..481a957 100644
--- a/tests/unit/src/android/net/ip/IpClientTest.java
+++ b/tests/unit/src/android/net/ip/IpClientTest.java
@@ -62,12 +62,12 @@
 import android.net.shared.Layer2Information;
 import android.net.shared.ProvisioningConfiguration;
 import android.net.shared.ProvisioningConfiguration.ScanResultInfo;
-import android.net.util.InterfaceParams;
 import android.os.Build;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.net.module.util.InterfaceParams;
 import com.android.networkstack.R;
 import com.android.server.NetworkObserver;
 import com.android.server.NetworkObserverRegistry;
diff --git a/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt b/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
index 0109022..ea64ca2 100644
--- a/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
+++ b/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
@@ -25,7 +25,6 @@
 import android.net.LinkProperties
 import android.net.RouteInfo
 import android.net.metrics.IpConnectivityLog
-import android.net.util.InterfaceParams
 import android.net.util.NetworkStackUtils.IP_REACHABILITY_MCAST_RESOLICIT_VERSION
 import android.net.util.SharedLog
 import android.os.Handler
@@ -54,6 +53,7 @@
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
 import com.android.networkstack.metrics.IpReachabilityMonitorMetrics
+import com.android.net.module.util.InterfaceParams
 import com.android.net.module.util.netlink.StructNdMsg.NUD_FAILED
 import com.android.net.module.util.netlink.StructNdMsg.NUD_REACHABLE
 import com.android.net.module.util.netlink.StructNdMsg.NUD_STALE
diff --git a/tests/unit/src/android/net/util/InterfaceParamsTest.java b/tests/unit/src/android/net/util/InterfaceParamsTest.java
deleted file mode 100644
index dc70bd0..0000000
--- a/tests/unit/src/android/net/util/InterfaceParamsTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.net.module.util.NetworkStackConstants;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class InterfaceParamsTest {
-    @Test
-    public void testNullInterfaceReturnsNull() {
-        assertNull(InterfaceParams.getByName(null));
-    }
-
-    @Test
-    public void testNonExistentInterfaceReturnsNull() {
-        assertNull(InterfaceParams.getByName("doesnotexist0"));
-    }
-
-    @Test
-    public void testLoopback() {
-        final InterfaceParams ifParams = InterfaceParams.getByName("lo");
-        assertNotNull(ifParams);
-        assertEquals("lo", ifParams.name);
-        assertTrue(ifParams.index > 0);
-        assertNotNull(ifParams.macAddr);
-        assertFalse(ifParams.hasMacAddress);
-        assertTrue(ifParams.defaultMtu >= NetworkStackConstants.ETHER_MTU);
-    }
-}
diff --git a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
index ff43325..01daf67 100644
--- a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -115,11 +115,13 @@
 import android.net.InetAddresses;
 import android.net.LinkProperties;
 import android.net.Network;
+import android.net.NetworkAgentConfig;
 import android.net.NetworkCapabilities;
 import android.net.NetworkTestResultParcelable;
 import android.net.Uri;
 import android.net.captiveportal.CaptivePortalProbeResult;
 import android.net.metrics.IpConnectivityLog;
+import android.net.networkstack.aidl.NetworkMonitorParameters;
 import android.net.shared.PrivateDnsConfig;
 import android.net.util.SharedLog;
 import android.net.wifi.WifiInfo;
@@ -296,6 +298,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 LinkProperties TEST_LINK_PROPERTIES = new LinkProperties();
 
     // Cannot have a static member for the LinkProperties with captive portal API information, as
@@ -555,6 +559,11 @@
             mRegisteredReceivers.add(invocation.getArgument(0));
             return new Intent();
         });
+        when(mContext.registerReceiver(any(BroadcastReceiver.class), any(), anyInt())).then(
+                (invocation) -> {
+                    mRegisteredReceivers.add(invocation.getArgument(0));
+                    return new Intent();
+                });
 
         doAnswer((invocation) -> {
             mRegisteredReceivers.remove(invocation.getArgument(0));
@@ -749,9 +758,10 @@
                 .addCapability(NET_CAPABILITY_INTERNET);
         doReturn(TEST_SPEED_TEST_URL).when(mResources).getString(
                 R.string.config_evaluating_bandwidth_url);
-        final NetworkMonitor nm = runNetworkTest(TEST_LINK_PROPERTIES, meteredCap,
-                NETWORK_VALIDATION_RESULT_VALID, NETWORK_VALIDATION_PROBE_DNS
-                | NETWORK_VALIDATION_PROBE_HTTPS, null /* redirectUrl */);
+        final NetworkMonitor nm = runNetworkTest(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES,
+                meteredCap, NETWORK_VALIDATION_RESULT_VALID,
+                NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS,
+                null /* redirectUrl */);
         // Evaluating bandwidth process won't be executed when the network is metered wifi.
         // Check that the connection hasn't been opened and the state should transition to validated
         // state directly.
@@ -769,9 +779,10 @@
                 .addCapability(NET_CAPABILITY_INTERNET)
                 .addCapability(NET_CAPABILITY_NOT_METERED);
         doReturn("").when(mResources).getString(R.string.config_evaluating_bandwidth_url);
-        final NetworkMonitor nm = runNetworkTest(TEST_LINK_PROPERTIES, nonMeteredCap,
-                NETWORK_VALIDATION_RESULT_VALID, NETWORK_VALIDATION_PROBE_DNS
-                | NETWORK_VALIDATION_PROBE_HTTPS, null /* redirectUrl */);
+        final NetworkMonitor nm = runNetworkTest(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES,
+                nonMeteredCap, NETWORK_VALIDATION_RESULT_VALID,
+                NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS,
+                null /* redirectUrl */);
         // Non-metered network with wrong configuration(the config_evaluating_bandwidth_url is
         // empty). Check that the connection hasn't been opened and the state should transition to
         // validated state directly.
@@ -1302,8 +1313,8 @@
                 + "'seconds-remaining': " + secondsRemaining + "}");
         setPortal302(mHttpConnection);
 
-        runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES, VALIDATION_RESULT_PORTAL,
-                0 /* probesSucceeded*/, TEST_LOGIN_URL);
+        runNetworkTest(TEST_AGENT_CONFIG, makeCapportLPs(), CELL_METERED_CAPABILITIES,
+                VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded*/, TEST_LOGIN_URL);
 
         verify(mCapportApiConnection).getResponseCode();
 
@@ -1324,8 +1335,8 @@
                 + "'bytes-remaining': " + bytesRemaining + ","
                 + "'seconds-remaining': " + secondsRemaining + "}");
 
-        runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES, VALIDATION_RESULT_PORTAL,
-                0 /* probesSucceeded*/, TEST_LOGIN_URL);
+        runNetworkTest(TEST_AGENT_CONFIG, makeCapportLPs(), CELL_METERED_CAPABILITIES,
+                VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded*/, TEST_LOGIN_URL);
 
         verify(mHttpConnection, never()).getResponseCode();
         verify(mCapportApiConnection).getResponseCode();
@@ -1385,7 +1396,8 @@
                 + "'user-portal-url': '" + TEST_LOGIN_URL + "'}");
 
         // After notifyNetworkConnected, validation uses the capport API contents
-        nm.notifyNetworkConnected(lp, CELL_METERED_CAPABILITIES);
+        nm.notifyNetworkConnectedParcel(
+                makeParams(TEST_AGENT_CONFIG, lp, CELL_METERED_CAPABILITIES));
         verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL);
 
         verify(mHttpConnection, never()).getResponseCode();
@@ -1399,8 +1411,8 @@
         setStatus(mHttpConnection, 500);
         setApiContent(mCapportApiConnection, "{'captive': false,"
                 + "'venue-info-url': '" + TEST_VENUE_INFO_URL + "'}");
-        runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES, VALIDATION_RESULT_INVALID,
-                0 /* probesSucceeded */, null /* redirectUrl */);
+        runNetworkTest(TEST_AGENT_CONFIG, makeCapportLPs(), CELL_METERED_CAPABILITIES,
+                VALIDATION_RESULT_INVALID, 0 /* probesSucceeded */, null /* redirectUrl */);
 
         final ArgumentCaptor<CaptivePortalData> capportCaptor = ArgumentCaptor.forClass(
                 CaptivePortalData.class);
@@ -1415,7 +1427,7 @@
         setStatus(mHttpConnection, 204);
         setApiContent(mCapportApiConnection, "{'captive': false,"
                 + "'venue-info-url': '" + TEST_VENUE_INFO_URL + "'}");
-        runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES,
+        runNetworkTest(TEST_AGENT_CONFIG, makeCapportLPs(), CELL_METERED_CAPABILITIES,
                 NETWORK_VALIDATION_RESULT_PARTIAL,
                 NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP,
                 null /* redirectUrl */);
@@ -1433,7 +1445,7 @@
         setStatus(mHttpConnection, 204);
         setApiContent(mCapportApiConnection, "{'captive': false,"
                 + "'venue-info-url': '" + TEST_VENUE_INFO_URL + "'}");
-        runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES,
+        runNetworkTest(TEST_AGENT_CONFIG, makeCapportLPs(), CELL_METERED_CAPABILITIES,
                 NETWORK_VALIDATION_RESULT_VALID,
                 NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP
                         | NETWORK_VALIDATION_PROBE_HTTPS,
@@ -1451,7 +1463,7 @@
         setSslException(mHttpsConnection);
         setPortal302(mHttpConnection);
         setApiContent(mCapportApiConnection, "{SomeInvalidText");
-        runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES,
+        runNetworkTest(TEST_AGENT_CONFIG, makeCapportLPs(), CELL_METERED_CAPABILITIES,
                 VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */,
                 TEST_LOGIN_URL);
 
@@ -1465,7 +1477,7 @@
         setPortal302(mHttpConnection);
         final LinkProperties lp = new LinkProperties(TEST_LINK_PROPERTIES);
         lp.setCaptivePortalApiUrl(Uri.parse(url));
-        runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES,
+        runNetworkTest(TEST_AGENT_CONFIG, makeCapportLPs(), CELL_METERED_CAPABILITIES,
                 VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */,
                 TEST_LOGIN_URL);
 
@@ -1498,9 +1510,8 @@
         setPortal302(mHttpConnection);
         setApiContent(mCapportApiConnection, "{'captive': false,"
                 + "'venue-info-url': '" + TEST_VENUE_INFO_URL + "'}");
-        runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES, VALIDATION_RESULT_PORTAL,
-                0 /* probesSucceeded */,
-                TEST_LOGIN_URL);
+        runNetworkTest(TEST_AGENT_CONFIG, makeCapportLPs(), CELL_METERED_CAPABILITIES,
+                VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL);
 
         verify(mCallbacks, never()).notifyCaptivePortalDataChanged(any());
         verify(mHttpConnection).getResponseCode();
@@ -1855,7 +1866,7 @@
 
     private void doValidationSkippedTest(NetworkCapabilities nc, int validationResult)
             throws Exception {
-        runNetworkTest(TEST_LINK_PROPERTIES, nc, validationResult,
+        runNetworkTest(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, nc, validationResult,
                 0 /* probesSucceeded */, null /* redirectUrl */);
         verify(mCleartextDnsNetwork, never()).openConnection(any());
     }
@@ -1919,7 +1930,7 @@
         setStatus(mHttpsConnection, 204);
         setStatus(mHttpConnection, 204);
 
-        final NetworkMonitor nm = runNetworkTest(
+        final NetworkMonitor nm = runNetworkTest(TEST_AGENT_CONFIG,
                 TEST_LINK_PROPERTIES, getVcnUnderlyingCarrierWifiCaps(),
                 NETWORK_VALIDATION_RESULT_VALID,
                 NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS,
@@ -1935,7 +1946,7 @@
         setStatus(mHttpConnection, 500);
         setStatus(mFallbackConnection, 404);
 
-        final NetworkMonitor nm = runNetworkTest(
+        final NetworkMonitor nm = runNetworkTest(TEST_AGENT_CONFIG,
                 TEST_LINK_PROPERTIES, getVcnUnderlyingCarrierWifiCaps(),
                 VALIDATION_RESULT_INVALID, 0 /* probesSucceeded */, null /* redirectUrl */);
         assertEquals(VALIDATION_RESULT_INVALID,
@@ -2061,7 +2072,8 @@
 
         WrappedNetworkMonitor wnm = makeCellNotMeteredNetworkMonitor();
         wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
-        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, CELL_NOT_METERED_CAPABILITIES);
+        wnm.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES,
+                CELL_NOT_METERED_CAPABILITIES));
         verifyNetworkTested(VALIDATION_RESULT_INVALID,
                 NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
         verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS)).notifyProbeStatusChanged(
@@ -2088,7 +2100,8 @@
 
         WrappedNetworkMonitor wnm = makeCellNotMeteredNetworkMonitor();
         wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
-        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, CELL_NOT_METERED_CAPABILITIES);
+        wnm.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES,
+                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(
@@ -2219,7 +2232,7 @@
             nm = null;
             fail("Undefined transport type");
         }
-        nm.notifyNetworkConnected(TEST_LINK_PROPERTIES, nc);
+        nm.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, nc));
         verifyNetworkTested(NETWORK_VALIDATION_RESULT_VALID,
                 NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS);
         nm.setLastProbeTime(SystemClock.elapsedRealtime() - STALL_EXPECTED_LAST_PROBE_TIME_MS);
@@ -2529,7 +2542,8 @@
         setStatus(mHttpsConnection, 204);
         setStatus(mHttpConnection, 204);
         final NetworkMonitor nm = makeMonitor(CELL_METERED_CAPABILITIES);
-        nm.notifyNetworkConnected(TEST_LINK_PROPERTIES, CELL_METERED_CAPABILITIES);
+        nm.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES,
+                CELL_METERED_CAPABILITIES));
 
         verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS))
                 .notifyNetworkTested(eq(NETWORK_VALIDATION_RESULT_VALID
@@ -2794,7 +2808,8 @@
         monitor.notifyLinkPropertiesChanged(linkProperties);
         final NetworkCapabilities networkCapabilities =
                 new NetworkCapabilities(WIFI_NOT_METERED_CAPABILITIES);
-        monitor.notifyNetworkConnected(linkProperties, networkCapabilities);
+        monitor.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG,
+                linkProperties, networkCapabilities));
         verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
                 .showProvisioningNotification(any(), any());
         assertCaptivePortalAppReceiverRegistered(true /* isPortal */);
@@ -2822,8 +2837,8 @@
     public void testOemPaidNetworkValidated() throws Exception {
         setValidProbes();
 
-        final NetworkMonitor nm = runNetworkTest(TEST_LINK_PROPERTIES,
-                WIFI_OEM_PAID_CAPABILITIES,
+        final NetworkMonitor nm = runNetworkTest(
+                TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, WIFI_OEM_PAID_CAPABILITIES,
                 NETWORK_VALIDATION_RESULT_VALID,
                 NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS,
                 null /* redirectUrl */);
@@ -2837,8 +2852,7 @@
         setStatus(mHttpConnection, 500);
         setStatus(mFallbackConnection, 404);
 
-        runNetworkTest(TEST_LINK_PROPERTIES,
-                WIFI_OEM_PAID_CAPABILITIES,
+        runNetworkTest(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, WIFI_OEM_PAID_CAPABILITIES,
                 VALIDATION_RESULT_INVALID, 0 /* probesSucceeded */, null /* redirectUrl */);
     }
 
@@ -2854,7 +2868,7 @@
 
         final int validationResult =
                 NETWORK_VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_SKIPPED;
-        runNetworkTest(TEST_LINK_PROPERTIES, networkCapabilities,
+        runNetworkTest(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, networkCapabilities,
                 validationResult, 0 /* probesSucceeded */, null /* redirectUrl */);
 
         verify(mCleartextDnsNetwork, never()).openConnection(any());
@@ -2869,7 +2883,7 @@
         setStatus(mFallbackConnection, 404);
         setPortal302(mHttpConnection);
 
-        runNetworkTest(TEST_LINK_PROPERTIES, WIFI_OEM_PAID_CAPABILITIES,
+        runNetworkTest(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, WIFI_OEM_PAID_CAPABILITIES,
                 VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */,
                 TEST_LOGIN_URL);
 
@@ -2995,14 +3009,15 @@
 
     private NetworkMonitor runNetworkTest(int testResult, int probesSucceeded, String redirectUrl)
             throws RemoteException {
-        return runNetworkTest(TEST_LINK_PROPERTIES, CELL_METERED_CAPABILITIES, testResult,
-                probesSucceeded, redirectUrl);
+        return runNetworkTest(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, CELL_METERED_CAPABILITIES,
+                testResult, probesSucceeded, redirectUrl);
     }
 
-    private NetworkMonitor runNetworkTest(LinkProperties lp, NetworkCapabilities nc,
+    private NetworkMonitor runNetworkTest(NetworkAgentConfig config,
+            LinkProperties lp, NetworkCapabilities nc,
             int testResult, int probesSucceeded, String redirectUrl) throws RemoteException {
         final NetworkMonitor monitor = makeMonitor(nc);
-        monitor.notifyNetworkConnected(lp, nc);
+        monitor.notifyNetworkConnectedParcel(makeParams(config, lp, nc));
         verifyNetworkTested(testResult, probesSucceeded, redirectUrl);
         HandlerUtils.waitForIdle(monitor.getHandler(), HANDLER_TIMEOUT_MS);
 
@@ -3040,7 +3055,16 @@
     }
 
     private void notifyNetworkConnected(NetworkMonitor nm, NetworkCapabilities nc) {
-        nm.notifyNetworkConnected(TEST_LINK_PROPERTIES, nc);
+        nm.notifyNetworkConnectedParcel(makeParams(TEST_AGENT_CONFIG, TEST_LINK_PROPERTIES, nc));
+    }
+
+    private NetworkMonitorParameters makeParams(@NonNull final NetworkAgentConfig config,
+            @NonNull final LinkProperties prop, @NonNull final NetworkCapabilities caps) {
+        final NetworkMonitorParameters params = new NetworkMonitorParameters();
+        params.networkAgentConfig = config;
+        params.linkProperties = prop;
+        params.networkCapabilities = caps;
+        return params;
     }
 
     private void setSslException(HttpURLConnection connection) throws IOException {