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 if (renderSinks_.count(id) == 0 && captureSources_.count(id) == 0) {
81 IdHandler::GetInstance().IncInfoIdUseCount(id);
82 }
83 CHECK_AND_RETURN_RET(isResident, id);
84 AUDIO_INFO_LOG("base: %{public}u, type: %{public}u, info: %{public}s", base, type, info.c_str());
85 IncRefCount(id);
86 return id;
87 }
88
GetRenderIdByDeviceClass(const std::string & deviceClass,const std::string & info,bool isResident)89 uint32_t HdiAdapterManager::GetRenderIdByDeviceClass(const std::string &deviceClass, const std::string &info,
90 bool isResident)
91 {
92 uint32_t id = IdHandler::GetInstance().GetRenderIdByDeviceClass(deviceClass, info);
93 CHECK_AND_RETURN_RET(id != HDI_INVALID_ID, HDI_INVALID_ID);
94 if (renderSinks_.count(id) == 0 && captureSources_.count(id) == 0) {
95 IdHandler::GetInstance().IncInfoIdUseCount(id);
96 }
97 CHECK_AND_RETURN_RET(isResident, id);
98 AUDIO_INFO_LOG("deviceClass: %{public}s, info: %{public}s", deviceClass.c_str(), info.c_str());
99 IncRefCount(id);
100 return id;
101 }
102
GetCaptureIdByDeviceClass(const std::string & deviceClass,const SourceType sourceType,const std::string & info,bool isResident)103 uint32_t HdiAdapterManager::GetCaptureIdByDeviceClass(const std::string &deviceClass, const SourceType sourceType,
104 const std::string &info, bool isResident)
105 {
106 uint32_t id = IdHandler::GetInstance().GetCaptureIdByDeviceClass(deviceClass, sourceType, info);
107 CHECK_AND_RETURN_RET(id != HDI_INVALID_ID, HDI_INVALID_ID);
108 if (renderSinks_.count(id) == 0 && captureSources_.count(id) == 0) {
109 IdHandler::GetInstance().IncInfoIdUseCount(id);
110 }
111 CHECK_AND_RETURN_RET(isResident, id);
112 AUDIO_INFO_LOG("deviceClass: %{public}s, sourceType: %{public}d, info: %{public}s", deviceClass.c_str(), sourceType,
113 info.c_str());
114 IncRefCount(id);
115 return id;
116 }
117
ReleaseId(uint32_t & id)118 void HdiAdapterManager::ReleaseId(uint32_t &id)
119 {
120 uint32_t tempId = id;
121 id = HDI_INVALID_ID;
122 CHECK_AND_RETURN(tempId != HDI_INVALID_ID && (renderSinks_.count(tempId) || captureSources_.count(tempId)));
123 DecRefCount(tempId);
124 }
125
GetRenderSink(uint32_t renderId,bool tryCreate)126 std::shared_ptr<IAudioRenderSink> HdiAdapterManager::GetRenderSink(uint32_t renderId, bool tryCreate)
127 {
128 CHECK_AND_RETURN_RET(IdHandler::GetInstance().CheckId(renderId, HDI_ID_BASE_RENDER), nullptr);
129
130 std::lock_guard<std::mutex> lock(renderSinkMtx_);
131 if (renderSinks_.count(renderId) != 0 && renderSinks_[renderId].sink_ != nullptr) {
132 return renderSinks_[renderId].sink_;
133 }
134 if (!tryCreate) {
135 AUDIO_ERR_LOG("no available sink, renderId: %{public}u", renderId);
136 return nullptr;
137 }
138 AUDIO_INFO_LOG("create sink, renderId: %{public}u", renderId);
139 HdiAdapterFactory &fac = HdiAdapterFactory::GetInstance();
140 std::shared_ptr<IAudioRenderSink> renderSink = fac.CreateRenderSink(renderId);
141 if (renderSink == nullptr) {
142 AUDIO_ERR_LOG("create sink fail, renderId: %{public}u", renderId);
143 return nullptr;
144 }
145 DoRegistSinkCallback(renderId, renderSink);
146 renderSinks_[renderId].sink_ = renderSink;
147 return renderSinks_[renderId].sink_;
148 }
149
GetCaptureSource(uint32_t captureId,bool tryCreate)150 std::shared_ptr<IAudioCaptureSource> HdiAdapterManager::GetCaptureSource(uint32_t captureId, bool tryCreate)
151 {
152 CHECK_AND_RETURN_RET(IdHandler::GetInstance().CheckId(captureId, HDI_ID_BASE_CAPTURE), nullptr);
153
154 std::lock_guard<std::mutex> lock(captureSourceMtx_);
155 if (captureSources_.count(captureId) != 0 && captureSources_[captureId].source_ != nullptr) {
156 return captureSources_[captureId].source_;
157 }
158 if (!tryCreate) {
159 AUDIO_ERR_LOG("no available source, captureId: %{public}u", captureId);
160 return nullptr;
161 }
162 AUDIO_INFO_LOG("create source, captureId: %{public}u", captureId);
163 HdiAdapterFactory &fac = HdiAdapterFactory::GetInstance();
164 std::shared_ptr<IAudioCaptureSource> captureSource = fac.CreateCaptureSource(captureId);
165 if (captureSource == nullptr) {
166 AUDIO_ERR_LOG("create source fail, captureId: %{public}u", captureId);
167 return nullptr;
168 }
169 DoRegistSourceCallback(captureId, captureSource);
170 captureSources_[captureId].source_ = captureSource;
171 return captureSources_[captureId].source_;
172 }
173
LoadAdapter(HdiDeviceManagerType type,const std::string & adapterName)174 int32_t HdiAdapterManager::LoadAdapter(HdiDeviceManagerType type, const std::string &adapterName)
175 {
176 std::shared_ptr<IDeviceManager> deviceManager = GetDeviceManager(type);
177 CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
178 return deviceManager->LoadAdapter(adapterName);
179 }
180
UnloadAdapter(HdiDeviceManagerType type,const std::string & adapterName,bool force)181 void HdiAdapterManager::UnloadAdapter(HdiDeviceManagerType type, const std::string &adapterName, bool force)
182 {
183 std::shared_ptr<IDeviceManager> deviceManager = GetDeviceManager(type);
184 CHECK_AND_RETURN(deviceManager != nullptr);
185 deviceManager->UnloadAdapter(adapterName, force);
186 }
187
ProcessSink(const std::function<int32_t (uint32_t,std::shared_ptr<IAudioRenderSink>)> & processFunc)188 int32_t HdiAdapterManager::ProcessSink(const std::function<int32_t(uint32_t,
189 std::shared_ptr<IAudioRenderSink>)> &processFunc)
190 {
191 int32_t ret = SUCCESS;
192 auto func = [&ret, &processFunc](const std::pair<const uint32_t, RenderSinkInfo> &item) -> void {
193 uint32_t renderId = item.first;
194 if (processFunc(renderId, item.second.sink_) != SUCCESS) {
195 AUDIO_ERR_LOG("process render sink fail, renderId: %{public}u", renderId);
196 ret = ERR_OPERATION_FAILED;
197 }
198 };
199 std::lock_guard<std::mutex> lock(renderSinkMtx_);
200 std::for_each(renderSinks_.begin(), renderSinks_.end(), func);
201 return ret;
202 }
203
ProcessSource(const std::function<int32_t (uint32_t,std::shared_ptr<IAudioCaptureSource>)> & processFunc)204 int32_t HdiAdapterManager::ProcessSource(const std::function<int32_t(uint32_t,
205 std::shared_ptr<IAudioCaptureSource>)> &processFunc)
206 {
207 int32_t ret = SUCCESS;
208 auto func = [&ret, &processFunc](const std::pair<const uint32_t, CaptureSourceInfo> &item) -> void {
209 uint32_t captureId = item.first;
210 if (processFunc(captureId, item.second.source_) != SUCCESS) {
211 AUDIO_ERR_LOG("process capture source fail, captureId: %{public}u", captureId);
212 ret = ERR_OPERATION_FAILED;
213 }
214 };
215 std::lock_guard<std::mutex> lock(captureSourceMtx_);
216 std::for_each(captureSources_.begin(), captureSources_.end(), func);
217 return ret;
218 }
219
RegistSinkCallback(HdiAdapterCallbackType type,std::shared_ptr<IAudioSinkCallback> cb,const std::function<bool (uint32_t)> & limitFunc)220 void HdiAdapterManager::RegistSinkCallback(HdiAdapterCallbackType type, std::shared_ptr<IAudioSinkCallback> cb,
221 const std::function<bool(uint32_t)> &limitFunc)
222 {
223 CHECK_AND_RETURN_LOG(cb != nullptr, "callback of type %{public}u is nullptr", type);
224
225 sinkCbs_.RegistCallback(type, cb);
226 cbLimitFunc_[HDI_ID_BASE_RENDER][type] = limitFunc;
227 AUDIO_INFO_LOG("regist sink callback succ, type: %{public}u", type);
228 }
229
RegistSinkCallback(HdiAdapterCallbackType type,IAudioSinkCallback * cb,const std::function<bool (uint32_t)> & limitFunc)230 void HdiAdapterManager::RegistSinkCallback(HdiAdapterCallbackType type, IAudioSinkCallback *cb,
231 const std::function<bool(uint32_t)> &limitFunc)
232 {
233 CHECK_AND_RETURN_LOG(cb != nullptr, "callback of type %{public}u is nullptr", type);
234
235 sinkCbs_.RegistCallback(type, cb);
236 cbLimitFunc_[HDI_ID_BASE_RENDER][type] = limitFunc;
237 AUDIO_INFO_LOG("regist sink callback succ, type: %{public}u", type);
238 }
239
RegistSourceCallback(HdiAdapterCallbackType type,std::shared_ptr<IAudioSourceCallback> cb,const std::function<bool (uint32_t)> & limitFunc)240 void HdiAdapterManager::RegistSourceCallback(HdiAdapterCallbackType type, std::shared_ptr<IAudioSourceCallback> cb,
241 const std::function<bool(uint32_t)> &limitFunc)
242 {
243 CHECK_AND_RETURN_LOG(cb != nullptr, "callback of type %{public}u is nullptr", type);
244
245 sourceCbs_.RegistCallback(type, cb);
246 cbLimitFunc_[HDI_ID_BASE_CAPTURE][type] = limitFunc;
247 AUDIO_INFO_LOG("regist source callback succ, type: %{public}u", type);
248 }
249
RegistSourceCallback(HdiAdapterCallbackType type,IAudioSourceCallback * cb,const std::function<bool (uint32_t)> & limitFunc)250 void HdiAdapterManager::RegistSourceCallback(HdiAdapterCallbackType type, IAudioSourceCallback *cb,
251 const std::function<bool(uint32_t)> &limitFunc)
252 {
253 CHECK_AND_RETURN_LOG(cb != nullptr, "callback of type %{public}u is nullptr", type);
254
255 sourceCbs_.RegistCallback(type, cb);
256 cbLimitFunc_[HDI_ID_BASE_CAPTURE][type] = limitFunc;
257 AUDIO_INFO_LOG("regist source callback succ, type: %{public}u", type);
258 }
259
DumpInfo(std::string & dumpString)260 void HdiAdapterManager::DumpInfo(std::string &dumpString)
261 {
262 dumpString += "- adapter\n";
263 deviceManagerMtx_.lock();
264 for (auto &item : deviceManagers_) {
265 if (item != nullptr) {
266 item->DumpInfo(dumpString);
267 }
268 }
269 deviceManagerMtx_.unlock();
270
271 if (!renderSinks_.empty()) {
272 dumpString += "\n- render\n";
273 renderSinkMtx_.lock();
274 for (auto &item : renderSinks_) {
275 if (item.second.sink_ == nullptr || !item.second.sink_->IsInited()) {
276 continue;
277 }
278 dumpString += " - id: " + std::to_string(item.first) + "\trefCount: " +
279 std::to_string(item.second.refCount_.load()) + "\t";
280 item.second.sink_->DumpInfo(dumpString);
281 }
282 renderSinkMtx_.unlock();
283 }
284
285 if (!captureSources_.empty()) {
286 dumpString += "\n- capture\n";
287 captureSourceMtx_.lock();
288 for (auto &item : captureSources_) {
289 if (item.second.source_ == nullptr || !item.second.source_->IsInited()) {
290 continue;
291 }
292 dumpString += " - id: " + std::to_string(item.first) + "\trefCount: " +
293 std::to_string(item.second.refCount_.load()) + "\t";
294 item.second.source_->DumpInfo(dumpString);
295 }
296 captureSourceMtx_.unlock();
297 }
298 }
299
IncRefCount(uint32_t id)300 void HdiAdapterManager::IncRefCount(uint32_t id)
301 {
302 uint32_t base = IdHandler::GetInstance().ParseBase(id);
303 if (base == HDI_ID_BASE_RENDER) {
304 std::lock_guard<std::mutex> lock(renderSinkMtx_);
305 renderSinks_[id].refCount_++;
306 } else {
307 std::lock_guard<std::mutex> lock(captureSourceMtx_);
308 captureSources_[id].refCount_++;
309 }
310 }
311
DecRefCount(uint32_t id)312 void HdiAdapterManager::DecRefCount(uint32_t id)
313 {
314 uint32_t base = IdHandler::GetInstance().ParseBase(id);
315 if (base == HDI_ID_BASE_RENDER) {
316 std::lock_guard<std::mutex> lock(renderSinkMtx_);
317 if (renderSinks_[id].refCount_.load() > 0) {
318 renderSinks_[id].refCount_--;
319 if (renderSinks_[id].refCount_.load() > 0) {
320 return;
321 }
322 }
323 AUDIO_INFO_LOG("no reference of id %{public}u, try remove the sink", id);
324 renderSinks_[id].sink_.reset();
325 renderSinks_.erase(id);
326 IdHandler::GetInstance().DecInfoIdUseCount(id);
327 } else {
328 std::lock_guard<std::mutex> lock(captureSourceMtx_);
329 if (captureSources_[id].refCount_.load() > 0) {
330 captureSources_[id].refCount_--;
331 if (captureSources_[id].refCount_.load() > 0) {
332 return;
333 }
334 }
335 AUDIO_INFO_LOG("no reference of id %{public}u, try remove the source", id);
336 captureSources_[id].source_.reset();
337 captureSources_.erase(id);
338 IdHandler::GetInstance().DecInfoIdUseCount(id);
339 }
340 }
341
DoRegistSinkCallback(uint32_t id,std::shared_ptr<IAudioRenderSink> sink)342 void HdiAdapterManager::DoRegistSinkCallback(uint32_t id, std::shared_ptr<IAudioRenderSink> sink)
343 {
344 CHECK_AND_RETURN_LOG(sink != nullptr, "sink is nullptr");
345
346 for (uint32_t type = 0; type < HDI_CB_TYPE_NUM; ++type) {
347 auto cb = sinkCbs_.GetCallback(type);
348 auto rawCb = sinkCbs_.GetRawCallback(type);
349 if (cbLimitFunc_[HDI_ID_BASE_RENDER][type] == nullptr || !cbLimitFunc_[HDI_ID_BASE_RENDER][type](id)) {
350 continue;
351 }
352 if (cb != nullptr) {
353 sink->RegistCallback(type, cb);
354 } else if (rawCb != nullptr) {
355 sink->RegistCallback(type, rawCb);
356 } else {
357 AUDIO_ERR_LOG("callback is nullptr, callback type: %{public}u", type);
358 }
359 }
360 }
361
DoRegistSourceCallback(uint32_t id,std::shared_ptr<IAudioCaptureSource> source)362 void HdiAdapterManager::DoRegistSourceCallback(uint32_t id, std::shared_ptr<IAudioCaptureSource> source)
363 {
364 CHECK_AND_RETURN_LOG(source != nullptr, "source is nullptr");
365
366 for (uint32_t type = 0; type < HDI_CB_TYPE_NUM; ++type) {
367 auto cb = sourceCbs_.GetCallback(type);
368 auto rawCb = sourceCbs_.GetRawCallback(type);
369 if (cbLimitFunc_[HDI_ID_BASE_CAPTURE][type] == nullptr || !cbLimitFunc_[HDI_ID_BASE_CAPTURE][type](id)) {
370 continue;
371 }
372 if (cb != nullptr) {
373 source->RegistCallback(type, cb);
374 } else if (rawCb != nullptr) {
375 source->RegistCallback(type, rawCb);
376 } else {
377 AUDIO_ERR_LOG("callback is nullptr, callback type: %{public}u", type);
378 }
379 }
380 }
381
382 } // namespace AudioStandard
383 } // namespace OHOS
384