diff --git a/common/include/daudio_constants.h b/common/include/daudio_constants.h index 48f1de952d3f63768d19849e5488629f6f46a524..77ede3fe1d9d2d6a764711c93dc4567ccbd6ce6d 100644 --- a/common/include/daudio_constants.h +++ b/common/include/daudio_constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -89,9 +89,6 @@ const std::string NAME = "name"; const std::string KEY_CODECTYPE = "codecType"; const std::string KEY_DEVICE_TYPE = "deviceType"; -const std::string KEY_HISTREAMER_AUDIO_ENCODER = "histmAudEnc"; -const std::string KEY_HISTREAMER_AUDIO_DECODER = "histmAudDec"; - const std::string HDF_EVENT_RESULT_SUCCESS = "DH_SUCCESS"; const std::string HDF_EVENT_INIT_ENGINE_FAILED = "ERR_DH_AUDIO_INIT_ENGINE_FAILED"; const std::string HDF_EVENT_NOTIFY_SINK_FAILED = "ERR_DH_AUDIO_NOTIFY_SINK_FAILED"; diff --git a/services/audiohdiproxy/include/daudio_hdi_handler.h b/services/audiohdiproxy/include/daudio_hdi_handler.h index a0b8ddfb4f708574992deac39281fa1a1fefdc02..8221af2dffb87eb5ea3c5e6036457732ad0bd3f8 100644 --- a/services/audiohdiproxy/include/daudio_hdi_handler.h +++ b/services/audiohdiproxy/include/daudio_hdi_handler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -26,6 +26,7 @@ #include "audio_event.h" #include "daudio_manager_callback.h" +#include "distributed_hardware_fwk_kit.h" #include "idaudio_hdi_callback.h" #include "single_instance.h" @@ -54,6 +55,7 @@ private: DAudioHdiHandler(); ~DAudioHdiHandler(); void ProcessEventMsg(const AudioEvent &audioEvent, DAudioEvent &newEvent); + std::shared_ptr GetDHFwkKit(); class AudioHdiRecipient : public IRemoteObject::DeathRecipient { public: @@ -67,6 +69,8 @@ private: std::map> mapAudioMgrCallback_; std::map> mapAudioMgrDhIds_; sptr remote_; + std::shared_ptr dHFwkKit_; + std::mutex dHFwkKitMutex_; }; } // DistributedHardware } // OHOS diff --git a/services/audiohdiproxy/src/daudio_hdi_handler.cpp b/services/audiohdiproxy/src/daudio_hdi_handler.cpp index 74e87a7520f230a151d97768716c6876e0c660c2..8dfe00df6b6f7055d4b24cd83dacbf8ada3049a9 100644 --- a/services/audiohdiproxy/src/daudio_hdi_handler.cpp +++ b/services/audiohdiproxy/src/daudio_hdi_handler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -24,7 +24,6 @@ #include "daudio_constants.h" #include "daudio_errorcode.h" -#include "daudio_hdf_operate.h" #include "daudio_hdi_handler.h" #include "daudio_hitrace.h" #include "daudio_log.h" @@ -57,7 +56,12 @@ int32_t DAudioHdiHandler::InitHdiHandler() } DHLOGD("Load hdf driver start."); - int32_t ret = DaudioHdfOperate::GetInstance().LoadDaudioHDFImpl(); + auto dHFwkKit = GetDHFwkKit(); + if (dHFwkKit == nullptr) { + DHLOGE("Get dHFwkKit is null when load hdf driver."); + return ERR_DH_AUDIO_NULLPTR; + } + int32_t ret = dHFwkKit->LoadDistributedHDF(DHType::AUDIO); DaudioRadar::GetInstance().ReportDaudioInit("LoadDaudioHDFImpl", AudioInit::LOAD_HDF_DRIVER, BizState::BIZ_STATE_END, ret); if (ret != DH_SUCCESS) { @@ -82,7 +86,12 @@ int32_t DAudioHdiHandler::UninitHdiHandler() remote_->RemoveDeathRecipient(audioHdiRecipient_); CHECK_NULL_RETURN(audioSrvHdf_, DH_SUCCESS); - int32_t ret = DaudioHdfOperate::GetInstance().UnLoadDaudioHDFImpl(); + auto dHFwkKit = GetDHFwkKit(); + if (dHFwkKit == nullptr) { + DHLOGE("Get dHFwkKit is null when unload hdf driver."); + return ERR_DH_AUDIO_NULLPTR; + } + int32_t ret = dHFwkKit->UnLoadDistributedHDF(DHType::AUDIO); if (ret != DH_SUCCESS) { DHLOGE("Unload hdf driver failed, ret: %{public}d", ret); return ret; @@ -223,6 +232,17 @@ int32_t DAudioHdiHandler::NotifyEvent(const std::string &devId, const int32_t dh return DH_SUCCESS; } +std::shared_ptr DAudioHdiHandler::GetDHFwkKit() +{ + if (dHFwkKit_ == nullptr) { + std::lock_guard lock(dHFwkKitMutex_); + if (dHFwkKit_ == nullptr) { + dHFwkKit_ = std::make_shared(); + } + } + return dHFwkKit_; +} + void DAudioHdiHandler::AudioHdiRecipient::OnRemoteDied(const wptr &remote) { DHLOGE("Exit the current process remote died."); diff --git a/services/audiohdiproxy/test/unittest/daudio_hdi_handler/BUILD.gn b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/BUILD.gn index 3d300bab7d648af8fcbecbdc18a35661fe16cb2a..fc17548958df1c6ca0d61b63da3ab6e045204a3c 100644 --- a/services/audiohdiproxy/test/unittest/daudio_hdi_handler/BUILD.gn +++ b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022-2024 Huawei Device Co., Ltd. +# Copyright (c) 2022-2025 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -35,7 +35,11 @@ config("module_private_config") { ohos_unittest("DAudioHdiHandlerTest") { module_out_path = module_out_path - sources = [ "src/daudio_hdi_handler_test.cpp" ] + sources = [ + "src/daudio_hdf_operate.cpp", + "src/daudio_hdi_handler_test.cpp", + "src/mock_distributed_hardware_fwk_kit.cpp", + ] configs = [ ":module_private_config" ] @@ -43,10 +47,17 @@ ohos_unittest("DAudioHdiHandlerTest") { [ "${services_path}/audiomanager/servicesource:distributed_audio_source" ] external_deps = [ + "cJSON:cjson", "c_utils:utils", + "distributed_hardware_fwk:distributed_av_receiver", "distributed_hardware_fwk:distributedhardwareutils", + "distributed_hardware_fwk:libdhfwk_sdk", "drivers_interface_distributed_audio:libdaudioext_proxy_2.0", "googletest:gmock", + "hdf_core:libhdf_ipc_adapter", + "hdf_core:libhdi", + "hdf_core:libpub_utils", + "hilog:libhilog", "ipc:ipc_core", ] } diff --git a/services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/audio_test_utils.h b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/audio_test_utils.h index 8c506ca037060140675d9e616358707cf347137a..b0f9473908b85c69c8548a0d9a6bc8bbac95c1b5 100644 --- a/services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/audio_test_utils.h +++ b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/audio_test_utils.h @@ -26,6 +26,7 @@ namespace OHOS { namespace DistributedHardware { using OHOS::HDI::DistributedAudio::Audioext::V2_0::IDAudioCallback; using OHOS::HDI::DistributedAudio::Audioext::V2_0::IDAudioManager; +using OHOS::HDI::DistributedAudio::Audioext::V2_0::IDAudioHdfCallback; class MockIDAudioManager : public IDAudioManager { public: @@ -48,6 +49,19 @@ public: { return DH_SUCCESS; } + + int32_t RegisterAudioHdfListener(const std::string &serviceName, const sptr &callbackObj) + { + (void)serviceName; + (void)callbackObj; + return DH_SUCCESS; + } + + int32_t UnRegisterAudioHdfListener(const std::string &serviceName) + { + (void)serviceName; + return DH_SUCCESS; + } }; class MockIDAudioHdiCallback : public IDAudioHdiCallback { diff --git a/services/audiohdiproxy/include/daudio_hdf_operate.h b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/daudio_hdf_operate.h similarity index 67% rename from services/audiohdiproxy/include/daudio_hdf_operate.h rename to services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/daudio_hdf_operate.h index a30a43ff4ca3d837044626c1a59edd01349846a2..fa51ef279d6d624f6eadaf19555bf9c7e051361a 100644 --- a/services/audiohdiproxy/include/daudio_hdf_operate.h +++ b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/include/daudio_hdf_operate.h @@ -1,74 +1,93 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_DAUDIO_HDF_OPERATE_H -#define OHOS_DAUDIO_HDF_OPERATE_H - -#include -#include -#include - -#include "iservstat_listener_hdi.h" -#include "idevmgr_hdi.h" -#include "iservmgr_hdi.h" -#include "single_instance.h" - -const std::string AUDIO_SERVICE_NAME = "daudio_primary_service"; -const std::string AUDIOEXT_SERVICE_NAME = "daudio_ext_service"; -constexpr uint16_t INVALID_VALUE = 0xffff; -constexpr int32_t WAIT_TIME = 5000; - -namespace OHOS { -namespace DistributedHardware { -using OHOS::HDI::DeviceManager::V1_0::IDeviceManager; -using OHOS::HDI::ServiceManager::V1_0::IServiceManager; -using OHOS::HDI::ServiceManager::V1_0::IServStatListener; -using OHOS::HDI::ServiceManager::V1_0::ServiceStatus; -using OHOS::HDI::ServiceManager::V1_0::ServStatListenerStub; - -class DaudioHdfOperate { -DECLARE_SINGLE_INSTANCE(DaudioHdfOperate); - -public: - int32_t LoadDaudioHDFImpl(); - int32_t UnLoadDaudioHDFImpl(); - -private: - int32_t WaitLoadService(const std::string& servName); - -private: - OHOS::sptr devmgr_; - OHOS::sptr servMgr_; - std::atomic audioServStatus_ = INVALID_VALUE; - std::atomic audioextServStatus_ = INVALID_VALUE; - std::condition_variable hdfOperateCon_; - std::mutex hdfOperateMutex_; -}; - -class DAudioHdfServStatListener : public OHOS::HDI::ServiceManager::V1_0::ServStatListenerStub { -public: - using StatusCallback = std::function; - explicit DAudioHdfServStatListener(StatusCallback callback) : callback_(std::move(callback)) - { - } - ~DAudioHdfServStatListener() override = default; - void OnReceive(const ServiceStatus& status) override; - -private: - StatusCallback callback_; -}; -} // namespace DistributedHardware -} // namespace OHOS +/* + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DAUDIO_HDF_OPERATE_H +#define OHOS_DAUDIO_HDF_OPERATE_H + +#include +#include +#include + +#include "iservstat_listener_hdi.h" +#include "idevmgr_hdi.h" +#include "iservmgr_hdi.h" +#include "single_instance.h" +#include + +namespace OHOS { +namespace DistributedHardware { +const std::string AUDIO_SERVICE_NAME = "daudio_primary_service"; +const std::string AUDIOEXT_SERVICE_NAME = "daudio_ext_service"; +constexpr uint16_t AUDIO_INVALID_VALUE = 0xffff; +constexpr int32_t AUDIO_WAIT_TIME = 5000; +using OHOS::HDI::DeviceManager::V1_0::IDeviceManager; +using OHOS::HDI::ServiceManager::V1_0::IServiceManager; +using OHOS::HDI::ServiceManager::V1_0::IServStatListener; +using OHOS::HDI::ServiceManager::V1_0::ServiceStatus; +using OHOS::HDI::ServiceManager::V1_0::ServStatListenerStub; +using OHOS::HDI::DistributedAudio::Audioext::V2_0::IDAudioManager; +using OHOS::HDI::DistributedAudio::Audioext::V2_0::IDAudioHdfCallback; +using OHOS::HDI::DistributedAudio::Audioext::V2_0::DAudioEvent; + +class FwkDAudioHdfCallback; +class DaudioHdfOperate { +DECLARE_SINGLE_INSTANCE(DaudioHdfOperate); + +public: + int32_t LoadDaudioHDFImpl(); + int32_t UnLoadDaudioHDFImpl(); + void ResetRefCount(); + +private: + int32_t WaitLoadService(const std::string& servName); + OHOS::sptr MakeServStatListener(); + int32_t LoadDevice(); + int32_t UnLoadDevice(); + int32_t RegisterHdfListener(); + int32_t UnRegisterHdfListener(); + +private: + OHOS::sptr devmgr_; + OHOS::sptr servMgr_; + OHOS::sptr audioSrvHdf_; + OHOS::sptr fwkDAudioHdfCallback_; + std::atomic audioServStatus_ = AUDIO_INVALID_VALUE; + std::atomic audioextServStatus_ = AUDIO_INVALID_VALUE; + std::condition_variable hdfOperateCon_; + std::mutex hdfOperateMutex_; + int32_t hdfLoadRef_ = 0; + std::mutex hdfLoadRefMutex_; +}; + +class DAudioHdfServStatListener : public OHOS::HDI::ServiceManager::V1_0::ServStatListenerStub { +public: + using StatusCallback = std::function; + explicit DAudioHdfServStatListener(StatusCallback callback) : callback_(std::move(callback)) + { + } + ~DAudioHdfServStatListener() override = default; + void OnReceive(const ServiceStatus& status) override; + +private: + StatusCallback callback_; +}; + +class FwkDAudioHdfCallback : public IDAudioHdfCallback { +protected: + int32_t NotifyEvent(int32_t devId, const DAudioEvent& event) override; +}; +} // namespace DistributedHardware +} // namespace OHOS #endif // OHOS_DAUDIO_HDF_OPERATE_H \ No newline at end of file diff --git a/services/audiohdiproxy/src/daudio_hdf_operate.cpp b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/src/daudio_hdf_operate.cpp similarity index 51% rename from services/audiohdiproxy/src/daudio_hdf_operate.cpp rename to services/audiohdiproxy/test/unittest/daudio_hdi_handler/src/daudio_hdf_operate.cpp index 7c72bfb7df7a848fd285e3b83f2128377727740d..bae93dbd9c0456706a499facd52de5b5f0cc2f8f 100644 --- a/services/audiohdiproxy/src/daudio_hdf_operate.cpp +++ b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/src/daudio_hdf_operate.cpp @@ -1,142 +1,258 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "daudio_hdf_operate.h" - -#include -#include - -#include "daudio_errorcode.h" -#include "daudio_log.h" - -#undef DH_LOG_TAG -#define DH_LOG_TAG "DAudioHdfServStatListener" - -namespace OHOS { -namespace DistributedHardware { -IMPLEMENT_SINGLE_INSTANCE(DaudioHdfOperate); -void DAudioHdfServStatListener::OnReceive(const ServiceStatus& status) -{ - DHLOGI("Service status on receive."); - if (status.serviceName == AUDIO_SERVICE_NAME || status.serviceName == AUDIOEXT_SERVICE_NAME) { - callback_(status); - } -} - -int32_t DaudioHdfOperate::LoadDaudioHDFImpl() -{ - if (audioServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START && - audioextServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) { - DHLOGD("Service has already start."); - return DH_SUCCESS; - } - servMgr_ = IServiceManager::Get(); - devmgr_ = IDeviceManager::Get(); - CHECK_NULL_RETURN(servMgr_, ERR_DH_AUDIO_NULLPTR); - CHECK_NULL_RETURN(devmgr_, ERR_DH_AUDIO_NULLPTR); - - ::OHOS::sptr listener( - new DAudioHdfServStatListener(DAudioHdfServStatListener::StatusCallback([&](const ServiceStatus& status) { - DHLOGI("Load audio service status callback, serviceName: %{public}s, status: %{public}d", - status.serviceName.c_str(), status.status); - std::unique_lock lock(hdfOperateMutex_); - if (status.serviceName == AUDIO_SERVICE_NAME) { - audioServStatus_.store(status.status); - hdfOperateCon_.notify_one(); - } else if (status.serviceName == AUDIOEXT_SERVICE_NAME) { - audioextServStatus_.store(status.status); - hdfOperateCon_.notify_one(); - } - }))); - if (servMgr_->RegisterServiceStatusListener(listener, DEVICE_CLASS_AUDIO) != HDF_SUCCESS) { - DHLOGE("Failed to register the service status listener."); - return ERR_DH_AUDIO_NULLPTR; - } - - int32_t ret = devmgr_->LoadDevice(AUDIO_SERVICE_NAME); - if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) { - return ERR_DH_AUDIO_FAILED; - } - if (WaitLoadService(AUDIO_SERVICE_NAME) != DH_SUCCESS) { - DHLOGE("Wait load audio service failed!"); - return ERR_DH_AUDIO_FAILED; - } - ret = devmgr_->LoadDevice(AUDIOEXT_SERVICE_NAME); - if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) { - return ERR_DH_AUDIO_FAILED; - } - if (WaitLoadService(AUDIOEXT_SERVICE_NAME) != DH_SUCCESS) { - DHLOGE("Wait load provider service failed!"); - return ERR_DH_AUDIO_FAILED; - } - - if (servMgr_->UnregisterServiceStatusListener(listener) != HDF_SUCCESS) { - DHLOGE("Failed to unregister the service status listener."); - } - return DH_SUCCESS; -} - -int32_t DaudioHdfOperate::WaitLoadService(const std::string& servName) -{ - std::unique_lock lock(hdfOperateMutex_); - if (servName == AUDIO_SERVICE_NAME) { - DHLOGD("WaitLoadService start service %s, status %hu", servName.c_str(), this->audioServStatus_.load()); - hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(WAIT_TIME), [this] { - return (this->audioServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START); - }); - - if (this->audioServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) { - DHLOGE("Wait load service %{public}s failed, status %{public}hu", servName.c_str(), - this->audioServStatus_.load()); - return ERR_DH_AUDIO_FAILED; - } - } - - if (servName == AUDIOEXT_SERVICE_NAME) { - DHLOGD("WaitLoadService start service %s, status %hu", servName.c_str(), this->audioextServStatus_.load()); - hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(WAIT_TIME), [this] { - return (this->audioextServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START); - }); - - if (this->audioextServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) { - DHLOGE("Wait load service %{public}s failed, status %{public}hu", servName.c_str(), - this->audioextServStatus_.load()); - return ERR_DH_AUDIO_FAILED; - } - } - return DH_SUCCESS; -} - -int32_t DaudioHdfOperate::UnLoadDaudioHDFImpl() -{ - DHLOGI("UnLoad daudio hdf impl begin!"); - devmgr_ = IDeviceManager::Get(); - CHECK_NULL_RETURN(devmgr_, ERR_DH_AUDIO_NULLPTR); - - int32_t ret = devmgr_->UnloadDevice(AUDIO_SERVICE_NAME); - if (ret != HDF_SUCCESS) { - DHLOGE("Unload audio service failed, ret: %{public}d", ret); - } - ret = devmgr_->UnloadDevice(AUDIOEXT_SERVICE_NAME); - if (ret != HDF_SUCCESS) { - DHLOGE("Unload device failed, ret: %{public}d", ret); - } - audioServStatus_.store(INVALID_VALUE); - audioextServStatus_.store(INVALID_VALUE); - DHLOGD("UnLoad daudio hdf impl end!"); - return DH_SUCCESS; -} -} // namespace DistributedHardware +/* + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "daudio_hdf_operate.h" + +#include +#include + +#include "daudio_errorcode.h" +#include "daudio_log.h" + +#undef DH_LOG_TAG +#define DH_LOG_TAG "DaudioHdfOperate" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DaudioHdfOperate); +int32_t DaudioHdfOperate::LoadDaudioHDFImpl() +{ + DHLOGI("Load daudio hdf impl begin!"); + std::unique_lock loadRefLocker(hdfLoadRefMutex_); + if (hdfLoadRef_ > 0) { + hdfLoadRef_++; + DHLOGI("The daudio hdf impl has been loaded, just inc ref!"); + return DH_SUCCESS; + } + int32_t ret = LoadDevice(); + if (ret != DH_SUCCESS) { + DHLOGE("LoadDevice failed, ret: %{public}d.", ret); + return ret; + } + ret = RegisterHdfListener(); + if (ret != DH_SUCCESS) { + DHLOGE("RegisterHdfListener failed, ret: %{public}d.", ret); + UnLoadDevice(); + return ret; + } + hdfLoadRef_++; + DHLOGI("Load daudio hdf impl end!"); + return DH_SUCCESS; +} + +int32_t DaudioHdfOperate::UnLoadDaudioHDFImpl() +{ + DHLOGI("UnLoad daudio hdf impl begin!"); + std::unique_lock loadRefLocker(hdfLoadRefMutex_); + if (hdfLoadRef_ == 0) { + DHLOGI("The daudio hdf impl has been unloaded!"); + return DH_SUCCESS; + } + if (hdfLoadRef_ > 1) { + hdfLoadRef_--; + DHLOGI("The daudio hdf impl has been loaded, just dec ref!"); + return DH_SUCCESS; + } + int32_t ret = UnRegisterHdfListener(); + if (ret != DH_SUCCESS) { + DHLOGE("UnRegisterHdfListener failed, ret: %{public}d.", ret); + } + ret = UnLoadDevice(); + if (ret != DH_SUCCESS) { + DHLOGE("UnLoadDevice failed, ret: %{public}d.", ret); + } + hdfLoadRef_--; + DHLOGI("UnLoad daudio hdf impl end!"); + return DH_SUCCESS; +} + +void DaudioHdfOperate::ResetRefCount() +{ + DHLOGI("Reset reference count for daudio."); + std::unique_lock loadRefLocker(hdfLoadRefMutex_); + hdfLoadRef_ = 0; +} + +int32_t DaudioHdfOperate::WaitLoadService(const std::string& servName) +{ + std::unique_lock lock(hdfOperateMutex_); + if (servName == AUDIO_SERVICE_NAME) { + DHLOGD("WaitLoadService start service %s, status %hu", servName.c_str(), this->audioServStatus_.load()); + hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(AUDIO_WAIT_TIME), [this] { + return (this->audioServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START); + }); + + if (this->audioServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) { + DHLOGE("Wait load service %{public}s failed, status %{public}hu", servName.c_str(), + this->audioServStatus_.load()); + return ERR_DH_AUDIO_FAILED; + } + } + + if (servName == AUDIOEXT_SERVICE_NAME) { + DHLOGD("WaitLoadService start service %s, status %hu", servName.c_str(), this->audioextServStatus_.load()); + hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(AUDIO_WAIT_TIME), [this] { + return (this->audioextServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START); + }); + + if (this->audioextServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) { + DHLOGE("Wait load service %{public}s failed, status %{public}hu", servName.c_str(), + this->audioextServStatus_.load()); + return ERR_DH_AUDIO_FAILED; + } + } + return DH_SUCCESS; +} + +OHOS::sptr DaudioHdfOperate::MakeServStatListener() +{ + return OHOS::sptr( + new DAudioHdfServStatListener(DAudioHdfServStatListener::StatusCallback([&](const ServiceStatus& status) { + DHLOGI("Load audio service status callback, serviceName: %{public}s, status: %{public}d", + status.serviceName.c_str(), status.status); + std::unique_lock lock(hdfOperateMutex_); + if (status.serviceName == AUDIO_SERVICE_NAME) { + audioServStatus_.store(status.status); + hdfOperateCon_.notify_one(); + } else if (status.serviceName == AUDIOEXT_SERVICE_NAME) { + audioextServStatus_.store(status.status); + hdfOperateCon_.notify_one(); + } + })) + ); +} + +int32_t DaudioHdfOperate::LoadDevice() +{ + DHLOGI("LoadDevice for daudio begin!"); + servMgr_ = IServiceManager::Get(); + devmgr_ = IDeviceManager::Get(); + if (servMgr_ == nullptr || devmgr_ == nullptr) { + DHLOGE("get hdi service manager or device manager failed!"); + return ERR_DH_AUDIO_NULLPTR; + } + OHOS::sptr listener = MakeServStatListener(); + if (servMgr_->RegisterServiceStatusListener(listener, DEVICE_CLASS_AUDIO) != HDF_SUCCESS) { + DHLOGE("Failed to register the service status listener."); + return ERR_DH_AUDIO_FAILED; + } + int32_t ret = devmgr_->LoadDevice(AUDIO_SERVICE_NAME); + if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) { + DHLOGE("Load audio service failed!"); + servMgr_->UnregisterServiceStatusListener(listener); + return ERR_DH_AUDIO_FAILED; + } + if (WaitLoadService(AUDIO_SERVICE_NAME) != DH_SUCCESS) { + DHLOGE("Wait load audio service failed!"); + servMgr_->UnregisterServiceStatusListener(listener); + return ERR_DH_AUDIO_FAILED; + } + ret = devmgr_->LoadDevice(AUDIOEXT_SERVICE_NAME); + if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) { + DHLOGE("Load audio provider service failed!"); + devmgr_->UnloadDevice(AUDIO_SERVICE_NAME); + servMgr_->UnregisterServiceStatusListener(listener); + return ERR_DH_AUDIO_FAILED; + } + if (WaitLoadService(AUDIOEXT_SERVICE_NAME) != DH_SUCCESS) { + DHLOGE("Wait load audio provider service failed!"); + devmgr_->UnloadDevice(AUDIO_SERVICE_NAME); + servMgr_->UnregisterServiceStatusListener(listener); + return ERR_DH_AUDIO_FAILED; + } + if (servMgr_->UnregisterServiceStatusListener(listener) != HDF_SUCCESS) { + DHLOGE("Failed to unregister the service status listener."); + } + DHLOGI("LoadDevice for daudio end!"); + return DH_SUCCESS; +} + +int32_t DaudioHdfOperate::UnLoadDevice() +{ + DHLOGI("UnLoadDevice for daudio begin!"); + if (devmgr_ == nullptr) { + DHLOGE("hdi device manager is nullptr!"); + return ERR_DH_AUDIO_NULLPTR; + } + int32_t ret = devmgr_->UnloadDevice(AUDIO_SERVICE_NAME); + if (ret != HDF_SUCCESS) { + DHLOGE("Unload audio service failed, ret: %{public}d", ret); + } + ret = devmgr_->UnloadDevice(AUDIOEXT_SERVICE_NAME); + if (ret != HDF_SUCCESS) { + DHLOGE("Unload device failed, ret: %{public}d", ret); + } + audioServStatus_.store(AUDIO_INVALID_VALUE); + audioextServStatus_.store(AUDIO_INVALID_VALUE); + DHLOGI("UnLoadDevice for daudio end!"); + return DH_SUCCESS; +} + +int32_t DaudioHdfOperate::RegisterHdfListener() +{ + DHLOGI("RegisterHdfListener for daudio begin!"); + audioSrvHdf_ = IDAudioManager::Get(AUDIOEXT_SERVICE_NAME.c_str(), false); + if (audioSrvHdf_ == nullptr) { + DHLOGE("Get hdi daudio manager failed."); + return ERR_DH_AUDIO_NULLPTR; + } + if (fwkDAudioHdfCallback_ == nullptr) { + fwkDAudioHdfCallback_ = new FwkDAudioHdfCallback(); + if (fwkDAudioHdfCallback_ == nullptr) { + DHLOGE("Create FwkDAudioHdfCallback failed."); + return ERR_DH_AUDIO_NULLPTR; + } + } + int32_t ret = audioSrvHdf_->RegisterAudioHdfListener("DHFWK", fwkDAudioHdfCallback_); + if (ret != DH_SUCCESS) { + DHLOGE("Call hdf proxy RegisterAudioHdfListener failed, ret: %{public}d.", ret); + return ret; + } + DHLOGI("RegisterHdfListener for daudio end!"); + return DH_SUCCESS; +} + +int32_t DaudioHdfOperate::UnRegisterHdfListener() +{ + DHLOGI("UnRegisterHdfListener for daudio begin!"); + if (audioSrvHdf_ == nullptr) { + DHLOGE("hdi daudio manager is nullptr!"); + return ERR_DH_AUDIO_NULLPTR; + } + int32_t ret = audioSrvHdf_->UnRegisterAudioHdfListener("DHFWK"); + if (ret != DH_SUCCESS) { + DHLOGE("Call hdf proxy UnRegisterAudioHdfListener failed, ret: %{public}d.", ret); + return ret; + } + DHLOGI("UnRegisterHdfListener for daudio end!"); + return DH_SUCCESS; +} + +void DAudioHdfServStatListener::OnReceive(const ServiceStatus& status) +{ + DHLOGI("Service status on receive."); + if (status.serviceName == AUDIO_SERVICE_NAME || status.serviceName == AUDIOEXT_SERVICE_NAME) { + callback_(status); + } +} + +int32_t FwkDAudioHdfCallback::NotifyEvent(int32_t devId, const DAudioEvent& event) +{ + (void)devId; + (void)event; + return DH_SUCCESS; +} +} // namespace DistributedHardware } // namespace OHOS \ No newline at end of file diff --git a/services/audiohdiproxy/test/unittest/daudio_hdi_handler/src/mock_distributed_hardware_fwk_kit.cpp b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/src/mock_distributed_hardware_fwk_kit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..53a79248521214a7ae0a6b9fb1a369efb0282d7a --- /dev/null +++ b/services/audiohdiproxy/test/unittest/daudio_hdi_handler/src/mock_distributed_hardware_fwk_kit.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "daudio_hdf_operate.h" +#include "daudio_hdi_handler_test.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +int32_t DistributedHardwareFwkKit::LoadDistributedHDF(const DHType dhType) +{ + return DaudioHdfOperate::GetInstance().LoadDaudioHDFImpl(); +} + +int32_t DistributedHardwareFwkKit::UnLoadDistributedHDF(const DHType dhType) +{ + return DaudioHdfOperate::GetInstance().UnLoadDaudioHDFImpl(); +} +} // DistributedHardware +} // OHOS diff --git a/services/audiomanager/servicesource/BUILD.gn b/services/audiomanager/servicesource/BUILD.gn index 0c760deee2758e8faa6edf5315d0b1072eddc055..58205f9c7a14cecd4e2eefa99caef87614186d03 100755 --- a/services/audiomanager/servicesource/BUILD.gn +++ b/services/audiomanager/servicesource/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Huawei Device Co., Ltd. +# Copyright (c) 2024-2025 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -64,7 +64,6 @@ ohos_shared_library("distributed_audio_source") { sources = [ "${audio_control_path}/controlsource/src/daudio_source_dev_ctrl_manager.cpp", - "${audio_hdi_proxy_path}/src/daudio_hdf_operate.cpp", "${audio_hdi_proxy_path}/src/daudio_hdi_handler.cpp", "${audio_hdi_proxy_path}/src/daudio_manager_callback.cpp", "${audio_transport_path}/audioctrltransport/src/daudio_source_ctrl_trans.cpp", @@ -103,6 +102,7 @@ ohos_shared_library("distributed_audio_source") { "distributed_hardware_fwk:distributed_av_receiver", "distributed_hardware_fwk:distributed_av_sender", "distributed_hardware_fwk:distributedhardwareutils", + "distributed_hardware_fwk:libdhfwk_sdk", "drivers_interface_distributed_audio:libdaudio_proxy_1.0", "drivers_interface_distributed_audio:libdaudioext_proxy_2.0", "dsoftbus:softbus_client", diff --git a/services/audiomanager/test/fuzztest/sourceserviceinitsource_fuzzer/BUILD.gn b/services/audiomanager/test/fuzztest/sourceserviceinitsource_fuzzer/BUILD.gn index 3159bb8d36eef9a1428e936a866f8a242d38e470..c5ed87092e035033206c24b63fa37eb94763dc13 100644 --- a/services/audiomanager/test/fuzztest/sourceserviceinitsource_fuzzer/BUILD.gn +++ b/services/audiomanager/test/fuzztest/sourceserviceinitsource_fuzzer/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2025 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -57,7 +57,9 @@ ohos_fuzztest("SourceServiceInitSourceFuzzTest") { "audio_framework:audio_renderer", "cJSON:cjson", "c_utils:utils", + "distributed_hardware_fwk:distributed_av_receiver", "distributed_hardware_fwk:distributedhardwareutils", + "distributed_hardware_fwk:libdhfwk_sdk", "drivers_interface_distributed_audio:libdaudio_proxy_1.0", "ipc:ipc_core", "safwk:system_ability_fwk", diff --git a/services/audiomanager/test/fuzztest/sourceserviceregisterdistributedhardware_fuzzer/BUILD.gn b/services/audiomanager/test/fuzztest/sourceserviceregisterdistributedhardware_fuzzer/BUILD.gn index 334c1a7d516ec2aaa9d770cda28cd70c7cea7ae7..42728e1213c3d2124b805fe60cb5a258cc4ef01c 100644 --- a/services/audiomanager/test/fuzztest/sourceserviceregisterdistributedhardware_fuzzer/BUILD.gn +++ b/services/audiomanager/test/fuzztest/sourceserviceregisterdistributedhardware_fuzzer/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2025 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -54,7 +54,9 @@ ohos_fuzztest("SourceServiceRegisterDistributedHardwareFuzzTest") { "audio_framework:audio_renderer", "cJSON:cjson", "c_utils:utils", + "distributed_hardware_fwk:distributed_av_receiver", "distributed_hardware_fwk:distributedhardwareutils", + "distributed_hardware_fwk:libdhfwk_sdk", "drivers_interface_distributed_audio:libdaudio_proxy_1.0", "ipc:ipc_core", "safwk:system_ability_fwk", diff --git a/services/audiomanager/test/fuzztest/sourceservicereleasesource_fuzzer/BUILD.gn b/services/audiomanager/test/fuzztest/sourceservicereleasesource_fuzzer/BUILD.gn index 12a50c7542a9c928f056144bfd8a359d24e61b19..7af27bd646055f8b4cfdd42be2a6305a3145c4d1 100644 --- a/services/audiomanager/test/fuzztest/sourceservicereleasesource_fuzzer/BUILD.gn +++ b/services/audiomanager/test/fuzztest/sourceservicereleasesource_fuzzer/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Huawei Device Co., Ltd. +# Copyright (c) 2023-2025 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -55,7 +55,9 @@ ohos_fuzztest("SourceServiceReleaseSourceFuzzTest") { "audio_framework:audio_renderer", "cJSON:cjson", "c_utils:utils", + "distributed_hardware_fwk:distributed_av_receiver", "distributed_hardware_fwk:distributedhardwareutils", + "distributed_hardware_fwk:libdhfwk_sdk", "drivers_interface_distributed_audio:libdaudio_proxy_1.0", "ipc:ipc_core", "safwk:system_ability_fwk", diff --git a/services/audiomanager/test/fuzztest/sourceserviceunregisterdistributedhardware_fuzzer/BUILD.gn b/services/audiomanager/test/fuzztest/sourceserviceunregisterdistributedhardware_fuzzer/BUILD.gn index fa3b4f86ca3ee4685487c5d2fae8b426f8e73f0e..bc8cf013be1769f265bf94a9a66c3608af819f5c 100644 --- a/services/audiomanager/test/fuzztest/sourceserviceunregisterdistributedhardware_fuzzer/BUILD.gn +++ b/services/audiomanager/test/fuzztest/sourceserviceunregisterdistributedhardware_fuzzer/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2025 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -55,6 +55,7 @@ ohos_fuzztest("SourceServiceUnregisterDistributedHardwareFuzzTest") { "cJSON:cjson", "c_utils:utils", "distributed_hardware_fwk:distributedhardwareutils", + "distributed_hardware_fwk:libdhfwk_sdk", "drivers_interface_distributed_audio:libdaudio_proxy_1.0", "ipc:ipc_core", "safwk:system_ability_fwk", diff --git a/services/audiomanager/test/unittest/sourcedevice/BUILD.gn b/services/audiomanager/test/unittest/sourcedevice/BUILD.gn index e671e7455e1de6f176479bdfb4b0032dd863d6c8..84ea83e7089c0575e2805c01267572db9693d0b4 100644 --- a/services/audiomanager/test/unittest/sourcedevice/BUILD.gn +++ b/services/audiomanager/test/unittest/sourcedevice/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Huawei Device Co., Ltd. +# Copyright (c) 2024-2025 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -116,6 +116,8 @@ ohos_unittest("DMicDevTest") { "cJSON:cjson", "distributed_hardware_fwk:distributed_av_receiver", "distributed_hardware_fwk:distributed_av_sender", + "distributed_hardware_fwk:distributedhardwareutils", + "distributed_hardware_fwk:libdhfwk_sdk", "drivers_interface_distributed_audio:libdaudioext_proxy_2.0", "dsoftbus:softbus_client", "googletest:gmock", @@ -155,6 +157,8 @@ ohos_unittest("DSpeakerDevTest") { "c_utils:utils", "distributed_hardware_fwk:distributed_av_receiver", "distributed_hardware_fwk:distributed_av_sender", + "distributed_hardware_fwk:distributedhardwareutils", + "distributed_hardware_fwk:libdhfwk_sdk", "drivers_interface_distributed_audio:libdaudioext_proxy_2.0", "dsoftbus:softbus_client", "googletest:gmock", @@ -198,6 +202,8 @@ ohos_unittest("DAudioEchoCannelManagerTest") { "c_utils:utils", "distributed_hardware_fwk:distributed_av_receiver", "distributed_hardware_fwk:distributed_av_sender", + "distributed_hardware_fwk:distributedhardwareutils", + "distributed_hardware_fwk:libdhfwk_sdk", "drivers_interface_distributed_audio:libdaudioext_proxy_2.0", "dsoftbus:softbus_client", "eventhandler:libeventhandler", diff --git a/services/audiomanager/test/unittest/sourcemanager/BUILD.gn b/services/audiomanager/test/unittest/sourcemanager/BUILD.gn index e45e7f5ec572d24f99154362903ff1f071d2b7f6..2027a64c003e64cb8db6065ad2d8fada00a0c404 100644 --- a/services/audiomanager/test/unittest/sourcemanager/BUILD.gn +++ b/services/audiomanager/test/unittest/sourcemanager/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Huawei Device Co., Ltd. +# Copyright (c) 2024-2025 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -44,6 +44,7 @@ config("module_private_config") { "${services_path}/common/audioeventcallback", "${services_path}/common/audioparam", "${services_path}/common/taskProcessor/include", + "${services_path}/audiohdiproxy/test/unittest/daudio_hdi_handler/include", ] } @@ -51,7 +52,11 @@ config("module_private_config") { ohos_unittest("DaudioSourceMgrTest") { module_out_path = module_out_path - sources = [ "src/daudio_source_mgr_test.cpp" ] + sources = [ + "src/daudio_source_mgr_test.cpp", + "../../../../audiohdiproxy/test/unittest/daudio_hdi_handler/src/daudio_hdf_operate.cpp", + "../../../../audiohdiproxy/test/unittest/daudio_hdi_handler/src/mock_distributed_hardware_fwk_kit.cpp", + ] configs = [ ":module_private_config" ]