Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e561b1d7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix ExternalVibrationUtils to be bound to [-1,1]" into main

parents 8ca62e4f 90e19d7a
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -74,11 +74,14 @@ float getHapticScaleFactor(HapticScale scale) {

float applyHapticScale(float value, float scaleFactor) {
    if (android_os_vibrator_haptics_scale_v2_enabled()) {
        if (scaleFactor <= 1 || value == 0) {
            return value * scaleFactor;
        } else {
        // Using S * x / (1 + (S - 1) * x^2) as the scale up function to converge to 1.0.
            return (value * scaleFactor) / (1 + (scaleFactor - 1) * value * value);
        float scaledValue = (scaleFactor <= 1 || value == 0)
                ? (value * scaleFactor)
                : (value * scaleFactor) / (1 + (scaleFactor - 1) * value * value);
        if (android_os_vibrator_vibration_scale_bounds_fix_enabled()) {
            return std::clamp(scaledValue, -1.0f, 1.0f);
        } else {
            return scaledValue;
        }
    }
    float scale = powf(scaleFactor, 1.0f / SCALE_GAMMA);
@@ -136,12 +139,25 @@ void applyHapticScale(float* buffer, size_t length, HapticScale scale) {
    for (size_t i = 0; i < length; i++) {
        buffer[i] = applyHapticScale(buffer[i], scale, scaleFactor);
        if (adaptiveScaleFactor >= 0 && adaptiveScaleFactor != 1.0f) {
            if (android_os_vibrator_vibration_scale_bounds_fix_enabled()) {
                buffer[i] = std::clamp(buffer[i] * adaptiveScaleFactor, -1.0f, 1.0f);
            } else {
                buffer[i] *= adaptiveScaleFactor;
            }
        }
    }
}

void clipHapticData(float* buffer, size_t length, float limit) {
    if (android_os_vibrator_vibration_scale_bounds_fix_enabled()) {
        if (isnan(limit) || limit <= 0 || limit >= 1) {
            return;
        }
        for (size_t i = 0; i < length; i++) {
            buffer[i] = std::clamp(buffer[i], -limit, limit);
        }
        return;
    }
    if (isnan(limit) || limit == 0) {
        return;
    }
+49 −0
Original line number Diff line number Diff line
@@ -282,6 +282,37 @@ TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestAdaptiveScaleFactorAppliedAfte
    EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);
}

TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestBoundedAdaptiveScaleFactorAppliedAfterScaleV2,
                  REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled),
                                         ACONFIG_FLAG(FLAG_NS,
                                                      vibration_scale_bounds_fix_enabled))) {
    // Adaptive scale mutes vibration
    float expectedMuted[TEST_BUFFER_LENGTH];
    std::fill(std::begin(expectedMuted), std::end(expectedMuted), 0);
    scaleBuffer(HapticLevel::VERY_HIGH, 0.0f /* adaptiveScaleFactor */);
    EXPECT_FLOATS_NEARLY_EQ(expectedMuted, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);

    // Haptic level scale up then adaptive scale down
    float expectedVeryHigh[TEST_BUFFER_LENGTH] = {0.2, -0.2, 0.15f, -0.07f};
    scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */);
    EXPECT_FLOATS_NEARLY_EQ(expectedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);

    // Haptic level scale up then adaptive scale up
    float expectedHigh[TEST_BUFFER_LENGTH] = {1, -1, 0.95f, -0.41f};
    scaleBuffer(HapticLevel::HIGH, 1.5f /* adaptiveScaleFactor */);
    EXPECT_FLOATS_NEARLY_EQ(expectedHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);

    // Haptic level scale down then adaptive scale down
    float expectedLow[TEST_BUFFER_LENGTH] = {0.42f, -0.42f, 0.21f, -0.08f};
    scaleBuffer(HapticLevel::LOW, 0.6f /* adaptiveScaleFactor */);
    EXPECT_FLOATS_NEARLY_EQ(expectedLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);

    // Haptic level scale down then adaptive scale up
    float expectedVeryLow[TEST_BUFFER_LENGTH] = {1, -1, 0.51f, -0.2f};
    scaleBuffer(HapticLevel::VERY_LOW, 2 /* adaptiveScaleFactor */);
    EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);
}

TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestLimitAppliedAfterScale,
                  REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) {
    // Scaled = { 0.2, -0.2, 0.16f, -0.13f };
@@ -307,3 +338,21 @@ TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestLimitAppliedAfterScaleV2,
    scaleBuffer(HapticLevel::VERY_LOW, 2 /* adaptiveScaleFactor */, 0.7f /* limit */);
    EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);
}

TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestInvalidLimitIgnored,
                  REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled),
                                         ACONFIG_FLAG(FLAG_NS,
                                                      vibration_scale_bounds_fix_enabled))) {
    float expectedClippedVeryHigh[TEST_BUFFER_LENGTH] = {0.2f, -0.2f, 0.15f, -0.07f};
    scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */, 0 /* limit */);
    EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);

    scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */, NAN /* limit */);
    EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);

    scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */, -0.5f /* limit */);
    EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);

    scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */, 1.5f /* limit */);
    EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE);
}