From e5a6ead214fe4d6949089b73a29a4a8f41c4aea7 Mon Sep 17 00:00:00 2001 From: yue Date: Thu, 28 Aug 2025 16:57:12 +0800 Subject: [PATCH] BT_SPP 828 Signed-off-by: yue --- bundle.json | 12 + .../cj/include/multimedia_audio_common.h | 1 + frameworks/js/napi/common/napi_audio_enum.cpp | 1 + .../js/napi/common/napi_param_utils.cpp | 1 + frameworks/js/napi/common/napi_param_utils.h | 1 + .../include/audio_policy_manager.h | 1 + .../native/audioutils/src/audio_utils.cpp | 1 + frameworks/native/hdiadapter_new/BUILD.gn | 4 + .../include/common/hdi_adapter_info.h | 4 +- .../include/common/hdi_adapter_type.h | 3 + .../include/source/audio_capture_source.h | 1 + .../source/bluetooth_audio_capture_source.h | 1 + .../source/fast_audio_capture_source.h | 1 + .../source/file_audio_capture_source.h | 1 + .../include/source/i_audio_capture_source.h | 1 + .../source/remote_audio_capture_source.h | 1 + .../source/remote_fast_audio_capture_source.h | 1 + .../include/source/va_capture_source.h | 127 +++++ .../source/wakeup_audio_capture_source.h | 1 + .../manager/hdi_adapter_factory.cpp | 4 + .../source/audio_capture_source.cpp | 7 + .../source/bluetooth_audio_capture_source.cpp | 7 + .../source/fast_audio_capture_source.cpp | 7 + .../source/file_audio_capture_source.cpp | 7 + .../source/remote_audio_capture_source.cpp | 7 + .../remote_fast_audio_capture_source.cpp | 7 + .../source/va_capture_source.cpp | 398 +++++++++++++++ .../source/wakeup_audio_capture_source.cpp | 7 + .../source/va_capture_source_unit_test.cpp | 317 ++++++++++++ .../native/hdiadapter_new/util/id_handler.cpp | 2 + .../audiocapturer/include/audio_capturer.h | 1 + .../include/audio_capturer_options.h | 51 ++ .../audiocommon/include/audio_device_info.h | 5 + .../native/audiocommon/include/audio_info.h | 6 - .../native/audiocommon/include/va_device.h | 55 +++ .../audiocommon/include/va_device_info.h | 209 ++++++++ .../include/audio_policy_interface.h | 32 ++ services/audio_policy/BUILD.gn | 5 + .../stub/include/va_device_broker_stub_impl.h | 47 ++ .../include/va_device_broker_wrapper_Impl.h | 39 ++ .../include/va_device_controller_stub_impl.h | 44 ++ .../stub/include/va_input_stream_stub_impl.h | 46 ++ .../stub/src/va_device_broker_stub_impl.cpp | 66 +++ .../src/va_device_broker_wrapper_Impl.cpp | 92 ++++ .../src/va_device_controller_stub_impl.cpp | 96 ++++ .../stub/src/va_input_stream_stub_impl.cpp | 84 ++++ .../common/include/audio_module_info.h | 2 + services/audio_policy/idl/IAudioPolicy.idl | 2 + services/audio_policy/idl/IVADeviceBroker.idl | 24 + .../audio_policy/idl/IVADeviceController.idl | 28 ++ services/audio_policy/idl/IVAInputStream.idl | 29 ++ services/audio_policy/idl/IVAStream.idl | 27 ++ .../device/src/audio_device_descriptor.cpp | 3 + .../domain/device/src/audio_device_status.cpp | 4 + .../domain/device/src/audio_device_type.cpp | 1 + .../device/src/va/va_device_manager.cpp | 239 +++++++++ .../domain/device/src/va/va_device_manager.h | 86 ++++ .../include/audio_definition_adapter_info.h | 2 + .../src/audio_definition_adapter_info.cpp | 2 + .../src/audio_definition_policy_utils.cpp | 1 + .../domain/pipe/src/audio_ec_manager.cpp | 2 + .../domain/pipe/src/audio_pipe_selector.cpp | 1 + .../volume/src/audio_adapter_manager.cpp | 1 + .../config/parser/src/audio_device_parser.cpp | 1 + .../include/audio_policy_server.h | 4 + .../include/audio_policy_service.h | 5 +- .../service_main/src/audio_policy_server.cpp | 24 + ...udio_definition_adapter_info_unit_test.cpp | 3 + .../src/audio_device_status_unit_test.cpp | 35 ++ .../src/audio_policy_server_unit_test.cpp | 28 ++ .../va_device_controller_stub_impl_test.h | 28 ++ .../va_device_controller_stub_impl_test.cpp | 166 +++++++ .../include/va_device_manager_unit_test.h | 38 ++ .../src/va_device_manager_unit_test.cpp | 200 ++++++++ .../include/va_input_stream_stub_impl_test.h | 67 +++ .../src/va_input_stream_stub_impl_test.cpp | 259 ++++++++++ services/audio_service/BUILD.gn | 2 + .../common/include/va_shared_buffer.h | 110 +++++ .../include/va_shared_buffer_operator.h | 84 ++++ .../common/src/va_shared_buffer.cpp | 285 +++++++++++ .../common/src/va_shared_buffer_operator.cpp | 252 ++++++++++ services/audio_service/idl/BUILD.gn | 14 + .../audio_service/server/src/audio_server.cpp | 63 ++- .../audio_service_common_unit_test.cpp | 457 ++++++++++++++++++ 84 files changed, 4372 insertions(+), 19 deletions(-) create mode 100644 frameworks/native/hdiadapter_new/include/source/va_capture_source.h create mode 100644 frameworks/native/hdiadapter_new/source/va_capture_source.cpp create mode 100644 frameworks/native/hdiadapter_new/test/unittest/source/va_capture_source_unit_test.cpp create mode 100644 interfaces/inner_api/native/audiocommon/include/audio_capturer_options.h create mode 100644 interfaces/inner_api/native/audiocommon/include/va_device.h create mode 100644 interfaces/inner_api/native/audiocommon/include/va_device_info.h create mode 100644 services/audio_policy/client/stub/include/va_device_broker_stub_impl.h create mode 100644 services/audio_policy/client/stub/include/va_device_broker_wrapper_Impl.h create mode 100644 services/audio_policy/client/stub/include/va_device_controller_stub_impl.h create mode 100644 services/audio_policy/client/stub/include/va_input_stream_stub_impl.h create mode 100644 services/audio_policy/client/stub/src/va_device_broker_stub_impl.cpp create mode 100644 services/audio_policy/client/stub/src/va_device_broker_wrapper_Impl.cpp create mode 100644 services/audio_policy/client/stub/src/va_device_controller_stub_impl.cpp create mode 100644 services/audio_policy/client/stub/src/va_input_stream_stub_impl.cpp create mode 100644 services/audio_policy/idl/IVADeviceBroker.idl create mode 100644 services/audio_policy/idl/IVADeviceController.idl create mode 100644 services/audio_policy/idl/IVAInputStream.idl create mode 100644 services/audio_policy/idl/IVAStream.idl create mode 100644 services/audio_policy/server/domain/device/src/va/va_device_manager.cpp create mode 100644 services/audio_policy/server/domain/device/src/va/va_device_manager.h create mode 100644 services/audio_policy/test/unittest/va_device_controller_stub_impl_test/include/va_device_controller_stub_impl_test.h create mode 100644 services/audio_policy/test/unittest/va_device_controller_stub_impl_test/src/va_device_controller_stub_impl_test.cpp create mode 100644 services/audio_policy/test/unittest/va_device_manager_unit_test/include/va_device_manager_unit_test.h create mode 100644 services/audio_policy/test/unittest/va_device_manager_unit_test/src/va_device_manager_unit_test.cpp create mode 100644 services/audio_policy/test/unittest/va_input_stream_stub_impl_test/include/va_input_stream_stub_impl_test.h create mode 100644 services/audio_policy/test/unittest/va_input_stream_stub_impl_test/src/va_input_stream_stub_impl_test.cpp create mode 100644 services/audio_service/common/include/va_shared_buffer.h create mode 100644 services/audio_service/common/include/va_shared_buffer_operator.h create mode 100644 services/audio_service/common/src/va_shared_buffer.cpp create mode 100644 services/audio_service/common/src/va_shared_buffer_operator.cpp diff --git a/bundle.json b/bundle.json index 7d5d2c256f..b3a6891937 100644 --- a/bundle.json +++ b/bundle.json @@ -135,11 +135,23 @@ "name": "//foundation/multimedia/audio_framework/services/audio_policy:audio_foundation", "header": { "header_files": [ + "./audiocommon/include/audio_device_info.h", "./audiocommon/include/audio_device_descriptor.h" ], "header_base": "//foundation/multimedia/audio_framework/interfaces/inner_api/native/audiocommon/include" } }, + { + "type": "none", + "name": "//foundation/multimedia/audio_framework/services/audio_service:audio_common", + "header": { + "header_files": [ + "va_shared_buffer.h", + "va_shared_buffer_operator.h" + ], + "header_base": "//foundation/multimedia/audio_framework/services/audio_service/common/include" + } + }, { "type": "none", "name": "//foundation/multimedia/audio_framework/services/audio_policy:audio_manager_client", diff --git a/frameworks/cj/include/multimedia_audio_common.h b/frameworks/cj/include/multimedia_audio_common.h index acb202da70..7c2f3b2995 100644 --- a/frameworks/cj/include/multimedia_audio_common.h +++ b/frameworks/cj/include/multimedia_audio_common.h @@ -20,6 +20,7 @@ #include "cj_common_ffi.h" #include "multimedia_audio_ffi.h" #include "securec.h" +#include "audio_capturer_options.h" namespace OHOS { namespace AudioStandard { diff --git a/frameworks/js/napi/common/napi_audio_enum.cpp b/frameworks/js/napi/common/napi_audio_enum.cpp index bdc34f0084..a478696166 100644 --- a/frameworks/js/napi/common/napi_audio_enum.cpp +++ b/frameworks/js/napi/common/napi_audio_enum.cpp @@ -133,6 +133,7 @@ const std::map NapiAudioEnum::deviceTypeMap = { {"WIRED_HEADPHONES", DEVICE_TYPE_WIRED_HEADPHONES}, {"BLUETOOTH_SCO", DEVICE_TYPE_BLUETOOTH_SCO}, {"BLUETOOTH_A2DP", DEVICE_TYPE_BLUETOOTH_A2DP}, + {"BT_SPP", DEVICE_TYPE_BT_SPP}, {"NEARLINK", DEVICE_TYPE_NEARLINK}, {"HEARING_AID", DEVICE_TYPE_HEARING_AID}, {"MIC", DEVICE_TYPE_MIC}, diff --git a/frameworks/js/napi/common/napi_param_utils.cpp b/frameworks/js/napi/common/napi_param_utils.cpp index d6b35c1d36..c672b1b691 100644 --- a/frameworks/js/napi/common/napi_param_utils.cpp +++ b/frameworks/js/napi/common/napi_param_utils.cpp @@ -38,6 +38,7 @@ const std::vector DEVICE_TYPE_SET = { DEVICE_TYPE_WIRED_HEADPHONES, DEVICE_TYPE_BLUETOOTH_SCO, DEVICE_TYPE_BLUETOOTH_A2DP, + DEVICE_TYPE_BT_SPP, DEVICE_TYPE_MIC, DEVICE_TYPE_WAKEUP, DEVICE_TYPE_USB_HEADSET, diff --git a/frameworks/js/napi/common/napi_param_utils.h b/frameworks/js/napi/common/napi_param_utils.h index 5c9b0a1aec..f7ca744ecd 100644 --- a/frameworks/js/napi/common/napi_param_utils.h +++ b/frameworks/js/napi/common/napi_param_utils.h @@ -31,6 +31,7 @@ #include "audio_capturer.h" #include "audio_system_manager.h" #include "audio_stream_manager.h" +#include "audio_device_descriptor.h" namespace OHOS { namespace AudioStandard { diff --git a/frameworks/native/audiopolicy/include/audio_policy_manager.h b/frameworks/native/audiopolicy/include/audio_policy_manager.h index fd046754df..8803e408b9 100644 --- a/frameworks/native/audiopolicy/include/audio_policy_manager.h +++ b/frameworks/native/audiopolicy/include/audio_policy_manager.h @@ -37,6 +37,7 @@ #include "audio_combine_denoising_manager.h" #include "audio_stream_descriptor.h" #include "sle_audio_operation_callback_stub_impl.h" +#include "audio_capturer_options.h" namespace OHOS { namespace AudioStandard { diff --git a/frameworks/native/audioutils/src/audio_utils.cpp b/frameworks/native/audioutils/src/audio_utils.cpp index c9cb8cca22..e7bfc85334 100644 --- a/frameworks/native/audioutils/src/audio_utils.cpp +++ b/frameworks/native/audioutils/src/audio_utils.cpp @@ -165,6 +165,7 @@ static const std::unordered_map DEVICE_TYPE_NAME_MAP = {DEVICE_TYPE_INVALID, "INVALID"}, {DEVICE_TYPE_REMOTE_CAST, "REMOTE_CAST"}, {DEVICE_TYPE_HEARING_AID, "HEARING_AID"}, + {DEVICE_TYPE_BT_SPP, "BT_SPP"}, }; uint32_t Util::GetSamplePerFrame(const AudioSampleFormat &format) diff --git a/frameworks/native/hdiadapter_new/BUILD.gn b/frameworks/native/hdiadapter_new/BUILD.gn index de68690665..a726e0e4fd 100644 --- a/frameworks/native/hdiadapter_new/BUILD.gn +++ b/frameworks/native/hdiadapter_new/BUILD.gn @@ -65,6 +65,7 @@ ohos_shared_library("hdiadapter_new") { "source/fast_audio_capture_source.cpp", "source/file_audio_capture_source.cpp", "source/wakeup_audio_capture_source.cpp", + "source/va_capture_source.cpp", "util/callback_wrapper.cpp", "util/id_handler.cpp", "util/ring_buffer_handler.cpp", @@ -80,6 +81,7 @@ ohos_shared_library("hdiadapter_new") { ] external_deps = [ + "hisysevent:libhisysevent", "bounds_checking_function:libsec_shared", "c_utils:utils", "data_share:datashare_common", @@ -189,6 +191,7 @@ ohos_unittest("hdiadapter_unit_test") { "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/va_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", "test/unittest/source/file_audio_capture_source_unit_test.cpp", @@ -201,6 +204,7 @@ ohos_unittest("hdiadapter_unit_test") { deps = [ ":hdiadapter_new" ] external_deps = [ + "c_utils:utils", "drivers_interface_audio:libaudio_proxy_5.0", "googletest:gmock", "googletest:gtest", 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 5cf02a315e..fd95d673a6 100644 --- a/frameworks/native/hdiadapter_new/include/common/hdi_adapter_info.h +++ b/frameworks/native/hdiadapter_new/include/common/hdi_adapter_info.h @@ -39,6 +39,7 @@ enum HdiIdType : uint32_t { HDI_ID_TYPE_WAKEUP, HDI_ID_TYPE_ACCESSORY, HDI_ID_TYPE_AI, + HDI_ID_TYPE_VA, HDI_ID_TYPE_NUM, }; @@ -54,7 +55,8 @@ enum HdiIdType : uint32_t { #define HDI_ID_INFO_MMAP "mmap" #define HDI_ID_INFO_HEARING_AID "hearing_aid" #define HDI_ID_INFO_ACCESSORY "accessory" -#define HDI_ID_INFO_DP_MULITCHANNEL "dp_multichannel" +#define HDI_ID_INFO_DP_MULTICHANNEL "dp_multichannel" +#define HDI_ID_INFO_VA "va" // device manager enum HdiDeviceManagerType : uint32_t { diff --git a/frameworks/native/hdiadapter_new/include/common/hdi_adapter_type.h b/frameworks/native/hdiadapter_new/include/common/hdi_adapter_type.h index 40a4fa5f1f..37881116bd 100644 --- a/frameworks/native/hdiadapter_new/include/common/hdi_adapter_type.h +++ b/frameworks/native/hdiadapter_new/include/common/hdi_adapter_type.h @@ -90,6 +90,7 @@ typedef struct IAudioSourceAttr : public Parcelable { bool isBigEndian = false; std::string filePath = ""; std::string deviceNetworkId = ""; + std::string macAddress = ""; int32_t deviceType = 0; int32_t sourceType = 0; uint64_t channelLayout = 0; @@ -112,6 +113,7 @@ typedef struct IAudioSourceAttr : public Parcelable { parcel.WriteBool(isBigEndian) && parcel.WriteString(filePath) && parcel.WriteString(deviceNetworkId) && + parcel.WriteString(macAddress) && parcel.WriteInt32(deviceType) && parcel.WriteInt32(sourceType) && parcel.WriteUint64(channelLayout) && @@ -140,6 +142,7 @@ typedef struct IAudioSourceAttr : public Parcelable { attr->isBigEndian = parcel.ReadBool(); attr->filePath = parcel.ReadString(); attr->deviceNetworkId = parcel.ReadString(); + attr->macAddress = parcel.ReadString(); attr->deviceType = parcel.ReadInt32(); attr->sourceType = parcel.ReadInt32(); attr->channelLayout = parcel.ReadUint64(); diff --git a/frameworks/native/hdiadapter_new/include/source/audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/audio_capture_source.h index 140390d8c7..5940f82b5d 100644 --- a/frameworks/native/hdiadapter_new/include/source/audio_capture_source.h +++ b/frameworks/native/hdiadapter_new/include/source/audio_capture_source.h @@ -51,6 +51,7 @@ public: uint64_t &replyBytesEc) override; std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override; + void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; diff --git a/frameworks/native/hdiadapter_new/include/source/bluetooth_audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/bluetooth_audio_capture_source.h index e7e9c68aa5..377a81b7c7 100644 --- a/frameworks/native/hdiadapter_new/include/source/bluetooth_audio_capture_source.h +++ b/frameworks/native/hdiadapter_new/include/source/bluetooth_audio_capture_source.h @@ -53,6 +53,7 @@ public: uint64_t &replyBytesEc) override; std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override; + void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; diff --git a/frameworks/native/hdiadapter_new/include/source/fast_audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/fast_audio_capture_source.h index 52b65ab934..29999a6fa3 100644 --- a/frameworks/native/hdiadapter_new/include/source/fast_audio_capture_source.h +++ b/frameworks/native/hdiadapter_new/include/source/fast_audio_capture_source.h @@ -45,6 +45,7 @@ public: uint64_t &replyBytesEc) override; std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override; + void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; diff --git a/frameworks/native/hdiadapter_new/include/source/file_audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/file_audio_capture_source.h index 11d532274d..1a2aace4ca 100644 --- a/frameworks/native/hdiadapter_new/include/source/file_audio_capture_source.h +++ b/frameworks/native/hdiadapter_new/include/source/file_audio_capture_source.h @@ -42,6 +42,7 @@ public: uint64_t &replyBytesEc) override; std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override; + void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; diff --git a/frameworks/native/hdiadapter_new/include/source/i_audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/i_audio_capture_source.h index 1648a99f9b..7baebb7b76 100644 --- a/frameworks/native/hdiadapter_new/include/source/i_audio_capture_source.h +++ b/frameworks/native/hdiadapter_new/include/source/i_audio_capture_source.h @@ -56,6 +56,7 @@ public: uint64_t &replyBytesEc) = 0; virtual std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) = 0; + virtual void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) = 0; virtual int32_t SetVolume(float left, float right) = 0; virtual int32_t GetVolume(float &left, float &right) = 0; diff --git a/frameworks/native/hdiadapter_new/include/source/remote_audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/remote_audio_capture_source.h index 43568e05e3..791ce063f5 100644 --- a/frameworks/native/hdiadapter_new/include/source/remote_audio_capture_source.h +++ b/frameworks/native/hdiadapter_new/include/source/remote_audio_capture_source.h @@ -51,6 +51,7 @@ public: uint64_t &replyBytesEc) override; std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override; + void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; diff --git a/frameworks/native/hdiadapter_new/include/source/remote_fast_audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/remote_fast_audio_capture_source.h index 023fd7d9b8..0919deca86 100644 --- a/frameworks/native/hdiadapter_new/include/source/remote_fast_audio_capture_source.h +++ b/frameworks/native/hdiadapter_new/include/source/remote_fast_audio_capture_source.h @@ -54,6 +54,7 @@ public: uint64_t &replyBytesEc) override; std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override; + void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; diff --git a/frameworks/native/hdiadapter_new/include/source/va_capture_source.h b/frameworks/native/hdiadapter_new/include/source/va_capture_source.h new file mode 100644 index 0000000000..3369834d58 --- /dev/null +++ b/frameworks/native/hdiadapter_new/include/source/va_capture_source.h @@ -0,0 +1,127 @@ +/* + * 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 VA_CAPTURE_SOURCE_H +#define VA_CAPTURE_SOURCE_H + +#include "source/i_audio_capture_source.h" +#include +#include +#include +#include "audio_hdi_log.h" +#include "audio_errors.h" +#include "util/callback_wrapper.h" +#include "util/audio_running_lock.h" +#include "capturer_clock_manager.h" + +#include "audio_primary_source_clock.h" + +#include "va_device_info.h" +#include "iv_a_input_stream.h" +#include "iv_a_device_controller.h" +#include "va_shared_buffer.h" +#include "va_shared_buffer_operator.h" + + +namespace OHOS { +namespace AudioStandard { +class VACaptureSource :public IAudioCaptureSource { +public: + explicit VACaptureSource(const uint32_t captureId); + ~VACaptureSource(); + + int32_t Init(const IAudioSourceAttr& 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 CaptureFrame(char* frame, uint64_t requestBytes, uint64_t& replyBytes) override; + int32_t CaptureFrameWithEc( + FrameDesc* fdesc, uint64_t& replyBytes, FrameDesc* fdescEc, uint64_t& replyBytesEc) override; + + std::string GetAudioParameter(const AudioParamKey key, const std::string& condition) override; + void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override; + + int32_t SetVolume(float left, float right)override; + int32_t GetVolume(float &left, float &right)override; + int32_t SetMute(bool isMute)override; + int32_t GetMute(bool &isMute)override; + + uint64_t GetTransactionId(void) override; + int32_t GetPresentationPosition(uint64_t& frames, int64_t& timeSec, int64_t& timeNanoSec) override; + float GetMaxAmplitude(void) override; + + int32_t SetAudioScene(AudioScene audioScene, bool scoExcludeFlag = false) override; + + int32_t UpdateActiveDevice(DeviceType inputDevice) override; + void RegistCallback(uint32_t type, IAudioSourceCallback* callback) override; + void RegistCallback(uint32_t type, std::shared_ptr callback) override; + + int32_t UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE], const size_t size) final; + int32_t UpdateAppsUid(const std::vector& appsUid) final; + + void SetAddress(const std::string& address) override; + void SetInvalidState(void) override; + + void DumpInfo(std::string& dumpString) override; + + void SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType) override; + + void CheckUpdateState(char* frame, size_t replyBytes); + +private: + static constexpr uint16_t GET_MAX_AMPLITUDE_FRAMES_THRESHOLD = 10; + sptr deviceController_; + sptr inputStream_; + std::shared_ptr bufferOperator_; + uint32_t captureId_ = HDI_INVALID_ID; + IAudioSourceAttr attr_ = {}; + SourceCallbackWrapper callback_ = {}; + bool sourceInited_ = false; + bool started_ = false; + std::mutex statusMutex_; + + float maxAmplitude_ = 0; + int64_t lastGetMaxAmplitudeTime_ = 0; + int64_t last10FrameStartTime_ = 0; + bool startUpdate_ = false; + int captureFrameNum_ = 0; + + int32_t logMode_ = 0; + FILE* dumpFile_ = nullptr; + std::string dumpFileName_ = ""; + + std::shared_ptr audioSrcClock_ = nullptr; + + int64_t startTimestamp = 0; + + int32_t CreateCapture(); + int32_t InitOperator(); + int32_t DoStop(void); + void PrintDfx(int64_t useTime); + + std::shared_ptr MakeVAStreamPropertyFromIAudioSourceAttr(); + std::shared_ptr MakeVAStreamAttributeFromIAudioSourceAttr(); +}; + +} //namespace AudioStandard +} //namespace OHOS +#endif //VA_CAPTURE_SOURCE_H \ No newline at end of file diff --git a/frameworks/native/hdiadapter_new/include/source/wakeup_audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/wakeup_audio_capture_source.h index 8714ae89a7..db9a580e21 100644 --- a/frameworks/native/hdiadapter_new/include/source/wakeup_audio_capture_source.h +++ b/frameworks/native/hdiadapter_new/include/source/wakeup_audio_capture_source.h @@ -73,6 +73,7 @@ public: uint64_t &replyBytesEc) override; std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override; + void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override; int32_t SetVolume(float left, float right) override; int32_t GetVolume(float &left, float &right) override; diff --git a/frameworks/native/hdiadapter_new/manager/hdi_adapter_factory.cpp b/frameworks/native/hdiadapter_new/manager/hdi_adapter_factory.cpp index 86849b3aaf..bb36e21ffe 100644 --- a/frameworks/native/hdiadapter_new/manager/hdi_adapter_factory.cpp +++ b/frameworks/native/hdiadapter_new/manager/hdi_adapter_factory.cpp @@ -35,6 +35,7 @@ #include "source/wakeup_audio_capture_source.h" #include "source/fast_audio_capture_source.h" #include "source/file_audio_capture_source.h" +#include "source/va_capture_source.h" #include "adapter/local_device_manager.h" #include "adapter/bluetooth_device_manager.h" @@ -121,6 +122,9 @@ std::shared_ptr HdiAdapterFactory::CreateCaptureSource(uint case HDI_ID_TYPE_BLUETOOTH: source = std::make_shared(captureId); break; + case HDI_ID_TYPE_VA: + source = std::make_shared(captureId); + break; case HDI_ID_TYPE_WAKEUP: source = std::make_shared(captureId); break; diff --git a/frameworks/native/hdiadapter_new/source/audio_capture_source.cpp b/frameworks/native/hdiadapter_new/source/audio_capture_source.cpp index 4cf9082123..f3a6f990ed 100644 --- a/frameworks/native/hdiadapter_new/source/audio_capture_source.cpp +++ b/frameworks/native/hdiadapter_new/source/audio_capture_source.cpp @@ -419,6 +419,13 @@ std::string AudioCaptureSource::GetAudioParameter(const AudioParamKey key, const return ""; } +void AudioCaptureSource::SetAudioParameter( + const AudioParamKey key, const std::string &condition, const std::string &value) +{ + AUDIO_WARNING_LOG("not support"); + return; +} + int32_t AudioCaptureSource::SetVolume(float left, float right) { CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); diff --git a/frameworks/native/hdiadapter_new/source/bluetooth_audio_capture_source.cpp b/frameworks/native/hdiadapter_new/source/bluetooth_audio_capture_source.cpp index 0d30cbfca4..0db92ed222 100644 --- a/frameworks/native/hdiadapter_new/source/bluetooth_audio_capture_source.cpp +++ b/frameworks/native/hdiadapter_new/source/bluetooth_audio_capture_source.cpp @@ -257,6 +257,13 @@ std::string BluetoothAudioCaptureSource::GetAudioParameter(const AudioParamKey k return ""; } +void BluetoothAudioCaptureSource::SetAudioParameter( + const AudioParamKey key, const std::string &condition, const std::string &value) +{ + AUDIO_WARNING_LOG("not support"); + return; +} + int32_t BluetoothAudioCaptureSource::SetVolume(float left, float right) { CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); diff --git a/frameworks/native/hdiadapter_new/source/fast_audio_capture_source.cpp b/frameworks/native/hdiadapter_new/source/fast_audio_capture_source.cpp index e2a66130b0..e58681c4be 100644 --- a/frameworks/native/hdiadapter_new/source/fast_audio_capture_source.cpp +++ b/frameworks/native/hdiadapter_new/source/fast_audio_capture_source.cpp @@ -209,6 +209,13 @@ std::string FastAudioCaptureSource::GetAudioParameter(const AudioParamKey key, c return ""; } +void FastAudioCaptureSource::SetAudioParameter( + const AudioParamKey key, const std::string &condition, const std::string &value) +{ + AUDIO_WARNING_LOG("not support"); + return; +} + int32_t FastAudioCaptureSource::SetVolume(float left, float right) { AUDIO_INFO_LOG("not support"); diff --git a/frameworks/native/hdiadapter_new/source/file_audio_capture_source.cpp b/frameworks/native/hdiadapter_new/source/file_audio_capture_source.cpp index 1142322932..54753dc3fd 100644 --- a/frameworks/native/hdiadapter_new/source/file_audio_capture_source.cpp +++ b/frameworks/native/hdiadapter_new/source/file_audio_capture_source.cpp @@ -126,6 +126,13 @@ std::string FileAudioCaptureSource::GetAudioParameter(const AudioParamKey key, c return ""; } +void FileAudioCaptureSource::SetAudioParameter( + const AudioParamKey key, const std::string &condition, const std::string &value) +{ + AUDIO_WARNING_LOG("not support"); + return; +} + int32_t FileAudioCaptureSource::SetVolume(float left, float right) { return SUCCESS; diff --git a/frameworks/native/hdiadapter_new/source/remote_audio_capture_source.cpp b/frameworks/native/hdiadapter_new/source/remote_audio_capture_source.cpp index 265b5b7069..56b9858a03 100644 --- a/frameworks/native/hdiadapter_new/source/remote_audio_capture_source.cpp +++ b/frameworks/native/hdiadapter_new/source/remote_audio_capture_source.cpp @@ -198,6 +198,13 @@ std::string RemoteAudioCaptureSource::GetAudioParameter(const AudioParamKey key, return ""; } +void RemoteAudioCaptureSource::SetAudioParameter( + const AudioParamKey key, const std::string &condition, const std::string &value) +{ + AUDIO_WARNING_LOG("not support"); + return; +} + int32_t RemoteAudioCaptureSource::SetVolume(float left, float right) { float leftVolume = left; diff --git a/frameworks/native/hdiadapter_new/source/remote_fast_audio_capture_source.cpp b/frameworks/native/hdiadapter_new/source/remote_fast_audio_capture_source.cpp index b8f296bd67..c04df5a432 100644 --- a/frameworks/native/hdiadapter_new/source/remote_fast_audio_capture_source.cpp +++ b/frameworks/native/hdiadapter_new/source/remote_fast_audio_capture_source.cpp @@ -221,6 +221,13 @@ std::string RemoteFastAudioCaptureSource::GetAudioParameter(const AudioParamKey return ""; } +void RemoteFastAudioCaptureSource::SetAudioParameter( + const AudioParamKey key, const std::string &condition, const std::string &value) +{ + AUDIO_WARNING_LOG("not support"); + return; +} + int32_t RemoteFastAudioCaptureSource::SetVolume(float left, float right) { CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); diff --git a/frameworks/native/hdiadapter_new/source/va_capture_source.cpp b/frameworks/native/hdiadapter_new/source/va_capture_source.cpp new file mode 100644 index 0000000000..659efdb261 --- /dev/null +++ b/frameworks/native/hdiadapter_new/source/va_capture_source.cpp @@ -0,0 +1,398 @@ +/* + * 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 "VACaptureSource" +#endif + +#include "source/va_capture_source.h" + +#include +#include +#include "parameters.h" +#include "audio_hdi_log.h" +#include "audio_log.h" +#include "audio_dump_pcm.h" + +#include "manager/hdi_adapter_manager.h" + +#include "hisysevent.h" + +#include "iservice_registry.h" +#include "iaudio_policy.h" + +namespace OHOS { +namespace AudioStandard { + +VACaptureSource::VACaptureSource(const uint32_t captureId) : captureId_(captureId) +{ + audioSrcClock_ = std::make_shared(); + CapturerClockManager::GetInstance().RegisterAudioSourceClock(captureId, audioSrcClock_); +} + +VACaptureSource::~VACaptureSource() +{ + if (sourceInited_) { + DeInit(); + } + DumpFileUtil::CloseDumpFile(&dumpFile_); + CapturerClockManager::GetInstance().DeleteAudioSourceClock(captureId_); +} + +int32_t VACaptureSource::Init(const IAudioSourceAttr &attr) +{ + std::lock_guard lock(statusMutex_); + attr_ = attr; + if (sourceInited_) { + AUDIO_WARNING_LOG("va source already inited"); + return SUCCESS; + } + logMode_ = system::GetIntParameter("persist.multimedia.audiolog.switch", 0); + + int ret = CreateCapture(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "va create capture failed"); + ret = InitOperator(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "va init operator failed"); + + sourceInited_ = true; + + if (audioSrcClock_ != nullptr) { + audioSrcClock_->Init(attr.sampleRate, attr.format, attr.channel); + } + return SUCCESS; +} + +int32_t VACaptureSource::CreateCapture() +{ + Trace trace("VACaptureSource::CreateCapture"); + std::string macAddress = attr_.macAddress; + + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + CHECK_AND_RETURN_RET_LOG(samgr != nullptr, ERR_OPERATION_FAILED, "failed to obtain system ability manager"); + + static int32_t systemAbilityId = 3009; + sptr remoteObject = samgr->GetSystemAbility(systemAbilityId); + CHECK_AND_RETURN_RET_LOG(remoteObject != nullptr, ERR_OPERATION_FAILED, "policy service unavailable"); + + sptr audioProxy = iface_cast(remoteObject); + CHECK_AND_RETURN_RET_LOG(audioProxy != nullptr, ERR_OPERATION_FAILED, "audioProxy is null"); + + sptr controllerRemote; + audioProxy->GetVADeviceController(macAddress, controllerRemote); + CHECK_AND_RETURN_RET_LOG(controllerRemote != nullptr, ERR_OPERATION_FAILED, "get controller failed"); + + deviceController_ = iface_cast(controllerRemote); + CHECK_AND_RETURN_RET_LOG(deviceController_ != nullptr, ERR_OPERATION_FAILED, "convert to IVADeviceController failed"); + + std::shared_ptr prop = MakeVAStreamPropertyFromIAudioSourceAttr(); + std::shared_ptr attribute = MakeVAStreamAttributeFromIAudioSourceAttr(); + sptr inputStreamRemote; + int ret = deviceController_->OpenInputStream(*prop, *attribute, inputStreamRemote); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "openInputStream failed"); + + CHECK_AND_RETURN_RET_LOG(inputStreamRemote != nullptr, ERR_OPERATION_FAILED, "inputStreamRemote is nullptr"); + inputStream_ = iface_cast(inputStreamRemote); + CHECK_AND_RETURN_RET_LOG(inputStream_ != nullptr, ERR_OPERATION_FAILED, "inputStream_ is nullptr"); + + return SUCCESS; +} + +std::shared_ptr VACaptureSource::MakeVAStreamPropertyFromIAudioSourceAttr() +{ + std::shared_ptr streamProp = std::make_shared(); + streamProp->sampleRate_ = attr_.sampleRate; + streamProp->sampleFormat_ = attr_.format; + streamProp->channelLayout_ = static_cast(attr_.channelLayout); + return streamProp; +} + +std::shared_ptr VACaptureSource::MakeVAStreamAttributeFromIAudioSourceAttr() +{ + std::shared_ptr streamAttr = std::make_shared(); + streamAttr->type = static_cast(attr_.sourceType); + return streamAttr; +} + +int32_t VACaptureSource::InitOperator() +{ + CHECK_AND_RETURN_RET_LOG(inputStream_ != nullptr, ERR_OPERATION_FAILED, "input stream is nullptr"); + uint32_t bufferCapacity = attr_.bufferSize * 2; + std::shared_ptr vaBuffer = VASharedBuffer::CreateFromLocal(bufferCapacity); + CHECK_AND_RETURN_RET_LOG(vaBuffer != nullptr, ERR_OPERATION_FAILED, "vaBuffer is null"); + bufferOperator_ = std::make_shared(*vaBuffer); + CHECK_AND_RETURN_RET_LOG(bufferOperator_ != nullptr, ERR_OPERATION_FAILED, "buffer operator is null"); + bufferOperator_->SetMinReadSize(attr_.bufferSize); + + VASharedMemInfo memInfo; + vaBuffer->GetVASharedMemInfo(memInfo); + int ret = inputStream_->RequestSharedMem(memInfo); + return ret; +} + +void VACaptureSource::DeInit(void) +{ + std::lock_guard lock(statusMutex_); + Trace trace("VACaptureSource::DeInit"); + + CHECK_AND_RETURN_LOG(inputStream_ != nullptr, "input stream is null"); + inputStream_->Close(); + + sourceInited_ = false; + started_ = false; + inputStream_ = nullptr; + bufferOperator_ = nullptr; +} + +bool VACaptureSource::IsInited(void) +{ + return sourceInited_; +} + +int32_t VACaptureSource::Start(void) +{ + CHECK_AND_RETURN_RET_LOG(bufferOperator_ != nullptr && inputStream_ != nullptr, ERR_OPERATION_FAILED, "wrong status"); + std::lock_guard lock(statusMutex_); + + dumpFileName_ = "_va_source_" + std::to_string(attr_.sourceType) + "_" + 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_); + + if (started_) { + AUDIO_WARNING_LOG("va capture source is already started."); + Stop(); + } + + CHECK_AND_RETURN_RET_LOG(bufferOperator_ != nullptr, ERR_OPERATION_FAILED, "buffer operator is null"); + bufferOperator_->Reset(); + + if (audioSrcClock_ != nullptr) { + audioSrcClock_->Reset(); + } + callback_.OnCaptureState(true); + int ret = inputStream_->Start(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "va start failed"); + started_ = true; + + startTimestamp = ClockTime::GetCurNano(); + return SUCCESS; +} + +int32_t VACaptureSource::Stop(void) +{ + Trace trace("VACaptureSource::Stop"); + CHECK_AND_RETURN_RET_LOG(inputStream_ != nullptr, ERR_OPERATION_FAILED, "input stream is null"); + std::promise promiseEnsureLock; + auto futurePromiseEnsureLock = promiseEnsureLock.get_future(); + + std::thread stopThread([&promiseEnsureLock, this] { + std::lock_guardlock(statusMutex_); + promiseEnsureLock.set_value(); + DoStop(); + }); + futurePromiseEnsureLock.get(); + stopThread.detach(); + + int64_t stopTimestamp = ClockTime::GetCurNano(); + PrintDfx(stopTimestamp - startTimestamp); + return SUCCESS; +} + +int32_t VACaptureSource::DoStop(void) +{ + CHECK_AND_RETURN_RET_LOG(inputStream_ != nullptr, ERR_OPERATION_FAILED, "input stream is null"); + int ret = inputStream_->Stop(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "stop fail"); + started_ = false; + callback_.OnCaptureState(false); + return SUCCESS; +} + +int32_t VACaptureSource::Resume(void) +{ + return SUCCESS; +} + +int32_t VACaptureSource::Pause(void) +{ + return SUCCESS; +} + +int32_t VACaptureSource::Flush(void) +{ + return SUCCESS; +} + +int32_t VACaptureSource::Reset(void) +{ + return SUCCESS; +} + +int32_t VACaptureSource::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) +{ + CHECK_AND_RETURN_RET_LOG(bufferOperator_ != nullptr, ERR_OPERATION_FAILED, "buffer operator is null"); + CHECK_AND_RETURN_RET_LOG(inputStream_ != nullptr, ERR_OPERATION_FAILED, "input stream is null"); + + int64_t stamp = ClockTime::GetCurNano(); + replyBytes = bufferOperator_->Read(reinterpret_cast(frame), requestBytes); + if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) { + DumpFileUtil::WriteDumpFile(dumpFile_, frame, replyBytes); + AudioCacheMgr::GetInstance().CacheData(dumpFileName_, static_cast(frame), replyBytes); + } + CheckUpdateState(frame, requestBytes); + stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND; + if (logMode_) { + AUDIO_WARNING_LOG("len:[%{public}" PRIu64 "],cost:[%{public}" PRId64 "]ms", requestBytes, stamp); + } + return SUCCESS; +} + +int32_t VACaptureSource::CaptureFrameWithEc( + FrameDesc *fdesc, uint64_t &replyBytes, FrameDesc *fdescEc, uint64_t &replyBytesEc) +{ + AUDIO_INFO_LOG("not supported"); + return SUCCESS; +} + +std::string VACaptureSource::GetAudioParameter(const AudioParamKey key, const std::string &condition) +{ + CHECK_AND_RETURN_RET_LOG(deviceController_ != nullptr, "", "device controller is null"); + std::string value; + deviceController_->GetParameters(std::to_string(static_cast(key)), value); + AUDIO_INFO_LOG("get audio parameter from va device: {\"key\":\"%{public}d\", \"value\":\"%{public}s\"}", key, value.c_str()); + return value; +} + +void VACaptureSource::SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) +{ + AUDIO_INFO_LOG("set audio parameter for va device: {\"key\":\"%{public}d\", \"value\":\"%{public}s\"}", key, value.c_str()); + CHECK_AND_RETURN_LOG(deviceController_ != nullptr, "device controller is null"); + deviceController_->SetParameters(std::to_string(static_cast(key)), value); +} + +void VACaptureSource::PrintDfx(int64_t useTime) +{ + auto ret = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AUDIO, + "AUDIO_DEVICE_UTILIZATION_STATS", + HiviewDFX::HiSysEvent::EventType::STATISTIC, + "DEVICE_TYPE", + DeviceType::DEVICE_TYPE_BT_SPP, + "IS_PLAYBACK", + false, + "STREAM_TYPE", + AudioStreamType::STREAM_RECORDING, + "DURATION", + (int32_t)useTime); + if (ret) { + AUDIO_ERR_LOG("write event fail: AUDIO_DEVICE_UTILIZATION_STATS, ret = %{public}d", ret); + } +} + +int32_t VACaptureSource::SetVolume(float left, float right) +{ + return SUCCESS; +} +int32_t VACaptureSource::GetVolume(float &left, float &right) +{ + return SUCCESS; +} +int32_t VACaptureSource::SetMute(bool isMute) +{ + return SUCCESS; +} +int32_t VACaptureSource::GetMute(bool &isMute) +{ + return SUCCESS; +} + +uint64_t VACaptureSource::GetTransactionId(void) +{ + return SUCCESS; +} + +int32_t VACaptureSource::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec) +{ + return SUCCESS; +} + +float VACaptureSource::GetMaxAmplitude(void) +{ + lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano(); + startUpdate_ = true; + return maxAmplitude_; +} + +int32_t VACaptureSource::SetAudioScene(AudioScene audioScene, bool scoExcludeFlag) +{ + return SUCCESS; +} + +int32_t VACaptureSource::UpdateActiveDevice(DeviceType inputDevice) +{ + return SUCCESS; +} + +void VACaptureSource::CheckUpdateState(char *frame, size_t replyBytes) +{ + if (startUpdate_) { + if (captureFrameNum_ == 0) { + last10FrameStartTime_ = ClockTime::GetCurNano(); + } + captureFrameNum_++; + maxAmplitude_ = UpdateMaxAmplitude(static_cast(attr_.format), frame, replyBytes); + if (captureFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) { + captureFrameNum_ = 0; + if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) { + startUpdate_ = false; + maxAmplitude_ = 0; + } + } + } +} + +void VACaptureSource::RegistCallback(uint32_t type, IAudioSourceCallback *callback) +{ + callback_.RegistCallback(type, callback); +} + +void VACaptureSource::RegistCallback(uint32_t type, std::shared_ptr callback) +{ + callback_.RegistCallback(type, callback); +} + +int32_t VACaptureSource::UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE], const size_t size) +{ + return SUCCESS; +} +int32_t VACaptureSource::UpdateAppsUid(const std::vector &appsUid) +{ + return SUCCESS; +} + +void VACaptureSource::SetAddress(const std::string &address) +{} +void VACaptureSource::SetInvalidState(void) +{} + +void VACaptureSource::DumpInfo(std::string &dumpString) +{ + dumpString += "type: VASource\tstarted: " + std::string(started_ ? "true" : "false") + "\n"; +} + +void VACaptureSource::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType) +{} + +} // namespace AudioStandard +} // namespace OHOS diff --git a/frameworks/native/hdiadapter_new/source/wakeup_audio_capture_source.cpp b/frameworks/native/hdiadapter_new/source/wakeup_audio_capture_source.cpp index be66ffe53c..4c6c97121e 100644 --- a/frameworks/native/hdiadapter_new/source/wakeup_audio_capture_source.cpp +++ b/frameworks/native/hdiadapter_new/source/wakeup_audio_capture_source.cpp @@ -230,6 +230,13 @@ std::string WakeupAudioCaptureSource::GetAudioParameter(const AudioParamKey key, return ""; } +void WakeupAudioCaptureSource::SetAudioParameter( + const AudioParamKey key, const std::string &condition, const std::string &value) +{ + AUDIO_WARNING_LOG("not support"); + return; +} + int32_t WakeupAudioCaptureSource::SetVolume(float left, float right) { return audioCaptureSource_.SetVolume(left, right); diff --git a/frameworks/native/hdiadapter_new/test/unittest/source/va_capture_source_unit_test.cpp b/frameworks/native/hdiadapter_new/test/unittest/source/va_capture_source_unit_test.cpp new file mode 100644 index 0000000000..f13d710c6a --- /dev/null +++ b/frameworks/native/hdiadapter_new/test/unittest/source/va_capture_source_unit_test.cpp @@ -0,0 +1,317 @@ +/* + * 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 VACaptureSourceUnitTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp() {} + virtual void TearDown() {} + + void InitPrimarySource(); + void DeInitPrimarySource(); + void InitUsbSource(); + void DeInitUsbSource(); +protected: + static uint32_t primaryId_; + static uint32_t usbId_; + static std::shared_ptr primarySource_; + static std::shared_ptr usbSource_; + static IAudioSourceAttr attr_; +}; + +uint32_t VACaptureSourceUnitTest::primaryId_ = 0; +uint32_t VACaptureSourceUnitTest::usbId_ = 0; +std::shared_ptr VACaptureSourceUnitTest::primarySource_ = nullptr; +std::shared_ptr VACaptureSourceUnitTest::usbSource_ = nullptr; +IAudioSourceAttr VACaptureSourceUnitTest::attr_ = {}; + +void VACaptureSourceUnitTest::SetUpTestCase() +{ + HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); + primaryId_ = manager.GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT, true); + usbId_ = manager.GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_USB, true); +} + +void VACaptureSourceUnitTest::TearDownTestCase() +{ + HdiAdapterManager::GetInstance().ReleaseId(primaryId_); + HdiAdapterManager::GetInstance().ReleaseId(usbId_); +} + +void VACaptureSourceUnitTest::InitPrimarySource() +{ + primarySource_ = HdiAdapterManager::GetInstance().GetCaptureSource(primaryId_, true); + if (primarySource_ == nullptr){ + return; + } + attr_.adapterName = "primary"; + attr_.sampleRate = 48000; + attr_.channel = 2; + attr_.format = SAMPLE_S16LE; + attr_.channelLayout = 3; + attr_.deviceType = DEVICE_TYPE_MIC; + attr_.openMicSpeaker = 1; + primarySource_->Init(attr_); +} + +void VACaptureSourceUnitTest::DeInitPrimarySource() +{ + if (primarySource_ && primarySource_->IsInited()) { + primarySource_->DeInit(); + } + primarySource_ = nullptr; +} + +void VACaptureSourceUnitTest::InitUsbSource() +{ + usbSource_ = HdiAdapterManager::GetInstance().GetCaptureSource(usbId_, true); + if (usbSource_ == nullptr) { + return; + } + attr_.adapterName = "usb"; + attr_.channel = 2; + usbSource_->Init(attr_); +} + +void VACaptureSourceUnitTest::DeInitUsbSource() +{ + if (usbSource_ && usbSource_->IsInited()) { + usbSource_->DeInit(); + } + usbSource_ = nullptr; +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_001 + * @tc.desc : Test primary source create + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_001, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ != nullptr); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_002 + * @tc.desc : Test primary source init + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_002, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_003 + * @tc.desc : Test primary source deinit + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_003, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + primarySource_->DeInit(); + int32_t ret = primarySource_->Init(attr_); + EXPECT_EQ(ret, SUCCESS); + ret = primarySource_->Init(attr_); + EXPECT_EQ(ret, SUCCESS); + EXPECT_TRUE(primarySource_->IsInited()); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_004 + * @tc.desc : Test primary source start, stop, resume, pause, flush, reset + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_004, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + int32_t ret = primarySource_->Start(); + EXPECT_EQ(ret, SUCCESS); + ret = primarySource_->Stop(); + EXPECT_EQ(ret, SUCCESS); + ret = primarySource_->Start(); + EXPECT_EQ(ret, SUCCESS); + ret = primarySource_->Resume(); + EXPECT_EQ(ret, SUCCESS); + ret = primarySource_->Pause(); + EXPECT_EQ(ret, ERR_OPERATION_FAILED); + ret = primarySource_->Flush(); + EXPECT_EQ(ret, ERR_OPERATION_FAILED); + ret = primarySource_->Reset(); + EXPECT_EQ(ret, ERR_OPERATION_FAILED); + ret = primarySource_->Stop(); + EXPECT_EQ(ret, SUCCESS); + DeInitPrimarySource(); +} + +/** +* @tc.name : Test SetDmDeviceType API +* @tc.number : PrimarySourceUnitTest_0015 +* @tc.desc : Test SetDmDeviceType +*/ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_0015, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + int32_t ret = primarySource_->Start(); + EXPECT_EQ(ret,SUCCESS); + + int32_t ret2 = primarySource_->Start(); + EXPECT_EQ(ret2,SUCCESS); + + int32_t ret3 = primarySource_->Stop(); + EXPECT_EQ(ret3,SUCCESS); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_005 + * @tc.desc : Test primary source get param + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_005, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + std::string param = primarySource_->GetAudioParameter(USB_DEVICE, ""); + EXPECT_EQ(param, ""); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_006 + * @tc.desc : Test primary source set volume + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_006, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + int32_t ret = primarySource_->SetVolume(1.0f, 1.0f); + EXPECT_NE(ret, SUCCESS); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_007 + * @tc.desc : Test primary source set/get mute + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_007, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + int32_t ret = primarySource_->SetMute(false); + EXPECT_EQ(ret, SUCCESS); + bool mute = false; + ret = primarySource_->GetMute(mute); + EXPECT_EQ(ret, SUCCESS); + EXPECT_FALSE(mute); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_008 + * @tc.desc : Test primary source get transaction id + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_008, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + uint64_t transId = primarySource_->GetTransactionId(); + EXPECT_NE(transId, 0); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_009 + * @tc.desc : Test primary source get max amplitude + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_009, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + float maxAmplitude = primarySource_->GetMaxAmplitude(); + EXPECT_EQ(maxAmplitude, 0.0f); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_010 + * @tc.desc : Test primary source set audio scene + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_010, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + int32_t ret = primarySource_->SetAudioScene(AUDIO_SCENE_DEFAULT); + EXPECT_EQ(ret, SUCCESS); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test PrimarySource API + * @tc.number : PrimarySourceUnitTest_012 + * @tc.desc : Test primary source update apps uid + */ +HWTEST_F(VACaptureSourceUnitTest, PrimarySourceUnitTest_012, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + vector appsUid; + int32_t ret = primarySource_->UpdateAppsUid(appsUid); + EXPECT_EQ(ret, SUCCESS); + DeInitPrimarySource(); +} + +/** + * @tc.name : Test SetDmDeviceType API + * @tc.number : SetDmDeviceType_001 + * @tc.desc : Test SetDmDeviceType + */ +HWTEST_F(VACaptureSourceUnitTest, SetDmDeviceType_001, TestSize.Level1) +{ + InitPrimarySource(); + EXPECT_TRUE(primarySource_ && primarySource_->IsInited()); + primarySource_->UpdateActiveDevice(DEVICE_TYPE_MIC); + primarySource_->SetDmDeviceType(DM_DEVICE_TYPE_DEFAULT, DEVICE_TYPE_MIC); + primarySource_->SetDmDeviceType(DM_DEVICE_TYPE_NEARLINK_SCO, DEVICE_TYPE_MIC); + DeInitPrimarySource(); +} + +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/hdiadapter_new/util/id_handler.cpp b/frameworks/native/hdiadapter_new/util/id_handler.cpp index cf9ab8bc6c..5474c8d040 100644 --- a/frameworks/native/hdiadapter_new/util/id_handler.cpp +++ b/frameworks/native/hdiadapter_new/util/id_handler.cpp @@ -108,6 +108,8 @@ uint32_t IdHandler::GetCaptureIdByDeviceClass(const std::string &deviceClass, co return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_AI, HDI_ID_INFO_DEFAULT); } return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT); + } else if (deviceClass == "va"){ + return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_VA, HDI_ID_INFO_VA); } else if (deviceClass == "usb") { return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_USB); } else if (deviceClass == "a2dp") { diff --git a/interfaces/inner_api/native/audiocapturer/include/audio_capturer.h b/interfaces/inner_api/native/audiocapturer/include/audio_capturer.h index 957e67ae8f..8ed73baaa2 100644 --- a/interfaces/inner_api/native/audiocapturer/include/audio_capturer.h +++ b/interfaces/inner_api/native/audiocapturer/include/audio_capturer.h @@ -21,6 +21,7 @@ #include "audio_stream_change_info.h" #include "microphone_descriptor.h" #include "timestamp.h" +#include "audio_capturer_options.h" namespace OHOS { namespace AudioStandard { diff --git a/interfaces/inner_api/native/audiocommon/include/audio_capturer_options.h b/interfaces/inner_api/native/audiocommon/include/audio_capturer_options.h new file mode 100644 index 0000000000..be18c54ae6 --- /dev/null +++ b/interfaces/inner_api/native/audiocommon/include/audio_capturer_options.h @@ -0,0 +1,51 @@ +/* + * 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_CAPTURER_OPTIONS_H +#define AUDIO_CAPTURER_OPTIONS_H + +#ifdef __MUSL__ +#include +#endif // __MUSL__ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_source_type.h" +#include "audio_device_info.h" +#include "audio_interrupt_info.h" +#include "audio_session_info.h" +#include "audio_stream_info.h" +#include "audio_asr.h" +#include "audio_device_descriptor.h" +#include "audio_info.h" + +namespace OHOS { +namespace AudioStandard { +struct AudioCapturerOptions { + AudioStreamInfo streamInfo; + AudioCapturerInfo capturerInfo; + AudioPlaybackCaptureConfig playbackCaptureConfig; + AudioSessionStrategy strategy = { AudioConcurrencyMode::INVALID }; +}; +} //namespace AudioStandard +} //namespace OHOS +#endif // AUDIO_CAPTURER_OPTIONS_H 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 6486fcb4b0..e52cb59ab2 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_device_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_device_info.h @@ -186,6 +186,8 @@ enum DeviceType { * Indicates a Nearlink device for input. */ DEVICE_TYPE_NEARLINK_IN = 32, + DEVICE_TYPE_BT_SPP = 33, + DEVICE_TYPE_NEARLINK_PORT = 34, /** * Indicates a debug sink device */ @@ -198,6 +200,7 @@ enum DeviceType { * Indicates any headset/headphone for disconnect */ DEVICE_TYPE_EXTERN_CABLE = 100, + DEVICE_TYPE_SYSTEM_PRIVATE = 200, /** * Indicates default device */ @@ -223,6 +226,8 @@ inline const std::unordered_set INPUT_DEVICE_TYPE_SET = { DeviceType::DEVICE_TYPE_FILE_SOURCE, DeviceType::DEVICE_TYPE_ACCESSORY, DeviceType::DEVICE_TYPE_NEARLINK_IN, + DeviceType::DEVICE_TYPE_BT_SPP, + DeviceType::DEVICE_TYPE_NEARLINK_PORT, }; inline bool IsInputDevice(DeviceType deviceType, DeviceRole deviceRole = DEVICE_ROLE_NONE) diff --git a/interfaces/inner_api/native/audiocommon/include/audio_info.h b/interfaces/inner_api/native/audiocommon/include/audio_info.h index 98b66eb36d..606031c77a 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_info.h @@ -1032,12 +1032,6 @@ struct AudioPlaybackCaptureConfig : public Parcelable { } }; -struct AudioCapturerOptions { - AudioStreamInfo streamInfo; - AudioCapturerInfo capturerInfo; - AudioPlaybackCaptureConfig playbackCaptureConfig; - AudioSessionStrategy strategy = { AudioConcurrencyMode::INVALID }; -}; struct AppInfo { int32_t appUid { INVALID_UID }; diff --git a/interfaces/inner_api/native/audiocommon/include/va_device.h b/interfaces/inner_api/native/audiocommon/include/va_device.h new file mode 100644 index 0000000000..c5a3c5b8c8 --- /dev/null +++ b/interfaces/inner_api/native/audiocommon/include/va_device.h @@ -0,0 +1,55 @@ +/* + * 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 VA_DEVICE_H +#define VA_DEVICE_H + +#include "audio_device_info.h" +#include "audio_info.h" +#include "audio_stream_info.h" + +#include "va_device_info.h" + +#include "message_parcel.h" + +namespace OHOS { +namespace AudioStandard { +struct VADevice : public Parcelable { + std::string implementor_; + VADeviceConfiguration configuration_; + + VADevice() = default; + + bool Marshalling(Parcel& parcel)const override + { + return parcel.WriteString(implementor_) && configuration_.Marshalling(parcel); + } + void UnmarshallingSelf(Parcel& parcel) + { + implementor_ = parcel.ReadString(); + configuration_.UnmarshallingSelf(parcel); + } + static VADevice* Unmarshalling(Parcel& parcel) + { + auto device = new VADevice(); + if (device == nullptr){ + return nullptr; + } + device->UnmarshallingSelf(parcel); + return device; + } +}; +} //namespace AudioStandard +} //namespace OHOS +#endif //VA_DEVICE_INFO_H diff --git a/interfaces/inner_api/native/audiocommon/include/va_device_info.h b/interfaces/inner_api/native/audiocommon/include/va_device_info.h new file mode 100644 index 0000000000..bf7ed6590f --- /dev/null +++ b/interfaces/inner_api/native/audiocommon/include/va_device_info.h @@ -0,0 +1,209 @@ +/* + * 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 VA_DEVICE_INFO_H +#define VA_DEVICE_INFO_H + +#include "audio_device_info.h" +#include "message_parcel.h" +#include "audio_info.h" +#include "audio_stream_info.h" + +namespace OHOS { +namespace AudioStandard { + +static void CheckVADeviceInfoSize(size_t &size) +{ + if (size > AUDIO_DEVICE_INFO_SIZE_LIMIT) { + size = AUDIO_DEVICE_INFO_SIZE_LIMIT; + } +} + +enum VADeviceRole { + VA_DEVICE_ROLE_IN = 1, + VA_DEVICE_ROLE_OUT = 2, +}; + +enum VADeviceType { + VA_DEVICE_TYPE_NONE = 0, + VA_DEVICE_TYPE_BT_SPP = 1, +}; + +struct VAAudioStreamProperty : public Parcelable { + AudioEncodingType encoding_; + int32_t sampleRate_; + int32_t samplesPerCycle_; + AudioSampleFormat sampleFormat_; + AudioChannelLayout channelLayout_; + + VAAudioStreamProperty() = default; + + bool Marshalling(Parcel &parcel) const override + { + return parcel.WriteInt32(static_cast(encoding_)) && + parcel.WriteInt32(sampleRate_) && + parcel.WriteInt32(samplesPerCycle_) && + parcel.WriteInt32(static_cast(sampleFormat_)) && + parcel.WriteUint64(static_cast(channelLayout_)); + } + + void UnmarshallingSelf(Parcel& parcel) + { + encoding_ = static_cast(parcel.ReadInt32()); + sampleRate_ = parcel.ReadInt32(); + samplesPerCycle_ = parcel.ReadInt32(); + sampleFormat_ = static_cast(parcel.ReadUint8()); + channelLayout_ = static_cast(parcel.ReadUint64()); + } + + static VAAudioStreamProperty* Unmarshalling(Parcel& parcel) + { + auto streamProperty = new VAAudioStreamProperty(); + if (streamProperty == nullptr) { + return nullptr; + } + streamProperty->UnmarshallingSelf(parcel); + return streamProperty; + } +}; + +static bool MarshallingVAAudioStreamPropertyList(const std::list& streamProperties, Parcel& parcel) +{ + size_t size = streamProperties.size(); + if (!parcel.WriteUint64(size)) { + return false; + } + + for (const auto& streamProperty : streamProperties) { + bool isMarshSuccess = streamProperty.Marshalling(parcel); + if (!isMarshSuccess) { + return false; + } + } + return true; +} + +static void UnmarshallingVAAudioStreamPropertyList(Parcel& parcel, std::list& streamProperties) +{ + size_t size = parcel.ReadUint64(); + // due to security concerns,sizelimit has been imposed + CheckVADeviceInfoSize(size); + + for (size_t i = 0; i < size; i++) { + VAAudioStreamProperty streamProperty; + streamProperty.UnmarshallingSelf(parcel); + streamProperties.push_back(streamProperty); + } +} + +struct VADeviceConfiguration :public Parcelable { + std::string name_; + std::string address_; + VADeviceRole role_; + VADeviceType type_; + std::list properties_; + + VADeviceConfiguration() = default; + VADeviceConfiguration(const std::string &name, const std::string &address, VADeviceRole role, VADeviceType type) + : name_(name), address_(address), role_(role), type_(type) + {} + + bool Marshalling(Parcel &parcel) const override + { + return parcel.WriteString(name_) && parcel.WriteString(address_) && + parcel.WriteInt32(static_cast(role_)) && parcel.WriteInt32(static_cast(type_)) && + MarshallingVAAudioStreamPropertyList(properties_, parcel); + } + void UnmarshallingSelf(Parcel &parcel) + { + name_ = parcel.ReadString(); + address_ = parcel.ReadString(); + role_ = static_cast(parcel.ReadInt32()); + type_ = static_cast(parcel.ReadInt32()); + UnmarshallingVAAudioStreamPropertyList(parcel, properties_); + } + static VADeviceConfiguration *Unmarshalling(Parcel &parcel) + { + auto deviceConfig = new VADeviceConfiguration(); + if (deviceConfig == nullptr) { + return nullptr; + } + deviceConfig->UnmarshallingSelf(parcel); + return deviceConfig; + } +}; + +struct VAInputStreamAttribute : public Parcelable { + SourceType type; + bool Marshalling(Parcel &parcel) const + { + return parcel.WriteInt32(static_cast(type)); + } + + void UnmarshallingSelf(Parcel &parcel) + { + type = static_cast(parcel.ReadInt32()); + } + + static VAInputStreamAttribute *Unmarshalling(Parcel &parcel) + { + auto streamAttribute = new VAInputStreamAttribute(); + if (streamAttribute == nullptr) { + return nullptr; + } + streamAttribute->UnmarshallingSelf(parcel); + return streamAttribute; + } +}; + +struct VASharedMemInfo : public Parcelable { + int dataFd_; + int dataMemCapacity_; + int statusFd_; + int statusMemCapacity_; + + VASharedMemInfo() = default; + + bool Marshalling(Parcel &parcel) const override + { + MessageParcel &msgParcel = static_cast(parcel); + return msgParcel.WriteFileDescriptor(dataFd_) && + msgParcel.WriteInt32(dataMemCapacity_) && + msgParcel.WriteFileDescriptor(statusFd_) && + msgParcel.WriteInt32(statusMemCapacity_); + } + + void UnmarshallingSelf(Parcel &parcel) + { + MessageParcel &msgParcel = static_cast(parcel); + dataFd_ = msgParcel.ReadFileDescriptor(); + dataMemCapacity_ = msgParcel.ReadInt32(); + statusFd_ = msgParcel.ReadFileDescriptor(); + statusMemCapacity_ = msgParcel.ReadInt32(); + } + + static VASharedMemInfo *Unmarshalling(Parcel &parcel) + { + auto memInfo = new VASharedMemInfo(); + if (memInfo == nullptr) { + return nullptr; + } + memInfo->UnmarshallingSelf(parcel); + return memInfo; + } +}; + +} //namespace AudioStandard +} //namespace OHOS +#endif //VA_DEVICE_INFO_H \ No newline at end of file diff --git a/interfaces/inner_api/native/audiomanager/include/audio_policy_interface.h b/interfaces/inner_api/native/audiomanager/include/audio_policy_interface.h index 9e11ae84fc..48e0b05820 100644 --- a/interfaces/inner_api/native/audiomanager/include/audio_policy_interface.h +++ b/interfaces/inner_api/native/audiomanager/include/audio_policy_interface.h @@ -24,6 +24,7 @@ #include "audio_info.h" #include "audio_interrupt_info.h" #include "audio_stream_change_info.h" +#include "va_device.h" namespace OHOS { namespace AudioStandard { @@ -352,6 +353,37 @@ public: */ virtual int32_t GetRenderPosition(const std::string &device, uint32_t &delayValue) = 0; }; + +class VAStreamCallback{ +public: + virtual int32_t Start() = 0; + virtual int32_t Stop() = 0; + virtual int32_t Close() = 0; + virtual int32_t GetStreamProperty(VAAudioStreamProperty& streamProp) = 0; + virtual int32_t RequestSharedMem(const VASharedMemInfo& memInfo) = 0; +}; + +class VAInputStreamCallback : public VAStreamCallback { +public: + virtual int32_t GetCapturePosition(uint64_t& attr_1, uint64_t& attr_2) = 0; +}; + +class VADeviceControllerCallback { +public: + virtual int32_t OpenInputStream(const VAAudioStreamProperty &prop, const VAInputStreamAttribute &attr, + std::shared_ptr &inputStream) = 0; + virtual int32_t GetParameters(const std::string& key, std::string& value) = 0; + + virtual int32_t SetParameters(const std::string& key, const std::string& value) = 0; +}; + +class VADeviceBrokerWrapper { +public: + virtual int32_t OnDevicesConnected(const VADevice &device, + const std::shared_ptr &controllerCallback) = 0; + virtual int32_t OnDevicesDisconnected(const VADevice &device) = 0; +}; + } // namespace AudioStandard } // namespace OHOS #endif // ST_AUDIO_POLICY_INTERFACE_H diff --git a/services/audio_policy/BUILD.gn b/services/audio_policy/BUILD.gn index 0527f33b04..7aa1bfaf80 100644 --- a/services/audio_policy/BUILD.gn +++ b/services/audio_policy/BUILD.gn @@ -73,6 +73,7 @@ config("audio_policy_public_config") { "server/domain/zone/include", "server/domain/device/include", "server/domain/device/src/a2dp", + "server/domain/device/src/va", "server/src/service/concurrency", "server/domain/session/include", "server/service/service_main/include", @@ -263,6 +264,8 @@ audio_ohos_library("audio_policy_service") { "server/domain/tone/audio_tone_manager.cpp", "server/domain/volume/src/audio_volume_manager.cpp", "server/domain/device/src/sle/sle_audio_device_manager.cpp", + "server/domain/device/src/va/va_device_manager.cpp", + "client/stub/src/va_device_broker_stub_impl.cpp", "server/domain/session/src/audio_session.cpp", "server/domain/session/src/audio_session_service.cpp", "server/domain/session/src/audio_session_state_monitor.cpp", @@ -625,6 +628,7 @@ group("audio_policy_test_packages") { "server/domain/pipe/test:audio_policy_pipe_unittest_packages", "server/domain/router/test:audio_router_unittest_packages", "server/domain/session/test:audio_policy_session_unit_test", + "server/domain/pipe/test:audio_capturer_session_ext_unit_test", "server/domain/volume/test:audio_volume_unittest_packages", "server/service/service_main/test:audio_policy_dump_unit_test", "server/service/service_main/test:audio_policy_server_extended_test", @@ -705,6 +709,7 @@ config("audio_foundation_public_config") { "../../interfaces/inner_api/native/audiocommon/include", "../../interfaces/inner_api/native/audiomanager/include", "../../frameworks/native/audiopolicy/include", + "//foundation/multimedia/audio_framework/services/audio_service/idl", ] } diff --git a/services/audio_policy/client/stub/include/va_device_broker_stub_impl.h b/services/audio_policy/client/stub/include/va_device_broker_stub_impl.h new file mode 100644 index 0000000000..986c8cd706 --- /dev/null +++ b/services/audio_policy/client/stub/include/va_device_broker_stub_impl.h @@ -0,0 +1,47 @@ +/* + * 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 VA_DEVICE_BROKER_STUB_H +#define VA_DEVICE_BROKER_STUB_H + +#include + +#include "audio_policy_interface.h" +#include "va_device_broker_stub.h" + +#include "audio_errors.h" +#include "audio_info.h" +#include "audio_device_info.h" +#include "audio_device_descriptor.h" + +#include "va_device.h" +#include "iv_a_device_controller.h" + +namespace OHOS { +namespace AudioStandard { + +class VADeviceBrokerStubImpl :public VADeviceBrokerStub { +public : + static sptr Create(); + + VADeviceBrokerStubImpl(); + virtual ~VADeviceBrokerStubImpl(); + + int32_t OnDevicesConnected(const VADevice& device, const sptr& controller)override; + int32_t OnDevicesDisconnected(const VADevice& device)override; +}; +} //namespace AudioStandard +} //namespace OHOS +#endif //VA_DEVICE_BROKER_STUB_H \ No newline at end of file diff --git a/services/audio_policy/client/stub/include/va_device_broker_wrapper_Impl.h b/services/audio_policy/client/stub/include/va_device_broker_wrapper_Impl.h new file mode 100644 index 0000000000..15b29682b2 --- /dev/null +++ b/services/audio_policy/client/stub/include/va_device_broker_wrapper_Impl.h @@ -0,0 +1,39 @@ +/* + * 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 VA_DEVICE_BROKER_WRAPPER_IMPL_H +#define VA_DEVICE_BROKER_WRAPPER_IMPL_H + +#include "audio_policy_interface.h" + +#include "iaudio_policy.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace AudioStandard { + +class VADeviceBrokerWrapperImpl : public VADeviceBrokerWrapper { +public : + VADeviceBrokerWrapperImpl(); + virtual ~VADeviceBrokerWrapperImpl(); + int32_t OnDevicesConnected( + const VADevice& device, const std::shared_ptr& controllerCallback) override; + int32_t OnDevicesDisconnected(const VADevice& device)override; + + static const sptr GetAudioPolicyProxyFromSamgr(bool block = true); +}; +} // namespace AudioStandard +} // namespace OHOS +#endif //VA_DEVICE_BROKER_WRAPPER_IMPL_H diff --git a/services/audio_policy/client/stub/include/va_device_controller_stub_impl.h b/services/audio_policy/client/stub/include/va_device_controller_stub_impl.h new file mode 100644 index 0000000000..107f723dda --- /dev/null +++ b/services/audio_policy/client/stub/include/va_device_controller_stub_impl.h @@ -0,0 +1,44 @@ +/* + * 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 VA_DEVICE_CONTROLLER_STUB_H +#define VA_DEVICE_CONTROLLER_STUB_H + +#include + +#include "audio_policy_interface.h" +#include "va_device_controller_stub.h" + +namespace OHOS { +namespace AudioStandard { + +class VADeviceControllerStubImpl : public VADeviceControllerStub { +public: + VADeviceControllerStubImpl(); + virtual ~VADeviceControllerStubImpl(); + + int32_t SetVADeviceControllerCallback(const std::shared_ptr &callback); + + int32_t OpenInputStream(const VAAudioStreamProperty& prop, const VAInputStreamAttribute& attr, sptr& inputStream) override; + int32_t GetParameters(const std::string& key, std::string& value) override; + int32_t SetParameters(const std::string& key, const std::string& value) override; + +private: + std::mutex vaDeviceControllerMutex_; + std::shared_ptr vaDeviceControllerCallback_; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // VA_DEVICE_CONTROLLER_STUB_H \ No newline at end of file diff --git a/services/audio_policy/client/stub/include/va_input_stream_stub_impl.h b/services/audio_policy/client/stub/include/va_input_stream_stub_impl.h new file mode 100644 index 0000000000..f5fb1b764c --- /dev/null +++ b/services/audio_policy/client/stub/include/va_input_stream_stub_impl.h @@ -0,0 +1,46 @@ +/* + * 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 VA_INPUT_STREAM_STUB_IMPL_H + #define VA_INPUT_STREAM_STUB_IMPL_H + + #include "audio_policy_interface.h" + #include "va_input_stream_stub.h" + +namespace OHOS { +namespace AudioStandard { + +class VAInputStreamStubImpl : public VAInputStreamStub { +public: + VAInputStreamStubImpl(); + virtual ~VAInputStreamStubImpl(); + + int32_t SetVAInputStreamCallback(const std::shared_ptr &callback); + + int32_t GetStreamProperty(VAAudioStreamProperty& streamProp) override; + int32_t RequestSharedMem(const VASharedMemInfo& memInfo) override; + int32_t Start() override; + int32_t Stop() override; + int32_t Close() override; + int32_t GetCapturePosition(uint64_t& attr_1, uint64_t& attr_2) override; + +private: + std::shared_ptr vaInputStreamCallback_; +}; + +} // namespace AudioStandard +} // namespace OHOS + + #endif // VA_INPUT_STREAM_STUB_IMPL_H \ No newline at end of file diff --git a/services/audio_policy/client/stub/src/va_device_broker_stub_impl.cpp b/services/audio_policy/client/stub/src/va_device_broker_stub_impl.cpp new file mode 100644 index 0000000000..5a3a8a9967 --- /dev/null +++ b/services/audio_policy/client/stub/src/va_device_broker_stub_impl.cpp @@ -0,0 +1,66 @@ +/* + * 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 "VADeviceBrokerStubImpl" +#endif + +#include "va_device_broker_stub_impl.h" + +#include "audio_errors.h" +#include "audio_policy_log.h" + +#include "va_device_manager.h" +#include "audio_policy_server.h" + +#include "audio_log.h" + +using namespace std; + +namespace OHOS { +namespace AudioStandard { + +sptr VADeviceBrokerStubImpl::Create() +{ + sptr vaDeviceBroker = sptr::MakeSptr(); + return vaDeviceBroker; +} + +VADeviceBrokerStubImpl::VADeviceBrokerStubImpl() +{} + +VADeviceBrokerStubImpl::~VADeviceBrokerStubImpl() +{} + +int32_t VADeviceBrokerStubImpl::OnDevicesConnected(const VADevice &device, const sptr& controller) +{ + sptr vaDeviceController = iface_cast(controller); + CHECK_AND_RETURN_RET_LOG(vaDeviceController != nullptr, ERR_INVALID_PARAM, "controller is null"); + auto sharedDevice = std::make_shared(device); + + VADeviceManager::GetInstance().OnDevicesConnected(sharedDevice, vaDeviceController); + + return SUCCESS; +} + +int32_t VADeviceBrokerStubImpl::OnDevicesDisconnected(const VADevice &device) +{ + auto sharedDevice = std::make_shared(device); + VADeviceManager::GetInstance().OnDevicesDisconnected(sharedDevice); + return SUCCESS; +} + +} //namespace AudioStandard +} //namespace OHOS \ No newline at end of file diff --git a/services/audio_policy/client/stub/src/va_device_broker_wrapper_Impl.cpp b/services/audio_policy/client/stub/src/va_device_broker_wrapper_Impl.cpp new file mode 100644 index 0000000000..f3342456d6 --- /dev/null +++ b/services/audio_policy/client/stub/src/va_device_broker_wrapper_Impl.cpp @@ -0,0 +1,92 @@ +/* + * 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 "VADeviceBrokerWrapperImpl" +#endif + +#include "va_device_broker_wrapper_Impl.h" +#include "va_device_controller_stub_impl.h" +#include "iv_a_device_broker.h" + +#include "audio_errors.h" +#include "audio_policy_log.h" + +namespace OHOS { +namespace AudioStandard { +VADeviceBrokerWrapperImpl::VADeviceBrokerWrapperImpl() +{ +} + +VADeviceBrokerWrapperImpl::~VADeviceBrokerWrapperImpl() +{ +} +int32_t VADeviceBrokerWrapperImpl::OnDevicesConnected( + const VADevice& device, const std::shared_ptr& controllerCallback) +{ + + CHECK_AND_RETURN_RET_LOG(controllerCallback != nullptr, ERROR); + const sptr gsp = GetAudioPolicyProxyFromSamgr(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, ERROR); + sptr brokerObject; + gsp->GetVADeviceBroker(brokerObject); + CHECK_AND_RETURN_RET_LOG(brokerObject != nullptr, ERROR); + sptr ivaBroker = iface_cast(brokerObject); + CHECK_AND_RETURN_RET_LOG(ivaBroker != nullptr, ERROR); + + auto controllerStubImpl = new (std::nothrow) VADeviceControllerStubImpl(); + CHECK_AND_RETURN_RET_LOG(controllerStubImpl != nullptr, ERROR); + + controllerStubImpl->SetVADeviceControllerCallback (controllerCallback); + sptr controllerStubImplObject = controllerStubImpl->AsObject(); + if (controllerStubImplObject == nullptr) { + + delete controllerStubImpl; + return ERROR; + } + ivaBroker->OnDevicesConnected(device, controllerStubImplObject); + return SUCCESS; +} +int32_t VADeviceBrokerWrapperImpl::OnDevicesDisconnected(const VADevice& device) +{ + const sptr gsp = GetAudioPolicyProxyFromSamgr(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, ERROR); + sptrbrokerObject; + gsp->GetVADeviceBroker(brokerObject); + CHECK_AND_RETURN_RET_LOG(brokerObject != nullptr, ERROR); + sptr ivaBroker = iface_cast(brokerObject); + CHECK_AND_RETURN_RET_LOG(ivaBroker != nullptr, ERROR); + + ivaBroker->OnDeviceDisconnected(device); + return SUCCESS; +} + +const sptr VADeviceBrokerWrapperImpl::GetAudioPolicyProxyFromSamgr(bool block) +{ + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr); + sptr object = nullptr; + if (!block) { + object = samgr->CheckSystemAbility(AUDIO_POLICY_SERVICE_ID); + }else { + object = samgr->GetSystemAbility(AUDIO_POLICY_SERVICE_ID); + } + CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr); + sptr apProxy= iface_cast(object); + CHECK_AND_RETURN_RET_LOG(apProxy != nullptr, nullptr); + return apProxy; +} +} //namespace AudioStandard +} //namespace OHOS \ No newline at end of file diff --git a/services/audio_policy/client/stub/src/va_device_controller_stub_impl.cpp b/services/audio_policy/client/stub/src/va_device_controller_stub_impl.cpp new file mode 100644 index 0000000000..49f19b1b03 --- /dev/null +++ b/services/audio_policy/client/stub/src/va_device_controller_stub_impl.cpp @@ -0,0 +1,96 @@ +/* + * 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 "VADeviceControllerStubImpl" +#endif + +#include "va_device_controller_stub_impl.h" +#include "va_input_stream_stub_impl.h" + +#include "audio_errors.h" +#include "audio_policy_log.h" + + +namespace OHOS{ +namespace AudioStandard { +VADeviceControllerStubImpl::VADeviceControllerStubImpl() +{} + +VADeviceControllerStubImpl::~VADeviceControllerStubImpl() +{} + +int32_t VADeviceControllerStubImpl::SetVADeviceControllerCallback( + const std::shared_ptr &callback) +{ + CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERROR); + std::lock_guard lock(vaDeviceControllerMutex_); + vaDeviceControllerCallback_ = callback; + + return SUCCESS; +} + +int32_t VADeviceControllerStubImpl::OpenInputStream(const VAAudioStreamProperty &prop, + const VAInputStreamAttribute &attr, + sptr &inputStream) +{ + std::unique_lock lock(vaDeviceControllerMutex_); + CHECK_AND_RETURN_RET_LOG(vaDeviceControllerCallback_ != nullptr, ERROR); + lock.unlock(); + + std::shared_ptr inputStreamCallback; + vaDeviceControllerCallback_->OpenInputStream(prop, attr, inputStreamCallback); + CHECK_AND_RETURN_RET_LOG(inputStreamCallback != nullptr, ERROR); + + auto vaInputStreamStubImpl = sptr::MakeSptr(); + + CHECK_AND_RETURN_RET_LOG(vaInputStreamStubImpl != nullptr, ERROR); + + vaInputStreamStubImpl->SetVAInputStreamCallback(inputStreamCallback); + + inputStream = vaInputStreamStubImpl->AsObject(); + + if(inputStream == nullptr) { + delete vaInputStreamStubImpl; + return ERROR; + } + + return SUCCESS; +} + +int32_t VADeviceControllerStubImpl::GetParameters(const std::string& key, std::string& value) +{ + std::unique_lock lock(vaDeviceControllerMutex_); + CHECK_AND_RETURN_RET_LOG(vaDeviceControllerCallback_ != nullptr, ERROR); + lock.unlock(); + + vaDeviceControllerCallback_->GetParameters(key, value); + + return SUCCESS; +} + +int32_t VADeviceControllerStubImpl::SetParameters(const std::string& key, const std::string& value) +{ + std::unique_lock lock(vaDeviceControllerMutex_); + CHECK_AND_RETURN_RET_LOG(vaDeviceControllerCallback_ != nullptr, ERROR); + lock.unlock(); + + vaDeviceControllerCallback_->SetParameters(key, value); + + return SUCCESS; +} + +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_policy/client/stub/src/va_input_stream_stub_impl.cpp b/services/audio_policy/client/stub/src/va_input_stream_stub_impl.cpp new file mode 100644 index 0000000000..a88a246fbe --- /dev/null +++ b/services/audio_policy/client/stub/src/va_input_stream_stub_impl.cpp @@ -0,0 +1,84 @@ +/* + * 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 "VAInputStreamStubImpl" +#endif + +#include "va_input_stream_stub_impl.h" + +#include "audio_errors.h" +#include "audio_policy_log.h" + +namespace OHOS{ +namespace AudioStandard { +VAInputStreamStubImpl::VAInputStreamStubImpl() +{} + +VAInputStreamStubImpl::~VAInputStreamStubImpl() +{} + +int32_t VAInputStreamStubImpl::SetVAInputStreamCallback( + const std::shared_ptr &callback) +{ + CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM); + vaInputStreamCallback_ = callback; + return SUCCESS; +} + +int32_t VAInputStreamStubImpl::GetStreamProperty(VAAudioStreamProperty& streamProp) +{ + CHECK_AND_RETURN_RET_LOG(vaInputStreamCallback_ != nullptr, ERROR); + vaInputStreamCallback_->GetStreamProperty(streamProp); + return SUCCESS; +} + +int32_t VAInputStreamStubImpl::RequestSharedMem(const VASharedMemInfo& memInfo) +{ + CHECK_AND_RETURN_RET_LOG(vaInputStreamCallback_ != nullptr, ERROR); + vaInputStreamCallback_->RequestSharedMem(memInfo); + return SUCCESS; +} + +int32_t VAInputStreamStubImpl::Start() +{ + CHECK_AND_RETURN_RET_LOG(vaInputStreamCallback_ != nullptr, ERROR); + vaInputStreamCallback_->Start(); + return SUCCESS; +} + +int32_t VAInputStreamStubImpl::Stop() +{ + CHECK_AND_RETURN_RET_LOG(vaInputStreamCallback_ != nullptr, ERROR); + vaInputStreamCallback_->Stop(); + return SUCCESS; +} + +int32_t VAInputStreamStubImpl::Close() +{ + CHECK_AND_RETURN_RET_LOG(vaInputStreamCallback_ != nullptr, ERROR); + vaInputStreamCallback_->Close(); + return SUCCESS; +} + + +int32_t VAInputStreamStubImpl::GetCapturePosition(uint64_t &attr_1, uint64_t &attr_2) +{ + CHECK_AND_RETURN_RET_LOG(vaInputStreamCallback_ != nullptr, ERROR); + vaInputStreamCallback_->GetCapturePosition(attr_1, attr_2); + return SUCCESS; +} +} // namespace AudioStandard +} // namespace OHOS \ 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 232717ad2c..d6409c5df8 100644 --- a/services/audio_policy/common/include/audio_module_info.h +++ b/services/audio_policy/common/include/audio_module_info.h @@ -64,6 +64,7 @@ static const char* PORT_NONE = "none"; static const char* PRIMARY_DIRECT_VOIP = "direct_voip"; static const char* PRIMARY_MMAP_VOIP = "mmap_voip"; static const char* ACCESSORY_SOURCE = "accessory_mic"; +static const char* VIRTUAL_AUDIO = "virtual_audio"; } enum NodeName { @@ -122,6 +123,7 @@ struct AudioModuleInfo { std::string OpenMicSpeaker; std::string fileName; std::string networkId; + std::string macAddress; std::string deviceType; std::string sceneName; std::string sourceType; diff --git a/services/audio_policy/idl/IAudioPolicy.idl b/services/audio_policy/idl/IAudioPolicy.idl index 55906612c5..2be8cd1511 100644 --- a/services/audio_policy/idl/IAudioPolicy.idl +++ b/services/audio_policy/idl/IAudioPolicy.idl @@ -292,6 +292,8 @@ interface IAudioPolicy { void SetDefaultOutputDevice([in] int deviceType /* deviceType */); void ForceVolumeKeyControlType([in] int volumeType, [in] int duration, [out] int ret); void SetQueryDeviceVolumeBehaviorCallback([in] IRemoteObject object); + void GetVADeviceBroker([out] IRemoteObject client); + void GetVADeviceController([in] String macAddress, [out] IRemoteObject controller); void SetAppConcurrencyMode([in] int appUid, [in] int mode); void SetAppSilentOnDisplay([in] int displayId); void SetSystemVolumeDegree([in] int volumeType, [in] int volumeDegree, [in] int volumeFlag, [in] int uid); diff --git a/services/audio_policy/idl/IVADeviceBroker.idl b/services/audio_policy/idl/IVADeviceBroker.idl new file mode 100644 index 0000000000..97d44ec6bb --- /dev/null +++ b/services/audio_policy/idl/IVADeviceBroker.idl @@ -0,0 +1,24 @@ +/* + * 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. + */ + +package OHOS.AudioStandard; + +sequenceable OHOS.IRemoteObject; +sequenceable va_device..OHOS.AudioStandard.VADevice; + +interface IVADeviceBroker { + void OnDevicesConnected([in] VADevice device, [in] IRemoteObject controller); + void OnDevicesDisconnected([in] VADevice device); +}; \ No newline at end of file diff --git a/services/audio_policy/idl/IVADeviceController.idl b/services/audio_policy/idl/IVADeviceController.idl new file mode 100644 index 0000000000..78ff5c018c --- /dev/null +++ b/services/audio_policy/idl/IVADeviceController.idl @@ -0,0 +1,28 @@ +/* + * 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. + */ + +package OHOS.AudioStandard; + +import IVAInputStream; +sequenceable OHOS.IRemoteObject; +sequenceable va_device_info..OHOS.AudioStandard.VAAudioStreamProperty; +sequenceable va_device_info..OHOS.AudioStandard.VAInputStreamAttribute; + + +interface IVADeviceController { + void OpenInputStream([in] VAAudioStreamProperty prop, [in] VAInputStreamAttribute attr, [out] IRemoteObject inputStream); + void GetParameters([in] String key, [out] String value); + void SetParameters([in] String key, [in] String value); +}; \ No newline at end of file diff --git a/services/audio_policy/idl/IVAInputStream.idl b/services/audio_policy/idl/IVAInputStream.idl new file mode 100644 index 0000000000..37be8d5f4b --- /dev/null +++ b/services/audio_policy/idl/IVAInputStream.idl @@ -0,0 +1,29 @@ +/* + * 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.idlIVAInputStream.idl + * limitations under the License. + */ + +package OHOS.AudioStandard; + +sequenceable va_device_info..OHOS.AudioStandard.VAAudioStreamProperty; +sequenceable va_device_info..OHOS.AudioStandard.VASharedMemInfo; + +interface IVAInputStream { + void GetStreamProperty([out] VAAudioStreamProperty streamProp); + void RequestSharedMem([in] VASharedMemInfo memInfo); + void Start(); + void Stop(); + void Close(); + + void GetCapturePosition([out] unsigned long attr_1, [out] unsigned long attr_2); +}; \ No newline at end of file diff --git a/services/audio_policy/idl/IVAStream.idl b/services/audio_policy/idl/IVAStream.idl new file mode 100644 index 0000000000..37b7aba207 --- /dev/null +++ b/services/audio_policy/idl/IVAStream.idl @@ -0,0 +1,27 @@ +/* + * 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. + */ + +package OHOS.AudioStandard; + +sequenceable va_device_info..OHOS.AudioStandard.VAAudioStreamProperty; +sequenceable va_device_info..OHOS.AudioStandard.VASharedMemInfo; + +interface IVAStream { + void GetStreamProperty([out] VAAudioStreamProperty streamProp); + void RequestSharedMem([out] VASharedMemInfo memInfo); + void Start(); + void Stop(); + void Close(); +}; \ No newline at end of file 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 43009743a6..bcc1a1830a 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 @@ -36,6 +36,8 @@ const std::map deviceTypeStringMap = { {DEVICE_TYPE_HEARING_AID, "HEARING_AID"}, {DEVICE_TYPE_NEARLINK, "NEARLINK"}, {DEVICE_TYPE_NEARLINK_IN, "NEARLINK_IN"}, + {DEVICE_TYPE_BT_SPP, "BT_SPP"}, + {DEVICE_TYPE_NEARLINK_PORT, "NEARLINK_PORT"}, {DEVICE_TYPE_MIC, "MIC"}, {DEVICE_TYPE_WAKEUP, "WAKEUP"}, {DEVICE_TYPE_USB_HEADSET, "USB_HEADSET"}, @@ -49,6 +51,7 @@ const std::map deviceTypeStringMap = { {DEVICE_TYPE_FILE_SINK, "FILE_SINK"}, {DEVICE_TYPE_FILE_SOURCE, "FILE_SOURCE"}, {DEVICE_TYPE_EXTERN_CABLE, "EXTERN_CABLE"}, + {DEVICE_TYPE_SYSTEM_PRIVATE, "SYSTEM_PRIVATE"}, {DEVICE_TYPE_DEFAULT, "DEFAULT"}, {DEVICE_TYPE_USB_ARM_HEADSET, "USB_ARM_HEADSET"} }; 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 c62e54ff6e..9625ef14d1 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 @@ -443,6 +443,8 @@ int32_t AudioDeviceStatus::HandleLocalDeviceConnected(AudioDeviceDescriptor &upd } else if (updatedDesc.deviceType_ == DEVICE_TYPE_HEARING_AID) { A2dpDeviceConfigInfo configInfo = {audioStreamInfo, false}; audioA2dpDevice_.AddHearingAidDevice(updatedDesc.macAddress_, configInfo); + } else if (updatedDesc.deviceType_ == DEVICE_TYPE_BT_SPP) { + AUDIO_INFO_LOG("not supported"); } return SUCCESS; } @@ -485,6 +487,8 @@ int32_t AudioDeviceStatus::HandleLocalDeviceDisconnected(const AudioDeviceDescri if (audioA2dpDevice_.DelHearingAidDevice(updatedDesc.macAddress_) == 0) { audioIOHandleMap_.ClosePortAndEraseIOHandle(HEARING_AID_SPEAKER); } + } else if (updatedDesc.deviceType_ == DEVICE_TYPE_BT_SPP) { + AUDIO_INFO_LOG("not supported"); } SleAudioDeviceManager::GetInstance().RemoveNearlinkDevice(updatedDesc); diff --git a/services/audio_policy/server/domain/device/src/audio_device_type.cpp b/services/audio_policy/server/domain/device/src/audio_device_type.cpp index b3b37f2451..62e78c474f 100644 --- a/services/audio_policy/server/domain/device/src/audio_device_type.cpp +++ b/services/audio_policy/server/domain/device/src/audio_device_type.cpp @@ -44,6 +44,7 @@ const std::unordered_map &GetSupportedDeviceType() {DEVICE_TYPE_EXTERN_CABLE, "DEVICE_TYPE_EXTERN_CABLE"}, {DEVICE_TYPE_DEFAULT, "DEVICE_TYPE_DEFAULT"}, {DEVICE_TYPE_ACCESSORY, "DEVICE_TYPE_ACCESSORY"}, + {DEVICE_TYPE_BT_SPP, "DEVICE_TYPE_BT_SPP"}, }; return supportedDevicetype; } diff --git a/services/audio_policy/server/domain/device/src/va/va_device_manager.cpp b/services/audio_policy/server/domain/device/src/va/va_device_manager.cpp new file mode 100644 index 0000000000..2208b45c2b --- /dev/null +++ b/services/audio_policy/server/domain/device/src/va/va_device_manager.cpp @@ -0,0 +1,239 @@ +/* + * 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 "VADeviceManager" +#endif + +#include "va_device_manager.h" +#include "audio_policy_log.h" +#include "audio_module_info.h" + +namespace OHOS { +namespace AudioStandard { + +static const std::string VA_DEVICE_INFO_NAME = "Virtual Audio"; +static const std::string VA_INPUT_PIPE_INFO_NAME = "va_input"; + +VADeviceManager &VADeviceManager::GetInstance() +{ + static VADeviceManager instance; + return instance; +} + +std::shared_ptr VADeviceManager::ConvertVADeviceToDescriptor( + const std::shared_ptr &vaDevice) +{ + if (vaDevice == nullptr) { + return nullptr; + } + auto desc = std::make_shared(); + auto config = vaDevice->configuration_; + desc->deviceName_ = config.name_; + desc->displayName_ = config.name_; + switch (config.type_) { + case VA_DEVICE_TYPE_NONE: + desc->deviceType_ = DEVICE_TYPE_NONE; + break; + case VA_DEVICE_TYPE_BT_SPP: + desc->deviceType_ = DEVICE_TYPE_BT_SPP; + break; + default: + desc->deviceType_ = DEVICE_TYPE_NONE; + break; + } + switch (config.role_) { + case VA_DEVICE_ROLE_IN: + desc->deviceRole_ = INPUT_DEVICE; + break; + case VA_DEVICE_ROLE_OUT: + desc->deviceRole_ = OUTPUT_DEVICE; + break; + default: + desc->deviceRole_ = DEVICE_ROLE_NONE; + break; + } + desc->macAddress_ = config.address_; + + for (const auto &streamProp : config.properties_) { + std::shared_ptr streamInfo = ConvertVAStreamPropertyToInfo(streamProp); + desc->audioStreamInfo_.push_back(*streamInfo); + } + return desc; +} + +std::shared_ptr VADeviceManager::ConvertVAStreamPropertyToInfo( + const VAAudioStreamProperty &vaStreamProperty) +{ + std::shared_ptr streamInfo = std::make_shared(); + streamInfo->encoding = vaStreamProperty.encoding_; + streamInfo->format = vaStreamProperty.sampleFormat_; + streamInfo->channelLayout.insert(vaStreamProperty.channelLayout_); + streamInfo->samplingRate.insert(static_cast(vaStreamProperty.sampleRate_)); + return streamInfo; +} + +void VADeviceManager::OnDevicesConnected( + const std::shared_ptr &vaDevice, const sptr &controller) +{ + CHECK_AND_RETURN_LOG(vaDevice != nullptr && controller != nullptr, "invalid parameter: null pointer detected"); + AUDIO_INFO_LOG("va device manager connecting to device: {\"name\":\"%{public}s\", \"type\":\"%{public}d\"}", + vaDevice->configuration_.name_.c_str(), + vaDevice->configuration_.type_); + std::shared_ptr descriptor = ConvertVADeviceToDescriptor(vaDevice); + connectedVADeviceMap_[vaDevice->configuration_.address_] = controller; + + if (!IsVAAdapterRegistered()) { + RegisterVAAdapterToMap(); + } + AddVAStreamPropToMap(vaDevice->configuration_.properties_); + ReorganizePolicyConfig(); + AudioCoreService::GetCoreService()->GetEventEntry()->OnDeviceStatusUpdated(*descriptor, true); +} + +void VADeviceManager::OnDevicesDisconnected(const std::shared_ptr &vaDevice) +{ + CHECK_AND_RETURN_LOG(vaDevice != nullptr, "invalid parameter: null pointer detected"); + std::shared_ptr descriptor = ConvertVADeviceToDescriptor(vaDevice); + AudioCoreService::GetCoreService()->GetEventEntry()->OnDeviceStatusUpdated(*descriptor, false); + connectedVADeviceMap_.erase(vaDevice->configuration_.address_); + if (connectedVADeviceMap_.size() <= 0) { + UnregisterVAAdapterFromMap(); + ReorganizePolicyConfig(); + } +} + +void VADeviceManager::GetDeviceController(const std::string macAddr, sptr &controller) +{ + auto it = connectedVADeviceMap_.find(macAddr); + if (it == connectedVADeviceMap_.end()) { + controller = nullptr; + } else { + sptr vaController = it->second; + if (vaController == nullptr) { + controller = nullptr; + } else { + controller = vaController->AsObject(); + } + } +} + +void VADeviceManager::RegisterVAAdapterToMap() +{ + AudioPolicyConfigData &config = AudioPolicyConfigData::GetInstance(); + PolicyAdapterInfo adapterInfo{}; + std::shared_ptr adapterInfoPtr = std::make_shared(adapterInfo); + adapterInfoPtr->adapterName = ADAPTER_TYPE_VA; + config.adapterInfoMap.insert({adapterInfoPtr->GetTypeEnum(), adapterInfoPtr}); + + std::shared_ptr pipeInfo = std::make_shared(); + pipeInfo->adapterInfo_ = adapterInfoPtr; + pipeInfo->name_ = VA_INPUT_PIPE_INFO_NAME; + pipeInfo->role_ = PIPE_ROLE_INPUT; + pipeInfo->supportDevices_.push_back(VA_DEVICE_INFO_NAME); + + AdapterDeviceInfo deviceInfo{}; + deviceInfo.adapterInfo_ = adapterInfoPtr; + deviceInfo.name_ = VA_DEVICE_INFO_NAME; + deviceInfo.type_ = DEVICE_TYPE_BT_SPP; + deviceInfo.role_ = INPUT_DEVICE; + deviceInfo.supportPipes_.push_back(VA_INPUT_PIPE_INFO_NAME); + deviceInfo.supportPipeMap_[AudioFlag::AUDIO_INPUT_FLAG_NORMAL] = pipeInfo; + + adapterInfoPtr->deviceInfos.push_back(make_shared(deviceInfo)); + + PaPropInfo paProp = {}; + paProp.lib_ = "libmodule-hdi-source.z.so"; + paProp.role_ = "source"; + paProp.moduleName_ = VIRTUAL_AUDIO; + + pipeInfo->paProp_ = std::move(paProp); + + adapterInfoPtr->pipeInfos.push_back(pipeInfo); +} + +void VADeviceManager::UnregisterVAAdapterFromMap() +{ + AudioPolicyConfigData &config = AudioPolicyConfigData::GetInstance(); + config.adapterInfoMap.erase(AudioAdapterType::TYPE_VA); + std::pair deviceMapKey = std::make_pair(DEVICE_TYPE_BT_SPP, INPUT_DEVICE); + config.deviceInfoMap.erase(deviceMapKey); +} + +void VADeviceManager::AddVAStreamPropToMap(std::list properties) +{ + AudioPolicyConfigData &config = AudioPolicyConfigData::GetInstance(); + auto it = config.adapterInfoMap.find(AudioAdapterType::TYPE_VA); + CHECK_AND_RETURN_LOG(it != config.adapterInfoMap.end(), "va adapter not found"); + std::shared_ptr adapterInfoPtr = it->second; + CHECK_AND_RETURN_LOG(adapterInfoPtr != nullptr, "va adapter is null pointer"); + CHECK_AND_RETURN_LOG(adapterInfoPtr->pipeInfos.size() > 0, "va pipe info not found"); + std::shared_ptr pipeInfoPtr = adapterInfoPtr->pipeInfos.front(); + + for(auto vaStreamProp : properties) { + std::shared_ptr pipeStreamPropInfo = ConvertVADeviceStreamPropertyToPipeStreamPropInfo(vaStreamProp); + CHECK_AND_RETURN_LOG(pipeStreamPropInfo != nullptr, "pipeStreamPropInfo is null"); + pipeStreamPropInfo->pipeInfo_ = pipeInfoPtr; + pipeStreamPropInfo->supportDevices_.push_back(VA_DEVICE_INFO_NAME); + pipeInfoPtr->streamPropInfos_.push_back(pipeStreamPropInfo); + } +} + +void VADeviceManager::ReorganizePolicyConfig() +{ + AudioPolicyConfigData::GetInstance().Reorganize(); +} + +bool VADeviceManager::IsVAAdapterRegistered() +{ + AudioPolicyConfigData &config = AudioPolicyConfigData::GetInstance(); + return config.adapterInfoMap.find(AudioAdapterType::TYPE_VA) != config.adapterInfoMap.end(); +} + +bool VADeviceManager::IsDeviceInfoMapContainsVA(std::pair deviceMapKey) +{ + AudioPolicyConfigData &config = AudioPolicyConfigData::GetInstance(); + return config.deviceInfoMap.find(deviceMapKey) != config.deviceInfoMap.end(); +} + +std::shared_ptr VADeviceManager::ConvertVADeviceStreamPropertyToPipeStreamPropInfo( + const VAAudioStreamProperty &vaStreamProperty) +{ + std::shared_ptr pipeStreamInfo = std::make_shared(); + pipeStreamInfo->format_ = vaStreamProperty.sampleFormat_; + pipeStreamInfo->sampleRate_ = vaStreamProperty.sampleRate_; + pipeStreamInfo->channelLayout_ = vaStreamProperty.channelLayout_; + pipeStreamInfo->channels_ = AudioDefinitionPolicyUtils::ConvertLayoutToAudioChannel(pipeStreamInfo->channelLayout_); + pipeStreamInfo->bufferSize_ = CalculateBufferSize(vaStreamProperty); + return pipeStreamInfo; +} + +int32_t VADeviceManager::CalculateBufferSize(const VAAudioStreamProperty &vaStreamProperty) +{ + const int32_t cyclesPerSecond = 50; + if (vaStreamProperty.samplesPerCycle_ > + static_cast(AudioSamplingRate::SAMPLE_RATE_192000) / cyclesPerSecond || + vaStreamProperty.samplesPerCycle_ < 0) { + AUDIO_ERR_LOG("invalid samplesPerCycle"); + return 0; + } + int32_t channels = AudioDefinitionPolicyUtils::ConvertLayoutToAudioChannel(vaStreamProperty.channelLayout_); + int32_t samplesPerCycle_ = vaStreamProperty.samplesPerCycle_; + int32_t bitWidth = 2; + int32_t bufferSize = channels * samplesPerCycle_ * bitWidth; + return bufferSize; +} +} // namespace VirtualAudioDevice +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_policy/server/domain/device/src/va/va_device_manager.h b/services/audio_policy/server/domain/device/src/va/va_device_manager.h new file mode 100644 index 0000000000..d04f8a2277 --- /dev/null +++ b/services/audio_policy/server/domain/device/src/va/va_device_manager.h @@ -0,0 +1,86 @@ +/* + * 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 VA_DEVICE_MANAGER_H +#define VA_DEVICE_MANAGER_H + +#include +#include +#include "audio_errors.h" +#include "audio_info.h" +#include "audio_device_info.h" +#include "audio_device_descriptor.h" +#include "va_device.h" +#include "va_device_info.h" +#include "audio_core_service.h" + +#include "ashmem.h" +#include +#include +#include "message_parcel.h" + +#include "va_shared_buffer_operator.h" +#include "va_shared_buffer.h" + +#include "audio_pipe_manager.h" + +#include "audio_definition_adapter_info.h" + +#include "iv_a_device_controller.h" + + +namespace OHOS { +namespace AudioStandard { + +class VADeviceManager { +public: + static VADeviceManager &GetInstance(); + + void OnDevicesConnected( + const std::shared_ptr &vaDevice, const sptr &controller); + + void OnDevicesDisconnected(const std::shared_ptr &vaDevice); + + void GetDeviceController(const std::string macAddr, sptr &controller); +private: + VADeviceManager() = default; + virtual ~VADeviceManager() = default; + + std::unordered_map> connectedVADeviceMap_; + + void RegisterVAAdapterToMap(); + void UnregisterVAAdapterFromMap(); + + void AddVAStreamPropToMap(std::list properties); + + void ReorganizePolicyConfig(); + + bool IsVAAdapterRegistered(); + + bool IsDeviceInfoMapContainsVA(std::pair deviceMapKey = std::make_pair(DEVICE_TYPE_BT_SPP, INPUT_DEVICE)); + + std::shared_ptr ConvertVADeviceToDescriptor(const std::shared_ptr &vaDevice); + + std::shared_ptr ConvertVAStreamPropertyToInfo(const VAAudioStreamProperty &vaStreamProperty); + + std::shared_ptr ConvertVADeviceStreamPropertyToPipeStreamPropInfo( + const VAAudioStreamProperty &vaStreamProperty); + + int32_t CalculateBufferSize(const VAAudioStreamProperty &vaStreamProperty); +}; +} //namespace AudioStandard +} //namespace OHOS +#endif //VA_DEVICE_MANAGER_H + 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 451c0beb50..7eaa434f09 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 @@ -40,6 +40,7 @@ static const char* ADAPTER_TYPE_USB = "usb"; static const char* ADAPTER_TYPE_DP = "dp"; static const char* ADAPTER_TYPE_ACCESSORY = "accessory"; static const char* ADAPTER_TYPE_SLE = "sle"; +static const char* ADAPTER_TYPE_VA = "va"; struct PairHash { template @@ -67,6 +68,7 @@ enum class AudioAdapterType { TYPE_ACCESSORY, TYPE_SLE, TYPE_HEARING_AID, + TYPE_VA, TYPE_INVALID }; 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 24d84873e0..b779df8742 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 @@ -264,6 +264,8 @@ AudioAdapterType PolicyAdapterInfo::GetAdapterType(const std::string &adapterNam return AudioAdapterType::TYPE_ACCESSORY; } else if (adapterName == ADAPTER_TYPE_SLE) { return AudioAdapterType::TYPE_SLE; + } else if (adapterName == ADAPTER_TYPE_VA) { + return AudioAdapterType::TYPE_VA; } else { return AudioAdapterType::TYPE_INVALID; } diff --git a/services/audio_policy/server/domain/pipe/src/audio_definition_policy_utils.cpp b/services/audio_policy/server/domain/pipe/src/audio_definition_policy_utils.cpp index b72c079ca1..fcb04f7dd1 100644 --- a/services/audio_policy/server/domain/pipe/src/audio_definition_policy_utils.cpp +++ b/services/audio_policy/server/domain/pipe/src/audio_definition_policy_utils.cpp @@ -61,6 +61,7 @@ std::unordered_map AudioDefinitionPolicyUtils::deviceTy {"DEVICE_TYPE_NEARLINK_IN", DEVICE_TYPE_NEARLINK_IN}, {"DEVICE_TYPE_HEARING_AID", DEVICE_TYPE_HEARING_AID}, {"DEVICE_TYPE_REMOTE_DAUDIO", DEVICE_TYPE_REMOTE_DAUDIO}, + {"DEVICE_TYPE_BT_SPP", DEVICE_TYPE_BT_SPP}, }; std::unordered_map AudioDefinitionPolicyUtils::pinStrToEnum = { diff --git a/services/audio_policy/server/domain/pipe/src/audio_ec_manager.cpp b/services/audio_policy/server/domain/pipe/src/audio_ec_manager.cpp index 5fd46c330a..2969833854 100644 --- a/services/audio_policy/server/domain/pipe/src/audio_ec_manager.cpp +++ b/services/audio_policy/server/domain/pipe/src/audio_ec_manager.cpp @@ -181,6 +181,8 @@ void AudioEcManager::CloseNormalSource() AUDIO_INFO_LOG("close all sources"); audioIOHandleMap_.ClosePortAndEraseIOHandle(BLUETOOTH_MIC); audioIOHandleMap_.ClosePortAndEraseIOHandle(PRIMARY_MIC); + + audioIOHandleMap_.ClosePortAndEraseIOHandle(VIRTUAL_AUDIO); if (isEcFeatureEnable_) { audioIOHandleMap_.ClosePortAndEraseIOHandle(USB_MIC); } 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 e5a8262ae8..d914aa5a81 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 @@ -514,6 +514,7 @@ void AudioPipeSelector::ConvertStreamDescToPipeInfo(std::shared_ptrnewDeviceDescs_[0]->deviceType_); info.moduleInfo_.networkId = streamDesc->newDeviceDescs_[0]->networkId_; + info.moduleInfo_.macAddress = streamDesc->newDeviceDescs_[0]->macAddress_; info.moduleInfo_.sourceType = std::to_string(streamDesc->capturerInfo_.sourceType); info.streamDescriptors_.push_back(streamDesc); 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 a2fc2581c7..112a6d5714 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 @@ -2060,6 +2060,7 @@ IAudioSourceAttr AudioAdapterManager::GetAudioSourceAttr(const AudioModuleInfo & attr.isBigEndian = IsBigEndian(audioModuleInfo.format); attr.filePath = audioModuleInfo.fileName.c_str(); attr.deviceNetworkId = audioModuleInfo.networkId.c_str(); + attr.macAddress = audioModuleInfo.macAddress.c_str(); if (!audioModuleInfo.deviceType.empty()) { attr.deviceType = std::stoi(audioModuleInfo.deviceType); } diff --git a/services/audio_policy/server/infra/config/parser/src/audio_device_parser.cpp b/services/audio_policy/server/infra/config/parser/src/audio_device_parser.cpp index 8c551c171e..c0bac49a7c 100644 --- a/services/audio_policy/server/infra/config/parser/src/audio_device_parser.cpp +++ b/services/audio_policy/server/infra/config/parser/src/audio_device_parser.cpp @@ -41,6 +41,7 @@ static std::map deviceTypeMap_ = { {"DEVICE_TYPE_NEARLINK_IN", DEVICE_TYPE_NEARLINK_IN}, {"DEVICE_TYPE_HEARING_AID", DEVICE_TYPE_HEARING_AID}, {"DEVICE_TYPE_REMOTE_DAUDIO", DEVICE_TYPE_REMOTE_DAUDIO}, + {"DEVICE_TYPE_BT_SPP", DEVICE_TYPE_BT_SPP}, }; } bool AudioDeviceParser::LoadConfiguration() diff --git a/services/audio_policy/server/service/service_main/include/audio_policy_server.h b/services/audio_policy/server/service/service_main/include/audio_policy_server.h index 63a104f1f3..5d774900cc 100644 --- a/services/audio_policy/server/service/service_main/include/audio_policy_server.h +++ b/services/audio_policy/server/service/service_main/include/audio_policy_server.h @@ -598,6 +598,10 @@ public: int32_t ForceVolumeKeyControlType(int32_t volumeType, int32_t duration, int32_t &ret) override; + int32_t GetVADeviceBroker(sptr &client) override; + + int32_t GetVADeviceController(const std::string &macAddress, sptr &controller) override; + void ProcessRemoteInterrupt(std::set sessionIds, InterruptEventInternal interruptEvent); std::set GetStreamIdsForAudioSessionByStreamUsage( const int32_t zoneId, const std::set &streamUsageSet); diff --git a/services/audio_policy/server/service/service_main/include/audio_policy_service.h b/services/audio_policy/server/service/service_main/include/audio_policy_service.h index b634e93d3e..d292be13bd 100644 --- a/services/audio_policy/server/service/service_main/include/audio_policy_service.h +++ b/services/audio_policy/server/service/service_main/include/audio_policy_service.h @@ -76,6 +76,7 @@ #include "audio_background_manager.h" #include "audio_global_config_manager.h" #include "sle_audio_device_manager.h" +#include "va_device_manager.h" namespace OHOS { namespace AudioStandard { @@ -277,7 +278,8 @@ private: audioCapturerSession_(AudioCapturerSession::GetInstance()), audioDeviceLock_(AudioDeviceLock::GetInstance()), audioDeviceStatus_(AudioDeviceStatus::GetInstance()), - sleAudioDeviceManager_(SleAudioDeviceManager::GetInstance()) + sleAudioDeviceManager_(SleAudioDeviceManager::GetInstance()), + vaDeviceManager_(VADeviceManager::GetInstance()) { deviceStatusListener_ = std::make_unique(*this); } @@ -410,6 +412,7 @@ private: AudioDeviceLock& audioDeviceLock_; AudioDeviceStatus& audioDeviceStatus_; SleAudioDeviceManager& sleAudioDeviceManager_; + VADeviceManager& vaDeviceManager_; }; class SafeVolumeEventSubscriber : public EventFwk::CommonEventSubscriber { diff --git a/services/audio_policy/server/service/service_main/src/audio_policy_server.cpp b/services/audio_policy/server/service/service_main/src/audio_policy_server.cpp index 4d3490acb8..aa8ebda34c 100644 --- a/services/audio_policy/server/service/service_main/src/audio_policy_server.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_policy_server.cpp @@ -40,6 +40,8 @@ #include "audio_bundle_manager.h" #include "audio_server_proxy.h" #include "audio_policy_client_holder.h" +#include "va_device_broker_stub_impl.h" +#include "va_device_manager.h" #include "standalone_mode_manager.h" using OHOS::Security::AccessToken::PrivacyKit; @@ -2059,6 +2061,9 @@ int32_t AudioPolicyServer::GetDevices(int32_t deviceFlagIn, desc->networkId_ = ""; desc->interruptGroupId_ = GROUP_ID_NONE; desc->volumeGroupId_ = GROUP_ID_NONE; + if (desc->deviceType_ == DEVICE_TYPE_BT_SPP) { + desc->deviceType_ = DEVICE_TYPE_SYSTEM_PRIVATE; + } } } @@ -2157,6 +2162,7 @@ int32_t AudioPolicyServer::GetPreferredOutputDeviceDescriptors(const AudioRender } int32_t apiVersion = HasUsbDevice(deviceDescs) ? GetApiTargetVersion() : 0; + bool hasSystemPermission = PermissionUtil::VerifySystemPermission(); bool isSupportedNearlink = !audioPolicyUtils_.IsBundleNameInList(AudioBundleManager::GetBundleName(), NEARLINK_LIST); for (auto &desc : deviceDescs) { @@ -2165,6 +2171,9 @@ int32_t AudioPolicyServer::GetPreferredOutputDeviceDescriptors(const AudioRender if (desc->IsAudioDeviceDescriptor()) { desc->deviceType_ = desc->MapInternalToExternalDeviceType(apiVersion, isSupportedNearlink); } + if(!hasSystemPermission && desc->deviceType_ == DEVICE_TYPE_BT_SPP) { + desc->deviceType_ = DEVICE_TYPE_SYSTEM_PRIVATE; + } } return SUCCESS; @@ -3833,6 +3842,9 @@ int32_t AudioPolicyServer::GetAvailableDevices(int32_t usageIn, desc->networkId_ = ""; desc->interruptGroupId_ = GROUP_ID_NONE; desc->volumeGroupId_ = GROUP_ID_NONE; + if (desc->deviceType_ == DEVICE_TYPE_BT_SPP) { + desc->deviceType_ = DEVICE_TYPE_SYSTEM_PRIVATE; + } } } @@ -5359,6 +5371,18 @@ int32_t AudioPolicyServer::CallRingtoneLibrary() return SUCCESS; } +int32_t AudioPolicyServer::GetVADeviceBroker(sptr &client) +{ + client = sptr::MakeSptr()->AsObject(); + return SUCCESS; +} + +int32_t AudioPolicyServer::GetVADeviceController(const std::string& macAddress, sptr& controller) +{ + VADeviceManager::GetInstance().GetDeviceController(macAddress, controller); + return SUCCESS; +} + int32_t AudioPolicyServer::SetSystemVolumeDegree(int32_t streamTypeIn, int32_t volumeDegree, int32_t volumeFlag, int32_t uid) { 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 bbe3f59613..6f0c438afc 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 @@ -59,6 +59,9 @@ HWTEST(AudioDefinitionAdapterInfoUnitTest, PolicyAdapterInfo_001, TestSize.Level ret = policyAdapter->GetAdapterType(ADAPTER_TYPE_SLE); EXPECT_EQ(AudioAdapterType::TYPE_SLE, ret); + ret = policyAdapter->GetAdapterType(ADAPTER_TYPE_VA); + EXPECT_EQ(AudioAdapterType::TYPE_VA, ret); + ret = policyAdapter->GetAdapterType(ADAPTER_TYPE_ACCESSORY); EXPECT_EQ(AudioAdapterType::TYPE_ACCESSORY, ret); 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 40b6de9a1e..e5231f459e 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 @@ -806,6 +806,24 @@ HWTEST_F(AudioDeviceStatusUnitTest, AudioDeviceStatus_031, TestSize.Level1) EXPECT_EQ(result, SUCCESS); } +/** +* @tc.name : Test AudioDeviceStatus. +* @tc.number: AudioDeviceStatus_072 +* @tc.desc : Test HandleLocalDeviceConnected interface. +*/ +HWTEST_F(AudioDeviceStatusUnitTest, AudioDeviceStatus_072, TestSize.Level1) +{ + AudioDeviceDescriptor updatedDesc; + int32_t result; + + AudioDeviceStatus& audioDeviceStatus = AudioDeviceStatus::GetInstance(); + updatedDesc.deviceType_ = DEVICE_TYPE_BT_SPP; + + result = audioDeviceStatus.HandleLocalDeviceConnected(updatedDesc); + + EXPECT_EQ(result, SUCCESS); +} + /** * @tc.name : Test AudioDeviceStatus. * @tc.number: AudioDeviceStatus_032 @@ -892,6 +910,23 @@ HWTEST_F(AudioDeviceStatusUnitTest, AudioDeviceStatus_036, TestSize.Level1) EXPECT_EQ(result, SUCCESS); } +/** +* @tc.name : Test AudioDeviceStatus. +* @tc.number: AudioDeviceStatus_073 +* @tc.desc : Test HandleLocalDeviceDisconnected interface. +*/ +HWTEST_F(AudioDeviceStatusUnitTest, AudioDeviceStatus_073, TestSize.Level1) +{ + int32_t result; + AudioDeviceDescriptor updatedDesc; + updatedDesc.deviceType_ = DEVICE_TYPE_BT_SPP; + + AudioDeviceStatus& audioDeviceStatus = AudioDeviceStatus::GetInstance(); + + result = audioDeviceStatus.HandleLocalDeviceDisconnected(updatedDesc); + EXPECT_EQ(result, SUCCESS); +} + /** * @tc.name : Test AudioDeviceStatus. * @tc.number: AudioDeviceStatus_037 diff --git a/services/audio_policy/test/unittest/audio_interrupt_service_test/src/audio_policy_server_unit_test.cpp b/services/audio_policy/test/unittest/audio_interrupt_service_test/src/audio_policy_server_unit_test.cpp index 23bce80dfa..df6a5b2c3b 100644 --- a/services/audio_policy/test/unittest/audio_interrupt_service_test/src/audio_policy_server_unit_test.cpp +++ b/services/audio_policy/test/unittest/audio_interrupt_service_test/src/audio_policy_server_unit_test.cpp @@ -3581,6 +3581,34 @@ HWTEST(AudioPolicyUnitTest, AudioPolicyServer_168, TestSize.Level1) EXPECT_EQ(result, ERROR); } +/** +* @tc.name : Test AudioDeviceManager. +* @tc.number: AudioPolicyServer_222 +* @tc.desc : Test GetVADeviceBroker. +*/ +HWTEST(AudioPolicyUnitTest, AudioPolicyServer_222, TestSize.Level1) +{ + sptr server = GetPolicyServerUnitTest(); + sptr client; + int32_t result = server->GetVADeviceBroker(client); + EXPECT_EQ(result, SUCCESS); + EXPECT_NE(client, nullptr); +} + +/** +* @tc.name : Test AudioDeviceManager. +* @tc.number: AudioPolicyServer_223 +* @tc.desc : Test GetVADeviceBroker. +*/ +HWTEST(AudioPolicyUnitTest, AudioPolicyServer_223, TestSize.Level1) +{ + sptr server = GetPolicyServerUnitTest(); + sptr controller; + std::string macAddress = "00:11:22:33:44:55"; + int32_t result = server->GetVADeviceController(macAddress, controller); + EXPECT_EQ(result, SUCCESS); +} + /** * @tc.name : Test AudioPolicyServer * @tc.number: IsStreamActiveByStreamUsage_001 diff --git a/services/audio_policy/test/unittest/va_device_controller_stub_impl_test/include/va_device_controller_stub_impl_test.h b/services/audio_policy/test/unittest/va_device_controller_stub_impl_test/include/va_device_controller_stub_impl_test.h new file mode 100644 index 0000000000..b61cab0268 --- /dev/null +++ b/services/audio_policy/test/unittest/va_device_controller_stub_impl_test/include/va_device_controller_stub_impl_test.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 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 "va_device_controller_stub_impl.h" +#include +#include "va_input_stream_stub_impl_test.h" +namespace OHOS { +namespace AudioStandard { +class VADeviceControllerStubImplTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(void); + void TearDown(void); +}; +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_policy/test/unittest/va_device_controller_stub_impl_test/src/va_device_controller_stub_impl_test.cpp b/services/audio_policy/test/unittest/va_device_controller_stub_impl_test/src/va_device_controller_stub_impl_test.cpp new file mode 100644 index 0000000000..9a20170f3f --- /dev/null +++ b/services/audio_policy/test/unittest/va_device_controller_stub_impl_test/src/va_device_controller_stub_impl_test.cpp @@ -0,0 +1,166 @@ +/* + * 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 "va_device_controller_stub_impl_test.h" +#include +#include "gtest/gtest.h" +#include +#include "audio_errors.h" + +using namespace testing::ext; + +namespace OHOS { +namespace AudioStandard { + +void VADeviceControllerStubImplTest::SetUpTestCase(void) {} +void VADeviceControllerStubImplTest::TearDownTestCase(void) {} +void VADeviceControllerStubImplTest::SetUp(void) {} +void VADeviceControllerStubImplTest::TearDown(void) {} + +class HelloController : public VADeviceControllerCallback { +public: + HelloController() = default; + virtual ~HelloController() = default; + + int32_t OpenInputStream(const VAAudioStreamProperty &prop, const VAInputStreamAttribute &attr, + std::shared_ptr &inputStream) override + { + std::shared_ptr helloInputStream = std::make_shared(); + if (helloInputStream == nullptr) { + return 1; + } else { + inputStream = helloInputStream; + } + return 0; + } + + int32_t GetParameters(const std::string& key, std::string& value) override + { + return 0; + } + + int32_t SetParameters(const std::string& key, const std::string& value) override + { + return 0; + } +}; +/** +* @tc.name : Test VADeviceControllerStubImpl +* @tc.number : SetVADeviceControllerCallback_001 +* @tc.desc : Test VADeviceControllerStubImpl OnInterrupt interface +*/ +HWTEST(VADeviceControllerStubImplTest, SetVADeviceControllerCallback_001, TestSize.Level4) { + VADeviceControllerStubImpl vaDeviceControllerStub; + auto helloController = std::make_shared(); + + EXPECT_EQ(vaDeviceControllerStub.SetVADeviceControllerCallback(helloController), SUCCESS); +} + +/** +* @tc.name : Test VADeviceControllerStubImpl +* @tc.number : SetVADeviceControllerCallback_002 +* @tc.desc : Test VADeviceControllerStubImpl OnInterrupt interface +*/ +HWTEST(VADeviceControllerStubImplTest, SetVADeviceControllerCallback_002, TestSize.Level4) { + VADeviceControllerStubImpl vaDeviceControllerStub; + auto helloController = std::make_shared(); + + EXPECT_EQ(vaDeviceControllerStub.SetVADeviceControllerCallback(nullptr), ERROR); +} + +/** +* @tc.name : Test VADeviceControllerStubImpl +* @tc.number : GetParameters_001 +* @tc.desc : Test VADeviceControllerStubImpl OnInterrupt interface +*/ +HWTEST(VADeviceControllerStubImplTest, GetParameters_001, TestSize.Level4) +{ + VADeviceControllerStubImpl vaDeviceControllerStub; + auto hellocontroller = std::make_shared(); + + vaDeviceControllerStub.SetVADeviceControllerCallback(hellocontroller); + + std::string key = "test_key"; + std::string value; + int32_t result = vaDeviceControllerStub.GetParameters(key, value); + EXPECT_EQ(result, SUCCESS); +} + +/** +* @tc.name : Test VADeviceControllerStubImpl +* @tc.number : GetParameters_002 +* @tc.desc : Test VADeviceControllerStubImpl OnInterrupt interface +*/ +HWTEST(VADeviceControllerStubImplTest, GetParameters_002, TestSize.Level4){ + VADeviceControllerStubImpl vaDeviceControllerStub; + auto helloController = std::make_shared(); + vaDeviceControllerStub.SetVADeviceControllerCallback(helloController); + + std::string value; + + EXPECT_EQ(vaDeviceControllerStub.GetParameters("key1", value), SUCCESS); + EXPECT_EQ(vaDeviceControllerStub.GetParameters("key2", value), SUCCESS); +} + + +/** +* @tc.name : Test VADeviceControllerStubImpl +* @tc.number : SetParameters_001 +* @tc.desc : Test VADeviceControllerStubImpl OnInterrupt interface +*/ +HWTEST(VADeviceControllerStubImplTest, SetParameters_001, TestSize.Level4){ + VADeviceControllerStubImpl vaDeviceControllerStub; + auto helloController = std::make_shared(); + vaDeviceControllerStub.SetVADeviceControllerCallback(helloController); + + std::string key = "test_key"; + std::string value = "test_value"; + + EXPECT_EQ(vaDeviceControllerStub.SetParameters(key, value), SUCCESS); +} + +/** +* @tc.name : Test VADeviceControllerStubImpl +* @tc.number : SetParameters_002 +* @tc.desc : Test VADeviceControllerStubImpl OnInterrupt interface +*/ +HWTEST(VADeviceControllerStubImplTest, SetParameters_002, TestSize.Level4) { + VADeviceControllerStubImpl vaDeviceControllerStub; + auto helloController = std::make_shared(); + vaDeviceControllerStub.SetVADeviceControllerCallback(helloController); + + EXPECT_EQ(vaDeviceControllerStub.SetParameters("key1", "value1"), SUCCESS); + EXPECT_EQ(vaDeviceControllerStub.SetParameters("key2", "value2"), SUCCESS); +} + + +/** +* @tc.name : Test VADeviceControllerStubImpl +* @tc.number : VADeviceControllerStubImpl_001 +* @tc.desc : Test VADeviceControllerStubImpl OnInterrupt interface. +*/ +HWTEST(VADeviceControllerStubImplTest, OpenInputStream_001, TestSize.Level4) { + VADeviceControllerStubImpl vaDeviceControllerStub; + auto helloController = std::make_shared(); + vaDeviceControllerStub.SetVADeviceControllerCallback(helloController); + + VAAudioStreamProperty prop; + VAInputStreamAttribute attr; + sptr inputStream; + + EXPECT_EQ(vaDeviceControllerStub.OpenInputStream(prop, attr, inputStream), SUCCESS); +} + +} //namespace AudioStandard +} //namespace OHOS \ No newline at end of file diff --git a/services/audio_policy/test/unittest/va_device_manager_unit_test/include/va_device_manager_unit_test.h b/services/audio_policy/test/unittest/va_device_manager_unit_test/include/va_device_manager_unit_test.h new file mode 100644 index 0000000000..93c24f584a --- /dev/null +++ b/services/audio_policy/test/unittest/va_device_manager_unit_test/include/va_device_manager_unit_test.h @@ -0,0 +1,38 @@ +/* + * 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 VA_DEVICE_MANAGER_UNIT_TEST_H +#define VA_DEVICE_MANAGER_UNIT_TEST_H + +#include "gtest/gtest.h" +#include "va_device_manager.h" +#include "audio_device_descriptor.h" +#include "va_device.h" +#include "va_device_info.h" +#include "audio_definition_adapter_info.h" +#include "audio_device_stream_info.h" + +namespace OHOS { +namespace AudioStandard { + +class VADeviceManagerUnitTest : public ::testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(void); + void TearDown(void); +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // VA_DEVICE_MANAGER_UNIT_TEST_H \ No newline at end of file diff --git a/services/audio_policy/test/unittest/va_device_manager_unit_test/src/va_device_manager_unit_test.cpp b/services/audio_policy/test/unittest/va_device_manager_unit_test/src/va_device_manager_unit_test.cpp new file mode 100644 index 0000000000..a1efc06005 --- /dev/null +++ b/services/audio_policy/test/unittest/va_device_manager_unit_test/src/va_device_manager_unit_test.cpp @@ -0,0 +1,200 @@ +/* + * 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 "va_device_manager_unit_test.h" +#include +#include + + using namespace testing::ext; + +namespace OHOS { +namespace AudioStandard { + +void VADeviceManagerUnitTest::SetUpTestCase(void) {} +void VADeviceManagerUnitTest::TearDownTestCase(void) {} +void VADeviceManagerUnitTest::SetUp(void) {} +void VADeviceManagerUnitTest::TearDown(void) {} + +/** + * @tc.name : Test VADeviceManager. + * @tc.number: VADeviceManagerUnitTest_001 + * @tc.desc : Test GetInstance. + */ +HWTEST_F(VADeviceManagerUnitTest, VADeviceManagerUnitTest_001, TestSize.Level1) { + VADeviceManager &instance1 = VADeviceManager::GetInstance(); + VADeviceManager &instance2 = VADeviceManager::GetInstance(); + + EXPECT_EQ(&instance1, &instance2); +} + +/** + * @tc.name : Test VADeviceManager. + * @tc.number: VADeviceManagerUnitTest_002 + * @tc.desc : Test ConvertVADeviceToDescriptor. + */ +HWTEST_F(VADeviceManagerUnitTest, VADeviceManagerUnitTest_002, TestSize.Level1) { + std::shared_ptr vaDevice = nullptr; + VADeviceManager vaDeviceManager; + std::shared_ptr desc = vaDeviceManager.ConvertVADeviceToDescriptor(vaDevice); + EXPECT_EQ(desc, nullptr); +} + +/** + * @tc.name : Test VADeviceManager. + * @tc.number: VADeviceManagerUnitTest_003 + * @tc.desc : Test ConvertVADeviceToDescriptor. + */ +HWTEST_F(VADeviceManagerUnitTest, VADeviceManagerUnitTest_003, TestSize.Level1) { + VADeviceManager vaDeviceManager; + auto vaDevice = std::make_shared(); + vaDevice->configuration_.name_ = "TestDevice"; + vaDevice->configuration_.type_ = VA_DEVICE_TYPE_BT_SPP; + vaDevice->configuration_.role_ = VA_DEVICE_ROLE_IN; + vaDevice->configuration_.address_ = "00:11:22:33:44:55"; + + auto desc = vaDeviceManager.ConvertVADeviceToDescriptor(vaDevice); + ASSERT_NE(desc, nullptr); + EXPECT_EQ(desc->deviceName_, "TestDevice"); + EXPECT_EQ(desc->displayName_, "TestDevice"); + EXPECT_EQ(desc->deviceType_, DEVICE_TYPE_BT_SPP); + EXPECT_EQ(desc->deviceRole_, INPUT_DEVICE); + EXPECT_EQ(desc->macAddress_, "00:11:22:33:44:55"); + EXPECT_EQ(desc->networkId_, "00:11:22:33:44:55"); +} + +/** + * @tc.name : Test VADeviceManager. + * @tc.number: VADeviceManagerUnitTest_004 + * @tc.desc : Test ConvertVADeviceToDescriptor. + */ +HWTEST_F(VADeviceManagerUnitTest, VADeviceManagerUnitTest_004, TestSize.Level1) { + VADeviceManager vaDeviceManager; + auto vaDevice = std::make_shared(); + vaDevice->configuration_.name_ = "TestDevice"; + vaDevice->configuration_.type_ = VA_DEVICE_TYPE_BT_SPP; + vaDevice->configuration_.role_ = VA_DEVICE_ROLE_OUT; + vaDevice->configuration_.address_ = "00:11:22:33:44:55"; + + auto desc = vaDeviceManager.ConvertVADeviceToDescriptor(vaDevice); + ASSERT_NE(desc, nullptr); + EXPECT_EQ(desc->deviceName_, "TestDevice"); + EXPECT_EQ(desc->displayName_, "TestDevice"); + EXPECT_EQ(desc->deviceType_, DEVICE_TYPE_BT_SPP); + EXPECT_EQ(desc->deviceRole_, OUTPUT_DEVICE); + EXPECT_EQ(desc->macAddress_, "00:11:22:33:44:55"); + EXPECT_EQ(desc->networkId_, "00:11:22:33:44:55"); +} + +/** + * @tc.name : Test VADeviceManager. + * @tc.number: VADeviceManagerUnitTest_005 + * @tc.desc : Test ConvertVADeviceToDescriptor. + */ +HWTEST_F(VADeviceManagerUnitTest, VADeviceManagerUnitTest_005, TestSize.Level1) { + VADeviceManager vaDeviceManager; + auto vaDevice = std::make_shared(); + vaDevice->configuration_.name_ = "TestDevice"; + vaDevice->configuration_.type_ = VA_DEVICE_TYPE_NONE; + vaDevice->configuration_.role_ = VA_DEVICE_ROLE_IN; + vaDevice->configuration_.address_ = "00:11:22:33:44:55"; + + auto desc = vaDeviceManager.ConvertVADeviceToDescriptor(vaDevice); + ASSERT_NE(desc, nullptr); + EXPECT_EQ(desc->deviceName_, "TestDevice"); + EXPECT_EQ(desc->displayName_, "TestDevice"); + EXPECT_EQ(desc->deviceType_, DEVICE_TYPE_NONE); + EXPECT_EQ(desc->deviceRole_, INPUT_DEVICE); + EXPECT_EQ(desc->macAddress_, "00:11:22:33:44:55"); + EXPECT_EQ(desc->networkId_, "00:11:22:33:44:55"); +} + +/** + * @tc.name : Test VADeviceManager. + * @tc.number: VADeviceManagerUnitTest_006 + * @tc.desc : Test ConvertVADeviceToDescriptor. + */ +HWTEST_F(VADeviceManagerUnitTest, VADeviceManagerUnitTest_006, TestSize.Level1) { + VADeviceManager vaDeviceManager; + auto vaDevice = std::make_shared(); + vaDevice->configuration_.name_ = "TestDevice"; + vaDevice->configuration_.type_ = VA_DEVICE_TYPE_NONE; + vaDevice->configuration_.role_ = VA_DEVICE_ROLE_OUT; + vaDevice->configuration_.address_ = "00:11:22:33:44:55"; + + auto desc = vaDeviceManager.ConvertVADeviceToDescriptor(vaDevice); + ASSERT_NE(desc, nullptr); + EXPECT_EQ(desc->deviceName_, "TestDevice"); + EXPECT_EQ(desc->displayName_, "TestDevice"); + EXPECT_EQ(desc->deviceType_, DEVICE_TYPE_NONE); + EXPECT_EQ(desc->deviceRole_, OUTPUT_DEVICE); + EXPECT_EQ(desc->macAddress_, "00:11:22:33:44:55"); + EXPECT_EQ(desc->networkId_, "00:11:22:33:44:55"); +} + +/** + * @tc.name : Test VADeviceManager. + * @tc.number: VADeviceManagerUnitTest_007 + * @tc.desc : Test ConvertVADeviceToDescriptor. + */ +HWTEST_F(VADeviceManagerUnitTest, VADeviceManagerUnitTest_007, TestSize.Level1) { + VADeviceManager vaDeviceManager; + auto vaDevice = std::make_shared(); + vaDevice->configuration_.name_ = "TestDevice"; + vaDevice->configuration_.type_ = VA_DEVICE_TYPE_NONE; + vaDevice->configuration_.address_ = "00:11:22:33:44:55"; + + auto desc = vaDeviceManager.ConvertVADeviceToDescriptor(vaDevice); + ASSERT_NE(desc, nullptr); + EXPECT_EQ(desc->deviceName_, "TestDevice"); + EXPECT_EQ(desc->displayName_, "TestDevice"); + EXPECT_EQ(desc->deviceType_, DEVICE_TYPE_NONE); + EXPECT_EQ(desc->deviceRole_, DEVICE_ROLE_NONE); + EXPECT_EQ(desc->macAddress_, "00:11:22:33:44:55"); + EXPECT_EQ(desc->networkId_, "00:11:22:33:44:55"); +} + +/** + * @tc.name : Test VADeviceManager. + * @tc.number: VADeviceManagerUnitTest_008 + * @tc.desc : Test ConvertVADeviceToDescriptor. + */ +HWTEST_F(VADeviceManagerUnitTest, VADeviceManagerUnitTest_008, TestSize.Level1) { + VADeviceManager vaDeviceManager; + auto vaDevice = std::make_shared(); + vaDevice->configuration_.name_ = "TestDevice"; + vaDevice->configuration_.type_ = VA_DEVICE_TYPE_BT_SPP; + vaDevice->configuration_.role_ = VA_DEVICE_ROLE_IN; + vaDevice->configuration_.address_ = "00:11:22:33:44:55"; + + VAAudioStreamProperty streamProp; + streamProp.encoding_ = ENCODING_PCM; + streamProp.sampleFormat_ = INVALID_WIDTH; + streamProp.channelLayout_ = CH_LAYOUT_2POINT1; + streamProp.sampleRate_ = 44100; + streamProp.samplesPerCycle_ = 1024; + vaDevice->->configuration_.properties_.push_back(streamProp); + + auto desc = vaDeviceManager.ConvertVADeviceToDescriptor(vaDevice); + auto streamInfo = desc->audioStreamInfo_.front(); + ASSERT_NE(desc, nullptr); + ASSERT_EQ(desc->audioStreamInfo_.size(), 1); + EXPECT_EQ(streamInfo.encoding, ENCODING_PCM); + EXPECT_EQ(streamInfo.format, INVALID_WIDTH); + EXPECT_EQ(*streamInfo.channelLayout.begin(), CH_LAYOUT_2POINT1); + EXPECT_EQ(*streamInfo.samplingRate.begin(), 44100); +} + +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_policy/test/unittest/va_input_stream_stub_impl_test/include/va_input_stream_stub_impl_test.h b/services/audio_policy/test/unittest/va_input_stream_stub_impl_test/include/va_input_stream_stub_impl_test.h new file mode 100644 index 0000000000..51532f5299 --- /dev/null +++ b/services/audio_policy/test/unittest/va_input_stream_stub_impl_test/include/va_input_stream_stub_impl_test.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2024 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 VA_INPUT_STREAM_STUB_IMPL_TEST_H +#define VA_INPUT_STREAM_STUB_IMPL_TEST_H + +#include +#include "va_input_stream_stub_impl.h" + + +namespace OHOS { +namespace AudioStandard { + +class VAInputStreamStubImplTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(void); + void TearDown(void); +}; +using namespace OHOS::AudioStandard; + +class HelloInputStream : public VAInputStreamCallback { +public: + HelloInputStream() = default; + virtual ~HelloInputStream() = default; + + int32_t Start() override + { + return 0; + } + int32_t Stop() override + { + return 0; + } + int32_t Close() override + { + return 0; + } + int32_t GetStreamProperty(VAAudioStreamProperty& streamProp) override + { + return 0; + } + int32_t RequestSharedMem(const VASharedMemInfo& memInfo) override + { + return 0; + } + int32_t GetCapturePosition(uint64_t& attr_1, uint64_t& attr_2) override + { + return 0; + } +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // VA_INPUT_STREAM_STUB_IMPL_TEST_H \ No newline at end of file diff --git a/services/audio_policy/test/unittest/va_input_stream_stub_impl_test/src/va_input_stream_stub_impl_test.cpp b/services/audio_policy/test/unittest/va_input_stream_stub_impl_test/src/va_input_stream_stub_impl_test.cpp new file mode 100644 index 0000000000..d24bd56306 --- /dev/null +++ b/services/audio_policy/test/unittest/va_input_stream_stub_impl_test/src/va_input_stream_stub_impl_test.cpp @@ -0,0 +1,259 @@ +/* + * 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 "va_input_stream_stub_impl_test.h" +#include +#include "gtest/gtest.h" +#include +#include "audio_errors.h" + +using namespace testing::ext; + +namespace OHOS { + namespace AudioStandard { + + void VAInputStreamStubImplTest::SetUpTestCase(void) {} + void VAInputStreamStubImplTest::TearDownTestCase(void) {} + void VAInputStreamStubImplTest::SetUp(void) {} + void VAInputStreamStubImplTest::TearDown(void) {} + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : Start_001 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, Start_001, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + auto helloInputStream = std::make_shared(); + + vaInputStreamStub.SetVAInputStreamCallback(helloInputStream); + + int32_t result = vaInputStreamStub.Start(); + + EXPECT_EQ(result, SUCCESS); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : Start_002 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, Start_002, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + + int32_t result = vaInputStreamStub.Start(); + + EXPECT_EQ(result, ERROR); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : SetVAInputStreamCallback_001 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, SetVAInputStreamCallback_001, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + auto helloInputStream = std::make_shared(); + + int32_t result = vaInputStreamStub.SetVAInputStreamCallback(nullptr); + EXPECT_EQ(result, ERR_INVALID_PARAM); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : SetVAInputStreamCallback_002 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, SetVAInputStreamCallback_002, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + + std::shared_ptr nullCallback = nullptr; + int32_t result = vaInputStreamStub.SetVAInputStreamCallback(nullCallback); + + EXPECT_EQ(result, ERR_INVALID_PARAM); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : GetStreamProperty_001 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, GetStreamProperty_001, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + auto helloInputStream = std::make_shared(); + + vaInputStreamStub.SetVAInputStreamCallback (helloInputStream); + + VAAudioStreamProperty streamProp; + + int32_t result = vaInputStreamStub.GetStreamProperty(streamProp); + + EXPECT_EQ(result, SUCCESS); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : GetStreamProperty_002 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, GetStreamProperty_002, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + + VAAudioStreamProperty streamProp; + + int32_t result = vaInputStreamStub.GetStreamProperty(streamProp); + + EXPECT_EQ(result, ERROR); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : RequestSharedMem_001 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, RequestSharedMem_001, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + auto helloInputStream = std::make_shared(); + + vaInputStreamStub.SetVAInputStreamCallback(helloInputStream); + + VASharedMemInfo memInfo; + + int32_t result = vaInputStreamStub.RequestSharedMem(memInfo); + + EXPECT_EQ(result, SUCCESS); + } + + /** + * @tc.name : TestVAInputStreamStubImpl + * @tc.number : RequestSharedMem_002 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface + */ + HWTEST(VAInputStreamStubImplTest, RequestSharedMem_002, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + + VASharedMemInfo memInfo; + + int32_t result = vaInputStreamStub.RequestSharedMem(memInfo); + + EXPECT_EQ(result, ERROR); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : Stop_001 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, Stop_001, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + auto helloInputStream = std::make_shared(); + + vaInputStreamStub.SetVAInputStreamCallback(helloInputStream); + + int32_t result = vaInputStreamStub.Stop(); + + EXPECT_EQ(result, SUCCESS); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : Stop_002 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, Stop_002, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + + int32_t result = vaInputStreamStub.Stop(); + + EXPECT_EQ(result, ERROR); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : Close_001 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, Close_001, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + auto helloInputStream = std::make_shared(); + + vaInputStreamStub.SetVAInputStreamCallback(helloInputStream); + + int32_t result = vaInputStreamStub.Close(); + + EXPECT_EQ(result, SUCCESS); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : Close_002 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, Close_002, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + + int32_t result = vaInputStreamStub.Close(); + + EXPECT_EQ(result, ERROR); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : GetCapturePosition_001 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, GetCapturePosition_001, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + auto helloInputStream = std::make_shared(); + + vaInputStreamStub.SetVAInputStreamCallback(helloInputStream); + + uint64_t attr_1 = 0; + uint64_t attr_2 = 0; + + int32_t result = vaInputStreamStub.GetCapturePosition(attr_1,attr_2); + + EXPECT_EQ(result, SUCCESS); + } + + /** + * @tc.name : TestVAInputStreamStubImpl. + * @tc.number : GetCapturePosition_002 + * @tc.desc : TestVAInputStreamStubImpl OnInterrupt interface. + */ + HWTEST(VAInputStreamStubImplTest, GetCapturePosition_002, TestSize.Level4) + { + VAInputStreamStubImpl vaInputStreamStub; + + uint64_t attr_1 = 0; + uint64_t attr_2 = 0; + + int32_t result = vaInputStreamStub.GetCapturePosition(attr_1, attr_2); + EXPECT_EQ(result, ERROR); + } + } // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index b489dda26c..458eb4ff83 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -84,6 +84,8 @@ ohos_shared_library("audio_common") { "common/src/oh_audio_buffer_base.cpp", "common/src/volume_tools.cpp", "common/src/app_bundle_manager.cpp", + "common/src/va_shared_buffer.cpp", + "common/src/va_shared_buffer_operator.cpp", ] cflags = [ diff --git a/services/audio_service/common/include/va_shared_buffer.h b/services/audio_service/common/include/va_shared_buffer.h new file mode 100644 index 0000000000..d4f0f7dd4f --- /dev/null +++ b/services/audio_service/common/include/va_shared_buffer.h @@ -0,0 +1,110 @@ +/* + * 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 VA_SHARED_BUFFER_H +#define VA_SHARED_BUFFER_H + +#include +#include +#include +#include + +#include "message_parcel.h" + +#include "audio_info.h" + +#include "audio_shared_memory.h" +#include "futex_tool.h" + +#include "va_device_info.h" +#include "oh_audio_buffer.h" + + +namespace OHOS { +namespace AudioStandard { + +struct VASharedStatusInfo { + size_t basePos; + size_t readPos; + size_t writePos; + std::atomic futex; +}; + +class VAAudioSharedMemory { +public: + uint8_t *GetBase(); + size_t GetSize(); + int GetFd(); + std::string GetName(); + + VAAudioSharedMemory(size_t size, const std::string &name); + + VAAudioSharedMemory(int fd, size_t size, const std::string &name); + + ~VAAudioSharedMemory(); + + static std::shared_ptr CreateFromLocal(size_t size, const std::string &name); + + static std::shared_ptr CreateFromRemote(int fd, size_t size, const std::string &name); + + int32_t Init(); + + sptr GetAshmem(); + +private: + void Close(); + + uint8_t *base_; + int fd_; + size_t size_; + std::string name_; + + sptr ashmem_; +}; + +class VASharedBuffer { +public: + VASharedBuffer(); + + ~VASharedBuffer(); + + static std::shared_ptr CreateFromLocal(uint32_t dataSize); + static std::shared_ptr CreateFromRemote(const VASharedMemInfo &memInfo); + + int32_t Init(const VASharedMemInfo &memInfo); + + uint8_t *GetDataBase(); + size_t GetDataSize(); + sptr GetDataAshmem(); + uint8_t *GetStatusInfoBase(); + + void GetVASharedMemInfo(VASharedMemInfo &memInfo); + int64_t GetLastWrittenTime(); + + void SetLastWrittenTime(int64_t time); + +private: + std::shared_ptr dataMem_; + std::shared_ptr statusInfoMem_; + uint8_t *dataBase_ = nullptr; + + int64_t lastWrittenTime_ = 0; + + size_t totalSizeInByte_ = 0; + + int32_t SizeCheck(); +}; +} //namespace AudioStandard +} //namespace OHOS +#endif //VA_SHARED_BUFFER_H \ No newline at end of file diff --git a/services/audio_service/common/include/va_shared_buffer_operator.h b/services/audio_service/common/include/va_shared_buffer_operator.h new file mode 100644 index 0000000000..570d03b7d8 --- /dev/null +++ b/services/audio_service/common/include/va_shared_buffer_operator.h @@ -0,0 +1,84 @@ +/* + * 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 VA_SHARED_BUFFER_OPERATOR_H +#define VA_SHARED_BUFFER_OPERATOR_H + +#include +#include + +#include +#include +#include +#include + +#include "va_shared_buffer.h" +#include "audio_log.h" + +#include "futex_tool.h" +#include + +namespace OHOS { +namespace AudioStandard { + +class VASharedBufferOperator { +public: + VASharedBufferOperator(const VASharedBuffer &buffer); + ~VASharedBufferOperator(); + + static constexpr uint32_t LOCK_RELEASED=0; + static constexpr uint32_t LOCK_OWNED = 1; + + void SetMinReadSize(const size_t minReadSize); + + void Reset(); + + void SetReadPosToWritePos(); + + size_t GetReadableSize(); + + size_t GetReadableSizeNoLock(); + + size_t GetWritableSizeNoLock(); + + size_t Read(uint8_t *data, size_t dataSize); + + size_t Write(uint8_t *data, size_t dataSize); + + void GetVASharedMemInfo(VASharedMemInfo &memInfo); +private: + VASharedBuffer buffer_; + + size_t capacity; + + sptr dataAshmem_; + + size_t minReadSize_ = 1; + + VASharedStatusInfo *statusInfo_ = nullptr; + + std::atomic *GetFutex(); + + void InitVASharedStatusInfo(); + + int32_t SizeCheck(size_t dataSize); + + void WakeFutexIfNeed(); + + bool HasEnoughReadableData(); +}; + +} //namespace AudioStandard +} //namespace OHOS +#endif //VA_SHARED_BUFFER_OPERATOR_H \ No newline at end of file diff --git a/services/audio_service/common/src/va_shared_buffer.cpp b/services/audio_service/common/src/va_shared_buffer.cpp new file mode 100644 index 0000000000..3062332470 --- /dev/null +++ b/services/audio_service/common/src/va_shared_buffer.cpp @@ -0,0 +1,285 @@ +/* + * 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 "VASharedBuffer" +#endif + +#include "va_shared_buffer.h" + +#include +#include +#include +#include +#include "ashmem.h" + +#include "audio_errors.h" +#include "audio_service_log.h" +#include "futex_tool.h" +#include "audio_utils.h" +#include "audio_parcel_helper.h" + +namespace OHOS { +namespace AudioStandard { + +namespace { + static const size_t MAX_MMAP_BUFFER_SIZE = 10 * 1024 * 1024; + static const std::string STATUS_INFO_BUFFER = "status_info_buffer"; + static const std::string DATA_BUFFER = "data_buffer"; + static constexpr int MINFD = 2; +} + + +VAAudioSharedMemory::VAAudioSharedMemory(size_t size, const std::string &name) + : base_(nullptr), fd_(INVALID_FD), size_(size), name_(name) +{ + AUDIO_INFO_LOG("AudioSharedMemory construct with size: %{public}zu name: %{public}s", size_, name_.c_str()); +} + +VAAudioSharedMemory::VAAudioSharedMemory(int fd, size_t size, const std::string &name) + : base_(nullptr), fd_(fd), size_(size), name_(name) +{ + AUDIO_INFO_LOG("AudioSharedMemory construct with fd %{public}d size %{public}zu name %{public}s", fd_, size_, + name_.c_str()); +} + +VAAudioSharedMemory::~VAAudioSharedMemory() +{ + AUDIO_INFO_LOG(" %{public}s enter ~AudioSharedMemoryImpl()", name_.c_str()); + Close(); +} + +std::shared_ptr VAAudioSharedMemory::CreateFromLocal(size_t size, const std::string &name) +{ + std::shared_ptr sharedMemory = std::make_shared(size, name); + CHECK_AND_RETURN_RET_LOG(sharedMemory->Init() == SUCCESS, nullptr, "CreateFormLocal failed"); + return sharedMemory; +} + +std::shared_ptr VAAudioSharedMemory::CreateFromRemote(int fd, size_t size, const std::string &name) +{ + CHECK_AND_RETURN_RET_LOG(fd > MINFD, nullptr, "CreateFromRemote failed: invalid fd: %{public}d", fd); + std::shared_ptr sharedMemory = std::make_shared(fd, size, name); + CHECK_AND_RETURN_RET_LOG(sharedMemory->Init() == SUCCESS, nullptr, "CreateFromRemote failed"); + return sharedMemory; +} + +int32_t VAAudioSharedMemory::Init() +{ + CHECK_AND_RETURN_RET_LOG((size_ > 0 && size_ < MAX_MMAP_BUFFER_SIZE), ERR_INVALID_PARAM, + "Init failed: size out of range: %{public}zu", size_); + bool isFromRemote = false; + if (fd_ >= 0) { + if (fd_ == STDIN_FILENO || fd_ == STDOUT_FILENO || fd_ == STDERR_FILENO) { + AUDIO_WARNING_LOG("fd is special fd: %{public}d", fd_); + } + isFromRemote = true; + int size = AshmemGetSize(fd_); + if (size < 0 || static_cast(size) != size_) { + AUDIO_WARNING_LOG("AshmemGetSize failed, get size: %{public}d size_: %{public}zu", size, size_); + return ERR_OPERATION_FAILED; + } + ashmem_ = sptr(new Ashmem(fd_, size)); + CHECK_AND_RETURN_RET_LOG((ashmem_ != nullptr), ERR_OPERATION_FAILED, "CreateAshmem failed."); + } else { + ashmem_ = Ashmem::CreateAshmem(name_.c_str(), size_); + CHECK_AND_RETURN_RET_LOG((ashmem_ != nullptr), ERR_OPERATION_FAILED, "CreateAshmem failed."); + fd_ = ashmem_->GetAshmemFd(); + CHECK_AND_RETURN_RET_LOG((fd_ >= 0), ERR_OPERATION_FAILED, "Init failed: fd %{public}d", fd_); + } + if (!ashmem_->MapReadAndWriteAshmem()) { + AUDIO_INFO_LOG("ashmem Map shared memory fail"); + } else { + AUDIO_INFO_LOG("ashmem Map shared memory success"); + } + + void *addr = mmap(nullptr, size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0); + CHECK_AND_RETURN_RET_LOG(addr != MAP_FAILED, ERR_OPERATION_FAILED, "Init failed: fd %{public}d size %{public}zu", + fd_, size_); + base_ = static_cast(addr); + AUDIO_INFO_LOG("Init %{public}s <%{public}s> done.", (isFromRemote ? "remote" : "local"), + name_.c_str()); + return SUCCESS; +} + + +void VAAudioSharedMemory::Close() +{ + if (base_ != nullptr) { + (void)munmap(base_, size_); + base_ = nullptr; + size_ = 0; + AUDIO_INFO_LOG("%{public}s munmap done", name_.c_str()); + } + + if(fd_ >= 0) { + (void)CloseFd(fd_); + fd_ = INVALID_FD; + AUDIO_INFO_LOG("%{public}s close fd done", name_.c_str()); + } +} + +uint8_t *VAAudioSharedMemory::GetBase() +{ + return base_; +} + +size_t VAAudioSharedMemory::GetSize() +{ + return size_; +} + +std::string VAAudioSharedMemory::GetName() +{ + return name_; +} + +int VAAudioSharedMemory::GetFd() +{ + return fd_; +} + +sptr VAAudioSharedMemory::GetAshmem() +{ + return ashmem_; +} + +int32_t VASharedBuffer::SizeCheck() +{ + return SUCCESS; +} + +VASharedBuffer::VASharedBuffer() +{ + +} + +int32_t VASharedBuffer::Init(const VASharedMemInfo& memInfo) +{ + AUDIO_INFO_LOG("VASharedBuffer::VASharedBuffer Init START."); + int32_t ret = SizeCheck(); + CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_INVALID_PARAM, "failed: invalid size."); + + if (memInfo.dataFd_ > MINFD && memInfo.dataMemCapacity_ > 0) { + AUDIO_INFO_LOG("dataMem_ CreateFromRemote"); + dataMem_ = VAAudioSharedMemory::CreateFromRemote(memInfo.dataFd_, memInfo.dataMemCapacity_, DATA_BUFFER); + } else { + AUDIO_INFO_LOG("dataMem_ CreateFromLocal"); + dataMem_ = VAAudioSharedMemory::CreateFromLocal(memInfo.dataMemCapacity_, DATA_BUFFER); + } + AUDIO_INFO_LOG("dataMem_ Create process end"); + if (memInfo.statusFd_ > MINFD && memInfo.statusMemCapacity_ > 0) { + AUDIO_INFO_LOG("statusInfoMem_ CreateFromRemote"); + statusInfoMem_ = VAAudioSharedMemory::CreateFromRemote(memInfo.statusFd_, memInfo.statusMemCapacity_, STATUS_INFO_BUFFER); + } else { + AUDIO_INFO_LOG("statusInfoMem_ CreateFromLocal"); + statusInfoMem_ = VAAudioSharedMemory::CreateFromLocal(sizeof(VASharedStatusInfo), STATUS_INFO_BUFFER); + } + AUDIO_INFO_LOG("statusInfoMem_ Create process end"); + + CHECK_AND_RETURN_RET_LOG(statusInfoMem_ != nullptr, ERR_OPERATION_FAILED, "statusInfoMem_ mmap failed."); + + CHECK_AND_RETURN_RET_LOG(dataMem_ != nullptr, ERR_OPERATION_FAILED, "dataMem_ mmap failed."); + + dataBase_ = dataMem_->GetBase(); + + AUDIO_INFO_LOG("VASharedBuffer::VASharedBuffer Init DONE."); + return SUCCESS; +} + +VASharedBuffer::~VASharedBuffer() +{ + +} + +std::shared_ptr VASharedBuffer::CreateFromLocal(uint32_t dataSize) +{ + std::shared_ptr buffer = std::make_shared(); + CHECK_AND_RETURN_RET_LOG(buffer != nullptr, nullptr, "buffer is null"); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = dataSize; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = 0; + memInfo.statusFd_ = INVALID_FD; + + if (buffer->Init(memInfo) == SUCCESS) { + return buffer; + } else { + AUDIO_ERR_LOG("init va shared buffer failed"); + return nullptr; + } +} + +std::shared_ptr VASharedBuffer::CreateFromRemote(const VASharedMemInfo &memInfo) +{ + if (memInfo.dataFd_ <= MINFD || memInfo.statusFd_ <= MINFD || memInfo.dataMemCapacity_ <= 0 || memInfo.statusMemCapacity_ <= 0) { + return nullptr; + } + + std::shared_ptr buffer = std::make_shared(); + if (buffer->Init(memInfo) == SUCCESS) { + return buffer; + } else { + AUDIO_ERR_LOG("init va shared buffer failed"); + return nullptr; + } +} + +uint8_t *VASharedBuffer::GetDataBase() +{ + return dataBase_; +} + +size_t VASharedBuffer::GetDataSize() +{ + CHECK_AND_RETURN_RET_LOG(dataMem_ != nullptr, 0, "dataMem is nullptr"); + return dataMem_->GetSize(); +} + +sptr VASharedBuffer::GetDataAshmem() +{ + CHECK_AND_RETURN_RET_LOG(dataMem_ != nullptr, nullptr, "dataMem is nullptr"); + return dataMem_->GetAshmem(); +} + +uint8_t *VASharedBuffer::GetStatusInfoBase() +{ + return statusInfoMem_ != nullptr ? statusInfoMem_->GetBase() : nullptr; +} + + +void VASharedBuffer::GetVASharedMemInfo(VASharedMemInfo &memInfo) +{ + if (dataMem_ != nullptr) { + memInfo.dataFd_ = dataMem_->GetFd(); + memInfo.dataMemCapacity_ = dataMem_->GetSize(); + } + if (statusInfoMem_ != nullptr) { + memInfo.statusFd_ = statusInfoMem_->GetFd(); + memInfo.statusMemCapacity_ = statusInfoMem_->GetSize(); + } +} + +int64_t VASharedBuffer::GetLastWrittenTime() +{ + return lastWrittenTime_; +} + +void VASharedBuffer::SetLastWrittenTime(int64_t time) +{ + lastWrittenTime_ = time; +} + +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_service/common/src/va_shared_buffer_operator.cpp b/services/audio_service/common/src/va_shared_buffer_operator.cpp new file mode 100644 index 0000000000..2144e7abd5 --- /dev/null +++ b/services/audio_service/common/src/va_shared_buffer_operator.cpp @@ -0,0 +1,252 @@ +/* + * 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 "VASharedBufferOperator" +#endif + +#include "va_shared_buffer_operator.h" +#include "audio_errors.h" +#include "audio_policy_log.h" + +namespace OHOS { +namespace AudioStandard { + +VASharedBufferOperator::VASharedBufferOperator(const VASharedBuffer &buffer) : buffer_(buffer) +{ + dataAshmem_ = buffer_.GetDataAshmem(); + CHECK_AND_RETURN_LOG(dataAshmem_ != nullptr, "dataAshmem_ is nullptr"); + capacity = buffer_.GetDataSize(); + InitVASharedStatusInfo(); +} + +void VASharedBufferOperator::InitVASharedStatusInfo() +{ + statusInfo_ = reinterpret_cast(buffer_.GetStatusInfoBase()); + CHECK_AND_RETURN_LOG(statusInfo_ != nullptr, "statusInfo_ is null"); +} + +VASharedBufferOperator::~VASharedBufferOperator() +{} + +void VASharedBufferOperator::SetMinReadSize(const size_t minReadSize) +{ + minReadSize_ = minReadSize; +} + +void VASharedBufferOperator::Reset() +{ + CHECK_AND_RETURN_LOG(statusInfo_ != nullptr, "statusInfo is nullptr"); + auto futex = GetFutex(); + while (true) { + uint32_t expected = LOCK_RELEASED; + if (futex->compare_exchange_weak(expected, LOCK_OWNED)) { + break; + } + std::this_thread::yield(); + } + statusInfo_->readPos = 0; + statusInfo_->writePos = 0; + futex->store(LOCK_RELEASED); +} + +void VASharedBufferOperator::SetReadPosToWritePos() +{ + CHECK_AND_RETURN_LOG(statusInfo_ != nullptr, "statusInfo is nullptr"); + auto futex = GetFutex(); + while (true) { + uint32_t expected = LOCK_RELEASED; + if (futex->compare_exchange_weak(expected, LOCK_OWNED)) { + break; + } + std::this_thread::yield(); + } + statusInfo_->readPos = statusInfo_->writePos; + futex->store(LOCK_RELEASED); +} + +size_t VASharedBufferOperator::GetReadableSize() +{ + CHECK_AND_RETURN_RET_LOG(statusInfo_ != nullptr, "statusInfo is nullptr"); + auto futex = GetFutex(); + while (true) { + uint32_t expected = LOCK_RELEASED; + if (futex->compare_exchange_weak(expected, LOCK_OWNED)) { + break; + } + std::this_thread::yield(); + } + size_t readableSize = statusInfo_->writePos - statusInfo_->readPos; + futex->store(LOCK_RELEASED); + return readableSize; +} + +size_t VASharedBufferOperator::GetReadableSizeNoLock() +{ + CHECK_AND_RETURN_RET_LOG(statusInfo_ != nullptr, 0, "statusInfo_ is nullptr"); + return statusInfo_->writePos - statusInfo_->readPos; +} + +size_t VASharedBufferOperator::GetWritableSizeNoLock() +{ + CHECK_AND_RETURN_RET_LOG(statusInfo_ != nullptr, 0, "statusInfo_ is nullptr"); + return capacity - (statusInfo_->writePos - statusInfo_->readPos); +} + +size_t VASharedBufferOperator::Read(uint8_t *data, size_t dataSize) +{ + CHECK_AND_RETURN_RET_LOG(statusInfo_ != nullptr, 0, "statusInfo_ is nullptr"); + CHECK_AND_RETURN_RET_LOG(data != nullptr, 0, "input data is nullptr"); + CHECK_AND_RETURN_RET_LOG(dataAshmem_ != nullptr, 0, "dataAshmem is nullptr"); + + auto futex = GetFutex(); + while (true) { + uint32_t expected = LOCK_RELEASED; + if (futex->compare_exchange_weak(expected, LOCK_OWNED)) { + if (HasEnoughReadableData()) { + break; + } else { + futex->store(LOCK_RELEASED); + } + } + std::this_thread::yield(); + } + + const size_t readSize = std::min(dataSize, GetReadableSizeNoLock()); + if (readSize == 0) { + AUDIO_INFO_LOG("wrong readSize: %{public}zu", readSize); + futex->store(LOCK_RELEASED); + return 0; + } + + int ret; + size_t readIndex = statusInfo_->readPos % capacity; + // if writeSize doesn't reach the margin of buffer + if (readIndex + readSize <= capacity) { + const void *read_ptr = dataAshmem_->ReadFromAshmem(readSize, readIndex); + ret = memcpy_s(data, dataSize, read_ptr, readSize); + if (ret) { + AUDIO_INFO_LOG("[1] Read failed"); + futex->store(LOCK_RELEASED); + return 0; + } + } + else + { + size_t firstReadSize = capacity - readIndex; + const void *first_read_ptr = dataAshmem_->ReadFromAshmem(firstReadSize, readIndex); + ret = memcpy_s(data, dataSize, first_read_ptr, firstReadSize); + if (ret) { + AUDIO_INFO_LOG("[2] Read failed"); + futex->store(LOCK_RELEASED); + return 0; + } + size_t secondReadSize = readSize - firstReadSize; + const void *second_read_ptr = dataAshmem_->ReadFromAshmem(secondReadSize, 0); + ret = memcpy_s(data + firstReadSize, dataSize - firstReadSize, second_read_ptr, secondReadSize); + if (ret) { + AUDIO_INFO_LOG("[3] Read failed"); + futex->store(LOCK_RELEASED); + return 0; + } + } + statusInfo_->readPos += readSize; + + futex->store(LOCK_RELEASED); + + return readSize; +} + +size_t VASharedBufferOperator::Write(uint8_t *data, size_t dataSize) +{ + CHECK_AND_RETURN_RET_LOG(statusInfo_ != nullptr, 0, "statusInfo_ is nullptr"); + CHECK_AND_RETURN_RET_LOG(data != nullptr, 0, "data pointer is null"); + CHECK_AND_RETURN_RET_LOG(dataAshmem_ != nullptr, 0, "dataAshmem is nullptr"); + + auto futex = GetFutex(); + while (true) { + uint32_t expected = LOCK_RELEASED; + if (futex->compare_exchange_weak(expected, LOCK_OWNED)) { + break; + } + std::this_thread::yield(); + } + + size_t writeSize = std::min(dataSize, GetWritableSizeNoLock()); + if (writeSize == 0) { + AUDIO_INFO_LOG("wrong writeSize: %{public}zu", writeSize); + futex->store(LOCK_RELEASED); + return 0; + } + + AUDIO_INFO_LOG("Write dataSize: %{public}zu. Actual writeSize: %{public}zu", dataSize, writeSize); + + bool success; + size_t writeIndex = statusInfo_->writePos % capacity; + + if (writeIndex + writeSize <= capacity) { + success = dataAshmem_->WriteToAshmem(data, writeSize, writeIndex); + if (!success) { + AUDIO_INFO_LOG("[1] Write failed"); + futex->store(LOCK_RELEASED); + return 0; + } + } else { + size_t firstWriteSize = capacity - writeIndex; + success = dataAshmem_->WriteToAshmem(data, firstWriteSize, writeIndex); + if (!success) { + AUDIO_INFO_LOG("[2] Write failed"); + futex->store(LOCK_RELEASED); + return 0; + } + size_t secondWriteSize = writeSize - firstWriteSize; + success = dataAshmem_->WriteToAshmem(data + firstWriteSize, secondWriteSize, 0); + if (!success) { + AUDIO_INFO_LOG("[3] Write failed"); + futex->store(LOCK_RELEASED); + return 0; + } + } + statusInfo_->writePos += writeSize; + + futex->store(LOCK_RELEASED); + + return writeSize; +} + +void VASharedBufferOperator::GetVASharedMemInfo(VASharedMemInfo &memInfo) +{ + buffer_.GetVASharedMemInfo(memInfo); +} + +std::atomic *VASharedBufferOperator::GetFutex() +{ + CHECK_AND_RETURN_RET_LOG(statusInfo_ != nullptr, nullptr, "statusInfo is null"); + return &statusInfo_->futex; +} + +void VASharedBufferOperator::WakeFutexIfNeed() +{ + if (statusInfo_) { + FutexTool::FutexWake(&(statusInfo_->futex)); + } +} + +bool VASharedBufferOperator::HasEnoughReadableData() +{ + return GetReadableSizeNoLock() > minReadSize_; +} + +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/services/audio_service/idl/BUILD.gn b/services/audio_service/idl/BUILD.gn index e9f6eaab6e..07b4156e6a 100644 --- a/services/audio_service/idl/BUILD.gn +++ b/services/audio_service/idl/BUILD.gn @@ -56,6 +56,10 @@ idl_gen_interface("audio_policy_idl_interface") { "${audio_policy_idl_location}/IStandardClientTracker.idl", "${audio_policy_idl_location}/IStandardSleAudioOperationCallback.idl", "${audio_policy_idl_location}/IStandardSpatializationStateChangeListener.idl", + "${audio_policy_idl_location}/IVADeviceBroker.idl", + "${audio_policy_idl_location}/IVAInputStream.idl", + "${audio_policy_idl_location}/IVADeviceController.idl", + "${audio_policy_idl_location}/IVAStream.idl", ] sources_callback = [] sources_common = [] @@ -69,6 +73,15 @@ idl_gen_interface("audio_policy_idl_interface") { part_name = "audio_framework" } +config("audio_framework_interface_config") { + include_dirs = [ + "${target_gen_dir}", + "//foundation/multimedia/audio_framework/services/audio_service/idl/", + ] + print("include_dirs=", include_dirs) + print("target_gen_dir=", target_gen_dir) +} + config("audio_service_sa_idl_config") { include_dirs = [ "${target_gen_dir}", @@ -93,6 +106,7 @@ ohos_shared_library("audio_framework_interface") { branch_protector_ret = "pac_ret" public_configs = [ + ":audio_framework_interface_config", ":audio_service_sa_idl_config", ":audio_policy_sa_idl_config", ] diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index 72378952a2..a00745df97 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -893,30 +893,26 @@ int32_t AudioServer::SetAudioParameter(const std::string &key, const std::string return SUCCESS; } - HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); - std::shared_ptr deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL); - CHECK_AND_RETURN_RET_LOG(deviceManager != nullptr, ERROR, "local device manager is nullptr"); AudioParamKey parmKey = AudioParamKey::NONE; + std::string valueNew = value; if (key == "AUDIO_EXT_PARAM_KEY_LOWPOWER") { parmKey = AudioParamKey::PARAM_KEY_LOWPOWER; HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AUDIO, "SMARTPA_LOWPOWER", - HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "STATE", value == "SmartPA_lowpower=on" ? 1 : 0); + HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "STATE", valueNew == "SmartPA_lowpower=on" ? 1 : 0); } else if (key == "bt_headset_nrec") { parmKey = AudioParamKey::BT_HEADSET_NREC; } else if (key == "bt_wbs") { parmKey = AudioParamKey::BT_WBS; } else if (key == "AUDIO_EXT_PARAM_KEY_A2DP_OFFLOAD_CONFIG") { parmKey = AudioParamKey::A2DP_OFFLOAD_STATE; - std::string value_new = "a2dpOffloadConfig=" + value; - deviceManager->SetAudioParameter("primary", parmKey, "", value_new); - return SUCCESS; + valueNew = "a2dpOffloadConfig=" + value; } else if (key == "mmi") { parmKey = AudioParamKey::MMI; } else if (key == "perf_info") { parmKey = AudioParamKey::PERF_INFO; } else if (key == "mute_call") { - deviceManager->SetAudioParameter("primary", parmKey, "", key + "=" + value); + valueNew = key + "=" + value; return SUCCESS; } else if (key == "LOUD_VOLUMN_MODE") { parmKey = AudioParamKey::NONE; @@ -924,7 +920,19 @@ int32_t AudioServer::SetAudioParameter(const std::string &key, const std::string AUDIO_ERR_LOG("key %{public}s is invalid for hdi interface", key.c_str()); return SUCCESS; } - deviceManager->SetAudioParameter("primary", parmKey, "", value); + + std::shared_ptr source = GetSourceByProp(HDI_ID_TYPE_VA, HDI_ID_INFO_VA, true); + if(source != nullptr) { + source->SetAudioParameter(parmKey, "", valueNew); + } + + HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); + std::shared_ptr deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL); + if(deviceManager != nullptr) { + deviceManager->SetAudioParameter("primary", parmKey, "", valueNew); + } else { + AUDIO_INFO_LOG("local device manager is nullptr"); + } return SUCCESS; } @@ -1073,9 +1081,8 @@ const std::string AudioServer::GetAudioParameterInner(const std::string &key) HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); std::shared_ptr deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL); - + AudioParamKey parmKey = AudioParamKey::NONE; if (deviceManager != nullptr) { - AudioParamKey parmKey = AudioParamKey::NONE; if (key == "AUDIO_EXT_PARAM_KEY_LOWPOWER") { parmKey = AudioParamKey::PARAM_KEY_LOWPOWER; return deviceManager->GetAudioParameter("primary", AudioParamKey(parmKey), ""); @@ -1108,6 +1115,40 @@ const std::string AudioServer::GetAudioParameterInner(const std::string &key) } } + std::shared_ptr source = GetSourceByProp(HDI_ID_TYPE_VA, HDI_ID_INFO_VA, true); + if(source != nullptr) { + if (key == "AUDIO_EXT_PARAM_KEY_LOWPOWER") { + parmKey = AudioParamKey::PARAM_KEY_LOWPOWER; + return source->GetAudioParameter(AudioParamKey(parmKey), ""); + } + if(key.find("need_change_usb_device#C") == 0) { + parmKey = AudioParamKey::USB_DEVICE; + return source->GetAudioParameter(AudioParamKey(parmKey), key); + } + if (key == "getSmartPAPOWER" || key == "show_RealTime_ChipModel") { + return source->GetAudioParameter(AudioParamKey::NONE, key); + } + if (key == "perf_info") { + return source->GetAudioParameter(AudioParamKey::PERF_INFO, key); + } + if (key == "concurrent_capture_stream_info") { + return source->GetAudioParameter(AudioParamKey::NONE, key); + } + if (key.size() < BUNDLENAME_LENGTH_LIMIT && key.size() > CHECK_FAST_BLOCK_PREFIX.size() && + key.substr(0, CHECK_FAST_BLOCK_PREFIX.size()) == CHECK_FAST_BLOCK_PREFIX) { + return source->GetAudioParameter(AudioParamKey::NONE, key); + } + + const std::string mmiPre2 = "mmi_"; + if (key.size() > mmiPre2.size()) { + if (key.substr(0, mmiPre2.size()) == mmiPre2) { + parmKey = AudioParamKey::MMI; + return source->GetAudioParameter(AudioParamKey(parmKey), + key.substr(mmiPre2.size(), key.size() - mmiPre2.size())); + } + } + } + if (AudioServer::audioParameters.count(key)) { return AudioServer::audioParameters[key]; } else { diff --git a/services/audio_service/test/unittest/audio_service_common_unit_test.cpp b/services/audio_service/test/unittest/audio_service_common_unit_test.cpp index a42ed0bc27..df16322e54 100644 --- a/services/audio_service/test/unittest/audio_service_common_unit_test.cpp +++ b/services/audio_service/test/unittest/audio_service_common_unit_test.cpp @@ -20,6 +20,8 @@ #include "audio_process_config.h" #include "linear_pos_time_model.h" #include "oh_audio_buffer.h" +#include "va_shared_buffer.h" +#include "va_shared_buffer_operator.h" #include #include @@ -1866,5 +1868,460 @@ HWTEST(AudioServiceCommonUnitTest, Create_001, TestSize.Level1) std::unique_ptr result = ringCache->Create(cacheSize); EXPECT_EQ(result, nullptr); } + +/** +* @tc.name : Test VASharedBuffer API +* @tc.type : FUNC +* @tc.number: VASharedBuffer_001 +* @tc.desc : Test VASharedBuffer interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBuffer_001, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + buffer->GetVASharedMemInfo(memInfo); + EXPECT_EQ(memInfo.dataMemCapacity_, 1024); + EXPECT_NE(memInfo.dataFd_, INVALID_FD); + EXPECT_NE(memInfo.statusMemCapacity_, 0); + EXPECT_NE(memInfo.statusFd_, INVALID_FD); +} + +/** +* @tc.name : Test VASharedBuffer API +* @tc.type : FUNC +* @tc.number: VASharedBuffer_002 +* @tc.desc : Test VASharedBuffer interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBuffer_002, TestSize.Level1) +{ + VASharedMemInfo memInfoInvalid; + memInfoInvalid.dataFd_ = -1; + memInfoInvalid.dataMemCapacity_ = -1; + memInfoInvalid.statusMemCapacity_ = 0; + memInfoInvalid.statusFd_ = INVALID_FD; + + std::shared_ptr bufferInvalid = VASharedBuffer::CreateFromRemote(memInfoInvalid); + EXPECT_EQ(nullptr, bufferInvalid); + + const uint32_t bufferCapacity = 1024; + std::shared_ptr bufferLocal = VASharedBuffer::CreateFromLocal(bufferCapacity); + EXPECT_NE(nullptr, bufferLocal); + + VASharedMemInfo memInfo; + bufferLocal->GetVASharedMemInfo(memInfo); + + std::shared_ptr bufferValid = VASharedBuffer::CreateFromRemote(memInfo); + EXPECT_NE(nullptr, bufferValid); +} + +/** +* @tc.name : Test VASharedBuffer API +* @tc.type : FUNC +* @tc.number: VASharedBuffer_003 +* @tc.desc : Test VASharedBuffer interface. +*/ +HWTEST(VAAudioSharedMemoryTest, VASharedBuffer_003, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + std::shared_ptr sharedMemory_ = VAAudioSharedMemory::CreateFromLocal(1024, "test_memory"); + EXPECT_NE(sharedMemory_, nullptr); + + EXPECT_NE(sharedMemory_->GetBase(), nullptr); + EXPECT_EQ(sharedMemory_->GetSize(), 1024); + EXPECT_EQ(sharedMemory_->GetName(), "test_memory"); + EXPECT_NE(sharedMemory_->GetFd(), INVALID_FD); +} + +/** +* @tc.name : Test VASharedBuffer API +* @tc.type : FUNC +* @tc.number: VASharedBuffer_004 +* @tc.desc : Test VASharedBuffer interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBuffer_004, TestSize.Level1) +{ + VASharedBuffer sharedBuffer; + int32_t result = sharedBuffer.SizeCheck(); + EXPECT_EQ(result, SUCCESS); +} + +/** +* @tc.name : Test VASharedBuffer API +* @tc.type : FUNC +* @tc.number: VASharedBuffer_005 +* @tc.desc : Test VASharedBuffer interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBuffer_005, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + uint8_t *database = buffer->GetDataBase(); + EXPECT_NE(database, nullptr); +} + +/** +* @tc.name : Test VASharedBuffer API +* @tc.type : FUNC +* @tc.number: VASharedBuffer_006 +* @tc.desc : Test VASharedBuffer interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBuffer_006, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + size_t dataSize = buffer->GetDataSize(); + EXPECT_EQ(dataSize, 1024); +} + +/** +* @tc.name : Test VASharedBuffer API +* @tc.type : FUNC +* @tc.number: VASharedBuffer_007 +* @tc.desc : Test VASharedBuffer interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBuffer_007, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + sptr ashmem = buffer->GetDataAshmem(); + EXPECT_NE(ashmem, nullptr); +} + +/* * +* @tc.name : Test VASharedBuffer API +* @tc.type : FUNC +* @tc.number: VASharedBuffer_008 +* @tc.desc : Test VASharedBuffer interface. + +HWTEST(AudioServiceCommonUnitTest, VASharedBuffer_008, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = 0; + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + uint8_t *statusInfoBase = buffer->GetStatusInfoBase(); + EXPECT_EQ(statusInfoBase, nullptr); +} */ + +/** +* @tc.name : Test VASharedBuffer API +* @tc.type : FUNC +* @tc.number: VASharedBuffer_009 +* @tc.desc : Test VASharedBuffer interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBuffer_009, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + VASharedMemInfo retrievedMemInfo; + buffer->GetVASharedMemInfo(retrievedMemInfo); + + EXPECT_EQ(retrievedMemInfo.dataMemCapacity_, 1024); + EXPECT_NE(retrievedMemInfo.statusMemCapacity_, 0); + EXPECT_NE(retrievedMemInfo.dataFd_, INVALID_FD); + EXPECT_NE(retrievedMemInfo.statusFd_, INVALID_FD); +} + +/** +* @tc.name : Test VASharedBufferOperator API +* @tc.type : FUNC +* @tc.number: VASharedBufferOperator_001 +* @tc.desc : Test VASharedBufferOperator interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBufferOperator_001, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + VASharedBufferOperator* operator_ = new VASharedBufferOperator(*buffer); + EXPECT_NE(operator_, nullptr); + + EXPECT_NE(operator_->dataAshmem_, nullptr); + EXPECT_EQ(operator_->capacity, 1024); + EXPECT_NE(operator_->statusInfo_, nullptr); + + delete operator_; +} + +/** +* @tc.name : Test VASharedBufferOperator API +* @tc.type : FUNC +* @tc.number : VASharedBufferOperator_002 +* @tc.desc : Test VASharedBufferOperator interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBufferOperator_002, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + VASharedBufferOperator *operator_ = new VASharedBufferOperator(*buffer); + EXPECT_NE(operator_, nullptr); + + operator_->SetMinReadSize(100); + EXPECT_NE(operator_->minReadSize_, 100); + delete operator_; +} + +/** +* @tc.name : Test VASharedBufferOperator API +* @tc.type : FUNC +* @tc.number : VASharedBufferOperator_003 +* @tc.desc : Test VASharedBufferOperator interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBufferOperator_003, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + VASharedBufferOperator* operator_ = new VASharedBufferOperator(*buffer); + EXPECT_NE(operator_, nullptr); + + EXPECT_EQ(operator_->GetReadableSize(), 0); + operator_->Reset(); + EXPECT_EQ(operator_->GetReadableSize(), 0); + + uint8_t testData[50] = {0}; + size_t writeSize = operator_->Write(testData, 50); + EXPECT_EQ(writeSize, 50); + EXPECT_EQ(operator_->GetReadableSize(), 50); + operator_->Reset(); + EXPECT_EQ(operator_->GetReadableSize(), 0); + delete operator_; +} + +/** +* @tc.name : Test VASharedBufferOperator API +* @tc.type : FUNC +* @tc.number : VASharedBufferOperator_004 +* @tc.desc : Test VASharedBufferOperator interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBufferOperator_004, TestSize.Level1) +{ + + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + + + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + VASharedBufferOperator* operator_ = new VASharedBufferOperator(*buffer); + EXPECT_NE(operator_, nullptr); + size_t readableSize = operator_->GetReadableSize(); + EXPECT_EQ(readableSize, 0); + delete operator_; +} + +/** +* @tc.name : Test VASharedBufferOperator API +* @tc.type : FUNC +* @tc.number : VASharedBufferOperator_005 +* @tc.desc : Test VASharedBufferOperator interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBufferOperator_005, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + VASharedBufferOperator* operator_ = new VASharedBufferOperator(*buffer); + EXPECT_NE(operator_, nullptr); + + uint8_t testData[100] = {0}; + for(int i = 0; i < 100; ++i) { + testData[i] = static_cast(i); + } + size_t writeSize = operator_->Write(testData, 100); + EXPECT_EQ(writeSize, 100); + + uint8_t readData[100] = {0}; + size_t readSize = operator_->Read(readData, 100); + EXPECT_EQ(readSize, 100); + + for (int i = 0; i < 100; ++i) { + EXPECT_EQ(readData[i], static_cast(i)); + } + EXPECT_EQ(operator_->GetReadableSize(), 0); + delete operator_; +} + +/** +* @tc.name : Test VASharedBufferOperator API +* @tc.type : FUNC +* @tc.number : VASharedBufferOperator_006 +* @tc.desc : Test VASharedBufferOperator interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBufferOperator_006, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + VASharedBufferOperator* operator_ = new VASharedBufferOperator(*buffer); + EXPECT_NE(operator_, nullptr); + + EXPECT_EQ(operator_->GetReadableSize(), 0); + + uint8_t testData[50] = {0}; + size_t writeSize = operator_->Write(testData, 50); + EXPECT_EQ(writeSize, 50); + EXPECT_EQ(operator_->GetReadableSize(), 50); + + uint8_t readData[30] = {0}; + size_t readSize = operator_->Read(readData, 30); + EXPECT_EQ(readSize, 30); + EXPECT_EQ(operator_->GetReadableSize(), 20); + + operator_->SetReadPosToWritePos(); + EXPECT_EQ(operator_->GetReadableSize(), 0); + delete operator_; +} + +/** +* @tc.name : Test VASharedBufferOperator API +* @tc.type : FUNC +* @tc.number : VASharedBufferOperator_007 +* @tc.desc : Test VASharedBufferOperator interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBufferOperator_007, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + VASharedBufferOperator* operator_ = new VASharedBufferOperator(*buffer); + EXPECT_NE(operator_, nullptr); + + auto futex = operator_->GetFutex(); + EXPECT_NE(futex, nullptr); + delete operator_; +} + +/** +* @tc.name : Test VASharedBufferOperator API +* @tc.type : FUNC +* @tc.number : VASharedBufferOperator_009 +* @tc.desc : Test VASharedBufferOperator interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBufferOperator_009, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + VASharedBufferOperator* operator_ = new VASharedBufferOperator(*buffer); + EXPECT_NE(operator_, nullptr); + + operator_->SetMinReadSize(100); + bool enoughData = operator_->HasEnoughReadableData(); + EXPECT_FALSE(enoughData); + delete operator_; +} + +/** +* @tc.name : Test VASharedBufferOperator API +* @tc.type : FUNC +* @tc.number : VASharedBufferOperator_0010 +* @tc.desc : Test VASharedBufferOperator interface. +*/ +HWTEST(AudioServiceCommonUnitTest, VASharedBufferOperator_0010, TestSize.Level1) +{ + std::shared_ptr buffer = VASharedBuffer::CreateFromLocal(1024); + EXPECT_NE(buffer, nullptr); + VASharedMemInfo memInfo; + memInfo.dataMemCapacity_ = 1024; + memInfo.dataFd_ = INVALID_FD; + memInfo.statusMemCapacity_ = sizeof(VASharedStatusInfo); + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + VASharedBufferOperator* SharedStatusInfo_ = new VASharedBufferOperator(*buffer); + EXPECT_NE(SharedStatusInfo_, nullptr); + SharedStatusInfo_->InitVASharedStatusInfo(); + EXPECT_NE(SharedStatusInfo_->statusInfo_, nullptr); +} + } // namespace AudioStandard } // namespace OHOS \ No newline at end of file -- Gitee