Merge remote-tracking branch 'aosp/pie-gsi' into lineage-16.0-pie-gsi

* aosp/pie-gsi:
  Fix VtsHalWifiV1_0Host#WifiStaIfaceHidlTest.SetScanningMacOui fail
  wifi(vts): Don't enforce interface combination in VTS tests
  Sleep one second after connect.
  health vts: implement GTEST_SKIP if not defined.
  health: skip VTS on healthd if vendor HAL is present.
  VTS tests to work with depth Y16
  omx:component: add support for tunneled components in ComponentTest
  Call notify for voiceReg and dataReg VTS tests
  Add REQUEST_NOT_SUPPORTED for changeIccPinForApp and changeIccPin2ForApp
  Fix free() in keymaster VTS
  Respect limited requirements for Strongbox KM implementations
  Disable arm32 asan for VtsHalNeuralnetworksV1_1TargetTest
  Revert "Restore "Add "Unlocked device required" parameter to keys""
  Revert "Add "Unlocked device required" parameter to keys"

Change-Id: I6603dae5afc7fdec1eb7b4f9623bbe8a92e56448
diff --git a/audio/common/all-versions/default/service/Android.mk b/audio/common/all-versions/default/service/Android.mk
index 43d7fe1..73d03f1 100644
--- a/audio/common/all-versions/default/service/Android.mk
+++ b/audio/common/all-versions/default/service/Android.mk
@@ -35,8 +35,10 @@
     libhidlbase \
     libhidltransport \
     liblog \
+    libcutils \
     libutils \
     libhardware \
+    libhwbinder \
     android.hardware.audio@2.0 \
     android.hardware.audio@4.0 \
     android.hardware.audio.common@2.0 \
@@ -55,4 +57,8 @@
 LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
 endif
 
+ifeq ($(TARGET_ARCH),arm)
+    LOCAL_CFLAGS += -DARCH_ARM_32
+endif
+
 include $(BUILD_EXECUTABLE)
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index c7ce638..f82a26f 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -27,10 +27,31 @@
 #include <hidl/HidlTransportSupport.h>
 #include <hidl/LegacySupport.h>
 
+#ifdef ARCH_ARM_32
+#include <hwbinder/ProcessState.h>
+#include <cutils/properties.h>
+#endif
+
 using namespace android::hardware;
 using android::OK;
 
+#ifdef ARCH_ARM_32
+// default h/w binder memsize is 1 MB
+#define DEFAULT_HW_BINDER_MEM_SIZE_KB 1024
+
+size_t getHWBinderMmapSize(){
+    int32_t value = DEFAULT_HW_BINDER_MEM_SIZE_KB;
+    value = property_get_int32("persist.vendor.audio.hw.binder.size_kbyte", value);
+    ALOGD("Init hw binder with mem  size = %d  ", value);
+    return 1024 * value;
+}
+#endif
+
 int main(int /* argc */, char* /* argv */ []) {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize(getHWBinderMmapSize());
+#endif
+
     android::ProcessState::initWithDriver("/dev/vndbinder");
     // start a threadpool for vndbinder interactions
     android::ProcessState::self()->startThreadPool();
diff --git a/boot/1.0/default/Android.bp b/boot/1.0/default/Android.bp
index 6cfbf32..f64eb91 100644
--- a/boot/1.0/default/Android.bp
+++ b/boot/1.0/default/Android.bp
@@ -31,6 +31,13 @@
         "libhidltransport",
         "libutils",
         "android.hardware.boot@1.0",
+        "libhwbinder",
     ],
-
+    arch: {
+        arm: {
+            cflags: [
+                "-DARCH_ARM_32"
+            ],
+        },
+    },
 }
diff --git a/boot/1.0/default/service.cpp b/boot/1.0/default/service.cpp
index f3996ef..8c92494 100644
--- a/boot/1.0/default/service.cpp
+++ b/boot/1.0/default/service.cpp
@@ -22,5 +22,9 @@
 using android::hardware::defaultPassthroughServiceImplementation;
 
 int main (int /* argc */, char * /* argv */ []) {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize((size_t)8192);
+#endif
+
     return defaultPassthroughServiceImplementation<IBootControl>();
 }
diff --git a/camera/device/1.0/default/Android.bp b/camera/device/1.0/default/Android.bp
index 4a7fc9c..adedfdc 100644
--- a/camera/device/1.0/default/Android.bp
+++ b/camera/device/1.0/default/Android.bp
@@ -29,6 +29,14 @@
     header_libs: [
         "media_plugin_headers",
     ],
+    product_variables: {
+        lineage: {
+            uses_qti_camera_device: {
+                cppflags: ["-DQTI_CAMERA_DEVICE"],
+                shared_libs: ["vendor.qti.hardware.camera.device@1.0"],
+            },
+        },
+    },
     export_include_dirs: ["."]
 }
 
