otter: vibrator: Update for 15

Update from vendor/qcom/opensource/vibrator
at commit 8f873decb09e5b4c2edf3ab1e1bad14764d943db

Change-Id: I12e0982fc051834628b00da14dde7a5c1c687e53
diff --git a/vibrator/Android.bp b/vibrator/Android.bp
index 83a93c0..b49b4e4 100644
--- a/vibrator/Android.bp
+++ b/vibrator/Android.bp
@@ -1,42 +1,10 @@
 Common_CFlags = ["-Wall"]
 Common_CFlags += ["-Werror"]
 
-soong_config_module_type {
-    name: "vibrator_cc_defaults",
-    module_type: "cc_defaults",
-    config_namespace: "vibrator",
-    variables: ["vibratortargets"],
-    properties: ["shared_libs"],
-}
-
-soong_config_string_variable {
-    name: "vibratortargets",
-    values: ["vibratoraidlV2platformtarget", "vibratoraidlV2target"],
-}
-
-vibrator_cc_defaults {
-    name: "vibrator_defaults",
-    soong_config_variables: {
-        vibratortargets: {
-            vibratoraidlV2platformtarget: {
-                 shared_libs: [
-                       "android.hardware.vibrator-V2-ndk_platform",
-                  ],
-            },
-            vibratoraidlV2target: {
-                 shared_libs: [
-                       "android.hardware.vibrator-V2-ndk",
-                  ],
-            },
-        },
-    },
-}
-
-
 cc_library_shared {
     name: "vendor.qti.hardware.vibrator.impl.otter",
-    defaults: ["vibrator_defaults"],
     vendor: true,
+    cflags: Common_CFlags,
     srcs: [
         "Vibrator.cpp",
         "VibratorOffload.cpp",
@@ -48,14 +16,15 @@
         "libqtivibratoreffect",
         "libqtivibratoreffectoffload",
         "libbinder_ndk",
+        "android.hardware.vibrator-V2-ndk",
     ],
     export_include_dirs: ["include"]
 }
 
 cc_binary {
     name: "vendor.qti.hardware.vibrator.service.otter",
-    defaults: ["vibrator_defaults"],
     vendor: true,
+    cflags: Common_CFlags,
     relative_install_path: "hw",
     init_rc: ["vendor.qti.hardware.vibrator.service.otter.rc"],
     vintf_fragments: [
@@ -69,6 +38,7 @@
         "libutils",
         "libbase",
         "libbinder_ndk",
+        "android.hardware.vibrator-V2-ndk",
         "vendor.qti.hardware.vibrator.impl.otter",
     ],
 }
diff --git a/vibrator/Vibrator.cpp b/vibrator/Vibrator.cpp
index 06d26e0..abecdc9 100644
--- a/vibrator/Vibrator.cpp
+++ b/vibrator/Vibrator.cpp
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -28,7 +27,7 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  * SPDX-License-Identifier: BSD-3-Clause-Clear
  */
 
@@ -77,6 +76,7 @@
 #define MSM_CPU_TARO            457
 #define MSM_CPU_TARO_LTE        552
 #define MSM_CPU_KALAMA          519
+#define MSM_CPU_PINEAPPLE       557
 
 #define test_bit(bit, array)    ((array)[(bit)/8] & (1<<((bit)%8)))
 
@@ -141,7 +141,8 @@
                 && strcmp(name, "aw8624_haptic")
                 && strcmp(name, "aw8695_haptic")
                 && strcmp(name, "aw8697_haptic")
-                && strcmp(name, "awinic_haptic")) {
+                && strcmp(name, "awinic_haptic")
+                && strcmp(name, "drv2624:haptics")) {
             ALOGD("not a supported haptics device\n");
             close(fd);
             continue;
@@ -179,6 +180,7 @@
             case MSM_CPU_CAPE:
             case APQ_CPU_CAPE:
             case MSM_CPU_KALAMA:
+            case MSM_CPU_PINEAPPLE:
                 mSupportExternalControl = true;
                 break;
             default:
@@ -221,10 +223,12 @@
     const struct effect_stream *stream;
 #endif
 
+    mtx.lock();
     /* For QMAA compliance, return OK even if vibrator device doesn't exist */
     if (mVibraFd == INVALID_VALUE) {
         if (playLengthMs != NULL)
             *playLengthMs = 0;
+        mtx.unlock();
         return 0;
     }
 
@@ -298,10 +302,12 @@
         }
         mCurrAppId = INVALID_VALUE;
     }
+    mtx.unlock();
     return 0;
 
 errout:
     mCurrAppId = INVALID_VALUE;
+    mtx.unlock();
     return ret;
 }
 
@@ -505,6 +511,8 @@
         close(pipefd[1]);
 }
 
+static int getPrimitiveDurationFromSysfs(uint32_t primitive_id, int32_t* durationMs);
+
 ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
     *_aidl_return = IVibrator::CAP_ON_CALLBACK;
 
