diff --git a/frameworks/native/audioutils/include/audio_utils.h b/frameworks/native/audioutils/include/audio_utils.h index a7caeef0b80f88e901c61a8dc9a0dfbc7e82e227..0c7879b8a704cd4056c1113d70ef769c60474ddd 100644 --- a/frameworks/native/audioutils/include/audio_utils.h +++ b/frameworks/native/audioutils/include/audio_utils.h @@ -84,7 +84,7 @@ const std::string DUMP_REMOTE_RENDER_SINK_FILENAME = "dump_remote_audiosink.pcm" const std::string DUMP_REMOTE_CAPTURE_SOURCE_FILENAME = "dump_remote_capture_audiosource.pcm"; const std::string DUMP_ENDPOINT_DCP_FILENAME = "dump_endpoint_dcp_audio.pcm"; const std::string DUMP_ENDPOINT_HDI_FILENAME = "dump_endpoint_hdi_audio.pcm"; -constexpr uint32_t PARAM_VALUE_LENTH = 64; +constexpr uint32_t PARAM_VALUE_LENTH = 128; class DumpFileUtil { public: diff --git a/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp b/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp index f9bee633e9ee0a01a32906a688ee74d55cb931e0..92d111b78863f7456601a824795a5bace341a3af 100644 --- a/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp +++ b/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp @@ -149,6 +149,32 @@ AudioRendererSink *AudioRendererSink::GetInstance(std::string halName) return &audioRenderer; } +static int32_t SwitchAdapterRender(struct AudioAdapterDescriptor *descs, string adapterNameCase, + enum AudioPortDirection portFlag, struct AudioPort &renderPort, uint32_t size) +{ + if (descs == nullptr) { + return ERROR; + } + for (uint32_t index = 0; index < size; index++) { + struct AudioAdapterDescriptor *desc = &descs[index]; + if (desc == nullptr || desc->adapterName == nullptr) { + continue; + } + if (!strcmp(desc->adapterName, adapterNameCase.c_str())) { + for (uint32_t port = 0; port < desc->portsLen; port++) { + // Only find out the port of out in the sound card + if (desc->ports[port].dir == portFlag) { + renderPort = desc->ports[port]; + return index; + } + } + } + } + AUDIO_ERR_LOG("SwitchAdapterRender Fail"); + + return ERR_INVALID_INDEX; +} + void AudioRendererSinkInner::SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) { @@ -169,6 +195,30 @@ std::string AudioRendererSinkInner::GetAudioParameter(const AudioParamKey key, c { AUDIO_INFO_LOG("GetAudioParameter: key %{public}d, condition: %{public}s", key, condition.c_str()); + if (condition == "get_usb_info") { + if (InitAudioManager() != 0) { + AUDIO_ERR_LOG("Init audio manager Fail."); + return ""; + } + uint32_t size = MAX_AUDIO_ADAPTER_NUM; + int32_t ret; + AudioAdapterDescriptor descs[MAX_AUDIO_ADAPTER_NUM]; + ret = audioManager_->GetAllAdapters(audioManager_, (struct AudioAdapterDescriptor *)&descs, &size); + if (size > MAX_AUDIO_ADAPTER_NUM || size == 0 || ret != 0) { + AUDIO_ERR_LOG("Get adapters Fail when get_usb_info."); + return ""; + } + enum AudioPortDirection port = PORT_OUT; + adapterNameCase_ = "usb"; + int32_t index = + SwitchAdapterRender((struct AudioAdapterDescriptor *)&descs, adapterNameCase_, port, audioPort_, size); + CHECK_AND_RETURN_RET_LOG((index >= 0), "", "Switch Adapter Fail when get_usb_info."); + adapterDesc_ = descs[index]; + CHECK_AND_RETURN_RET_LOG((audioManager_->LoadAdapter(audioManager_, &adapterDesc_, &audioAdapter_) == SUCCESS), + "", "Load Adapter Fail."); + CHECK_AND_RETURN_RET_LOG((audioAdapter_ != nullptr), "", "Load audio device failed when get_usb_info."); + } + AudioExtParamKey hdiKey = AudioExtParamKey(key); char value[PARAM_VALUE_LENTH]; if (audioAdapter_ == nullptr) { @@ -322,32 +372,6 @@ void InitAttrs(struct AudioSampleAttributes &attrs) attrs.silenceThreshold = 0; } -static int32_t SwitchAdapterRender(struct AudioAdapterDescriptor *descs, string adapterNameCase, - enum AudioPortDirection portFlag, struct AudioPort &renderPort, uint32_t size) -{ - if (descs == nullptr) { - return ERROR; - } - for (uint32_t index = 0; index < size; index++) { - struct AudioAdapterDescriptor *desc = &descs[index]; - if (desc == nullptr || desc->adapterName == nullptr) { - continue; - } - if (!strcmp(desc->adapterName, adapterNameCase.c_str())) { - for (uint32_t port = 0; port < desc->portsLen; port++) { - // Only find out the port of out in the sound card - if (desc->ports[port].dir == portFlag) { - renderPort = desc->ports[port]; - return index; - } - } - } - } - AUDIO_ERR_LOG("SwitchAdapterRender Fail"); - - return ERR_INVALID_INDEX; -} - int32_t AudioRendererSinkInner::InitAudioManager() { AUDIO_INFO_LOG("Initialize audio proxy manager"); diff --git a/services/audio_policy/server/include/service/audio_policy_service.h b/services/audio_policy/server/include/service/audio_policy_service.h index 9431a4bf6f173a7f30152985b008daf1ba95cf68..0cf0302007882e55e54408e17ac1e77b23ef7b58 100644 --- a/services/audio_policy/server/include/service/audio_policy_service.h +++ b/services/audio_policy/server/include/service/audio_policy_service.h @@ -375,9 +375,11 @@ private: int32_t LoadA2dpModule(DeviceType deviceType); - int32_t LoadUsbModule(DeviceType deviceType); + int32_t LoadUsbModule(string deviceInfo); - int32_t HandleUsbDevice(DeviceType deviceType); + int32_t LoadDefaultUsbModule(); + + int32_t HandleArmUsbDevice(DeviceType deviceType); int32_t HandleFileDevice(DeviceType deviceType); @@ -562,6 +564,8 @@ private: std::mutex deviceClassInfoMutex_; std::shared_mutex deviceStatusUpdateSharedMutex_; + + bool isArmUsbDevice_ = false; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/src/service/audio_policy_service.cpp b/services/audio_policy/server/src/service/audio_policy_service.cpp index 7017673f609c4313d57c3d095dd7e77c7d8ba5c7..6422464c5523ad55c1b54d82f6e1f78086fe22ca 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -883,6 +883,9 @@ bool AudioPolicyService::IsStreamActive(AudioStreamType streamType) const std::string AudioPolicyService::GetSinkPortName(InternalDeviceType deviceType) { std::string portName = PORT_NONE; + if (deviceType == DEVICE_TYPE_USB_HEADSET && isArmUsbDevice_) { + deviceType = DEVICE_TYPE_USB_ARM_HEADSET; + } switch (deviceType) { case InternalDeviceType::DEVICE_TYPE_BLUETOOTH_A2DP: portName = BLUETOOTH_SPEAKER; @@ -912,6 +915,9 @@ std::string AudioPolicyService::GetSinkPortName(InternalDeviceType deviceType) std::string AudioPolicyService::GetSourcePortName(InternalDeviceType deviceType) { std::string portName = PORT_NONE; + if (deviceType == DEVICE_TYPE_USB_HEADSET && isArmUsbDevice_) { + deviceType = DEVICE_TYPE_USB_ARM_HEADSET; + } switch (deviceType) { case InternalDeviceType::DEVICE_TYPE_MIC: portName = PRIMARY_MIC; @@ -1334,11 +1340,52 @@ static uint32_t GetSampleFormatValue(AudioSampleFormat sampleFormat) } } +static string ParseAudioFormat(string format) +{ + if (format == "AUDIO_FORMAT_PCM_16_BIT") { + return "s16"; + } else if (format == "AUDIO_FORMAT_PCM_24_BIT") { + return "s24"; + } else if (format == "AUDIO_FORMAT_PCM_32_BIT") { + return "s32"; + } else { + return ""; + } +} + +static void GetUsbModuleInfo(AudioModuleInfo &moduleInfo, string deviceInfo) +{ + if (moduleInfo.role == "sink") { + auto sinkRate_begin = deviceInfo.find("sink_rate"); + auto sinkRate_end = deviceInfo.find_first_of(";", sinkRate_begin); + moduleInfo.rate = deviceInfo.substr(sinkRate_begin + std::strlen("sink_rate"), + sinkRate_end - sinkRate_begin - std::strlen("sink_rate")); + auto sinkFormat_begin = deviceInfo.find("sink_format"); + auto sinkFormat_end = deviceInfo.find_first_of(";", sinkFormat_begin); + string format = deviceInfo.substr(sinkFormat_begin + std::strlen("sink_format"), + sinkFormat_end - sinkFormat_begin - std::strlen("sink_format")); + moduleInfo.format = ParseAudioFormat(format); + } else { + auto sourceRate_begin = deviceInfo.find("source_rate"); + auto sourceRate_end = deviceInfo.find_first_of(";", sourceRate_begin); + moduleInfo.rate = deviceInfo.substr(sourceRate_begin + std::strlen("source_rate"), + sourceRate_end - sourceRate_begin - std::strlen("source_rate")); + auto sourceFormat_begin = deviceInfo.find("source_format"); + auto sourceFormat_end = deviceInfo.find_first_of(";", sourceFormat_begin); + string format = deviceInfo.substr(sourceFormat_begin + std::strlen("source_format"), + sourceFormat_end - sourceFormat_begin - std::strlen("source_format")); + moduleInfo.format = ParseAudioFormat(format); + } +} + int32_t AudioPolicyService::SelectNewDevice(DeviceRole deviceRole, const sptr &deviceDescriptor) { Trace trace("AudioPolicyService::SelectNewDevice:" + std::to_string(deviceDescriptor->deviceType_)); int32_t result = SUCCESS; - + DeviceType deviceType = deviceDescriptor->deviceType_; + if (deviceType == DEVICE_TYPE_USB_HEADSET && isArmUsbDevice_) { + deviceType = DEVICE_TYPE_USB_ARM_HEADSET; + } if (deviceRole == DeviceRole::OUTPUT_DEVICE) { std::string activePort = GetSinkPortName(currentActiveDevice_.deviceType_); AUDIO_INFO_LOG("SelectNewDevice: port %{public}s, active device %{public}d", @@ -1347,14 +1394,13 @@ int32_t AudioPolicyService::SelectNewDevice(DeviceRole deviceRole, const sptrdeviceType_) : GetSourcePortName(deviceDescriptor->deviceType_); + GetSinkPortName(deviceType) : GetSourcePortName(deviceType); CHECK_AND_RETURN_RET_LOG(portName != PORT_NONE, ERR_INVALID_PARAM, "SelectNewDevice: Invalid port name %{public}s", portName.c_str()); if (deviceRole == DeviceRole::OUTPUT_DEVICE) { int32_t muteDuration = 200000; // us - std::thread switchThread(&AudioPolicyService::KeepPortMute, this, muteDuration, portName, - deviceDescriptor->deviceType_); + std::thread switchThread(&AudioPolicyService::KeepPortMute, this, muteDuration, portName, deviceType); switchThread.detach(); // add another sleep before switch local can avoid pop in some case } @@ -1365,7 +1411,7 @@ int32_t AudioPolicyService::SelectNewDevice(DeviceRole deviceRole, const sptrdeviceType_, portName); + result = audioPolicyManager_.SelectDevice(deviceRole, deviceType, portName); CHECK_AND_RETURN_RET_LOG(portName != PORT_NONE, result, "SetDeviceActive failed %{public}d", result); audioPolicyManager_.SuspendAudioDevice(portName, false); @@ -1373,7 +1419,7 @@ int32_t AudioPolicyService::SelectNewDevice(DeviceRole deviceRole, const sptr gsp = GetAudioServerProxy(); CHECK_AND_RETURN_RET_LOG(gsp != nullptr, ERR_OPERATION_FAILED, "Service proxy unavailable"); - gsp->UpdateActiveDeviceRoute(deviceDescriptor->deviceType_, deviceFlag); + gsp->UpdateActiveDeviceRoute(deviceType, deviceFlag); } if (deviceRole == DeviceRole::OUTPUT_DEVICE) { @@ -1483,45 +1529,66 @@ int32_t AudioPolicyService::ReloadA2dpAudioPort(AudioModuleInfo &moduleInfo) return SUCCESS; } -int32_t AudioPolicyService::LoadUsbModule(DeviceType deviceType) +int32_t AudioPolicyService::LoadUsbModule(string deviceInfo) { std::list moduleInfoList; { std::lock_guard deviceInfoLock(deviceClassInfoMutex_); auto usbModulesPos = deviceClassInfo_.find(ClassType::TYPE_USB); if (usbModulesPos == deviceClassInfo_.end()) { - AUDIO_ERR_LOG("Usb module is not exist in the configuration file"); return ERR_OPERATION_FAILED; } moduleInfoList = usbModulesPos->second; } for (auto &moduleInfo : moduleInfoList) { - std::lock_guard ioHandleLock(ioHandlesMutex_); + AUDIO_INFO_LOG("[module_load]::load module[%{public}s]", moduleInfo.name.c_str()); if (IOHandles_.find(moduleInfo.name) == IOHandles_.end()) { - AUDIO_INFO_LOG("[module_load]::Load module[%{public}s]", moduleInfo.name.c_str()); - moduleInfo.sinkLatency = sinkLatencyInMsec_ != 0 ? to_string(sinkLatencyInMsec_) : ""; + GetUsbModuleInfo(moduleInfo, deviceInfo); AudioIOHandle ioHandle = audioPolicyManager_.OpenAudioPort(moduleInfo); CHECK_AND_RETURN_RET_LOG(ioHandle != OPEN_PORT_FAILURE, ERR_OPERATION_FAILED, "OpenAudioPort failed %{public}d", ioHandle); IOHandles_[moduleInfo.name] = ioHandle; } } - std::string activePort = GetSinkPortName(currentActiveDevice_.deviceType_); - AUDIO_INFO_LOG("port %{public}s, active device %{public}d", activePort.c_str(), currentActiveDevice_.deviceType_); - audioPolicyManager_.SuspendAudioDevice(activePort, true); return SUCCESS; } -int32_t AudioPolicyService::HandleActiveDevice(DeviceType deviceType) +int32_t AudioPolicyService::LoadDefaultUsbModule() { - if (isUpdateRouteSupported_) { - UpdateActiveDeviceRoute(deviceType); + std::list moduleInfoList; + { + std::lock_guard deviceInfoLock(deviceClassInfoMutex_); + auto usbModulesPos = deviceClassInfo_.find(ClassType::TYPE_USB); + if (usbModulesPos == deviceClassInfo_.end()) { + return ERR_OPERATION_FAILED; + } + moduleInfoList = usbModulesPos->second; } + for (auto &moduleInfo : moduleInfoList) { + AUDIO_INFO_LOG("[module_load]::load default module[%{public}s]", moduleInfo.name.c_str()); + if (IOHandles_.find(moduleInfo.name) == IOHandles_.end()) { + AudioIOHandle ioHandle = audioPolicyManager_.OpenAudioPort(moduleInfo); + CHECK_AND_RETURN_RET_LOG(ioHandle != OPEN_PORT_FAILURE, ERR_OPERATION_FAILED, + "OpenAudioPort failed %{public}d", ioHandle); + IOHandles_[moduleInfo.name] = ioHandle; + } + } + + return SUCCESS; +} + +int32_t AudioPolicyService::HandleActiveDevice(DeviceType deviceType) +{ if (GetVolumeGroupType(currentActiveDevice_.deviceType_) != GetVolumeGroupType(deviceType)) { SetVolumeForSwitchDevice(deviceType); } - + if (deviceType == DEVICE_TYPE_USB_HEADSET && isArmUsbDevice_) { + deviceType = DEVICE_TYPE_USB_ARM_HEADSET; + } + if (isUpdateRouteSupported_) { + UpdateActiveDeviceRoute(deviceType); + } std::string sinkPortName = GetSinkPortName(deviceType); std::string sourcePortName = GetSourcePortName(deviceType); if (sinkPortName == PORT_NONE && sourcePortName == PORT_NONE) { @@ -1565,21 +1632,34 @@ int32_t AudioPolicyService::HandleA2dpDevice(DeviceType deviceType) return HandleActiveDevice(deviceType); } -int32_t AudioPolicyService::HandleUsbDevice(DeviceType deviceType) +int32_t AudioPolicyService::HandleArmUsbDevice(DeviceType deviceType) { - Trace trace("AudioPolicyService::HandleUsbDevice"); + Trace trace("AudioPolicyService::HandleArmUsbDevice"); - if (deviceType == DEVICE_TYPE_USB_ARM_HEADSET) { - int32_t ret = LoadUsbModule(deviceType); + if (deviceType == DEVICE_TYPE_USB_HEADSET) { + string deviceInfo = ""; + if (g_adProxy != nullptr) { + deviceInfo = g_adProxy->GetAudioParameter("get_usb_info"); + AUDIO_INFO_LOG("device info from usb hal is %{public}s", deviceInfo.c_str()); + } + int32_t ret; + if (!deviceInfo.empty()) { + ret = LoadUsbModule(deviceInfo); + } else { + ret = LoadDefaultUsbModule(); + } if (ret != SUCCESS) { - AUDIO_ERR_LOG ("load Usb module failed"); + AUDIO_ERR_LOG ("load usb module failed"); return ERR_OPERATION_FAILED; } - } else if (currentActiveDevice_.deviceType_ == DEVICE_TYPE_USB_ARM_HEADSET) { - std::string activePort = GetSinkPortName(currentActiveDevice_.deviceType_); + std::string activePort = GetSinkPortName(DEVICE_TYPE_USB_ARM_HEADSET); + AUDIO_INFO_LOG("port %{public}s, active device %{public}d", activePort.c_str(), DEVICE_TYPE_USB_ARM_HEADSET); + audioPolicyManager_.SuspendAudioDevice(activePort, true); + } else if (currentActiveDevice_.deviceType_ == DEVICE_TYPE_USB_HEADSET) { + std::string activePort = GetSinkPortName(DEVICE_TYPE_USB_ARM_HEADSET); audioPolicyManager_.SuspendAudioDevice(activePort, true); int32_t muteDuration = 1000000; // us - std::thread switchThread(&AudioPolicyService::KeepPortMute, this, muteDuration, activePort, deviceType); + std::thread switchThread(&AudioPolicyService::KeepPortMute, this, muteDuration, activePort, DEVICE_TYPE_USB_ARM_HEADSET); switchThread.detach(); int32_t beforSwitchDelay = 300000; usleep(beforSwitchDelay); @@ -1630,8 +1710,9 @@ int32_t AudioPolicyService::ActivateNewDevice(DeviceType deviceType, bool isScen return result; } - if (deviceType == DEVICE_TYPE_USB_ARM_HEADSET || currentActiveDevice_.deviceType_ == DEVICE_TYPE_USB_ARM_HEADSET) { - result = HandleUsbDevice(deviceType); + if (isArmUsbDevice_ && + (deviceType == DEVICE_TYPE_USB_HEADSET || currentActiveDevice_.deviceType_ == DEVICE_TYPE_USB_HEADSET)) { + result = HandleArmUsbDevice(deviceType); return result; } @@ -2115,7 +2196,7 @@ int32_t AudioPolicyService::HandleLocalDeviceDisconnected(DeviceType devType, co result = SUCCESS; } - if (devType == DEVICE_TYPE_USB_ARM_HEADSET) { + if (devType == DEVICE_TYPE_USB_HEADSET && isArmUsbDevice_) { if (IOHandles_.find(USB_SPEAKER) != IOHandles_.end()) { audioPolicyManager_.CloseAudioPort(IOHandles_[USB_SPEAKER]); IOHandles_.erase(USB_SPEAKER); @@ -2177,21 +2258,14 @@ DeviceType AudioPolicyService::FindConnectedHeadset() int32_t AudioPolicyService::handleSpecialDeviceType(DeviceType &devType, bool &isConnected) { // usb device needs to be distinguished form arm or hifi - if (devType == DEVICE_TYPE_USB_HEADSET) { - if (isConnected) { - if (g_adProxy == nullptr) { - return ERROR; - } - const std::string value = g_adProxy->GetAudioParameter("need_change_usb_device"); - AUDIO_INFO_LOG("get value %{public}s from hal when usb device connect", value.c_str()); - if (value == "false") { - devType = DEVICE_TYPE_USB_ARM_HEADSET; - } - } else { - DeviceType connectedHeadsetType = FindConnectedHeadset(); - if (connectedHeadsetType == DEVICE_TYPE_USB_ARM_HEADSET) { - devType = DEVICE_TYPE_USB_ARM_HEADSET; - } + if (devType == DEVICE_TYPE_USB_HEADSET && isConnected) { + if (g_adProxy == nullptr) { + return ERROR; + } + const std::string value = g_adProxy->GetAudioParameter("need_change_usb_device"); + AUDIO_INFO_LOG("get value %{public}s from hal when usb device connect", value.c_str()); + if (value == "false") { + isArmUsbDevice_ = true; } } @@ -2256,6 +2330,9 @@ void AudioPolicyService::OnDeviceStatusUpdated(DeviceType devType, bool isConnec } else { UpdateConnectedDevicesWhenDisconnecting(deviceDesc, deviceChangeDescriptor); result = HandleLocalDeviceDisconnected(devType, macAddress); + if (devType == DEVICE_TYPE_USB_HEADSET && isArmUsbDevice_) { + isArmUsbDevice_ = false; + } CHECK_AND_RETURN_LOG(result == SUCCESS, "Disconnect local device failed."); } @@ -3644,9 +3721,11 @@ void AudioPolicyService::UpdateInputDeviceInfo(DeviceType deviceType) case DEVICE_TYPE_FILE_SINK: activeInputDevice_ = DEVICE_TYPE_FILE_SOURCE; break; + case DEVICE_TYPE_USB_ARM_HEADSET: + activeInputDevice_ = DEVICE_TYPE_USB_HEADSET; + break; case DEVICE_TYPE_WIRED_HEADSET: case DEVICE_TYPE_USB_HEADSET: - case DEVICE_TYPE_USB_ARM_HEADSET: case DEVICE_TYPE_BLUETOOTH_SCO: activeInputDevice_ = deviceType; break; diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index 2c2db536615358f14d22fff16a190b41fadaec98..3fe9496fe2e1f875e8f4edbe8f78fd4b54aa6d87 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -205,6 +205,13 @@ const std::string AudioServer::GetAudioParameter(const std::string &key) int32_t id = HiviewDFX::XCollie::GetInstance().SetTimer("AudioServer::SetAudioScene", TIME_OUT_SECONDS, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG); AUDIO_DEBUG_LOG("server: get audio parameter"); + if (key == "get_usb_info") { + IAudioRendererSink *usbAudioRendererSinkInstance = IAudioRendererSink::GetInstance("usb", ""); + if (usbAudioRendererSinkInstance != nullptr) { + AudioParamKey parmKey = AudioParamKey::USB_DEVICE; + return usbAudioRendererSinkInstance->GetAudioParameter(AudioParamKey(parmKey), "get_usb_info"); + } + } IAudioRendererSink *audioRendererSinkInstance = IAudioRendererSink::GetInstance("primary", ""); if (audioRendererSinkInstance != nullptr) { AudioParamKey parmKey = AudioParamKey::NONE;