diff --git a/camera/device/1.0/default/CameraDevice.cpp b/camera/device/1.0/default/CameraDevice.cpp
index a03bbc8..a1f1830 100644
--- a/camera/device/1.0/default/CameraDevice.cpp
+++ b/camera/device/1.0/default/CameraDevice.cpp
@@ -428,30 +428,72 @@
              index, mem->mNumBufs);
         return;
     }
-    if (object->mDeviceCallback != nullptr) {
-        CameraFrameMetadata hidlMetadata;
-        if (metadata) {
-            hidlMetadata.faces.resize(metadata->number_of_faces);
-            for (size_t i = 0; i < hidlMetadata.faces.size(); i++) {
-                hidlMetadata.faces[i].score = metadata->faces[i].score;
-                hidlMetadata.faces[i].id = metadata->faces[i].id;
-                for (int k = 0; k < 4; k++) {
-                    hidlMetadata.faces[i].rect[k] = metadata->faces[i].rect[k];
-                }
-                for (int k = 0; k < 2; k++) {
-                    hidlMetadata.faces[i].leftEye[k] = metadata->faces[i].left_eye[k];
-                }
-                for (int k = 0; k < 2; k++) {
-                    hidlMetadata.faces[i].rightEye[k] = metadata->faces[i].right_eye[k];
-                }
-                for (int k = 0; k < 2; k++) {
-                    hidlMetadata.faces[i].mouth[k] = metadata->faces[i].mouth[k];
-                }
-            }
-        }
-        CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle);
-        object->mDeviceCallback->dataCallback(
-                (DataCallbackMsg) msg_type, mem->handle.mId, index, hidlMetadata);
+#ifdef QTI_CAMERA_DEVICE
+    if(object->mQDeviceCallback != nullptr) {
+         vendor::qti::hardware::camera::device::V1_0::QCameraFrameMetadata hidlMetadata;
+         if (metadata) {
+             hidlMetadata.faces.resize(metadata->number_of_faces);
+             for (size_t i = 0; i < hidlMetadata.faces.size(); i++) {
+                 hidlMetadata.faces[i].score = metadata->faces[i].score;
+                 hidlMetadata.faces[i].id = metadata->faces[i].id;
+                 for (int k = 0; k < 4; k++) {
+                     hidlMetadata.faces[i].rect[k] = metadata->faces[i].rect[k];
+                 }
+                 for (int k = 0; k < 2; k++) {
+                     hidlMetadata.faces[i].leftEye[k] = metadata->faces[i].left_eye[k];
+                 }
+                 for (int k = 0; k < 2; k++) {
+                     hidlMetadata.faces[i].rightEye[k] = metadata->faces[i].right_eye[k];
+                 }
+                 for (int k = 0; k < 2; k++) {
+                     hidlMetadata.faces[i].mouth[k] = metadata->faces[i].mouth[k];
+                 }
+                 hidlMetadata.faces[i].smile_degree = metadata->faces[i].smile_degree;
+                 hidlMetadata.faces[i].smile_score = metadata->faces[i].smile_score;
+                 hidlMetadata.faces[i].blink_detected = metadata->faces[i].blink_detected;
+                 hidlMetadata.faces[i].face_recognised = metadata->faces[i].face_recognised;
+                 hidlMetadata.faces[i].gaze_angle = metadata->faces[i].gaze_angle;
+                 hidlMetadata.faces[i].updown_dir = metadata->faces[i].updown_dir;
+                 hidlMetadata.faces[i].leftright_dir = metadata->faces[i].leftright_dir;
+                 hidlMetadata.faces[i].roll_dir = metadata->faces[i].roll_dir;
+                 hidlMetadata.faces[i].left_right_gaze = metadata->faces[i].left_right_gaze;
+                 hidlMetadata.faces[i].top_bottom_gaze = metadata->faces[i].top_bottom_gaze;
+                 hidlMetadata.faces[i].leye_blink = metadata->faces[i].leye_blink;
+                 hidlMetadata.faces[i].reye_blink = metadata->faces[i].reye_blink;
+             }
+         }
+         CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle);
+         object->mQDeviceCallback->QDataCallback(
+                 (DataCallbackMsg) msg_type, mem->handle.mId, index, hidlMetadata);
+    } else {
+#endif
+       if (object->mDeviceCallback != nullptr) {
+           CameraFrameMetadata hidlMetadata;
+           if (metadata) {
+               hidlMetadata.faces.resize(metadata->number_of_faces);
+               for (size_t i = 0; i < hidlMetadata.faces.size(); i++) {
+                   hidlMetadata.faces[i].score = metadata->faces[i].score;
+                   hidlMetadata.faces[i].id = metadata->faces[i].id;
+                   for (int k = 0; k < 4; k++) {
+                       hidlMetadata.faces[i].rect[k] = metadata->faces[i].rect[k];
+                   }
+                   for (int k = 0; k < 2; k++) {
+                       hidlMetadata.faces[i].leftEye[k] = metadata->faces[i].left_eye[k];
+                   }
+                   for (int k = 0; k < 2; k++) {
+                       hidlMetadata.faces[i].rightEye[k] = metadata->faces[i].right_eye[k];
+                   }
+                   for (int k = 0; k < 2; k++) {
+                       hidlMetadata.faces[i].mouth[k] = metadata->faces[i].mouth[k];
+                   }
+               }
+           }
+           CameraHeapMemory* mem = static_cast<CameraHeapMemory *>(data->handle);
+           object->mDeviceCallback->dataCallback(
+                   (DataCallbackMsg) msg_type, mem->handle.mId, index, hidlMetadata);
+#ifdef QTI_CAMERA_DEVICE
+       }
+#endif
     }
 }
 
