diff --git a/Cronet/tests/mts/Android.bp b/Cronet/tests/mts/Android.bp
index 03d163c..ac71653 100644
--- a/Cronet/tests/mts/Android.bp
+++ b/Cronet/tests/mts/Android.bp
@@ -19,7 +19,7 @@
 
 android_library {
     name: "NetHttpTestsLibPreJarJar",
-    srcs: [":cronet_aml_javatests_sources"],
+    srcs: ["//external/cronet:cronet_aml_javatests_sources"],
     sdk_version: "test_current",
     min_sdk_version: "30",
     static_libs: [
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index d2f6d15..8810a8c 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -61,9 +61,13 @@
         "modules-utils-build",
         "modules-utils-statemachine",
         "networkstack-client",
+        // AIDL tetheroffload implementation
+        "android.hardware.tetheroffload-V1-java",
+        // HIDL tetheroffload implementation
         "android.hardware.tetheroffload.config-V1.0-java",
         "android.hardware.tetheroffload.control-V1.0-java",
         "android.hardware.tetheroffload.control-V1.1-java",
+        "android.hidl.manager-V1.2-java",
         "net-utils-framework-common",
         "net-utils-device-common",
         "net-utils-device-common-bpf",
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 67206cd..ff5acf5 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -66,11 +66,19 @@
 
 apex_defaults {
     name: "CronetInTetheringApexDefaultsEnabled",
-    jni_libs: ["cronet_aml_components_cronet_android_cronet"],
+    jni_libs: [
+        "//external/cronet:cronet_aml_components_cronet_android_cronet",
+        "//external/cronet/third_party/boringssl:libcrypto",
+        "//external/cronet/third_party/boringssl:libssl",
+    ],
     arch: {
         riscv64: {
             // TODO: remove this when there is a riscv64 libcronet
-            exclude_jni_libs: ["cronet_aml_components_cronet_android_cronet"],
+            exclude_jni_libs: [
+                "//external/cronet:cronet_aml_components_cronet_android_cronet",
+                "//external/cronet/third_party/boringssl:libcrypto",
+                "//external/cronet/third_party/boringssl:libssl",
+            ],
         },
     },
 }
diff --git a/Tethering/common/TetheringLib/Android.bp b/Tethering/common/TetheringLib/Android.bp
index 4f95bdd..a3756e0 100644
--- a/Tethering/common/TetheringLib/Android.bp
+++ b/Tethering/common/TetheringLib/Android.bp
@@ -75,12 +75,12 @@
 
 java_defaults {
     name: "CronetJavaDefaultsEnabled",
-    srcs: [":cronet_aml_api_sources"],
+    srcs: ["//external/cronet:cronet_aml_api_sources"],
     libs: [
         "androidx.annotation_annotation",
     ],
     impl_only_static_libs: [
-        "cronet_aml_java",
+        "//external/cronet:cronet_aml_java",
     ],
     api_dir: "cronet_enabled/api",
 }
@@ -101,8 +101,8 @@
 java_defaults {
   name: "CronetJavaPrejarjarDefaultsEnabled",
   static_libs: [
-    "cronet_aml_api_java",
-    "cronet_aml_java"
+    "//external/cronet:cronet_aml_api_java",
+    "//external/cronet:cronet_aml_java"
   ],
 }
 
diff --git a/Tethering/src/com/android/networkstack/tethering/IOffloadHal.java b/Tethering/src/com/android/networkstack/tethering/IOffloadHal.java
new file mode 100644
index 0000000..e66e7ae
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/IOffloadHal.java
@@ -0,0 +1,64 @@
+/*
+ * 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.tethering;
+
+import android.annotation.NonNull;
+import android.os.NativeHandle;
+
+import com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
+import com.android.networkstack.tethering.OffloadHardwareInterface.OffloadHalCallback;
+
+import java.util.ArrayList;
+
+/** Abstraction of Tetheroffload HAL interface */
+interface IOffloadHal {
+    /*
+     * Initialize the Tetheroffload HAL. Offload management process need to know conntrack rules to
+     * support NAT, but it may not have permission to create netlink netfilter sockets. Create two
+     * netlink netfilter sockets and share them with offload management process.
+     */
+    boolean initOffload(@NonNull NativeHandle handle1, @NonNull NativeHandle handle2,
+            @NonNull OffloadHalCallback callback);
+
+    /** Stop the Tetheroffload HAL. */
+    boolean stopOffload();
+
+    /** Get HAL interface version number. */
+    int getVersion();
+
+    /** Get Tx/Rx usage from last query. */
+    ForwardedStats getForwardedStats(@NonNull String upstream);
+
+    /** Set local prefixes to offload management process. */
+    boolean setLocalPrefixes(@NonNull ArrayList<String> localPrefixes);
+
+    /** Set data limit value to offload management process. */
+    boolean setDataLimit(@NonNull String iface, long limit);
+
+    /** Set data warning and limit value to offload management process. */
+    boolean setDataWarningAndLimit(@NonNull String iface, long warning, long limit);
+
+    /** Set upstream parameters to offload management process. */
+    boolean setUpstreamParameters(@NonNull String iface, @NonNull String v4addr,
+            @NonNull String v4gateway, @NonNull ArrayList<String> v6gws);
+
+    /** Add downstream prefix to offload management process. */
+    boolean addDownstream(@NonNull String ifname, @NonNull String prefix);
+
+    /** Remove downstream prefix from offload management process. */
+    boolean removeDownstream(@NonNull String ifname, @NonNull String prefix);
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadController.java b/Tethering/src/com/android/networkstack/tethering/OffloadController.java
index d2f177d..5fa6b2d 100644
--- a/Tethering/src/com/android/networkstack/tethering/OffloadController.java
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadController.java
@@ -26,8 +26,8 @@
 import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
 import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
 
-import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0;
-import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_1;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_0;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_1;
 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE;
 import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
 
@@ -98,9 +98,8 @@
     private final OffloadTetheringStatsProvider mStatsProvider;
     private final SharedLog mLog;
     private final HashMap<String, LinkProperties> mDownstreams;
-    private boolean mConfigInitialized;
     @OffloadHardwareInterface.OffloadHalVersion
-    private int mControlHalVersion;
+    private int mOffloadHalVersion;
     private LinkProperties mUpstreamLinkProperties;
     // The complete set of offload-exempt prefixes passed in via Tethering from
     // all upstream and downstream sources.
@@ -205,20 +204,11 @@
             return false;
         }
 
-        if (!mConfigInitialized) {
-            mConfigInitialized = mHwInterface.initOffloadConfig();
-            if (!mConfigInitialized) {
-                mLog.i("tethering offload config not supported");
-                stop();
-                return false;
-            }
-        }
-
-        mControlHalVersion = mHwInterface.initOffloadControl(
+        mOffloadHalVersion = mHwInterface.initOffload(
                 // OffloadHardwareInterface guarantees that these callback
                 // methods are called on the handler passed to it, which is the
                 // same as mHandler, as coordinated by the setup in Tethering.
-                new OffloadHardwareInterface.ControlCallback() {
+                new OffloadHardwareInterface.OffloadHalCallback() {
                     @Override
                     public void onStarted() {
                         if (!started()) return;
@@ -305,11 +295,11 @@
 
         final boolean isStarted = started();
         if (!isStarted) {
-            mLog.i("tethering offload control not supported");
+            mLog.i("tethering offload not supported");
             stop();
         } else {
             mLog.log("tethering offload started, version: "
-                    + OffloadHardwareInterface.halVerToString(mControlHalVersion));
+                    + OffloadHardwareInterface.halVerToString(mOffloadHalVersion));
             mNatUpdateCallbacksReceived = 0;
             mNatUpdateNetlinkErrors = 0;
             maybeSchedulePollingStats();
@@ -325,9 +315,8 @@
         final boolean wasStarted = started();
         updateStatsForCurrentUpstream();
         mUpstreamLinkProperties = null;
-        mHwInterface.stopOffloadControl();
-        mControlHalVersion = OFFLOAD_HAL_VERSION_NONE;
-        mConfigInitialized = false;
+        mHwInterface.stopOffload();
+        mOffloadHalVersion = OFFLOAD_HAL_VERSION_NONE;
         if (mHandler.hasCallbacks(mScheduledPollingTask)) {
             mHandler.removeCallbacks(mScheduledPollingTask);
         }
@@ -335,7 +324,7 @@
     }
 
     private boolean started() {
-        return mConfigInitialized && mControlHalVersion != OFFLOAD_HAL_VERSION_NONE;
+        return mOffloadHalVersion != OFFLOAD_HAL_VERSION_NONE;
     }
 
     @VisibleForTesting
@@ -528,7 +517,7 @@
     }
 
     private boolean useStatsPolling() {
-        return mControlHalVersion == OFFLOAD_HAL_VERSION_1_0;
+        return mOffloadHalVersion == OFFLOAD_HAL_VERSION_HIDL_1_0;
     }
 
     private boolean maybeUpdateDataWarningAndLimit(String iface) {
@@ -540,7 +529,7 @@
 
         final InterfaceQuota quota = mInterfaceQuotas.getOrDefault(iface, InterfaceQuota.MAX_VALUE);
         final boolean ret;
-        if (mControlHalVersion >= OFFLOAD_HAL_VERSION_1_1) {
+        if (mOffloadHalVersion >= OFFLOAD_HAL_VERSION_HIDL_1_1) {
             ret = mHwInterface.setDataWarningAndLimit(iface, quota.warningBytes, quota.limitBytes);
         } else {
             ret = mHwInterface.setDataLimit(iface, quota.limitBytes);
@@ -611,7 +600,7 @@
         for (RouteInfo ri : oldRoutes) {
             if (shouldIgnoreDownstreamRoute(ri)) continue;
             if (!newRoutes.contains(ri)) {
-                mHwInterface.removeDownstreamPrefix(ifname, ri.getDestination().toString());
+                mHwInterface.removeDownstream(ifname, ri.getDestination().toString());
             }
         }
 
@@ -619,7 +608,7 @@
         for (RouteInfo ri : newRoutes) {
             if (shouldIgnoreDownstreamRoute(ri)) continue;
             if (!oldRoutes.contains(ri)) {
-                mHwInterface.addDownstreamPrefix(ifname, ri.getDestination().toString());
+                mHwInterface.addDownstream(ifname, ri.getDestination().toString());
             }
         }
     }
@@ -639,7 +628,7 @@
 
         for (RouteInfo route : lp.getRoutes()) {
             if (shouldIgnoreDownstreamRoute(route)) continue;
-            mHwInterface.removeDownstreamPrefix(ifname, route.getDestination().toString());
+            mHwInterface.removeDownstream(ifname, route.getDestination().toString());
         }
     }
 
@@ -768,7 +757,7 @@
         final boolean isStarted = started();
         pw.println("Offload HALs " + (isStarted ? "started" : "not started"));
         pw.println("Offload Control HAL version: "
-                + OffloadHardwareInterface.halVerToString(mControlHalVersion));
+                + OffloadHardwareInterface.halVerToString(mOffloadHalVersion));
         LinkProperties lp = mUpstreamLinkProperties;
         String upstream = (lp != null) ? lp.getInterfaceName() : null;
         pw.println("Current upstream: " + upstream);
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadHalAidlImpl.java b/Tethering/src/com/android/networkstack/tethering/OffloadHalAidlImpl.java
new file mode 100644
index 0000000..e7dc757
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadHalAidlImpl.java
@@ -0,0 +1,304 @@
+/*
+ * 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.tethering;
+
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_AIDL;
+
+import android.annotation.NonNull;
+import android.hardware.tetheroffload.ForwardedStats;
+import android.hardware.tetheroffload.IOffload;
+import android.hardware.tetheroffload.ITetheringOffloadCallback;
+import android.hardware.tetheroffload.NatTimeoutUpdate;
+import android.hardware.tetheroffload.NetworkProtocol;
+import android.hardware.tetheroffload.OffloadCallbackEvent;
+import android.os.Handler;
+import android.os.NativeHandle;
+import android.os.ParcelFileDescriptor;
+import android.os.ServiceManager;
+import android.system.OsConstants;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.SharedLog;
+import com.android.networkstack.tethering.OffloadHardwareInterface.OffloadHalCallback;
+
+import java.util.ArrayList;
+
+/**
+ * The implementation of IOffloadHal which based on Stable AIDL interface
+ */
+public class OffloadHalAidlImpl implements IOffloadHal {
+    private static final String TAG = OffloadHalAidlImpl.class.getSimpleName();
+    private static final String HAL_INSTANCE_NAME = IOffload.DESCRIPTOR + "/default";
+
+    private final Handler mHandler;
+    private final SharedLog mLog;
+    private final IOffload mIOffload;
+    @OffloadHardwareInterface.OffloadHalVersion
+    private final int mOffloadVersion;
+
+    private TetheringOffloadCallback mTetheringOffloadCallback;
+
+    public OffloadHalAidlImpl(int version, @NonNull IOffload offload, @NonNull Handler handler,
+            @NonNull SharedLog log) {
+        mOffloadVersion = version;
+        mIOffload = offload;
+        mHandler = handler;
+        mLog = log.forSubComponent(TAG);
+    }
+
+    /**
+     * Initialize the Tetheroffload HAL. Provides bound netlink file descriptors for use in the
+     * management process.
+     */
+    public boolean initOffload(@NonNull NativeHandle handle1, @NonNull NativeHandle handle2,
+            @NonNull OffloadHalCallback callback) {
+        final String methodStr = String.format("initOffload(%d, %d, %s)",
+                handle1.getFileDescriptor().getInt$(), handle2.getFileDescriptor().getInt$(),
+                (callback == null) ? "null"
+                : "0x" + Integer.toHexString(System.identityHashCode(callback)));
+        mTetheringOffloadCallback = new TetheringOffloadCallback(mHandler, callback, mLog);
+        try {
+            mIOffload.initOffload(
+                    ParcelFileDescriptor.adoptFd(handle1.getFileDescriptor().getInt$()),
+                    ParcelFileDescriptor.adoptFd(handle2.getFileDescriptor().getInt$()),
+                    mTetheringOffloadCallback);
+        } catch (Exception e) {
+            logAndIgnoreException(e, methodStr);
+            return false;
+        }
+        mLog.i(methodStr);
+        return true;
+    }
+
+    /** Stop the Tetheroffload HAL. */
+    public boolean stopOffload() {
+        final String methodStr = "stopOffload()";
+        try {
+            mIOffload.stopOffload();
+        } catch (Exception e) {
+            logAndIgnoreException(e, methodStr);
+            return false;
+        }
+
+        mTetheringOffloadCallback = null;
+        mLog.i(methodStr);
+        return true;
+    }
+
+    /** Get HAL interface version number. */
+    public int getVersion() {
+        return mOffloadVersion;
+    }
+
+    /** Get Tx/Rx usage from last query. */
+    public OffloadHardwareInterface.ForwardedStats getForwardedStats(@NonNull String upstream) {
+        ForwardedStats stats = new ForwardedStats();
+        final String methodStr = String.format("getForwardedStats(%s)",  upstream);
+        try {
+            stats = mIOffload.getForwardedStats(upstream);
+        } catch (Exception e) {
+            logAndIgnoreException(e, methodStr);
+        }
+        mLog.i(methodStr);
+        return new OffloadHardwareInterface.ForwardedStats(stats.rxBytes, stats.txBytes);
+    }
+
+    /** Set local prefixes to offload management process. */
+    public boolean setLocalPrefixes(@NonNull ArrayList<String> localPrefixes) {
+        final String methodStr = String.format("setLocalPrefixes([%s])",
+                String.join(",", localPrefixes));
+        try {
+            mIOffload.setLocalPrefixes(localPrefixes.toArray(new String[localPrefixes.size()]));
+        } catch (Exception e) {
+            logAndIgnoreException(e, methodStr);
+            return false;
+        }
+        mLog.i(methodStr);
+        return true;
+    }
+
+    /**
+     * Set data limit value to offload management process.
+     * Method setDataLimit is deprecated in AIDL, so call setDataWarningAndLimit instead,
+     * with warningBytes set to its MAX_VALUE.
+     */
+    public boolean setDataLimit(@NonNull String iface, long limit) {
+        final long warning = Long.MAX_VALUE;
+        final String methodStr = String.format("setDataLimit(%s, %d)", iface, limit);
+        try {
+            mIOffload.setDataWarningAndLimit(iface, warning, limit);
+        } catch (Exception e) {
+            logAndIgnoreException(e, methodStr);
+            return false;
+        }
+        mLog.i(methodStr);
+        return true;
+    }
+
+    /** Set data warning and limit value to offload management process. */
+    public boolean setDataWarningAndLimit(@NonNull String iface, long warning, long limit) {
+        final String methodStr =
+                String.format("setDataWarningAndLimit(%s, %d, %d)", iface, warning, limit);
+        try {
+            mIOffload.setDataWarningAndLimit(iface, warning, limit);
+        } catch (Exception e) {
+            logAndIgnoreException(e, methodStr);
+            return false;
+        }
+        mLog.i(methodStr);
+        return true;
+    }
+
+    /** Set upstream parameters to offload management process. */
+    public boolean setUpstreamParameters(@NonNull String iface, @NonNull String v4addr,
+            @NonNull String v4gateway, @NonNull ArrayList<String> v6gws) {
+        final String methodStr = String.format("setUpstreamParameters(%s, %s, %s, [%s])",
+                iface, v4addr, v4gateway, String.join(",", v6gws));
+        try {
+            mIOffload.setUpstreamParameters(iface, v4addr, v4gateway,
+                    v6gws.toArray(new String[v6gws.size()]));
+        } catch (Exception e) {
+            logAndIgnoreException(e, methodStr);
+            return false;
+        }
+        mLog.i(methodStr);
+        return true;
+    }
+
+    /** Add downstream prefix to offload management process. */
+    public boolean addDownstream(@NonNull String ifname, @NonNull String prefix) {
+        final String methodStr = String.format("addDownstream(%s, %s)", ifname, prefix);
+        try {
+            mIOffload.addDownstream(ifname, prefix);
+        } catch (Exception e) {
+            logAndIgnoreException(e, methodStr);
+            return false;
+        }
+        mLog.i(methodStr);
+        return true;
+    }
+
+    /** Remove downstream prefix from offload management process. */
+    public boolean removeDownstream(@NonNull String ifname, @NonNull String prefix) {
+        final String methodStr = String.format("removeDownstream(%s, %s)", ifname, prefix);
+        try {
+            mIOffload.removeDownstream(ifname, prefix);
+        } catch (Exception e) {
+            logAndIgnoreException(e, methodStr);
+            return false;
+        }
+        mLog.i(methodStr);
+        return true;
+    }
+
+    /**
+     * Get {@link IOffloadHal} object from the AIDL service.
+     *
+     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
+     * @param log Log to be used by the repository.
+     */
+    public static IOffloadHal getIOffloadHal(Handler handler, SharedLog log) {
+        // Tetheroffload AIDL interface is only supported after U.
+        if (!SdkLevel.isAtLeastU() || !ServiceManager.isDeclared(HAL_INSTANCE_NAME)) return null;
+
+        IOffload offload = IOffload.Stub.asInterface(
+                ServiceManager.waitForDeclaredService(HAL_INSTANCE_NAME));
+        if (offload == null) return null;
+
+        return new OffloadHalAidlImpl(OFFLOAD_HAL_VERSION_AIDL, offload, handler, log);
+    }
+
+    private void logAndIgnoreException(Exception e, final String methodStr) {
+        mLog.e(methodStr + " failed with " + e.getClass().getSimpleName() + ": ", e);
+    }
+
+    private static class TetheringOffloadCallback extends ITetheringOffloadCallback.Stub {
+        public final Handler handler;
+        public final OffloadHalCallback callback;
+        public final SharedLog log;
+
+        TetheringOffloadCallback(
+                Handler h, OffloadHalCallback cb, SharedLog sharedLog) {
+            handler = h;
+            callback = cb;
+            log = sharedLog;
+        }
+
+        private void handleOnEvent(int event) {
+            switch (event) {
+                case OffloadCallbackEvent.OFFLOAD_STARTED:
+                    callback.onStarted();
+                    break;
+                case OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR:
+                    callback.onStoppedError();
+                    break;
+                case OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED:
+                    callback.onStoppedUnsupported();
+                    break;
+                case OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE:
+                    callback.onSupportAvailable();
+                    break;
+                case OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED:
+                    callback.onStoppedLimitReached();
+                    break;
+                case OffloadCallbackEvent.OFFLOAD_WARNING_REACHED:
+                    callback.onWarningReached();
+                    break;
+                default:
+                    log.e("Unsupported OffloadCallbackEvent: " + event);
+            }
+        }
+
+        @Override
+        public void onEvent(int event) {
+            handler.post(() -> {
+                handleOnEvent(event);
+            });
+        }
+
+        @Override
+        public void updateTimeout(NatTimeoutUpdate params) {
+            handler.post(() -> {
+                callback.onNatTimeoutUpdate(
+                        networkProtocolToOsConstant(params.proto),
+                        params.src.addr, params.src.port,
+                        params.dst.addr, params.dst.port);
+            });
+        }
+
+        @Override
+        public String getInterfaceHash() {
+            return ITetheringOffloadCallback.HASH;
+        }
+
+        @Override
+        public int getInterfaceVersion() {
+            return ITetheringOffloadCallback.VERSION;
+        }
+    }
+
+    private static int networkProtocolToOsConstant(int proto) {
+        switch (proto) {
+            case NetworkProtocol.TCP: return OsConstants.IPPROTO_TCP;
+            case NetworkProtocol.UDP: return OsConstants.IPPROTO_UDP;
+            default:
+                // The caller checks this value and will log an error. Just make
+                // sure it won't collide with valid OsConstants.IPPROTO_* values.
+                return -Math.abs(proto);
+        }
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadHalHidlImpl.java b/Tethering/src/com/android/networkstack/tethering/OffloadHalHidlImpl.java
new file mode 100644
index 0000000..3e02543
--- /dev/null
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadHalHidlImpl.java
@@ -0,0 +1,436 @@
+/*
+ * 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.tethering;
+
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_0;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_1;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.halVerToString;
+import static com.android.networkstack.tethering.util.TetheringUtils.uint16;
+
+import android.annotation.NonNull;
+import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
+import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
+import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
+import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
+import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
+import android.hardware.tetheroffload.control.V1_1.ITetheringOffloadCallback;
+import android.os.Handler;
+import android.os.NativeHandle;
+import android.os.RemoteException;
+import android.system.OsConstants;
+import android.util.Log;
+
+import com.android.net.module.util.SharedLog;
+import com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
+import com.android.networkstack.tethering.OffloadHardwareInterface.OffloadHalCallback;
+
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+/**
+ * The implementation of IOffloadHal which based on HIDL interfaces
+ */
+public class OffloadHalHidlImpl implements IOffloadHal {
+    private static final String TAG = OffloadHalHidlImpl.class.getSimpleName();
+    private static final String YIELDS = " -> ";
+
+    private final Handler mHandler;
+    private final SharedLog mLog;
+    private final IOffloadConfig mIOffloadConfig;
+    private final IOffloadControl mIOffloadControl;
+    @OffloadHardwareInterface.OffloadHalVersion
+    private final int mOffloadControlVersion;
+
+    private OffloadHalCallback mOffloadHalCallback;
+    private TetheringOffloadCallback mTetheringOffloadCallback;
+
+    public OffloadHalHidlImpl(int version, @NonNull IOffloadConfig config,
+            @NonNull IOffloadControl control, @NonNull Handler handler, @NonNull SharedLog log) {
+        mOffloadControlVersion = version;
+        mIOffloadConfig = config;
+        mIOffloadControl = control;
+        mHandler = handler;
+        mLog = log.forSubComponent(TAG);
+    }
+
+    /**
+     * Initialize the Tetheroffload HAL. Provides bound netlink file descriptors for use in the
+     * management process.
+     */
+    public boolean initOffload(@NonNull NativeHandle handle1, @NonNull NativeHandle handle2,
+            @NonNull OffloadHalCallback callback) {
+        final String logmsg = String.format("initOffload(%d, %d, %s)",
+                handle1.getFileDescriptor().getInt$(), handle2.getFileDescriptor().getInt$(),
+                (callback == null) ? "null"
+                : "0x" + Integer.toHexString(System.identityHashCode(callback)));
+
+        mOffloadHalCallback = callback;
+        mTetheringOffloadCallback = new TetheringOffloadCallback(
+                mHandler, mOffloadHalCallback, mLog, mOffloadControlVersion);
+        final CbResults results = new CbResults();
+        try {
+            mIOffloadConfig.setHandles(handle1, handle2,
+                    (boolean success, String errMsg) -> {
+                        results.mSuccess = success;
+                        results.mErrMsg = errMsg;
+                    });
+            mIOffloadControl.initOffload(
+                    mTetheringOffloadCallback,
+                    (boolean success, String errMsg) -> {
+                        results.mSuccess = success;
+                        results.mErrMsg = errMsg;
+                    });
+        } catch (RemoteException e) {
+            record(logmsg, e);
+            return false;
+        }
+
+        record(logmsg, results);
+        return results.mSuccess;
+    }
+
+    /** Stop the Tetheroffload HAL. */
+    public boolean stopOffload() {
+        try {
+            mIOffloadControl.stopOffload(
+                    (boolean success, String errMsg) -> {
+                        if (!success) mLog.e("stopOffload failed: " + errMsg);
+                    });
+        } catch (RemoteException e) {
+            mLog.e("failed to stopOffload: " + e);
+        }
+        mOffloadHalCallback = null;
+        mTetheringOffloadCallback = null;
+        mLog.log("stopOffload()");
+        return true;
+    }
+
+    /** Get HAL interface version number. */
+    public int getVersion() {
+        return mOffloadControlVersion;
+    }
+
+    /** Get Tx/Rx usage from last query. */
+    public ForwardedStats getForwardedStats(@NonNull String upstream) {
+        final String logmsg = String.format("getForwardedStats(%s)",  upstream);
+
+        final ForwardedStats stats = new ForwardedStats();
+        try {
+            mIOffloadControl.getForwardedStats(
+                    upstream,
+                    (long rxBytes, long txBytes) -> {
+                        stats.rxBytes = (rxBytes > 0) ? rxBytes : 0;
+                        stats.txBytes = (txBytes > 0) ? txBytes : 0;
+                    });
+        } catch (RemoteException e) {
+            record(logmsg, e);
+            return stats;
+        }
+
+        return stats;
+    }
+
+    /** Set local prefixes to offload management process. */
+    public boolean setLocalPrefixes(@NonNull ArrayList<String> localPrefixes) {
+        final String logmsg = String.format("setLocalPrefixes([%s])",
+                String.join(",", localPrefixes));
+
+        final CbResults results = new CbResults();
+        try {
+            mIOffloadControl.setLocalPrefixes(localPrefixes,
+                    (boolean success, String errMsg) -> {
+                        results.mSuccess = success;
+                        results.mErrMsg = errMsg;
+                    });
+        } catch (RemoteException e) {
+            record(logmsg, e);
+            return false;
+        }
+
+        record(logmsg, results);
+        return results.mSuccess;
+    }
+
+    /** Set data limit value to offload management process. */
+    public boolean setDataLimit(@NonNull String iface, long limit) {
+
+        final String logmsg = String.format("setDataLimit(%s, %d)", iface, limit);
+
+        final CbResults results = new CbResults();
+        try {
+            mIOffloadControl.setDataLimit(
+                    iface, limit,
+                    (boolean success, String errMsg) -> {
+                        results.mSuccess = success;
+                        results.mErrMsg = errMsg;
+                    });
+        } catch (RemoteException e) {
+            record(logmsg, e);
+            return false;
+        }
+
+        record(logmsg, results);
+        return results.mSuccess;
+    }
+
+    /** Set data warning and limit value to offload management process. */
+    public boolean setDataWarningAndLimit(@NonNull String iface, long warning, long limit) {
+        if (mOffloadControlVersion < OFFLOAD_HAL_VERSION_HIDL_1_1) {
+            throw new UnsupportedOperationException(
+                    "setDataWarningAndLimit is not supported below HAL V1.1");
+        }
+        final String logmsg =
+                String.format("setDataWarningAndLimit(%s, %d, %d)", iface, warning, limit);
+
+        final CbResults results = new CbResults();
+        try {
+            ((android.hardware.tetheroffload.control.V1_1.IOffloadControl) mIOffloadControl)
+                    .setDataWarningAndLimit(
+                            iface, warning, limit,
+                            (boolean success, String errMsg) -> {
+                                results.mSuccess = success;
+                                results.mErrMsg = errMsg;
+                            });
+        } catch (RemoteException e) {
+            record(logmsg, e);
+            return false;
+        }
+
+        record(logmsg, results);
+        return results.mSuccess;
+    }
+
+    /** Set upstream parameters to offload management process. */
+    public boolean setUpstreamParameters(@NonNull String iface, @NonNull String v4addr,
+            @NonNull String v4gateway, @NonNull ArrayList<String> v6gws) {
+        final String logmsg = String.format("setUpstreamParameters(%s, %s, %s, [%s])",
+                iface, v4addr, v4gateway, String.join(",", v6gws));
+
+        final CbResults results = new CbResults();
+        try {
+            mIOffloadControl.setUpstreamParameters(
+                    iface, v4addr, v4gateway, v6gws,
+                    (boolean success, String errMsg) -> {
+                        results.mSuccess = success;
+                        results.mErrMsg = errMsg;
+                    });
+        } catch (RemoteException e) {
+            record(logmsg, e);
+            return false;
+        }
+
+        record(logmsg, results);
+        return results.mSuccess;
+    }
+
+    /** Add downstream prefix to offload management process. */
+    public boolean addDownstream(@NonNull String ifname, @NonNull String prefix) {
+        final String logmsg = String.format("addDownstream(%s, %s)", ifname, prefix);
+
+        final CbResults results = new CbResults();
+        try {
+            mIOffloadControl.addDownstream(ifname, prefix,
+                    (boolean success, String errMsg) -> {
+                        results.mSuccess = success;
+                        results.mErrMsg = errMsg;
+                    });
+        } catch (RemoteException e) {
+            record(logmsg, e);
+            return false;
+        }
+
+        record(logmsg, results);
+        return results.mSuccess;
+    }
+
+    /** Remove downstream prefix from offload management process. */
+    public boolean removeDownstream(@NonNull String ifname, @NonNull String prefix) {
+        final String logmsg = String.format("removeDownstream(%s, %s)", ifname, prefix);
+
+        final CbResults results = new CbResults();
+        try {
+            mIOffloadControl.removeDownstream(ifname, prefix,
+                    (boolean success, String errMsg) -> {
+                        results.mSuccess = success;
+                        results.mErrMsg = errMsg;
+                    });
+        } catch (RemoteException e) {
+            record(logmsg, e);
+            return false;
+        }
+
+        record(logmsg, results);
+        return results.mSuccess;
+    }
+
+    /**
+     * Get {@link IOffloadHal} object from the HIDL service.
+     *
+     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
+     * @param log Log to be used by the repository.
+     */
+    public static IOffloadHal getIOffloadHal(Handler handler, SharedLog log) {
+        IOffloadConfig config = null;
+        try {
+            config = IOffloadConfig.getService(true /*retry*/);
+        } catch (RemoteException | NoSuchElementException e) {
+            log.e("getIOffloadConfig error " + e);
+            return null;
+        }
+
+        IOffloadControl control = null;
+        int version = OFFLOAD_HAL_VERSION_NONE;
+        try {
+            control = android.hardware.tetheroffload.control
+                    .V1_1.IOffloadControl.getService(true /*retry*/);
+            version = OFFLOAD_HAL_VERSION_HIDL_1_1;
+        } catch (NoSuchElementException e) {
+            // Unsupported by device.
+        } catch (RemoteException e) {
+            log.e("Unable to get offload control " + OFFLOAD_HAL_VERSION_HIDL_1_1);
+        }
+        if (control == null) {
+            try {
+                control = IOffloadControl.getService(true /*retry*/);
+                version = OFFLOAD_HAL_VERSION_HIDL_1_0;
+            } catch (NoSuchElementException e) {
+                // Unsupported by device.
+            } catch (RemoteException e) {
+                log.e("Unable to get offload control " + OFFLOAD_HAL_VERSION_HIDL_1_0);
+            }
+        }
+
+        if (config == null || control == null) return null;
+
+        return new OffloadHalHidlImpl(version, config, control, handler, log);
+    }
+
+    private void record(String msg, Throwable t) {
+        mLog.e(msg + YIELDS + "exception: " + t);
+    }
+
+    private void record(String msg, CbResults results) {
+        final String logmsg = msg + YIELDS + results;
+        if (!results.mSuccess) {
+            mLog.e(logmsg);
+        } else {
+            mLog.log(logmsg);
+        }
+    }
+
+    private static class TetheringOffloadCallback extends ITetheringOffloadCallback.Stub {
+        public final Handler handler;
+        public final OffloadHalCallback callback;
+        public final SharedLog log;
+        private final int mOffloadControlVersion;
+
+        TetheringOffloadCallback(
+                Handler h, OffloadHalCallback cb, SharedLog sharedLog, int offloadControlVersion) {
+            handler = h;
+            callback = cb;
+            log = sharedLog;
+            this.mOffloadControlVersion = offloadControlVersion;
+        }
+
+        private void handleOnEvent(int event) {
+            switch (event) {
+                case OffloadCallbackEvent.OFFLOAD_STARTED:
+                    callback.onStarted();
+                    break;
+                case OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR:
+                    callback.onStoppedError();
+                    break;
+                case OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED:
+                    callback.onStoppedUnsupported();
+                    break;
+                case OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE:
+                    callback.onSupportAvailable();
+                    break;
+                case OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED:
+                    callback.onStoppedLimitReached();
+                    break;
+                case android.hardware.tetheroffload.control
+                        .V1_1.OffloadCallbackEvent.OFFLOAD_WARNING_REACHED:
+                    callback.onWarningReached();
+                    break;
+                default:
+                    log.e("Unsupported OffloadCallbackEvent: " + event);
+            }
+        }
+
+        @Override
+        public void onEvent(int event) {
+            // The implementation should never call onEvent()) if the event is already reported
+            // through newer callback.
+            if (mOffloadControlVersion > OFFLOAD_HAL_VERSION_HIDL_1_0) {
+                Log.wtf(TAG, "onEvent(" + event + ") fired on HAL "
+                        + halVerToString(mOffloadControlVersion));
+            }
+            handler.post(() -> {
+                handleOnEvent(event);
+            });
+        }
+
+        @Override
+        public void onEvent_1_1(int event) {
+            if (mOffloadControlVersion < OFFLOAD_HAL_VERSION_HIDL_1_1) {
+                Log.wtf(TAG, "onEvent_1_1(" + event + ") fired on HAL "
+                        + halVerToString(mOffloadControlVersion));
+                return;
+            }
+            handler.post(() -> {
+                handleOnEvent(event);
+            });
+        }
+
+        @Override
+        public void updateTimeout(NatTimeoutUpdate params) {
+            handler.post(() -> {
+                callback.onNatTimeoutUpdate(
+                        networkProtocolToOsConstant(params.proto),
+                        params.src.addr, uint16(params.src.port),
+                        params.dst.addr, uint16(params.dst.port));
+            });
+        }
+    }
+
+    private static int networkProtocolToOsConstant(int proto) {
+        switch (proto) {
+            case NetworkProtocol.TCP: return OsConstants.IPPROTO_TCP;
+            case NetworkProtocol.UDP: return OsConstants.IPPROTO_UDP;
+            default:
+                // The caller checks this value and will log an error. Just make
+                // sure it won't collide with valid OsConstants.IPPROTO_* values.
+                return -Math.abs(proto);
+        }
+    }
+
+    private static class CbResults {
+        boolean mSuccess;
+        String mErrMsg;
+
+        @Override
+        public String toString() {
+            if (mSuccess) {
+                return "ok";
+            } else {
+                return "fail: " + mErrMsg;
+            }
+        }
+    }
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index 76ddfe5..ea20063 100644
--- a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -18,25 +18,15 @@
 
 import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_DUMP;
 import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
-import static com.android.networkstack.tethering.util.TetheringUtils.uint16;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
-import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
-import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
-import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
-import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
-import android.hardware.tetheroffload.control.V1_1.ITetheringOffloadCallback;
 import android.net.util.SocketUtils;
 import android.os.Handler;
 import android.os.NativeHandle;
-import android.os.RemoteException;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
-import android.util.Log;
-import android.util.Pair;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.net.module.util.SharedLog;
@@ -54,8 +44,6 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.ArrayList;
-import java.util.NoSuchElementException;
-
 
 /**
  * Capture tethering dependencies, for injection.
@@ -86,43 +74,43 @@
     private final Handler mHandler;
     private final SharedLog mLog;
     private final Dependencies mDeps;
-    private IOffloadControl mOffloadControl;
+    private IOffloadHal mIOffload;
 
     // TODO: Use major-minor version control to prevent from defining new constants.
     static final int OFFLOAD_HAL_VERSION_NONE = 0;
-    static final int OFFLOAD_HAL_VERSION_1_0 = 1;
-    static final int OFFLOAD_HAL_VERSION_1_1 = 2;
+    static final int OFFLOAD_HAL_VERSION_HIDL_1_0 = 1;
+    static final int OFFLOAD_HAL_VERSION_HIDL_1_1 = 2;
+    static final int OFFLOAD_HAL_VERSION_AIDL = 3;
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = "OFFLOAD_HAL_VERSION_", value = {
             OFFLOAD_HAL_VERSION_NONE,
-            OFFLOAD_HAL_VERSION_1_0,
-            OFFLOAD_HAL_VERSION_1_1
+            OFFLOAD_HAL_VERSION_HIDL_1_0,
+            OFFLOAD_HAL_VERSION_HIDL_1_1,
+            OFFLOAD_HAL_VERSION_AIDL,
     })
     public @interface OffloadHalVersion {}
-    @OffloadHalVersion
-    private int mOffloadControlVersion = OFFLOAD_HAL_VERSION_NONE;
 
     @NonNull
     static String halVerToString(int version) {
         switch(version) {
-            case OFFLOAD_HAL_VERSION_1_0:
-                return "1.0";
-            case OFFLOAD_HAL_VERSION_1_1:
-                return "1.1";
+            case OFFLOAD_HAL_VERSION_HIDL_1_0:
+                return "HIDL 1.0";
+            case OFFLOAD_HAL_VERSION_HIDL_1_1:
+                return "HIDL 1.1";
+            case OFFLOAD_HAL_VERSION_AIDL:
+                return "AIDL";
             case OFFLOAD_HAL_VERSION_NONE:
                 return "None";
             default:
                 throw new IllegalArgumentException("Unsupported version int " + version);
         }
-
     }
 
-    private TetheringOffloadCallback mTetheringOffloadCallback;
-    private ControlCallback mControlCallback;
+    private OffloadHalCallback mOffloadHalCallback;
 
     /** The callback to notify status of offload management process. */
-    public static class ControlCallback {
+    public static class OffloadHalCallback {
         /** Offload started. */
         public void onStarted() {}
         /**
@@ -179,7 +167,7 @@
     }
 
     public OffloadHardwareInterface(Handler h, SharedLog log) {
-        this(h, log, new Dependencies(log));
+        this(h, log, new Dependencies(h, log));
     }
 
     OffloadHardwareInterface(Handler h, SharedLog log, Dependencies deps) {
@@ -190,45 +178,21 @@
 
     /** Capture OffloadHardwareInterface dependencies, for injection. */
     static class Dependencies {
+        private final Handler mHandler;
         private final SharedLog mLog;
 
-        Dependencies(SharedLog log) {
+        Dependencies(Handler handler, SharedLog log) {
+            mHandler = handler;
             mLog = log;
         }
 
-        public IOffloadConfig getOffloadConfig() {
-            try {
-                return IOffloadConfig.getService(true /*retry*/);
-            } catch (RemoteException | NoSuchElementException e) {
-                mLog.e("getIOffloadConfig error " + e);
-                return null;
-            }
-        }
-
-        @NonNull
-        public Pair<IOffloadControl, Integer> getOffloadControl() {
-            IOffloadControl hal = null;
-            int version = OFFLOAD_HAL_VERSION_NONE;
-            try {
-                hal = android.hardware.tetheroffload.control
-                        .V1_1.IOffloadControl.getService(true /*retry*/);
-                version = OFFLOAD_HAL_VERSION_1_1;
-            } catch (NoSuchElementException e) {
-                // Unsupported by device.
-            } catch (RemoteException e) {
-                mLog.e("Unable to get offload control " + OFFLOAD_HAL_VERSION_1_1);
-            }
+        public IOffloadHal getOffload() {
+            // Prefer AIDL implementation if its service is declared.
+            IOffloadHal hal = OffloadHalAidlImpl.getIOffloadHal(mHandler, mLog);
             if (hal == null) {
-                try {
-                    hal = IOffloadControl.getService(true /*retry*/);
-                    version = OFFLOAD_HAL_VERSION_1_0;
-                } catch (NoSuchElementException e) {
-                    // Unsupported by device.
-                } catch (RemoteException e) {
-                    mLog.e("Unable to get offload control " + OFFLOAD_HAL_VERSION_1_0);
-                }
+                hal = OffloadHalHidlImpl.getIOffloadHal(mHandler, mLog);
             }
-            return new Pair<IOffloadControl, Integer>(hal, version);
+            return hal;
         }
 
         public NativeHandle createConntrackSocket(final int groups) {
@@ -273,56 +237,6 @@
         return DEFAULT_TETHER_OFFLOAD_DISABLED;
     }
 
-    /**
-     * Offload management process need to know conntrack rules to support NAT, but it may not have
-     * permission to create netlink netfilter sockets. Create two netlink netfilter sockets and
-     * share them with offload management process.
-     */
-    public boolean initOffloadConfig() {
-        final IOffloadConfig offloadConfig = mDeps.getOffloadConfig();
-        if (offloadConfig == null) {
-            mLog.e("Could not find IOffloadConfig service");
-            return false;
-        }
-        // Per the IConfigOffload definition:
-        //
-        // h1    provides a file descriptor bound to the following netlink groups
-        //       (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY).
-        //
-        // h2    provides a file descriptor bound to the following netlink groups
-        //       (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY).
-        final NativeHandle h1 = mDeps.createConntrackSocket(
-                NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
-        if (h1 == null) return false;
-
-        requestSocketDump(h1);
-
-        final NativeHandle h2 = mDeps.createConntrackSocket(
-                NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
-        if (h2 == null) {
-            closeFdInNativeHandle(h1);
-            return false;
-        }
-
-        final CbResults results = new CbResults();
-        try {
-            offloadConfig.setHandles(h1, h2,
-                    (boolean success, String errMsg) -> {
-                        results.mSuccess = success;
-                        results.mErrMsg = errMsg;
-                    });
-        } catch (RemoteException e) {
-            record("initOffloadConfig, setHandles fail", e);
-            return false;
-        }
-        // Explicitly close FDs.
-        closeFdInNativeHandle(h1);
-        closeFdInNativeHandle(h2);
-
-        record("initOffloadConfig, setHandles results:", results);
-        return results.mSuccess;
-    }
-
     @VisibleForTesting
     void sendIpv4NfGenMsg(@NonNull NativeHandle handle, short type, short flags) {
         final int length = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE;
@@ -355,165 +269,107 @@
                 (short) (NLM_F_REQUEST | NLM_F_DUMP));
     }
 
-    private void closeFdInNativeHandle(final NativeHandle h) {
-        try {
-            h.close();
-        } catch (IOException | IllegalStateException e) {
-            // IllegalStateException means fd is already closed, do nothing here.
-            // Also nothing we can do if IOException.
+    private void maybeCloseFdInNativeHandles(final NativeHandle... handles) {
+        for (NativeHandle h : handles) {
+            if (h == null) continue;
+            try {
+                h.close();
+            } catch (IOException | IllegalStateException e) {
+                // IllegalStateException means fd is already closed, do nothing here.
+                // Also nothing we can do if IOException.
+            }
         }
     }
 
+    private int initWithHandles(NativeHandle h1, NativeHandle h2) {
+        if (h1 == null || h2 == null) {
+            mLog.e("Failed to create socket.");
+            return OFFLOAD_HAL_VERSION_NONE;
+        }
+
+        requestSocketDump(h1);
+        if (!mIOffload.initOffload(h1, h2, mOffloadHalCallback)) {
+            mIOffload.stopOffload();
+            mLog.e("Failed to initialize offload.");
+            return OFFLOAD_HAL_VERSION_NONE;
+        }
+
+        return mIOffload.getVersion();
+    }
+
     /**
      * Initialize the tethering offload HAL.
      *
      * @return one of {@code OFFLOAD_HAL_VERSION_*} represents the HAL version, or
      *         {@link #OFFLOAD_HAL_VERSION_NONE} if failed.
      */
-    public int initOffloadControl(ControlCallback controlCb) {
-        mControlCallback = controlCb;
-
-        if (mOffloadControl == null) {
-            final Pair<IOffloadControl, Integer> halAndVersion = mDeps.getOffloadControl();
-            mOffloadControl = halAndVersion.first;
-            mOffloadControlVersion = halAndVersion.second;
-            if (mOffloadControl == null) {
-                mLog.e("tethering IOffloadControl.getService() returned null");
+    public int initOffload(OffloadHalCallback offloadCb) {
+        if (mIOffload == null) {
+            mIOffload = mDeps.getOffload();
+            if (mIOffload == null) {
+                mLog.e("No tethering offload HAL service found.");
                 return OFFLOAD_HAL_VERSION_NONE;
             }
-            mLog.i("tethering offload control version "
-                    + halVerToString(mOffloadControlVersion) + " is supported.");
+            mLog.i("Tethering offload version "
+                    + halVerToString(mIOffload.getVersion()) + " is supported.");
         }
 
-        final String logmsg = String.format("initOffloadControl(%s)",
-                (controlCb == null) ? "null"
-                        : "0x" + Integer.toHexString(System.identityHashCode(controlCb)));
+        // Per the IOffload definition:
+        //
+        // h1    provides a file descriptor bound to the following netlink groups
+        //       (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY).
+        //
+        // h2    provides a file descriptor bound to the following netlink groups
+        //       (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY).
+        final NativeHandle h1 = mDeps.createConntrackSocket(
+                NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
+        final NativeHandle h2 = mDeps.createConntrackSocket(
+                NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
 
-        mTetheringOffloadCallback = new TetheringOffloadCallback(
-                mHandler, mControlCallback, mLog, mOffloadControlVersion);
-        final CbResults results = new CbResults();
-        try {
-            mOffloadControl.initOffload(
-                    mTetheringOffloadCallback,
-                    (boolean success, String errMsg) -> {
-                        results.mSuccess = success;
-                        results.mErrMsg = errMsg;
-                    });
-        } catch (RemoteException e) {
-            record(logmsg, e);
-            return OFFLOAD_HAL_VERSION_NONE;
+        mOffloadHalCallback = offloadCb;
+        final int version = initWithHandles(h1, h2);
+
+        // Explicitly close FDs for HIDL. AIDL will pass the original FDs to the service,
+        // they shouldn't be closed here.
+        if (version < OFFLOAD_HAL_VERSION_AIDL) {
+            maybeCloseFdInNativeHandles(h1, h2);
         }
-
-        record(logmsg, results);
-        return results.mSuccess ? mOffloadControlVersion : OFFLOAD_HAL_VERSION_NONE;
+        return version;
     }
 
-    /** Stop IOffloadControl. */
-    public void stopOffloadControl() {
-        if (mOffloadControl != null) {
-            try {
-                mOffloadControl.stopOffload(
-                        (boolean success, String errMsg) -> {
-                            if (!success) mLog.e("stopOffload failed: " + errMsg);
-                        });
-            } catch (RemoteException e) {
-                mLog.e("failed to stopOffload: " + e);
+    /** Stop the tethering offload HAL. */
+    public void stopOffload() {
+        if (mIOffload != null) {
+            if (!mIOffload.stopOffload()) {
+                mLog.e("Failed to stop offload.");
             }
         }
-        mOffloadControl = null;
-        mTetheringOffloadCallback = null;
-        mControlCallback = null;
-        mLog.log("stopOffloadControl()");
+        mIOffload = null;
+        mOffloadHalCallback = null;
     }
 
     /** Get Tx/Rx usage from last query. */
     public ForwardedStats getForwardedStats(String upstream) {
-        final String logmsg = String.format("getForwardedStats(%s)",  upstream);
-
-        final ForwardedStats stats = new ForwardedStats();
-        try {
-            mOffloadControl.getForwardedStats(
-                    upstream,
-                    (long rxBytes, long txBytes) -> {
-                        stats.rxBytes = (rxBytes > 0) ? rxBytes : 0;
-                        stats.txBytes = (txBytes > 0) ? txBytes : 0;
-                    });
-        } catch (RemoteException e) {
-            record(logmsg, e);
-            return stats;
-        }
-
-        return stats;
+        return mIOffload.getForwardedStats(upstream);
     }
 
     /** Set local prefixes to offload management process. */
     public boolean setLocalPrefixes(ArrayList<String> localPrefixes) {
-        final String logmsg = String.format("setLocalPrefixes([%s])",
-                String.join(",", localPrefixes));
-
-        final CbResults results = new CbResults();
-        try {
-            mOffloadControl.setLocalPrefixes(localPrefixes,
-                    (boolean success, String errMsg) -> {
-                        results.mSuccess = success;
-                        results.mErrMsg = errMsg;
-                    });
-        } catch (RemoteException e) {
-            record(logmsg, e);
-            return false;
-        }
-
-        record(logmsg, results);
-        return results.mSuccess;
+        return mIOffload.setLocalPrefixes(localPrefixes);
     }
 
     /** Set data limit value to offload management process. */
     public boolean setDataLimit(String iface, long limit) {
-
-        final String logmsg = String.format("setDataLimit(%s, %d)", iface, limit);
-
-        final CbResults results = new CbResults();
-        try {
-            mOffloadControl.setDataLimit(
-                    iface, limit,
-                    (boolean success, String errMsg) -> {
-                        results.mSuccess = success;
-                        results.mErrMsg = errMsg;
-                    });
-        } catch (RemoteException e) {
-            record(logmsg, e);
-            return false;
-        }
-
-        record(logmsg, results);
-        return results.mSuccess;
+        return mIOffload.setDataLimit(iface, limit);
     }
 
     /** Set data warning and limit value to offload management process. */
     public boolean setDataWarningAndLimit(String iface, long warning, long limit) {
-        if (mOffloadControlVersion < OFFLOAD_HAL_VERSION_1_1) {
-            throw new IllegalArgumentException(
+        if (mIOffload.getVersion() < OFFLOAD_HAL_VERSION_HIDL_1_1) {
+            throw new UnsupportedOperationException(
                     "setDataWarningAndLimit is not supported below HAL V1.1");
         }
-        final String logmsg =
-                String.format("setDataWarningAndLimit(%s, %d, %d)", iface, warning, limit);
-
-        final CbResults results = new CbResults();
-        try {
-            ((android.hardware.tetheroffload.control.V1_1.IOffloadControl) mOffloadControl)
-                    .setDataWarningAndLimit(
-                            iface, warning, limit,
-                            (boolean success, String errMsg) -> {
-                                results.mSuccess = success;
-                                results.mErrMsg = errMsg;
-                            });
-        } catch (RemoteException e) {
-            record(logmsg, e);
-            return false;
-        }
-
-        record(logmsg, results);
-        return results.mSuccess;
+        return mIOffload.setDataWarningAndLimit(iface, warning, limit);
     }
 
     /** Set upstream parameters to offload management process. */
@@ -523,178 +379,16 @@
         v4addr = (v4addr != null) ? v4addr : NO_IPV4_ADDRESS;
         v4gateway = (v4gateway != null) ? v4gateway : NO_IPV4_GATEWAY;
         v6gws = (v6gws != null) ? v6gws : new ArrayList<>();
-
-        final String logmsg = String.format("setUpstreamParameters(%s, %s, %s, [%s])",
-                iface, v4addr, v4gateway, String.join(",", v6gws));
-
-        final CbResults results = new CbResults();
-        try {
-            mOffloadControl.setUpstreamParameters(
-                    iface, v4addr, v4gateway, v6gws,
-                    (boolean success, String errMsg) -> {
-                        results.mSuccess = success;
-                        results.mErrMsg = errMsg;
-                    });
-        } catch (RemoteException e) {
-            record(logmsg, e);
-            return false;
-        }
-
-        record(logmsg, results);
-        return results.mSuccess;
+        return mIOffload.setUpstreamParameters(iface, v4addr, v4gateway, v6gws);
     }
 
     /** Add downstream prefix to offload management process. */
-    public boolean addDownstreamPrefix(String ifname, String prefix) {
-        final String logmsg = String.format("addDownstreamPrefix(%s, %s)", ifname, prefix);
-
-        final CbResults results = new CbResults();
-        try {
-            mOffloadControl.addDownstream(ifname, prefix,
-                    (boolean success, String errMsg) -> {
-                        results.mSuccess = success;
-                        results.mErrMsg = errMsg;
-                    });
-        } catch (RemoteException e) {
-            record(logmsg, e);
-            return false;
-        }
-
-        record(logmsg, results);
-        return results.mSuccess;
+    public boolean addDownstream(String ifname, String prefix) {
+        return  mIOffload.addDownstream(ifname, prefix);
     }
 
     /** Remove downstream prefix from offload management process. */
-    public boolean removeDownstreamPrefix(String ifname, String prefix) {
-        final String logmsg = String.format("removeDownstreamPrefix(%s, %s)", ifname, prefix);
-
-        final CbResults results = new CbResults();
-        try {
-            mOffloadControl.removeDownstream(ifname, prefix,
-                    (boolean success, String errMsg) -> {
-                        results.mSuccess = success;
-                        results.mErrMsg = errMsg;
-                    });
-        } catch (RemoteException e) {
-            record(logmsg, e);
-            return false;
-        }
-
-        record(logmsg, results);
-        return results.mSuccess;
-    }
-
-    private void record(String msg, Throwable t) {
-        mLog.e(msg + YIELDS + "exception: " + t);
-    }
-
-    private void record(String msg, CbResults results) {
-        final String logmsg = msg + YIELDS + results;
-        if (!results.mSuccess) {
-            mLog.e(logmsg);
-        } else {
-            mLog.log(logmsg);
-        }
-    }
-
-    private static class TetheringOffloadCallback extends ITetheringOffloadCallback.Stub {
-        public final Handler handler;
-        public final ControlCallback controlCb;
-        public final SharedLog log;
-        private final int mOffloadControlVersion;
-
-        TetheringOffloadCallback(
-                Handler h, ControlCallback cb, SharedLog sharedLog, int offloadControlVersion) {
-            handler = h;
-            controlCb = cb;
-            log = sharedLog;
-            this.mOffloadControlVersion = offloadControlVersion;
-        }
-
-        private void handleOnEvent(int event) {
-            switch (event) {
-                case OffloadCallbackEvent.OFFLOAD_STARTED:
-                    controlCb.onStarted();
-                    break;
-                case OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR:
-                    controlCb.onStoppedError();
-                    break;
-                case OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED:
-                    controlCb.onStoppedUnsupported();
-                    break;
-                case OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE:
-                    controlCb.onSupportAvailable();
-                    break;
-                case OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED:
-                    controlCb.onStoppedLimitReached();
-                    break;
-                case android.hardware.tetheroffload.control
-                        .V1_1.OffloadCallbackEvent.OFFLOAD_WARNING_REACHED:
-                    controlCb.onWarningReached();
-                    break;
-                default:
-                    log.e("Unsupported OffloadCallbackEvent: " + event);
-            }
-        }
-
-        @Override
-        public void onEvent(int event) {
-            // The implementation should never call onEvent()) if the event is already reported
-            // through newer callback.
-            if (mOffloadControlVersion > OFFLOAD_HAL_VERSION_1_0) {
-                Log.wtf(TAG, "onEvent(" + event + ") fired on HAL "
-                        + halVerToString(mOffloadControlVersion));
-            }
-            handler.post(() -> {
-                handleOnEvent(event);
-            });
-        }
-
-        @Override
-        public void onEvent_1_1(int event) {
-            if (mOffloadControlVersion < OFFLOAD_HAL_VERSION_1_1) {
-                Log.wtf(TAG, "onEvent_1_1(" + event + ") fired on HAL "
-                        + halVerToString(mOffloadControlVersion));
-                return;
-            }
-            handler.post(() -> {
-                handleOnEvent(event);
-            });
-        }
-
-        @Override
-        public void updateTimeout(NatTimeoutUpdate params) {
-            handler.post(() -> {
-                controlCb.onNatTimeoutUpdate(
-                        networkProtocolToOsConstant(params.proto),
-                        params.src.addr, uint16(params.src.port),
-                        params.dst.addr, uint16(params.dst.port));
-            });
-        }
-    }
-
-    private static int networkProtocolToOsConstant(int proto) {
-        switch (proto) {
-            case NetworkProtocol.TCP: return OsConstants.IPPROTO_TCP;
-            case NetworkProtocol.UDP: return OsConstants.IPPROTO_UDP;
-            default:
-                // The caller checks this value and will log an error. Just make
-                // sure it won't collide with valid OsContants.IPPROTO_* values.
-                return -Math.abs(proto);
-        }
-    }
-
-    private static class CbResults {
-        boolean mSuccess;
-        String mErrMsg;
-
-        @Override
-        public String toString() {
-            if (mSuccess) {
-                return "ok";
-            } else {
-                return "fail: " + mErrMsg;
-            }
-        }
+    public boolean removeDownstream(String ifname, String prefix) {
+        return  mIOffload.removeDownstream(ifname, prefix);
     }
 }
diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
index 706df4e..b3fb3e4 100644
--- a/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
+++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
@@ -80,7 +80,7 @@
         // Looper must be prepared here since AndroidJUnitRunner runs tests on separate threads.
         if (Looper.myLooper() == null) Looper.prepare();
 
-        mDeps = new OffloadHardwareInterface.Dependencies(mLog);
+        mDeps = new OffloadHardwareInterface.Dependencies(mHandler, mLog);
         mOffloadHw = new OffloadHardwareInterface(mHandler, mLog, mDeps);
     }
 
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
index faca1c8..36c15a7 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
@@ -31,8 +31,8 @@
 import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_IFACE;
 import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_UID;
 import static com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
-import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0;
-import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_1;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_0;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_1;
 import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
 import static com.android.testutils.MiscAsserts.assertContainsAll;
 import static com.android.testutils.MiscAsserts.assertThrows;
@@ -79,6 +79,7 @@
 
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.net.module.util.SharedLog;
+import com.android.networkstack.tethering.OffloadHardwareInterface.OffloadHalCallback;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 import com.android.testutils.TestableNetworkStatsProviderCbBinder;
@@ -125,8 +126,8 @@
     private OffloadController.OffloadTetheringStatsProvider mTetherStatsProvider;
     private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
             ArgumentCaptor.forClass(ArrayList.class);
-    private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor =
-            ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class);
+    private final ArgumentCaptor<OffloadHalCallback> mOffloadHalCallbackCaptor =
+            ArgumentCaptor.forClass(OffloadHalCallback.class);
     private MockContentResolver mContentResolver;
     private final TestLooper mTestLooper = new TestLooper();
     private OffloadController.Dependencies mDeps = new OffloadController.Dependencies() {
@@ -151,10 +152,9 @@
         FakeSettingsProvider.clearSettingsProvider();
     }
 
-    private void setupFunctioningHardwareInterface(int controlVersion) {
-        when(mHardware.initOffloadConfig()).thenReturn(true);
-        when(mHardware.initOffloadControl(mControlCallbackCaptor.capture()))
-                .thenReturn(controlVersion);
+    private void setupFunctioningHardwareInterface(int offloadHalVersion) {
+        when(mHardware.initOffload(mOffloadHalCallbackCaptor.capture()))
+                .thenReturn(offloadHalVersion);
         when(mHardware.setUpstreamParameters(anyString(), any(), any(), any())).thenReturn(true);
         when(mHardware.getForwardedStats(any())).thenReturn(new ForwardedStats());
         when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(true);
@@ -192,9 +192,9 @@
     @Test
     public void testStartStop() throws Exception {
         stopOffloadController(
-                startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/));
+                startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, true /*expectStart*/));
         stopOffloadController(
-                startOffloadController(OFFLOAD_HAL_VERSION_1_1, true /*expectStart*/));
+                startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_1, true /*expectStart*/));
     }
 
     @NonNull
@@ -206,9 +206,8 @@
 
         final InOrder inOrder = inOrder(mHardware);
         inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
-        inOrder.verify(mHardware, times(expectStart ? 1 : 0)).initOffloadConfig();
-        inOrder.verify(mHardware, times(expectStart ? 1 : 0)).initOffloadControl(
-                any(OffloadHardwareInterface.ControlCallback.class));
+        inOrder.verify(mHardware, times(expectStart ? 1 : 0)).initOffload(
+                any(OffloadHalCallback.class));
         inOrder.verifyNoMoreInteractions();
         // Clear counters only instead of whole mock to preserve the mocking setup.
         clearInvocations(mHardware);
@@ -218,7 +217,7 @@
     private void stopOffloadController(final OffloadController offload) throws Exception {
         final InOrder inOrder = inOrder(mHardware);
         offload.stop();
-        inOrder.verify(mHardware, times(1)).stopOffloadControl();
+        inOrder.verify(mHardware, times(1)).stopOffload();
         inOrder.verifyNoMoreInteractions();
         reset(mHardware);
     }
@@ -228,7 +227,7 @@
         when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(1);
         assertThrows(SettingNotFoundException.class, () ->
                 Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED));
-        startOffloadController(OFFLOAD_HAL_VERSION_1_0, false /*expectStart*/);
+        startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, false /*expectStart*/);
     }
 
     @Test
@@ -236,26 +235,26 @@
         when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(0);
         assertThrows(SettingNotFoundException.class, () ->
                 Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED));
-        startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
+        startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, true /*expectStart*/);
     }
 
     @Test
     public void testSettingsAllowsStart() throws Exception {
         Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 0);
-        startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
+        startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, true /*expectStart*/);
     }
 
     @Test
     public void testSettingsDisablesStart() throws Exception {
         Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 1);
-        startOffloadController(OFFLOAD_HAL_VERSION_1_0, false /*expectStart*/);
+        startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, false /*expectStart*/);
     }
 
     @Test
     public void testSetUpstreamLinkPropertiesWorking() throws Exception {
         enableOffload();
         final OffloadController offload =
-                startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
+                startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, true /*expectStart*/);
 
         // In reality, the UpstreamNetworkMonitor would have passed down to us
         // a covering set of local prefixes representing a minimum essential
@@ -426,7 +425,7 @@
     public void testGetForwardedStats() throws Exception {
         enableOffload();
         final OffloadController offload =
-                startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
+                startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, true /*expectStart*/);
 
         final String ethernetIface = "eth1";
         final String mobileIface = "rmnet_data0";
@@ -521,11 +520,11 @@
         // Verify the OffloadController is called by R framework, where the framework doesn't send
         // warning.
         // R only uses HAL 1.0.
-        checkSetDataWarningAndLimit(false, OFFLOAD_HAL_VERSION_1_0);
+        checkSetDataWarningAndLimit(false, OFFLOAD_HAL_VERSION_HIDL_1_0);
         // Verify the OffloadController is called by S+ framework, where the framework sends
         // warning along with limit.
-        checkSetDataWarningAndLimit(true, OFFLOAD_HAL_VERSION_1_0);
-        checkSetDataWarningAndLimit(true, OFFLOAD_HAL_VERSION_1_1);
+        checkSetDataWarningAndLimit(true, OFFLOAD_HAL_VERSION_HIDL_1_0);
+        checkSetDataWarningAndLimit(true, OFFLOAD_HAL_VERSION_HIDL_1_1);
     }
 
     private void checkSetDataWarningAndLimit(boolean isProviderSetWarning, int controlVersion)
@@ -550,7 +549,7 @@
         when(mHardware.setDataWarningAndLimit(anyString(), anyLong(), anyLong())).thenReturn(true);
         offload.setUpstreamLinkProperties(lp);
         // Applying an interface sends the initial quota to the hardware.
-        if (controlVersion >= OFFLOAD_HAL_VERSION_1_1) {
+        if (controlVersion >= OFFLOAD_HAL_VERSION_HIDL_1_1) {
             inOrder.verify(mHardware).setDataWarningAndLimit(ethernetIface, Long.MAX_VALUE,
                     Long.MAX_VALUE);
         } else {
@@ -576,7 +575,7 @@
             mTetherStatsProvider.onSetLimit(ethernetIface, ethernetLimit);
         }
         waitForIdle();
-        if (controlVersion >= OFFLOAD_HAL_VERSION_1_1) {
+        if (controlVersion >= OFFLOAD_HAL_VERSION_HIDL_1_1) {
             inOrder.verify(mHardware).setDataWarningAndLimit(ethernetIface, Long.MAX_VALUE,
                     ethernetLimit);
         } else {
@@ -591,7 +590,7 @@
             mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
         }
         waitForIdle();
-        if (controlVersion >= OFFLOAD_HAL_VERSION_1_1) {
+        if (controlVersion >= OFFLOAD_HAL_VERSION_HIDL_1_1) {
             inOrder.verify(mHardware, never()).setDataWarningAndLimit(anyString(), anyLong(),
                     anyLong());
         } else {
@@ -603,7 +602,7 @@
         lp.setInterfaceName(mobileIface);
         offload.setUpstreamLinkProperties(lp);
         waitForIdle();
-        if (controlVersion >= OFFLOAD_HAL_VERSION_1_1) {
+        if (controlVersion >= OFFLOAD_HAL_VERSION_HIDL_1_1) {
             inOrder.verify(mHardware).setDataWarningAndLimit(mobileIface,
                     isProviderSetWarning ? mobileWarning : Long.MAX_VALUE,
                     mobileLimit);
@@ -620,7 +619,7 @@
             mTetherStatsProvider.onSetLimit(mobileIface, NetworkStatsProvider.QUOTA_UNLIMITED);
         }
         waitForIdle();
-        if (controlVersion >= OFFLOAD_HAL_VERSION_1_1) {
+        if (controlVersion >= OFFLOAD_HAL_VERSION_HIDL_1_1) {
             inOrder.verify(mHardware).setDataWarningAndLimit(mobileIface, Long.MAX_VALUE,
                     Long.MAX_VALUE);
         } else {
@@ -655,15 +654,15 @@
         }
         waitForIdle();
         inOrder.verify(mHardware).getForwardedStats(ethernetIface);
-        inOrder.verify(mHardware).stopOffloadControl();
+        inOrder.verify(mHardware).stopOffload();
     }
 
     @Test
     public void testDataWarningAndLimitCallback_LimitReached() throws Exception {
         enableOffload();
-        startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
+        startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, true /*expectStart*/);
 
-        final OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
+        final OffloadHalCallback callback = mOffloadHalCallbackCaptor.getValue();
         callback.onStoppedLimitReached();
         mTetherStatsProviderCb.expectNotifyStatsUpdated();
 
@@ -679,8 +678,8 @@
     @Test
     @IgnoreUpTo(Build.VERSION_CODES.R)  // HAL 1.1 is only supported from S
     public void testDataWarningAndLimitCallback_WarningReached() throws Exception {
-        startOffloadController(OFFLOAD_HAL_VERSION_1_1, true /*expectStart*/);
-        final OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
+        startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_1, true /*expectStart*/);
+        final OffloadHalCallback callback = mOffloadHalCallbackCaptor.getValue();
         callback.onWarningReached();
         mTetherStatsProviderCb.expectNotifyStatsUpdated();
 
@@ -695,7 +694,7 @@
     public void testAddRemoveDownstreams() throws Exception {
         enableOffload();
         final OffloadController offload =
-                startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
+                startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, true /*expectStart*/);
         final InOrder inOrder = inOrder(mHardware);
 
         // Tethering makes several calls to setLocalPrefixes() before add/remove
@@ -710,14 +709,14 @@
         usbLinkProperties.addRoute(
                 new RouteInfo(new IpPrefix(USB_PREFIX), null, null, RTN_UNICAST));
         offload.notifyDownstreamLinkProperties(usbLinkProperties);
-        inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, USB_PREFIX);
+        inOrder.verify(mHardware, times(1)).addDownstream(RNDIS0, USB_PREFIX);
         inOrder.verifyNoMoreInteractions();
 
         // [2] Routes for IPv6 link-local prefixes should never be added.
         usbLinkProperties.addRoute(
                 new RouteInfo(new IpPrefix(IPV6_LINKLOCAL), null, null, RTN_UNICAST));
         offload.notifyDownstreamLinkProperties(usbLinkProperties);
-        inOrder.verify(mHardware, never()).addDownstreamPrefix(eq(RNDIS0), anyString());
+        inOrder.verify(mHardware, never()).addDownstream(eq(RNDIS0), anyString());
         inOrder.verifyNoMoreInteractions();
 
         // [3] Add an IPv6 prefix for good measure. Only new offload-able
@@ -726,14 +725,14 @@
         usbLinkProperties.addRoute(
                 new RouteInfo(new IpPrefix(IPV6_DOC_PREFIX), null, null, RTN_UNICAST));
         offload.notifyDownstreamLinkProperties(usbLinkProperties);
-        inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, IPV6_DOC_PREFIX);
+        inOrder.verify(mHardware, times(1)).addDownstream(RNDIS0, IPV6_DOC_PREFIX);
         inOrder.verifyNoMoreInteractions();
 
         // [4] Adding addresses doesn't affect notifyDownstreamLinkProperties().
         // The address is passed in by a separate setLocalPrefixes() invocation.
         usbLinkProperties.addLinkAddress(new LinkAddress("2001:db8::2/64"));
         offload.notifyDownstreamLinkProperties(usbLinkProperties);
-        inOrder.verify(mHardware, never()).addDownstreamPrefix(eq(RNDIS0), anyString());
+        inOrder.verify(mHardware, never()).addDownstream(eq(RNDIS0), anyString());
 
         // [5] Differences in local routes are converted into addDownstream()
         // and removeDownstream() invocations accordingly.
@@ -742,8 +741,8 @@
         usbLinkProperties.addRoute(
                 new RouteInfo(new IpPrefix(IPV6_DISCARD_PREFIX), null, null, RTN_UNICAST));
         offload.notifyDownstreamLinkProperties(usbLinkProperties);
-        inOrder.verify(mHardware, times(1)).removeDownstreamPrefix(RNDIS0, IPV6_DOC_PREFIX);
-        inOrder.verify(mHardware, times(1)).addDownstreamPrefix(RNDIS0, IPV6_DISCARD_PREFIX);
+        inOrder.verify(mHardware, times(1)).removeDownstream(RNDIS0, IPV6_DOC_PREFIX);
+        inOrder.verify(mHardware, times(1)).addDownstream(RNDIS0, IPV6_DISCARD_PREFIX);
         inOrder.verifyNoMoreInteractions();
 
         // [6] Removing a downstream interface which was never added causes no
@@ -753,8 +752,8 @@
 
         // [7] Removing an active downstream removes all remaining prefixes.
         offload.removeDownstreamInterface(RNDIS0);
-        inOrder.verify(mHardware, times(1)).removeDownstreamPrefix(RNDIS0, USB_PREFIX);
-        inOrder.verify(mHardware, times(1)).removeDownstreamPrefix(RNDIS0, IPV6_DISCARD_PREFIX);
+        inOrder.verify(mHardware, times(1)).removeDownstream(RNDIS0, USB_PREFIX);
+        inOrder.verify(mHardware, times(1)).removeDownstream(RNDIS0, IPV6_DISCARD_PREFIX);
         inOrder.verifyNoMoreInteractions();
     }
 
@@ -762,7 +761,7 @@
     public void testControlCallbackOnStoppedUnsupportedFetchesAllStats() throws Exception {
         enableOffload();
         final OffloadController offload =
-                startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
+                startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, true /*expectStart*/);
 
         // Pretend to set a few different upstreams (only the interface name
         // matters for this test; we're ignoring IP and route information).
@@ -776,7 +775,7 @@
         // that happen with setUpstreamParameters().
         clearInvocations(mHardware);
 
-        OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
+        OffloadHalCallback callback = mOffloadHalCallbackCaptor.getValue();
         callback.onStoppedUnsupported();
 
         // Verify forwarded stats behaviour.
@@ -793,7 +792,7 @@
             throws Exception {
         enableOffload();
         final OffloadController offload =
-                startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
+                startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, true /*expectStart*/);
 
         // Pretend to set a few different upstreams (only the interface name
         // matters for this test; we're ignoring IP and route information).
@@ -840,7 +839,7 @@
         // that happen with setUpstreamParameters().
         clearInvocations(mHardware);
 
-        OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
+        OffloadHalCallback callback = mOffloadHalCallbackCaptor.getValue();
         callback.onSupportAvailable();
 
         // Verify forwarded stats behaviour.
@@ -859,8 +858,8 @@
                 // into OffloadController proper. After this, also check for:
                 //     "192.168.43.1/32", "2001:2::1/128", "2001:2::2/128"
                 "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64");
-        verify(mHardware, times(1)).addDownstreamPrefix(WLAN0, "192.168.43.0/24");
-        verify(mHardware, times(1)).addDownstreamPrefix(WLAN0, "2001:2::/64");
+        verify(mHardware, times(1)).addDownstream(WLAN0, "192.168.43.0/24");
+        verify(mHardware, times(1)).addDownstream(WLAN0, "2001:2::/64");
         verify(mHardware, times(1)).setUpstreamParameters(eq(RMNET0), any(), any(), any());
         verify(mHardware, times(1)).setDataLimit(eq(RMNET0), anyLong());
         verifyNoMoreInteractions(mHardware);
@@ -871,7 +870,7 @@
         enableOffload();
         setOffloadPollInterval(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
         final OffloadController offload =
-                startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
+                startOffloadController(OFFLOAD_HAL_VERSION_HIDL_1_0, true /*expectStart*/);
 
         // Initialize with fake eth upstream.
         final String ethernetIface = "eth1";
@@ -925,7 +924,7 @@
         offload.setUpstreamLinkProperties(makeEthernetLinkProperties());
         mTetherStatsProvider.onSetAlert(0);
         waitForIdle();
-        if (controlVersion >= OFFLOAD_HAL_VERSION_1_1) {
+        if (controlVersion >= OFFLOAD_HAL_VERSION_HIDL_1_1) {
             mTetherStatsProviderCb.assertNoCallback();
         } else {
             mTetherStatsProviderCb.expectNotifyAlertReached();
@@ -935,7 +934,7 @@
 
     @Test
     public void testSoftwarePollingUsed() throws Exception {
-        checkSoftwarePollingUsed(OFFLOAD_HAL_VERSION_1_0);
-        checkSoftwarePollingUsed(OFFLOAD_HAL_VERSION_1_1);
+        checkSoftwarePollingUsed(OFFLOAD_HAL_VERSION_HIDL_1_0);
+        checkSoftwarePollingUsed(OFFLOAD_HAL_VERSION_HIDL_1_1);
     }
 }
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHalAidlImplTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHalAidlImplTest.java
new file mode 100644
index 0000000..c9ce64f
--- /dev/null
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHalAidlImplTest.java
@@ -0,0 +1,390 @@
+/*
+ * 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.tethering;
+
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_AIDL;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.tetheroffload.ForwardedStats;
+import android.hardware.tetheroffload.IOffload;
+import android.hardware.tetheroffload.IPv4AddrPortPair;
+import android.hardware.tetheroffload.ITetheringOffloadCallback;
+import android.hardware.tetheroffload.NatTimeoutUpdate;
+import android.hardware.tetheroffload.NetworkProtocol;
+import android.hardware.tetheroffload.OffloadCallbackEvent;
+import android.os.Handler;
+import android.os.NativeHandle;
+import android.os.ParcelFileDescriptor;
+import android.os.ServiceSpecificException;
+import android.os.test.TestLooper;
+import android.system.OsConstants;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.SharedLog;
+import com.android.networkstack.tethering.OffloadHardwareInterface.OffloadHalCallback;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+import org.mockito.MockitoAnnotations;
+
+import java.io.FileDescriptor;
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class OffloadHalAidlImplTest {
+    private static final String RMNET0 = "test_rmnet_data0";
+
+    private final SharedLog mLog = new SharedLog("test");
+    private final TestLooper mTestLooper = new TestLooper();
+
+    private IOffload mIOffloadMock;
+    private OffloadHalAidlImpl mIOffloadHal;
+    private ITetheringOffloadCallback mTetheringOffloadCallback;
+    private OffloadHalCallback mOffloadHalCallback;
+
+    private void initAndValidateOffloadHal(boolean initSuccess)
+            throws Exception {
+        final FileDescriptor fd1 = new FileDescriptor();
+        final FileDescriptor fd2 = new FileDescriptor();
+        final NativeHandle handle1 = new NativeHandle(fd1, true);
+        final NativeHandle handle2 = new NativeHandle(fd2, true);
+        final ArgumentCaptor<ParcelFileDescriptor> fdCaptor1 =
+                ArgumentCaptor.forClass(ParcelFileDescriptor.class);
+        final ArgumentCaptor<ParcelFileDescriptor> fdCaptor2 =
+                ArgumentCaptor.forClass(ParcelFileDescriptor.class);
+        final ArgumentCaptor<ITetheringOffloadCallback> offloadCallbackCaptor =
+                ArgumentCaptor.forClass(ITetheringOffloadCallback.class);
+        if (initSuccess) {
+            doNothing().when(mIOffloadMock).initOffload(any(), any(), any());
+        } else {
+            doThrow(new IllegalStateException()).when(mIOffloadMock).initOffload(any(), any(),
+                    any());
+        }
+        assertEquals(mIOffloadHal.initOffload(handle1, handle2, mOffloadHalCallback),
+                     initSuccess);
+        verify(mIOffloadMock).initOffload(fdCaptor1.capture(), fdCaptor2.capture(),
+                                          offloadCallbackCaptor.capture());
+        assertEquals(fdCaptor1.getValue().getFd(), fd1.getInt$());
+        assertEquals(fdCaptor2.getValue().getFd(), fd2.getInt$());
+        mTetheringOffloadCallback = offloadCallbackCaptor.getValue();
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mIOffloadMock = mock(IOffload.class);
+        mIOffloadHal = new OffloadHalAidlImpl(OFFLOAD_HAL_VERSION_AIDL, mIOffloadMock,
+                new Handler(mTestLooper.getLooper()), mLog);
+        mOffloadHalCallback = spy(new OffloadHalCallback());
+    }
+
+    @Test
+    public void testInitOffloadSuccess() throws Exception {
+        initAndValidateOffloadHal(true /* initSuccess */);
+    }
+
+    @Test
+    public void testInitOffloadFailure() throws Exception {
+        initAndValidateOffloadHal(false /* initSuccess */);
+    }
+
+    @Test
+    public void testStopOffloadSuccess() throws Exception {
+        initAndValidateOffloadHal(true);
+        doNothing().when(mIOffloadMock).stopOffload();
+        assertTrue(mIOffloadHal.stopOffload());
+        verify(mIOffloadMock).stopOffload();
+    }
+
+    @Test
+    public void testStopOffloadFailure() throws Exception {
+        initAndValidateOffloadHal(true);
+        doThrow(new IllegalStateException()).when(mIOffloadMock).stopOffload();
+        assertFalse(mIOffloadHal.stopOffload());
+    }
+
+    private void doTestGetForwardedStats(boolean expectSuccess) throws Exception {
+        initAndValidateOffloadHal(true);
+        final ForwardedStats returnStats = new ForwardedStats();
+        if (expectSuccess) {
+            returnStats.rxBytes = 12345;
+            returnStats.txBytes = 67890;
+            when(mIOffloadMock.getForwardedStats(anyString())).thenReturn(returnStats);
+        } else {
+            when(mIOffloadMock.getForwardedStats(anyString()))
+                    .thenThrow(new ServiceSpecificException(IOffload.ERROR_CODE_UNUSED));
+        }
+        final OffloadHardwareInterface.ForwardedStats stats =
+                mIOffloadHal.getForwardedStats(RMNET0);
+        verify(mIOffloadMock).getForwardedStats(eq(RMNET0));
+        assertNotNull(stats);
+        assertEquals(stats.rxBytes, returnStats.rxBytes);
+        assertEquals(stats.txBytes, returnStats.txBytes);
+    }
+
+    @Test
+    public void testGetForwardedStatsSuccess() throws Exception {
+        doTestGetForwardedStats(true);
+    }
+
+    @Test
+    public void testGetForwardedStatsFailure() throws Exception {
+        doTestGetForwardedStats(false);
+    }
+
+    private void doTestSetLocalPrefixes(boolean expectSuccess) throws Exception {
+        initAndValidateOffloadHal(true);
+        final ArrayList<String> localPrefixes = new ArrayList<>();
+        localPrefixes.add("127.0.0.0/8");
+        localPrefixes.add("fe80::/64");
+        final String[] localPrefixesArray =
+                localPrefixes.toArray(new String[localPrefixes.size()]);
+        if (expectSuccess) {
+            doNothing().when(mIOffloadMock).setLocalPrefixes(any());
+        } else {
+            doThrow(new IllegalArgumentException()).when(mIOffloadMock).setLocalPrefixes(any());
+        }
+        assertEquals(expectSuccess, mIOffloadHal.setLocalPrefixes(localPrefixes));
+        verify(mIOffloadMock).setLocalPrefixes(eq(localPrefixesArray));
+    }
+
+    @Test
+    public void testSetLocalPrefixesSuccess() throws Exception {
+        doTestSetLocalPrefixes(true);
+    }
+
+    @Test
+    public void testSetLocalPrefixesFailure() throws Exception {
+        doTestSetLocalPrefixes(false);
+    }
+
+    private void doTestSetDataLimit(boolean expectSuccess) throws Exception {
+        initAndValidateOffloadHal(true);
+        final long limit = 12345;
+        if (expectSuccess) {
+            doNothing().when(mIOffloadMock).setDataWarningAndLimit(anyString(), anyLong(),
+                    anyLong());
+        } else {
+            doThrow(new IllegalArgumentException())
+                    .when(mIOffloadMock).setDataWarningAndLimit(anyString(), anyLong(), anyLong());
+        }
+        assertEquals(expectSuccess, mIOffloadHal.setDataLimit(RMNET0, limit));
+        verify(mIOffloadMock).setDataWarningAndLimit(eq(RMNET0), eq(Long.MAX_VALUE), eq(limit));
+    }
+
+    @Test
+    public void testSetDataLimitSuccess() throws Exception {
+        doTestSetDataLimit(true);
+    }
+
+    @Test
+    public void testSetDataLimitFailure() throws Exception {
+        doTestSetDataLimit(false);
+    }
+
+    private void doTestSetDataWarningAndLimit(boolean expectSuccess) throws Exception {
+        initAndValidateOffloadHal(true);
+        final long warning = 12345;
+        final long limit = 67890;
+        if (expectSuccess) {
+            doNothing().when(mIOffloadMock).setDataWarningAndLimit(anyString(), anyLong(),
+                    anyLong());
+        } else {
+            doThrow(new IllegalArgumentException())
+                    .when(mIOffloadMock).setDataWarningAndLimit(anyString(), anyLong(), anyLong());
+        }
+        assertEquals(expectSuccess, mIOffloadHal.setDataWarningAndLimit(RMNET0, warning, limit));
+        verify(mIOffloadMock).setDataWarningAndLimit(eq(RMNET0), eq(warning), eq(limit));
+    }
+
+    @Test
+    public void testSetDataWarningAndLimitSuccess() throws Exception {
+        doTestSetDataWarningAndLimit(true);
+    }
+
+    @Test
+    public void testSetDataWarningAndLimitFailure() throws Exception {
+        doTestSetDataWarningAndLimit(false);
+    }
+
+    private void doTestSetUpstreamParameters(boolean expectSuccess) throws Exception {
+        initAndValidateOffloadHal(true);
+        final String v4addr = "192.168.10.1";
+        final String v4gateway = "192.168.10.255";
+        final ArrayList<String> v6gws = new ArrayList<>(0);
+        v6gws.add("2001:db8::1");
+        String[] v6gwsArray = v6gws.toArray(new String[v6gws.size()]);
+        if (expectSuccess) {
+            doNothing().when(mIOffloadMock).setUpstreamParameters(anyString(), anyString(),
+                    anyString(), any());
+        } else {
+            doThrow(new IllegalArgumentException()).when(mIOffloadMock).setUpstreamParameters(
+                    anyString(), anyString(), anyString(), any());
+        }
+        assertEquals(expectSuccess, mIOffloadHal.setUpstreamParameters(RMNET0, v4addr, v4gateway,
+                  v6gws));
+        verify(mIOffloadMock).setUpstreamParameters(eq(RMNET0), eq(v4addr), eq(v4gateway),
+                  eq(v6gwsArray));
+    }
+
+    @Test
+    public void testSetUpstreamParametersSuccess() throws Exception {
+        doTestSetUpstreamParameters(true);
+    }
+
+    @Test
+    public void testSetUpstreamParametersFailure() throws Exception {
+        doTestSetUpstreamParameters(false);
+    }
+
+    private void doTestAddDownstream(boolean expectSuccess) throws Exception {
+        initAndValidateOffloadHal(true);
+        final String ifName = "wlan1";
+        final String prefix = "192.168.43.0/24";
+        if (expectSuccess) {
+            doNothing().when(mIOffloadMock).addDownstream(anyString(), anyString());
+        } else {
+            doThrow(new IllegalStateException()).when(mIOffloadMock).addDownstream(anyString(),
+                    anyString());
+        }
+        assertEquals(expectSuccess, mIOffloadHal.addDownstream(ifName, prefix));
+        verify(mIOffloadMock).addDownstream(eq(ifName), eq(prefix));
+    }
+
+    @Test
+    public void testAddDownstreamSuccess() throws Exception {
+        doTestAddDownstream(true);
+    }
+
+    @Test
+    public void testAddDownstreamFailure() throws Exception {
+        doTestAddDownstream(false);
+    }
+
+    private void doTestRemoveDownstream(boolean expectSuccess) throws Exception {
+        initAndValidateOffloadHal(true);
+        final String ifName = "wlan1";
+        final String prefix = "192.168.43.0/24";
+        if (expectSuccess) {
+            doNothing().when(mIOffloadMock).removeDownstream(anyString(), anyString());
+        } else {
+            doThrow(new IllegalArgumentException()).when(mIOffloadMock).removeDownstream(
+                    anyString(), anyString());
+        }
+        assertEquals(expectSuccess, mIOffloadHal.removeDownstream(ifName, prefix));
+        verify(mIOffloadMock).removeDownstream(eq(ifName), eq(prefix));
+    }
+
+    @Test
+    public void testRemoveDownstreamSuccess() throws Exception {
+        doTestRemoveDownstream(true);
+    }
+
+    @Test
+    public void testRemoveDownstreamFailure() throws Exception {
+        doTestRemoveDownstream(false);
+    }
+
+    @Test
+    public void testTetheringOffloadCallback() throws Exception {
+        initAndValidateOffloadHal(true);
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED);
+        mTestLooper.dispatchAll();
+        final InOrder inOrder = inOrder(mOffloadHalCallback);
+        inOrder.verify(mOffloadHalCallback).onStarted();
+        inOrder.verifyNoMoreInteractions();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR);
+        mTestLooper.dispatchAll();
+        inOrder.verify(mOffloadHalCallback).onStoppedError();
+        inOrder.verifyNoMoreInteractions();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED);
+        mTestLooper.dispatchAll();
+        inOrder.verify(mOffloadHalCallback).onStoppedUnsupported();
+        inOrder.verifyNoMoreInteractions();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE);
+        mTestLooper.dispatchAll();
+        inOrder.verify(mOffloadHalCallback).onSupportAvailable();
+        inOrder.verifyNoMoreInteractions();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED);
+        mTestLooper.dispatchAll();
+        inOrder.verify(mOffloadHalCallback).onStoppedLimitReached();
+        inOrder.verifyNoMoreInteractions();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_WARNING_REACHED);
+        mTestLooper.dispatchAll();
+        inOrder.verify(mOffloadHalCallback).onWarningReached();
+        inOrder.verifyNoMoreInteractions();
+
+        final NatTimeoutUpdate tcpParams = buildNatTimeoutUpdate(NetworkProtocol.TCP);
+        mTetheringOffloadCallback.updateTimeout(tcpParams);
+        mTestLooper.dispatchAll();
+        inOrder.verify(mOffloadHalCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_TCP),
+                eq(tcpParams.src.addr),
+                eq(tcpParams.src.port),
+                eq(tcpParams.dst.addr),
+                eq(tcpParams.dst.port));
+        inOrder.verifyNoMoreInteractions();
+
+        final NatTimeoutUpdate udpParams = buildNatTimeoutUpdate(NetworkProtocol.UDP);
+        mTetheringOffloadCallback.updateTimeout(udpParams);
+        mTestLooper.dispatchAll();
+        inOrder.verify(mOffloadHalCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_UDP),
+                eq(udpParams.src.addr),
+                eq(udpParams.src.port),
+                eq(udpParams.dst.addr),
+                eq(udpParams.dst.port));
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) {
+        final NatTimeoutUpdate params = new NatTimeoutUpdate();
+        params.proto = proto;
+        params.src = new IPv4AddrPortPair();
+        params.dst = new IPv4AddrPortPair();
+        params.src.addr = "192.168.43.200";
+        params.src.port = 100;
+        params.dst.addr = "172.50.46.169";
+        params.dst.port = 150;
+        return params;
+    }
+}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHalHidlImplTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHalHidlImplTest.java
new file mode 100644
index 0000000..6fdab5a
--- /dev/null
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHalHidlImplTest.java
@@ -0,0 +1,359 @@
+/*
+ * 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.tethering;
+
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_0;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_1;
+import static com.android.networkstack.tethering.util.TetheringUtils.uint16;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
+import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
+import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
+import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
+import android.hardware.tetheroffload.control.V1_1.ITetheringOffloadCallback;
+import android.hardware.tetheroffload.control.V1_1.OffloadCallbackEvent;
+import android.os.Handler;
+import android.os.NativeHandle;
+import android.os.test.TestLooper;
+import android.system.OsConstants;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.SharedLog;
+import com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
+import com.android.networkstack.tethering.OffloadHardwareInterface.OffloadHalCallback;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+import org.mockito.MockitoAnnotations;
+
+import java.io.FileDescriptor;
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class OffloadHalHidlImplTest {
+    private static final String RMNET0 = "test_rmnet_data0";
+
+    private final SharedLog mLog = new SharedLog("test");
+    private final TestLooper mTestLooper = new TestLooper();
+
+    private OffloadHalHidlImpl mIOffloadHal;
+    private IOffloadConfig mIOffloadConfigMock;
+    private IOffloadControl mIOffloadControlMock;
+    private ITetheringOffloadCallback mTetheringOffloadCallback;
+    private OffloadHalCallback mOffloadHalCallback;
+
+    private void createAndInitOffloadHal(int version) throws Exception {
+        final FileDescriptor fd1 = new FileDescriptor();
+        final FileDescriptor fd2 = new FileDescriptor();
+        final NativeHandle handle1 = new NativeHandle(fd1, true);
+        final NativeHandle handle2 = new NativeHandle(fd2, true);
+        mIOffloadConfigMock = mock(IOffloadConfig.class);
+        switch (version) {
+            case OFFLOAD_HAL_VERSION_HIDL_1_0:
+                mIOffloadControlMock = mock(IOffloadControl.class);
+                break;
+            case OFFLOAD_HAL_VERSION_HIDL_1_1:
+                mIOffloadControlMock = mock(
+                        android.hardware.tetheroffload.control.V1_1.IOffloadControl.class);
+                break;
+            default:
+                fail("Nonexistent HAL version");
+                return;
+        }
+        mIOffloadHal = new OffloadHalHidlImpl(version, mIOffloadConfigMock,
+                mIOffloadControlMock, new Handler(mTestLooper.getLooper()), mLog);
+        mIOffloadHal.initOffload(handle1, handle2, mOffloadHalCallback);
+
+        final ArgumentCaptor<NativeHandle> nativeHandleCaptor1 =
+                ArgumentCaptor.forClass(NativeHandle.class);
+        final ArgumentCaptor<NativeHandle> nativeHandleCaptor2 =
+                ArgumentCaptor.forClass(NativeHandle.class);
+        final ArgumentCaptor<ITetheringOffloadCallback> offloadCallbackCaptor =
+                ArgumentCaptor.forClass(ITetheringOffloadCallback.class);
+        verify(mIOffloadConfigMock).setHandles(nativeHandleCaptor1.capture(),
+                nativeHandleCaptor2.capture(), any());
+        verify(mIOffloadControlMock).initOffload(offloadCallbackCaptor.capture(), any());
+        assertEquals(nativeHandleCaptor1.getValue().getFileDescriptor().getInt$(),
+                handle1.getFileDescriptor().getInt$());
+        assertEquals(nativeHandleCaptor2.getValue().getFileDescriptor().getInt$(),
+                handle2.getFileDescriptor().getInt$());
+        mTetheringOffloadCallback = offloadCallbackCaptor.getValue();
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mOffloadHalCallback = spy(new OffloadHalCallback());
+    }
+
+    @Test
+    public void testGetForwardedStats() throws Exception {
+        createAndInitOffloadHal(OFFLOAD_HAL_VERSION_HIDL_1_0);
+        final long rxBytes = 12345;
+        final long txBytes = 67890;
+        doAnswer(invocation -> {
+            ((IOffloadControl.getForwardedStatsCallback) invocation.getArgument(1))
+                    .onValues(rxBytes, txBytes);
+            return null;
+        }).when(mIOffloadControlMock).getForwardedStats(eq(RMNET0), any());
+        final ForwardedStats stats = mIOffloadHal.getForwardedStats(RMNET0);
+        verify(mIOffloadControlMock).getForwardedStats(eq(RMNET0), any());
+        assertNotNull(stats);
+        assertEquals(rxBytes, stats.rxBytes);
+        assertEquals(txBytes, stats.txBytes);
+    }
+
+    private void doTestSetLocalPrefixes(boolean expectSuccess) throws Exception {
+        createAndInitOffloadHal(OFFLOAD_HAL_VERSION_HIDL_1_0);
+        final ArrayList<String> localPrefixes = new ArrayList<>();
+        localPrefixes.add("127.0.0.0/8");
+        localPrefixes.add("fe80::/64");
+        doAnswer(invocation -> {
+            ((IOffloadControl.setLocalPrefixesCallback) invocation.getArgument(1))
+                    .onValues(expectSuccess, "");
+            return null;
+        }).when(mIOffloadControlMock).setLocalPrefixes(eq(localPrefixes), any());
+        assertEquals(expectSuccess, mIOffloadHal.setLocalPrefixes(localPrefixes));
+        verify(mIOffloadControlMock).setLocalPrefixes(eq(localPrefixes), any());
+    }
+
+    @Test
+    public void testSetLocalPrefixesSuccess() throws Exception {
+        doTestSetLocalPrefixes(true);
+    }
+
+    @Test
+    public void testSetLocalPrefixesFailure() throws Exception {
+        doTestSetLocalPrefixes(false);
+    }
+
+    private void doTestSetDataLimit(boolean expectSuccess) throws Exception {
+        createAndInitOffloadHal(OFFLOAD_HAL_VERSION_HIDL_1_0);
+        final long limit = 12345;
+        doAnswer(invocation -> {
+            ((IOffloadControl.setDataLimitCallback) invocation.getArgument(2))
+                    .onValues(expectSuccess, "");
+            return null;
+        }).when(mIOffloadControlMock).setDataLimit(eq(RMNET0), eq(limit), any());
+        assertEquals(expectSuccess, mIOffloadHal.setDataLimit(RMNET0, limit));
+        verify(mIOffloadControlMock).setDataLimit(eq(RMNET0), eq(limit), any());
+    }
+
+    @Test
+    public void testSetDataLimitSuccess() throws Exception {
+        doTestSetDataLimit(true);
+    }
+
+    @Test
+    public void testSetDataLimitFailure() throws Exception {
+        doTestSetDataLimit(false);
+    }
+
+    private void doTestSetDataWarningAndLimit(boolean expectSuccess) throws Exception {
+        createAndInitOffloadHal(OFFLOAD_HAL_VERSION_HIDL_1_1);
+        final long warning = 12345;
+        final long limit = 67890;
+        doAnswer(invocation -> {
+            ((android.hardware.tetheroffload.control.V1_1.IOffloadControl
+                    .setDataWarningAndLimitCallback) invocation.getArgument(3))
+                    .onValues(expectSuccess, "");
+            return null;
+        }).when((android.hardware.tetheroffload.control.V1_1.IOffloadControl) mIOffloadControlMock)
+                .setDataWarningAndLimit(eq(RMNET0), eq(warning), eq(limit), any());
+        assertEquals(expectSuccess, mIOffloadHal.setDataWarningAndLimit(RMNET0, warning, limit));
+        verify((android.hardware.tetheroffload.control.V1_1.IOffloadControl) mIOffloadControlMock)
+                .setDataWarningAndLimit(eq(RMNET0), eq(warning), eq(limit), any());
+    }
+
+    @Test
+    public void testSetDataWarningAndLimitSuccess() throws Exception {
+        doTestSetDataWarningAndLimit(true);
+    }
+
+    @Test
+    public void testSetDataWarningAndLimitFailure() throws Exception {
+        // Verify that V1.0 control HAL would reject the function call with exception.
+        createAndInitOffloadHal(OFFLOAD_HAL_VERSION_HIDL_1_0);
+        final long warning = 12345;
+        final long limit = 67890;
+        assertThrows(UnsupportedOperationException.class,
+                () -> mIOffloadHal.setDataWarningAndLimit(RMNET0, warning, limit));
+
+        doTestSetDataWarningAndLimit(false);
+    }
+
+    private void doTestSetUpstreamParameters(boolean expectSuccess) throws Exception {
+        createAndInitOffloadHal(OFFLOAD_HAL_VERSION_HIDL_1_0);
+        final String v4addr = "192.168.10.1";
+        final String v4gateway = "192.168.10.255";
+        final ArrayList<String> v6gws = new ArrayList<>(0);
+        v6gws.add("2001:db8::1");
+        doAnswer(invocation -> {
+            ((IOffloadControl.setUpstreamParametersCallback) invocation.getArgument(4))
+                    .onValues(expectSuccess, "");
+            return null;
+        }).when(mIOffloadControlMock).setUpstreamParameters(eq(RMNET0), eq(v4addr), eq(v4gateway),
+                eq(v6gws), any());
+        assertEquals(expectSuccess, mIOffloadHal.setUpstreamParameters(RMNET0, v4addr, v4gateway,
+                v6gws));
+        verify(mIOffloadControlMock).setUpstreamParameters(eq(RMNET0), eq(v4addr), eq(v4gateway),
+                eq(v6gws), any());
+    }
+
+    @Test
+    public void testSetUpstreamParametersSuccess() throws Exception {
+        doTestSetUpstreamParameters(true);
+    }
+
+    @Test
+    public void testSetUpstreamParametersFailure() throws Exception {
+        doTestSetUpstreamParameters(false);
+    }
+
+    private void doTestAddDownstream(boolean expectSuccess) throws Exception {
+        createAndInitOffloadHal(OFFLOAD_HAL_VERSION_HIDL_1_0);
+        final String ifName = "wlan1";
+        final String prefix = "192.168.43.0/24";
+        doAnswer(invocation -> {
+            ((IOffloadControl.addDownstreamCallback) invocation.getArgument(2))
+                    .onValues(expectSuccess, "");
+            return null;
+        }).when(mIOffloadControlMock).addDownstream(eq(ifName), eq(prefix), any());
+        assertEquals(expectSuccess, mIOffloadHal.addDownstream(ifName, prefix));
+        verify(mIOffloadControlMock).addDownstream(eq(ifName), eq(prefix), any());
+    }
+
+    @Test
+    public void testAddDownstreamSuccess() throws Exception {
+        doTestAddDownstream(true);
+    }
+
+    @Test
+    public void testAddDownstreamFailure() throws Exception {
+        doTestAddDownstream(false);
+    }
+
+    private void doTestRemoveDownstream(boolean expectSuccess) throws Exception {
+        createAndInitOffloadHal(OFFLOAD_HAL_VERSION_HIDL_1_0);
+        final String ifName = "wlan1";
+        final String prefix = "192.168.43.0/24";
+        doAnswer(invocation -> {
+            ((IOffloadControl.removeDownstreamCallback) invocation.getArgument(2))
+                    .onValues(expectSuccess, "");
+            return null;
+        }).when(mIOffloadControlMock).removeDownstream(eq(ifName), eq(prefix), any());
+        assertEquals(expectSuccess, mIOffloadHal.removeDownstream(ifName, prefix));
+        verify(mIOffloadControlMock).removeDownstream(eq(ifName), eq(prefix), any());
+    }
+
+    @Test
+    public void testRemoveDownstreamSuccess() throws Exception {
+        doTestRemoveDownstream(true);
+    }
+
+    @Test
+    public void testRemoveDownstreamFailure() throws Exception {
+        doTestRemoveDownstream(false);
+    }
+
+    @Test
+    public void testTetheringOffloadCallback() throws Exception {
+        createAndInitOffloadHal(OFFLOAD_HAL_VERSION_HIDL_1_0);
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED);
+        mTestLooper.dispatchAll();
+        verify(mOffloadHalCallback).onStarted();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR);
+        mTestLooper.dispatchAll();
+        verify(mOffloadHalCallback).onStoppedError();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED);
+        mTestLooper.dispatchAll();
+        verify(mOffloadHalCallback).onStoppedUnsupported();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE);
+        mTestLooper.dispatchAll();
+        verify(mOffloadHalCallback).onSupportAvailable();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED);
+        mTestLooper.dispatchAll();
+        verify(mOffloadHalCallback).onStoppedLimitReached();
+
+        final NatTimeoutUpdate tcpParams = buildNatTimeoutUpdate(NetworkProtocol.TCP);
+        mTetheringOffloadCallback.updateTimeout(tcpParams);
+        mTestLooper.dispatchAll();
+        verify(mOffloadHalCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_TCP),
+                eq(tcpParams.src.addr),
+                eq(uint16(tcpParams.src.port)),
+                eq(tcpParams.dst.addr),
+                eq(uint16(tcpParams.dst.port)));
+
+        final NatTimeoutUpdate udpParams = buildNatTimeoutUpdate(NetworkProtocol.UDP);
+        mTetheringOffloadCallback.updateTimeout(udpParams);
+        mTestLooper.dispatchAll();
+        verify(mOffloadHalCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_UDP),
+                eq(udpParams.src.addr),
+                eq(uint16(udpParams.src.port)),
+                eq(udpParams.dst.addr),
+                eq(uint16(udpParams.dst.port)));
+        reset(mOffloadHalCallback);
+
+        createAndInitOffloadHal(OFFLOAD_HAL_VERSION_HIDL_1_1);
+
+        // Verify the interface will process the events that comes from V1.1 HAL.
+        mTetheringOffloadCallback.onEvent_1_1(OffloadCallbackEvent.OFFLOAD_STARTED);
+        mTestLooper.dispatchAll();
+        final InOrder inOrder = inOrder(mOffloadHalCallback);
+        inOrder.verify(mOffloadHalCallback).onStarted();
+        inOrder.verifyNoMoreInteractions();
+
+        mTetheringOffloadCallback.onEvent_1_1(OffloadCallbackEvent.OFFLOAD_WARNING_REACHED);
+        mTestLooper.dispatchAll();
+        inOrder.verify(mOffloadHalCallback).onWarningReached();
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) {
+        final NatTimeoutUpdate params = new NatTimeoutUpdate();
+        params.proto = proto;
+        params.src.addr = "192.168.43.200";
+        params.src.port = 100;
+        params.dst.addr = "172.50.46.169";
+        params.dst.port = 150;
+        return params;
+    }
+}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
index 36b439b..b1f875b 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
@@ -20,36 +20,29 @@
 import static android.system.OsConstants.AF_UNIX;
 import static android.system.OsConstants.SOCK_STREAM;
 
-import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0;
-import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_1;
-import static com.android.networkstack.tethering.util.TetheringUtils.uint16;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_AIDL;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_0;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_1;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
-import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
-import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
-import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
-import android.hardware.tetheroffload.control.V1_1.ITetheringOffloadCallback;
-import android.hardware.tetheroffload.control.V1_1.OffloadCallbackEvent;
 import android.os.Handler;
 import android.os.NativeHandle;
 import android.os.test.TestLooper;
 import android.system.ErrnoException;
 import android.system.Os;
-import android.system.OsConstants;
-import android.util.Pair;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -57,12 +50,13 @@
 import com.android.net.module.util.SharedLog;
 import com.android.net.module.util.netlink.StructNfGenMsg;
 import com.android.net.module.util.netlink.StructNlMsgHdr;
+import com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
+import com.android.networkstack.tethering.OffloadHardwareInterface.OffloadHalCallback;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -79,11 +73,9 @@
     private final TestLooper mTestLooper = new TestLooper();
 
     private OffloadHardwareInterface mOffloadHw;
-    private ITetheringOffloadCallback mTetheringOffloadCallback;
-    private OffloadHardwareInterface.ControlCallback mControlCallback;
+    private OffloadHalCallback mOffloadHalCallback;
 
-    @Mock private IOffloadConfig mIOffloadConfig;
-    private IOffloadControl mIOffloadControl;
+    @Mock private IOffloadHal mIOffload;
     @Mock private NativeHandle mNativeHandle;
 
     // Random values to test Netlink message.
@@ -91,32 +83,16 @@
     private static final short TEST_FLAGS = 263;
 
     class MyDependencies extends OffloadHardwareInterface.Dependencies {
-        private final int mMockControlVersion;
-        MyDependencies(SharedLog log, final int mockControlVersion) {
-            super(log);
-            mMockControlVersion = mockControlVersion;
+        private final int mMockOffloadHalVersion;
+        MyDependencies(Handler handler, SharedLog log, final int mockOffloadHalVersion) {
+            super(handler, log);
+            mMockOffloadHalVersion = mockOffloadHalVersion;
+            when(mIOffload.getVersion()).thenReturn(mMockOffloadHalVersion);
         }
 
         @Override
-        public IOffloadConfig getOffloadConfig() {
-            return mIOffloadConfig;
-        }
-
-        @Override
-        public Pair<IOffloadControl, Integer> getOffloadControl() {
-            switch (mMockControlVersion) {
-                case OFFLOAD_HAL_VERSION_1_0:
-                    mIOffloadControl = mock(IOffloadControl.class);
-                    break;
-                case OFFLOAD_HAL_VERSION_1_1:
-                    mIOffloadControl =
-                            mock(android.hardware.tetheroffload.control.V1_1.IOffloadControl.class);
-                    break;
-                default:
-                    throw new IllegalArgumentException("Invalid offload control version "
-                            + mMockControlVersion);
-            }
-            return new Pair<IOffloadControl, Integer>(mIOffloadControl, mMockControlVersion);
+        public IOffloadHal getOffload() {
+            return mMockOffloadHalVersion == OFFLOAD_HAL_VERSION_NONE ? null : mIOffload;
         }
 
         @Override
@@ -128,156 +104,140 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mControlCallback = spy(new OffloadHardwareInterface.ControlCallback());
+        mOffloadHalCallback = new OffloadHalCallback();
+        when(mIOffload.initOffload(any(NativeHandle.class), any(NativeHandle.class),
+                any(OffloadHalCallback.class))).thenReturn(true);
     }
 
-    private void startOffloadHardwareInterface(int controlVersion) throws Exception {
+    private void startOffloadHardwareInterface(int offloadHalVersion)
+            throws Exception {
         final SharedLog log = new SharedLog("test");
-        mOffloadHw = new OffloadHardwareInterface(new Handler(mTestLooper.getLooper()), log,
-                new MyDependencies(log, controlVersion));
-        mOffloadHw.initOffloadConfig();
-        mOffloadHw.initOffloadControl(mControlCallback);
-        final ArgumentCaptor<ITetheringOffloadCallback> mOffloadCallbackCaptor =
-                ArgumentCaptor.forClass(ITetheringOffloadCallback.class);
-        verify(mIOffloadControl).initOffload(mOffloadCallbackCaptor.capture(), any());
-        mTetheringOffloadCallback = mOffloadCallbackCaptor.getValue();
+        final Handler handler = new Handler(mTestLooper.getLooper());
+        final int num = offloadHalVersion != OFFLOAD_HAL_VERSION_NONE ? 1 : 0;
+        mOffloadHw = new OffloadHardwareInterface(handler, log,
+                new MyDependencies(handler, log, offloadHalVersion));
+        assertEquals(offloadHalVersion, mOffloadHw.initOffload(mOffloadHalCallback));
+        verify(mIOffload, times(num)).initOffload(any(NativeHandle.class), any(NativeHandle.class),
+                eq(mOffloadHalCallback));
+    }
+
+    @Test
+    public void testInitFailureWithNoHal() throws Exception {
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_NONE);
+    }
+
+    @Test
+    public void testInitSuccessWithAidl() throws Exception {
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_AIDL);
+    }
+
+    @Test
+    public void testInitSuccessWithHidl_1_0() throws Exception {
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+    }
+
+    @Test
+    public void testInitSuccessWithHidl_1_1() throws Exception {
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_1);
     }
 
     @Test
     public void testGetForwardedStats() throws Exception {
-        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
-        final OffloadHardwareInterface.ForwardedStats stats = mOffloadHw.getForwardedStats(RMNET0);
-        verify(mIOffloadControl).getForwardedStats(eq(RMNET0), any());
-        assertNotNull(stats);
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+        ForwardedStats stats = new ForwardedStats(12345, 56780);
+        when(mIOffload.getForwardedStats(anyString())).thenReturn(stats);
+        assertEquals(mOffloadHw.getForwardedStats(RMNET0), stats);
+        verify(mIOffload).getForwardedStats(eq(RMNET0));
     }
 
     @Test
     public void testSetLocalPrefixes() throws Exception {
-        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
         final ArrayList<String> localPrefixes = new ArrayList<>();
         localPrefixes.add("127.0.0.0/8");
         localPrefixes.add("fe80::/64");
-        mOffloadHw.setLocalPrefixes(localPrefixes);
-        verify(mIOffloadControl).setLocalPrefixes(eq(localPrefixes), any());
+        when(mIOffload.setLocalPrefixes(any())).thenReturn(true);
+        assertTrue(mOffloadHw.setLocalPrefixes(localPrefixes));
+        verify(mIOffload).setLocalPrefixes(eq(localPrefixes));
+        when(mIOffload.setLocalPrefixes(any())).thenReturn(false);
+        assertFalse(mOffloadHw.setLocalPrefixes(localPrefixes));
     }
 
     @Test
     public void testSetDataLimit() throws Exception {
-        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
         final long limit = 12345;
-        mOffloadHw.setDataLimit(RMNET0, limit);
-        verify(mIOffloadControl).setDataLimit(eq(RMNET0), eq(limit), any());
+        when(mIOffload.setDataLimit(anyString(), anyLong())).thenReturn(true);
+        assertTrue(mOffloadHw.setDataLimit(RMNET0, limit));
+        verify(mIOffload).setDataLimit(eq(RMNET0), eq(limit));
+        when(mIOffload.setDataLimit(anyString(), anyLong())).thenReturn(false);
+        assertFalse(mOffloadHw.setDataLimit(RMNET0, limit));
+    }
+
+    @Test
+    public void testSetDataWarningAndLimitFailureWithHidl_1_0() throws Exception {
+        // Verify V1.0 control HAL would reject the function call with exception.
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
+        final long warning = 12345;
+        final long limit = 67890;
+        assertThrows(UnsupportedOperationException.class,
+                () -> mOffloadHw.setDataWarningAndLimit(RMNET0, warning, limit));
     }
 
     @Test
     public void testSetDataWarningAndLimit() throws Exception {
-        // Verify V1.0 control HAL would reject the function call with exception.
-        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
+        // Verify V1.1 control HAL could receive this function call.
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_1);
         final long warning = 12345;
         final long limit = 67890;
-        assertThrows(IllegalArgumentException.class,
-                () -> mOffloadHw.setDataWarningAndLimit(RMNET0, warning, limit));
-        reset(mIOffloadControl);
-
-        // Verify V1.1 control HAL could receive this function call.
-        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_1);
-        mOffloadHw.setDataWarningAndLimit(RMNET0, warning, limit);
-        verify((android.hardware.tetheroffload.control.V1_1.IOffloadControl) mIOffloadControl)
-                .setDataWarningAndLimit(eq(RMNET0), eq(warning), eq(limit), any());
+        when(mIOffload.setDataWarningAndLimit(anyString(), anyLong(), anyLong())).thenReturn(true);
+        assertTrue(mOffloadHw.setDataWarningAndLimit(RMNET0, warning, limit));
+        verify(mIOffload).setDataWarningAndLimit(eq(RMNET0), eq(warning), eq(limit));
+        when(mIOffload.setDataWarningAndLimit(anyString(), anyLong(), anyLong())).thenReturn(false);
+        assertFalse(mOffloadHw.setDataWarningAndLimit(RMNET0, warning, limit));
     }
 
     @Test
     public void testSetUpstreamParameters() throws Exception {
-        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
         final String v4addr = "192.168.10.1";
         final String v4gateway = "192.168.10.255";
         final ArrayList<String> v6gws = new ArrayList<>(0);
         v6gws.add("2001:db8::1");
-        mOffloadHw.setUpstreamParameters(RMNET0, v4addr, v4gateway, v6gws);
-        verify(mIOffloadControl).setUpstreamParameters(eq(RMNET0), eq(v4addr), eq(v4gateway),
-                eq(v6gws), any());
+        when(mIOffload.setUpstreamParameters(anyString(), anyString(), anyString(), any()))
+                .thenReturn(true);
+        assertTrue(mOffloadHw.setUpstreamParameters(RMNET0, v4addr, v4gateway, v6gws));
+        verify(mIOffload).setUpstreamParameters(eq(RMNET0), eq(v4addr), eq(v4gateway), eq(v6gws));
 
         final ArgumentCaptor<ArrayList<String>> mArrayListCaptor =
                 ArgumentCaptor.forClass(ArrayList.class);
-        mOffloadHw.setUpstreamParameters(null, null, null, null);
-        verify(mIOffloadControl).setUpstreamParameters(eq(""), eq(""), eq(""),
-                mArrayListCaptor.capture(), any());
+        when(mIOffload.setUpstreamParameters(anyString(), anyString(), anyString(), any()))
+                .thenReturn(false);
+        assertFalse(mOffloadHw.setUpstreamParameters(null, null, null, null));
+        verify(mIOffload).setUpstreamParameters(eq(""), eq(""), eq(""), mArrayListCaptor.capture());
         assertEquals(mArrayListCaptor.getValue().size(), 0);
     }
 
     @Test
-    public void testUpdateDownstreamPrefix() throws Exception {
-        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
+    public void testUpdateDownstream() throws Exception {
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
         final String ifName = "wlan1";
         final String prefix = "192.168.43.0/24";
-        mOffloadHw.addDownstreamPrefix(ifName, prefix);
-        verify(mIOffloadControl).addDownstream(eq(ifName), eq(prefix), any());
-
-        mOffloadHw.removeDownstreamPrefix(ifName, prefix);
-        verify(mIOffloadControl).removeDownstream(eq(ifName), eq(prefix), any());
-    }
-
-    @Test
-    public void testTetheringOffloadCallback() throws Exception {
-        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
-
-        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED);
-        mTestLooper.dispatchAll();
-        verify(mControlCallback).onStarted();
-
-        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR);
-        mTestLooper.dispatchAll();
-        verify(mControlCallback).onStoppedError();
-
-        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED);
-        mTestLooper.dispatchAll();
-        verify(mControlCallback).onStoppedUnsupported();
-
-        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE);
-        mTestLooper.dispatchAll();
-        verify(mControlCallback).onSupportAvailable();
-
-        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED);
-        mTestLooper.dispatchAll();
-        verify(mControlCallback).onStoppedLimitReached();
-
-        final NatTimeoutUpdate tcpParams = buildNatTimeoutUpdate(NetworkProtocol.TCP);
-        mTetheringOffloadCallback.updateTimeout(tcpParams);
-        mTestLooper.dispatchAll();
-        verify(mControlCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_TCP),
-                eq(tcpParams.src.addr),
-                eq(uint16(tcpParams.src.port)),
-                eq(tcpParams.dst.addr),
-                eq(uint16(tcpParams.dst.port)));
-
-        final NatTimeoutUpdate udpParams = buildNatTimeoutUpdate(NetworkProtocol.UDP);
-        mTetheringOffloadCallback.updateTimeout(udpParams);
-        mTestLooper.dispatchAll();
-        verify(mControlCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_UDP),
-                eq(udpParams.src.addr),
-                eq(uint16(udpParams.src.port)),
-                eq(udpParams.dst.addr),
-                eq(uint16(udpParams.dst.port)));
-        reset(mControlCallback);
-
-        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_1);
-
-        // Verify the interface will process the events that comes from V1.1 HAL.
-        mTetheringOffloadCallback.onEvent_1_1(OffloadCallbackEvent.OFFLOAD_STARTED);
-        mTestLooper.dispatchAll();
-        final InOrder inOrder = inOrder(mControlCallback);
-        inOrder.verify(mControlCallback).onStarted();
-        inOrder.verifyNoMoreInteractions();
-
-        mTetheringOffloadCallback.onEvent_1_1(OffloadCallbackEvent.OFFLOAD_WARNING_REACHED);
-        mTestLooper.dispatchAll();
-        inOrder.verify(mControlCallback).onWarningReached();
-        inOrder.verifyNoMoreInteractions();
+        when(mIOffload.addDownstream(anyString(), anyString())).thenReturn(true);
+        assertTrue(mOffloadHw.addDownstream(ifName, prefix));
+        verify(mIOffload).addDownstream(eq(ifName), eq(prefix));
+        when(mIOffload.addDownstream(anyString(), anyString())).thenReturn(false);
+        assertFalse(mOffloadHw.addDownstream(ifName, prefix));
+        when(mIOffload.removeDownstream(anyString(), anyString())).thenReturn(true);
+        assertTrue(mOffloadHw.removeDownstream(ifName, prefix));
+        verify(mIOffload).removeDownstream(eq(ifName), eq(prefix));
+        when(mIOffload.removeDownstream(anyString(), anyString())).thenReturn(false);
+        assertFalse(mOffloadHw.removeDownstream(ifName, prefix));
     }
 
     @Test
     public void testSendIpv4NfGenMsg() throws Exception {
-        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
+        startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_HIDL_1_0);
         FileDescriptor writeSocket = new FileDescriptor();
         FileDescriptor readSocket = new FileDescriptor();
         try {
@@ -308,14 +268,4 @@
         assertEquals(0 /* error */, buffer.getShort());  // res_id
         assertEquals(expectedLen, buffer.position());
     }
-
-    private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) {
-        final NatTimeoutUpdate params = new NatTimeoutUpdate();
-        params.proto = proto;
-        params.src.addr = "192.168.43.200";
-        params.src.port = 100;
-        params.dst.addr = "172.50.46.169";
-        params.dst.port = 150;
-        return params;
-    }
 }
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 79590b7..adb1590 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -68,7 +68,7 @@
 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
 import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
 import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
