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 "LocalDeviceManager"
18 #endif
19
20 #include "adapter/local_device_manager.h"
21 #include "manager/hdi_monitor.h"
22 #include "audio_hdi_log.h"
23 #include "audio_errors.h"
24 #include "audio_utils.h"
25 #include "ipc_skeleton.h"
26
27 namespace OHOS {
28 namespace AudioStandard {
LoadAdapter(const std::string & adapterName)29 int32_t LocalDeviceManager::LoadAdapter(const std::string &adapterName)
30 {
31 CHECK_AND_RETURN_RET_LOG(adapters_.count(adapterName) == 0 || adapters_[adapterName] == nullptr, SUCCESS,
32 "adapter %{public}s already loaded", adapterName.c_str());
33
34 if (audioManager_ == nullptr) {
35 InitAudioManager();
36 }
37 CHECK_AND_RETURN_RET(audioManager_ != nullptr, ERR_INVALID_HANDLE);
38
39 struct AudioAdapterDescriptor descs[MAX_AUDIO_ADAPTER_NUM];
40 uint32_t size = MAX_AUDIO_ADAPTER_NUM;
41 int32_t ret = audioManager_->GetAllAdapters(audioManager_, (struct AudioAdapterDescriptor *)&descs, &size);
42 CHECK_AND_RETURN_RET_LOG(size <= MAX_AUDIO_ADAPTER_NUM && size != 0 && ret == SUCCESS, ERR_NOT_STARTED,
43 "get adapters fail");
44 int32_t index = SwitchAdapterDesc((struct AudioAdapterDescriptor *)&descs, adapterName, size);
45 CHECK_AND_RETURN_RET(index >= 0, ERR_NOT_STARTED);
46
47 struct IAudioAdapter *adapter = nullptr;
48 ret = audioManager_->LoadAdapter(audioManager_, &(descs[index]), &adapter);
49 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && adapter != nullptr, ERR_NOT_STARTED, "load adapter fail");
50 ret = adapter->InitAllPorts(adapter);
51 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "init all ports fail");
52 adapterMtx_.lock();
53 adapters_[adapterName] = std::make_shared<LocalAdapterWrapper>();
54 adapters_[adapterName]->adapterDesc_ = descs[index];
55 adapters_[adapterName]->adapter_ = adapter;
56 adapterMtx_.unlock();
57 // LCOV_EXCL_START
58 std::lock_guard<std::mutex> lock(reSetParamsMtx_);
59 for (auto it = reSetParams_.begin(); it != reSetParams_.end();) {
60 if (it->adapterName_ == adapterName) {
61 SetAudioParameter(adapterName, it->key_, it->condition_, it->value_);
62 it = reSetParams_.erase(it);
63 continue;
64 }
65 ++it;
66 }
67 // LCOV_EXCL_STOP
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 LocalDeviceManager::UnloadAdapter(const std::string &adapterName, bool force)
73 {
74 CHECK_AND_RETURN_LOG(audioManager_ != nullptr, "audio manager is nullptr");
75
76 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName);
77 CHECK_AND_RETURN_LOG(wrapper != nullptr, "adapter %{public}s is nullptr", adapterName.c_str());
78 std::unique_lock<std::mutex> innerLock(wrapper->adapterMtx_);
79 CHECK_AND_RETURN_LOG(wrapper->adapter_ != nullptr, "adapter %{public}s is nullptr", adapterName.c_str());
80 CHECK_AND_RETURN_LOG(force || (wrapper->hdiRenderIds_.size() == 0 && wrapper->hdiCaptureIds_.size() == 0),
81 "adapter %{public}s has some ports busy, renderNum: %{public}zu, captureNum: %{public}zu", adapterName.c_str(),
82 wrapper->hdiRenderIds_.size(), wrapper->hdiCaptureIds_.size());
83
84 if (wrapper->routeHandle_ != -1) {
85 wrapper->adapter_->ReleaseAudioRoute(wrapper->adapter_, wrapper->routeHandle_);
86 }
87 audioManager_->UnloadAdapter(audioManager_, wrapper->adapterDesc_.adapterName);
88 wrapper->adapter_ = nullptr;
89 innerLock.unlock();
90 std::lock_guard<std::mutex> lock(adapterMtx_);
91 adapters_[adapterName].reset();
92 adapters_.erase(adapterName);
93 AUDIO_INFO_LOG("unload adapter %{public}s success", adapterName.c_str());
94 }
95
AllAdapterSetMicMute(bool isMute)96 void LocalDeviceManager::AllAdapterSetMicMute(bool isMute)
97 {
98 AUDIO_INFO_LOG("isMute: %{public}s", isMute ? "true" : "false");
99
100 std::lock_guard<std::mutex> lock(adapterMtx_);
101 for (auto &item : adapters_) {
102 std::shared_ptr<LocalAdapterWrapper> wrapper = item.second;
103 if (wrapper == nullptr || wrapper->adapter_ == nullptr) {
104 continue;
105 }
106 int32_t ret = wrapper->adapter_->SetMicMute(wrapper->adapter_, isMute);
107 if (ret != SUCCESS) {
108 AUDIO_WARNING_LOG("set mute fail, adapterName: %{public}s", item.first.c_str());
109 } else {
110 AUDIO_INFO_LOG("set mute success, adapterName: %{public}s", item.first.c_str());
111 }
112 }
113 }
114
SetAudioParameter(const std::string & adapterName,const AudioParamKey key,const std::string & condition,const std::string & value)115 void LocalDeviceManager::SetAudioParameter(const std::string &adapterName, const AudioParamKey key,
116 const std::string &condition, const std::string &value)
117 {
118 AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str());
119
120 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName);
121 // LCOV_EXCL_START
122 if (wrapper == nullptr || wrapper->adapter_ == nullptr) {
123 AUDIO_ERR_LOG("adapter %{public}s is nullptr", adapterName.c_str());
124 SaveSetParameter(adapterName, key, condition, value);
125 return;
126 }
127 // LCOV_EXCL_STOP
128 AudioExtParamKey hdiKey = AudioExtParamKey(key);
129 int32_t ret = wrapper->adapter_->SetExtraParams(wrapper->adapter_, hdiKey, condition.c_str(), value.c_str());
130 CHECK_AND_RETURN_LOG(ret == SUCCESS, "set param fail, error code: %{public}d", ret);
131 }
132
GetAudioParameter(const std::string & adapterName,const AudioParamKey key,const std::string & condition)133 std::string LocalDeviceManager::GetAudioParameter(const std::string &adapterName, const AudioParamKey key,
134 const std::string &condition)
135 {
136 AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s", key, condition.c_str());
137
138 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName);
139 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, "", "adapter %{public}s is nullptr",
140 adapterName.c_str());
141 AudioExtParamKey hdiKey = AudioExtParamKey(key);
142 char value[DumpFileUtil::PARAM_VALUE_LENTH];
143 int32_t ret = wrapper->adapter_->GetExtraParams(wrapper->adapter_, hdiKey, condition.c_str(), value,
144 DumpFileUtil::PARAM_VALUE_LENTH);
145 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "", "get param fail, error code: %{public}d", ret);
146 return value;
147 }
148
SetVoiceVolume(const std::string & adapterName,float volume)149 int32_t LocalDeviceManager::SetVoiceVolume(const std::string &adapterName, float volume)
150 {
151 AUDIO_INFO_LOG("set modem call, volume: %{public}f", volume);
152
153 Trace trace("LocalDeviceManager::SetVoiceVolume");
154 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName);
155 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, ERR_INVALID_HANDLE,
156 "adapter %{public}s is nullptr", adapterName.c_str());
157 return wrapper->adapter_->SetVoiceVolume(wrapper->adapter_, volume);
158 }
159
SetOutputRoute(const std::string & adapterName,const std::vector<DeviceType> & devices,int32_t streamId)160 int32_t LocalDeviceManager::SetOutputRoute(const std::string &adapterName, const std::vector<DeviceType> &devices,
161 int32_t streamId)
162 {
163 CHECK_AND_RETURN_RET_LOG(!devices.empty() && devices.size() <= AUDIO_CONCURRENT_ACTIVE_DEVICES_LIMIT,
164 ERR_INVALID_PARAM, "invalid audio devices");
165
166 Trace trace("LocalDeviceManager::SetOutputRoute device " + std::to_string(devices[0]));
167 AudioRouteNode source = {
168 .portId = 0,
169 .role = AUDIO_PORT_SOURCE_ROLE,
170 .type = AUDIO_PORT_MIX_TYPE,
171 .ext.mix.moduleId = 0,
172 .ext.mix.streamId = streamId,
173 .ext.device.desc = (char *)"",
174 };
175 AudioRouteNode sinks[devices.size()];
176 for (size_t i = 0; i < devices.size(); ++i) {
177 sinks[i] = {};
178 int32_t ret = SetOutputPortPin(devices[i], sinks[i]);
179 CHECK_AND_RETURN_RET(ret == SUCCESS, ret);
180 AUDIO_INFO_LOG("output[%{public}zu], device: %{public}d, pin: 0x%{public}X", i, devices[i],
181 sinks[i].ext.device.type);
182 sinks[i].portId = static_cast<int32_t>(GetPortId(adapterName, PORT_OUT));
183 sinks[i].role = AUDIO_PORT_SINK_ROLE;
184 sinks[i].type = AUDIO_PORT_DEVICE_TYPE;
185 sinks[i].ext.device.moduleId = 0;
186 sinks[i].ext.device.desc = (char *)"";
187 }
188 AudioRoute route = {
189 .sources = &source,
190 .sourcesLen = 1,
191 .sinks = sinks,
192 .sinksLen = devices.size(),
193 };
194
195 int64_t stamp = ClockTime::GetCurNano();
196 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName);
197 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, ERR_INVALID_HANDLE,
198 "adapter %{public}s is nullptr", adapterName.c_str());
199 int32_t ret = wrapper->adapter_->UpdateAudioRoute(wrapper->adapter_, &route, &(wrapper->routeHandle_));
200 stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
201 AUDIO_INFO_LOG("update route, adapterName: %{public}s, device: %{public}d, cost: [%{public}" PRId64 "]ms",
202 adapterName.c_str(), devices[0], stamp);
203
204 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "update route fail");
205 return SUCCESS;
206 }
207
SetInputRoute(const std::string & adapterName,DeviceType device,int32_t streamId,int32_t inputType)208 int32_t LocalDeviceManager::SetInputRoute(const std::string &adapterName, DeviceType device, int32_t streamId,
209 int32_t inputType)
210 {
211 AudioRouteNode source = {};
212 int32_t ret = SetInputPortPin(device, source);
213 CHECK_AND_RETURN_RET(ret == SUCCESS, ret);
214 AUDIO_INFO_LOG("input, device: %{public}d, pin: 0x%{public}X", device, source.ext.device.type);
215 source.portId = static_cast<int32_t>(GetPortId(adapterName, PORT_IN));
216 source.role = AUDIO_PORT_SOURCE_ROLE;
217 source.type = AUDIO_PORT_DEVICE_TYPE;
218 source.ext.mix.moduleId = 0;
219 source.ext.device.desc = (char *)"";
220 AudioRouteNode sink = {
221 .portId = 0,
222 .role = AUDIO_PORT_SINK_ROLE,
223 .type = AUDIO_PORT_MIX_TYPE,
224 .ext.mix.moduleId = 0,
225 .ext.mix.streamId = streamId,
226 .ext.mix.source = inputType,
227 .ext.device.desc = (char *)"",
228 };
229 AudioRoute route = {
230 .sources = &source,
231 .sourcesLen = 1,
232 .sinks = &sink,
233 .sinksLen = 1,
234 };
235
236 int64_t stamp = ClockTime::GetCurNano();
237 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName);
238 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, ERR_INVALID_HANDLE,
239 "adapter %{public}s is nullptr", adapterName.c_str());
240 ret = wrapper->adapter_->UpdateAudioRoute(wrapper->adapter_, &route, &(wrapper->routeHandle_));
241 stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
242 AUDIO_INFO_LOG("update route, adapterName: %{public}s, device: %{public}d, cost: [%{public}" PRId64 "]ms",
243 adapterName.c_str(), device, stamp);
244
245 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "update route fail");
246 return SUCCESS;
247 }
248
SetMicMute(const std::string & adapterName,bool isMute)249 void LocalDeviceManager::SetMicMute(const std::string &adapterName, bool isMute)
250 {
251 AUDIO_INFO_LOG("isMute: %{public}s", isMute ? "true" : "false");
252
253 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName);
254 CHECK_AND_RETURN_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, "adapter %{public}s is nullptr",
255 adapterName.c_str());
256 int32_t ret = wrapper->adapter_->SetMicMute(wrapper->adapter_, isMute);
257 if (ret != SUCCESS) {
258 AUDIO_WARNING_LOG("set mute fail");
259 } else {
260 AUDIO_INFO_LOG("set mute success");
261 }
262 }
263
CreateRender(const std::string & adapterName,void * param,void * deviceDesc,uint32_t & hdiRenderId)264 void *LocalDeviceManager::CreateRender(const std::string &adapterName, void *param, void *deviceDesc,
265 uint32_t &hdiRenderId)
266 {
267 CHECK_AND_RETURN_RET_LOG(param != nullptr && deviceDesc != nullptr, nullptr, "param or deviceDesc is nullptr");
268 struct AudioSampleAttributes *localParam = static_cast<struct AudioSampleAttributes *>(param);
269 struct AudioDeviceDescriptor *localDeviceDesc = static_cast<struct AudioDeviceDescriptor *>(deviceDesc);
270
271 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName, true);
272 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, nullptr,
273 "adapter %{public}s is nullptr", adapterName.c_str());
274 localDeviceDesc->portId = GetPortId(adapterName, PORT_OUT);
275
276 struct IAudioRender *render = nullptr;
277 int32_t ret = wrapper->adapter_->CreateRender(wrapper->adapter_, localDeviceDesc, localParam, &render,
278 &hdiRenderId);
279 if (ret != SUCCESS || render == nullptr) {
280 AUDIO_ERR_LOG("create render fail");
281 HdiMonitor::ReportHdiException(HdiType::LOCAL, ErrorCase::CALL_HDI_FAILED, ret, (adapterName +
282 " create render fail, id:" + std::to_string(hdiRenderId)));
283 UnloadAdapter(adapterName);
284 return nullptr;
285 }
286 AUDIO_INFO_LOG("create render success, hdiRenderId: %{public}u, desc: %{public}s", hdiRenderId,
287 localDeviceDesc->desc);
288
289 std::lock_guard<std::mutex> lock(wrapper->renderMtx_);
290 wrapper->hdiRenderIds_.insert(hdiRenderId);
291 return render;
292 }
293
DestroyRender(const std::string & adapterName,uint32_t hdiRenderId)294 void LocalDeviceManager::DestroyRender(const std::string &adapterName, uint32_t hdiRenderId)
295 {
296 AUDIO_INFO_LOG("destroy render, hdiRenderId: %{public}u", hdiRenderId);
297
298 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName);
299 CHECK_AND_RETURN_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, "adapter %{public}s is nullptr",
300 adapterName.c_str());
301 CHECK_AND_RETURN_LOG(wrapper->hdiRenderIds_.count(hdiRenderId) != 0, "render not exist");
302 wrapper->adapter_->DestroyRender(wrapper->adapter_, hdiRenderId);
303
304 std::lock_guard<std::mutex> lock(wrapper->renderMtx_);
305 wrapper->hdiRenderIds_.erase(hdiRenderId);
306 }
307
CreateCapture(const std::string & adapterName,void * param,void * deviceDesc,uint32_t & hdiCaptureId)308 void *LocalDeviceManager::CreateCapture(const std::string &adapterName, void *param, void *deviceDesc,
309 uint32_t &hdiCaptureId)
310 {
311 CHECK_AND_RETURN_RET_LOG(param != nullptr && deviceDesc != nullptr, nullptr, "param or deviceDesc is nullptr");
312 struct AudioSampleAttributes *localParam = static_cast<struct AudioSampleAttributes *>(param);
313 struct AudioDeviceDescriptor *localDeviceDesc = static_cast<struct AudioDeviceDescriptor *>(deviceDesc);
314
315 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName, true);
316 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, nullptr,
317 "adapter %{public}s is nullptr", adapterName.c_str());
318 localDeviceDesc->portId = GetPortId(adapterName, PORT_IN);
319
320 struct IAudioCapture *capture = nullptr;
321 int32_t ret = wrapper->adapter_->CreateCapture(wrapper->adapter_, localDeviceDesc, localParam, &capture,
322 &hdiCaptureId);
323 if (ret != SUCCESS || capture == nullptr) {
324 AUDIO_ERR_LOG("create capture fail");
325 HdiMonitor::ReportHdiException(HdiType::LOCAL, ErrorCase::CALL_HDI_FAILED, ret, (adapterName +
326 " create capture fail, id:" + std::to_string(hdiCaptureId)));
327 UnloadAdapter(adapterName);
328 return nullptr;
329 }
330 AUDIO_INFO_LOG("create capture success, hdiCaptureId: %{public}u, desc: %{public}s", hdiCaptureId,
331 localDeviceDesc->desc);
332
333 std::lock_guard<std::mutex> lock(wrapper->captureMtx_);
334 wrapper->hdiCaptureIds_.insert(hdiCaptureId);
335 return capture;
336 }
337
DestroyCapture(const std::string & adapterName,uint32_t hdiCaptureId)338 void LocalDeviceManager::DestroyCapture(const std::string &adapterName, uint32_t hdiCaptureId)
339 {
340 AUDIO_INFO_LOG("destroy capture, hdiCaptureId: %{public}u", hdiCaptureId);
341
342 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName);
343 CHECK_AND_RETURN_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, "adapter %{public}s is nullptr",
344 adapterName.c_str());
345 CHECK_AND_RETURN_LOG(wrapper->hdiCaptureIds_.count(hdiCaptureId) != 0, "capture not exist");
346 wrapper->adapter_->DestroyCapture(wrapper->adapter_, hdiCaptureId);
347
348 std::lock_guard<std::mutex> lock(wrapper->captureMtx_);
349 wrapper->hdiCaptureIds_.erase(hdiCaptureId);
350 }
351
DumpInfo(std::string & dumpString)352 void LocalDeviceManager::DumpInfo(std::string &dumpString)
353 {
354 for (auto &item : adapters_) {
355 uint32_t renderNum = item.second == nullptr ? 0 : item.second->hdiRenderIds_.size();
356 uint32_t captureNum = item.second == nullptr ? 0 : item.second->hdiCaptureIds_.size();
357 dumpString += " - local/" + item.first + "\trenderNum: " + std::to_string(renderNum) + "\tcaptureNum: " +
358 std::to_string(captureNum) + "\n";
359 }
360 }
361
AudioHostOnRemoteDied(struct HdfDeathRecipient * recipent,struct HdfRemoteService * service)362 static void AudioHostOnRemoteDied(struct HdfDeathRecipient *recipent, struct HdfRemoteService *service)
363 {
364 CHECK_AND_RETURN_LOG(recipent != nullptr && service != nullptr, "receive die message but params are nullptr");
365 AUDIO_ERR_LOG("auto exit for audio host die");
366 _Exit(0);
367 }
368
InitAudioManager(void)369 void LocalDeviceManager::InitAudioManager(void)
370 {
371 CHECK_AND_RETURN_LOG(audioManager_ == nullptr, "audio manager already inited");
372 AUDIO_INFO_LOG("init audio manager");
373 audioManager_ = IAudioManagerGet(false);
374 if (audioManager_ == nullptr) {
375 HdiMonitor::ReportHdiException(HdiType::LOCAL, ErrorCase::CALL_HDI_FAILED, 0,
376 "get hdi manager fail");
377 }
378 CHECK_AND_RETURN_LOG(audioManager_ != nullptr, "get audio manager fail");
379
380 CHECK_AND_RETURN_LOG(hdfRemoteService_ == nullptr, "hdf remote service already inited");
381 hdfRemoteService_ = audioManager_->AsObject(audioManager_);
382 // Don't need to free, existing with process
383 hdfDeathRecipient_ = (struct HdfDeathRecipient *)calloc(1, sizeof(*hdfDeathRecipient_));
384 CHECK_AND_RETURN_LOG(hdfDeathRecipient_ != nullptr, "create hdf death recipient fail");
385 hdfDeathRecipient_->OnRemoteDied = AudioHostOnRemoteDied;
386 HdfRemoteServiceAddDeathRecipient(hdfRemoteService_, hdfDeathRecipient_);
387
388 AUDIO_INFO_LOG("init audio manager succ");
389 }
390
GetAdapter(const std::string & adapterName,bool tryCreate)391 std::shared_ptr<LocalAdapterWrapper> LocalDeviceManager::GetAdapter(const std::string &adapterName, bool tryCreate)
392 {
393 {
394 std::lock_guard<std::mutex> lock(adapterMtx_);
395 if (adapters_.count(adapterName) != 0 && adapters_[adapterName] != nullptr) {
396 return adapters_[adapterName];
397 }
398 }
399 if (!tryCreate) {
400 return nullptr;
401 }
402 LoadAdapter(adapterName);
403 std::lock_guard<std::mutex> lock(adapterMtx_);
404 return adapters_.count(adapterName) == 0 ? nullptr : adapters_[adapterName];
405 }
406
SwitchAdapterDesc(struct AudioAdapterDescriptor * descs,const std::string & adapterName,uint32_t size)407 int32_t LocalDeviceManager::SwitchAdapterDesc(struct AudioAdapterDescriptor *descs, const std::string &adapterName,
408 uint32_t size)
409 {
410 CHECK_AND_RETURN_RET(descs != nullptr, ERROR);
411
412 for (uint32_t index = 0; index < size; ++index) {
413 struct AudioAdapterDescriptor *desc = &descs[index];
414 if (desc == nullptr || desc->adapterName == nullptr) {
415 continue;
416 }
417 AUDIO_DEBUG_LOG("index: %{public}u, adapterName: %{public}s", index, desc->adapterName);
418 if (!strcmp(desc->adapterName, adapterName.c_str())) {
419 AUDIO_INFO_LOG("match adapter %{public}s", desc->adapterName);
420 return index;
421 }
422 }
423 AUDIO_ERR_LOG("switch adapter fail, adapterName: %{public}s", adapterName.c_str());
424 return ERR_INVALID_INDEX;
425 }
426
GetPortId(const std::string & adapterName,enum AudioPortDirection portFlag)427 uint32_t LocalDeviceManager::GetPortId(const std::string &adapterName, enum AudioPortDirection portFlag)
428 {
429 std::shared_ptr<LocalAdapterWrapper> wrapper = GetAdapter(adapterName);
430 CHECK_AND_RETURN_RET_LOG(wrapper != nullptr && wrapper->adapter_ != nullptr, 0,
431 "adapter %{public}s is nullptr", adapterName.c_str());
432 struct AudioAdapterDescriptor &desc = wrapper->adapterDesc_;
433 uint32_t portId = 0;
434 for (uint32_t port = 0; port < desc.portsLen; ++port) {
435 if (desc.ports[port].dir == portFlag) {
436 portId = desc.ports[port].portId;
437 break;
438 }
439 }
440 AUDIO_DEBUG_LOG("portId: %{public}u", portId);
441 return portId;
442 }
443
444 static const std::unordered_map<DeviceType, std::pair<AudioPortPin, const char *>> devicePinMap = {
445 {DEVICE_TYPE_EARPIECE, {PIN_OUT_EARPIECE, "pin_out_earpiece"}},
446 {DEVICE_TYPE_SPEAKER, {PIN_OUT_SPEAKER, "pin_out_speaker"}},
447 {DEVICE_TYPE_WIRED_HEADSET, {PIN_OUT_HEADSET, "pin_out_headset"}},
448 {DEVICE_TYPE_WIRED_HEADPHONES, {PIN_OUT_HEADPHONE, "pin_out_headphone"}},
449 {DEVICE_TYPE_USB_ARM_HEADSET, {PIN_OUT_USB_HEADSET, "pin_out_usb_headset"}},
450 {DEVICE_TYPE_USB_HEADSET, {PIN_OUT_USB_EXT, "pin_out_usb_ext"}},
451 {DEVICE_TYPE_BLUETOOTH_SCO, {PIN_OUT_BLUETOOTH_SCO, "pin_out_bluetooth_sco"}},
452 {DEVICE_TYPE_BLUETOOTH_A2DP, {PIN_OUT_BLUETOOTH_A2DP, "pin_out_bluetooth_a2dp"}},
453 {DEVICE_TYPE_HDMI, {PIN_OUT_HDMI, "pin_out_hdmi"}},
454 {DEVICE_TYPE_NONE, {PIN_NONE, "pin_out_none"}}
455 };
456
SetOutputPortPin(DeviceType outputDevice,AudioRouteNode & sink)457 int32_t LocalDeviceManager::SetOutputPortPin(DeviceType outputDevice, AudioRouteNode &sink)
458 {
459 if (outputDevice == DEVICE_TYPE_NEARLINK) {
460 HandleNearlinkScene(outputDevice, sink);
461 return SUCCESS;
462 }
463
464 auto it = devicePinMap.find(outputDevice);
465 if (it != devicePinMap.end()) {
466 sink.ext.device.type = it->second.first;
467 sink.ext.device.desc = const_cast<char*>(it->second.second);
468 return SUCCESS;
469 }
470
471 return ERR_NOT_SUPPORTED;
472 }
473
HandleNearlinkScene(DeviceType deviceType,AudioRouteNode & node)474 int32_t LocalDeviceManager::HandleNearlinkScene(DeviceType deviceType, AudioRouteNode &node)
475 {
476 if (currentAudioScene_.load() != AUDIO_SCENE_DEFAULT ||
477 dmDeviceTypeMap_[DEVICE_TYPE_NEARLINK_IN] == DM_DEVICE_TYPE_NEARLINK_SCO) {
478 node.ext.device.type = PIN_OUT_NEARLINK_SCO;
479 node.ext.device.desc = (char *)"pin_out_nearlink_sco";
480 return SUCCESS;
481 }
482 if (deviceType == DEVICE_TYPE_NEARLINK) {
483 node.ext.device.type = PIN_OUT_NEARLINK;
484 node.ext.device.desc = (char *)"pin_out_nearlink";
485 } else {
486 node.ext.device.type = PIN_IN_NEARLINK;
487 node.ext.device.desc = (char *)"pin_in_nearlink";
488 }
489 return SUCCESS;
490 }
491
SetInputPortPin(DeviceType inputDevice,AudioRouteNode & source)492 int32_t LocalDeviceManager::SetInputPortPin(DeviceType inputDevice, AudioRouteNode &source)
493 {
494 int32_t ret = SUCCESS;
495 switch (inputDevice) {
496 case DEVICE_TYPE_MIC:
497 case DEVICE_TYPE_EARPIECE:
498 case DEVICE_TYPE_SPEAKER:
499 case DEVICE_TYPE_BLUETOOTH_A2DP_IN:
500 source.ext.device.type = PIN_IN_MIC;
501 source.ext.device.desc = (char *)"pin_in_mic";
502 break;
503 case DEVICE_TYPE_WIRED_HEADSET:
504 source.ext.device.type = PIN_IN_HS_MIC;
505 source.ext.device.desc = (char *)"pin_in_hs_mic";
506 break;
507 case DEVICE_TYPE_USB_ARM_HEADSET:
508 source.ext.device.type = PIN_IN_USB_HEADSET;
509 source.ext.device.desc = (char *)"pin_in_usb_headset";
510 break;
511 case DEVICE_TYPE_USB_HEADSET:
512 source.ext.device.type = PIN_IN_USB_EXT;
513 source.ext.device.desc = (char *)"pin_in_usb_ext";
514 break;
515 case DEVICE_TYPE_BLUETOOTH_SCO:
516 source.ext.device.type = PIN_IN_BLUETOOTH_SCO_HEADSET;
517 source.ext.device.desc = (char *)"pin_in_bluetooth_sco_headset";
518 break;
519 case DEVICE_TYPE_ACCESSORY:
520 if (dmDeviceTypeMap_[DEVICE_TYPE_ACCESSORY] == DM_DEVICE_TYPE_PENCIL) {
521 source.ext.device.type = PIN_IN_PENCIL;
522 source.ext.device.desc = (char *)"pin_in_pencil";
523 } else if (dmDeviceTypeMap_[DEVICE_TYPE_ACCESSORY] == DM_DEVICE_TYPE_UWB) {
524 source.ext.device.type = PIN_IN_UWB;
525 source.ext.device.desc = (char *)"pin_in_uwb";
526 }
527 break;
528 case DEVICE_TYPE_NEARLINK_IN:
529 HandleNearlinkScene(inputDevice, source);
530 break;
531 default:
532 ret = ERR_NOT_SUPPORTED;
533 break;
534 }
535
536 return ret;
537 }
538
SaveSetParameter(const std::string & adapterName,const AudioParamKey key,const std::string & condition,const std::string & value)539 void LocalDeviceManager::SaveSetParameter(const std::string &adapterName, const AudioParamKey key,
540 const std::string &condition, const std::string &value)
541 {
542 // save set param
543 auto callerUid = IPCSkeleton::GetCallingUid();
544 AUDIO_INFO_LOG("save param when adapter is nullptr, callerUid is %{public}u", callerUid);
545 std::lock_guard<std::mutex> lock(reSetParamsMtx_);
546 reSetParams_.push_back({ adapterName, key, condition, value });
547 }
548
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)549 void LocalDeviceManager::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
550 {
551 dmDeviceTypeMap_[deviceType] = dmDeviceType;
552 }
553
SetAudioScene(const AudioScene scene)554 void LocalDeviceManager::SetAudioScene(const AudioScene scene)
555 {
556 currentAudioScene_.store(scene);
557 }
558
559 } // namespace AudioStandard
560 } // namespace OHOS
561