Snap for 8146243 from 048387b6c3a3ebc80654769a90627bc9c8b155b8 to mainline-neuralnetworks-release

Change-Id: Icd755f6aefab23ccf8e7c2559fc34687a3cbe844
diff --git a/Android.bp b/Android.bp
index e241b4c..a4e694c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -45,6 +45,19 @@
     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.
+java_defaults {
+    name: "NetworkStackNextEnableDefaults",
+    enabled: false,
+}
+// This is a placeholder comment to avoid merge conflicts
+// as the above target may have different "enabled" values
+// depending on the branch
+
 java_defaults {
     name: "NetworkStackDevApiLevel",
     min_sdk_version: "29",
@@ -147,17 +160,20 @@
 // stable and have no defined version number. These could be called 10000, but they use the next
 // integer so if the next SDK release happens to use that integer, we don't need to rename them.
 java_library {
-    name: "NetworkStackApi32Shims",
-    defaults: ["NetworkStackShimsDefaults"],
+    name: "NetworkStackApi33Shims",
+    defaults: ["NetworkStackShimsDefaults", "ConnectivityNextEnableDefaults"],
     srcs: [
-        "apishim/32/**/*.java",
+        "apishim/33/**/*.java",
     ],
     libs: [
         "NetworkStackShimsCommon",
         "NetworkStackApi29Shims",
         "NetworkStackApi30Shims",
         "NetworkStackApi31Shims",
+        "framework-bluetooth",
         "framework-connectivity",
+        "framework-connectivity-tiramisu.stubs.module_lib",
+        "framework-tethering",
     ],
     sdk_version: "module_current",
     visibility: ["//visibility:private"],
@@ -168,18 +184,21 @@
 // called directly by the networkstack code.
 java_library {
     name: "NetworkStackApiCurrentShims",
-    defaults: ["NetworkStackShimsDefaults"],
+    defaults: ["NetworkStackShimsDefaults", "ConnectivityNextEnableDefaults"],
     static_libs: [
         "NetworkStackShimsCommon",
         "NetworkStackApi29Shims",
         "NetworkStackApi30Shims",
         "NetworkStackApi31Shims",
-        "NetworkStackApi32Shims",
+        "NetworkStackApi33Shims",
     ],
     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",
     ],
 }
 
@@ -199,7 +218,10 @@
     sdk_version: "module_31",
     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",
     ],
 }
 