-import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_0;
 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE;
 import static com.android.networkstack.tethering.TestConnectivityManager.BROADCAST_FIRST;
 import static com.android.networkstack.tethering.TestConnectivityManager.CALLBACKS_FIRST;
@@ -649,8 +649,7 @@
         mInterfaceConfiguration.flags = new String[0];
         when(mRouterAdvertisementDaemon.start())
                 .thenReturn(true);
-        initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0,
-                0 /* defaultDisabled */);
+        initOffloadConfiguration(OFFLOAD_HAL_VERSION_HIDL_1_0, 0 /* defaultDisabled */);
         when(mOffloadHardwareInterface.getForwardedStats(any())).thenReturn(mForwardedStats);
 
         mServiceContext = new TestContext(mContext);
@@ -2345,25 +2344,15 @@
         mLooper.dispatchAll();
         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
 
-        // 1. Offload fail if no OffloadConfig.
-        initOffloadConfiguration(false /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0,
-                0 /* defaultDisabled */);
+        // 1. Offload fail if no IOffloadHal.
+        initOffloadConfiguration(OFFLOAD_HAL_VERSION_NONE, 0 /* defaultDisabled */);
         runUsbTethering(upstreamState);
         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
         runStopUSBTethering();
         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
         reset(mUsbManager, mIPv6TetheringCoordinator);
