//
-// 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"],
{ 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.
*/
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();
}
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) {
return status;
}
+#ifdef VIBRATOR_SUPPORTS_DURATION_AMPLITUDE_CONTROL
+ ms *= DURATION_AMPLITUDE[strength];
+#endif
+
status = activate(ms);
if (callback != nullptr) {
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();
}
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
#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"
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;