@@ -667,6 +709,13 @@
 
     initHalPreviewWindow();
     mDeviceCallback = callback;
+#ifdef QTI_CAMERA_DEVICE
+    mQDeviceCallback =
+        vendor::qti::hardware::camera::device::V1_0::IQCameraDeviceCallback::castFrom(callback);
+    if(mQDeviceCallback == nullptr) {
+        ALOGI("could not cast ICameraDeviceCallback to IQCameraDeviceCallback");
+    }
+#endif
 
     if (mDevice->ops->set_callbacks) {
         mDevice->ops->set_callbacks(mDevice,
diff --git a/camera/device/1.0/default/CameraDevice_1_0.h b/camera/device/1.0/default/CameraDevice_1_0.h
index 2c980f0..2b35a73 100644
--- a/camera/device/1.0/default/CameraDevice_1_0.h
+++ b/camera/device/1.0/default/CameraDevice_1_0.h
@@ -24,6 +24,9 @@
 #include "HandleImporter.h"
 
 #include <android/hardware/camera/device/1.0/ICameraDevice.h>
+#ifdef QTI_CAMERA_DEVICE
+#include <vendor/qti/hardware/camera/device/1.0/IQCameraDeviceCallback.h>
+#endif
 #include <android/hidl/allocator/1.0/IAllocator.h>
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <hidl/MQDescriptor.h>
@@ -44,6 +47,9 @@
 using ::android::hardware::camera::device::V1_0::CameraInfo;
 using ::android::hardware::camera::device::V1_0::CommandType;
 using ::android::hardware::camera::device::V1_0::ICameraDevice;
+#ifdef QTI_CAMERA_DEVICE
+using ::vendor::qti::hardware::camera::device::V1_0::IQCameraDeviceCallback;
+#endif
 using ::android::hardware::camera::device::V1_0::ICameraDeviceCallback;
 using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
 using ::android::hardware::camera::device::V1_0::MemoryId;
@@ -164,6 +170,9 @@
     const SortedVector<std::pair<std::string, std::string>>& mCameraDeviceNames;
 
     sp<ICameraDeviceCallback> mDeviceCallback = nullptr;
+#ifdef QTI_CAMERA_DEVICE
+    sp<IQCameraDeviceCallback> mQDeviceCallback = nullptr;
+#endif
 
     mutable Mutex mMemoryMapLock; // gating access to mMemoryMap
                                   // must not hold mLock after this lock is acquired
diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp
index ae24d78..f3de961 100644
--- a/camera/provider/2.4/default/Android.bp
+++ b/camera/provider/2.4/default/Android.bp
@@ -33,6 +33,14 @@
         "camera.device@3.4-impl_headers",
         "camera.device@3.4-external-impl_headers"
     ],
+    product_variables: {
+        lineage: {
+            uses_qti_camera_device: {
+                cppflags: ["-DQTI_CAMERA_DEVICE"],
+                shared_libs: ["vendor.qti.hardware.camera.device@1.0"],
+            },
+        },
+    },
     static_libs: [
         "android.hardware.camera.common@1.0-helper",
     ],
@@ -105,4 +113,12 @@
         "android.hardware.camera.provider@2.4",
         "android.hardware.camera.common@1.0",
     ],
+    product_variables: {
+        lineage: {
+            uses_qti_camera_device: {
+                cppflags: ["-DQTI_CAMERA_DEVICE"],
+                shared_libs: ["vendor.qti.hardware.camera.device@1.0"],
+            },
+        },
+    },
 }
diff --git a/cas/1.0/default/Android.bp b/cas/1.0/default/Android.bp
index 544162b..f65a990 100644
--- a/cas/1.0/default/Android.bp
+++ b/cas/1.0/default/Android.bp
@@ -25,9 +25,15 @@
       "libhidltransport",
       "liblog",
       "libutils",
+      "libhwbinder"
     ],
     header_libs: [
       "libstagefright_foundation_headers",
       "media_plugin_headers",
     ],
+    arch: {
+        arm: {
+            cflags: ["-DARCH_ARM_32"],
+        },
+    },
 }
diff --git a/cas/1.0/default/service.cpp b/cas/1.0/default/service.cpp
index 04a8ad9..91ee8ac 100644
--- a/cas/1.0/default/service.cpp
+++ b/cas/1.0/default/service.cpp
@@ -23,12 +23,20 @@
 
 #include "MediaCasService.h"
 