-        // 2. Offload fail if no OffloadControl.
-        initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_NONE,
-                0 /* defaultDisabled */);
-        runUsbTethering(upstreamState);
-        callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
-        runStopUSBTethering();
-        callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
-        reset(mUsbManager, mIPv6TetheringCoordinator);
-        // 3. Offload fail if disabled by settings.
-        initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0,
-                1 /* defaultDisabled */);
+        // 2. Offload fail if disabled by settings.
+        initOffloadConfiguration(OFFLOAD_HAL_VERSION_HIDL_1_0, 1 /* defaultDisabled */);
         runUsbTethering(upstreamState);
         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
         runStopUSBTethering();
@@ -2378,11 +2367,10 @@
         verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE);
     }
 
-    private void initOffloadConfiguration(final boolean offloadConfig,
-            @OffloadHardwareInterface.OffloadHalVersion final int offloadControlVersion,
+    private void initOffloadConfiguration(
+            @OffloadHardwareInterface.OffloadHalVersion final int offloadHalVersion,
             final int defaultDisabled) {
-        when(mOffloadHardwareInterface.initOffloadConfig()).thenReturn(offloadConfig);
-        when(mOffloadHardwareInterface.initOffloadControl(any())).thenReturn(offloadControlVersion);
+        when(mOffloadHardwareInterface.initOffload(any())).thenReturn(offloadHalVersion);
         when(mOffloadHardwareInterface.getDefaultTetherOffloadDisabled()).thenReturn(
                 defaultDisabled);
     }
diff --git a/bpf_progs/clatd.c b/bpf_progs/clatd.c
index 7350209..7c6811a 100644
--- a/bpf_progs/clatd.c
+++ b/bpf_progs/clatd.c
@@ -91,6 +91,12 @@
     if (ip6->version != 6) return TC_ACT_PIPE;
 
     // Maximum IPv6 payload length that can be translated to IPv4
+    // Note: technically this check is too strict for an IPv6 fragment,
+    // which by virtue of stripping the extra 8 byte fragment extension header,
+    // could thus be 8 bytes larger and still fit in an ipv4 packet post
+    // translation.  However... who ever heard of receiving ~64KB frags...
+    // fragments are kind of by definition smaller than ingress device mtu,
+    // and thus, on the internet, very very unlikely to exceed 1500 bytes.
     if (ntohs(ip6->payload_len) > 0xFFFF - sizeof(struct iphdr)) return TC_ACT_PIPE;
 
     ClatIngress6Key k = {
diff --git a/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/Android.bp b/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/Android.bp
index 284d5c2..ec0392c 100644
--- a/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/Android.bp
+++ b/nearby/tests/multidevices/clients/test_support/snippet_helper/tests/Android.bp
@@ -35,4 +35,5 @@
         // timeout in seconds.
         timeout: 36000,
     },
-}
\ No newline at end of file
+    upstream: true,
+}
diff --git a/nearby/tests/robotests/Android.bp b/nearby/tests/robotests/Android.bp
index 56c0107..70fa0c3 100644
--- a/nearby/tests/robotests/Android.bp
+++ b/nearby/tests/robotests/Android.bp
@@ -42,15 +42,14 @@
         "androidx.lifecycle_lifecycle-runtime",
         "androidx.mediarouter_mediarouter-nodeps",
         "error_prone_annotations",