@@ -233,7 +255,11 @@
 // The versions of the android library containing network stack code compiled for each SDK variant.
 android_library {
     name: "NetworkStackApiCurrentLib",
-    defaults: ["NetworkStackDevApiLevel", "NetworkStackAndroidLibraryDefaults"],
+    defaults: [
+        "NetworkStackDevApiLevel",
+        "NetworkStackAndroidLibraryDefaults",
+        "ConnectivityNextEnableDefaults",
+    ],
     srcs: [
         "src/**/*.java",
         ":statslog-networkstack-java-gen-current"
@@ -302,7 +328,11 @@
 // Non-updatable network stack running in the system server process for devices not using the module
 android_app {
     name: "InProcessNetworkStack",
-    defaults: [ "NetworkStackAppDefaults", "NetworkStackDevApiLevel"],
+    defaults: [
+        "NetworkStackAppDefaults",
+        "NetworkStackDevApiLevel",
+        "ConnectivityNextEnableDefaults",
+    ],
     static_libs: ["NetworkStackApiCurrentLib"],
     certificate: "platform",
     manifest: "AndroidManifest_InProcess.xml",
@@ -320,7 +350,11 @@
 // Pre-merge the AndroidManifest for NetworkStackNext, so that its manifest can be merged on top
 android_library {
     name: "NetworkStackNextManifestBase",
-    defaults: ["NetworkStackAppDefaults", "NetworkStackDevApiLevel"],
+    defaults: [
+        "NetworkStackAppDefaults",
+        "NetworkStackDevApiLevel",
+        "ConnectivityNextEnableDefaults",
+    ],
     static_libs: ["NetworkStackApiCurrentLib"],
     manifest: "AndroidManifest.xml"
 }
@@ -328,7 +362,11 @@
 // NetworkStack build targeting the current API release, for testing on in-development SDK
 android_app {
     name: "NetworkStackNext",
-    defaults: ["NetworkStackAppDefaults", "NetworkStackDevApiLevel"],
+    defaults: [
+        "NetworkStackAppDefaults",
+        "NetworkStackDevApiLevel",
+        "ConnectivityNextEnableDefaults",
+    ],
     static_libs: ["NetworkStackNextManifestBase"],
     certificate: "networkstack",
     manifest: "AndroidManifest_Next.xml",
diff --git a/OWNERS b/OWNERS
index 8cb7492..62c5737 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,8 +1,2 @@
-codewiz@google.com
-jchalard@google.com
-junyulai@google.com
-lorenzo@google.com
-maze@google.com
-reminv@google.com
-satk@google.com
-xiaom@google.com
+set noparent
+file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking
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/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/29/com/android/networkstack/apishim/api29/VpnServiceBuilderShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/VpnServiceBuilderShimImpl.java
new file mode 100644
index 0000000..0f221bf
--- /dev/null
+++ b/apishim/29/com/android/networkstack/apishim/api29/VpnServiceBuilderShimImpl.java
@@ -0,0 +1,48 @@
+/*
+ * 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.net.IpPrefix;
+import android.net.VpnService;
+
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+import com.android.networkstack.apishim.common.VpnServiceBuilderShim;
+
+/**
+ * Implementation of {@link com.android.networkstack.apishim.common.VpnServiceBuilderShim}.
+ */
+public class VpnServiceBuilderShimImpl implements VpnServiceBuilderShim {
+
+    /**
+     * Get a new instance of {@link VpnServiceBuilderShim}.
+     */
+    public static VpnServiceBuilderShim newInstance() {
+        return new VpnServiceBuilderShimImpl();
+    }
+
+    @Override
+    public VpnService.Builder excludeRoute(VpnService.Builder builder, IpPrefix prefix)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported after API level 31.");
+    }
+
+    @Override
+    public VpnService.Builder addRoute(VpnService.Builder builder, IpPrefix prefix)
+            throws UnsupportedApiLevelException {
+        throw new UnsupportedApiLevelException("Only supported after API level 31.");
+    }
+}
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/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/32/com/android/networkstack/apishim/SocketUtilsShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/BluetoothPanShimImpl.java
similarity index 60%
copy from apishim/32/com/android/networkstack/apishim/SocketUtilsShimImpl.java
copy to apishim/31/com/android/networkstack/apishim/api31/BluetoothPanShimImpl.java
index 2f4e500..eb7f719 100644
--- a/apishim/32/com/android/networkstack/apishim/SocketUtilsShimImpl.java
+++ b/apishim/31/com/android/networkstack/apishim/api31/BluetoothPanShimImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -14,18 +14,20 @@
  * limitations under the License.
  */
 
-package com.android.networkstack.apishim;
+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.SocketUtilsShim}.
+ * Implementation of {@link com.android.networkstack.apishim.common.BluetoothPanShim}.
  */
-@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods
-public class SocketUtilsShimImpl
-        extends com.android.networkstack.apishim.api30.SocketUtilsShimImpl {
-    // Currently, this is the same as the API 31 shim, so inherit everything from that.
-    protected SocketUtilsShimImpl() {}
+@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..e73e7f5 100644
--- a/apishim/31/com/android/networkstack/apishim/api31/ConstantsShim.java
+++ b/apishim/31/com/android/networkstack/apishim/api31/ConstantsShim.java
@@ -34,4 +34,11 @@
     // 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 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/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/31/com/android/networkstack/apishim/api31/VpnServiceBuilderShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/VpnServiceBuilderShimImpl.java
new file mode 100644
index 0000000..8b82935
--- /dev/null
+++ b/apishim/31/com/android/networkstack/apishim/api31/VpnServiceBuilderShimImpl.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+/**
+ * Implementation of {@link com.android.networkstack.apishim.common.VpnServiceBuilderShim}.
+ */
+public class VpnServiceBuilderShimImpl extends
+        com.android.networkstack.apishim.api29.VpnServiceBuilderShimImpl {
+}
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/32/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java b/apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
similarity index 92%
rename from apishim/32/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
index 2056b1b..63fa021 100644
--- a/apishim/32/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
@@ -27,7 +27,7 @@
 /**
  * Compatibility implementation of {@link CaptivePortalDataShim}.
  */
-@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class CaptivePortalDataShimImpl
         extends com.android.networkstack.apishim.api31.CaptivePortalDataShimImpl {
     // Currently identical to the API 31 shim, so inherit everything
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/32/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
similarity index 92%
rename from apishim/32/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
index a7aa0c8..7675960 100644
--- a/apishim/32/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
@@ -26,7 +26,7 @@
 /**
  * Compatibility implementation of {@link ConnectivityManagerShim}.
  */
-@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class ConnectivityManagerShimImpl
         extends com.android.networkstack.apishim.api31.ConnectivityManagerShimImpl  {
     // Currently identical to the API 31 shim, so inherit everything
diff --git a/apishim/32/com/android/networkstack/apishim/ConstantsShim.java b/apishim/33/com/android/networkstack/apishim/ConstantsShim.java
similarity index 96%
rename from apishim/32/com/android/networkstack/apishim/ConstantsShim.java
rename to apishim/33/com/android/networkstack/apishim/ConstantsShim.java
index 0a5b555..6d146f5 100644
--- a/apishim/32/com/android/networkstack/apishim/ConstantsShim.java
+++ b/apishim/33/com/android/networkstack/apishim/ConstantsShim.java
@@ -29,5 +29,5 @@
      * the shimmed objects and methods themselves.
      */
     @VisibleForTesting
-    public static final int VERSION = 32;
+    public static final int VERSION = 33;
 }
diff --git a/apishim/32/com/android/networkstack/apishim/NetworkInformationShimImpl.java b/apishim/33/com/android/networkstack/apishim/NetworkInformationShimImpl.java
similarity index 91%
rename from apishim/32/com/android/networkstack/apishim/NetworkInformationShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/NetworkInformationShimImpl.java
index 28aa75c..d51ef40 100644
--- a/apishim/32/com/android/networkstack/apishim/NetworkInformationShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/NetworkInformationShimImpl.java
@@ -25,7 +25,7 @@
 /**
  * Compatibility implementation of {@link NetworkInformationShim}.
  */
-@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class NetworkInformationShimImpl
         extends com.android.networkstack.apishim.api31.NetworkInformationShimImpl {
     // Currently identical to the API 31 shim, so inherit everything
diff --git a/apishim/32/com/android/networkstack/apishim/NetworkRequestShimImpl.java b/apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java
similarity index 86%
rename from apishim/32/com/android/networkstack/apishim/NetworkRequestShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java
index 95ae5ba..72dfef2 100644
--- a/apishim/32/com/android/networkstack/apishim/NetworkRequestShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java
@@ -23,9 +23,9 @@
 import com.android.networkstack.apishim.common.NetworkRequestShim;
 
 /**
- * Implementation of {@link NetworkRequestShim} for API 31.
+ * Implementation of {@link NetworkRequestShim} for API 33.
  */
-@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class NetworkRequestShimImpl
         extends com.android.networkstack.apishim.api31.NetworkRequestShimImpl {
     // Currently identical to the API 31 shim, so inherit everything
diff --git a/apishim/32/com/android/networkstack/apishim/NetworkShimImpl.java b/apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java
similarity index 91%
rename from apishim/32/com/android/networkstack/apishim/NetworkShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java
index 2e31a78..0968c4c 100644
--- a/apishim/32/com/android/networkstack/apishim/NetworkShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java
@@ -25,7 +25,7 @@
 /**
  * Compatibility implementation of {@link com.android.networkstack.apishim.common.NetworkShim}.
  */
-@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class NetworkShimImpl extends com.android.networkstack.apishim.api30.NetworkShimImpl {
     // Currently, this is the same as the API 31 shim, so inherit everything from that.
     protected NetworkShimImpl(@NonNull Network network) {
diff --git a/apishim/32/com/android/networkstack/apishim/SettingsShimImpl.java b/apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java
similarity index 90%
rename from apishim/32/com/android/networkstack/apishim/SettingsShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java
index 46d2102..cd3a463 100644
--- a/apishim/32/com/android/networkstack/apishim/SettingsShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java
@@ -23,9 +23,9 @@
 import com.android.networkstack.apishim.common.SettingsShim;
 
 /**
- * Compatibility implementation of {@link SettingsShim} for API 31.
+ * Compatibility implementation of {@link SettingsShim} for API 33.
  */
-@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class SettingsShimImpl
         extends com.android.networkstack.apishim.api30.SettingsShimImpl {
     // Currently identical to the API 31 shim, so inherit everything
diff --git a/apishim/32/com/android/networkstack/apishim/SocketUtilsShimImpl.java b/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
similarity index 91%
rename from apishim/32/com/android/networkstack/apishim/SocketUtilsShimImpl.java
rename to apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
index 2f4e500..d4ab534 100644
--- a/apishim/32/com/android/networkstack/apishim/SocketUtilsShimImpl.java
+++ b/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
@@ -23,7 +23,7 @@
 /**
  * Implementation of {@link com.android.networkstack.apishim.common.SocketUtilsShim}.
  */
-@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
 public class SocketUtilsShimImpl
         extends com.android.networkstack.apishim.api30.SocketUtilsShimImpl {
     // Currently, this is the same as the API 31 shim, so inherit everything from that.
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/33/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java b/apishim/33/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java
new file mode 100644
index 0000000..da8f774
--- /dev/null
+++ b/apishim/33/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+import android.net.IpPrefix;
+import android.net.VpnService;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+import com.android.networkstack.apishim.common.VpnServiceBuilderShim;
+
+/**
+ * Implementation of {@link com.android.networkstack.apishim.common.VpnServiceBuilderShim}.
+ */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class VpnServiceBuilderShimImpl extends
+        com.android.networkstack.apishim.api31.VpnServiceBuilderShimImpl {
+
+    /**
+     * Get a new instance of {@link VpnServiceBuilderShim}.
+     */
+    @RequiresApi(Build.VERSION_CODES.Q)
+    public static VpnServiceBuilderShim newInstance() {
+        if (SdkLevel.isAtLeastT()) {
+            return new VpnServiceBuilderShimImpl();
+        } else {
+            return new com.android.networkstack.apishim.api31.VpnServiceBuilderShimImpl();
+        }
+    }
+
+    @Override
+    public VpnService.Builder excludeRoute(VpnService.Builder builder, IpPrefix prefix)
+            throws UnsupportedApiLevelException {
+        return builder.excludeRoute(prefix);
+    }
+
+    @Override
+    public VpnService.Builder addRoute(VpnService.Builder builder, IpPrefix prefix)
+            throws UnsupportedApiLevelException {
+        return builder.addRoute(prefix);
+    }
+}
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/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/apishim/common/com/android/networkstack/apishim/common/VpnServiceBuilderShim.java b/apishim/common/com/android/networkstack/apishim/common/VpnServiceBuilderShim.java
new file mode 100644
index 0000000..fbfcf6c
--- /dev/null
+++ b/apishim/common/com/android/networkstack/apishim/common/VpnServiceBuilderShim.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.common;
+
+import android.net.IpPrefix;
+import android.net.VpnService;
+
+/** Shim for {@link VpnService.Builder}. */
+public interface VpnServiceBuilderShim {
+    /**
+     * @see VpnService.Builder#excludeRoute(IpPrefix)
+     */
+    VpnService.Builder excludeRoute(VpnService.Builder builder, IpPrefix prefix)
+            throws UnsupportedApiLevelException;
+
+    /**
+     * @see VpnService.Builder#addRoute(IpPrefix)
+     */
+    VpnService.Builder addRoute(VpnService.Builder builder, IpPrefix prefix)
+            throws UnsupportedApiLevelException;
+}
diff --git a/common/networkstackclient/Android.bp b/common/networkstackclient/Android.bp
index 983bb61..3c97dc2 100644
--- a/common/networkstackclient/Android.bp
+++ b/common/networkstackclient/Android.bp
@@ -35,7 +35,6 @@
             apex_available: [
                 "//apex_available:platform",
                 "com.android.wifi",
-                "com.android.bluetooth.updatable",
                 "com.android.tethering",
             ],
             // this is part of updatable modules(NetworkStack) which targets 29(Q)
@@ -102,12 +101,13 @@
         // New AIDL classes should go into android.net.networkstack.aidl so they can be clearly
         // identified
         "src/android/net/networkstack/aidl/dhcp/DhcpOption.aidl",
+        "src/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl",
+        "src/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl",
     ],
     backend: {
         java: {
             apex_available: [
                 "//apex_available:platform",
-                "com.android.bluetooth.updatable",
                 "com.android.wifi",
                 "com.android.tethering",
             ],
@@ -135,6 +135,7 @@
         "10",
         "11",
         "12",
+        "13",
     ],
     // TODO: have tethering depend on networkstack-client and set visibility to private
     visibility: [
@@ -150,7 +151,7 @@
     min_sdk_version: "29",
     static_libs: [
         "ipmemorystore-aidl-interfaces-V10-java",
-        "networkstack-aidl-interfaces-V12-java",
+        "networkstack-aidl-interfaces-V13-java",
     ],
     visibility: ["//packages/modules/NetworkStack:__subpackages__"],
     apex_available: [
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/.hash b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/.hash
new file mode 100644
index 0000000..8047fe9
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/.hash
@@ -0,0 +1 @@
+8adb67bdf8c295e5bf053155269198fba9ab021e
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/DataStallReportParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/DataStallReportParcelable.aidl
new file mode 100644
index 0000000..771deda
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/DhcpResultsParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/DhcpResultsParcelable.aidl
new file mode 100644
index 0000000..31f2194
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/INetworkMonitor.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/INetworkMonitor.aidl
new file mode 100644
index 0000000..d92196d
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/INetworkMonitor.aidl
@@ -0,0 +1,59 @@
+/**
+ * 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);
+  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/13/android/net/INetworkMonitorCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/INetworkMonitorCallbacks.aidl
new file mode 100644
index 0000000..36eda8e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/INetworkStackConnector.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/INetworkStackConnector.aidl
new file mode 100644
index 0000000..8120ffc
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/INetworkStackStatusCallback.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/INetworkStackStatusCallback.aidl
new file mode 100644
index 0000000..0b6b778
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/InformationElementParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/InformationElementParcelable.aidl
new file mode 100644
index 0000000..6103774
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/InitialConfigurationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/InitialConfigurationParcelable.aidl
new file mode 100644
index 0000000..6a597e6
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/Layer2InformationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/Layer2InformationParcelable.aidl
new file mode 100644
index 0000000..83796ee
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/Layer2PacketParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/Layer2PacketParcelable.aidl
new file mode 100644
index 0000000..4b3fff5
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/NattKeepalivePacketDataParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/NattKeepalivePacketDataParcelable.aidl
new file mode 100644
index 0000000..18cf954
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/NetworkTestResultParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/NetworkTestResultParcelable.aidl
new file mode 100644
index 0000000..4d6d5a2
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/PrivateDnsConfigParcel.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/PrivateDnsConfigParcel.aidl
new file mode 100644
index 0000000..1457caf
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/ProvisioningConfigurationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/ProvisioningConfigurationParcelable.aidl
new file mode 100644
index 0000000..9ecd110
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/ScanResultInfoParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/ScanResultInfoParcelable.aidl
new file mode 100644
index 0000000..94fc27f
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/TcpKeepalivePacketDataParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/TcpKeepalivePacketDataParcelable.aidl
new file mode 100644
index 0000000..0e1c21c
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/dhcp/DhcpLeaseParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/dhcp/DhcpLeaseParcelable.aidl
new file mode 100644
index 0000000..3cd8860
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/dhcp/DhcpServingParamsParcel.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/dhcp/DhcpServingParamsParcel.aidl
new file mode 100644
index 0000000..fa412cb
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/dhcp/IDhcpEventCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/dhcp/IDhcpEventCallbacks.aidl
new file mode 100644
index 0000000..9312f47
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/dhcp/IDhcpServer.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/dhcp/IDhcpServer.aidl
new file mode 100644
index 0000000..1109f35
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/dhcp/IDhcpServerCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/dhcp/IDhcpServerCallbacks.aidl
new file mode 100644
index 0000000..ab8577c
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/ip/IIpClient.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/ip/IIpClient.aidl
new file mode 100644
index 0000000..a97511e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/ip/IIpClientCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/ip/IIpClientCallbacks.aidl
new file mode 100644
index 0000000..24bbf64
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/networkstack/aidl/dhcp/DhcpOption.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/networkstack/aidl/dhcp/DhcpOption.aidl
new file mode 100644
index 0000000..eea3e0d
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl
new file mode 100644
index 0000000..bb88434
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/13/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl
new file mode 100644
index 0000000..70a7db2
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/13/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/ip/IIpClientCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/ip/IIpClientCallbacks.aidl
index 488510d..24bbf64 100644
--- a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/ip/IIpClientCallbacks.aidl
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/ip/IIpClientCallbacks.aidl
@@ -48,4 +48,5 @@
   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/current/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl
new file mode 100644
index 0000000..bb88434
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/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/current/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl
new file mode 100644
index 0000000..70a7db2
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/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/src/android/net/ip/IIpClientCallbacks.aidl b/common/networkstackclient/src/android/net/ip/IIpClientCallbacks.aidl
index de398ed..932672e 100644
--- a/common/networkstackclient/src/android/net/ip/IIpClientCallbacks.aidl
+++ b/common/networkstackclient/src/android/net/ip/IIpClientCallbacks.aidl
@@ -18,6 +18,7 @@
 import android.net.Layer2PacketParcelable;
 import android.net.LinkProperties;
 import android.net.ip.IIpClient;
+import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable;
 import android.net.DhcpResultsParcelable;
 
 /** @hide */
@@ -67,4 +68,8 @@
 
     // Invoked on starting preconnection process.
     void onPreconnectionStart(in List<Layer2PacketParcelable> packets);
+
+    // Called when the internal IpReachabilityMonitor (if enabled) has detected the loss of a
+    // critical number of required neighbors or DHCP roaming fails.
+    void onReachabilityFailure(in ReachabilityLossInfoParcelable lossInfo);
 }
diff --git a/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java b/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java
index b17fcaa..7cf46f5 100644
--- a/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java
+++ b/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java
@@ -19,6 +19,7 @@
 import android.net.DhcpResultsParcelable;
 import android.net.Layer2PacketParcelable;
 import android.net.LinkProperties;
+import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable;
 
 import java.util.List;
 
@@ -133,4 +134,16 @@
      * Invoked on starting preconnection process.
      */
     public void onPreconnectionStart(List<Layer2PacketParcelable> packets) {}
+
+    /**
+     * Called when the internal IpReachabilityMonitor (if enabled) has detected the loss of a
+     * critical number of required neighbors or DHCP roaming fails.
+     *
+     * @param lossInfo the specific neighbor reachability loss information.
+     */
+    public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) {
+        // If the client does not implement this method, call the older
+        // onReachabilityLost method.
+        onReachabilityLost(lossInfo.message);
+    }
 }
diff --git a/common/networkstackclient/src/android/net/ip/IpClientUtil.java b/common/networkstackclient/src/android/net/ip/IpClientUtil.java
index 1b55776..d488578 100644
--- a/common/networkstackclient/src/android/net/ip/IpClientUtil.java
+++ b/common/networkstackclient/src/android/net/ip/IpClientUtil.java
@@ -21,6 +21,7 @@
 import android.net.Layer2PacketParcelable;
 import android.net.LinkProperties;
 import android.net.networkstack.ModuleNetworkStackClient;
+import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable;
 import android.os.ConditionVariable;
 
 import java.io.FileDescriptor;
@@ -182,6 +183,13 @@
             mCb.onPreconnectionStart(packets);
         }
 
+        // Called when the internal IpReachabilityMonitor (if enabled) has detected the loss of a
+        // critical number of required neighbors or DHCP roaming fails.
+        @Override
+        public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) {
+            mCb.onReachabilityFailure(lossInfo);
+        }
+
         @Override
         public int getInterfaceVersion() {
             return this.VERSION;
diff --git a/common/networkstackclient/src/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl b/common/networkstackclient/src/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl
new file mode 100644
index 0000000..fda6264
--- /dev/null
+++ b/common/networkstackclient/src/android/net/networkstack/aidl/ip/ReachabilityLossInfoParcelable.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.networkstack.aidl.ip;
+
+import android.net.networkstack.aidl.ip.ReachabilityLossReason;
+
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable ReachabilityLossInfoParcelable {
+    /** The log message when reachability loss happens. */
+    String message;
+
+    /** The specific reason of reachability loss. */
+    ReachabilityLossReason reason;
+}
diff --git a/common/networkstackclient/src/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl b/common/networkstackclient/src/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl
new file mode 100644
index 0000000..cc2e9e7
--- /dev/null
+++ b/common/networkstackclient/src/android/net/networkstack/aidl/ip/ReachabilityLossReason.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.networkstack.aidl.ip;
+
+@Backing(type="int")
+enum ReachabilityLossReason {
+    ROAM,    // reachability loss due to L2 roaming.
+    CONFIRM, // reachability loss due to WiFi RSSI check.
+    ORGANIC, // reachability loss notification comes from kernel.
+}
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index e3b7121..b5a08ec 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -21,6 +21,6 @@
     <string name="notification_channel_name_network_venue_info" msgid="6526543187249265733">"Maklumat tempat rangkaian"</string>
     <string name="notification_channel_description_network_venue_info" msgid="5131499595382733605">"Pemberitahuan dipaparkan untuk menunjukkan rangkaian mempunyai halaman maklumat tempat"</string>
     <string name="connected" msgid="4563643884927480998">"Disambungkan"</string>
-    <string name="tap_for_info" msgid="6849746325626883711">"Disambungkan / Ketik untuk melihat tapak web"</string>
+    <string name="tap_for_info" msgid="6849746325626883711">"Disambungkan / Ketik untuk melihat laman web"</string>
     <string name="application_label" msgid="1322847171305285454">"Pengurus rangkaian"</string>
 </resources>
diff --git a/src/android/net/dhcp/DhcpClient.java b/src/android/net/dhcp/DhcpClient.java
index 8e0e9d3..704ca7d 100644
--- a/src/android/net/dhcp/DhcpClient.java
+++ b/src/android/net/dhcp/DhcpClient.java
@@ -251,6 +251,7 @@
     public static final int DHCP_SUCCESS = 1;
     public static final int DHCP_FAILURE = 2;
     public static final int DHCP_IPV6_ONLY = 3;
+    public static final int DHCP_REFRESH_FAILURE = 4;
 
     // Internal messages.
     private static final int PRIVATE_BASE         = IpClient.DHCPCLIENT_CMD_BASE + 100;
@@ -391,6 +392,7 @@
     private State mIpAddressConflictDetectingState = new IpAddressConflictDetectingState();
     private State mDhcpDecliningState = new DhcpDecliningState();
     private State mIpv6OnlyWaitState = new Ipv6OnlyWaitState();
+    private State mDhcpRefreshingAddressState = new DhcpRefreshingAddressState();
 
     private WakeupMessage makeWakeupMessage(String cmdName, int cmd) {
         cmdName = DhcpClient.class.getSimpleName() + "." + mIfaceName + "." + cmdName;
@@ -499,6 +501,7 @@
                 addState(mDhcpRenewingState, mDhcpHaveLeaseState);
                 addState(mDhcpRebindingState, mDhcpHaveLeaseState);
                 addState(mDhcpDecliningState, mDhcpHaveLeaseState);
+                addState(mDhcpRefreshingAddressState, mDhcpHaveLeaseState);
             addState(mDhcpInitRebootState, mDhcpState);
             addState(mDhcpRebootingState, mDhcpState);
         // CHECKSTYLE:ON IndentationCheck
@@ -747,9 +750,14 @@
     }
 
     private boolean sendDiscoverPacket() {
+        // When Rapid Commit option is enabled, limit only the first 3 DHCPDISCOVER packets
+        // taking Rapid Commit option, in order to prevent the potential interoperability issue
+        // and be able to rollback later. See {@link DHCP_TIMEOUT_MS} for the (re)transmission
+        // schedule with 10% jitter.
+        final boolean requestRapidCommit = isDhcpRapidCommitEnabled() && (getSecs() <= 4);
         final ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
                 DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr,
-                DO_UNICAST, getRequestedParams(), isDhcpRapidCommitEnabled(), mHostname,
+                DO_UNICAST, getRequestedParams(), requestRapidCommit, mHostname,
                 mConfiguration.options);
         mMetrics.incrementCountForDiscover();
         return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST);
@@ -844,11 +852,11 @@
                 CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));
     }
 
-    private void notifyFailure() {
+    private void notifyFailure(int arg) {
         if (isDhcpLeaseCacheEnabled()) {
             setLeaseExpiredToIpMemoryStore();
         }
-        mController.sendMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0, null);
+        mController.sendMessage(CMD_POST_DHCP_ACTION, arg, 0, null);
     }
 
     private void acceptDhcpResults(DhcpResults results, String msg) {
@@ -1044,7 +1052,7 @@
                 if (mDhcpPacketHandler.start()) return;
                 Log.e(TAG, "Fail to start DHCP Packet Handler");
             }
-            notifyFailure();
+            notifyFailure(DHCP_FAILURE);
             // We cannot call transitionTo because a transition is still in progress.
             // Instead, ensure that we process CMD_STOP_DHCP as soon as the transition is complete.
             deferMessage(obtainMessage(CMD_STOP_DHCP));
@@ -1449,8 +1457,8 @@
             switch (message.what) {
                 case CMD_EXPIRE_DHCP:
                     Log.d(TAG, "Lease expired!");
-                    notifyFailure();
-                    transitionTo(mDhcpInitState);
+                    notifyFailure(DHCP_FAILURE);
+                    transitionTo(mStoppedState);
                     return HANDLED;
                 default:
                     return NOT_HANDLED;
@@ -1761,7 +1769,7 @@
                 // return an IPv4 address from another interface, or even return "0.0.0.0".
                 //
                 // TODO: Consider deleting this check, following testing on several kernels.
-                notifyFailure();
+                notifyFailure(DHCP_FAILURE);
                 transitionTo(mStoppedState);
             }
 
@@ -1783,7 +1791,7 @@
                     preDhcpTransitionTo(mWaitBeforeRenewalState, mDhcpRenewingState);
                     return HANDLED;
                 case CMD_REFRESH_LINKADDRESS:
-                    transitionTo(mDhcpRebindingState);
+                    transitionTo(mDhcpRefreshingAddressState);
                     return HANDLED;
                 default:
                     return NOT_HANDLED;
@@ -1811,6 +1819,10 @@
 
         protected abstract Inet4Address packetDestination();
 
+        // Check whether DhcpClient should notify provisioning failure when receiving DHCPNAK
+        // in renew/rebind state or just restart reconfiguration from StoppedState.
+        protected abstract boolean shouldRestartOnNak();
+
         protected boolean sendPacket() {
             return sendRequestPacket(
                     (Inet4Address) mDhcpLease.ipAddress.getAddress(),  // ciaddr
@@ -1829,8 +1841,8 @@
                 if (results != null) {
                     if (!mDhcpLease.ipAddress.equals(results.ipAddress)) {
                         Log.d(TAG, "Renewed lease not for our current IP address!");
-                        notifyFailure();
-                        transitionTo(mDhcpInitState);
+                        notifyFailure(DHCP_FAILURE);
+                        transitionTo(mStoppedState);
                         return;
                     }
                     setDhcpLeaseExpiry(packet);
@@ -1844,9 +1856,9 @@
                     transitionTo(mDhcpBoundState);
                 }
             } else if (packet instanceof DhcpNakPacket) {
-                Log.d(TAG, "Received NAK, returning to INIT");
-                notifyFailure();
-                transitionTo(mDhcpInitState);
+                Log.d(TAG, "Received NAK, returning to StoppedState");
+                notifyFailure(shouldRestartOnNak() ? DHCP_REFRESH_FAILURE : DHCP_FAILURE);
+                transitionTo(mStoppedState);
             }
         }
     }
@@ -1878,6 +1890,11 @@
             return (mDhcpLease.serverAddress != null) ?
                     mDhcpLease.serverAddress : INADDR_BROADCAST;
         }
+
+        @Override
+        protected boolean shouldRestartOnNak() {
+            return false;
+        }
     }
 
     class DhcpRebindingState extends DhcpReacquiringState {
@@ -1902,6 +1919,22 @@
         protected Inet4Address packetDestination() {
             return INADDR_BROADCAST;
         }
+
+        @Override
+        protected boolean shouldRestartOnNak() {
+            return false;
+        }
+    }
+
+    class DhcpRefreshingAddressState extends DhcpRebindingState {
+        DhcpRefreshingAddressState() {
+            mLeaseMsg = "Refreshing address";
+        }
+
+        @Override
+        protected boolean shouldRestartOnNak() {
+            return true;
+        }
     }
 
     class DhcpInitRebootState extends DhcpRequestingState {
diff --git a/src/android/net/dhcp/DhcpPacket.java b/src/android/net/dhcp/DhcpPacket.java
index 76dc807..63c5b0c 100644
--- a/src/android/net/dhcp/DhcpPacket.java
+++ b/src/android/net/dhcp/DhcpPacket.java
@@ -321,7 +321,8 @@
      * packet may include this option.
      */
     public static final byte DHCP_RAPID_COMMIT = 80;
-    protected boolean mRapidCommit;
+    @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+    public boolean mRapidCommit;
 
     /**
      * DHCP IPv6-Only Preferred Option(RFC 8925).
diff --git a/src/android/net/dhcp/DhcpServingParams.java b/src/android/net/dhcp/DhcpServingParams.java
index 0fd649d..9d395f7 100644
--- a/src/android/net/dhcp/DhcpServingParams.java
+++ b/src/android/net/dhcp/DhcpServingParams.java
@@ -24,6 +24,7 @@
 
 import static java.lang.Integer.toUnsignedLong;
 
+import android.annotation.SuppressLint;
 import android.net.IpPrefix;
 import android.net.LinkAddress;
 import android.util.ArraySet;
@@ -411,6 +412,7 @@
     /**
      * Utility method to create an IpPrefix with the address and prefix length of a LinkAddress.
      */
+    @SuppressLint("NewApi")
     @NonNull
     static IpPrefix makeIpPrefix(@NonNull LinkAddress addr) {
         return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index a81ab5c..b08e0b9 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -21,6 +21,8 @@
 import static android.net.ip.IIpClient.PROV_IPV4_DISABLED;
 import static android.net.ip.IIpClient.PROV_IPV6_DISABLED;
 import static android.net.ip.IIpClient.PROV_IPV6_LINKLOCAL;
+import static android.net.ip.IpReachabilityMonitor.INVALID_REACHABILITY_LOSS_TYPE;
+import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt;
 import static android.net.util.NetworkStackUtils.IPCLIENT_DISABLE_ACCEPT_RA_VERSION;
 import static android.net.util.NetworkStackUtils.IPCLIENT_GARP_NA_ROAMING_VERSION;
 import static android.net.util.NetworkStackUtils.IPCLIENT_GRATUITOUS_NA_VERSION;
@@ -63,6 +65,8 @@
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.IpManagerEvent;
 import android.net.networkstack.aidl.dhcp.DhcpOption;
+import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable;
+import android.net.networkstack.aidl.ip.ReachabilityLossReason;
 import android.net.shared.InitialConfiguration;
 import android.net.shared.Layer2Information;
 import android.net.shared.ProvisioningConfiguration;
@@ -81,6 +85,7 @@
 import android.os.SystemClock;
 import android.stats.connectivity.DisconnectCode;
 import android.stats.connectivity.NetworkQuirkEvent;
+import android.stats.connectivity.NudEventType;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.text.TextUtils;
@@ -90,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;
@@ -316,6 +322,11 @@
         /**
          * Called when the internal IpReachabilityMonitor (if enabled) has detected the loss of
          * required neighbors (e.g. on-link default gw or dns servers) due to NUD_FAILED.
+         *
+         * Note this method is only supported on networkstack-aidl-interfaces-v12 or below.
+         * For above aidl versions, the caller should call {@link onReachabilityFailure} instead.
+         * For callbacks extending IpClientCallbacks, this method will be called iff the callback
+         * does not implement onReachabilityFailure.
          */
         public void onReachabilityLost(String logMsg) {
             log("onReachabilityLost(" + logMsg + ")");
@@ -402,6 +413,20 @@
         }
 
         /**
+         * Called when Neighbor Unreachability Detection fails, that might be caused by the organic
+         * probe or probeAll from IpReachabilityMonitor (if enabled).
+         */
+        public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) {
+            log("onReachabilityFailure(" + lossInfo.message + ", loss reason: "
+                    + reachabilityLossReasonToString(lossInfo.reason) + ")");
+            try {
+                mCallback.onReachabilityFailure(lossInfo);
+            } catch (RemoteException e) {
+                log("Failed to call onReachabilityFailure", e);
+            }
+        }
+
+        /**
          * Get the version of the IIpClientCallbacks AIDL interface.
          */
         public int getInterfaceVersion() {
@@ -478,6 +503,10 @@
     private static final int PROV_CHANGE_GAINED_PROVISIONING = 3;
     private static final int PROV_CHANGE_STILL_PROVISIONED = 4;
 
+    // onReachabilityFailure callback is added since networkstack-aidl-interfaces-v13.
+    @VisibleForTesting
+    static final int VERSION_ADDED_REACHABILITY_FAILURE = 13;
+
     // Specific vendor OUI(3 bytes)/vendor specific type(1 byte) pattern for upstream hotspot
     // device detection. Add new byte array pattern below in turn.
     private static final List<byte[]> METERED_IE_PATTERN_LIST = Collections.unmodifiableList(
@@ -712,9 +741,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) {
@@ -747,21 +794,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));
@@ -1250,6 +1282,20 @@
         transitionTo(mStoppingState);
     }
 
+    // Convert reachability loss reason enum to a string.
+    private static String reachabilityLossReasonToString(int reason) {
+        switch (reason) {
+            case ReachabilityLossReason.ROAM:
+                return "reachability_loss_after_roam";
+            case ReachabilityLossReason.CONFIRM:
+                return "reachability_loss_after_confirm";
+            case ReachabilityLossReason.ORGANIC:
+                return "reachability_loss_organic";
+            default:
+                return "unknown";
+        }
+    }
+
     private static boolean hasIpv6LinkLocalInterfaceRoute(final LinkProperties lp) {
         for (RouteInfo r : lp.getRoutes()) {
             if (r.getDestination().equals(new IpPrefix("fe80::/64"))
@@ -1621,6 +1667,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;
@@ -1630,6 +1677,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;
 
@@ -1650,7 +1707,7 @@
                         + targetIp.getHostAddress() + (afterRoaming ? " after roaming" : ""));
             }
             sendGratuitousNA(srcIp, targetIp);
-            if (!afterRoaming) mGratuitousNaTargetAddresses.add(targetIp);
+            if (!afterRoaming) updateGratuitousNaTargetSet(targetIp, true /* add address */);
         }
     }
 