+#ifdef ARCH_ARM_32
+#include <hwbinder/ProcessState.h>
+#endif
+
 using android::hardware::configureRpcThreadpool;
 using android::hardware::joinRpcThreadpool;
 using android::hardware::cas::V1_0::implementation::MediaCasService;
 using android::hardware::cas::V1_0::IMediaCasService;
 
 int main() {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize((size_t)16384);
+#endif
+
     ALOGD("android.hardware.cas@1.0-service starting...");
 
     // The CAS HAL may communicate to other vendor components via
diff --git a/configstore/1.1/default/Android.mk b/configstore/1.1/default/Android.mk
index 40f621b..0a03cfa 100644
--- a/configstore/1.1/default/Android.mk
+++ b/configstore/1.1/default/Android.mk
@@ -18,6 +18,7 @@
 LOCAL_SHARED_LIBRARIES := \
     libhidlbase \
     libhidltransport \
+    libhwbinder \
     libbase \
     libhwminijail \
     liblog \
@@ -25,6 +26,10 @@
     android.hardware.configstore@1.0 \
     android.hardware.configstore@1.1
 
+ifeq ($(TARGET_ARCH),arm)
+    LOCAL_CFLAGS += -DARCH_ARM_32
+endif
+
 include $(BUILD_EXECUTABLE)
 
 # seccomp filter for configstore
diff --git a/configstore/1.1/default/service.cpp b/configstore/1.1/default/service.cpp
index 3b4e774..6f30c0a 100644
--- a/configstore/1.1/default/service.cpp
+++ b/configstore/1.1/default/service.cpp
@@ -20,6 +20,10 @@
 #include <hidl/HidlTransportSupport.h>
 #include <hwminijail/HardwareMinijail.h>
 
+#ifdef ARCH_ARM_32
+#include <hwbinder/ProcessState.h>
+#endif
+
 #include "SurfaceFlingerConfigs.h"
 
 using android::hardware::configureRpcThreadpool;
@@ -32,6 +36,10 @@
 using android::OK;
 
 int main() {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize((size_t)(32768));
+#endif
+
     configureRpcThreadpool(10, true);
 
     SetupMinijail("/vendor/etc/seccomp_policy/configstore@1.1.policy");
diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp
index 9980ae0..9841e01 100644
--- a/graphics/allocator/2.0/default/Android.bp
+++ b/graphics/allocator/2.0/default/Android.bp
@@ -32,7 +32,15 @@
         "android.hardware.graphics.allocator@2.0",
         "libhidlbase",
         "libhidltransport",
+        "libhwbinder",
         "liblog",
         "libutils",
     ],
+    arch: {
+        arm: {
+            cflags: [
+                "-DARCH_ARM_32"
+            ],
+        },
+    },
 }
diff --git a/graphics/allocator/2.0/default/service.cpp b/graphics/allocator/2.0/default/service.cpp
index bc0539a..60ed232 100644
--- a/graphics/allocator/2.0/default/service.cpp
+++ b/graphics/allocator/2.0/default/service.cpp
@@ -20,9 +20,17 @@
 
 #include <hidl/LegacySupport.h>
 
+#ifdef ARCH_ARM_32
+#include <hwbinder/ProcessState.h>
+#endif
+
 using android::hardware::defaultPassthroughServiceImplementation;
 using android::hardware::graphics::allocator::V2_0::IAllocator;
 
 int main() {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize((size_t)(32768));
+#endif
+
     return defaultPassthroughServiceImplementation<IAllocator>(4);
 }
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index 2de1e3c..858d32a 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -36,6 +36,7 @@
     init_rc: ["android.hardware.graphics.composer@2.1-service.rc"],
     shared_libs: [
         "android.hardware.graphics.composer@2.1",
+        "libhwbinder",
         "libbinder",
         "libhidlbase",
         "libhidltransport",
@@ -43,4 +44,11 @@
         "libsync",
         "libutils",
     ],
+    arch: {
+        arm: {
+            cflags: [
+                "-DARCH_ARM_32"
+            ],
+        },
+    },
 }
diff --git a/graphics/composer/2.1/default/service.cpp b/graphics/composer/2.1/default/service.cpp
index 82a33f6..980f678 100644
--- a/graphics/composer/2.1/default/service.cpp
+++ b/graphics/composer/2.1/default/service.cpp
@@ -23,10 +23,18 @@
 #include <binder/ProcessState.h>
 #include <hidl/LegacySupport.h>
 