-        "mockito-robolectric-prebuilt",
         "service-nearby-pre-jarjar",
         "truth-prebuilt",
         "robolectric_android-all-stub",
-        "Robolectric_all-target",
     ],
 
     test_options: {
         // timeout in seconds.
         timeout: 36000,
     },
+    upstream: true,
 }
diff --git a/service/src/com/android/metrics/stats.proto b/service/src/com/android/metrics/stats.proto
index 8104632..006d20a 100644
--- a/service/src/com/android/metrics/stats.proto
+++ b/service/src/com/android/metrics/stats.proto
@@ -347,3 +347,89 @@
     // How long(in seconds) this slice has been connected
     optional int32 slice_connection_duration_sec = 6;
 }
+
+/**
+ *  Logs DailykeepaliveInfoReported
+ *
+ * Logs from: packages/modules/Connectivity/service/src/com/android/
+ *            server/connectivity/AutomaticOnOffKeepaliveTracker.
+ */
+message DailykeepaliveInfoReported{
+    // Daily duration per number of concurrent keepalive
+    optional DurationPerNumOfKeepalive duration_per_num_of_keepalive = 1;
+
+    // Daily keepalive registered/active duration on each list of keepalive session, in
+    // milli-seconds
+    optional KeepaliveLifetimePerCarrier keepalive_lifetime_per_carrier = 2;
+
+    // Daily number of keepalive requests
+    optional int32 keepalive_requests = 3;
+
+    // Daily number of automatic keepalive requests
+    optional int32 automatic_keepalive_requests = 4;
+
+    // Daily number of distinct apps that requested keepalives
+    optional int32 distinct_user_count = 5;
+
+    // Daily distinct apps uid list that requested keepalives
+    repeated int32 uid = 6;
+}
+
+/**
+ * Daily duration per number of concurrent keepalive
+ *
+ * Logs from: packages/modules/Connectivity/service/src/com/android/
+ *            server/connectivity/AutomaticOnOffKeepaliveTracker.
+ */
+message DurationPerNumOfKeepalive {
+    repeated DurationForNumOfKeepalive duration_for_num_of_keepalive = 1;
+}
+
+message DurationForNumOfKeepalive {
+    // The number of concurrent keepalives is in the device
+    optional int32 num_of_keepalive = 1;
+
+    // How many milliseconds the device has keepalive registration number is num_of_keepalive
+    optional int32 keepalive_registered_durations_msec = 2;
+
+    // How many milliseconds the device has keepalive active(not paused) number is num_of_keepalive
+    optional int32 keepalive_active_durations_msec = 3;
+}
+
+/**
+ * Daily keepalive registered/active duration on each list of Keepalive session, in milli-seconds
+ *
+ * Logs from: packages/modules/Connectivity/service/src/com/android/
+ *            server/connectivity/AutomaticOnOffKeepaliveTracker.
+ */
+message KeepaliveLifetimePerCarrier {
+    // The number of network count on each list of carriers
+    repeated KeepaliveLifetimeForCarrier keepalive_lifetime_for_carrier = 1;
+}
+
+/**
+ * Logs the keepalive registered/active duration in milli-seconds and carrier
+ * info(carrier id, transport, keepalive interval).
+ *
+ * Logs from: packages/modules/Connectivity/service/src/com/android/
+ *            server/connectivity/AutomaticOnOffKeepaliveTracker.
+ */
+message KeepaliveLifetimeForCarrier {
+    // The carrier ID for each keepalive, or TelephonyManager.UNKNOWN_CARRIER_ID(-1) if not cell
+    optional int32 carrier_id = 1;
+
+    // The transport types of the underlying network for each keepalive. A network may include
+    // multiple transport types. Each transfer type is represented by a different bit, defined in
+    // packages/modules/Connectivity/framework/src/android/net/NetworkCapabilities.java
+    optional int32 transport_types = 2;
+
+    // The keepalive interval for each keepalive
+    optional int32 intervals_msec = 3;
+
+    // The lifetime of the keepalive registered today
+    optional int32 lifetime_msec = 4;
+
+    // The duration for which the keepalive was active (not suspended)
+    optional int32 active_lifetime_msec = 5;
+}
+
diff --git a/tests/unit/java/com/android/server/connectivity/VpnTest.java b/tests/unit/java/com/android/server/connectivity/VpnTest.java
index 1f965d9..79987e6 100644
--- a/tests/unit/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/unit/java/com/android/server/connectivity/VpnTest.java
@@ -35,15 +35,24 @@
 import static android.net.cts.util.IkeSessionTestUtils.getTestIkeSessionParams;
 import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_MOBIKE;
 import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_AUTO;