@@ -516,10 +524,12 @@
     if (ff.mSupportGain)
         *_aidl_return |= IVibrator::CAP_AMPLITUDE_CONTROL;
     if (ff.mSupportEffects) {
-       *_aidl_return |= IVibrator::CAP_PERFORM_CALLBACK;
-        if (access("/sys/class/qcom-haptics/primitive_duration", F_OK) == 0) {
+        *_aidl_return |= IVibrator::CAP_PERFORM_CALLBACK;
+        int32_t primitiveDuration = 0;
+        uint32_t primitiveId = static_cast<uint32_t>(CompositePrimitive::CLICK);
+        getPrimitiveDurationFromSysfs(primitiveId, &primitiveDuration);
+        if (primitiveDuration != 0)
             *_aidl_return |= IVibrator::CAP_COMPOSE_EFFECTS;
-        }
     }
     if (ff.mSupportExternalControl)
         *_aidl_return |= IVibrator::CAP_EXTERNAL_CONTROL;
@@ -821,8 +831,32 @@
                 ALOGE("Failed to read stop status from pipe(playLengthMs), status = %d", status);
                 break;
             }
-            if (status == STOP_COMPOSE)
+            if (status == STOP_COMPOSE) {
+
+                /*
+                 * There is a corner case that the off() command could be executed in
+                 * main thread before the primitive play is triggered in the child thread,
+                 * such as, when playing a very short primitive effect while the system is
+                 * pretty busy (one example is enabling all kernel console log after executed
+                 * "echo Y > /sys/module/printk/parameters/ignore_loglevel"), the child thread
+                 * may not be able to schedule out for running before the main thread times out
+                 * on the primitive duration and sent the off() command, there won't be any
+                 * off() command coming again to stop the primitive effect after it's triggered.
+                 *
+                 * However, the primitive could be played out and stopped automatically but the
+                 * haptics driver does expect an explicit off() command to restore HW/SW logic
+                 * after that, so call it here. It would result a redundant off() command in
+                 * normal case but it won't do any harm because it would be ignored and not sent
+                 * to haptics driver because of an invalid mCurrAppId. It would also result in the
+                 * primitive effect to stop immediately right after it's triggered in such
+                 * corner case. But considering the main thread has stopped it before off() is
+                 * called here, take this as a limitation and it is expected not playing the
+                 * vibration out.
+                 */
+
+                vibrator->ff.off();
                 break;
+            }
         }
     }
 
@@ -877,15 +911,17 @@
             ALOGE("wait for last composePlayThread done timeout");
             return ndk::ScopedAStatus::fromExceptionCode(EX_SERVICE_SPECIFIC);
         }
+    }
 
-        /* Read the pipe again to remove any stale data before triggering a new play */
-        nfd = epoll_wait(epollfd, &events, 1, 0);
-        if (nfd == -1 && (errno != EINTR)) {
-            ALOGE("Failed to wait sleep playLengthMs, error=%d", errno);
-            return ndk::ScopedAStatus::fromExceptionCode(EX_SERVICE_SPECIFIC);
-        }
-        if (nfd > 0)
-            read(pipefd[0], &status, sizeof(int));
+    /* Read the pipe again to remove any stale data before triggering a new play */
+    nfd = epoll_wait(epollfd, &events, 1, 0);
+    if (nfd == -1 && (errno != EINTR)) {
+        ALOGE("Failed to wait sleep playLengthMs, error=%d", errno);
+        return ndk::ScopedAStatus::fromExceptionCode(EX_SERVICE_SPECIFIC);
+    }
+    if (nfd > 0) {
+        ALOGD("A stale event is cached in the pipe, remove it");
+        read(pipefd[0], &status, sizeof(int));
     }
 
     inComposition = true;
diff --git a/vibrator/VibratorOffload.cpp b/vibrator/VibratorOffload.cpp
index 2f07767..fad3200 100644
--- a/vibrator/VibratorOffload.cpp
+++ b/vibrator/VibratorOffload.cpp
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -28,7 +27,7 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * SPDX-License-Identifier: BSD-3-Clause-Clear
  */
 
diff --git a/vibrator/excluded-input-devices.xml b/vibrator/excluded-input-devices.xml
index 32acdab..c0f00c2 100755
--- a/vibrator/excluded-input-devices.xml
+++ b/vibrator/excluded-input-devices.xml
@@ -32,4 +32,5 @@
     <device name="aw8695_haptic"/>
     <device name="aw8697_haptic"/>
     <device name="awinic_haptic"/>
+    <device name="drv2624:haptics"/>
 </devices>
diff --git a/vibrator/include/Vibrator.h b/vibrator/include/Vibrator.h
index 2945855..8ceb697 100644
--- a/vibrator/include/Vibrator.h
+++ b/vibrator/include/Vibrator.h
@@ -27,7 +27,7 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  * SPDX-License-Identifier: BSD-3-Clause-Clear
  */
 
@@ -35,6 +35,7 @@
 
 #include <aidl/android/hardware/vibrator/BnVibrator.h>
 #include <thread>
+#include <mutex>
 
 namespace aidl {
 namespace android {
@@ -59,6 +60,7 @@
     int mVibraFd;
     int16_t mCurrAppId;
     int16_t mCurrMagnitude;
+    std::mutex mtx;
 };
 
 class LedVibratorDevice {