Loading libs/vibrator/ExternalVibration.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -93,8 +93,8 @@ os::HapticScale ExternalVibration::externalVibrationScaleToHapticScale( externalVibrationScale.scaleLevel); } return {/*level=*/scaleLevel, /*adaptiveScaleFactor=*/ externalVibrationScale.adaptiveHapticsScale}; return os::HapticScale(scaleLevel, externalVibrationScale.scaleFactor, externalVibrationScale.adaptiveHapticsScale); } } // namespace os Loading libs/vibrator/ExternalVibrationUtils.cpp +43 −5 Original line number Diff line number Diff line Loading @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "ExternalVibrationUtils" #include <cstring> #include <android_os_vibrator.h> Loading @@ -20,6 +22,7 @@ #include <algorithm> #include <math.h> #include <log/log.h> #include <vibrator/ExternalVibrationUtils.h> namespace android::os { Loading @@ -29,6 +32,7 @@ static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2.0f / 3.0f; static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f; static constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f; static constexpr float SCALE_GAMMA = 0.65f; // Same as VibrationEffect.SCALE_GAMMA static constexpr float SCALE_LEVEL_GAIN = 1.4f; // Same as VibrationConfig.DEFAULT_SCALE_LEVEL_GAIN float getOldHapticScaleGamma(HapticLevel level) { switch (level) { Loading Loading @@ -60,9 +64,34 @@ float getOldHapticMaxAmplitudeRatio(HapticLevel level) { } } /* Same as VibrationScaler.SCALE_LEVEL_* */ float getHapticScaleFactor(HapticLevel level) { /* Same as VibrationScaler.getScaleFactor */ float getHapticScaleFactor(HapticScale scale) { if (android_os_vibrator_haptics_scale_v2_enabled()) { if (scale.getScaleFactor() >= 0) { // ExternalVibratorService provided the scale factor, use it. return scale.getScaleFactor(); } HapticLevel level = scale.getLevel(); switch (level) { case HapticLevel::MUTE: return 0.0f; case HapticLevel::NONE: return 1.0f; default: float scaleFactor = powf(SCALE_LEVEL_GAIN, static_cast<int32_t>(level)); if (scaleFactor <= 0) { ALOGE("Invalid scale factor %.2f for level %d, using fallback to 1.0", scaleFactor, static_cast<int32_t>(level)); scaleFactor = 1.0f; } return scaleFactor; } } // Same as VibrationScaler.SCALE_FACTOR_* switch (scale.getLevel()) { case HapticLevel::MUTE: return 0.0f; case HapticLevel::VERY_LOW: return 0.6f; case HapticLevel::LOW: Loading @@ -83,6 +112,14 @@ float applyOldHapticScale(float value, float gamma, float maxAmplitudeRatio) { } float applyNewHapticScale(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 scale = powf(scaleFactor, 1.0f / SCALE_GAMMA); if (scaleFactor <= 1) { // Scale down is simply a gamma corrected application of scaleFactor to the intensity. Loading Loading @@ -115,14 +152,15 @@ void applyHapticScale(float* buffer, size_t length, HapticScale scale) { return; } HapticLevel hapticLevel = scale.getLevel(); float scaleFactor = getHapticScaleFactor(hapticLevel); float scaleFactor = getHapticScaleFactor(scale); float adaptiveScaleFactor = scale.getAdaptiveScaleFactor(); float oldGamma = getOldHapticScaleGamma(hapticLevel); float oldMaxAmplitudeRatio = getOldHapticMaxAmplitudeRatio(hapticLevel); for (size_t i = 0; i < length; i++) { if (hapticLevel != HapticLevel::NONE) { if (android_os_vibrator_fix_audio_coupled_haptics_scaling()) { if (android_os_vibrator_fix_audio_coupled_haptics_scaling() || android_os_vibrator_haptics_scale_v2_enabled()) { buffer[i] = applyNewHapticScale(buffer[i], scaleFactor); } else { buffer[i] = applyOldHapticScale(buffer[i], oldGamma, oldMaxAmplitudeRatio); Loading libs/vibrator/include/vibrator/ExternalVibrationUtils.h +30 −16 Original line number Diff line number Diff line Loading @@ -17,9 +17,13 @@ #ifndef ANDROID_EXTERNAL_VIBRATION_UTILS_H #define ANDROID_EXTERNAL_VIBRATION_UTILS_H #include <cstring> #include <sstream> #include <string> namespace android::os { enum class HapticLevel { enum class HapticLevel : int32_t { MUTE = -100, VERY_LOW = -2, LOW = -1, Loading @@ -31,32 +35,42 @@ enum class HapticLevel { class HapticScale { private: HapticLevel mLevel = HapticLevel::NONE; float mScaleFactor = -1.0f; // undefined, use haptic level to define scale factor float mAdaptiveScaleFactor = 1.0f; public: constexpr HapticScale(HapticLevel level, float adaptiveScaleFactor) : mLevel(level), mAdaptiveScaleFactor(adaptiveScaleFactor) {} constexpr HapticScale(HapticLevel level) : mLevel(level) {} explicit HapticScale(HapticLevel level, float scaleFactor, float adaptiveScaleFactor) : mLevel(level), mScaleFactor(scaleFactor), mAdaptiveScaleFactor(adaptiveScaleFactor) {} explicit HapticScale(HapticLevel level) : mLevel(level) {} constexpr HapticScale() {} HapticLevel getLevel() const { return mLevel; } float getScaleFactor() const { return mScaleFactor; } float getAdaptiveScaleFactor() const { return mAdaptiveScaleFactor; } bool operator==(const HapticScale& other) const { return mLevel == other.mLevel && mAdaptiveScaleFactor == other.mAdaptiveScaleFactor; return mLevel == other.mLevel && mScaleFactor == other.mScaleFactor && mAdaptiveScaleFactor == other.mAdaptiveScaleFactor; } bool isScaleNone() const { return mLevel == HapticLevel::NONE && mAdaptiveScaleFactor == 1.0f; return (mLevel == HapticLevel::NONE || mScaleFactor == 1.0f) && mAdaptiveScaleFactor == 1.0f; } bool isScaleMute() const { return mLevel == HapticLevel::MUTE; } bool isScaleMute() const { return mLevel == HapticLevel::MUTE || mScaleFactor == 0; } static HapticScale mute() { return {/*level=*/os::HapticLevel::MUTE}; std::string toString() const { std::ostringstream os; os << "HapticScale { level: " << static_cast<int>(mLevel); os << ", scaleFactor: " << mScaleFactor; os << ", adaptiveScaleFactor: " << mAdaptiveScaleFactor; os << "}"; return os.str(); } static HapticScale mute() { return os::HapticScale(os::HapticLevel::MUTE); } static HapticScale none() { return os::HapticScale(os::HapticLevel::NONE); } }; bool isValidHapticScale(HapticScale scale); Loading libs/vibrator/tests/ExternalVibrationTest.cpp +13 −1 Original line number Diff line number Diff line Loading @@ -57,11 +57,14 @@ TEST_F(ExternalVibrationTest, TestReadAndWriteToParcel) { originalAttrs.usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION; originalAttrs.source = AUDIO_SOURCE_VOICE_COMMUNICATION; originalAttrs.flags = AUDIO_FLAG_BYPASS_MUTE; sp<TestVibrationController> vibrationController = new TestVibrationController(); ASSERT_NE(vibrationController, nullptr); sp<os::ExternalVibration> original = new os::ExternalVibration(uid, pkg, originalAttrs, vibrationController); ASSERT_NE(original, nullptr); EXPECT_EQ(original->getUid(), uid); EXPECT_EQ(original->getPackage(), pkg); EXPECT_EQ(original->getAudioAttributes().content_type, originalAttrs.content_type); Loading @@ -69,18 +72,22 @@ TEST_F(ExternalVibrationTest, TestReadAndWriteToParcel) { EXPECT_EQ(original->getAudioAttributes().source, originalAttrs.source); EXPECT_EQ(original->getAudioAttributes().flags, originalAttrs.flags); EXPECT_EQ(original->getController(), vibrationController); audio_attributes_t defaultAttrs; defaultAttrs.content_type = AUDIO_CONTENT_TYPE_UNKNOWN; defaultAttrs.usage = AUDIO_USAGE_UNKNOWN; defaultAttrs.source = AUDIO_SOURCE_DEFAULT; defaultAttrs.flags = AUDIO_FLAG_NONE; sp<os::ExternalVibration> parceled = new os::ExternalVibration(0, std::string(""), defaultAttrs, nullptr); ASSERT_NE(parceled, nullptr); Parcel parcel; original->writeToParcel(&parcel); parcel.setDataPosition(0); parceled->readFromParcel(&parcel); EXPECT_EQ(parceled->getUid(), uid); EXPECT_EQ(parceled->getPackage(), pkg); EXPECT_EQ(parceled->getAudioAttributes().content_type, originalAttrs.content_type); Loading @@ -93,12 +100,17 @@ TEST_F(ExternalVibrationTest, TestReadAndWriteToParcel) { TEST_F(ExternalVibrationTest, TestExternalVibrationScaleToHapticScale) { os::ExternalVibrationScale externalVibrationScale; externalVibrationScale.scaleLevel = ScaleLevel::SCALE_HIGH; externalVibrationScale.scaleFactor = 0.5f; externalVibrationScale.adaptiveHapticsScale = 0.8f; os::HapticScale hapticScale = os::ExternalVibration::externalVibrationScaleToHapticScale(externalVibrationScale); // Check scale factor is forwarded. // Check scale factors are forwarded. EXPECT_EQ(hapticScale.getLevel(), HapticLevel::HIGH); EXPECT_EQ(hapticScale.getScaleFactor(), 0.5f); EXPECT_EQ(hapticScale.getAdaptiveScaleFactor(), 0.8f); // Check conversion for all levels. EXPECT_EQ(toHapticLevel(ScaleLevel::SCALE_MUTE), HapticLevel::MUTE); EXPECT_EQ(toHapticLevel(ScaleLevel::SCALE_VERY_LOW), HapticLevel::VERY_LOW); Loading libs/vibrator/tests/ExternalVibrationUtilsTest.cpp +138 −48 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ public: protected: void scaleBuffer(HapticLevel hapticLevel) { scaleBuffer(HapticScale(hapticLevel), 0 /* limit */); scaleBuffer(HapticScale(hapticLevel)); } void scaleBuffer(HapticLevel hapticLevel, float adaptiveScaleFactor) { Loading @@ -49,7 +49,11 @@ protected: } void scaleBuffer(HapticLevel hapticLevel, float adaptiveScaleFactor, float limit) { scaleBuffer(HapticScale(hapticLevel, adaptiveScaleFactor), limit); scaleBuffer(HapticScale(hapticLevel, -1 /* scaleFactor */, adaptiveScaleFactor), limit); } void scaleBuffer(HapticScale hapticScale) { scaleBuffer(hapticScale, 0 /* limit */); } void scaleBuffer(HapticScale hapticScale, float limit) { Loading @@ -60,11 +64,9 @@ protected: float mBuffer[TEST_BUFFER_LENGTH]; }; TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestLegacyScaleMute, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestLegacyScaleMute, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling), ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::fill(std::begin(expected), std::end(expected), 0); Loading @@ -72,11 +74,9 @@ TEST_F_WITH_FLAGS( EXPECT_FLOATS_NEARLY_EQ(expected, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestFixedScaleMute, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestFixedScaleMute, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::fill(std::begin(expected), std::end(expected), 0); Loading @@ -85,10 +85,19 @@ TEST_F_WITH_FLAGS( } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestLegacyScaleNone, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { ExternalVibrationUtilsTest, TestScaleV2Mute, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::fill(std::begin(expected), std::end(expected), 0); scaleBuffer(HapticLevel::MUTE); EXPECT_FLOATS_NEARLY_EQ(expected, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestLegacyScaleNone, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling), ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::copy(std::begin(TEST_BUFFER), std::end(TEST_BUFFER), std::begin(expected)); Loading @@ -96,11 +105,9 @@ TEST_F_WITH_FLAGS( EXPECT_FLOATS_NEARLY_EQ(expected, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestFixedScaleNone, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestFixedScaleNone, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::copy(std::begin(TEST_BUFFER), std::end(TEST_BUFFER), std::begin(expected)); Loading @@ -109,10 +116,19 @@ TEST_F_WITH_FLAGS( } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestLegacyScaleToHapticLevel, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { ExternalVibrationUtilsTest, TestScaleV2None, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::copy(std::begin(TEST_BUFFER), std::end(TEST_BUFFER), std::begin(expected)); scaleBuffer(HapticLevel::NONE); EXPECT_FLOATS_NEARLY_EQ(expected, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestLegacyScaleToHapticLevel, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling), ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expectedVeryHigh[TEST_BUFFER_LENGTH] = { 1, -1, 0.84f, -0.66f }; scaleBuffer(HapticLevel::VERY_HIGH); EXPECT_FLOATS_NEARLY_EQ(expectedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); Loading @@ -130,11 +146,9 @@ TEST_F_WITH_FLAGS( EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestFixedScaleToHapticLevel, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestFixedScaleToHapticLevel, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_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); Loading @@ -153,10 +167,52 @@ TEST_F_WITH_FLAGS( } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestAdaptiveScaleFactorAppliedAfterLegacyScale, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { ExternalVibrationUtilsTest, TestScaleV2ToHapticLevel, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expectedVeryHigh[TEST_BUFFER_LENGTH] = { 1, -1, 0.8f, -0.38f }; scaleBuffer(HapticLevel::VERY_HIGH); EXPECT_FLOATS_NEARLY_EQ(expectedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedHigh[TEST_BUFFER_LENGTH] = { 1, -1, 0.63f, -0.27f }; scaleBuffer(HapticLevel::HIGH); EXPECT_FLOATS_NEARLY_EQ(expectedHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedLow[TEST_BUFFER_LENGTH] = { 0.71f, -0.71f, 0.35f, -0.14f }; scaleBuffer(HapticLevel::LOW); EXPECT_FLOATS_NEARLY_EQ(expectedLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedVeryLow[TEST_BUFFER_LENGTH] = { 0.51f, -0.51f, 0.25f, -0.1f }; scaleBuffer(HapticLevel::VERY_LOW); EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestScaleV2ToScaleFactorIgnoresLevel, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_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, TestAdaptiveScaleFactorAppliedAfterLegacyScale, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling), ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // Haptic level scale up then adaptive scale down float expectedVeryHigh[TEST_BUFFER_LENGTH] = { 0.2, -0.2, 0.16f, -0.13f }; scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */); Loading @@ -178,11 +234,9 @@ TEST_F_WITH_FLAGS( EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestAdaptiveScaleFactorAppliedAfterFixedScale, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestAdaptiveScaleFactorAppliedAfterFixedScale, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // Haptic level scale up then adaptive scale down float expectedVeryHigh[TEST_BUFFER_LENGTH] = { 0.2, -0.2, 0.16f, -0.07f }; scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */); Loading @@ -205,10 +259,33 @@ TEST_F_WITH_FLAGS( } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestLimitAppliedAfterLegacyScale, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { ExternalVibrationUtilsTest, TestAdaptiveScaleFactorAppliedAfterScaleV2, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // 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.5f, -1.5f, 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.02f, -1.02f, 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, TestLimitAppliedAfterLegacyScale, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling), ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // Scaled = { 0.2, -0.2, 0.16f, -0.13f }; float expectedClippedVeryHigh[TEST_BUFFER_LENGTH] = { 0.15f, -0.15f, 0.15f, -0.13f }; scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */, 0.15f /* limit */); Loading @@ -220,11 +297,9 @@ TEST_F_WITH_FLAGS( EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestLimitAppliedAfterFixedScale, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestLimitAppliedAfterFixedScale, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // Scaled = { 0.2, -0.2, 0.16f, -0.13f }; float expectedClippedVeryHigh[TEST_BUFFER_LENGTH] = { 0.15f, -0.15f, 0.15f, -0.07f }; scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */, 0.15f /* limit */); Loading @@ -235,3 +310,18 @@ TEST_F_WITH_FLAGS( 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, TestLimitAppliedAfterScaleV2, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // Scaled = { 0.2, -0.2, 0.15f, -0.07f }; float expectedClippedVeryHigh[TEST_BUFFER_LENGTH] = { 0.15f, -0.15f, 0.15f, -0.07f }; scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */, 0.15f /* limit */); EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); // Scaled = { 1.02f, -1.02f, 0.51f, -0.2f } float expectedClippedVeryLow[TEST_BUFFER_LENGTH] = { 0.7f, -0.7f, 0.51f, -0.2f }; scaleBuffer(HapticLevel::VERY_LOW, 2 /* adaptiveScaleFactor */, 0.7f /* limit */); EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } Loading
libs/vibrator/ExternalVibration.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -93,8 +93,8 @@ os::HapticScale ExternalVibration::externalVibrationScaleToHapticScale( externalVibrationScale.scaleLevel); } return {/*level=*/scaleLevel, /*adaptiveScaleFactor=*/ externalVibrationScale.adaptiveHapticsScale}; return os::HapticScale(scaleLevel, externalVibrationScale.scaleFactor, externalVibrationScale.adaptiveHapticsScale); } } // namespace os Loading
libs/vibrator/ExternalVibrationUtils.cpp +43 −5 Original line number Diff line number Diff line Loading @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "ExternalVibrationUtils" #include <cstring> #include <android_os_vibrator.h> Loading @@ -20,6 +22,7 @@ #include <algorithm> #include <math.h> #include <log/log.h> #include <vibrator/ExternalVibrationUtils.h> namespace android::os { Loading @@ -29,6 +32,7 @@ static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2.0f / 3.0f; static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f; static constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f; static constexpr float SCALE_GAMMA = 0.65f; // Same as VibrationEffect.SCALE_GAMMA static constexpr float SCALE_LEVEL_GAIN = 1.4f; // Same as VibrationConfig.DEFAULT_SCALE_LEVEL_GAIN float getOldHapticScaleGamma(HapticLevel level) { switch (level) { Loading Loading @@ -60,9 +64,34 @@ float getOldHapticMaxAmplitudeRatio(HapticLevel level) { } } /* Same as VibrationScaler.SCALE_LEVEL_* */ float getHapticScaleFactor(HapticLevel level) { /* Same as VibrationScaler.getScaleFactor */ float getHapticScaleFactor(HapticScale scale) { if (android_os_vibrator_haptics_scale_v2_enabled()) { if (scale.getScaleFactor() >= 0) { // ExternalVibratorService provided the scale factor, use it. return scale.getScaleFactor(); } HapticLevel level = scale.getLevel(); switch (level) { case HapticLevel::MUTE: return 0.0f; case HapticLevel::NONE: return 1.0f; default: float scaleFactor = powf(SCALE_LEVEL_GAIN, static_cast<int32_t>(level)); if (scaleFactor <= 0) { ALOGE("Invalid scale factor %.2f for level %d, using fallback to 1.0", scaleFactor, static_cast<int32_t>(level)); scaleFactor = 1.0f; } return scaleFactor; } } // Same as VibrationScaler.SCALE_FACTOR_* switch (scale.getLevel()) { case HapticLevel::MUTE: return 0.0f; case HapticLevel::VERY_LOW: return 0.6f; case HapticLevel::LOW: Loading @@ -83,6 +112,14 @@ float applyOldHapticScale(float value, float gamma, float maxAmplitudeRatio) { } float applyNewHapticScale(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 scale = powf(scaleFactor, 1.0f / SCALE_GAMMA); if (scaleFactor <= 1) { // Scale down is simply a gamma corrected application of scaleFactor to the intensity. Loading Loading @@ -115,14 +152,15 @@ void applyHapticScale(float* buffer, size_t length, HapticScale scale) { return; } HapticLevel hapticLevel = scale.getLevel(); float scaleFactor = getHapticScaleFactor(hapticLevel); float scaleFactor = getHapticScaleFactor(scale); float adaptiveScaleFactor = scale.getAdaptiveScaleFactor(); float oldGamma = getOldHapticScaleGamma(hapticLevel); float oldMaxAmplitudeRatio = getOldHapticMaxAmplitudeRatio(hapticLevel); for (size_t i = 0; i < length; i++) { if (hapticLevel != HapticLevel::NONE) { if (android_os_vibrator_fix_audio_coupled_haptics_scaling()) { if (android_os_vibrator_fix_audio_coupled_haptics_scaling() || android_os_vibrator_haptics_scale_v2_enabled()) { buffer[i] = applyNewHapticScale(buffer[i], scaleFactor); } else { buffer[i] = applyOldHapticScale(buffer[i], oldGamma, oldMaxAmplitudeRatio); Loading
libs/vibrator/include/vibrator/ExternalVibrationUtils.h +30 −16 Original line number Diff line number Diff line Loading @@ -17,9 +17,13 @@ #ifndef ANDROID_EXTERNAL_VIBRATION_UTILS_H #define ANDROID_EXTERNAL_VIBRATION_UTILS_H #include <cstring> #include <sstream> #include <string> namespace android::os { enum class HapticLevel { enum class HapticLevel : int32_t { MUTE = -100, VERY_LOW = -2, LOW = -1, Loading @@ -31,32 +35,42 @@ enum class HapticLevel { class HapticScale { private: HapticLevel mLevel = HapticLevel::NONE; float mScaleFactor = -1.0f; // undefined, use haptic level to define scale factor float mAdaptiveScaleFactor = 1.0f; public: constexpr HapticScale(HapticLevel level, float adaptiveScaleFactor) : mLevel(level), mAdaptiveScaleFactor(adaptiveScaleFactor) {} constexpr HapticScale(HapticLevel level) : mLevel(level) {} explicit HapticScale(HapticLevel level, float scaleFactor, float adaptiveScaleFactor) : mLevel(level), mScaleFactor(scaleFactor), mAdaptiveScaleFactor(adaptiveScaleFactor) {} explicit HapticScale(HapticLevel level) : mLevel(level) {} constexpr HapticScale() {} HapticLevel getLevel() const { return mLevel; } float getScaleFactor() const { return mScaleFactor; } float getAdaptiveScaleFactor() const { return mAdaptiveScaleFactor; } bool operator==(const HapticScale& other) const { return mLevel == other.mLevel && mAdaptiveScaleFactor == other.mAdaptiveScaleFactor; return mLevel == other.mLevel && mScaleFactor == other.mScaleFactor && mAdaptiveScaleFactor == other.mAdaptiveScaleFactor; } bool isScaleNone() const { return mLevel == HapticLevel::NONE && mAdaptiveScaleFactor == 1.0f; return (mLevel == HapticLevel::NONE || mScaleFactor == 1.0f) && mAdaptiveScaleFactor == 1.0f; } bool isScaleMute() const { return mLevel == HapticLevel::MUTE; } bool isScaleMute() const { return mLevel == HapticLevel::MUTE || mScaleFactor == 0; } static HapticScale mute() { return {/*level=*/os::HapticLevel::MUTE}; std::string toString() const { std::ostringstream os; os << "HapticScale { level: " << static_cast<int>(mLevel); os << ", scaleFactor: " << mScaleFactor; os << ", adaptiveScaleFactor: " << mAdaptiveScaleFactor; os << "}"; return os.str(); } static HapticScale mute() { return os::HapticScale(os::HapticLevel::MUTE); } static HapticScale none() { return os::HapticScale(os::HapticLevel::NONE); } }; bool isValidHapticScale(HapticScale scale); Loading
libs/vibrator/tests/ExternalVibrationTest.cpp +13 −1 Original line number Diff line number Diff line Loading @@ -57,11 +57,14 @@ TEST_F(ExternalVibrationTest, TestReadAndWriteToParcel) { originalAttrs.usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION; originalAttrs.source = AUDIO_SOURCE_VOICE_COMMUNICATION; originalAttrs.flags = AUDIO_FLAG_BYPASS_MUTE; sp<TestVibrationController> vibrationController = new TestVibrationController(); ASSERT_NE(vibrationController, nullptr); sp<os::ExternalVibration> original = new os::ExternalVibration(uid, pkg, originalAttrs, vibrationController); ASSERT_NE(original, nullptr); EXPECT_EQ(original->getUid(), uid); EXPECT_EQ(original->getPackage(), pkg); EXPECT_EQ(original->getAudioAttributes().content_type, originalAttrs.content_type); Loading @@ -69,18 +72,22 @@ TEST_F(ExternalVibrationTest, TestReadAndWriteToParcel) { EXPECT_EQ(original->getAudioAttributes().source, originalAttrs.source); EXPECT_EQ(original->getAudioAttributes().flags, originalAttrs.flags); EXPECT_EQ(original->getController(), vibrationController); audio_attributes_t defaultAttrs; defaultAttrs.content_type = AUDIO_CONTENT_TYPE_UNKNOWN; defaultAttrs.usage = AUDIO_USAGE_UNKNOWN; defaultAttrs.source = AUDIO_SOURCE_DEFAULT; defaultAttrs.flags = AUDIO_FLAG_NONE; sp<os::ExternalVibration> parceled = new os::ExternalVibration(0, std::string(""), defaultAttrs, nullptr); ASSERT_NE(parceled, nullptr); Parcel parcel; original->writeToParcel(&parcel); parcel.setDataPosition(0); parceled->readFromParcel(&parcel); EXPECT_EQ(parceled->getUid(), uid); EXPECT_EQ(parceled->getPackage(), pkg); EXPECT_EQ(parceled->getAudioAttributes().content_type, originalAttrs.content_type); Loading @@ -93,12 +100,17 @@ TEST_F(ExternalVibrationTest, TestReadAndWriteToParcel) { TEST_F(ExternalVibrationTest, TestExternalVibrationScaleToHapticScale) { os::ExternalVibrationScale externalVibrationScale; externalVibrationScale.scaleLevel = ScaleLevel::SCALE_HIGH; externalVibrationScale.scaleFactor = 0.5f; externalVibrationScale.adaptiveHapticsScale = 0.8f; os::HapticScale hapticScale = os::ExternalVibration::externalVibrationScaleToHapticScale(externalVibrationScale); // Check scale factor is forwarded. // Check scale factors are forwarded. EXPECT_EQ(hapticScale.getLevel(), HapticLevel::HIGH); EXPECT_EQ(hapticScale.getScaleFactor(), 0.5f); EXPECT_EQ(hapticScale.getAdaptiveScaleFactor(), 0.8f); // Check conversion for all levels. EXPECT_EQ(toHapticLevel(ScaleLevel::SCALE_MUTE), HapticLevel::MUTE); EXPECT_EQ(toHapticLevel(ScaleLevel::SCALE_VERY_LOW), HapticLevel::VERY_LOW); Loading
libs/vibrator/tests/ExternalVibrationUtilsTest.cpp +138 −48 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ public: protected: void scaleBuffer(HapticLevel hapticLevel) { scaleBuffer(HapticScale(hapticLevel), 0 /* limit */); scaleBuffer(HapticScale(hapticLevel)); } void scaleBuffer(HapticLevel hapticLevel, float adaptiveScaleFactor) { Loading @@ -49,7 +49,11 @@ protected: } void scaleBuffer(HapticLevel hapticLevel, float adaptiveScaleFactor, float limit) { scaleBuffer(HapticScale(hapticLevel, adaptiveScaleFactor), limit); scaleBuffer(HapticScale(hapticLevel, -1 /* scaleFactor */, adaptiveScaleFactor), limit); } void scaleBuffer(HapticScale hapticScale) { scaleBuffer(hapticScale, 0 /* limit */); } void scaleBuffer(HapticScale hapticScale, float limit) { Loading @@ -60,11 +64,9 @@ protected: float mBuffer[TEST_BUFFER_LENGTH]; }; TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestLegacyScaleMute, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestLegacyScaleMute, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling), ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::fill(std::begin(expected), std::end(expected), 0); Loading @@ -72,11 +74,9 @@ TEST_F_WITH_FLAGS( EXPECT_FLOATS_NEARLY_EQ(expected, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestFixedScaleMute, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestFixedScaleMute, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::fill(std::begin(expected), std::end(expected), 0); Loading @@ -85,10 +85,19 @@ TEST_F_WITH_FLAGS( } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestLegacyScaleNone, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { ExternalVibrationUtilsTest, TestScaleV2Mute, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::fill(std::begin(expected), std::end(expected), 0); scaleBuffer(HapticLevel::MUTE); EXPECT_FLOATS_NEARLY_EQ(expected, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestLegacyScaleNone, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling), ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::copy(std::begin(TEST_BUFFER), std::end(TEST_BUFFER), std::begin(expected)); Loading @@ -96,11 +105,9 @@ TEST_F_WITH_FLAGS( EXPECT_FLOATS_NEARLY_EQ(expected, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestFixedScaleNone, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestFixedScaleNone, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::copy(std::begin(TEST_BUFFER), std::end(TEST_BUFFER), std::begin(expected)); Loading @@ -109,10 +116,19 @@ TEST_F_WITH_FLAGS( } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestLegacyScaleToHapticLevel, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { ExternalVibrationUtilsTest, TestScaleV2None, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expected[TEST_BUFFER_LENGTH]; std::copy(std::begin(TEST_BUFFER), std::end(TEST_BUFFER), std::begin(expected)); scaleBuffer(HapticLevel::NONE); EXPECT_FLOATS_NEARLY_EQ(expected, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestLegacyScaleToHapticLevel, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling), ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expectedVeryHigh[TEST_BUFFER_LENGTH] = { 1, -1, 0.84f, -0.66f }; scaleBuffer(HapticLevel::VERY_HIGH); EXPECT_FLOATS_NEARLY_EQ(expectedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); Loading @@ -130,11 +146,9 @@ TEST_F_WITH_FLAGS( EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestFixedScaleToHapticLevel, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestFixedScaleToHapticLevel, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_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); Loading @@ -153,10 +167,52 @@ TEST_F_WITH_FLAGS( } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestAdaptiveScaleFactorAppliedAfterLegacyScale, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { ExternalVibrationUtilsTest, TestScaleV2ToHapticLevel, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { float expectedVeryHigh[TEST_BUFFER_LENGTH] = { 1, -1, 0.8f, -0.38f }; scaleBuffer(HapticLevel::VERY_HIGH); EXPECT_FLOATS_NEARLY_EQ(expectedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedHigh[TEST_BUFFER_LENGTH] = { 1, -1, 0.63f, -0.27f }; scaleBuffer(HapticLevel::HIGH); EXPECT_FLOATS_NEARLY_EQ(expectedHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedLow[TEST_BUFFER_LENGTH] = { 0.71f, -0.71f, 0.35f, -0.14f }; scaleBuffer(HapticLevel::LOW); EXPECT_FLOATS_NEARLY_EQ(expectedLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); float expectedVeryLow[TEST_BUFFER_LENGTH] = { 0.51f, -0.51f, 0.25f, -0.1f }; scaleBuffer(HapticLevel::VERY_LOW); EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestScaleV2ToScaleFactorIgnoresLevel, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_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, TestAdaptiveScaleFactorAppliedAfterLegacyScale, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling), ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // Haptic level scale up then adaptive scale down float expectedVeryHigh[TEST_BUFFER_LENGTH] = { 0.2, -0.2, 0.16f, -0.13f }; scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */); Loading @@ -178,11 +234,9 @@ TEST_F_WITH_FLAGS( EXPECT_FLOATS_NEARLY_EQ(expectedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestAdaptiveScaleFactorAppliedAfterFixedScale, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestAdaptiveScaleFactorAppliedAfterFixedScale, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // Haptic level scale up then adaptive scale down float expectedVeryHigh[TEST_BUFFER_LENGTH] = { 0.2, -0.2, 0.16f, -0.07f }; scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */); Loading @@ -205,10 +259,33 @@ TEST_F_WITH_FLAGS( } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestLimitAppliedAfterLegacyScale, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { ExternalVibrationUtilsTest, TestAdaptiveScaleFactorAppliedAfterScaleV2, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // 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.5f, -1.5f, 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.02f, -1.02f, 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, TestLimitAppliedAfterLegacyScale, REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling), ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // Scaled = { 0.2, -0.2, 0.16f, -0.13f }; float expectedClippedVeryHigh[TEST_BUFFER_LENGTH] = { 0.15f, -0.15f, 0.15f, -0.13f }; scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */, 0.15f /* limit */); Loading @@ -220,11 +297,9 @@ TEST_F_WITH_FLAGS( EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); } TEST_F_WITH_FLAGS( ExternalVibrationUtilsTest, TestLimitAppliedAfterFixedScale, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)) ) { TEST_F_WITH_FLAGS(ExternalVibrationUtilsTest, TestLimitAppliedAfterFixedScale, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, fix_audio_coupled_haptics_scaling)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // Scaled = { 0.2, -0.2, 0.16f, -0.13f }; float expectedClippedVeryHigh[TEST_BUFFER_LENGTH] = { 0.15f, -0.15f, 0.15f, -0.07f }; scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */, 0.15f /* limit */); Loading @@ -235,3 +310,18 @@ TEST_F_WITH_FLAGS( 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, TestLimitAppliedAfterScaleV2, // Value of fix_audio_coupled_haptics_scaling is not important, should work with either REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(FLAG_NS, haptics_scale_v2_enabled))) { // Scaled = { 0.2, -0.2, 0.15f, -0.07f }; float expectedClippedVeryHigh[TEST_BUFFER_LENGTH] = { 0.15f, -0.15f, 0.15f, -0.07f }; scaleBuffer(HapticLevel::VERY_HIGH, 0.2f /* adaptiveScaleFactor */, 0.15f /* limit */); EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryHigh, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); // Scaled = { 1.02f, -1.02f, 0.51f, -0.2f } float expectedClippedVeryLow[TEST_BUFFER_LENGTH] = { 0.7f, -0.7f, 0.51f, -0.2f }; scaleBuffer(HapticLevel::VERY_LOW, 2 /* adaptiveScaleFactor */, 0.7f /* limit */); EXPECT_FLOATS_NEARLY_EQ(expectedClippedVeryLow, mBuffer, TEST_BUFFER_LENGTH, TEST_TOLERANCE); }