@@ -1859,8 +1916,17 @@
                     mLog,
                     new IpReachabilityMonitor.Callback() {
                         @Override
-                        public void notifyLost(InetAddress ip, String logMsg) {
-                            mCallback.onReachabilityLost(logMsg);
+                        public void notifyLost(InetAddress ip, String logMsg, NudEventType type) {
+                            final int version = mCallback.getInterfaceVersion();
+                            if (version >= VERSION_ADDED_REACHABILITY_FAILURE) {
+                                final int reason = nudEventTypeToInt(type);
+                                if (reason == INVALID_REACHABILITY_LOSS_TYPE) return;
+                                final ReachabilityLossInfoParcelable lossInfo =
+                                        new ReachabilityLossInfoParcelable(logMsg, reason);
+                                mCallback.onReachabilityFailure(lossInfo);
+                            } else {
+                                mCallback.onReachabilityLost(logMsg);
+                            }
                         }
                     },
                     mConfiguration.mUsingMultinetworkPolicyTracker,
@@ -1938,18 +2004,18 @@
         // If the BSSID has not changed, there is nothing to do.
         if (info.bssid.equals(mCurrentBssid)) return;
 
-        // Before trigger probing to the interesting neighbors, send Gratuitous ARP
+        // Before trigger probing to the critical neighbors, send Gratuitous ARP
         // and Neighbor Advertisment in advance to propgate host's IPv4/v6 addresses.
         if (isGratuitousArpNaRoamingEnabled()) {
             maybeSendGratuitousARP(mLinkProperties);
             maybeSendGratuitousNAs(mLinkProperties, true /* isGratuitousNaAfterRoaming */);
         }
 
-        if (mIpReachabilityMonitor != null) {
-            mIpReachabilityMonitor.probeAll(true /* dueToRoam */);
-        }
-
-        // Check whether to refresh previous IP lease on L2 roaming happened.
+        // Check whether attempting to refresh previous IP lease on specific networks or need to
+        // probe the critical neighbors proactively on L2 roaming happened. The NUD probe on the
+        // specific networks is cancelled because otherwise the probe will happen in parallel with
+        // DHCP refresh, it will be difficult to understand what happened exactly and error-prone
+        // to introduce race condition.
         final String ssid = removeDoubleQuotes(mConfiguration.mDisplayName);
         if (DHCP_ROAMING_SSID_SET.contains(ssid) && mDhcpClient != null) {
             if (DBG) {
@@ -1959,6 +2025,8 @@
                         + " , starting refresh leased IP address");
             }
             mDhcpClient.sendMessage(DhcpClient.CMD_REFRESH_LINKADDRESS);
+        } else if (mIpReachabilityMonitor != null) {
+            mIpReachabilityMonitor.probeAll(true /* dueToRoam */);
         }
         mCurrentBssid = info.bssid;
     }
