diff --git a/bundle.json b/bundle.json index 7d5d2c256fa371c5c69c7bbe11fcdf7d2b91bef4..116049cc666c9d0039f7ef4a55feb5333c4f08b9 100644 --- a/bundle.json +++ b/bundle.json @@ -135,11 +135,44 @@ "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/idl:audio_framework_interface", + "header": { + "header_files": [ + "va_device_controller_stub.h", + "va_input_stream_stub.h" + ], + "header_base": "//out/generic_generic_arm_64only/general_all_phone_standard/gen/foundation/multimedia/audio_framework/services/audio_service/idl" + } + }, + { + "type": "none", + "name": "//foundation/multimedia/audio_framework/services/audio_policy:audio_policy_service", + "header": { + "header_files": [ + "va_device_broker_stub_impl.h" + ], + "header_base": "//foundation/multimedia/audio_framework/services/audio_policy/client/stub/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 acb202da703b239f2e9f3bda1299faca68958407..7c2f3b2995f541ea2f1e705fd27ba6f0f21faa8c 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 551e9941185cfd0ab708b88bf8e8a0e39e01caa4..211507857b457d7d96497092451d5cb56e7dc470 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 d6b35c1d3682b7b3fdbf0a90dedfc8e2b7975eb0..c672b1b6915e547733505a569566e6f736d36e4d 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 5c9b0a1aec358ddc85278382d1a2243510b8b23b..f7ca744ecd59b37db053aaa6f9b3d1428ce52d0a 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 e7ed0c67730d907be41eef9c354c8eca5d86f9dd..1922d4f77e8f83fe50a6fe1f721dcd952b7b4846 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 9ea0c5c8e652fdaae733847384bb0f77c2c55f3e..a7255c395bf333d2c22580af4257db6e011d4955 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 de68690665171224d7c038e702947e1ee5220306..a726e0e4fdf095f7d4421a76264c43e8601d66e4 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 5cf02a315e85a2bd47e09d4a0e26d8c8d460801d..fd95d673a6f39596f4782068f202019a11c4bf8f 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/source/audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/audio_capture_source.h index 140390d8c761186e0b2cbe356bf6e2661321909d..5940f82b5d132dcbb01c8c65e601d5403d785d8e 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 e7e9c68aa5bd859762d3f734cd3c427ab254dddb..377a81b7c74877a0834fc72e22c829ae2a778741 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 52b65ab93486bbdd3aac3d5d7c0a0ceac8911af7..29999a6fa3f8037808d0b916c7997a9ee090c4ff 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 11d532274d094dcf260ab09ff0cde740d95784a3..1a2aace4cab4570a60af09944ff466f5836e50c4 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 1648a99f9bf2fb43beb6f8b2ab687444127d88ed..7baebb7b7670ac248c5c240a1a584727bf8f5a5c 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 43568e05e3d0e4cac8953b3268a9bbbd4624db1b..791ce063f5b08b945896d6619e061149b6a20cb2 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 023fd7d9b85537e96a8e642287982785d1ba53e0..0919deca869053db19d76dd925e117f86a97aa3e 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 0000000000000000000000000000000000000000..e95a871afa656d41ab74812b9332e937a0e7f8f9 --- /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_; + //for get amplitude + float maxAmplitude_ = 0; + int64_t lastGetMaxAmplitudeTime_ = 0; + int64_t last10FrameStartTime_ = 0; + bool startUpdate_ = false; + int captureFrameNum_ = 0; + //for dfx log + 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 8714ae89a7e30dd5f5a460919b63420e8082855a..db9a580e215a865e5f5a5ec0a54e4edec50b6710 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 86849b3aaf9846d5f7d15bd81240adfa10a822fe..bb36e21ffe437d47eddd9d893b2ab0faad4b70e6 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 4cf9082123cd65956224d4b17dec706804152bae..f3a6f990edb8bd5863a981d99048d97d523313bc 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 0d30cbfca46097095b123c5e33fc506e21ac1d79..0db92ed222080646452c6f61d802274723b2caf7 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 e2a66130b02660aaab75ae3eb44d8a2e9328314b..e58681c4bec091dcc212fe9124e11321e093f1fe 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 11423229321bab541d861057f2b1ef0520603cfa..54753dc3fd35abcac16211ad7ac9380a8fba47f7 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 265b5b7069263cc949873dd0d2d7ad095bdf7b50..56b9858a03e4fb62e201c97827bc880f6cd421a1 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 b8f296bd67a3180dd401897deb12e5d457a35d4c..c04df5a432a8a02c5290d89da44fb80ab990b1ac 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 0000000000000000000000000000000000000000..a1fe3a955ddd3963f593afd084fc72be6822e780 --- /dev/null +++ b/frameworks/native/hdiadapter_new/source/va_capture_source.cpp @@ -0,0 +1,385 @@ +/* + * 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_.deviceNetworkId; + 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, "inputStream 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, "bufferOperator_ 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, "inputStream_ is null"); + inputStream_->Close(); + + sourceInited_ = false; + started_ = false; + inputStream_ = nullptr; + bufferOperator_ = nullptr; +} + +bool VACaptureSource::IsInited(void) +{ + return sourceInited_; +} + +int32_t VACaptureSource::Start(void) +{ + 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(); + } + + bufferOperator_->Reset(); + + if (audioSrcClock_ != nullptr) { + audioSrcClock_->Reset(); + } + CHECK_AND_RETURN_RET_LOG(inputStream_ != nullptr, ERR_OPERATION_FAILED, "inputStream_ is null"); + 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, "inputStream_ 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) +{ + 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(inputStream_ != nullptr, ERR_OPERATION_FAILED, "inputStream_ 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); + return value; +} + +void VACaptureSource::SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) +{ + 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 be66ffe53c734d4a9096e7ced5539af3bc64fac9..4c6c97121ec022e2b7c2b9f899522fccff8fed56 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 0000000000000000000000000000000000000000..cce48d3ec53981779c43ff4472ba9bd7fd3d2e03 --- /dev/null +++ b/frameworks/native/hdiadapter_new/test/unittest/source/va_capture_source_unit_test.cpp @@ -0,0 +1,297 @@ +/* + * 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; // 48000: sample rate + attr_.channel = 2; // 2: channel + attr_.format = SAMPLE_S16LE; + attr_.channelLayout = 3; // 3: channel layout + 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; // 2: channel + 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 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 cf9ab8bc6c86d401f54e3b9107a9533b9c923276..853e1b61cab07d1952ae8c932ce8bab6a4938758 100644 --- a/frameworks/native/hdiadapter_new/util/id_handler.cpp +++ b/frameworks/native/hdiadapter_new/util/id_handler.cpp @@ -104,10 +104,9 @@ uint32_t IdHandler::GetCaptureIdByDeviceClass(const std::string &deviceClass, co if (info == HDI_ID_INFO_EC || info == HDI_ID_INFO_MIC_REF) { return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, info); } - if (sourceType == SOURCE_TYPE_VOICE_TRANSCRIPTION) { - 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 957e67ae8f635b87b8663140055983df402986d0..8ed73baaa25d4c884490f46aecbf1edf279b72e1 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 0000000000000000000000000000000000000000..be18c54ae6806635d0c0435b227bc10ec9b2bee2 --- /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 6486fcb4b01714979c4c710ca8651c6be3622a96..477380eba2e5e9b2ff0b5ede66ba4e9e873ca75d 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 */ @@ -212,7 +215,7 @@ enum DeviceType { DEVICE_TYPE_MAX }; -inline const std::unordered_set INPUT_DEVICE_TYPE_SET = { +const std::unordered_set INPUT_DEVICE_TYPE_SET = { DeviceType::DEVICE_TYPE_WIRED_HEADSET, DeviceType::DEVICE_TYPE_BLUETOOTH_SCO, DeviceType::DEVICE_TYPE_BLUETOOTH_A2DP_IN, @@ -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 4650862b658190e7af2b29bd0bdf2838cb61cbec..1cac08ca42f9824ae7c1eafd6cee1897204d2093 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 }; @@ -1950,14 +1944,6 @@ enum BoostTriggerMethod : uint32_t { METHOD_WRITE_OR_READ, METHOD_MAX }; - -enum XperfEventId : int32_t { - XPERF_EVENT_START = 0, - XPERF_EVENT_STOP = 1, - XPERF_EVENT_RELEASE = 2, - XPERF_EVENT_FAULT = 3, - XPERF_EVENT_MAX = 4, -}; } // namespace AudioStandard } // namespace OHOS #endif // AUDIO_INFO_H 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 0000000000000000000000000000000000000000..a1beeb934f1175810f18e36050b28f130051ae24 --- /dev/null +++ b/interfaces/inner_api/native/audiocommon/include/va_device.h @@ -0,0 +1,58 @@ +/* + * 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 "audio_policy_interface.h" + +#include "iv_a_device_controller.h" +#include "message_parcel.h" + +namespace OHOS { + namespace AudioStandard { + struct VADevice :public Parcelable { + std::string implementor_; + VADeviceConfiguration configuration_; + sptr deviceController_; + + 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 0000000000000000000000000000000000000000..a91a526cb2c1d399689913ad23e4c5136eea8d08 --- /dev/null +++ b/interfaces/inner_api/native/audiocommon/include/va_device_info.h @@ -0,0 +1,210 @@ +/* + * 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" +#include "audio_log.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.Unmarshalling(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/services/audio_engine/manager/include/i_hpae_capturer_manager.h b/services/audio_engine/manager/include/i_hpae_capturer_manager.h index 616e47b888f2fc678802ea326dbe0e86f305b58c..4c4a0bcce1300d310bcae9d4bffd56ceef8e6aad 100644 --- a/services/audio_engine/manager/include/i_hpae_capturer_manager.h +++ b/services/audio_engine/manager/include/i_hpae_capturer_manager.h @@ -25,6 +25,7 @@ namespace OHOS { namespace AudioStandard { namespace HPAE { +//仅有HpaeCapturerManager一个实现类 class IHpaeCapturerManager : public HpaeStreamManager { public: virtual ~IHpaeCapturerManager() {} diff --git a/services/audio_engine/manager/src/hpae_manager.cpp b/services/audio_engine/manager/src/hpae_manager.cpp index c869cf6e28515d0e5ea2229530b812ef19c1be73..4e0b71daa6bd4c5dd59d5b1cf4d61577f0ffad4a 100644 --- a/services/audio_engine/manager/src/hpae_manager.cpp +++ b/services/audio_engine/manager/src/hpae_manager.cpp @@ -33,13 +33,11 @@ namespace OHOS { namespace AudioStandard { namespace HPAE { namespace { -constexpr uint32_t DEFAULT_PAUSE_STREAM_TIME_IN_MS = 60; // 60ms static inline const std::unordered_set INNER_SOURCE_TYPE_SET = { SOURCE_TYPE_PLAYBACK_CAPTURE, SOURCE_TYPE_REMOTE_CAST}; } // namespace static constexpr int32_t SINK_INVALID_ID = -1; static const std::string BT_SINK_NAME = "Bt_Speaker"; -static const std::string DEFAULT_CORE_SOURCE_NAME = "Virtual_Capture"; HpaeManagerThread::~HpaeManagerThread() { @@ -63,15 +61,8 @@ void HpaeManagerThread::Run() std::unique_lock lock(mutex_); bool isProcessing = m_hpaeManager->IsMsgProcessing(); bool signal = recvSignal_.load(); - uint64_t sleepTime = m_hpaeManager->ProcessPendingTransitionsAndGetNextDelay(); - Trace trace("runFunc:" + std::to_string(signal) + " isPorcessing:" + std::to_string(isProcessing) + - " sleepTime:" + std::to_string(sleepTime)); - if (sleepTime > 0) { - condition_.wait_for(lock, std::chrono::milliseconds(sleepTime), - [this] { return m_hpaeManager->IsMsgProcessing() || recvSignal_.load(); }); - } else { - condition_.wait(lock, [this] { return m_hpaeManager->IsMsgProcessing() || recvSignal_.load(); }); - } + Trace trace("runFunc:" + std::to_string(signal) + " isPorcessing:" + std::to_string(isProcessing)); + condition_.wait(lock, [this] { return m_hpaeManager->IsMsgProcessing() || recvSignal_.load(); }); } m_hpaeManager->HandleMsg(); recvSignal_.store(false); @@ -340,28 +331,12 @@ int32_t HpaeManager::OpenInputAudioPort(const AudioModuleInfo &audioModuleInfo, capturerManagerMap_[audioModuleInfo.name] = capturerManager; sourceNameSourceIdMap_[audioModuleInfo.name] = sinkSourceIndex; sourceIdSourceNameMap_[sinkSourceIndex] = audioModuleInfo.name; - if (defaultSource_ == "" && coreSource_ == "") { - CreateCoreSourceManager(); - } capturerManagerMap_[audioModuleInfo.name]->Init(); AUDIO_INFO_LOG( "open source name: %{public}s end sourceIndex is %{public}u", audioModuleInfo.name.c_str(), sinkSourceIndex); return SUCCESS; } -void HpaeManager::CreateCoreSourceManager() -{ - defaultSource_ = DEFAULT_CORE_SOURCE_NAME; - coreSource_ = DEFAULT_CORE_SOURCE_NAME; - uint32_t sinkSourceIndex = static_cast(sinkSourceIndex_.load()); - sinkSourceIndex_.fetch_add(1); - auto capturerManager = std::make_shared(); - capturerManager->RegisterSendMsgCallback(weak_from_this()); - capturerManagerMap_[DEFAULT_CORE_SOURCE_NAME] = capturerManager; - sourceNameSourceIdMap_[DEFAULT_CORE_SOURCE_NAME] = sinkSourceIndex; - sourceIdSourceNameMap_[sinkSourceIndex] = DEFAULT_CORE_SOURCE_NAME; -} - int32_t HpaeManager::OpenVirtualAudioPort(const AudioModuleInfo &audioModuleInfo, uint32_t sinkSourceIndex) { if (SafeGetMap(rendererManagerMap_, audioModuleInfo.name)) { @@ -400,7 +375,9 @@ int32_t HpaeManager::OpenVirtualAudioPort(const AudioModuleInfo &audioModuleInfo int32_t HpaeManager::OpenAudioPortInner(const AudioModuleInfo &audioModuleInfo) { uint32_t sinkSourceIndex = static_cast(sinkSourceIndex_.load()); - if ((audioModuleInfo.lib != "libmodule-hdi-source.z.so") && + if(audioModuleInfo.lib == "va_lib"){ + OpenInputAudioPort(audioModuleInfo, sinkSourceIndex); + } else if ((audioModuleInfo.lib != "libmodule-hdi-source.z.so") && (audioModuleInfo.lib != "libmodule-inner-capturer-sink.z.so")) { OpenOutputAudioPort(audioModuleInfo, sinkSourceIndex); } else if (audioModuleInfo.lib == "libmodule-hdi-source.z.so") { @@ -567,14 +544,6 @@ int32_t HpaeManager::CloseInAudioPort(std::string sourceName) AUDIO_WARNING_LOG("can not find sourceName: %{public}s in capturerManagerMap_", sourceName.c_str()); return SUCCESS; } - if (sourceName == defaultSource_ && defaultSource_ != coreSource_) { - if (GetCapturerManagerByName(coreSource_) != nullptr) { - AUDIO_INFO_LOG("reset default source to core source"); - defaultSource_ = coreSource_; - } else { - AUDIO_ERR_LOG("cannot find core source to replace default source"); - } - } capturerManagerMap_[sourceName]->DeInit(sourceName != defaultSource_); if (sourceName != defaultSource_) { capturerManagerMap_.erase(sourceName); @@ -1136,30 +1105,13 @@ void HpaeManager::HandleUpdateStatus( // maybe dosomething while move sink inputs return; } - if (streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY) { - auto it = rendererIdStreamInfoMap_.find(sessionId); - CHECK_AND_RETURN(it != rendererIdStreamInfoMap_.end()); - CHECK_AND_RETURN(IsValidUpdateStatus(operation, it->second.state)); - if (operation == OPERATION_PAUSED || operation == OPERATION_STOPPED) { - DequeuePendingTransition(sessionId); - it->second.state = status; - } - UpdateStatus(it->second.statusCallback, operation, sessionId); - } else { - auto it = capturerIdStreamInfoMap_.find(sessionId); - CHECK_AND_RETURN(it != capturerIdStreamInfoMap_.end()); + auto it = streamClassType == HPAE_STREAM_CLASS_TYPE_PLAY ? rendererIdStreamInfoMap_.find(sessionId) + : capturerIdStreamInfoMap_.find(sessionId); + if (it != rendererIdStreamInfoMap_.end() && it != capturerIdStreamInfoMap_.end()) { UpdateStatus(it->second.statusCallback, operation, sessionId); } } -bool HpaeManager::IsValidUpdateStatus(IOperation operation, HpaeSessionState currentState) -{ - CHECK_AND_RETURN_RET_LOG(!(operation == OPERATION_STOPPED && currentState != HPAE_SESSION_STOPPING) && - !(operation == OPERATION_PAUSED && currentState != HPAE_SESSION_PAUSING), false, - "stopped or paused, currentState:%{public}d", currentState); - return true; -} - void HpaeManager::UpdateStatus(const std::weak_ptr &callback, IOperation operation, uint32_t sessionId) { @@ -1250,45 +1202,6 @@ void HpaeManager::SendRequest(Request &&request, std::string funcName) CHECK_AND_RETURN_LOG(hpaeManagerThread_, "hpaeManagerThread_ is nullptr"); hpaeManagerThread_->Notify(); } - -uint64_t HpaeManager::ProcessPendingTransitionsAndGetNextDelay() -{ - constexpr auto timeout = std::chrono::milliseconds(DEFAULT_PAUSE_STREAM_TIME_IN_MS); - const auto now = std::chrono::high_resolution_clock::now(); - while (!pendingTransitionsTracker_.empty()) { - auto front = pendingTransitionsTracker_.front(); - auto elapsed = now - front.time; - if (elapsed >= timeout) { - AUDIO_INFO_LOG("sessionid:%{public}u status:%{public}d operation:%{public}d", - front.sessionId, front.state, front.operation); - pendingTransitionsTracker_.pop_front(); - HandleUpdateStatus(HPAE_STREAM_CLASS_TYPE_PLAY, front.sessionId, front.state, front.operation); - } else { - return std::chrono::duration_cast(timeout - elapsed).count(); - } - } - return 0; -} - -void HpaeManager::DequeuePendingTransition(uint32_t sessionId) -{ - auto it = pendingTransitionsTracker_.begin(); - while (it != pendingTransitionsTracker_.end()) { - if (it->sessionId == sessionId) { - it = pendingTransitionsTracker_.erase(it); - AUDIO_INFO_LOG("DequeuePendingTransition sessionid:%{public}u", sessionId); - break; - } else { - ++it; - } - } -} - -void HpaeManager::EnqueuePendingTransition(uint32_t sessionId, HpaeSessionState state, IOperation operation) -{ - pendingTransitionsTracker_.push_back({sessionId, state, operation, std::chrono::high_resolution_clock::now()}); -} - // play and record stream interface int32_t HpaeManager::CreateStream(const HpaeStreamInfo &streamInfo) { @@ -1568,7 +1481,6 @@ int32_t HpaeManager::Pause(HpaeStreamClassType streamClassType, uint32_t session "cannot find device:%{public}s", rendererIdSinkNameMap_[sessionId].c_str()); rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Pause(sessionId); rendererIdStreamInfoMap_[sessionId].state = HPAE_SESSION_PAUSING; - EnqueuePendingTransition(sessionId, HPAE_SESSION_PAUSED, OPERATION_PAUSED); } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { AUDIO_INFO_LOG("capturer Pause sessionId: %{public}u deviceName:%{public}s", @@ -1695,7 +1607,6 @@ int32_t HpaeManager::Stop(HpaeStreamClassType streamClassType, uint32_t sessionI "cannot find device:%{public}s", rendererIdSinkNameMap_[sessionId].c_str()); rendererManagerMap_[rendererIdSinkNameMap_[sessionId]]->Stop(sessionId); rendererIdStreamInfoMap_[sessionId].state = HPAE_SESSION_STOPPING; - EnqueuePendingTransition(sessionId, HPAE_SESSION_STOPPED, OPERATION_STOPPED); } else if (streamClassType == HPAE_STREAM_CLASS_TYPE_RECORD && capturerIdSourceNameMap_.find(sessionId) != capturerIdSourceNameMap_.end()) { AUDIO_INFO_LOG("capturer Stop sessionId: %{public}u deviceName:%{public}s", diff --git a/services/audio_policy/BUILD.gn b/services/audio_policy/BUILD.gn index cba57a80c58d5c6f4b201f02a21f336e3ce79102..6a2ca76392c4c2fe8eb3385f3d7f12c74a7342a7 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", @@ -262,6 +263,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", @@ -615,24 +618,19 @@ group("audio_policy_test_packages") { ":audio_policy_test", "test:audio_policy_unittest_packages", "client/stub:audio_zone_client_unit_test", - "client/stub:audio_policy_manager_listener_stub_impl_unit_test", "client/service/test:audio_policy_manager_device_unit_test", "server/infra/config/parser/test:audio_policy_config_parser_unittest_packages", "server/domain/device:audio_device_common_unit_next_test", "server/domain/device/test:audio_device_status_extended_test", "server/domain/effect/test:audio_spatialization_service_extended_test", - "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", "server/service/service_main/test:audio_policy_service_ext_unit_test", "server/service/service_main/test:device_init_callback_unit_test", "server/infra/state_monitor/test:audio_policy_state_monitor_unittest_packages", - "server/infra/ipc_proxy/test:audio_policy_ipc_proxy_unittest_packages", "server/common/test:audio_policy_server_common_unittest_packages", - "server/src/test:audio_server_src_unittest_packages", ] } @@ -704,6 +702,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 0000000000000000000000000000000000000000..5411c7a90301e726c148d328a9da12f3c3b41373 --- /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 "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/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 0000000000000000000000000000000000000000..4a96789ff2ab124ff4e717a0db9f6f677736c129 --- /dev/null +++ b/services/audio_policy/client/stub/src/va_device_broker_stub_impl.cpp @@ -0,0 +1,65 @@ +/* + * 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); + 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/idl/IAudioPolicy.idl b/services/audio_policy/idl/IAudioPolicy.idl index 62b3c23018eb9ba89cac21d24f5bc75efa4539c4..ff430d1c3549f24075378c8f48d704f8ac1577e3 100644 --- a/services/audio_policy/idl/IAudioPolicy.idl +++ b/services/audio_policy/idl/IAudioPolicy.idl @@ -289,6 +289,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 SetAppSlientOnDisplay([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 0000000000000000000000000000000000000000..97d44ec6bb8fba036b8e86f38d7defed4defbb23 --- /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 0000000000000000000000000000000000000000..78ff5c018cbf732d7dac13f427579026ee44ff49 --- /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 0000000000000000000000000000000000000000..37be8d5f4bad29308e8d8d7aff146964834a0949 --- /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 0000000000000000000000000000000000000000..37b7aba207ee10bcd508c2508e9ae386f4a990d6 --- /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 f2a5c90ecf97023c8f5d714cd70e786ae15d1701..0f1fbd52f096a6f5f22014736f824bdbad553d38 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 @@ -35,6 +35,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"}, @@ -48,6 +50,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 c62e54ff6e0e4476c2a670e66af26c72b8856d34..9625ef14d15b26ffbe656fa8914d4a55a84e3254 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 b3b37f2451e76c9c77bf9c3069cb03d49d8b12b5..62e78c474fd5fa5b87d7b1bea2a4673ca11d1921 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 0000000000000000000000000000000000000000..6f153c26c2e6edb37a600c3d138a9d2ce820148c --- /dev/null +++ b/services/audio_policy/server/domain/device/src/va/va_device_manager.cpp @@ -0,0 +1,178 @@ +/* + * 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" + +namespace OHOS { +namespace AudioStandard { +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_ = VA_DEVICE_TYPE_NONE; + break; + case VA_DEVICE_TYPE_BT_SPP: + desc->deviceType_ = VA_DEVICE_TYPE_BT_SPP; + break; + } + switch (config.role_) + { + case VA_DEVICE_ROLE_IN: + desc->deviceRole_ = INPUT_DEVICE; + break; + case VA_DEVICE_ROLE_OUT: + desc->deviceRole_ = OUTPUT_DEVICE; + break; + } + desc->macAddress_ = config.address_; + desc->networkId_ = 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) +{ + std::shared_ptr descriptor = ConvertVADeviceToDescriptor(vaDevice); + connectedVADeviceMap_[vaDevice->configuration_.address_] = controller; + + AudioPolicyConfigData &config = AudioPolicyConfigData::GetInstance(); + if (config.adapterInfoMap.find(AudioAdapterType::TYPE_VA) == config.adapterInfoMap.end()) { + RegisterVAAdapterToMap(config); + } + AudioCoreService::GetCoreService()->GetEventEntry()->OnDeviceStatusUpdated(*descriptor, true); +} + +void VADeviceManager::OnDevicesDisconnected(const std::shared_ptr &vaDevice) +{ + std::shared_ptr descriptor = ConvertVADeviceToDescriptor(vaDevice); + AudioCoreService::GetCoreService()->GetEventEntry()->OnDeviceStatusUpdated(*descriptor, false); + connectedVADeviceMap_.erase(vaDevice->configuration_.address_); + if (connectedVADeviceMap_.size() <= 0) { + AudioPolicyConfigData &config = AudioPolicyConfigData::GetInstance(); + UnregisterVAAdapterFromMap(config); + } +} + +void VADeviceManager::GetDeviceController(const std::string macAddr, sptr &controller) +{ + sptr vaController = connectedVADeviceMap_[macAddr]; + if (vaController == nullptr) { + AUDIO_WARNING_LOG("cannot find controller"); + controller = nullptr; + } else { + controller = vaController->AsObject(); + } + return; +} + +void VADeviceManager::RegisterVAAdapterToMap(AudioPolicyConfigData &config) +{ + /*添加 va adapter 信息*/ + PolicyAdapterInfo adapterInfo{}; + std::shared_ptr adapterInfoPtr = std::make_shared(adapterInfo); + adapterInfoPtr->adapterName = ADAPTER_TYPE_VA; + config.adapterINfoMap.insert({adapterInfoPtr->GetTypeEnum(), adapterInfoPtr}); + + // 添加 pipeInfo + std::shared_ptr pipeInfo = std::make_shared(); + pipeInfo->adapterInfo_ = adapterInfoPtr; + pipeInfo->name_ = "va_input"; + pipeInfo->role_ = AudioDefinitionPolicyUtils::pipeRoleStrToEnum["input"]; + pipeInfo->supportDevices_.push_back("Virtual Audio"); + + // 添加 deviceInfo + AdapterDeviceInfo deviceInfo{}; + deviceInfo.adapterInfo_ = adapterInfoPtr; + deviceInfo.name = "Virtual Audio"; + deviceInfo.type_ = AudioDefinitionPolicyUtils::deviceTypeStrToEnum["DEVICE_TYPE_BT_SPP"]; + deviceInfo.role_ = AudioDefinitionPolicyUtils::deviceRoleStrToEnum["input"]; + deviceInfo.supportPipes_.push_back("va_input"); // 这里需要和pipeinfo的名字一致 + deviceInfo.supportPipeMap_[AudioFlag::AUDIO_INPUT_FLAG_NORMAL] = pipeInfo; + + adapterInfoPtr->deviceInfos.push_back(make_shared(deviceInfo)); + + // 添加 streamPropInfo + PipeStreamPropInfo streamPropInfo = {}; + streamPropInfo.pipeInfo_ = pipeInfo; + streamPropInfo.format_ = AudioDefinitionPolicyUtils::formatStrToEnum["s16le"]; + streamPropInfo.sampleRate_ = AudioSamplingRate::SAMPLE_RATE_16000; + streamPropInfo.channelLayout_ = AudioDefinitionPolicyUtils::layoutStrToEnum["CH_LAYOUT_MONO"]; + streamPropInfo.channels_ = AudioDefinitionPolicyUtils::ConvertLayoutToAudioChannel(streamPropInfo.channelLayout_); + streamPropInfo.bufferSize_ = 640; // 640 + streamPropInfo.supportDevices_.push_back("Virtual Audio"); + + // pipeInfo 中添加 streamPropInfo + pipeInfo->streamPropInfos_.push_back(make_shared(streamPropInfo)); + + // 添加 paPropInfo + PaPropInfo paProp = {}; + paProp.lib_ = "va_lib"; // must align with va lib name in HpaeManager::OpenAudioPortInner + paProp.role_ = "source"; + paProp.moduleName_ = "va_module_name"; + paProp.fixedLatency_ = ""; + paProp.renderInIdleState_ = ""; + + // pipeInfo 中添加 pipeInfo + pipeInfo->paProp_ = std::move(paProp); + + // adapter 中添加 pipeInfo + adapterInfoPtr->pipeInfos.push_back(pipeInfo); + + config.Reorganize(); +} + +void VADeviceManager::UnregisterVAAdapterFromMap(AudioPolicyConfigData &config) +{ + config.adapterInfoMap.erase(AudioAdapterType::TYPE_VA); + std::pair deviceMapkey = std::make_pair(DEVICE_TYPE_BT_SPP, INPUT_DEVICE); + config.deviceInfoMap.erase(deviceMapKey); +} +} //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 0000000000000000000000000000000000000000..0651e4397424f7478c27d3a71d91bb37e676b674 --- /dev/null +++ b/services/audio_policy/server/domain/device/src/va/va_device_manager.h @@ -0,0 +1,71 @@ +/* + * 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" + + +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(AudioPolicyConfigData &config); + void UnregisterVAAdapterFromMap(AudioPolicyConfigData &config); + + std::shared_ptr ConvertVADeviceToDescriptor(const std::shared_ptr &vaDevice); + + std::shared_ptr ConvertVAStreamPropertyToInfo(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 ee199dd1e98b6e693eddafd60dcc43eee0f3c205..8efbe560e03f16696ab0b0a1af3e44b411ee8220 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 a36f78ac58fbe8e77107d60792d2f51feb5f957c..448b7aa7801ad6f6621e49b0e2f2579a37ea9180 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 b72c079ca1ca9e74d237eaa533f7f6a72f4e4d7f..bfe98a51ab1dd05739e5ad42059817d042e7bb81 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 @@ -60,7 +60,7 @@ std::unordered_map AudioDefinitionPolicyUtils::deviceTy {"DEVICE_TYPE_NEARLINK", DEVICE_TYPE_NEARLINK}, {"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/infra/config/parser/src/audio_device_parser.cpp b/services/audio_policy/server/infra/config/parser/src/audio_device_parser.cpp index 8c551c171eab7eb568394d8fbde561f45f1c7895..c0bac49a7c9384a1c3a1bb9b2acb688386c04bba 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 73b8147036197aaa4fa4c917394a89fd88f88cd9..720d985402c9c375a261c76d42664c3b8cdae4e9 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 @@ -592,6 +592,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); @@ -677,6 +681,7 @@ public: int32_t UpdateDeviceInfo(const std::shared_ptr &deviceDesc, int32_t command) override; int32_t SetSleAudioOperationCallback(const sptr &object) override; int32_t CallRingtoneLibrary(); + void SetVoiceMuteState(uint32_t sessionId, bool isMute); int32_t SetSystemVolumeDegree(int32_t streamType, int32_t volumeDegree, int32_t volumeFlag, int32_t uid) override; int32_t GetSystemVolumeDegree(int32_t streamType, int32_t uid, int32_t &volumeDegree) override; int32_t GetMinVolumeDegree(int32_t volumeType, int32_t &volumeDegree) override; 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 b634e93d3e7dac7c3f9a11120e1cd020752cfb3a..d292be13bd87ea768af2a791156233040c5aee76 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_core_service.cpp b/services/audio_policy/server/service/service_main/src/audio_core_service.cpp index 4407373569c5922ca72eb4762c9f4248d344065e..93470078e3de347240cab833b3c92c31800473ba 100644 --- a/services/audio_policy/server/service/service_main/src/audio_core_service.cpp +++ b/services/audio_policy/server/service/service_main/src/audio_core_service.cpp @@ -169,6 +169,10 @@ int32_t AudioCoreService::CreateRendererClient( audioFlag = AUDIO_FLAG_NORMAL; AddSessionId(sessionId); pipeManager_->AddModemCommunicationId(sessionId, streamDesc); + } else if (streamDesc->rendererInfo_.streamUsage == STREAM_USAGE_RINGTONE || + streamDesc->rendererInfo_.streamUsage == STREAM_USAGE_VOICE_COMMUNICATION) { + std::string bundleName = AudioBundleManager::GetBundleNameFromUid(streamDesc->appInfo_.appUid); + Bluetooth::AudioHfpManager::AddVirtualCallBundleName(bundleName, streamDesc->sessionId_); } AUDIO_INFO_LOG("[DeviceFetchStart] for stream %{public}d", sessionId); @@ -216,6 +220,11 @@ int32_t AudioCoreService::CreateCapturerClient( std::shared_ptr inputDeviceDesc = audioRouterCenter_.FetchInputDevice(streamDesc->capturerInfo_.sourceType, GetRealUid(streamDesc), sessionId); + + if (inputDeviceDesc->deviceType_ == DEVICE_TYPE_BT_SPP) { + inputDeviceDesc->networkId_ = inputDeviceDesc->macAddress_; + } + CHECK_AND_RETURN_RET_LOG(inputDeviceDesc != nullptr, ERR_INVALID_PARAM, "inputDeviceDesc is nullptr"); streamDesc->newDeviceDescs_.clear(); streamDesc->newDeviceDescs_.push_back(inputDeviceDesc); @@ -959,6 +968,15 @@ int32_t AudioCoreService::UpdateTracker(AudioMode &mode, AudioStreamChangeInfo & return ret; // only update tracker in new and prepared } + const auto &rendererChangeInfo = streamChangeInfo.audioRendererChangeInfo; + if ((mode == AUDIO_MODE_PLAYBACK) && (rendererChangeInfo.rendererInfo.streamUsage == STREAM_USAGE_RINGTONE || + rendererChangeInfo.rendererInfo.streamUsage == STREAM_USAGE_VOICE_COMMUNICATION)) { + if ((rendererState == RENDERER_STOPPED ||rendererState == RENDERER_RELEASED || + rendererState == RENDERER_PAUSED)) { + Bluetooth::AudioHfpManager::DeleteVirtualCallStream(rendererChangeInfo.sessionId); + } + } + UpdateTracker(mode, streamChangeInfo, rendererState); if (audioA2dpOffloadManager_) { @@ -1252,14 +1270,9 @@ int32_t AudioCoreService::FetchOutputDeviceAndRoute(std::string caller, const Au } streamUsage = (streamUsage != StreamUsage::STREAM_USAGE_INVALID) ? streamUsage : streamDesc->rendererInfo_.streamUsage; - std::vector> devices; - if (VolumeUtils::IsPCVolumeEnable() && !isFirstScreenOn_) { - devices.push_back(AudioDeviceManager::GetAudioDeviceManager().GetRenderDefaultDevice()); - } else { - devices = audioRouterCenter_.FetchOutputDevices(streamUsage, GetRealUid(streamDesc), + streamDesc->newDeviceDescs_ = + audioRouterCenter_.FetchOutputDevices(streamUsage, GetRealUid(streamDesc), caller + "FetchOutputDeviceAndRoute"); - } - streamDesc->UpdateNewDevice(devices); AUDIO_INFO_LOG("[AudioSession] streamUsage %{public}d renderer streamUsage %{public}d", streamUsage, streamDesc->rendererInfo_.streamUsage); AUDIO_INFO_LOG("[DeviceFetchInfo] device %{public}s for stream %{public}d with status %{public}u", @@ -1408,10 +1421,5 @@ int32_t AudioCoreService::CaptureConcurrentCheck(uint32_t sessionId) WriteCapturerConcurrentEvent(dfxResult); return SUCCESS; } - -void AudioCoreService::SetFirstScreenOn() -{ - isFirstScreenOn_ = true; -} } // namespace AudioStandard } // namespace OHOS 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 f466e82bbd03110050db30b1fa288b53439b33bf..4d14214e6846db20e05efb67772ca30a63a42ba9 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; @@ -274,7 +276,7 @@ void AudioPolicyServer::OnStart() SubscribeVolumeKeyEvents(); #endif if (getpid() > FIRST_SCREEN_ON_PID) { - coreService_->SetFirstScreenOn(); + audioDeviceCommon_.SetFirstScreenOn(); } // Restart to reload the volume. InitKVStore(); @@ -1059,9 +1061,11 @@ void AudioPolicyServer::OnReceiveEvent(const EventFwk::CommonEventData &eventDat eventEntry_->OnReceiveUpdateDeviceNameEvent(macAddress, deviceName); } else if (action == "usual.event.SCREEN_ON") { AUDIO_INFO_LOG("receive SCREEN_ON action, control audio focus if need"); - CHECK_AND_RETURN_LOG(coreService_, "coreService_ is nullptr"); - coreService_->SetFirstScreenOn(); - CHECK_AND_RETURN_LOG(powerStateListener_, "powerStateListener_ is nullptr"); + audioDeviceCommon_.SetFirstScreenOn(); + if (powerStateListener_ == nullptr) { + AUDIO_ERR_LOG("powerStateListener_ is nullptr"); + return; + } powerStateListener_->ControlAudioFocus(false); } else if (action == "usual.event.SCREEN_LOCKED") { AUDIO_INFO_LOG("receive SCREEN_OFF or SCREEN_LOCKED action, control audio volume change if stream is active"); @@ -5326,6 +5330,24 @@ 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; +} + +void AudioPolicyServer::SetVoiceMuteState(uint32_t sessionId, bool isMute) +{ + CHECK_AND_RETURN_LOG(coreService_ != nullptr, "coreService_ is nullptr"); + return coreService_->SetVoiceMuteState(sessionId, isMute); +} + 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_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 756be3a4c7f49779977ee7b5047b69ca3a7ed803..efe9cad5f0c41e74f23e3b2b2ac812843e887c88 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 @@ -799,6 +799,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 @@ -885,6 +903,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 @@ -1465,120 +1500,5 @@ HWTEST_F(AudioDeviceStatusUnitTest, AudioDeviceStatus_069, TestSize.Level1) int32_t result = audioDeviceStatus.HandleLocalDeviceDisconnected(updatedDesc); EXPECT_EQ(result, SUCCESS); } - -/** -* @tc.name : Test AudioDeviceStatus. -* @tc.number: WriteOutputDeviceChangedSysEvents_001 -* @tc.desc : Test WriteOutputDeviceChangedSysEvents interface. -*/ -HWTEST_F(AudioDeviceStatusUnitTest, WriteOutputDeviceChangedSysEvents_001, TestSize.Level1) -{ - std::shared_ptr deviceDescriptor = std::make_shared(); - SinkInput sinkInput; - deviceDescriptor->deviceType_ = DEVICE_TYPE_USB_ARM_HEADSET; - deviceDescriptor->macAddress_ = "00:11:22:33:44:55"; - deviceDescriptor->deviceRole_ = DeviceRole::OUTPUT_DEVICE; - deviceDescriptor->networkId_ = "123456"; - deviceDescriptor->deviceName_ = "usb_headset"; - deviceDescriptor->deviceCategory_ = BT_UNWEAR_HEADPHONE; - sinkInput.streamId = 1; - sinkInput.streamType = STREAM_RING; - AudioDeviceStatus& audioDeviceStatus = AudioDeviceStatus::GetInstance(); - - audioDeviceStatus.WriteOutputDeviceChangedSysEvents(deviceDescriptor, sinkInput); - EXPECT_EQ(deviceDescriptor->deviceId_, 0); -} - -/** -* @tc.name : Test AudioDeviceStatus. -* @tc.number: WriteInputDeviceChangedSysEvents_001 -* @tc.desc : Test WriteInputDeviceChangedSysEvents interface. -*/ -HWTEST_F(AudioDeviceStatusUnitTest, WriteInputDeviceChangedSysEvents_001, TestSize.Level1) -{ - std::shared_ptr deviceDescriptor = std::make_shared(); - SourceOutput sourceOutput; - deviceDescriptor->deviceType_ = DEVICE_TYPE_USB_ARM_HEADSET; - deviceDescriptor->macAddress_ = "00:11:22:33:44:55"; - deviceDescriptor->deviceRole_ = DeviceRole::OUTPUT_DEVICE; - deviceDescriptor->networkId_ = "123456"; - deviceDescriptor->deviceName_ = "usb_headset"; - deviceDescriptor->deviceCategory_ = BT_UNWEAR_HEADPHONE; - sourceOutput.streamId = 1; - sourceOutput.streamType = STREAM_RING; - AudioDeviceStatus& audioDeviceStatus = AudioDeviceStatus::GetInstance(); - - audioDeviceStatus.WriteInputDeviceChangedSysEvents(deviceDescriptor, sourceOutput); - EXPECT_EQ(deviceDescriptor->deviceId_, 0); -} - -/** -* @tc.name : Test AudioDeviceStatus. -* @tc.number: RemoveDeviceFromGlobalOnly_001 -* @tc.desc : Test RemoveDeviceFromGlobalOnly interface. -*/ -HWTEST_F(AudioDeviceStatusUnitTest, RemoveDeviceFromGlobalOnly_001, TestSize.Level1) -{ - std::shared_ptr deviceDescriptor = std::make_shared(); - deviceDescriptor->deviceType_ = DEVICE_TYPE_USB_ARM_HEADSET; - deviceDescriptor->macAddress_ = "00:11:22:33:44:55"; - deviceDescriptor->deviceRole_ = DeviceRole::OUTPUT_DEVICE; - deviceDescriptor->networkId_ = "123456"; - deviceDescriptor->deviceName_ = "usb_headset"; - deviceDescriptor->deviceCategory_ = BT_UNWEAR_HEADPHONE; - AudioDeviceStatus& audioDeviceStatus = AudioDeviceStatus::GetInstance(); - - audioDeviceStatus.RemoveDeviceFromGlobalOnly(deviceDescriptor); - EXPECT_EQ(deviceDescriptor->deviceId_, 0); -} - -/** -* @tc.name : Test AudioDeviceStatus. -* @tc.number: AddDeviceBackToGlobalOnly_001 -* @tc.desc : Test AddDeviceBackToGlobalOnly interface. -*/ -HWTEST_F(AudioDeviceStatusUnitTest, AddDeviceBackToGlobalOnly_001, TestSize.Level1) -{ - std::shared_ptr deviceDescriptor = std::make_shared(); - deviceDescriptor->deviceType_ = DEVICE_TYPE_USB_ARM_HEADSET; - deviceDescriptor->macAddress_ = "00:11:22:33:44:55"; - deviceDescriptor->deviceRole_ = DeviceRole::OUTPUT_DEVICE; - deviceDescriptor->networkId_ = "123456"; - deviceDescriptor->deviceName_ = "usb_headset"; - deviceDescriptor->deviceCategory_ = BT_UNWEAR_HEADPHONE; - AudioDeviceStatus& audioDeviceStatus = AudioDeviceStatus::GetInstance(); - - audioDeviceStatus.AddDeviceBackToGlobalOnly(deviceDescriptor); - EXPECT_EQ(deviceDescriptor->deviceId_, 0); -} - -/** -* @tc.name : Test AudioDeviceStatus. -* @tc.number: GetDmDeviceType_001 -* @tc.desc : Test GetDmDeviceType interface. -*/ -HWTEST_F(AudioDeviceStatusUnitTest, GetDmDeviceType_001, TestSize.Level1) -{ - AudioDeviceStatus& audioDeviceStatus = AudioDeviceStatus::GetInstance(); - - uint16_t ret = audioDeviceStatus.GetDmDeviceType(); - EXPECT_EQ(ret, 0); -} - -/** -* @tc.name : Test AudioDeviceStatus. -* @tc.number: GetPaIndexByPortName_001 -* @tc.desc : Test GetPaIndexByPortName interface. -*/ -HWTEST_F(AudioDeviceStatusUnitTest, GetPaIndexByPortName_001, TestSize.Level1) -{ - string portName = PRIMARY_SPEAKER; - AudioIOHandle moduleId = 2; - AudioDeviceStatus& audioDeviceStatus = AudioDeviceStatus::GetInstance(); - - audioDeviceStatus.audioIOHandleMap_.AddIOHandleInfo(portName, moduleId); - uint32_t ret = audioDeviceStatus.GetPaIndexByPortName(portName); - EXPECT_NE(ret, moduleId); -} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index b489dda26c00179481a24557724893c78de0a1ae..458eb4ff83af2fdab402e0c3d0281480e9e6f238 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 0000000000000000000000000000000000000000..f13adbc9fa744d12c6d9b732c6e5f5fd3d6b41de --- /dev/null +++ b/services/audio_service/common/include/va_shared_buffer.h @@ -0,0 +1,111 @@ +/* + * 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" + + +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; + + // available only in single process + int64_t lastWrittenTime_ = 0; + + // calculated in advance + 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 0000000000000000000000000000000000000000..0970359b0b9d80254999e9702d2baf26003a6fed --- /dev/null +++ b/services/audio_service/common/include/va_shared_buffer_operator.h @@ -0,0 +1,81 @@ +/* + * 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 + +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; // writing or reading + + 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_; + + VASharedStatusInfo *statusInfo_ = nullptr; + + std::atomic *GetFutex(); + + size_t minReadSize_ = 1; + + void InitVASharedStatusInfo(); + + int32_t SizeCheck(size_t dataSize); + + 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._operator.cpp b/services/audio_service/common/src/va_shared_buffer._operator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7893e3179b36f6ffac8ac19beefbdfdfc3f59957 --- /dev/null +++ b/services/audio_service/common/src/va_shared_buffer._operator.cpp @@ -0,0 +1,269 @@ +/* + * 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_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() +{ + 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() +{ + 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() +{ + 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 writeSize doesn't reach the margin of buffer + 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/common/src/va_shared_buffer.cpp b/services/audio_service/common/src/va_shared_buffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..acdce173ee133b988d180663b9d7af9a19aed6b5 --- /dev/null +++ b/services/audio_service/common/src/va_shared_buffer.cpp @@ -0,0 +1,284 @@ +/* + * 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; //10M + 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) +{ + // ignore stdout, stdin and stderr. + 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_); //hdi fd may not support + 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() +{ + return dataMem_->GetSize(); +} + +sptr VASharedBuffer::GetDataAshmem() +{ + 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/idl/BUILD.gn b/services/audio_service/idl/BUILD.gn index e9f6eaab6e5db75d9b79ef42cbfb9eb12c47c24f..07b4156e6a45830c7c9f9d6e0fa1ea308a5a83a3 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 5a4e81ba44499bc14717e25a12d30deeb5f26a51..c9b7bb815c28562530854d1f6091179dae833721 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -893,24 +893,20 @@ 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 value_new = 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", value_new == "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; + value_new = "a2dpOffloadConfig=" + value; } else if (key == "mmi") { parmKey = AudioParamKey::MMI; } else if (key == "perf_info") { @@ -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, "", value_new); + } + + HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); + std::shared_ptr deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL); + if(deviceManager != nullptr) { + deviceManager->SetAudioParameter("primary", parmKey, "", value_new); + } else { + AUDIO_INFO_LOG("local device manager is nullptr"); + } return SUCCESS; } @@ -1108,6 +1116,41 @@ 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) { + AudioParamKey parmKey = AudioParamKey::NONE; + 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 mmiPre = "mmi_"; + if (key.size() > mmiPre.size()) { + if (key.substr(0, mmiPre.size()) == mmiPre) { + parmKey = AudioParamKey::MMI; + return source->GetAudioParameter(AudioParamKey(parmKey), + key.substr(mmiPre.size(), key.size() - mmiPre.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 a42ed0bc27142af26e11a1860104d58c0db21eba..198b685692d03b8b6a2ec56530333c6194bd2149 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,267 @@ 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; + + std::shared_ptr bufferInvalid = VASharedBuffer::CreateFromRemote(memInfoInvaild); + EXPECT_EQ(nullptr, bufferInvalid); + + VASharedMemInfo memInfo; + memInfo.dataFd_ = 1; + memInfo.dataMemCapacity_ = 1000; + + 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_ = 0; + 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_ = 0; + 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_ = 0; + 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_ = 0; + 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_ = 0; + 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_ = 0; + 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); +} + +/** +* @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_ = 0; + 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); +} + +/** +* @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_ = 0; + memInfo.statusFd_ = INVALID_FD; + EXPECT_EQ(buffer->Init(memInfo), SUCCESS); + + VASharedBufferOperator*chek_ = new VASharedBufferOperator(*buffer); + EXPECT_NE(chek_, nullptr); + + EXPECT_EQ(chek_->SizeCheck(512), SUCCESS); + EXPECT_EQ(chek_->SizeCheck(1024), SUCCESS); + EXPECT_EQ(chek_->SizeCheck(2048), -1); +} + } // namespace AudioStandard } // namespace OHOS \ No newline at end of file