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