• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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