+import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_NONE;
+import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_UDP;
 import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_AUTO;
+import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_IPV4;
+import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_IPV6;
 import static android.os.Build.VERSION_CODES.S_V2;
 import static android.os.UserHandle.PER_USER_RANGE;
 import static android.telephony.CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL;
 import static android.telephony.CarrierConfigManager.KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT;
 
 import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
 import static com.android.server.connectivity.Vpn.AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
 import static com.android.server.connectivity.Vpn.DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT;
+import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_AUTO;
+import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_IPV4_UDP;
+import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_IPV6_ESP;
+import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_IPV6_UDP;
 import static com.android.testutils.Cleanup.testAndCleanup;
 import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 import static com.android.testutils.MiscAsserts.assertThrows;
@@ -277,6 +286,7 @@
     private static final int IKE_NATT_KEEPALIVE_DELAY_SEC_DEFAULT = 10;
     private static final int TEST_KEEPALIVE_TIMER = 800;
     private static final int TEST_SUB_ID = 1234;
+    private static final String TEST_MCCMNC = "12345";
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
     @Mock private UserManager mUserManager;
@@ -1945,43 +1955,54 @@
     }
 
     @Test
-    public void testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerNoTimer()
-            throws Exception {
+    public void testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerNoTimer() throws Exception {
         doTestMigrateIkeSession_FromIkeTunnConnParams(
                 false /* isAutomaticIpVersionSelectionEnabled */,
                 true /* isAutomaticNattKeepaliveTimerEnabled */,
-                TEST_KEEPALIVE_TIMEOUT_UNSET);
+                TEST_KEEPALIVE_TIMEOUT_UNSET /* keepaliveInProfile */,
+                ESP_IP_VERSION_AUTO /* ipVersionInProfile */,
+                ESP_ENCAP_TYPE_AUTO /* encapTypeInProfile */);
     }
 
     @Test
