From aa8f76af92cc0f706e0bd13508c7b6b596e0aac4 Mon Sep 17 00:00:00 2001 From: Lorena Torres-Huerta Date: Mon, 12 Dec 2022 18:17:10 +0000 Subject: [PATCH] audio: Provide code for parsing surround sound config from XML The main change is to convert the result of parsing from XSDC types to AIDL, and add a VTS test for IConfig.getSurroundSoundConfig. Extra changes: - add 'Unchecked' suffix to conversion functions that do not wrap the result into ConversionResult; - enable more compile-time checks for the default AIDL service, fix issues found. Bug: 205884982 Test: atest VtsHalAudioCoreTargetTest Change-Id: Icf578b8d28647e6355ed5328599c77d2ca1234f9 --- audio/aidl/common/include/Utils.h | 3 +- audio/aidl/default/AidlConversionXsdc.cpp | 56 ++++++++++++++++ audio/aidl/default/Android.bp | 22 ++++++ .../default/AudioPolicyConfigXmlConverter.cpp | 67 ++++++++++++++++++- audio/aidl/default/Config.cpp | 13 +++- .../aidl/default/EngineConfigXmlConverter.cpp | 45 ++++++------- .../include/core-impl/AidlConversionXsdc.h | 32 +++++++++ .../core-impl/AudioPolicyConfigXmlConverter.h | 5 +- .../default/include/core-impl/XmlConverter.h | 12 ++-- audio/aidl/default/main.cpp | 1 + .../vts/VtsHalAudioCoreConfigTargetTest.cpp | 55 ++++++++++++++- 11 files changed, 274 insertions(+), 37 deletions(-) create mode 100644 audio/aidl/default/AidlConversionXsdc.cpp create mode 100644 audio/aidl/default/include/core-impl/AidlConversionXsdc.h diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h index 652d63c01d..bd903d76ae 100644 --- a/audio/aidl/common/include/Utils.h +++ b/audio/aidl/common/include/Utils.h @@ -102,7 +102,8 @@ constexpr size_t getFrameSizeInBytes( constexpr bool isDefaultAudioFormat( const ::aidl::android::media::audio::common::AudioFormatDescription& desc) { return desc.type == ::aidl::android::media::audio::common::AudioFormatType::DEFAULT && - desc.pcm == ::aidl::android::media::audio::common::PcmType::DEFAULT; + desc.pcm == ::aidl::android::media::audio::common::PcmType::DEFAULT && + desc.encoding.empty(); } constexpr bool isTelephonyDeviceType( diff --git a/audio/aidl/default/AidlConversionXsdc.cpp b/audio/aidl/default/AidlConversionXsdc.cpp new file mode 100644 index 0000000000..c404d6728b --- /dev/null +++ b/audio/aidl/default/AidlConversionXsdc.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * 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. + */ + +#define LOG_TAG "AHAL_AidlXsdc" +#include +#include +#include +#include + +#include "core-impl/AidlConversionXsdc.h" + +using aidl::android::media::audio::common::AudioFormatDescription; + +namespace xsd = android::audio::policy::configuration; + +namespace aidl::android::hardware::audio::core::internal { + +ConversionResult xsdc2aidl_AudioFormatDescription(const std::string& xsdc) { + return legacy2aidl_audio_format_t_AudioFormatDescription(::android::formatFromString(xsdc)); +} + +ConversionResult xsdc2aidl_SurroundFormatFamily( + const ::xsd::SurroundFormats::Format& xsdc) { + SurroundSoundConfig::SurroundFormatFamily aidl; + aidl.primaryFormat = VALUE_OR_RETURN(xsdc2aidl_AudioFormatDescription(xsdc.getName())); + if (xsdc.hasSubformats()) { + aidl.subFormats = VALUE_OR_RETURN(convertContainer>( + xsdc.getSubformats(), xsdc2aidl_AudioFormatDescription)); + } + return aidl; +} + +ConversionResult xsdc2aidl_SurroundSoundConfig( + const ::xsd::SurroundSound& xsdc) { + SurroundSoundConfig aidl; + if (!xsdc.hasFormats() || !xsdc.getFirstFormats()->hasFormat()) return aidl; + aidl.formatFamilies = VALUE_OR_RETURN( + convertContainer>( + xsdc.getFirstFormats()->getFormat(), xsdc2aidl_SurroundFormatFamily)); + return aidl; +} + +} // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp index 31ed044514..bda0de2b6d 100644 --- a/audio/aidl/default/Android.bp +++ b/audio/aidl/default/Android.bp @@ -65,6 +65,7 @@ cc_library { ], export_include_dirs: ["include"], srcs: [ + "AidlConversionXsdc.cpp", "AudioPolicyConfigXmlConverter.cpp", "Bluetooth.cpp", "Config.cpp", @@ -92,11 +93,20 @@ cc_library { "audio_policy_configuration_aidl_default", "audio_policy_engine_configuration_aidl_default", ], + shared_libs: [ + "libaudio_aidl_conversion_common_ndk", + "libmedia_helper", + "libstagefright_foundation", + ], + export_shared_lib_headers: [ + "libaudio_aidl_conversion_common_ndk", + ], cflags: [ "-Wall", "-Wextra", "-Werror", "-Wthread-safety", + "-DBACKEND_NDK", ], } @@ -114,7 +124,19 @@ cc_binary { static_libs: [ "libaudioserviceexampleimpl", ], + shared_libs: [ + "libaudio_aidl_conversion_common_ndk", + "libmedia_helper", + "libstagefright_foundation", + ], srcs: ["main.cpp"], + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + "-Wthread-safety", + "-DBACKEND_NDK", + ], } cc_defaults { diff --git a/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp b/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp index 6290912774..2848d719c7 100644 --- a/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp +++ b/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp @@ -21,11 +21,17 @@ #include #include +#define LOG_TAG "AHAL_ApmXmlConverter" +#include + #include +#include #include +#include "core-impl/AidlConversionXsdc.h" #include "core-impl/AudioPolicyConfigXmlConverter.h" +using aidl::android::media::audio::common::AudioFormatDescription; using aidl::android::media::audio::common::AudioHalEngineConfig; using aidl::android::media::audio::common::AudioHalVolumeCurve; using aidl::android::media::audio::common::AudioHalVolumeGroup; @@ -68,13 +74,13 @@ AudioHalVolumeCurve AudioPolicyConfigXmlConverter::convertVolumeCurveToAidl( getXsdcConfig()->getVolumes()); } aidlVolumeCurve.curvePoints = - convertCollectionToAidl( + convertCollectionToAidlUnchecked( mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(), std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this, std::placeholders::_1)); } else { aidlVolumeCurve.curvePoints = - convertCollectionToAidl( + convertCollectionToAidlUnchecked( xsdcVolumeCurve.getPoint(), std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this, std::placeholders::_1)); @@ -87,6 +93,22 @@ void AudioPolicyConfigXmlConverter::mapStreamToVolumeCurve(const xsd::Volume& xs convertVolumeCurveToAidl(xsdcVolumeCurve)); } +const SurroundSoundConfig& AudioPolicyConfigXmlConverter::getSurroundSoundConfig() { + static const SurroundSoundConfig aidlSurroundSoundConfig = [this]() { + if (auto xsdcConfig = getXsdcConfig(); xsdcConfig && xsdcConfig->hasSurroundSound()) { + auto configConv = xsdc2aidl_SurroundSoundConfig(*xsdcConfig->getFirstSurroundSound()); + if (configConv.ok()) { + return configConv.value(); + } + LOG(ERROR) << "There was an error converting surround formats to AIDL: " + << configConv.error(); + } + LOG(WARNING) << "Audio policy config does not have section, using default"; + return getDefaultSurroundSoundConfig(); + }(); + return aidlSurroundSoundConfig; +} + const AudioHalEngineConfig& AudioPolicyConfigXmlConverter::getAidlEngineConfig() { if (mAidlEngineConfig.volumeGroups.empty() && getXsdcConfig() && getXsdcConfig()->hasVolumes()) { @@ -95,6 +117,47 @@ const AudioHalEngineConfig& AudioPolicyConfigXmlConverter::getAidlEngineConfig() return mAidlEngineConfig; } +// static +const SurroundSoundConfig& AudioPolicyConfigXmlConverter::getDefaultSurroundSoundConfig() { + // Provide a config similar to the one used by the framework by default + // (see AudioPolicyConfig::setDefaultSurroundFormats). +#define ENCODED_FORMAT(format) \ + AudioFormatDescription { \ + .encoding = ::android::format \ + } +#define SIMPLE_FORMAT(format) \ + SurroundSoundConfig::SurroundFormatFamily { \ + .primaryFormat = ENCODED_FORMAT(format) \ + } + + static const SurroundSoundConfig defaultConfig = { + .formatFamilies = { + SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_AC3), + SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_EAC3), + SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS), + SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_HD), + SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_HD_MA), + SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_UHD), + SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2), + SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DOLBY_TRUEHD), + SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_EAC3_JOC), + SurroundSoundConfig::SurroundFormatFamily{ + .primaryFormat = ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_LC), + .subFormats = + { + ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_HE_V1), + ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_HE_V2), + ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_ELD), + ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_XHE), + }}, + SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_AC4), + }}; +#undef SIMPLE_FORMAT +#undef ENCODED_FORMAT + + return defaultConfig; +} + void AudioPolicyConfigXmlConverter::mapStreamsToVolumeCurves() { if (getXsdcConfig()->hasVolumes()) { for (const xsd::Volumes& xsdcWrapperType : getXsdcConfig()->getVolumes()) { diff --git a/audio/aidl/default/Config.cpp b/audio/aidl/default/Config.cpp index e87af071a2..d1023da6f5 100644 --- a/audio/aidl/default/Config.cpp +++ b/audio/aidl/default/Config.cpp @@ -27,9 +27,16 @@ using aidl::android::media::audio::common::AudioHalEngineConfig; namespace aidl::android::hardware::audio::core { ndk::ScopedAStatus Config::getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) { - SurroundSoundConfig surroundSoundConfig; - // TODO: parse from XML; for now, use empty config as default - *_aidl_return = std::move(surroundSoundConfig); + static const SurroundSoundConfig surroundSoundConfig = [this]() { + SurroundSoundConfig surroundCfg; + if (mAudioPolicyConverter.getStatus() == ::android::OK) { + surroundCfg = mAudioPolicyConverter.getSurroundSoundConfig(); + } else { + LOG(WARNING) << __func__ << mAudioPolicyConverter.getError(); + } + return surroundCfg; + }(); + *_aidl_return = surroundSoundConfig; LOG(DEBUG) << __func__ << ": returning " << _aidl_return->toString(); return ndk::ScopedAStatus::ok(); } diff --git a/audio/aidl/default/EngineConfigXmlConverter.cpp b/audio/aidl/default/EngineConfigXmlConverter.cpp index 5f17d7125d..96b555c640 100644 --- a/audio/aidl/default/EngineConfigXmlConverter.cpp +++ b/audio/aidl/default/EngineConfigXmlConverter.cpp @@ -140,7 +140,7 @@ AudioHalAttributesGroup EngineConfigXmlConverter::convertAttributesGroupToAidl( aidlAttributesGroup.volumeGroupName = xsdcAttributesGroup.getVolumeGroup(); if (xsdcAttributesGroup.hasAttributes_optional()) { aidlAttributesGroup.attributes = - convertCollectionToAidl( + convertCollectionToAidlUnchecked( xsdcAttributesGroup.getAttributes_optional(), std::bind(&EngineConfigXmlConverter::convertAudioAttributesToAidl, this, std::placeholders::_1)); @@ -172,7 +172,7 @@ AudioHalProductStrategy EngineConfigXmlConverter::convertProductStrategyToAidl( if (xsdcProductStrategy.hasAttributesGroup()) { aidlProductStrategy.attributesGroups = - convertCollectionToAidl( + convertCollectionToAidlUnchecked( xsdcProductStrategy.getAttributesGroup(), std::bind(&EngineConfigXmlConverter::convertAttributesGroupToAidl, this, std::placeholders::_1)); @@ -204,13 +204,13 @@ AudioHalVolumeCurve EngineConfigXmlConverter::convertVolumeCurveToAidl( getXsdcConfig()->getVolumes()); } aidlVolumeCurve.curvePoints = - convertCollectionToAidl( + convertCollectionToAidlUnchecked( mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(), std::bind(&EngineConfigXmlConverter::convertCurvePointToAidl, this, std::placeholders::_1)); } else { aidlVolumeCurve.curvePoints = - convertCollectionToAidl( + convertCollectionToAidlUnchecked( xsdcVolumeCurve.getPoint(), std::bind(&EngineConfigXmlConverter::convertCurvePointToAidl, this, std::placeholders::_1)); @@ -224,10 +224,11 @@ AudioHalVolumeGroup EngineConfigXmlConverter::convertVolumeGroupToAidl( aidlVolumeGroup.name = xsdcVolumeGroup.getName(); aidlVolumeGroup.minIndex = xsdcVolumeGroup.getIndexMin(); aidlVolumeGroup.maxIndex = xsdcVolumeGroup.getIndexMax(); - aidlVolumeGroup.volumeCurves = convertCollectionToAidl( - xsdcVolumeGroup.getVolume(), - std::bind(&EngineConfigXmlConverter::convertVolumeCurveToAidl, this, - std::placeholders::_1)); + aidlVolumeGroup.volumeCurves = + convertCollectionToAidlUnchecked( + xsdcVolumeGroup.getVolume(), + std::bind(&EngineConfigXmlConverter::convertVolumeCurveToAidl, this, + std::placeholders::_1)); return aidlVolumeGroup; } @@ -251,7 +252,7 @@ AudioHalCapCriterionType EngineConfigXmlConverter::convertCapCriterionTypeToAidl aidlCapCriterionType.name = xsdcCriterionType.getName(); aidlCapCriterionType.isInclusive = !(static_cast(xsdcCriterionType.getType())); aidlCapCriterionType.values = - convertWrappedCollectionToAidl( + convertWrappedCollectionToAidlUnchecked( xsdcCriterionType.getValues(), &xsd::ValuesType::getValue, std::bind(&EngineConfigXmlConverter::convertCriterionTypeValueToAidl, this, std::placeholders::_1)); @@ -266,9 +267,9 @@ void EngineConfigXmlConverter::init() { initProductStrategyMap(); if (getXsdcConfig()->hasProductStrategies()) { mAidlEngineConfig.productStrategies = - convertWrappedCollectionToAidl( + convertWrappedCollectionToAidlUnchecked( getXsdcConfig()->getProductStrategies(), &xsd::ProductStrategies::getProductStrategy, std::bind(&EngineConfigXmlConverter::convertProductStrategyToAidl, this, @@ -278,7 +279,7 @@ void EngineConfigXmlConverter::init() { } } if (getXsdcConfig()->hasVolumeGroups()) { - mAidlEngineConfig.volumeGroups = convertWrappedCollectionToAidl< + mAidlEngineConfig.volumeGroups = convertWrappedCollectionToAidlUnchecked< xsd::VolumeGroupsType, xsd::VolumeGroupsType::VolumeGroup, AudioHalVolumeGroup>( getXsdcConfig()->getVolumeGroups(), &xsd::VolumeGroupsType::getVolumeGroup, std::bind(&EngineConfigXmlConverter::convertVolumeGroupToAidl, this, @@ -287,19 +288,17 @@ void EngineConfigXmlConverter::init() { if (getXsdcConfig()->hasCriteria() && getXsdcConfig()->hasCriterion_types()) { AudioHalEngineConfig::CapSpecificConfig capSpecificConfig; capSpecificConfig.criteria = - convertWrappedCollectionToAidl( + convertWrappedCollectionToAidlUnchecked( getXsdcConfig()->getCriteria(), &xsd::CriteriaType::getCriterion, std::bind(&EngineConfigXmlConverter::convertCapCriterionToAidl, this, std::placeholders::_1)); - capSpecificConfig.criterionTypes = - convertWrappedCollectionToAidl( - getXsdcConfig()->getCriterion_types(), - &xsd::CriterionTypesType::getCriterion_type, - std::bind(&EngineConfigXmlConverter::convertCapCriterionTypeToAidl, this, - std::placeholders::_1)); + capSpecificConfig.criterionTypes = convertWrappedCollectionToAidlUnchecked< + xsd::CriterionTypesType, xsd::CriterionTypeType, AudioHalCapCriterionType>( + getXsdcConfig()->getCriterion_types(), &xsd::CriterionTypesType::getCriterion_type, + std::bind(&EngineConfigXmlConverter::convertCapCriterionTypeToAidl, this, + std::placeholders::_1)); mAidlEngineConfig.capSpecificConfig = capSpecificConfig; } } -} // namespace aidl::android::hardware::audio::core::internal \ No newline at end of file +} // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/include/core-impl/AidlConversionXsdc.h b/audio/aidl/default/include/core-impl/AidlConversionXsdc.h new file mode 100644 index 0000000000..c9aefc7cd8 --- /dev/null +++ b/audio/aidl/default/include/core-impl/AidlConversionXsdc.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +namespace aidl::android::hardware::audio::core::internal { + +ConversionResult<::aidl::android::media::audio::common::AudioFormatDescription> +xsdc2aidl_AudioFormatDescription(const std::string& xsdc); + +ConversionResult xsdc2aidl_SurroundSoundConfig( + const ::android::audio::policy::configuration::SurroundSound& xsdc); + +} // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h b/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h index 47918f0839..94501a81ba 100644 --- a/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h +++ b/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h @@ -18,6 +18,7 @@ #include +#include #include #include #include @@ -35,8 +36,11 @@ class AudioPolicyConfigXmlConverter { ::android::status_t getStatus() const { return mConverter.getStatus(); } const ::aidl::android::media::audio::common::AudioHalEngineConfig& getAidlEngineConfig(); + const SurroundSoundConfig& getSurroundSoundConfig(); private: + static const SurroundSoundConfig& getDefaultSurroundSoundConfig(); + const std::optional<::android::audio::policy::configuration::AudioPolicyConfiguration>& getXsdcConfig() const { return mConverter.getXsdcConfig(); @@ -48,7 +52,6 @@ class AudioPolicyConfigXmlConverter { void parseVolumes(); ::aidl::android::media::audio::common::AudioHalVolumeCurve::CurvePoint convertCurvePointToAidl( const std::string& xsdcCurvePoint); - ::aidl::android::media::audio::common::AudioHalVolumeCurve convertVolumeCurveToAidl( const ::android::audio::policy::configuration::Volume& xsdcVolumeCurve); diff --git a/audio/aidl/default/include/core-impl/XmlConverter.h b/audio/aidl/default/include/core-impl/XmlConverter.h index ec23edb70a..a68a6fdde9 100644 --- a/audio/aidl/default/include/core-impl/XmlConverter.h +++ b/audio/aidl/default/include/core-impl/XmlConverter.h @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -78,7 +79,7 @@ class XmlConverter { * */ template -static std::vector convertWrappedCollectionToAidl( +std::vector convertWrappedCollectionToAidlUnchecked( const std::vector& xsdcWrapperTypeVec, std::function&(const W&)> getInnerTypeVec, std::function convertToAidl) { @@ -100,12 +101,12 @@ static std::vector convertWrappedCollectionToAidl( } template -static std::vector convertCollectionToAidl(const std::vector& xsdcTypeVec, - std::function convertToAidl) { +std::vector convertCollectionToAidlUnchecked(const std::vector& xsdcTypeVec, + std::function itemConversion) { std::vector resultAidlTypeVec; resultAidlTypeVec.reserve(xsdcTypeVec.size()); std::transform(xsdcTypeVec.begin(), xsdcTypeVec.end(), std::back_inserter(resultAidlTypeVec), - convertToAidl); + itemConversion); return resultAidlTypeVec; } @@ -121,8 +122,7 @@ static std::vector convertCollectionToAidl(const std::vector& xsdcTypeVec, * */ template -static std::unordered_map generateReferenceMap( - const std::vector& xsdcWrapperTypeVec) { +std::unordered_map generateReferenceMap(const std::vector& xsdcWrapperTypeVec) { std::unordered_map resultMap; if (!xsdcWrapperTypeVec.empty()) { /* diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp index af71aa872e..12c0c4b53e 100644 --- a/audio/aidl/default/main.cpp +++ b/audio/aidl/default/main.cpp @@ -64,6 +64,7 @@ int main() { auto modules = {createModule(Module::Type::DEFAULT, "default"), createModule(Module::Type::R_SUBMIX, "r_submix"), createModule(Module::Type::USB, "usb")}; + (void)modules; ABinderProcess_joinThreadPool(); return EXIT_FAILURE; // should not reach diff --git a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp index e5e06ebce2..f82e8e57c6 100644 --- a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp +++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp @@ -20,21 +20,27 @@ #include #include +#define LOG_TAG "VtsHalAudioCore.Config" + +#include #include #include #include #include #include -#define LOG_TAG "VtsHalAudioCore.Config" #include #include "AudioHalBinderServiceUtil.h" #include "TestUtils.h" using namespace android; +using aidl::android::hardware::audio::common::isDefaultAudioFormat; using aidl::android::hardware::audio::core::IConfig; +using aidl::android::hardware::audio::core::SurroundSoundConfig; using aidl::android::media::audio::common::AudioAttributes; using aidl::android::media::audio::common::AudioFlag; +using aidl::android::media::audio::common::AudioFormatDescription; +using aidl::android::media::audio::common::AudioFormatType; using aidl::android::media::audio::common::AudioHalAttributesGroup; using aidl::android::media::audio::common::AudioHalCapCriterion; using aidl::android::media::audio::common::AudioHalCapCriterionType; @@ -46,6 +52,7 @@ using aidl::android::media::audio::common::AudioProductStrategyType; using aidl::android::media::audio::common::AudioSource; using aidl::android::media::audio::common::AudioStreamType; using aidl::android::media::audio::common::AudioUsage; +using aidl::android::media::audio::common::PcmType; class AudioCoreConfig : public testing::TestWithParam { public: @@ -58,6 +65,7 @@ class AudioCoreConfig : public testing::TestWithParam { void RestartService() { ASSERT_NE(mConfig, nullptr); mEngineConfig.reset(); + mSurroundSoundConfig.reset(); mConfig = IConfig::fromBinder(mBinderUtil.restartService()); ASSERT_NE(mConfig, nullptr); } @@ -70,6 +78,14 @@ class AudioCoreConfig : public testing::TestWithParam { } } + void SetUpSurroundSoundConfig() { + if (mSurroundSoundConfig == nullptr) { + auto tempConfig = std::make_unique(); + ASSERT_IS_OK(mConfig->getSurroundSoundConfig(tempConfig.get())); + mSurroundSoundConfig = std::move(tempConfig); + } + } + static bool IsProductStrategyTypeReservedForSystemUse(const AudioProductStrategyType& pst) { switch (pst) { case AudioProductStrategyType::SYS_RESERVED_NONE: @@ -325,9 +341,41 @@ class AudioCoreConfig : public testing::TestWithParam { } } + void ValidateAudioFormatDescription(const AudioFormatDescription& format) { + EXPECT_NE(AudioFormatType::SYS_RESERVED_INVALID, format.type); + if (format.type == AudioFormatType::PCM) { + EXPECT_NE(PcmType::DEFAULT, format.pcm); + EXPECT_TRUE(format.encoding.empty()) << format.encoding; + } else { + EXPECT_FALSE(format.encoding.empty()); + } + } + + /** + * Verify that the surround sound configuration is not empty. + * Verify each of the formatFamilies has a non-empty primaryFormat. + * Verify that each format only appears once. + */ + void ValidateSurroundSoundConfig() { + EXPECT_FALSE(mSurroundSoundConfig->formatFamilies.empty()); + std::set formatSet; + for (const SurroundSoundConfig::SurroundFormatFamily& family : + mSurroundSoundConfig->formatFamilies) { + EXPECT_NO_FATAL_FAILURE(ValidateAudioFormatDescription(family.primaryFormat)); + EXPECT_FALSE(isDefaultAudioFormat(family.primaryFormat)); + EXPECT_TRUE(formatSet.insert(family.primaryFormat).second); + for (const AudioFormatDescription& subformat : family.subFormats) { + EXPECT_NO_FATAL_FAILURE(ValidateAudioFormatDescription(subformat)); + EXPECT_FALSE(isDefaultAudioFormat(subformat)); + EXPECT_TRUE(formatSet.insert(subformat).second); + } + } + } + private: std::shared_ptr mConfig; std::unique_ptr mEngineConfig; + std::unique_ptr mSurroundSoundConfig; AudioHalBinderServiceUtil mBinderUtil; }; @@ -344,6 +392,11 @@ TEST_P(AudioCoreConfig, GetEngineConfigIsValid) { EXPECT_NO_FATAL_FAILURE(ValidateAudioHalEngineConfig()); } +TEST_P(AudioCoreConfig, GetSurroundSoundConfigIsValid) { + ASSERT_NO_FATAL_FAILURE(SetUpSurroundSoundConfig()); + EXPECT_NO_FATAL_FAILURE(ValidateSurroundSoundConfig()); +} + INSTANTIATE_TEST_SUITE_P(AudioCoreConfigTest, AudioCoreConfig, testing::ValuesIn(android::getAidlHalInstanceNames(IConfig::descriptor)), android::PrintInstanceNameToString);