From 84aff4ddff6f6a4a6b42ce6d8ae5462b6485d07c Mon Sep 17 00:00:00 2001 From: wz2023 <752856023@qq.com> Date: Mon, 8 Sep 2025 19:35:35 +0800 Subject: [PATCH 1/2] AudioInjector Signed-off-by: wz2023 <752856023@qq.com> --- .../include/audio_service_adapter.h | 3 + .../include/pro_audio_service_adapter_impl.h | 2 + .../pulse_audio_service_adapter_impl.h | 2 + .../src/pro_audio_service_adapter_impl.cpp | 14 ++ .../src/pulse_audio_service_adapter_impl.cpp | 10 ++ .../audiorenderer/src/audio_renderer.cpp | 1 + .../audiostream/include/i_audio_stream.h | 1 + .../common/include/audio_service_enum.h | 5 + .../domain/pipe/include/audio_pipe_manager.h | 5 + .../domain/pipe/src/audio_pipe_manager.cpp | 59 +++++++ .../volume/include/audio_adapter_manager.h | 5 + .../volume/include/iaudio_policy_interface.h | 5 + .../volume/src/audio_adapter_manager.cpp | 29 ++++ .../service_main/include/audio_core_service.h | 7 + .../include/audio_injector_policy.h | 70 ++++++++ .../service_main/src/audio_core_service.cpp | 27 ++- .../src/audio_core_service_entry.cpp | 12 ++ .../src/audio_core_service_private.cpp | 24 +++ .../src/audio_injector_policy.cpp | 161 ++++++++++++++++++ .../include/core_service_provider_stub.h | 2 + .../include/renderer_in_client_private.h | 2 + .../client/src/core_service_provider_stub.cpp | 14 ++ .../client/src/renderer_in_client_public.cpp | 1 + .../common/include/i_core_service_provider.h | 2 + .../idl/ICoreServiceProviderIpc.idl | 8 + .../idl/IStandardAudioService.idl | 2 + .../server/include/audio_injector_service.h | 5 +- .../server/include/audio_server.h | 3 + .../server/include/core_service_handler.h | 3 + .../server/include/renderer_in_server.h | 4 + .../server/src/audio_injector_service.cpp | 6 +- .../audio_service/server/src/audio_server.cpp | 12 ++ .../server/src/core_service_handler.cpp | 16 ++ .../server/src/renderer_in_server.cpp | 19 +++ 34 files changed, 536 insertions(+), 5 deletions(-) create mode 100644 services/audio_policy/server/service/service_main/include/audio_injector_policy.h create mode 100644 services/audio_policy/server/service/service_main/src/audio_injector_policy.cpp diff --git a/frameworks/native/audioadapter/include/audio_service_adapter.h b/frameworks/native/audioadapter/include/audio_service_adapter.h index 35b6189dd3..f6fe2bfa76 100644 --- a/frameworks/native/audioadapter/include/audio_service_adapter.h +++ b/frameworks/native/audioadapter/include/audio_service_adapter.h @@ -243,6 +243,9 @@ public: */ virtual int32_t SetSystemVolumeToEffect(AudioStreamType streamType, float volume) NOT_SUPPORT_RET virtual ~AudioServiceAdapter(); + + virtual int32_t AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) = 0; + virtual int32_t RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) = 0; }; } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h b/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h index 8fed4960e8..6be197b77d 100644 --- a/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h +++ b/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h @@ -60,6 +60,8 @@ public: int32_t UpdateCollaborativeState(bool isCollaborationEnabled) override; int32_t SetAbsVolumeStateToEffect(const bool absVolumeState) override; int32_t SetSystemVolumeToEffect(AudioStreamType streamType, float volume) override; + int32_t AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) override; + int32_t RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) override; // callback Member functions virtual void OnOpenAudioPortCb(int32_t portId) override; virtual void OnReloadAudioPortCb(int32_t portId) override; diff --git a/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h b/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h index 58c7ec7fc7..3ffb83800e 100644 --- a/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h +++ b/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h @@ -56,6 +56,8 @@ public: DeviceType deviceType = DEVICE_TYPE_NONE) override { return 0; } int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override { return 0; } + int32_t AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) override; + int32_t RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) override; // Static Member functions static void PaGetSinksCb(pa_context *c, const pa_sink_info *i, int eol, void *userdata); diff --git a/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp b/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp index 695f6dc90d..ecbe5b716e 100644 --- a/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp +++ b/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp @@ -569,6 +569,20 @@ int32_t ProAudioServiceAdapterImpl::SetSystemVolumeToEffect(AudioStreamType stre IHpaeManager::GetHpaeManager().SetEffectSystemVolume(streamType, volume); return SUCCESS; } + +int32_t ProAudioServiceAdapterImpl::AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + lock_guard lock(lock_); + IHpaeManager::GetHpaeManager().AddCaptureInjector(sinkPortIndex, sourcePortIndex, sourceType); + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + lock_guard lock(lock_); + IHpaeManager::GetHpaeManager().RemoveCaptureInjector(sinkPortIndex, sourcePortIndex, sourceType); + return SUCCESS; +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp b/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp index a192de6de9..59b23d66e1 100644 --- a/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp +++ b/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp @@ -957,6 +957,16 @@ void PulseAudioServiceAdapterImpl::PaSubscribeCb(pa_context *c, pa_subscription_ break; } } + +int32_t PulseAudioServiceAdapterImpl::AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + return SUCCESS; +} + +int32_t PulseAudioServiceAdapterImpl::RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + return SUCCESS; +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index 2fab083fa8..49e5a949f5 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -2304,6 +2304,7 @@ bool AudioRendererPrivate::GenerateNewStream(IAudioStream::StreamClass targetCla // Otherwise GetBufferDesc will return the buffer pointer of oldStream (causing Use-After-Free). UpdateRendererAudioStream(newAudioStream); newAudioStream->NotifyRouteUpdate(flag, networkId); + // newAudioStream->SetTarget(switchInfo.target); // Start new stream if old stream was in running state. // When restoring for audio server died, no need for restart. diff --git a/frameworks/native/audiostream/include/i_audio_stream.h b/frameworks/native/audiostream/include/i_audio_stream.h index 0f7ea11366..13ad1c72bc 100644 --- a/frameworks/native/audiostream/include/i_audio_stream.h +++ b/frameworks/native/audiostream/include/i_audio_stream.h @@ -112,6 +112,7 @@ public: std::vector> lastFramePosAndTimePairWithSpeed = { Timestamp::Timestampbase::BASESIZE, {0, 0} }; + uint32_t target = 0; }; virtual ~IAudioStream() = default; diff --git a/services/audio_policy/common/include/audio_service_enum.h b/services/audio_policy/common/include/audio_service_enum.h index a8d3f6222b..725fc18f2c 100644 --- a/services/audio_policy/common/include/audio_service_enum.h +++ b/services/audio_policy/common/include/audio_service_enum.h @@ -29,6 +29,11 @@ enum SessionOperationMsg : uint32_t { SESSION_OP_MSG_DEFAULT = 0, SESSION_OP_MSG_REMOVE_PIPE = 1, }; + +enum RendererTarget { + PLAYBACK_DEFAULT = 0, + INJECT_TO_VOICE_COMMUNICATION_CAPTURE = 1, +}; } // namespace AudioStandard } // namespace OHOS #endif // AUDIO_SERVICE_ENUM_H diff --git a/services/audio_policy/server/domain/pipe/include/audio_pipe_manager.h b/services/audio_policy/server/domain/pipe/include/audio_pipe_manager.h index 69969bc7eb..0557ce7456 100644 --- a/services/audio_policy/server/domain/pipe/include/audio_pipe_manager.h +++ b/services/audio_policy/server/domain/pipe/include/audio_pipe_manager.h @@ -88,6 +88,11 @@ public: uint32_t sessionId); bool IsStreamUsageActive(const StreamUsage &usage); + int32_t IsVoIPCall(); + bool IsPipeAlive(std::shared_ptr pipe); + std::shared_ptr GetPipeBySessionId(uint32_t sessionId); + uint32_t GetPaIndexByName(std::string portName); + private: bool IsSpecialPipe(uint32_t routeFlag); bool IsNormalRecordPipe(std::shared_ptr pipeInfo); diff --git a/services/audio_policy/server/domain/pipe/src/audio_pipe_manager.cpp b/services/audio_policy/server/domain/pipe/src/audio_pipe_manager.cpp index 405609cf4f..d24aff3ae5 100644 --- a/services/audio_policy/server/domain/pipe/src/audio_pipe_manager.cpp +++ b/services/audio_policy/server/domain/pipe/src/audio_pipe_manager.cpp @@ -597,5 +597,64 @@ bool AudioPipeManager::IsStreamUsageActive(const StreamUsage &usage) } return false; } + +int32_t AudioPipeManager::IsVoIPCall() +{ + std::shared_lock pLock(pipeListLock_); + for (auto it = curPipeList_.rbegin(); it != curPipeList_.rend(); ++it) { + if ((*it)->routeFlag_ & AUDIO_INPUT_FLAG_VOIP) { + AudioInjectorPolicy &audioInjectorPolicy = AudioInjectorPolicy::GetInstance(); + audioInjectorPolicy.SetCapturePortIdx((*it)->paIndex_); + if ((*it)->routeFlag_ & AUDIO_INPUT_FLAG_NORMAL) { + return NORMAL_VOIP; + } else if ((*it)->routeFlag_ & AUDIO_INPUT_FLAG_FAST) { + return FAST_VOIP; + } + } + } + return NO_VOIP; +} + +std::shared_ptr AudioPipeManager::GetPipeBySessionId(uint32_t sessionId) +{ + std::unique_lock pLock(pipeListLock_); + for (const auto &pipe : curPipeList_) { + if (pipe == nullptr) { + continue; + } + for (const auto &stream : pipe->streamDescriptors_) { + if (stream == nullptr) { + continue; + } + if (stream->sessionId_ == sessionId) { + AUDIO_INFO_LOG("find pipe: %{public}s by sessionId: %{public}u", pipe->name_.c_str(), sessionId); + return pipe; + } + } + } + return nullptr; +} + +bool AudioPipeManager::IsPipeAlive(std::shared_ptr pipe) +{ + std::unique_lock pLock(pipeListLock_); + for (auto iter = curPipeList_.begin(); iter != curPipeList_.end(); iter++) { + if (IsSamePipe(pipe, *iter)) { + return true; + } + } + return false; +} + +uint32_t AudioPipeManager::GetPaIndexByName(std::string portName) +{ + std::unique_lock pLock(pipeListLock_); + for (auto iter = curPipeList_.begin(); iter != curPipeList_.end(); iter++) { + if ((*iter)->name_ == portName) { + return (*iter)->paIndex_; + } + } + return HDI_INVALID_ID; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h b/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h index fdcea314e5..126f913f3e 100644 --- a/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h +++ b/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h @@ -306,6 +306,11 @@ public: void SaveSystemVolumeForEffect(DeviceType deviceType, AudioStreamType streamType, int32_t volumeLevel); int32_t GetSystemVolumeForEffect(DeviceType deviceType, AudioStreamType streamType); int32_t SetSystemVolumeToEffect(AudioStreamType streamType, float volume); + + int32_t AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType); + int32_t RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType); + int32_t AddCaptureInjector(); + int32_t RemoveCaptureInjector(); private: friend class PolicyCallbackImpl; diff --git a/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h b/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h index 8be01d59d3..248627bfff 100644 --- a/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h +++ b/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h @@ -257,6 +257,11 @@ public: virtual float CalculateVolumeDbNonlinear(AudioStreamType streamType, DeviceType deviceType, int32_t volumeLevel) = 0; + + virtual int32_t AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) = 0; + virtual int32_t RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) = 0; + virtual int32_t AddCaptureInjector() = 0; + virtual int32_t RemoveCaptureInjector() = 0; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp b/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp index f47ba066b5..6027bce4ad 100644 --- a/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp +++ b/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp @@ -3405,6 +3405,35 @@ int32_t AudioAdapterManager::SetSystemVolumeToEffect(AudioStreamType streamType, CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_, ERROR, "audioServiceAdapter is null"); return audioServiceAdapter_->SetSystemVolumeToEffect(streamType, volume); } + +int32_t AudioAdapterManager::AddCaptureInjector() +{ + AudioInjectorPolicy &audioInjectorPolicy = AudioInjectorPolicy::GetInstance(); + AudioModuleInfo &info = audioInjectorPolicy.GetAudioModuleInfo(); + uint32_t rendererPortIdx = audioInjectorPolicy.GetRendererPortIdx(); + CHECK_AND_RETURN_RET_LOG(audioServerProxy_ != nullptr, ERROR, "audioServerProxy_ null"); + return audioServerProxy_->AddCaptureInjector(rendererPortIdx, info.rate, info.format, info.channels); +} + +int32_t AudioAdapterManager::RemoveCaptureInjector() +{ + AudioInjectorPolicy &audioInjectorPolicy = AudioInjectorPolicy::GetInstance(); + uint32_t rendererPortIdx = audioInjectorPolicy.GetRendererPortIdx(); + CHECK_AND_RETURN_RET_LOG(audioServerProxy_ != nullptr, ERROR, "audioServerProxy_ null"); + return audioServerProxy_->RemoveCaptureInjector(rendererPortIdx); +} + +int32_t AudioAdapterManager::AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); + return audioServiceAdapter_->AddCaptureInjector(sinkPortIndex, sourcePortIndex, sourceType); +} + +int32_t AudioAdapterManager::RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); + return audioServiceAdapter_->RemoveCaptureInjector(sinkPortIndex, sourcePortIndex, sourceType); +} // LCOV_EXCL_STOP } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/service/service_main/include/audio_core_service.h b/services/audio_policy/server/service/service_main/include/audio_core_service.h index 5aee838b50..d09cf77e74 100644 --- a/services/audio_policy/server/service/service_main/include/audio_core_service.h +++ b/services/audio_policy/server/service/service_main/include/audio_core_service.h @@ -48,6 +48,7 @@ #include "audio_event_utils.h" #include "audio_stream_id_allocator.h" #include "i_hpae_soft_link.h" +#include "audio_injector_policy.h" namespace OHOS { namespace AudioStandard { enum OffloadType { @@ -177,6 +178,8 @@ public: std::vector> GetVolumeGroupInfos(); int32_t SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config) override; int32_t ReleaseOffloadPipe(AudioIOHandle id, uint32_t paIndex, OffloadType type); + int32_t SetRendererTarget(RendererTarget target, RendererTarget lastTarget, uint32_t sessionId) override; + int32_t StartInjection(uint32_t sessionId) override; private: std::shared_ptr coreService_; std::shared_mutex eventMutex_; @@ -318,6 +321,8 @@ private: void SetFirstScreenOn(); void FetchOutputDupDevice(std::string caller, uint32_t sessionId, std::shared_ptr &streamDesc); + int32_t SetRendererTarget(RendererTarget target, RendererTarget lastTarget, uint32_t sessionId); + int32_t StartInjection(uint32_t sessionId); private: static std::string GetEncryptAddr(const std::string &addr); int32_t FetchRendererPipesAndExecute(std::vector> &streamDescs, @@ -609,6 +614,8 @@ private: .type = CAST_TYPE_NULL }; bool isFirstScreenOn_ = false; + + AudioInjectorPolicy &audioInjectorPolicy_; }; } } diff --git a/services/audio_policy/server/service/service_main/include/audio_injector_policy.h b/services/audio_policy/server/service/service_main/include/audio_injector_policy.h new file mode 100644 index 0000000000..17f5ac85c0 --- /dev/null +++ b/services/audio_policy/server/service/service_main/include/audio_injector_policy.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef AUDIO_INJECTOR_POLICY_H +#define AUDIO_INJECTOR_POLICY_H + +#include +#include "audio_module_info.h" +#include "audio_pipe_info.h" +#include "audio_iohandle_map.h" +#include "iaudio_policy_interface.h" +#include "audio_pipe_manager.h" + +namespace OHOS { +namespace AudioStandard { +enum VoIpType { + NO_VOIP = 0, + NORMAL_VOIP = 1, + FAST_VOIP = 2, +}; + +class AudioInjectorPolicy { +public: + static AudioInjectorPolicy& GetInstance() + { + static AudioInjectorPolicy instance; + return instance; + } + int32_t Init(); + int32_t DeInit(); + int32_t UpdateAudioInfo(AudioModuleInfo &info); + int32_t MoveStream(uint32_t renderId, bool flag); + int32_t GetRendererStreamCount(); + void SetCapturePortIdx(uint32_t idx); + uint32_t GetCapturePortIdx(); + void SetRendererPortIdx(uint32_t idx); + uint32_t GetRendererPortIdx(); + AudioModuleInfo& GetAudioModuleInfo(); + int32_t AddCaptureInjector(); + int32_t RemoveCaptureInjector(); + +private: + AudioInjectorPolicy(); + AudioInjectorPolicy(const AudioInjectorPolicy&) = delete; + AudioInjectorPolicy& operator=(const AudioInjectorPolicy&) = delete; +private: + AudioModuleInfo moduleInfo_; + uint32_t capturePortIdx_; + uint32_t renderPortIdx_; + bool isConnected_; + std::unordered_map> rendererStreamMap_ = {}; + AudioIOHandleMap &audioIOHandleMap_; + IAudioPolicyInterface &audioPolicyManager_; + std::shared_ptr pipeManager_ = nullptr; + std::shared_mutex injectLock_; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // AUDIO_INJECTOR_POLICY_H \ No newline at end of file diff --git a/services/audio_policy/server/service/service_main/src/audio_core_service.cpp b/services/audio_policy/server/service/service_main/src/audio_core_service.cpp index 9515f906c2..ae5602d5ae 100644 --- a/services/audio_policy/server/service/service_main/src/audio_core_service.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_core_service.cpp @@ -83,7 +83,8 @@ AudioCoreService::AudioCoreService() audioUsrSelectManager_(AudioUsrSelectManager::GetAudioUsrSelectManager()), audioPipeSelector_(AudioPipeSelector::GetPipeSelector()), audioSessionService_(AudioSessionService::GetAudioSessionService()), - pipeManager_(AudioPipeManager::GetPipeManager()) + pipeManager_(AudioPipeManager::GetPipeManager()), + audioInjectorPolicy_(AudioInjectorPolicy::GetInstance()) { AUDIO_INFO_LOG("Ctor"); } @@ -1519,5 +1520,29 @@ void AudioCoreService::SetFirstScreenOn() { isFirstScreenOn_ = true; } + +int32_t AudioCoreService::SetRendererTarget(RendererTarget target, RendererTarget lastTarget, uint32_t sessionId) +{ + int32_t ret = ERROR; + if (lastTarget == PLAYBACK_DEFAULT && target == INJECT_TO_VOICE_COMMUNICATION_CAPTURE) { + ret = PlayBackToInjection(sessionId); + } else if(lastTarget == INJECT_TO_VOICE_COMMUNICATION_CAPTURE && target == PLAYBACK_DEFAULT) { + ret = InjectionToPlayBack(sessionId); + } + return ret; +} + +int32_t AudioCoreService::StartInjection(uint32_t streamId) +{ + if (pipeManager_->IsVoIPCall() == NO_VOIP) { + return ERROR; + } + int32_t ret = ERROR; + ret = audioInjectorPolicy_.AddCaptureInjector(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "AddCaptureInjector failed"); + ret = audioInjectorPolicy_.MoveStream(streamId, true); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "Move Stream in failed"); + return SUCCESS; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp b/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp index f049bb588f..102b20648c 100644 --- a/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp @@ -599,5 +599,17 @@ int32_t AudioCoreService::EventEntry::ReleaseOffloadPipe(AudioIOHandle id, uint3 coreService_->isOffloadInRelease_[type].store(false); return SUCCESS; } + +int32_t AudioCoreService::EventEntry::SetRendererTarget(RendererTarget target, RendererTarget lastTarget, uint32_t sessionId) +{ + std::lock_guard lock(eventMutex_); + return coreService_->SetRendererTarget(target, lastTarget, sessionId); +} + +int32_t AudioCoreService::EventEntry::StartInjection(uint32_t sessionId) +{ + std::lock_guard lock(eventMutex_); + return coreService_->StartInjection(sessionId); +} } } diff --git a/services/audio_policy/server/service/service_main/src/audio_core_service_private.cpp b/services/audio_policy/server/service/service_main/src/audio_core_service_private.cpp index 0c8963750e..5e2b8ee5a0 100644 --- a/services/audio_policy/server/service/service_main/src/audio_core_service_private.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_core_service_private.cpp @@ -3144,5 +3144,29 @@ int32_t AudioCoreService::SetSleVoiceStatusFlag(AudioScene audioScene) } return SUCCESS; } + +int32_t AudioCoreService::PlayBackToInjection(uint32_t sessionId) +{ + if (!PermissionUtil::VerifySystemPermission()) { + return ERR_PERMISSION_DENIED; + } + if (pipeManager_->IsVoIPCall() == NO_VOIP) { + return ERROR; + } + int32_t ret = audioInjectorPolicy_.Init(); + //策略 + return ret; +} + +int32_t AudioCoreService::InjectionToPlayBack(uint32_t sessionId) +{ + int32_t ret = ERROR; + ret = audioInjectorPolicy_.MoveStream(sessionId, false); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "Move Stream out failed"); + ret = audioInjectorPolicy_.RemoveCaptureInjector(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "RemoveCaptureInjector failed"); + ret = audioInjectorPolicy_.DeInit(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "DeInit failed"); + return SUCCESS; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/service/service_main/src/audio_injector_policy.cpp b/services/audio_policy/server/service/service_main/src/audio_injector_policy.cpp new file mode 100644 index 0000000000..ac2a1d6d38 --- /dev/null +++ b/services/audio_policy/server/service/service_main/src/audio_injector_policy.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "audio_injector_policy.h" +#include "audio_policy_manager_factory.h" + +namespace OHOS { +namespace AudioStandard { +AudioInjectorPolicy::AudioInjectorPolicy() + :audioIOHandleMap_(AudioIOHandleMap::GetInstance()), + audioPolicyManager_(AudioPolicyManagerFactory::GetAudioPolicyManager()) +{ + pipeManager_ = AudioPipeManager::GetPipeManager(); + isConnected_ = false; +} + +int32_t AudioInjectorPolicy::Init() +{ + std::lock_guard lock(injectLock_); + if (rendererStreamMap_.size() == 0) { + AUDIO_INFO_LOG("Start"); + AudioModuleInfo moduleInfo = {}; + moduleInfo.lib = "libmodule-hdi-sink.z.so"; + std::string name = ""; + moduleInfo.name = name; + + moduleInfo.format = "s16le"; + moduleInfo.channels = "2"; // 2 channel + moduleInfo.rate = "48000"; + moduleInfo.bufferSize = "3840"; // 20ms + + int32_t ret = audioIOHandleMap_.OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "open port failed"); + this->moduleInfo_ = moduleInfo; + renderPortIdx_ = pipeManager_->GetPaIndexByName(moduleInfo.name); + CHECK_AND_RETURN_RET_LOG(renderPortIdx_ != HDI_INVALID_ID, ERROR, "renderPortIdx error!"); + } + return SUCCESS; +} + +int32_t AudioInjectorPolicy::DeInit() +{ + std::lock_guard lock(injectLock_); + if (rendererStreamMap_.size() == 0) { + int32_t ret = audioIOHandleMap_.ClosePortAndEraseIOHandle(moduleInfo_.name); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "close port failed"); + renderPortIdx_ = HDI_INVALID_ID; + } + return SUCCESS; +} + +int32_t AudioInjectorPolicy::UpdateAudioInfo(AudioModuleInfo &info) +{ + return SUCCESS; +} + +int32_t AudioInjectorPolicy::MoveStream(uint32_t renderId, bool flag) +{ + std::lock_guard lock(injectLock_); + if (flag) { + std::shared_ptr info = pipeManager_->GetPipeBySessionId(renderId); + CHECK_AND_RETURN_RET_LOG(info != nullptr, ERROR, "get pipeinfo failed"); + int32_t ret = audioPolicyManager_.MoveSinkInputByIndexOrName(renderId, 1, moduleInfo_.name); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "move stream in failed"); + rendererStreamMap_[renderId] = info; + } else { + std::string portName = ""; + std::shared_ptr oldInfo = rendererStreamMap_[renderId]; + if (pipeManager_->IsPipeAlive(oldInfo)) { + portName = oldInfo->name_; + } else { + AudioModuleInfo moduleInfo = oldInfo->moduleInfo_; + portName = moduleInfo.name; + int32_t ret = audioIOHandleMap_.OpenPortAndInsertIOHandle(portName, moduleInfo); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "open original port failed"); + } + int32_t ret = audioPolicyManager_.MoveSinkInputByIndexOrName(renderId, 1, portName); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "move stream out failed"); + rendererStreamMap_[renderId] = nullptr; + rendererStreamMap_.erase(renderId); + } + return SUCCESS; +} + +// get the number of rendererStream moved in Injector +int32_t AudioInjectorPolicy::GetRendererStreamCount() +{ + return rendererStreamMap_.size(); +} + +void AudioInjectorPolicy::SetCapturePortIdx(uint32_t idx) +{ + std::lock_guard lock(injectLock_); + capturePortIdx_ = idx; +} + +uint32_t AudioInjectorPolicy::GetCapturePortIdx() +{ + return capturePortIdx_; +} + +void AudioInjectorPolicy::SetRendererPortIdx(uint32_t idx) +{ + std::lock_guard lock(injectLock_); + renderPortIdx_ = idx; +} + +uint32_t AudioInjectorPolicy::GetRendererPortIdx() +{ + return renderPortIdx_; +} + +AudioModuleInfo& AudioInjectorPolicy::GetAudioModuleInfo() +{ + return moduleInfo_; +} + +int32_t AudioInjectorPolicy::AddCaptureInjector() +{ + std::lock_guard lock(injectLock_); + int32_t ret = ERROR; + if (!isConnected_) { + if (pipeManager_->IsVoIPCall() == NORMAL_VOIP) { + ret = audioPolicyManager_.AddCaptureInjector(renderPortIdx_, capturePortIdx_, SOURCE_TYPE_VOICE_COMMUNICATION); + } else if (pipeManager_->IsVoIPCall() == FAST_VOIP) { + ret = audioPolicyManager_.AddCaptureInjector(); + } + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "AddCaptureInjector failed"); + } + isConnected_ = true; + return SUCCESS; +} + +int32_t AudioInjectorPolicy::RemoveCaptureInjector() +{ + std::lock_guard lock(injectLock_); + int32_t ret = ERROR; + if (isConnected_) { + if (pipeManager_->IsVoIPCall() == NORMAL_VOIP) { + ret = audioPolicyManager_.RemoveCaptureInjector(renderPortIdx_, capturePortIdx_, SOURCE_TYPE_VOICE_COMMUNICATION); + } else if (pipeManager_->IsVoIPCall() == FAST_VOIP) { + ret = audioPolicyManager_.RemoveCaptureInjector(); + } + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "RemoveCaptureInjector failed"); + } + isConnected_ = false; + return SUCCESS; +} +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_service/client/include/core_service_provider_stub.h b/services/audio_service/client/include/core_service_provider_stub.h index cd8ef6a536..9dfb67c0ad 100644 --- a/services/audio_service/client/include/core_service_provider_stub.h +++ b/services/audio_service/client/include/core_service_provider_stub.h @@ -37,6 +37,8 @@ public: int32_t GetPaIndexByPortName(const std::string &portName, uint32_t &ret) override; int32_t SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config, int32_t &ret) override; + int32_t SetRendererTarget(uint32_t target, uint32_t lastTarget, uint32_t sessionId, int32_t &ret) override; + int32_t StartInjection(uint32_t streamId, int32_t &ret) override; private: ICoreServiceProvider *coreServiceWorker_; }; diff --git a/services/audio_service/client/include/renderer_in_client_private.h b/services/audio_service/client/include/renderer_in_client_private.h index e847917ac8..765bbac205 100644 --- a/services/audio_service/client/include/renderer_in_client_private.h +++ b/services/audio_service/client/include/renderer_in_client_private.h @@ -502,6 +502,8 @@ private: std::optional lastCallStartByUserTid_ = std::nullopt; std::function uidGetter_ = [] { return getuid(); }; + + uint32_t target_ = 0; }; class SpatializationStateChangeCallbackImpl : public AudioSpatializationStateChangeCallback { diff --git a/services/audio_service/client/src/core_service_provider_stub.cpp b/services/audio_service/client/src/core_service_provider_stub.cpp index d112abf64f..7dfbecbed2 100644 --- a/services/audio_service/client/src/core_service_provider_stub.cpp +++ b/services/audio_service/client/src/core_service_provider_stub.cpp @@ -89,5 +89,19 @@ int32_t CoreServiceProviderWrapper::GetPaIndexByPortName(const std::string &port ret = coreServiceWorker_->GetPaIndexByPortName(portName); return SUCCESS; } + +int32_t CoreServiceProviderWrapper::SetRendererTarget(uint32_t target, uint32_t lastTarget, uint32_t sessionId, int32_t &ret) +{ + CHECK_AND_RETURN_RET_LOG(coreServiceWorker_ != nullptr, AUDIO_INIT_FAIL, "coreServiceWorker_ is null"); + ret = coreServiceWorker_->SetRendererTarget(static_cast(target), static_cast(lastTarget), sessionId); + return SUCCESS; +} + +int32_t CoreServiceProviderWrapper::StartInjection(uint32_t streamId, int32_t &ret) +{ + CHECK_AND_RETURN_RET_LOG(coreServiceWorker_ != nullptr, AUDIO_INIT_FAIL, "coreServiceWorker_ is null"); + ret = coreServiceWorker_->StartInjection(streamId); + return SUCCESS; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/client/src/renderer_in_client_public.cpp b/services/audio_service/client/src/renderer_in_client_public.cpp index a25ba3773f..d423471232 100644 --- a/services/audio_service/client/src/renderer_in_client_public.cpp +++ b/services/audio_service/client/src/renderer_in_client_public.cpp @@ -1468,6 +1468,7 @@ void RendererInClientInner::GetSwitchInfo(IAudioStream::SwitchInfo& info) info.defaultOutputDevice = defaultOutputDevice_; info.lastFramePosAndTimePair = lastFramePosAndTimePair_; info.lastFramePosAndTimePairWithSpeed = lastFramePosAndTimePairWithSpeed_; + info.target = target_; GetStreamSwitchInfo(info); { diff --git a/services/audio_service/common/include/i_core_service_provider.h b/services/audio_service/common/include/i_core_service_provider.h index 73a9ff372b..6b1fb3c438 100644 --- a/services/audio_service/common/include/i_core_service_provider.h +++ b/services/audio_service/common/include/i_core_service_provider.h @@ -39,6 +39,8 @@ public: virtual int32_t SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config) = 0; virtual ~ICoreServiceProvider() = default; + virtual int32_t SetRendererTarget(RendererTarget target, RendererTarget lastTarget, uint32_t sessionId) = 0; + virtual int32_t StartInjection(uint32_t sessionId) = 0; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/idl/ICoreServiceProviderIpc.idl b/services/audio_service/idl/ICoreServiceProviderIpc.idl index bf7d9f9b94..ec1215f420 100644 --- a/services/audio_service/idl/ICoreServiceProviderIpc.idl +++ b/services/audio_service/idl/ICoreServiceProviderIpc.idl @@ -47,4 +47,12 @@ interface ICoreServiceProviderIpc { void GetPaIndexByPortName( [in] String portName, [out] unsigned int ret); + void SetRendererTarget( + [in] unsigned int target, + [in] unsigned int lastTarget, + [in] unsigned int sessionId, + [out] int ret); + void StartInjection( + [in] unsigned int target, + [out] int ret); } diff --git a/services/audio_service/idl/IStandardAudioService.idl b/services/audio_service/idl/IStandardAudioService.idl index 83b9f171d2..82678d0f93 100644 --- a/services/audio_service/idl/IStandardAudioService.idl +++ b/services/audio_service/idl/IStandardAudioService.idl @@ -140,6 +140,8 @@ interface IStandardAudioService { void RestoreAudioWorkgroupPrio([in] int pid, [in] Map threads); void SetRenderWhitelist([in] List list); void GetVolumeBySessionId([in] unsigned int sessionId, [out] float volume); + void AddCaptureInjector([in] unsigned int sinkPortidx, [out] String rate, [out] String format, [out] String channels); + void RemoveCaptureInjector([in] unsigned int sinkPortidx); // WARNING: above functions correspond with AudioServerInterfaceCode // undefined in AudioServerInterfaceCode diff --git a/services/audio_service/server/include/audio_injector_service.h b/services/audio_service/server/include/audio_injector_service.h index 0b5dd8c84f..cb8611187b 100644 --- a/services/audio_service/server/include/audio_injector_service.h +++ b/services/audio_service/server/include/audio_injector_service.h @@ -32,11 +32,12 @@ public: void SetSinkPortIdx(uint32_t sinkPortIdx); int32_t GetSinkPortIdx(); private: - AudioInjectorService(); + AudioInjectorService() = default; + ~AudioInjectorService() = default; AudioInjectorService(const AudioInjectorService&) = delete; AudioInjectorService& operator=(const AudioInjectorService&) = delete; private: - AudioModuleInfo moudleInfo_; + AudioModuleInfo moduleInfo_; uint32_t sinkPortIndex_; }; } // namespace AudioStandard diff --git a/services/audio_service/server/include/audio_server.h b/services/audio_service/server/include/audio_server.h index 93462af2ea..ae608d1290 100644 --- a/services/audio_service/server/include/audio_server.h +++ b/services/audio_service/server/include/audio_server.h @@ -270,6 +270,9 @@ public: int32_t SendInterruptEventToAudioServer(uint32_t sessionId, const InterruptEventInternal &interruptEvent) override; int32_t GetVolumeBySessionId(uint32_t sessionId, float &volume) override; + + int32_t AddCaptureInjector(uint32_t sinkPortidx, std::string &rate, std::string &format, std::string &channels) override; + int32_t RemoveCaptureInjector(uint32_t sinkPortidx) override; protected: void OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; diff --git a/services/audio_service/server/include/core_service_handler.h b/services/audio_service/server/include/core_service_handler.h index 68ed4c89b2..fa44b86fe8 100644 --- a/services/audio_service/server/include/core_service_handler.h +++ b/services/audio_service/server/include/core_service_handler.h @@ -47,6 +47,9 @@ public: AudioStreamInfo &streamInfo, bool isReloadProcess); uint32_t GenerateSessionId(); int32_t SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config); + + int32_t SetRendererTarget(uint32_t target, uint32_t lastTarget, uint32_t sessionId); + int32_t StartInjection(uint32_t sessionId); private: CoreServiceHandler(); sptr iCoreServiceProvider_ = nullptr; diff --git a/services/audio_service/server/include/renderer_in_server.h b/services/audio_service/server/include/renderer_in_server.h index 5208dc1698..ff1bed1ec9 100644 --- a/services/audio_service/server/include/renderer_in_server.h +++ b/services/audio_service/server/include/renderer_in_server.h @@ -26,6 +26,7 @@ #include "audio_stream_monitor.h" #include "audio_stream_checker.h" #include "player_dfx_writer.h" +#include "audio_service_enum.h" namespace OHOS { namespace AudioStandard { @@ -151,6 +152,7 @@ public: int32_t InitSoftLink(int32_t innerCapId); int32_t DestroySoftLink(int32_t innerCapId); int32_t InitSoftLinkVolume(std::shared_ptr softLinkPtr); + int32_t SetTarget(RendererTarget target, int32_t &ret); public: const AudioProcessConfig processConfig_; private: @@ -287,6 +289,8 @@ private: std::unordered_map softLinkInfos_; FILE *dumpSoftLink = nullptr; + + RendererTarget lastTarget_; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/src/audio_injector_service.cpp b/services/audio_service/server/src/audio_injector_service.cpp index a106310563..957742d1de 100644 --- a/services/audio_service/server/src/audio_injector_service.cpp +++ b/services/audio_service/server/src/audio_injector_service.cpp @@ -22,13 +22,15 @@ AudioInjectorService::AudioInjectorService() int32_t AudioInjectorService::UpdateAudioInfo(AudioModuleInfo &info) { - return 0; + HPAE::IHpaeManager::GetHpaeManager().UpdateAudioPortInfo(sinkPortIndex_, info); + return SUCCESS; } int32_t AudioInjectorService::PeekAudioData(const uint32_t sinkPortIndex, uint8_t *buffer, const size_t bufferSize, AudioStreamInfo &streamInfo) { - return 0; + HPAE::IHpaeManager::GetHpaeManager().PeekAudioData(sinkPortIndex, buffer, bufferSize, streamInfo); + return SUCCESS; } void AudioInjectorService::SetSinkPortIdx(uint32_t sinkPortIdx) diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index fe72497d99..10d0376372 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -3168,6 +3168,18 @@ int32_t AudioServer::GetPrivacyTypeAudioServer(uint32_t sessionId, int32_t &priv privacyType = static_cast(type); return SUCCESS; } + +int32_t AudioServer::AddCaptureInjector(uint32_t sinkPortidx, std::string &rate, std::string &format, std::string &channels) +{ + //endpoint::AddCaptureInjector + return SUCCESS; +} + +int32_t AudioServer::RemoveCaptureInjector(uint32_t sinkPortidx) +{ + //endpoint::RemoveCaptureInjector + return SUCCESS; +} // LCOV_EXCL_STOP } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/src/core_service_handler.cpp b/services/audio_service/server/src/core_service_handler.cpp index 7534d09176..0ca3a81c45 100644 --- a/services/audio_service/server/src/core_service_handler.cpp +++ b/services/audio_service/server/src/core_service_handler.cpp @@ -114,5 +114,21 @@ uint32_t CoreServiceHandler::GetPaIndexByPortName(const std::string &portName) iCoreServiceProvider_->GetPaIndexByPortName(portName, ret); return ret; } + +int32_t CoreServiceHandler::SetRendererTarget(uint32_t target, uint32_t lastTarget, uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(iCoreServiceProvider_ != nullptr, ERROR, "iCoreServiceProvider_ is nullptr!"); + int32_t ret = ERROR; + iCoreServiceProvider_->SetRendererTarget(target, lastTarget, sessionId, ret); + return ret; +} + +int32_t CoreServiceHandler::StartInjection(uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(iCoreServiceProvider_ != nullptr, ERROR, "iCoreServiceProvider_ is nullptr!"); + int32_t ret = ERROR; + iCoreServiceProvider_->StartInjection(sessionId, ret); + return ret; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/src/renderer_in_server.cpp b/services/audio_service/server/src/renderer_in_server.cpp index e49341db39..be202d1f22 100644 --- a/services/audio_service/server/src/renderer_in_server.cpp +++ b/services/audio_service/server/src/renderer_in_server.cpp @@ -1003,6 +1003,10 @@ int32_t RendererInServer::StartInner() { AUDIO_INFO_LOG("sessionId: %{public}u", streamIndex_); int32_t ret = 0; + if (lastTarget_ == INJECT_TO_VOICE_COMMUNICATION_CAPTURE) { + ret = CoreServiceHandler::GetInstance().StartInjection(streamIndex_); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "StartInjection failed"); + } if (standByEnable_) { return StartInnerDuringStandby(); } else { @@ -2474,5 +2478,20 @@ bool RendererInServer::IsMovieStream() return processConfig_.streamType == STREAM_MOVIE && processConfig_.rendererInfo.originalFlag == AUDIO_FLAG_PCM_OFFLOAD; } + +int32_t RendererInServer::SetTarget(RendererTarget target, int32_t &ret) +{ + if (target == lastTarget_) { + ret = SUCCESS; + return ret; + } + if (status_ == I_STATUS_IDLE || status_ == I_STATUS_PAUSED || status_ == I_STATUS_STOPPED) { + ret = CoreServiceHandler::GetInstance().SetRendererTarget(target, lastTarget_, streamIndex_); + lastTarget_ = target; + return ret; + } + ret = ERR_ILLEGAL_STATE; + return ret; +} } // namespace AudioStandard } // namespace OHOS -- Gitee From b855d13f7ea3ebe0dd8a570f6b760876a08d823a Mon Sep 17 00:00:00 2001 From: wz2023 <752856023@qq.com> Date: Mon, 8 Sep 2025 19:35:35 +0800 Subject: [PATCH 2/2] AudioInjector Signed-off-by: wz2023 <752856023@qq.com> --- .../include/audio_service_adapter.h | 3 + .../include/pro_audio_service_adapter_impl.h | 2 + .../pulse_audio_service_adapter_impl.h | 2 + .../src/pro_audio_service_adapter_impl.cpp | 14 ++ .../src/pulse_audio_service_adapter_impl.cpp | 10 ++ .../audiorenderer/src/audio_renderer.cpp | 1 + .../audiostream/include/i_audio_stream.h | 1 + services/audio_policy/BUILD.gn | 1 + .../common/include/audio_service_enum.h | 5 + .../domain/pipe/include/audio_pipe_manager.h | 5 + .../domain/pipe/src/audio_pipe_manager.cpp | 61 +++++++ .../volume/include/audio_adapter_manager.h | 5 + .../volume/include/iaudio_policy_interface.h | 5 + .../volume/src/audio_adapter_manager.cpp | 29 +++ .../service_main/include/audio_core_service.h | 11 ++ .../include/audio_injector_policy.h | 70 ++++++++ .../service_main/src/audio_core_service.cpp | 28 ++- .../src/audio_core_service_entry.cpp | 12 ++ .../src/audio_core_service_private.cpp | 25 +++ .../src/audio_injector_policy.cpp | 167 ++++++++++++++++++ .../include/core_service_provider_stub.h | 2 + .../include/renderer_in_client_private.h | 2 + .../client/src/core_service_provider_stub.cpp | 14 ++ .../client/src/renderer_in_client_public.cpp | 1 + .../common/include/i_core_service_provider.h | 2 + .../idl/ICoreServiceProviderIpc.idl | 8 + .../idl/IStandardAudioService.idl | 2 + .../server/include/audio_injector_service.h | 3 +- .../server/include/audio_server.h | 3 + .../server/include/core_service_handler.h | 3 + .../server/include/renderer_in_server.h | 4 + .../server/src/audio_injector_service.cpp | 10 +- .../audio_service/server/src/audio_server.cpp | 12 ++ .../server/src/core_service_handler.cpp | 16 ++ .../server/src/renderer_in_server.cpp | 19 ++ 35 files changed, 553 insertions(+), 5 deletions(-) create mode 100644 services/audio_policy/server/service/service_main/include/audio_injector_policy.h create mode 100644 services/audio_policy/server/service/service_main/src/audio_injector_policy.cpp diff --git a/frameworks/native/audioadapter/include/audio_service_adapter.h b/frameworks/native/audioadapter/include/audio_service_adapter.h index 35b6189dd3..f6fe2bfa76 100644 --- a/frameworks/native/audioadapter/include/audio_service_adapter.h +++ b/frameworks/native/audioadapter/include/audio_service_adapter.h @@ -243,6 +243,9 @@ public: */ virtual int32_t SetSystemVolumeToEffect(AudioStreamType streamType, float volume) NOT_SUPPORT_RET virtual ~AudioServiceAdapter(); + + virtual int32_t AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) = 0; + virtual int32_t RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) = 0; }; } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h b/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h index 8fed4960e8..6be197b77d 100644 --- a/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h +++ b/frameworks/native/audioadapter/include/pro_audio_service_adapter_impl.h @@ -60,6 +60,8 @@ public: int32_t UpdateCollaborativeState(bool isCollaborationEnabled) override; int32_t SetAbsVolumeStateToEffect(const bool absVolumeState) override; int32_t SetSystemVolumeToEffect(AudioStreamType streamType, float volume) override; + int32_t AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) override; + int32_t RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) override; // callback Member functions virtual void OnOpenAudioPortCb(int32_t portId) override; virtual void OnReloadAudioPortCb(int32_t portId) override; diff --git a/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h b/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h index 58c7ec7fc7..3ffb83800e 100644 --- a/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h +++ b/frameworks/native/audioadapter/include/pulse_audio_service_adapter_impl.h @@ -56,6 +56,8 @@ public: DeviceType deviceType = DEVICE_TYPE_NONE) override { return 0; } int32_t GetAudioEnhanceProperty(AudioEnhancePropertyArray &propertyArray, DeviceType deviceType = DEVICE_TYPE_NONE) override { return 0; } + int32_t AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) override; + int32_t RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) override; // Static Member functions static void PaGetSinksCb(pa_context *c, const pa_sink_info *i, int eol, void *userdata); diff --git a/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp b/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp index 695f6dc90d..ecbe5b716e 100644 --- a/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp +++ b/frameworks/native/audioadapter/src/pro_audio_service_adapter_impl.cpp @@ -569,6 +569,20 @@ int32_t ProAudioServiceAdapterImpl::SetSystemVolumeToEffect(AudioStreamType stre IHpaeManager::GetHpaeManager().SetEffectSystemVolume(streamType, volume); return SUCCESS; } + +int32_t ProAudioServiceAdapterImpl::AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + lock_guard lock(lock_); + IHpaeManager::GetHpaeManager().AddCaptureInjector(sinkPortIndex, sourcePortIndex, sourceType); + return SUCCESS; +} + +int32_t ProAudioServiceAdapterImpl::RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + lock_guard lock(lock_); + IHpaeManager::GetHpaeManager().RemoveCaptureInjector(sinkPortIndex, sourcePortIndex, sourceType); + return SUCCESS; +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp b/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp index a192de6de9..59b23d66e1 100644 --- a/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp +++ b/frameworks/native/audioadapter/src/pulse_audio_service_adapter_impl.cpp @@ -957,6 +957,16 @@ void PulseAudioServiceAdapterImpl::PaSubscribeCb(pa_context *c, pa_subscription_ break; } } + +int32_t PulseAudioServiceAdapterImpl::AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + return SUCCESS; +} + +int32_t PulseAudioServiceAdapterImpl::RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + return SUCCESS; +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index 2fab083fa8..49e5a949f5 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -2304,6 +2304,7 @@ bool AudioRendererPrivate::GenerateNewStream(IAudioStream::StreamClass targetCla // Otherwise GetBufferDesc will return the buffer pointer of oldStream (causing Use-After-Free). UpdateRendererAudioStream(newAudioStream); newAudioStream->NotifyRouteUpdate(flag, networkId); + // newAudioStream->SetTarget(switchInfo.target); // Start new stream if old stream was in running state. // When restoring for audio server died, no need for restart. diff --git a/frameworks/native/audiostream/include/i_audio_stream.h b/frameworks/native/audiostream/include/i_audio_stream.h index 0f7ea11366..13ad1c72bc 100644 --- a/frameworks/native/audiostream/include/i_audio_stream.h +++ b/frameworks/native/audiostream/include/i_audio_stream.h @@ -112,6 +112,7 @@ public: std::vector> lastFramePosAndTimePairWithSpeed = { Timestamp::Timestampbase::BASESIZE, {0, 0} }; + uint32_t target = 0; }; virtual ~IAudioStream() = default; diff --git a/services/audio_policy/BUILD.gn b/services/audio_policy/BUILD.gn index bc4bd63a64..f4c2c6b1ee 100644 --- a/services/audio_policy/BUILD.gn +++ b/services/audio_policy/BUILD.gn @@ -282,6 +282,7 @@ audio_ohos_library("audio_policy_service") { "server/service/service_main/src/audio_core_service_utils.cpp", "server/domain/pipe/src/audio_pipe_manager.cpp", "server/domain/pipe/src/audio_pipe_selector.cpp", + "server/service/service_main/src/audio_injector_policy.cpp", ] defines = [] diff --git a/services/audio_policy/common/include/audio_service_enum.h b/services/audio_policy/common/include/audio_service_enum.h index a8d3f6222b..725fc18f2c 100644 --- a/services/audio_policy/common/include/audio_service_enum.h +++ b/services/audio_policy/common/include/audio_service_enum.h @@ -29,6 +29,11 @@ enum SessionOperationMsg : uint32_t { SESSION_OP_MSG_DEFAULT = 0, SESSION_OP_MSG_REMOVE_PIPE = 1, }; + +enum RendererTarget { + PLAYBACK_DEFAULT = 0, + INJECT_TO_VOICE_COMMUNICATION_CAPTURE = 1, +}; } // namespace AudioStandard } // namespace OHOS #endif // AUDIO_SERVICE_ENUM_H diff --git a/services/audio_policy/server/domain/pipe/include/audio_pipe_manager.h b/services/audio_policy/server/domain/pipe/include/audio_pipe_manager.h index 69969bc7eb..0557ce7456 100644 --- a/services/audio_policy/server/domain/pipe/include/audio_pipe_manager.h +++ b/services/audio_policy/server/domain/pipe/include/audio_pipe_manager.h @@ -88,6 +88,11 @@ public: uint32_t sessionId); bool IsStreamUsageActive(const StreamUsage &usage); + int32_t IsVoIPCall(); + bool IsPipeAlive(std::shared_ptr pipe); + std::shared_ptr GetPipeBySessionId(uint32_t sessionId); + uint32_t GetPaIndexByName(std::string portName); + private: bool IsSpecialPipe(uint32_t routeFlag); bool IsNormalRecordPipe(std::shared_ptr pipeInfo); diff --git a/services/audio_policy/server/domain/pipe/src/audio_pipe_manager.cpp b/services/audio_policy/server/domain/pipe/src/audio_pipe_manager.cpp index 405609cf4f..78ae188eb0 100644 --- a/services/audio_policy/server/domain/pipe/src/audio_pipe_manager.cpp +++ b/services/audio_policy/server/domain/pipe/src/audio_pipe_manager.cpp @@ -17,6 +17,7 @@ #endif #include "audio_pipe_manager.h" +#include "audio_injector_policy.h" namespace OHOS { namespace AudioStandard { @@ -597,5 +598,65 @@ bool AudioPipeManager::IsStreamUsageActive(const StreamUsage &usage) } return false; } + +int32_t AudioPipeManager::IsVoIPCall() +{ + std::shared_lock pLock(pipeListLock_); + for (auto it = curPipeList_.rbegin(); it != curPipeList_.rend(); ++it) { + if ((*it)->routeFlag_ & AUDIO_INPUT_FLAG_VOIP) { + AudioInjectorPolicy &audioInjectorPolicy = AudioInjectorPolicy::GetInstance(); + audioInjectorPolicy.SetCapturePortIdx((*it)->paIndex_); + if ((*it)->routeFlag_ & AUDIO_INPUT_FLAG_NORMAL) { + return NORMAL_VOIP; + } else if ((*it)->routeFlag_ & AUDIO_INPUT_FLAG_FAST) { + return FAST_VOIP; + } + } + } + return NO_VOIP; +} + +std::shared_ptr AudioPipeManager::GetPipeBySessionId(uint32_t sessionId) +{ + std::unique_lock pLock(pipeListLock_); + for (const auto &pipe : curPipeList_) { + if (pipe == nullptr) { + continue; + } + for (const auto &stream : pipe->streamDescriptors_) { + if (stream == nullptr) { + continue; + } + if (stream->sessionId_ == sessionId) { + AUDIO_INFO_LOG("find pipe: %{public}s by sessionId: %{public}u", pipe->name_.c_str(), sessionId); + return pipe; + } + } + } + return nullptr; +} + +bool AudioPipeManager::IsPipeAlive(std::shared_ptr pipe) +{ + std::unique_lock pLock(pipeListLock_); + for (auto iter = curPipeList_.begin(); iter != curPipeList_.end(); iter++) { + if (IsSamePipe(pipe, *iter)) { + return true; + } + } + return false; +} + +uint32_t AudioPipeManager::GetPaIndexByName(std::string portName) +{ + std::unique_lock pLock(pipeListLock_); + for (auto iter = curPipeList_.begin(); iter != curPipeList_.end(); iter++) { + CHECK_AND_CONTINUE_LOG((*iter) != nullptr, "iter is null"); + if ((*iter)->name_ == portName) { + return (*iter)->paIndex_; + } + } + return HDI_INVALID_ID; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h b/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h index fdcea314e5..126f913f3e 100644 --- a/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h +++ b/services/audio_policy/server/domain/volume/include/audio_adapter_manager.h @@ -306,6 +306,11 @@ public: void SaveSystemVolumeForEffect(DeviceType deviceType, AudioStreamType streamType, int32_t volumeLevel); int32_t GetSystemVolumeForEffect(DeviceType deviceType, AudioStreamType streamType); int32_t SetSystemVolumeToEffect(AudioStreamType streamType, float volume); + + int32_t AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType); + int32_t RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType); + int32_t AddCaptureInjector(); + int32_t RemoveCaptureInjector(); private: friend class PolicyCallbackImpl; diff --git a/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h b/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h index 8be01d59d3..248627bfff 100644 --- a/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h +++ b/services/audio_policy/server/domain/volume/include/iaudio_policy_interface.h @@ -257,6 +257,11 @@ public: virtual float CalculateVolumeDbNonlinear(AudioStreamType streamType, DeviceType deviceType, int32_t volumeLevel) = 0; + + virtual int32_t AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) = 0; + virtual int32_t RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) = 0; + virtual int32_t AddCaptureInjector() = 0; + virtual int32_t RemoveCaptureInjector() = 0; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp b/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp index f47ba066b5..6027bce4ad 100644 --- a/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp +++ b/services/audio_policy/server/domain/volume/src/audio_adapter_manager.cpp @@ -3405,6 +3405,35 @@ int32_t AudioAdapterManager::SetSystemVolumeToEffect(AudioStreamType streamType, CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_, ERROR, "audioServiceAdapter is null"); return audioServiceAdapter_->SetSystemVolumeToEffect(streamType, volume); } + +int32_t AudioAdapterManager::AddCaptureInjector() +{ + AudioInjectorPolicy &audioInjectorPolicy = AudioInjectorPolicy::GetInstance(); + AudioModuleInfo &info = audioInjectorPolicy.GetAudioModuleInfo(); + uint32_t rendererPortIdx = audioInjectorPolicy.GetRendererPortIdx(); + CHECK_AND_RETURN_RET_LOG(audioServerProxy_ != nullptr, ERROR, "audioServerProxy_ null"); + return audioServerProxy_->AddCaptureInjector(rendererPortIdx, info.rate, info.format, info.channels); +} + +int32_t AudioAdapterManager::RemoveCaptureInjector() +{ + AudioInjectorPolicy &audioInjectorPolicy = AudioInjectorPolicy::GetInstance(); + uint32_t rendererPortIdx = audioInjectorPolicy.GetRendererPortIdx(); + CHECK_AND_RETURN_RET_LOG(audioServerProxy_ != nullptr, ERROR, "audioServerProxy_ null"); + return audioServerProxy_->RemoveCaptureInjector(rendererPortIdx); +} + +int32_t AudioAdapterManager::AddCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); + return audioServiceAdapter_->AddCaptureInjector(sinkPortIndex, sourcePortIndex, sourceType); +} + +int32_t AudioAdapterManager::RemoveCaptureInjector(const uint32_t &sinkPortIndex, const uint32_t &sourcePortIndex, const SourceType &sourceType) +{ + CHECK_AND_RETURN_RET_LOG(audioServiceAdapter_ != nullptr, ERR_OPERATION_FAILED, "ServiceAdapter is null"); + return audioServiceAdapter_->RemoveCaptureInjector(sinkPortIndex, sourcePortIndex, sourceType); +} // LCOV_EXCL_STOP } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/service/service_main/include/audio_core_service.h b/services/audio_policy/server/service/service_main/include/audio_core_service.h index 5aee838b50..78e57d908d 100644 --- a/services/audio_policy/server/service/service_main/include/audio_core_service.h +++ b/services/audio_policy/server/service/service_main/include/audio_core_service.h @@ -48,6 +48,7 @@ #include "audio_event_utils.h" #include "audio_stream_id_allocator.h" #include "i_hpae_soft_link.h" +#include "audio_injector_policy.h" namespace OHOS { namespace AudioStandard { enum OffloadType { @@ -177,6 +178,8 @@ public: std::vector> GetVolumeGroupInfos(); int32_t SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config) override; int32_t ReleaseOffloadPipe(AudioIOHandle id, uint32_t paIndex, OffloadType type); + int32_t SetRendererTarget(RendererTarget target, RendererTarget lastTarget, uint32_t sessionId) override; + int32_t StartInjection(uint32_t sessionId) override; private: std::shared_ptr coreService_; std::shared_mutex eventMutex_; @@ -318,6 +321,9 @@ private: void SetFirstScreenOn(); void FetchOutputDupDevice(std::string caller, uint32_t sessionId, std::shared_ptr &streamDesc); + int32_t SetRendererTarget(RendererTarget target, RendererTarget lastTarget, uint32_t sessionId); + int32_t StartInjection(uint32_t sessionId); + private: static std::string GetEncryptAddr(const std::string &addr); int32_t FetchRendererPipesAndExecute(std::vector> &streamDescs, @@ -523,6 +529,9 @@ private: void CheckOpenHearingAidCall(const bool isModemCallRunning, const DeviceType type); std::shared_ptr GetCaptureClientDevice( std::shared_ptr streamDesc, uint32_t sessionId); + + int32_t PlayBackToInjection(uint32_t sessionId); + int32_t InjectionToPlayBack(uint32_t sessionId); private: std::shared_ptr eventEntry_; @@ -609,6 +618,8 @@ private: .type = CAST_TYPE_NULL }; bool isFirstScreenOn_ = false; + + AudioInjectorPolicy &audioInjectorPolicy_; }; } } diff --git a/services/audio_policy/server/service/service_main/include/audio_injector_policy.h b/services/audio_policy/server/service/service_main/include/audio_injector_policy.h new file mode 100644 index 0000000000..17f5ac85c0 --- /dev/null +++ b/services/audio_policy/server/service/service_main/include/audio_injector_policy.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef AUDIO_INJECTOR_POLICY_H +#define AUDIO_INJECTOR_POLICY_H + +#include +#include "audio_module_info.h" +#include "audio_pipe_info.h" +#include "audio_iohandle_map.h" +#include "iaudio_policy_interface.h" +#include "audio_pipe_manager.h" + +namespace OHOS { +namespace AudioStandard { +enum VoIpType { + NO_VOIP = 0, + NORMAL_VOIP = 1, + FAST_VOIP = 2, +}; + +class AudioInjectorPolicy { +public: + static AudioInjectorPolicy& GetInstance() + { + static AudioInjectorPolicy instance; + return instance; + } + int32_t Init(); + int32_t DeInit(); + int32_t UpdateAudioInfo(AudioModuleInfo &info); + int32_t MoveStream(uint32_t renderId, bool flag); + int32_t GetRendererStreamCount(); + void SetCapturePortIdx(uint32_t idx); + uint32_t GetCapturePortIdx(); + void SetRendererPortIdx(uint32_t idx); + uint32_t GetRendererPortIdx(); + AudioModuleInfo& GetAudioModuleInfo(); + int32_t AddCaptureInjector(); + int32_t RemoveCaptureInjector(); + +private: + AudioInjectorPolicy(); + AudioInjectorPolicy(const AudioInjectorPolicy&) = delete; + AudioInjectorPolicy& operator=(const AudioInjectorPolicy&) = delete; +private: + AudioModuleInfo moduleInfo_; + uint32_t capturePortIdx_; + uint32_t renderPortIdx_; + bool isConnected_; + std::unordered_map> rendererStreamMap_ = {}; + AudioIOHandleMap &audioIOHandleMap_; + IAudioPolicyInterface &audioPolicyManager_; + std::shared_ptr pipeManager_ = nullptr; + std::shared_mutex injectLock_; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // AUDIO_INJECTOR_POLICY_H \ No newline at end of file diff --git a/services/audio_policy/server/service/service_main/src/audio_core_service.cpp b/services/audio_policy/server/service/service_main/src/audio_core_service.cpp index 9515f906c2..685b8b5192 100644 --- a/services/audio_policy/server/service/service_main/src/audio_core_service.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_core_service.cpp @@ -83,7 +83,8 @@ AudioCoreService::AudioCoreService() audioUsrSelectManager_(AudioUsrSelectManager::GetAudioUsrSelectManager()), audioPipeSelector_(AudioPipeSelector::GetPipeSelector()), audioSessionService_(AudioSessionService::GetAudioSessionService()), - pipeManager_(AudioPipeManager::GetPipeManager()) + pipeManager_(AudioPipeManager::GetPipeManager()), + audioInjectorPolicy_(AudioInjectorPolicy::GetInstance()) { AUDIO_INFO_LOG("Ctor"); } @@ -1519,5 +1520,30 @@ void AudioCoreService::SetFirstScreenOn() { isFirstScreenOn_ = true; } + +int32_t AudioCoreService::SetRendererTarget(RendererTarget target, RendererTarget lastTarget, uint32_t sessionId) +{ + int32_t ret = ERROR; + if (lastTarget == PLAYBACK_DEFAULT && target == INJECT_TO_VOICE_COMMUNICATION_CAPTURE) { + ret = PlayBackToInjection(sessionId); + } else if(lastTarget == INJECT_TO_VOICE_COMMUNICATION_CAPTURE && target == PLAYBACK_DEFAULT) { + ret = InjectionToPlayBack(sessionId); + } + return ret; +} + +int32_t AudioCoreService::StartInjection(uint32_t streamId) +{ + CHECK_AND_RETURN_RET_LOG(pipeManager_ != nullptr, ERR_NULL_POINTER, "pipeManager_ is null"); + if (pipeManager_->IsVoIPCall() == NO_VOIP) { + return ERROR; + } + int32_t ret = ERROR; + ret = audioInjectorPolicy_.AddCaptureInjector(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "AddCaptureInjector failed"); + ret = audioInjectorPolicy_.MoveStream(streamId, true); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "Move Stream in failed"); + return SUCCESS; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp b/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp index f049bb588f..102b20648c 100644 --- a/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_core_service_entry.cpp @@ -599,5 +599,17 @@ int32_t AudioCoreService::EventEntry::ReleaseOffloadPipe(AudioIOHandle id, uint3 coreService_->isOffloadInRelease_[type].store(false); return SUCCESS; } + +int32_t AudioCoreService::EventEntry::SetRendererTarget(RendererTarget target, RendererTarget lastTarget, uint32_t sessionId) +{ + std::lock_guard lock(eventMutex_); + return coreService_->SetRendererTarget(target, lastTarget, sessionId); +} + +int32_t AudioCoreService::EventEntry::StartInjection(uint32_t sessionId) +{ + std::lock_guard lock(eventMutex_); + return coreService_->StartInjection(sessionId); +} } } diff --git a/services/audio_policy/server/service/service_main/src/audio_core_service_private.cpp b/services/audio_policy/server/service/service_main/src/audio_core_service_private.cpp index 0c8963750e..301e260b19 100644 --- a/services/audio_policy/server/service/service_main/src/audio_core_service_private.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_core_service_private.cpp @@ -3144,5 +3144,30 @@ int32_t AudioCoreService::SetSleVoiceStatusFlag(AudioScene audioScene) } return SUCCESS; } + +int32_t AudioCoreService::PlayBackToInjection(uint32_t sessionId) +{ + if (!PermissionUtil::VerifySystemPermission()) { + return ERR_PERMISSION_DENIED; + } + if (pipeManager_->IsVoIPCall() == NO_VOIP) { + return ERROR; + } + int32_t ret = audioInjectorPolicy_.Init(); + //策略 + return ret; +} + +int32_t AudioCoreService::InjectionToPlayBack(uint32_t sessionId) +{ + int32_t ret = ERROR; + ret = audioInjectorPolicy_.MoveStream(sessionId, false); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "Move Stream out failed"); + ret = audioInjectorPolicy_.RemoveCaptureInjector(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "RemoveCaptureInjector failed"); + ret = audioInjectorPolicy_.DeInit(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "DeInit failed"); + return SUCCESS; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/service/service_main/src/audio_injector_policy.cpp b/services/audio_policy/server/service/service_main/src/audio_injector_policy.cpp new file mode 100644 index 0000000000..5834749a6a --- /dev/null +++ b/services/audio_policy/server/service/service_main/src/audio_injector_policy.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "audio_injector_policy.h" +#include "audio_policy_manager_factory.h" + +namespace OHOS { +namespace AudioStandard { +AudioInjectorPolicy::AudioInjectorPolicy() + :audioIOHandleMap_(AudioIOHandleMap::GetInstance()), + audioPolicyManager_(AudioPolicyManagerFactory::GetAudioPolicyManager()) +{ + pipeManager_ = AudioPipeManager::GetPipeManager(); + isConnected_ = false; +} + +int32_t AudioInjectorPolicy::Init() +{ + std::lock_guard lock(injectLock_); + if (rendererStreamMap_.size() == 0) { + AUDIO_INFO_LOG("Start"); + AudioModuleInfo moduleInfo = {}; + moduleInfo.lib = "libmodule-hdi-sink.z.so"; + std::string name = ""; + moduleInfo.name = name; + + moduleInfo.format = "s16le"; + moduleInfo.channels = "2"; // 2 channel + moduleInfo.rate = "48000"; + moduleInfo.bufferSize = "3840"; // 20ms + + int32_t ret = audioIOHandleMap_.OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "open port failed"); + this->moduleInfo_ = moduleInfo; + CHECK_AND_RETURN_RET_LOG(pipeManager_ != nullptr, ERROR, "pipeManager_ is null"); + renderPortIdx_ = pipeManager_->GetPaIndexByName(moduleInfo.name); + CHECK_AND_RETURN_RET_LOG(renderPortIdx_ != HDI_INVALID_ID, ERROR, "renderPortIdx error!"); + } + return SUCCESS; +} + +int32_t AudioInjectorPolicy::DeInit() +{ + std::lock_guard lock(injectLock_); + if (rendererStreamMap_.size() == 0) { + int32_t ret = audioIOHandleMap_.ClosePortAndEraseIOHandle(moduleInfo_.name); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "close port failed"); + renderPortIdx_ = HDI_INVALID_ID; + } + return SUCCESS; +} + +int32_t AudioInjectorPolicy::UpdateAudioInfo(AudioModuleInfo &info) +{ + return SUCCESS; +} + +int32_t AudioInjectorPolicy::MoveStream(uint32_t renderId, bool flag) +{ + std::lock_guard lock(injectLock_); + CHECK_AND_RETURN_RET_LOG(pipeManager_ != nullptr, ERROR, "pipeManager_ is null"); + int32_t ret = ERROR; + if (flag) { + std::shared_ptr info = pipeManager_->GetPipeBySessionId(renderId); + CHECK_AND_RETURN_RET_LOG(info != nullptr, ERROR, "get pipeinfo failed"); + ret = audioPolicyManager_.MoveSinkInputByIndexOrName(renderId, 1, moduleInfo_.name); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "move stream in failed"); + rendererStreamMap_[renderId] = info; + } else { + std::string portName = ""; + std::shared_ptr oldInfo = rendererStreamMap_[renderId]; + if (pipeManager_->IsPipeAlive(oldInfo)) { + CHECK_AND_RETURN_RET_LOG(oldInfo != nullptr, ERROR, "oldInfo is null"); + portName = oldInfo->name_; + } else { + AudioModuleInfo moduleInfo = oldInfo->moduleInfo_; + portName = moduleInfo.name; + ret = audioIOHandleMap_.OpenPortAndInsertIOHandle(portName, moduleInfo); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "open original port failed"); + } + ret = audioPolicyManager_.MoveSinkInputByIndexOrName(renderId, 1, portName); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "move stream out failed"); + rendererStreamMap_[renderId] = nullptr; + rendererStreamMap_.erase(renderId); + } + return SUCCESS; +} + +// get the number of rendererStream moved in Injector +int32_t AudioInjectorPolicy::GetRendererStreamCount() +{ + return rendererStreamMap_.size(); +} + +void AudioInjectorPolicy::SetCapturePortIdx(uint32_t idx) +{ + std::lock_guard lock(injectLock_); + capturePortIdx_ = idx; +} + +uint32_t AudioInjectorPolicy::GetCapturePortIdx() +{ + return capturePortIdx_; +} + +void AudioInjectorPolicy::SetRendererPortIdx(uint32_t idx) +{ + std::lock_guard lock(injectLock_); + renderPortIdx_ = idx; +} + +uint32_t AudioInjectorPolicy::GetRendererPortIdx() +{ + return renderPortIdx_; +} + +AudioModuleInfo& AudioInjectorPolicy::GetAudioModuleInfo() +{ + return moduleInfo_; +} + +int32_t AudioInjectorPolicy::AddCaptureInjector() +{ + std::lock_guard lock(injectLock_); + int32_t ret = ERROR; + if (!isConnected_) { + CHECK_AND_RETURN_RET_LOG(pipeManager_ != nullptr, ERROR, "pipeManager_ is null"); + if (pipeManager_->IsVoIPCall() == NORMAL_VOIP) { + ret = audioPolicyManager_.AddCaptureInjector(renderPortIdx_, capturePortIdx_, SOURCE_TYPE_VOICE_COMMUNICATION); + } else if (pipeManager_->IsVoIPCall() == FAST_VOIP) { + ret = audioPolicyManager_.AddCaptureInjector(); + } + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "AddCaptureInjector failed"); + } + isConnected_ = true; + return SUCCESS; +} + +int32_t AudioInjectorPolicy::RemoveCaptureInjector() +{ + std::lock_guard lock(injectLock_); + int32_t ret = ERROR; + if (isConnected_) { + CHECK_AND_RETURN_RET_LOG(pipeManager_ != nullptr, ERROR, "pipeManager_ is null"); + if (pipeManager_->IsVoIPCall() == NORMAL_VOIP) { + ret = audioPolicyManager_.RemoveCaptureInjector(renderPortIdx_, capturePortIdx_, SOURCE_TYPE_VOICE_COMMUNICATION); + } else if (pipeManager_->IsVoIPCall() == FAST_VOIP) { + ret = audioPolicyManager_.RemoveCaptureInjector(); + } + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "RemoveCaptureInjector failed"); + } + isConnected_ = false; + return SUCCESS; +} +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_service/client/include/core_service_provider_stub.h b/services/audio_service/client/include/core_service_provider_stub.h index cd8ef6a536..9dfb67c0ad 100644 --- a/services/audio_service/client/include/core_service_provider_stub.h +++ b/services/audio_service/client/include/core_service_provider_stub.h @@ -37,6 +37,8 @@ public: int32_t GetPaIndexByPortName(const std::string &portName, uint32_t &ret) override; int32_t SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config, int32_t &ret) override; + int32_t SetRendererTarget(uint32_t target, uint32_t lastTarget, uint32_t sessionId, int32_t &ret) override; + int32_t StartInjection(uint32_t streamId, int32_t &ret) override; private: ICoreServiceProvider *coreServiceWorker_; }; diff --git a/services/audio_service/client/include/renderer_in_client_private.h b/services/audio_service/client/include/renderer_in_client_private.h index e847917ac8..765bbac205 100644 --- a/services/audio_service/client/include/renderer_in_client_private.h +++ b/services/audio_service/client/include/renderer_in_client_private.h @@ -502,6 +502,8 @@ private: std::optional lastCallStartByUserTid_ = std::nullopt; std::function uidGetter_ = [] { return getuid(); }; + + uint32_t target_ = 0; }; class SpatializationStateChangeCallbackImpl : public AudioSpatializationStateChangeCallback { diff --git a/services/audio_service/client/src/core_service_provider_stub.cpp b/services/audio_service/client/src/core_service_provider_stub.cpp index d112abf64f..7dfbecbed2 100644 --- a/services/audio_service/client/src/core_service_provider_stub.cpp +++ b/services/audio_service/client/src/core_service_provider_stub.cpp @@ -89,5 +89,19 @@ int32_t CoreServiceProviderWrapper::GetPaIndexByPortName(const std::string &port ret = coreServiceWorker_->GetPaIndexByPortName(portName); return SUCCESS; } + +int32_t CoreServiceProviderWrapper::SetRendererTarget(uint32_t target, uint32_t lastTarget, uint32_t sessionId, int32_t &ret) +{ + CHECK_AND_RETURN_RET_LOG(coreServiceWorker_ != nullptr, AUDIO_INIT_FAIL, "coreServiceWorker_ is null"); + ret = coreServiceWorker_->SetRendererTarget(static_cast(target), static_cast(lastTarget), sessionId); + return SUCCESS; +} + +int32_t CoreServiceProviderWrapper::StartInjection(uint32_t streamId, int32_t &ret) +{ + CHECK_AND_RETURN_RET_LOG(coreServiceWorker_ != nullptr, AUDIO_INIT_FAIL, "coreServiceWorker_ is null"); + ret = coreServiceWorker_->StartInjection(streamId); + return SUCCESS; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/client/src/renderer_in_client_public.cpp b/services/audio_service/client/src/renderer_in_client_public.cpp index a25ba3773f..d423471232 100644 --- a/services/audio_service/client/src/renderer_in_client_public.cpp +++ b/services/audio_service/client/src/renderer_in_client_public.cpp @@ -1468,6 +1468,7 @@ void RendererInClientInner::GetSwitchInfo(IAudioStream::SwitchInfo& info) info.defaultOutputDevice = defaultOutputDevice_; info.lastFramePosAndTimePair = lastFramePosAndTimePair_; info.lastFramePosAndTimePairWithSpeed = lastFramePosAndTimePairWithSpeed_; + info.target = target_; GetStreamSwitchInfo(info); { diff --git a/services/audio_service/common/include/i_core_service_provider.h b/services/audio_service/common/include/i_core_service_provider.h index 73a9ff372b..6b1fb3c438 100644 --- a/services/audio_service/common/include/i_core_service_provider.h +++ b/services/audio_service/common/include/i_core_service_provider.h @@ -39,6 +39,8 @@ public: virtual int32_t SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config) = 0; virtual ~ICoreServiceProvider() = default; + virtual int32_t SetRendererTarget(RendererTarget target, RendererTarget lastTarget, uint32_t sessionId) = 0; + virtual int32_t StartInjection(uint32_t sessionId) = 0; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/idl/ICoreServiceProviderIpc.idl b/services/audio_service/idl/ICoreServiceProviderIpc.idl index bf7d9f9b94..ec1215f420 100644 --- a/services/audio_service/idl/ICoreServiceProviderIpc.idl +++ b/services/audio_service/idl/ICoreServiceProviderIpc.idl @@ -47,4 +47,12 @@ interface ICoreServiceProviderIpc { void GetPaIndexByPortName( [in] String portName, [out] unsigned int ret); + void SetRendererTarget( + [in] unsigned int target, + [in] unsigned int lastTarget, + [in] unsigned int sessionId, + [out] int ret); + void StartInjection( + [in] unsigned int target, + [out] int ret); } diff --git a/services/audio_service/idl/IStandardAudioService.idl b/services/audio_service/idl/IStandardAudioService.idl index 83b9f171d2..82678d0f93 100644 --- a/services/audio_service/idl/IStandardAudioService.idl +++ b/services/audio_service/idl/IStandardAudioService.idl @@ -140,6 +140,8 @@ interface IStandardAudioService { void RestoreAudioWorkgroupPrio([in] int pid, [in] Map threads); void SetRenderWhitelist([in] List list); void GetVolumeBySessionId([in] unsigned int sessionId, [out] float volume); + void AddCaptureInjector([in] unsigned int sinkPortidx, [out] String rate, [out] String format, [out] String channels); + void RemoveCaptureInjector([in] unsigned int sinkPortidx); // WARNING: above functions correspond with AudioServerInterfaceCode // undefined in AudioServerInterfaceCode diff --git a/services/audio_service/server/include/audio_injector_service.h b/services/audio_service/server/include/audio_injector_service.h index 0b5dd8c84f..2b4cd02e0e 100644 --- a/services/audio_service/server/include/audio_injector_service.h +++ b/services/audio_service/server/include/audio_injector_service.h @@ -33,10 +33,11 @@ public: int32_t GetSinkPortIdx(); private: AudioInjectorService(); + ~AudioInjectorService() = default; AudioInjectorService(const AudioInjectorService&) = delete; AudioInjectorService& operator=(const AudioInjectorService&) = delete; private: - AudioModuleInfo moudleInfo_; + AudioModuleInfo moduleInfo_; uint32_t sinkPortIndex_; }; } // namespace AudioStandard diff --git a/services/audio_service/server/include/audio_server.h b/services/audio_service/server/include/audio_server.h index 93462af2ea..ae608d1290 100644 --- a/services/audio_service/server/include/audio_server.h +++ b/services/audio_service/server/include/audio_server.h @@ -270,6 +270,9 @@ public: int32_t SendInterruptEventToAudioServer(uint32_t sessionId, const InterruptEventInternal &interruptEvent) override; int32_t GetVolumeBySessionId(uint32_t sessionId, float &volume) override; + + int32_t AddCaptureInjector(uint32_t sinkPortidx, std::string &rate, std::string &format, std::string &channels) override; + int32_t RemoveCaptureInjector(uint32_t sinkPortidx) override; protected: void OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; diff --git a/services/audio_service/server/include/core_service_handler.h b/services/audio_service/server/include/core_service_handler.h index 68ed4c89b2..fa44b86fe8 100644 --- a/services/audio_service/server/include/core_service_handler.h +++ b/services/audio_service/server/include/core_service_handler.h @@ -47,6 +47,9 @@ public: AudioStreamInfo &streamInfo, bool isReloadProcess); uint32_t GenerateSessionId(); int32_t SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config); + + int32_t SetRendererTarget(uint32_t target, uint32_t lastTarget, uint32_t sessionId); + int32_t StartInjection(uint32_t sessionId); private: CoreServiceHandler(); sptr iCoreServiceProvider_ = nullptr; diff --git a/services/audio_service/server/include/renderer_in_server.h b/services/audio_service/server/include/renderer_in_server.h index 5208dc1698..ff1bed1ec9 100644 --- a/services/audio_service/server/include/renderer_in_server.h +++ b/services/audio_service/server/include/renderer_in_server.h @@ -26,6 +26,7 @@ #include "audio_stream_monitor.h" #include "audio_stream_checker.h" #include "player_dfx_writer.h" +#include "audio_service_enum.h" namespace OHOS { namespace AudioStandard { @@ -151,6 +152,7 @@ public: int32_t InitSoftLink(int32_t innerCapId); int32_t DestroySoftLink(int32_t innerCapId); int32_t InitSoftLinkVolume(std::shared_ptr softLinkPtr); + int32_t SetTarget(RendererTarget target, int32_t &ret); public: const AudioProcessConfig processConfig_; private: @@ -287,6 +289,8 @@ private: std::unordered_map softLinkInfos_; FILE *dumpSoftLink = nullptr; + + RendererTarget lastTarget_; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/src/audio_injector_service.cpp b/services/audio_service/server/src/audio_injector_service.cpp index a106310563..f7328b8994 100644 --- a/services/audio_service/server/src/audio_injector_service.cpp +++ b/services/audio_service/server/src/audio_injector_service.cpp @@ -13,22 +13,26 @@ * limitations under the License. */ #include "audio_injector_service.h" +#include "i_hpae_manager.h" +#include "audio_errors.h" namespace OHOS { namespace AudioStandard { -AudioInjectorService::AudioInjectorService() +AudioInjectorService::AudioInjectorService() { } int32_t AudioInjectorService::UpdateAudioInfo(AudioModuleInfo &info) { - return 0; + HPAE::IHpaeManager::GetHpaeManager().UpdateAudioPortInfo(sinkPortIndex_, info); + return SUCCESS; } int32_t AudioInjectorService::PeekAudioData(const uint32_t sinkPortIndex, uint8_t *buffer, const size_t bufferSize, AudioStreamInfo &streamInfo) { - return 0; + HPAE::IHpaeManager::GetHpaeManager().PeekAudioData(sinkPortIndex, buffer, bufferSize, streamInfo); + return SUCCESS; } void AudioInjectorService::SetSinkPortIdx(uint32_t sinkPortIdx) diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index fe72497d99..10d0376372 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -3168,6 +3168,18 @@ int32_t AudioServer::GetPrivacyTypeAudioServer(uint32_t sessionId, int32_t &priv privacyType = static_cast(type); return SUCCESS; } + +int32_t AudioServer::AddCaptureInjector(uint32_t sinkPortidx, std::string &rate, std::string &format, std::string &channels) +{ + //endpoint::AddCaptureInjector + return SUCCESS; +} + +int32_t AudioServer::RemoveCaptureInjector(uint32_t sinkPortidx) +{ + //endpoint::RemoveCaptureInjector + return SUCCESS; +} // LCOV_EXCL_STOP } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/src/core_service_handler.cpp b/services/audio_service/server/src/core_service_handler.cpp index 7534d09176..0ca3a81c45 100644 --- a/services/audio_service/server/src/core_service_handler.cpp +++ b/services/audio_service/server/src/core_service_handler.cpp @@ -114,5 +114,21 @@ uint32_t CoreServiceHandler::GetPaIndexByPortName(const std::string &portName) iCoreServiceProvider_->GetPaIndexByPortName(portName, ret); return ret; } + +int32_t CoreServiceHandler::SetRendererTarget(uint32_t target, uint32_t lastTarget, uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(iCoreServiceProvider_ != nullptr, ERROR, "iCoreServiceProvider_ is nullptr!"); + int32_t ret = ERROR; + iCoreServiceProvider_->SetRendererTarget(target, lastTarget, sessionId, ret); + return ret; +} + +int32_t CoreServiceHandler::StartInjection(uint32_t sessionId) +{ + CHECK_AND_RETURN_RET_LOG(iCoreServiceProvider_ != nullptr, ERROR, "iCoreServiceProvider_ is nullptr!"); + int32_t ret = ERROR; + iCoreServiceProvider_->StartInjection(sessionId, ret); + return ret; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/src/renderer_in_server.cpp b/services/audio_service/server/src/renderer_in_server.cpp index e49341db39..be202d1f22 100644 --- a/services/audio_service/server/src/renderer_in_server.cpp +++ b/services/audio_service/server/src/renderer_in_server.cpp @@ -1003,6 +1003,10 @@ int32_t RendererInServer::StartInner() { AUDIO_INFO_LOG("sessionId: %{public}u", streamIndex_); int32_t ret = 0; + if (lastTarget_ == INJECT_TO_VOICE_COMMUNICATION_CAPTURE) { + ret = CoreServiceHandler::GetInstance().StartInjection(streamIndex_); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "StartInjection failed"); + } if (standByEnable_) { return StartInnerDuringStandby(); } else { @@ -2474,5 +2478,20 @@ bool RendererInServer::IsMovieStream() return processConfig_.streamType == STREAM_MOVIE && processConfig_.rendererInfo.originalFlag == AUDIO_FLAG_PCM_OFFLOAD; } + +int32_t RendererInServer::SetTarget(RendererTarget target, int32_t &ret) +{ + if (target == lastTarget_) { + ret = SUCCESS; + return ret; + } + if (status_ == I_STATUS_IDLE || status_ == I_STATUS_PAUSED || status_ == I_STATUS_STOPPED) { + ret = CoreServiceHandler::GetInstance().SetRendererTarget(target, lastTarget_, streamIndex_); + lastTarget_ = target; + return ret; + } + ret = ERR_ILLEGAL_STATE; + return ret; +} } // namespace AudioStandard } // namespace OHOS -- Gitee