Merge "Add number of ticks in HW_KEY_INPUT" into qt-dev
diff --git a/audio/common/5.0/types.hal b/audio/common/5.0/types.hal
index e1279ee..33a8d62 100644
--- a/audio/common/5.0/types.hal
+++ b/audio/common/5.0/types.hal
@@ -331,7 +331,13 @@
 
 /**
  * A channel mask per se only defines the presence or absence of a channel, not
- * the order.  See AUDIO_INTERLEAVE_* for the platform convention of order.
+ * the order.
+ *
+ * The channel order convention is that channels are interleaved in order from
+ * least significant channel mask bit to most significant channel mask bit,
+ * with unused bits skipped. For example for stereo, LEFT would be first,
+ * followed by RIGHT.
+ * Any exceptions to this convention are noted at the appropriate API.
  *
  * AudioChannelMask is an opaque type and its internal layout should not be
  * assumed as it may change in the future.  Instead, always use functions
diff --git a/audio/common/all-versions/util/include/common/all-versions/HidlSupport.h b/audio/common/all-versions/util/include/common/all-versions/HidlSupport.h
new file mode 100644
index 0000000..b514a43
--- /dev/null
+++ b/audio/common/all-versions/util/include/common/all-versions/HidlSupport.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_audio_common_HidlSupport_H_
+#define android_hardware_audio_common_HidlSupport_H_
+
+
+#include <hidl/HidlSupport.h>
+#include <algorithm>
+
+namespace android::hardware::audio::common::utils {
+
+template <typename Enum>
+bool isValidHidlEnum(Enum e) {
+    hidl_enum_range<Enum> values;
+    return std::find(values.begin(), values.end(), e) != values.end();
+}
+
+} // namespace android::hardware::audio::common::utils
+
+#endif  // android_hardware_audio_common_HidlSupport_H_
diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp
index daba6f7..d316f83 100644
--- a/audio/core/all-versions/default/StreamIn.cpp
+++ b/audio/core/all-versions/default/StreamIn.cpp
@@ -19,6 +19,7 @@
 #include "core/default/StreamIn.h"
 #include "core/default/Conversions.h"
 #include "core/default/Util.h"
+#include "common/all-versions/HidlSupport.h"
 
 //#define LOG_NDEBUG 0
 #define ATRACE_TAG ATRACE_TAG_AUDIO
@@ -27,6 +28,7 @@
 #include <hardware/audio.h>
 #include <utils/Trace.h>
 #include <memory>
+#include <cmath>
 
 namespace android {
 namespace hardware {
@@ -501,6 +503,10 @@
     if (mStream->set_microphone_direction == nullptr) {
         return Result::NOT_SUPPORTED;
     }
+    if (!common::utils::isValidHidlEnum(direction)) {
+        ALOGE("%s: Invalid direction %d", __func__, direction);
+        return Result::INVALID_ARGUMENTS;
+    }
     return Stream::analyzeStatus(
             "set_microphone_direction",
             mStream->set_microphone_direction(
@@ -511,6 +517,10 @@
     if (mStream->set_microphone_field_dimension == nullptr) {
         return Result::NOT_SUPPORTED;
     }
+    if (std::isnan(zoom) || zoom < -1 || zoom > 1) {
+        ALOGE("%s: Invalid zoom %f", __func__, zoom);
+        return Result::INVALID_ARGUMENTS;
+    }
     return Stream::analyzeStatus("set_microphone_field_dimension",
                                  mStream->set_microphone_field_dimension(mStream, zoom));
 }
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 259473e..6c76d7b 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -641,7 +641,9 @@
     /**
      * Night mode
      *
-     * True indicates that night mode is currently enabled.
+     * True indicates that the night mode sensor has detected that the car cabin environment has
+     * low light. The platform could use this, for example, to enable appropriate UI for
+     * better viewing in dark or low light environments.
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ
@@ -983,6 +985,10 @@
      *
      * Indicates whether the vehicle is displaying temperature to the user as
      * Celsius or Fahrenheit.
+     * VehiclePropConfig.configArray is used to indicate the supported temperature display units.
+     * For example: configArray[0] = CELSIUS
+     *              configArray[1] = FAHRENHEIT
+     *
      * This parameter MAY be used for displaying any HVAC temperature in the system.
      * Values must be one of VehicleUnit::CELSIUS or VehicleUnit::FAHRENHEIT
      * Note that internally, all temperatures are represented in floating point Celsius.
@@ -2794,6 +2800,14 @@
      */
     int32_t areaId;
 
+    /**
+     * If the property has @data_enum, leave the range to zero.
+     *
+     * Range will be ignored in the following cases:
+     *    - The VehiclePropertyType is not INT32, INT64 or FLOAT.
+     *    - Both of min value and max value are zero.
+     */
+
     int32_t minInt32Value;
     int32_t maxInt32Value;
 
diff --git a/camera/common/1.0/default/Android.bp b/camera/common/1.0/default/Android.bp
index 21f81f5..3e5c6d7 100644
--- a/camera/common/1.0/default/Android.bp
+++ b/camera/common/1.0/default/Android.bp
@@ -20,6 +20,7 @@
         "libhardware",
         "libcamera_metadata",
         "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
         "libexif",
     ],
     include_dirs: ["system/media/private/camera/include"],
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp
index 21706a8..b8c40e9 100644
--- a/camera/common/1.0/default/HandleImporter.cpp
+++ b/camera/common/1.0/default/HandleImporter.cpp
@@ -25,7 +25,9 @@
 namespace V1_0 {
 namespace helper {
 
-using MapperError = android::hardware::graphics::mapper::V2_0::Error;
+using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error;
+using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error;
+using IMapperV3 = android::hardware::graphics::mapper::V3_0::IMapper;
 
 HandleImporter::HandleImporter() : mInitialized(false) {}
 
@@ -34,8 +36,14 @@
         return;
     }
 
-    mMapper = IMapper::getService();
-    if (mMapper == nullptr) {
+    mMapperV3 = IMapperV3::getService();
+    if (mMapperV3 != nullptr) {
+        mInitialized = true;
+        return;
+    }
+
+    mMapperV2 = IMapper::getService();
+    if (mMapperV2 == nullptr) {
         ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__);
         return;
     }
@@ -45,10 +53,90 @@
 }
 
 void HandleImporter::cleanup() {
-    mMapper.clear();
+    mMapperV3.clear();
+    mMapperV2.clear();
     mInitialized = false;
 }
 
+template<class M, class E>
+bool HandleImporter::importBufferInternal(const sp<M> mapper, buffer_handle_t& handle) {
+    E error;
+    buffer_handle_t importedHandle;
+    auto ret = mapper->importBuffer(
+        hidl_handle(handle),
+        [&](const auto& tmpError, const auto& tmpBufferHandle) {
+            error = tmpError;
+            importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
+        });
+
+    if (!ret.isOk()) {
+        ALOGE("%s: mapper importBuffer failed: %s",
+                __FUNCTION__, ret.description().c_str());
+        return false;
+    }
+
+    if (error != E::NONE) {
+        return false;
+    }
+
+    handle = importedHandle;
+    return true;
+}
+
+template<class M, class E>
+YCbCrLayout HandleImporter::lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf,
+        uint64_t cpuUsage, const IMapper::Rect& accessRegion) {
+    hidl_handle acquireFenceHandle;
+    auto buffer = const_cast<native_handle_t*>(buf);
+    YCbCrLayout layout = {};
+
+    typename M::Rect accessRegionCopy = {accessRegion.left, accessRegion.top,
+            accessRegion.width, accessRegion.height};
+    mapper->lockYCbCr(buffer, cpuUsage, accessRegionCopy, acquireFenceHandle,
+            [&](const auto& tmpError, const auto& tmpLayout) {
+                if (tmpError == E::NONE) {
+                    // Member by member copy from different versions of YCbCrLayout.
+                    layout.y = tmpLayout.y;
+                    layout.cb = tmpLayout.cb;
+                    layout.cr = tmpLayout.cr;
+                    layout.yStride = tmpLayout.yStride;
+                    layout.cStride = tmpLayout.cStride;
+                    layout.chromaStep = tmpLayout.chromaStep;
+                } else {
+                    ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, tmpError);
+                }
+           });
+    return layout;
+}
+
+template<class M, class E>
+int HandleImporter::unlockInternal(const sp<M> mapper, buffer_handle_t& buf) {
+    int releaseFence = -1;
+    auto buffer = const_cast<native_handle_t*>(buf);
+
+    mapper->unlock(
+        buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+            if (tmpError == E::NONE) {
+                auto fenceHandle = tmpReleaseFence.getNativeHandle();
+                if (fenceHandle) {
+                    if (fenceHandle->numInts != 0 || fenceHandle->numFds != 1) {
+                        ALOGE("%s: bad release fence numInts %d numFds %d",
+                                __FUNCTION__, fenceHandle->numInts, fenceHandle->numFds);
+                        return;
+                    }
+                    releaseFence = dup(fenceHandle->data[0]);
+                    if (releaseFence < 0) {
+                        ALOGE("%s: bad release fence FD %d",
+                                __FUNCTION__, releaseFence);
+                    }
+                }
+            } else {
+                ALOGE("%s: failed to unlock error %d!", __FUNCTION__, tmpError);
+            }
+        });
+    return releaseFence;
+}
+
 // In IComposer, any buffer_handle_t is owned by the caller and we need to
 // make a clone for hwcomposer2.  We also need to translate empty handle
 // to nullptr.  This function does that, in-place.