+#ifdef ARCH_ARM_32
+#include <hwbinder/ProcessState.h>
+#endif
+
 using android::hardware::graphics::composer::V2_1::IComposer;
 using android::hardware::defaultPassthroughServiceImplementation;
 
 int main() {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize((size_t)(32768));
+#endif
+
     // the conventional HAL might start binder services
     android::ProcessState::initWithDriver("/dev/vndbinder");
     android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
diff --git a/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h b/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
index 9e7d252..0836e76 100644
--- a/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
+++ b/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
@@ -73,6 +73,9 @@
 static const int32_t KM_TAG_DIGEST_OLD = static_cast<int32_t>(TagType::ENUM) | 5;
 static const int32_t KM_TAG_PADDING_OLD = static_cast<int32_t>(TagType::ENUM) | 7;
 
+static const int32_t KM_TAG_FBE_ICE = static_cast<int32_t>(TagType::BOOL) | 16201;
+static const int32_t KM_TAG_KEY_TYPE = static_cast<int32_t>(TagType::UINT) | 16202;
+
 constexpr TagType typeFromTag(Tag tag) {
     return static_cast<TagType>(static_cast<uint32_t>(tag) & static_cast<uint32_t>(0xf0000000));
 }
diff --git a/light/2.0/default/Android.bp b/light/2.0/default/Android.bp
index 8b5f780..4e12427 100644
--- a/light/2.0/default/Android.bp
+++ b/light/2.0/default/Android.bp
@@ -44,10 +44,17 @@
         "libbase",
         "libdl",
         "libutils",
+        "libhwbinder",
         "libhardware",
         "libhidlbase",
         "libhidltransport",
         "android.hardware.light@2.0",
     ],
-
-}
\ No newline at end of file
+    arch: {
+        arm: {
+            cflags: [
+                "-DARCH_ARM_32"
+            ],
+        },
+    },
+}
diff --git a/light/2.0/default/service.cpp b/light/2.0/default/service.cpp
index 70ae565..d33c379 100644
--- a/light/2.0/default/service.cpp
+++ b/light/2.0/default/service.cpp
@@ -19,9 +19,17 @@
 #include <android/hardware/light/2.0/ILight.h>
 #include <hidl/LegacySupport.h>
 
+#ifdef ARCH_ARM_32
+#include <hwbinder/ProcessState.h>
+#endif
+
 using android::hardware::light::V2_0::ILight;
 using android::hardware::defaultPassthroughServiceImplementation;
 
 int main() {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize((size_t)(32768));
+#endif
+
     return defaultPassthroughServiceImplementation<ILight>();
 }
diff --git a/power/1.0/default/Android.bp b/power/1.0/default/Android.bp
index 4f43b95..9b6fe4f 100644
--- a/power/1.0/default/Android.bp
+++ b/power/1.0/default/Android.bp
@@ -56,6 +56,12 @@
         "libhidlbase",
         "libhidltransport",
         "android.hardware.power@1.0",
+        "libhwbinder"
     ],
 
+    arch: {
+        arm: {
+            cflags: ["-DARCH_ARM_32"],
+        },
+    },
 }
diff --git a/power/1.0/default/service.cpp b/power/1.0/default/service.cpp
index e8618b8..97a1403 100644
--- a/power/1.0/default/service.cpp
+++ b/power/1.0/default/service.cpp
@@ -19,9 +19,17 @@
 #include <android/hardware/power/1.0/IPower.h>
 #include <hidl/LegacySupport.h>
 
+#ifdef ARCH_ARM_32
+#include <hwbinder/ProcessState.h>
+#endif
+
 using android::hardware::power::V1_0::IPower;
 using android::hardware::defaultPassthroughServiceImplementation;
 
 int main() {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize((size_t)16384);
+#endif
+
     return defaultPassthroughServiceImplementation<IPower>();
 }
diff --git a/sensors/1.0/default/Android.bp b/sensors/1.0/default/Android.bp
index 2485b05..6338821 100644
--- a/sensors/1.0/default/Android.bp
+++ b/sensors/1.0/default/Android.bp
@@ -48,6 +48,7 @@
     relative_install_path: "hw",
     vendor: true,
     init_rc: ["android.hardware.sensors@1.0-service.rc"],
+    defaults: ["hidl_defaults"],
     srcs: ["service.cpp"],
 
     shared_libs: [
@@ -59,5 +60,11 @@
         "libhidlbase",
         "libhidltransport",
         "android.hardware.sensors@1.0",
+        "libhwbinder",
     ],
+    arch: {
+        arm: {
+            cflags: ["-DARCH_ARM_32"],
+        },
+    },
 }
diff --git a/sensors/1.0/default/service.cpp b/sensors/1.0/default/service.cpp
index 65f6d81..3636b85 100644
--- a/sensors/1.0/default/service.cpp
+++ b/sensors/1.0/default/service.cpp
@@ -19,10 +19,31 @@
 #include <android/hardware/sensors/1.0/ISensors.h>
 #include <hidl/LegacySupport.h>
 
+#ifdef ARCH_ARM_32
+#include <hwbinder/ProcessState.h>
+#include <cutils/properties.h>
+#endif
+
 using android::hardware::sensors::V1_0::ISensors;
 using android::hardware::defaultPassthroughServiceImplementation;
 
