1 /*
2 * Copyright (c) 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 #ifndef LOG_TAG
17 #define LOG_TAG "HdiAdapterManager"
18 #endif
19
20 #include "manager/hdi_adapter_manager.h"
21 #include "audio_hdi_log.h"
22 #include "audio_errors.h"
23 #include "util/id_handler.h"
24 #include "manager/hdi_adapter_factory.h"
25
26 namespace OHOS {
27 namespace AudioStandard {
~HdiAdapterManager()28 HdiAdapterManager::~HdiAdapterManager()
29 {
30 renderSinkMtx_.lock();
31 renderSinks_.clear();
32 renderSinkMtx_.unlock();
33
34 captureSourceMtx_.lock();
35 captureSources_.clear();
36 captureSourceMtx_.unlock();
37
38 std::lock_guard<std::mutex> lock(deviceManagerMtx_);
39 for (uint32_t i = 0; i < HDI_DEVICE_MANAGER_TYPE_NUM; ++i) {
40 if (deviceManagers_[i] == nullptr) {
41 continue;
42 }
43 deviceManagers_[i].reset();
44 }
45 }
46
GetInstance(void)47 HdiAdapterManager &HdiAdapterManager::GetInstance(void)
48 {
49 static HdiAdapterManager instance;
50 return instance;
51 }
52
GetDeviceManager(HdiDeviceManagerType type)53 std::shared_ptr<IDeviceManager> HdiAdapterManager::GetDeviceManager(HdiDeviceManagerType type)
54 {
55 CHECK_AND_RETURN_RET_LOG(type < HDI_DEVICE_MANAGER_TYPE_NUM, nullptr, "invalid type");
56
57 std::lock_guard<std::mutex> lock(deviceManagerMtx_);
58 if (deviceManagers_[type] == nullptr) {
59 HdiAdapterFactory &fac = HdiAdapterFactory::GetInstance();
60 deviceManagers_[type] = fac.CreateDeviceManager(type);
61 }
62 return deviceManagers_[type];
63 }
64
ReleaseDeviceManager(HdiDeviceManagerType type)65 void HdiAdapterManager::ReleaseDeviceManager(HdiDeviceManagerType type)
66 {
67 CHECK_AND_RETURN_LOG(type < HDI_DEVICE_MANAGER_TYPE_NUM, "invalid type");
68
69 std::lock_guard<std::mutex> lock(deviceManagerMtx_);
70 if (deviceManagers_[type] == nullptr) {
71 return;
72 }
73 deviceManagers_[type].reset();
74 }
75
GetId(HdiIdBase base,HdiIdType type,const std::string & info,bool isResident)76 uint32_t HdiAdapterManager::GetId(HdiIdBase base, HdiIdType type, const std::string &info, bool isResident)
77 {
78 uint32_t id = IdHandler::GetInstance().GetId(base, type, info);
79 CHECK_AND_RETURN_RET(id != HDI_INVALID_ID, HDI_INVALID_ID);
80 CHECK_AND_RETURN_RET(isResident, id);
81 std::unique_lock<std::mutex> renderLock(renderSinkMtx_);
82 std::unique_lock<std::mutex> captureLock(captureSourceMtx_);
83 if (renderSinks_.count(id) == 0 && captureSources_.count(id) == 0) {
84 IdHandler::GetInstance().IncInfoIdUseCount(id);
85 }
86 AUDIO_INFO_LOG("base: %{public}u, type: %{public}u, info: %{public}s, id: %{public}u", base, type, info.c_str(),
87 id);
88 IncRefCount(id);
89 return id;
90 }
91
GetRenderIdByDeviceClass(const std::string & deviceClass,const std::string & info,bool isResident)92 uint32_t HdiAdapterManager::GetRenderIdByDeviceClass(const std::string &deviceClass, const std::string &info,
93 bool isResident)
94 {
95 uint32_t id = IdHandler::GetInstance().GetRenderIdByDeviceClass(deviceClass, info);
96 AUDIO_INFO_LOG("Device class: %{public}s, info: %{public}s, id: %{public}u",
97 deviceClass.c_str(), info.c_str(), id);
98 CHECK_AND_RETURN_RET(id != HDI_INVALID_ID, HDI_INVALID_ID);
99 CHECK_AND_RETURN_RET(isResident, id);
100 std::unique_lock<std::mutex> renderLock(renderSinkMtx_);
101 std::unique_lock<std::mutex> captureLock(captureSourceMtx_);
102 if (renderSinks_.count(id) == 0 && captureSources_.count(id) == 0) {
103 IdHandler::GetInstance().IncInfoIdUseCount(id);
104 }
105 IncRefCount(id);
106 return id;
107 }
108
GetCaptureIdByDeviceClass(const std::string & deviceClass,const SourceType sourceType,const std::string & info,bool isResident)109 uint32_t HdiAdapterManager::GetCaptureIdByDeviceClass(const std::string &deviceClass, const SourceType sourceType,
110 const std::string &info, bool isResident)
111 {
112 uint32_t id = IdHandler::GetInstance().GetCaptureIdByDeviceClass(deviceClass, sourceType, info);
113 AUDIO_INFO_LOG("Device class: %{public}s, sourceType: %{public}d, info: %{public}s, id: %{public}u",
114 deviceClass.c_str(), sourceType, info.c_str(), id);
115 CHECK_AND_RETURN_RET(id != HDI_INVALID_ID, HDI_INVALID_ID);
116 CHECK_AND_RETURN_RET(isResident, id);
117 std::unique_lock<std::mutex> renderLock(renderSinkMtx_);
118 std::unique_lock<std::mutex> captureLock(captureSourceMtx_);
119 if (renderSinks_.count(id) == 0 && captureSources_.count(id) == 0) {
120 IdHandler::GetInstance().IncInfoIdUseCount(id);
121 }
122 IncRefCount(id);
123 return id;
124 }
125
ReleaseId(uint32_t & id)126 void HdiAdapterManager::ReleaseId(uint32_t &id)
127 {
128 uint32_t tempId = id;
129 id = HDI_INVALID_ID;
130 std::unique_lock<std::mutex> renderLock(renderSinkMtx_);
131 std::unique_lock<std::mutex> captureLock(captureSourceMtx_);
132 CHECK_AND_RETURN(tempId != HDI_INVALID_ID && (renderSinks_.count(tempId) || captureSources_.count(tempId)));
133 DecRefCount(tempId);
134 }
135
GetRenderSink(uint32_t renderId,bool tryCreate)136 std::shared_ptr<IAudioRenderSink> HdiAdapterManager::GetRenderSink(uint32_t renderId, bool tryCreate)
137 {
138 CHECK_AND_RETURN_RET(IdHandler::GetInstance().CheckId(renderId, HDI_ID_BASE_RENDER), nullptr);
139
140 std::lock_guard<std::mutex> lock(renderSinkMtx_);
141 if (renderSinks_.count(renderId) != 0 && renderSinks_[renderId].sink_ != nullptr) {
142 return renderSinks_[renderId].sink_;
143 }
144 if (!tryCreate) {
145 AUDIO_ERR_LOG("no available sink, renderId: %{public}u", renderId);
146 return nullptr;
147 }
148 AUDIO_INFO_LOG("create sink, renderId: %{public}u", renderId);
149 HdiAdapterFactory &fac = HdiAdapterFactory::GetInstance();
150 std::shared_ptr<IAudioRenderSink> renderSink = fac.CreateRenderSink(renderId);
151 if (renderSink == nullptr) {
152 AUDIO_ERR_LOG("create sink fail, renderId: %{public}u", renderId);
153 return nullptr;
154 }
155 DoRegistSinkCallback(renderId, renderSink);
156 DoSetSinkPrestoreInfo(renderSink);
157 renderSinks_[renderId].sink_ = renderSink;
158 return renderSinks_[renderId].sink_;
159 }
160
GetCaptureSource(uint32_t captureId,bool tryCreate)161 std::shared_ptr<IAudioCaptureSource> HdiAdapterManager::GetCaptureSource(uint32_t captureId, bool tryCreate)
162 {
163 CHECK_AND_RETURN_RET(IdHandler::GetInstance().CheckId(captureId, HDI_ID_BASE_CAPTURE), nullptr);
164
165 std::lock_guard<std::mutex> lock(captureSourceMtx_);
166 if (captureSources_.count(captureId) != 0 && captureSources_[captureId].source_ != nullptr) {
167 return captureSources_[captureId].source_;
168 }
169 if (!tryCreate) {
170 AUDIO_ERR_LOG("no available source, captureId: %{public}u", captureId);
171 return nullptr;
172 }
173 AUDIO_INFO_LOG("create source, captureId: %{public}u", captureId);
174 HdiAdapterFactory &fac = HdiAdapterFactory::GetInstance();
175 std::shared_ptr<IAudioCaptureSource> captureSource = fac.CreateCaptureSource(captureId);
176 if (captureSource == nullptr) {
177 AUDIO_ERR_LOG("create source fail, captureId: %{public}u", captureId);
178 return nullptr;
179 }
180 DoRegistSourceCallback(captureId, captureSource);
181 captureSources_[captureId].source_ = captureSource;
182 return captureSources_[captureId].source_;
183 }
184
LoadAdapter(HdiDeviceManagerType type,const std::string & adapterName)185 int32_t HdiAdapterManager::LoadAdapter(HdiDeviceManagerType type, const std::string &adapterName)
186 {
187 std::shared_ptr<IDeviceManager> deviceManager = GetDeviceManager(type);
188 CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
189 return deviceManager->LoadAdapter(adapterName);
190 }
191
UnloadAdapter(HdiDeviceManagerType type,const std::string & adapterName,bool force)192 void HdiAdapterManager::UnloadAdapter(HdiDeviceManagerType type, const std::string &adapterName, bool force)
193 {
194 std::shared_ptr<IDeviceManager> deviceManager = GetDeviceManager(type);
195 CHECK_AND_RETURN(deviceManager != nullptr);
196 deviceManager->UnloadAdapter(adapterName, force);
197 }
198
ProcessSink(const std::function<int32_t (uint32_t,std::shared_ptr<IAudioRenderSink>)> & processFunc)199 int32_t HdiAdapterManager::ProcessSink(const std::function<int32_t(uint32_t,
200 std::shared_ptr<IAudioRenderSink>)> &processFunc)
201 {
202 int32_t ret = SUCCESS;
203 auto func = [&ret, &processFunc](const std::pair<const uint32_t, RenderSinkInfo> &item) -> void {
204 uint32_t renderId = item.first;
205 if (processFunc(renderId, item.second.sink_) != SUCCESS) {
206 AUDIO_ERR_LOG("process render sink fail, renderId: %{public}u", renderId);
207 ret = ERR_OPERATION_FAILED;
208 }
209 };
210 std::lock_guard<std::mutex> lock(renderSinkMtx_);
211 std::for_each(renderSinks_.begin(), renderSinks_.end(), func);
212 return ret;
213 }
214
ProcessSource(const std::function<int32_t (uint32_t,std::shared_ptr<IAudioCaptureSource>)> & processFunc)215 int32_t HdiAdapterManager::ProcessSource(const std::function<int32_t(uint32_t,
216 std::shared_ptr<IAudioCaptureSource>)> &processFunc)
217 {
218 int32_t ret = SUCCESS;
219 auto func = [&ret, &processFunc](const std::pair<const uint32_t, CaptureSourceInfo> &item) -> void {
220 uint32_t captureId = item.first;
221 if (processFunc(captureId, item.second.source_) != SUCCESS) {
222 AUDIO_ERR_LOG("process capture source fail, captureId: %{public}u", captureId);
223 ret = ERR_OPERATION_FAILED;
224 }
225 };
226 std::lock_guard<std::mutex> lock(captureSourceMtx_);
227 std::for_each(captureSources_.begin(), captureSources_.end(), func);
228 return ret;
229 }
230
RegistSinkCallback(HdiAdapterCallbackType type,std::shared_ptr<IAudioSinkCallback> cb,const std::function<bool (uint32_t)> & limitFunc)231 void HdiAdapterManager::RegistSinkCallback(HdiAdapterCallbackType type, std::shared_ptr<IAudioSinkCallback> cb,
232 const std::function<bool(uint32_t)> &limitFunc)
233 {
234 CHECK_AND_RETURN_LOG(cb != nullptr, "callback of type %{public}u is nullptr", type);
235
236 sinkCbs_.RegistCallback(type, cb);
237 cbLimitFunc_[HDI_ID_BASE_RENDER][type] = limitFunc;
238 AUDIO_INFO_LOG("regist sink callback succ, type: %{public}u", type);
239 }
240
RegistSinkCallback(HdiAdapterCallbackType type,IAudioSinkCallback * cb,const std::function<bool (uint32_t)> & limitFunc)241 void HdiAdapterManager::RegistSinkCallback(HdiAdapterCallbackType type, IAudioSinkCallback *cb,
242 const std::function<bool(uint32_t)> &limitFunc)
243 {
244 CHECK_AND_RETURN_LOG(cb != nullptr, "callback of type %{public}u is nullptr", type);
245
246 sinkCbs_.RegistCallback(type, cb);
247 cbLimitFunc_[HDI_ID_BASE_RENDER][type] = limitFunc;
248 AUDIO_INFO_LOG("regist sink callback succ, type: %{public}u", type);
249 }
250
RegistSinkCallbackGenerator(HdiAdapterCallbackType type,const std::function<std::shared_ptr<IAudioSinkCallback> (uint32_t)> cbGenerator,const std::function<bool (uint32_t)> & limitFunc)251 void HdiAdapterManager::RegistSinkCallbackGenerator(HdiAdapterCallbackType type,
252 const std::function<std::shared_ptr<IAudioSinkCallback>(uint32_t)> cbGenerator,
253 const std::function<bool(uint32_t)> &limitFunc)
254 {
255 CHECK_AND_RETURN_LOG(cbGenerator, "callback generator of type %{public}u is nullptr", type);
256
257 sinkCbs_.RegistCallbackGenerator(type, cbGenerator);
258 cbLimitFunc_[HDI_ID_BASE_RENDER][type] = limitFunc;
259 AUDIO_INFO_LOG("regist sink callback generator succ, type: %{public}u", type);
260 }
261
RegistSourceCallback(HdiAdapterCallbackType type,std::shared_ptr<IAudioSourceCallback> cb,const std::function<bool (uint32_t)> & limitFunc)262 void HdiAdapterManager::RegistSourceCallback(HdiAdapterCallbackType type, std::shared_ptr<IAudioSourceCallback> cb,
263 const std::function<bool(uint32_t)> &limitFunc)
264 {
265 CHECK_AND_RETURN_LOG(cb != nullptr, "callback of type %{public}u is nullptr", type);
266
267 sourceCbs_.RegistCallback(type, cb);
268 cbLimitFunc_[HDI_ID_BASE_CAPTURE][type] = limitFunc;
269 AUDIO_INFO_LOG("regist source callback succ, type: %{public}u", type);
270 }
271
RegistSourceCallback(HdiAdapterCallbackType type,IAudioSourceCallback * cb,const std::function<bool (uint32_t)> & limitFunc)272 void HdiAdapterManager::RegistSourceCallback(HdiAdapterCallbackType type, IAudioSourceCallback *cb,
273 const std::function<bool(uint32_t)> &limitFunc)
274 {
275 CHECK_AND_RETURN_LOG(cb != nullptr, "callback of type %{public}u is nullptr", type);
276
277 sourceCbs_.RegistCallback(type, cb);
278 cbLimitFunc_[HDI_ID_BASE_CAPTURE][type] = limitFunc;
279 AUDIO_INFO_LOG("regist source callback succ, type: %{public}u", type);
280 }
281
RegistSourceCallbackGenerator(HdiAdapterCallbackType type,const std::function<std::shared_ptr<IAudioSourceCallback> (uint32_t)> cbGenerator,const std::function<bool (uint32_t)> & limitFunc)282 void HdiAdapterManager::RegistSourceCallbackGenerator(HdiAdapterCallbackType type,
283 const std::function<std::shared_ptr<IAudioSourceCallback>(uint32_t)> cbGenerator,
284 const std::function<bool(uint32_t)> &limitFunc)
285 {
286 CHECK_AND_RETURN_LOG(cbGenerator, "callback generator of type %{public}u is nullptr", type);
287
288 sourceCbs_.RegistCallbackGenerator(type, cbGenerator);
289 cbLimitFunc_[HDI_ID_BASE_CAPTURE][type] = limitFunc;
290 AUDIO_INFO_LOG("regist source callback generator succ, type: %{public}u", type);
291 }
292
DumpInfo(std::string & dumpString)293 void HdiAdapterManager::DumpInfo(std::string &dumpString)
294 {
295 dumpString += "- adapter\n";
296 deviceManagerMtx_.lock();
297 for (auto &item : deviceManagers_) {
298 if (item != nullptr) {
299 item->DumpInfo(dumpString);
300 }
301 }
302 deviceManagerMtx_.unlock();
303
304 if (!renderSinks_.empty()) {
305 dumpString += "\n- render\n";
306 renderSinkMtx_.lock();
307 for (auto &item : renderSinks_) {
308 if (item.second.sink_ == nullptr || !item.second.sink_->IsInited()) {
309 continue;
310 }
311 dumpString += " - id: " + std::to_string(item.first) + "\trefCount: " +
312 std::to_string(item.second.refCount_.load()) + "\t";
313 item.second.sink_->DumpInfo(dumpString);
314 }
315 renderSinkMtx_.unlock();
316 }
317
318 if (!captureSources_.empty()) {
319 dumpString += "\n- capture\n";
320 captureSourceMtx_.lock();
321 for (auto &item : captureSources_) {
322 if (item.second.source_ == nullptr || !item.second.source_->IsInited()) {
323 continue;
324 }
325 dumpString += " - id: " + std::to_string(item.first) + "\trefCount: " +
326 std::to_string(item.second.refCount_.load()) + "\t";
327 item.second.source_->DumpInfo(dumpString);
328 }
329 captureSourceMtx_.unlock();
330 }
331 }
332
IncRefCount(uint32_t id)333 void HdiAdapterManager::IncRefCount(uint32_t id)
334 {
335 uint32_t base = IdHandler::GetInstance().ParseBase(id);
336 if (base == HDI_ID_BASE_RENDER) {
337 renderSinks_[id].refCount_++;
338 } else {
339 captureSources_[id].refCount_++;
340 }
341 }
342
DecRefCount(uint32_t id)343 void HdiAdapterManager::DecRefCount(uint32_t id)
344 {
345 uint32_t base = IdHandler::GetInstance().ParseBase(id);
346 if (base == HDI_ID_BASE_RENDER) {
347 if (renderSinks_[id].refCount_.load() > 0) {
348 renderSinks_[id].refCount_--;
349 if (renderSinks_[id].refCount_.load() > 0) {
350 return;
351 }
352 }
353 AUDIO_INFO_LOG("no reference of id %{public}u, try remove the sink", id);
354 renderSinks_[id].sink_.reset();
355 renderSinks_.erase(id);
356 IdHandler::GetInstance().DecInfoIdUseCount(id);
357 } else {
358 if (captureSources_[id].refCount_.load() > 0) {
359 captureSources_[id].refCount_--;
360 if (captureSources_[id].refCount_.load() > 0) {
361 return;
362 }
363 }
364 AUDIO_INFO_LOG("no reference of id %{public}u, try remove the source", id);
365 captureSources_[id].source_.reset();
366 captureSources_.erase(id);
367 IdHandler::GetInstance().DecInfoIdUseCount(id);
368 }
369 }
370
DoRegistSinkCallback(uint32_t id,std::shared_ptr<IAudioRenderSink> sink)371 void HdiAdapterManager::DoRegistSinkCallback(uint32_t id, std::shared_ptr<IAudioRenderSink> sink)
372 {
373 CHECK_AND_RETURN_LOG(sink != nullptr, "sink is nullptr");
374
375 for (uint32_t type = 0; type < HDI_CB_TYPE_NUM; ++type) {
376 auto cb = sinkCbs_.GetCallback(type, id);
377 auto rawCb = sinkCbs_.GetRawCallback(type);
378 if (cbLimitFunc_[HDI_ID_BASE_RENDER][type] == nullptr || !cbLimitFunc_[HDI_ID_BASE_RENDER][type](id)) {
379 continue;
380 }
381 if (cb != nullptr) {
382 sink->RegistCallback(type, cb);
383 } else if (rawCb != nullptr) {
384 sink->RegistCallback(type, rawCb);
385 } else {
386 AUDIO_ERR_LOG("callback is nullptr, callback type: %{public}u", type);
387 }
388 }
389 }
390
DoRegistSourceCallback(uint32_t id,std::shared_ptr<IAudioCaptureSource> source)391 void HdiAdapterManager::DoRegistSourceCallback(uint32_t id, std::shared_ptr<IAudioCaptureSource> source)
392 {
393 CHECK_AND_RETURN_LOG(source != nullptr, "source is nullptr");
394
395 for (uint32_t type = 0; type < HDI_CB_TYPE_NUM; ++type) {
396 auto cb = sourceCbs_.GetCallback(type, id);
397 auto rawCb = sourceCbs_.GetRawCallback(type);
398 if (cbLimitFunc_[HDI_ID_BASE_CAPTURE][type] == nullptr || !cbLimitFunc_[HDI_ID_BASE_CAPTURE][type](id)) {
399 continue;
400 }
401 if (cb != nullptr) {
402 source->RegistCallback(type, cb);
403 } else if (rawCb != nullptr) {
404 source->RegistCallback(type, rawCb);
405 } else {
406 AUDIO_ERR_LOG("callback is nullptr, callback type: %{public}u", type);
407 }
408 }
409 }
410
DoSetSinkPrestoreInfo(std::shared_ptr<IAudioRenderSink> sink)411 void HdiAdapterManager::DoSetSinkPrestoreInfo(std::shared_ptr<IAudioRenderSink> sink)
412 {
413 float audioBalance = 0.0;
414 int32_t ret = sinkPrestoreInfo_.Get(PRESTORE_INFO_AUDIO_BALANCE, audioBalance);
415 if (ret == SUCCESS) {
416 sink->SetAudioBalanceValue(audioBalance);
417 } else {
418 AUDIO_WARNING_LOG("get %s fail", PRESTORE_INFO_AUDIO_BALANCE);
419 }
420
421 bool audioMono = false;
422 ret = sinkPrestoreInfo_.Get(PRESTORE_INFO_AUDIO_MONO, audioMono);
423 if (ret == SUCCESS) {
424 sink->SetAudioMonoState(audioMono);
425 } else {
426 AUDIO_WARNING_LOG("get %s fail", PRESTORE_INFO_AUDIO_MONO);
427 }
428 }
429
430 } // namespace AudioStandard
431 } // namespace OHOS
432