@@ -2549,6 +2617,20 @@
                             break;
                         case DhcpClient.DHCP_IPV6_ONLY:
                             break;
+                        case DhcpClient.DHCP_REFRESH_FAILURE:
+                            // This case should only happen on the receipt of DHCPNAK when
+                            // refreshing IP address post L2 roaming on some specific networks.
+                            // WiFi should try to restart a new provisioning immediately without
+                            // disconnecting L2 when it receives DHCP roaming failure event. IPv4
+                            // link address still will be cleared when DhcpClient transits to
+                            // StoppedState from RefreshingAddress State, although it will result
+                            // in a following onProvisioningFailure then, WiFi should ignore this
+                            // failure and start a new DHCP reconfiguration from INIT state.
+                            final ReachabilityLossInfoParcelable lossInfo =
+                                    new ReachabilityLossInfoParcelable("DHCP refresh failure",
+                                            ReachabilityLossReason.ROAM);
+                            mCallback.onReachabilityFailure(lossInfo);
+                            break;
                         default:
                             logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1);
                     }
diff --git a/src/android/net/ip/IpClientLinkObserver.java b/src/android/net/ip/IpClientLinkObserver.java
index f8ba367..adc527b 100644
--- a/src/android/net/ip/IpClientLinkObserver.java
+++ b/src/android/net/ip/IpClientLinkObserver.java
@@ -42,6 +42,8 @@
 import android.system.OsConstants;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+
 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 435d4ca..c716fdf 100644
--- a/src/android/net/ip/IpReachabilityMonitor.java
+++ b/src/android/net/ip/IpReachabilityMonitor.java
@@ -32,6 +32,7 @@
 import android.net.ip.IpNeighborMonitor.NeighborEventConsumer;
 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;
@@ -157,6 +158,7 @@
     private static final int INVALID_NUD_MCAST_RESOLICIT_NUM = -1;
 
     private static final int INVALID_LEGACY_NUD_FAILURE_TYPE = -1;
+    public static final int INVALID_REACHABILITY_LOSS_TYPE = -1;
 
     public interface Callback {
         /**
@@ -165,7 +167,7 @@
          *
          * TODO: refactor to something like notifyProvisioningLost(String msg).
          */
-        void notifyLost(InetAddress ip, String logMsg);
+        void notifyLost(InetAddress ip, String logMsg, NudEventType type);
     }
 
     /**
@@ -408,9 +410,11 @@
             final String logMsg = "ALERT neighbor: " + event.ip
                     + " MAC address changed from: " + prev.macAddr
                     + " to: " + event.macAddr;
+            final NudEventType type =
+                    getMacAddressChangedEventType(isFromProbe(), isNudFailureDueToRoam());
             mLog.w(logMsg);
-            mCallback.notifyLost(event.ip, logMsg);
-            logNudFailed(event, NudEventType.NUD_MAC_ADDRESS_CHANGED);
+            mCallback.notifyLost(event.ip, logMsg, type);
+            logNudFailed(event, type);
             return;
         }
         maybeRestoreNeighborParameters();
@@ -457,7 +461,7 @@
             Log.w(TAG, logMsg);
             // TODO: remove |ip| when the callback signature no longer has
             // an InetAddress argument.
-            mCallback.notifyLost(ip, logMsg);
+            mCallback.notifyLost(ip, logMsg, type);
         }
         logNudFailed(event, type);
     }
@@ -519,7 +523,9 @@
 
     private long getProbeWakeLockDuration() {
         final long gracePeriodMs = 500;
-        return (long) (mNumSolicits * mInterSolicitIntervalMs) + gracePeriodMs;
+        final int numSolicits =
+                mNumSolicits + (isMulticastResolicitEnabled() ? NUD_MCAST_RESOLICIT_NUM : 0);
+        return (long) (numSolicits * mInterSolicitIntervalMs) + gracePeriodMs;
     }
 
     private void setNeighbourParametersPostRoaming() {
@@ -570,7 +576,7 @@
             }
         }
 
-        mNumSolicits = isMulticastResolicitEnabled() ? (numSolicits + numResolicits) : numSolicits;
+        mNumSolicits = numSolicits;
         mInterSolicitIntervalMs = interSolicitIntervalMs;
     }
 
@@ -646,6 +652,19 @@
     }
 
     /**
+     * Returns the NUD failure event type code due to neighbor's MAC address has changed
+     * corresponding to the given conditions.
+     */
+    private static NudEventType getMacAddressChangedEventType(boolean isFromProbe,
+            boolean isDueToRoam) {
+        return isFromProbe
+                ? isDueToRoam
+                        ? NudEventType.NUD_POST_ROAMING_MAC_ADDRESS_CHANGED
+                        : NudEventType.NUD_CONFIRM_MAC_ADDRESS_CHANGED
+                : NudEventType.NUD_ORGANIC_MAC_ADDRESS_CHANGED;
+    }
+
+    /**
      * Log NUD failure metrics with new Westworld APIs while the function using mMetricsLog API
      * still sends the legacy metrics, @see #logNudFailed.
      */