+#ifdef ARCH_ARM_32
+//default h/w binder memsize for sensors is 8 KB
+#define DEFAULT_SENSORS_HW_BINDER_MEM_SIZE_KB 8
+size_t getHWBinderMmapSize() {
+    int32_t value = DEFAULT_SENSORS_HW_BINDER_MEM_SIZE_KB;
+
+    value = property_get_int32("persist.vendor.sensor.hw.binder.size", value);
+    ALOGD("Init hw binder with mem size = %d", value);
+    return 1024 * value;
+}
+#endif
+
 int main() {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize((size_t)getHWBinderMmapSize());
+#endif
+
     /* Sensors framework service needs at least two threads.
      * One thread blocks on a "poll"
      * The second thread is needed for all other HAL methods.
diff --git a/vibrator/1.0/default/Android.bp b/vibrator/1.0/default/Android.bp
index 0c7d155..c977942 100644
--- a/vibrator/1.0/default/Android.bp
+++ b/vibrator/1.0/default/Android.bp
@@ -44,5 +44,13 @@
         "libutils",
         "libhardware",
         "android.hardware.vibrator@1.0",
+        "libhwbinder",
     ],
+    arch: {
+        arm: {
+            cflags: [
+                "-DARCH_ARM_32"
+            ],
+        },
+    },
 }
diff --git a/vibrator/1.0/default/service.cpp b/vibrator/1.0/default/service.cpp
index 7cc0744..a4b43f4 100644
--- a/vibrator/1.0/default/service.cpp
+++ b/vibrator/1.0/default/service.cpp
@@ -22,5 +22,9 @@
 using android::hardware::defaultPassthroughServiceImplementation;
 
 int main() {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize((size_t)8192);
+#endif
+
     return defaultPassthroughServiceImplementation<IVibrator>();
 }
diff --git a/wifi/1.2/default/Android.mk b/wifi/1.2/default/Android.mk
index 3919690..7240333 100644
--- a/wifi/1.2/default/Android.mk
+++ b/wifi/1.2/default/Android.mk
@@ -30,6 +30,9 @@
 ifdef WIFI_HIDL_FEATURE_DISABLE_AP
 LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP
 endif
+ifdef QC_WIFI_HIDL_FEATURE_DUAL_AP
+LOCAL_CPPFLAGS += -DQC_WIFI_HIDL_FEATURE_DUAL_AP
+endif
 LOCAL_SRC_FILES := \
     hidl_struct_util.cpp \
     hidl_sync_util.cpp \
@@ -70,6 +73,10 @@
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_PROPRIETARY_MODULE := true
 LOCAL_CPPFLAGS := -Wall -Werror -Wextra
+ifeq ($(TARGET_ARCH),arm)
+    LOCAL_CPPFLAGS += -DARCH_ARM_32
+endif
+
 LOCAL_SRC_FILES := \
     service.cpp
 LOCAL_SHARED_LIBRARIES := \
@@ -80,6 +87,7 @@
     liblog \
     libnl \
     libutils \
+    libhwbinder \
     libwifi-hal \
     libwifi-system-iface \
     android.hardware.wifi@1.0 \
diff --git a/wifi/1.2/default/service.cpp b/wifi/1.2/default/service.cpp
index 01d22bd..be56257 100644
--- a/wifi/1.2/default/service.cpp
+++ b/wifi/1.2/default/service.cpp
@@ -19,6 +19,11 @@
 #include <utils/Looper.h>
 #include <utils/StrongPointer.h>
 
+#ifdef ARCH_ARM_32
+#include <hwbinder/ProcessState.h>
+#include <cutils/properties.h>
+#endif
+
 #include "wifi.h"
 #include "wifi_feature_flags.h"
 #include "wifi_legacy_hal.h"
@@ -32,7 +37,22 @@
 using android::hardware::wifi::V1_2::implementation::mode_controller::
     WifiModeController;
 
+#ifdef ARCH_ARM_32
+#define DEFAULT_WIFIHAL_HW_BINDER_SIZE_KB 4
+size_t getHWBinderMmapSize() {
+    size_t value = 0;
+    value = property_get_int32("persist.vendor.wifi.wifihal.hw.binder.size", DEFAULT_WIFIHAL_HW_BINDER_SIZE_KB);
+    if (!value) value = DEFAULT_WIFIHAL_HW_BINDER_SIZE_KB; // deafult to 1 page of 4 Kb
+
+    return 1024 * value;
+}
+#endif /* ARCH_ARM_32 */
+
 int main(int /*argc*/, char** argv) {
+#ifdef ARCH_ARM_32
+    android::hardware::ProcessState::initWithMmapSize(getHWBinderMmapSize());
+#endif /* ARCH_ARM_32 */
+
     android::base::InitLogging(
         argv, android::base::LogdLogger(android::base::SYSTEM));
     LOG(INFO) << "Wifi Hal is booting up...";
diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.2/default/wifi_chip.cpp
index 3bd0557..1f15fe4 100644
--- a/wifi/1.2/default/wifi_chip.cpp
+++ b/wifi/1.2/default/wifi_chip.cpp
@@ -21,6 +21,7 @@
 #include <cutils/properties.h>
 #include <sys/stat.h>
 #include <sys/sysmacros.h>
+#include <net/if.h>
 
 #include "hidl_return_util.h"
 #include "hidl_struct_util.h"
@@ -596,6 +597,8 @@
     invalidateAndClearAll(nan_ifaces_);
     invalidateAndClearAll(p2p_ifaces_);
     invalidateAndClearAll(sta_ifaces_);
+    invalidateAndClearAll(created_ap_ifaces_);
+    invalidateAndClearAll(created_sta_ifaces_);
     // Since all the ifaces are invalid now, all RTT controller objects
     // using those ifaces also need to be invalidated.
     for (const auto& rtt : rtt_controllers_) {
@@ -744,9 +747,23 @@
     if (!canCurrentModeSupportIfaceOfType(IfaceType::AP)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
+
+    bool iface_created = false;
     std::string ifname = allocateApOrStaIfaceName();
+    if (!if_nametoindex(ifname.c_str())) {
+        legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->QcAddInterface(getWlan0IfaceName(), ifname,
+                                               (uint32_t)IfaceType::AP);
+        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+            LOG(ERROR) << "Failed to add interface: " << ifname << " "
+                       << legacyErrorToString(legacy_status);
+            return {createWifiStatusFromLegacyError(legacy_status), {}};
+        }
+        iface_created = true;
+    }
     sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_);
     ap_ifaces_.push_back(iface);
+    if (iface_created) created_ap_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
@@ -777,6 +794,16 @@
     if (!iface.get()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
+
+    if (findUsingName(created_ap_ifaces_, ifname) != nullptr) {
+        legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->QcRemoveInterface(getWlan0IfaceName(), ifname);
+        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+            LOG(ERROR) << "Failed to remove interface: " << ifname << " "
+                       << legacyErrorToString(legacy_status);
+        }
+        invalidateAndClear(created_ap_ifaces_, iface);
+    }
     invalidateAndClear(ap_ifaces_, iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
@@ -883,9 +910,22 @@
     if (!canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
+    bool iface_created = false;
     std::string ifname = allocateApOrStaIfaceName();
+    if (!if_nametoindex(ifname.c_str())) {
+        legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->QcAddInterface(getWlan0IfaceName(), ifname,
+                                               (uint32_t)IfaceType::STA);
+        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+            LOG(ERROR) << "Failed to add interface: " << ifname << " "
+                       << legacyErrorToString(legacy_status);
+            return {createWifiStatusFromLegacyError(legacy_status), {}};
+        }
+        iface_created = true;
+    }
     sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_);
     sta_ifaces_.push_back(iface);
+    if (iface_created) created_sta_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
@@ -916,6 +956,15 @@
     if (!iface.get()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
+    if (findUsingName(created_sta_ifaces_, ifname) != nullptr) {
+        legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->QcRemoveInterface(getWlan0IfaceName(), ifname);
+        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+            LOG(ERROR) << "Failed to remove interface: " << ifname << " "
+                       << legacyErrorToString(legacy_status);
+        }
+        invalidateAndClear(created_sta_ifaces_, iface);
+    }
     invalidateAndClear(sta_ifaces_, iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
@@ -1217,9 +1266,21 @@
               {chip_iface_combination_2}};
           modes_ = {chip_mode};
         } else {
-          const IWifiChip::ChipMode chip_mode = {
-            kV2ChipModeId,
-            {chip_iface_combination_1, chip_iface_combination_2}};
+          IWifiChip::ChipMode chip_mode;
+          if (feature_flags_.lock()->isQcDualApSupported()) {
+            const IWifiChip::ChipIfaceCombinationLimit
+                chip_iface_combination_limit_4 = {{IfaceType::AP}, 2};
+            const IWifiChip::ChipIfaceCombination chip_iface_combination_3 = {
+                {chip_iface_combination_limit_4}};
+            chip_mode = {kV2ChipModeId,
+                         {chip_iface_combination_1,
+                          chip_iface_combination_2,
+                          chip_iface_combination_3}};
+          } else {
+            chip_mode = {kV2ChipModeId,
+                         {chip_iface_combination_1,
+                          chip_iface_combination_2}};
+          }
           modes_ = {chip_mode};
         }
     } else {
diff --git a/wifi/1.2/default/wifi_chip.h b/wifi/1.2/default/wifi_chip.h
index ada9458..2308747 100644
--- a/wifi/1.2/default/wifi_chip.h
+++ b/wifi/1.2/default/wifi_chip.h
@@ -239,6 +239,9 @@
     hidl_callback_util::HidlCallbackHandler<IWifiChipEventCallback>
         event_cb_handler_;
 
+    std::vector<sp<WifiApIface>> created_ap_ifaces_;
+    std::vector<sp<WifiStaIface>> created_sta_ifaces_;
+
     DISALLOW_COPY_AND_ASSIGN(WifiChip);
 };
 
