diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp index af12e75e8c..112d3e28fc 100644 --- a/audio/aidl/default/Android.bp +++ b/audio/aidl/default/Android.bp @@ -12,6 +12,7 @@ cc_defaults { vendor: true, shared_libs: [ "libalsautilsv2", + "libaudio_aidl_conversion_common_ndk", "libaudioaidlcommon", "libaudioutils", "libbase", @@ -19,6 +20,8 @@ cc_defaults { "libcutils", "libfmq", "libnbaio_mono", + "liblog", + "libmedia_helper", "libstagefright_foundation", "libtinyalsav2", "libutils", @@ -31,6 +34,9 @@ cc_defaults { "libaudioaidl_headers", "libxsdc-utils", ], + cflags: [ + "-DBACKEND_NDK", + ], } cc_library { @@ -87,6 +93,7 @@ cc_library { "Stream.cpp", "StreamSwitcher.cpp", "Telephony.cpp", + "XsdcConversion.cpp", "alsa/Mixer.cpp", "alsa/ModuleAlsa.cpp", "alsa/StreamAlsa.cpp", @@ -187,6 +194,7 @@ cc_test { "libbase", "libbinder_ndk", "libcutils", + "libfmq", "libmedia_helper", "libstagefright_foundation", "libutils", @@ -199,9 +207,11 @@ cc_test { ], generated_sources: [ "audio_policy_configuration_aidl_default", + "audio_policy_engine_configuration_aidl_default", ], generated_headers: [ "audio_policy_configuration_aidl_default", + "audio_policy_engine_configuration_aidl_default", ], srcs: [ "AudioPolicyConfigXmlConverter.cpp", diff --git a/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp b/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp index 7452c8ec7a..5d06cb607c 100644 --- a/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp +++ b/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp @@ -30,6 +30,7 @@ #include "core-impl/AidlConversionXsdc.h" #include "core-impl/AudioPolicyConfigXmlConverter.h" +#include "core-impl/XsdcConversion.h" using aidl::android::media::audio::common::AudioFormatDescription; using aidl::android::media::audio::common::AudioHalEngineConfig; @@ -37,60 +38,39 @@ using aidl::android::media::audio::common::AudioHalVolumeCurve; using aidl::android::media::audio::common::AudioHalVolumeGroup; using aidl::android::media::audio::common::AudioStreamType; -namespace xsd = android::audio::policy::configuration; +namespace ap_xsd = android::audio::policy::configuration; namespace aidl::android::hardware::audio::core::internal { static const int kDefaultVolumeIndexMin = 0; static const int kDefaultVolumeIndexMax = 100; static const int KVolumeIndexDeferredToAudioService = -1; -/** - * Valid curve points take the form ",", where the index - * must be in the range [0,100]. kInvalidCurvePointIndex is used to indicate - * that a point was formatted incorrectly (e.g. if a vendor accidentally typed a - * '.' instead of a ',' in their XML) -- using such a curve point will result in - * failed VTS tests. - */ -static const int8_t kInvalidCurvePointIndex = -1; -AudioHalVolumeCurve::CurvePoint AudioPolicyConfigXmlConverter::convertCurvePointToAidl( - const std::string& xsdcCurvePoint) { - AudioHalVolumeCurve::CurvePoint aidlCurvePoint{}; - if (sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index, - &aidlCurvePoint.attenuationMb) != 2) { - aidlCurvePoint.index = kInvalidCurvePointIndex; - } - return aidlCurvePoint; -} - -AudioHalVolumeCurve AudioPolicyConfigXmlConverter::convertVolumeCurveToAidl( - const xsd::Volume& xsdcVolumeCurve) { +ConversionResult AudioPolicyConfigXmlConverter::convertVolumeCurveToAidl( + const ap_xsd::Volume& xsdcVolumeCurve) { AudioHalVolumeCurve aidlVolumeCurve; aidlVolumeCurve.deviceCategory = static_cast(xsdcVolumeCurve.getDeviceCategory()); if (xsdcVolumeCurve.hasRef()) { if (mVolumesReferenceMap.empty()) { - mVolumesReferenceMap = generateReferenceMap( + mVolumesReferenceMap = generateReferenceMap( getXsdcConfig()->getVolumes()); } - aidlVolumeCurve.curvePoints = - convertCollectionToAidlUnchecked( + aidlVolumeCurve.curvePoints = VALUE_OR_FATAL( + (convertCollectionToAidl( mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(), - std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this, - std::placeholders::_1)); + &convertCurvePointToAidl))); } else { - aidlVolumeCurve.curvePoints = - convertCollectionToAidlUnchecked( - xsdcVolumeCurve.getPoint(), - std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this, - std::placeholders::_1)); + aidlVolumeCurve.curvePoints = VALUE_OR_FATAL( + (convertCollectionToAidl( + xsdcVolumeCurve.getPoint(), &convertCurvePointToAidl))); } return aidlVolumeCurve; } -void AudioPolicyConfigXmlConverter::mapStreamToVolumeCurve(const xsd::Volume& xsdcVolumeCurve) { +void AudioPolicyConfigXmlConverter::mapStreamToVolumeCurve(const ap_xsd::Volume& xsdcVolumeCurve) { mStreamToVolumeCurvesMap[xsdcVolumeCurve.getStream()].push_back( - convertVolumeCurveToAidl(xsdcVolumeCurve)); + VALUE_OR_FATAL(convertVolumeCurveToAidl(xsdcVolumeCurve))); } const SurroundSoundConfig& AudioPolicyConfigXmlConverter::getSurroundSoundConfig() { @@ -109,6 +89,11 @@ const SurroundSoundConfig& AudioPolicyConfigXmlConverter::getSurroundSoundConfig return aidlSurroundSoundConfig; } +std::unique_ptr +AudioPolicyConfigXmlConverter::releaseModuleConfigs() { + return std::move(mModuleConfigurations); +} + const AudioHalEngineConfig& AudioPolicyConfigXmlConverter::getAidlEngineConfig() { if (mAidlEngineConfig.volumeGroups.empty() && getXsdcConfig() && getXsdcConfig()->hasVolumes()) { @@ -160,8 +145,8 @@ const SurroundSoundConfig& AudioPolicyConfigXmlConverter::getDefaultSurroundSoun void AudioPolicyConfigXmlConverter::mapStreamsToVolumeCurves() { if (getXsdcConfig()->hasVolumes()) { - for (const xsd::Volumes& xsdcWrapperType : getXsdcConfig()->getVolumes()) { - for (const xsd::Volume& xsdcVolume : xsdcWrapperType.getVolume()) { + for (const ap_xsd::Volumes& xsdcWrapperType : getXsdcConfig()->getVolumes()) { + for (const ap_xsd::Volume& xsdcVolume : xsdcWrapperType.getVolume()) { mapStreamToVolumeCurve(xsdcVolume); } } @@ -171,7 +156,7 @@ void AudioPolicyConfigXmlConverter::mapStreamsToVolumeCurves() { void AudioPolicyConfigXmlConverter::addVolumeGroupstoEngineConfig() { for (const auto& [xsdcStream, volumeCurves] : mStreamToVolumeCurvesMap) { AudioHalVolumeGroup volumeGroup; - volumeGroup.name = xsd::toString(xsdcStream); + volumeGroup.name = ap_xsd::toString(xsdcStream); if (static_cast(xsdcStream) >= AUDIO_STREAM_PUBLIC_CNT) { volumeGroup.minIndex = kDefaultVolumeIndexMin; volumeGroup.maxIndex = kDefaultVolumeIndexMax; @@ -190,4 +175,18 @@ void AudioPolicyConfigXmlConverter::parseVolumes() { addVolumeGroupstoEngineConfig(); } } + +void AudioPolicyConfigXmlConverter::init() { + if (!getXsdcConfig()->hasModules()) return; + for (const ap_xsd::Modules& xsdcModulesType : getXsdcConfig()->getModules()) { + if (!xsdcModulesType.has_module()) continue; + for (const ap_xsd::Modules::Module& xsdcModule : xsdcModulesType.get_module()) { + // 'primary' in the XML schema used by HIDL is equivalent to 'default' module. + const std::string name = + xsdcModule.getName() != "primary" ? xsdcModule.getName() : "default"; + mModuleConfigurations->emplace_back( + name, VALUE_OR_FATAL(convertModuleConfigToAidl(xsdcModule))); + } + } +} } // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp index 3c3dadb112..a20bb54ea8 100644 --- a/audio/aidl/default/Configuration.cpp +++ b/audio/aidl/default/Configuration.cpp @@ -43,6 +43,7 @@ using aidl::android::media::audio::common::AudioProfile; using aidl::android::media::audio::common::Int; using aidl::android::media::audio::common::MicrophoneInfo; using aidl::android::media::audio::common::PcmType; +using Configuration = aidl::android::hardware::audio::core::Module::Configuration; namespace aidl::android::hardware::audio::core::internal { @@ -677,4 +678,19 @@ std::unique_ptr getBluetoothConfiguration() { return std::make_unique(configuration); } +std::unique_ptr getConfiguration(Module::Type moduleType) { + switch (moduleType) { + case Module::Type::DEFAULT: + return getPrimaryConfiguration(); + case Module::Type::R_SUBMIX: + return getRSubmixConfiguration(); + case Module::Type::STUB: + return getStubConfiguration(); + case Module::Type::USB: + return getUsbConfiguration(); + case Module::Type::BLUETOOTH: + return getBluetoothConfiguration(); + } +} + } // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/EngineConfigXmlConverter.cpp b/audio/aidl/default/EngineConfigXmlConverter.cpp index 96b555c640..631cdce1a0 100644 --- a/audio/aidl/default/EngineConfigXmlConverter.cpp +++ b/audio/aidl/default/EngineConfigXmlConverter.cpp @@ -20,11 +20,14 @@ #include #include +#define LOG_TAG "AHAL_Config" #include #include #include +#include #include "core-impl/EngineConfigXmlConverter.h" +#include "core-impl/XsdcConversion.h" using aidl::android::media::audio::common::AudioAttributes; using aidl::android::media::audio::common::AudioContentType; @@ -40,20 +43,13 @@ 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 ::android::BAD_VALUE; +using ::android::base::unexpected; -namespace xsd = android::audio::policy::engine::configuration; +namespace eng_xsd = android::audio::policy::engine::configuration; namespace aidl::android::hardware::audio::core::internal { -/** - * Valid curve points take the form ",", where the index - * must be in the range [0,100]. kInvalidCurvePointIndex is used to indicate - * that a point was formatted incorrectly (e.g. if a vendor accidentally typed a - * '.' instead of a ',' in their XML)-- using such a curve point will result in - * failed VTS tests. - */ -static const int8_t kInvalidCurvePointIndex = -1; - void EngineConfigXmlConverter::initProductStrategyMap() { #define STRATEGY_ENTRY(name) {"STRATEGY_" #name, static_cast(AudioProductStrategyType::name)} @@ -68,7 +64,7 @@ void EngineConfigXmlConverter::initProductStrategyMap() { #undef STRATEGY_ENTRY } -int EngineConfigXmlConverter::convertProductStrategyNameToAidl( +ConversionResult EngineConfigXmlConverter::convertProductStrategyNameToAidl( const std::string& xsdcProductStrategyName) { const auto [it, success] = mProductStrategyMap.insert( std::make_pair(xsdcProductStrategyName, mNextVendorStrategy)); @@ -85,12 +81,12 @@ bool isDefaultAudioAttributes(const AudioAttributes& attributes) { (attributes.tags.empty())); } -AudioAttributes EngineConfigXmlConverter::convertAudioAttributesToAidl( - const xsd::AttributesType& xsdcAudioAttributes) { +ConversionResult EngineConfigXmlConverter::convertAudioAttributesToAidl( + const eng_xsd::AttributesType& xsdcAudioAttributes) { if (xsdcAudioAttributes.hasAttributesRef()) { if (mAttributesReferenceMap.empty()) { mAttributesReferenceMap = - generateReferenceMap( + generateReferenceMap( getXsdcConfig()->getAttributesRef()); } return convertAudioAttributesToAidl( @@ -111,16 +107,16 @@ AudioAttributes EngineConfigXmlConverter::convertAudioAttributesToAidl( static_cast(xsdcAudioAttributes.getFirstSource()->getValue()); } if (xsdcAudioAttributes.hasFlags()) { - std::vector xsdcFlagTypeVec = + std::vector xsdcFlagTypeVec = xsdcAudioAttributes.getFirstFlags()->getValue(); - for (const xsd::FlagType& xsdcFlagType : xsdcFlagTypeVec) { - if (xsdcFlagType != xsd::FlagType::AUDIO_FLAG_NONE) { + for (const eng_xsd::FlagType& xsdcFlagType : xsdcFlagTypeVec) { + if (xsdcFlagType != eng_xsd::FlagType::AUDIO_FLAG_NONE) { aidlAudioAttributes.flags |= 1 << (static_cast(xsdcFlagType) - 1); } } } if (xsdcAudioAttributes.hasBundle()) { - const xsd::BundleType* xsdcBundle = xsdcAudioAttributes.getFirstBundle(); + const eng_xsd::BundleType* xsdcBundle = xsdcAudioAttributes.getFirstBundle(); aidlAudioAttributes.tags[0] = xsdcBundle->getKey() + "=" + xsdcBundle->getValue(); } if (isDefaultAudioAttributes(aidlAudioAttributes)) { @@ -129,53 +125,54 @@ AudioAttributes EngineConfigXmlConverter::convertAudioAttributesToAidl( return aidlAudioAttributes; } -AudioHalAttributesGroup EngineConfigXmlConverter::convertAttributesGroupToAidl( - const xsd::AttributesGroup& xsdcAttributesGroup) { +ConversionResult EngineConfigXmlConverter::convertAttributesGroupToAidl( + const eng_xsd::AttributesGroup& xsdcAttributesGroup) { AudioHalAttributesGroup aidlAttributesGroup; static const int kStreamTypeEnumOffset = - static_cast(xsd::Stream::AUDIO_STREAM_VOICE_CALL) - + static_cast(eng_xsd::Stream::AUDIO_STREAM_VOICE_CALL) - static_cast(AudioStreamType::VOICE_CALL); aidlAttributesGroup.streamType = static_cast( static_cast(xsdcAttributesGroup.getStreamType()) - kStreamTypeEnumOffset); aidlAttributesGroup.volumeGroupName = xsdcAttributesGroup.getVolumeGroup(); if (xsdcAttributesGroup.hasAttributes_optional()) { aidlAttributesGroup.attributes = - convertCollectionToAidlUnchecked( + VALUE_OR_FATAL((convertCollectionToAidl( xsdcAttributesGroup.getAttributes_optional(), std::bind(&EngineConfigXmlConverter::convertAudioAttributesToAidl, this, - std::placeholders::_1)); + std::placeholders::_1)))); } else if (xsdcAttributesGroup.hasContentType_optional() || xsdcAttributesGroup.hasUsage_optional() || xsdcAttributesGroup.hasSource_optional() || xsdcAttributesGroup.hasFlags_optional() || xsdcAttributesGroup.hasBundle_optional()) { - aidlAttributesGroup.attributes.push_back(convertAudioAttributesToAidl(xsd::AttributesType( - xsdcAttributesGroup.getContentType_optional(), - xsdcAttributesGroup.getUsage_optional(), xsdcAttributesGroup.getSource_optional(), - xsdcAttributesGroup.getFlags_optional(), xsdcAttributesGroup.getBundle_optional(), - std::nullopt))); + aidlAttributesGroup.attributes.push_back(VALUE_OR_FATAL(convertAudioAttributesToAidl( + eng_xsd::AttributesType(xsdcAttributesGroup.getContentType_optional(), + xsdcAttributesGroup.getUsage_optional(), + xsdcAttributesGroup.getSource_optional(), + xsdcAttributesGroup.getFlags_optional(), + xsdcAttributesGroup.getBundle_optional(), std::nullopt)))); } else { - // do nothing; - // TODO: check if this is valid or if we should treat as an error. - // Currently, attributes are not mandatory in schema, but an AttributesGroup - // without attributes does not make much sense. + LOG(ERROR) << __func__ << " Review Audio Policy config: no audio attributes provided for " + << aidlAttributesGroup.toString(); + return unexpected(BAD_VALUE); } return aidlAttributesGroup; } -AudioHalProductStrategy EngineConfigXmlConverter::convertProductStrategyToAidl( - const xsd::ProductStrategies::ProductStrategy& xsdcProductStrategy) { +ConversionResult EngineConfigXmlConverter::convertProductStrategyToAidl( + const eng_xsd::ProductStrategies::ProductStrategy& xsdcProductStrategy) { AudioHalProductStrategy aidlProductStrategy; - aidlProductStrategy.id = convertProductStrategyNameToAidl(xsdcProductStrategy.getName()); + aidlProductStrategy.id = + VALUE_OR_FATAL(convertProductStrategyNameToAidl(xsdcProductStrategy.getName())); if (xsdcProductStrategy.hasAttributesGroup()) { - aidlProductStrategy.attributesGroups = - convertCollectionToAidlUnchecked( + aidlProductStrategy.attributesGroups = VALUE_OR_FATAL( + (convertCollectionToAidl( xsdcProductStrategy.getAttributesGroup(), std::bind(&EngineConfigXmlConverter::convertAttributesGroupToAidl, this, - std::placeholders::_1)); + std::placeholders::_1)))); } if ((mDefaultProductStrategyId != std::nullopt) && (mDefaultProductStrategyId.value() == -1)) { mDefaultProductStrategyId = aidlProductStrategy.id; @@ -183,82 +180,42 @@ AudioHalProductStrategy EngineConfigXmlConverter::convertProductStrategyToAidl( return aidlProductStrategy; } -AudioHalVolumeCurve::CurvePoint EngineConfigXmlConverter::convertCurvePointToAidl( - const std::string& xsdcCurvePoint) { - AudioHalVolumeCurve::CurvePoint aidlCurvePoint{}; - if (sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index, - &aidlCurvePoint.attenuationMb) != 2) { - aidlCurvePoint.index = kInvalidCurvePointIndex; - } - return aidlCurvePoint; -} - -AudioHalVolumeCurve EngineConfigXmlConverter::convertVolumeCurveToAidl( - const xsd::Volume& xsdcVolumeCurve) { +ConversionResult EngineConfigXmlConverter::convertVolumeCurveToAidl( + const eng_xsd::Volume& xsdcVolumeCurve) { AudioHalVolumeCurve aidlVolumeCurve; aidlVolumeCurve.deviceCategory = static_cast(xsdcVolumeCurve.getDeviceCategory()); if (xsdcVolumeCurve.hasRef()) { if (mVolumesReferenceMap.empty()) { - mVolumesReferenceMap = generateReferenceMap( + mVolumesReferenceMap = generateReferenceMap( getXsdcConfig()->getVolumes()); } - aidlVolumeCurve.curvePoints = - convertCollectionToAidlUnchecked( + aidlVolumeCurve.curvePoints = VALUE_OR_FATAL( + (convertCollectionToAidl( mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(), - std::bind(&EngineConfigXmlConverter::convertCurvePointToAidl, this, - std::placeholders::_1)); + &convertCurvePointToAidl))); } else { - aidlVolumeCurve.curvePoints = - convertCollectionToAidlUnchecked( - xsdcVolumeCurve.getPoint(), - std::bind(&EngineConfigXmlConverter::convertCurvePointToAidl, this, - std::placeholders::_1)); + aidlVolumeCurve.curvePoints = VALUE_OR_FATAL( + (convertCollectionToAidl( + xsdcVolumeCurve.getPoint(), &convertCurvePointToAidl))); } return aidlVolumeCurve; } -AudioHalVolumeGroup EngineConfigXmlConverter::convertVolumeGroupToAidl( - const xsd::VolumeGroupsType::VolumeGroup& xsdcVolumeGroup) { +ConversionResult EngineConfigXmlConverter::convertVolumeGroupToAidl( + const eng_xsd::VolumeGroupsType::VolumeGroup& xsdcVolumeGroup) { AudioHalVolumeGroup aidlVolumeGroup; aidlVolumeGroup.name = xsdcVolumeGroup.getName(); aidlVolumeGroup.minIndex = xsdcVolumeGroup.getIndexMin(); aidlVolumeGroup.maxIndex = xsdcVolumeGroup.getIndexMax(); aidlVolumeGroup.volumeCurves = - convertCollectionToAidlUnchecked( + VALUE_OR_FATAL((convertCollectionToAidl( xsdcVolumeGroup.getVolume(), std::bind(&EngineConfigXmlConverter::convertVolumeCurveToAidl, this, - std::placeholders::_1)); + std::placeholders::_1)))); return aidlVolumeGroup; } -AudioHalCapCriterion EngineConfigXmlConverter::convertCapCriterionToAidl( - const xsd::CriterionType& xsdcCriterion) { - AudioHalCapCriterion aidlCapCriterion; - aidlCapCriterion.name = xsdcCriterion.getName(); - aidlCapCriterion.criterionTypeName = xsdcCriterion.getType(); - aidlCapCriterion.defaultLiteralValue = xsdcCriterion.get_default(); - return aidlCapCriterion; -} - -std::string EngineConfigXmlConverter::convertCriterionTypeValueToAidl( - const xsd::ValueType& xsdcCriterionTypeValue) { - return xsdcCriterionTypeValue.getLiteral(); -} - -AudioHalCapCriterionType EngineConfigXmlConverter::convertCapCriterionTypeToAidl( - const xsd::CriterionTypeType& xsdcCriterionType) { - AudioHalCapCriterionType aidlCapCriterionType; - aidlCapCriterionType.name = xsdcCriterionType.getName(); - aidlCapCriterionType.isInclusive = !(static_cast(xsdcCriterionType.getType())); - aidlCapCriterionType.values = - convertWrappedCollectionToAidlUnchecked( - xsdcCriterionType.getValues(), &xsd::ValuesType::getValue, - std::bind(&EngineConfigXmlConverter::convertCriterionTypeValueToAidl, this, - std::placeholders::_1)); - return aidlCapCriterionType; -} - AudioHalEngineConfig& EngineConfigXmlConverter::getAidlEngineConfig() { return mAidlEngineConfig; } @@ -266,39 +223,42 @@ AudioHalEngineConfig& EngineConfigXmlConverter::getAidlEngineConfig() { void EngineConfigXmlConverter::init() { initProductStrategyMap(); if (getXsdcConfig()->hasProductStrategies()) { - mAidlEngineConfig.productStrategies = - convertWrappedCollectionToAidlUnchecked( + mAidlEngineConfig.productStrategies = VALUE_OR_FATAL( + (convertWrappedCollectionToAidl( getXsdcConfig()->getProductStrategies(), - &xsd::ProductStrategies::getProductStrategy, + &eng_xsd::ProductStrategies::getProductStrategy, std::bind(&EngineConfigXmlConverter::convertProductStrategyToAidl, this, - std::placeholders::_1)); + std::placeholders::_1)))); if (mDefaultProductStrategyId) { mAidlEngineConfig.defaultProductStrategyId = mDefaultProductStrategyId.value(); } } if (getXsdcConfig()->hasVolumeGroups()) { - mAidlEngineConfig.volumeGroups = convertWrappedCollectionToAidlUnchecked< - xsd::VolumeGroupsType, xsd::VolumeGroupsType::VolumeGroup, AudioHalVolumeGroup>( - getXsdcConfig()->getVolumeGroups(), &xsd::VolumeGroupsType::getVolumeGroup, - std::bind(&EngineConfigXmlConverter::convertVolumeGroupToAidl, this, - std::placeholders::_1)); + mAidlEngineConfig.volumeGroups = VALUE_OR_FATAL( + (convertWrappedCollectionToAidl( + getXsdcConfig()->getVolumeGroups(), + &eng_xsd::VolumeGroupsType::getVolumeGroup, + std::bind(&EngineConfigXmlConverter::convertVolumeGroupToAidl, this, + std::placeholders::_1)))); } if (getXsdcConfig()->hasCriteria() && getXsdcConfig()->hasCriterion_types()) { AudioHalEngineConfig::CapSpecificConfig capSpecificConfig; - capSpecificConfig.criteria = - convertWrappedCollectionToAidlUnchecked( - getXsdcConfig()->getCriteria(), &xsd::CriteriaType::getCriterion, - std::bind(&EngineConfigXmlConverter::convertCapCriterionToAidl, 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; + capSpecificConfig.criteria = VALUE_OR_FATAL( + (convertWrappedCollectionToAidl( + getXsdcConfig()->getCriteria(), &eng_xsd::CriteriaType::getCriterion, + &convertCapCriterionToAidl))); + capSpecificConfig.criterionTypes = + VALUE_OR_FATAL((convertWrappedCollectionToAidl( + getXsdcConfig()->getCriterion_types(), + &eng_xsd::CriterionTypesType::getCriterion_type, + &convertCapCriterionTypeToAidl))); } } } // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp index 9fc99d4f8c..def812b1a6 100644 --- a/audio/aidl/default/Module.cpp +++ b/audio/aidl/default/Module.cpp @@ -25,6 +25,7 @@ #include #include +#include "core-impl/Configuration.h" #include "core-impl/Module.h" #include "core-impl/ModuleBluetooth.h" #include "core-impl/ModulePrimary.h" @@ -132,21 +133,36 @@ bool findAudioProfile(const AudioPort& port, const AudioFormatDescription& forma } // namespace // static -std::shared_ptr Module::createInstance(Type type) { +std::shared_ptr Module::createInstance(Type type, std::unique_ptr&& config) { switch (type) { case Type::DEFAULT: - return ndk::SharedRefBase::make(); + return ndk::SharedRefBase::make(std::move(config)); case Type::R_SUBMIX: - return ndk::SharedRefBase::make(); + return ndk::SharedRefBase::make(std::move(config)); case Type::STUB: - return ndk::SharedRefBase::make(); + return ndk::SharedRefBase::make(std::move(config)); case Type::USB: - return ndk::SharedRefBase::make(); + return ndk::SharedRefBase::make(std::move(config)); case Type::BLUETOOTH: - return ndk::SharedRefBase::make(); + return ndk::SharedRefBase::make(std::move(config)); } } +// static +std::optional Module::typeFromString(const std::string& type) { + if (type == "default") + return Module::Type::DEFAULT; + else if (type == "r_submix") + return Module::Type::R_SUBMIX; + else if (type == "stub") + return Module::Type::STUB; + else if (type == "usb") + return Module::Type::USB; + else if (type == "bluetooth") + return Module::Type::BLUETOOTH; + return {}; +} + std::ostream& operator<<(std::ostream& os, Module::Type t) { switch (t) { case Module::Type::DEFAULT: @@ -321,26 +337,8 @@ std::set Module::portIdsFromPortConfigIds(C portConfigIds) { return result; } -std::unique_ptr Module::initializeConfig() { - std::unique_ptr config; - switch (getType()) { - case Type::DEFAULT: - config = std::move(internal::getPrimaryConfiguration()); - break; - case Type::R_SUBMIX: - config = std::move(internal::getRSubmixConfiguration()); - break; - case Type::STUB: - config = std::move(internal::getStubConfiguration()); - break; - case Type::USB: - config = std::move(internal::getUsbConfiguration()); - break; - case Type::BLUETOOTH: - config = std::move(internal::getBluetoothConfiguration()); - break; - } - return config; +std::unique_ptr Module::initializeConfig() { + return internal::getConfiguration(getType()); } std::vector Module::getAudioRoutesForAudioPortImpl(int32_t portId) { @@ -355,7 +353,7 @@ std::vector Module::getAudioRoutesForAudioPortImpl(int32_t portId) return result; } -internal::Configuration& Module::getConfig() { +Module::Configuration& Module::getConfig() { if (!mConfig) { mConfig = std::move(initializeConfig()); } @@ -802,7 +800,7 @@ ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_ar context.fillDescriptor(&_aidl_return->desc); std::shared_ptr stream; RETURN_STATUS_IF_ERROR(createInputStream(std::move(context), in_args.sinkMetadata, - mConfig->microphones, &stream)); + getConfig().microphones, &stream)); StreamWrapper streamWrapper(stream); if (auto patchIt = mPatches.find(in_args.portConfigId); patchIt != mPatches.end()) { RETURN_STATUS_IF_ERROR( diff --git a/audio/aidl/default/Telephony.cpp b/audio/aidl/default/Telephony.cpp index bf05a8da98..d9da39f0a8 100644 --- a/audio/aidl/default/Telephony.cpp +++ b/audio/aidl/default/Telephony.cpp @@ -16,9 +16,9 @@ #define LOG_TAG "AHAL_Telephony" #include +#include #include -#include #include "core-impl/Telephony.h" diff --git a/audio/aidl/default/XsdcConversion.cpp b/audio/aidl/default/XsdcConversion.cpp new file mode 100644 index 0000000000..2feb0c3b8c --- /dev/null +++ b/audio/aidl/default/XsdcConversion.cpp @@ -0,0 +1,444 @@ +#include + +#include + +#define LOG_TAG "AHAL_Config" +#include +#include + +#include +#include +#include +#include + +#include "core-impl/XmlConverter.h" +#include "core-impl/XsdcConversion.h" + +using aidl::android::media::audio::common::AudioChannelLayout; +using aidl::android::media::audio::common::AudioDevice; +using aidl::android::media::audio::common::AudioDeviceAddress; +using aidl::android::media::audio::common::AudioDeviceDescription; +using aidl::android::media::audio::common::AudioDeviceType; +using aidl::android::media::audio::common::AudioFormatDescription; +using aidl::android::media::audio::common::AudioFormatType; +using aidl::android::media::audio::common::AudioGain; +using aidl::android::media::audio::common::AudioHalCapCriterion; +using aidl::android::media::audio::common::AudioHalCapCriterionType; +using aidl::android::media::audio::common::AudioHalVolumeCurve; +using aidl::android::media::audio::common::AudioIoFlags; +using aidl::android::media::audio::common::AudioPort; +using aidl::android::media::audio::common::AudioPortConfig; +using aidl::android::media::audio::common::AudioPortDeviceExt; +using aidl::android::media::audio::common::AudioPortExt; +using aidl::android::media::audio::common::AudioPortMixExt; +using aidl::android::media::audio::common::AudioProfile; +using ::android::BAD_VALUE; +using ::android::base::unexpected; + +namespace ap_xsd = android::audio::policy::configuration; +namespace eng_xsd = android::audio::policy::engine::configuration; + +namespace aidl::android::hardware::audio::core::internal { + +inline ConversionResult assertNonEmpty(const std::string& s) { + if (s.empty()) { + LOG(ERROR) << __func__ << " Review Audio Policy config: " + << " empty string is not valid."; + return unexpected(BAD_VALUE); + } + return s; +} + +#define NON_EMPTY_STRING_OR_FATAL(s) VALUE_OR_FATAL(assertNonEmpty(s)) + +ConversionResult convertAudioFormatToAidl(const std::string& xsdcFormat) { + audio_format_t legacyFormat = ::android::formatFromString(xsdcFormat, AUDIO_FORMAT_DEFAULT); + ConversionResult result = + legacy2aidl_audio_format_t_AudioFormatDescription(legacyFormat); + if ((legacyFormat == AUDIO_FORMAT_DEFAULT && xsdcFormat.compare("AUDIO_FORMAT_DEFAULT") != 0) || + !result.ok()) { + LOG(ERROR) << __func__ << " Review Audio Policy config: " << xsdcFormat + << " is not a valid audio format."; + return unexpected(BAD_VALUE); + } + return result; +} + +std::unordered_set getAttachedDevices(const ap_xsd::Modules::Module& moduleConfig) { + std::unordered_set attachedDeviceSet; + if (moduleConfig.hasAttachedDevices()) { + for (const ap_xsd::AttachedDevices& attachedDevices : moduleConfig.getAttachedDevices()) { + if (attachedDevices.hasItem()) { + attachedDeviceSet.insert(attachedDevices.getItem().begin(), + attachedDevices.getItem().end()); + } + } + } + return attachedDeviceSet; +} + +ConversionResult convertDeviceTypeToAidl(const std::string& xType) { + audio_devices_t legacyDeviceType = AUDIO_DEVICE_NONE; + ::android::DeviceConverter::fromString(xType, legacyDeviceType); + ConversionResult result = + legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyDeviceType); + if ((legacyDeviceType == AUDIO_DEVICE_NONE) || !result.ok()) { + LOG(ERROR) << __func__ << " Review Audio Policy config: " << xType + << " is not a valid device type."; + return unexpected(BAD_VALUE); + } + return result; +} + +ConversionResult createAudioDevice( + const ap_xsd::DevicePorts::DevicePort& xDevicePort) { + AudioDevice device = { + .type = VALUE_OR_FATAL(convertDeviceTypeToAidl(xDevicePort.getType())), + .address = xDevicePort.hasAddress() + ? AudioDeviceAddress::make( + xDevicePort.getAddress()) + : AudioDeviceAddress{}}; + if (device.type.type == AudioDeviceType::IN_MICROPHONE && device.type.connection.empty()) { + device.address = "bottom"; + } else if (device.type.type == AudioDeviceType::IN_MICROPHONE_BACK && + device.type.connection.empty()) { + device.address = "back"; + } + return device; +} + +ConversionResult createAudioPortExt( + const ap_xsd::DevicePorts::DevicePort& xDevicePort, + const std::string& xDefaultOutputDevice) { + AudioPortDeviceExt deviceExt = { + .device = VALUE_OR_FATAL(createAudioDevice(xDevicePort)), + .flags = (xDevicePort.getTagName() == xDefaultOutputDevice) + ? 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE + : 0, + .encodedFormats = + xDevicePort.hasEncodedFormats() + ? VALUE_OR_FATAL( + (convertCollectionToAidl( + xDevicePort.getEncodedFormats(), + &convertAudioFormatToAidl))) + : std::vector{}, + }; + return AudioPortExt::make(deviceExt); +} + +ConversionResult createAudioPortExt(const ap_xsd::MixPorts::MixPort& xMixPort) { + AudioPortMixExt mixExt = { + .maxOpenStreamCount = + xMixPort.hasMaxOpenCount() ? static_cast(xMixPort.getMaxOpenCount()) : 0, + .maxActiveStreamCount = xMixPort.hasMaxActiveCount() + ? static_cast(xMixPort.getMaxActiveCount()) + : 1, + .recommendedMuteDurationMs = + xMixPort.hasRecommendedMuteDurationMs() + ? static_cast(xMixPort.getRecommendedMuteDurationMs()) + : 0}; + return AudioPortExt::make(mixExt); +} + +ConversionResult convertGainModeToAidl(const std::vector& gainModeVec) { + static const char gainModeSeparator = ' '; + int gainModeMask = 0; + for (const ap_xsd::AudioGainMode& gainMode : gainModeVec) { + gainModeMask |= static_cast(::android::GainModeConverter::maskFromString( + ap_xsd::toString(gainMode), &gainModeSeparator)); + } + return gainModeMask; +} + +ConversionResult convertChannelMaskToAidl( + const ap_xsd::AudioChannelMask& xChannelMask) { + std::string xChannelMaskLiteral = ap_xsd::toString(xChannelMask); + audio_channel_mask_t legacyChannelMask = ::android::channelMaskFromString(xChannelMaskLiteral); + ConversionResult result = + legacy2aidl_audio_channel_mask_t_AudioChannelLayout( + legacyChannelMask, + /* isInput= */ xChannelMaskLiteral.find("AUDIO_CHANNEL_IN_") == 0); + if ((legacyChannelMask == AUDIO_CHANNEL_INVALID) || !result.ok()) { + LOG(ERROR) << __func__ << " Review Audio Policy config: " << xChannelMaskLiteral + << " is not a valid audio channel mask."; + return unexpected(BAD_VALUE); + } + return result; +} + +ConversionResult convertGainToAidl(const ap_xsd::Gains::Gain& xGain) { + return AudioGain{ + .mode = VALUE_OR_FATAL(convertGainModeToAidl(xGain.getMode())), + .channelMask = + xGain.hasChannel_mask() + ? VALUE_OR_FATAL(convertChannelMaskToAidl(xGain.getChannel_mask())) + : AudioChannelLayout{}, + .minValue = xGain.hasMinValueMB() ? xGain.getMinValueMB() : 0, + .maxValue = xGain.hasMaxValueMB() ? xGain.getMaxValueMB() : 0, + .defaultValue = xGain.hasDefaultValueMB() ? xGain.getDefaultValueMB() : 0, + .stepValue = xGain.hasStepValueMB() ? xGain.getStepValueMB() : 0, + .minRampMs = xGain.hasMinRampMs() ? xGain.getMinRampMs() : 0, + .maxRampMs = xGain.hasMaxRampMs() ? xGain.getMaxRampMs() : 0, + .useForVolume = xGain.hasUseForVolume() ? xGain.getUseForVolume() : false, + }; +} + +ConversionResult convertAudioProfileToAidl(const ap_xsd::Profile& xProfile) { + return AudioProfile{ + .format = xProfile.hasFormat() + ? VALUE_OR_FATAL(convertAudioFormatToAidl(xProfile.getFormat())) + : AudioFormatDescription{}, + .channelMasks = + xProfile.hasChannelMasks() + ? VALUE_OR_FATAL((convertCollectionToAidl( + xProfile.getChannelMasks(), &convertChannelMaskToAidl))) + : std::vector{}, + .sampleRates = xProfile.hasSamplingRates() + ? VALUE_OR_FATAL((convertCollectionToAidl( + xProfile.getSamplingRates(), + [](const int64_t x) -> int { return x; }))) + : std::vector{}}; +} + +ConversionResult convertIoFlagsToAidl( + const std::vector& flags, const ap_xsd::Role role, + bool flagsForMixPort) { + static const char flagSeparator = ' '; + int flagMask = 0; + if ((role == ap_xsd::Role::sink && flagsForMixPort) || + (role == ap_xsd::Role::source && !flagsForMixPort)) { + for (const ap_xsd::AudioInOutFlag& flag : flags) { + flagMask |= static_cast(::android::InputFlagConverter::maskFromString( + ap_xsd::toString(flag), &flagSeparator)); + } + return AudioIoFlags::make(flagMask); + } else { + for (const ap_xsd::AudioInOutFlag& flag : flags) { + flagMask |= static_cast(::android::OutputFlagConverter::maskFromString( + ap_xsd::toString(flag), &flagSeparator)); + } + } + return AudioIoFlags::make(flagMask); +} + +ConversionResult convertDevicePortToAidl( + const ap_xsd::DevicePorts::DevicePort& xDevicePort, const std::string& xDefaultOutputDevice, + int32_t& nextPortId) { + return AudioPort{ + .id = nextPortId++, + .name = NON_EMPTY_STRING_OR_FATAL(xDevicePort.getTagName()), + .profiles = VALUE_OR_FATAL((convertCollectionToAidl( + xDevicePort.getProfile(), convertAudioProfileToAidl))), + .flags = VALUE_OR_FATAL(convertIoFlagsToAidl({}, xDevicePort.getRole(), false)), + .gains = VALUE_OR_FATAL( + (convertWrappedCollectionToAidl( + xDevicePort.getGains(), &ap_xsd::Gains::getGain, convertGainToAidl))), + + .ext = VALUE_OR_FATAL(createAudioPortExt(xDevicePort, xDefaultOutputDevice))}; +} + +ConversionResult> convertDevicePortsInModuleToAidl( + const ap_xsd::Modules::Module& xModuleConfig, int32_t& nextPortId) { + std::vector audioPortVec; + std::vector xDevicePortsVec = xModuleConfig.getDevicePorts(); + if (xDevicePortsVec.size() > 1) { + LOG(ERROR) << __func__ << "Having multiple '' elements is not allowed, found: " + << xDevicePortsVec.size(); + return unexpected(BAD_VALUE); + } + if (!xDevicePortsVec.empty()) { + const std::string xDefaultOutputDevice = xModuleConfig.hasDefaultOutputDevice() + ? xModuleConfig.getDefaultOutputDevice() + : ""; + audioPortVec.reserve(xDevicePortsVec[0].getDevicePort().size()); + for (const ap_xsd::DevicePorts& xDevicePortsType : xDevicePortsVec) { + for (const ap_xsd::DevicePorts::DevicePort& xDevicePort : + xDevicePortsType.getDevicePort()) { + audioPortVec.push_back(VALUE_OR_FATAL( + convertDevicePortToAidl(xDevicePort, xDefaultOutputDevice, nextPortId))); + } + } + } + const std::unordered_set xAttachedDeviceSet = getAttachedDevices(xModuleConfig); + for (const auto& port : audioPortVec) { + const auto& devicePort = port.ext.get(); + if (xAttachedDeviceSet.count(port.name) != devicePort.device.type.connection.empty()) { + LOG(ERROR) << __func__ << ": Review Audio Policy config: " + << "list is incorrect or devicePort \"" << port.name + << "\" type= " << devicePort.device.type.toString() << " is incorrect."; + return unexpected(BAD_VALUE); + } + } + return audioPortVec; +} + +ConversionResult convertMixPortToAidl(const ap_xsd::MixPorts::MixPort& xMixPort, + int32_t& nextPortId) { + return AudioPort{ + .id = nextPortId++, + .name = NON_EMPTY_STRING_OR_FATAL(xMixPort.getName()), + .profiles = VALUE_OR_FATAL((convertCollectionToAidl( + xMixPort.getProfile(), convertAudioProfileToAidl))), + .flags = xMixPort.hasFlags() + ? VALUE_OR_FATAL(convertIoFlagsToAidl(xMixPort.getFlags(), + xMixPort.getRole(), true)) + : VALUE_OR_FATAL(convertIoFlagsToAidl({}, xMixPort.getRole(), true)), + .gains = VALUE_OR_FATAL( + (convertWrappedCollectionToAidl( + xMixPort.getGains(), &ap_xsd::Gains::getGain, &convertGainToAidl))), + .ext = VALUE_OR_FATAL(createAudioPortExt(xMixPort)), + }; +} + +ConversionResult> convertMixPortsInModuleToAidl( + const ap_xsd::Modules::Module& xModuleConfig, int32_t& nextPortId) { + std::vector audioPortVec; + std::vector xMixPortsVec = xModuleConfig.getMixPorts(); + if (xMixPortsVec.size() > 1) { + LOG(ERROR) << __func__ << "Having multiple '' elements is not allowed, found: " + << xMixPortsVec.size(); + return unexpected(BAD_VALUE); + } + if (!xMixPortsVec.empty()) { + audioPortVec.reserve(xMixPortsVec[0].getMixPort().size()); + for (const ap_xsd::MixPorts& xMixPortsType : xMixPortsVec) { + for (const ap_xsd::MixPorts::MixPort& xMixPort : xMixPortsType.getMixPort()) { + audioPortVec.push_back(VALUE_OR_FATAL(convertMixPortToAidl(xMixPort, nextPortId))); + } + } + } + return audioPortVec; +} + +ConversionResult getSinkPortId(const ap_xsd::Routes::Route& xRoute, + const std::unordered_map& portMap) { + auto portMapIter = portMap.find(xRoute.getSink()); + if (portMapIter == portMap.end()) { + LOG(ERROR) << __func__ << " Review Audio Policy config: audio route" + << "has sink: " << xRoute.getSink() + << " which is neither a device port nor mix port."; + return unexpected(BAD_VALUE); + } + return portMapIter->second; +} + +ConversionResult> getSourcePortIds( + const ap_xsd::Routes::Route& xRoute, + const std::unordered_map& portMap) { + std::vector sourcePortIds; + for (const std::string& rawSource : ::android::base::Split(xRoute.getSources(), ",")) { + const std::string source = ::android::base::Trim(rawSource); + auto portMapIter = portMap.find(source); + if (portMapIter == portMap.end()) { + LOG(ERROR) << __func__ << " Review Audio Policy config: audio route" + << "has source \"" << source + << "\" which is neither a device port nor mix port."; + return unexpected(BAD_VALUE); + } + sourcePortIds.push_back(portMapIter->second); + } + return sourcePortIds; +} + +ConversionResult convertRouteToAidl(const ap_xsd::Routes::Route& xRoute, + const std::vector& aidlAudioPorts) { + std::unordered_map portMap; + for (const AudioPort& port : aidlAudioPorts) { + portMap.insert({port.name, port.id}); + } + return AudioRoute{.sourcePortIds = VALUE_OR_FATAL(getSourcePortIds(xRoute, portMap)), + .sinkPortId = VALUE_OR_FATAL(getSinkPortId(xRoute, portMap)), + .isExclusive = (xRoute.getType() == ap_xsd::MixType::mux)}; +} + +ConversionResult> convertRoutesInModuleToAidl( + const ap_xsd::Modules::Module& xModuleConfig, + const std::vector& aidlAudioPorts) { + std::vector audioRouteVec; + std::vector xRoutesVec = xModuleConfig.getRoutes(); + if (!xRoutesVec.empty()) { + /* + * xRoutesVec likely only contains one element; that is, it's + * likely that all ap_xsd::Routes::MixPort types that we need to convert + * are inside of xRoutesVec[0]. + */ + audioRouteVec.reserve(xRoutesVec[0].getRoute().size()); + for (const ap_xsd::Routes& xRoutesType : xRoutesVec) { + for (const ap_xsd::Routes::Route& xRoute : xRoutesType.getRoute()) { + audioRouteVec.push_back(VALUE_OR_FATAL(convertRouteToAidl(xRoute, aidlAudioPorts))); + } + } + } + return audioRouteVec; +} + +ConversionResult> convertModuleConfigToAidl( + const ap_xsd::Modules::Module& xModuleConfig) { + auto result = std::make_unique(); + auto& aidlModuleConfig = *result; + std::vector devicePorts = VALUE_OR_FATAL( + convertDevicePortsInModuleToAidl(xModuleConfig, aidlModuleConfig.nextPortId)); + + // The XML config does not specify the default input device. + // Assign the first attached input device as the default. + for (auto& port : devicePorts) { + if (port.flags.getTag() != AudioIoFlags::input) continue; + auto& deviceExt = port.ext.get(); + if (!deviceExt.device.type.connection.empty()) continue; + deviceExt.flags |= 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE; + break; + } + + std::vector mixPorts = VALUE_OR_FATAL( + convertMixPortsInModuleToAidl(xModuleConfig, aidlModuleConfig.nextPortId)); + aidlModuleConfig.ports.reserve(devicePorts.size() + mixPorts.size()); + aidlModuleConfig.ports.insert(aidlModuleConfig.ports.end(), devicePorts.begin(), + devicePorts.end()); + aidlModuleConfig.ports.insert(aidlModuleConfig.ports.end(), mixPorts.begin(), mixPorts.end()); + + aidlModuleConfig.routes = + VALUE_OR_FATAL(convertRoutesInModuleToAidl(xModuleConfig, aidlModuleConfig.ports)); + return result; +} + +ConversionResult convertCapCriterionToAidl( + const eng_xsd::CriterionType& xsdcCriterion) { + AudioHalCapCriterion aidlCapCriterion; + aidlCapCriterion.name = xsdcCriterion.getName(); + aidlCapCriterion.criterionTypeName = xsdcCriterion.getType(); + aidlCapCriterion.defaultLiteralValue = xsdcCriterion.get_default(); + return aidlCapCriterion; +} + +ConversionResult convertCriterionTypeValueToAidl( + const eng_xsd::ValueType& xsdcCriterionTypeValue) { + return xsdcCriterionTypeValue.getLiteral(); +} + +ConversionResult convertCapCriterionTypeToAidl( + const eng_xsd::CriterionTypeType& xsdcCriterionType) { + AudioHalCapCriterionType aidlCapCriterionType; + aidlCapCriterionType.name = xsdcCriterionType.getName(); + aidlCapCriterionType.isInclusive = !(static_cast(xsdcCriterionType.getType())); + aidlCapCriterionType.values = VALUE_OR_RETURN( + (convertWrappedCollectionToAidl( + xsdcCriterionType.getValues(), &eng_xsd::ValuesType::getValue, + &convertCriterionTypeValueToAidl))); + return aidlCapCriterionType; +} + +ConversionResult convertCurvePointToAidl( + const std::string& xsdcCurvePoint) { + AudioHalVolumeCurve::CurvePoint aidlCurvePoint{}; + if ((sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index, + &aidlCurvePoint.attenuationMb) != 2) || + (aidlCurvePoint.index < AudioHalVolumeCurve::CurvePoint::MIN_INDEX) || + (aidlCurvePoint.index > AudioHalVolumeCurve::CurvePoint::MAX_INDEX)) { + LOG(ERROR) << __func__ << " Review Audio Policy config: volume curve point:" + << "\"" << xsdcCurvePoint << "\" is invalid"; + return unexpected(BAD_VALUE); + } + return aidlCurvePoint; +} +} // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/android.hardware.audio.service-aidl.xml b/audio/aidl/default/android.hardware.audio.service-aidl.xml index 9db606157a..57f61c9b2c 100644 --- a/audio/aidl/default/android.hardware.audio.service-aidl.xml +++ b/audio/aidl/default/android.hardware.audio.service-aidl.xml @@ -9,16 +9,6 @@ 1 IModule/r_submix - - android.hardware.audio.core - 1 - IModule/stub - - - android.hardware.audio.core - 1 - IModule/usb - android.hardware.audio.core 1 @@ -29,4 +19,16 @@ 1 IConfig/default + diff --git a/audio/aidl/default/config/audioPolicy/api/current.txt b/audio/aidl/default/config/audioPolicy/api/current.txt index e2bc833d43..3547f54d3b 100644 --- a/audio/aidl/default/config/audioPolicy/api/current.txt +++ b/audio/aidl/default/config/audioPolicy/api/current.txt @@ -85,16 +85,6 @@ package android.audio.policy.configuration { enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK; } - public enum AudioContentType { - method @NonNull public String getRawName(); - enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_MOVIE; - enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_MUSIC; - enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_SONIFICATION; - enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_SPEECH; - enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_ULTRASOUND; - enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_UNKNOWN; - } - public enum AudioDevice { method @NonNull public String getRawName(); enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_AMBIENT; @@ -168,13 +158,6 @@ package android.audio.policy.configuration { enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADSET; } - public enum AudioEncapsulationType { - method @NonNull public String getRawName(); - enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_IEC61937; - enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_NONE; - enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_PCM; - } - public enum AudioFormat { method @NonNull public String getRawName(); enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC; @@ -359,29 +342,6 @@ package android.audio.policy.configuration { enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_VOICE_CALL; } - public enum AudioUsage { - method @NonNull public String getRawName(); - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ALARM; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ANNOUNCEMENT; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANCE_SONIFICATION; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANT; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_CALL_ASSISTANT; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_EMERGENCY; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_GAME; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_MEDIA; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_NOTIFICATION; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_NOTIFICATION_EVENT; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_SAFETY; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_UNKNOWN; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VEHICLE_STATUS; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VIRTUAL_SOURCE; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION; - enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING; - } - public enum DeviceCategory { method @NonNull public String getRawName(); enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_EARPIECE; @@ -435,7 +395,6 @@ package android.audio.policy.configuration { method @Nullable public int getMinRampMs(); method @Nullable public int getMinValueMB(); method @Nullable public java.util.List getMode(); - method @Nullable public String getName(); method @Nullable public int getStepValueMB(); method @Nullable public boolean getUseForVolume(); method public void setChannel_mask(@Nullable android.audio.policy.configuration.AudioChannelMask); @@ -445,7 +404,6 @@ package android.audio.policy.configuration { method public void setMinRampMs(@Nullable int); method public void setMinValueMB(@Nullable int); method public void setMode(@Nullable java.util.List); - method public void setName(@Nullable String); method public void setStepValueMB(@Nullable int); method public void setUseForVolume(@Nullable boolean); } @@ -478,7 +436,6 @@ package android.audio.policy.configuration { method @Nullable public long getMaxActiveCount(); method @Nullable public long getMaxOpenCount(); method @Nullable public String getName(); - method @Nullable public java.util.List getPreferredUsage(); method @Nullable public java.util.List getProfile(); method @Nullable public long getRecommendedMuteDurationMs(); method @Nullable public android.audio.policy.configuration.Role getRole(); @@ -487,7 +444,6 @@ package android.audio.policy.configuration { method public void setMaxActiveCount(@Nullable long); method public void setMaxOpenCount(@Nullable long); method public void setName(@Nullable String); - method public void setPreferredUsage(@Nullable java.util.List); method public void setRecommendedMuteDurationMs(@Nullable long); method public void setRole(@Nullable android.audio.policy.configuration.Role); } @@ -524,14 +480,10 @@ package android.audio.policy.configuration { public class Profile { ctor public Profile(); method @Nullable public java.util.List getChannelMasks(); - method @Nullable public android.audio.policy.configuration.AudioEncapsulationType getEncapsulationType(); method @Nullable public String getFormat(); - method @Nullable public String getName(); method @Nullable public java.util.List getSamplingRates(); method public void setChannelMasks(@Nullable java.util.List); - method public void setEncapsulationType(@Nullable android.audio.policy.configuration.AudioEncapsulationType); method public void setFormat(@Nullable String); - method public void setName(@Nullable String); method public void setSamplingRates(@Nullable java.util.List); } diff --git a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd index 9a3a447b5f..d93f6972e1 100644 --- a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd +++ b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd @@ -217,20 +217,6 @@ - - - - When choosing the mixPort of an audio track, the audioPolicy - first considers the mixPorts with a preferredUsage including - the track AudioUsage preferred . - If non support the track format, the other mixPorts are considered. - Eg: a will receive - the audio of all apps playing with a MEDIA usage. - It may receive audio from ALARM if there are no audio compatible - . - - - @@ -434,56 +420,6 @@ - - - - Audio usage specifies the intended use case for the sound being played. - Please consult frameworks/base/media/java/android/media/AudioAttributes.java - for the description of each value. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Audio content type expresses the general category of the content. - Please consult frameworks/base/media/java/android/media/AudioAttributes.java - for the description of each value. - - - - - - - - - - - @@ -579,19 +515,10 @@ - - - - - - - - - @@ -612,7 +539,6 @@ - diff --git a/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h b/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h index 090d58585f..bff4b4a5d4 100644 --- a/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h +++ b/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h @@ -16,27 +16,42 @@ #pragma once +#include +#include #include +#include +#include +#include #include #include #include #include +#include +#include "core-impl/Module.h" #include "core-impl/XmlConverter.h" namespace aidl::android::hardware::audio::core::internal { class AudioPolicyConfigXmlConverter { public: + using ModuleConfiguration = std::pair>; + using ModuleConfigs = std::vector; + explicit AudioPolicyConfigXmlConverter(const std::string& configFilePath) - : mConverter(configFilePath, &::android::audio::policy::configuration::read) {} + : mConverter(configFilePath, &::android::audio::policy::configuration::read) { + if (mConverter.getXsdcConfig()) { + init(); + } + } std::string getError() const { return mConverter.getError(); } ::android::status_t getStatus() const { return mConverter.getStatus(); } const ::aidl::android::media::audio::common::AudioHalEngineConfig& getAidlEngineConfig(); const SurroundSoundConfig& getSurroundSoundConfig(); + std::unique_ptr releaseModuleConfigs(); // Public for testing purposes. static const SurroundSoundConfig& getDefaultSurroundSoundConfig(); @@ -47,13 +62,13 @@ class AudioPolicyConfigXmlConverter { return mConverter.getXsdcConfig(); } void addVolumeGroupstoEngineConfig(); + void init(); void mapStreamToVolumeCurve( const ::android::audio::policy::configuration::Volume& xsdcVolumeCurve); void mapStreamsToVolumeCurves(); void parseVolumes(); - ::aidl::android::media::audio::common::AudioHalVolumeCurve::CurvePoint convertCurvePointToAidl( - const std::string& xsdcCurvePoint); - ::aidl::android::media::audio::common::AudioHalVolumeCurve convertVolumeCurveToAidl( + ConversionResult<::aidl::android::media::audio::common::AudioHalVolumeCurve> + convertVolumeCurveToAidl( const ::android::audio::policy::configuration::Volume& xsdcVolumeCurve); ::aidl::android::media::audio::common::AudioHalEngineConfig mAidlEngineConfig; @@ -63,6 +78,7 @@ class AudioPolicyConfigXmlConverter { std::unordered_map<::android::audio::policy::configuration::AudioStreamType, std::vector<::aidl::android::media::audio::common::AudioHalVolumeCurve>> mStreamToVolumeCurvesMap; + std::unique_ptr mModuleConfigurations = std::make_unique(); }; } // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/include/core-impl/ChildInterface.h b/audio/aidl/default/include/core-impl/ChildInterface.h index 2421b59a1a..3b74c5e4d7 100644 --- a/audio/aidl/default/include/core-impl/ChildInterface.h +++ b/audio/aidl/default/include/core-impl/ChildInterface.h @@ -42,12 +42,16 @@ struct ChildInterface : private std::pair, ndk::SpAIBinder> { C* operator->() const { return this->first; } // Use 'getInstance' when returning the interface instance. std::shared_ptr getInstance() { + (void)getBinder(); + return this->first; + } + AIBinder* getBinder() { if (this->second.get() == nullptr) { this->second = this->first->asBinder(); AIBinder_setMinSchedulerPolicy(this->second.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); } - return this->first; + return this->second.get(); } }; diff --git a/audio/aidl/default/include/core-impl/Config.h b/audio/aidl/default/include/core-impl/Config.h index 96a6cb9e8e..63d4b3d0c2 100644 --- a/audio/aidl/default/include/core-impl/Config.h +++ b/audio/aidl/default/include/core-impl/Config.h @@ -26,11 +26,16 @@ namespace aidl::android::hardware::audio::core { static const std::string kEngineConfigFileName = "audio_policy_engine_configuration.xml"; class Config : public BnConfig { + public: + explicit Config(internal::AudioPolicyConfigXmlConverter& apConverter) + : mAudioPolicyConverter(apConverter) {} + + private: ndk::ScopedAStatus getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) override; ndk::ScopedAStatus getEngineConfig( aidl::android::media::audio::common::AudioHalEngineConfig* _aidl_return) override; - internal::AudioPolicyConfigXmlConverter mAudioPolicyConverter{ - ::android::audio_get_audio_policy_config_file()}; + + internal::AudioPolicyConfigXmlConverter& mAudioPolicyConverter; internal::EngineConfigXmlConverter mEngConfigConverter{ ::android::audio_find_readable_configuration_file(kEngineConfigFileName.c_str())}; }; diff --git a/audio/aidl/default/include/core-impl/Configuration.h b/audio/aidl/default/include/core-impl/Configuration.h index 6277c38db2..aa7b9fff97 100644 --- a/audio/aidl/default/include/core-impl/Configuration.h +++ b/audio/aidl/default/include/core-impl/Configuration.h @@ -16,37 +16,12 @@ #pragma once -#include #include -#include -#include -#include -#include -#include -#include +#include "Module.h" namespace aidl::android::hardware::audio::core::internal { -struct Configuration { - std::vector<::aidl::android::media::audio::common::MicrophoneInfo> microphones; - std::vector<::aidl::android::media::audio::common::AudioPort> ports; - std::vector<::aidl::android::media::audio::common::AudioPortConfig> portConfigs; - std::vector<::aidl::android::media::audio::common::AudioPortConfig> initialConfigs; - // Port id -> List of profiles to use when the device port state is set to 'connected' - // in connection simulation mode. - std::map> - connectedProfiles; - std::vector routes; - std::vector patches; - int32_t nextPortId = 1; - int32_t nextPatchId = 1; -}; - -std::unique_ptr getPrimaryConfiguration(); -std::unique_ptr getRSubmixConfiguration(); -std::unique_ptr getStubConfiguration(); -std::unique_ptr getUsbConfiguration(); -std::unique_ptr getBluetoothConfiguration(); +std::unique_ptr getConfiguration(Module::Type moduleType); } // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h b/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h index b34441d9ac..22ac8cb42c 100644 --- a/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h +++ b/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h @@ -19,10 +19,9 @@ #include #include -#include - #include #include +#include #include "core-impl/XmlConverter.h" @@ -49,29 +48,24 @@ class EngineConfigXmlConverter { } void init(); void initProductStrategyMap(); - ::aidl::android::media::audio::common::AudioAttributes convertAudioAttributesToAidl( + ConversionResult<::aidl::android::media::audio::common::AudioAttributes> + convertAudioAttributesToAidl( const ::android::audio::policy::engine::configuration::AttributesType& xsdcAudioAttributes); - ::aidl::android::media::audio::common::AudioHalAttributesGroup convertAttributesGroupToAidl( + ConversionResult<::aidl::android::media::audio::common::AudioHalAttributesGroup> + convertAttributesGroupToAidl( const ::android::audio::policy::engine::configuration::AttributesGroup& xsdcAttributesGroup); - ::aidl::android::media::audio::common::AudioHalCapCriterion convertCapCriterionToAidl( - const ::android::audio::policy::engine::configuration::CriterionType& xsdcCriterion); - ::aidl::android::media::audio::common::AudioHalCapCriterionType convertCapCriterionTypeToAidl( - const ::android::audio::policy::engine::configuration::CriterionTypeType& - xsdcCriterionType); - std::string convertCriterionTypeValueToAidl( - const ::android::audio::policy::engine::configuration::ValueType& - xsdcCriterionTypeValue); - ::aidl::android::media::audio::common::AudioHalVolumeCurve::CurvePoint convertCurvePointToAidl( - const std::string& xsdcCurvePoint); - ::aidl::android::media::audio::common::AudioHalProductStrategy convertProductStrategyToAidl( - const ::android::audio::policy::engine::configuration::ProductStrategies:: - ProductStrategy& xsdcProductStrategy); - int convertProductStrategyNameToAidl(const std::string& xsdcProductStrategyName); - ::aidl::android::media::audio::common::AudioHalVolumeCurve convertVolumeCurveToAidl( + ConversionResult<::aidl::android::media::audio::common::AudioHalProductStrategy> + convertProductStrategyToAidl(const ::android::audio::policy::engine::configuration:: + ProductStrategies::ProductStrategy& xsdcProductStrategy); + ConversionResult convertProductStrategyNameToAidl( + const std::string& xsdcProductStrategyName); + ConversionResult<::aidl::android::media::audio::common::AudioHalVolumeCurve> + convertVolumeCurveToAidl( const ::android::audio::policy::engine::configuration::Volume& xsdcVolumeCurve); - ::aidl::android::media::audio::common::AudioHalVolumeGroup convertVolumeGroupToAidl( + ConversionResult<::aidl::android::media::audio::common::AudioHalVolumeGroup> + convertVolumeGroupToAidl( const ::android::audio::policy::engine::configuration::VolumeGroupsType::VolumeGroup& xsdcVolumeGroup); diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h index f407e25bf7..64953cf1cf 100644 --- a/audio/aidl/default/include/core-impl/Module.h +++ b/audio/aidl/default/include/core-impl/Module.h @@ -19,31 +19,51 @@ #include #include #include +#include #include #include #include "core-impl/ChildInterface.h" -#include "core-impl/Configuration.h" #include "core-impl/Stream.h" namespace aidl::android::hardware::audio::core { class Module : public BnModule { public: - // This value is used for all AudioPatches and reported by all streams. - static constexpr int32_t kLatencyMs = 10; + struct Configuration { + std::vector<::aidl::android::media::audio::common::MicrophoneInfo> microphones; + std::vector<::aidl::android::media::audio::common::AudioPort> ports; + std::vector<::aidl::android::media::audio::common::AudioPortConfig> portConfigs; + std::vector<::aidl::android::media::audio::common::AudioPortConfig> initialConfigs; + // Port id -> List of profiles to use when the device port state is set to 'connected' + // in connection simulation mode. + std::map> + connectedProfiles; + std::vector routes; + std::vector patches; + int32_t nextPortId = 1; + int32_t nextPatchId = 1; + }; enum Type : int { DEFAULT, R_SUBMIX, STUB, USB, BLUETOOTH }; enum BtInterface : int { BTCONF, BTA2DP, BTLE }; - - static std::shared_ptr createInstance(Type type); - - explicit Module(Type type) : mType(type) {} - typedef std::tuple, std::weak_ptr, std::weak_ptr> BtProfileHandles; + // This value is used by default for all AudioPatches and reported by all streams. + static constexpr int32_t kLatencyMs = 10; + + static std::shared_ptr createInstance(Type type) { + return createInstance(type, std::make_unique()); + } + static std::shared_ptr createInstance(Type type, + std::unique_ptr&& config); + static std::optional typeFromString(const std::string& type); + + Module(Type type, std::unique_ptr&& config) + : mType(type), mConfig(std::move(config)) {} + protected: // The vendor extension done via inheritance can override interface methods and augment // a call to the base implementation. @@ -148,7 +168,7 @@ class Module : public BnModule { using Patches = std::multimap; const Type mType; - std::unique_ptr mConfig; + std::unique_ptr mConfig; ModuleDebug mDebug; VendorDebug mVendorDebug; ConnectedDevicePorts mConnectedDevicePorts; @@ -187,7 +207,7 @@ class Module : public BnModule { const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected); virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute); virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume); - virtual std::unique_ptr initializeConfig(); + virtual std::unique_ptr initializeConfig(); // Utility and helper functions accessible to subclasses. ndk::ScopedAStatus bluetoothParametersUpdated(); @@ -204,7 +224,7 @@ class Module : public BnModule { int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port); std::vector getAudioRoutesForAudioPortImpl(int32_t portId); virtual BtProfileHandles getBtProfileManagerHandles(); - internal::Configuration& getConfig(); + Configuration& getConfig(); const ConnectedDevicePorts& getConnectedDevicePorts() const { return mConnectedDevicePorts; } bool getMasterMute() const { return mMasterMute; } bool getMasterVolume() const { return mMasterVolume; } diff --git a/audio/aidl/default/include/core-impl/ModuleAlsa.h b/audio/aidl/default/include/core-impl/ModuleAlsa.h index 5815961f7c..2774fe5b9e 100644 --- a/audio/aidl/default/include/core-impl/ModuleAlsa.h +++ b/audio/aidl/default/include/core-impl/ModuleAlsa.h @@ -27,7 +27,8 @@ namespace aidl::android::hardware::audio::core { // provide necessary overrides for all interface methods omitted here. class ModuleAlsa : public Module { public: - explicit ModuleAlsa(Module::Type type) : Module(type) {} + ModuleAlsa(Type type, std::unique_ptr&& config) + : Module(type, std::move(config)) {} protected: // Extension methods of 'Module'. diff --git a/audio/aidl/default/include/core-impl/ModuleBluetooth.h b/audio/aidl/default/include/core-impl/ModuleBluetooth.h index 526a809fdf..7ac2d34d42 100644 --- a/audio/aidl/default/include/core-impl/ModuleBluetooth.h +++ b/audio/aidl/default/include/core-impl/ModuleBluetooth.h @@ -23,7 +23,8 @@ namespace aidl::android::hardware::audio::core { class ModuleBluetooth final : public Module { public: - ModuleBluetooth() : Module(Type::BLUETOOTH) {} + ModuleBluetooth(std::unique_ptr&& config) + : Module(Type::BLUETOOTH, std::move(config)) {} private: BtProfileHandles getBtProfileManagerHandles() override; diff --git a/audio/aidl/default/include/core-impl/ModulePrimary.h b/audio/aidl/default/include/core-impl/ModulePrimary.h index 6264237fe3..ee86d644c4 100644 --- a/audio/aidl/default/include/core-impl/ModulePrimary.h +++ b/audio/aidl/default/include/core-impl/ModulePrimary.h @@ -22,7 +22,8 @@ namespace aidl::android::hardware::audio::core { class ModulePrimary final : public Module { public: - ModulePrimary() : Module(Type::DEFAULT) {} + ModulePrimary(std::unique_ptr&& config) + : Module(Type::DEFAULT, std::move(config)) {} protected: ndk::ScopedAStatus getTelephony(std::shared_ptr* _aidl_return) override; diff --git a/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h b/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h index c4bf7b99c2..ebf4558763 100644 --- a/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h +++ b/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h @@ -22,7 +22,8 @@ namespace aidl::android::hardware::audio::core { class ModuleRemoteSubmix : public Module { public: - ModuleRemoteSubmix() : Module(Type::R_SUBMIX) {} + ModuleRemoteSubmix(std::unique_ptr&& config) + : Module(Type::R_SUBMIX, std::move(config)) {} private: // IModule interfaces diff --git a/audio/aidl/default/include/core-impl/ModuleStub.h b/audio/aidl/default/include/core-impl/ModuleStub.h index 4f771611ab..e9b7db4286 100644 --- a/audio/aidl/default/include/core-impl/ModuleStub.h +++ b/audio/aidl/default/include/core-impl/ModuleStub.h @@ -22,7 +22,7 @@ namespace aidl::android::hardware::audio::core { class ModuleStub final : public Module { public: - ModuleStub() : Module(Type::STUB) {} + ModuleStub(std::unique_ptr&& config) : Module(Type::STUB, std::move(config)) {} protected: ndk::ScopedAStatus getBluetooth(std::shared_ptr* _aidl_return) override; diff --git a/audio/aidl/default/include/core-impl/ModuleUsb.h b/audio/aidl/default/include/core-impl/ModuleUsb.h index a296b8c042..6ee8f8a691 100644 --- a/audio/aidl/default/include/core-impl/ModuleUsb.h +++ b/audio/aidl/default/include/core-impl/ModuleUsb.h @@ -22,7 +22,7 @@ namespace aidl::android::hardware::audio::core { class ModuleUsb final : public ModuleAlsa { public: - ModuleUsb() : ModuleAlsa(Type::USB) {} + ModuleUsb(std::unique_ptr&& config) : ModuleAlsa(Type::USB, std::move(config)) {} private: // IModule interfaces diff --git a/audio/aidl/default/include/core-impl/XmlConverter.h b/audio/aidl/default/include/core-impl/XmlConverter.h index 383ea24836..68e6b8e3a3 100644 --- a/audio/aidl/default/include/core-impl/XmlConverter.h +++ b/audio/aidl/default/include/core-impl/XmlConverter.h @@ -22,7 +22,6 @@ #include #include -#include namespace aidl::android::hardware::audio::core::internal { @@ -85,10 +84,10 @@ class XmlConverter { * */ template -std::vector convertWrappedCollectionToAidlUnchecked( +static ConversionResult> convertWrappedCollectionToAidl( const std::vector& xsdcWrapperTypeVec, std::function&(const W&)> getInnerTypeVec, - std::function convertToAidl) { + std::function(const X&)> convertToAidl) { std::vector resultAidlTypeVec; if (!xsdcWrapperTypeVec.empty()) { /* @@ -98,21 +97,23 @@ std::vector convertWrappedCollectionToAidlUnchecked( */ resultAidlTypeVec.reserve(getInnerTypeVec(xsdcWrapperTypeVec[0]).size()); for (const W& xsdcWrapperType : xsdcWrapperTypeVec) { - std::transform(getInnerTypeVec(xsdcWrapperType).begin(), - getInnerTypeVec(xsdcWrapperType).end(), - std::back_inserter(resultAidlTypeVec), convertToAidl); + for (const X& xsdcType : getInnerTypeVec(xsdcWrapperType)) { + resultAidlTypeVec.push_back(VALUE_OR_FATAL(convertToAidl(xsdcType))); + } } } return resultAidlTypeVec; } template -std::vector convertCollectionToAidlUnchecked(const std::vector& xsdcTypeVec, - std::function itemConversion) { +static ConversionResult> convertCollectionToAidl( + const std::vector& xsdcTypeVec, + std::function(const X&)> convertToAidl) { std::vector resultAidlTypeVec; resultAidlTypeVec.reserve(xsdcTypeVec.size()); - std::transform(xsdcTypeVec.begin(), xsdcTypeVec.end(), std::back_inserter(resultAidlTypeVec), - itemConversion); + for (const X& xsdcType : xsdcTypeVec) { + resultAidlTypeVec.push_back(VALUE_OR_FATAL(convertToAidl(xsdcType))); + } return resultAidlTypeVec; } diff --git a/audio/aidl/default/include/core-impl/XsdcConversion.h b/audio/aidl/default/include/core-impl/XsdcConversion.h new file mode 100644 index 0000000000..30dc8b635b --- /dev/null +++ b/audio/aidl/default/include/core-impl/XsdcConversion.h @@ -0,0 +1,29 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core-impl/Module.h" + +namespace aidl::android::hardware::audio::core::internal { + +ConversionResult<::aidl::android::media::audio::common::AudioHalCapCriterion> +convertCapCriterionToAidl( + const ::android::audio::policy::engine::configuration::CriterionType& xsdcCriterion); +ConversionResult<::aidl::android::media::audio::common::AudioHalCapCriterionType> +convertCapCriterionTypeToAidl( + const ::android::audio::policy::engine::configuration::CriterionTypeType& + xsdcCriterionType); +ConversionResult<::aidl::android::media::audio::common::AudioHalVolumeCurve::CurvePoint> +convertCurvePointToAidl(const std::string& xsdcCurvePoint); +ConversionResult> convertModuleConfigToAidl( + const ::android::audio::policy::configuration::Modules::Module& moduleConfig); +} // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp index a0c0fab40a..6ab747db32 100644 --- a/audio/aidl/default/main.cpp +++ b/audio/aidl/default/main.cpp @@ -16,21 +16,51 @@ #include #include -#include #include #include +#define LOG_TAG "AHAL_Main" #include #include #include #include #include +#include "core-impl/AudioPolicyConfigXmlConverter.h" +#include "core-impl/ChildInterface.h" #include "core-impl/Config.h" #include "core-impl/Module.h" +using aidl::android::hardware::audio::core::ChildInterface; using aidl::android::hardware::audio::core::Config; using aidl::android::hardware::audio::core::Module; +using aidl::android::hardware::audio::core::internal::AudioPolicyConfigXmlConverter; + +namespace { + +ChildInterface createModule(const std::string& name, + std::unique_ptr&& config) { + ChildInterface result; + { + auto moduleType = Module::typeFromString(name); + if (!moduleType.has_value()) { + LOG(ERROR) << __func__ << ": module type \"" << name << "\" is not supported"; + return result; + } + auto module = Module::createInstance(*moduleType, std::move(config)); + if (module == nullptr) return result; + result = std::move(module); + } + const std::string moduleFqn = std::string().append(Module::descriptor).append("/").append(name); + binder_status_t status = AServiceManager_addService(result.getBinder(), moduleFqn.c_str()); + if (status != STATUS_OK) { + LOG(ERROR) << __func__ << ": failed to register service for \"" << moduleFqn << "\""; + return ChildInterface(); + } + return result; +}; + +} // namespace int main() { // Random values are used in the implementation. @@ -45,29 +75,27 @@ int main() { // Guaranteed log for b/210919187 and logd_integration_test LOG(INFO) << "Init for Audio AIDL HAL"; + AudioPolicyConfigXmlConverter audioPolicyConverter{ + ::android::audio_get_audio_policy_config_file()}; + // Make the default config service - auto config = ndk::SharedRefBase::make(); - const std::string configName = std::string() + Config::descriptor + "/default"; + auto config = ndk::SharedRefBase::make(audioPolicyConverter); + const std::string configFqn = std::string().append(Config::descriptor).append("/default"); binder_status_t status = - AServiceManager_addService(config->asBinder().get(), configName.c_str()); - CHECK_EQ(STATUS_OK, status); + AServiceManager_addService(config->asBinder().get(), configFqn.c_str()); + if (status != STATUS_OK) { + LOG(ERROR) << "failed to register service for \"" << configFqn << "\""; + } // Make modules - auto createModule = [](Module::Type type) { - auto module = Module::createInstance(type); - ndk::SpAIBinder moduleBinder = module->asBinder(); - std::stringstream moduleName; - moduleName << Module::descriptor << "/" << type; - AIBinder_setMinSchedulerPolicy(moduleBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); - binder_status_t status = - AServiceManager_addService(moduleBinder.get(), moduleName.str().c_str()); - CHECK_EQ(STATUS_OK, status); - return std::make_pair(module, moduleBinder); - }; - auto modules = {createModule(Module::Type::DEFAULT), createModule(Module::Type::R_SUBMIX), - createModule(Module::Type::USB), createModule(Module::Type::STUB), - createModule(Module::Type::BLUETOOTH)}; - (void)modules; + std::vector> moduleInstances; + auto configs(audioPolicyConverter.releaseModuleConfigs()); + for (std::pair>& configPair : *configs) { + std::string name = configPair.first; + if (auto instance = createModule(name, std::move(configPair.second)); instance) { + moduleInstances.push_back(std::move(instance)); + } + } ABinderProcess_joinThreadPool(); return EXIT_FAILURE; // should not reach