Loading libs/vibrator/ExternalVibrationUtils.cpp +19 −5 Original line number Diff line number Diff line Loading @@ -104,6 +104,24 @@ float applyHapticScale(float value, float scaleFactor) { return sign * std::clamp(a * fx, 0.0f, 1.0f); } // TODO(b/345186129): remove this once flag android_os_vibrator_haptics_scale_v2_enabled removed float applyHapticScale(float value, HapticScale scale, float scaleFactor) { if (android_os_vibrator_vibration_scale_device_config_enabled()) { if (scale.getScaleFactor() >= 0) { // Has device configured scale factor, use scale v2 for it. scaleFactor = scale.getScaleFactor(); float scaledValue = (scaleFactor <= 1 || value == 0) ? (value * scaleFactor) : (value * scaleFactor) / (1 + (scaleFactor - 1) * value * value); return std::clamp(scaledValue, -1.0f, 1.0f); } // else apply regular scaling } if (scale.getLevel() == HapticLevel::NONE) { return value; } return applyHapticScale(value, scaleFactor); } void applyHapticScale(float* buffer, size_t length, HapticScale scale) { if (scale.isScaleMute()) { memset(buffer, 0, length * sizeof(float)); Loading @@ -112,15 +130,11 @@ void applyHapticScale(float* buffer, size_t length, HapticScale scale) { if (scale.isScaleNone()) { return; } HapticLevel hapticLevel = scale.getLevel(); float scaleFactor = getHapticScaleFactor(scale); float adaptiveScaleFactor = scale.getAdaptiveScaleFactor(); for (size_t i = 0; i < length; i++) { if (hapticLevel != HapticLevel::NONE) { buffer[i] = applyHapticScale(buffer[i], scaleFactor); } buffer[i] = applyHapticScale(buffer[i], scale, scaleFactor); if (adaptiveScaleFactor >= 0 && adaptiveScaleFactor != 1.0f) { buffer[i] *= adaptiveScaleFactor; } Loading libs/vibrator/include/vibrator/ExternalVibrationUtils.h +1 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ namespace android::os { // TODO(b/345186129): remove this once flag android_os_vibrator_haptics_scale_v2_enabled removed enum class HapticLevel : int32_t { MUTE = -100, VERY_LOW = -2, Loading libs/vibrator/tests/ExternalVibrationUtilsTest.cpp +43 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,49 @@ TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestScaleV2ToScaleFactorIgnoresLev EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestScaleConfigWithScaleFactorAppliesFactor, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, vibration_scale_device_config_enabled))) { constexpr float adaptiveScaleNone = 1.0f; float expectedVeryHigh[TEST_BUFFER_LENGTH] = {1, -1, 1, -0.55f}; scaleBuffer(HapticScale(HapticLevel::LOW, 3.0f /* scaleFactor */, adaptiveScaleNone)); EXPECT_FLOATS_NEARLY_EQ(expectedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedHigh[TEST_BUFFER_LENGTH] = {1, -1, 0.66f, -0.29f}; scaleBuffer(HapticScale(HapticLevel::LOW, 1.5f /* scaleFactor */, adaptiveScaleNone)); EXPECT_FLOATS_NEARLY_EQ(expectedHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedLow[TEST_BUFFER_LENGTH] = {0.8f, -0.8f, 0.4f, -0.16f}; scaleBuffer(HapticScale(HapticLevel::HIGH, 0.8f /* scaleFactor */, adaptiveScaleNone)); EXPECT_FLOATS_NEARLY_EQ(expectedLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedVeryLow[TEST_BUFFER_LENGTH] = {0.4f, -0.4f, 0.2f, -0.08f}; scaleBuffer(HapticScale(HapticLevel::HIGH, 0.4f /* scaleFactor */, adaptiveScaleNone)); EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestScaleConfigWithoutScaleFactorAppliesScaleLevel, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled)), REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, vibration_scale_device_config_enabled))) { float expectedVeryHigh[TEST_BUFFER_LENGTH] = {1, -1, 0.79f, -0.39f}; scaleBuffer(HapticLevel::VERY_HIGH); EXPECT_FLOATS_NEARLY_EQ(expectedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedHigh[TEST_BUFFER_LENGTH] = {1, -1, 0.62f, -0.27f}; scaleBuffer(HapticLevel::HIGH); EXPECT_FLOATS_NEARLY_EQ(expectedHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedLow[TEST_BUFFER_LENGTH] = {0.70f, -0.70f, 0.35f, -0.14f}; scaleBuffer(HapticLevel::LOW); EXPECT_FLOATS_NEARLY_EQ(expectedLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedVeryLow[TEST_BUFFER_LENGTH] = {0.45f, -0.45f, 0.22f, -0.09f}; scaleBuffer(HapticLevel::VERY_LOW); EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestAdaptiveScaleFactorUndefinedIgnoredScale, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expectedVeryHigh[TEST_BUFFER_LENGTH] = {1, -1, 0.79f, -0.39f}; Loading Loading
libs/vibrator/ExternalVibrationUtils.cpp +19 −5 Original line number Diff line number Diff line Loading @@ -104,6 +104,24 @@ float applyHapticScale(float value, float scaleFactor) { return sign * std::clamp(a * fx, 0.0f, 1.0f); } // TODO(b/345186129): remove this once flag android_os_vibrator_haptics_scale_v2_enabled removed float applyHapticScale(float value, HapticScale scale, float scaleFactor) { if (android_os_vibrator_vibration_scale_device_config_enabled()) { if (scale.getScaleFactor() >= 0) { // Has device configured scale factor, use scale v2 for it. scaleFactor = scale.getScaleFactor(); float scaledValue = (scaleFactor <= 1 || value == 0) ? (value * scaleFactor) : (value * scaleFactor) / (1 + (scaleFactor - 1) * value * value); return std::clamp(scaledValue, -1.0f, 1.0f); } // else apply regular scaling } if (scale.getLevel() == HapticLevel::NONE) { return value; } return applyHapticScale(value, scaleFactor); } void applyHapticScale(float* buffer, size_t length, HapticScale scale) { if (scale.isScaleMute()) { memset(buffer, 0, length * sizeof(float)); Loading @@ -112,15 +130,11 @@ void applyHapticScale(float* buffer, size_t length, HapticScale scale) { if (scale.isScaleNone()) { return; } HapticLevel hapticLevel = scale.getLevel(); float scaleFactor = getHapticScaleFactor(scale); float adaptiveScaleFactor = scale.getAdaptiveScaleFactor(); for (size_t i = 0; i < length; i++) { if (hapticLevel != HapticLevel::NONE) { buffer[i] = applyHapticScale(buffer[i], scaleFactor); } buffer[i] = applyHapticScale(buffer[i], scale, scaleFactor); if (adaptiveScaleFactor >= 0 && adaptiveScaleFactor != 1.0f) { buffer[i] *= adaptiveScaleFactor; } Loading
libs/vibrator/include/vibrator/ExternalVibrationUtils.h +1 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ namespace android::os { // TODO(b/345186129): remove this once flag android_os_vibrator_haptics_scale_v2_enabled removed enum class HapticLevel : int32_t { MUTE = -100, VERY_LOW = -2, Loading
libs/vibrator/tests/ExternalVibrationUtilsTest.cpp +43 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,49 @@ TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestScaleV2ToScaleFactorIgnoresLev EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestScaleConfigWithScaleFactorAppliesFactor, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, vibration_scale_device_config_enabled))) { constexpr float adaptiveScaleNone = 1.0f; float expectedVeryHigh[TEST_BUFFER_LENGTH] = {1, -1, 1, -0.55f}; scaleBuffer(HapticScale(HapticLevel::LOW, 3.0f /* scaleFactor */, adaptiveScaleNone)); EXPECT_FLOATS_NEARLY_EQ(expectedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedHigh[TEST_BUFFER_LENGTH] = {1, -1, 0.66f, -0.29f}; scaleBuffer(HapticScale(HapticLevel::LOW, 1.5f /* scaleFactor */, adaptiveScaleNone)); EXPECT_FLOATS_NEARLY_EQ(expectedHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedLow[TEST_BUFFER_LENGTH] = {0.8f, -0.8f, 0.4f, -0.16f}; scaleBuffer(HapticScale(HapticLevel::HIGH, 0.8f /* scaleFactor */, adaptiveScaleNone)); EXPECT_FLOATS_NEARLY_EQ(expectedLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedVeryLow[TEST_BUFFER_LENGTH] = {0.4f, -0.4f, 0.2f, -0.08f}; scaleBuffer(HapticScale(HapticLevel::HIGH, 0.4f /* scaleFactor */, adaptiveScaleNone)); EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestScaleConfigWithoutScaleFactorAppliesScaleLevel, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled)), REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, vibration_scale_device_config_enabled))) { float expectedVeryHigh[TEST_BUFFER_LENGTH] = {1, -1, 0.79f, -0.39f}; scaleBuffer(HapticLevel::VERY_HIGH); EXPECT_FLOATS_NEARLY_EQ(expectedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedHigh[TEST_BUFFER_LENGTH] = {1, -1, 0.62f, -0.27f}; scaleBuffer(HapticLevel::HIGH); EXPECT_FLOATS_NEARLY_EQ(expectedHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedLow[TEST_BUFFER_LENGTH] = {0.70f, -0.70f, 0.35f, -0.14f}; scaleBuffer(HapticLevel::LOW); EXPECT_FLOATS_NEARLY_EQ(expectedLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedVeryLow[TEST_BUFFER_LENGTH] = {0.45f, -0.45f, 0.22f, -0.09f}; scaleBuffer(HapticLevel::VERY_LOW); EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestAdaptiveScaleFactorUndefinedIgnoredScale, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expectedVeryHigh[TEST_BUFFER_LENGTH] = {1, -1, 0.79f, -0.39f}; Loading