diff --git a/wifi/1.2/default/wifi_feature_flags.cpp b/wifi/1.2/default/wifi_feature_flags.cpp
index 778944d..78b6320 100644
--- a/wifi/1.2/default/wifi_feature_flags.cpp
+++ b/wifi/1.2/default/wifi_feature_flags.cpp
@@ -32,6 +32,11 @@
 #else
 static const bool wifiHidlFeatureDisableAp = false;
 #endif  // WIFI_HIDL_FEATURE_DISABLE_AP
+#ifdef QC_WIFI_HIDL_FEATURE_DUAL_AP
+static const bool qcWifiHidlFeatureDualAp = true;
+#else
+static const bool qcWifiHidlFeatureDualAp = false;
+#endif  // QC_WIFI_HIDL_FEATURE_DUAL_AP
 
 }  // namespace
 
@@ -50,6 +55,9 @@
 bool WifiFeatureFlags::isApDisabled() {
   return wifiHidlFeatureDisableAp;
 }
+bool WifiFeatureFlags::isQcDualApSupported() {
+  return qcWifiHidlFeatureDualAp;
+}
 
 }  // namespace feature_flags
 }  // namespace implementation
diff --git a/wifi/1.2/default/wifi_feature_flags.h b/wifi/1.2/default/wifi_feature_flags.h
index 4a7b2d2..b1413a0 100644
--- a/wifi/1.2/default/wifi_feature_flags.h
+++ b/wifi/1.2/default/wifi_feature_flags.h
@@ -32,6 +32,7 @@
     virtual bool isAwareSupported();
     virtual bool isDualInterfaceSupported();
     virtual bool isApDisabled();