@@ -63,33 +151,16 @@
         initializeLocked();
     }
 
-    if (mMapper == nullptr) {
-        ALOGE("%s: mMapper is null!", __FUNCTION__);
-        return false;
+    if (mMapperV3 != nullptr) {
+        return importBufferInternal<IMapperV3, MapperErrorV3>(mMapperV3, handle);
     }
 
-    MapperError error;
-    buffer_handle_t importedHandle;
-    auto ret = mMapper->importBuffer(
-        hidl_handle(handle),
-        [&](const auto& tmpError, const auto& tmpBufferHandle) {
-            error = tmpError;
-            importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
-        });
-
-    if (!ret.isOk()) {
-        ALOGE("%s: mapper importBuffer failed: %s",
-                __FUNCTION__, ret.description().c_str());
-        return false;
+    if (mMapperV2 != nullptr) {
+        return importBufferInternal<IMapper, MapperErrorV2>(mMapperV2, handle);
     }
 
-    if (error != MapperError::NONE) {
-        return false;
-    }
-
-    handle = importedHandle;
-
-    return true;
+    ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
+    return false;
 }
 
 void HandleImporter::freeBuffer(buffer_handle_t handle) {
@@ -98,15 +169,23 @@
     }
 
     Mutex::Autolock lock(mLock);
-    if (mMapper == nullptr) {
-        ALOGE("%s: mMapper is null!", __FUNCTION__);
+    if (mMapperV3 == nullptr && mMapperV2 == nullptr) {
+        ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
         return;
     }
 
-    auto ret = mMapper->freeBuffer(const_cast<native_handle_t*>(handle));
-    if (!ret.isOk()) {
-        ALOGE("%s: mapper freeBuffer failed: %s",
-                __FUNCTION__, ret.description().c_str());
+    if (mMapperV3 != nullptr) {
+        auto ret = mMapperV3->freeBuffer(const_cast<native_handle_t*>(handle));
+        if (!ret.isOk()) {
+            ALOGE("%s: mapper freeBuffer failed: %s",
+                    __FUNCTION__, ret.description().c_str());
+        }
+    } else {
+        auto ret = mMapperV2->freeBuffer(const_cast<native_handle_t*>(handle));
+        if (!ret.isOk()) {
+            ALOGE("%s: mapper freeBuffer failed: %s",
+                    __FUNCTION__, ret.description().c_str());
+        }
     }
 }
 
@@ -138,91 +217,82 @@
         buffer_handle_t& buf, uint64_t cpuUsage, size_t size) {
     Mutex::Autolock lock(mLock);
     void *ret = 0;
-    IMapper::Rect accessRegion { 0, 0, static_cast<int>(size), 1 };
 
     if (!mInitialized) {
         initializeLocked();
     }
 
-    if (mMapper == nullptr) {
-        ALOGE("%s: mMapper is null!", __FUNCTION__);
+    if (mMapperV3 == nullptr && mMapperV2 == nullptr) {
+        ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
         return ret;
     }
 
     hidl_handle acquireFenceHandle;
     auto buffer = const_cast<native_handle_t*>(buf);
-    mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
-            [&](const auto& tmpError, const auto& tmpPtr) {
-                if (tmpError == MapperError::NONE) {
-                    ret = tmpPtr;
-                } else {
-                    ALOGE("%s: failed to lock error %d!",
-                          __FUNCTION__, tmpError);
-                }
-           });
+    if (mMapperV3 != nullptr) {
+        IMapperV3::Rect accessRegion { 0, 0, static_cast<int>(size), 1 };
+        // No need to use bytesPerPixel and bytesPerStride because we are using
+        // an 1-D buffer and accressRegion.
+        mMapperV3->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+                [&](const auto& tmpError, const auto& tmpPtr, const auto& /*bytesPerPixel*/,
+                        const auto& /*bytesPerStride*/) {
+                    if (tmpError == MapperErrorV3::NONE) {
+                        ret = tmpPtr;
+                    } else {
+                        ALOGE("%s: failed to lock error %d!",
+                              __FUNCTION__, tmpError);
+                    }
+               });
+    } else {
+        IMapper::Rect accessRegion { 0, 0, static_cast<int>(size), 1 };
+        mMapperV2->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+                [&](const auto& tmpError, const auto& tmpPtr) {
+                    if (tmpError == MapperErrorV2::NONE) {
+                        ret = tmpPtr;
+                    } else {
+                        ALOGE("%s: failed to lock error %d!",
+                              __FUNCTION__, tmpError);
+                    }
+               });
+    }
 
     ALOGV("%s: ptr %p size: %zu", __FUNCTION__, ret, size);
     return ret;
 }
 
-
 YCbCrLayout HandleImporter::lockYCbCr(
         buffer_handle_t& buf, uint64_t cpuUsage,
         const IMapper::Rect& accessRegion) {
     Mutex::Autolock lock(mLock);
-    YCbCrLayout layout = {};
 
     if (!mInitialized) {
         initializeLocked();
     }
 
-    if (mMapper == nullptr) {
-        ALOGE("%s: mMapper is null!", __FUNCTION__);
-        return layout;
+    if (mMapperV3 != nullptr) {
+        return lockYCbCrInternal<IMapperV3, MapperErrorV3>(
+                mMapperV3, buf, cpuUsage, accessRegion);
     }
 
-    hidl_handle acquireFenceHandle;
-    auto buffer = const_cast<native_handle_t*>(buf);
-    mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
-            [&](const auto& tmpError, const auto& tmpLayout) {
-                if (tmpError == MapperError::NONE) {
-                    layout = tmpLayout;
-                } else {
-                    ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, tmpError);
-                }
-           });
+    if (mMapperV2 != nullptr) {
+        return lockYCbCrInternal<IMapper, MapperErrorV2>(
+                mMapperV2, buf, cpuUsage, accessRegion);
+    }
 
-    ALOGV("%s: layout y %p cb %p cr %p y_str %d c_str %d c_step %d",
-            __FUNCTION__, layout.y, layout.cb, layout.cr,
-            layout.yStride, layout.cStride, layout.chromaStep);
-    return layout;
+    ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
+    return {};
 }
 
 int HandleImporter::unlock(buffer_handle_t& buf) {
-    int releaseFence = -1;
-    auto buffer = const_cast<native_handle_t*>(buf);
-    mMapper->unlock(
-        buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
-            if (tmpError == MapperError::NONE) {
-                auto fenceHandle = tmpReleaseFence.getNativeHandle();
-                if (fenceHandle) {
-                    if (fenceHandle->numInts != 0 || fenceHandle->numFds != 1) {
-                        ALOGE("%s: bad release fence numInts %d numFds %d",
-                                __FUNCTION__, fenceHandle->numInts, fenceHandle->numFds);
-                        return;
-                    }
-                    releaseFence = dup(fenceHandle->data[0]);
-                    if (releaseFence <= 0) {
-                        ALOGE("%s: bad release fence FD %d",
-                                __FUNCTION__, releaseFence);
-                    }
-                }
-            } else {
-                ALOGE("%s: failed to unlock error %d!", __FUNCTION__, tmpError);
-            }
-        });
+    if (mMapperV3 != nullptr) {
+        return unlockInternal<IMapperV3, MapperErrorV3>(mMapperV3, buf);
+    }
+    if (mMapperV2 != nullptr) {
+        return unlockInternal<IMapper, MapperErrorV2>(mMapperV2, buf);
+    }
 
-    return releaseFence;
+    ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
+    return -1;
 }
 
 } // namespace helper
diff --git a/camera/common/1.0/default/OWNERS b/camera/common/1.0/default/OWNERS
index 70128c7..f48a95c 100644
--- a/camera/common/1.0/default/OWNERS
+++ b/camera/common/1.0/default/OWNERS
@@ -1 +1 @@
-include platform/frameworks/av:camera/OWNERS
+include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/common/1.0/default/include/HandleImporter.h b/camera/common/1.0/default/include/HandleImporter.h
index f9cd9fb..a93d455 100644
--- a/camera/common/1.0/default/include/HandleImporter.h
+++ b/camera/common/1.0/default/include/HandleImporter.h
@@ -19,6 +19,7 @@
 
 #include <utils/Mutex.h>
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
 #include <cutils/native_handle.h>
 
 using android::hardware::graphics::mapper::V2_0::IMapper;
@@ -57,10 +58,18 @@
     void initializeLocked();
     void cleanup();
 
+    template<class M, class E>
+    bool importBufferInternal(const sp<M> mapper, buffer_handle_t& handle);
+    template<class M, class E>
+    YCbCrLayout lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf, uint64_t cpuUsage,
+            const IMapper::Rect& accessRegion);
+    template<class M, class E>
+    int unlockInternal(const sp<M> mapper, buffer_handle_t& buf);
+
     Mutex mLock;
     bool mInitialized;
-    sp<IMapper> mMapper;
-
+    sp<IMapper> mMapperV2;
+    sp<graphics::mapper::V3_0::IMapper> mMapperV3;
 };
 
 } // namespace helper
diff --git a/camera/device/1.0/default/Android.bp b/camera/device/1.0/default/Android.bp
index 4a7fc9c..aa3b941 100644
--- a/camera/device/1.0/default/Android.bp
+++ b/camera/device/1.0/default/Android.bp
@@ -15,6 +15,7 @@
         "android.hardware.camera.common@1.0",
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
         "android.hardware.graphics.common@1.0",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
