Add adaptive haptics scaling to external vibrations
We've converted HapticScale into a struct which includes both scale
level and adaptive haptics scale. The adaptive haptics scale is now included in the process of scaling vibrations.
Bug: 305957324
Test: N/A
Change-Id: Ic46f11812e2599da6ec7f8363932a0d9368e7157
diff --git a/libs/vibrator/ExternalVibration.cpp b/libs/vibrator/ExternalVibration.cpp
index 80e911c..c97e496 100644
--- a/libs/vibrator/ExternalVibration.cpp
+++ b/libs/vibrator/ExternalVibration.cpp
@@ -17,7 +17,7 @@
#include <vibrator/ExternalVibration.h>
#include <vibrator/ExternalVibrationUtils.h>
-#include <android/os/IExternalVibratorService.h>
+#include <android/os/ExternalVibrationScale.h>
#include <binder/Parcel.h>
#include <log/log.h>
#include <utils/Errors.h>
@@ -65,24 +65,36 @@
return mToken == rhs.mToken;
}
-os::HapticScale ExternalVibration::externalVibrationScaleToHapticScale(int externalVibrationScale) {
- switch (externalVibrationScale) {
- case IExternalVibratorService::SCALE_MUTE:
- return os::HapticScale::MUTE;
- case IExternalVibratorService::SCALE_VERY_LOW:
- return os::HapticScale::VERY_LOW;
- case IExternalVibratorService::SCALE_LOW:
- return os::HapticScale::LOW;
- case IExternalVibratorService::SCALE_NONE:
- return os::HapticScale::NONE;
- case IExternalVibratorService::SCALE_HIGH:
- return os::HapticScale::HIGH;
- case IExternalVibratorService::SCALE_VERY_HIGH:
- return os::HapticScale::VERY_HIGH;
+os::HapticScale ExternalVibration::externalVibrationScaleToHapticScale(
+ os::ExternalVibrationScale externalVibrationScale) {
+ os::HapticLevel scaleLevel = os::HapticLevel::NONE;
+
+ switch (externalVibrationScale.scaleLevel) {
+ case os::ExternalVibrationScale::ScaleLevel::SCALE_MUTE:
+ scaleLevel = os::HapticLevel::MUTE;
+ break;
+ case os::ExternalVibrationScale::ScaleLevel::SCALE_VERY_LOW:
+ scaleLevel = os::HapticLevel::VERY_LOW;
+ break;
+ case os::ExternalVibrationScale::ScaleLevel::SCALE_LOW:
+ scaleLevel = os::HapticLevel::LOW;
+ break;
+ case os::ExternalVibrationScale::ScaleLevel::SCALE_NONE:
+ scaleLevel = os::HapticLevel::NONE;
+ break;
+ case os::ExternalVibrationScale::ScaleLevel::SCALE_HIGH:
+ scaleLevel = os::HapticLevel::HIGH;
+ break;
+ case os::ExternalVibrationScale::ScaleLevel::SCALE_VERY_HIGH:
+ scaleLevel = os::HapticLevel::VERY_HIGH;
+ break;
default:
- ALOGE("Unknown ExternalVibrationScale %d, not applying scaling", externalVibrationScale);
- return os::HapticScale::NONE;
- }
+ ALOGE("Unknown ExternalVibrationScale %d, not applying scaling",
+ externalVibrationScale.scaleLevel);
+ }
+
+ return {/*level=*/scaleLevel, /*adaptiveScaleFactor=*/
+ externalVibrationScale.adaptiveHapticsScale};
}
} // namespace os
diff --git a/libs/vibrator/ExternalVibrationUtils.cpp b/libs/vibrator/ExternalVibrationUtils.cpp
index 980b08b..761ac1b 100644
--- a/libs/vibrator/ExternalVibrationUtils.cpp
+++ b/libs/vibrator/ExternalVibrationUtils.cpp
@@ -26,30 +26,30 @@
static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f;
static constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f;
-float getHapticScaleGamma(HapticScale scale) {
- switch (scale) {
- case HapticScale::VERY_LOW:
+float getHapticScaleGamma(HapticLevel level) {
+ switch (level) {
+ case HapticLevel::VERY_LOW:
return 2.0f;
- case HapticScale::LOW:
+ case HapticLevel::LOW:
return 1.5f;
- case HapticScale::HIGH:
+ case HapticLevel::HIGH:
return 0.5f;
- case HapticScale::VERY_HIGH:
+ case HapticLevel::VERY_HIGH:
return 0.25f;
default:
return 1.0f;
}
}
-float getHapticMaxAmplitudeRatio(HapticScale scale) {
- switch (scale) {
- case HapticScale::VERY_LOW:
+float getHapticMaxAmplitudeRatio(HapticLevel level) {
+ switch (level) {
+ case HapticLevel::VERY_LOW:
return HAPTIC_SCALE_VERY_LOW_RATIO;
- case HapticScale::LOW:
+ case HapticLevel::LOW:
return HAPTIC_SCALE_LOW_RATIO;
- case HapticScale::NONE:
- case HapticScale::HIGH:
- case HapticScale::VERY_HIGH:
+ case HapticLevel::NONE:
+ case HapticLevel::HIGH:
+ case HapticLevel::VERY_HIGH:
return 1.0f;
default:
return 0.0f;
@@ -57,19 +57,28 @@
}
void applyHapticScale(float* buffer, size_t length, HapticScale scale) {
- if (scale == HapticScale::MUTE) {
+ if (scale.isScaleMute()) {
memset(buffer, 0, length * sizeof(float));
return;
}
- if (scale == HapticScale::NONE) {
+ if (scale.isScaleNone()) {
return;
}
- float gamma = getHapticScaleGamma(scale);
- float maxAmplitudeRatio = getHapticMaxAmplitudeRatio(scale);
+ HapticLevel hapticLevel = scale.getLevel();
+ float adaptiveScaleFactor = scale.getAdaptiveScaleFactor();
+ float gamma = getHapticScaleGamma(hapticLevel);
+ float maxAmplitudeRatio = getHapticMaxAmplitudeRatio(hapticLevel);
+
for (size_t i = 0; i < length; i++) {
- float sign = buffer[i] >= 0 ? 1.0 : -1.0;
- buffer[i] = powf(fabsf(buffer[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma)
- * maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * sign;
+ if (hapticLevel != HapticLevel::NONE) {
+ float sign = buffer[i] >= 0 ? 1.0 : -1.0;
+ buffer[i] = powf(fabsf(buffer[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma)
+ * maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * sign;
+ }
+
+ if (adaptiveScaleFactor != 1.0f) {
+ buffer[i] *= adaptiveScaleFactor;
+ }
}
}
@@ -89,13 +98,13 @@
} // namespace
bool isValidHapticScale(HapticScale scale) {
- switch (scale) {
- case HapticScale::MUTE:
- case HapticScale::VERY_LOW:
- case HapticScale::LOW:
- case HapticScale::NONE:
- case HapticScale::HIGH:
- case HapticScale::VERY_HIGH:
+ switch (scale.getLevel()) {
+ case HapticLevel::MUTE:
+ case HapticLevel::VERY_LOW:
+ case HapticLevel::LOW:
+ case HapticLevel::NONE:
+ case HapticLevel::HIGH:
+ case HapticLevel::VERY_HIGH:
return true;
}
return false;
diff --git a/libs/vibrator/include/vibrator/ExternalVibration.h b/libs/vibrator/include/vibrator/ExternalVibration.h
index 00cd3cd..ac2767e 100644
--- a/libs/vibrator/include/vibrator/ExternalVibration.h
+++ b/libs/vibrator/include/vibrator/ExternalVibration.h
@@ -24,6 +24,7 @@
#include <system/audio.h>
#include <utils/RefBase.h>
#include <vibrator/ExternalVibrationUtils.h>
+#include <android/os/ExternalVibrationScale.h>
namespace android {
namespace os {
@@ -45,10 +46,11 @@
audio_attributes_t getAudioAttributes() const { return mAttrs; }
sp<IExternalVibrationController> getController() { return mController; }
- /* Converts the scale from non-public ExternalVibrationService into the HapticScale
+ /* Converts the scale from non-public ExternalVibrationService into the HapticScaleLevel
* used by the utils.
*/
- static os::HapticScale externalVibrationScaleToHapticScale(int externalVibrationScale);
+ static os::HapticScale externalVibrationScaleToHapticScale(
+ os::ExternalVibrationScale externalVibrationScale);
private:
int32_t mUid;
diff --git a/libs/vibrator/include/vibrator/ExternalVibrationUtils.h b/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
index ca219d3..d9a2b81 100644
--- a/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
+++ b/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
@@ -19,7 +19,7 @@
namespace android::os {
-enum class HapticScale {
+enum class HapticLevel {
MUTE = -100,
VERY_LOW = -2,
LOW = -1,
@@ -28,10 +28,41 @@
VERY_HIGH = 2,
};
+class HapticScale {
+private:
+HapticLevel mLevel = HapticLevel::NONE;
+float mAdaptiveScaleFactor = 1.0f;
+
+public:
+constexpr HapticScale(HapticLevel level, float adaptiveScaleFactor)
+ : mLevel(level), mAdaptiveScaleFactor(adaptiveScaleFactor) {}
+constexpr HapticScale(HapticLevel level) : mLevel(level) {}
+constexpr HapticScale() {}
+
+HapticLevel getLevel() const { return mLevel; }
+float getAdaptiveScaleFactor() const { return mAdaptiveScaleFactor; }
+
+bool operator==(const HapticScale& other) const {
+ return mLevel == other.mLevel && mAdaptiveScaleFactor == other.mAdaptiveScaleFactor;
+}
+
+bool isScaleNone() const {
+ return mLevel == HapticLevel::NONE && mAdaptiveScaleFactor == 1.0f;
+}
+
+bool isScaleMute() const {
+ return mLevel == HapticLevel::MUTE;
+}
+
+static HapticScale mute() {
+ return {/*level=*/os::HapticLevel::MUTE};
+}
+};
+
bool isValidHapticScale(HapticScale scale);
-/* Scales the haptic data in given buffer using the selected HapticScale and ensuring no absolute
- * value will be larger than the absolute of given limit.
+/* Scales the haptic data in given buffer using the selected HapticScaleLevel and ensuring no
+ * absolute value will be larger than the absolute of given limit.
* The limit will be ignored if it is NaN or zero.
*/
void scaleHapticData(float* buffer, size_t length, HapticScale scale, float limit);