1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "daudio_hdf_operate.h" 17 18#include <hdf_io_service_if.h> 19#include <hdf_base.h> 20 21#include "daudio_errorcode.h" 22#include "daudio_log.h" 23 24#undef DH_LOG_TAG 25#define DH_LOG_TAG "DAudioHdfServStatListener" 26 27namespace OHOS { 28namespace DistributedHardware { 29IMPLEMENT_SINGLE_INSTANCE(DaudioHdfOperate); 30void DAudioHdfServStatListener::OnReceive(const ServiceStatus& status) 31{ 32 DHLOGI("Service status on receive."); 33 if (status.serviceName == AUDIO_SERVICE_NAME || status.serviceName == AUDIOEXT_SERVICE_NAME) { 34 callback_(status); 35 } 36} 37 38int32_t DaudioHdfOperate::LoadDaudioHDFImpl() 39{ 40 if (audioServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START && 41 audioextServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) { 42 DHLOGD("Service has already start."); 43 return DH_SUCCESS; 44 } 45 servMgr_ = IServiceManager::Get(); 46 devmgr_ = IDeviceManager::Get(); 47 CHECK_NULL_RETURN(servMgr_, ERR_DH_AUDIO_NULLPTR); 48 CHECK_NULL_RETURN(devmgr_, ERR_DH_AUDIO_NULLPTR); 49 50 ::OHOS::sptr<IServStatListener> listener( 51 new DAudioHdfServStatListener(DAudioHdfServStatListener::StatusCallback([&](const ServiceStatus& status) { 52 DHLOGI("Load audio service status callback, serviceName: %{public}s, status: %{public}d", 53 status.serviceName.c_str(), status.status); 54 std::unique_lock<std::mutex> lock(hdfOperateMutex_); 55 if (status.serviceName == AUDIO_SERVICE_NAME) { 56 audioServStatus_.store(status.status); 57 hdfOperateCon_.notify_one(); 58 } else if (status.serviceName == AUDIOEXT_SERVICE_NAME) { 59 audioextServStatus_.store(status.status); 60 hdfOperateCon_.notify_one(); 61 } 62 }))); 63 if (servMgr_->RegisterServiceStatusListener(listener, DEVICE_CLASS_AUDIO) != HDF_SUCCESS) { 64 DHLOGE("Failed to register the service status listener."); 65 return ERR_DH_AUDIO_NULLPTR; 66 } 67 68 int32_t ret = devmgr_->LoadDevice(AUDIO_SERVICE_NAME); 69 if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) { 70 return ERR_DH_AUDIO_FAILED; 71 } 72 if (WaitLoadService(AUDIO_SERVICE_NAME) != DH_SUCCESS) { 73 DHLOGE("Wait load audio service failed!"); 74 return ERR_DH_AUDIO_FAILED; 75 } 76 ret = devmgr_->LoadDevice(AUDIOEXT_SERVICE_NAME); 77 if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) { 78 return ERR_DH_AUDIO_FAILED; 79 } 80 if (WaitLoadService(AUDIOEXT_SERVICE_NAME) != DH_SUCCESS) { 81 DHLOGE("Wait load provider service failed!"); 82 return ERR_DH_AUDIO_FAILED; 83 } 84 85 if (servMgr_->UnregisterServiceStatusListener(listener) != HDF_SUCCESS) { 86 DHLOGE("Failed to unregister the service status listener."); 87 } 88 return DH_SUCCESS; 89} 90 91int32_t DaudioHdfOperate::WaitLoadService(const std::string& servName) 92{ 93 std::unique_lock<std::mutex> lock(hdfOperateMutex_); 94 if (servName == AUDIO_SERVICE_NAME) { 95 DHLOGD("WaitLoadService start service %s, status %hu", servName.c_str(), this->audioServStatus_.load()); 96 hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(WAIT_TIME), [this] { 97 return (this->audioServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START); 98 }); 99 100 if (this->audioServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) { 101 DHLOGE("Wait load service %{public}s failed, status %{public}hu", servName.c_str(), 102 this->audioServStatus_.load()); 103 return ERR_DH_AUDIO_FAILED; 104 } 105 } 106 107 if (servName == AUDIOEXT_SERVICE_NAME) { 108 DHLOGD("WaitLoadService start service %s, status %hu", servName.c_str(), this->audioextServStatus_.load()); 109 hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(WAIT_TIME), [this] { 110 return (this->audioextServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START); 111 }); 112 113 if (this->audioextServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) { 114 DHLOGE("Wait load service %{public}s failed, status %{public}hu", servName.c_str(), 115 this->audioextServStatus_.load()); 116 return ERR_DH_AUDIO_FAILED; 117 } 118 } 119 return DH_SUCCESS; 120} 121 122int32_t DaudioHdfOperate::UnLoadDaudioHDFImpl() 123{ 124 DHLOGI("UnLoad daudio hdf impl begin!"); 125 devmgr_ = IDeviceManager::Get(); 126 CHECK_NULL_RETURN(devmgr_, ERR_DH_AUDIO_NULLPTR); 127 128 int32_t ret = devmgr_->UnloadDevice(AUDIO_SERVICE_NAME); 129 if (ret != HDF_SUCCESS) { 130 DHLOGE("Unload audio service failed, ret: %{public}d", ret); 131 } 132 ret = devmgr_->UnloadDevice(AUDIOEXT_SERVICE_NAME); 133 if (ret != HDF_SUCCESS) { 134 DHLOGE("Unload device failed, ret: %{public}d", ret); 135 } 136 audioServStatus_.store(INVALID_VALUE); 137 audioextServStatus_.store(INVALID_VALUE); 138 DHLOGD("UnLoad daudio hdf impl end!"); 139 return DH_SUCCESS; 140} 141} // namespace DistributedHardware 142} // namespace OHOS