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