-    public void testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerTimerSet()
-            throws Exception {
+    public void testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerTimerSet() throws Exception {
         doTestMigrateIkeSession_FromIkeTunnConnParams(
                 false /* isAutomaticIpVersionSelectionEnabled */,
                 true /* isAutomaticNattKeepaliveTimerEnabled */,
-                TEST_KEEPALIVE_TIMER);
+                TEST_KEEPALIVE_TIMER /* keepaliveInProfile */,
+                ESP_IP_VERSION_AUTO /* ipVersionInProfile */,
+                ESP_ENCAP_TYPE_AUTO /* encapTypeInProfile */);
     }
 
     @Test
-    public void testMigrateIkeSession_FromIkeTunnConnParams_AutoIp()
-            throws Exception {
+    public void testMigrateIkeSession_FromIkeTunnConnParams_AutoIp() throws Exception {
         doTestMigrateIkeSession_FromIkeTunnConnParams(
                 true /* isAutomaticIpVersionSelectionEnabled */,
                 false /* isAutomaticNattKeepaliveTimerEnabled */,
-                TEST_KEEPALIVE_TIMEOUT_UNSET);
+                TEST_KEEPALIVE_TIMEOUT_UNSET /* keepaliveInProfile */,
+                ESP_IP_VERSION_AUTO /* ipVersionInProfile */,
+                ESP_ENCAP_TYPE_AUTO /* encapTypeInProfile */);
     }
 
     @Test