diff --git a/camera/device/3.2/default/Android.bp b/camera/device/3.2/default/Android.bp
index 325c008..edb008e 100644
--- a/camera/device/3.2/default/Android.bp
+++ b/camera/device/3.2/default/Android.bp
@@ -13,6 +13,7 @@
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.provider@2.4",
         "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
         "liblog",
         "libhardware",
         "libcamera_metadata",
diff --git a/camera/device/3.3/default/Android.bp b/camera/device/3.3/default/Android.bp
index b1e9b46..39d379d 100644
--- a/camera/device/3.3/default/Android.bp
+++ b/camera/device/3.3/default/Android.bp
@@ -15,6 +15,7 @@
         "android.hardware.camera.device@3.3",
         "android.hardware.camera.provider@2.4",
         "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
         "liblog",
         "libhardware",
         "libcamera_metadata",
diff --git a/camera/device/3.4/default/Android.bp b/camera/device/3.4/default/Android.bp
index 272bf42..c22b13c 100644
--- a/camera/device/3.4/default/Android.bp
+++ b/camera/device/3.4/default/Android.bp
@@ -48,6 +48,7 @@
         "android.hardware.camera.device@3.4",
         "android.hardware.camera.provider@2.4",
         "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
         "liblog",
         "libhardware",
         "libcamera_metadata",
@@ -84,6 +85,7 @@
         "android.hardware.camera.device@3.4",
         "android.hardware.camera.provider@2.4",
         "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
         "liblog",
         "libhardware",
         "libcamera_metadata",
diff --git a/camera/device/3.5/default/Android.bp b/camera/device/3.5/default/Android.bp
index 7a48865..26b3b67 100644
--- a/camera/device/3.5/default/Android.bp
+++ b/camera/device/3.5/default/Android.bp
@@ -49,6 +49,7 @@
         "android.hardware.camera.device@3.5",
         "android.hardware.camera.provider@2.4",
         "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
         "liblog",
         "libhardware",
         "libcamera_metadata",
@@ -82,6 +83,7 @@
         "android.hardware.camera.device@3.5",
         "android.hardware.camera.provider@2.4",
         "android.hardware.graphics.mapper@2.0",
+	"android.hardware.graphics.mapper@3.0",
         "liblog",
         "libhardware",
         "libcamera_metadata",
diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp
index 9d73934..cb78fcb 100644
--- a/camera/provider/2.4/default/Android.bp
+++ b/camera/provider/2.4/default/Android.bp
@@ -12,6 +12,7 @@
         "android.hardware.camera.device@3.5",
         "android.hardware.camera.provider@2.4",
         "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
         "camera.device@1.0-impl",
@@ -50,6 +51,7 @@
         "android.hardware.camera.device@3.5",
         "android.hardware.camera.provider@2.4",
         "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
         "camera.device@3.3-impl",
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 5fb1fd8..2c3ed37 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -42,8 +42,10 @@
         "android.hardware.camera.provider@2.4",
         "android.hardware.camera.provider@2.5",
         "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.allocator@3.0",
         "android.hardware.graphics.common@1.0",
         "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
         "android.hidl.allocator@1.0",
         "libgrallocusage",
         "libhidlmemory",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 33d23a0..200dd3f 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -54,8 +54,10 @@
 #include <ui/GraphicBuffer.h>
 
 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
 #include <android/hardware/graphics/mapper/2.0/types.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
 #include <android/hidl/allocator/1.0/IAllocator.h>
 #include <android/hidl/memory/1.0/IMapper.h>
 #include <android/hidl/memory/1.0/IMemory.h>
@@ -6104,36 +6106,66 @@
 
     sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
         android::hardware::graphics::allocator::V2_0::IAllocator::getService();
-    ASSERT_NE(nullptr, allocator.get());
+    sp<android::hardware::graphics::allocator::V3_0::IAllocator> allocatorV3 =
+        android::hardware::graphics::allocator::V3_0::IAllocator::getService();
 
+    sp<android::hardware::graphics::mapper::V3_0::IMapper> mapperV3 =
+        android::hardware::graphics::mapper::V3_0::IMapper::getService();
     sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
         android::hardware::graphics::mapper::V2_0::IMapper::getService();
-    ASSERT_NE(mapper.get(), nullptr);
-
-    android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {};
-    descriptorInfo.width = width;
-    descriptorInfo.height = height;
-    descriptorInfo.layerCount = 1;
-    descriptorInfo.format = format;
-    descriptorInfo.usage = usage;
-
     ::android::hardware::hidl_vec<uint32_t> descriptor;
-    auto ret = mapper->createDescriptor(
-        descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V2_0::Error err,
-                            ::android::hardware::hidl_vec<uint32_t> desc) {
-            ASSERT_EQ(err, android::hardware::graphics::mapper::V2_0::Error::NONE);
-            descriptor = desc;
-        });
-    ASSERT_TRUE(ret.isOk());
+    if (mapperV3 != nullptr && allocatorV3 != nullptr) {
+        android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo descriptorInfo {};
+        descriptorInfo.width = width;
+        descriptorInfo.height = height;
+        descriptorInfo.layerCount = 1;
+        descriptorInfo.format =
+                static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
+        descriptorInfo.usage = usage;
 
-    ret = allocator->allocate(descriptor, 1u,
-        [&](android::hardware::graphics::mapper::V2_0::Error err, uint32_t /*stride*/,
-            const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
-            ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE, err);
-            ASSERT_EQ(buffers.size(), 1u);
-            *buffer_handle = buffers[0];
-        });
-    ASSERT_TRUE(ret.isOk());
+        auto ret = mapperV3->createDescriptor(
+            descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V3_0::Error err,
+                                ::android::hardware::hidl_vec<uint32_t> desc) {
+                ASSERT_EQ(err, android::hardware::graphics::mapper::V3_0::Error::NONE);
+                descriptor = desc;
+            });
+        ASSERT_TRUE(ret.isOk());
+
+        ret = allocatorV3->allocate(descriptor, 1u,
+            [&](android::hardware::graphics::mapper::V3_0::Error err, uint32_t /*stride*/,
+                const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
+                ASSERT_EQ(android::hardware::graphics::mapper::V3_0::Error::NONE, err);
+                ASSERT_EQ(buffers.size(), 1u);
+                *buffer_handle = buffers[0];
+            });
+        ASSERT_TRUE(ret.isOk());
+    } else {
+        ASSERT_NE(mapper.get(), nullptr);
+        ASSERT_NE(allocator.get(), nullptr);
+        android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {};
+        descriptorInfo.width = width;
+        descriptorInfo.height = height;
+        descriptorInfo.layerCount = 1;
+        descriptorInfo.format = format;
+        descriptorInfo.usage = usage;
+
+        auto ret = mapper->createDescriptor(
+            descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V2_0::Error err,
+                                ::android::hardware::hidl_vec<uint32_t> desc) {
+                ASSERT_EQ(err, android::hardware::graphics::mapper::V2_0::Error::NONE);
+                descriptor = desc;
+            });
+        ASSERT_TRUE(ret.isOk());
+
+        ret = allocator->allocate(descriptor, 1u,
+            [&](android::hardware::graphics::mapper::V2_0::Error err, uint32_t /*stride*/,
+                const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
+                ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE, err);
+                ASSERT_EQ(buffers.size(), 1u);
+                *buffer_handle = buffers[0];
+            });
+        ASSERT_TRUE(ret.isOk());
+    }
 }
 
 void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) {
diff --git a/current.txt b/current.txt
index d97c0b3..5742d66 100644
--- a/current.txt
+++ b/current.txt
@@ -410,7 +410,9 @@
 ed9da80ec0c96991fd03f0a46107815d0e50f764656e49dba4980fa5c31d5bc3 android.hardware.radio@1.0::types
 1d19720d4fd38b1095f0f555a4bd92b3b12c9b1d0f560b0e9a474cd6dcc20db6 android.hardware.radio@1.2::IRadio
 cd1757867a5e3a3faa362e785239515870d1a3c9ce756c6f0cf0f0fd8aac2547 android.hardware.radio@1.2::types
+722b3595548ed7f1953b6e0143dc842d4d6e290ff009a134eb518d7c17a09347 android.hardware.radio@1.2::types # b/112486807
 e78cf871f9fd1c072874e481e06e18e2681763cf2aa38c1fd777d53bab4eb69b android.hardware.sensors@1.0::types
+c28859a334c1f540dea0a7d4f0baef0551ba76a3232f53c936196543ee35bc4d android.hardware.sensors@1.0::types # b/133264933
 3d01e29e8129186f7567c4f9c8bee7480a0768e587b1be9b28adb0a6cbec6bf2 android.hardware.tv.cec@1.0::types
 1722ad002317b1fae1400de709e90f442d94ef22864e05f7a12af48c32e8edc8 android.hardware.usb@1.1::types
 29c8da7a13c40d488f569c812441d5754ee45bdcdb8ce6564f524b708d10a057 android.hardware.vibrator@1.1::types
@@ -427,6 +429,7 @@
 1b0500367ed2b32a841667ac3200edf3d3a164e8004aca445ff1b085ac831e93 android.hardware.audio@5.0::IStreamOutCallback
 83e365479cc77d8717c155e1787ee668cd2ae4c557b467cf75b8e7cd53697ad8 android.hardware.audio@5.0::types
 07d17800b298331e90d4ea5d8ba19a1ae3fe9c1dbff08d9f75fd3ade09496d67 android.hardware.audio.common@5.0::types
+b3c1ec989f317b9a36eac10f4e7b66aad2997302156899481553a67476e148dd android.hardware.audio.common@5.0::types # b/133453897
 f269297866765b95ddd1825676cc8a772f0c7c9863286df596fc302781a42ff5 android.hardware.audio.effect@5.0::IAcousticEchoCancelerEffect
 fa187b602d8939644ef708ed7627f2e3deac97899a4bda1de07f2ff126abe243 android.hardware.audio.effect@5.0::IAutomaticGainControlEffect
 e1bf864ccb8458c0da1dcc74a2e748b1dca8ac360df590591cf82d98292d7981 android.hardware.audio.effect@5.0::IBassBoostEffect
@@ -526,6 +529,7 @@
 a1c6b0761bcb89d6bf15a156f9306b8090b3a916a15fea1689b4b0c1738e382f android.hardware.radio@1.3::IRadio
 e9d0f11a52715f5a29d89e2d8e2e21db1e16a43174af6b9d51a62d705cda1455 android.hardware.radio@1.3::IRadioIndication
 d233f0da44f55fdef0a95db5229231412787bb67695cd1ea197ce89a3c2908b9 android.hardware.radio@1.3::IRadioResponse
+f5fbe4f28a9e346be36063eca4e6c864114a1a6fb64884db03fdd825791ad9b8 android.hardware.radio@1.3::IRadioResponse # b/132818184 for Android Q
 750a363c8cec70baa1aac19e275c15233c5898e93c6bb5155fa2ca7f365490dc android.hardware.radio@1.3::types
 ef4ab741f7e7762fb45e2e24ca83871f72006ce05f57aa9addc574893dd29872 android.hardware.radio@1.4::IRadio
 33d9e6895cca98aa56296bb01720d18b8acd0e4de4960beb712e63ad147438a5 android.hardware.radio@1.4::IRadioIndication
diff --git a/radio/1.2/types.hal b/radio/1.2/types.hal
index 2dceeb1..dffebd3 100644
--- a/radio/1.2/types.hal
+++ b/radio/1.2/types.hal
@@ -193,7 +193,8 @@
      * the client (in seconds).
      * Expected range for the input is
      * [IncrementalResultsPeriodicityRange:MIN - IncrementalResultsPeriodicityRange:MAX]
-     * This value must be less than or equal to maxSearchTime.
+     * This value must be less than or equal to maxSearchTime. If incremental results are
+     * not requested, implementations may ignore this value.
      */
     int32_t incrementalResultsPeriodicity;
 
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index a3073ac..63d3187 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -228,7 +228,7 @@
             .interval = 60,
             .specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
             .maxSearchTime = 600,
-            .incrementalResults = false,
+            .incrementalResults = true,
             .incrementalResultsPeriodicity = 0};
 
     Return<void> res = radio_v1_2->startNetworkScan_1_2(serial, request);
