From 04e91ea4cc239c5ab98e0a2c3ff095dea4b541d2 Mon Sep 17 00:00:00 2001 From: Maninblack <1215156554@qq.com> Date: Fri, 12 Sep 2025 10:01:26 +0800 Subject: [PATCH] fix crash when enhance chain is applied and released concurrently Signed-off-by: Maninblack <1215156554@qq.com> --- .../audioeffect/include/audio_enhance_chain.h | 3 ++- .../audioeffect/src/audio_enhance_chain.cpp | 18 +++++++++++++++--- .../src/audio_enhance_chain_manager_impl.cpp | 4 ++++ .../src/audio_enhance_chain_unit_test.cpp | 9 +++++++++ .../domain/pipe/src/audio_ec_manager.cpp | 1 + .../infra/ipc_proxy/src/audio_server_proxy.cpp | 3 +-- 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/frameworks/native/audioeffect/include/audio_enhance_chain.h b/frameworks/native/audioeffect/include/audio_enhance_chain.h index 074571e776..a5c92f2c2b 100644 --- a/frameworks/native/audioeffect/include/audio_enhance_chain.h +++ b/frameworks/native/audioeffect/include/audio_enhance_chain.h @@ -77,6 +77,7 @@ public: void GetAlgoConfig(AudioBufferConfig &micConfig, AudioBufferConfig &ecConfig, AudioBufferConfig &micRefConfig); uint64_t GetChainId(void) const; ScenePriority GetScenePriority(void) const; + void ReleaseAllEnhanceModule(void); int32_t CreateAllEnhanceModule(const std::vector &moduleParas); int32_t SetEnhanceProperty(const std::string &effect, const std::string &property); int32_t SetEnhanceParam(bool mute, uint32_t systemVol); @@ -89,7 +90,6 @@ public: private: void InitAudioEnhanceChain(); - void ReleaseAllEnhanceModule(); int32_t DeinterleaverData(uint8_t *src, uint32_t channel, uint8_t *dst, uint32_t offset); int32_t SetPropertyToHandle(AudioEffectHandle handle, const std::string &property); int32_t SetEnhanceParamToHandle(AudioEffectHandle handle); @@ -101,6 +101,7 @@ private: int32_t ProcessSetInputDevice(const std::string &inputDevice, const std::string &deviceName); int32_t ProcessSetEnhanceProperty(const std::string &enhance, const std::string &property); int32_t ProcessApplyEnhanceChain(void); + int32_t ProcessReleaseAllEnhanceModule(void); int32_t WriteChainOutputData(void *buf, size_t bufSize); int32_t CacheChainInputData(const EnhanceTransBuffer &transBuf); int32_t InitSingleEnhanceModule(AudioEffectHandle enhanceHandle, const std::string &enhanceProp); diff --git a/frameworks/native/audioeffect/src/audio_enhance_chain.cpp b/frameworks/native/audioeffect/src/audio_enhance_chain.cpp index d9ff0d54b9..0602bd8bd5 100644 --- a/frameworks/native/audioeffect/src/audio_enhance_chain.cpp +++ b/frameworks/native/audioeffect/src/audio_enhance_chain.cpp @@ -136,13 +136,11 @@ void AudioEnhanceChain::InitAudioEnhanceChain() AudioEnhanceChain::~AudioEnhanceChain() { - threadHandler_ = nullptr; - ReleaseAllEnhanceModule(); DumpFileUtil::CloseDumpFile(&dumpFileIn_); DumpFileUtil::CloseDumpFile(&dumpFileOut_); } -void AudioEnhanceChain::ReleaseAllEnhanceModule() +int32_t AudioEnhanceChain::ProcessReleaseAllEnhanceModule(void) { for (auto &module : enhanceModules_) { if (module.libHandle != nullptr) { @@ -150,6 +148,20 @@ void AudioEnhanceChain::ReleaseAllEnhanceModule() } } enhanceModules_.clear(); + return SUCCESS; +} + +void AudioEnhanceChain::ReleaseAllEnhanceModule(void) +{ + auto task = [self = weak_from_this()]() { + if (auto chain = self.lock(); chain != nullptr) { + chain->ProcessReleaseAllEnhanceModule(); + } + }; + if (threadHandler_ != nullptr) { + threadHandler_->EnsureTask(task); + } + threadHandler_ = nullptr; } int32_t AudioEnhanceChain::SetThreadHandler(const std::shared_ptr &threadHandler) diff --git a/frameworks/native/audioeffect/src/audio_enhance_chain_manager_impl.cpp b/frameworks/native/audioeffect/src/audio_enhance_chain_manager_impl.cpp index d66ef73e4c..7c84e45514 100644 --- a/frameworks/native/audioeffect/src/audio_enhance_chain_manager_impl.cpp +++ b/frameworks/native/audioeffect/src/audio_enhance_chain_manager_impl.cpp @@ -408,6 +408,10 @@ int32_t AudioEnhanceChainManagerImpl::ReleaseAudioEnhanceChainDynamic(uint64_t s { std::lock_guard lock(chainManagerMutex_); + auto chain = ChainPool::GetInstance().GetChainById(sceneKeyCode); + if (chain != nullptr) { + chain->ReleaseAllEnhanceModule(); + } AUDIO_INFO_LOG("release chain: %{public}" PRIu64, sceneKeyCode); ChainPool::GetInstance().DeleteChain(sceneKeyCode); diff --git a/frameworks/native/audioeffect/test/unittest/enhance_unit_test/src/audio_enhance_chain_unit_test.cpp b/frameworks/native/audioeffect/test/unittest/enhance_unit_test/src/audio_enhance_chain_unit_test.cpp index 960a6815c0..9233e6aca1 100644 --- a/frameworks/native/audioeffect/test/unittest/enhance_unit_test/src/audio_enhance_chain_unit_test.cpp +++ b/frameworks/native/audioeffect/test/unittest/enhance_unit_test/src/audio_enhance_chain_unit_test.cpp @@ -177,6 +177,7 @@ HWTEST(AudioEnhanceChainUnitTest, CreateAllEnhanceModuleFailWithCmdFail, TestSiz SetCommandRet(cmd, SUCCESS); } ClearCommandRetMap(); + chain->ReleaseAllEnhanceModule(); } HWTEST(AudioEnhanceChainUnitTest, CreateAllEnhanceModuleSucc, TestSize.Level1) @@ -190,6 +191,7 @@ HWTEST(AudioEnhanceChainUnitTest, CreateAllEnhanceModuleSucc, TestSize.Level1) moduleParas.emplace_back(para); EXPECT_EQ(chain->CreateAllEnhanceModule(moduleParas), 0); EXPECT_EQ(chain->IsEmptyEnhanceHandles(), false); + chain->ReleaseAllEnhanceModule(); } HWTEST(AudioEnhanceChainUnitTest, SetThreadHandler_Fail, TestSize.Level1) @@ -208,6 +210,7 @@ HWTEST(AudioEnhanceChainUnitTest, InitCommandSucc, TestSize.Level1) AudioEffectLibrary lib = { 0, "name", "implementor", CheckEffectTest, CreateEffectTestSucc, ReleaseEffectTest }; CreateModuleForChain(chain, &lib); EXPECT_EQ(chain->InitCommand(), 0); + chain->ReleaseAllEnhanceModule(); } HWTEST(AudioEnhanceChainUnitTest, SetEnhancePropertySucc, TestSize.Level1) @@ -222,6 +225,7 @@ HWTEST(AudioEnhanceChainUnitTest, SetEnhancePropertySucc, TestSize.Level1) AudioEffectLibrary lib = { 0, "name", "implementor", CheckEffectTest, CreateEffectTestSucc, ReleaseEffectTest }; CreateModuleForChain(chain, &lib); EXPECT_EQ(chain->SetEnhanceProperty(enhance, property), SUCCESS); + chain->ReleaseAllEnhanceModule(); } HWTEST(AudioEnhanceChainUnitTest, SetEmptyInputDevice, TestSize.Level1) @@ -259,6 +263,7 @@ HWTEST(AudioEnhanceChainUnitTest, UpdateInputDeviceSucc, TestSize.Level1) std::string newDevice = "newDevice"; std::string newDeviceName = "newDeviceName"; EXPECT_EQ(chain->SetInputDevice(inputDevice, deviceName), SUCCESS); + chain->ReleaseAllEnhanceModule(); } HWTEST(AudioEnhanceChainUnitTest, SetFoldStateSucc, TestSize.Level1) @@ -282,6 +287,7 @@ HWTEST(AudioEnhanceChainUnitTest, UpdateFoldStateSucc, TestSize.Level1) EXPECT_EQ(chain->SetFoldState(state), SUCCESS); const uint32_t newState = 3; EXPECT_EQ(chain->SetFoldState(newState), SUCCESS); + chain->ReleaseAllEnhanceModule(); } HWTEST(AudioEnhanceChainUnitTest, SetEnhanceParamSucc, TestSize.Level1) @@ -295,6 +301,7 @@ HWTEST(AudioEnhanceChainUnitTest, SetEnhanceParamSucc, TestSize.Level1) const uint32_t systemVol = 10; EXPECT_EQ(chain->SetEnhanceParam(false, systemVol), SUCCESS); EXPECT_EQ(chain->SetEnhanceParam(true, systemVol), SUCCESS); + chain->ReleaseAllEnhanceModule(); } HWTEST(AudioEnhanceChainUnitTest, GetAlgoConfigSucc, TestSize.Level1) @@ -363,6 +370,7 @@ HWTEST(AudioEnhanceChainUnitTest, ApplyEmptyEnhanceChain, TestSize.Level1) std::vector output(micDataLen); EXPECT_EQ(chain->GetOutputDataFromChain(output.data(), output.size() * sizeof(int16_t)), SUCCESS); EXPECT_THAT(output, ElementsAreArray(micInput)); + chain->ReleaseAllEnhanceModule(); } HWTEST(AudioEnhanceChainUnitTest, ApplyEnhanceChainSucc, TestSize.Level1) @@ -393,6 +401,7 @@ HWTEST(AudioEnhanceChainUnitTest, ApplyEnhanceChainSucc, TestSize.Level1) std::vector output(dataLen); EXPECT_EQ(chain->GetOutputDataFromChain(output.data(), output.size() * sizeof(int16_t)), SUCCESS); EXPECT_THAT(output, ElementsAreArray(targetOut)); + chain->ReleaseAllEnhanceModule(); } } // AudioStandard } // OHOS diff --git a/services/audio_policy/server/domain/pipe/src/audio_ec_manager.cpp b/services/audio_policy/server/domain/pipe/src/audio_ec_manager.cpp index 8cbebe00a8..c96d20bbef 100644 --- a/services/audio_policy/server/domain/pipe/src/audio_ec_manager.cpp +++ b/services/audio_policy/server/domain/pipe/src/audio_ec_manager.cpp @@ -258,6 +258,7 @@ void AudioEcManager::UpdateStreamCommonInfo(AudioModuleInfo &moduleInfo, PipeStr if (inputDesc != nullptr && inputDesc->deviceType_ == DEVICE_TYPE_USB_ARM_HEADSET) { moduleInfo = usbSourceModuleInfo_; moduleInfo.sourceType = std::to_string(sourceType); + moduleInfo.deviceType = std::to_string(static_cast(DEVICE_TYPE_USB_ARM_HEADSET)); } else { moduleInfo = primaryMicModuleInfo_; // current layout represents the number of channel. This will need to be modify in the future. diff --git a/services/audio_policy/server/infra/ipc_proxy/src/audio_server_proxy.cpp b/services/audio_policy/server/infra/ipc_proxy/src/audio_server_proxy.cpp index 43dbdb9213..36a041e81e 100644 --- a/services/audio_policy/server/infra/ipc_proxy/src/audio_server_proxy.cpp +++ b/services/audio_policy/server/infra/ipc_proxy/src/audio_server_proxy.cpp @@ -466,8 +466,7 @@ int32_t AudioServerProxy::SetAudioEffectPropertyProxy(const AudioEffectPropertyA const sptr gsp = GetAudioServerProxy(); CHECK_AND_RETURN_RET_LOG(gsp != nullptr, ERR_INVALID_HANDLE, "Service proxy unavailable"); std::string identity = IPCSkeleton::ResetCallingIdentity(); - (void) deviceType; - int32_t ret = gsp->SetAudioEffectProperty(propertyArray, DeviceType::DEVICE_TYPE_NONE); + int32_t ret = gsp->SetAudioEffectProperty(propertyArray, deviceType); IPCSkeleton::SetCallingIdentity(identity); return ret; } -- Gitee