@@ -677,4 +696,24 @@
                 return INVALID_LEGACY_NUD_FAILURE_TYPE;
         }
     }
+
+    /**
+     * Convert the NUD critical failure event type to a int constant defined in IIpClientCallbacks.
+     */
+    public static int nudEventTypeToInt(final NudEventType type) {
+        switch (type) {
+            case NUD_POST_ROAMING_FAILED_CRITICAL:
+            case NUD_POST_ROAMING_MAC_ADDRESS_CHANGED:
+                return ReachabilityLossReason.ROAM;
+            case NUD_CONFIRM_FAILED_CRITICAL:
+            case NUD_CONFIRM_MAC_ADDRESS_CHANGED:
+                return ReachabilityLossReason.CONFIRM;
+            case NUD_ORGANIC_FAILED_CRITICAL:
+            case NUD_ORGANIC_MAC_ADDRESS_CHANGED:
+                return ReachabilityLossReason.ORGANIC;
+            // For other NudEventType which won't trigger notifyLost, just ignore these events.
+            default:
+                return INVALID_REACHABILITY_LOSS_TYPE;
+        }
+    }
 }
diff --git a/src/com/android/server/connectivity/NetworkMonitor.java b/src/com/android/server/connectivity/NetworkMonitor.java
index 948ce8d..72c55df 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;
@@ -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;
@@ -1428,7 +1430,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 9137c5c..36c6162 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -81,6 +81,7 @@
     defaults: [
         "NetworkStackIntegrationTestsDefaults",
         "NetworkStackIntegrationTestsJniDefaults",
+        "ConnectivityNextEnableDefaults",
     ],
     static_libs: [
         "NetworkStackApiCurrentLib",
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt b/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
index 748ee5a..fa379d3 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
@@ -21,8 +21,6 @@
 import android.net.ipmemorystore.Status
 import android.net.ipmemorystore.Status.SUCCESS
 import android.util.ArrayMap
-import java.net.Inet6Address
-import kotlin.test.assertEquals
 import org.mockito.Mockito.any
 import org.mockito.Mockito.doAnswer
 import org.mockito.ArgumentCaptor
@@ -63,17 +61,6 @@
         verify(mIpMemoryStore, never()).storeNetworkAttributes(eq(l2Key), any(), any())
     }
 
-    override fun assertNotifyNeighborLost(targetIp: Inet6Address) {
-        val target = ArgumentCaptor.forClass(Inet6Address::class.java)
-
-        verify(mCallback, timeout(TEST_TIMEOUT_MS)).notifyLost(target.capture(), any())
-        assertEquals(targetIp, target.getValue())
-    }
-
-    override fun assertNeverNotifyNeighborLost() {
-        verify(mCallback, never()).notifyLost(any(), any())
-    }
-
     override fun storeNetworkAttributes(l2Key: String, na: NetworkAttributes) {
         doAnswer { inv ->
             val listener = inv.getArgument<OnNetworkAttributesRetrievedListener>(1)
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
index 47abaf7..0ae7012 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;
@@ -29,8 +30,8 @@
 import static android.net.dhcp.DhcpResultsParcelableUtil.fromStableParcelable;
 import static android.net.ip.IpReachabilityMonitor.MIN_NUD_SOLICIT_NUM;
 import static android.net.ip.IpReachabilityMonitor.NUD_MCAST_RESOLICIT_NUM;
+import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt;
 import static android.net.ipmemorystore.Status.SUCCESS;
-import static android.net.shared.ProvisioningConfiguration.VERSION_ADDED_PROVISIONING_ENUM;
 import static android.system.OsConstants.ETH_P_IPV6;
 import static android.system.OsConstants.IFA_F_TEMPORARY;
 import static android.system.OsConstants.IPPROTO_ICMPV6;
@@ -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;
 
@@ -71,6 +73,7 @@
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.contains;
 import static org.mockito.ArgumentMatchers.longThat;
 import static org.mockito.Mockito.any;
@@ -124,6 +127,8 @@
 import android.net.ipmemorystore.Status;
 import android.net.networkstack.TestNetworkStackServiceClient;
 import android.net.networkstack.aidl.dhcp.DhcpOption;
+import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable;
+import android.net.networkstack.aidl.ip.ReachabilityLossReason;
 import android.net.shared.Layer2Information;
 import android.net.shared.ProvisioningConfiguration;
 import android.net.shared.ProvisioningConfiguration.ScanResultInfo;
@@ -140,6 +145,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.stats.connectivity.NetworkQuirkEvent;
+import android.stats.connectivity.NudEventType;
 import android.system.ErrnoException;
 import android.system.Os;
 
@@ -155,6 +161,7 @@
 import com.android.net.module.util.structs.LlaOption;
 import com.android.net.module.util.structs.PrefixInformationOption;
 import com.android.net.module.util.structs.RdnssOption;
+import com.android.networkstack.R;
 import com.android.networkstack.apishim.CaptivePortalDataShimImpl;
 import com.android.networkstack.apishim.ConstantsShim;
 import com.android.networkstack.apishim.common.ShimUtils;
@@ -290,7 +297,6 @@
     @Mock protected NetworkStackIpMemoryStore mIpMemoryStore;
     @Mock private NetworkQuirkMetrics.Dependencies mNetworkQuirkMetricsDeps;
     @Mock private IpReachabilityMonitorMetrics mIpReachabilityMonitorMetrics;
-    @Mock protected IpReachabilityMonitor.Callback mCallback;
 
     @Spy private INetd mNetd;
     private NetworkObserverRegistry mNetworkObserverRegistry;
@@ -436,7 +442,7 @@
                 InterfaceParams ifParams, Handler h, SharedLog log,
                 IpReachabilityMonitor.Callback callback, boolean usingMultinetworkPolicyTracker,
                 IpReachabilityMonitor.Dependencies deps, final INetd netd) {
-            return new IpReachabilityMonitor(context, ifParams, h, log, mCallback,
+            return new IpReachabilityMonitor(context, ifParams, h, log, callback,
                     usingMultinetworkPolicyTracker, deps, netd);
         }
 
@@ -540,10 +546,6 @@
 
     protected abstract void assertIpMemoryNeverStoreNetworkAttributes(String l2Key, long timeout);
 
-    protected abstract void assertNotifyNeighborLost(Inet6Address targetIp);
-
-    protected abstract void assertNeverNotifyNeighborLost();
-
     protected final boolean testSkipped() {
         // TODO: split out a test suite for root tests, and fail hard instead of skipping the test
         // if it is run on devices where TestNetworkStackServiceClient is not supported
@@ -592,6 +594,8 @@
         if (useNetworkStackSignature()) {
             setUpMocks();
             setUpIpClient();
+            // Enable packet retransmit alarm in DhcpClient.
+            enableRealAlarm("DhcpClient." + mIfaceName + ".KICK");
         }
 
         mIIpClient = makeIIpClient(mIfaceName, mCb);
@@ -604,10 +608,17 @@
         when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm);
         when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm);
         when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getInteger(eq(R.integer.config_nud_postroaming_solicit_num))).thenReturn(5);
+        when(mResources.getInteger(eq(R.integer.config_nud_postroaming_solicit_interval)))
+                 .thenReturn(750);
+        when(mResources.getInteger(eq(R.integer.config_nud_steadystate_solicit_num)))
+                 .thenReturn(10);
+        when(mResources.getInteger(eq(R.integer.config_nud_steadystate_solicit_interval)))
+                 .thenReturn(750);
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
         when(mNetworkStackServiceManager.getIpMemoryStoreService())
                 .thenReturn(mIpMemoryStoreService);
-        when(mCb.getInterfaceVersion()).thenReturn(VERSION_ADDED_PROVISIONING_ENUM);
+        when(mCb.getInterfaceVersion()).thenReturn(IpClient.VERSION_ADDED_REACHABILITY_FAILURE);
 
         mDependencies.setDeviceConfigProperty(IpClient.CONFIG_MIN_RDNSS_LIFETIME, 67);
         mDependencies.setDeviceConfigProperty(DhcpClient.DHCP_RESTART_CONFIG_DELAY, 10);
@@ -632,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(
@@ -688,6 +691,17 @@
         }
     }
 
+    private void enableRealAlarm(String cmdName) {
+        doAnswer((inv) -> {
+            final Context context = InstrumentationRegistry.getTargetContext();
+            final AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
+            alarmManager.setExact(inv.getArgument(0), inv.getArgument(1), inv.getArgument(2),
+                    inv.getArgument(3), inv.getArgument(4));
+            return null;
+        }).when(mAlarm).setExact(anyInt(), anyLong(), eq(cmdName), any(OnAlarmListener.class),
+                any(Handler.class));
+    }
+
     private IpClient makeIpClient() throws Exception {
         IpClient ipc = new IpClient(mContext, mIfaceName, mCb, mNetworkObserverRegistry,
                 mNetworkStackServiceManager, mDependencies);
@@ -855,10 +869,10 @@
                 captivePortalApiUrl, null /* ipv6OnlyWaitTime */);
     }
 
-    private static ByteBuffer buildDhcpNakPacket(final DhcpPacket packet) {
+    private static ByteBuffer buildDhcpNakPacket(final DhcpPacket packet, final String message) {
         return DhcpPacket.buildNakPacket(DhcpPacket.ENCAP_L2, packet.getTransactionId(),
             SERVER_ADDR /* serverIp */, INADDR_ANY /* relayIp */, packet.getClientMac(),
-            false /* broadcast */, "duplicated request IP address");
+            false /* broadcast */, message);
     }
 
     private void sendArpReply(final byte[] clientMac) throws IOException {
@@ -996,7 +1010,7 @@
                 final ByteBuffer byteBuffer = isSuccessLease
                         ? buildDhcpAckPacket(packet, CLIENT_ADDR, leaseTimeSec, (short) mtu,
                                 false /* rapidCommit */, captivePortalApiUrl)
-                        : buildDhcpNakPacket(packet);
+                        : buildDhcpNakPacket(packet, "duplicated request IP address");
                 mPacketReader.sendResponse(byteBuffer);
             } else {
                 fail("invalid DHCP packet");
@@ -1388,6 +1402,27 @@
         assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime, TEST_DEFAULT_MTU);
     }
 
