1 /*
2 * Copyright (c) 2022-2025 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 #include "iproxy_broker.h"
24
25 #undef DH_LOG_TAG
26 #define DH_LOG_TAG "DaudioHdfOperate"
27
28 namespace OHOS {
29 namespace DistributedHardware {
30 IMPLEMENT_SINGLE_INSTANCE(DaudioHdfOperate);
LoadDaudioHDFImpl(std::shared_ptr<HdfDeathCallback> callback)31 int32_t DaudioHdfOperate::LoadDaudioHDFImpl(std::shared_ptr<HdfDeathCallback> callback)
32 {
33 DHLOGI("Load daudio hdf impl begin!");
34 int32_t ret = LoadDevice();
35 if (ret != DH_SUCCESS) {
36 DHLOGE("LoadDevice failed, ret: %{public}d.", ret);
37 return ret;
38 }
39 ret = RegisterHdfListener();
40 if (ret != DH_SUCCESS) {
41 DHLOGE("RegisterHdfListener failed, ret: %{public}d.", ret);
42 UnLoadDevice();
43 return ret;
44 }
45 hdfDeathCallback_ = callback;
46 ret = AddHdfDeathBind();
47 if (ret != DH_SUCCESS) {
48 DHLOGE("AddHdfDeathBind failed, ret: %{public}d.", ret);
49 UnRegisterHdfListener();
50 UnLoadDevice();
51 return ret;
52 }
53 DHLOGI("Load daudio hdf impl end!");
54 return DH_SUCCESS;
55 }
56
UnLoadDaudioHDFImpl()57 int32_t DaudioHdfOperate::UnLoadDaudioHDFImpl()
58 {
59 DHLOGI("UnLoad daudio hdf impl begin!");
60 int32_t ret = RemoveHdfDeathBind();
61 if (ret != DH_SUCCESS) {
62 DHLOGE("RemoveHdfDeathBind failed, ret: %{public}d.", ret);
63 }
64 ret = UnRegisterHdfListener();
65 if (ret != DH_SUCCESS) {
66 DHLOGE("UnRegisterHdfListener failed, ret: %{public}d.", ret);
67 }
68 ret = UnLoadDevice();
69 if (ret != DH_SUCCESS) {
70 DHLOGE("UnLoadDevice failed, ret: %{public}d.", ret);
71 }
72 DHLOGI("UnLoad daudio hdf impl end!");
73 return DH_SUCCESS;
74 }
75
OnHdfHostDied()76 void DaudioHdfOperate::OnHdfHostDied()
77 {
78 DHLOGI("On hdf host died begin!");
79 if (hdfDeathCallback_) {
80 DHLOGI("Call hdf host died callback!");
81 hdfDeathCallback_->OnHdfHostDied();
82 }
83 DHLOGI("On hdf host died end!");
84 }
85
WaitLoadService(const std::string & servName)86 int32_t DaudioHdfOperate::WaitLoadService(const std::string& servName)
87 {
88 std::unique_lock<std::mutex> lock(hdfOperateMutex_);
89 if (servName == AUDIO_SERVICE_NAME) {
90 DHLOGD("WaitLoadService start service %s, status %hu", servName.c_str(), this->audioServStatus_.load());
91 hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(AUDIO_WAIT_TIME), [this] {
92 return (this->audioServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START);
93 });
94
95 if (this->audioServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) {
96 DHLOGE("Wait load service %{public}s failed, status %{public}hu", servName.c_str(),
97 this->audioServStatus_.load());
98 return ERR_DH_AUDIO_FAILED;
99 }
100 }
101
102 if (servName == AUDIOEXT_SERVICE_NAME) {
103 DHLOGD("WaitLoadService start service %s, status %hu", servName.c_str(), this->audioextServStatus_.load());
104 hdfOperateCon_.wait_for(lock, std::chrono::milliseconds(AUDIO_WAIT_TIME), [this] {
105 return (this->audioextServStatus_.load() == OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START);
106 });
107
108 if (this->audioextServStatus_.load() != OHOS::HDI::ServiceManager::V1_0::SERVIE_STATUS_START) {
109 DHLOGE("Wait load service %{public}s failed, status %{public}hu", servName.c_str(),
110 this->audioextServStatus_.load());
111 return ERR_DH_AUDIO_FAILED;
112 }
113 }
114 return DH_SUCCESS;
115 }
116
MakeServStatListener()117 OHOS::sptr<IServStatListener> DaudioHdfOperate::MakeServStatListener()
118 {
119 return OHOS::sptr<IServStatListener>(
120 new DAudioHdfServStatListener(DAudioHdfServStatListener::StatusCallback([&](const ServiceStatus& status) {
121 DHLOGI("Load audio service status callback, serviceName: %{public}s, status: %{public}d",
122 status.serviceName.c_str(), status.status);
123 std::unique_lock<std::mutex> lock(hdfOperateMutex_);
124 if (status.serviceName == AUDIO_SERVICE_NAME) {
125 audioServStatus_.store(status.status);
126 hdfOperateCon_.notify_one();
127 } else if (status.serviceName == AUDIOEXT_SERVICE_NAME) {
128 audioextServStatus_.store(status.status);
129 hdfOperateCon_.notify_one();
130 }
131 }))
132 );
133 }
134
LoadDevice()135 int32_t DaudioHdfOperate::LoadDevice()
136 {
137 DHLOGI("LoadDevice for daudio begin!");
138 servMgr_ = IServiceManager::Get();
139 devmgr_ = IDeviceManager::Get();
140 if (servMgr_ == nullptr || devmgr_ == nullptr) {
141 DHLOGE("get hdi service manager or device manager failed!");
142 return ERR_DH_AUDIO_NULLPTR;
143 }
144 OHOS::sptr<IServStatListener> listener = MakeServStatListener();
145 if (servMgr_->RegisterServiceStatusListener(listener, DEVICE_CLASS_AUDIO) != HDF_SUCCESS) {
146 DHLOGE("Failed to register the service status listener.");
147 return ERR_DH_AUDIO_FAILED;
148 }
149 int32_t ret = devmgr_->LoadDevice(AUDIO_SERVICE_NAME);
150 if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) {
151 DHLOGE("Load audio service failed!");
152 servMgr_->UnregisterServiceStatusListener(listener);
153 return ERR_DH_AUDIO_FAILED;
154 }
155 if (WaitLoadService(AUDIO_SERVICE_NAME) != DH_SUCCESS) {
156 DHLOGE("Wait load audio service failed!");
157 servMgr_->UnregisterServiceStatusListener(listener);
158 return ERR_DH_AUDIO_FAILED;
159 }
160 ret = devmgr_->LoadDevice(AUDIOEXT_SERVICE_NAME);
161 if (ret != HDF_SUCCESS && ret != HDF_ERR_DEVICE_BUSY) {
162 DHLOGE("Load audio provider service failed!");
163 devmgr_->UnloadDevice(AUDIO_SERVICE_NAME);
164 servMgr_->UnregisterServiceStatusListener(listener);
165 return ERR_DH_AUDIO_FAILED;
166 }
167 if (WaitLoadService(AUDIOEXT_SERVICE_NAME) != DH_SUCCESS) {
168 DHLOGE("Wait load audio provider service failed!");
169 devmgr_->UnloadDevice(AUDIO_SERVICE_NAME);
170 servMgr_->UnregisterServiceStatusListener(listener);
171 return ERR_DH_AUDIO_FAILED;
172 }
173 if (servMgr_->UnregisterServiceStatusListener(listener) != HDF_SUCCESS) {
174 DHLOGE("Failed to unregister the service status listener.");
175 }
176 DHLOGI("LoadDevice for daudio end!");
177 return DH_SUCCESS;
178 }
179
UnLoadDevice()180 int32_t DaudioHdfOperate::UnLoadDevice()
181 {
182 DHLOGI("UnLoadDevice for daudio begin!");
183 if (devmgr_ == nullptr) {
184 DHLOGE("hdi device manager is nullptr!");
185 return ERR_DH_AUDIO_NULLPTR;
186 }
187 int32_t ret = devmgr_->UnloadDevice(AUDIO_SERVICE_NAME);
188 if (ret != HDF_SUCCESS) {
189 DHLOGE("Unload audio service failed, ret: %{public}d", ret);
190 }
191 ret = devmgr_->UnloadDevice(AUDIOEXT_SERVICE_NAME);
192 if (ret != HDF_SUCCESS) {
193 DHLOGE("Unload device failed, ret: %{public}d", ret);
194 }
195 audioServStatus_.store(AUDIO_INVALID_VALUE);
196 audioextServStatus_.store(AUDIO_INVALID_VALUE);
197 DHLOGI("UnLoadDevice for daudio end!");
198 return DH_SUCCESS;
199 }
200
RegisterHdfListener()201 int32_t DaudioHdfOperate::RegisterHdfListener()
202 {
203 DHLOGI("RegisterHdfListener for daudio begin!");
204 audioSrvHdf_ = IDAudioManager::Get(AUDIOEXT_SERVICE_NAME.c_str(), false);
205 if (audioSrvHdf_ == nullptr) {
206 DHLOGE("Get hdi daudio manager failed.");
207 return ERR_DH_AUDIO_NULLPTR;
208 }
209 if (fwkDAudioHdfCallback_ == nullptr) {
210 if (MakeFwkDAudioHdfCallback() != DH_SUCCESS) {
211 DHLOGE("Create FwkDAudioHdfCallback failed.");
212 return ERR_DH_AUDIO_NULLPTR;
213 }
214 }
215 int32_t ret = audioSrvHdf_->RegisterAudioHdfListener(HDF_LISTENER_SERVICE_NAME, fwkDAudioHdfCallback_);
216 if (ret != DH_SUCCESS) {
217 DHLOGE("Call hdf proxy RegisterAudioHdfListener failed, ret: %{public}d.", ret);
218 return ret;
219 }
220 DHLOGI("RegisterHdfListener for daudio end!");
221 return DH_SUCCESS;
222 }
223
UnRegisterHdfListener()224 int32_t DaudioHdfOperate::UnRegisterHdfListener()
225 {
226 DHLOGI("UnRegisterHdfListener for daudio begin!");
227 if (audioSrvHdf_ == nullptr) {
228 DHLOGE("hdi daudio manager is nullptr!");
229 return ERR_DH_AUDIO_NULLPTR;
230 }
231 int32_t ret = audioSrvHdf_->UnRegisterAudioHdfListener(HDF_LISTENER_SERVICE_NAME);
232 if (ret != DH_SUCCESS) {
233 DHLOGE("Call hdf proxy UnRegisterAudioHdfListener failed, ret: %{public}d.", ret);
234 return ret;
235 }
236 DHLOGI("UnRegisterHdfListener for daudio end!");
237 return DH_SUCCESS;
238 }
239
AddHdfDeathBind()240 int32_t DaudioHdfOperate::AddHdfDeathBind()
241 {
242 DHLOGI("AddHdfDeathBind for daudio begin!");
243 if (audioSrvHdf_ == nullptr) {
244 DHLOGE("hdi daudio manager is nullptr!");
245 return ERR_DH_AUDIO_NULLPTR;
246 }
247 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<IDAudioManager>(audioSrvHdf_);
248 if (remote == nullptr) {
249 DHLOGE("Get remote from hdi daudio manager failed!");
250 return ERR_DH_AUDIO_NULLPTR;
251 }
252 if (remote->AddDeathRecipient(hdfDeathRecipient_) == false) {
253 DHLOGE("Call AddDeathRecipient failed!");
254 return ERR_DH_AUDIO_FAILED;
255 }
256 DHLOGI("AddHdfDeathBind for daudio end!");
257 return DH_SUCCESS;
258 }
259
RemoveHdfDeathBind()260 int32_t DaudioHdfOperate::RemoveHdfDeathBind()
261 {
262 DHLOGI("RemoveHdfDeathBind for daudio begin!");
263 if (audioSrvHdf_ == nullptr) {
264 DHLOGE("hdi daudio manager is nullptr!");
265 return ERR_DH_AUDIO_NULLPTR;
266 }
267 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<IDAudioManager>(audioSrvHdf_);
268 if (remote == nullptr) {
269 DHLOGE("Get remote from hdi daudio manager failed!");
270 return ERR_DH_AUDIO_NULLPTR;
271 }
272 if (remote->RemoveDeathRecipient(hdfDeathRecipient_) == false) {
273 DHLOGE("Call RemoveDeathRecipient failed!");
274 return ERR_DH_AUDIO_FAILED;
275 }
276 DHLOGI("RemoveHdfDeathBind for daudio end!");
277 return DH_SUCCESS;
278 }
279
MakeFwkDAudioHdfCallback()280 int32_t DaudioHdfOperate::MakeFwkDAudioHdfCallback()
281 {
282 std::lock_guard<std::mutex> locker(fwkDAudioHdfCallbackMutex_);
283 if (fwkDAudioHdfCallback_ == nullptr) {
284 fwkDAudioHdfCallback_ = sptr<FwkDAudioHdfCallback>(new FwkDAudioHdfCallback());
285 if (fwkDAudioHdfCallback_ == nullptr) {
286 return ERR_DH_AUDIO_NULLPTR;
287 }
288 }
289 return DH_SUCCESS;
290 }
291
OnReceive(const ServiceStatus & status)292 void DAudioHdfServStatListener::OnReceive(const ServiceStatus& status)
293 {
294 DHLOGI("Service status on receive.");
295 if (status.serviceName == AUDIO_SERVICE_NAME || status.serviceName == AUDIOEXT_SERVICE_NAME) {
296 callback_(status);
297 }
298 }
299
NotifyEvent(int32_t devId,const DAudioEvent & event)300 int32_t FwkDAudioHdfCallback::NotifyEvent(int32_t devId, const DAudioEvent& event)
301 {
302 (void)devId;
303 (void)event;
304 return DH_SUCCESS;
305 }
306
OnRemoteDied(const wptr<IRemoteObject> & remote)307 void HdfDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
308 {
309 DHLOGI("On remote died!");
310 DaudioHdfOperate::GetInstance().OnHdfHostDied();
311 }
312 } // namespace DistributedHardware
313 } // namespace OHOS