@@ -260,7 +260,7 @@
             .interval = 60,
             .specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850},
             .maxSearchTime = 600,
-            .incrementalResults = false,
+            .incrementalResults = true,
             .incrementalResultsPeriodicity = 11};
 
     Return<void> res = radio_v1_2->startNetworkScan_1_2(serial, request);
diff --git a/radio/1.3/IRadioResponse.hal b/radio/1.3/IRadioResponse.hal
index c3bbe65..85085e2 100644
--- a/radio/1.3/IRadioResponse.hal
+++ b/radio/1.3/IRadioResponse.hal
@@ -44,6 +44,9 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:MODEM_ERR
+     *   RadioError:INVALID_STATE: this is for the case that the API is called in a single-sim
+     *              mode, or when there is only one modem available, as this API should only
+     *              be called in multi sim status.
      */
     oneway enableModemResponse(RadioResponseInfo info);
 
diff --git a/radio/1.3/vts/functional/radio_hidl_hal_api.cpp b/radio/1.3/vts/functional/radio_hidl_hal_api.cpp
index 5b7a06d..813dd13 100644
--- a/radio/1.3/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.3/vts/functional/radio_hidl_hal_api.cpp
@@ -35,7 +35,7 @@
           toString(radioRsp_v1_3->rspInfo.error).c_str());
     ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_3->rspInfo.error,
                                  {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
-                                  RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+                                  RadioError::MODEM_ERR, RadioError::INVALID_STATE}));
 
     // checking if getModemStackStatus returns true, as modem was enabled above
     if (RadioError::NONE == radioRsp_v1_3->rspInfo.error) {
@@ -52,7 +52,7 @@
               toString(radioRsp_v1_3->rspInfo.error).c_str());
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_3->rspInfo.error,
                                      {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
-                                      RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+                                      RadioError::MODEM_ERR, RadioError::INVALID_STATE}));
         // verify that enableModem did set isEnabled correctly
         EXPECT_EQ(true, radioRsp_v1_3->isModemEnabled);
     }
diff --git a/radio/1.4/vts/functional/Android.bp b/radio/1.4/vts/functional/Android.bp
index 2d0e089..6827132 100644
--- a/radio/1.4/vts/functional/Android.bp
+++ b/radio/1.4/vts/functional/Android.bp
@@ -31,7 +31,9 @@
         "android.hardware.radio@1.2",
         "android.hardware.radio@1.1",
         "android.hardware.radio@1.0",
+        "android.hardware.radio.config@1.0",
+        "android.hardware.radio.config@1.1",
     ],
     header_libs: ["radio.util.header@1.0"],
     test_suites: ["general-tests"]
-}
\ No newline at end of file
+}
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index 2093c25..696c746 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -119,6 +119,10 @@
 
     network_type_bitmap |= ::android::hardware::radio::V1_4::RadioAccessFamily::LTE;
 
+    // TODO(b/131634656): LTE_CA will be sent to modem as a RAF in Q, but LTE_CA is not a RAF,
+    // we will not send it to modem as a RAF in R.
+    network_type_bitmap |= ::android::hardware::radio::V1_4::RadioAccessFamily::LTE_CA;
+
     Return<void> res = radio_v1_4->setPreferredNetworkTypeBitmap(serial, network_type_bitmap);
 
     ASSERT_OK(res);
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_test.cpp b/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
index 4d80696..d2d21ce 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
@@ -47,6 +47,13 @@
     EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
     EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
 
+    sp<::android::hardware::radio::config::V1_1::IRadioConfig> radioConfig =
+            ::testing::VtsHalHidlTargetTestBase::getService<
+                    ::android::hardware::radio::config::V1_1::IRadioConfig>();
+
+    /* Enforce Vts tesing with RadioConfig is existed. */
+    ASSERT_NE(nullptr, radioConfig.get());
+
     /* Enforce Vts Testing with Sim Status Present only. */
     EXPECT_EQ(CardState::PRESENT, cardStatus.base.base.cardState);
 }
@@ -84,4 +91,4 @@
     serial = GetRandomSerialNumber();
     radio_v1_4->getIccCardStatus(serial);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
-}
\ No newline at end of file
+}
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
index de7742c..f662472 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
+++ b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
@@ -22,6 +22,8 @@
 #include <condition_variable>
 #include <mutex>
 
+#include <android/hardware/radio/config/1.1/IRadioConfig.h>
+
 #include <android/hardware/radio/1.4/IRadio.h>
 #include <android/hardware/radio/1.4/IRadioIndication.h>
 #include <android/hardware/radio/1.4/IRadioResponse.h>
diff --git a/radio/config/1.0/vts/functional/radio_config_response.cpp b/radio/config/1.0/vts/functional/radio_config_response.cpp
index 97e8dca..a92db64 100644
--- a/radio/config/1.0/vts/functional/radio_config_response.cpp
+++ b/radio/config/1.0/vts/functional/radio_config_response.cpp
@@ -21,11 +21,15 @@
 RadioConfigResponse::RadioConfigResponse(RadioConfigHidlTest& parent) : parent(parent) {}
 
 Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
-    const RadioResponseInfo& /* info */,
-    const ::android::hardware::hidl_vec<SimSlotStatus>& /* slotStatus */) {
+        const RadioResponseInfo& info,
+        const ::android::hardware::hidl_vec<SimSlotStatus>& /* slotStatus */) {
+    rspInfo = info;
+    parent.notify();
     return Void();
 }
 
-Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const RadioResponseInfo& /* info */) {
+Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent.notify();
     return Void();
-}
\ No newline at end of file
+}
diff --git a/sensors/1.0/types.hal b/sensors/1.0/types.hal
index e91820c..cbbe92f 100644
--- a/sensors/1.0/types.hal
+++ b/sensors/1.0/types.hal
@@ -1008,10 +1008,40 @@
     AINFO_VEC3_CALIBRATION,
 
     /**
-     * Location and orientation of sensor element in the device frame: origin is
-     * the geometric center of the mobile device screen surface; the axis
-     * definition corresponds to Android sensor definitions.
-     * float[12]: 3x4 matrix in row major order
+     * Provides the orientation and location of the sensor element in terms of
+     * the Android coordinate system. This data is given as a 3x4 matrix
+     * consisting of a 3x3 rotation matrix (R) concatenated with a 3x1 location
+     * vector (t). The rotation matrix provides the orientation of the Android
+     * device coordinate frame relative to the local coordinate frame of the
+     * sensor. Note that assuming the axes conventions of the sensor are the
+     * same as Android, this is the inverse of the matrix applied to raw
+     * samples read from the sensor to convert them into the Android
+     * representation. The location vector represents the translation from the
+     * origin of the Android sensor coordinate system to the geometric center
+     * of the sensor, specified in millimeters (mm).
+     *
+     * float[12]: 3x4 matrix in row major order [R; t]
+     *
+     * Example:
+     *     This raw buffer: {0, 1, 0, 0, -1, 0, 0, 10, 0, 0, 1, -2.5}
+     *     Corresponds to this 3x4 matrix:
+     *         0 1 0    0
+     *        -1 0 0   10
+     *         0 0 1 -2.5
+     *     The sensor is oriented such that:
+     *         - the device X axis corresponds to the sensor's local -Y axis
+     *         - the device Y axis corresponds to the sensor's local X axis
+     *         - the device Z axis and sensor's local Z axis are equivalent
+     *     In other words, if viewing the origin of the Android coordinate
+     *     system from the positive Z direction, the device coordinate frame is
+     *     to be rotated 90 degrees counter-clockwise about the Z axis to align
+     *     with the sensor's local coordinate frame. Equivalently, a vector in
+     *     the Android coordinate frame may be multiplied with R to rotate it
+     *     90 degrees clockwise (270 degrees counter-clockwise), yielding its
+     *     representation in the sensor's coordinate frame.
+     *     Relative to the origin of the Android coordinate system, the physical
+     *     center of the sensor is located 10mm in the positive Y direction, and
+     *     2.5mm in the negative Z direction.
      */
     AINFO_SENSOR_PLACEMENT,
 
