From 6a7a6f3e2bec2cdb7e5f8c49cdb0ac9928c30920 Mon Sep 17 00:00:00 2001 From: seveno0 Date: Mon, 28 Apr 2025 18:52:58 +0800 Subject: [PATCH] hiplay feature Signed-off-by: seveno0 --- frameworks/cj/src/multimedia_audio_common.cpp | 16 +- .../js/napi/common/napi_param_utils.cpp | 16 +- .../src/audio_manager_unit_test.cpp | 30 +- .../src/audio_stream_manager_unit_test.cpp | 26 +- .../native/audioutils/include/audio_utils.h | 1 + frameworks/native/hdiadapter_new/BUILD.gn | 2 + .../include/common/hdi_adapter_info.h | 1 + .../include/manager/hdi_adapter_factory.h | 1 + .../sink/remote_offload_audio_render_sink.h | 197 ++++ .../manager/hdi_adapter_factory.cpp | 10 + .../sink/remote_offload_audio_render_sink.cpp | 842 ++++++++++++++++++ ...te_offload_audio_render_sink_unit_test.cpp | 165 ++++ .../native/hdiadapter_new/util/id_handler.cpp | 2 + .../ohaudio/OHAudioDeviceDescriptor.cpp | 11 +- .../include/audio_device_descriptor.h | 6 +- .../audiocommon/include/audio_device_info.h | 81 +- .../include/audio_device_stream_info.h | 333 +++++++ .../native/audiocommon/include/audio_info.h | 2 +- .../manager/src/i_hpae_renderer_manager.cpp | 3 +- .../node/src/hpae_offload_sinkoutput_node.cpp | 5 +- .../manager/hpae_render_manager_test.cpp | 20 + .../common/include/audio_module_info.h | 2 +- .../domain/device/src/audio_active_device.cpp | 4 +- .../device/src/audio_connected_device.cpp | 2 +- .../domain/device/src/audio_device_common.cpp | 5 +- .../device/src/audio_device_descriptor.cpp | 96 +- .../domain/device/src/audio_device_status.cpp | 20 +- .../device/src/device_status_listener.cpp | 30 + .../include/audio_definition_adapter_info.h | 17 + .../include/audio_policy_config_manager.h | 6 + .../src/audio_definition_adapter_info.cpp | 88 ++ .../domain/pipe/src/audio_pipe_selector.cpp | 63 +- .../pipe/src/audio_policy_config_manager.cpp | 74 ++ .../volume/src/audio_adapter_manager.cpp | 2 +- .../parser/src/audio_policy_config_parser.cpp | 10 +- .../config/parser/src/audio_policy_parser.cpp | 2 +- .../service_main/include/audio_core_service.h | 22 +- .../service_main/src/audio_core_service.cpp | 27 +- .../src/audio_core_service_private.cpp | 70 +- .../service_main/src/audio_policy_dump.cpp | 22 +- .../service_main/src/audio_policy_service.cpp | 6 +- .../src/audio_a2dp_device_unit_test.cpp | 12 +- .../audio_core_service_private_unit_test.cpp | 31 + ...udio_definition_adapter_info_unit_test.cpp | 56 ++ .../src/audio_device_status_unit_test.cpp | 23 + .../src/audio_pipe_selector_unit_test.cpp | 10 + ...udio_policy_service_thirdext_unit_test.cpp | 25 + .../server/src/audio_endpoint.cpp | 16 +- .../server/src/audio_endpoint_separate.cpp | 17 +- .../server/src/audio_process_in_server.cpp | 7 +- .../server/src/audio_service.cpp | 20 +- .../server/src/hpae_renderer_stream_impl.cpp | 5 +- .../src/audio_endpoint_plus_unit_test.cpp | 7 +- .../src/audio_endpoint_unit_test.cpp | 95 +- .../audio_process_in_server_unit_test.cpp | 2 +- .../test/unittest/audio_service_unit_test.cpp | 8 +- .../hpae_renderer_stream_impl_unit_test.cpp | 12 + .../audio_service_fuzzer.cpp | 6 +- .../audio_service_server_src_fuzzer.cpp | 4 +- .../audio_stream_fuzzer.cpp | 2 +- 60 files changed, 2353 insertions(+), 343 deletions(-) create mode 100644 frameworks/native/hdiadapter_new/include/sink/remote_offload_audio_render_sink.h create mode 100644 frameworks/native/hdiadapter_new/sink/remote_offload_audio_render_sink.cpp create mode 100644 frameworks/native/hdiadapter_new/test/unittest/sink/remote_offload_audio_render_sink_unit_test.cpp create mode 100644 interfaces/inner_api/native/audiocommon/include/audio_device_stream_info.h diff --git a/frameworks/cj/src/multimedia_audio_common.cpp b/frameworks/cj/src/multimedia_audio_common.cpp index 3ac45a57c6..e5cf1925d6 100644 --- a/frameworks/cj/src/multimedia_audio_common.cpp +++ b/frameworks/cj/src/multimedia_audio_common.cpp @@ -157,7 +157,8 @@ void Convert2CArrDeviceDescriptorByDeviceInfo( void InitializeDeviceChannels(CDeviceDescriptor* device, const AudioDeviceDescriptor& deviceInfo, int32_t* errorCode) { - size_t channelSize = deviceInfo.audioStreamInfo_.channels.size(); + std::set deviceInfoChannels = deviceInfo.GetDeviceStreamInfo().GetChannels(); + size_t channelSize = deviceInfoChannels.size(); if (channelSize == 0 || channelSize > MAX_MEM_MALLOC_SIZE) { *errorCode = CJ_ERR_SYSTEM; return; @@ -181,7 +182,7 @@ void InitializeDeviceChannels(CDeviceDescriptor* device, const AudioDeviceDescri int32_t iter = 0; device->channelCounts.size = static_cast(channelSize); device->channelCounts.head = channels; - for (auto channel : deviceInfo.audioStreamInfo_.channels) { + for (auto channel : deviceInfoChannels) { channels[iter] = static_cast(channel); iter++; } @@ -189,7 +190,7 @@ void InitializeDeviceChannels(CDeviceDescriptor* device, const AudioDeviceDescri void InitializeDeviceRates(CDeviceDescriptor* device, const AudioDeviceDescriptor& deviceInfo, int32_t* errorCode) { - size_t rateSize = deviceInfo.audioStreamInfo_.samplingRate.size(); + size_t rateSize = deviceInfo.GetDeviceStreamInfo().samplingRate.size(); if (rateSize == 0 || rateSize > MAX_MEM_MALLOC_SIZE) { *errorCode = CJ_ERR_SYSTEM; return; @@ -213,7 +214,7 @@ void InitializeDeviceRates(CDeviceDescriptor* device, const AudioDeviceDescripto int32_t iter = 0; device->sampleRates.size = static_cast(rateSize); device->sampleRates.head = rates; - for (auto rate : deviceInfo.audioStreamInfo_.samplingRate) { + for (auto rate : deviceInfo.GetDeviceStreamInfo().samplingRate) { rates[iter] = static_cast(rate); iter++; } @@ -268,7 +269,7 @@ void Convert2CDeviceDescriptor(CDeviceDescriptor* device, const AudioDeviceDescr device->encodingTypes.hasValue = true; device->encodingTypes.arr.size = static_cast(deviceSize); device->encodingTypes.arr.head = encodings; - encodings[iter] = static_cast(deviceInfo.audioStreamInfo_.encoding); + encodings[iter] = static_cast(deviceInfo.GetDeviceStreamInfo().encoding); } void Convert2CArrDeviceDescriptor(CArrDeviceDescriptor& devices, @@ -322,10 +323,7 @@ void ConvertAudioDeviceDescriptor2DeviceInfo( deviceInfo.volumeGroupId_ = audioDeviceDescriptor->volumeGroupId_; deviceInfo.networkId_ = audioDeviceDescriptor->networkId_; deviceInfo.displayName_ = audioDeviceDescriptor->displayName_; - deviceInfo.audioStreamInfo_.samplingRate = audioDeviceDescriptor->audioStreamInfo_.samplingRate; - deviceInfo.audioStreamInfo_.encoding = audioDeviceDescriptor->audioStreamInfo_.encoding; - deviceInfo.audioStreamInfo_.format = audioDeviceDescriptor->audioStreamInfo_.format; - deviceInfo.audioStreamInfo_.channels = audioDeviceDescriptor->audioStreamInfo_.channels; + deviceInfo.audioStreamInfo_ = audioDeviceDescriptor->audioStreamInfo_; } void FreeCDeviceDescriptor(CDeviceDescriptor& device) diff --git a/frameworks/js/napi/common/napi_param_utils.cpp b/frameworks/js/napi/common/napi_param_utils.cpp index f91e5addd3..75b056ffd7 100644 --- a/frameworks/js/napi/common/napi_param_utils.cpp +++ b/frameworks/js/napi/common/napi_param_utils.cpp @@ -327,10 +327,7 @@ void NapiParamUtils::ConvertDeviceInfoToAudioDeviceDescriptor( audioDeviceDescriptor->volumeGroupId_ = deviceInfo.volumeGroupId_; audioDeviceDescriptor->networkId_ = deviceInfo.networkId_; audioDeviceDescriptor->displayName_ = deviceInfo.displayName_; - audioDeviceDescriptor->audioStreamInfo_.samplingRate = deviceInfo.audioStreamInfo_.samplingRate; - audioDeviceDescriptor->audioStreamInfo_.encoding = deviceInfo.audioStreamInfo_.encoding; - audioDeviceDescriptor->audioStreamInfo_.format = deviceInfo.audioStreamInfo_.format; - audioDeviceDescriptor->audioStreamInfo_.channels = deviceInfo.audioStreamInfo_.channels; + audioDeviceDescriptor->audioStreamInfo_ = deviceInfo.audioStreamInfo_; } napi_status NapiParamUtils::GetRendererOptions(const napi_env &env, AudioRendererOptions *opts, napi_value in) @@ -505,10 +502,10 @@ napi_status NapiParamUtils::SetDeviceDescriptor(const napi_env &env, const Audio napi_value value = nullptr; napi_value sampleRates; - size_t size = deviceInfo.audioStreamInfo_.samplingRate.size(); + size_t size = deviceInfo.GetDeviceStreamInfo().samplingRate.size(); napi_create_array_with_length(env, size, &sampleRates); size_t count = 0; - for (const auto &samplingRate : deviceInfo.audioStreamInfo_.samplingRate) { + for (const auto &samplingRate : deviceInfo.GetDeviceStreamInfo().samplingRate) { napi_create_int32(env, samplingRate, &value); napi_set_element(env, sampleRates, count, value); count++; @@ -516,10 +513,11 @@ napi_status NapiParamUtils::SetDeviceDescriptor(const napi_env &env, const Audio napi_set_named_property(env, result, "sampleRates", sampleRates); napi_value channelCounts; - size = deviceInfo.audioStreamInfo_.channels.size(); + std::set channelSet = deviceInfo.GetDeviceStreamInfo().GetChannels(); + size = channelSet.size(); napi_create_array_with_length(env, size, &channelCounts); count = 0; - for (const auto &channels : deviceInfo.audioStreamInfo_.channels) { + for (const auto &channels : channelSet) { napi_create_int32(env, channels, &value); napi_set_element(env, channelCounts, count, value); count++; @@ -535,7 +533,7 @@ napi_status NapiParamUtils::SetDeviceDescriptor(const napi_env &env, const Audio SetValueInt32Element(env, "channelIndexMasks", channelIndexMasks_, result); std::vector encoding; - encoding.push_back(deviceInfo.audioStreamInfo_.encoding); + encoding.push_back(deviceInfo.GetDeviceStreamInfo().encoding); SetValueInt32Element(env, "encodingTypes", encoding, result); SetValueBoolean(env, "spatializationSupported", deviceInfo.spatializationSupported_, result); return napi_ok; diff --git a/frameworks/native/audiopolicy/test/unittest/manager_test/src/audio_manager_unit_test.cpp b/frameworks/native/audiopolicy/test/unittest/manager_test/src/audio_manager_unit_test.cpp index a799420a89..8296db1ba4 100644 --- a/frameworks/native/audiopolicy/test/unittest/manager_test/src/audio_manager_unit_test.cpp +++ b/frameworks/native/audiopolicy/test/unittest/manager_test/src/audio_manager_unit_test.cpp @@ -83,9 +83,11 @@ HWTEST(AudioManagerUnitTest, GetConnectedDevicesList_002, TestSize.Level1) EXPECT_EQ(inputDevice->deviceRole_, DeviceRole::INPUT_DEVICE); EXPECT_EQ(inputDevice->deviceType_, DeviceType::DEVICE_TYPE_MIC); EXPECT_GE(inputDevice->deviceId_, MIN_DEVICE_ID); - EXPECT_THAT(inputDevice->audioStreamInfo_.samplingRate, Each(AllOf(Le(SAMPLE_RATE_96000), Ge(SAMPLE_RATE_8000)))); - EXPECT_EQ(inputDevice->audioStreamInfo_.encoding, AudioEncodingType::ENCODING_PCM); - EXPECT_THAT(inputDevice->audioStreamInfo_.channels, Each(AllOf(Le(CHANNEL_8), Ge(MONO)))); + auto audioStreamInfo = inputDevice->GetDeviceStreamInfo(); + EXPECT_THAT(audioStreamInfo.samplingRate, Each(AllOf(Le(SAMPLE_RATE_96000), Ge(SAMPLE_RATE_8000)))); + EXPECT_EQ(audioStreamInfo.encoding, AudioEncodingType::ENCODING_PCM); + std::set channels = audioStreamInfo.GetChannels(); + EXPECT_THAT(channels, Each(AllOf(Le(CHANNEL_8), Ge(MONO)))); } /** @@ -115,10 +117,11 @@ HWTEST(AudioManagerUnitTest, GetConnectedDevicesList_003, TestSize.Level1) continue; } EXPECT_GE(outputDevice->deviceId_, MIN_DEVICE_ID); - EXPECT_THAT(outputDevice->audioStreamInfo_.samplingRate, Each(AllOf(Le(SAMPLE_RATE_96000), - Ge(SAMPLE_RATE_8000)))); - EXPECT_EQ(outputDevice->audioStreamInfo_.encoding, AudioEncodingType::ENCODING_PCM); - EXPECT_THAT(outputDevice->audioStreamInfo_.channels, Each(AllOf(Le(CHANNEL_8), Ge(MONO)))); + auto audioStreamInfo = outputDevice->GetDeviceStreamInfo(); + EXPECT_THAT(audioStreamInfo.samplingRate, Each(AllOf(Le(SAMPLE_RATE_96000), Ge(SAMPLE_RATE_8000)))); + EXPECT_EQ(audioStreamInfo.encoding, AudioEncodingType::ENCODING_PCM); + std::set channels = audioStreamInfo.GetChannels(); + EXPECT_THAT(channels, Each(AllOf(Le(CHANNEL_8), Ge(MONO)))); } } @@ -2037,12 +2040,13 @@ HWTEST(AudioManagerUnitTest, SetDeviceAbsVolumeSupported_001, TestSize.Level1) continue; } EXPECT_GE(outputDevice->deviceId_, MIN_DEVICE_ID); - EXPECT_THAT(outputDevice->audioStreamInfo_.samplingRate, Each(AllOf(Le(SAMPLE_RATE_96000), - Ge(SAMPLE_RATE_8000)))); - EXPECT_EQ(outputDevice->audioStreamInfo_.encoding, AudioEncodingType::ENCODING_PCM); - EXPECT_THAT(outputDevice->audioStreamInfo_.channels, Each(AllOf(Le(CHANNEL_8), Ge(MONO)))); - EXPECT_EQ(true, (outputDevice->audioStreamInfo_.format >= SAMPLE_U8) - && ((outputDevice->audioStreamInfo_.format <= SAMPLE_F32LE))); + DeviceStreamInfo audioStreamInfo = outputDevice->GetDeviceStreamInfo(); + EXPECT_THAT(audioStreamInfo.samplingRate, Each(AllOf(Le(SAMPLE_RATE_96000), Ge(SAMPLE_RATE_8000)))); + EXPECT_EQ(audioStreamInfo.encoding, AudioEncodingType::ENCODING_PCM); + std::set channels = audioStreamInfo.GetChannels(); + EXPECT_THAT(channels, Each(AllOf(Le(CHANNEL_8), Ge(MONO)))); + + EXPECT_EQ(true, (audioStreamInfo.format >= SAMPLE_U8) && ((audioStreamInfo.format <= SAMPLE_F32LE))); if ((outputDevice->macAddress_).c_str()!= nullptr) { ret = AudioSystemManager::GetInstance()->SetDeviceAbsVolumeSupported(outputDevice->macAddress_, support); EXPECT_EQ(SUCCESS, ret); diff --git a/frameworks/native/audiopolicy/test/unittest/stream_manager_test/src/audio_stream_manager_unit_test.cpp b/frameworks/native/audiopolicy/test/unittest/stream_manager_test/src/audio_stream_manager_unit_test.cpp index 7c8a5386ba..253786976e 100644 --- a/frameworks/native/audiopolicy/test/unittest/stream_manager_test/src/audio_stream_manager_unit_test.cpp +++ b/frameworks/native/audiopolicy/test/unittest/stream_manager_test/src/audio_stream_manager_unit_test.cpp @@ -582,14 +582,12 @@ HWTEST_F(AudioStreamManagerUnitTest, Audio_Stream_Change_Listner_GetCurrentRende EXPECT_EQ(audioRendererChangeInfos[0]->outputDeviceInfo.deviceRole_, DeviceRole::OUTPUT_DEVICE); EXPECT_EQ(audioRendererChangeInfos[0]->outputDeviceInfo.deviceType_, DeviceType::DEVICE_TYPE_SPEAKER); EXPECT_GE(audioRendererChangeInfos[0]->outputDeviceInfo.deviceId_, MIN_DEVICE_ID); - EXPECT_EQ(true, (*audioRendererChangeInfos[0]->outputDeviceInfo.audioStreamInfo_.samplingRate.rbegin() - >= SAMPLE_RATE_8000) || - ((*audioRendererChangeInfos[0]->outputDeviceInfo.audioStreamInfo_.samplingRate.begin() - <= SAMPLE_RATE_96000))); - EXPECT_EQ(audioRendererChangeInfos[0]->outputDeviceInfo.audioStreamInfo_.encoding, - AudioEncodingType::ENCODING_PCM); - EXPECT_EQ(true, (*audioRendererChangeInfos[0]->outputDeviceInfo.audioStreamInfo_.channels.rbegin() >= MONO) - && ((*audioRendererChangeInfos[0]->outputDeviceInfo.audioStreamInfo_.channels.begin() <= CHANNEL_8))); + DeviceStreamInfo audioStreamInfo = audioRendererChangeInfos[0]->outputDeviceInfo.GetDeviceStreamInfo(); + EXPECT_EQ(true, (*audioStreamInfo.samplingRate.rbegin() >= SAMPLE_RATE_8000) || + ((*audioStreamInfo.samplingRate.begin() <= SAMPLE_RATE_96000))); + EXPECT_EQ(audioStreamInfo.encoding, AudioEncodingType::ENCODING_PCM); + std::set channels = audioStreamInfo.GetChannels(); + EXPECT_EQ(true, (*channels.rbegin() >= MONO) && (*channels.begin() <= CHANNEL_8)); audioRendererChangeInfos.clear(); } @@ -1290,13 +1288,13 @@ HWTEST_F(AudioStreamManagerUnitTest, AudioStreamChangeListnerGetCurrentCapturerC EXPECT_EQ(audioCapturerChangeInfos[0]->inputDeviceInfo.deviceRole_, DeviceRole::INPUT_DEVICE); EXPECT_EQ(audioCapturerChangeInfos[0]->inputDeviceInfo.deviceType_, DeviceType::DEVICE_TYPE_MIC); EXPECT_GE(audioCapturerChangeInfos[0]->inputDeviceInfo.deviceId_, MIN_DEVICE_ID); + DeviceStreamInfo audioStreamInfo = audioCapturerChangeInfos[0]->inputDeviceInfo.GetDeviceStreamInfo(); EXPECT_EQ(true, - (*audioCapturerChangeInfos[0]->inputDeviceInfo.audioStreamInfo_.samplingRate.rbegin() >= SAMPLE_RATE_8000) - || ((*audioCapturerChangeInfos[0]->inputDeviceInfo.audioStreamInfo_.samplingRate.begin() - <= SAMPLE_RATE_96000))); - EXPECT_EQ(audioCapturerChangeInfos[0]->inputDeviceInfo.audioStreamInfo_.encoding, AudioEncodingType::ENCODING_PCM); - EXPECT_EQ(true, (*audioCapturerChangeInfos[0]->inputDeviceInfo.audioStreamInfo_.channels.rbegin() >= MONO) - && ((*audioCapturerChangeInfos[0]->inputDeviceInfo.audioStreamInfo_.channels.begin() <= CHANNEL_8))); + (*audioStreamInfo.samplingRate.rbegin() >= SAMPLE_RATE_8000) + || ((*audioStreamInfo.samplingRate.begin() <= SAMPLE_RATE_96000))); + EXPECT_EQ(audioStreamInfo.encoding, AudioEncodingType::ENCODING_PCM); + std::set channels = audioStreamInfo.GetChannels(); + EXPECT_EQ(true, (*channels.rbegin() >= MONO) && (*channels.begin() <= CHANNEL_8)); bool isStopped = audioCapturer->Stop(); EXPECT_EQ(true, isStopped); diff --git a/frameworks/native/audioutils/include/audio_utils.h b/frameworks/native/audioutils/include/audio_utils.h index 5dc07bf3bc..6095ece057 100644 --- a/frameworks/native/audioutils/include/audio_utils.h +++ b/frameworks/native/audioutils/include/audio_utils.h @@ -562,6 +562,7 @@ enum HdiRenderOffset : uint32_t { HDI_RENDER_OFFSET_USB = 11, HDI_RENDER_OFFSET_VOIP_FAST = 12, HDI_RENDER_OFFSET_EAC3 = 13, + HDI_RENDER_OFFSET_REMOTE_OFFLOAD = 14, }; uint32_t GenerateUniqueID(AudioHdiUniqueIDBase base, uint32_t offset); diff --git a/frameworks/native/hdiadapter_new/BUILD.gn b/frameworks/native/hdiadapter_new/BUILD.gn index d3f4ced217..7bc564b570 100644 --- a/frameworks/native/hdiadapter_new/BUILD.gn +++ b/frameworks/native/hdiadapter_new/BUILD.gn @@ -106,6 +106,7 @@ ohos_shared_library("hdiadapter_new") { "adapter/remote_device_manager.cpp", "sink/remote_audio_render_sink.cpp", "sink/remote_fast_audio_render_sink.cpp", + "sink/remote_offload_audio_render_sink.cpp", "source/remote_audio_capture_source.cpp", "source/remote_fast_audio_capture_source.cpp", ] @@ -185,6 +186,7 @@ ohos_unittest("hdiadapter_unit_test") { "test/unittest/sink/offload_audio_render_sink_unit_test.cpp", "test/unittest/sink/remote_audio_render_sink_unit_test.cpp", "test/unittest/sink/remote_fast_audio_render_sink_unit_test.cpp", + "test/unittest/sink/remote_offload_audio_render_sink_unit_test.cpp", "test/unittest/source/audio_capture_source_unit_test.cpp", "test/unittest/source/bluetooth_audio_capture_source_unit_test.cpp", "test/unittest/source/fast_audio_capture_source_unit_test.cpp", diff --git a/frameworks/native/hdiadapter_new/include/common/hdi_adapter_info.h b/frameworks/native/hdiadapter_new/include/common/hdi_adapter_info.h index 84a21f1595..0ba3ef7086 100644 --- a/frameworks/native/hdiadapter_new/include/common/hdi_adapter_info.h +++ b/frameworks/native/hdiadapter_new/include/common/hdi_adapter_info.h @@ -30,6 +30,7 @@ enum HdiIdType : uint32_t { HDI_ID_TYPE_FAST, HDI_ID_TYPE_REMOTE, HDI_ID_TYPE_REMOTE_FAST, + HDI_ID_TYPE_REMOTE_OFFLOAD, HDI_ID_TYPE_FILE, HDI_ID_TYPE_BLUETOOTH, HDI_ID_TYPE_OFFLOAD, diff --git a/frameworks/native/hdiadapter_new/include/manager/hdi_adapter_factory.h b/frameworks/native/hdiadapter_new/include/manager/hdi_adapter_factory.h index 4f933b15c3..15db4defbd 100644 --- a/frameworks/native/hdiadapter_new/include/manager/hdi_adapter_factory.h +++ b/frameworks/native/hdiadapter_new/include/manager/hdi_adapter_factory.h @@ -45,6 +45,7 @@ private: #ifdef FEATURE_DISTRIBUTE_AUDIO std::shared_ptr CreateRemoteRenderSink(const std::string &info); std::shared_ptr CreateRemoteFastRenderSink(const std::string &info); + std::shared_ptr CreateRemoteOffloadRenderSink(const std::string &info); #endif std::shared_ptr CreatePrimaryCaptureSource(const uint32_t captureId, const std::string &info); #ifdef FEATURE_DISTRIBUTE_AUDIO diff --git a/frameworks/native/hdiadapter_new/include/sink/remote_offload_audio_render_sink.h b/frameworks/native/hdiadapter_new/include/sink/remote_offload_audio_render_sink.h new file mode 100644 index 0000000000..8e158d7872 --- /dev/null +++ b/frameworks/native/hdiadapter_new/include/sink/remote_offload_audio_render_sink.h @@ -0,0 +1,197 @@ +/* + * 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 REMOTE_OFFLOAD_AUDIO_RENDER_SINK_H +#define REMOTE_OFFLOAD_AUDIO_RENDER_SINK_H + +#include "sink/i_audio_render_sink.h" +#include +#include +#include +#include "audio_utils.h" +#include "adapter/i_device_manager.h" +#include "util/audio_running_lock.h" +#include "util/callback_wrapper.h" + +namespace OHOS { +namespace AudioStandard { +typedef OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioCallback RemoteIAudioCallback; +typedef OHOS::HDI::DistributedAudio::Audio::V1_0::AudioExtParamKey RemoteAudioExtParamKey; +typedef OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioRender RemoteIAudioRender; +typedef OHOS::HDI::DistributedAudio::Audio::V1_0::AudioFormat RemoteAudioFormat; +typedef OHOS::HDI::DistributedAudio::Audio::V1_0::AudioSampleAttributes RemoteAudioSampleAttributes; +typedef OHOS::HDI::DistributedAudio::Audio::V1_0::AudioDeviceDescriptor RemoteAudioDeviceDescriptor; +typedef OHOS::HDI::DistributedAudio::Audio::V1_0::AudioCallbackType RemoteAudioCallbackType; + +class RemoteOffloadAudioRenderSink; + +class RemoteOffloadHdiCallbackImpl final : public RemoteIAudioCallback { +public: + RemoteOffloadHdiCallbackImpl(RemoteOffloadAudioRenderSink *sink); + ~RemoteOffloadHdiCallbackImpl() override {} + + int32_t RenderCallback(RemoteAudioCallbackType type, int8_t &reserved, int8_t &cookie) override; + int32_t ParamCallback(RemoteAudioExtParamKey key, const std::string &condition, const std::string &value, + int8_t &reserved, int8_t cookie) override; + +private: + RemoteOffloadAudioRenderSink *sink_ = nullptr; +}; + +struct RemoteOffloadHdiCallback { + sptr callback_; + std::function serviceCallback_; +}; + +class RemoteOffloadAudioRenderSink : public IAudioRenderSink, public IDeviceManagerCallback { + friend class RemoteOffloadHdiCallbackImpl; +public: + explicit RemoteOffloadAudioRenderSink(const std::string &deviceNetworkId); + ~RemoteOffloadAudioRenderSink(); + + int32_t Init(const IAudioSinkAttr &attr) override; + void DeInit(void) override; + bool IsInited(void) override; + + int32_t Start(void) override; + int32_t Stop(void) override; + int32_t Resume(void) override; + int32_t Pause(void) override; + int32_t Flush(void) override; + int32_t Reset(void) override; + int32_t RenderFrame(char &data, uint64_t len, uint64_t &writeLen) override; + int64_t GetVolumeDataCount(void) override; + + int32_t SuspendRenderSink(void) override; + int32_t RestoreRenderSink(void) override; + + void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override; + std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override; + + int32_t SetVolume(float left, float right) override; + int32_t GetVolume(float &left, float &right) override; + + int32_t GetLatency(uint32_t &latency) override; + int32_t GetTransactionId(uint64_t &transactionId) override; + int32_t GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec) override; + float GetMaxAmplitude(void) override; + void SetAudioMonoState(bool audioMono) override; + void SetAudioBalanceValue(float audioBalance) override; + int32_t SetSinkMuteForSwitchDevice(bool mute) final; + + int32_t SetAudioScene(AudioScene audioScene, std::vector &activeDevices, + bool scoExcludeFlag = false) override; + int32_t GetAudioScene(void) override; + + int32_t UpdateActiveDevice(std::vector &outputDevices) override; + void RegistCallback(uint32_t type, IAudioSinkCallback *callback) override; + void ResetActiveDeviceForDisconnect(DeviceType device) override; + + int32_t SetPaPower(int32_t flag) override; + int32_t SetPriPaPower(void) override; + + int32_t UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size) final; + int32_t UpdateAppsUid(const std::vector &appsUid) final; + + int32_t Drain(AudioDrainType type) override; + void RegistOffloadHdiCallback(std::function callback) override; + int32_t SetBufferSize(uint32_t sizeMs) override; + int32_t SetOffloadRenderCallbackType(RenderCallbackType type) override; + int32_t LockOffloadRunningLock(void) override; + int32_t UnLockOffloadRunningLock(void) override; + + void DumpInfo(std::string &dumpString) override; + + void OnAudioParamChange(const std::string &adapterName, const AudioParamKey key, const std::string &condition, + const std::string &value) override; + +private: + static uint32_t PcmFormatToBit(AudioSampleFormat format); + static RemoteAudioFormat ConvertToHdiFormat(AudioSampleFormat format); + void InitAudioSampleAttr(RemoteAudioSampleAttributes ¶m); + void InitDeviceDesc(RemoteAudioDeviceDescriptor &deviceDesc); + int32_t CreateRender(void); + void InitLatencyMeasurement(void); + void DeInitLatencyMeasurement(void); + void CheckLatencySignal(uint8_t *data, size_t len); + void AdjustStereoToMono(char *data, uint64_t len); + void AdjustAudioBalance(char *data, uint64_t len); + void CheckUpdateState(char *data, uint64_t len); + int32_t SetVolumeInner(float left, float right); + void UpdateSinkState(bool started); + +private: + static constexpr uint32_t AUDIO_CHANNELCOUNT = 2; + static constexpr uint32_t AUDIO_SAMPLE_RATE_48K = 48000; + static constexpr uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 4096; + static constexpr uint32_t STEREO_CHANNEL_COUNT = 2; + static constexpr float DEFAULT_VOLUME_LEVEL = 1.0f; + static constexpr uint16_t GET_MAX_AMPLITUDE_FRAMES_THRESHOLD = 10; + static constexpr int32_t HALF_FACTOR = 2; + static constexpr size_t OFFLOAD_DFX_SPLIT = 2; +#ifdef FEATURE_POWER_MANAGER + static constexpr const char *RUNNING_LOCK_NAME = "AudioRemoteOffloadBackgroundPlay"; + static constexpr int32_t RUNNING_LOCK_TIMEOUTMS_LASTING = -1; +#endif + + const std::string deviceNetworkId_ = ""; + IAudioSinkAttr attr_ = {}; + SinkCallbackWrapper callback_ = {}; + struct RemoteOffloadHdiCallback hdiCallback_ = {}; + std::atomic sinkInited_ = false; + std::atomic renderInited_ = false; + std::atomic started_ = false; + std::atomic paused_ = false; + std::atomic isFlushing_ = false; + bool isNeedRestart_ = false; + float leftVolume_ = DEFAULT_VOLUME_LEVEL; + float rightVolume_ = DEFAULT_VOLUME_LEVEL; + uint32_t hdiRenderId_ = 0; + sptr audioRender_ = nullptr; + bool audioMonoState_ = false; + bool audioBalanceState_ = false; + float leftBalanceCoef_ = 1.0f; + float rightBalanceCoef_ = 1.0f; + // for signal detect + std::shared_ptr signalDetectAgent_ = nullptr; + bool signalDetected_ = false; + size_t signalDetectedTime_ = 0; + // for get amplitude + float maxAmplitude_ = 0; + int64_t lastGetMaxAmplitudeTime_ = 0; + int64_t last10FrameStartTime_ = 0; + bool startUpdate_ = false; + int renderFrameNum_ = 0; + // for device switch + std::mutex switchDeviceMutex_; + int32_t muteCount_ = 0; + std::atomic switchDeviceMute_ = false; + // for dfx log + std::string logUtilsTag_ = "RemoteOffloadSink"; + mutable int64_t volumeDataCount_ = 0; +#ifdef FEATURE_POWER_MANAGER + std::shared_ptr runningLock_; + bool runningLocked_ = false; +#endif + FILE *dumpFile_ = nullptr; + std::string dumpFileName_ = ""; + uint64_t renderPos_ = 0; + std::mutex sinkMutex_; +}; + +} // namespace AudioStandard +} // namespace OHOS + +#endif // REMOTE_OFFLOAD_AUDIO_RENDER_SINK_H diff --git a/frameworks/native/hdiadapter_new/manager/hdi_adapter_factory.cpp b/frameworks/native/hdiadapter_new/manager/hdi_adapter_factory.cpp index 8710c9907b..b3ce9f0ea5 100644 --- a/frameworks/native/hdiadapter_new/manager/hdi_adapter_factory.cpp +++ b/frameworks/native/hdiadapter_new/manager/hdi_adapter_factory.cpp @@ -41,6 +41,7 @@ #ifdef FEATURE_DISTRIBUTE_AUDIO #include "sink/remote_audio_render_sink.h" #include "sink/remote_fast_audio_render_sink.h" +#include "sink/remote_offload_audio_render_sink.h" #include "source/remote_audio_capture_source.h" #include "source/remote_fast_audio_capture_source.h" #include "adapter/remote_device_manager.h" @@ -92,6 +93,9 @@ std::shared_ptr HdiAdapterFactory::CreateRenderSink(uint32_t r case HDI_ID_TYPE_REMOTE_FAST: sink = CreateRemoteFastRenderSink(info); break; + case HDI_ID_TYPE_REMOTE_OFFLOAD: + sink = CreateRemoteOffloadRenderSink(info); + break; #endif default: AUDIO_ERR_LOG("invalid type"); @@ -192,6 +196,12 @@ std::shared_ptr HdiAdapterFactory::CreateRemoteFastRenderSink( CHECK_AND_RETURN_RET_LOG(!info.empty(), nullptr, "deviceNetworkId is nullptr"); return std::make_shared(info); } + +std::shared_ptr HdiAdapterFactory::CreateRemoteOffloadRenderSink(const std::string &info) +{ + CHECK_AND_RETURN_RET_LOG(!info.empty(), nullptr, "deviceNetworkId is nullptr"); + return std::make_shared(info); +} #endif std::shared_ptr HdiAdapterFactory::CreatePrimaryCaptureSource(const uint32_t captureId, diff --git a/frameworks/native/hdiadapter_new/sink/remote_offload_audio_render_sink.cpp b/frameworks/native/hdiadapter_new/sink/remote_offload_audio_render_sink.cpp new file mode 100644 index 0000000000..1d9fd3c3ed --- /dev/null +++ b/frameworks/native/hdiadapter_new/sink/remote_offload_audio_render_sink.cpp @@ -0,0 +1,842 @@ +/* + * 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 LOG_TAG +#define LOG_TAG "RemoteOffloadAudioRenderSink" +#endif + +#include "sink/remote_offload_audio_render_sink.h" +#include +#include +#include "audio_hdi_log.h" +#include "audio_errors.h" +#include "audio_dump_pcm.h" +#include "volume_tools.h" +#include "media_monitor_manager.h" +#include "common/hdi_adapter_info.h" +#include "manager/hdi_adapter_manager.h" + +using namespace OHOS::HDI::DistributedAudio::Audio::V1_0; + +namespace OHOS { +namespace AudioStandard { +RemoteOffloadHdiCallbackImpl::RemoteOffloadHdiCallbackImpl(RemoteOffloadAudioRenderSink *sink) + : sink_(sink) +{ +} + +int32_t RemoteOffloadHdiCallbackImpl::RenderCallback(AudioCallbackType type, int8_t &reserved, int8_t &cookie) +{ + (void)reserved; + (void)cookie; + CHECK_AND_RETURN_RET_LOG(sink_ != nullptr, ERR_OPERATION_FAILED, "sink is nullptr"); + if (!sink_->started_.load() || sink_->isFlushing_.load()) { + AUDIO_DEBUG_LOG("invalid call, started: %{public}d, isFlushing: %{public}d", sink_->started_.load(), + sink_->isFlushing_.load()); + return SUCCESS; + } + sink_->hdiCallback_.serviceCallback_(static_cast(type)); + return SUCCESS; +} + +int32_t RemoteOffloadHdiCallbackImpl::ParamCallback(AudioExtParamKey key, const std::string &condition, + const std::string &value, int8_t &reserved, int8_t cookie) +{ + (void)key; + (void)condition; + (void)value; + (void)reserved; + (void)cookie; + return SUCCESS; +} + +RemoteOffloadAudioRenderSink::RemoteOffloadAudioRenderSink(const std::string &deviceNetworkId) + : deviceNetworkId_(deviceNetworkId) +{ + AUDIO_DEBUG_LOG("construction"); +} + +RemoteOffloadAudioRenderSink::~RemoteOffloadAudioRenderSink() +{ + if (sinkInited_.load()) { + DeInit(); + } + AUDIO_INFO_LOG("volumeDataCount: %{public}" PRId64, volumeDataCount_); +} + +int32_t RemoteOffloadAudioRenderSink::Init(const IAudioSinkAttr &attr) +{ + AUDIO_INFO_LOG("in"); + std::lock_guard lock(sinkMutex_); + Trace trace("RemoteOffloadAudioRenderSink::Init"); + attr_ = attr; + int32_t ret = CreateRender(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create render fail"); + + renderInited_.store(true); + sinkInited_.store(true); + return SUCCESS; +} + +void RemoteOffloadAudioRenderSink::DeInit(void) +{ + AUDIO_INFO_LOG("in"); + Trace trace("RemoteOffloadAudioRenderSink::DeInit"); + std::lock_guard lock(sinkMutex_); + std::lock_guard switchDeviceLock(switchDeviceMutex_); + sinkInited_.store(false); + renderInited_.store(false); + started_.store(false); + HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); + std::shared_ptr deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE); + CHECK_AND_RETURN(deviceManager != nullptr); + deviceManager->DestroyRender(deviceNetworkId_, hdiRenderId_); + deviceManager->UnRegistRenderSinkCallback(deviceNetworkId_, hdiRenderId_); + audioRender_.ForceSetRefPtr(nullptr); + hdiCallback_ = {}; + muteCount_ = 0; + switchDeviceMute_ = false; + DumpFileUtil::CloseDumpFile(&dumpFile_); +} + +bool RemoteOffloadAudioRenderSink::IsInited(void) +{ + return sinkInited_.load(); +} + +int32_t RemoteOffloadAudioRenderSink::Start(void) +{ + std::lock_guard lock(sinkMutex_); + AUDIO_INFO_LOG("in"); + Trace trace("RemoteOffloadAudioRenderSink::Start"); + if (!renderInited_.load()) { + int32_t ret = CreateRender(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create render fail"); + renderInited_.store(true); + } + InitLatencyMeasurement(); + + if (started_.load()) { + if (isFlushing_.load()) { + isNeedRestart_ = true; + AUDIO_ERR_LOG("start fail, will restart after flush"); + return ERR_OPERATION_FAILED; + } + return SUCCESS; + } + AudioXCollie audioXCollie("RemoteOffloadAudioRenderSink::Start", TIMEOUT_SECONDS_10, + nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY); + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + int32_t ret = audioRender_->Start(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "start fail, ret: %{public}d", ret); + UpdateSinkState(true); + dumpFileName_ = "remote_offload_sink_" + GetTime() + "_" + std::to_string(attr_.sampleRate) + "_" + + std::to_string(attr_.channel) + "_" + std::to_string(attr_.format) + ".pcm"; + DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpFile_); + + started_.store(true); + renderPos_ = 0; + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::Stop(void) +{ + std::lock_guard lock(sinkMutex_); + AUDIO_INFO_LOG("in"); + Trace trace("RemoteOffloadAudioRenderSink::Stop"); + DeInitLatencyMeasurement(); + + if (!started_.load()) { + UnLockOffloadRunningLock(); + return SUCCESS; + } + int32_t ret = Flush(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "flush fail"); + AudioXCollie audioXCollie("RemoteOffloadAudioRenderSink::Stop", TIMEOUT_SECONDS_10, + nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY); + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + ret = audioRender_->Stop(); + UpdateSinkState(false); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "stop fail"); + started_.store(false); + + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::Resume(void) +{ + std::lock_guard lock(sinkMutex_); + AUDIO_INFO_LOG("in"); + CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state"); + + if (!paused_.load()) { + AUDIO_INFO_LOG("already resumed"); + return SUCCESS; + } + + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + int32_t ret = audioRender_->Resume(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "resume fail, ret: %{public}d", ret); + paused_.store(false); + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::Pause(void) +{ + std::lock_guard lock(sinkMutex_); + AUDIO_INFO_LOG("in"); + CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state"); + + if (paused_.load()) { + AUDIO_INFO_LOG("already paused"); + return SUCCESS; + } + + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + int32_t ret = audioRender_->Pause(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "pause fail, ret: %{public}d", ret); + paused_.store(true); + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::Flush(void) +{ + Trace trace("RemoteOffloadAudioRenderSink::Flush"); + CHECK_AND_RETURN_RET_LOG(!isFlushing_.load(), ERR_OPERATION_FAILED, "duplicate flush"); + CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_OPERATION_FAILED, "not start, invalid state"); + + isFlushing_.store(true); + std::thread([&] { + auto future = async(std::launch::async, [&] { + std::lock_guard lock(sinkMutex_); + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + return audioRender_->Flush(); + }); + if (future.wait_for(std::chrono::milliseconds(250)) == std::future_status::timeout) { // 250: max wait 250ms + AUDIO_ERR_LOG("flush fail, timeout of 250ms"); + } else { + int32_t ret = future.get(); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("flush fail, ret: %{public}d", ret); + } + } + isFlushing_.store(false); + if (isNeedRestart_) { + isNeedRestart_ = false; + Start(); + } + }).detach(); + renderPos_ = 0; + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::Reset(void) +{ + std::lock_guard lock(sinkMutex_); + Trace trace("RemoteOffloadAudioRenderSink::Reset"); + CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_OPERATION_FAILED, "not start, invalid state"); + + isNeedRestart_ = true; + int32_t ret = Flush(); + if (ret != SUCCESS) { + isNeedRestart_ = false; + AUDIO_ERR_LOG("reset fail"); + return ERR_OPERATION_FAILED; + } + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen) +{ + int64_t stamp = ClockTime::GetCurNano(); + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_OPERATION_FAILED, "not start, invalid state"); + CHECK_AND_RETURN_RET_LOG(!isFlushing_.load(), ERR_OPERATION_FAILED, "during flushing"); + + if (audioMonoState_) { + AdjustStereoToMono(&data, len); + } + if (audioBalanceState_) { + AdjustAudioBalance(&data, len); + } + Trace trace("RemoteOffloadAudioRenderSink::RenderFrame"); + CheckLatencySignal(reinterpret_cast(&data), len); + std::vector bufferVec(len); + int32_t ret = memcpy_s(bufferVec.data(), len, &data, len); + CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "copy fail, error code: %{public}d", ret); + + ret = audioRender_->RenderFrame(bufferVec, writeLen); +#ifdef FEATURE_POWER_MANAGER + if (runningLock_) { + runningLock_->UpdateAppsUidToPowerMgr(); + } +#endif + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_WRITE_FAILED, "fail, ret: %{public}x", ret); + if (writeLen != 0) { + BufferDesc buffer = { reinterpret_cast(&data), len, len }; + AudioStreamInfo streamInfo(static_cast(attr_.sampleRate), AudioEncodingType::ENCODING_PCM, + static_cast(attr_.format), static_cast(attr_.channel)); + VolumeTools::DfxOperation(buffer, streamInfo, logUtilsTag_, volumeDataCount_, OFFLOAD_DFX_SPLIT); + if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) { + DumpFileUtil::WriteDumpFile(dumpFile_, static_cast(&data), writeLen); + AudioCacheMgr::GetInstance().CacheData(dumpFileName_, static_cast(&data), writeLen); + } + CheckUpdateState(&data, len); + } + renderPos_ += writeLen; + stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND; + int64_t stampThresholdMs = 50; // 50ms + if (stamp >= stampThresholdMs) { + AUDIO_WARNING_LOG("len: [%{public}" PRIu64 "], cost: [%{public}" PRId64 "]ms", len, stamp); + } + return SUCCESS; +} + +int64_t RemoteOffloadAudioRenderSink::GetVolumeDataCount(void) +{ + return volumeDataCount_; +} + +int32_t RemoteOffloadAudioRenderSink::SuspendRenderSink(void) +{ + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::RestoreRenderSink(void) +{ + return SUCCESS; +} + +void RemoteOffloadAudioRenderSink::SetAudioParameter(const AudioParamKey key, const std::string &condition, + const std::string &value) +{ +} + +std::string RemoteOffloadAudioRenderSink::GetAudioParameter(const AudioParamKey key, const std::string &condition) +{ + return ""; +} + +int32_t RemoteOffloadAudioRenderSink::SetVolume(float left, float right) +{ + std::lock_guard lock(switchDeviceMutex_); + Trace trace("RemoteOffloadAudioRenderSink::SetVolume"); + + leftVolume_ = left; + rightVolume_ = right; + + if (switchDeviceMute_) { + AUDIO_WARNING_LOG("mute for switch device, store volume, left: %{public}f, right: %{public}f", left, right); + return SUCCESS; + } + return SetVolumeInner(left, right); +} + +int32_t RemoteOffloadAudioRenderSink::GetVolume(float &left, float &right) +{ + left = leftVolume_; + right = rightVolume_; + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::GetLatency(uint32_t &latency) +{ + Trace trace("RemoteOffloadAudioRenderSink::GetLatency"); + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + + uint32_t hdiLatency; + int32_t ret = audioRender_->GetLatency(hdiLatency); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get latency fail, ret: %{public}d", ret); + latency = hdiLatency; + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::GetTransactionId(uint64_t &transactionId) +{ + AUDIO_INFO_LOG("not support"); + return ERR_NOT_SUPPORTED; +} + +int32_t RemoteOffloadAudioRenderSink::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec) +{ + AUDIO_INFO_LOG("not support"); + return ERR_NOT_SUPPORTED; +} + +float RemoteOffloadAudioRenderSink::GetMaxAmplitude(void) +{ + lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano(); + startUpdate_ = true; + return maxAmplitude_; +} + +void RemoteOffloadAudioRenderSink::SetAudioMonoState(bool audioMono) +{ + audioMonoState_ = audioMono; +} + +void RemoteOffloadAudioRenderSink::SetAudioBalanceValue(float audioBalance) +{ + // reset the balance coefficient value firstly + leftBalanceCoef_ = 1.0f; + rightBalanceCoef_ = 1.0f; + + if (std::abs(audioBalance - 0.0f) <= std::numeric_limits::epsilon()) { + // audioBalance is equal to 0.0f + audioBalanceState_ = false; + } else { + // audioBalance is not equal to 0.0f + audioBalanceState_ = true; + // calculate the balance coefficient + if (audioBalance > 0.0f) { + leftBalanceCoef_ -= audioBalance; + } else if (audioBalance < 0.0f) { + rightBalanceCoef_ += audioBalance; + } + } +} + +int32_t RemoteOffloadAudioRenderSink::SetSinkMuteForSwitchDevice(bool mute) +{ + std::lock_guard lock(switchDeviceMutex_); + AUDIO_INFO_LOG("set offload mute %{public}d", mute); + + if (mute) { + muteCount_++; + if (switchDeviceMute_) { + AUDIO_INFO_LOG("offload already muted"); + return SUCCESS; + } + switchDeviceMute_ = true; + SetVolumeInner(0.0f, 0.0f); + } else { + muteCount_--; + if (muteCount_ > 0) { + AUDIO_WARNING_LOG("offload not all unmuted"); + return SUCCESS; + } + switchDeviceMute_ = false; + muteCount_ = 0; + SetVolumeInner(leftVolume_, rightVolume_); + } + + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::SetAudioScene(AudioScene audioScene, std::vector &activeDevices, + bool scoExcludeFlag) +{ + AUDIO_INFO_LOG("not support"); + return ERR_NOT_SUPPORTED; +} + +int32_t RemoteOffloadAudioRenderSink::GetAudioScene(void) +{ + AUDIO_INFO_LOG("not support"); + return ERR_NOT_SUPPORTED; +} + +int32_t RemoteOffloadAudioRenderSink::UpdateActiveDevice(std::vector &outputDevices) +{ + AUDIO_INFO_LOG("not support"); + return ERR_NOT_SUPPORTED; +} + +void RemoteOffloadAudioRenderSink::RegistCallback(uint32_t type, IAudioSinkCallback *callback) +{ + std::lock_guard lock(sinkMutex_); + callback_.RegistCallback(type, callback); + AUDIO_INFO_LOG("regist succ"); +} + +void RemoteOffloadAudioRenderSink::ResetActiveDeviceForDisconnect(DeviceType device) +{ + AUDIO_INFO_LOG("not support"); +} + +int32_t RemoteOffloadAudioRenderSink::SetPaPower(int32_t flag) +{ + AUDIO_INFO_LOG("not support"); + return ERR_NOT_SUPPORTED; +} + +int32_t RemoteOffloadAudioRenderSink::SetPriPaPower(void) +{ + AUDIO_INFO_LOG("not support"); + return ERR_NOT_SUPPORTED; +} + +int32_t RemoteOffloadAudioRenderSink::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size) +{ +#ifdef FEATURE_POWER_MANAGER + CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr"); + runningLock_->UpdateAppsUid(appsUid, appsUid + size); +#endif + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::UpdateAppsUid(const std::vector &appsUid) +{ +#ifdef FEATURE_POWER_MANAGER + CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr"); + runningLock_->UpdateAppsUid(appsUid.cbegin(), appsUid.cend()); +#endif + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::Drain(AudioDrainType type) +{ + Trace trace("RemoteOffloadAudioRenderSink::Drain"); + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + auto drainType = static_cast(type); + int32_t ret = audioRender_->DrainBuffer(drainType); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "drain fail"); + return SUCCESS; +} + +void RemoteOffloadAudioRenderSink::RegistOffloadHdiCallback(std::function callback) +{ + CHECK_AND_RETURN_LOG(hdiCallback_.serviceCallback_ == nullptr, "already registed"); + AUDIO_INFO_LOG("in"); + + hdiCallback_ = { + .callback_ = new RemoteOffloadHdiCallbackImpl(this), + .serviceCallback_ = callback, + }; + int32_t ret = audioRender_->RegCallback(hdiCallback_.callback_, (int8_t)0); + if (ret != SUCCESS) { + AUDIO_WARNING_LOG("fail, error code: %{public}d", ret); + } +} + +int32_t RemoteOffloadAudioRenderSink::SetBufferSize(uint32_t sizeMs) +{ + Trace trace("RemoteOffloadAudioRenderSink::SetBufferSize"); + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET_LOG(!isFlushing_.load(), ERR_OPERATION_FAILED, "during flushing"); + + // 4: bytewidth + uint32_t size = (uint64_t) sizeMs * attr_.sampleRate * 4 * STEREO_CHANNEL_COUNT / SECOND_TO_MILLISECOND; + AUDIO_INFO_LOG("size: %{public}u, sizeMs: %{public}u", size, sizeMs); + AudioMmapBufferDescriptor desc; + int32_t ret = audioRender_->ReqMmapBuffer(size, desc); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "set buffer size fail"); + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::SetOffloadRenderCallbackType(RenderCallbackType type) +{ + AUDIO_INFO_LOG("type: %{public}d", type); + CHECK_AND_RETURN_RET_LOG(hdiCallback_.serviceCallback_ != nullptr, ERR_ILLEGAL_STATE, "callback is nullptr"); + CHECK_AND_RETURN_RET_LOG(started_.load() && !isFlushing_.load(), ERR_ILLEGAL_STATE, + "not start or flushing, invalid state"); + + hdiCallback_.serviceCallback_(type); + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::LockOffloadRunningLock(void) +{ +#ifdef FEATURE_POWER_MANAGER + if (runningLock_ == nullptr) { + WatchTimeout guard("create AudioRunningLock start"); + runningLock_ = std::make_shared(std::string(RUNNING_LOCK_NAME)); + guard.CheckCurrTimeout(); + } + CHECK_AND_RETURN_RET_LOG(runningLock_ != nullptr, ERR_OPERATION_FAILED, + "running lock is null, playback can not work well"); + CHECK_AND_RETURN_RET(!runningLocked_, SUCCESS); + AUDIO_INFO_LOG("in"); + runningLock_->Lock(RUNNING_LOCK_TIMEOUTMS_LASTING); + runningLocked_ = true; +#endif + return SUCCESS; +} + +int32_t RemoteOffloadAudioRenderSink::UnLockOffloadRunningLock(void) +{ +#ifdef FEATURE_POWER_MANAGER + CHECK_AND_RETURN_RET_LOG(runningLock_ != nullptr, ERR_OPERATION_FAILED, + "running lock is null, playback can not work well"); + CHECK_AND_RETURN_RET(runningLocked_, SUCCESS); + AUDIO_INFO_LOG("in"); + runningLock_->UnLock(); + runningLocked_ = false; +#endif + return SUCCESS; +} + +void RemoteOffloadAudioRenderSink::DumpInfo(std::string &dumpString) +{ + dumpString += "type: RemoteOffloadSink\tstarted: " + std::string(started_.load() ? "true" : "false") + "\n"; +} + +void RemoteOffloadAudioRenderSink::OnAudioParamChange(const std::string &adapterName, const AudioParamKey key, + const std::string &condition, const std::string &value) +{ + AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str()); + if (key == AudioParamKey::PARAM_KEY_STATE) { + DeInit(); + } + + callback_.OnRenderSinkParamChange(adapterName, key, condition, value); +} + +uint32_t RemoteOffloadAudioRenderSink::PcmFormatToBit(AudioSampleFormat format) +{ + AudioFormat hdiFormat = ConvertToHdiFormat(format); + switch (hdiFormat) { + case AUDIO_FORMAT_TYPE_PCM_8_BIT: + return PCM_8_BIT; + case AUDIO_FORMAT_TYPE_PCM_16_BIT: + return PCM_16_BIT; + case AUDIO_FORMAT_TYPE_PCM_24_BIT: + return PCM_24_BIT; + case AUDIO_FORMAT_TYPE_PCM_32_BIT: + return PCM_32_BIT; + default: + AUDIO_DEBUG_LOG("unknown format type, set it to default"); + return PCM_24_BIT; + } +} + +AudioFormat RemoteOffloadAudioRenderSink::ConvertToHdiFormat(AudioSampleFormat format) +{ + AudioFormat hdiFormat; + switch (format) { + case SAMPLE_U8: + hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT; + break; + case SAMPLE_S16LE: + hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT; + break; + case SAMPLE_S24LE: + hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT; + break; + case SAMPLE_S32LE: + hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT; + break; + default: + hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT; + break; + } + return hdiFormat; +} + +void RemoteOffloadAudioRenderSink::InitAudioSampleAttr(AudioSampleAttributes ¶m) +{ + param.channelCount = AUDIO_CHANNELCOUNT; + param.sampleRate = AUDIO_SAMPLE_RATE_48K; + param.interleaved = 0; + param.streamId = static_cast(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_REMOTE_OFFLOAD)); + param.type = AUDIO_OFFLOAD; + param.period = DEEP_BUFFER_RENDER_PERIOD_SIZE; + param.isBigEndian = false; + param.isSignedData = true; + param.stopThreshold = INT_MAX; + param.silenceThreshold = 0; + + param.sampleRate = attr_.sampleRate; + param.channelCount = attr_.channel; + param.format = ConvertToHdiFormat(attr_.format); + param.frameSize = PcmFormatToBit(attr_.format) * param.channelCount / PCM_8_BIT; + if (param.frameSize != 0) { + param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize); + } +} + +void RemoteOffloadAudioRenderSink::InitDeviceDesc(AudioDeviceDescriptor &deviceDesc) +{ + deviceDesc.pins = PIN_OUT_SPEAKER; + deviceDesc.desc = const_cast(""); +} + +int32_t RemoteOffloadAudioRenderSink::CreateRender(void) +{ + Trace trace("RemoteOffloadAudioRenderSink::CreateRender"); + + AudioSampleAttributes param; + AudioDeviceDescriptor deviceDesc; + InitAudioSampleAttr(param); + InitDeviceDesc(deviceDesc); + + AUDIO_INFO_LOG("create render, rate: %{public}u, channel: %{public}u, format: %{public}u", param.sampleRate, + param.channelCount, param.format); + AudioXCollie audioXCollie("RemoteOffloadAudioRenderSink::CreateRender", TIMEOUT_SECONDS_10, + nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY); + HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); + std::shared_ptr deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE); + CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE); + void *render = deviceManager->CreateRender(deviceNetworkId_, ¶m, &deviceDesc, hdiRenderId_); + audioRender_.ForceSetRefPtr(static_cast(render)); + CHECK_AND_RETURN_RET(audioRender_ != nullptr, ERR_NOT_STARTED); + deviceManager->RegistRenderSinkCallback(deviceNetworkId_, hdiRenderId_, this); + return SUCCESS; +} + +void RemoteOffloadAudioRenderSink::InitLatencyMeasurement(void) +{ + if (!AudioLatencyMeasurement::CheckIfEnabled()) { + return; + } + + AUDIO_INFO_LOG("in"); + signalDetectAgent_ = std::make_shared(); + CHECK_AND_RETURN_LOG(signalDetectAgent_ != nullptr, "signalDetectAgent is nullptr"); + signalDetectAgent_->sampleFormat_ = attr_.format; + signalDetectAgent_->formatByteSize_ = GetFormatByteSize(attr_.format); + signalDetected_ = false; +} + +void RemoteOffloadAudioRenderSink::DeInitLatencyMeasurement(void) +{ + signalDetectAgent_ = nullptr; +} + +void RemoteOffloadAudioRenderSink::CheckLatencySignal(uint8_t *data, size_t len) +{ + CHECK_AND_RETURN(signalDetectAgent_ != nullptr); + uint32_t byteSize = static_cast(GetFormatByteSize(attr_.format)); + size_t newlyCheckedTime = len / (attr_.sampleRate / MILLISECOND_PER_SECOND) / + (byteSize * sizeof(uint8_t) * attr_.channel); + signalDetectedTime_ += newlyCheckedTime; + if (signalDetectedTime_ >= MILLISECOND_PER_SECOND && signalDetectAgent_->signalDetected_ && + !signalDetectAgent_->dspTimestampGot_) { + AudioParamKey key = NONE; + std::string condition = "debug_audio_latency_measurement"; + HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); + std::shared_ptr deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE); + CHECK_AND_RETURN(deviceManager != nullptr); + std::string value = deviceManager->GetAudioParameter(attr_.adapterName, key, condition); + + LatencyMonitor::GetInstance().UpdateDspTime(value.c_str()); + LatencyMonitor::GetInstance().UpdateSinkOrSourceTime(true, signalDetectAgent_->lastPeakBufferTime_); + LatencyMonitor::GetInstance().ShowTimestamp(true); + signalDetectAgent_->dspTimestampGot_ = true; + signalDetectAgent_->signalDetected_ = false; + } + signalDetected_ = signalDetectAgent_->CheckAudioData(data, len); + if (signalDetected_) { + AUDIO_INFO_LOG("signal detected"); + signalDetectedTime_ = 0; + } +} + +void RemoteOffloadAudioRenderSink::AdjustStereoToMono(char *data, uint64_t len) +{ + // only stereo is supported now (stereo channel count is 2) + CHECK_AND_RETURN_LOG(attr_.channel == STEREO_CHANNEL_COUNT, "unsupport, channel: %{public}d", attr_.channel); + + switch (attr_.format) { + case SAMPLE_U8: + AdjustStereoToMonoForPCM8Bit(reinterpret_cast(data), len); + break; + case SAMPLE_S16LE: + AdjustStereoToMonoForPCM16Bit(reinterpret_cast(data), len); + break; + case SAMPLE_S24LE: + AdjustStereoToMonoForPCM24Bit(reinterpret_cast(data), len); + break; + case SAMPLE_S32LE: + AdjustStereoToMonoForPCM32Bit(reinterpret_cast(data), len); + break; + default: + // if the audio format is unsupported, the audio data will not be changed + AUDIO_ERR_LOG("unsupport, format: %{public}d", attr_.format); + break; + } +} + +void RemoteOffloadAudioRenderSink::AdjustAudioBalance(char *data, uint64_t len) +{ + // only stereo is supported now (stereo channel count is 2) + CHECK_AND_RETURN_LOG(attr_.channel == STEREO_CHANNEL_COUNT, "unsupport, channel: %{public}d", attr_.channel); + + switch (attr_.format) { + case SAMPLE_U8: + // this function needs further tested for usability + AdjustAudioBalanceForPCM8Bit(reinterpret_cast(data), len, leftBalanceCoef_, rightBalanceCoef_); + break; + case SAMPLE_S16LE: + AdjustAudioBalanceForPCM16Bit(reinterpret_cast(data), len, leftBalanceCoef_, rightBalanceCoef_); + break; + case SAMPLE_S24LE: + // this function needs further tested for usability + AdjustAudioBalanceForPCM24Bit(reinterpret_cast(data), len, leftBalanceCoef_, rightBalanceCoef_); + break; + case SAMPLE_S32LE: + AdjustAudioBalanceForPCM32Bit(reinterpret_cast(data), len, leftBalanceCoef_, rightBalanceCoef_); + break; + default: + // if the audio format is unsupported, the audio data will not be changed + AUDIO_ERR_LOG("unsupport, format: %{public}d", attr_.format); + break; + } +} + +void RemoteOffloadAudioRenderSink::CheckUpdateState(char *data, uint64_t len) +{ + if (startUpdate_) { + if (renderFrameNum_ == 0) { + last10FrameStartTime_ = ClockTime::GetCurNano(); + } + renderFrameNum_++; + maxAmplitude_ = UpdateMaxAmplitude(static_cast(attr_.format), data, len); + if (renderFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) { + renderFrameNum_ = 0; + if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) { + startUpdate_ = false; + maxAmplitude_ = 0; + } + } + } +} + +int32_t RemoteOffloadAudioRenderSink::SetVolumeInner(float left, float right) +{ + AudioXCollie audioXCollie("RemoteOffloadAudioRenderSink::SetVolumeInner", TIMEOUT_SECONDS_10, nullptr, nullptr, + AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY); + AUDIO_INFO_LOG("set offload vol, left: %{public}f, right: %{public}f", left, right); + + CHECK_AND_RETURN_RET_LOG(!isFlushing_.load(), ERR_OPERATION_FAILED, "during flushing"); + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, + "render is nullptr, because set volume on device which offload is not available"); + + float volume; + if ((left == 0) && (right != 0)) { + volume = right; + } else if ((left != 0) && (right == 0)) { + volume = left; + } else { + volume = (left + right) / HALF_FACTOR; + } + + int32_t ret = audioRender_->SetVolume(volume); + if (ret != SUCCESS) { + AUDIO_WARNING_LOG("set volume fail"); + } + + return ret; +} + +// must be called with sinkMutex_ held +void RemoteOffloadAudioRenderSink::UpdateSinkState(bool started) +{ + callback_.OnRenderSinkStateChange(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_REMOTE_OFFLOAD), + started); +} + +} // namespace AudioStandard +} // namespace OHOS diff --git a/frameworks/native/hdiadapter_new/test/unittest/sink/remote_offload_audio_render_sink_unit_test.cpp b/frameworks/native/hdiadapter_new/test/unittest/sink/remote_offload_audio_render_sink_unit_test.cpp new file mode 100644 index 0000000000..8f271a212a --- /dev/null +++ b/frameworks/native/hdiadapter_new/test/unittest/sink/remote_offload_audio_render_sink_unit_test.cpp @@ -0,0 +1,165 @@ +/* + * 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 +#include +#include +#include "audio_utils.h" +#include "common/hdi_adapter_info.h" +#include "manager/hdi_adapter_manager.h" + +using namespace testing::ext; + +namespace OHOS { +namespace AudioStandard { +class RemoteOffloadAudioRenderSinkUnitTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp(); + virtual void TearDown(); + +protected: + static uint32_t id_; + static std::shared_ptr sink_; + static IAudioSinkAttr attr_; +}; + +uint32_t RemoteOffloadAudioRenderSinkUnitTest::id_ = HDI_INVALID_ID; +std::shared_ptr RemoteOffloadAudioRenderSinkUnitTest::sink_ = nullptr; +IAudioSinkAttr RemoteOffloadAudioRenderSinkUnitTest::attr_ = {}; + +void RemoteOffloadAudioRenderSinkUnitTest::SetUpTestCase() +{ + id_ = HdiAdapterManager::GetInstance().GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_REMOTE_OFFLOAD, HDI_ID_INFO_DEFAULT, + true); +} + +void RemoteOffloadAudioRenderSinkUnitTest::TearDownTestCase() +{ + HdiAdapterManager::GetInstance().ReleaseId(id_); +} + +void RemoteOffloadAudioRenderSinkUnitTest::SetUp() +{ + sink_ = HdiAdapterManager::GetInstance().GetRenderSink(id_, true); + if (sink_ == nullptr) { + return; + } +} + +void RemoteOffloadAudioRenderSinkUnitTest::TearDown() +{ + sink_ = nullptr; +} + +/** + * @tc.name : Test OffloadSink API + * @tc.number : RemoteOffloadSinkUnitTest_001 + * @tc.desc : Test remote offload sink create + */ +HWTEST_F(RemoteOffloadAudioRenderSinkUnitTest, RemoteOffloadSinkUnitTest_001, TestSize.Level1) +{ + EXPECT_TRUE(sink_); +} + +/** + * @tc.name : Test OffloadSink API + * @tc.number : RemoteOffloadSinkUnitTest_002 + * @tc.desc : Test remote offload sink deinit + */ +HWTEST_F(RemoteOffloadAudioRenderSinkUnitTest, RemoteOffloadSinkUnitTest_002, TestSize.Level1) +{ + EXPECT_TRUE(sink_); + if (sink_->IsInited()) { + sink_->DeInit(); + } + EXPECT_FALSE(sink_->IsInited()); +} + +/** + * @tc.name : Test OffloadSink API + * @tc.number : RemoteOffloadSinkUnitTest_003 + * @tc.desc : Test remote offload sink start, stop, resume, pause, flush, reset + */ +HWTEST_F(RemoteOffloadAudioRenderSinkUnitTest, RemoteOffloadSinkUnitTest_003, TestSize.Level1) +{ + EXPECT_TRUE(sink_); + int32_t ret = sink_->Start(); + EXPECT_EQ(ret, ERR_NOT_STARTED); + ret = sink_->Stop(); + EXPECT_EQ(ret, SUCCESS); + ret = sink_->Resume(); + EXPECT_EQ(ret, ERR_ILLEGAL_STATE); + ret = sink_->Pause(); + EXPECT_EQ(ret, ERR_ILLEGAL_STATE); + ret = sink_->Flush(); + EXPECT_EQ(ret, ERR_OPERATION_FAILED); + ret = sink_->Reset(); + EXPECT_EQ(ret, ERR_OPERATION_FAILED); + ret = sink_->Stop(); + EXPECT_EQ(ret, SUCCESS); +} + +/** + * @tc.name : Test OffloadSink API + * @tc.number : RemoteOffloadSinkUnitTest_004 + * @tc.desc : Test remote offload sink set/get volume + */ +HWTEST_F(RemoteOffloadAudioRenderSinkUnitTest, RemoteOffloadSinkUnitTest_004, TestSize.Level1) +{ + EXPECT_TRUE(sink_); + int32_t ret = sink_->SetVolume(0.0f, 0.0f); + EXPECT_EQ(ret, ERR_INVALID_HANDLE); + ret = sink_->SetVolume(0.0f, 1.0f); + EXPECT_EQ(ret, ERR_INVALID_HANDLE); + ret = sink_->SetVolume(1.0f, 0.0f); + EXPECT_EQ(ret, ERR_INVALID_HANDLE); + ret = sink_->SetVolume(1.0f, 1.0f); + EXPECT_EQ(ret, ERR_INVALID_HANDLE); + float left; + float right; + ret = sink_->GetVolume(left, right); + EXPECT_EQ(ret, SUCCESS); +} + +/** + * @tc.name : Test OffloadSink API + * @tc.number : RemoteOffloadSinkUnitTest_005 + * @tc.desc : Test remote offload sink set audio scene + */ +HWTEST_F(RemoteOffloadAudioRenderSinkUnitTest, RemoteOffloadSinkUnitTest_005, TestSize.Level1) +{ + EXPECT_TRUE(sink_); + std::vector deviceTypes = { DEVICE_TYPE_SPEAKER }; + int32_t ret = sink_->SetAudioScene(AUDIO_SCENE_DEFAULT, deviceTypes); + EXPECT_EQ(ret, ERR_NOT_SUPPORTED); +} + +/** + * @tc.name : Test OffloadSink API + * @tc.number : RemoteOffloadSinkUnitTest_006 + * @tc.desc : Test remote offload sink update active device + */ +HWTEST_F(RemoteOffloadAudioRenderSinkUnitTest, RemoteOffloadSinkUnitTest_006, TestSize.Level1) +{ + EXPECT_TRUE(sink_); + std::vector deviceTypes = { DEVICE_TYPE_SPEAKER }; + int32_t ret = sink_->UpdateActiveDevice(deviceTypes); + EXPECT_EQ(ret, ERR_NOT_SUPPORTED); +} + +} // namespace AudioStandard +} // namespace OHOS diff --git a/frameworks/native/hdiadapter_new/util/id_handler.cpp b/frameworks/native/hdiadapter_new/util/id_handler.cpp index 6fe990002c..0272a79393 100644 --- a/frameworks/native/hdiadapter_new/util/id_handler.cpp +++ b/frameworks/native/hdiadapter_new/util/id_handler.cpp @@ -70,6 +70,8 @@ uint32_t IdHandler::GetRenderIdByDeviceClass(const std::string &deviceClass, con #ifdef FEATURE_DISTRIBUTE_AUDIO } else if (deviceClass == "remote") { return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_REMOTE, info); + } else if (deviceClass == "remote_offload") { + return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_REMOTE_OFFLOAD, info); #endif } else if (deviceClass == "offload") { return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_OFFLOAD, HDI_ID_INFO_DEFAULT); diff --git a/frameworks/native/ohaudio/OHAudioDeviceDescriptor.cpp b/frameworks/native/ohaudio/OHAudioDeviceDescriptor.cpp index a64acd04c7..e23e181660 100644 --- a/frameworks/native/ohaudio/OHAudioDeviceDescriptor.cpp +++ b/frameworks/native/ohaudio/OHAudioDeviceDescriptor.cpp @@ -201,7 +201,7 @@ OH_AudioCommon_Result OHAudioDeviceDescriptor::GetDeviceSampleRates(uint32_t **s { CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptor_ != nullptr, AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioDeviceDescriptor_ is nullptr"); - DeviceStreamInfo audioStreamInfo = audioDeviceDescriptor_->audioStreamInfo_; + DeviceStreamInfo audioStreamInfo = audioDeviceDescriptor_->GetDeviceStreamInfo(); uint32_t samplingRateSize = (uint32_t)audioStreamInfo.samplingRate.size(); if (samplingRateSize == 0) { @@ -223,15 +223,16 @@ OH_AudioCommon_Result OHAudioDeviceDescriptor::GetDeviceChannelCounts(uint32_t * { CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptor_ != nullptr, AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioDeviceDescriptor_ is nullptr"); - DeviceStreamInfo audioStreamInfo = audioDeviceDescriptor_->audioStreamInfo_; - uint32_t channelsSize = (uint32_t)audioStreamInfo.channels.size(); + DeviceStreamInfo audioStreamInfo = audioDeviceDescriptor_->GetDeviceStreamInfo(); + std::set channelSet = audioStreamInfo.GetChannels(); + uint32_t channelsSize = (uint32_t)channelSet.size(); if (channelsSize == 0) { return AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM; } if (audioChannel_ == nullptr) { audioChannel_ = new uint32_t[channelsSize]; int index = 0; - for (const auto channels : audioStreamInfo.channels) { + for (const auto channels : channelSet) { audioChannel_[index++] = static_cast(channels); } } @@ -254,7 +255,7 @@ OH_AudioCommon_Result OHAudioDeviceDescriptor::GetDeviceEncodingTypes(OH_AudioSt { CHECK_AND_RETURN_RET_LOG(audioDeviceDescriptor_ != nullptr, AUDIOCOMMON_RESULT_ERROR_INVALID_PARAM, "audioDeviceDescriptor_ is nullptr"); - DeviceStreamInfo audioStreamInfo = audioDeviceDescriptor_->audioStreamInfo_; + DeviceStreamInfo audioStreamInfo = audioDeviceDescriptor_->GetDeviceStreamInfo(); if (encodingType_ == nullptr) { encodingType_ = new OH_AudioStream_EncodingType[1]; encodingType_[0] = (OH_AudioStream_EncodingType)audioStreamInfo.encoding; diff --git a/interfaces/inner_api/native/audiocommon/include/audio_device_descriptor.h b/interfaces/inner_api/native/audiocommon/include/audio_device_descriptor.h index 36e8a15a7b..f8d5e54201 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_device_descriptor.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_device_descriptor.h @@ -86,7 +86,7 @@ public: void SetDeviceInfo(std::string deviceName, std::string macAddress); - void SetDeviceCapability(const DeviceStreamInfo &audioStreamInfo, int32_t channelMask, + void SetDeviceCapability(const std::list &audioStreamInfo, int32_t channelMask, int32_t channelIndexMasks = 0); bool IsSameDeviceDesc(const AudioDeviceDescriptor &deviceDescriptor) const; @@ -101,6 +101,8 @@ public: DeviceType MapInternalToExternalDeviceType(int32_t apiVersion) const; + DeviceStreamInfo GetDeviceStreamInfo(void) const; + void Dump(std::string &dumpString); std::string GetDeviceTypeString(); @@ -144,7 +146,7 @@ public: std::string networkId_; uint16_t dmDeviceType_{0}; std::string displayName_; - DeviceStreamInfo audioStreamInfo_ = {}; + std::list audioStreamInfo_; DeviceCategory deviceCategory_ = CATEGORY_DEFAULT; ConnectState connectState_ = CONNECTED; // AudioDeviceDescriptor diff --git a/interfaces/inner_api/native/audiocommon/include/audio_device_info.h b/interfaces/inner_api/native/audiocommon/include/audio_device_info.h index 81454f2585..5239ffde09 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_device_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_device_info.h @@ -20,10 +20,10 @@ #include #include #include +#include "audio_device_stream_info.h" namespace OHOS { namespace AudioStandard { -constexpr size_t AUDIO_DEVICE_INFO_SIZE_LIMIT = 30; constexpr int32_t INVALID_GROUP_ID = -1; namespace { const char* LOCAL_NETWORK_ID = "LocalDevice"; @@ -381,85 +381,6 @@ struct AffinityDeviceInfo { bool SupportedConcurrency; }; -template bool MarshallingSetInt32(const std::set &value, Parcel &parcel) -{ - size_t size = value.size(); - if (!parcel.WriteUint64(size)) { - return false; - } - for (const auto &i : value) { - if (!parcel.WriteInt32(i)) { - return false; - } - } - return true; -} - -template std::set UnmarshallingSetInt32(Parcel &parcel, - const size_t maxSize = std::numeric_limits::max()) -{ - size_t size = parcel.ReadUint64(); - // due to security concerns, sizelimit has been imposed - if (size > maxSize) { - size = maxSize; - } - - std::set res; - for (size_t i = 0; i < size; i++) { - res.insert(static_cast(parcel.ReadInt32())); - } - return res; -} - -struct DeviceStreamInfo { - AudioEncodingType encoding = AudioEncodingType::ENCODING_PCM; - AudioSampleFormat format = AudioSampleFormat::INVALID_WIDTH; - AudioChannelLayout channelLayout = AudioChannelLayout::CH_LAYOUT_UNKNOWN; - std::set samplingRate; - std::set channels; - - DeviceStreamInfo(AudioSamplingRate samplingRate_, AudioEncodingType encoding_, AudioSampleFormat format_, - AudioChannel channels_) : encoding(encoding_), format(format_), - samplingRate({samplingRate_}), channels({channels_}) - {} - DeviceStreamInfo(AudioStreamInfo audioStreamInfo) : DeviceStreamInfo(audioStreamInfo.samplingRate, - audioStreamInfo.encoding, audioStreamInfo.format, audioStreamInfo.channels) - {} - DeviceStreamInfo() = default; - - bool Marshalling(Parcel &parcel) const - { - return parcel.WriteInt32(static_cast(encoding)) - && parcel.WriteInt32(static_cast(format)) - && MarshallingSetInt32(samplingRate, parcel) - && MarshallingSetInt32(channels, parcel); - } - void Unmarshalling(Parcel &parcel) - { - encoding = static_cast(parcel.ReadInt32()); - format = static_cast(parcel.ReadInt32()); - samplingRate = UnmarshallingSetInt32(parcel, AUDIO_DEVICE_INFO_SIZE_LIMIT); - channels = UnmarshallingSetInt32(parcel, AUDIO_DEVICE_INFO_SIZE_LIMIT); - } - - bool operator==(const DeviceStreamInfo& info) const - { - return encoding == info.encoding && format == info.format && channels == info.channels && - channelLayout == info.channelLayout && samplingRate == info.samplingRate; - } - - bool CheckParams() - { - if (samplingRate.size() == 0) { - return false; - } - if (channels.size() == 0) { - return false; - } - return true; - } -}; - enum class AudioStreamDeviceChangeReason { UNKNOWN = 0, NEW_DEVICE_AVAILABLE = 1, diff --git a/interfaces/inner_api/native/audiocommon/include/audio_device_stream_info.h b/interfaces/inner_api/native/audiocommon/include/audio_device_stream_info.h new file mode 100644 index 0000000000..1179261454 --- /dev/null +++ b/interfaces/inner_api/native/audiocommon/include/audio_device_stream_info.h @@ -0,0 +1,333 @@ +/* + * 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_DEVICE_STREAM_INFO_H +#define AUDIO_DEVICE_STREAM_INFO_H + +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include + +namespace OHOS { +namespace AudioStandard { +constexpr size_t AUDIO_DEVICE_INFO_SIZE_LIMIT = 30; + +template bool MarshallingSetInt32(const std::set &value, Parcel &parcel) +{ + size_t size = value.size(); + if (!parcel.WriteUint64(size)) { + return false; + } + for (const auto &i : value) { + if (!parcel.WriteInt32(i)) { + return false; + } + } + return true; +} + +template std::set UnmarshallingSetInt32(Parcel &parcel, + const size_t maxSize = std::numeric_limits::max()) +{ + size_t size = parcel.ReadUint64(); + // due to security concerns, sizelimit has been imposed + if (size > maxSize) { + size = maxSize; + } + + std::set res; + for (size_t i = 0; i < size; i++) { + res.insert(static_cast(parcel.ReadInt32())); + } + return res; +} + +template bool MarshallingSetInt64(const std::set &value, Parcel &parcel) +{ + size_t size = value.size(); + if (!parcel.WriteUint64(size)) { + return false; + } + for (const auto &i : value) { + if (!parcel.WriteInt64(i)) { + return false; + } + } + return true; +} + +template std::set UnmarshallingSetInt64(Parcel &parcel, + const size_t maxSize = std::numeric_limits::max()) +{ + size_t size = parcel.ReadUint64(); + // due to security concerns, sizelimit has been imposed + if (size > maxSize) { + size = maxSize; + } + + std::set res; + for (size_t i = 0; i < size; i++) { + res.insert(static_cast(parcel.ReadInt64())); + } + return res; +} + +static AudioChannel ConvertLayoutToAudioChannel(AudioChannelLayout layout) +{ + AudioChannel channel = AudioChannel::CHANNEL_UNKNOW; + switch (layout) { + case AudioChannelLayout::CH_LAYOUT_MONO: + channel = AudioChannel::MONO; + break; + case AudioChannelLayout::CH_LAYOUT_STEREO: + channel = AudioChannel::STEREO; + break; + case AudioChannelLayout::CH_LAYOUT_2POINT1: + case AudioChannelLayout::CH_LAYOUT_3POINT0: + channel = AudioChannel::CHANNEL_3; + break; + case AudioChannelLayout::CH_LAYOUT_3POINT1: + case AudioChannelLayout::CH_LAYOUT_4POINT0: + case AudioChannelLayout::CH_LAYOUT_QUAD: + channel = AudioChannel::CHANNEL_4; + break; + case AudioChannelLayout::CH_LAYOUT_5POINT0: + case AudioChannelLayout::CH_LAYOUT_2POINT1POINT2: + channel = AudioChannel::CHANNEL_5; + break; + case AudioChannelLayout::CH_LAYOUT_5POINT1: + case AudioChannelLayout::CH_LAYOUT_HEXAGONAL: + case AudioChannelLayout::CH_LAYOUT_3POINT1POINT2: + channel = AudioChannel::CHANNEL_6; + break; + case AudioChannelLayout::CH_LAYOUT_7POINT0: + channel = AudioChannel::CHANNEL_7; + break; + case AudioChannelLayout::CH_LAYOUT_7POINT1: + channel = AudioChannel::CHANNEL_8; + break; + case AudioChannelLayout::CH_LAYOUT_7POINT1POINT2: + channel = AudioChannel::CHANNEL_10; + break; + case AudioChannelLayout::CH_LAYOUT_7POINT1POINT4: + channel = AudioChannel::CHANNEL_12; + break; + default: + channel = AudioChannel::CHANNEL_UNKNOW; + break; + } + return channel; +} + +static AudioChannelLayout ConvertAudioChannelToLayout(AudioChannel channel) +{ + AudioChannelLayout channelLayout = AudioChannelLayout::CH_LAYOUT_UNKNOWN; + + switch (channel) { + case AudioChannel::MONO: + channelLayout = AudioChannelLayout::CH_LAYOUT_MONO; + break; + case AudioChannel::STEREO: + channelLayout = AudioChannelLayout::CH_LAYOUT_STEREO; + break; + case AudioChannel::CHANNEL_3: + channelLayout = AudioChannelLayout::CH_LAYOUT_2POINT1; + break; + case AudioChannel::CHANNEL_4: + channelLayout = AudioChannelLayout::CH_LAYOUT_3POINT1; + break; + case AudioChannel::CHANNEL_5: + channelLayout = AudioChannelLayout::CH_LAYOUT_2POINT1POINT2; + break; + case AudioChannel::CHANNEL_6: + channelLayout = AudioChannelLayout::CH_LAYOUT_5POINT1; + break; + case AudioChannel::CHANNEL_7: + channelLayout = AudioChannelLayout::CH_LAYOUT_7POINT0; + break; + case AudioChannel::CHANNEL_8: + channelLayout = AudioChannelLayout::CH_LAYOUT_7POINT1; + break; + case AudioChannel::CHANNEL_10: + channelLayout = AudioChannelLayout::CH_LAYOUT_7POINT1POINT2; + break; + case AudioChannel::CHANNEL_12: + channelLayout = AudioChannelLayout::CH_LAYOUT_7POINT1POINT4; + break; + default: + channelLayout = AudioChannelLayout::CH_LAYOUT_UNKNOWN; + break; + } + + return channelLayout; +} + +static std::vector SplitStr(const std::string &str, const char delimiter) +{ + std::vector res; + std::istringstream iss(str); + std::string item; + while (getline(iss, item, delimiter)) { + res.push_back(item); + } + return res; +} + +struct DeviceStreamInfo { + AudioEncodingType encoding = AudioEncodingType::ENCODING_PCM; + AudioSampleFormat format = AudioSampleFormat::INVALID_WIDTH; + std::set channelLayout; + std::set samplingRate; + + DeviceStreamInfo(AudioSamplingRate samplingRate_, AudioEncodingType encoding_, AudioSampleFormat format_, + AudioChannelLayout channelLayout_) + : encoding(encoding_), format(format_), channelLayout({channelLayout_}), samplingRate({samplingRate_}) + {} + DeviceStreamInfo(AudioSamplingRate samplingRate_, AudioEncodingType encoding_, AudioSampleFormat format_, + AudioChannel channels_) : DeviceStreamInfo(samplingRate_, encoding_, format_, + ConvertAudioChannelToLayout(channels_)) + {} + DeviceStreamInfo(AudioStreamInfo audioStreamInfo) : DeviceStreamInfo(audioStreamInfo.samplingRate, + audioStreamInfo.encoding, audioStreamInfo.format, ConvertAudioChannelToLayout(audioStreamInfo.channels)) + {} + DeviceStreamInfo() = default; + + std::set GetChannels() const + { + std::set channels; + for (const auto &layout : channelLayout) { + channels.insert(ConvertLayoutToAudioChannel(layout)); + } + return channels; + } + + // warning: force set default channelLayout by channel + void SetChannels(const std::set &channels) + { + channelLayout.clear(); + for (const auto &channel : channels) { + channelLayout.insert(ConvertAudioChannelToLayout(channel)); + } + } + + bool Marshalling(Parcel &parcel) const + { + return parcel.WriteInt32(static_cast(encoding)) + && parcel.WriteInt32(static_cast(format)) + && MarshallingSetInt32(samplingRate, parcel) + && MarshallingSetInt64(channelLayout, parcel); + } + void Unmarshalling(Parcel &parcel) + { + encoding = static_cast(parcel.ReadInt32()); + format = static_cast(parcel.ReadInt32()); + samplingRate = UnmarshallingSetInt32(parcel, AUDIO_DEVICE_INFO_SIZE_LIMIT); + channelLayout = UnmarshallingSetInt64(parcel, AUDIO_DEVICE_INFO_SIZE_LIMIT); + } + + static std::string SerializeList(const std::list &streamInfoList) + { + std::string res; + bool isFirst = true; + for (const auto &streamInfo : streamInfoList) { + std::string infoStr = streamInfo.Serialize(); + if (!isFirst) { + res.append("-"); + } + res.append(infoStr); + isFirst = false; + } + return res; + } + + static std::list DeserializeList(const std::string &data) + { + std::list res; + std::vector strList = SplitStr(data, '-'); + for (const auto &str : strList) { + DeviceStreamInfo streamInfo; + streamInfo.Deserialize(str); + res.push_back(streamInfo); + } + return res; + } + + std::string Serialize() const + { + std::stringstream ss; + ss << std::to_string(encoding) << "," << std::to_string(format) << ","; + bool isFirst = true; + for (const auto &item : samplingRate) { + if (!isFirst) { + ss << ":"; + } + ss << std::to_string(item); + isFirst = false; + } + ss << ","; + isFirst = true; + for (const auto &item : channelLayout) { + if (!isFirst) { + ss << ":"; + } + ss << std::to_string(item); + isFirst = false; + } + return ss.str(); + } + + void Deserialize(const std::string &data) + { + std::vector strList = SplitStr(data, ','); + if (strList.size() != 4) { // 4: member num + return; + } + encoding = static_cast(std::stoi(strList[0])); // 0: encoding + format = static_cast(std::stoi(strList[1])); // 1: format + std::vector rateList = SplitStr(strList[2], ':'); // 2: sampling rate + for (const auto &str : rateList) { + samplingRate.insert(static_cast(std::stoi(str))); + } + std::vector layoutList = SplitStr(strList[3], ':'); // 3: channel layout + for (const auto &str : layoutList) { + channelLayout.insert(static_cast(std::stoll(str))); + } + } + + bool operator==(const DeviceStreamInfo& info) const + { + return encoding == info.encoding && format == info.format && + channelLayout == info.channelLayout && samplingRate == info.samplingRate; + } + + bool CheckParams() + { + if (samplingRate.size() == 0) { + return false; + } + if (channelLayout.size() == 0) { + return false; + } + return true; + } +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // AUDIO_DEVICE_STREAM_INFO_H \ No newline at end of file diff --git a/interfaces/inner_api/native/audiocommon/include/audio_info.h b/interfaces/inner_api/native/audiocommon/include/audio_info.h index 235c93483b..2512777e61 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_info.h @@ -1157,7 +1157,7 @@ struct DStatusInfo { std::string deviceName = ""; bool isConnected = false; std::string macAddress; - DeviceStreamInfo streamInfo = {}; + std::list streamInfo = {}; ConnectType connectType = CONNECT_TYPE_LOCAL; }; diff --git a/services/audio_engine/manager/src/i_hpae_renderer_manager.cpp b/services/audio_engine/manager/src/i_hpae_renderer_manager.cpp index 226fd2815c..c41e3b9867 100644 --- a/services/audio_engine/manager/src/i_hpae_renderer_manager.cpp +++ b/services/audio_engine/manager/src/i_hpae_renderer_manager.cpp @@ -24,11 +24,12 @@ namespace OHOS { namespace AudioStandard { namespace HPAE { static const std::string DEVICE_CLASS_OFFLOAD = "offload"; +static const std::string DEVICE_CLASS_REMOTE_OFFLOAD = "remote_offload"; static const std::string DEVICE_NAME_INNER_CAP = "InnerCapturerSink"; static const std::string DEVICE_NAME_CAST_INNER_CAP = "RemoteCastInnerCapturer"; std::shared_ptr IHpaeRendererManager::CreateRendererManager(HpaeSinkInfo &sinkInfo) { - if (sinkInfo.deviceClass == DEVICE_CLASS_OFFLOAD) { + if (sinkInfo.deviceClass == DEVICE_CLASS_OFFLOAD || sinkInfo.deviceClass == DEVICE_CLASS_REMOTE_OFFLOAD) { return std::make_shared(sinkInfo); } else if ((sinkInfo.deviceName.compare(0, DEVICE_NAME_INNER_CAP.length(), DEVICE_NAME_INNER_CAP) == 0) || sinkInfo.deviceName == DEVICE_NAME_CAST_INNER_CAP) { diff --git a/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp b/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp index 31edcf7de3..b493c85e25 100644 --- a/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp +++ b/services/audio_engine/node/src/hpae_offload_sinkoutput_node.cpp @@ -154,8 +154,9 @@ void HpaeOffloadSinkOutputNode::DisConnect(const std::shared_ptrGetVolume(GetSessionId(), volumeType, DEVICE_CLASS_OFFLOAD, &volumes); + float volumeEnd = AudioVolume::GetInstance()->GetVolume(GetSessionId(), volumeType, GetDeviceClass(), &volumes); float volumeBeg = AudioVolume::GetInstance()->GetHistoryVolume(GetSessionId()); if (fabs(volumeBeg - volumeEnd) > EPSILON) { AUDIO_INFO_LOG("HpaeOffloadSinkOutputNode::sessionID:%{public}u, volumeBeg:%{public}f, volumeEnd:%{public}f", diff --git a/services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp b/services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp index 4b09998099..a96f885e81 100644 --- a/services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp +++ b/services/audio_engine/test/unittest/manager/hpae_render_manager_test.cpp @@ -881,4 +881,24 @@ TEST_F(HpaeRendererManagerTest, HpaeRendererSetLoudnessGain_001) std::cout << "test innercapture manager" << std::endl; TestIRendererManagerSetLoudnessGain(); } + +/** + * @tc.name: CreateRendererManager + * @tc.type: FUNC + * @tc.number: CreateRendererManager_001 + * @tc.desc: Test CreateRendererManager + */ +TEST_F(HpaeRendererManagerTest, CreateRendererManager_001) +{ + HpaeSinkInfo sinkInfo; + sinkInfo.deviceClass = "remote_offload"; + std::shared_ptr hpaeRendererManager = IHpaeRendererManager::CreateRendererManager(sinkInfo); + EXPECT_NE(hpaeRendererManager, nullptr); + sinkInfo.deviceClass = "offload"; + hpaeRendererManager = IHpaeRendererManager::CreateRendererManager(sinkInfo); + EXPECT_NE(hpaeRendererManager, nullptr); + sinkInfo.deviceClass = "test"; + hpaeRendererManager = IHpaeRendererManager::CreateRendererManager(sinkInfo); + EXPECT_NE(hpaeRendererManager, nullptr); +} } // namespace \ No newline at end of file diff --git a/services/audio_policy/common/include/audio_module_info.h b/services/audio_policy/common/include/audio_module_info.h index f2d5a4dbd1..58e51fa540 100644 --- a/services/audio_policy/common/include/audio_module_info.h +++ b/services/audio_policy/common/include/audio_module_info.h @@ -106,7 +106,7 @@ struct AudioModuleInfo { std::string rate; std::set supportedRate_; - std::set supportedChannels_; + std::set supportedChannelLayout_; std::string format; std::string channels; diff --git a/services/audio_policy/server/domain/device/src/audio_active_device.cpp b/services/audio_policy/server/domain/device/src/audio_active_device.cpp index 3991d21b27..f897b899f6 100644 --- a/services/audio_policy/server/domain/device/src/audio_active_device.cpp +++ b/services/audio_policy/server/domain/device/src/audio_active_device.cpp @@ -53,7 +53,7 @@ bool AudioActiveDevice::GetActiveA2dpDeviceStreamInfo(DeviceType deviceType, Aud if (audioA2dpDevice_.GetA2dpDeviceInfo(activeBTDevice_, info)) { streamInfo.samplingRate = *info.streamInfo.samplingRate.rbegin(); streamInfo.format = info.streamInfo.format; - streamInfo.channels = *info.streamInfo.channels.rbegin(); + streamInfo.channels = *info.streamInfo.GetChannels().rbegin(); return true; } } else if (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP_IN) { @@ -61,7 +61,7 @@ bool AudioActiveDevice::GetActiveA2dpDeviceStreamInfo(DeviceType deviceType, Aud if (audioA2dpDevice_.GetA2dpInDeviceInfo(activeBTInDevice_, info)) { streamInfo.samplingRate = *info.streamInfo.samplingRate.rbegin(); streamInfo.format = info.streamInfo.format; - streamInfo.channels = *info.streamInfo.channels.rbegin(); + streamInfo.channels = *info.streamInfo.GetChannels().rbegin(); return true; } } diff --git a/services/audio_policy/server/domain/device/src/audio_connected_device.cpp b/services/audio_policy/server/domain/device/src/audio_connected_device.cpp index 016385e195..116f463d7c 100644 --- a/services/audio_policy/server/domain/device/src/audio_connected_device.cpp +++ b/services/audio_policy/server/domain/device/src/audio_connected_device.cpp @@ -308,7 +308,7 @@ void AudioConnectedDevice::UpdateConnectDevice(DeviceType deviceType, const std: auto it = std::find_if(connectedDevices_.begin(), connectedDevices_.end(), isPresent); if (it != connectedDevices_.end()) { (*it)->deviceName_ = deviceName; - (*it)->audioStreamInfo_ = streamInfo; + (*it)->audioStreamInfo_ = { streamInfo }; } } diff --git a/services/audio_policy/server/domain/device/src/audio_device_common.cpp b/services/audio_policy/server/domain/device/src/audio_device_common.cpp index deac71007b..451612147c 100644 --- a/services/audio_policy/server/domain/device/src/audio_device_common.cpp +++ b/services/audio_policy/server/domain/device/src/audio_device_common.cpp @@ -274,10 +274,7 @@ void AudioDeviceCommon::UpdateDeviceInfo(AudioDeviceDescriptor &deviceInfo, deviceInfo.volumeGroupId_ = GROUP_ID_NONE; deviceInfo.interruptGroupId_ = GROUP_ID_NONE; } - deviceInfo.audioStreamInfo_.samplingRate = desc->audioStreamInfo_.samplingRate; - deviceInfo.audioStreamInfo_.encoding = desc->audioStreamInfo_.encoding; - deviceInfo.audioStreamInfo_.format = desc->audioStreamInfo_.format; - deviceInfo.audioStreamInfo_.channels = desc->audioStreamInfo_.channels; + deviceInfo.audioStreamInfo_ = desc->audioStreamInfo_; } int32_t AudioDeviceCommon::DeviceParamsCheck(DeviceRole targetRole, diff --git a/services/audio_policy/server/domain/device/src/audio_device_descriptor.cpp b/services/audio_policy/server/domain/device/src/audio_device_descriptor.cpp index 10ed7c698d..ef64107dd6 100644 --- a/services/audio_policy/server/domain/device/src/audio_device_descriptor.cpp +++ b/services/audio_policy/server/domain/device/src/audio_device_descriptor.cpp @@ -51,6 +51,9 @@ const std::map deviceTypeStringMap = { {DEVICE_TYPE_USB_ARM_HEADSET, "USB_ARM_HEADSET"} }; +const DeviceStreamInfo DEFAULT_DEVICE_STREAM_INFO(SAMPLE_RATE_44100, ENCODING_PCM, AudioSampleFormat::INVALID_WIDTH, + CH_LAYOUT_STEREO); + static const char *DeviceTypeToString(DeviceType type) { if (deviceTypeStringMap.count(type) != 0) { @@ -59,6 +62,36 @@ static const char *DeviceTypeToString(DeviceType type) return "UNKNOWN"; } +static void CheckDeviceInfoSize(size_t &size) +{ + CHECK_AND_RETURN(size > AUDIO_DEVICE_INFO_SIZE_LIMIT); + size = AUDIO_DEVICE_INFO_SIZE_LIMIT; +} + +static bool MarshallingDeviceStreamInfoList(const std::list &deviceStreamInfos, Parcel &parcel) +{ + size_t size = deviceStreamInfos.size(); + CHECK_AND_RETURN_RET(parcel.WriteUint64(size), false); + + for (const auto &deviceStreamInfo : deviceStreamInfos) { + CHECK_AND_RETURN_RET(deviceStreamInfo.Marshalling(parcel), false); + } + return true; +} + +static void UnmarshallingDeviceStreamInfoList(Parcel &parcel, std::list &deviceStreamInfos) +{ + size_t size = parcel.ReadUint64(); + // due to security concerns, sizelimit has been imposed + CheckDeviceInfoSize(size); + + for (size_t i = 0; i < size; i++) { + DeviceStreamInfo deviceStreamInfo; + deviceStreamInfo.Unmarshalling(parcel); + deviceStreamInfos.push_back(deviceStreamInfo); + } +} + AudioDeviceDescriptor::AudioDeviceDescriptor(int32_t descriptorType) : AudioDeviceDescriptor(DeviceType::DEVICE_TYPE_NONE, DeviceRole::DEVICE_ROLE_NONE) { @@ -128,10 +161,7 @@ AudioDeviceDescriptor::AudioDeviceDescriptor(const AudioDeviceDescriptor &device macAddress_ = deviceDescriptor.macAddress_; deviceType_ = deviceDescriptor.deviceType_; deviceRole_ = deviceDescriptor.deviceRole_; - audioStreamInfo_.channels = deviceDescriptor.audioStreamInfo_.channels; - audioStreamInfo_.encoding = deviceDescriptor.audioStreamInfo_.encoding; - audioStreamInfo_.format = deviceDescriptor.audioStreamInfo_.format; - audioStreamInfo_.samplingRate = deviceDescriptor.audioStreamInfo_.samplingRate; + audioStreamInfo_ = deviceDescriptor.audioStreamInfo_; channelMasks_ = deviceDescriptor.channelMasks_; channelIndexMasks_ = deviceDescriptor.channelIndexMasks_; volumeGroupId_ = deviceDescriptor.volumeGroupId_; @@ -163,10 +193,7 @@ AudioDeviceDescriptor::AudioDeviceDescriptor(const std::shared_ptrmacAddress_; deviceType_ = deviceDescriptor->deviceType_; deviceRole_ = deviceDescriptor->deviceRole_; - audioStreamInfo_.channels = deviceDescriptor->audioStreamInfo_.channels; - audioStreamInfo_.encoding = deviceDescriptor->audioStreamInfo_.encoding; - audioStreamInfo_.format = deviceDescriptor->audioStreamInfo_.format; - audioStreamInfo_.samplingRate = deviceDescriptor->audioStreamInfo_.samplingRate; + audioStreamInfo_ = deviceDescriptor->audioStreamInfo_; channelMasks_ = deviceDescriptor->channelMasks_; channelIndexMasks_ = deviceDescriptor->channelIndexMasks_; volumeGroupId_ = deviceDescriptor->volumeGroupId_; @@ -234,7 +261,7 @@ bool AudioDeviceDescriptor::MarshallingToDeviceDescriptor(Parcel &parcel, int32_ parcel.WriteInt32(MapInternalToExternalDeviceType(apiVersion)); parcel.WriteInt32(deviceRole_); parcel.WriteInt32(deviceId_); - audioStreamInfo_.Marshalling(parcel); + MarshallingDeviceStreamInfoList(audioStreamInfo_, parcel); parcel.WriteInt32(channelMasks_); parcel.WriteInt32(channelIndexMasks_); parcel.WriteString(deviceName_); @@ -261,7 +288,7 @@ bool AudioDeviceDescriptor::MarshallingToDeviceInfo(Parcel &parcel) const parcel.WriteInt32(channelIndexMasks_) && parcel.WriteString(deviceName_) && parcel.WriteString(macAddress_) && - audioStreamInfo_.Marshalling(parcel) && + MarshallingDeviceStreamInfoList(audioStreamInfo_, parcel) && parcel.WriteString(networkId_) && parcel.WriteUint16(dmDeviceType_) && parcel.WriteString(displayName_) && @@ -279,12 +306,30 @@ bool AudioDeviceDescriptor::Marshalling(Parcel &parcel, bool hasBTPermission, bo return MarshallingToDeviceInfo(parcel, hasBTPermission, hasSystemPermission, apiVersion); } +static void SetDefaultStreamInfoIfEmpty(std::list &streamInfo) +{ + if (streamInfo.empty()) { + streamInfo.push_back(DEFAULT_DEVICE_STREAM_INFO); + } else { + for (auto &info : streamInfo) { + // If does not set sampleRates use SAMPLE_RATE_44100 instead. + if (info.samplingRate.empty()) { + info.samplingRate = DEFAULT_DEVICE_STREAM_INFO.samplingRate; + } + // If does not set channelCounts use STEREO instead. + if (info.channelLayout.empty()) { + info.channelLayout = DEFAULT_DEVICE_STREAM_INFO.channelLayout; + } + } + } +} + bool AudioDeviceDescriptor::MarshallingToDeviceInfo(Parcel &parcel, bool hasBTPermission, bool hasSystemPermission, int32_t apiVersion) const { DeviceType devType = deviceType_; int32_t devId = deviceId_; - DeviceStreamInfo streamInfo = audioStreamInfo_; + std::list streamInfo = audioStreamInfo_; // If api target version < 11 && does not set deviceType, fix api compatibility. if (apiVersion < API_11 && (deviceType_ == DEVICE_TYPE_NONE || deviceType_ == DEVICE_TYPE_INVALID)) { @@ -297,14 +342,7 @@ bool AudioDeviceDescriptor::MarshallingToDeviceInfo(Parcel &parcel, bool hasBTPe devId = 2; // 2 default mic device id. } - //If does not set sampleRates use SAMPLE_RATE_44100 instead. - if (streamInfo.samplingRate.empty()) { - streamInfo.samplingRate.insert(SAMPLE_RATE_44100); - } - // If does not set channelCounts use STEREO instead. - if (streamInfo.channels.empty()) { - streamInfo.channels.insert(STEREO); - } + SetDefaultStreamInfoIfEmpty(streamInfo); } return parcel.WriteInt32(static_cast(devType)) && @@ -316,7 +354,7 @@ bool AudioDeviceDescriptor::MarshallingToDeviceInfo(Parcel &parcel, bool hasBTPe deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO)) ? "" : deviceName_) && parcel.WriteString((!hasBTPermission && (deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP || deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO)) ? "" : macAddress_) && - streamInfo.Marshalling(parcel) && + MarshallingDeviceStreamInfoList(streamInfo, parcel) && parcel.WriteString(hasSystemPermission ? networkId_ : "") && parcel.WriteUint16(dmDeviceType_) && parcel.WriteString(displayName_) && @@ -349,7 +387,7 @@ void AudioDeviceDescriptor::UnmarshallingToDeviceDescriptor(Parcel &parcel) deviceType_ = static_cast(parcel.ReadInt32()); deviceRole_ = static_cast(parcel.ReadInt32()); deviceId_ = parcel.ReadInt32(); - audioStreamInfo_.Unmarshalling(parcel); + UnmarshallingDeviceStreamInfoList(parcel, audioStreamInfo_); channelMasks_ = parcel.ReadInt32(); channelIndexMasks_ = parcel.ReadInt32(); deviceName_ = parcel.ReadString(); @@ -375,7 +413,7 @@ void AudioDeviceDescriptor::UnmarshallingToDeviceInfo(Parcel &parcel) channelIndexMasks_ = parcel.ReadInt32(); deviceName_ = parcel.ReadString(); macAddress_ = parcel.ReadString(); - audioStreamInfo_.Unmarshalling(parcel); + UnmarshallingDeviceStreamInfoList(parcel, audioStreamInfo_); networkId_ = parcel.ReadString(); dmDeviceType_ = parcel.ReadUint16(); displayName_ = parcel.ReadString(); @@ -393,13 +431,10 @@ void AudioDeviceDescriptor::SetDeviceInfo(std::string deviceName, std::string ma macAddress_ = macAddress; } -void AudioDeviceDescriptor::SetDeviceCapability(const DeviceStreamInfo &audioStreamInfo, int32_t channelMask, +void AudioDeviceDescriptor::SetDeviceCapability(const std::list &audioStreamInfo, int32_t channelMask, int32_t channelIndexMasks) { - audioStreamInfo_.channels = audioStreamInfo.channels; - audioStreamInfo_.encoding = audioStreamInfo.encoding; - audioStreamInfo_.format = audioStreamInfo.format; - audioStreamInfo_.samplingRate = audioStreamInfo.samplingRate; + audioStreamInfo_ = audioStreamInfo; channelMasks_ = channelMask; channelIndexMasks_ = channelIndexMasks; } @@ -477,5 +512,12 @@ DeviceType AudioDeviceDescriptor::MapInternalToExternalDeviceType(int32_t apiVer return deviceType_; } } + +DeviceStreamInfo AudioDeviceDescriptor::GetDeviceStreamInfo(void) const +{ + DeviceStreamInfo streamInfo; + CHECK_AND_RETURN_RET_LOG(!audioStreamInfo_.empty(), streamInfo, "streamInfo empty, get default streamInfo"); + return *audioStreamInfo_.rbegin(); +} } // AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/domain/device/src/audio_device_status.cpp b/services/audio_policy/server/domain/device/src/audio_device_status.cpp index 6e95b50bfc..681a16e1a6 100644 --- a/services/audio_policy/server/domain/device/src/audio_device_status.cpp +++ b/services/audio_policy/server/domain/device/src/audio_device_status.cpp @@ -293,7 +293,7 @@ void AudioDeviceStatus::UpdateLocalGroupInfo(bool isConnected, const std::string const std::string& deviceName, const DeviceStreamInfo& streamInfo, AudioDeviceDescriptor& deviceDesc) { deviceDesc.SetDeviceInfo(deviceName, macAddress); - deviceDesc.SetDeviceCapability(streamInfo, 0); + deviceDesc.SetDeviceCapability({ streamInfo }, 0); audioVolumeManager_.UpdateGroupInfo(VOLUME_TYPE, GROUP_NAME_DEFAULT, deviceDesc.volumeGroupId_, LOCAL_NETWORK_ID, isConnected, NO_REMOTE_ID); audioVolumeManager_.UpdateGroupInfo(INTERRUPT_TYPE, GROUP_NAME_DEFAULT, deviceDesc.interruptGroupId_, @@ -393,11 +393,12 @@ int32_t AudioDeviceStatus::HandleAccessoryDevice(DeviceType deviceType, const st int32_t AudioDeviceStatus::HandleLocalDeviceConnected(AudioDeviceDescriptor &updatedDesc) { + DeviceStreamInfo audioStreamInfo = updatedDesc.GetDeviceStreamInfo(); if (updatedDesc.deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP) { - A2dpDeviceConfigInfo configInfo = {updatedDesc.audioStreamInfo_, false}; + A2dpDeviceConfigInfo configInfo = {audioStreamInfo, false}; audioA2dpDevice_.AddA2dpDevice(updatedDesc.macAddress_, configInfo); } else if (updatedDesc.deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP_IN) { - A2dpDeviceConfigInfo configInfo = {updatedDesc.audioStreamInfo_, false}; + A2dpDeviceConfigInfo configInfo = {audioStreamInfo, false}; audioA2dpDevice_.AddA2dpInDevice(updatedDesc.macAddress_, configInfo); } else if (updatedDesc.deviceType_ == DEVICE_TYPE_DP) { // DP device only for output. CheckAndWriteDeviceChangeExceptionEvent(!audioDeviceCommon_.GetHasDpFlag(), @@ -869,7 +870,10 @@ int32_t AudioDeviceStatus::HandleDistributedDeviceUpdate(DStatusInfo &statusInfo const std::string networkId = statusInfo.networkId; AudioDeviceDescriptor deviceDesc(devType, devRole); deviceDesc.SetDeviceInfo(statusInfo.deviceName, statusInfo.macAddress); - deviceDesc.SetDeviceCapability(statusInfo.streamInfo, 0); + DeviceStreamInfo streamInfo = {}; + std::list streamInfoList = statusInfo.streamInfo.empty() ? + std::list{ streamInfo } : statusInfo.streamInfo; + deviceDesc.SetDeviceCapability(streamInfoList, 0); deviceDesc.networkId_ = networkId; audioVolumeManager_.UpdateGroupInfo(VOLUME_TYPE, GROUP_NAME_DEFAULT, deviceDesc.volumeGroupId_, networkId, statusInfo.isConnected, statusInfo.mappingVolumeId); @@ -965,15 +969,15 @@ void AudioDeviceStatus::AddAudioDevice(AudioModuleInfo& moduleInfo, DeviceType d AudioPolicyUtils::GetInstance().GetDeviceRole(moduleInfo.role), volumeGroupId, interruptGroupId, LOCAL_NETWORK_ID); CHECK_AND_RETURN_LOG(audioDescriptor != nullptr, "audioDescriptor is nullptr."); - if (!moduleInfo.supportedRate_.empty() && !moduleInfo.supportedChannels_.empty()) { + if (!moduleInfo.supportedRate_.empty() && !moduleInfo.supportedChannelLayout_.empty()) { DeviceStreamInfo streamInfo = {}; for (auto supportedRate : moduleInfo.supportedRate_) { streamInfo.samplingRate.insert(static_cast(supportedRate)); } - for (auto supportedChannels : moduleInfo.supportedChannels_) { - streamInfo.channels.insert(static_cast(supportedChannels)); + for (auto supportedChannelLayout : moduleInfo.supportedChannelLayout_) { + streamInfo.channelLayout.insert(static_cast(supportedChannelLayout)); } - audioDescriptor->SetDeviceCapability(streamInfo, 0); + audioDescriptor->SetDeviceCapability({ streamInfo }, 0); } audioDescriptor->deviceId_ = AudioPolicyUtils::startDeviceId++; diff --git a/services/audio_policy/server/domain/device/src/device_status_listener.cpp b/services/audio_policy/server/domain/device/src/device_status_listener.cpp index 77cd3071e4..eaa4b60b53 100644 --- a/services/audio_policy/server/domain/device/src/device_status_listener.cpp +++ b/services/audio_policy/server/domain/device/src/device_status_listener.cpp @@ -31,6 +31,7 @@ #include "audio_errors.h" #include "audio_policy_log.h" +#include "audio_core_service.h" namespace OHOS { namespace AudioStandard { @@ -42,6 +43,7 @@ const std::string DP_ADDRESS = "card=0;port="; const uint8_t EVENT_NUM_TYPE = 2; const uint8_t EVENT_PARAMS = 4; const uint8_t D_EVENT_PARAMS = 5; +const std::string DEVICE_STREAM_INFO_PREFIX = "CAPS="; static DeviceType GetInternalDeviceType(PnpDeviceType pnpDeviceType) { @@ -80,6 +82,33 @@ static DeviceType GetInternalDeviceType(PnpDeviceType pnpDeviceType) return internalDeviceType; } +static std::list ParseDeviceStreamInfo(const std::string &info) +{ + std::string deviceStreamInfoStr; + auto pos = info.find(DEVICE_STREAM_INFO_PREFIX); + CHECK_AND_RETURN_RET_LOG(pos != std::string::npos, {}, "invalid info"); + pos += DEVICE_STREAM_INFO_PREFIX.length(); + auto endPos = info.find(";", pos); + deviceStreamInfoStr = endPos == std::string::npos ? info.substr(pos) : info.substr(pos, endPos - pos); + AUDIO_INFO_LOG("deviceStreamInfo: %{public}s", deviceStreamInfoStr.c_str()); + return DeviceStreamInfo::DeserializeList(deviceStreamInfoStr); +} + +static void ReceiveRemoteOffloadInfo(std::string &info, DStatusInfo &statusInfo) +{ + if (statusInfo.isConnected) { + CHECK_AND_RETURN(info.find(DEVICE_STREAM_INFO_PREFIX) != std::string::npos); + auto deviceStreamInfoList = ParseDeviceStreamInfo(info); + AUDIO_INFO_LOG("device stream info size: %{public}zu", deviceStreamInfoList.size()); + statusInfo.streamInfo = deviceStreamInfoList; + std::list supportDevices = { "Distributed_Output" }; + AudioCoreService::GetCoreService()->UpdateStreamPropInfo("remote", "offload_distributed_output", + deviceStreamInfoList, supportDevices); + } else { + AudioCoreService::GetCoreService()->ClearStreamPropInfo("remote", "offload_distributed_output"); + } +} + static void ReceviceDistributedInfo(struct ServiceStatus* serviceStatus, std::string & info, DeviceStatusListener * devListener) { @@ -97,6 +126,7 @@ static void ReceviceDistributedInfo(struct ServiceStatus* serviceStatus, std::st } statusInfo.isConnected = (pnpEventType == PNP_EVENT_DEVICE_ADD) ? true : false; + ReceiveRemoteOffloadInfo(info, statusInfo); devListener->deviceObserver_.OnDeviceStatusUpdated(statusInfo); } else if (serviceStatus->status == SERVIE_STATUS_STOP) { AUDIO_DEBUG_LOG("distributed service offline"); diff --git a/services/audio_policy/server/domain/pipe/include/audio_definition_adapter_info.h b/services/audio_policy/server/domain/pipe/include/audio_definition_adapter_info.h index 7c0ebad7f3..c66f2fa722 100644 --- a/services/audio_policy/server/domain/pipe/include/audio_definition_adapter_info.h +++ b/services/audio_policy/server/domain/pipe/include/audio_definition_adapter_info.h @@ -132,6 +132,9 @@ class AdapterPipeInfo { public: void SelfCheck(); + void UpdateDynamicStreamProps(const std::list> &streamProps); + void ClearDynamicStreamProps(); + std::string name_ = STR_INITED; AudioPipeRole role_ = PIPE_ROLE_NONE; PaPropInfo paProp_ {}; @@ -144,6 +147,11 @@ public: std::weak_ptr adapterInfo_; std::list> streamPropInfos_ {}; std::list> attributeInfos_ {}; + + // for dynamic + std::mutex dynamicMtx_; + std::list> dynamicStreamPropInfos_ {}; + std::list supportDevices_ {}; }; class AdapterDeviceInfo { @@ -207,6 +215,15 @@ public: std::shared_ptr GetAdapterDeviceInfo(DeviceType type_, DeviceRole role_, const std::string &networkId_, uint32_t flags, int32_t a2dpOffloadFlag = 0); + void UpdateDynamicStreamProps(const std::string adapterName, const std::string &pipeName, + const std::list> &streamProps); + void ClearDynamicStreamProps(const std::string adapterName, const std::string &pipeName); + uint32_t GetConfigStreamPropsSize(const std::string adapterName, const std::string &pipeName) const; + uint32_t GetDynamicStreamPropsSize(const std::string adapterName, const std::string &pipeName) const; + + std::weak_ptr pipeInfo_; + std::list supportDevices_ {}; + std::unordered_map> adapterInfoMap {}; std::unordered_map, std::set>, PairHash> deviceInfoMap {}; diff --git a/services/audio_policy/server/domain/pipe/include/audio_policy_config_manager.h b/services/audio_policy/server/domain/pipe/include/audio_policy_config_manager.h index d76c4729b0..cbc7bb8817 100644 --- a/services/audio_policy/server/domain/pipe/include/audio_policy_config_manager.h +++ b/services/audio_policy/server/domain/pipe/include/audio_policy_config_manager.h @@ -57,6 +57,9 @@ public: // update void SetNormalVoipFlag(const bool &normalVoipFlag); + void UpdateStreamPropInfo(const std::string &adapterName, const std::string &pipeName, + const std::list &deviceStreamInfo, const std::list &supportDevices); + void ClearStreamPropInfo(const std::string &adapterName, const std::string &pipeName); // query bool GetModuleListByType(ClassType type, std::list& moduleList); @@ -84,6 +87,7 @@ public: bool IsFastStreamSupported(AudioStreamInfo &streamInfo, std::vector> &desc); bool GetFastStreamSupport(AudioStreamInfo &streamInfo, std::shared_ptr &deviceInfo); + uint32_t GetStreamPropInfoSize(const std::string &adapterName, const std::string &pipeName); uint32_t GetRouteFlag(std::shared_ptr &desc); void GetStreamPropInfo(std::shared_ptr &desc, std::shared_ptr &info); @@ -107,6 +111,8 @@ private: std::shared_ptr adapterPipeInfo, std::shared_ptr &info, const AudioChannel &tempChannel); std::shared_ptr GetNormalRecordAdapterInfo(std::shared_ptr desc); + std::shared_ptr GetDynamicStreamPropInfoFromPipe(std::shared_ptr &info, + AudioSampleFormat format, uint32_t sampleRate, AudioChannel channels); bool xmlHasLoaded_ = false; diff --git a/services/audio_policy/server/domain/pipe/src/audio_definition_adapter_info.cpp b/services/audio_policy/server/domain/pipe/src/audio_definition_adapter_info.cpp index 5c2185aff5..46aed5d045 100644 --- a/services/audio_policy/server/domain/pipe/src/audio_definition_adapter_info.cpp +++ b/services/audio_policy/server/domain/pipe/src/audio_definition_adapter_info.cpp @@ -52,6 +52,16 @@ void AudioPolicyConfigData::SetDeviceInfoMap(std::list &pipeInfo_, std::unordered_map> &tmpDeviceInfoMap_) { + if (pipeInfo_->streamPropInfos_.size() == 0) { + AUDIO_INFO_LOG("dynamic setting"); + for (auto deviceName : pipeInfo_->supportDevices_) { + auto uniqueDeviceIt = tmpDeviceInfoMap_.find(deviceName); + CHECK_AND_CONTINUE_LOG(uniqueDeviceIt != tmpDeviceInfoMap_.end(), + "pipe needed device:%{public}s not exists.", deviceName.c_str()); + uniqueDeviceIt->second->supportPipeMap_.insert({pipeInfo_->supportFlags_, pipeInfo_}); + } + return; + } for (auto &streamPropInfo : pipeInfo_->streamPropInfos_) { for (auto deviceName : streamPropInfo->supportDevices_) { auto uniqueDeviceIt = tmpDeviceInfoMap_.find(deviceName); @@ -158,6 +168,71 @@ std::shared_ptr AudioPolicyConfigData::GetAdapterDeviceInfo( return nullptr; } +void AudioPolicyConfigData::UpdateDynamicStreamProps(const std::string adapterName, const std::string &pipeName, + const std::list> &streamProps) +{ + CHECK_AND_RETURN_LOG(!streamProps.empty(), "streamProps is empty"); + AudioAdapterType adapterType = PolicyAdapterInfo::GetAdapterType(adapterName); + CHECK_AND_RETURN_LOG(adapterInfoMap.count(adapterType) != 0, "adapter not exist"); + std::shared_ptr adapterInfo = adapterInfoMap[adapterType]; + CHECK_AND_RETURN_LOG(adapterInfo != nullptr, "adapterInfo is nullptr"); + std::shared_ptr pipeInfo = adapterInfo->GetPipeInfoByName(pipeName); + CHECK_AND_RETURN_LOG(pipeInfo != nullptr, "pipeInfo is nullptr"); + + std::unordered_map> tmpDeviceInfoMap; + for (auto &deviceInfo : adapterInfo->deviceInfos) { + tmpDeviceInfoMap.insert({deviceInfo->name_, deviceInfo}); + } + for (auto &streamProp : streamProps) { + CHECK_AND_RETURN_LOG(streamProp != nullptr, "streamProp is nullptr"); + streamProp->pipeInfo_ = pipeInfo; + for (auto deviceName : streamProp->supportDevices_) { + auto uniqueDeviceIt = tmpDeviceInfoMap.find(deviceName); + CHECK_AND_CONTINUE_LOG(uniqueDeviceIt != tmpDeviceInfoMap.end(), + "streamProp needed device %{public}s not exist", deviceName.c_str()); + streamProp->supportDeviceMap_.insert({uniqueDeviceIt->second->type_, uniqueDeviceIt->second}); + } + } + pipeInfo->UpdateDynamicStreamProps(streamProps); +} + +void AudioPolicyConfigData::ClearDynamicStreamProps(const std::string adapterName, const std::string &pipeName) +{ + AudioAdapterType adapterType = PolicyAdapterInfo::GetAdapterType(adapterName); + CHECK_AND_RETURN_LOG(adapterInfoMap.count(adapterType) != 0, "adapter not exist"); + std::shared_ptr adapterInfo = adapterInfoMap[adapterType]; + CHECK_AND_RETURN_LOG(adapterInfo != nullptr, "adapterInfo is nullptr"); + std::shared_ptr pipeInfo = adapterInfo->GetPipeInfoByName(pipeName); + CHECK_AND_RETURN_LOG(pipeInfo != nullptr, "pipeInfo is nullptr"); + pipeInfo->ClearDynamicStreamProps(); +} + +uint32_t AudioPolicyConfigData::GetConfigStreamPropsSize(const std::string adapterName, + const std::string &pipeName) const +{ + AudioAdapterType adapterType = PolicyAdapterInfo::GetAdapterType(adapterName); + auto it = adapterInfoMap.find(adapterType); + CHECK_AND_RETURN_RET_LOG(it != adapterInfoMap.end(), 0, "adapter not exist"); + std::shared_ptr adapterInfo = it->second; + CHECK_AND_RETURN_RET_LOG(adapterInfo != nullptr, 0, "adapterInfo is nullptr"); + std::shared_ptr pipeInfo = adapterInfo->GetPipeInfoByName(pipeName); + CHECK_AND_RETURN_RET_LOG(pipeInfo != nullptr, 0, "pipeInfo is nullptr"); + return pipeInfo->streamPropInfos_.size(); +} + +uint32_t AudioPolicyConfigData::GetDynamicStreamPropsSize(const std::string adapterName, + const std::string &pipeName) const +{ + AudioAdapterType adapterType = PolicyAdapterInfo::GetAdapterType(adapterName); + auto it = adapterInfoMap.find(adapterType); + CHECK_AND_RETURN_RET_LOG(it != adapterInfoMap.end(), 0, "adapter not exist"); + std::shared_ptr adapterInfo = it->second; + CHECK_AND_RETURN_RET_LOG(adapterInfo != nullptr, 0, "adapterInfo is nullptr"); + std::shared_ptr pipeInfo = adapterInfo->GetPipeInfoByName(pipeName); + CHECK_AND_RETURN_RET_LOG(pipeInfo != nullptr, 0, "pipeInfo is nullptr"); + return pipeInfo->dynamicStreamPropInfos_.size(); +} + AudioAdapterType PolicyAdapterInfo::GetTypeEnum() { return GetAdapterType(adapterName); @@ -263,6 +338,19 @@ void AdapterPipeInfo::SelfCheck() } } +void AdapterPipeInfo::UpdateDynamicStreamProps(const std::list> &streamProps) +{ + CHECK_AND_RETURN_LOG(streamProps.size() != 0, "streamProps is empty"); + std::lock_guard lock(dynamicMtx_); + dynamicStreamPropInfos_ = streamProps; +} + +void AdapterPipeInfo::ClearDynamicStreamProps() +{ + std::lock_guard lock(dynamicMtx_); + dynamicStreamPropInfos_.clear(); +} + void PipeStreamPropInfo::SelfCheck() { std::shared_ptr pipeInfoPtr = pipeInfo_.lock(); diff --git a/services/audio_policy/server/domain/pipe/src/audio_pipe_selector.cpp b/services/audio_policy/server/domain/pipe/src/audio_pipe_selector.cpp index acc22837cf..843528c8db 100644 --- a/services/audio_policy/server/domain/pipe/src/audio_pipe_selector.cpp +++ b/services/audio_policy/server/domain/pipe/src/audio_pipe_selector.cpp @@ -20,6 +20,7 @@ #include "audio_stream_collector.h" #include "audio_stream_info.h" #include "audio_definition_adapter_info.h" +#include "audio_policy_utils.h" #include namespace OHOS { @@ -35,6 +36,17 @@ static std::map flagPipeTypeMap_ = { {AUDIO_OUTPUT_FLAG_DIRECT, PIPE_TYPE_DIRECT_OUT}, }; +static bool IsRemoteOffloadNeedRecreate(std::shared_ptr newPipe, std::shared_ptr oldPipe) +{ + CHECK_AND_RETURN_RET(newPipe != nullptr && oldPipe != nullptr, false); + CHECK_AND_RETURN_RET(newPipe->moduleInfo_.className == "remote_offload" && + oldPipe->moduleInfo_.className == "remote_offload", false); + return (newPipe->moduleInfo_.format != oldPipe->moduleInfo_.format) || + (newPipe->moduleInfo_.rate != oldPipe->moduleInfo_.rate) || + (newPipe->moduleInfo_.channels != oldPipe->moduleInfo_.channels) || + (newPipe->moduleInfo_.bufferSize != oldPipe->moduleInfo_.bufferSize); +} + AudioPipeSelector::AudioPipeSelector() : configManager_(AudioPolicyConfigManager::GetInstance()) { } @@ -328,6 +340,37 @@ std::string AudioPipeSelector::GetAdapterNameByStreamDesc(std::shared_ptr pipeInfoPtr, + std::shared_ptr streamDesc, std::shared_ptr streamPropInfo) +{ + if (pipeInfoPtr->name_ == "multichannel_output") { + info.moduleInfo_.className = "multichannel"; + info.moduleInfo_.fileName = "mch_dump_file"; + info.moduleInfo_.fixedLatency = "1"; // for fix max request + info.moduleInfo_.bufferSize = + std::to_string(((streamPropInfo->bufferSize_ / std::stoul(info.moduleInfo_.channels)) * STEREO)); + AUDIO_INFO_LOG("Buffer size: %{public}s", info.moduleInfo_.bufferSize.c_str()); + } else if (pipeInfoPtr->name_ == "offload_output") { + info.moduleInfo_.className = "offload"; + info.moduleInfo_.offloadEnable = "1"; + info.moduleInfo_.fixedLatency = "1"; + info.moduleInfo_.fileName = "offload_dump_file"; + } else if (pipeInfoPtr->name_ == "dp_multichannel_output") { + info.moduleInfo_.className = "dp_multichannel"; + info.moduleInfo_.fileName = "mch_dump_file"; + info.moduleInfo_.fixedLatency = "1"; + info.moduleInfo_.bufferSize = std::to_string(streamPropInfo->bufferSize_); + } else if (pipeInfoPtr->name_ == "offload_distributed_output") { + info.moduleInfo_.className = "remote_offload"; + info.moduleInfo_.offloadEnable = "1"; + info.moduleInfo_.fixedLatency = "1"; + info.moduleInfo_.fileName = "remote_offload_dump_file"; + info.moduleInfo_.name = + AudioPolicyUtils::GetInstance().GetRemoteModuleName(streamDesc->newDeviceDescs_[0]->networkId_, + AudioPolicyUtils::GetInstance().GetDeviceRole(streamDesc->newDeviceDescs_[0]->deviceType_)) + "_offload"; + } +} + void AudioPipeSelector::ConvertStreamDescToPipeInfo(std::shared_ptr streamDesc, std::shared_ptr streamPropInfo, AudioPipeInfo &info) { @@ -357,24 +400,7 @@ void AudioPipeSelector::ConvertStreamDescToPipeInfo(std::shared_ptrname_.c_str()); - if (pipeInfoPtr->name_ == "multichannel_output") { - info.moduleInfo_.className = "multichannel"; - info.moduleInfo_.fileName = "mch_dump_file"; - info.moduleInfo_.fixedLatency = "1"; // for fix max request - info.moduleInfo_.bufferSize = - std::to_string(((streamPropInfo->bufferSize_ / std::stoul(info.moduleInfo_.channels)) * STEREO)); - AUDIO_INFO_LOG("Buffer size: %{public}s", info.moduleInfo_.bufferSize.c_str()); - } else if (pipeInfoPtr->name_ == "offload_output") { - info.moduleInfo_.className = "offload"; - info.moduleInfo_.offloadEnable = "1"; - info.moduleInfo_.fixedLatency = "1"; - info.moduleInfo_.fileName = "offload_dump_file"; - } else if (pipeInfoPtr->name_ == "dp_multichannel_output") { - info.moduleInfo_.className = "dp_multichannel"; - info.moduleInfo_.fileName = "mch_dump_file"; - info.moduleInfo_.fixedLatency = "1"; - info.moduleInfo_.bufferSize = std::to_string(streamPropInfo->bufferSize_); - } + FillSpecialPipeInfo(info, pipeInfoPtr, streamDesc, streamPropInfo); info.moduleInfo_.deviceType = std::to_string(streamDesc->newDeviceDescs_[0]->deviceType_); info.moduleInfo_.networkId = streamDesc->newDeviceDescs_[0]->networkId_; @@ -391,6 +417,7 @@ void AudioPipeSelector::ConvertStreamDescToPipeInfo(std::shared_ptr newPipe, std::shared_ptr oldPipe) { + CHECK_AND_RETURN_RET(!IsRemoteOffloadNeedRecreate(newPipe, oldPipe), AUDIO_STREAM_ACTION_RECREATE); if (newPipe->adapterName_ == oldPipe->adapterName_ && newPipe->routeFlag_ == oldPipe->routeFlag_) { return AUDIO_STREAM_ACTION_DEFAULT; } diff --git a/services/audio_policy/server/domain/pipe/src/audio_policy_config_manager.cpp b/services/audio_policy/server/domain/pipe/src/audio_policy_config_manager.cpp index df4c529593..15aa029c48 100644 --- a/services/audio_policy/server/domain/pipe/src/audio_policy_config_manager.cpp +++ b/services/audio_policy/server/domain/pipe/src/audio_policy_config_manager.cpp @@ -38,6 +38,8 @@ const int32_t DEFAULT_MAX_FAST_NORMAL_INSTANCES = 6; const uint32_t PC_MIC_CHANNEL_NUM = 4; const uint32_t HEADPHONE_CHANNEL_NUM = 2; +const uint32_t FRAMES_PER_SEC = 50; + bool AudioPolicyConfigManager::Init(bool isRefresh) { if (xmlHasLoaded_ && !isRefresh) { @@ -165,6 +167,48 @@ void AudioPolicyConfigManager::OnHasEarpiece() audioDeviceManager_.UpdateEarpieceStatus(hasEarpiece_); } +static void ConvertDeviceStreamInfoToStreamPropInfo(const DeviceStreamInfo &deviceStreamInfo, + std::list> &streamPropInfos) +{ + for (const auto &rate : deviceStreamInfo.samplingRate) { + for (const auto &layout : deviceStreamInfo.channelLayout) { + std::shared_ptr streamProp = std::make_shared(); + CHECK_AND_RETURN_LOG(streamProp != nullptr, "alloc fail"); + streamProp->format_ = deviceStreamInfo.format; + streamProp->sampleRate_ = static_cast(rate); + streamProp->channelLayout_ = layout; + streamProp->channels_ = AudioDefinitionPolicyUtils::ConvertLayoutToAudioChannel(layout); + streamProp->bufferSize_ = AudioDefinitionPolicyUtils::PcmFormatToBytes(streamProp->format_) * + streamProp->sampleRate_ * streamProp->channels_ / FRAMES_PER_SEC; + streamPropInfos.push_back(streamProp); + } + } +} + +void AudioPolicyConfigManager::UpdateStreamPropInfo(const std::string &adapterName, const std::string &pipeName, + const std::list &deviceStreamInfo, const std::list &supportDevices) +{ + CHECK_AND_RETURN_LOG(deviceStreamInfo.size() > 0, "deviceStreamInfo is empty"); + std::list> streamProps; + for (auto &deviceStream : deviceStreamInfo) { + std::list> tmpStreamProps; + ConvertDeviceStreamInfoToStreamPropInfo(deviceStream, tmpStreamProps); + streamProps.splice(streamProps.end(), tmpStreamProps); + } + for (auto &streamProp : streamProps) { + for (auto &deviceName : supportDevices) { + CHECK_AND_CONTINUE_LOG(streamProp != nullptr, "streamProp is nullptr"); + streamProp->supportDevices_.push_back(deviceName); + } + } + audioPolicyConfig_.UpdateDynamicStreamProps(adapterName, pipeName, streamProps); +} + +void AudioPolicyConfigManager::ClearStreamPropInfo(const std::string &adapterName, const std::string &pipeName) +{ + audioPolicyConfig_.ClearDynamicStreamProps(adapterName, pipeName); +} + void AudioPolicyConfigManager::SetNormalVoipFlag(const bool &normalVoipFlag) { normalVoipFlag_ = normalVoipFlag; @@ -402,6 +446,14 @@ bool AudioPolicyConfigManager::GetFastStreamSupport(AudioStreamInfo &streamInfo, return false; } +uint32_t AudioPolicyConfigManager::GetStreamPropInfoSize(const std::string &adapterName, const std::string &pipeName) +{ + uint32_t size = audioPolicyConfig_.GetConfigStreamPropsSize(adapterName, pipeName); + CHECK_AND_RETURN_RET(size == 0, size); + AUDIO_INFO_LOG("no stream prop config, get dynamic size"); + return audioPolicyConfig_.GetDynamicStreamPropsSize(adapterName, pipeName); +} + uint32_t AudioPolicyConfigManager::GetRouteFlag(std::shared_ptr &desc) { // device -> adapter -> flag -> stream @@ -566,9 +618,31 @@ void AudioPolicyConfigManager::GetStreamPropInfo(std::shared_ptr AudioPolicyConfigManager::GetDynamicStreamPropInfoFromPipe( + std::shared_ptr &info, AudioSampleFormat format, uint32_t sampleRate, AudioChannel channels) +{ + std::unique_lock lock(info->dynamicMtx_); + CHECK_AND_RETURN_RET(info && !info->dynamicStreamPropInfos_.empty(), nullptr); + + std::shared_ptr defaultStreamProp = nullptr; + AUDIO_INFO_LOG("use dynamic streamProp"); + for (auto &streamProp : info->dynamicStreamPropInfos_) { + CHECK_AND_CONTINUE(streamProp->format_ == format && streamProp->channels_ == channels && + streamProp->sampleRate_ >= sampleRate); + CHECK_AND_RETURN_RET(streamProp->sampleRate_ != sampleRate, streamProp); + CHECK_AND_CONTINUE(defaultStreamProp != nullptr && + defaultStreamProp->sampleRate_ < streamProp->sampleRate_); + defaultStreamProp = streamProp; + } + return defaultStreamProp; +} + std::shared_ptr AudioPolicyConfigManager::GetStreamPropInfoFromPipe( std::shared_ptr &info, AudioSampleFormat format, uint32_t sampleRate, AudioChannel channels) { + std::shared_ptr propInfo = GetDynamicStreamPropInfoFromPipe(info, format, sampleRate, channels); + CHECK_AND_RETURN_RET(propInfo == nullptr, propInfo); + for (auto &streamProp : info->streamPropInfos_) { if (streamProp->format_ == format && streamProp->sampleRate_ == sampleRate && 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 ed333666ba..97c807b2c6 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 @@ -1713,7 +1713,7 @@ std::string AudioAdapterManager::GetModuleArgs(const AudioModuleInfo &audioModul std::string AudioAdapterManager::GetHdiSinkIdInfo(const AudioModuleInfo &audioModuleInfo) const { - if (audioModuleInfo.className == "remote") { + if (audioModuleInfo.className == "remote" || audioModuleInfo.className == "remote_offload") { return audioModuleInfo.networkId; } return HDI_ID_INFO_DEFAULT; diff --git a/services/audio_policy/server/infra/config/parser/src/audio_policy_config_parser.cpp b/services/audio_policy/server/infra/config/parser/src/audio_policy_config_parser.cpp index c3e697ed4b..eb9241e3b7 100644 --- a/services/audio_policy/server/infra/config/parser/src/audio_policy_config_parser.cpp +++ b/services/audio_policy/server/infra/config/parser/src/audio_policy_config_parser.cpp @@ -152,8 +152,7 @@ void AudioPolicyConfigParser::ParsePipes(std::shared_ptr curNode, while (curNode->IsNodeValid()) { if (curNode->IsElementNode()) { - AdapterPipeInfo pipeInfo {}; - std::shared_ptr pipeInfoPtr = std::make_shared(pipeInfo); + std::shared_ptr pipeInfoPtr = std::make_shared(); pipeInfoPtr->adapterInfo_ = adapterInfo; curNode->GetProp("name", pipeInfoPtr->name_); if (pipeInfoPtr->name_.find(FAST_DISTRIBUTE_TAG) != string::npos) { @@ -164,6 +163,11 @@ void AudioPolicyConfigParser::ParsePipes(std::shared_ptr curNode, std::string pipeRole; curNode->GetProp("role", pipeRole); pipeInfoPtr->role_ = AudioDefinitionPolicyUtils::pipeRoleStrToEnum[pipeRole]; + std::string supportDevicesStr; + curNode->GetProp("supportDevices", supportDevicesStr); + if (supportDevicesStr != "") { + SplitStringToList(supportDevicesStr, pipeInfoPtr->supportDevices_, ", "); + } ParsePipeInfos(curNode->GetCopyNode(), pipeInfoPtr); pipeInfos.push_back(pipeInfoPtr); } @@ -674,7 +678,7 @@ void AudioPolicyConfigParser::GetCommontAudioModuleInfo(std::shared_ptrstreamPropInfos_) { audioModuleInfo.supportedRate_.insert(streamPropInfo->sampleRate_); - audioModuleInfo.supportedChannels_.insert(streamPropInfo->channels_); + audioModuleInfo.supportedChannelLayout_.insert(streamPropInfo->channelLayout_); } audioModuleInfo.lib = pipeInfo->paProp_.lib_; diff --git a/services/audio_policy/server/infra/config/parser/src/audio_policy_parser.cpp b/services/audio_policy/server/infra/config/parser/src/audio_policy_parser.cpp index 828a422006..5d538be42f 100644 --- a/services/audio_policy/server/infra/config/parser/src/audio_policy_parser.cpp +++ b/services/audio_policy/server/infra/config/parser/src/audio_policy_parser.cpp @@ -155,7 +155,7 @@ void AudioPolicyParser::GetCommontAudioModuleInfo(PipeInfo &pipeInfo, AudioModul audioModuleInfo.supportedRate_.insert(sampleRate); } for (auto channelLayout : pipeInfo.channelLayouts_) { - audioModuleInfo.supportedChannels_.insert(channelLayout); + audioModuleInfo.supportedChannelLayout_.insert(channelLayout); } audioModuleInfo.lib = pipeInfo.lib_; 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 a2c829d762..7d38e85883 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 @@ -46,6 +46,12 @@ #include "audio_event_utils.h" namespace OHOS { namespace AudioStandard { +enum OffloadType { + LOCAL_OFFLOAD, + REMOTE_OFFLOAD, + OFFLOAD_TYPE_NUM, +}; + class AudioA2dpOffloadManager; class AudioCoreService : public enable_shared_from_this { public: @@ -244,6 +250,9 @@ private: void SetAudioServerProxy(); bool GetDisableFastStreamParam(); bool IsFastAllowed(std::string &bundleName); + void UpdateStreamPropInfo(const std::string &adapterName, const std::string &pipeName, + const std::list &deviceStreamInfo, const std::list &supportDevices); + void ClearStreamPropInfo(const std::string &adapterName, const std::string &pipeName); private: static std::string GetEncryptAddr(const std::string &addr); @@ -299,7 +308,8 @@ private: std::shared_ptr pipeInfo, const AudioStreamDeviceChangeReasonExt reason = AudioStreamDeviceChangeReason::UNKNOWN); int32_t MoveToRemoteOutputDevice( - std::vector sinkInputIds, std::shared_ptr remoteDeviceDescriptor); + std::vector sinkInputIds, std::shared_ptr pipeInfo, + std::shared_ptr remoteDeviceDescriptor); void MoveStreamSource(std::shared_ptr streamDesc); void MoveToNewInputDevice(std::shared_ptr streamDesc); int32_t MoveToLocalInputDevice( @@ -368,8 +378,8 @@ private: bool NeedRehandleA2DPDevice(std::shared_ptr &desc); void UpdateTracker(AudioMode &mode, AudioStreamChangeInfo &streamChangeInfo, RendererState rendererState); void HandleCommonSourceOpened(std::shared_ptr &pipeInfo); - void DelayReleaseOffloadPipe(AudioIOHandle id, uint32_t paIndex); - int32_t ReleaseOffloadPipe(AudioIOHandle id, uint32_t paIndex); + void DelayReleaseOffloadPipe(AudioIOHandle id, uint32_t paIndex, OffloadType type); + int32_t ReleaseOffloadPipe(AudioIOHandle id, uint32_t paIndex, OffloadType type); void CheckOffloadStream(AudioStreamChangeInfo &streamChangeInfo); void ReConfigOffloadStatus(uint32_t sessionId, std::shared_ptr &pipeInfo, std::string &oldSinkName); void PrepareMoveAttrs(std::shared_ptr &streamDesc, DeviceType &oldDeviceType, @@ -402,6 +412,8 @@ private: void CheckAndSetCurrentOutputDevice(std::shared_ptr &desc, int32_t sessionId); void CheckAndSetCurrentInputDevice(std::shared_ptr &desc); void ClearRingMuteWhenCallStart(bool pre, bool after); + void UpdateRemoteOffloadModuleName(std::shared_ptr pipeInfo, std::string &moduleName); + void UpdateOffloadState(std::shared_ptr pipeInfo); private: std::shared_ptr eventEntry_; std::shared_ptr audioPolicyServerHandler_ = nullptr; @@ -462,8 +474,8 @@ private: std::mutex serviceFlagMutex_; // offload delay release - std::atomic isOffloadOpened_ = false; - std::condition_variable offloadCloseCondition_; + std::atomic isOffloadOpened_[OFFLOAD_TYPE_NUM] = {}; + std::condition_variable offloadCloseCondition_[OFFLOAD_TYPE_NUM]; std::mutex offloadCloseMutex_; std::mutex offloadReOpenMutex_; 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 6b137ff82f..dc9ec48b9c 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 @@ -38,6 +38,14 @@ static const int32_t BLUETOOTH_FETCH_RESULT_CONTINUE = 1; static const int32_t BLUETOOTH_FETCH_RESULT_ERROR = 2; } +static bool IsRemoteOffloadActive(uint32_t remoteOffloadStreamPropSize, int32_t streamUsage) +{ + CHECK_AND_RETURN_RET_LOG(remoteOffloadStreamPropSize != 0 && streamUsage == STREAM_USAGE_MUSIC, false, + "Use normal for remote device or remotecast"); + AUDIO_INFO_LOG("remote offload active, music use offload"); + return true; +} + bool AudioCoreService::isBtListenerRegistered = false; bool AudioCoreService::isBtCrashed = false; #ifdef BLUETOOTH_ENABLE @@ -281,9 +289,11 @@ void AudioCoreService::UpdatePlaybackStreamFlag(std::shared_ptrnewDeviceDescs_.back()->deviceType_ == DEVICE_TYPE_REMOTE_CAST || - streamDesc->newDeviceDescs_.back()->networkId_ == "REMOTE_NETWORK_ID") { - streamDesc->audioFlag_ = AUDIO_OUTPUT_FLAG_NORMAL; - AUDIO_INFO_LOG("Use normal for remote device or remotecast"); + streamDesc->newDeviceDescs_.back()->networkId_ != LOCAL_NETWORK_ID) { + auto remoteOffloadStreamPropSize = policyConfigMananger_.GetStreamPropInfoSize("remote", + "offload_distributed_output"); + streamDesc->audioFlag_ = IsRemoteOffloadActive(remoteOffloadStreamPropSize, + streamDesc->rendererInfo_.streamUsage) ? AUDIO_OUTPUT_FLAG_LOWPOWER : AUDIO_OUTPUT_FLAG_NORMAL; return; } @@ -1236,5 +1246,16 @@ void AudioCoreService::BluetoothServiceCrashedCallback(pid_t pid, pid_t uid) Bluetooth::AudioHfpManager::DisconnectBluetoothHfpSink(); } #endif + +void AudioCoreService::UpdateStreamPropInfo(const std::string &adapterName, const std::string &pipeName, + const std::list &deviceStreamInfo, const std::list &supportDevices) +{ + policyConfigMananger_.UpdateStreamPropInfo(adapterName, pipeName, deviceStreamInfo, supportDevices); +} + +void AudioCoreService::ClearStreamPropInfo(const std::string &adapterName, const std::string &pipeName) +{ + policyConfigMananger_.ClearStreamPropInfo(adapterName, pipeName); +} } // namespace AudioStandard } // namespace OHOS 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 7ab83e98c0..76c36dc8d4 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 @@ -129,6 +129,16 @@ void AudioCoreService::UpdateActiveDeviceAndVolumeBeforeMoveSession( } } +void AudioCoreService::UpdateOffloadState(std::shared_ptr pipeInfo) +{ + CHECK_AND_RETURN(pipeInfo && pipeInfo->streamDescriptors_.size() > 0); + CHECK_AND_RETURN(pipeInfo->moduleInfo_.name == OFFLOAD_PRIMARY_SPEAKER || + pipeInfo->moduleInfo_.className == "remote_offload"); + OffloadType type = pipeInfo->moduleInfo_.className == "remote_offload" ? REMOTE_OFFLOAD : LOCAL_OFFLOAD; + isOffloadOpened_[type].store(true); + offloadCloseCondition_[type].notify_all(); +} + int32_t AudioCoreService::FetchRendererPipesAndExecute( std::vector> &streamDescs, const AudioStreamDeviceChangeReasonExt reason) { @@ -141,11 +151,7 @@ int32_t AudioCoreService::FetchRendererPipesAndExecute( CHECK_AND_CONTINUE_LOG(pipeInfo != nullptr, "pipeInfo is nullptr"); AUDIO_INFO_LOG("[PipeExecInfo] Scan Pipe adapter: %{public}s, name: %{public}s, action: %{public}d", pipeInfo->moduleInfo_.adapterName.c_str(), pipeInfo->name_.c_str(), pipeInfo->pipeAction_); - if (pipeInfo->moduleInfo_.name == OFFLOAD_PRIMARY_SPEAKER && - pipeInfo->streamDescriptors_.size() > 0) { - isOffloadOpened_.store(true); - offloadCloseCondition_.notify_all(); - } + UpdateOffloadState(pipeInfo); if (pipeInfo->pipeAction_ == PIPE_ACTION_UPDATE) { ProcessOutputPipeUpdate(pipeInfo, audioFlag, reason); } else if (pipeInfo->pipeAction_ == PIPE_ACTION_NEW) { @@ -572,11 +578,7 @@ int32_t AudioCoreService::FetchRendererPipeAndExecute(std::shared_ptrmoduleInfo_.adapterName.c_str(), pipeInfo->name_.c_str(), pipeInfo->pipeAction_); - if (pipeInfo->moduleInfo_.name == OFFLOAD_PRIMARY_SPEAKER && - pipeInfo->streamDescriptors_.size() > 0) { - isOffloadOpened_.store(true); - offloadCloseCondition_.notify_all(); - } + UpdateOffloadState(pipeInfo); if (pipeInfo->pipeAction_ == PIPE_ACTION_UPDATE) { ProcessOutputPipeUpdate(pipeInfo, audioFlag, reason); } else if (pipeInfo->pipeAction_ == PIPE_ACTION_NEW) { // new @@ -757,7 +759,8 @@ void AudioCoreService::RemoveUnusedPipe() CHECK_AND_CONTINUE_LOG(pipeInfo != nullptr, "pipeInfo is nullptr"); AUDIO_INFO_LOG("[PipeExecInfo] Remove and close Pipe %{public}s", pipeInfo->ToString().c_str()); if (pipeInfo->routeFlag_ & AUDIO_OUTPUT_FLAG_LOWPOWER) { - DelayReleaseOffloadPipe(pipeInfo->id_, pipeInfo->paIndex_); + OffloadType type = pipeInfo->moduleInfo_.className == "remote_offload" ? REMOTE_OFFLOAD : LOCAL_OFFLOAD; + DelayReleaseOffloadPipe(pipeInfo->id_, pipeInfo->paIndex_, type); continue; } audioPolicyManager_.CloseAudioPort(pipeInfo->id_, pipeInfo->paIndex_); @@ -859,9 +862,11 @@ void AudioCoreService::OnDeviceStatusUpdated(AudioDeviceDescriptor &updatedDesc, bool isActualConnection = (updatedDesc.connectState_ != VIRTUAL_CONNECTED); AUDIO_INFO_LOG("Device connection is actual connection: %{public}d", isActualConnection); - AudioStreamInfo streamInfo = updatedDesc.audioStreamInfo_.CheckParams() ? - AudioStreamInfo(*updatedDesc.audioStreamInfo_.samplingRate.rbegin(), updatedDesc.audioStreamInfo_.encoding, - updatedDesc.audioStreamInfo_.format, *updatedDesc.audioStreamInfo_.channels.rbegin()) : AudioStreamInfo(); + DeviceStreamInfo audioStreamInfo = updatedDesc.GetDeviceStreamInfo(); + std::set channels = audioStreamInfo.GetChannels(); + AudioStreamInfo streamInfo = audioStreamInfo.CheckParams() ? + AudioStreamInfo(*audioStreamInfo.samplingRate.rbegin(), audioStreamInfo.encoding, + audioStreamInfo.format, *channels.rbegin()) : AudioStreamInfo(); #ifdef BLUETOOTH_ENABLE if (devType == DEVICE_TYPE_BLUETOOTH_A2DP && isActualConnection && isConnected) { int32_t ret = Bluetooth::AudioA2dpManager::GetA2dpDeviceStreamInfo(macAddress, streamInfo); @@ -905,7 +910,7 @@ void AudioCoreService::MoveStreamSink(std::shared_ptr str auto ret = (newDeviceDesc->networkId_ == LOCAL_NETWORK_ID) ? MoveToLocalOutputDevice(targetSinkInputs, pipeInfo, newDeviceDesc) - : MoveToRemoteOutputDevice(targetSinkInputs, newDeviceDesc); + : MoveToRemoteOutputDevice(targetSinkInputs, pipeInfo, newDeviceDesc); audioIOHandleMap_.NotifyUnmutePort(); CHECK_AND_RETURN_LOG(ret == SUCCESS, "Move sink input %{public}d to device %{public}d failed!", streamDesc->sessionId_, newDeviceDesc->deviceType_); @@ -960,7 +965,7 @@ void AudioCoreService::MoveToNewOutputDevice(std::shared_ptrnetworkId_ == LOCAL_NETWORK_ID) ? MoveToLocalOutputDevice(targetSinkInputs, pipeInfo, newDeviceDesc) - : MoveToRemoteOutputDevice(targetSinkInputs, newDeviceDesc); + : MoveToRemoteOutputDevice(targetSinkInputs, pipeInfo, newDeviceDesc); if (ret != SUCCESS) { AudioPolicyUtils::GetInstance().UpdateEffectDefaultSink(oldDeviceType); AUDIO_ERR_LOG("Move sink input %{public}d to device %{public}d failed!", @@ -1006,7 +1011,15 @@ void AudioCoreService::OnForcedDeviceSelected(DeviceType devType, const std::str audioDeviceStatus_.OnForcedDeviceSelected(devType, macAddress); } +void AudioCoreService::UpdateRemoteOffloadModuleName(std::shared_ptr pipeInfo, std::string &moduleName) +{ + CHECK_AND_RETURN(pipeInfo && pipeInfo->moduleInfo_.className == "remote_offload"); + moduleName = pipeInfo->moduleInfo_.name; + AUDIO_INFO_LOG("remote offload, set module name %{public}s", moduleName.c_str()); +} + int32_t AudioCoreService::MoveToRemoteOutputDevice(std::vector sinkInputIds, + std::shared_ptr pipeInfo, std::shared_ptr remoteDeviceDescriptor) { AUDIO_INFO_LOG("Start for [%{public}zu] sink-inputs", sinkInputIds.size()); @@ -1021,6 +1034,7 @@ int32_t AudioCoreService::MoveToRemoteOutputDevice(std::vector sinkIn uint32_t sinkId = -1; // invalid sink id, use sink name instead. std::string moduleName = AudioPolicyUtils::GetInstance().GetRemoteModuleName(networkId, deviceRole); + UpdateRemoteOffloadModuleName(pipeInfo, moduleName); AUDIO_ERR_LOG("moduleName %{public}s", moduleName.c_str()); AudioIOHandle moduleId; @@ -2015,33 +2029,31 @@ void AudioCoreService::HandleCommonSourceOpened(std::shared_ptr & } } -void AudioCoreService::DelayReleaseOffloadPipe(AudioIOHandle id, uint32_t paIndex) +void AudioCoreService::DelayReleaseOffloadPipe(AudioIOHandle id, uint32_t paIndex, OffloadType type) { AUDIO_INFO_LOG("In"); - CHECK_AND_RETURN_LOG(isOffloadOpened_.load(), "Offload is already released"); - isOffloadOpened_.store(false); - auto unloadOffloadThreadFuc = [this, id, paIndex] { this->ReleaseOffloadPipe(id, paIndex); }; + CHECK_AND_RETURN_LOG(type < OFFLOAD_TYPE_NUM && isOffloadOpened_[type].load(), "Offload is already released"); + isOffloadOpened_[type].store(false); + auto unloadOffloadThreadFuc = [this, id, paIndex, type] { this->ReleaseOffloadPipe(id, paIndex, type); }; std::thread unloadOffloadThread(unloadOffloadThreadFuc); unloadOffloadThread.detach(); } -int32_t AudioCoreService::ReleaseOffloadPipe(AudioIOHandle id, uint32_t paIndex) +int32_t AudioCoreService::ReleaseOffloadPipe(AudioIOHandle id, uint32_t paIndex, OffloadType type) { AUDIO_INFO_LOG("unload offload module"); std::unique_lock lock(offloadCloseMutex_); // Try to wait 10 seconds before unloading the module, because the audio driver takes some time to process // the shutdown process.. - offloadCloseCondition_.wait_for(lock, std::chrono::seconds(WAIT_OFFLOAD_CLOSE_TIME_SEC), [this] () { - return isOffloadOpened_.load(); + CHECK_AND_RETURN_RET_LOG(type < OFFLOAD_TYPE_NUM, ERR_INVALID_PARAM, "invalid type"); + offloadCloseCondition_[type].wait_for(lock, std::chrono::seconds(WAIT_OFFLOAD_CLOSE_TIME_SEC), [this, type] () { + return isOffloadOpened_[type].load(); }); { std::lock_guard lk(offloadReOpenMutex_); - AUDIO_INFO_LOG("After wait, isOffloadOpened: %{public}d", isOffloadOpened_.load()); - if (isOffloadOpened_.load()) { - AUDIO_INFO_LOG("offload restart"); - return ERROR; - } + AUDIO_INFO_LOG("After wait, isOffloadOpened: %{public}d", isOffloadOpened_[type].load()); + CHECK_AND_RETURN_RET_LOG(!isOffloadOpened_[type].load(), ERROR, "offload restart"); AUDIO_INFO_LOG("Close hdi port id: %{public}u, index %{public}u", id, paIndex); audioPolicyManager_.CloseAudioPort(id, paIndex); pipeManager_->RemoveAudioPipeInfo(id); @@ -2073,7 +2085,7 @@ void AudioCoreService::ReConfigOffloadStatus(uint32_t sessionId, { AUDIO_INFO_LOG("new sink: %{public}s, old sink: %{public}s, sessionId: %{public}u", pipeInfo->moduleInfo_.name.c_str(), oldSinkName.c_str(), sessionId); - if (pipeInfo->moduleInfo_.name == OFFLOAD_PRIMARY_SPEAKER) { + if (pipeInfo->moduleInfo_.name == OFFLOAD_PRIMARY_SPEAKER || pipeInfo->moduleInfo_.className == "remote_offload") { audioOffloadStream_.SetOffloadStatus(sessionId); } else if (oldSinkName == OFFLOAD_PRIMARY_SPEAKER) { audioOffloadStream_.ResetOffloadStatus(sessionId); diff --git a/services/audio_policy/server/service/service_main/src/audio_policy_dump.cpp b/services/audio_policy/server/service/service_main/src/audio_policy_dump.cpp index dbca9c6076..f61d57ef27 100644 --- a/services/audio_policy/server/service/service_main/src/audio_policy_dump.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_policy_dump.cpp @@ -146,13 +146,19 @@ std::vector> AudioPolicyDump::GetDumpDevi conneceType_ = CONNECT_TYPE_DISTRIBUTED; } AppendFormat(dumpString, " - connect type:%s\n", AudioInfoDumpUtils::GetConnectTypeName(conneceType_).c_str()); - for (auto &samplingRate : devDesc->audioStreamInfo_.samplingRate) { - AppendFormat(dumpString, " - device sampleRates:%d\n", samplingRate); - } - for (auto &channel : devDesc->audioStreamInfo_.channels) { - AppendFormat(dumpString, " - device channels:%d\n", channel); + for (auto &streamInfo : devDesc->audioStreamInfo_) { + AppendFormat(dumpString, " - device sampleRates:"); + for (auto &samplingRate : streamInfo.samplingRate) { + AppendFormat(dumpString, "%d ", samplingRate); + } + AppendFormat(dumpString, "\n"); + AppendFormat(dumpString, " - device channelLayouts:"); + for (auto &layout : streamInfo.channelLayout) { + AppendFormat(dumpString, "%d ", layout); + } + AppendFormat(dumpString, "\n"); + AppendFormat(dumpString, " - device format:%d\n", streamInfo.format); } - AppendFormat(dumpString, " - device format:%d\n", devDesc->audioStreamInfo_.format); } return deviceDescs; } @@ -603,8 +609,8 @@ void AudioPolicyDump::XmlParsedDataMapDump(std::string &dumpString) AppendFormat(dumpString, " - rate:%u\n", rate); } - for (auto supportedChannel : deviceClassInfoIter.supportedChannels_) { - AppendFormat(dumpString, " - supportedChannel:%u\n", supportedChannel); + for (auto supportedChannelLayout : deviceClassInfoIter.supportedChannelLayout_) { + AppendFormat(dumpString, " - supportedChannelLayout:%u\n", supportedChannelLayout); } AppendFormat(dumpString, " -DeviceClassInfo : format:%s, channels:%s, bufferSize:%s, fixedLatency:%s, " diff --git a/services/audio_policy/server/service/service_main/src/audio_policy_service.cpp b/services/audio_policy/server/service/service_main/src/audio_policy_service.cpp index 45d823ee59..8ee032f8df 100644 --- a/services/audio_policy/server/service/service_main/src/audio_policy_service.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_policy_service.cpp @@ -685,7 +685,7 @@ int32_t AudioPolicyService::GetProcessDeviceInfo(const AudioProcessConfig &confi // check process in routerMap, return target device for it // put the currentActiveDevice_ in deviceinfo, so it can create with current using device. // genarate the unique deviceid? - deviceInfo.audioStreamInfo_ = targetStreamInfo; + deviceInfo.audioStreamInfo_ = { targetStreamInfo }; deviceInfo.deviceName_ = "mmap_device"; audioRouteMap_.GetNetworkIDInFastRouterMap(config.appInfo.appUid, deviceInfo.deviceRole_, deviceInfo.networkId_); deviceInfo.a2dpOffloadFlag_ = GetA2dpOffloadFlag(); @@ -704,9 +704,9 @@ int32_t AudioPolicyService::GetVoipDeviceInfo(const AudioProcessConfig &config, deviceInfo.deviceType_ = preferredDeviceList[0]->deviceType_; deviceInfo.deviceName_ = preferredDeviceList[0]->deviceName_; if (config.streamInfo.samplingRate <= SAMPLE_RATE_16000) { - deviceInfo.audioStreamInfo_ = {SAMPLE_RATE_16000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; + deviceInfo.audioStreamInfo_ = {{SAMPLE_RATE_16000, ENCODING_PCM, SAMPLE_S16LE, CH_LAYOUT_STEREO}}; } else { - deviceInfo.audioStreamInfo_ = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; + deviceInfo.audioStreamInfo_ = {{SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, CH_LAYOUT_STEREO}}; } if (type == AUDIO_FLAG_VOIP_DIRECT) { AUDIO_INFO_LOG("Direct VoIP stream, deviceInfo has been updated: deviceInfo.deviceType %{public}d", diff --git a/services/audio_policy/test/unittest/audio_a2dp_device_unit_test/src/audio_a2dp_device_unit_test.cpp b/services/audio_policy/test/unittest/audio_a2dp_device_unit_test/src/audio_a2dp_device_unit_test.cpp index 6e07b879f2..69f9a9a014 100644 --- a/services/audio_policy/test/unittest/audio_a2dp_device_unit_test/src/audio_a2dp_device_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_a2dp_device_unit_test/src/audio_a2dp_device_unit_test.cpp @@ -34,7 +34,7 @@ void AudioA2dpDeviceUnitTest::TearDown(void) {} HWTEST_F(AudioA2dpDeviceUnitTest, GetA2dpDeviceInfo_001, TestSize.Level1) { DeviceStreamInfo streamInfo(AudioSamplingRate::SAMPLE_RATE_44100, AudioEncodingType::ENCODING_PCM, - AudioSampleFormat::SAMPLE_S16LE, AudioChannel::STEREO); + AudioSampleFormat::SAMPLE_S16LE, AudioChannelLayout::CH_LAYOUT_STEREO); A2dpDeviceConfigInfo configInfo; configInfo.streamInfo = streamInfo; configInfo.absVolumeSupport = true; @@ -49,8 +49,8 @@ HWTEST_F(AudioA2dpDeviceUnitTest, GetA2dpDeviceInfo_001, TestSize.Level1) EXPECT_EQ(info.streamInfo.format, AudioSampleFormat::SAMPLE_S16LE); EXPECT_EQ(info.streamInfo.samplingRate.size(), 1); EXPECT_EQ(*info.streamInfo.samplingRate.begin(), AudioSamplingRate::SAMPLE_RATE_44100); - EXPECT_EQ(info.streamInfo.channels.size(), 1); - EXPECT_EQ(*info.streamInfo.channels.begin(), AudioChannel::STEREO); + EXPECT_EQ(info.streamInfo.channelLayout.size(), 1); + EXPECT_EQ(*info.streamInfo.channelLayout.begin(), AudioChannelLayout::CH_LAYOUT_STEREO); EXPECT_TRUE(info.absVolumeSupport); EXPECT_EQ(info.volumeLevel, 50); EXPECT_FALSE(info.mute); @@ -80,7 +80,7 @@ HWTEST_F(AudioA2dpDeviceUnitTest, GetA2dpDeviceInfo_002, TestSize.Level1) HWTEST_F(AudioA2dpDeviceUnitTest, GetA2dpInDeviceInfo_001, TestSize.Level1) { DeviceStreamInfo streamInfo(AudioSamplingRate::SAMPLE_RATE_44100, AudioEncodingType::ENCODING_PCM, - AudioSampleFormat::SAMPLE_S16LE, AudioChannel::STEREO); + AudioSampleFormat::SAMPLE_S16LE, AudioChannelLayout::CH_LAYOUT_STEREO); A2dpDeviceConfigInfo configInfo; configInfo.streamInfo = streamInfo; configInfo.absVolumeSupport = true; @@ -95,8 +95,8 @@ HWTEST_F(AudioA2dpDeviceUnitTest, GetA2dpInDeviceInfo_001, TestSize.Level1) EXPECT_EQ(info.streamInfo.format, AudioSampleFormat::SAMPLE_S16LE); EXPECT_EQ(info.streamInfo.samplingRate.size(), 1); EXPECT_EQ(*info.streamInfo.samplingRate.begin(), AudioSamplingRate::SAMPLE_RATE_44100); - EXPECT_EQ(info.streamInfo.channels.size(), 1); - EXPECT_EQ(*info.streamInfo.channels.begin(), AudioChannel::STEREO); + EXPECT_EQ(info.streamInfo.channelLayout.size(), 1); + EXPECT_EQ(*info.streamInfo.channelLayout.begin(), CH_LAYOUT_STEREO); EXPECT_TRUE(info.absVolumeSupport); EXPECT_EQ(info.volumeLevel, 50); EXPECT_FALSE(info.mute); diff --git a/services/audio_policy/test/unittest/audio_core_service_private_unit_test/src/audio_core_service_private_unit_test.cpp b/services/audio_policy/test/unittest/audio_core_service_private_unit_test/src/audio_core_service_private_unit_test.cpp index 8099414572..fe54b3fd48 100644 --- a/services/audio_policy/test/unittest/audio_core_service_private_unit_test/src/audio_core_service_private_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_core_service_private_unit_test/src/audio_core_service_private_unit_test.cpp @@ -2049,5 +2049,36 @@ HWTEST(AudioCoreServicePrivateTest, IsStreamSupportLowpower_002, TestSize.Level1 bool isSupportLowPower = audioCoreService->IsStreamSupportLowpower(streamDesc); EXPECT_EQ(isSupportLowPower, false); } + +/** + * @tc.name : Test AudioCoreService. + * @tc.number: AudioCoreServicePrivate_122 + * @tc.desc : Test AudioCoreService::ReConfigOffloadStatus + */ +HWTEST(AudioCoreServicePrivateTest, AudioCoreServicePrivate_122, TestSize.Level1) +{ + auto audioCoreService = std::make_shared(); + ASSERT_NE(audioCoreService, nullptr); + std::shared_ptr pipeInfo = std::make_shared(); + ASSERT_NE(pipeInfo, nullptr); + std::string sinkName = "test"; + + pipeInfo->moduleInfo_.name = "test"; + pipeInfo->moduleInfo_.className = "test"; + audioCoreService->ReConfigOffloadStatus(0, pipeInfo, sinkName); + + pipeInfo->moduleInfo_.name = "test"; + pipeInfo->moduleInfo_.className = "remote_offload"; + audioCoreService->ReConfigOffloadStatus(0, pipeInfo, sinkName); + + pipeInfo->moduleInfo_.name = "Offload_Speaker"; + pipeInfo->moduleInfo_.className = "test"; + audioCoreService->ReConfigOffloadStatus(0, pipeInfo, sinkName); + + pipeInfo->moduleInfo_.name = "Offload_Speaker"; + pipeInfo->moduleInfo_.className = "remote_offload"; + audioCoreService->ReConfigOffloadStatus(0, pipeInfo, sinkName); + EXPECT_EQ(audioCoreService->audioOffloadStream_.offloadSessionID_.has_value(), true); +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/test/unittest/audio_definition_adapter_info_unit_test/src/audio_definition_adapter_info_unit_test.cpp b/services/audio_policy/test/unittest/audio_definition_adapter_info_unit_test/src/audio_definition_adapter_info_unit_test.cpp index 3137eb8ef5..d1ec5e294c 100644 --- a/services/audio_policy/test/unittest/audio_definition_adapter_info_unit_test/src/audio_definition_adapter_info_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_definition_adapter_info_unit_test/src/audio_definition_adapter_info_unit_test.cpp @@ -336,5 +336,61 @@ HWTEST(AudioDefinitionAdapterInfoUnitTest, AudioPolicyConfigData_007, TestSize.L auto ret = audioPolicyConfigData->GetAdapterDeviceInfo(type_, role_, networkId_, flags); EXPECT_EQ(ret, nullptr); } + +/** +* @tc.name : Test AudioDefinitionAdapterInfoUnitTest. +* @tc.number: AudioPolicyConfigData_008 +* @tc.desc : Test GetAdapterType +*/ +HWTEST(AudioDefinitionAdapterInfoUnitTest, AudioPolicyConfigData_008, TestSize.Level1) +{ + auto audioPolicyConfigData = std::make_shared(); + EXPECT_NE(audioPolicyConfigData, nullptr); + + DeviceType type_ = DEVICE_TYPE_REMOTE_CAST; + DeviceRole role_ = INPUT_DEVICE; + std::string networkId_ = LOCAL_NETWORK_ID; + uint32_t flags = 0; + + std::pair deviceMapKey = std::make_pair(DEVICE_TYPE_SPEAKER, role_); + + auto adapterDeviceInfo = std::make_shared(); + std::shared_ptr adapterInfo = std::make_shared(); + adapterInfo->adapterName = "abc"; + adapterDeviceInfo->adapterInfo_ = adapterInfo; + auto adapterDeviceInfo2 = std::make_shared(); + std::set> adapterDeviceInfoSet; + + adapterDeviceInfoSet.insert(adapterDeviceInfo); + adapterDeviceInfoSet.insert(adapterDeviceInfo2); + + audioPolicyConfigData->deviceInfoMap.insert({deviceMapKey, adapterDeviceInfoSet}); + auto ret = audioPolicyConfigData->GetAdapterDeviceInfo(type_, role_, networkId_, flags); + EXPECT_EQ(ret, nullptr); +} + +/** +* @tc.name : Test AudioDefinitionAdapterInfoUnitTest. +* @tc.number: AudioPolicyConfigData_009 +* @tc.desc : Test SetSupportDeviceAndPipeMap +*/ +HWTEST(AudioDefinitionAdapterInfoUnitTest, AudioPolicyConfigData_009, TestSize.Level1) +{ + auto audioPolicyConfigData = std::make_shared(); + EXPECT_NE(audioPolicyConfigData, nullptr); + auto pipeInfo = std::make_shared(); + EXPECT_NE(pipeInfo, nullptr); + pipeInfo->streamPropInfos_ = {}; + pipeInfo->supportDevices_.push_back("test"); + pipeInfo->supportDevices_.push_back("test1"); + std::unordered_map> deviceInfoMap; + deviceInfoMap["test"] = std::make_shared(); + audioPolicyConfigData->SetSupportDeviceAndPipeMap(pipeInfo, deviceInfoMap); + + auto pipeStreamPtr = std::make_shared(); + pipeInfo->streamPropInfos_.push_back(pipeStreamPtr); + audioPolicyConfigData->SetSupportDeviceAndPipeMap(pipeInfo, deviceInfoMap); + EXPECT_NE(deviceInfoMap["test"]->supportPipeMap_.size(), 0); +} } // namespace AudioStandard } // namespace OHOS \ No newline at end of file diff --git a/services/audio_policy/test/unittest/audio_device_status_unit_test/src/audio_device_status_unit_test.cpp b/services/audio_policy/test/unittest/audio_device_status_unit_test/src/audio_device_status_unit_test.cpp index afa5061204..bc1670f065 100644 --- a/services/audio_policy/test/unittest/audio_device_status_unit_test/src/audio_device_status_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_device_status_unit_test/src/audio_device_status_unit_test.cpp @@ -1320,5 +1320,28 @@ HWTEST_F(AudioDeviceStatusUnitTest, AudioDeviceStatus_062, TestSize.Level1) audioDeviceStatus.OnForcedDeviceSelected(devType, macAddress); EXPECT_NE(audioDeviceStatus.audioPolicyServerHandler_, nullptr); } + +/** +* @tc.name : Test AudioDeviceStatus. +* @tc.number: AudioDeviceStatus_063 +* @tc.desc : Test AddAudioDevice. +*/ +HWTEST_F(AudioDeviceStatusUnitTest, AudioDeviceStatus_063, TestSize.Level1) +{ + AudioModuleInfo info; + AudioDeviceStatus& audioDeviceStatus = AudioDeviceStatus::GetInstance(); + audioDeviceStatus.AddAudioDevice(info, DEVICE_TYPE_SPEAKER); + info = {}; + info.supportedRate_.insert(CH_LAYOUT_STEREO); + audioDeviceStatus.AddAudioDevice(info, DEVICE_TYPE_SPEAKER); + info = {}; + info.supportedChannelLayout_.insert(SAMPLE_RATE_48000); + audioDeviceStatus.AddAudioDevice(info, DEVICE_TYPE_SPEAKER); + info = {}; + info.supportedRate_.insert(CH_LAYOUT_STEREO); + info.supportedChannelLayout_.insert(SAMPLE_RATE_48000); + audioDeviceStatus.AddAudioDevice(info, DEVICE_TYPE_SPEAKER); + EXPECT_NE(audioDeviceStatus.audioConnectedDevice_.connectedDevices_.size(), 0); +} } // namespace AudioStandard } // namespace OHOS \ No newline at end of file diff --git a/services/audio_policy/test/unittest/audio_pipe_selector_unit_test/src/audio_pipe_selector_unit_test.cpp b/services/audio_policy/test/unittest/audio_pipe_selector_unit_test/src/audio_pipe_selector_unit_test.cpp index 7d3dda3561..ef53c23a8a 100644 --- a/services/audio_policy/test/unittest/audio_pipe_selector_unit_test/src/audio_pipe_selector_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_pipe_selector_unit_test/src/audio_pipe_selector_unit_test.cpp @@ -336,6 +336,16 @@ HWTEST_F(AudioPipeSelectorUnitTest, ConvertStreamDescToPipeInfo_001, TestSize.Le auto audioPipeSelector = AudioPipeSelector::GetPipeSelector(); audioPipeSelector->ConvertStreamDescToPipeInfo(streamDesc, streamPropInfo, info); EXPECT_EQ(info.pipeRole_, PIPE_ROLE_OUTPUT); + + pipeInfoPtr->name_ = "multichannel_output"; + audioPipeSelector->ConvertStreamDescToPipeInfo(streamDesc, streamPropInfo, info); + EXPECT_EQ(info.pipeRole_, PIPE_ROLE_OUTPUT); + pipeInfoPtr->name_ = "offload_output"; + audioPipeSelector->ConvertStreamDescToPipeInfo(streamDesc, streamPropInfo, info); + EXPECT_EQ(info.pipeRole_, PIPE_ROLE_OUTPUT); + pipeInfoPtr->name_ = "offload_distributed_output"; + audioPipeSelector->ConvertStreamDescToPipeInfo(streamDesc, streamPropInfo, info); + EXPECT_EQ(info.pipeRole_, PIPE_ROLE_OUTPUT); } /** diff --git a/services/audio_policy/test/unittest/audio_policy_service_unit_test/src/audio_policy_service_thirdext_unit_test.cpp b/services/audio_policy/test/unittest/audio_policy_service_unit_test/src/audio_policy_service_thirdext_unit_test.cpp index 986cafe4df..226c04b728 100644 --- a/services/audio_policy/test/unittest/audio_policy_service_unit_test/src/audio_policy_service_thirdext_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_policy_service_unit_test/src/audio_policy_service_thirdext_unit_test.cpp @@ -1564,5 +1564,30 @@ HWTEST_F(AudioPolicyServiceFourthUnitTest, DfxMsgManagerActionTest_001, TestSize manager.reportQueue_.clear(); } +/** +* @tc.name : Test AudioDeviceDescriptor. +* @tc.number: AudioDeviceDescriptor_001 +* @tc.desc : Test AudioDeviceDescriptor. +*/ +HWTEST_F(AudioPolicyServiceFourthUnitTest, AudioDeviceDescriptor_001, TestSize.Level1) +{ + Parcel parcel; + std::shared_ptr audioDeviceDescriptor = std::make_shared(); + EXPECT_NE(audioDeviceDescriptor, nullptr); + audioDeviceDescriptor->deviceType_ = DEVICE_TYPE_NONE; + audioDeviceDescriptor->MarshallingToDeviceInfo(parcel, false, false, API_10); + EXPECT_NE(audioDeviceDescriptor->audioStreamInfo_.size(), 0); + + DeviceStreamInfo streamInfo; + audioDeviceDescriptor->audioStreamInfo_.push_back(streamInfo); + audioDeviceDescriptor->MarshallingToDeviceInfo(parcel, false, false, API_10); + EXPECT_NE(audioDeviceDescriptor->GetDeviceStreamInfo().samplingRate.size(), 0); + + streamInfo.samplingRate.insert(SAMPLE_RATE_44100); + streamInfo.channelLayout.insert(CH_LAYOUT_STEREO); + audioDeviceDescriptor->audioStreamInfo_.push_back(streamInfo); + audioDeviceDescriptor->MarshallingToDeviceInfo(parcel, false, false, API_10); + EXPECT_NE(audioDeviceDescriptor->GetDeviceStreamInfo().samplingRate.size(), 0); +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/src/audio_endpoint.cpp b/services/audio_service/server/src/audio_endpoint.cpp index 00dac8631c..e8e5e07a6f 100644 --- a/services/audio_service/server/src/audio_endpoint.cpp +++ b/services/audio_service/server/src/audio_endpoint.cpp @@ -541,18 +541,16 @@ void AudioEndpointInner::StartThread(const IAudioSinkAttr &attr) bool AudioEndpointInner::Config(const AudioDeviceDescriptor &deviceInfo) { - AUDIO_INFO_LOG("Role %{public}d, format %{public}d", deviceInfo.deviceRole_, deviceInfo.audioStreamInfo_.format); + AUDIO_INFO_LOG("Role %{public}d, format %{public}d", deviceInfo.deviceRole_, + deviceInfo.GetDeviceStreamInfo().format); deviceInfo_ = deviceInfo; - bool res = deviceInfo_.audioStreamInfo_.CheckParams(); + DeviceStreamInfo audioStreamInfo = deviceInfo_.GetDeviceStreamInfo(); + bool res = audioStreamInfo.CheckParams(); CHECK_AND_RETURN_RET_LOG(res, false, "samplingRate or channels size is 0"); - dstStreamInfo_ = { - *deviceInfo.audioStreamInfo_.samplingRate.rbegin(), - deviceInfo.audioStreamInfo_.encoding, - deviceInfo.audioStreamInfo_.format, - *deviceInfo.audioStreamInfo_.channels.rbegin() - }; - dstStreamInfo_.channelLayout = deviceInfo.audioStreamInfo_.channelLayout; + dstStreamInfo_ = { *audioStreamInfo.samplingRate.rbegin(), audioStreamInfo.encoding, audioStreamInfo.format, + *audioStreamInfo.GetChannels().rbegin() }; + dstStreamInfo_.channelLayout = *audioStreamInfo.channelLayout.rbegin(); if (deviceInfo.deviceRole_ == INPUT_DEVICE) { return ConfigInputPoint(deviceInfo); diff --git a/services/audio_service/server/src/audio_endpoint_separate.cpp b/services/audio_service/server/src/audio_endpoint_separate.cpp index cb007c6fcc..94dd354b11 100644 --- a/services/audio_service/server/src/audio_endpoint_separate.cpp +++ b/services/audio_service/server/src/audio_endpoint_separate.cpp @@ -180,17 +180,12 @@ bool AudioEndpointSeparate::Config(const AudioDeviceDescriptor &deviceInfo) } deviceInfo_ = deviceInfo; - if (!deviceInfo_.audioStreamInfo_.CheckParams()) { - AUDIO_ERR_LOG("%{public}s samplingRate or channels size is 0", __func__); - return false; - } - dstStreamInfo_ = { - *deviceInfo.audioStreamInfo_.samplingRate.rbegin(), - deviceInfo.audioStreamInfo_.encoding, - deviceInfo.audioStreamInfo_.format, - *deviceInfo.audioStreamInfo_.channels.rbegin() - }; - dstStreamInfo_.channelLayout = deviceInfo.audioStreamInfo_.channelLayout; + DeviceStreamInfo audioStreamInfo = deviceInfo_.GetDeviceStreamInfo(); + CHECK_AND_RETURN_RET_LOG(audioStreamInfo.CheckParams(), false, "samplingRate or channels size is 0"); + std::set channels = audioStreamInfo.GetChannels(); + dstStreamInfo_ = { *audioStreamInfo.samplingRate.rbegin(), audioStreamInfo.encoding, audioStreamInfo.format, + *channels.rbegin() }; + dstStreamInfo_.channelLayout = *audioStreamInfo.channelLayout.rbegin(); HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); fastRenderId_ = manager.GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_FAST, "endpoint_sep_" + std::to_string(id_), true); diff --git a/services/audio_service/server/src/audio_process_in_server.cpp b/services/audio_service/server/src/audio_process_in_server.cpp index a625ba4274..2f45cc0dea 100644 --- a/services/audio_service/server/src/audio_process_in_server.cpp +++ b/services/audio_service/server/src/audio_process_in_server.cpp @@ -603,7 +603,8 @@ int32_t AudioProcessInServer::ConfigProcessBuffer(uint32_t &totalSizeInframe, // check CHECK_AND_RETURN_RET_LOG(totalSizeInframe != 0 && spanSizeInframe != 0 && totalSizeInframe % spanSizeInframe == 0, ERR_INVALID_PARAM, "ConfigProcessBuffer failed: ERR_INVALID_PARAM"); - CHECK_AND_RETURN_RET_LOG(serverStreamInfo.samplingRate.size() > 0 && serverStreamInfo.channels.size() > 0, + std::set channels = serverStreamInfo.GetChannels(); + CHECK_AND_RETURN_RET_LOG(serverStreamInfo.samplingRate.size() > 0 && channels.size() > 0, ERR_INVALID_PARAM, "Invalid stream info in server"); uint32_t spanTime = spanSizeInframe * AUDIO_MS_PER_SECOND / *serverStreamInfo.samplingRate.rbegin(); spanSizeInframe_ = spanTime * processConfig_.streamInfo.samplingRate / AUDIO_MS_PER_SECOND; @@ -612,11 +613,11 @@ int32_t AudioProcessInServer::ConfigProcessBuffer(uint32_t &totalSizeInframe, uint32_t channel = processConfig_.streamInfo.channels; uint32_t formatbyte = PcmFormatToBits(processConfig_.streamInfo.format); byteSizePerFrame_ = channel * formatbyte; - if (*serverStreamInfo.channels.rbegin() != processConfig_.streamInfo.channels || + if (*channels.rbegin() != processConfig_.streamInfo.channels || serverStreamInfo.format != processConfig_.streamInfo.format) { size_t spanSizeInByte = 0; if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK) { - uint32_t serverByteSize = *serverStreamInfo.channels.rbegin() * PcmFormatToBits(serverStreamInfo.format); + uint32_t serverByteSize = *channels.rbegin() * PcmFormatToBits(serverStreamInfo.format); spanSizeInByte = static_cast(spanSizeInframe * serverByteSize); } else { spanSizeInByte = static_cast(spanSizeInframe_ * byteSizePerFrame_); diff --git a/services/audio_service/server/src/audio_service.cpp b/services/audio_service/server/src/audio_service.cpp index 20d7cb2a8d..3e693a2511 100644 --- a/services/audio_service/server/src/audio_service.cpp +++ b/services/audio_service/server/src/audio_service.cpp @@ -798,7 +798,9 @@ sptr AudioService::GetAudioProcess(const AudioProcessConfi uint32_t totalSizeInframe = 0; uint32_t spanSizeInframe = 0; audioEndpoint->GetPreferBufferInfo(totalSizeInframe, spanSizeInframe); - CHECK_AND_RETURN_RET_LOG(*deviceInfo.audioStreamInfo_.samplingRate.rbegin() > 0, nullptr, + + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + CHECK_AND_RETURN_RET_LOG(*audioStreamInfo.samplingRate.rbegin() > 0, nullptr, "Sample rate in server is invalid."); sptr process = AudioProcessInServer::Create(config, this); @@ -807,7 +809,7 @@ sptr AudioService::GetAudioProcess(const AudioProcessConfi std::shared_ptr buffer = audioEndpoint->GetEndpointType() == AudioEndpoint::TYPE_INDEPENDENT ? audioEndpoint->GetBuffer() : nullptr; - ret = process->ConfigProcessBuffer(totalSizeInframe, spanSizeInframe, deviceInfo.audioStreamInfo_, buffer); + ret = process->ConfigProcessBuffer(totalSizeInframe, spanSizeInframe, audioStreamInfo, buffer); CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, nullptr, "ConfigProcessBuffer failed"); ret = LinkProcessToEndpoint(process, audioEndpoint); @@ -989,15 +991,16 @@ AudioDeviceDescriptor AudioService::GetDeviceInfoForProcess(const AudioProcessCo config.capturerInfo.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) { if (config.streamInfo.samplingRate <= SAMPLE_RATE_16000) { AUDIO_INFO_LOG("VoIP 16K"); - deviceInfo.audioStreamInfo_ = {SAMPLE_RATE_16000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; + deviceInfo.audioStreamInfo_ = {{SAMPLE_RATE_16000, ENCODING_PCM, SAMPLE_S16LE, CH_LAYOUT_STEREO}}; } else { AUDIO_INFO_LOG("VoIP 48K"); - deviceInfo.audioStreamInfo_ = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; + deviceInfo.audioStreamInfo_ = {{SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, CH_LAYOUT_STEREO}}; } } else { AUDIO_INFO_LOG("Fast stream"); - AudioStreamInfo targetStreamInfo = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; - deviceInfo.audioStreamInfo_ = targetStreamInfo; + AudioStreamInfo targetStreamInfo = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO, + CH_LAYOUT_STEREO}; + deviceInfo.audioStreamInfo_ = { targetStreamInfo }; deviceInfo.deviceName_ = "mmap_device"; } return deviceInfo; @@ -1015,8 +1018,9 @@ AudioDeviceDescriptor AudioService::GetDeviceInfoForProcess(const AudioProcessCo deviceInfo.deviceRole_ = OUTPUT_DEVICE; deviceInfo.deviceType_ = DEVICE_TYPE_SPEAKER; } - AudioStreamInfo targetStreamInfo = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; // note: read from xml - deviceInfo.audioStreamInfo_ = targetStreamInfo; + AudioStreamInfo targetStreamInfo = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO, + CH_LAYOUT_STEREO}; // note: read from xml + deviceInfo.audioStreamInfo_ = { targetStreamInfo }; deviceInfo.deviceName_ = "mmap_device"; return deviceInfo; } diff --git a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp index 922cf6cc0f..899d778858 100644 --- a/services/audio_service/server/src/hpae_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/hpae_renderer_stream_impl.cpp @@ -45,6 +45,7 @@ static constexpr uint64_t FRAME_LEN_20MS = 20; static constexpr uint64_t FRAME_LEN_40MS = 40; static constexpr int32_t DEFAULT_PAUSED_LATENCY = 40; static const std::string DEVICE_CLASS_OFFLOAD = "offload"; +static const std::string DEVICE_CLASS_REMOTE_OFFLOAD = "remote_offload"; static std::shared_ptr GetRenderSinkInstance(std::string deviceClass, std::string deviceNetId); static inline FadeType GetFadeType(uint64_t expectedPlaybackDurationMs); HpaeRendererStreamImpl::HpaeRendererStreamImpl(AudioProcessConfig processConfig, bool isMoveAble, bool isCallbackMode) @@ -255,7 +256,7 @@ void HpaeRendererStreamImpl::GetLatencyInner(uint64_t ×tamp, uint64_t &late uint32_t sinkLatency = 0; uint32_t a2dpOffloadLatency = GetA2dpOffloadLatency(); latencyUs = latency_; - if (deviceClass_ != DEVICE_CLASS_OFFLOAD) { + if (deviceClass_ != DEVICE_CLASS_OFFLOAD && deviceClass_ != DEVICE_CLASS_REMOTE_OFFLOAD) { std::shared_ptr audioRendererSink = GetRenderSinkInstance(deviceClass_, deviceNetId_); if (audioRendererSink) { audioRendererSink->GetLatency(sinkLatency); @@ -434,7 +435,7 @@ int32_t HpaeRendererStreamImpl::OffloadSetVolume(float volume) if (!offloadEnable_) { return ERR_OPERATION_FAILED; } - std::shared_ptr audioRendererSinkInstance = GetRenderSinkInstance(DEVICE_CLASS_OFFLOAD, ""); + std::shared_ptr audioRendererSinkInstance = GetRenderSinkInstance(deviceClass_, ""); if (audioRendererSinkInstance == nullptr) { AUDIO_ERR_LOG("Renderer is null."); return ERROR; diff --git a/services/audio_service/test/unittest/audio_endpoint_unit_test/src/audio_endpoint_plus_unit_test.cpp b/services/audio_service/test/unittest/audio_endpoint_unit_test/src/audio_endpoint_plus_unit_test.cpp index 689a0cd521..4ae75bf1a4 100644 --- a/services/audio_service/test/unittest/audio_endpoint_unit_test/src/audio_endpoint_plus_unit_test.cpp +++ b/services/audio_service/test/unittest/audio_endpoint_unit_test/src/audio_endpoint_plus_unit_test.cpp @@ -81,14 +81,15 @@ static sptr CreateAudioProcessInServer() { AudioService *audioServicePtr = AudioService::GetInstance(); AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); AudioProcessConfig serverConfig = InitServerProcessConfig(); sptr processStream = AudioProcessInServer::Create(serverConfig, audioServicePtr); std::shared_ptr buffer = nullptr; uint32_t spanSizeInFrame = 1000; uint32_t totalSizeInFrame = spanSizeInFrame; - processStream->ConfigProcessBuffer(totalSizeInFrame, spanSizeInFrame, deviceInfo.audioStreamInfo_, buffer); + processStream->ConfigProcessBuffer(totalSizeInFrame, spanSizeInFrame, audioStreamInfo, buffer); return processStream; } diff --git a/services/audio_service/test/unittest/audio_endpoint_unit_test/src/audio_endpoint_unit_test.cpp b/services/audio_service/test/unittest/audio_endpoint_unit_test/src/audio_endpoint_unit_test.cpp index 8218e7741e..5c625322c0 100644 --- a/services/audio_service/test/unittest/audio_endpoint_unit_test/src/audio_endpoint_unit_test.cpp +++ b/services/audio_service/test/unittest/audio_endpoint_unit_test/src/audio_endpoint_unit_test.cpp @@ -77,8 +77,9 @@ static std::shared_ptr CreateInputEndpointInner(AudioEndpoin AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::INPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpoint = std::make_shared(type, AUDIO_ENDPOINT_ID, config); @@ -93,9 +94,9 @@ static std::shared_ptr CreateOutputEndpointInner(AudioEndpoi AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::OUTPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); - deviceInfo.audioStreamInfo_.channelLayout = CH_LAYOUT_STEREO; + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpointInner = CreateEndpointInner(type, AUDIO_ENDPOINT_ID, config, deviceInfo); @@ -124,14 +125,15 @@ static sptr CreateAudioProcessInServer() { AudioService *audioServicePtr = AudioService::GetInstance(); AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); AudioProcessConfig serverConfig = InitServerProcessConfig(); sptr processStream = AudioProcessInServer::Create(serverConfig, audioServicePtr); std::shared_ptr buffer = nullptr; uint32_t spanSizeInFrame = 1000; uint32_t totalSizeInFrame = spanSizeInFrame; - processStream->ConfigProcessBuffer(totalSizeInFrame, spanSizeInFrame, deviceInfo.audioStreamInfo_, buffer); + processStream->ConfigProcessBuffer(totalSizeInFrame, spanSizeInFrame, audioStreamInfo, buffer); return processStream; } @@ -145,8 +147,9 @@ HWTEST_F(AudioEndpointUnitTest, AudioEndpointCreateEndpoint_001, TestSize.Level1 { AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpoint = AudioEndpoint::CreateEndpoint(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); @@ -164,21 +167,22 @@ HWTEST_F(AudioEndpointUnitTest, CreateEndpoint_002, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::INPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); - deviceInfo.audioStreamInfo_.format = AudioSampleFormat::SAMPLE_U8; + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); + audioStreamInfo.format = AudioSampleFormat::SAMPLE_U8; deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); - deviceInfo.audioStreamInfo_.format = AudioSampleFormat::SAMPLE_S24LE; + audioStreamInfo.format = AudioSampleFormat::SAMPLE_S24LE; audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); - deviceInfo.audioStreamInfo_.format = AudioSampleFormat::SAMPLE_S32LE; + audioStreamInfo.format = AudioSampleFormat::SAMPLE_S32LE; audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); - deviceInfo.audioStreamInfo_.format = AudioSampleFormat::INVALID_WIDTH; + audioStreamInfo.format = AudioSampleFormat::INVALID_WIDTH; audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); EXPECT_NE(nullptr, audioEndpointInner); - deviceInfo.audioStreamInfo_.format = AudioSampleFormat::SAMPLE_S16LE; + audioStreamInfo.format = AudioSampleFormat::SAMPLE_S16LE; audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); EXPECT_NE(nullptr, audioEndpointInner); } @@ -194,8 +198,9 @@ HWTEST_F(AudioEndpointUnitTest, AudioEndpointCreateEndpoint_002, TestSize.Level1 AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::INPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpoint = AudioEndpoint::CreateEndpoint(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); @@ -213,8 +218,9 @@ HWTEST_F(AudioEndpointUnitTest, EnableCreateEndpoint_003, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::OUTPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpoint = AudioEndpoint::CreateEndpoint(AudioEndpoint::TYPE_INDEPENDENT, 123, config, deviceInfo); @@ -242,8 +248,9 @@ HWTEST_F(AudioEndpointUnitTest, AudioEnableFastInnerCap_001, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::OUTPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpoint = AudioEndpoint::CreateEndpoint(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); @@ -266,8 +273,9 @@ HWTEST_F(AudioEndpointUnitTest, AudioEnableFastInnerCap_002, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::INPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); @@ -308,9 +316,9 @@ HWTEST_F(AudioEndpointUnitTest, HandleZeroVolumeCheckEvent_001, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::OUTPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); - deviceInfo.audioStreamInfo_.channelLayout = CH_LAYOUT_STEREO; + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); @@ -356,9 +364,9 @@ HWTEST_F(AudioEndpointUnitTest, ZeroVolumeCheck_001, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::OUTPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); - deviceInfo.audioStreamInfo_.channelLayout = CH_LAYOUT_STEREO; + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); @@ -408,8 +416,9 @@ HWTEST_F(AudioEndpointUnitTest, KeepWorkloopRunning_001, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::INPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); @@ -454,8 +463,9 @@ HWTEST_F(AudioEndpointUnitTest, CheckUpdateState_001, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::INPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); @@ -495,8 +505,9 @@ HWTEST_F(AudioEndpointUnitTest, CheckProcessToDupStream_001, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::INPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo streamInfo = deviceInfo.GetDeviceStreamInfo(); + streamInfo.samplingRate.insert(SAMPLE_RATE_48000); + streamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); @@ -523,8 +534,9 @@ HWTEST_F(AudioEndpointUnitTest, GetFastSink_001, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::INPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; std::shared_ptr audioEndpointInner = CreateEndpointInner(AudioEndpoint::TYPE_MMAP, 123, config, deviceInfo); @@ -575,8 +587,9 @@ HWTEST_F(AudioEndpointUnitTest, AudioEndpointMix_001, TestSize.Level1) AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::INPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo audioStreamInfo = deviceInfo.GetDeviceStreamInfo(); + audioStreamInfo.samplingRate.insert(SAMPLE_RATE_48000); + audioStreamInfo.channelLayout.insert(CH_LAYOUT_STEREO); deviceInfo.networkId_ = LOCAL_NETWORK_ID; result = audioEndpointInner->Config(deviceInfo); EXPECT_FALSE(result); diff --git a/services/audio_service/test/unittest/audio_process_in_server_unit_test.cpp b/services/audio_service/test/unittest/audio_process_in_server_unit_test.cpp index ce137d589c..92c72c4a76 100644 --- a/services/audio_service/test/unittest/audio_process_in_server_unit_test.cpp +++ b/services/audio_service/test/unittest/audio_process_in_server_unit_test.cpp @@ -61,7 +61,7 @@ DeviceStreamInfo g_audioStreamInfo = { SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, - STEREO + CH_LAYOUT_STEREO }; static AudioProcessConfig InitProcessConfig() diff --git a/services/audio_service/test/unittest/audio_service_unit_test.cpp b/services/audio_service/test/unittest/audio_service_unit_test.cpp index c8964580b0..cc1763cfd5 100644 --- a/services/audio_service/test/unittest/audio_service_unit_test.cpp +++ b/services/audio_service/test/unittest/audio_service_unit_test.cpp @@ -303,13 +303,13 @@ HWTEST(AudioServiceUnitTest, AudioDeviceDescriptor_001, TestSize.Level1) SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, - STEREO + CH_LAYOUT_STEREO }; int32_t channelMask = 1; - audioDeviceDescriptor->SetDeviceCapability(audioStreamInfo, channelMask); + audioDeviceDescriptor->SetDeviceCapability({ audioStreamInfo }, channelMask); - DeviceStreamInfo streamInfo = audioDeviceDescriptor->audioStreamInfo_; - EXPECT_EQ(streamInfo.channels, audioStreamInfo.channels); + DeviceStreamInfo streamInfo = audioDeviceDescriptor->GetDeviceStreamInfo(); + EXPECT_EQ(streamInfo.channelLayout, audioStreamInfo.channelLayout); EXPECT_EQ(streamInfo.encoding, audioStreamInfo.encoding); EXPECT_EQ(streamInfo.format, audioStreamInfo.format); EXPECT_EQ(streamInfo.samplingRate, audioStreamInfo.samplingRate); diff --git a/services/audio_service/test/unittest/hpae_renderer_stream_impl_unit_test.cpp b/services/audio_service/test/unittest/hpae_renderer_stream_impl_unit_test.cpp index 9226f30183..d464537020 100644 --- a/services/audio_service/test/unittest/hpae_renderer_stream_impl_unit_test.cpp +++ b/services/audio_service/test/unittest/hpae_renderer_stream_impl_unit_test.cpp @@ -166,6 +166,12 @@ HWTEST_F(HpaeRendererStreamUnitTest, HpaeRenderer_004, TestSize.Level1) uint64_t latency = 0; int32_t ret = unit->GetCurrentPosition(framePosition, timestamp, latency, Timestamp::MONOTONIC); EXPECT_EQ(ret, SUCCESS); + unit->deviceClass_ = "remote_offload"; + ret = unit->GetCurrentPosition(framePosition, timestamp, latency, Timestamp::MONOTONIC); + EXPECT_EQ(ret, SUCCESS); + unit->deviceClass_ = "offload"; + ret = unit->GetCurrentPosition(framePosition, timestamp, latency, Timestamp::MONOTONIC); + EXPECT_EQ(ret, SUCCESS); } /** @@ -511,6 +517,12 @@ HWTEST_F(HpaeRendererStreamUnitTest, HpaeRenderer_026, TestSize.Level1) uint64_t latency = 0; int32_t ret = unit->GetLatency(latency); EXPECT_EQ(ret, SUCCESS); + unit->deviceClass_ = "remote_offload"; + ret = unit->GetLatency(latency); + EXPECT_EQ(ret, SUCCESS); + unit->deviceClass_ = "offload"; + ret = unit->GetLatency(latency); + EXPECT_EQ(ret, SUCCESS); } /** diff --git a/test/fuzztest/audioservice_fuzzer/audio_service_fuzzer.cpp b/test/fuzztest/audioservice_fuzzer/audio_service_fuzzer.cpp index 4693f52cd4..a531e8e79e 100644 --- a/test/fuzztest/audioservice_fuzzer/audio_service_fuzzer.cpp +++ b/test/fuzztest/audioservice_fuzzer/audio_service_fuzzer.cpp @@ -178,8 +178,10 @@ static void CreateFuzzTestPtr() AudioProcessConfig config = {}; AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO); deviceInfo.deviceRole_ = DeviceRole::OUTPUT_DEVICE; - deviceInfo.audioStreamInfo_.samplingRate.insert(SAMPLE_RATE_48000); - deviceInfo.audioStreamInfo_.channels.insert(STEREO); + DeviceStreamInfo streamInfo; + streamInfo.samplingRate.insert(SAMPLE_RATE_48000); + streamInfo.channelLayout.insert(CH_LAYOUT_STEREO); + deviceInfo.audioStreamInfo_.push_back(streamInfo); deviceInfo.networkId_ = LOCAL_NETWORK_ID; audioEndpointPtr_ = AudioEndpoint::CreateEndpoint( AudioEndpoint::TYPE_INDEPENDENT, GetData(), config, deviceInfo); diff --git a/test/fuzztest/audioserviceserversrc_fuzzer/audio_service_server_src_fuzzer.cpp b/test/fuzztest/audioserviceserversrc_fuzzer/audio_service_server_src_fuzzer.cpp index dd1a432904..77220bd946 100644 --- a/test/fuzztest/audioserviceserversrc_fuzzer/audio_service_server_src_fuzzer.cpp +++ b/test/fuzztest/audioserviceserversrc_fuzzer/audio_service_server_src_fuzzer.cpp @@ -229,9 +229,9 @@ void AudioEndPointSeparateConfigFuzzTest() SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, - STEREO + CH_LAYOUT_STEREO }; - deviceInfo.audioStreamInfo_ = audioStreamInfo; + deviceInfo.audioStreamInfo_ = { audioStreamInfo }; std::shared_ptr audioEndpoint = nullptr; uint64_t id = GetData(); AudioEndpoint::EndpointType type = GetData(); diff --git a/test/fuzztest/audiostream_fuzzer/audio_stream_fuzzer.cpp b/test/fuzztest/audiostream_fuzzer/audio_stream_fuzzer.cpp index 486dd039b3..cf183190f5 100644 --- a/test/fuzztest/audiostream_fuzzer/audio_stream_fuzzer.cpp +++ b/test/fuzztest/audiostream_fuzzer/audio_stream_fuzzer.cpp @@ -116,7 +116,7 @@ int32_t MockPolicyProvider::GetProcessDeviceInfo(const AudioProcessConfig &confi deviceInfo.networkId_ = "LocalDevice"; deviceInfo.deviceName_ = "testname"; - deviceInfo.audioStreamInfo_ = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; + deviceInfo.audioStreamInfo_ = {{SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, CH_LAYOUT_STEREO}}; return SUCCESS; } -- Gitee