+    @Test
+    public void testRollbackFromRapidCommitOption() throws Exception {
+        startIpClientProvisioning(false /* isDhcpLeaseCacheEnabled */,
+                true /* isDhcpRapidCommitEnabled */, false /* isPreConnectionEnabled */,
+                false /* isDhcpIpConflictDetectEnabled */, false /* isIPv6OnlyPreferredEnabled */);
+
+        final List<DhcpPacket> discoverList = new ArrayList<DhcpPacket>();
+        DhcpPacket packet;
+        do {
+            packet = getNextDhcpPacket();
+            assertTrue(packet instanceof DhcpDiscoverPacket);
+            discoverList.add(packet);
+        } while (discoverList.size() < 4);
+
+        // Check the only first 3 DHCPDISCOVERs take rapid commit option.
+        assertTrue(discoverList.get(0).mRapidCommit);
+        assertTrue(discoverList.get(1).mRapidCommit);
+        assertTrue(discoverList.get(2).mRapidCommit);
+        assertFalse(discoverList.get(3).mRapidCommit);
+    }
+
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
     public void testDhcpClientStartWithCachedInfiniteLease() throws Exception {
         final DhcpPacket packet = getReplyFromDhcpLease(
@@ -2459,7 +2494,8 @@
     }
 
     private void doDhcpRoamingTest(final boolean hasMismatchedIpAddress, final String displayName,
-            final MacAddress bssid, final boolean expectRoaming) throws Exception {
+            final MacAddress bssid, final boolean expectRoaming,
+            final boolean shouldReplyNakOnRoam) throws Exception {
         long currentTime = System.currentTimeMillis();
         final Layer2Information layer2Info = new Layer2Information(TEST_L2KEY, TEST_CLUSTER, bssid);
 
@@ -2501,21 +2537,37 @@
         assertNull(packet.mRequestedIp);                // requested IP option
         assertNull(packet.mServerIdentifier);           // server ID
 
-        mPacketReader.sendResponse(buildDhcpAckPacket(packet,
-                hasMismatchedIpAddress ? CLIENT_ADDR_NEW : CLIENT_ADDR, TEST_LEASE_DURATION_S,
-                (short) TEST_DEFAULT_MTU, false /* rapidcommit */, null /* captivePortalUrl */));
+        final ByteBuffer packetBuffer = shouldReplyNakOnRoam
+                ? buildDhcpNakPacket(packet, "request IP on a wrong subnet")
+                : buildDhcpAckPacket(packet,
+                        hasMismatchedIpAddress ? CLIENT_ADDR_NEW : CLIENT_ADDR,
+                        TEST_LEASE_DURATION_S, (short) TEST_DEFAULT_MTU,
+                        false /* rapidCommit */, null /* captivePortalApiUrl */);
+        mPacketReader.sendResponse(packetBuffer);
         HandlerUtils.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS);
-        if (hasMismatchedIpAddress) {
-            // notifyFailure
-            ArgumentCaptor<DhcpResultsParcelable> captor =
+
+        if (shouldReplyNakOnRoam) {
+            ArgumentCaptor<ReachabilityLossInfoParcelable> lossInfoCaptor =
+                    ArgumentCaptor.forClass(ReachabilityLossInfoParcelable.class);
+            verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityFailure(lossInfoCaptor.capture());
+            assertEquals(ReachabilityLossReason.ROAM, lossInfoCaptor.getValue().reason);
+
+            // IPv4 address will be still deleted when DhcpClient state machine exits from
+            // DhcpHaveLeaseState, a following onProvisioningFailure will be thrown then.
+            // Also check DhcpClient won't send any DHCPDISCOVER packet.
+            verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningFailure(any());
+            assertNull(getNextDhcpPacket(TEST_TIMEOUT_MS));
+            verify(mCb, never()).onNewDhcpResults(any());
+        } else if (hasMismatchedIpAddress) {
+            ArgumentCaptor<DhcpResultsParcelable> resultsCaptor =
                     ArgumentCaptor.forClass(DhcpResultsParcelable.class);
-            verify(mCb, timeout(TEST_TIMEOUT_MS)).onNewDhcpResults(captor.capture());
-            DhcpResults lease = fromStableParcelable(captor.getValue());
+            verify(mCb, timeout(TEST_TIMEOUT_MS)).onNewDhcpResults(resultsCaptor.capture());
+            DhcpResults lease = fromStableParcelable(resultsCaptor.getValue());
             assertNull(lease);
 
-            // roll back to INIT state.
-            packet = getNextDhcpPacket();
-            assertTrue(packet instanceof DhcpDiscoverPacket);
+            // DhcpClient rolls back to StoppedState instead of INIT state after calling
+            // notifyFailure, DHCPDISCOVER should not be sent out.
+            assertNull(getNextDhcpPacket(TEST_TIMEOUT_MS));
         } else {
             assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime,
                     TEST_DEFAULT_MTU);
@@ -2525,31 +2577,42 @@
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
     public void testDhcpRoaming() throws Exception {
         doDhcpRoamingTest(false /* hasMismatchedIpAddress */, "\"0001docomo\"" /* display name */,
-                MacAddress.fromString(TEST_DEFAULT_BSSID), true /* expectRoaming */);
+                MacAddress.fromString(TEST_DEFAULT_BSSID), true /* expectRoaming */,
+                false /* shouldReplyNakOnRoam */);
     }
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
     public void testDhcpRoaming_invalidBssid() throws Exception {
         doDhcpRoamingTest(false /* hasMismatchedIpAddress */, "\"0001docomo\"" /* display name */,
-                MacAddress.fromString(TEST_DHCP_ROAM_BSSID), false /* expectRoaming */);
+                MacAddress.fromString(TEST_DHCP_ROAM_BSSID), false /* expectRoaming */,
+                false/* shouldReplyNakOnRoam */);
     }
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
     public void testDhcpRoaming_nullBssid() throws Exception {
         doDhcpRoamingTest(false /* hasMismatchedIpAddress */, "\"0001docomo\"" /* display name */,
-                null /* BSSID */, false /* expectRoaming */);
+                null /* BSSID */, false /* expectRoaming */, false /* shouldReplyNakOnRoam */);
     }
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
     public void testDhcpRoaming_invalidDisplayName() throws Exception {
         doDhcpRoamingTest(false /* hasMismatchedIpAddress */, "\"test-ssid\"" /* display name */,
-                MacAddress.fromString(TEST_DEFAULT_BSSID), false /* expectRoaming */);
+                MacAddress.fromString(TEST_DEFAULT_BSSID), false /* expectRoaming */,
+                false /* shouldReplyNakOnRoam */);
     }
 
     @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
     public void testDhcpRoaming_mismatchedLeasedIpAddress() throws Exception {
         doDhcpRoamingTest(true /* hasMismatchedIpAddress */, "\"0001docomo\"" /* display name */,
-                MacAddress.fromString(TEST_DEFAULT_BSSID), true /* expectRoaming */);
+                MacAddress.fromString(TEST_DEFAULT_BSSID), true /* expectRoaming */,
+                false /* shouldReplyNakOnRoam */);
+    }
+
+    @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")
+    public void testDhcpRoaming_failureLeaseOnNak() throws Exception {
+        doDhcpRoamingTest(false /* hasMismatchedIpAddress */, "\"0001docomo\"" /* display name */,
+                MacAddress.fromString(TEST_DEFAULT_BSSID), true /* expectRoaming */,
+                true /* shouldReplyNakOnRoam */);
     }
 
     private void performDualStackProvisioning() throws Exception {
@@ -3407,6 +3470,38 @@
         prepareIpReachabilityMonitorTest(false /* isMulticastResolicitEnabled */);
     }
 
+    private void assertNotifyNeighborLost(Inet6Address targetIp, NudEventType eventType)
+            throws Exception {
+        // For root test suite, rely on the IIpClient aidl interface version constant defined in
+        // {@link IpClientRootTest.BinderCbWrapper}; for privileged integration test suite that
+        // requires signature permission, use the mocked aidl version defined in {@link setUpMocks},
+        // which results in only new callbacks are verified. And add separate test cases to test the
+        // legacy callbacks explicitly as well.
+        assertNeighborReachabilityLoss(targetIp, eventType,
+                useNetworkStackSignature()
+                        ? IpClient.VERSION_ADDED_REACHABILITY_FAILURE
+                        : mIIpClient.getInterfaceVersion());
+    }
+
+    private void assertNeighborReachabilityLoss(Inet6Address targetIp, NudEventType eventType,
+            int targetAidlVersion) throws Exception {
+        if (targetAidlVersion >= IpClient.VERSION_ADDED_REACHABILITY_FAILURE) {
+            final ArgumentCaptor<ReachabilityLossInfoParcelable> lossInfoCaptor =
+                    ArgumentCaptor.forClass(ReachabilityLossInfoParcelable.class);
+            verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityFailure(lossInfoCaptor.capture());
+            assertEquals(nudEventTypeToInt(eventType), lossInfoCaptor.getValue().reason);
+            verify(mCb, never()).onReachabilityLost(any());
+        } else {
+            verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(any());
+            verify(mCb, never()).onReachabilityFailure(any());
+        }
+    }
+
+    private void assertNeverNotifyNeighborLost() throws Exception {
+        verify(mCb, never()).onReachabilityFailure(any());
+        verify(mCb, never()).onReachabilityLost(any());
+    }
+
     private void prepareIpReachabilityMonitorTest(boolean isMulticastResolicitEnabled)
             throws Exception {
         final ScanResultInfo info = makeScanResultInfo(TEST_DEFAULT_SSID, TEST_DEFAULT_BSSID);
@@ -3427,8 +3522,7 @@
         forceLayer2Roaming();
     }
 
-    @Test
-    public void testIpReachabilityMonitor_probeFailed() throws Exception {
+    private void runIpReachabilityMonitorProbeFailedTest() throws Exception {
         prepareIpReachabilityMonitorTest();
 
         final List<NeighborSolicitation> nsList = waitForMultipleNeighborSolicitations();
@@ -3437,7 +3531,22 @@
             assertUnicastNeighborSolicitation(ns, ROUTER_MAC /* dstMac */,
                     ROUTER_LINK_LOCAL /* dstIp */, ROUTER_LINK_LOCAL /* targetIp */);
         }
-        assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */);
+    }
+
+    @Test
+    public void testIpReachabilityMonitor_probeFailed() throws Exception {
+        runIpReachabilityMonitorProbeFailedTest();
+        assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */,
+                NudEventType.NUD_POST_ROAMING_FAILED_CRITICAL);
+    }
+
+    @Test @SignatureRequiredTest(reason = "requires mock callback object")
+    public void testIpReachabilityMonitor_probeFailed_legacyCallback() throws Exception {
+        when(mCb.getInterfaceVersion()).thenReturn(12 /* assign an older interface aidl version */);
+
+        runIpReachabilityMonitorProbeFailedTest();
+        verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(any());
+        verify(mCb, never()).onReachabilityFailure(any());
     }
 
     @Test
@@ -3456,8 +3565,7 @@
         assertNeverNotifyNeighborLost();
     }
 
-    @Test
-    public void testIpReachabilityMonitor_mcastResoclicitProbeFailed() throws Exception {
+    private void runIpReachabilityMonitorMcastResolicitProbeFailedTest() throws Exception {
         prepareIpReachabilityMonitorTest(true /* isMulticastResolicitEnabled */);
 
         final List<NeighborSolicitation> nsList = waitForMultipleNeighborSolicitations();
@@ -3470,11 +3578,27 @@
         for (NeighborSolicitation ns : nsList.subList(MIN_NUD_SOLICIT_NUM, nsList.size())) {
             assertMulticastNeighborSolicitation(ns, ROUTER_LINK_LOCAL /* targetIp */);
         }
-        assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */);
     }
 
     @Test
