• 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     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