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 "BluetoothDeviceManager"
18 #endif
19
20 #include "adapter/bluetooth_device_manager.h"
21 #include "manager/hdi_monitor.h"
22 #include <dlfcn.h>
23 #include "audio_hdi_log.h"
24 #include "audio_errors.h"
25 #include "audio_utils.h"
26
27 using namespace OHOS::HDI::Audio_Bluetooth;
28
29 namespace OHOS {
30 namespace AudioStandard {
~BluetoothDeviceManager()31 BluetoothDeviceManager::~BluetoothDeviceManager()
32 {
33 if (handle_ != nullptr) {
34 #ifndef TEST_COVERAGE
35 dlclose(handle_);
36 #endif
37 handle_ = nullptr;
38 }
39 }
40
LoadAdapter(const std::string & adapterName)41 int32_t BluetoothDeviceManager::LoadAdapter(const std::string &adapterName)
42 {
43 CHECK_AND_RETURN_RET_LOG(adapters_.count(adapterName) == 0 || adapters_[adapterName] == nullptr, SUCCESS,
44 "adapter %{public}s already loaded", adapterName.c_str());
45 if (audioManager_ == nullptr || adapters_.size() == 0) {
46 audioManager_ = nullptr;
47 InitAudioManager();
48 }
49 CHECK_AND_RETURN_RET(audioManager_ != nullptr, ERR_INVALID_HANDLE);
50
51 struct AudioAdapterDescriptor *descs = nullptr;
52 int32_t size = 0;
53 int32_t ret = audioManager_->GetAllAdapters(audioManager_, &descs, &size);
54 CHECK_AND_RETURN_RET_LOG(size <= (int32_t)MAX_AUDIO_ADAPTER_NUM && size != 0 && ret == SUCCESS && descs != nullptr,
55 ERR_NOT_STARTED, "get adapters fail");
56 int32_t index = SwitchAdapterDesc(descs, adapterName, size);
57 CHECK_AND_RETURN_RET(index >= 0, ERR_NOT_STARTED);
58
59 struct AudioAdapter *adapter = nullptr;
60 ret = audioManager_->LoadAdapter(audioManager_, &(descs[index]), &adapter);
61 if (ret != SUCCESS) {
62 HdiMonitor::ReportHdiException(HdiType::A2DP, ErrorCase::CALL_HDI_FAILED, ret, (adapterName +
63 " load adapter fail, ret: " + std::to_string(ret)));
64 }
65 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && adapter != nullptr, ERR_NOT_STARTED, "load adapter fail");
66 ret = adapter->InitAllPorts(adapter);
67 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "init all ports fail");
68 std::lock_guard<std::mutex> lock(adapterMtx_);
69 adapters_[adapterName] = std::make_shared<BluetoothAdapterWrapper>();
70 adapters_[adapterName]->adapterDesc_ = descs[index];
71 adapters_[adapterName]->adapter_ = adapter;
72 AUDIO_INFO_LOG("load adapter %{public}s success", adapterName.c_str());
73 return SUCCESS;
74 }
75
UnloadAdapter(const std::string & adapterName,bool force)76 void BluetoothDeviceManager::UnloadAdapter(const std::string &adapterName, bool force)
77 {
78 CHECK_AND_RETURN_LOG(audioManager_ != nullptr, "audio manager is nullptr");
79
80 std::shared_ptr<BluetoothAdapterWrapper> wrapper = GetAdapter(adapterName);
81 CHECK_AND_RETURN_LOG(wrapper != nullptr, "adapter %{public}s is nullptr", adapterName.c_str());
82 std::unique_lock<std::mutex> innerLock(wrapper->adapterMtx_);
83 CHECK_AND_RETURN_LOG(wrapper->adapter_ != nullptr, "adapter %{public}s is nullptr", adapterName.c_str());
84 CHECK_AND_RETURN_LOG(force || (wrapper->renders_.size() == 0 && wrapper->captures_.size() == 0),
85 "adapter %{public}s has some ports busy, renderNum: %{public}zu, captureNum: %{public}zu", adapterName.c_str(),
86 wrapper->renders_.size(), wrapper->captures_.size());
87
88 audioManager_->UnloadAdapter(audioManager_, wrapper->adapter_);
89 wrapper->adapter_ = nullptr;
90 innerLock.unlock();
91 std::lock_guard<std::mutex> lock(adapterMtx_);
92 adapters_[adapterName].reset();
93 adapters_.erase(adapterName);
94 if (adapters_.size() == 0) {
95 audioManager_ = nullptr;
96 }
97 AUDIO_INFO_LOG("unload adapter %{public}s success", adapterName.c_str());
98 }
99
AllAdapterSetMicMute(bool isMute)100 void BluetoothDeviceManager::AllAdapterSetMicMute(bool isMute)
101 {
102 AUDIO_INFO_LOG("not support");
103 }
104
SetAudioParameter(const std::string & adapterName,const AudioParamKey key,const std::string & condition,const std::string & value)105 void BluetoothDeviceManager::SetAudioParameter(const std::string &adapterName, const AudioParamKey key,
106 const std::string &condition, const std::string &value)
107 {
108 AUDIO_INFO_LOG("not support");
109 }
110
GetAudioParameter(const std::string & adapterName,const AudioParamKey key,const std::string & condition)111 std::string BluetoothDeviceManager::GetAudioParameter(const std::string &adapterName, const AudioParamKey key,
112 const std::string &condition)
113 {
114 AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s", key, condition.c_str());
115
116 std::shared_ptr<BluetoothAdapterWrapper> wrapper = GetAdapter(adapterName);
117 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, "", "adapter %{public}s is nullptr",
118 adapterName.c_str());
119 AudioExtParamKey hdiKey = AudioExtParamKey(key);
120 char value[DumpFileUtil::PARAM_VALUE_LENTH];
121 int32_t ret = wrapper->adapter_->GetExtraParams(wrapper->adapter_, hdiKey, condition.c_str(), value,
122 DumpFileUtil::PARAM_VALUE_LENTH);
123 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "", "get param fail, error code: %{public}d", ret);
124 return value;
125 }
126
SetVoiceVolume(const std::string & adapterName,float volume)127 int32_t BluetoothDeviceManager::SetVoiceVolume(const std::string &adapterName, float volume)
128 {
129 AUDIO_INFO_LOG("not support");
130 return ERR_NOT_SUPPORTED;
131 }
132
SetOutputRoute(const std::string & adapterName,const std::vector<DeviceType> & devices,int32_t streamId)133 int32_t BluetoothDeviceManager::SetOutputRoute(const std::string &adapterName, const std::vector<DeviceType> &devices,
134 int32_t streamId)
135 {
136 AUDIO_INFO_LOG("not support");
137 return ERR_NOT_SUPPORTED;
138 }
139
SetInputRoute(const std::string & adapterName,DeviceType device,int32_t streamId,int32_t inputType)140 int32_t BluetoothDeviceManager::SetInputRoute(const std::string &adapterName, DeviceType device, int32_t streamId,
141 int32_t inputType)
142 {
143 AUDIO_INFO_LOG("not support");
144 return ERR_NOT_SUPPORTED;
145 }
146
SetMicMute(const std::string & adapterName,bool isMute)147 void BluetoothDeviceManager::SetMicMute(const std::string &adapterName, bool isMute)
148 {
149 AUDIO_INFO_LOG("not support");
150 }
151
CreateRender(const std::string & adapterName,void * param,void * deviceDesc,uint32_t & hdiRenderId)152 void *BluetoothDeviceManager::CreateRender(const std::string &adapterName, void *param, void *deviceDesc,
153 uint32_t &hdiRenderId)
154 {
155 CHECK_AND_RETURN_RET_LOG(param != nullptr && deviceDesc != nullptr, nullptr, "param or deviceDesc is nullptr");
156 struct AudioSampleAttributes *bluetoothParam = static_cast<struct AudioSampleAttributes *>(param);
157 struct AudioDeviceDescriptor *bluetoothDeviceDesc = static_cast<struct AudioDeviceDescriptor *>(deviceDesc);
158
159 std::shared_ptr<BluetoothAdapterWrapper> wrapper = GetAdapter(adapterName, true);
160 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, nullptr,
161 "adapter %{public}s is nullptr", adapterName.c_str());
162 bluetoothDeviceDesc->portId = GetPortId(adapterName, PORT_OUT);
163
164 struct AudioRender *render = nullptr;
165 int32_t ret = wrapper->adapter_->CreateRender(wrapper->adapter_, bluetoothDeviceDesc, bluetoothParam, &render);
166 if (ret != SUCCESS || render == nullptr) {
167 AUDIO_ERR_LOG("create render fail");
168 HdiMonitor::ReportHdiException(HdiType::A2DP, ErrorCase::CALL_HDI_FAILED, ret, (adapterName +
169 " create render fail, id:" + std::to_string(hdiRenderId)));
170 UnloadAdapter(adapterName);
171 return nullptr;
172 }
173 AUDIO_INFO_LOG("create render success, desc: %{public}s", bluetoothDeviceDesc->desc);
174
175 std::lock_guard<std::mutex> lock(wrapper->renderMtx_);
176 hdiRenderId = GetHdiRenderId(adapterName);
177 wrapper->renders_[hdiRenderId] = render;
178 return render;
179 }
180
DestroyRender(const std::string & adapterName,uint32_t hdiRenderId)181 void BluetoothDeviceManager::DestroyRender(const std::string &adapterName, uint32_t hdiRenderId)
182 {
183 AUDIO_INFO_LOG("destroy render, hdiRenderId: %{public}u", hdiRenderId);
184
185 std::shared_ptr<BluetoothAdapterWrapper> wrapper = GetAdapter(adapterName);
186 CHECK_AND_RETURN_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, "adapter %{public}s is nullptr",
187 adapterName.c_str());
188 CHECK_AND_RETURN_LOG(wrapper->renders_.count(hdiRenderId) != 0, "render not exist");
189 std::lock_guard<std::mutex> lock(wrapper->renderMtx_);
190 wrapper->adapter_->DestroyRender(wrapper->adapter_, wrapper->renders_[hdiRenderId]);
191 wrapper->renders_.erase(hdiRenderId);
192 wrapper->freeHdiRenderIdSet_.insert(hdiRenderId);
193 UnloadAdapter(adapterName);
194 }
195
CreateCapture(const std::string & adapterName,void * param,void * deviceDesc,uint32_t & hdiCaptureId)196 void *BluetoothDeviceManager::CreateCapture(const std::string &adapterName, void *param, void *deviceDesc,
197 uint32_t &hdiCaptureId)
198 {
199 CHECK_AND_RETURN_RET_LOG(param != nullptr && deviceDesc != nullptr, nullptr, "param or deviceDesc is nullptr");
200 struct AudioSampleAttributes *bluetoothParam = static_cast<struct AudioSampleAttributes *>(param);
201 struct AudioDeviceDescriptor *bluetoothDeviceDesc = static_cast<struct AudioDeviceDescriptor *>(deviceDesc);
202
203 std::shared_ptr<BluetoothAdapterWrapper> wrapper = GetAdapter(adapterName, true);
204 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, nullptr,
205 "adapter %{public}s is nullptr", adapterName.c_str());
206 bluetoothDeviceDesc->portId = GetPortId(adapterName, PORT_IN);
207
208 struct AudioCapture *capture = nullptr;
209 int32_t ret = wrapper->adapter_->CreateCapture(wrapper->adapter_, bluetoothDeviceDesc, bluetoothParam, &capture);
210 if (ret != SUCCESS || capture == nullptr) {
211 AUDIO_ERR_LOG("create capture fail");
212 HdiMonitor::ReportHdiException(HdiType::A2DP, ErrorCase::CALL_HDI_FAILED, ret, (adapterName +
213 " create capture fail, id:" + std::to_string(hdiCaptureId)));
214 UnloadAdapter(adapterName);
215 return nullptr;
216 }
217 AUDIO_INFO_LOG("create capture success, desc: %{public}s", bluetoothDeviceDesc->desc);
218
219 std::lock_guard<std::mutex> lock(wrapper->captureMtx_);
220 hdiCaptureId = GetHdiCaptureId(adapterName);
221 wrapper->captures_[hdiCaptureId] = capture;
222 return capture;
223 }
224
DestroyCapture(const std::string & adapterName,uint32_t hdiCaptureId)225 void BluetoothDeviceManager::DestroyCapture(const std::string &adapterName, uint32_t hdiCaptureId)
226 {
227 AUDIO_INFO_LOG("destroy capture, hdiCaptureId: %{public}u", hdiCaptureId);
228
229 std::shared_ptr<BluetoothAdapterWrapper> wrapper = GetAdapter(adapterName);
230 CHECK_AND_RETURN_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, "adapter %{public}s is nullptr",
231 adapterName.c_str());
232 CHECK_AND_RETURN_LOG(wrapper->captures_.count(hdiCaptureId) != 0, "capture not exist");
233 std::lock_guard<std::mutex> lock(wrapper->captureMtx_);
234 wrapper->adapter_->DestroyCapture(wrapper->adapter_, wrapper->captures_[hdiCaptureId]);
235 wrapper->captures_.erase(hdiCaptureId);
236 wrapper->freeHdiCaptureIdSet_.insert(hdiCaptureId);
237 UnloadAdapter(adapterName);
238 }
239
DumpInfo(std::string & dumpString)240 void BluetoothDeviceManager::DumpInfo(std::string &dumpString)
241 {
242 for (auto &item : adapters_) {
243 uint32_t renderNum = item.second == nullptr ? 0 : item.second->renders_.size();
244 uint32_t captureNum = item.second == nullptr ? 0 : item.second->captures_.size();
245 dumpString += " - bt/" + item.first + "\trenderNum: " + std::to_string(renderNum) + "\tcaptureNum: " +
246 std::to_string(captureNum) + "\n";
247 }
248 }
249
InitAudioManager(void)250 void BluetoothDeviceManager::InitAudioManager(void)
251 {
252 CHECK_AND_RETURN_LOG(audioManager_ == nullptr, "audio manager already inited");
253 AUDIO_INFO_LOG("init audio manager");
254
255 char resolvedPath[] = "libaudio_bluetooth_hdi_proxy_server.z.so";
256 handle_ = dlopen(resolvedPath, RTLD_LAZY);
257 CHECK_AND_RETURN_LOG(handle_ != nullptr, "dlopen %{public}s fail", resolvedPath);
258 struct AudioProxyManager *(*getAudioManager)() = nullptr;
259 getAudioManager = (struct AudioProxyManager *(*)())(dlsym(handle_, "GetAudioProxyManagerFuncs"));
260 CHECK_AND_RETURN_LOG(getAudioManager != nullptr, "dlsym fail");
261 audioManager_ = getAudioManager();
262 if (audioManager_ == nullptr) {
263 HdiMonitor::ReportHdiException(HdiType::A2DP, ErrorCase::CALL_HDI_FAILED, 0,
264 "get hdi manager fail");
265 }
266 CHECK_AND_RETURN_LOG(audioManager_ != nullptr, "get audio manager fail");
267 AUDIO_INFO_LOG("init audio manager succ");
268 }
269
GetAdapter(const std::string & adapterName,bool tryCreate)270 std::shared_ptr<BluetoothAdapterWrapper> BluetoothDeviceManager::GetAdapter(const std::string &adapterName,
271 bool tryCreate)
272 {
273 {
274 std::lock_guard<std::mutex> lock(adapterMtx_);
275 if (adapters_.count(adapterName) != 0 && adapters_[adapterName] != nullptr) {
276 return adapters_[adapterName];
277 }
278 }
279 if (!tryCreate) {
280 return nullptr;
281 }
282 LoadAdapter(adapterName);
283 std::lock_guard<std::mutex> lock(adapterMtx_);
284 return adapters_.count(adapterName) == 0 ? nullptr : adapters_[adapterName];
285 }
286
SwitchAdapterDesc(struct AudioAdapterDescriptor * descs,const std::string & adapterName,uint32_t size)287 int32_t BluetoothDeviceManager::SwitchAdapterDesc(struct AudioAdapterDescriptor *descs, const std::string &adapterName,
288 uint32_t size)
289 {
290 CHECK_AND_RETURN_RET(descs != nullptr, ERROR);
291
292 for (uint32_t index = 0; index < size; ++index) {
293 struct AudioAdapterDescriptor *desc = &descs[index];
294 if (desc == nullptr || desc->adapterName == nullptr) {
295 continue;
296 }
297 AUDIO_DEBUG_LOG("index: %{public}u, adapterName: %{public}s", index, desc->adapterName);
298 if (!strcmp(desc->adapterName, adapterName.c_str())) {
299 AUDIO_INFO_LOG("match adapter %{public}s", desc->adapterName);
300 return index;
301 }
302 }
303 AUDIO_ERR_LOG("switch adapter fail, adapterName: %{public}s", adapterName.c_str());
304 return ERR_INVALID_INDEX;
305 }
306
GetPortId(const std::string & adapterName,enum AudioPortDirection portFlag)307 uint32_t BluetoothDeviceManager::GetPortId(const std::string &adapterName, enum AudioPortDirection portFlag)
308 {
309 std::shared_ptr<BluetoothAdapterWrapper> wrapper = GetAdapter(adapterName);
310 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, 0, "adapter %{public}s is nullptr",
311 adapterName.c_str());
312 struct AudioAdapterDescriptor &desc = wrapper->adapterDesc_;
313 uint32_t portId = 0;
314 for (uint32_t port = 0; port < desc.portNum; ++port) {
315 if (desc.ports[port].dir == portFlag) {
316 portId = desc.ports[port].portId;
317 break;
318 }
319 }
320 AUDIO_DEBUG_LOG("portId: %{public}u", portId);
321 return portId;
322 }
323
GetHdiRenderId(const std::string & adapterName)324 uint32_t BluetoothDeviceManager::GetHdiRenderId(const std::string &adapterName)
325 {
326 std::shared_ptr<BluetoothAdapterWrapper> wrapper = GetAdapter(adapterName);
327 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr, 0, "adapter %{public}s is nullptr", adapterName.c_str());
328
329 if (wrapper->freeHdiRenderIdSet_.empty()) {
330 return wrapper->renders_.size();
331 }
332 uint32_t hdiRenderId = *(wrapper->freeHdiRenderIdSet_.begin());
333 wrapper->freeHdiRenderIdSet_.erase(hdiRenderId);
334 return hdiRenderId;
335 }
336
GetHdiCaptureId(const std::string & adapterName)337 uint32_t BluetoothDeviceManager::GetHdiCaptureId(const std::string &adapterName)
338 {
339 std::shared_ptr<BluetoothAdapterWrapper> wrapper = GetAdapter(adapterName);
340 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr, 0, "adapter %{public}s is nullptr", adapterName.c_str());
341
342 if (wrapper->freeHdiCaptureIdSet_.empty()) {
343 return wrapper->captures_.size();
344 }
345 uint32_t hdiCaptureId = *(wrapper->freeHdiCaptureIdSet_.begin());
346 wrapper->freeHdiCaptureIdSet_.erase(hdiCaptureId);
347 return hdiCaptureId;
348 }
349
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)350 void BluetoothDeviceManager::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
351 {
352 AUDIO_INFO_LOG("not support");
353 }
354
SetAudioScene(const AudioScene scene)355 void BluetoothDeviceManager::SetAudioScene(const AudioScene scene)
356 {
357 AUDIO_INFO_LOG("not support");
358 }
359 } // namespace AudioStandard
360 } // namespace OHOS
361