Loading audio/aidl/default/EffectImpl.cpp +32 −25 Original line number Diff line number Diff line Loading @@ -23,6 +23,9 @@ #include "include/effect-impl/EffectTypes.h" using aidl::android::hardware::audio::effect::IEffect; using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty; using aidl::android::hardware::audio::effect::kEventFlagNotEmpty; using aidl::android::hardware::audio::effect::kReopenSupportedVersion; using aidl::android::hardware::audio::effect::State; using aidl::android::media::audio::common::PcmType; using ::android::hardware::EventFlag; Loading @@ -43,7 +46,6 @@ namespace aidl::android::hardware::audio::effect { ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common, const std::optional<Parameter::Specific>& specific, OpenEffectReturn* ret) { LOG(DEBUG) << getEffectName() << __func__; // effect only support 32bits float RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm || common.input.base.format.pcm != PcmType::FLOAT_32_BIT, Loading @@ -54,11 +56,12 @@ ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common, mImplContext = createContext(common); RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext"); int version = 0; RETURN_IF(!getInterfaceVersion(&version).isOk(), EX_UNSUPPORTED_OPERATION, RETURN_IF(!getInterfaceVersion(&mVersion).isOk(), EX_UNSUPPORTED_OPERATION, "FailedToGetInterfaceVersion"); mImplContext->setVersion(version); mImplContext->setVersion(mVersion); mEventFlag = mImplContext->getStatusEventFlag(); mDataMqNotEmptyEf = mVersion >= kReopenSupportedVersion ? kEventFlagDataMqNotEmpty : kEventFlagNotEmpty; if (specific.has_value()) { RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(specific.value()), "setSpecParamErr"); Loading @@ -66,8 +69,9 @@ ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common, mState = State::IDLE; mImplContext->dupeFmq(ret); RETURN_IF(createThread(getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION, "FailedToCreateWorker"); RETURN_IF(createThread(getEffectNameWithVersion()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION, "FailedToCreateWorker"); LOG(INFO) << getEffectNameWithVersion() << __func__; return ndk::ScopedAStatus::ok(); } Loading @@ -89,7 +93,7 @@ ndk::ScopedAStatus EffectImpl::close() { mState = State::INIT; } RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE, RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE, "notifyEventFlagNotEmptyFailed"); // stop the worker thread, ignore the return code RETURN_IF(destroyThread() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION, Loading @@ -101,13 +105,13 @@ ndk::ScopedAStatus EffectImpl::close() { mImplContext.reset(); } LOG(DEBUG) << getEffectName() << __func__; LOG(INFO) << getEffectNameWithVersion() << __func__; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) { std::lock_guard lg(mImplMutex); LOG(VERBOSE) << getEffectName() << __func__ << " with: " << param.toString(); LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << " with: " << param.toString(); const auto& tag = param.getTag(); switch (tag) { Loading @@ -122,7 +126,7 @@ ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) { return setParameterSpecific(param.get<Parameter::specific>()); } default: { LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag " LOG(ERROR) << getEffectNameWithVersion() << __func__ << " unsupportedParameterTag " << toString(tag); return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "ParameterNotSupported"); Loading @@ -147,7 +151,7 @@ ndk::ScopedAStatus EffectImpl::getParameter(const Parameter::Id& id, Parameter* break; } } LOG(VERBOSE) << getEffectName() << __func__ << id.toString() << param->toString(); LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << id.toString() << param->toString(); return ndk::ScopedAStatus::ok(); } Loading Loading @@ -180,7 +184,7 @@ ndk::ScopedAStatus EffectImpl::setParameterCommon(const Parameter& param) { EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed"); break; default: { LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag " LOG(ERROR) << getEffectNameWithVersion() << __func__ << " unsupportedParameterTag " << toString(tag); return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "commonParamNotSupported"); Loading Loading @@ -214,7 +218,8 @@ ndk::ScopedAStatus EffectImpl::getParameterCommon(const Parameter::Tag& tag, Par break; } default: { LOG(DEBUG) << getEffectName() << __func__ << " unsupported tag " << toString(tag); LOG(DEBUG) << getEffectNameWithVersion() << __func__ << " unsupported tag " << toString(tag); return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "tagNotSupported"); } Loading @@ -236,7 +241,7 @@ ndk::ScopedAStatus EffectImpl::command(CommandId command) { RETURN_OK_IF(mState == State::PROCESSING); RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed"); mState = State::PROCESSING; RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE, RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE, "notifyEventFlagNotEmptyFailed"); startThread(); break; Loading @@ -244,17 +249,18 @@ ndk::ScopedAStatus EffectImpl::command(CommandId command) { case CommandId::RESET: RETURN_OK_IF(mState == State::IDLE); mState = State::IDLE; RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE, RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE, "notifyEventFlagNotEmptyFailed"); stopThread(); RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed"); break; default: LOG(ERROR) << getEffectName() << __func__ << " instance still processing"; LOG(ERROR) << getEffectNameWithVersion() << __func__ << " instance still processing"; return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "CommandIdNotSupported"); } LOG(VERBOSE) << getEffectName() << __func__ << " transfer to state: " << toString(mState); LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << " transfer to state: " << toString(mState); return ndk::ScopedAStatus::ok(); } Loading Loading @@ -284,14 +290,14 @@ void EffectImpl::cleanUp() { RetCode EffectImpl::notifyEventFlag(uint32_t flag) { if (!mEventFlag) { LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag invalid"; LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": StatusEventFlag invalid"; return RetCode::ERROR_EVENT_FLAG_ERROR; } if (const auto ret = mEventFlag->wake(flag); ret != ::android::OK) { LOG(ERROR) << getEffectName() << __func__ << ": wake failure with ret " << ret; LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": wake failure with ret " << ret; return RetCode::ERROR_EVENT_FLAG_ERROR; } LOG(VERBOSE) << getEffectName() << __func__ << ": " << std::hex << mEventFlag; LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << ": " << std::hex << mEventFlag; return RetCode::SUCCESS; } Loading @@ -304,17 +310,17 @@ IEffect::Status EffectImpl::status(binder_status_t status, size_t consumed, size } void EffectImpl::process() { ATRACE_NAME(getEffectName().c_str()); ATRACE_NAME(getEffectNameWithVersion().c_str()); /** * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change * in the life cycle of workerThread (threadLoop). */ uint32_t efState = 0; if (!mEventFlag || ::android::OK != mEventFlag->wait(kEventFlagNotEmpty, &efState, 0 /* no timeout */, ::android::OK != mEventFlag->wait(mDataMqNotEmptyEf, &efState, 0 /* no timeout */, true /* retry */) || !(efState & kEventFlagNotEmpty)) { LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag - " << mEventFlag !(efState & mDataMqNotEmptyEf)) { LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": StatusEventFlag - " << mEventFlag << " efState - " << std::hex << efState; return; } Loading @@ -322,7 +328,8 @@ void EffectImpl::process() { { std::lock_guard lg(mImplMutex); if (mState != State::PROCESSING) { LOG(DEBUG) << getEffectName() << " skip process in state: " << toString(mState); LOG(DEBUG) << getEffectNameWithVersion() << " skip process in state: " << toString(mState); return; } RETURN_VALUE_IF(!mImplContext, void(), "nullContext"); Loading audio/aidl/default/include/effect-impl/EffectImpl.h +10 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,11 @@ class EffectImpl : public BnEffect, public EffectThread { void process() override; protected: // current Hal version int mVersion = 0; // Use kEventFlagNotEmpty for V1 HAL, kEventFlagDataMqNotEmpty for V2 and above int mDataMqNotEmptyEf = aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty; State mState GUARDED_BY(mImplMutex) = State::INIT; IEffect::Status status(binder_status_t status, size_t consumed, size_t produced); Loading @@ -107,6 +112,11 @@ class EffectImpl : public BnEffect, public EffectThread { virtual ndk::ScopedAStatus commandImpl(CommandId id) REQUIRES(mImplMutex); RetCode notifyEventFlag(uint32_t flag); std::string getEffectNameWithVersion() { return getEffectName() + "V" + std::to_string(mVersion); } ::android::hardware::EventFlag* mEventFlag; }; } // namespace aidl::android::hardware::audio::effect audio/aidl/vts/EffectHelper.h +9 −3 Original line number Diff line number Diff line Loading @@ -43,8 +43,10 @@ using namespace android; using aidl::android::hardware::audio::effect::CommandId; using aidl::android::hardware::audio::effect::Descriptor; using aidl::android::hardware::audio::effect::IEffect; using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty; using aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate; using aidl::android::hardware::audio::effect::kEventFlagNotEmpty; using aidl::android::hardware::audio::effect::kReopenSupportedVersion; using aidl::android::hardware::audio::effect::Parameter; using aidl::android::hardware::audio::effect::Range; using aidl::android::hardware::audio::effect::State; Loading Loading @@ -158,7 +160,7 @@ class EffectHelper { std::fill(buffer.begin(), buffer.end(), 0x5a); } static void writeToFmq(std::unique_ptr<StatusMQ>& statusMq, std::unique_ptr<DataMQ>& dataMq, const std::vector<float>& buffer) { const std::vector<float>& buffer, int version) { const size_t available = dataMq->availableToWrite(); ASSERT_NE(0Ul, available); auto bufferFloats = buffer.size(); Loading @@ -169,7 +171,8 @@ class EffectHelper { ASSERT_EQ(::android::OK, EventFlag::createEventFlag(statusMq->getEventFlagWord(), &efGroup)); ASSERT_NE(nullptr, efGroup); efGroup->wake(kEventFlagNotEmpty); efGroup->wake(version >= kReopenSupportedVersion ? kEventFlagDataMqNotEmpty : kEventFlagNotEmpty); ASSERT_EQ(::android::OK, EventFlag::deleteEventFlag(&efGroup)); } static void readFromFmq(std::unique_ptr<StatusMQ>& statusMq, size_t statusNum, Loading Loading @@ -320,7 +323,10 @@ class EffectHelper { ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING)); // Write from buffer to message queues and calling process EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer, [&]() { int version = 0; return (mEffect && mEffect->getInterfaceVersion(&version).isOk()) ? version : 0; }())); // Read the updated message queues into buffer EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 1, outputMQ, Loading audio/aidl/vts/TestUtils.h +1 −1 Original line number Diff line number Diff line Loading @@ -108,7 +108,7 @@ inline ::testing::AssertionResult assertResultOrUnknownTransaction( ({ \ if ((flags).hwAcceleratorMode == \ aidl::android::hardware::audio::effect::Flags::HardwareAccelerator::TUNNEL || \ (flags).bypass) { \ (flags).bypass || (flags).offloadIndication) { \ GTEST_SKIP() << "Skip data path for offload"; \ } \ }) Loading audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp +14 −13 Original line number Diff line number Diff line Loading @@ -42,7 +42,6 @@ using aidl::android::hardware::audio::effect::Descriptor; using aidl::android::hardware::audio::effect::Flags; using aidl::android::hardware::audio::effect::IEffect; using aidl::android::hardware::audio::effect::IFactory; using aidl::android::hardware::audio::effect::kReopenSupportedVersion; using aidl::android::hardware::audio::effect::Parameter; using aidl::android::hardware::audio::effect::State; using aidl::android::media::audio::common::AudioDeviceDescription; Loading @@ -58,6 +57,7 @@ class AudioEffectTest : public testing::TestWithParam<EffectTestParam>, public E public: AudioEffectTest() { std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam()); mVersion = EffectFactoryHelper::getHalVersion(mFactory); } void SetUp() override {} Loading @@ -76,6 +76,7 @@ class AudioEffectTest : public testing::TestWithParam<EffectTestParam>, public E std::shared_ptr<IFactory> mFactory; std::shared_ptr<IEffect> mEffect; Descriptor mDescriptor; int mVersion = 0; void setAndGetParameter(Parameter::Id id, const Parameter& set) { Parameter get; Loading Loading @@ -682,7 +683,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataInProcessingState) { std::vector<float> buffer; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); Loading Loading @@ -722,7 +723,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataAfterRestart) { ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING)); EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); Loading Loading @@ -759,7 +760,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataAfterReopen) { ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START)); ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING)); EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); Loading @@ -779,7 +780,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataAfterReopen) { // verify data consume again EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); Loading Loading @@ -810,7 +811,7 @@ TEST_P(AudioEffectDataPathTest, SendDataAtIdleAndConsumeDataInProcessing) { std::vector<float> buffer; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START)); ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING)); Loading Loading @@ -844,7 +845,7 @@ TEST_P(AudioEffectDataPathTest, ProcessDataMultipleTimes) { std::vector<float> buffer; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer)); ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START)); Loading @@ -853,7 +854,7 @@ TEST_P(AudioEffectDataPathTest, ProcessDataMultipleTimes) { EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); Loading Loading @@ -886,13 +887,13 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataAndRestart) { ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING)); std::vector<float> buffer; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP)); ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer)); ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START)); Loading Loading @@ -928,7 +929,7 @@ TEST_P(AudioEffectDataPathTest, NotConsumeDataByClosedEffect) { std::vector<float> buffer; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer)); ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect)); Loading Loading @@ -964,7 +965,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataMultipleEffects) { std::vector<float> buffer1, buffer2; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common1, inputMQ1, buffer1)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1)); Loading @@ -975,7 +976,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataMultipleEffects) { auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ); ASSERT_TRUE(outputMQ2->isValid()); EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common2, inputMQ2, buffer2)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2)); Loading Loading
audio/aidl/default/EffectImpl.cpp +32 −25 Original line number Diff line number Diff line Loading @@ -23,6 +23,9 @@ #include "include/effect-impl/EffectTypes.h" using aidl::android::hardware::audio::effect::IEffect; using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty; using aidl::android::hardware::audio::effect::kEventFlagNotEmpty; using aidl::android::hardware::audio::effect::kReopenSupportedVersion; using aidl::android::hardware::audio::effect::State; using aidl::android::media::audio::common::PcmType; using ::android::hardware::EventFlag; Loading @@ -43,7 +46,6 @@ namespace aidl::android::hardware::audio::effect { ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common, const std::optional<Parameter::Specific>& specific, OpenEffectReturn* ret) { LOG(DEBUG) << getEffectName() << __func__; // effect only support 32bits float RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm || common.input.base.format.pcm != PcmType::FLOAT_32_BIT, Loading @@ -54,11 +56,12 @@ ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common, mImplContext = createContext(common); RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext"); int version = 0; RETURN_IF(!getInterfaceVersion(&version).isOk(), EX_UNSUPPORTED_OPERATION, RETURN_IF(!getInterfaceVersion(&mVersion).isOk(), EX_UNSUPPORTED_OPERATION, "FailedToGetInterfaceVersion"); mImplContext->setVersion(version); mImplContext->setVersion(mVersion); mEventFlag = mImplContext->getStatusEventFlag(); mDataMqNotEmptyEf = mVersion >= kReopenSupportedVersion ? kEventFlagDataMqNotEmpty : kEventFlagNotEmpty; if (specific.has_value()) { RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(specific.value()), "setSpecParamErr"); Loading @@ -66,8 +69,9 @@ ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common, mState = State::IDLE; mImplContext->dupeFmq(ret); RETURN_IF(createThread(getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION, "FailedToCreateWorker"); RETURN_IF(createThread(getEffectNameWithVersion()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION, "FailedToCreateWorker"); LOG(INFO) << getEffectNameWithVersion() << __func__; return ndk::ScopedAStatus::ok(); } Loading @@ -89,7 +93,7 @@ ndk::ScopedAStatus EffectImpl::close() { mState = State::INIT; } RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE, RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE, "notifyEventFlagNotEmptyFailed"); // stop the worker thread, ignore the return code RETURN_IF(destroyThread() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION, Loading @@ -101,13 +105,13 @@ ndk::ScopedAStatus EffectImpl::close() { mImplContext.reset(); } LOG(DEBUG) << getEffectName() << __func__; LOG(INFO) << getEffectNameWithVersion() << __func__; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) { std::lock_guard lg(mImplMutex); LOG(VERBOSE) << getEffectName() << __func__ << " with: " << param.toString(); LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << " with: " << param.toString(); const auto& tag = param.getTag(); switch (tag) { Loading @@ -122,7 +126,7 @@ ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) { return setParameterSpecific(param.get<Parameter::specific>()); } default: { LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag " LOG(ERROR) << getEffectNameWithVersion() << __func__ << " unsupportedParameterTag " << toString(tag); return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "ParameterNotSupported"); Loading @@ -147,7 +151,7 @@ ndk::ScopedAStatus EffectImpl::getParameter(const Parameter::Id& id, Parameter* break; } } LOG(VERBOSE) << getEffectName() << __func__ << id.toString() << param->toString(); LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << id.toString() << param->toString(); return ndk::ScopedAStatus::ok(); } Loading Loading @@ -180,7 +184,7 @@ ndk::ScopedAStatus EffectImpl::setParameterCommon(const Parameter& param) { EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed"); break; default: { LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag " LOG(ERROR) << getEffectNameWithVersion() << __func__ << " unsupportedParameterTag " << toString(tag); return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "commonParamNotSupported"); Loading Loading @@ -214,7 +218,8 @@ ndk::ScopedAStatus EffectImpl::getParameterCommon(const Parameter::Tag& tag, Par break; } default: { LOG(DEBUG) << getEffectName() << __func__ << " unsupported tag " << toString(tag); LOG(DEBUG) << getEffectNameWithVersion() << __func__ << " unsupported tag " << toString(tag); return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "tagNotSupported"); } Loading @@ -236,7 +241,7 @@ ndk::ScopedAStatus EffectImpl::command(CommandId command) { RETURN_OK_IF(mState == State::PROCESSING); RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed"); mState = State::PROCESSING; RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE, RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE, "notifyEventFlagNotEmptyFailed"); startThread(); break; Loading @@ -244,17 +249,18 @@ ndk::ScopedAStatus EffectImpl::command(CommandId command) { case CommandId::RESET: RETURN_OK_IF(mState == State::IDLE); mState = State::IDLE; RETURN_IF(notifyEventFlag(kEventFlagNotEmpty) != RetCode::SUCCESS, EX_ILLEGAL_STATE, RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE, "notifyEventFlagNotEmptyFailed"); stopThread(); RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed"); break; default: LOG(ERROR) << getEffectName() << __func__ << " instance still processing"; LOG(ERROR) << getEffectNameWithVersion() << __func__ << " instance still processing"; return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "CommandIdNotSupported"); } LOG(VERBOSE) << getEffectName() << __func__ << " transfer to state: " << toString(mState); LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << " transfer to state: " << toString(mState); return ndk::ScopedAStatus::ok(); } Loading Loading @@ -284,14 +290,14 @@ void EffectImpl::cleanUp() { RetCode EffectImpl::notifyEventFlag(uint32_t flag) { if (!mEventFlag) { LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag invalid"; LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": StatusEventFlag invalid"; return RetCode::ERROR_EVENT_FLAG_ERROR; } if (const auto ret = mEventFlag->wake(flag); ret != ::android::OK) { LOG(ERROR) << getEffectName() << __func__ << ": wake failure with ret " << ret; LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": wake failure with ret " << ret; return RetCode::ERROR_EVENT_FLAG_ERROR; } LOG(VERBOSE) << getEffectName() << __func__ << ": " << std::hex << mEventFlag; LOG(VERBOSE) << getEffectNameWithVersion() << __func__ << ": " << std::hex << mEventFlag; return RetCode::SUCCESS; } Loading @@ -304,17 +310,17 @@ IEffect::Status EffectImpl::status(binder_status_t status, size_t consumed, size } void EffectImpl::process() { ATRACE_NAME(getEffectName().c_str()); ATRACE_NAME(getEffectNameWithVersion().c_str()); /** * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change * in the life cycle of workerThread (threadLoop). */ uint32_t efState = 0; if (!mEventFlag || ::android::OK != mEventFlag->wait(kEventFlagNotEmpty, &efState, 0 /* no timeout */, ::android::OK != mEventFlag->wait(mDataMqNotEmptyEf, &efState, 0 /* no timeout */, true /* retry */) || !(efState & kEventFlagNotEmpty)) { LOG(ERROR) << getEffectName() << __func__ << ": StatusEventFlag - " << mEventFlag !(efState & mDataMqNotEmptyEf)) { LOG(ERROR) << getEffectNameWithVersion() << __func__ << ": StatusEventFlag - " << mEventFlag << " efState - " << std::hex << efState; return; } Loading @@ -322,7 +328,8 @@ void EffectImpl::process() { { std::lock_guard lg(mImplMutex); if (mState != State::PROCESSING) { LOG(DEBUG) << getEffectName() << " skip process in state: " << toString(mState); LOG(DEBUG) << getEffectNameWithVersion() << " skip process in state: " << toString(mState); return; } RETURN_VALUE_IF(!mImplContext, void(), "nullContext"); Loading
audio/aidl/default/include/effect-impl/EffectImpl.h +10 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,11 @@ class EffectImpl : public BnEffect, public EffectThread { void process() override; protected: // current Hal version int mVersion = 0; // Use kEventFlagNotEmpty for V1 HAL, kEventFlagDataMqNotEmpty for V2 and above int mDataMqNotEmptyEf = aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty; State mState GUARDED_BY(mImplMutex) = State::INIT; IEffect::Status status(binder_status_t status, size_t consumed, size_t produced); Loading @@ -107,6 +112,11 @@ class EffectImpl : public BnEffect, public EffectThread { virtual ndk::ScopedAStatus commandImpl(CommandId id) REQUIRES(mImplMutex); RetCode notifyEventFlag(uint32_t flag); std::string getEffectNameWithVersion() { return getEffectName() + "V" + std::to_string(mVersion); } ::android::hardware::EventFlag* mEventFlag; }; } // namespace aidl::android::hardware::audio::effect
audio/aidl/vts/EffectHelper.h +9 −3 Original line number Diff line number Diff line Loading @@ -43,8 +43,10 @@ using namespace android; using aidl::android::hardware::audio::effect::CommandId; using aidl::android::hardware::audio::effect::Descriptor; using aidl::android::hardware::audio::effect::IEffect; using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty; using aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate; using aidl::android::hardware::audio::effect::kEventFlagNotEmpty; using aidl::android::hardware::audio::effect::kReopenSupportedVersion; using aidl::android::hardware::audio::effect::Parameter; using aidl::android::hardware::audio::effect::Range; using aidl::android::hardware::audio::effect::State; Loading Loading @@ -158,7 +160,7 @@ class EffectHelper { std::fill(buffer.begin(), buffer.end(), 0x5a); } static void writeToFmq(std::unique_ptr<StatusMQ>& statusMq, std::unique_ptr<DataMQ>& dataMq, const std::vector<float>& buffer) { const std::vector<float>& buffer, int version) { const size_t available = dataMq->availableToWrite(); ASSERT_NE(0Ul, available); auto bufferFloats = buffer.size(); Loading @@ -169,7 +171,8 @@ class EffectHelper { ASSERT_EQ(::android::OK, EventFlag::createEventFlag(statusMq->getEventFlagWord(), &efGroup)); ASSERT_NE(nullptr, efGroup); efGroup->wake(kEventFlagNotEmpty); efGroup->wake(version >= kReopenSupportedVersion ? kEventFlagDataMqNotEmpty : kEventFlagNotEmpty); ASSERT_EQ(::android::OK, EventFlag::deleteEventFlag(&efGroup)); } static void readFromFmq(std::unique_ptr<StatusMQ>& statusMq, size_t statusNum, Loading Loading @@ -320,7 +323,10 @@ class EffectHelper { ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING)); // Write from buffer to message queues and calling process EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer, [&]() { int version = 0; return (mEffect && mEffect->getInterfaceVersion(&version).isOk()) ? version : 0; }())); // Read the updated message queues into buffer EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 1, outputMQ, Loading
audio/aidl/vts/TestUtils.h +1 −1 Original line number Diff line number Diff line Loading @@ -108,7 +108,7 @@ inline ::testing::AssertionResult assertResultOrUnknownTransaction( ({ \ if ((flags).hwAcceleratorMode == \ aidl::android::hardware::audio::effect::Flags::HardwareAccelerator::TUNNEL || \ (flags).bypass) { \ (flags).bypass || (flags).offloadIndication) { \ GTEST_SKIP() << "Skip data path for offload"; \ } \ }) Loading
audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp +14 −13 Original line number Diff line number Diff line Loading @@ -42,7 +42,6 @@ using aidl::android::hardware::audio::effect::Descriptor; using aidl::android::hardware::audio::effect::Flags; using aidl::android::hardware::audio::effect::IEffect; using aidl::android::hardware::audio::effect::IFactory; using aidl::android::hardware::audio::effect::kReopenSupportedVersion; using aidl::android::hardware::audio::effect::Parameter; using aidl::android::hardware::audio::effect::State; using aidl::android::media::audio::common::AudioDeviceDescription; Loading @@ -58,6 +57,7 @@ class AudioEffectTest : public testing::TestWithParam<EffectTestParam>, public E public: AudioEffectTest() { std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam()); mVersion = EffectFactoryHelper::getHalVersion(mFactory); } void SetUp() override {} Loading @@ -76,6 +76,7 @@ class AudioEffectTest : public testing::TestWithParam<EffectTestParam>, public E std::shared_ptr<IFactory> mFactory; std::shared_ptr<IEffect> mEffect; Descriptor mDescriptor; int mVersion = 0; void setAndGetParameter(Parameter::Id id, const Parameter& set) { Parameter get; Loading Loading @@ -682,7 +683,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataInProcessingState) { std::vector<float> buffer; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); Loading Loading @@ -722,7 +723,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataAfterRestart) { ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING)); EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); Loading Loading @@ -759,7 +760,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataAfterReopen) { ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START)); ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING)); EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); Loading @@ -779,7 +780,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataAfterReopen) { // verify data consume again EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); Loading Loading @@ -810,7 +811,7 @@ TEST_P(AudioEffectDataPathTest, SendDataAtIdleAndConsumeDataInProcessing) { std::vector<float> buffer; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START)); ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING)); Loading Loading @@ -844,7 +845,7 @@ TEST_P(AudioEffectDataPathTest, ProcessDataMultipleTimes) { std::vector<float> buffer; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer)); ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START)); Loading @@ -853,7 +854,7 @@ TEST_P(AudioEffectDataPathTest, ProcessDataMultipleTimes) { EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); Loading Loading @@ -886,13 +887,13 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataAndRestart) { ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING)); std::vector<float> buffer; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer)); ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP)); ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer)); ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START)); Loading Loading @@ -928,7 +929,7 @@ TEST_P(AudioEffectDataPathTest, NotConsumeDataByClosedEffect) { std::vector<float> buffer; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer, mVersion)); EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer)); ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect)); Loading Loading @@ -964,7 +965,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataMultipleEffects) { std::vector<float> buffer1, buffer2; EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common1, inputMQ1, buffer1)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1)); Loading @@ -975,7 +976,7 @@ TEST_P(AudioEffectDataPathTest, ConsumeDataMultipleEffects) { auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ); ASSERT_TRUE(outputMQ2->isValid()); EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common2, inputMQ2, buffer2)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2)); EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2, mVersion)); EXPECT_NO_FATAL_FAILURE( EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2)); Loading