From cb8a236d610dfa67b95557e66976b0681a8b4336 Mon Sep 17 00:00:00 2001 From: hwwuhaobo Date: Sat, 18 Nov 2023 21:12:53 +0800 Subject: [PATCH] modify source manager dead-lock Signed-off-by: hwwuhaobo --- audiohandler/src/daudio_handler.cpp | 4 +- common/include/daudio_constants.h | 2 + .../managersink/src/daudio_sink_dev.cpp | 6 +- .../managersource/include/daudio_source_dev.h | 1 + .../include/daudio_source_manager.h | 22 +++ .../managersource/src/daudio_source_dev.cpp | 22 ++- .../src/daudio_source_manager.cpp | 145 +++++++++++++++++- 7 files changed, 186 insertions(+), 16 deletions(-) diff --git a/audiohandler/src/daudio_handler.cpp b/audiohandler/src/daudio_handler.cpp index 1091b37d..f8ed4866 100644 --- a/audiohandler/src/daudio_handler.cpp +++ b/audiohandler/src/daudio_handler.cpp @@ -101,12 +101,12 @@ std::vector DAudioHandler::Query() std::string audioEncoders = HiStreamerQueryTool::GetInstance().QueryHiStreamerPluginInfo(HISTREAM_PLUGIN_TYPE::AUDIO_ENCODER); - DHLOGI("DScreen QueryAudioEncoderAbility info: %s", audioEncoders.c_str()); + DHLOGI("DAudio QueryAudioEncoderAbility info: %s", audioEncoders.c_str()); infoJson[KEY_HISTREAMER_AUDIO_ENCODER] = audioEncoders; std::string audioDecoders = HiStreamerQueryTool::GetInstance().QueryHiStreamerPluginInfo(HISTREAM_PLUGIN_TYPE::AUDIO_DECODER); - DHLOGI("DScreen QueryAudioDecoderAbility info: %s", audioDecoders.c_str()); + DHLOGI("DAudio QueryAudioDecoderAbility info: %s", audioDecoders.c_str()); infoJson[KEY_HISTREAMER_AUDIO_DECODER] = audioDecoders; dhItem.dhId = std::to_string(dhId); diff --git a/common/include/daudio_constants.h b/common/include/daudio_constants.h index a3346295..6034fc0b 100644 --- a/common/include/daudio_constants.h +++ b/common/include/daudio_constants.h @@ -114,6 +114,8 @@ constexpr const char *KEY_CHANGE_TYPE = "ChangeType"; constexpr const char *KEY_EVENT_CONTENT = "content"; constexpr const char *KEY_DH_ID = "dhId"; constexpr const char *KEY_DEV_ID = "devId"; +constexpr const char *KEY_VERSION = "version"; +constexpr const char *KEY_REQID = "reqId"; constexpr const char *KEY_RESULT = "result"; constexpr const char *KEY_EVENT_TYPE = "eventType"; constexpr const char *KEY_AUDIO_PARAM = "audioParam"; diff --git a/services/audiomanager/managersink/src/daudio_sink_dev.cpp b/services/audiomanager/managersink/src/daudio_sink_dev.cpp index e207e541..94433e1a 100644 --- a/services/audiomanager/managersink/src/daudio_sink_dev.cpp +++ b/services/audiomanager/managersink/src/daudio_sink_dev.cpp @@ -60,10 +60,10 @@ void DAudioSinkDev::SleepAudioDev() return; } while (!handler_->IsIdle()) { - DHLOGI("handler is running, wait for idle."); + DHLOGD("handler is running, wait for idle."); usleep(WAIT_HANDLER_IDLE_TIME_US); } - DHLOGD("Sleep audio dev over."); + DHLOGI("Sleep audio dev over."); } int32_t DAudioSinkDev::InitAVTransEngines(const ChannelState channelState, IAVEngineProvider *providerPtr) @@ -577,7 +577,7 @@ void DAudioSinkDev::SinkEventHandler::ProcessEvent(const AppExecFwk::InnerEvent: { auto iter = mapEventFuncs_.find(event->GetInnerEventId()); if (iter == mapEventFuncs_.end()) { - DHLOGE("Event Id is invaild.", event->GetInnerEventId()); + DHLOGE("Event Id is invaild. %d", event->GetInnerEventId()); return; } SinkEventFunc &func = iter->second; diff --git a/services/audiomanager/managersource/include/daudio_source_dev.h b/services/audiomanager/managersource/include/daudio_source_dev.h index e84aaf3e..05e70d5c 100644 --- a/services/audiomanager/managersource/include/daudio_source_dev.h +++ b/services/audiomanager/managersource/include/daudio_source_dev.h @@ -122,6 +122,7 @@ private: static constexpr uint8_t EVENT_NOTIFY_CLOSE_MIC = 0x08; static constexpr uint8_t EVENT_NOTIFY_OPEN_CTRL = 0x10; static constexpr uint8_t EVENT_NOTIFY_CLOSE_CTRL = 0x20; + static constexpr size_t WAIT_HANDLER_IDLE_TIME_US = 10000; std::string devId_; std::shared_ptr mgrCallback_; diff --git a/services/audiomanager/managersource/include/daudio_source_manager.h b/services/audiomanager/managersource/include/daudio_source_manager.h index b58ccde4..e11e8ae5 100644 --- a/services/audiomanager/managersource/include/daudio_source_manager.h +++ b/services/audiomanager/managersource/include/daudio_source_manager.h @@ -20,6 +20,8 @@ #include #include +#include "event_handler.h" + #include "daudio_hdi_handler.h" #include "daudio_source_dev.h" #include "daudio_source_mgr_callback.h" @@ -59,6 +61,8 @@ private: void ClearAudioDev(const std::string &devId); void ListenAudioDev(); void RestoreThreadStatus(); + int32_t DoEnableDAudio(const std::string &args); + int32_t DoDisableDAudio(const std::string &args); typedef struct { std::string devId; @@ -72,6 +76,7 @@ private: static constexpr int32_t WATCHDOG_INTERVAL_TIME = 20000; static constexpr int32_t WATCHDOG_DELAY_TIME = 5000; static constexpr size_t SLEEP_TIME = 1000000; + static constexpr size_t WAIT_HANDLER_IDLE_TIME_US = 10000; std::string localDevId_; std::mutex devMapMtx_; @@ -87,6 +92,23 @@ private: void *pSHandler_ = nullptr; void *pRHandler_ = nullptr; std::atomic isHicollieRunning_ = false; + + class SourceManagerHandler : public AppExecFwk::EventHandler { + public: + SourceManagerHandler(const std::shared_ptr &runner); + ~SourceManagerHandler() override; + void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; + + private: + void EnableDAudioCallback(const AppExecFwk::InnerEvent::Pointer &event); + void DisableDAudioCallback(const AppExecFwk::InnerEvent::Pointer &event); + int32_t GetEventParam(const AppExecFwk::InnerEvent::Pointer &event, std::string &eventParam); + + private: + using SourceManagerFunc = void (SourceManagerHandler::*)(const AppExecFwk::InnerEvent::Pointer &event); + std::map mapEventFuncs_; + }; + std::shared_ptr handler_; }; } // DistributedHardware } // OHOS diff --git a/services/audiomanager/managersource/src/daudio_source_dev.cpp b/services/audiomanager/managersource/src/daudio_source_dev.cpp index 44463380..645355ce 100644 --- a/services/audiomanager/managersource/src/daudio_source_dev.cpp +++ b/services/audiomanager/managersource/src/daudio_source_dev.cpp @@ -100,8 +100,16 @@ int32_t DAudioSourceDev::AwakeAudioDev() void DAudioSourceDev::SleepAudioDev() { - handler_ = nullptr; - DHLOGD("Sleep audio dev over."); + DHLOGD("Sleep audio dev."); + if (handler_ == nullptr) { + DHLOGI("Event handler is already stopped."); + return; + } + while (!handler_->IsIdle()) { + DHLOGD("handler is running, wait for idle."); + usleep(WAIT_HANDLER_IDLE_TIME_US); + } + DHLOGI("Sleep audio dev over."); } int32_t DAudioSourceDev::EnableDAudio(const std::string &dhId, const std::string &attrs) @@ -119,7 +127,7 @@ int32_t DAudioSourceDev::EnableDAudio(const std::string &dhId, const std::string DHLOGE("Send event failed."); return ERR_DH_AUDIO_FAILED; } - DHLOGD("Enable audio task generate successfully."); + DHLOGI("Enable audio task generate successfully."); return DH_SUCCESS; } @@ -160,7 +168,7 @@ int32_t DAudioSourceDev::DisableDAudio(const std::string &dhId) DHLOGE("Send event failed."); return ERR_DH_AUDIO_FAILED; } - DHLOGD("Disable audio task generate successfully."); + DHLOGI("Disable audio task generate successfully."); return DH_SUCCESS; } @@ -308,7 +316,7 @@ int32_t DAudioSourceDev::HandleCloseDMic(const AudioEvent &event) DHLOGE("Send event failed."); return ERR_DH_AUDIO_FAILED; } - DHLOGD("Closing DSpeaker event is sent successfully."); + DHLOGD("Closing DMic event is sent successfully."); return DH_SUCCESS; } @@ -1296,7 +1304,7 @@ void DAudioSourceDev::SourceEventHandler::ProcessEvent(const AppExecFwk::InnerEv { auto iter = mapEventFuncs_.find(event->GetInnerEventId()); if (iter == mapEventFuncs_.end()) { - DHLOGE("Event Id is invaild.", event->GetInnerEventId()); + DHLOGE("Event Id is invaild. %d", event->GetInnerEventId()); return; } SourceEventFunc &func = iter->second; @@ -1323,7 +1331,6 @@ void DAudioSourceDev::SourceEventHandler::EnableDAudioCallback(const AppExecFwk: if (ret != DH_SUCCESS) { DHLOGE("Open ctrl channel failed."); } - sourceDevObj->OnEnableTaskResult(ret, jParam->dump(), ""); } void DAudioSourceDev::SourceEventHandler::DisableDAudioCallback(const AppExecFwk::InnerEvent::Pointer &event) @@ -1346,7 +1353,6 @@ void DAudioSourceDev::SourceEventHandler::DisableDAudioCallback(const AppExecFwk if (ret != DH_SUCCESS) { DHLOGE("Disable distributed audio failed."); } - sourceDevObj->OnDisableTaskResult(ret, jParam->dump(), ""); } void DAudioSourceDev::SourceEventHandler::OpenDSpeakerCallback(const AppExecFwk::InnerEvent::Pointer &event) diff --git a/services/audiomanager/managersource/src/daudio_source_manager.cpp b/services/audiomanager/managersource/src/daudio_source_manager.cpp index ee8d82b7..1ab7ac89 100644 --- a/services/audiomanager/managersource/src/daudio_source_manager.cpp +++ b/services/audiomanager/managersource/src/daudio_source_manager.cpp @@ -33,6 +33,8 @@ namespace DistributedHardware { namespace { constexpr uint32_t MAX_DEVICE_ID_LENGTH = 200; constexpr uint32_t MAX_DISTRIBUTED_HARDWARE_ID_LENGTH = 100; +constexpr uint32_t EVENT_MANAGER_ENABLE_DAUDIO = 11; +constexpr uint32_t EVENT_MANAGER_DISABLE_DAUDIO = 12; } IMPLEMENT_SINGLE_INSTANCE(DAudioSourceManager); using AVTransProviderClass = IAVEngineProvider *(*)(const std::string &); @@ -98,6 +100,14 @@ int32_t DAudioSourceManager::Init(const sptr &callback) if (pthread_setname_np(listenThread_.native_handle(), LISTEN_THREAD) != DH_SUCCESS) { DHLOGE("Dev clear thread setname failed."); } + // init event handler + auto runner = AppExecFwk::EventRunner::Create(true); + if (runner == nullptr) { + DHLOGE("Create runner failed."); + return ERR_DH_AUDIO_NULLPTR; + } + handler_ = std::make_shared(runner); + DHLOGI("Init DAudioManager successfuly."); return DH_SUCCESS; } @@ -115,6 +125,7 @@ int32_t DAudioSourceManager::UnInit() iter->second.dev->SleepAudioDev(); } audioDevMap_.clear(); + DHLOGI("Audio dev map cleared."); } if (devClearThread_.joinable()) { devClearThread_.join(); @@ -131,6 +142,16 @@ int32_t DAudioSourceManager::UnInit() DHLOGE("Uninit Hdi handler failed."); return ERR_DH_AUDIO_FAILED; } + // uninit event handler + if (handler_ == nullptr) { + DHLOGI("Uninit audio source manager exit. handler is null"); + return DH_SUCCESS; + } + while (!handler_->IsIdle()) { + DHLOGD("manager handler is running, wait for idle."); + usleep(WAIT_HANDLER_IDLE_TIME_US); + } + DHLOGI("Uninit audio source manager exit."); return DH_SUCCESS; } @@ -149,6 +170,31 @@ int32_t DAudioSourceManager::EnableDAudio(const std::string &devId, const std::s { DHLOGI("Enable distributed audio, devId: %s, dhId: %s, version: %s, reqId: %s.", GetAnonyString(devId).c_str(), dhId.c_str(), version.c_str(), reqId.c_str()); + if (handler_ == nullptr) { + DHLOGE("Event handler is null."); + return ERR_DH_AUDIO_NULLPTR; + } + json jParam = { { KEY_DEV_ID, devId }, { KEY_DH_ID, dhId }, { KEY_VERSION, version }, + { KEY_ATTRS, attrs }, { KEY_REQID, reqId } }; + auto eventParam = std::make_shared(jParam); + auto msgEvent = AppExecFwk::InnerEvent::Get(EVENT_MANAGER_ENABLE_DAUDIO, eventParam, 0); + if (!handler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) { + DHLOGE("Send event failed."); + return ERR_DH_AUDIO_FAILED; + } + DHLOGI("Enable audio task generate successfully."); + return DH_SUCCESS; +} + +int32_t DAudioSourceManager::DoEnableDAudio(const std::string &args) +{ + std::string devId = ParseStringFromArgs(args, KEY_DEV_ID); + std::string dhId = ParseStringFromArgs(args, KEY_DH_ID); + std::string version = ParseStringFromArgs(args, KEY_VERSION); + std::string attrs = ParseStringFromArgs(args, KEY_ATTRS); + std::string reqId = ParseStringFromArgs(args, KEY_REQID); + DHLOGI("Do Enable distributed audio, devId: %s, dhId: %s, version:%s, reqId:%s.", + GetAnonyString(devId).c_str(), dhId.c_str(), version.c_str(), reqId.c_str()); if (!CheckParams(devId, dhId) || attrs.empty()) { DHLOGE("Enable params are incorrect."); return ERR_DH_AUDIO_FAILED; @@ -161,13 +207,37 @@ int32_t DAudioSourceManager::EnableDAudio(const std::string &devId, const std::s } } audioDevMap_[devId].ports[dhId] = reqId; - return audioDevMap_[devId].dev->EnableDAudio(dhId, attrs); + DHLOGI("Call source dev to enable daudio."); + int32_t result = audioDevMap_[devId].dev->EnableDAudio(dhId, attrs); + return OnEnableDAudio(devId, dhId, result); } int32_t DAudioSourceManager::DisableDAudio(const std::string &devId, const std::string &dhId, const std::string &reqId) { DHLOGI("Disable distributed audio, devId: %s, dhId: %s, reqId: %s.", GetAnonyString(devId).c_str(), dhId.c_str(), reqId.c_str()); + if (handler_ == nullptr) { + DHLOGE("Event handler is null."); + return ERR_DH_AUDIO_NULLPTR; + } + json jParam = { { KEY_DEV_ID, devId }, { KEY_DH_ID, dhId }, { KEY_REQID, reqId } }; + auto eventParam = std::make_shared(jParam); + auto msgEvent = AppExecFwk::InnerEvent::Get(EVENT_MANAGER_DISABLE_DAUDIO, eventParam, 0); + if (!handler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) { + DHLOGE("Send event failed."); + return ERR_DH_AUDIO_FAILED; + } + DHLOGI("Disable audio task generate successfully."); + return DH_SUCCESS; +} + +int32_t DAudioSourceManager::DoDisableDAudio(const std::string &args) +{ + std::string devId = ParseStringFromArgs(args, KEY_DEV_ID); + std::string dhId = ParseStringFromArgs(args, KEY_DH_ID); + std::string reqId = ParseStringFromArgs(args, KEY_REQID); + DHLOGI("Do Enable distributed audio, devId: %s, dhId: %s, reqId:%s.", + GetAnonyString(devId).c_str(), dhId.c_str(), reqId.c_str()); if (!CheckParams(devId, dhId)) { DHLOGE("Enable params are incorrect."); return ERR_DH_AUDIO_FAILED; @@ -183,7 +253,9 @@ int32_t DAudioSourceManager::DisableDAudio(const std::string &devId, const std:: return DH_SUCCESS; } audioDevMap_[devId].ports[dhId] = reqId; - return audioDevMap_[devId].dev->DisableDAudio(dhId); + DHLOGI("Call source dev to enable daudio."); + int32_t result = audioDevMap_[devId].dev->DisableDAudio(dhId); + return OnDisableDAudio(devId, dhId, result); } int32_t DAudioSourceManager::HandleDAudioNotify(const std::string &devId, const std::string &dhId, @@ -341,7 +413,7 @@ std::string DAudioSourceManager::GetRequestId(const std::string &devId, const st void DAudioSourceManager::ClearAudioDev(const std::string &devId) { - DHLOGI("ClearAudioDev, devId = %s.", devId.c_str()); + DHLOGI("ClearAudioDev, devId = %s.", GetAnonyString(devId).c_str()); std::lock_guard lock(devMapMtx_); if (audioDevMap_[devId].ports.empty()) { DHLOGI("audioDevMap_[devId].ports is empty."); @@ -473,5 +545,72 @@ IAVEngineProvider *DAudioSourceManager::getReceiverProvider() { return rcvProviderPtr_; } + +DAudioSourceManager::SourceManagerHandler::SourceManagerHandler(const std::shared_ptr + &runner) : AppExecFwk::EventHandler(runner) +{ + DHLOGD("Event handler is constructing."); + mapEventFuncs_[EVENT_MANAGER_ENABLE_DAUDIO] = &DAudioSourceManager::SourceManagerHandler::EnableDAudioCallback; + mapEventFuncs_[EVENT_MANAGER_DISABLE_DAUDIO] = &DAudioSourceManager::SourceManagerHandler::DisableDAudioCallback; +} + +DAudioSourceManager::SourceManagerHandler::~SourceManagerHandler() {} + +void DAudioSourceManager::SourceManagerHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) +{ + auto iter = mapEventFuncs_.find(event->GetInnerEventId()); + if (iter == mapEventFuncs_.end()) { + DHLOGE("Event Id is invalid. %d.", event->GetInnerEventId()); + return; + } + SourceManagerFunc &func = iter->second; + (this->*func)(event); +} + +void DAudioSourceManager::SourceManagerHandler::EnableDAudioCallback(const AppExecFwk::InnerEvent::Pointer &event) +{ + if (event == nullptr) { + DHLOGE("The input event is null."); + return; + } + std::string eventParam; + if (GetEventParam(event, eventParam) != DH_SUCCESS) { + DHLOGE("Failed to get event parameters."); + return; + } + DHLOGI("Enable audio device, param:%s.", eventParam.c_str()); + DAudioSourceManager::GetInstance().DoEnableDAudio(eventParam); +} + +void DAudioSourceManager::SourceManagerHandler::DisableDAudioCallback(const AppExecFwk::InnerEvent::Pointer &event) +{ + if (event == nullptr) { + DHLOGE("The input event is null."); + return; + } + std::string eventParam; + if (GetEventParam(event, eventParam) != DH_SUCCESS) { + DHLOGE("Failed to get event parameters."); + return; + } + DHLOGI("Disable audio device, param:%s.", eventParam.c_str()); + DAudioSourceManager::GetInstance().DoDisableDAudio(eventParam); +} + +int32_t DAudioSourceManager::SourceManagerHandler::GetEventParam(const AppExecFwk::InnerEvent::Pointer &event, + std::string &eventParam) +{ + if (event == nullptr) { + DHLOGE("The input event id null."); + return ERR_DH_AUDIO_NULLPTR; + } + std::shared_ptr paramObj = event->GetSharedObject(); + if (paramObj == nullptr) { + DHLOGE("The event parameter object is nullptr."); + return ERR_DH_AUDIO_NULLPTR; + } + eventParam = paramObj->dump(); + return DH_SUCCESS; +} } // DistributedHardware } // OHOS -- Gitee