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