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 c24c2a45b7aaa6ad4ab1403b0383b5fb46bfc57b..50cc40bcdd017c3dc59a114535f5bc315f05c92b 100644 --- a/services/audio_policy/server/include/service/audio_policy_service.h +++ b/services/audio_policy/server/include/service/audio_policy_service.h @@ -229,6 +229,8 @@ private: DeviceRole GetDeviceRole(const std::string &role); + int32_t SelectNewDevice(DeviceRole deviceRole, DeviceType deviceType); + int32_t ActivateNewDevice(DeviceType deviceType, bool isSceneActivation); DeviceRole GetDeviceRole(AudioPin pin) const; @@ -266,6 +268,8 @@ private: bool interruptEnabled_ = true; bool isUpdateRouteSupported_ = true; + bool isCurrentRemoteRenderer = false; + bool remoteCapturerSwitch = false; bool isOpenRemoteDevice = false; bool isBtListenerRegistered = false; const int32_t G_UNKNOWN_PID = -1; diff --git a/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h b/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h index bab0ba1b74636592bc404983abdf03c834401b1b..4a7a86f1c1d664e0f8997a2b734363194bdae330 100644 --- a/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h +++ b/services/audio_policy/server/include/service/interface/iaudio_policy_interface.h @@ -57,6 +57,8 @@ public: virtual int32_t CloseAudioPort(AudioIOHandle ioHandle) = 0; + virtual int32_t SelectDevice(DeviceRole deviceRole, InternalDeviceType deviceType, std::string name); + virtual int32_t SetDeviceActive(AudioIOHandle ioHandle, InternalDeviceType deviceType, std::string name, bool active) = 0; diff --git a/services/audio_policy/server/include/service/manager/audio_adapter_manager.h b/services/audio_policy/server/include/service/manager/audio_adapter_manager.h index 30318028c7a0fec7cbe32abb5ed430883d5917a5..65a903531add98316cea991a2e59b56f8973706b 100644 --- a/services/audio_policy/server/include/service/manager/audio_adapter_manager.h +++ b/services/audio_policy/server/include/service/manager/audio_adapter_manager.h @@ -73,8 +73,12 @@ public: int32_t CloseAudioPort(AudioIOHandle ioHandle); + int32_t SelectDevice(DeviceRole deviceRole, InternalDeviceType deviceType, std::string name); + int32_t SetDeviceActive(AudioIOHandle ioHandle, InternalDeviceType deviceType, std::string name, bool active); + void SetVolumeForSwitchDevice(InternalDeviceType deviceType); + int32_t MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName); int32_t MoveSourceOutputByIndexOrName(uint32_t sourceOutputId, uint32_t sourceIndex, std::string sourceName); 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 2da802e4edef0861f3d56e47ed4e9074f5b7fb32..be17816bf418e3528097ba6ef013714960039946 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -300,11 +300,11 @@ int32_t AudioPolicyService::SelectOutputDevice(sptr audioRe DeviceType deviceType = audioDeviceDescriptors[0]->deviceType_; // switch between local devices - if (LOCAL_NETWORK_ID == networkId && currentActiveDevice_ != deviceType) { + if (!isCurrentRemoteRenderer && LOCAL_NETWORK_ID == networkId && currentActiveDevice_ != deviceType) { if (deviceType == DeviceType::DEVICE_TYPE_DEFAULT) { deviceType = FetchHighPriorityDevice(); } - return SetDeviceActive(deviceType, true); + return SelectNewDevice(DeviceRole::OUTPUT_DEVICE, deviceType); } int32_t targetUid = audioRendererFilter->uid; @@ -407,6 +407,7 @@ int32_t AudioPolicyService::MoveToLocalOutputDevice(std::vector sinkI routerMap_[sinkInputIds[i].uid] = std::pair(LOCAL_NETWORK_ID, sinkInputIds[i].pid); } + isCurrentRemoteRenderer = false; return SUCCESS; } @@ -475,6 +476,7 @@ int32_t AudioPolicyService::MoveToRemoteOutputDevice(std::vector sink if (deviceType != DeviceType::DEVICE_TYPE_DEFAULT) { AUDIO_WARNING_LOG("Not defult type[%{public}d] on device:[%{public}s]", deviceType, networkId.c_str()); } + isCurrentRemoteRenderer = true; return SUCCESS; } @@ -501,7 +503,18 @@ int32_t AudioPolicyService::SelectInputDevice(sptr audioCap static_cast(audioDeviceDescriptors[0]->deviceRole_)); return ERR_INVALID_OPERATION; } + std::string networkId = audioDeviceDescriptors[0]->networkId_; + DeviceType deviceType = audioDeviceDescriptors[0]->deviceType_; + // switch between local devices + if (LOCAL_NETWORK_ID == networkId && activeInputDevice_ != deviceType) { + return SelectNewDevice(DeviceRole::INPUT_DEVICE, deviceType); + } + + if (!remoteCapturerSwitch) { + AUDIO_DEBUG_LOG("remote capturer capbility is not open now"); + return SUCCESS; + } int32_t targetUid = audioCapturerFilter->uid; // move all source-output. bool moveAll = false; @@ -521,7 +534,6 @@ int32_t AudioPolicyService::SelectInputDevice(sptr audioCap } int32_t ret = SUCCESS; - std::string networkId = audioDeviceDescriptors[0]->networkId_; if (LOCAL_NETWORK_ID == networkId) { ret = MoveToLocalInputDevice(targetSourceOutputIds, audioDeviceDescriptors[0]); } else { @@ -821,6 +833,38 @@ static uint32_t GetSampleFormatValue(AudioSampleFormat sampleFormat) } } +int32_t AudioPolicyService::SelectNewDevice(DeviceRole deviceRole, DeviceType deviceType) +{ + int32_t result = SUCCESS; + DeviceType activeDevice = deviceRole == DeviceRole::OUTPUT_DEVICE ? currentActiveDevice_ : activeInputDevice_; + + if (activeDevice == deviceType) { + return result; + } + + std::string activePort = GetPortName(activeDevice); + AUDIO_INFO_LOG("port %{public}s, active device %{public}d", activePort.c_str(), activeDevice); + audioPolicyManager_.SuspendAudioDevice(activePort, true); + + std::string portName = GetPortName(deviceType); + CHECK_AND_RETURN_RET_LOG(portName != PORT_NONE, result, "Invalid port name %{public}s", portName.c_str()); + + result = audioPolicyManager_.SelectDevice(deviceRole, deviceType, portName); + CHECK_AND_RETURN_RET_LOG(portName != PORT_NONE, result, "SetDeviceActive failed %{public}d", result); + audioPolicyManager_.SuspendAudioDevice(portName, false); + + if (isUpdateRouteSupported_) { + DeviceFlag deviceFlag = deviceRole == DeviceRole::OUTPUT_DEVICE ? OUTPUT_DEVICES_FLAG : INPUT_DEVICES_FLAG; + g_sProxy->UpdateActiveDeviceRoute(deviceType, deviceFlag); + } + + if (deviceRole == DeviceRole::OUTPUT_DEVICE) { + currentActiveDevice_ = deviceType; + } else { + activeInputDevice_ = deviceType; + } + return SUCCESS; +} int32_t AudioPolicyService::ActivateNewDevice(DeviceType deviceType, bool isSceneActivation = false) { int32_t result = SUCCESS; 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 785fed0f273e107af3de61d0cf96eb4b6ad429df..be83d3a4d4dd8be4e229fa14d09e608c61e94b73 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 @@ -191,6 +191,27 @@ int32_t AudioAdapterManager::SuspendAudioDevice(std::string &portName, bool isSu return mAudioServiceAdapter->SuspendAudioDevice(portName, isSuspend); } +int32_t AudioAdapterManager::SelectDevice(DeviceRole deviceRole, InternalDeviceType deviceType, std::string name) +{ + if (!mAudioServiceAdapter) { + AUDIO_ERR_LOG("[AudioAdapterManager] audio adapter null"); + return ERR_OPERATION_FAILED; + } + switch (deviceRole) { + case DeviceRole::INPUT_DEVICE: + return mAudioServiceAdapter->SetDefaultSource(name); + case DeviceRole::OUTPUT_DEVICE: { + SetVolumeForSwitchDevice(deviceType); + AUDIO_INFO_LOG("SetDefaultSink %{public}d", deviceType); + return mAudioServiceAdapter->SetDefaultSink(name); + } + default: + AUDIO_ERR_LOG("[AudioAdapterManager] error deviceRole %{public}d", deviceRole); + return ERR_OPERATION_FAILED; + } + return SUCCESS; +} + int32_t AudioAdapterManager::SetDeviceActive(AudioIOHandle ioHandle, InternalDeviceType deviceType, std::string name, bool active) { @@ -206,29 +227,7 @@ int32_t AudioAdapterManager::SetDeviceActive(AudioIOHandle ioHandle, InternalDev case InternalDeviceType::DEVICE_TYPE_USB_HEADSET: case InternalDeviceType::DEVICE_TYPE_BLUETOOTH_A2DP: case InternalDeviceType::DEVICE_TYPE_BLUETOOTH_SCO: { - if (mAudioPolicyKvStore == nullptr) { - AUDIO_ERR_LOG("[AudioAdapterManager] mAudioPolicyKvStore is null!"); - return ERR_OPERATION_FAILED; - } - currentActiveDevice_ = deviceType; - LoadVolumeMap(); - std::vector streamTypeList = { - STREAM_MUSIC, - STREAM_RING, - STREAM_VOICE_CALL, - STREAM_VOICE_ASSISTANT - }; - auto iter = streamTypeList.begin(); - while (iter != streamTypeList.end()) { - Key key = GetStreamNameByStreamType(deviceType, *iter); - Value value = Value(TransferTypeToByteArray(0)); - Status status = mAudioPolicyKvStore->Get(key, value); - if (status == SUCCESS) { - float volume = TransferByteArrayToType(value.Data()); - SetStreamVolume(*iter, volume); - } - iter++; - } + SetVolumeForSwitchDevice(deviceType); AUDIO_INFO_LOG("SetDefaultSink %{public}d", deviceType); return mAudioServiceAdapter->SetDefaultSink(name); } @@ -243,6 +242,33 @@ int32_t AudioAdapterManager::SetDeviceActive(AudioIOHandle ioHandle, InternalDev return SUCCESS; } +void AudioAdapterManager::SetVolumeForSwitchDevice(InternalDeviceType deviceType) +{ + if (mAudioPolicyKvStore == nullptr) { + AUDIO_ERR_LOG("[AudioAdapterManager] mAudioPolicyKvStore is null!"); + return; + } + currentActiveDevice_ = deviceType; + LoadVolumeMap(); + std::vector streamTypeList = { + STREAM_MUSIC, + STREAM_RING, + STREAM_VOICE_CALL, + STREAM_VOICE_ASSISTANT + }; + auto iter = streamTypeList.begin(); + while (iter != streamTypeList.end()) { + Key key = GetStreamNameByStreamType(deviceType, *iter); + Value value = Value(TransferTypeToByteArray(0)); + Status status = mAudioPolicyKvStore->Get(key, value); + if (status == SUCCESS) { + float volume = TransferByteArrayToType(value.Data()); + SetStreamVolume(*iter, volume); + } + iter++; + } +} + int32_t AudioAdapterManager::MoveSinkInputByIndexOrName(uint32_t sinkInputId, uint32_t sinkIndex, std::string sinkName) { return mAudioServiceAdapter->MoveSinkInputByIndexOrName(sinkInputId, sinkIndex, sinkName);