From c7d237de07b7dbf64e4ede98a6a320f67375bc95 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Sun, 18 Dec 2022 15:01:14 +0530 Subject: [PATCH] Haptic Generator : Modify HapticScale param to be a list Bug: 258124419 Test: atest VtsHalHapticGeneratorTargetTest Change-Id: I8c44709e92410fbad4dda7aaea66846ed4893786 --- .../audio/effect/HapticGenerator.aidl | 2 +- .../audio/effect/HapticGenerator.aidl | 2 +- .../hapticGenerator/HapticGeneratorSw.cpp | 24 +- .../hapticGenerator/HapticGeneratorSw.h | 10 +- .../vts/VtsHalHapticGeneratorTargetTest.cpp | 239 ++++++++++++++++-- 5 files changed, 241 insertions(+), 36 deletions(-) diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl index 40a8d72c87..959594b988 100644 --- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl +++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl @@ -35,7 +35,7 @@ package android.hardware.audio.effect; @VintfStability union HapticGenerator { android.hardware.audio.effect.VendorExtension vendorExtension; - android.hardware.audio.effect.HapticGenerator.HapticScale hapticScale; + android.hardware.audio.effect.HapticGenerator.HapticScale[] hapticScales; android.hardware.audio.effect.HapticGenerator.VibratorInformation vibratorInfo; @VintfStability union Id { diff --git a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl index 944155fbcc..3063ee37be 100644 --- a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl +++ b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl @@ -90,6 +90,6 @@ union HapticGenerator { float maxAmplitude; } - HapticScale hapticScale; + HapticScale[] hapticScales; VibratorInformation vibratorInfo; } diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp index f6211c467d..3c3b66fda5 100644 --- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp +++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp @@ -90,8 +90,8 @@ ndk::ScopedAStatus HapticGeneratorSw::setParameterSpecific(const Parameter::Spec auto tag = hgParam.getTag(); switch (tag) { - case HapticGenerator::hapticScale: { - RETURN_IF(mContext->setHgHapticScale(hgParam.get()) != + case HapticGenerator::hapticScales: { + RETURN_IF(mContext->setHgHapticScales(hgParam.get()) != RetCode::SUCCESS, EX_ILLEGAL_ARGUMENT, "HapticScaleNotSupported"); return ndk::ScopedAStatus::ok(); @@ -133,8 +133,8 @@ ndk::ScopedAStatus HapticGeneratorSw::getParameterHapticGenerator(const HapticGe HapticGenerator hgParam; switch (tag) { - case HapticGenerator::hapticScale: { - hgParam.set(mContext->getHgHapticScale()); + case HapticGenerator::hapticScales: { + hgParam.set(mContext->getHgHapticScales()); break; } case HapticGenerator::vibratorInfo: { @@ -183,4 +183,20 @@ IEffect::Status HapticGeneratorSw::effectProcessImpl(float* in, float* out, int return {STATUS_OK, samples, samples}; } +RetCode HapticGeneratorSwContext::setHgHapticScales( + const std::vector& hapticScales) { + // Assume any audio track ID is valid + for (auto& it : hapticScales) { + mHapticScales[it.id] = it; + } + return RetCode::SUCCESS; +} + +std::vector HapticGeneratorSwContext::getHgHapticScales() const { + std::vector result; + std::transform(mHapticScales.begin(), mHapticScales.end(), std::back_inserter(result), + [](auto& scaleIt) { return scaleIt.second; }); + return result; +} + } // namespace aidl::android::hardware::audio::effect diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h index d9ec74471d..7159501379 100644 --- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h +++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h @@ -33,12 +33,8 @@ class HapticGeneratorSwContext final : public EffectContext { LOG(DEBUG) << __func__; } - RetCode setHgHapticScale(const HapticGenerator::HapticScale& hapticScale) { - // All int values are valid for ID - mHapticScale = hapticScale; - return RetCode::SUCCESS; - } - HapticGenerator::HapticScale getHgHapticScale() const { return mHapticScale; } + RetCode setHgHapticScales(const std::vector& hapticScales); + std::vector getHgHapticScales() const; RetCode setHgVibratorInformation(const HapticGenerator::VibratorInformation& vibratorInfo) { // All float values are valid for resonantFrequencyHz, qFactor, maxAmplitude @@ -54,7 +50,7 @@ class HapticGeneratorSwContext final : public EffectContext { static constexpr float DEFAULT_RESONANT_FREQUENCY = 150.0f; static constexpr float DEFAULT_Q_FACTOR = 1.0f; static constexpr float DEFAULT_MAX_AMPLITUDE = 0.0f; - HapticGenerator::HapticScale mHapticScale = {0, HapticGenerator::VibratorScale::MUTE}; + std::map mHapticScales; HapticGenerator::VibratorInformation mVibratorInformation = { DEFAULT_RESONANT_FREQUENCY, DEFAULT_Q_FACTOR, DEFAULT_MAX_AMPLITUDE}; }; diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp index d1f3b97d19..b8ea9c148e 100644 --- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp +++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp @@ -19,7 +19,9 @@ #include #include #include -#include +#include +#include +#include #include "EffectHelper.h" @@ -87,12 +89,11 @@ class HapticGeneratorParamTest : public ::testing::TestWithParam(hapticScale); - Parameter::Specific specific = - Parameter::Specific::make(hg); - return specific; - } - static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100; std::shared_ptr mFactory; std::shared_ptr mEffect; @@ -122,13 +114,13 @@ class HapticGeneratorParamTest : public ::testing::TestWithParam(it); + auto& setHg = std::get(it); // set parameter Parameter expectParam; Parameter::Specific specific; - specific.set(hg); + specific.set(setHg); expectParam.set(specific); EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString(); @@ -139,15 +131,16 @@ class HapticGeneratorParamTest : public ::testing::TestWithParam(tag); id.set(hgId); EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam)); - EXPECT_EQ(expectParam, getParam); + EXPECT_EQ(expectParam, getParam) << expectParam.toString() << "\n" + << getParam.toString(); } } void addHapticScaleParam(int id, HapticGenerator::VibratorScale scale) { - HapticGenerator hg; - HapticGenerator::HapticScale hapticScale = {.id = id, .scale = scale}; - hg.set(hapticScale); - mTags.push_back({HapticGenerator::hapticScale, hg}); + HapticGenerator setHg; + std::vector hapticScales = {{.id = id, .scale = scale}}; + setHg.set(hapticScales); + mTags.push_back({HapticGenerator::hapticScales, setHg}); } void addVibratorInformationParam(float resonantFrequencyHz, float qFactor, float maxAmplitude) { @@ -161,7 +154,8 @@ class HapticGeneratorParamTest : public ::testing::TestWithParam> mTags; + enum ParamTestEnum { PARAM_TEST_TAG, PARAM_TEST_TARGET }; + std::vector> mTags; void CleanUp() { mTags.clear(); } }; @@ -171,6 +165,12 @@ TEST_P(HapticGeneratorParamTest, SetAndGetHapticScale) { SetAndGetHapticGeneratorParameters(); } +TEST_P(HapticGeneratorParamTest, SetAndGetMultipleHapticScales) { + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale)); + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale)); + SetAndGetHapticGeneratorParameters(); +} + TEST_P(HapticGeneratorParamTest, SetAndGetVibratorInformation) { EXPECT_NO_FATAL_FAILURE(addVibratorInformationParam(mParamResonantFrequency, mParamQFactor, mParamMaxAmplitude)); @@ -212,7 +212,7 @@ INSTANTIATE_TEST_SUITE_P( ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( IFactory::descriptor, kHapticGeneratorTypeUUID)), testing::Values(MIN_ID - 1), - testing::Values(HapticGenerator::VibratorScale::MUTE), + testing::Values(HapticGenerator::VibratorScale::NONE), testing::Values(MIN_FLOAT), testing::Values(MIN_FLOAT), testing::Values(MIN_FLOAT)), [](const testing::TestParamInfo& info) { @@ -236,9 +236,202 @@ INSTANTIATE_TEST_SUITE_P( name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); return name; }); - GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorParamTest); +// Test HapticScale[] hapticScales parameter +using HapticGeneratorScalesTestParam = std::tuple, Descriptor>>; +class HapticGeneratorScalesTest : public ::testing::TestWithParam, + public EffectHelper { + public: + HapticGeneratorScalesTest() { + std::tie(mFactory, mDescriptor) = std::get(GetParam()); + } + + void SetUp() override { + ASSERT_NE(nullptr, mFactory); + ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor)); + + Parameter::Common common = EffectHelper::createParamCommon( + 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */, + kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */); + IEffect::OpenEffectReturn ret; + ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE)); + ASSERT_NE(nullptr, mEffect); + } + + void TearDown() override { + ASSERT_NO_FATAL_FAILURE(close(mEffect)); + ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect)); + CleanUp(); + } + + static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100; + std::shared_ptr mFactory; + std::shared_ptr mEffect; + Descriptor mDescriptor; + + void addHapticScaleParam(std::vector scales) { + mHapticScales.push_back(HapticGenerator::make(scales)); + for (const auto& scale : scales) { + expectMap.insert_or_assign(scale.id, scale.scale); + } + } + + void SetHapticScaleParameters() { + // std::unordered_set target; + for (auto& it : mHapticScales) { + Parameter::Specific specific = + Parameter::Specific::make(it); + Parameter param = Parameter::make(specific); + EXPECT_STATUS(EX_NONE, mEffect->setParameter(param)) << param.toString(); + } + } + + void checkHapticScaleParameter() { + // get parameter + Parameter targetParam; + HapticGenerator::Id hgId = HapticGenerator::Id::make( + HapticGenerator::hapticScales); + Parameter::Id id = Parameter::Id::make(hgId); + EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &targetParam)); + ASSERT_EQ(Parameter::specific, targetParam.getTag()); + Parameter::Specific specific = targetParam.get(); + ASSERT_EQ(Parameter::Specific::hapticGenerator, specific.getTag()); + HapticGenerator hg = specific.get(); + ASSERT_EQ(HapticGenerator::hapticScales, hg.getTag()); + std::vector scales = hg.get(); + ASSERT_EQ(scales.size(), expectMap.size()); + for (const auto& scale : scales) { + auto itor = expectMap.find(scale.id); + ASSERT_NE(expectMap.end(), itor); + ASSERT_EQ(scale.scale, itor->second); + expectMap.erase(scale.id); + } + ASSERT_EQ(0ul, expectMap.size()); + } + + const static HapticGenerator::HapticScale kHapticScaleWithMinId; + const static HapticGenerator::HapticScale kHapticScaleWithMinIdNew; + const static HapticGenerator::HapticScale kHapticScale; + const static HapticGenerator::HapticScale kHapticScaleNew; + const static HapticGenerator::HapticScale kHapticScaleWithMaxId; + const static HapticGenerator::HapticScale kHapticScaleWithMaxIdNew; + + std::vector mHapticScales; + + void CleanUp() { + mHapticScales.clear(); + expectMap.clear(); + } + + private: + std::map expectMap; +}; + +const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMinId = { + .id = MIN_ID, .scale = HapticGenerator::VibratorScale::MUTE}; +const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMinIdNew = { + .id = MIN_ID, .scale = HapticGenerator::VibratorScale::VERY_LOW}; +const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScale = { + .id = 1, .scale = HapticGenerator::VibratorScale::LOW}; +const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleNew = { + .id = 1, .scale = HapticGenerator::VibratorScale::NONE}; +const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMaxId = { + .id = MAX_ID, .scale = HapticGenerator::VibratorScale::VERY_HIGH}; +const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMaxIdNew = { + .id = MAX_ID, .scale = HapticGenerator::VibratorScale::MUTE}; + +TEST_P(HapticGeneratorScalesTest, SetAndUpdateOne) { + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleNew})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMinId})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMinIdNew})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxIdNew})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + + EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter()); +} + +TEST_P(HapticGeneratorScalesTest, SetAndUpdateVector) { + EXPECT_NO_FATAL_FAILURE( + addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam( + {kHapticScaleNew, kHapticScaleWithMaxIdNew, kHapticScaleWithMinIdNew})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + + EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter()); +} + +TEST_P(HapticGeneratorScalesTest, SetAndUpdateMultipleVector) { + EXPECT_NO_FATAL_FAILURE( + addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam( + {kHapticScaleNew, kHapticScaleWithMaxIdNew, kHapticScaleWithMinIdNew})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + EXPECT_NO_FATAL_FAILURE( + addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + + EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter()); +} + +TEST_P(HapticGeneratorScalesTest, SetOneAndAddMoreVector) { + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId, kHapticScaleWithMinId})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + + EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter()); +} + +TEST_P(HapticGeneratorScalesTest, SetMultipleAndAddOneVector) { + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId, kHapticScaleWithMinId})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + + EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter()); +} + +TEST_P(HapticGeneratorScalesTest, SetMultipleVectorRepeat) { + EXPECT_NO_FATAL_FAILURE( + addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + EXPECT_NO_FATAL_FAILURE( + addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + EXPECT_NO_FATAL_FAILURE( + addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId})); + EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters()); + + EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter()); +} + +INSTANTIATE_TEST_SUITE_P( + HapticGeneratorScalesTest, HapticGeneratorScalesTest, + ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( + IFactory::descriptor, kHapticGeneratorTypeUUID))), + [](const testing::TestParamInfo& info) { + auto descriptor = std::get(info.param).second; + std::string name = "Implementor_" + descriptor.common.implementor + "_name_" + + descriptor.common.name + "_UUID_" + + descriptor.common.id.uuid.toString(); + std::replace_if( + name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); + return name; + }); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorScalesTest); + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); ABinderProcess_setThreadPoolMaxThreadCount(1);