diff --git a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
index 85bcccd..64b4fb6 100644
--- a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -91,12 +91,12 @@
     };
 
     /* Test code calls this function to wait for data/event callback */
+    /* Must set callbackType = INVALID before call this function */
     inline std::cv_status wait(CallbackType waitForCallbackType) {
       std::unique_lock<std::mutex> lock(mtx_);
 
       EXPECT_NE(INVALID, waitForCallbackType); // can't ASSERT in a non-void-returning method
 
-      callbackType = INVALID;
       std::cv_status status = std::cv_status::no_timeout;
       auto now = std::chrono::system_clock::now();
       while (count_ == 0) {
@@ -469,6 +469,7 @@
  */
 TEST_F(WifiNanIfaceHidlTest, getCapabilitiesRequest) {
   uint16_t inputCmdId = 10;
+  callbackType = INVALID;
   ASSERT_EQ(WifiStatusCode::SUCCESS,
         HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, inputCmdId).code);
   // wait for a callback
diff --git a/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp
index cc36fae..4dbc82b 100644
--- a/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp
+++ b/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -100,13 +100,13 @@
     };
 
     /* Test code calls this function to wait for data/event callback */
+    /* Must set callbackType = INVALID before call this function */
     inline std::cv_status wait(CallbackType waitForCallbackType) {
         std::unique_lock<std::mutex> lock(mtx_);
 
         EXPECT_NE(INVALID, waitForCallbackType);  // can't ASSERT in a
                                                   // non-void-returning method
 
-        callbackType = INVALID;
         std::cv_status status = std::cv_status::no_timeout;
         auto now = std::chrono::system_clock::now();
         while (count_ == 0) {
@@ -475,6 +475,7 @@
  */
 TEST_F(WifiNanIfaceHidlTest, enableRequest_1_2InvalidArgs) {
     uint16_t inputCmdId = 10;
+    callbackType = INVALID;
     NanEnableRequest nanEnableRequest = {};
     NanConfigRequestSupplemental nanConfigRequestSupp = {};
     ASSERT_EQ(WifiStatusCode::SUCCESS,
@@ -509,6 +510,7 @@
  */
 TEST_F(WifiNanIfaceHidlTest, configRequest_1_2InvalidArgs) {
     uint16_t inputCmdId = 10;
+    callbackType = INVALID;
     NanConfigRequest nanConfigRequest = {};
     NanConfigRequestSupplemental nanConfigRequestSupp = {};
     ASSERT_EQ(WifiStatusCode::SUCCESS,
diff --git a/wifi/1.3/default/Android.mk b/wifi/1.3/default/Android.mk
index 199ea3b..1f91861 100644
--- a/wifi/1.3/default/Android.mk
+++ b/wifi/1.3/default/Android.mk
@@ -142,12 +142,14 @@
 LOCAL_SRC_FILES := \
     tests/hidl_struct_util_unit_tests.cpp \
     tests/main.cpp \
+    tests/mock_interface_tool.cpp \
     tests/mock_wifi_feature_flags.cpp \
     tests/mock_wifi_iface_util.cpp \
     tests/mock_wifi_legacy_hal.cpp \
     tests/mock_wifi_mode_controller.cpp \
     tests/ringbuffer_unit_tests.cpp \
     tests/wifi_ap_iface_unit_tests.cpp \
+    tests/wifi_nan_iface_unit_tests.cpp \
     tests/wifi_chip_unit_tests.cpp \
     tests/wifi_iface_util_unit_tests.cpp
 LOCAL_STATIC_LIBRARIES := \
diff --git a/wifi/1.3/default/service.cpp b/wifi/1.3/default/service.cpp
index 73015cf..fcbc37c 100644
--- a/wifi/1.3/default/service.cpp
+++ b/wifi/1.3/default/service.cpp
@@ -48,12 +48,14 @@
 
     configureRpcThreadpool(1, true /* callerWillJoin */);
 
+    const auto iface_tool =
+        std::make_shared<android::wifi_system::InterfaceTool>();
     // Setup hwbinder service
     android::sp<android::hardware::wifi::V1_3::IWifi> service =
         new android::hardware::wifi::V1_3::implementation::Wifi(
-            std::make_shared<WifiLegacyHal>(),
+            iface_tool, std::make_shared<WifiLegacyHal>(iface_tool),
             std::make_shared<WifiModeController>(),
-            std::make_shared<WifiIfaceUtil>(),
+            std::make_shared<WifiIfaceUtil>(iface_tool),
             std::make_shared<WifiFeatureFlags>());
     if (kLazyService) {
         LazyServiceRegistrar registrar;
diff --git a/wifi/1.3/default/tests/mock_interface_tool.cpp b/wifi/1.3/default/tests/mock_interface_tool.cpp
new file mode 100644
index 0000000..b99a164
--- /dev/null
+++ b/wifi/1.3/default/tests/mock_interface_tool.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
+#include "mock_interface_tool.h"
+
+namespace android {
+namespace wifi_system {
+
+MockInterfaceTool::MockInterfaceTool() {}
+
+}  // namespace wifi_system
+}  // namespace android
diff --git a/wifi/1.3/default/tests/mock_interface_tool.h b/wifi/1.3/default/tests/mock_interface_tool.h
new file mode 100644
index 0000000..0f17551
--- /dev/null
+++ b/wifi/1.3/default/tests/mock_interface_tool.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_INTERFACE_TOOL_H
+#define MOCK_INTERFACE_TOOL_H
+
+#include <gmock/gmock.h>
+#include <wifi_system/interface_tool.h>
+
+namespace android {
+namespace wifi_system {
+
+class MockInterfaceTool : public InterfaceTool {
+   public:
+    MockInterfaceTool();
+
+    MOCK_METHOD1(GetUpState, bool(const char* if_name));
+    MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up));
+    MOCK_METHOD1(SetWifiUpState, bool(bool request_up));
+    MOCK_METHOD2(SetMacAddress,
+                 bool(const char* if_name,
+                      const std::array<uint8_t, ETH_ALEN>& address));
+    MOCK_METHOD1(GetFactoryMacAddress,
+                 std::array<uint8_t, ETH_ALEN>(const char* if_name));
+
+};  // class MockInterfaceTool
+
+}  // namespace wifi_system
+}  // namespace android
+
+#endif  // MOCK_INTERFACE_TOOL_H
diff --git a/wifi/1.3/default/tests/mock_wifi_iface_util.cpp b/wifi/1.3/default/tests/mock_wifi_iface_util.cpp
index 706cb6a..3d877c0 100644
--- a/wifi/1.3/default/tests/mock_wifi_iface_util.cpp
+++ b/wifi/1.3/default/tests/mock_wifi_iface_util.cpp
@@ -28,7 +28,9 @@
 namespace implementation {
 namespace iface_util {
 
-MockWifiIfaceUtil::MockWifiIfaceUtil() : WifiIfaceUtil() {}
+MockWifiIfaceUtil::MockWifiIfaceUtil(
+    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
+    : WifiIfaceUtil(iface_tool) {}
 }  // namespace iface_util
 }  // namespace implementation
 }  // namespace V1_3
diff --git a/wifi/1.3/default/tests/mock_wifi_iface_util.h b/wifi/1.3/default/tests/mock_wifi_iface_util.h
index 87ab5db..8ec93eb 100644
--- a/wifi/1.3/default/tests/mock_wifi_iface_util.h
+++ b/wifi/1.3/default/tests/mock_wifi_iface_util.h
@@ -30,12 +30,16 @@
 
 class MockWifiIfaceUtil : public WifiIfaceUtil {
    public:
-    MockWifiIfaceUtil();
+    MockWifiIfaceUtil(
+        const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
     MOCK_METHOD1(getFactoryMacAddress,
                  std::array<uint8_t, 6>(const std::string&));
     MOCK_METHOD2(setMacAddress,
                  bool(const std::string&, const std::array<uint8_t, 6>&));
     MOCK_METHOD0(getOrCreateRandomMacAddress, std::array<uint8_t, 6>());
+    MOCK_METHOD2(registerIfaceEventHandlers,
+                 void(const std::string&, IfaceEventHandlers));
+    MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&));
 };
 }  // namespace iface_util
 }  // namespace implementation
diff --git a/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp
index 4cd279d..0a202c4 100644
--- a/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp
+++ b/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp
@@ -28,7 +28,9 @@
 namespace implementation {
 namespace legacy_hal {
 
-MockWifiLegacyHal::MockWifiLegacyHal() : WifiLegacyHal() {}
+MockWifiLegacyHal::MockWifiLegacyHal(
+    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
+    : WifiLegacyHal(iface_tool) {}
 }  // namespace legacy_hal
 }  // namespace implementation
 }  // namespace V1_3
diff --git a/wifi/1.3/default/tests/mock_wifi_legacy_hal.h b/wifi/1.3/default/tests/mock_wifi_legacy_hal.h
index 53fa8d6..81cb1de 100644
--- a/wifi/1.3/default/tests/mock_wifi_legacy_hal.h
+++ b/wifi/1.3/default/tests/mock_wifi_legacy_hal.h
@@ -30,7 +30,8 @@
 
 class MockWifiLegacyHal : public WifiLegacyHal {
    public:
-    MockWifiLegacyHal();
+    MockWifiLegacyHal(
+        const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
     MOCK_METHOD0(initialize, wifi_error());
     MOCK_METHOD0(start, wifi_error());
     MOCK_METHOD2(stop, wifi_error(std::unique_lock<std::recursive_mutex>*,
diff --git a/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp b/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp
index 28e028b..680f534 100644
--- a/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp
+++ b/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp
@@ -22,6 +22,7 @@
 #undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
 #include "wifi_ap_iface.h"
 
+#include "mock_interface_tool.h"
 #include "mock_wifi_feature_flags.h"
 #include "mock_wifi_iface_util.h"
 #include "mock_wifi_legacy_hal.h"
@@ -42,10 +43,12 @@
 
 class WifiApIfaceTest : public Test {
    protected:
+    std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
+        new NiceMock<wifi_system::MockInterfaceTool>};
     std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
-        new NiceMock<legacy_hal::MockWifiLegacyHal>};
+        new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_)};
     std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
-        new NiceMock<iface_util::MockWifiIfaceUtil>};
+        new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_)};
     std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
         feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
 };
