vibrator: Add support for duration based amplitude control
authorSamarV-121 <samarvispute121@pm.me>
Mon, 8 May 2023 10:47:17 +0000 (16:17 +0530)
committerJan Altensen (Stricted) <info@stricted.net>
Sun, 21 May 2023 07:35:53 +0000 (09:35 +0200)
 * Similar to what samsung is doing on devices without hardware intensity control.
 * Add `$(call soong_config_set,samsungVibratorVars,duration_amplitude,true)` in BoardConfig.mk to enable.

Change-Id: I87a767e00363c36f8bd4d61cb6dd23b5c033a3d3

aidl/vibrator/Android.bp
aidl/vibrator/Vibrator.cpp
aidl/vibrator/Vibrator.h

index 0a255a18aed29fb39b006abc27f00d8581c6051a..bcd6a66a2b920858ef36f0325755e61f4ab0083e 100644 (file)
@@ -1,11 +1,31 @@
 //
-// Copyright (C) 2021 The LineageOS Project
+// Copyright (C) 2021-2023 The LineageOS Project
 //
 // SPDX-License-Identifier: Apache-2.0
 //
 
+soong_config_module_type {
+    name: "samsung_vibrator",
+    module_type: "cc_defaults",
+    config_namespace: "samsungVibratorVars",
+    bool_variables: ["duration_amplitude"],
+    properties: ["cflags"],
+}
+
+samsung_vibrator {
+    name: "samsung_vibrator_defaults",
+    soong_config_variables: {
+        duration_amplitude: {
+            cflags: [
+                "-DVIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL",
+            ],
+        },
+    },
+}
+
 cc_binary {
     name: "android.hardware.vibrator-service.samsung",
+    defaults: ["samsung_vibrator_defaults"],
     relative_install_path: "hw",
     init_rc: ["android.hardware.vibrator-service.samsung.rc"],
     vintf_fragments: ["android.hardware.vibrator-service.samsung.xml"],
index c2159a353ce8d1ee48c78764b87365dc8f5f01bc..6818f77f08bdf48370c6a6892affe3abac6648e6 100644 (file)
@@ -31,6 +31,14 @@ static std::map<Effect, int> CP_TRIGGER_EFFECTS {
     { Effect::TICK, 50 }
 };
 
+#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
+static std::map<EffectStrength, float> DURATION_AMPLITUDE = {
+    { EffectStrength::LIGHT, DURATION_AMPLITUDE_LIGHT },
+    { EffectStrength::MEDIUM, DURATION_AMPLITUDE_MEDIUM },
+    { EffectStrength::STRONG, DURATION_AMPLITUDE_STRONG }
+};
+#endif
+
 /*
  * Write value to path and close file.
  */
@@ -73,10 +81,12 @@ ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
                     IVibrator::CAP_EXTERNAL_CONTROL /*| IVibrator::CAP_COMPOSE_EFFECTS |
                     IVibrator::CAP_ALWAYS_ON_CONTROL*/;
 
-    if (mHasTimedOutIntensity) {
-        *_aidl_return = *_aidl_return | IVibrator::CAP_AMPLITUDE_CONTROL |
-                        IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
-    }
+#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
+    *_aidl_return |= IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
+#else
+    if (mHasTimedOutIntensity)
+        *_aidl_return |= IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
+#endif
 
     return ndk::ScopedAStatus::ok();
 }
@@ -91,6 +101,10 @@ ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs, const std::shared_ptr<IVibrat
     if (mHasTimedOutEffect)
         writeNode(VIBRATOR_CP_TRIGGER_PATH, 0); // Clear all effects
 
+#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
+    timeoutMs *= mDurationAmplitude;
+#endif
+
     status = activate(timeoutMs);
 
     if (callback != nullptr) {
@@ -130,6 +144,10 @@ ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength, con
             return status;
     }
 
+#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
+    ms *= DURATION_AMPLITUDE[strength];
+#endif
+
     status = activate(ms);
 
     if (callback != nullptr) {
@@ -163,15 +181,21 @@ ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
         return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
     }
 
+#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
+    mDurationAmplitude = durationAmplitude(amplitude);
+#endif
+
     LOG(DEBUG) << "Setting amplitude: " << amplitude;
 
     intensity = amplitude * INTENSITY_MAX;
 
+#ifndef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
     LOG(DEBUG) << "Setting intensity: " << intensity;
 
     if (mHasTimedOutIntensity) {
         return writeNode(VIBRATOR_INTENSITY_PATH, intensity);
     }
+#endif
 
     return ndk::ScopedAStatus::ok();
 }
@@ -297,6 +321,18 @@ uint32_t Vibrator::effectToMs(Effect effect, ndk::ScopedAStatus* status) {
     return 0;
 }
 
+#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
+float Vibrator::durationAmplitude(float amplitude) {
+    if (amplitude == 1) {
+        return DURATION_AMPLITUDE_STRONG;
+    } else if (amplitude >= 0.5) {
+        return DURATION_AMPLITUDE_MEDIUM;
+    }
+
+    return DURATION_AMPLITUDE_LIGHT;
+}
+#endif
+
 } // namespace vibrator
 } // namespace hardware
 } // namespace android
index db91b983f4efdcef016e844fb777c039ccf2d23c..09e88d393c93457537a9605e2ce835318d8ffe27 100644 (file)
 #define AMPLITUDE_MEDIUM 0.5
 #define AMPLITUDE_STRONG 1
 
+#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
+#define DURATION_AMPLITUDE_LIGHT 0.65
+#define DURATION_AMPLITUDE_MEDIUM 0.8
+#define DURATION_AMPLITUDE_STRONG 1
+#endif
+
 #define VIBRATOR_TIMEOUT_PATH "/sys/class/timed_output/vibrator/enable"
 #define VIBRATOR_INTENSITY_PATH "/sys/class/timed_output/vibrator/intensity"
 #define VIBRATOR_CP_TRIGGER_PATH "/sys/class/timed_output/vibrator/cp_trigger_index"
@@ -66,6 +72,11 @@ private:
     uint32_t effectToMs(Effect effect, ndk::ScopedAStatus* status);
     static float strengthToAmplitude(EffectStrength strength, ndk::ScopedAStatus* status);
 
+#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
+    static float durationAmplitude(float amplitude);
+    float mDurationAmplitude;
+#endif
+
     bool mEnabled{false};
     bool mExternalControl{false};
     std::mutex mMutex;