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