+    virtual bool isQcDualApSupported();
 };
 
 }  // namespace feature_flags
diff --git a/wifi/1.2/default/wifi_legacy_hal.cpp b/wifi/1.2/default/wifi_legacy_hal.cpp
index 375204c..6b7c27d 100644
--- a/wifi/1.2/default/wifi_legacy_hal.cpp
+++ b/wifi/1.2/default/wifi_legacy_hal.cpp
@@ -34,7 +34,7 @@
 static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
 static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
 static constexpr uint32_t kMaxRingBuffers = 10;
-static constexpr uint32_t kMaxStopCompleteWaitMs = 100;
+static constexpr uint32_t kMaxStopCompleteWaitMs = 250;
 
 // Helper function to create a non-const char* for legacy Hal API's.
 std::vector<char> makeCharVec(const std::string& str) {
@@ -1383,6 +1383,35 @@
     return {status, std::move(cached_scan_results)};
 }
 
+wifi_error WifiLegacyHal::QcAddInterface(const std::string& iface_name,
+                                         const std::string& new_ifname,
+                                         uint32_t type) {
+    wifi_error status = global_func_table_.wifi_add_or_remove_virtual_intf(
+                           getIfaceHandle(iface_name),
+                           new_ifname.c_str(), type, true);
+
+    if (status == WIFI_SUCCESS) {
+        // refresh list of handlers now.
+        iface_name_to_handle_.clear();
+        status = retrieveIfaceHandles();
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::QcRemoveInterface(const std::string& iface_name,
+                                            const std::string& ifname) {
+    wifi_error status =  global_func_table_.wifi_add_or_remove_virtual_intf(
+                             getIfaceHandle(iface_name),
+                             ifname.c_str(), 0, false);
+
+    if (status == WIFI_SUCCESS) {
+        // refresh list of handlers now.
+        iface_name_to_handle_.clear();
+        status = retrieveIfaceHandles();
+    }
+    return status;
+}
+
 void WifiLegacyHal::invalidate() {
     global_handle_ = nullptr;
     iface_name_to_handle_.clear();
diff --git a/wifi/1.2/default/wifi_legacy_hal.h b/wifi/1.2/default/wifi_legacy_hal.h
index 60905ab..2c00d6c 100644
--- a/wifi/1.2/default/wifi_legacy_hal.h
+++ b/wifi/1.2/default/wifi_legacy_hal.h
@@ -354,6 +354,13 @@
     wifi_error setCountryCode(const std::string& iface_name,
                               std::array<int8_t, 2> code);
 
+    wifi_error QcAddInterface(const std::string& iface_name,
+                              const std::string& new_ifname,
+                              uint32_t type);
+    wifi_error QcRemoveInterface(const std::string& iface_name,
+                                 const std::string& ifname);
+
+
    private:
     // Retrieve interface handles for all the available interfaces.
     wifi_error retrieveIfaceHandles();
diff --git a/wifi/1.2/default/wifi_legacy_hal_stubs.cpp b/wifi/1.2/default/wifi_legacy_hal_stubs.cpp
index fc28bb5..3cb9fd1 100644
--- a/wifi/1.2/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.2/default/wifi_legacy_hal_stubs.cpp
@@ -137,6 +137,7 @@
     populateStubFor(&hal_fn->wifi_select_tx_power_scenario);
     populateStubFor(&hal_fn->wifi_reset_tx_power_scenario);
     populateStubFor(&hal_fn->wifi_set_radio_mode_change_handler);
+    populateStubFor(&hal_fn->wifi_add_or_remove_virtual_intf);
     return true;
 }
 }  // namespace legacy_hal