-    public void testIpReachabilityMonitor_mcastResoclicitProbeReachableWithSameLinkLayerAddress()
+    public void testIpReachabilityMonitor_mcastResolicitProbeFailed() throws Exception {
+        runIpReachabilityMonitorMcastResolicitProbeFailedTest();
+        assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */,
+                NudEventType.NUD_POST_ROAMING_FAILED_CRITICAL);
+    }
+
+    @Test @SignatureRequiredTest(reason = "requires mock callback object")
+    public void testIpReachabilityMonitor_mcastResolicitProbeFailed_legacyCallback()
+            throws Exception {
+        when(mCb.getInterfaceVersion()).thenReturn(12 /* assign an older interface aidl version */);
+
+        runIpReachabilityMonitorMcastResolicitProbeFailedTest();
+        verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(any());
+        verify(mCb, never()).onReachabilityFailure(any());
+    }
+
+    @Test
+    public void testIpReachabilityMonitor_mcastResolicitProbeReachableWithSameLinkLayerAddress()
             throws Exception {
         prepareIpReachabilityMonitorTest(true /* isMulticastResolicitEnabled */);
 
@@ -3491,7 +3615,7 @@
     }
 
     @Test
-    public void testIpReachabilityMonitor_mcastResoclicitProbeReachableWithDiffLinkLayerAddress()
+    public void testIpReachabilityMonitor_mcastResolicitProbeReachableWithDiffLinkLayerAddress()
             throws Exception {
         prepareIpReachabilityMonitorTest(true /* isMulticastResolicitEnabled */);
 
@@ -3510,7 +3634,8 @@
                 ns.ethHdr.srcMac /* dstMac */, ROUTER_LINK_LOCAL /* srcIp */,
                 ns.ipv6Hdr.srcIp /* dstIp */, flag, ROUTER_LINK_LOCAL /* target */);
         mPacketReader.sendResponse(na);
-        assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */);
+        assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */,
+                NudEventType.NUD_POST_ROAMING_MAC_ADDRESS_CHANGED);
     }
 
     @Test
diff --git a/tests/integration/src/android/net/ip/IpClientRootTest.kt b/tests/integration/src/android/net/ip/IpClientRootTest.kt
index d861639..7359e05 100644
--- a/tests/integration/src/android/net/ip/IpClientRootTest.kt
+++ b/tests/integration/src/android/net/ip/IpClientRootTest.kt
@@ -33,7 +33,6 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.net.module.util.DeviceConfigUtils
 import java.lang.System.currentTimeMillis
-import java.net.Inet6Address
 import java.util.concurrent.CompletableFuture
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
@@ -46,8 +45,6 @@
 import org.junit.AfterClass
 import org.junit.BeforeClass
 import org.mockito.ArgumentCaptor
-import org.mockito.Mockito.anyString
-import org.mockito.Mockito.never
 import org.mockito.Mockito.timeout
 import org.mockito.Mockito.verify
 
@@ -265,14 +262,6 @@
         assertNull(listener.getBlockingNetworkAttributes(timeout))
     }
 
-    override fun assertNotifyNeighborLost(targetIp: Inet6Address) {
-        verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(anyString())
-    }
-
-    override fun assertNeverNotifyNeighborLost() {
-        verify(mCb, never()).onReachabilityLost(anyString())
-    }
-
     override fun storeNetworkAttributes(l2Key: String, na: NetworkAttributes) {
         mStore.storeNetworkAttributes(l2Key, na, null /* listener */)
     }
diff --git a/tests/integration/src/android/net/networkstack/TestNetworkStackServiceClient.kt b/tests/integration/src/android/net/networkstack/TestNetworkStackServiceClient.kt
index bc3e5e0..47936ac 100644
--- a/tests/integration/src/android/net/networkstack/TestNetworkStackServiceClient.kt
+++ b/tests/integration/src/android/net/networkstack/TestNetworkStackServiceClient.kt
@@ -33,7 +33,7 @@
     companion object {
         private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
         private val networkStackVersion by lazy {
-            val component = getNetworkStackComponent()
+            val component = getNetworkStackComponent(INetworkStackConnector::class.java.name)
             val info = context.packageManager.getPackageInfo(component.packageName, 0 /* flags */)
             info.longVersionCode
         }
@@ -54,8 +54,8 @@
             return networkStackVersion == 300000000L || networkStackVersion >= 301100000L
         }
 
-        private fun getNetworkStackComponent(): ComponentName {
-            val connectorIntent = Intent(INetworkStackConnector::class.java.name)
+        private fun getNetworkStackComponent(connectorAction: String): ComponentName {
+            val connectorIntent = Intent(connectorAction)
             return connectorIntent.resolveSystemService(context.packageManager, MATCH_SYSTEM_ONLY)
                     ?: fail("TestNetworkStackService not found")
         }
@@ -71,7 +71,7 @@
 
     private fun init() {
         val bindIntent = Intent(INetworkStackConnector::class.java.name + ".Test")
-        bindIntent.component = getNetworkStackComponent()
+        bindIntent.component = getNetworkStackComponent(bindIntent.action)
         context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE)
     }
 
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index fa054fe..7bb0d48 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -47,6 +47,7 @@
         "libnetworkstackutilsjni",
     ],
     jni_uses_sdk_apis: true,
+    exclude_kotlinc_generated_files: false,
 }
 
 // Tests for NetworkStackNext.
@@ -56,8 +57,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"],
+    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 +87,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/dhcp/DhcpLeaseRepositoryTest.java b/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
index 7b0af69..b9b1652 100644
--- a/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
+++ b/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
@@ -45,6 +45,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.net.IpPrefix;
 import android.net.MacAddress;
 import android.net.dhcp.DhcpServer.Clock;
@@ -84,6 +85,7 @@
     private static final Inet4Address TEST_INETADDR_2 = parseAddr4("192.168.42.249");
     private static final String TEST_HOSTNAME_1 = "hostname1";
     private static final String TEST_HOSTNAME_2 = "hostname2";
+    @SuppressLint("NewApi")
     private static final IpPrefix TEST_IP_PREFIX = new IpPrefix(TEST_SERVER_ADDR, 22);
     private static final long TEST_TIME = 100L;
     private static final int TEST_LEASE_TIME_MS = 3_600_000;
@@ -149,6 +151,7 @@
         }
     }
 
+    @SuppressLint("NewApi")
     @Test
     public void testAddressExhaustion() throws Exception {
         // Use a /28 to quickly run out of addresses
@@ -169,6 +172,7 @@
         verifyNoMoreInteractions(mCallbacks);
     }
 
+    @SuppressLint("NewApi")
     @Test
     public void testUpdateParams_LeaseCleanup() throws Exception {
         // Inside /28:
@@ -229,6 +233,7 @@
         }
     }
 
+    @SuppressLint("NewApi")
     @Test
     public void testUpdateParams_UsesNewPrefix() throws Exception {
         final IpPrefix newPrefix = new IpPrefix(parseAddr4("192.168.123.0"), 24);
@@ -538,6 +543,7 @@
         assertNotEquals(lease.getNetAddr(), newLease.getNetAddr());
     }
 
+    @SuppressLint("NewApi")
     @Test
     public void testMarkLeaseDeclined_UsedIfOutOfAddresses() throws Exception {
         // Use a /28 to quickly run out of addresses
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java
index 173a9e1..37f12ca 100644
--- a/tests/unit/src/android/net/ip/IpClientTest.java
+++ b/tests/unit/src/android/net/ip/IpClientTest.java
@@ -40,6 +40,7 @@
 
 import static java.util.Collections.emptySet;
 
+import android.annotation.SuppressLint;
 import android.app.AlarmManager;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -296,6 +297,7 @@
         return ipc;
     }
 
+    @SuppressLint("NewApi")
     private void addIPv4Provisioning(LinkProperties lp) {
         final LinkAddress la = new LinkAddress(TEST_IPV4_LINKADDRESS);
         final RouteInfo defaultRoute = new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
@@ -625,6 +627,7 @@
                 TEST_IFNAME));
     }
 
+    @SuppressLint("NewApi")
     static RouteInfo defaultIPV6Route(String gateway) {
         return new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
                 InetAddresses.parseNumericAddress(gateway), TEST_IFNAME);
diff --git a/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt b/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
index ea8f1da..0109022 100644
--- a/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
+++ b/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
@@ -15,6 +15,7 @@
  */
 package android.net.ip
 
+import android.annotation.SuppressLint
 import android.content.Context
 import android.net.ip.IpNeighborMonitor.NeighborEventConsumer
 import android.net.INetd
@@ -37,11 +38,13 @@
 import android.stats.connectivity.NudEventType
 import android.stats.connectivity.NudEventType.NUD_CONFIRM_FAILED
 import android.stats.connectivity.NudEventType.NUD_CONFIRM_FAILED_CRITICAL
-import android.stats.connectivity.NudEventType.NUD_MAC_ADDRESS_CHANGED
+import android.stats.connectivity.NudEventType.NUD_CONFIRM_MAC_ADDRESS_CHANGED
 import android.stats.connectivity.NudEventType.NUD_POST_ROAMING_FAILED
 import android.stats.connectivity.NudEventType.NUD_POST_ROAMING_FAILED_CRITICAL
+import android.stats.connectivity.NudEventType.NUD_POST_ROAMING_MAC_ADDRESS_CHANGED
 import android.stats.connectivity.NudEventType.NUD_ORGANIC_FAILED
 import android.stats.connectivity.NudEventType.NUD_ORGANIC_FAILED_CRITICAL
+import android.stats.connectivity.NudEventType.NUD_ORGANIC_MAC_ADDRESS_CHANGED
 import android.stats.connectivity.NudNeighborType
 import android.stats.connectivity.NudNeighborType.NUD_NEIGHBOR_BOTH
 import android.stats.connectivity.NudNeighborType.NUD_NEIGHBOR_DNS
@@ -104,6 +107,8 @@
 private val TEST_IPV6_DNS2 = parseNumericAddress("2001:db8::456") as Inet6Address
 
 private val TEST_IFACE = InterfaceParams("fake0", 21, null)
+
+@SuppressLint("NewApi")
 private val TEST_LINK_PROPERTIES = LinkProperties().apply {
     interfaceName = TEST_IFACE.name
     addLinkAddress(TEST_IPV4_LINKADDR)
@@ -121,6 +126,7 @@
     addDnsServer(TEST_IPV6_DNS)
 }
 
+@SuppressLint("NewApi")
 private val TEST_IPV4_ONLY_LINK_PROPERTIES = LinkProperties().apply {
     interfaceName = TEST_IFACE.name
     addLinkAddress(TEST_IPV4_LINKADDR)
@@ -134,6 +140,7 @@
     addDnsServer(TEST_IPV4_GATEWAY_DNS)
 }
 
+@SuppressLint("NewApi")
 private val TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES = LinkProperties().apply {
     interfaceName = TEST_IFACE.name
     addLinkAddress(TEST_IPV6_LINKADDR)
@@ -149,6 +156,7 @@
     addDnsServer(TEST_IPV6_DNS)
 }
 
+@SuppressLint("NewApi")
 private val TEST_DUAL_LINK_PROPERTIES = LinkProperties().apply {
     interfaceName = TEST_IFACE.name
     addLinkAddress(TEST_IPV4_LINKADDR)
@@ -285,10 +293,15 @@
         reachabilityMonitor.updateLinkProperties(TEST_LINK_PROPERTIES)
 
         neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_FAILED))