-    public void testMigrateIkeSession_FromNotIkeTunnConnParams_AutoTimer()
-            throws Exception {
+    public void testMigrateIkeSession_FromIkeTunnConnParams_AssignedIpProtocol() throws Exception {
+        doTestMigrateIkeSession_FromIkeTunnConnParams(
+                false /* isAutomaticIpVersionSelectionEnabled */,
+                false /* isAutomaticNattKeepaliveTimerEnabled */,
+                TEST_KEEPALIVE_TIMEOUT_UNSET /* keepaliveInProfile */,
+                ESP_IP_VERSION_IPV4 /* ipVersionInProfile */,
+                ESP_ENCAP_TYPE_UDP /* encapTypeInProfile */);
+    }
+
+    @Test
+    public void testMigrateIkeSession_FromNotIkeTunnConnParams_AutoTimer() throws Exception {
         doTestMigrateIkeSession_FromNotIkeTunnConnParams(
                 false /* isAutomaticIpVersionSelectionEnabled */,
                 true /* isAutomaticNattKeepaliveTimerEnabled */);
     }
 
     @Test
-    public void testMigrateIkeSession_FromNotIkeTunnConnParams_AutoIp()
-            throws Exception {
+    public void testMigrateIkeSession_FromNotIkeTunnConnParams_AutoIp() throws Exception {
         doTestMigrateIkeSession_FromNotIkeTunnConnParams(
                 true /* isAutomaticIpVersionSelectionEnabled */,
                 false /* isAutomaticNattKeepaliveTimerEnabled */);
@@ -2001,16 +2022,27 @@
         final int expectedKeepalive = isAutomaticNattKeepaliveTimerEnabled
                 ? AUTOMATIC_KEEPALIVE_DELAY_SECONDS
                 : DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT;
-        doTestMigrateIkeSession(ikeProfile.toVpnProfile(), expectedKeepalive,
-                isAutomaticIpVersionSelectionEnabled);
+        doTestMigrateIkeSession(ikeProfile.toVpnProfile(),
+                expectedKeepalive,
+                ESP_IP_VERSION_AUTO /* expectedIpVersion */,
+                ESP_ENCAP_TYPE_AUTO /* expectedEncapType */);
     }
 
     private void doTestMigrateIkeSession_FromIkeTunnConnParams(
             boolean isAutomaticIpVersionSelectionEnabled,
             boolean isAutomaticNattKeepaliveTimerEnabled,
-            int keepaliveInProfile) throws Exception {
-        final IkeSessionParams ikeSessionParams = getTestIkeSessionParams(true /* testIpv6 */,
+            int keepaliveInProfile,
+            int ipVersionInProfile,
+            int encapTypeInProfile) throws Exception {
+        // TODO: Update helper function in IkeSessionTestUtils to support building IkeSessionParams
+        // with IP version and encap type when mainline-prod branch support these two APIs.
+        final IkeSessionParams params = getTestIkeSessionParams(true /* testIpv6 */,
                 new IkeFqdnIdentification(TEST_IDENTITY), keepaliveInProfile);
+        final IkeSessionParams ikeSessionParams = new IkeSessionParams.Builder(params)
+                .setIpVersion(ipVersionInProfile)
+                .setEncapType(encapTypeInProfile)
+                .build();
+
         final IkeTunnelConnectionParams tunnelParams =
                 new IkeTunnelConnectionParams(ikeSessionParams, CHILD_PARAMS);
         final Ikev2VpnProfile ikeProfile = new Ikev2VpnProfile.Builder(tunnelParams)
@@ -2022,17 +2054,18 @@
         final int expectedKeepalive = isAutomaticNattKeepaliveTimerEnabled
                 ? AUTOMATIC_KEEPALIVE_DELAY_SECONDS
                 : ikeSessionParams.getNattKeepAliveDelaySeconds();
+        final int expectedIpVersion = isAutomaticIpVersionSelectionEnabled
+                ? ESP_IP_VERSION_AUTO
+                : ikeSessionParams.getIpVersion();
+        final int expectedEncapType = isAutomaticIpVersionSelectionEnabled
+                ? ESP_ENCAP_TYPE_AUTO
+                : ikeSessionParams.getEncapType();
         doTestMigrateIkeSession(ikeProfile.toVpnProfile(), expectedKeepalive,
-                isAutomaticIpVersionSelectionEnabled);
+                expectedIpVersion, expectedEncapType);
     }
 
-    private void doTestMigrateIkeSession(VpnProfile profile, int expectedKeepalive,
-            boolean isAutomaticIpVersionSelectionEnabled) throws Exception {
-        final int expectedIpVersion = isAutomaticIpVersionSelectionEnabled
-                ? ESP_IP_VERSION_AUTO : ESP_IP_VERSION_AUTO;
-        final int expectedEncapType = isAutomaticIpVersionSelectionEnabled
-                ? ESP_ENCAP_TYPE_AUTO : ESP_IP_VERSION_AUTO;
-
+    private void doTestMigrateIkeSession(VpnProfile profile,
+            int expectedKeepalive, int expectedIpVersion, int expectedEncapType) throws Exception {
         final PlatformVpnSnapshot vpnSnapShot =
                 verifySetupPlatformVpn(profile,
                         createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */),
@@ -2050,16 +2083,18 @@
         vpnSnapShot.vpn.mVpnRunner.exitVpnRunner();
     }
 
-    private void mockCarrierConfig(int subId, int keepaliveTimer, int simStatus) {
+    private void mockCarrierConfig(int subId, int simStatus, int keepaliveTimer, int ikeProtocol) {
         final SubscriptionInfo subscriptionInfo = mock(SubscriptionInfo.class);
         doReturn(subId).when(subscriptionInfo).getSubscriptionId();
         doReturn(List.of(subscriptionInfo)).when(mSubscriptionManager)
                 .getActiveSubscriptionInfoList();
 
         doReturn(simStatus).when(mTmPerSub).getSimApplicationState();
+        doReturn(TEST_MCCMNC).when(mTmPerSub).getSimOperator(subId);
 
         final PersistableBundle persistableBundle = new PersistableBundle();
         persistableBundle.putInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT, keepaliveTimer);
+        persistableBundle.putInt(KEY_PREFERRED_IKE_PROTOCOL_INT, ikeProtocol);
         // For CarrierConfigManager.isConfigForIdentifiedCarrier check
         persistableBundle.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
         doReturn(persistableBundle).when(mConfigManager).getConfigForSubId(subId);
@@ -2076,26 +2111,32 @@
 
     @Test
     public void testNattKeepaliveTimerFromCarrierConfig_noSubId() throws Exception {
-        doTestNattKeepaliveTimerFromCarrierConfig(new NetworkCapabilities(),
-                TelephonyManager.SIM_STATE_LOADED, AUTOMATIC_KEEPALIVE_DELAY_SECONDS);
+        doTestReadCarrierConfig(new NetworkCapabilities(),
+                TelephonyManager.SIM_STATE_LOADED,
+                PREFERRED_IKE_PROTOCOL_IPV4_UDP,
+                AUTOMATIC_KEEPALIVE_DELAY_SECONDS /* expectedKeepaliveTimer */,
+                ESP_IP_VERSION_AUTO /* expectedIpVersion */,
+                ESP_ENCAP_TYPE_AUTO /* expectedEncapType */);
     }
 
     @Test
     public void testNattKeepaliveTimerFromCarrierConfig_simAbsent() throws Exception {
-        doTestNattKeepaliveTimerFromCarrierConfig(new NetworkCapabilities.Builder().build(),
-                TelephonyManager.SIM_STATE_ABSENT, AUTOMATIC_KEEPALIVE_DELAY_SECONDS);
+        doTestReadCarrierConfig(new NetworkCapabilities.Builder().build(),
+                TelephonyManager.SIM_STATE_ABSENT,
+                PREFERRED_IKE_PROTOCOL_IPV4_UDP,
+                AUTOMATIC_KEEPALIVE_DELAY_SECONDS /* expectedKeepaliveTimer */,
+                ESP_IP_VERSION_AUTO /* expectedIpVersion */,
+                ESP_ENCAP_TYPE_AUTO /* expectedEncapType */);
     }
 
     @Test
     public void testNattKeepaliveTimerFromCarrierConfig() throws Exception {
-        final NetworkCapabilities nc = new NetworkCapabilities.Builder()
-                .addTransportType(TRANSPORT_CELLULAR)
-                .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
-                        .setSubscriptionId(TEST_SUB_ID)
-                        .build())
-                .build();
-        doTestNattKeepaliveTimerFromCarrierConfig(nc,
-                TelephonyManager.SIM_STATE_LOADED, TEST_KEEPALIVE_TIMER);
+        doTestReadCarrierConfig(createTestCellNc(),
+                TelephonyManager.SIM_STATE_LOADED,
+                PREFERRED_IKE_PROTOCOL_AUTO,
+                TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */,
+                ESP_IP_VERSION_AUTO /* expectedIpVersion */,
+                ESP_ENCAP_TYPE_AUTO /* expectedEncapType */);
     }
 
     @Test
@@ -2104,17 +2145,62 @@
                 .addTransportType(TRANSPORT_WIFI)
                 .setTransportInfo(new WifiInfo.Builder().build())
                 .build();
-        doTestNattKeepaliveTimerFromCarrierConfig(nc,
-                TelephonyManager.SIM_STATE_LOADED, AUTOMATIC_KEEPALIVE_DELAY_SECONDS);
+        doTestReadCarrierConfig(nc,
+                TelephonyManager.SIM_STATE_LOADED,
+                PREFERRED_IKE_PROTOCOL_IPV4_UDP,
+                AUTOMATIC_KEEPALIVE_DELAY_SECONDS /* expectedKeepaliveTimer */,
+                ESP_IP_VERSION_AUTO /* expectedIpVersion */,
+                ESP_ENCAP_TYPE_AUTO /* expectedEncapType */);
     }
 
-    private void doTestNattKeepaliveTimerFromCarrierConfig(NetworkCapabilities nc, int simState,
-            int expectedKeepaliveTimer) throws Exception {
+    @Test
+    public void testPreferredIpProtocolFromCarrierConfig_v4UDP() throws Exception {
+        doTestReadCarrierConfig(createTestCellNc(),
+                TelephonyManager.SIM_STATE_LOADED,
+                PREFERRED_IKE_PROTOCOL_IPV4_UDP,
+                TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */,
+                ESP_IP_VERSION_IPV4 /* expectedIpVersion */,
+                ESP_ENCAP_TYPE_UDP /* expectedEncapType */);
+    }
+
+    @Test
+    public void testPreferredIpProtocolFromCarrierConfig_v6ESP() throws Exception {
+        doTestReadCarrierConfig(createTestCellNc(),
+                TelephonyManager.SIM_STATE_LOADED,
+                PREFERRED_IKE_PROTOCOL_IPV6_ESP,
+                TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */,
+                ESP_IP_VERSION_IPV6 /* expectedIpVersion */,
+                ESP_ENCAP_TYPE_NONE /* expectedEncapType */);
+    }
+
+    @Test
+    public void testPreferredIpProtocolFromCarrierConfig_v6UDP() throws Exception {
+        doTestReadCarrierConfig(createTestCellNc(),
+                TelephonyManager.SIM_STATE_LOADED,
+                PREFERRED_IKE_PROTOCOL_IPV6_UDP,
+                TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */,
+                ESP_IP_VERSION_IPV6 /* expectedIpVersion */,
+                ESP_ENCAP_TYPE_UDP /* expectedEncapType */);
+    }
+
+    private NetworkCapabilities createTestCellNc() {
+        return new NetworkCapabilities.Builder()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
+                        .setSubscriptionId(TEST_SUB_ID)
+                        .build())
+                .build();
+    }
+
+    private void doTestReadCarrierConfig(NetworkCapabilities nc, int simState, int preferredIpProto,
+            int expectedKeepaliveTimer, int expectedIpVersion, int expectedEncapType)
+            throws Exception {
         final Ikev2VpnProfile ikeProfile =
                 new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY)
                         .setAuthPsk(TEST_VPN_PSK)
                         .setBypassable(true /* isBypassable */)
                         .setAutomaticNattKeepaliveTimerEnabled(true)
+                        .setAutomaticIpVersionSelectionEnabled(true)
                         .build();
 
         final PlatformVpnSnapshot vpnSnapShot =
@@ -2131,10 +2217,10 @@
         verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt());
 
         reset(mIkeSessionWrapper);
-        mockCarrierConfig(TEST_SUB_ID, TEST_KEEPALIVE_TIMER, simState);
+        mockCarrierConfig(TEST_SUB_ID, simState, TEST_KEEPALIVE_TIMER, preferredIpProto);
         vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, nc);
         verify(mIkeSessionWrapper).setNetwork(TEST_NETWORK_2,
-                ESP_IP_VERSION_AUTO, ESP_ENCAP_TYPE_AUTO, expectedKeepaliveTimer);
+                expectedIpVersion, expectedEncapType, expectedKeepaliveTimer);
 
         reset(mExecutor);
         reset(mIkeSessionWrapper);
@@ -2143,7 +2229,7 @@
         listener.onCarrierConfigChanged(1 /* logicalSlotIndex */, TEST_SUB_ID,
                 -1 /* carrierId */, -1 /* specificCarrierId */);
         verify(mIkeSessionWrapper).setNetwork(TEST_NETWORK_2,
-                ESP_IP_VERSION_AUTO, ESP_ENCAP_TYPE_AUTO, expectedKeepaliveTimer);
+                expectedIpVersion, expectedEncapType, expectedKeepaliveTimer);
     }
 
     @Test