diff --git a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
index 7928328..d8ce278 100644
--- a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
@@ -22,6 +22,7 @@
 #undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
 #include "wifi_chip.h"
 
+#include "mock_interface_tool.h"
 #include "mock_wifi_feature_flags.h"
 #include "mock_wifi_iface_util.h"
 #include "mock_wifi_legacy_hal.h"
@@ -263,12 +264,14 @@
 
     sp<WifiChip> chip_;
     ChipId chip_id_ = kFakeChipId;
+    std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
+        new NiceMock<wifi_system::MockInterfaceTool>};
     std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
-        new NiceMock<legacy_hal::MockWifiLegacyHal>};
+        new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_)};
     std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>>
         mode_controller_{new NiceMock<mode_controller::MockWifiModeController>};
     std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
-        new NiceMock<iface_util::MockWifiIfaceUtil>};
+        new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_)};
     std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
         feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
 
@@ -700,6 +703,72 @@
         });
 }
 
+TEST_F(WifiChipV2_AwareIfaceCombinationTest,
+       InvalidateAndRemoveNanOnStaRemove) {
+    findModeAndConfigureForIfaceType(IfaceType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+
+    // Create NAN iface
+    ASSERT_EQ(createIface(IfaceType::NAN), "wlan0");
+
+    // We should have 1 nan iface.
+    chip_->getNanIfaceNames(
+        [](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
+            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+            ASSERT_EQ(iface_names.size(), 1u);
+            ASSERT_EQ(iface_names[0], "wlan0");
+        });
+    // Retrieve the exact iface object.
+    sp<IWifiNanIface> nan_iface;
+    chip_->getNanIface("wlan0", [&nan_iface](const WifiStatus& status,
+                                             const sp<IWifiNanIface>& iface) {
+        ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+        ASSERT_NE(iface.get(), nullptr);
+        nan_iface = iface;
+    });
+
+    // Remove the STA iface.
+    removeIface(IfaceType::STA, "wlan0");
+    // We should have 0 nan iface now.
+    chip_->getNanIfaceNames(
+        [](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
+            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+            ASSERT_EQ(iface_names.size(), 0u);
+        });
+    // Any operation on the nan iface object should return error now.
+    nan_iface->getName(
+        [](const WifiStatus& status, const std::string& /* iface_name */) {
+            ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, status.code);
+        });
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest,
+       InvalidateAndRemoveRttControllerOnStaRemove) {
+    findModeAndConfigureForIfaceType(IfaceType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+
+    // Create RTT controller
+    sp<IWifiRttController> rtt_controller;
+    chip_->createRttController(
+        NULL, [&rtt_controller](const WifiStatus& status,
+                                const sp<IWifiRttController>& rtt) {
+            if (WifiStatusCode::SUCCESS == status.code) {
+                ASSERT_NE(rtt.get(), nullptr);
+                rtt_controller = rtt;
+            }
+        });
+
+    // Remove the STA iface.
+    removeIface(IfaceType::STA, "wlan0");
+
+    // Any operation on the rtt controller object should return error now.
+    rtt_controller->getBoundIface(
+        [](const WifiStatus& status, const sp<IWifiIface>& /* iface */) {
+            ASSERT_EQ(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                      status.code);
+        });
+}
+
 ////////// V1 Iface Combinations when AP creation is disabled //////////
 class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
    public:
@@ -732,6 +801,7 @@
     ASSERT_TRUE(createIface(IfaceType::AP).empty());
 }
 
+////////// Hypothetical Iface Combination with multiple ifaces //////////
 class WifiChip_MultiIfaceTest : public WifiChipTest {
    public:
     void SetUp() override {
diff --git a/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp
index e5758fa..28d23ff 100644
--- a/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp
+++ b/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp
@@ -21,10 +21,15 @@
 #undef NAN
 #include "wifi_iface_util.h"
 
+#include "mock_interface_tool.h"
+
+using testing::NiceMock;
 using testing::Test;
 
 namespace {
 constexpr uint8_t kValidUnicastLocallyAssignedMacAddressMask = 0x02;
+constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc};
+constexpr char kIfaceName[] = "test-wlan0";
 
 bool isValidUnicastLocallyAssignedMacAddress(
     const std::array<uint8_t, 6>& mac_address) {
@@ -38,19 +43,52 @@
 namespace wifi {
 namespace V1_3 {
 namespace implementation {
+namespace iface_util {
 class WifiIfaceUtilTest : public Test {
    protected:
-    iface_util::WifiIfaceUtil iface_util_;
+    std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
+        new NiceMock<wifi_system::MockInterfaceTool>};
+    WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_);
 };
 
 TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) {
-    auto mac_address = iface_util_.getOrCreateRandomMacAddress();
+    auto mac_address = iface_util_->getOrCreateRandomMacAddress();
     ASSERT_TRUE(isValidUnicastLocallyAssignedMacAddress(mac_address));
 
     // All further calls should return the same MAC address.
-    ASSERT_EQ(mac_address, iface_util_.getOrCreateRandomMacAddress());
-    ASSERT_EQ(mac_address, iface_util_.getOrCreateRandomMacAddress());
+    ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
+    ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
 }
+
+TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) {
+    std::array<uint8_t, 6> mac_address = {};
+    std::copy(std::begin(kMacAddress), std::end(kMacAddress),
+              std::begin(mac_address));
+    EXPECT_CALL(*iface_tool_, SetMacAddress(testing::_, testing::_))
+        .WillRepeatedly(testing::Return(true));
+    EXPECT_CALL(*iface_tool_, SetUpState(testing::_, testing::_))
+        .WillRepeatedly(testing::Return(true));
+
+    // Register for iface state toggle events.
+    bool callback_invoked = false;
+    iface_util::IfaceEventHandlers event_handlers = {};
+    event_handlers.on_state_toggle_off_on =
+        [&callback_invoked](const std::string& /* iface_name */) {
+            callback_invoked = true;
+        };
+    iface_util_->registerIfaceEventHandlers(kIfaceName, event_handlers);
+    // Invoke setMacAddress and ensure that the cb is invoked.
+    ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
+    ASSERT_TRUE(callback_invoked);
+
+    // Unregister for iface state toggle events.
+    callback_invoked = false;
+    iface_util_->unregisterIfaceEventHandlers(kIfaceName);
+    // Invoke setMacAddress and ensure that the cb is not invoked.
+    ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
+    ASSERT_FALSE(callback_invoked);
+}
+}  // namespace iface_util
 }  // namespace implementation
 }  // namespace V1_3
 }  // namespace wifi