-        verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(TEST_IPV4_DNS), anyString())
+        verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(TEST_IPV4_DNS), anyString(),
+                eq(NUD_ORGANIC_FAILED_CRITICAL))
     }
 
-    private fun runLoseProvisioningTest(newLp: LinkProperties, lostNeighbor: InetAddress) {
+    private fun runLoseProvisioningTest(
+        newLp: LinkProperties,
+        lostNeighbor: InetAddress,
+        eventType: NudEventType
+    ) {
         reachabilityMonitor.updateLinkProperties(newLp)
 
         neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_STALE))
@@ -297,7 +310,8 @@
         neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_STALE))
 
         neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED))
-        verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(lostNeighbor), anyString())
+        verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(lostNeighbor), anyString(),
+                eq(eventType))
     }
 
     private fun verifyNudFailureMetrics(
@@ -325,14 +339,13 @@
 
         neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED))
         handlerThread.waitForIdle(TEST_TIMEOUT_MS)
-        verify(callback, never()).notifyLost(any(), anyString())
+        verify(callback, never()).notifyLost(any(), anyString(), any(NudEventType::class.java))
         verifyNudFailureMetrics(eventType, ipType, lostNeighborType)
     }
 
-    private fun runNeighborReachableButMacAddrChangedTest(
+    private fun prepareNeighborReachableButMacAddrChangedTest(
         newLp: LinkProperties,
-        neighbor: InetAddress,
-        ipType: IpType
+        neighbor: InetAddress
     ) {
         doReturn(true).`when`(dependencies).isFeatureEnabled(anyObject(),
                 eq(IP_REACHABILITY_MCAST_RESOLICIT_VERSION), anyBoolean())
@@ -342,34 +355,30 @@
         neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE,
                 "001122334455" /* oldMac */))
         handlerThread.waitForIdle(TEST_TIMEOUT_MS)
-        verify(callback, never()).notifyLost(eq(neighbor), anyString())
-
-        reachabilityMonitor.probeAll(true /* dueToRoam */)
-
-        neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE,
-                "1122334455aa" /* newMac */))
-        verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(neighbor), anyString())
-        verifyNudFailureMetrics(NUD_MAC_ADDRESS_CHANGED, ipType, NUD_NEIGHBOR_GATEWAY)
+        verify(callback, never()).notifyLost(eq(neighbor), anyString(),
+                any(NudEventType::class.java))
     }
 
     @Test
     fun testLoseProvisioning_Ipv4DnsLost() {
-        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS)
+        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS, NUD_ORGANIC_FAILED_CRITICAL)
     }
 
     @Test
     fun testLoseProvisioning_Ipv6DnsLost() {
-        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS)
+        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS, NUD_ORGANIC_FAILED_CRITICAL)
     }
 
     @Test
     fun testLoseProvisioning_Ipv4GatewayLost() {
-        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY)
+        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY,
+                NUD_ORGANIC_FAILED_CRITICAL)
     }
 
     @Test
     fun testLoseProvisioning_Ipv6GatewayLost() {
-        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
+        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
+                NUD_ORGANIC_FAILED_CRITICAL)
     }
 
     private fun runNudProbeFailureMetricsTest(
@@ -379,7 +388,7 @@
         ipType: IpType,
         lostNeighborType: NudNeighborType
     ) {
-        runLoseProvisioningTest(lp, lostNeighbor)
+        runLoseProvisioningTest(lp, lostNeighbor, eventType)
         verifyNudFailureMetrics(eventType, ipType, lostNeighborType)
     }
 
@@ -532,7 +541,8 @@
         handlerThread.waitForIdle(TEST_TIMEOUT_MS)
         Thread.sleep(2)
         reachabilityMonitor.probeAll(false /* dueToRoam */)
-        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
+        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
+                NUD_POST_ROAMING_FAILED_CRITICAL)
 
         verifyNudFailureMetrics(NUD_POST_ROAMING_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
     }
@@ -543,18 +553,52 @@
         handlerThread.waitForIdle(TEST_TIMEOUT_MS)
         Thread.sleep(2)
         reachabilityMonitor.probeAll(true /* dueToRoam */)
-        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
+        runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
+                NUD_CONFIRM_FAILED_CRITICAL)
 
         verifyNudFailureMetrics(NUD_CONFIRM_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
     }
 
-    @Test
-    fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChanged() {
-        runNeighborReachableButMacAddrChangedTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY, IPV6)
+    private fun verifyNudMacAddrChangedType(
+        neighbor: InetAddress,
+        eventType: NudEventType,
+        ipType: IpType
+    ) {
+        neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE,
+                "1122334455aa" /* newMac */))
+        verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(neighbor), anyString(),
+                eq(eventType))
+        verifyNudFailureMetrics(eventType, ipType, NUD_NEIGHBOR_GATEWAY)
     }
 
     @Test
-    fun testNudProbeFailedMetrics_defaultIPv4GatewayMacAddrChanged() {
-        runNeighborReachableButMacAddrChangedTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY, IPV4)
+    fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterRoaming() {
+        prepareNeighborReachableButMacAddrChangedTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
+
+        reachabilityMonitor.probeAll(true /* dueToRoam */)
+        verifyNudMacAddrChangedType(TEST_IPV6_GATEWAY, NUD_POST_ROAMING_MAC_ADDRESS_CHANGED, IPV6)
+    }
+
+    @Test
+    fun testNudProbeFailedMetrics_defaultIPv4GatewayMacAddrChangedAfterRoaming() {
+        prepareNeighborReachableButMacAddrChangedTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY)
+
+        reachabilityMonitor.probeAll(true /* dueToRoam */)
+        verifyNudMacAddrChangedType(TEST_IPV4_GATEWAY, NUD_POST_ROAMING_MAC_ADDRESS_CHANGED, IPV4)
+    }
+
+    @Test
+    fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterConfirm() {
+        prepareNeighborReachableButMacAddrChangedTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
+
+        reachabilityMonitor.probeAll(false /* dueToRoam */)
+        verifyNudMacAddrChangedType(TEST_IPV6_GATEWAY, NUD_CONFIRM_MAC_ADDRESS_CHANGED, IPV6)
+    }
+
+    @Test
+    fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterOrganic() {
+        prepareNeighborReachableButMacAddrChangedTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
+
+        verifyNudMacAddrChangedType(TEST_IPV6_GATEWAY, NUD_ORGANIC_MAC_ADDRESS_CHANGED, IPV6)
     }
 }
diff --git a/tests/unit/src/android/net/shared/InitialConfigurationTest.java b/tests/unit/src/android/net/shared/InitialConfigurationTest.java
index 4d5a7df..0ec0053 100644
--- a/tests/unit/src/android/net/shared/InitialConfigurationTest.java
+++ b/tests/unit/src/android/net/shared/InitialConfigurationTest.java
@@ -23,6 +23,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 
+import android.annotation.SuppressLint;
 import android.net.IpPrefix;
 import android.net.LinkAddress;
 
@@ -44,6 +45,7 @@
 public class InitialConfigurationTest {
     private InitialConfiguration mConfig;
 
+    @SuppressLint("NewApi")
     @Before
     public void setUp() {
         mConfig = new InitialConfiguration();
@@ -67,6 +69,7 @@
         assertEquals(mConfig, unparceled);
     }
 
+    @SuppressLint("NewApi")
     @Test
     public void testEquals() {
         assertEquals(mConfig, InitialConfiguration.copy(mConfig));
diff --git a/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java b/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java
index 198ac99..457f0c3 100644
--- a/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java
+++ b/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java
@@ -24,7 +24,6 @@
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 import static com.android.net.module.util.netlink.NetlinkConstants.SOCKDIAG_MSG_HEADER_SIZE;
 
 import static junit.framework.Assert.assertEquals;
@@ -52,7 +51,6 @@
 
 import com.android.net.module.util.netlink.StructNlMsgHdr;
 import com.android.networkstack.apishim.ConstantsShim;
-import com.android.networkstack.apishim.NetworkShimImpl;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -66,8 +64,6 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
 
 import java.io.FileDescriptor;
 import java.nio.ByteBuffer;
@@ -210,7 +206,6 @@
     @Mock private INetd mNetd;
     private final Network mNetwork = new Network(TEST_NETID1);
     private final Network mOtherNetwork = new Network(TEST_NETID2);
-    private MockitoSession mSession;
     private TerribleFailureHandler mOldWtfHandler;
 
     @Rule
@@ -230,10 +225,6 @@
                 eq(NAMESPACE_CONNECTIVITY),
                 eq(CONFIG_TCP_PACKETS_FAIL_PERCENTAGE),
                 anyInt())).thenReturn(DEFAULT_TCP_PACKETS_FAIL_PERCENTAGE);
-        mSession = mockitoSession()
-                .spyStatic(NetworkShimImpl.class)
-                .strictness(Strictness.WARN)
-                .startMocking();
 
         when(mNetd.getFwmarkForNetwork(eq(TEST_NETID1)))
                 .thenReturn(makeMarkMaskParcel(NETID_MASK, TEST_NETID1_FWMARK));
@@ -241,7 +232,6 @@
 
     @After
     public void tearDown() {
-        mSession.finishMocking();
         Log.setWtfHandler(mOldWtfHandler);
     }
 
diff --git a/tests/unit/src/com/android/server/NetworkStackServiceTest.kt b/tests/unit/src/com/android/server/NetworkStackServiceTest.kt
index cf65cd7..40abe9e 100644
--- a/tests/unit/src/com/android/server/NetworkStackServiceTest.kt
+++ b/tests/unit/src/com/android/server/NetworkStackServiceTest.kt
@@ -29,6 +29,7 @@
 import android.net.dhcp.IDhcpServerCallbacks
 import android.net.ip.IIpClientCallbacks
 import android.net.ip.IpClient
+import android.os.Binder
 import android.os.Build
 import android.os.IBinder
 import android.os.Process
@@ -48,6 +49,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.eq
 import org.mockito.Mockito.mock
@@ -170,11 +172,14 @@
         // Call makeNetworkMonitor
         // Use a spy of INetworkMonitorCallbacks and not a mock, as mockito can't create a mock on Q
         // because of the missing CaptivePortalData class that is an argument of one of the methods
-        val mockNetworkMonitorCb = spy(INetworkMonitorCallbacks.Stub.asInterface(
-                mock(IBinder::class.java)))
+        val mockBinder = mock(IBinder::class.java)
+        val mockNetworkMonitorCb = spy(INetworkMonitorCallbacks.Stub.asInterface(mockBinder))
         doReturn(9990003).`when`(mockNetworkMonitorCb).interfaceVersion
         doReturn("networkmonitor_hash").`when`(mockNetworkMonitorCb).interfaceHash
-        INetworkMonitorCallbacks.Stub.setDefaultImpl(INetworkMonitorCallbacks.Default())
+        // Oneway transactions are always successful (return true). INetworkMonitorCallbacks is a
+        // oneway interface. This avoids the stub throwing because the method is not implemented by
+        // the (mock) remote.
+        doReturn(true).`when`(mockBinder).transact(anyInt(), any(), any(), eq(Binder.FLAG_ONEWAY))
 
         connector.makeNetworkMonitor(Network(123), "test_nm", mockNetworkMonitorCb)
 
diff --git a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
index ff43325..8099725 100644
--- a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -555,6 +555,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));