diff --git a/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.cpp b/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.cpp index 5f55e997519215650d8890a82410c4cc8bd47c6d..ea10ba68ccab918afa910223d636f0b5f2a8f7b3 100644 --- a/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.cpp +++ b/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.cpp @@ -35,13 +35,17 @@ IAudioRendererSink *IAudioRendererSink::GetInstance(const char *devceClass, cons } AUDIO_DEBUG_LOG("%{public}s Sink:GetInstance[%{public}s]", devceClass, deviceNetworkId); const char *deviceClassPrimary = "primary"; + const char *deviceClassUsb = "usb"; const char *deviceClassA2DP = "a2dp"; const char *deviceClassFile = "file_io"; const char *deviceClassRemote = "remote"; IAudioRendererSink *iAudioRendererSink = nullptr; if (!strcmp(devceClass, deviceClassPrimary)) { - iAudioRendererSink = AudioRendererSink::GetInstance(); + iAudioRendererSink = AudioRendererSink::GetInstance("primary"); + } + if (!strcmp(devceClass, deviceClassUsb)) { + iAudioRendererSink = AudioRendererSink::GetInstance("usb"); } if (!strcmp(devceClass, deviceClassA2DP)) { iAudioRendererSink = BluetoothRendererSink::GetInstance(); diff --git a/frameworks/native/hdiadapter/sink/common/renderer_sink_adapter.c b/frameworks/native/hdiadapter/sink/common/renderer_sink_adapter.c index 10efa734dc129ab05b456aff37059d81796a2928..99419f7bab0978a66975f40ad1358a42c4515d5d 100644 --- a/frameworks/native/hdiadapter/sink/common/renderer_sink_adapter.c +++ b/frameworks/native/hdiadapter/sink/common/renderer_sink_adapter.c @@ -31,8 +31,10 @@ const int32_t CLASS_TYPE_PRIMARY = 0; const int32_t CLASS_TYPE_A2DP = 1; const int32_t CLASS_TYPE_FILE = 2; const int32_t CLASS_TYPE_REMOTE = 3; +const int32_t CLASS_TYPE_USB = 4; const char *g_deviceClassPrimary = "primary"; +const char *g_deviceClassUsb = "usb"; const char *g_deviceClassA2DP = "a2dp"; const char *g_deviceClassFile = "file_io"; const char *g_deviceClassRemote = "remote"; @@ -60,6 +62,9 @@ int32_t LoadSinkAdapter(const char *device, const char *deviceNetworkId, struct if (!strcmp(device, g_deviceClassPrimary)) { adapter->deviceClass = CLASS_TYPE_PRIMARY; } + if (!strcmp(device, g_deviceClassUsb)) { + adapter->deviceClass = CLASS_TYPE_USB; + } if (!strcmp(device, g_deviceClassA2DP)) { adapter->deviceClass = CLASS_TYPE_A2DP; } @@ -100,6 +105,8 @@ const char *GetDeviceClass(int32_t deviceClass) { if (deviceClass == CLASS_TYPE_PRIMARY) { return g_deviceClassPrimary; + } else if (deviceClass == CLASS_TYPE_USB) { + return g_deviceClassUsb; } else if (deviceClass == CLASS_TYPE_A2DP) { return g_deviceClassA2DP; } else if (deviceClass == CLASS_TYPE_FILE) { diff --git a/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp b/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp index 0191f9d51edfaec57931295bac3bd5e424eca9a2..03190c2690c37913c8d456a68abe8dc92e1d77ca 100644 --- a/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp +++ b/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.cpp @@ -86,7 +86,7 @@ public: int32_t SetOutputRoute(DeviceType outputDevice) override; int32_t SetOutputRoute(DeviceType outputDevice, AudioPortPin &outputPortPin); - AudioRendererSinkInner(); + explicit AudioRendererSinkInner(const std::string halName = "primary"); ~AudioRendererSinkInner(); private: IAudioSinkAttr attr_; @@ -102,6 +102,7 @@ private: struct IAudioManager *audioManager_; struct IAudioAdapter *audioAdapter_; struct IAudioRender *audioRender_; + std::string halName_; struct AudioAdapterDescriptor adapterDesc_; struct AudioPort audioPort_ = {}; bool audioMonoState_ = false; @@ -129,10 +130,10 @@ private: #endif // DUMPFILE }; -AudioRendererSinkInner::AudioRendererSinkInner() +AudioRendererSinkInner::AudioRendererSinkInner(const std::string halName) : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL), rightVolume_(DEFAULT_VOLUME_LEVEL), openSpeaker_(0), audioManager_(nullptr), audioAdapter_(nullptr), - audioRender_(nullptr) + audioRender_(nullptr), halName_(halName) { attr_ = {}; #ifdef DUMPFILE @@ -145,10 +146,13 @@ AudioRendererSinkInner::~AudioRendererSinkInner() AUDIO_ERR_LOG("~AudioRendererSinkInner"); } -AudioRendererSink *AudioRendererSink::GetInstance() +AudioRendererSink *AudioRendererSink::GetInstance(std::string halName) { + if (halName == "usb") { + static AudioRendererSinkInner audioRendererUsb(halName); + return &audioRendererUsb; + } static AudioRendererSinkInner audioRenderer; - return &audioRenderer; } @@ -424,6 +428,9 @@ int32_t AudioRendererSinkInner::CreateRender(const struct AudioPort &renderPort) deviceDesc.portId = renderPort.portId; deviceDesc.desc = const_cast(""); deviceDesc.pins = PIN_OUT_SPEAKER; + if (halName_ == "usb") { + deviceDesc.pins = PIN_OUT_USB_HEADSET; + } ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, ¶m, &audioRender_, &renderId_); if (ret != 0 || audioRender_ == nullptr) { AUDIO_ERR_LOG("AudioDeviceCreateRender failed."); @@ -475,7 +482,11 @@ int32_t AudioRendererSinkInner::Init(IAudioSinkAttr attr) return ERR_NOT_STARTED; } if (openSpeaker_) { - ret = SetOutputRoute(DEVICE_TYPE_SPEAKER); + if (halName_ == "usb") { + ret = SetOutputRoute(DEVICE_TYPE_USB_ARM_HEADSET); + } else { + ret = SetOutputRoute(DEVICE_TYPE_SPEAKER); + } if (ret < 0) { AUDIO_ERR_LOG("Update route FAILED: %{public}d", ret); } @@ -684,6 +695,10 @@ static int32_t SetOutputPortPin(DeviceType outputDevice, AudioRouteNode &sink) sink.ext.device.type = PIN_OUT_HEADSET; sink.ext.device.desc = (char *)"pin_out_headset"; break; + case DEVICE_TYPE_USB_ARM_HEADSET: + sink.ext.device.type = PIN_OUT_USB_HEADSET; + sink.ext.device.desc = (char *)"pin_out_usb_headset"; + break; case DEVICE_TYPE_USB_HEADSET: sink.ext.device.type = PIN_OUT_USB_EXT; sink.ext.device.desc = (char *)"pin_out_usb_ext"; @@ -774,6 +789,9 @@ int32_t AudioRendererSinkInner::SetAudioScene(AudioScene audioScene, DeviceType } if (openSpeaker_) { AudioPortPin audioSceneOutPort = PIN_OUT_SPEAKER; + if (halName_ == "usb") { + audioSceneOutPort = PIN_OUT_USB_HEADSET; + } int32_t ret = SetOutputRoute(activeDevice, audioSceneOutPort); if (ret < 0) { AUDIO_ERR_LOG("Update route FAILED: %{public}d", ret); diff --git a/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.h b/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.h index 182fa184ac80247ee1d4e3fdb898aca822c71422..8c06e7588446509577c9cc0e6df69bd7bb2e247b 100644 --- a/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.h +++ b/frameworks/native/hdiadapter/sink/primary/audio_renderer_sink.h @@ -26,7 +26,7 @@ namespace OHOS { namespace AudioStandard { class AudioRendererSink : public IAudioRendererSink { public: - static AudioRendererSink *GetInstance(void); + static AudioRendererSink *GetInstance(std::string halName); AudioRendererSink() = default; ~AudioRendererSink() = default; diff --git a/frameworks/native/hdiadapter/source/common/capturer_source_adapter.c b/frameworks/native/hdiadapter/source/common/capturer_source_adapter.c index abaae3b4f8ef4001499692df7eb9691cd7f5c720..5f35251408eac7cd8360dc86145ebc534679461c 100644 --- a/frameworks/native/hdiadapter/source/common/capturer_source_adapter.c +++ b/frameworks/native/hdiadapter/source/common/capturer_source_adapter.c @@ -32,8 +32,10 @@ const int32_t CLASS_TYPE_PRIMARY = 0; const int32_t CLASS_TYPE_A2DP = 1; const int32_t CLASS_TYPE_FILE = 2; const int32_t CLASS_TYPE_REMOTE = 3; +const int32_t CLASS_TYPE_USB = 4; const char *g_deviceClassPrimary = "primary"; +const char *g_deviceClassUsb = "usb"; const char *g_deviceClassA2DP = "a2dp"; const char *g_deviceClassFile = "file_io"; const char *g_deviceClassRemote = "remote"; @@ -75,6 +77,9 @@ int32_t LoadSourceAdapter(const char *device, const char *deviceNetworkId, const if (!strcmp(device, g_deviceClassPrimary)) { adapter->deviceClass = CLASS_TYPE_PRIMARY; } + if (!strcmp(device, g_deviceClassUsb)) { + adapter->deviceClass = CLASS_TYPE_USB; + } if (!strcmp(device, g_deviceClassA2DP)) { adapter->deviceClass = CLASS_TYPE_A2DP; } @@ -115,6 +120,8 @@ const char *GetDeviceClass(int32_t deviceClass) { if (deviceClass == CLASS_TYPE_PRIMARY) { return g_deviceClassPrimary; + } else if (deviceClass == CLASS_TYPE_USB) { + return g_deviceClassUsb; } else if (deviceClass == CLASS_TYPE_A2DP) { return g_deviceClassA2DP; } else if (deviceClass == CLASS_TYPE_FILE) { diff --git a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.cpp index 265ddb6c09fb46b19da8b6181ce7ee1d9e9b812a..a66de473448ab98963930ba53082b6c821cfb1b0 100644 --- a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.cpp @@ -34,12 +34,16 @@ IAudioCapturerSource *IAudioCapturerSource::GetInstance(const char *deviceClass, AUDIO_DEBUG_LOG("%{public}s Source:GetInstance deviceNetworkId:[%{public}s] sourceType:[%{public}d]", deviceClass, deviceNetworkId, sourceType); const char *deviceClassPrimary = "primary"; + const char *deviceClassUsb = "usb"; const char *deviceClassA2DP = "a2dp"; const char *deviceClassFile = "file_io"; const char *deviceClassRemote = "remote"; if (!strcmp(deviceClass, deviceClassPrimary)) { - return AudioCapturerSource::GetInstance(sourceType, sourceName); + return AudioCapturerSource::GetInstance("primary", sourceType, sourceName); + } + if (!strcmp(deviceClass, deviceClassUsb)) { + return AudioCapturerSource::GetInstance("usb", sourceType, sourceName); } if (!strcmp(deviceClass, deviceClassA2DP)) { static AudioCapturerFileSource audioCapturer; diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp index 716d4598c2a0e316b8a9a0088026ae07284e4f2a..764f60849ffefda938d050df6ae1222573cccb05 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.cpp @@ -58,7 +58,7 @@ public: void RegisterWakeupCloseCallback(IAudioSourceCallback* callback) override; void RegisterAudioCapturerSourceCallback(IAudioSourceCallback* callback) override; - AudioCapturerSourceInner(); + explicit AudioCapturerSourceInner(const std::string halName = "primary"); ~AudioCapturerSourceInner(); private: @@ -86,6 +86,7 @@ private: struct IAudioManager *audioManager_; struct IAudioAdapter *audioAdapter_; struct IAudioCapture *audioCapture_; + std::string halName_; struct AudioAdapterDescriptor adapterDesc_; struct AudioPort audioPort; @@ -260,10 +261,10 @@ const char *g_audioOutTestFilePath = "/data/data/.pulse_dir/dump_audiosource.pcm bool AudioCapturerSource::micMuteState_ = false; constexpr int32_t RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING = -1; -AudioCapturerSourceInner::AudioCapturerSourceInner() +AudioCapturerSourceInner::AudioCapturerSourceInner(const std::string halName) : capturerInited_(false), started_(false), paused_(false), leftVolume_(MAX_VOLUME_LEVEL), rightVolume_(MAX_VOLUME_LEVEL), openMic_(0), audioManager_(nullptr), audioAdapter_(nullptr), - audioCapture_(nullptr) + audioCapture_(nullptr), halName_(halName) { attr_ = {}; #ifdef CAPTURE_DUMP @@ -276,8 +277,14 @@ AudioCapturerSourceInner::~AudioCapturerSourceInner() AUDIO_ERR_LOG("~AudioCapturerSourceInner"); } -AudioCapturerSource *AudioCapturerSource::GetInstance(const SourceType sourceType, const char *sourceName) +AudioCapturerSource *AudioCapturerSource::GetInstance(const std::string halName, + const SourceType sourceType, const char *sourceName) { + if (halName == "usb") { + static AudioCapturerSourceInner audioCapturerUsb(halName); + return &audioCapturerUsb; + } + switch (sourceType) { case SourceType::SOURCE_TYPE_MIC: return GetMicInstance(); @@ -452,6 +459,9 @@ int32_t AudioCapturerSourceInner::CreateCapture(struct AudioPort &capturePort) struct AudioDeviceDescriptor deviceDesc; deviceDesc.portId = capturePort.portId; deviceDesc.pins = PIN_IN_MIC; + if (halName_ == "usb") { + deviceDesc.pins = PIN_IN_USB_HEADSET; + } deviceDesc.desc = (char *)""; ret = audioAdapter_->CreateCapture(audioAdapter_, &deviceDesc, ¶m, &audioCapture_, &captureId_); @@ -505,7 +515,11 @@ int32_t AudioCapturerSourceInner::Init(IAudioSourceAttr &attr) return ERR_NOT_STARTED; } if (openMic_) { - ret = SetInputRoute(DEVICE_TYPE_MIC); + if (halName_ == "usb") { + ret = SetInputRoute(DEVICE_TYPE_USB_ARM_HEADSET); + } else { + ret = SetInputRoute(DEVICE_TYPE_MIC); + } if (ret < 0) { AUDIO_ERR_LOG("update route FAILED: %{public}d", ret); } @@ -716,6 +730,10 @@ static int32_t SetInputPortPin(DeviceType inputDevice, AudioRouteNode &source) source.ext.device.type = PIN_IN_HS_MIC; source.ext.device.desc = (char *)"pin_in_hs_mic"; break; + case DEVICE_TYPE_USB_ARM_HEADSET: + source.ext.device.type = PIN_IN_USB_HEADSET; + source.ext.device.desc = (char *)"pin_in_usb_headset"; + break; case DEVICE_TYPE_USB_HEADSET: source.ext.device.type = PIN_IN_USB_EXT; source.ext.device.desc = (char *)"pin_in_usb_ext"; @@ -797,6 +815,9 @@ int32_t AudioCapturerSourceInner::SetAudioScene(AudioScene audioScene, DeviceTyp } if (openMic_) { AudioPortPin audioSceneInPort = PIN_IN_MIC; + if (halName_ == "usb") { + audioSceneInPort = PIN_IN_USB_HEADSET; + } int32_t ret = SetInputRoute(activeDevice, audioSceneInPort); if (ret < 0) { AUDIO_ERR_LOG("Update route FAILED: %{public}d", ret); diff --git a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.h b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.h index 82f08aef24b4129912bc497b23f1dc43b8672665..f11714725e25f81b2cb06e97531842fbe644a426 100644 --- a/frameworks/native/hdiadapter/source/primary/audio_capturer_source.h +++ b/frameworks/native/hdiadapter/source/primary/audio_capturer_source.h @@ -36,7 +36,8 @@ namespace AudioStandard { class AudioCapturerSource : public IAudioCapturerSource { public: - static AudioCapturerSource *GetInstance(const SourceType sourceType = SourceType::SOURCE_TYPE_MIC, + static AudioCapturerSource *GetInstance(const std::string halName = "primary", + const SourceType sourceType = SourceType::SOURCE_TYPE_MIC, const char *sourceName = "Built_in_wakeup"); static AudioCapturerSource *GetMicInstance(void); static AudioCapturerSource *GetWakeupInstance(bool isMirror = false); diff --git a/interfaces/inner_api/native/audiocommon/include/audio_info.h b/interfaces/inner_api/native/audiocommon/include/audio_info.h index ed813a249870c65c64e4685be92cf5dee688db89..5863a97cc17570682cf2c27fc759daa5ebf4a5fa 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_info.h @@ -199,6 +199,10 @@ enum DeviceType { * Indicates a microphone built in a device. */ DEVICE_TYPE_USB_HEADSET = 22, + /** + * Indicates a usb-arm device. + */ + DEVICE_TYPE_USB_ARM_HEADSET = 23, /** * Indicates a debug sink device */ @@ -1073,19 +1077,24 @@ struct AudioStreamChangeInfo { }; enum AudioPin { - AUDIO_PIN_NONE = 0, - AUDIO_PIN_OUT_SPEAKER = 1, - AUDIO_PIN_OUT_HEADSET = 2, - AUDIO_PIN_OUT_LINEOUT = 4, - AUDIO_PIN_OUT_HDMI = 8, - AUDIO_PIN_OUT_USB = 16, - AUDIO_PIN_OUT_USB_EXT = 32, - AUDIO_PIN_OUT_DAUDIO_DEFAULT = 64, - AUDIO_PIN_IN_MIC = 134217729, - AUDIO_PIN_IN_HS_MIC = 134217730, - AUDIO_PIN_IN_LINEIN = 134217732, - AUDIO_PIN_IN_USB_EXT = 134217736, - AUDIO_PIN_IN_DAUDIO_DEFAULT = 134217744, + AUDIO_PIN_NONE = 0, // Invalid pin + AUDIO_PIN_OUT_SPEAKER = 1 << 0, // Speaker output pin + AUDIO_PIN_OUT_HEADSET = 1 << 1, // Wired headset pin for output + AUDIO_PIN_OUT_LINEOUT = 1 << 2, // Line-out pin + AUDIO_PIN_OUT_HDMI = 1 << 3, // HDMI output pin + AUDIO_PIN_OUT_USB = 1 << 4, // USB output pin + AUDIO_PIN_OUT_USB_EXT = 1 << 5, // Extended USB output pin + AUDIO_PIN_OUT_BLUETOOTH_SCO = 1 << 6, // Bluetooth SCO output pin + AUDIO_PIN_OUT_DAUDIO_DEFAULT = 1 << 7, // Daudio default output pin + AUDIO_PIN_OUT_HEADPHONE = 1 << 8, // Wired headphone output pin + AUDIO_PIN_OUT_USB_HEADSET = 1 << 9, // Arm usb output pin + AUDIO_PIN_IN_MIC = 1 << 27 | 1 << 0, // Microphone input pin + AUDIO_PIN_IN_HS_MIC = 1 << 27 | 1 << 1, // Wired headset microphone pin for input + AUDIO_PIN_IN_LINEIN = 1 << 27 | 1 << 2, // Line-in pin + AUDIO_PIN_IN_USB_EXT = 1 << 27 | 1 << 3, // Extended USB input pin + AUDIO_PIN_IN_BLUETOOTH_SCO_HEADSET = 1 << 27 | 1 << 4, // Bluetooth SCO headset input pin + AUDIO_PIN_IN_DAUDIO_DEFAULT = 1 << 27 | 1 << 5, // Daudio default input pin + AUDIO_PIN_IN_USB_HEADSET = 1 << 27 | 1 << 6, // Arm usb input pin }; enum AudioParamKey { @@ -1096,6 +1105,7 @@ enum AudioParamKey { A2DP_SUSPEND_STATE = 6, // for bluetooth sink BT_HEADSET_NREC = 7, BT_WBS = 8, + USB_DEVICE = 101, // Check USB device type ARM or HIFI PARAM_KEY_LOWPOWER = 1000, }; 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 e97f11be63bad22a1c5187e8bf9f518872d3f425..39388e09eb612c2b6c965a7ae2a16b74655a6035 100644 --- a/services/audio_policy/server/include/service/audio_policy_service.h +++ b/services/audio_policy/server/include/service/audio_policy_service.h @@ -164,6 +164,8 @@ public: const std::string &macAddress, const std::string &deviceName, const AudioStreamInfo &streamInfo); + int32_t handleSpecialDeviceType(DeviceType &devType, bool &isConnected); + void OnPnpDeviceStatusUpdated(DeviceType devType, bool isConnected); void OnDeviceConfigurationChanged(DeviceType deviceType, @@ -308,7 +310,9 @@ private: ~AudioPolicyService(); - std::string GetPortName(InternalDeviceType deviceType); + std::string GetSinkPortName(InternalDeviceType deviceType); + + std::string GetSourcePortName(InternalDeviceType deviceType); int32_t RememberRoutingInfo(sptr audioRendererFilter, sptr deviceDescriptor); @@ -330,7 +334,9 @@ private: AudioModuleInfo ConstructWakeUpAudioModuleInfo(int32_t wakeupNo); - AudioIOHandle GetAudioIOHandle(InternalDeviceType deviceType); + AudioIOHandle GetSinkIOHandle(InternalDeviceType deviceType); + + AudioIOHandle GetSourceIOHandle(InternalDeviceType deviceType); int32_t OpenRemoteAudioDevice(std::string networkId, DeviceRole deviceRole, DeviceType deviceType, sptr remoteDeviceDescriptor); @@ -354,8 +360,16 @@ private: int32_t SelectNewDevice(DeviceRole deviceRole, DeviceType deviceType); + int32_t HandleActiveDevice(DeviceType deviceType); + int32_t HandleA2dpDevice(DeviceType deviceType); + int32_t LoadA2dpModule(DeviceType deviceType); + + int32_t LoadUsbModule(DeviceType deviceType); + + int32_t HandleUsbDevice(DeviceType deviceType); + int32_t HandleFileDevice(DeviceType deviceType); int32_t ActivateNewDevice(DeviceType deviceType, bool isSceneActivation); @@ -524,6 +538,7 @@ private: int wakeupCount_ = 0; std::mutex wakeupCountMutex_; + std::mutex deviceClassInfoMutex_; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/include/service/common/audio_module_info.h b/services/audio_policy/server/include/service/common/audio_module_info.h index 412a5aad5ae29973d52b306eff54916d6d3755a4..1d48bf7823a3fd98268342a9f8a61c67b5dd20a7 100644 --- a/services/audio_policy/server/include/service/common/audio_module_info.h +++ b/services/audio_policy/server/include/service/common/audio_module_info.h @@ -33,6 +33,8 @@ static const std::string USB_CLASS = "usb"; static const std::string FILE_CLASS = "file_io"; static const std::string BLUETOOTH_SPEAKER = "Bt_Speaker"; static const std::string PRIMARY_SPEAKER = "Speaker"; +static const std::string USB_SPEAKER = "Usb_arm_speaker"; +static const std::string USB_MIC = "Usb_arm_mic"; static const std::string PRIMARY_MIC = "Built_in_mic"; static const std::string FILE_SINK = "file_sink"; static const std::string FILE_SOURCE = "file_source"; 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 2cdfc2a8b890759d3c78bf1a68077bf95d00fab4..e8e606d20055baddc9e2f7871f5c32f975867a1e 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -575,7 +575,7 @@ int32_t AudioPolicyService::MoveToLocalOutputDevice(std::vector sinkI // start move. uint32_t sinkId = -1; // invalid sink id, use sink name instead. - std::string sinkName = GetPortName(currentActiveDevice_); + std::string sinkName = GetSinkPortName(currentActiveDevice_); for (size_t i = 0; i < sinkInputIds.size(); i++) { if (audioPolicyManager_.MoveSinkInputByIndexOrName(sinkInputIds[i].paStreamId, sinkId, sinkName) != SUCCESS) { AUDIO_ERR_LOG("move [%{public}d] to local failed", sinkInputIds[i].streamId); @@ -748,7 +748,7 @@ int32_t AudioPolicyService::MoveToLocalInputDevice(std::vector sourceO // start move. uint32_t sourceId = -1; // invalid source id, use source name instead. - std::string sourceName = GetPortName(activeInputDevice_); + std::string sourceName = GetSourcePortName(activeInputDevice_); for (size_t i = 0; i < sourceOutputIds.size(); i++) { if (audioPolicyManager_.MoveSourceOutputByIndexOrName(sourceOutputIds[i], sourceId, sourceName) != SUCCESS) { AUDIO_DEBUG_LOG("move [%{public}d] to local failed", sourceOutputIds[i]); @@ -813,7 +813,7 @@ bool AudioPolicyService::IsStreamActive(AudioStreamType streamType) const return audioPolicyManager_.IsStreamActive(streamType); } -std::string AudioPolicyService::GetPortName(InternalDeviceType deviceType) +std::string AudioPolicyService::GetSinkPortName(InternalDeviceType deviceType) { std::string portName = PORT_NONE; switch (deviceType) { @@ -828,15 +828,33 @@ std::string AudioPolicyService::GetPortName(InternalDeviceType deviceType) case InternalDeviceType::DEVICE_TYPE_BLUETOOTH_SCO: portName = PRIMARY_SPEAKER; break; + case InternalDeviceType::DEVICE_TYPE_USB_ARM_HEADSET: + portName = USB_SPEAKER; + break; + case InternalDeviceType::DEVICE_TYPE_FILE_SINK: + portName = FILE_SINK; + break; + default: + portName = PORT_NONE; + break; + } + + return portName; +} + +std::string AudioPolicyService::GetSourcePortName(InternalDeviceType deviceType) +{ + std::string portName = PORT_NONE; + switch (deviceType) { case InternalDeviceType::DEVICE_TYPE_MIC: portName = PRIMARY_MIC; break; + case InternalDeviceType::DEVICE_TYPE_USB_ARM_HEADSET: + portName = USB_MIC; + break; case InternalDeviceType::DEVICE_TYPE_WAKEUP: portName = PRIMARY_WAKEUP; break; - case InternalDeviceType::DEVICE_TYPE_FILE_SINK: - portName = FILE_SINK; - break; case InternalDeviceType::DEVICE_TYPE_FILE_SOURCE: portName = FILE_SOURCE; break; @@ -845,7 +863,6 @@ std::string AudioPolicyService::GetPortName(InternalDeviceType deviceType) break; } - AUDIO_INFO_LOG("port name is %{public}s", portName.c_str()); return portName; } @@ -1185,7 +1202,8 @@ void UpdateActiveDeviceRoute(InternalDeviceType deviceType) switch (deviceType) { case DEVICE_TYPE_BLUETOOTH_SCO: case DEVICE_TYPE_USB_HEADSET: - case DEVICE_TYPE_WIRED_HEADSET: { + case DEVICE_TYPE_WIRED_HEADSET: + case DEVICE_TYPE_USB_ARM_HEADSET: { ret = g_adProxy->UpdateActiveDeviceRoute(deviceType, DeviceFlag::ALL_DEVICES_FLAG); CHECK_AND_RETURN_LOG(ret == SUCCESS, "Failed to update the route for %{public}d", deviceType); break; @@ -1245,12 +1263,17 @@ int32_t AudioPolicyService::SelectNewDevice(DeviceRole deviceRole, DeviceType de int32_t result = SUCCESS; if (deviceRole == DeviceRole::OUTPUT_DEVICE) { - std::string activePort = GetPortName(currentActiveDevice_); + std::string activePort = GetSinkPortName(currentActiveDevice_); AUDIO_INFO_LOG("port %{public}s, active device %{public}d", activePort.c_str(), currentActiveDevice_); audioPolicyManager_.SuspendAudioDevice(activePort, true); } - std::string portName = GetPortName(deviceType); + std::string portName; + if (deviceRole == DeviceRole::OUTPUT_DEVICE) { + portName = GetSinkPortName(deviceType); + } else { + portName = GetSourcePortName(deviceType); + } CHECK_AND_RETURN_RET_LOG(portName != PORT_NONE, result, "Invalid port name %{public}s", portName.c_str()); if (deviceRole == DeviceRole::OUTPUT_DEVICE) { @@ -1281,39 +1304,116 @@ int32_t AudioPolicyService::SelectNewDevice(DeviceRole deviceRole, DeviceType de return SUCCESS; } -int32_t AudioPolicyService::HandleA2dpDevice(DeviceType deviceType) +int32_t AudioPolicyService::LoadA2dpModule(DeviceType deviceType) { - Trace trace("AudioPolicyService::HandleA2dpDevice"); - std::string activePort = GetPortName(currentActiveDevice_); - if (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP) { + std::list moduleInfoList; + { + std::lock_guard deviceInfoLock(deviceClassInfoMutex_); auto primaryModulesPos = deviceClassInfo_.find(ClassType::TYPE_A2DP); - if (primaryModulesPos != deviceClassInfo_.end()) { - auto moduleInfoList = primaryModulesPos->second; - for (auto &moduleInfo : moduleInfoList) { - if (IOHandles_.find(moduleInfo.name) == IOHandles_.end()) { - AUDIO_INFO_LOG("Load a2dp module [%{public}s]", moduleInfo.name.c_str()); - AudioStreamInfo audioStreamInfo = {}; - GetActiveDeviceStreamInfo(deviceType, audioStreamInfo); - uint32_t bufferSize = (audioStreamInfo.samplingRate * GetSampleFormatValue(audioStreamInfo.format) * - audioStreamInfo.channels) / (PCM_8_BIT * BT_BUFFER_ADJUSTMENT_FACTOR); - AUDIO_INFO_LOG("a2dp rate: %{public}d, format: %{public}d, channel: %{public}d", - audioStreamInfo.samplingRate, audioStreamInfo.format, audioStreamInfo.channels); - moduleInfo.channels = to_string(audioStreamInfo.channels); - moduleInfo.rate = to_string(audioStreamInfo.samplingRate); - moduleInfo.format = ConvertToHDIAudioFormat(audioStreamInfo.format); - moduleInfo.bufferSize = to_string(bufferSize); + if (primaryModulesPos == deviceClassInfo_.end()) { + AUDIO_ERR_LOG("A2dp module is not exist in the configuration file"); + return ERR_OPERATION_FAILED; + } + moduleInfoList = primaryModulesPos->second; + } + for (auto &moduleInfo : moduleInfoList) { + std::lock_guard ioHandleLock(ioHandlesMutex_); + if (IOHandles_.find(moduleInfo.name) == IOHandles_.end()) { + AUDIO_INFO_LOG("Load a2dp module [%{public}s]", moduleInfo.name.c_str()); + AudioStreamInfo audioStreamInfo = {}; + GetActiveDeviceStreamInfo(deviceType, audioStreamInfo); + uint32_t bufferSize = (audioStreamInfo.samplingRate * GetSampleFormatValue(audioStreamInfo.format) * + audioStreamInfo.channels) / (PCM_8_BIT * BT_BUFFER_ADJUSTMENT_FACTOR); + AUDIO_INFO_LOG("a2dp rate: %{public}d, format: %{public}d, channel: %{public}d", + audioStreamInfo.samplingRate, audioStreamInfo.format, audioStreamInfo.channels); + moduleInfo.channels = to_string(audioStreamInfo.channels); + moduleInfo.rate = to_string(audioStreamInfo.samplingRate); + moduleInfo.format = ConvertToHDIAudioFormat(audioStreamInfo.format); + moduleInfo.bufferSize = to_string(bufferSize); - 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; - } + 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; + } + } - AUDIO_INFO_LOG("port %{public}s, active device %{public}d", activePort.c_str(), currentActiveDevice_); - audioPolicyManager_.SuspendAudioDevice(activePort, true); - } + std::string activePort = GetSinkPortName(currentActiveDevice_); + AUDIO_INFO_LOG("port %{public}s, active device %{public}d", activePort.c_str(), currentActiveDevice_); + audioPolicyManager_.SuspendAudioDevice(activePort, true); + + return SUCCESS; +} + +int32_t AudioPolicyService::LoadUsbModule(DeviceType deviceType) +{ + 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_); + 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_) : ""; + 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_); + AUDIO_INFO_LOG("port %{public}s, active device %{public}d", activePort.c_str(), currentActiveDevice_); + audioPolicyManager_.SuspendAudioDevice(activePort, true); + + return SUCCESS; +} + +int32_t AudioPolicyService::HandleActiveDevice(DeviceType deviceType) +{ + if (isUpdateRouteSupported_) { + UpdateActiveDeviceRoute(deviceType); + } + SetVolumeForSwitchDevice(deviceType); + + std::string sinkPortName = GetSinkPortName(deviceType); + std::string sourcePortName = GetSourcePortName(deviceType); + if (sinkPortName == PORT_NONE && sourcePortName == PORT_NONE) { + AUDIO_ERR_LOG("HandleActiveDevice failed for sinkPortName and sourcePortName are none"); + return ERR_OPERATION_FAILED; + } + if (sinkPortName != PORT_NONE) { + AudioIOHandle ioHandle = GetSinkIOHandle(deviceType); + audioPolicyManager_.SetDeviceActive(ioHandle, deviceType, sinkPortName, true); + audioPolicyManager_.SuspendAudioDevice(sinkPortName, false); + } + if (sourcePortName != PORT_NONE) { + AudioIOHandle ioHandle = GetSourceIOHandle(deviceType); + audioPolicyManager_.SetDeviceActive(ioHandle, deviceType, sourcePortName, true); + audioPolicyManager_.SuspendAudioDevice(sourcePortName, false); + } + UpdateInputDeviceInfo(deviceType); + + return SUCCESS; +} + +int32_t AudioPolicyService::HandleA2dpDevice(DeviceType deviceType) +{ + Trace trace("AudioPolicyService::HandleA2dpDevice"); + if (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP) { + int32_t ret = LoadA2dpModule(deviceType); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("load A2dp module failed"); + return ERR_OPERATION_FAILED; } } else if (currentActiveDevice_ == DEVICE_TYPE_BLUETOOTH_A2DP) { + std::string activePort = GetSinkPortName(currentActiveDevice_); audioPolicyManager_.SuspendAudioDevice(activePort, true); int32_t muteDuration = 1000000; // us std::thread switchThread(&AudioPolicyService::KeepPortMute, this, muteDuration, PRIMARY_SPEAKER, deviceType); @@ -1322,35 +1422,52 @@ int32_t AudioPolicyService::HandleA2dpDevice(DeviceType deviceType) usleep(beforSwitchDelay); } - if (isUpdateRouteSupported_) { - UpdateActiveDeviceRoute(deviceType); - } - SetVolumeForSwitchDevice(deviceType); - - AudioIOHandle ioHandle = GetAudioIOHandle(deviceType); - std::string portName = GetPortName(deviceType); - CHECK_AND_RETURN_RET_LOG(portName != PORT_NONE, ERR_OPERATION_FAILED, "Invalid port %{public}s", portName.c_str()); + return HandleActiveDevice(deviceType); +} - int32_t result = audioPolicyManager_.SetDeviceActive(ioHandle, deviceType, portName, true); - CHECK_AND_RETURN_RET_LOG(portName != PORT_NONE, result, "SetDeviceActive failed %{public}d", result); - audioPolicyManager_.SuspendAudioDevice(portName, false); +int32_t AudioPolicyService::HandleUsbDevice(DeviceType deviceType) +{ + Trace trace("AudioPolicyService::HandleUsbDevice"); - UpdateInputDeviceInfo(deviceType); + if (deviceType == DEVICE_TYPE_USB_ARM_HEADSET) { + int32_t ret = LoadUsbModule(deviceType); + if (ret != SUCCESS) { + AUDIO_ERR_LOG ("load Usb module failed"); + return ERR_OPERATION_FAILED; + } + } else if (currentActiveDevice_ == DEVICE_TYPE_USB_ARM_HEADSET) { + std::string activePort = GetSinkPortName(currentActiveDevice_); + audioPolicyManager_.SuspendAudioDevice(activePort, true); + int32_t muteDuration = 1000000; // us + std::thread switchThread(&AudioPolicyService::KeepPortMute, this, muteDuration, activePort, deviceType); + switchThread.detach(); + int32_t beforSwitchDelay = 300000; + usleep(beforSwitchDelay); + } - return SUCCESS; + return HandleActiveDevice(deviceType); } int32_t AudioPolicyService::HandleFileDevice(DeviceType deviceType) { AUDIO_INFO_LOG("HandleFileDevice"); - AudioIOHandle ioHandle = GetAudioIOHandle(deviceType); - std::string portName = GetPortName(deviceType); - CHECK_AND_RETURN_RET_LOG(portName != PORT_NONE, ERR_OPERATION_FAILED, "Invalid port %{public}s", portName.c_str()); - - int32_t result = audioPolicyManager_.SetDeviceActive(ioHandle, deviceType, portName, true); - CHECK_AND_RETURN_RET_LOG(portName != PORT_NONE, result, "SetDeviceActive failed %{public}d", result); - audioPolicyManager_.SuspendAudioDevice(portName, false); + std::string sinkPortName = GetSinkPortName(deviceType); + std::string sourcePortName = GetSourcePortName(deviceType); + if (sinkPortName == PORT_NONE && sourcePortName == PORT_NONE) { + AUDIO_ERR_LOG("HandleFileDevice failed for sinkPortName and sourcePortName are none"); + return ERR_OPERATION_FAILED; + } + if (sinkPortName != PORT_NONE) { + AudioIOHandle ioHandle = GetSinkIOHandle(deviceType); + audioPolicyManager_.SetDeviceActive(ioHandle, deviceType, sinkPortName, true); + audioPolicyManager_.SuspendAudioDevice(sinkPortName, false); + } + if (sourcePortName != PORT_NONE) { + AudioIOHandle ioHandle = GetSourceIOHandle(deviceType); + audioPolicyManager_.SetDeviceActive(ioHandle, deviceType, sourcePortName, true); + audioPolicyManager_.SuspendAudioDevice(sourcePortName, false); + } if (isUpdateRouteSupported_) { UpdateActiveDeviceRoute(deviceType); } @@ -1373,12 +1490,17 @@ int32_t AudioPolicyService::ActivateNewDevice(DeviceType deviceType, bool isScen return result; } + if (deviceType == DEVICE_TYPE_USB_ARM_HEADSET || currentActiveDevice_ == DEVICE_TYPE_USB_ARM_HEADSET) { + result = HandleUsbDevice(deviceType); + return result; + } + if (deviceType == DEVICE_TYPE_FILE_SINK || currentActiveDevice_ == DEVICE_TYPE_FILE_SINK) { result = HandleFileDevice(deviceType); return result; } - std::string portName = GetPortName(deviceType); + std::string portName = GetSinkPortName(deviceType); CHECK_AND_RETURN_RET_LOG(portName != PORT_NONE, ERR_OPERATION_FAILED, "Invalid port %{public}s", portName.c_str()); bool isVolumeSwitched = false; if (isUpdateRouteSupported_ && !isSceneActivation) { @@ -1763,10 +1885,10 @@ void AudioPolicyService::OnPnpDeviceStatusUpdated(DeviceType devType, bool isCon isPnpDeviceConnected = isConnected; return; } - AudioStreamInfo streamInfo = {}; if (g_adProxy == nullptr) { GetAudioServerProxy(); } + AudioStreamInfo streamInfo = {}; OnDeviceStatusUpdated(devType, isConnected, "", "", streamInfo); } @@ -1836,7 +1958,16 @@ int32_t AudioPolicyService::HandleLocalDeviceDisconnected(DeviceType devType, co IOHandles_.erase(BLUETOOTH_SPEAKER); } } - + if (devType == DEVICE_TYPE_USB_ARM_HEADSET) { + if (IOHandles_.find(USB_SPEAKER) != IOHandles_.end()) { + audioPolicyManager_.CloseAudioPort(IOHandles_[USB_SPEAKER]); + IOHandles_.erase(USB_SPEAKER); + } + if (IOHandles_.find(USB_MIC) != IOHandles_.end()) { + audioPolicyManager_.CloseAudioPort(IOHandles_[USB_MIC]); + IOHandles_.erase(USB_MIC); + } + } return result; } @@ -1846,7 +1977,8 @@ DeviceType AudioPolicyService::FindConnectedHeadset() for (const auto& devDesc: connectedDevices_) { if ((devDesc->deviceType_ == DEVICE_TYPE_WIRED_HEADSET) || (devDesc->deviceType_ == DEVICE_TYPE_WIRED_HEADPHONES) || - (devDesc->deviceType_ == DEVICE_TYPE_USB_HEADSET)) { + (devDesc->deviceType_ == DEVICE_TYPE_USB_HEADSET) || + (devDesc->deviceType_ == DEVICE_TYPE_USB_ARM_HEADSET)) { retType = devDesc->deviceType_; break; } @@ -1854,27 +1986,53 @@ DeviceType AudioPolicyService::FindConnectedHeadset() return retType; } -void AudioPolicyService::OnDeviceStatusUpdated(DeviceType devType, bool isConnected, const std::string& macAddress, - const std::string& deviceName, const AudioStreamInfo& streamInfo) +int32_t AudioPolicyService::handleSpecialDeviceType(DeviceType &devType, bool &isConnected) { - AUDIO_INFO_LOG("Device connection state updated | TYPE[%{public}d] STATUS[%{public}d]", devType, 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; + } + } + } // Special logic for extern cable, need refactor if (devType == DEVICE_TYPE_EXTERN_CABLE) { if (!isConnected) { AUDIO_INFO_LOG("Extern cable disconnected, do nothing"); - return; + return ERROR; } DeviceType connectedHeadsetType = FindConnectedHeadset(); if (connectedHeadsetType == DEVICE_TYPE_NONE) { AUDIO_INFO_LOG("Extern cable connect without headset connected before, do nothing"); - return; + return ERROR; } devType = connectedHeadsetType; - isConnected = false; + isConnected = false; } + return SUCCESS; +} + +void AudioPolicyService::OnDeviceStatusUpdated(DeviceType devType, bool isConnected, const std::string& macAddress, + const std::string& deviceName, const AudioStreamInfo& streamInfo) +{ + AUDIO_INFO_LOG("Device connection state updated | TYPE[%{public}d] STATUS[%{public}d]", devType, isConnected); + int32_t result = ERROR; + result = handleSpecialDeviceType(devType, isConnected); + CHECK_AND_RETURN_LOG(result == SUCCESS, "handle special deviceType failed."); AudioDeviceDescriptor deviceDesc(devType, GetDeviceRole(devType)); UpdateLocalGroupInfo(isConnected, macAddress, deviceName, streamInfo, deviceDesc); @@ -1963,7 +2121,7 @@ void AudioPolicyService::OnDeviceConfigurationChanged(DeviceType deviceType, con // First unload the existing bt sink AUDIO_DEBUG_LOG("UnLoad existing a2dp module"); - std::string currentActivePort = GetPortName(currentActiveDevice_); + std::string currentActivePort = GetSinkPortName(currentActiveDevice_); AudioIOHandle activateDeviceIOHandle = IOHandles_[BLUETOOTH_SPEAKER]; audioPolicyManager_.SuspendAudioDevice(currentActivePort, true); audioPolicyManager_.CloseAudioPort(activateDeviceIOHandle); @@ -1973,7 +2131,7 @@ void AudioPolicyService::OnDeviceConfigurationChanged(DeviceType deviceType, con AudioIOHandle ioHandle = audioPolicyManager_.OpenAudioPort(moduleInfo); CHECK_AND_RETURN_LOG(ioHandle != OPEN_PORT_FAILURE, "OpenAudioPort failed %{public}d", ioHandle); IOHandles_[moduleInfo.name] = ioHandle; - std::string portName = GetPortName(deviceType); + std::string portName = GetSinkPortName(deviceType); audioPolicyManager_.SetDeviceActive(ioHandle, deviceType, portName, true); audioPolicyManager_.SuspendAudioDevice(portName, false); @@ -2265,11 +2423,12 @@ void AudioPolicyService::UpdateEffectDefaultSink(DeviceType deviceType) case DeviceType::DEVICE_TYPE_FILE_SINK: case DeviceType::DEVICE_TYPE_WIRED_HEADSET: case DeviceType::DEVICE_TYPE_USB_HEADSET: + case DeviceType::DEVICE_TYPE_USB_ARM_HEADSET: case DeviceType::DEVICE_TYPE_BLUETOOTH_A2DP: case DeviceType::DEVICE_TYPE_BLUETOOTH_SCO: { const sptr gsp = GetAudioServerProxy(); CHECK_AND_RETURN_LOG(gsp != nullptr, "Service proxy unavailable"); - std::string sinkName = GetPortName(deviceType); + std::string sinkName = GetSinkPortName(deviceType); bool ret = gsp->SetOutputDeviceSink(deviceType, sinkName); CHECK_AND_RETURN_LOG(ret, "Failed to set output device sink"); int res = audioPolicyManager_.UpdateSwapDeviceStatus(); @@ -2854,7 +3013,7 @@ int32_t AudioPolicyService::ReconfigureAudioChannel(const uint32_t &channelCount } // private methods -AudioIOHandle AudioPolicyService::GetAudioIOHandle(InternalDeviceType deviceType) +AudioIOHandle AudioPolicyService::GetSinkIOHandle(InternalDeviceType deviceType) { AudioIOHandle ioHandle; switch (deviceType) { @@ -2866,15 +3025,32 @@ AudioIOHandle AudioPolicyService::GetAudioIOHandle(InternalDeviceType deviceType case InternalDeviceType::DEVICE_TYPE_BLUETOOTH_SCO: ioHandle = IOHandles_[PRIMARY_SPEAKER]; break; + case InternalDeviceType::DEVICE_TYPE_USB_ARM_HEADSET: + ioHandle = IOHandles_[USB_SPEAKER]; + break; case InternalDeviceType::DEVICE_TYPE_BLUETOOTH_A2DP: ioHandle = IOHandles_[BLUETOOTH_SPEAKER]; break; - case InternalDeviceType::DEVICE_TYPE_MIC: - ioHandle = IOHandles_[PRIMARY_MIC]; - break; case InternalDeviceType::DEVICE_TYPE_FILE_SINK: ioHandle = IOHandles_[FILE_SINK]; break; + default: + ioHandle = IOHandles_[PRIMARY_SPEAKER]; + break; + } + return ioHandle; +} + +AudioIOHandle AudioPolicyService::GetSourceIOHandle(InternalDeviceType deviceType) +{ + AudioIOHandle ioHandle; + switch (deviceType) { + case InternalDeviceType::DEVICE_TYPE_USB_ARM_HEADSET: + ioHandle = IOHandles_[USB_MIC]; + break; + case InternalDeviceType::DEVICE_TYPE_MIC: + ioHandle = IOHandles_[PRIMARY_MIC]; + break; case InternalDeviceType::DEVICE_TYPE_FILE_SOURCE: ioHandle = IOHandles_[FILE_SOURCE]; break; @@ -3163,6 +3339,7 @@ bool AudioPolicyService::IsInputDevice(DeviceType deviceType) const case DeviceType::DEVICE_TYPE_MIC: case DeviceType::DEVICE_TYPE_WAKEUP: case DeviceType::DEVICE_TYPE_USB_HEADSET: + case DeviceType::DEVICE_TYPE_USB_ARM_HEADSET: return true; default: return false; @@ -3179,6 +3356,7 @@ bool AudioPolicyService::IsOutputDevice(DeviceType deviceType) const case DeviceType::DEVICE_TYPE_BLUETOOTH_SCO: case DeviceType::DEVICE_TYPE_BLUETOOTH_A2DP: case DeviceType::DEVICE_TYPE_USB_HEADSET: + case DeviceType::DEVICE_TYPE_USB_ARM_HEADSET: return true; default: return false; @@ -3194,6 +3372,7 @@ DeviceRole AudioPolicyService::GetDeviceRole(DeviceType deviceType) const case DeviceType::DEVICE_TYPE_WIRED_HEADSET: case DeviceType::DEVICE_TYPE_WIRED_HEADPHONES: case DeviceType::DEVICE_TYPE_USB_HEADSET: + case DeviceType::DEVICE_TYPE_USB_ARM_HEADSET: return DeviceRole::OUTPUT_DEVICE; case DeviceType::DEVICE_TYPE_MIC: case DeviceType::DEVICE_TYPE_WAKEUP: @@ -3273,6 +3452,7 @@ void AudioPolicyService::UpdateInputDeviceInfo(DeviceType deviceType) 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; @@ -3307,6 +3487,9 @@ DeviceType AudioPolicyService::GetDeviceTypeFromPin(AudioPin hdiPin) break; case OHOS::AudioStandard::AUDIO_PIN_OUT_USB_EXT: break; + case OHOS::AudioStandard::AUDIO_PIN_OUT_USB_HEADSET: + case OHOS::AudioStandard::AUDIO_PIN_IN_USB_HEADSET: + return DeviceType::DEVICE_TYPE_USB_ARM_HEADSET; case OHOS::AudioStandard::AUDIO_PIN_IN_MIC: case OHOS::AudioStandard::AUDIO_PIN_IN_DAUDIO_DEFAULT: return DeviceType::DEVICE_TYPE_MIC; diff --git a/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp b/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp index 0e040abd76ab2781a97f1550bf4b0bfd5521a8a4..008a7db5c298530c00c76ad0d6a05fab9e67df14 100644 --- a/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp +++ b/services/audio_policy/server/src/service/manager/audio_adapter_manager.cpp @@ -387,6 +387,13 @@ int32_t AudioAdapterManager::SetDeviceActive(AudioIOHandle ioHandle, InternalDev } switch (deviceType) { + case InternalDeviceType::DEVICE_TYPE_USB_ARM_HEADSET: { + if (name == USB_SPEAKER) { + return audioServiceAdapter_->SetDefaultSink(name); + } else { + return audioServiceAdapter_->SetDefaultSource(name); + } + } case InternalDeviceType::DEVICE_TYPE_EARPIECE: case InternalDeviceType::DEVICE_TYPE_SPEAKER: case InternalDeviceType::DEVICE_TYPE_FILE_SINK: diff --git a/services/audio_service/server/include/audio_server.h b/services/audio_service/server/include/audio_server.h index a9701eea6ad584626e670828cdc5b23a0f468df9..5cf9cc9a0f92f9625760f1acc2477da0feecf62a 100644 --- a/services/audio_service/server/include/audio_server.h +++ b/services/audio_service/server/include/audio_server.h @@ -104,6 +104,7 @@ private: void AudioServerDied(pid_t pid); void RegisterPolicyServerDeathRecipient(); void RegisterAudioCapturerSourceCallback(); + int32_t SetIORoute(DeviceType type, DeviceFlag flag); private: static constexpr int32_t MEDIA_SERVICE_UID = 1013; diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index b2814fa5d4bfc31c0f3880bbeab8e1c9247b7804..f14db61526b6cd037472761692ef37dc06a45d97 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -213,6 +213,10 @@ const std::string AudioServer::GetAudioParameter(const std::string &key) HiviewDFX::XCollie::GetInstance().CancelTimer(id); return audioRendererSinkInstance->GetAudioParameter(AudioParamKey(parmKey), ""); } + if (key == "need_change_usb_device") { + parmKey = AudioParamKey::USB_DEVICE; + return audioRendererSinkInstance->GetAudioParameter(AudioParamKey(parmKey), "need_change_usb_device"); + } } if (AudioServer::audioParameters.count(key)) { @@ -276,7 +280,12 @@ uint64_t AudioServer::GetTransactionId(DeviceType deviceType, DeviceRole deviceR return ERR_INVALID_PARAM; } if (deviceRole == INPUT_DEVICE) { - AudioCapturerSource *audioCapturerSourceInstance = AudioCapturerSource::GetInstance(); + AudioCapturerSource *audioCapturerSourceInstance; + if (deviceType == DEVICE_TYPE_USB_ARM_HEADSET) { + audioCapturerSourceInstance = AudioCapturerSource::GetInstance("usb"); + } else { + audioCapturerSourceInstance = AudioCapturerSource::GetInstance("primary"); + } if (audioCapturerSourceInstance) { transactionId = audioCapturerSourceInstance->GetTransactionId(); } @@ -288,6 +297,8 @@ uint64_t AudioServer::GetTransactionId(DeviceType deviceType, DeviceRole deviceR IAudioRendererSink *iRendererInstance = nullptr; if (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP) { iRendererInstance = IAudioRendererSink::GetInstance("a2dp", ""); + } else if (deviceType == DEVICE_TYPE_USB_ARM_HEADSET) { + iRendererInstance = IAudioRendererSink::GetInstance("usb", ""); } else { iRendererInstance = IAudioRendererSink::GetInstance("primary", ""); } @@ -433,56 +444,61 @@ int32_t AudioServer::SetAudioScene(AudioScene audioScene, DeviceType activeDevic return SUCCESS; } -int32_t AudioServer::UpdateActiveDeviceRoute(DeviceType type, DeviceFlag flag) +int32_t AudioServer::SetIORoute(DeviceType type, DeviceFlag flag) { - int32_t callingUid = IPCSkeleton::GetCallingUid(); - if (callingUid != audioUid_ && callingUid != ROOT_UID) { - AUDIO_ERR_LOG("UpdateActiveDeviceRoute refused for %{public}d", callingUid); - return ERR_NOT_SUPPORTED; + AUDIO_INFO_LOG("SetIORoute deviceType: %{public}d, flag: %{public}d", type, flag); + AudioCapturerSource *audioCapturerSourceInstance; + IAudioRendererSink *audioRendererSinkInstance; + if (type == DEVICE_TYPE_USB_ARM_HEADSET) { + audioCapturerSourceInstance = AudioCapturerSource::GetInstance("usb"); + audioRendererSinkInstance = IAudioRendererSink::GetInstance("usb", ""); + } else { + audioCapturerSourceInstance = AudioCapturerSource::GetInstance("primary"); + audioRendererSinkInstance = IAudioRendererSink::GetInstance("primary", ""); } - AUDIO_INFO_LOG("UpdateActiveDeviceRoute deviceType: %{public}d, flag: %{public}d", type, flag); - AudioCapturerSource *audioCapturerSourceInstance = AudioCapturerSource::GetInstance(); - IAudioRendererSink *audioRendererSinkInstance = IAudioRendererSink::GetInstance("primary", ""); - if (audioCapturerSourceInstance == nullptr || audioRendererSinkInstance == nullptr) { - AUDIO_ERR_LOG("UpdateActiveDeviceRoute null instance!"); + AUDIO_ERR_LOG("SetIORoute failed for null instance!"); return ERR_INVALID_PARAM; } - switch (flag) { - case DeviceFlag::INPUT_DEVICES_FLAG: { - if (audioScene_ != AUDIO_SCENE_DEFAULT) { - audioCapturerSourceInstance->SetAudioScene(audioScene_, type); - } else { - audioCapturerSourceInstance->SetInputRoute(type); - } - break; + if (flag == DeviceFlag::INPUT_DEVICES_FLAG) { + if (audioScene_ != AUDIO_SCENE_DEFAULT) { + audioCapturerSourceInstance->SetAudioScene(audioScene_, type); + } else { + audioCapturerSourceInstance->SetInputRoute(type); } - case DeviceFlag::OUTPUT_DEVICES_FLAG: { - if (audioScene_ != AUDIO_SCENE_DEFAULT) { - audioRendererSinkInstance->SetAudioScene(audioScene_, type); - } else { - audioRendererSinkInstance->SetOutputRoute(type); - } - break; + } else if (flag == DeviceFlag::OUTPUT_DEVICES_FLAG) { + if (audioScene_ != AUDIO_SCENE_DEFAULT) { + audioRendererSinkInstance->SetAudioScene(audioScene_, type); + } else { + audioRendererSinkInstance->SetOutputRoute(type); } - case DeviceFlag::ALL_DEVICES_FLAG: { - if (audioScene_ != AUDIO_SCENE_DEFAULT) { - SetAudioScene(audioScene_, type); - } else { - audioCapturerSourceInstance->SetInputRoute(type); - audioRendererSinkInstance->SetOutputRoute(type); - } - break; + PolicyHandler::GetInstance().SetActiveOutputDevice(type); + } else if (flag == DeviceFlag::ALL_DEVICES_FLAG) { + if (audioScene_ != AUDIO_SCENE_DEFAULT) { + SetAudioScene(audioScene_, type); + } else { + audioCapturerSourceInstance->SetInputRoute(type); + audioRendererSinkInstance->SetOutputRoute(type); } - default: - break; - } - if (flag == ALL_DEVICES_FLAG || flag == OUTPUT_DEVICES_FLAG) { PolicyHandler::GetInstance().SetActiveOutputDevice(type); + } else { + AUDIO_ERR_LOG("SetIORoute invalid device flag"); + return ERR_INVALID_PARAM; } - return SUCCESS; + return SUCCESS; +} + +int32_t AudioServer::UpdateActiveDeviceRoute(DeviceType type, DeviceFlag flag) +{ + int32_t callingUid = IPCSkeleton::GetCallingUid(); + if (callingUid != audioUid_ && callingUid != ROOT_UID) { + AUDIO_ERR_LOG("UpdateActiveDeviceRoute refused for %{public}d", callingUid); + return ERR_NOT_SUPPORTED; + } + + return SetIORoute(type, flag); } void AudioServer::SetAudioMonoState(bool audioMono)