diff --git a/wifi/1.3/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.3/default/tests/wifi_nan_iface_unit_tests.cpp
new file mode 100644
index 0000000..eb6c610
--- /dev/null
+++ b/wifi/1.3/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <cutils/properties.h>
+#include <gmock/gmock.h>
+
+#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
+#include "wifi_nan_iface.h"
+
+#include "mock_interface_tool.h"
+#include "mock_wifi_feature_flags.h"
+#include "mock_wifi_iface_util.h"
+#include "mock_wifi_legacy_hal.h"
+
+using testing::NiceMock;
+using testing::Return;
+using testing::Test;
+
+namespace {
+constexpr char kIfaceName[] = "mockWlan0";
+}  // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_3 {
+namespace implementation {
+
+bool CaptureIfaceEventHandlers(
+    const std::string& /* iface_name*/,
+    iface_util::IfaceEventHandlers in_iface_event_handlers,
+    iface_util::IfaceEventHandlers* out_iface_event_handlers) {
+    *out_iface_event_handlers = in_iface_event_handlers;
+    return true;
+}
+
+class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback {
+   public:
+    MockNanIfaceEventCallback() = default;
+
+    MOCK_METHOD3(notifyCapabilitiesResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&,
+                              const NanCapabilities&));
+    MOCK_METHOD2(notifyEnableResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyConfigResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyDisableResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD3(notifyStartPublishResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&, uint8_t));
+    MOCK_METHOD2(notifyStopPublishResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD3(notifyStartSubscribeResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&, uint8_t));
+    MOCK_METHOD2(notifyStopSubscribeResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyTransmitFollowupResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyCreateDataInterfaceResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyDeleteDataInterfaceResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD3(notifyInitiateDataPathResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&, uint32_t));
+    MOCK_METHOD2(notifyRespondToDataPathIndicationResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyTerminateDataPathResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD1(eventClusterEvent, Return<void>(const NanClusterEventInd&));
+    MOCK_METHOD1(eventDisabled, Return<void>(const WifiNanStatus&));
+    MOCK_METHOD2(eventPublishTerminated,
+                 Return<void>(uint8_t, const WifiNanStatus&));
+    MOCK_METHOD2(eventSubscribeTerminated,
+                 Return<void>(uint8_t, const WifiNanStatus&));
+    MOCK_METHOD1(eventMatch, Return<void>(const NanMatchInd&));
+    MOCK_METHOD2(eventMatchExpired, Return<void>(uint8_t, uint32_t));
+    MOCK_METHOD1(eventFollowupReceived,
+                 Return<void>(const NanFollowupReceivedInd&));
+    MOCK_METHOD2(eventTransmitFollowup,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD1(eventDataPathRequest,
+                 Return<void>(const NanDataPathRequestInd&));
+    MOCK_METHOD1(eventDataPathConfirm,
+                 Return<void>(const NanDataPathConfirmInd&));
+    MOCK_METHOD1(eventDataPathTerminated, Return<void>(uint32_t));
+};
+
+class WifiNanIfaceTest : public Test {
+   protected:
+    std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
+        new NiceMock<wifi_system::MockInterfaceTool>};
+    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+        new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_)};
+    std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
+        new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_)};
+};
+
+TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
+    iface_util::IfaceEventHandlers captured_iface_event_handlers = {};
+    EXPECT_CALL(*legacy_hal_,
+                nanRegisterCallbackHandlers(testing::_, testing::_))
+        .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+    EXPECT_CALL(*iface_util_,
+                registerIfaceEventHandlers(testing::_, testing::_))
+        .WillOnce(testing::Invoke(
+            bind(CaptureIfaceEventHandlers, std::placeholders::_1,
+                 std::placeholders::_2, &captured_iface_event_handlers)));
+    sp<WifiNanIface> nan_iface =
+        new WifiNanIface(kIfaceName, legacy_hal_, iface_util_);
+
+    // Register a mock nan event callback.
+    sp<NiceMock<MockNanIfaceEventCallback>> mock_event_callback{
+        new NiceMock<MockNanIfaceEventCallback>};
+    nan_iface->registerEventCallback(
+        mock_event_callback, [](const WifiStatus& status) {
+            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+        });
+    // Ensure that the eventDisabled() function in mock callback will be
+    // invoked.
+    WifiNanStatus expected_nan_status = {
+        NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+    EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status))
+        .Times(1);
+
+    // Trigger the iface state toggle callback.
+    captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName);
+}
+}  // namespace implementation
+}  // namespace V1_3
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.3/default/wifi.cpp b/wifi/1.3/default/wifi.cpp
index 1f64085..2f21819 100644
--- a/wifi/1.3/default/wifi.cpp
+++ b/wifi/1.3/default/wifi.cpp
@@ -34,11 +34,13 @@
 using hidl_return_util::validateAndCallWithLock;
 
 Wifi::Wifi(
+    const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
     const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
     const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
     const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
     const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
-    : legacy_hal_(legacy_hal),
+    : iface_tool_(iface_tool),
+      legacy_hal_(legacy_hal),
       mode_controller_(mode_controller),
       iface_util_(iface_util),
       feature_flags_(feature_flags),
diff --git a/wifi/1.3/default/wifi.h b/wifi/1.3/default/wifi.h
index c4ab773..1c2a154 100644
--- a/wifi/1.3/default/wifi.h
+++ b/wifi/1.3/default/wifi.h
@@ -40,7 +40,8 @@
  */
 class Wifi : public V1_3::IWifi {
    public:
-    Wifi(const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+    Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
+         const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
          const std::shared_ptr<mode_controller::WifiModeController>
              mode_controller,
          const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
@@ -77,6 +78,7 @@
 
     // Instance is created in this root level |IWifi| HIDL interface object
     // and shared with all the child HIDL interface objects.
+    std::shared_ptr<wifi_system::InterfaceTool> iface_tool_;
     std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
     std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
     std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp
index b768959..e9991dc 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.3/default/wifi_chip.cpp
@@ -634,6 +634,27 @@
     rtt_controllers_.clear();
 }
 
+void WifiChip::invalidateAndRemoveDependencies(
+    const std::string& removed_iface_name) {
+    for (const auto& nan_iface : nan_ifaces_) {
+        if (nan_iface->getName() == removed_iface_name) {
+            invalidateAndClear(nan_ifaces_, nan_iface);
+            for (const auto& callback : event_cb_handler_.getCallbacks()) {
+                if (!callback
+                         ->onIfaceRemoved(IfaceType::NAN, removed_iface_name)
+                         .isOk()) {
+                    LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+                }
+            }
+        }
+    }
+    for (const auto& rtt : rtt_controllers_) {
+        if (rtt->getIfaceName() == removed_iface_name) {
+            invalidateAndClear(rtt_controllers_, rtt);
+        }
+    }
+}
+
 std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
     return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
 }
@@ -819,6 +840,11 @@
     if (!iface.get()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
+    // Invalidate & remove any dependent objects first.
+    // Note: This is probably not required because we never create
+    // nan/rtt objects over AP iface. But, there is no harm to do it
+    // here and not make that assumption all over the place.
+    invalidateAndRemoveDependencies(ifname);
     invalidateAndClear(ap_ifaces_, iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
@@ -835,7 +861,7 @@
     }
     // These are still assumed to be based on wlan0.
     std::string ifname = getFirstActiveWlanIfaceName();
-    sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
+    sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_, iface_util_);
     nan_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
@@ -960,6 +986,8 @@
     if (!iface.get()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
+    // Invalidate & remove any dependent objects first.
+    invalidateAndRemoveDependencies(ifname);
     invalidateAndClear(sta_ifaces_, iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
@@ -1435,6 +1463,13 @@
     return canCurrentModeSupportIfaceCombo(req_iface_combo);
 }
 
+bool WifiChip::isDualApAllowedInCurrentMode() {
+    // Check if we can support atleast 1 STA & 1 AP concurrently.
+    std::map<IfaceType, size_t> req_iface_combo;
+    req_iface_combo[IfaceType::AP] = 2;
+    return canCurrentModeSupportIfaceCombo(req_iface_combo);
+}
+
 std::string WifiChip::getFirstActiveWlanIfaceName() {
     if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
     if (ap_ifaces_.size() > 0) return ap_ifaces_[0]->getName();
@@ -1460,10 +1495,12 @@
 }
 
 // AP iface names start with idx 1 for modes supporting
-// concurrent STA, else start with idx 0.
+// concurrent STA and not dual AP, else start with idx 0.
 std::string WifiChip::allocateApIfaceName() {
-    return allocateApOrStaIfaceName(
-        isStaApConcurrencyAllowedInCurrentMode() ? 1 : 0);
+    return allocateApOrStaIfaceName((isStaApConcurrencyAllowedInCurrentMode() &&
+                                     !isDualApAllowedInCurrentMode())
+                                        ? 1
+                                        : 0);
 }
 
 // STA iface names start with idx 0.
diff --git a/wifi/1.3/default/wifi_chip.h b/wifi/1.3/default/wifi_chip.h
index 3d12f4c..153ca6a 100644
--- a/wifi/1.3/default/wifi_chip.h
+++ b/wifi/1.3/default/wifi_chip.h
@@ -155,6 +155,9 @@
 
    private:
     void invalidateAndRemoveAllIfaces();
+    // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are
+    // invalidated & removed.
+    void invalidateAndRemoveDependencies(const std::string& removed_iface_name);
 
     // Corresponding worker functions for the HIDL methods.
     std::pair<WifiStatus, ChipId> getIdInternal();
@@ -237,6 +240,7 @@
     bool canCurrentModeSupportIfaceOfType(IfaceType requested_type);
     bool isValidModeId(ChipModeId mode_id);
     bool isStaApConcurrencyAllowedInCurrentMode();
+    bool isDualApAllowedInCurrentMode();
     std::string getFirstActiveWlanIfaceName();
     std::string allocateApOrStaIfaceName(uint32_t start_idx);
     std::string allocateApIfaceName();
diff --git a/wifi/1.3/default/wifi_iface_util.cpp b/wifi/1.3/default/wifi_iface_util.cpp
index 5d61271..34bc02d 100644
--- a/wifi/1.3/default/wifi_iface_util.cpp
+++ b/wifi/1.3/default/wifi_iface_util.cpp
@@ -39,27 +39,39 @@
 namespace implementation {
 namespace iface_util {
 
-WifiIfaceUtil::WifiIfaceUtil() : random_mac_address_(nullptr) {}
+WifiIfaceUtil::WifiIfaceUtil(
+    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
+    : iface_tool_(iface_tool),
+      random_mac_address_(nullptr),
+      event_handlers_map_() {}
 
 std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(
     const std::string& iface_name) {
-    return iface_tool_.GetFactoryMacAddress(iface_name.c_str());
+    return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str());
 }
 
 bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
                                   const std::array<uint8_t, 6>& mac) {
-    if (!iface_tool_.SetUpState(iface_name.c_str(), false)) {
+    if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) {
         LOG(ERROR) << "SetUpState(false) failed.";
         return false;
     }
-    if (!iface_tool_.SetMacAddress(iface_name.c_str(), mac)) {
+    if (!iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac)) {
         LOG(ERROR) << "SetMacAddress failed.";
         return false;
     }
-    if (!iface_tool_.SetUpState(iface_name.c_str(), true)) {
+    if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
         LOG(ERROR) << "SetUpState(true) failed.";
         return false;
     }
+    IfaceEventHandlers event_handlers = {};
+    const auto it = event_handlers_map_.find(iface_name);
+    if (it != event_handlers_map_.end()) {
+        event_handlers = it->second;
+    }
+    if (event_handlers.on_state_toggle_off_on != nullptr) {
+        event_handlers.on_state_toggle_off_on(iface_name);
+    }
     LOG(DEBUG) << "Successfully SetMacAddress.";
     return true;
 }
@@ -73,6 +85,16 @@
     return *random_mac_address_.get();
 }
 
+void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name,
+                                               IfaceEventHandlers handlers) {
+    event_handlers_map_[iface_name] = handlers;
+}
+
+void WifiIfaceUtil::unregisterIfaceEventHandlers(
+    const std::string& iface_name) {
+    event_handlers_map_.erase(iface_name);
+}
+
 std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
     std::array<uint8_t, 6> address = {};
     std::random_device rd;
diff --git a/wifi/1.3/default/wifi_iface_util.h b/wifi/1.3/default/wifi_iface_util.h
index b238234..98073e0 100644
--- a/wifi/1.3/default/wifi_iface_util.h
+++ b/wifi/1.3/default/wifi_iface_util.h
@@ -28,12 +28,19 @@
 namespace implementation {
 namespace iface_util {
 
+// Iface event handlers.
+struct IfaceEventHandlers {
+    // Callback to be invoked when the iface is set down & up for MAC address
+    // change.
+    std::function<void(const std::string& iface_name)> on_state_toggle_off_on;
+};
+
 /**
  * Util class for common iface operations.
  */
 class WifiIfaceUtil {
    public:
-    WifiIfaceUtil();
+    WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
     virtual ~WifiIfaceUtil() = default;
 
     virtual std::array<uint8_t, 6> getFactoryMacAddress(
@@ -45,11 +52,17 @@
     // daemon. (So, changes on every reboot)
     virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress();
 
+    // Register for any iface event callbacks for the provided interface.
+    virtual void registerIfaceEventHandlers(const std::string& iface_name,
+                                            IfaceEventHandlers handlers);
+    virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
+
    private:
     std::array<uint8_t, 6> createRandomMacAddress();
 
-    wifi_system::InterfaceTool iface_tool_;
+    std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
     std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
+    std::map<std::string, IfaceEventHandlers> event_handlers_map_;
 };
 
 }  // namespace iface_util
diff --git a/wifi/1.3/default/wifi_legacy_hal.cpp b/wifi/1.3/default/wifi_legacy_hal.cpp
index 7f9b635..485bd16 100644
--- a/wifi/1.3/default/wifi_legacy_hal.cpp
+++ b/wifi/1.3/default/wifi_legacy_hal.cpp
@@ -333,10 +333,12 @@
 }
 // End of the free-standing "C" style callbacks.
 
-WifiLegacyHal::WifiLegacyHal()
+WifiLegacyHal::WifiLegacyHal(
+    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
     : global_handle_(nullptr),
       awaiting_event_loop_termination_(false),
-      is_started_(false) {}
+      is_started_(false),
+      iface_tool_(iface_tool) {}
 
 wifi_error WifiLegacyHal::initialize() {
     LOG(DEBUG) << "Initialize legacy HAL";
@@ -371,7 +373,7 @@
     property_set(kDriverPropName, "ok");
 
     LOG(DEBUG) << "Starting legacy HAL";
-    if (!iface_tool_.SetWifiUpState(true)) {
+    if (!iface_tool_.lock()->SetWifiUpState(true)) {
         LOG(ERROR) << "Failed to set WiFi interface up";
         return WIFI_ERROR_UNKNOWN;
     }
@@ -407,7 +409,7 @@
         // Invalidate all the internal pointers now that the HAL is
         // stopped.
         invalidate();
-        iface_tool_.SetWifiUpState(false);
+        iface_tool_.lock()->SetWifiUpState(false);
         on_stop_complete_user_callback();
         is_started_ = false;
     };
diff --git a/wifi/1.3/default/wifi_legacy_hal.h b/wifi/1.3/default/wifi_legacy_hal.h
index a3ed460..9cfa172 100644
--- a/wifi/1.3/default/wifi_legacy_hal.h
+++ b/wifi/1.3/default/wifi_legacy_hal.h
@@ -170,7 +170,7 @@
  */
 class WifiLegacyHal {
    public:
-    WifiLegacyHal();
+    WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
     virtual ~WifiLegacyHal() = default;
 
     // Initialize the legacy HAL function table.
@@ -391,7 +391,7 @@
     std::condition_variable_any stop_wait_cv_;
     // Flag to indicate if the legacy HAL has been started.
     bool is_started_;
-    wifi_system::InterfaceTool iface_tool_;
+    std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
 };
 
 }  // namespace legacy_hal
diff --git a/wifi/1.3/default/wifi_nan_iface.cpp b/wifi/1.3/default/wifi_nan_iface.cpp
index 4325f44..ff9f422 100644
--- a/wifi/1.3/default/wifi_nan_iface.cpp
+++ b/wifi/1.3/default/wifi_nan_iface.cpp
@@ -30,8 +30,12 @@
 
 WifiNanIface::WifiNanIface(
     const std::string& ifname,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
-    : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {
+    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+    const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+    : ifname_(ifname),
+      legacy_hal_(legacy_hal),
+      iface_util_(iface_util),
+      is_valid_(true) {
     // Register all the callbacks here. these should be valid for the lifetime
     // of the object. Whenever the mode changes legacy HAL will remove
     // all of these callbacks.
@@ -498,6 +502,26 @@
         LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
         invalidate();
     }
+
+    // Register for iface state toggle events.
+    iface_util::IfaceEventHandlers event_handlers = {};
+    event_handlers.on_state_toggle_off_on =
+        [weak_ptr_this](const std::string& /* iface_name */) {
+            const auto shared_ptr_this = weak_ptr_this.promote();
+            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                LOG(ERROR) << "Callback invoked on an invalid object";
+                return;
+            }
+            // Tell framework that NAN has been disabled.
+            WifiNanStatus status = {
+                NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                if (!callback->eventDisabled(status).isOk()) {
+                    LOG(ERROR) << "Failed to invoke the callback";
+                }
+            }
+        };
+    iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
 }
 
 void WifiNanIface::invalidate() {
@@ -505,7 +529,7 @@
     legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
     legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
     legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
-
+    iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
     legacy_hal_.reset();
     event_cb_handler_.invalidate();
     event_cb_handler_1_2_.invalidate();
diff --git a/wifi/1.3/default/wifi_nan_iface.h b/wifi/1.3/default/wifi_nan_iface.h
index f735d61..737be93 100644
--- a/wifi/1.3/default/wifi_nan_iface.h
+++ b/wifi/1.3/default/wifi_nan_iface.h
@@ -22,6 +22,7 @@
 #include <android/hardware/wifi/1.2/IWifiNanIface.h>
 
 #include "hidl_callback_util.h"
+#include "wifi_iface_util.h"
 #include "wifi_legacy_hal.h"
 
 namespace android {
@@ -37,7 +38,8 @@
 class WifiNanIface : public V1_2::IWifiNanIface {
    public:
     WifiNanIface(const std::string& ifname,
-                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
     // Refer to |WifiChip::invalidate()|.
     void invalidate();
     bool isValid();
@@ -147,6 +149,7 @@
 
     std::string ifname_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
     bool is_valid_;
     hidl_callback_util::HidlCallbackHandler<V1_0::IWifiNanIfaceEventCallback>
         event_cb_handler_;
diff --git a/wifi/1.3/default/wifi_rtt_controller.cpp b/wifi/1.3/default/wifi_rtt_controller.cpp
index fa317e3..3dcbee6 100644
--- a/wifi/1.3/default/wifi_rtt_controller.cpp
+++ b/wifi/1.3/default/wifi_rtt_controller.cpp
@@ -49,6 +49,8 @@
     return event_callbacks_;
 }
 
+std::string WifiRttController::getIfaceName() { return ifname_; }
+
 Return<void> WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) {
     return validateAndCall(
         this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
diff --git a/wifi/1.3/default/wifi_rtt_controller.h b/wifi/1.3/default/wifi_rtt_controller.h
index 9798b79..eedd22a 100644
--- a/wifi/1.3/default/wifi_rtt_controller.h
+++ b/wifi/1.3/default/wifi_rtt_controller.h
@@ -42,6 +42,7 @@
     void invalidate();
     bool isValid();
     std::vector<sp<IWifiRttControllerEventCallback>> getEventCallbacks();
+    std::string getIfaceName();
 
     // HIDL methods exposed.
     Return<void> getBoundIface(getBoundIface_cb hidl_status_cb) override;