Add missing Cap Settings aidl support and helper
Bug: 307310023
Test: atest AudioCoreConfig
Change-Id: I08c71ce9a67f065df36f71c0602e2c9e4e97ae6b
Signed-off-by: François Gaffie <francois.gaffie@renault.com>
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index f5b590b..f51f65e 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -54,6 +54,7 @@
"AidlConversionXsdc.cpp",
"AudioPolicyConfigXmlConverter.cpp",
"Bluetooth.cpp",
+ "CapEngineConfigXmlConverter.cpp",
"Config.cpp",
"Configuration.cpp",
"EngineConfigXmlConverter.cpp",
@@ -83,14 +84,17 @@
"usb/UsbAlsaMixerControl.cpp",
],
generated_sources: [
+ "audio_policy_capengine_configuration_aidl_default",
"audio_policy_configuration_aidl_default",
"audio_policy_engine_configuration_aidl_default",
],
generated_headers: [
+ "audio_policy_capengine_configuration_aidl_default",
"audio_policy_configuration_aidl_default",
"audio_policy_engine_configuration_aidl_default",
],
export_generated_headers: [
+ "audio_policy_capengine_configuration_aidl_default",
"audio_policy_configuration_aidl_default",
"audio_policy_engine_configuration_aidl_default",
],
diff --git a/audio/aidl/default/CapEngineConfigXmlConverter.cpp b/audio/aidl/default/CapEngineConfigXmlConverter.cpp
new file mode 100644
index 0000000..8210664
--- /dev/null
+++ b/audio/aidl/default/CapEngineConfigXmlConverter.cpp
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2024 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_Config"
+
+#include <aidl/android/media/audio/common/AudioProductStrategyType.h>
+#include <android-base/logging.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/TypeConverter.h>
+#include <media/convert.h>
+#include <utils/FastStrcmp.h>
+
+#include "core-impl/CapEngineConfigXmlConverter.h"
+#include "core-impl/XsdcConversion.h"
+
+using aidl::android::hardware::audio::common::iequals;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioHalCapConfiguration;
+using aidl::android::media::audio::common::AudioHalCapCriterionV2;
+using aidl::android::media::audio::common::AudioHalCapDomain;
+using aidl::android::media::audio::common::AudioHalCapParameter;
+using aidl::android::media::audio::common::AudioHalCapRule;
+using aidl::android::media::audio::common::AudioPolicyForceUse;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
+
+using ::android::BAD_VALUE;
+using ::android::base::unexpected;
+using ::android::utilities::convertTo;
+
+namespace eng_xsd = android::audio::policy::capengine::configuration;
+
+namespace aidl::android::hardware::audio::core::internal {
+
+static constexpr const char* gStrategiesParameter = "product_strategies";
+static constexpr const char* gInputSourcesParameter = "input_sources";
+static constexpr const char* gStreamsParameter = "streams";
+static constexpr const char* gOutputDevicesParameter = "selected_output_devices";
+static constexpr const char* gOutputDeviceAddressParameter = "device_address";
+static constexpr const char* gStrategyPrefix = "vx_";
+static constexpr const char* gLegacyOutputDevicePrefix = "AUDIO_DEVICE_OUT_";
+static constexpr const char* gLegacyInputDevicePrefix = "AUDIO_DEVICE_IN_";
+static constexpr const char* gLegacyStreamPrefix = "AUDIO_STREAM_";
+static constexpr const char* gLegacySourcePrefix = "AUDIO_SOURCE_";
+
+std::optional<std::vector<std::optional<AudioHalCapDomain>>>&
+CapEngineConfigXmlConverter::getAidlCapEngineConfig() {
+ return mAidlCapDomains;
+}
+
+ConversionResult<AudioHalCapRule::CriterionRule> convertCriterionRuleToAidl(
+ const eng_xsd::SelectionCriterionRuleType& xsdcRule) {
+ using Tag = AudioHalCapCriterionV2::Tag;
+ AudioHalCapRule::CriterionRule rule{};
+ std::string criterionName = xsdcRule.getSelectionCriterion();
+ std::string criterionValue = xsdcRule.getValue();
+ if (iequals(criterionName, toString(Tag::availableInputDevices))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::availableInputDevices>();
+ rule.criterionTypeValue =
+ VALUE_OR_RETURN(convertDeviceTypeToAidl(gLegacyInputDevicePrefix + criterionValue));
+ } else if (iequals(criterionName, toString(Tag::availableOutputDevices))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::availableOutputDevices>();
+ rule.criterionTypeValue = VALUE_OR_RETURN(
+ convertDeviceTypeToAidl(gLegacyOutputDevicePrefix + criterionValue));
+ } else if (iequals(criterionName, toString(Tag::availableInputDevicesAddresses))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::availableInputDevicesAddresses>();
+ rule.criterionTypeValue =
+ AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(criterionValue);
+ } else if (iequals(criterionName, toString(Tag::availableOutputDevicesAddresses))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::availableOutputDevicesAddresses>();
+ rule.criterionTypeValue =
+ AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(criterionValue);
+ } else if (iequals(criterionName, toString(Tag::telephonyMode))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::telephonyMode>();
+ rule.criterionTypeValue = VALUE_OR_RETURN(convertTelephonyModeToAidl(criterionValue));
+ } else if (!fastcmp<strncmp>(criterionName.c_str(), kXsdcForceConfigForUse,
+ strlen(kXsdcForceConfigForUse))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::forceConfigForUse>(
+ VALUE_OR_RETURN(convertForceUseCriterionToAidl(criterionName)));
+ rule.criterionTypeValue = VALUE_OR_RETURN(convertForcedConfigToAidl(criterionValue));
+ } else {
+ LOG(ERROR) << __func__ << " unrecognized criterion " << criterionName;
+ return unexpected(BAD_VALUE);
+ }
+ if (xsdcRule.getMatchesWhen() == eng_xsd::MatchesWhenEnum::Excludes) {
+ rule.matchingRule = AudioHalCapRule::MatchingRule::EXCLUDES;
+ } else if (xsdcRule.getMatchesWhen() == eng_xsd::MatchesWhenEnum::Includes) {
+ rule.matchingRule = AudioHalCapRule::MatchingRule::INCLUDES;
+ } else if (xsdcRule.getMatchesWhen() == eng_xsd::MatchesWhenEnum::Is) {
+ rule.matchingRule = AudioHalCapRule::MatchingRule::IS;
+ } else if (xsdcRule.getMatchesWhen() == eng_xsd::MatchesWhenEnum::IsNot) {
+ rule.matchingRule = AudioHalCapRule::MatchingRule::IS_NOT;
+ } else {
+ LOG(ERROR) << "Unsupported match when rule.";
+ return unexpected(BAD_VALUE);
+ }
+ return rule;
+}
+
+ConversionResult<AudioHalCapRule> convertRule(const eng_xsd::CompoundRuleType& xsdcCompoundRule) {
+ AudioHalCapRule rule{};
+ bool isPreviousCompoundRule = true;
+ if (xsdcCompoundRule.getType() == eng_xsd::TypeEnum::Any) {
+ rule.compoundRule = AudioHalCapRule::CompoundRule::ANY;
+ } else if (xsdcCompoundRule.getType() == eng_xsd::TypeEnum::All) {
+ rule.compoundRule = AudioHalCapRule::CompoundRule::ALL;
+ } else {
+ LOG(ERROR) << "Unsupported compound rule type.";
+ return unexpected(BAD_VALUE);
+ }
+ for (const auto& childXsdcCoumpoundRule : xsdcCompoundRule.getCompoundRule_optional()) {
+ if (childXsdcCoumpoundRule.hasCompoundRule_optional()) {
+ rule.nestedRules.push_back(VALUE_OR_FATAL(convertRule(childXsdcCoumpoundRule)));
+ } else if (childXsdcCoumpoundRule.hasSelectionCriterionRule_optional()) {
+ rule.nestedRules.push_back(VALUE_OR_FATAL(convertRule(childXsdcCoumpoundRule)));
+ }
+ }
+ if (xsdcCompoundRule.hasSelectionCriterionRule_optional()) {
+ for (const auto& xsdcRule : xsdcCompoundRule.getSelectionCriterionRule_optional()) {
+ rule.criterionRules.push_back(VALUE_OR_FATAL(convertCriterionRuleToAidl(xsdcRule)));
+ }
+ }
+ return rule;
+}
+
+ConversionResult<int> getAudioProductStrategyId(const std::string& path) {
+ std::vector<std::string> strings;
+ std::istringstream pathStream(path);
+ std::string stringToken;
+ while (getline(pathStream, stringToken, '/')) {
+ std::size_t pos = stringToken.find(gStrategyPrefix);
+ if (pos != std::string::npos) {
+ std::string strategyIdLiteral = stringToken.substr(pos + std::strlen(gStrategyPrefix));
+ int strategyId;
+ if (!convertTo(strategyIdLiteral, strategyId)) {
+ LOG(ERROR) << "Invalid strategy " << stringToken << " from path " << path;
+ return unexpected(BAD_VALUE);
+ }
+ return strategyId;
+ }
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioSource> getAudioSource(const std::string& path) {
+ std::vector<std::string> strings;
+ std::istringstream pathStream(path);
+ std::string stringToken;
+ while (getline(pathStream, stringToken, '/')) {
+ if (stringToken.find(gInputSourcesParameter) != std::string::npos) {
+ getline(pathStream, stringToken, '/');
+ std::transform(stringToken.begin(), stringToken.end(), stringToken.begin(),
+ [](char c) { return std::toupper(c); });
+ std::string legacySourceLiteral = "AUDIO_SOURCE_" + stringToken;
+ audio_source_t legacySource;
+ if (!::android::SourceTypeConverter::fromString(legacySourceLiteral, legacySource)) {
+ LOG(ERROR) << "Invalid source " << stringToken << " from path " << path;
+ return unexpected(BAD_VALUE);
+ }
+ return legacy2aidl_audio_source_t_AudioSource(legacySource);
+ }
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioStreamType> getAudioStreamType(const std::string& path) {
+ std::vector<std::string> strings;
+ std::istringstream pathStream(path);
+ std::string stringToken;
+
+ while (getline(pathStream, stringToken, '/')) {
+ if (stringToken.find(gStreamsParameter) != std::string::npos) {
+ getline(pathStream, stringToken, '/');
+ std::transform(stringToken.begin(), stringToken.end(), stringToken.begin(),
+ [](char c) { return std::toupper(c); });
+ std::string legacyStreamLiteral = std::string(gLegacyStreamPrefix) + stringToken;
+ audio_stream_type_t legacyStream;
+ if (!::android::StreamTypeConverter::fromString(legacyStreamLiteral, legacyStream)) {
+ LOG(ERROR) << "Invalid stream " << stringToken << " from path " << path;
+ return unexpected(BAD_VALUE);
+ }
+ return legacy2aidl_audio_stream_type_t_AudioStreamType(legacyStream);
+ }
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<std::string> toUpperAndAppendPrefix(const std::string& capName,
+ const std::string& legacyPrefix) {
+ std::string legacyName = capName;
+ std::transform(legacyName.begin(), legacyName.end(), legacyName.begin(),
+ [](char c) { return std::toupper(c); });
+ return legacyPrefix + legacyName;
+}
+
+ConversionResult<AudioHalCapParameter> CapEngineConfigXmlConverter::convertParamToAidl(
+ const eng_xsd::ConfigurableElementSettingsType& element) {
+ const auto& path = element.getPath();
+
+ AudioHalCapParameter parameterSetting;
+ if (path.find(gStrategiesParameter) != std::string::npos) {
+ int strategyId = VALUE_OR_FATAL(getAudioProductStrategyId(path));
+ if (path.find(gOutputDevicesParameter) != std::string::npos) {
+ // Value is 1 or 0
+ if (!element.hasBitParameter_optional()) {
+ LOG(ERROR) << "Invalid strategy value type";
+ return unexpected(BAD_VALUE);
+ }
+ // Convert name to output device type
+ const auto* xsdcParam = element.getFirstBitParameter_optional();
+ std::string outputDevice = VALUE_OR_FATAL(toUpperAndAppendPrefix(
+ eng_xsd::toString(xsdcParam->getName()), gLegacyOutputDevicePrefix));
+ audio_devices_t legacyType;
+ if (!::android::OutputDeviceConverter::fromString(outputDevice, legacyType)) {
+ LOG(ERROR) << "Invalid strategy device type " << outputDevice;
+ return unexpected(BAD_VALUE);
+ }
+ AudioDeviceDescription aidlDevice =
+ VALUE_OR_FATAL(legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyType));
+ bool isSelected;
+ if (!convertTo(xsdcParam->getValue(), isSelected)) {
+ LOG(ERROR) << "Invalid strategy device selection value " << xsdcParam->getValue();
+ return unexpected(BAD_VALUE);
+ }
+ parameterSetting =
+ AudioHalCapParameter::StrategyDevice(aidlDevice, strategyId, isSelected);
+ } else if (path.find(gOutputDeviceAddressParameter) != std::string::npos) {
+ // Value is the address
+ if (!element.hasStringParameter_optional()) {
+ return unexpected(BAD_VALUE);
+ }
+ std::string address = element.getFirstStringParameter_optional()->getValue();
+ parameterSetting = AudioHalCapParameter::StrategyDeviceAddress(
+ AudioDeviceAddress(address), strategyId);
+ }
+ } else if (path.find(gInputSourcesParameter) != std::string::npos) {
+ // Value is 1 or 0
+ if (!element.hasBitParameter_optional()) {
+ LOG(ERROR) << "Invalid source value type";
+ return unexpected(BAD_VALUE);
+ }
+ AudioSource audioSourceAidl = VALUE_OR_FATAL(getAudioSource(path));
+ const auto* xsdcParam = element.getFirstBitParameter_optional();
+ std::string inputDeviceLiteral = VALUE_OR_FATAL(toUpperAndAppendPrefix(
+ eng_xsd::toString(xsdcParam->getName()), gLegacyInputDevicePrefix));
+ audio_devices_t inputDeviceType;
+ if (!::android::InputDeviceConverter::fromString(inputDeviceLiteral, inputDeviceType)) {
+ LOG(ERROR) << "Invalid source device type " << inputDeviceLiteral;
+ return unexpected(BAD_VALUE);
+ }
+ AudioDeviceDescription aidlDevice =
+ VALUE_OR_FATAL(legacy2aidl_audio_devices_t_AudioDeviceDescription(inputDeviceType));
+
+ bool isSelected;
+ if (!convertTo(xsdcParam->getValue(), isSelected)) {
+ LOG(ERROR) << "Invalid source value type " << xsdcParam->getValue();
+ return unexpected(BAD_VALUE);
+ }
+ parameterSetting =
+ AudioHalCapParameter::InputSourceDevice(aidlDevice, audioSourceAidl, isSelected);
+ } else if (path.find(gStreamsParameter) != std::string::npos) {
+ AudioStreamType audioStreamAidl = VALUE_OR_FATAL(getAudioStreamType(path));
+ if (!element.hasEnumParameter_optional()) {
+ LOG(ERROR) << "Invalid stream value type";
+ return unexpected(BAD_VALUE);
+ }
+ const auto* xsdcParam = element.getFirstEnumParameter_optional();
+ std::string profileLiteral =
+ VALUE_OR_FATAL(toUpperAndAppendPrefix(xsdcParam->getValue(), gLegacyStreamPrefix));
+ audio_stream_type_t profileLegacyStream;
+ if (!::android::StreamTypeConverter::fromString(profileLiteral, profileLegacyStream)) {
+ LOG(ERROR) << "Invalid stream value " << profileLiteral;
+ return unexpected(BAD_VALUE);
+ }
+ AudioStreamType profileStreamAidl = VALUE_OR_FATAL(
+ legacy2aidl_audio_stream_type_t_AudioStreamType(profileLegacyStream));
+ parameterSetting =
+ AudioHalCapParameter::StreamVolumeProfile(audioStreamAidl, profileStreamAidl);
+ }
+ return parameterSetting;
+}
+
+ConversionResult<std::vector<AudioHalCapParameter>>
+CapEngineConfigXmlConverter::convertSettingToAidl(
+ const eng_xsd::SettingsType::Configuration& xsdcSetting) {
+ std::vector<AudioHalCapParameter> aidlCapParameterSettings;
+ for (const auto& element : xsdcSetting.getConfigurableElement()) {
+ aidlCapParameterSettings.push_back(VALUE_OR_FATAL(convertParamToAidl(element)));
+ }
+ return aidlCapParameterSettings;
+}
+
+ConversionResult<AudioHalCapConfiguration> CapEngineConfigXmlConverter::convertConfigurationToAidl(
+ const eng_xsd::ConfigurationsType::Configuration& xsdcConfiguration,
+ const eng_xsd::SettingsType::Configuration& xsdcSettingConfiguration) {
+ AudioHalCapConfiguration aidlCapConfiguration;
+ aidlCapConfiguration.name = xsdcConfiguration.getName();
+ if (xsdcConfiguration.hasCompoundRule()) {
+ if (xsdcConfiguration.getCompoundRule().size() != 1) {
+ return unexpected(BAD_VALUE);
+ }
+ aidlCapConfiguration.rule =
+ VALUE_OR_FATAL(convertRule(xsdcConfiguration.getCompoundRule()[0]));
+ aidlCapConfiguration.parameterSettings =
+ VALUE_OR_FATAL(convertSettingToAidl(xsdcSettingConfiguration));
+ }
+ return aidlCapConfiguration;
+}
+
+ConversionResult<eng_xsd::SettingsType::Configuration> getConfigurationByName(
+ const std::string& name, const std::vector<eng_xsd::SettingsType>& xsdcSettingsVec) {
+ for (const auto& xsdcSettings : xsdcSettingsVec) {
+ for (const auto& xsdcConfiguration : xsdcSettings.getConfiguration()) {
+ if (xsdcConfiguration.getName() == name) {
+ return xsdcConfiguration;
+ }
+ }
+ }
+ LOG(ERROR) << __func__ << " failed to find configuration " << name;
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<std::vector<AudioHalCapConfiguration>>
+CapEngineConfigXmlConverter::convertConfigurationsToAidl(
+ const std::vector<eng_xsd::ConfigurationsType>& xsdcConfigurationsVec,
+ const std::vector<eng_xsd::SettingsType>& xsdcSettingsVec) {
+ if (xsdcConfigurationsVec.empty() || xsdcSettingsVec.empty()) {
+ LOG(ERROR) << __func__ << " empty configurations/settings";
+ return unexpected(BAD_VALUE);
+ }
+ std::vector<AudioHalCapConfiguration> aidlConfigurations;
+ for (const auto& xsdcConfigurations : xsdcConfigurationsVec) {
+ for (const auto& xsdcConfiguration : xsdcConfigurations.getConfiguration()) {
+ auto xsdcSettingConfiguration = VALUE_OR_FATAL(
+ getConfigurationByName(xsdcConfiguration.getName(), xsdcSettingsVec));
+ aidlConfigurations.push_back(VALUE_OR_FATAL(
+ convertConfigurationToAidl(xsdcConfiguration, xsdcSettingConfiguration)));
+ }
+ }
+ return aidlConfigurations;
+}
+
+ConversionResult<AudioHalCapDomain> CapEngineConfigXmlConverter::convertConfigurableDomainToAidl(
+ const eng_xsd::ConfigurableDomainType& xsdcConfigurableDomain) {
+ AudioHalCapDomain aidlConfigurableDomain;
+
+ aidlConfigurableDomain.name = xsdcConfigurableDomain.getName();
+ if (xsdcConfigurableDomain.hasSequenceAware() && xsdcConfigurableDomain.getSequenceAware()) {
+ LOG(ERROR) << "sequence aware not supported.";
+ return unexpected(BAD_VALUE);
+ }
+ if (xsdcConfigurableDomain.hasConfigurations() && xsdcConfigurableDomain.hasSettings()) {
+ aidlConfigurableDomain.configurations = VALUE_OR_FATAL(convertConfigurationsToAidl(
+ xsdcConfigurableDomain.getConfigurations(), xsdcConfigurableDomain.getSettings()));
+ }
+ return aidlConfigurableDomain;
+}
+
+void CapEngineConfigXmlConverter::init() {
+ if (getXsdcConfig()->hasConfigurableDomain()) {
+ mAidlCapDomains = std::make_optional<>(VALUE_OR_FATAL(
+ (convertCollectionToAidlOptionalValues<eng_xsd::ConfigurableDomainType,
+ AudioHalCapDomain>(
+ getXsdcConfig()->getConfigurableDomain(),
+ std::bind(&CapEngineConfigXmlConverter::convertConfigurableDomainToAidl,
+ this, std::placeholders::_1)))));
+ } else {
+ mAidlCapDomains = std::nullopt;
+ }
+}
+
+} // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/EngineConfigXmlConverter.cpp b/audio/aidl/default/EngineConfigXmlConverter.cpp
index 631cdce..5a8b0a3 100644
--- a/audio/aidl/default/EngineConfigXmlConverter.cpp
+++ b/audio/aidl/default/EngineConfigXmlConverter.cpp
@@ -26,15 +26,19 @@
#include <aidl/android/media/audio/common/AudioProductStrategyType.h>
#include <android-base/logging.h>
+#include "core-impl/CapEngineConfigXmlConverter.h"
#include "core-impl/EngineConfigXmlConverter.h"
#include "core-impl/XsdcConversion.h"
+using aidl::android::hardware::audio::core::internal::CapEngineConfigXmlConverter;
+using aidl::android::hardware::audio::core::internal::convertAudioUsageToAidl;
using aidl::android::media::audio::common::AudioAttributes;
using aidl::android::media::audio::common::AudioContentType;
using aidl::android::media::audio::common::AudioFlag;
using aidl::android::media::audio::common::AudioHalAttributesGroup;
using aidl::android::media::audio::common::AudioHalCapCriterion;
using aidl::android::media::audio::common::AudioHalCapCriterionType;
+using aidl::android::media::audio::common::AudioHalCapCriterionV2;
using aidl::android::media::audio::common::AudioHalEngineConfig;
using aidl::android::media::audio::common::AudioHalProductStrategy;
using aidl::android::media::audio::common::AudioHalVolumeCurve;
@@ -43,6 +47,7 @@
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;
@@ -50,6 +55,10 @@
namespace aidl::android::hardware::audio::core::internal {
+/** Default path of audio policy cap engine configuration file. */
+static constexpr char kCapEngineConfigFileName[] =
+ "/parameter-framework/Settings/Policy/PolicyConfigurableDomains.xml";
+
void EngineConfigXmlConverter::initProductStrategyMap() {
#define STRATEGY_ENTRY(name) {"STRATEGY_" #name, static_cast<int>(AudioProductStrategyType::name)}
@@ -74,6 +83,13 @@
return it->second;
}
+ConversionResult<int> EngineConfigXmlConverter::convertProductStrategyIdToAidl(int xsdcId) {
+ if (xsdcId < AudioHalProductStrategy::VENDOR_STRATEGY_ID_START) {
+ return unexpected(BAD_VALUE);
+ }
+ return xsdcId;
+}
+
bool isDefaultAudioAttributes(const AudioAttributes& attributes) {
return ((attributes.contentType == AudioContentType::UNKNOWN) &&
(attributes.usage == AudioUsage::UNKNOWN) &&
@@ -95,29 +111,26 @@
}
AudioAttributes aidlAudioAttributes;
if (xsdcAudioAttributes.hasContentType()) {
- aidlAudioAttributes.contentType = static_cast<AudioContentType>(
- xsdcAudioAttributes.getFirstContentType()->getValue());
+ aidlAudioAttributes.contentType = VALUE_OR_FATAL(convertAudioContentTypeToAidl(
+ xsdcAudioAttributes.getFirstContentType()->getValue()));
}
if (xsdcAudioAttributes.hasUsage()) {
- aidlAudioAttributes.usage =
- static_cast<AudioUsage>(xsdcAudioAttributes.getFirstUsage()->getValue());
+ aidlAudioAttributes.usage = VALUE_OR_FATAL(
+ convertAudioUsageToAidl(xsdcAudioAttributes.getFirstUsage()->getValue()));
}
if (xsdcAudioAttributes.hasSource()) {
- aidlAudioAttributes.source =
- static_cast<AudioSource>(xsdcAudioAttributes.getFirstSource()->getValue());
+ aidlAudioAttributes.source = VALUE_OR_FATAL(
+ convertAudioSourceToAidl(xsdcAudioAttributes.getFirstSource()->getValue()));
}
if (xsdcAudioAttributes.hasFlags()) {
std::vector<eng_xsd::FlagType> xsdcFlagTypeVec =
xsdcAudioAttributes.getFirstFlags()->getValue();
- for (const eng_xsd::FlagType& xsdcFlagType : xsdcFlagTypeVec) {
- if (xsdcFlagType != eng_xsd::FlagType::AUDIO_FLAG_NONE) {
- aidlAudioAttributes.flags |= 1 << (static_cast<int>(xsdcFlagType) - 1);
- }
- }
+ aidlAudioAttributes.flags = VALUE_OR_FATAL(convertAudioFlagsToAidl(xsdcFlagTypeVec));
}
if (xsdcAudioAttributes.hasBundle()) {
const eng_xsd::BundleType* xsdcBundle = xsdcAudioAttributes.getFirstBundle();
- aidlAudioAttributes.tags[0] = xsdcBundle->getKey() + "=" + xsdcBundle->getValue();
+ aidlAudioAttributes.tags.reserve(1);
+ aidlAudioAttributes.tags.push_back(xsdcBundle->getKey() + "_" + xsdcBundle->getValue());
}
if (isDefaultAudioAttributes(aidlAudioAttributes)) {
mDefaultProductStrategyId = std::optional<int>{-1};
@@ -131,8 +144,10 @@
static const int kStreamTypeEnumOffset =
static_cast<int>(eng_xsd::Stream::AUDIO_STREAM_VOICE_CALL) -
static_cast<int>(AudioStreamType::VOICE_CALL);
- aidlAttributesGroup.streamType = static_cast<AudioStreamType>(
- static_cast<int>(xsdcAttributesGroup.getStreamType()) - kStreamTypeEnumOffset);
+ aidlAttributesGroup.streamType = xsdcAttributesGroup.hasStreamType()
+ ? VALUE_OR_FATAL(convertAudioStreamTypeToAidl(
+ xsdcAttributesGroup.getStreamType()))
+ : AudioStreamType::INVALID;
aidlAttributesGroup.volumeGroupName = xsdcAttributesGroup.getVolumeGroup();
if (xsdcAttributesGroup.hasAttributes_optional()) {
aidlAttributesGroup.attributes =
@@ -165,7 +180,8 @@
AudioHalProductStrategy aidlProductStrategy;
aidlProductStrategy.id =
- VALUE_OR_FATAL(convertProductStrategyNameToAidl(xsdcProductStrategy.getName()));
+ VALUE_OR_FATAL(convertProductStrategyIdToAidl(xsdcProductStrategy.getId()));
+ aidlProductStrategy.name = xsdcProductStrategy.getName();
if (xsdcProductStrategy.hasAttributesGroup()) {
aidlProductStrategy.attributesGroups = VALUE_OR_FATAL(
@@ -247,18 +263,15 @@
}
if (getXsdcConfig()->hasCriteria() && getXsdcConfig()->hasCriterion_types()) {
AudioHalEngineConfig::CapSpecificConfig capSpecificConfig;
- capSpecificConfig.criteria = VALUE_OR_FATAL(
- (convertWrappedCollectionToAidl<eng_xsd::CriteriaType, eng_xsd::CriterionType,
- AudioHalCapCriterion>(
- getXsdcConfig()->getCriteria(), &eng_xsd::CriteriaType::getCriterion,
- &convertCapCriterionToAidl)));
- capSpecificConfig.criterionTypes =
- VALUE_OR_FATAL((convertWrappedCollectionToAidl<eng_xsd::CriterionTypesType,
- eng_xsd::CriterionTypeType,
- AudioHalCapCriterionType>(
- getXsdcConfig()->getCriterion_types(),
- &eng_xsd::CriterionTypesType::getCriterion_type,
- &convertCapCriterionTypeToAidl)));
+ capSpecificConfig.criteriaV2 =
+ std::make_optional<>(VALUE_OR_FATAL((convertCapCriteriaCollectionToAidl(
+ getXsdcConfig()->getCriteria(), getXsdcConfig()->getCriterion_types()))));
+ internal::CapEngineConfigXmlConverter capEngConfigConverter{
+ ::android::audio_find_readable_configuration_file(kCapEngineConfigFileName)};
+ if (capEngConfigConverter.getStatus() == ::android::OK) {
+ capSpecificConfig.domains = std::move(capEngConfigConverter.getAidlCapEngineConfig());
+ }
+ mAidlEngineConfig.capSpecificConfig = capSpecificConfig;
}
}
} // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/XsdcConversion.cpp b/audio/aidl/default/XsdcConversion.cpp
index 1720949..ba6110d 100644
--- a/audio/aidl/default/XsdcConversion.cpp
+++ b/audio/aidl/default/XsdcConversion.cpp
@@ -10,11 +10,21 @@
#include <aidl/android/media/audio/common/AudioPortConfig.h>
#include <media/AidlConversionCppNdk.h>
#include <media/TypeConverter.h>
+#include <media/convert.h>
+#include <utils/FastStrcmp.h>
+
+#include <Utils.h>
#include "core-impl/XmlConverter.h"
#include "core-impl/XsdcConversion.h"
+using aidl::android::hardware::audio::common::iequals;
+using aidl::android::hardware::audio::common::isValidAudioMode;
+using aidl::android::hardware::audio::common::isValidAudioPolicyForcedConfig;
+using aidl::android::hardware::audio::common::kValidAudioModes;
+using aidl::android::hardware::audio::common::kValidAudioPolicyForcedConfig;
using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioContentType;
using aidl::android::media::audio::common::AudioDevice;
using aidl::android::media::audio::common::AudioDeviceAddress;
using aidl::android::media::audio::common::AudioDeviceDescription;
@@ -24,22 +34,39 @@
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::AudioHalCapCriterionV2;
using aidl::android::media::audio::common::AudioHalVolumeCurve;
using aidl::android::media::audio::common::AudioIoFlags;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::AudioPolicyForcedConfig;
+using aidl::android::media::audio::common::AudioPolicyForceUse;
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 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;
+using ::android::utilities::convertTo;
namespace ap_xsd = android::audio::policy::configuration;
namespace eng_xsd = android::audio::policy::engine::configuration;
namespace aidl::android::hardware::audio::core::internal {
+static constexpr const char kXsdcForceConfigForCommunication[] = "ForceUseForCommunication";
+static constexpr const char kXsdcForceConfigForMedia[] = "ForceUseForMedia";
+static constexpr const char kXsdcForceConfigForRecord[] = "ForceUseForRecord";
+static constexpr const char kXsdcForceConfigForDock[] = "ForceUseForDock";
+static constexpr const char kXsdcForceConfigForSystem[] = "ForceUseForSystem";
+static constexpr const char kXsdcForceConfigForHdmiSystemAudio[] = "ForceUseForHdmiSystemAudio";
+static constexpr const char kXsdcForceConfigForEncodedSurround[] = "ForceUseForEncodedSurround";
+static constexpr const char kXsdcForceConfigForVibrateRinging[] = "ForceUseForVibrateRinging";
+
inline ConversionResult<std::string> assertNonEmpty(const std::string& s) {
if (s.empty()) {
LOG(ERROR) << __func__ << " Review Audio Policy config: "
@@ -51,6 +78,100 @@
#define NON_EMPTY_STRING_OR_FATAL(s) VALUE_OR_FATAL(assertNonEmpty(s))
+ConversionResult<int32_t> convertAudioFlagsToAidl(
+ const std::vector<eng_xsd::FlagType>& xsdcFlagTypeVec) {
+ int legacyFlagMask = 0;
+ for (const eng_xsd::FlagType& xsdcFlagType : xsdcFlagTypeVec) {
+ if (xsdcFlagType != eng_xsd::FlagType::AUDIO_FLAG_NONE) {
+ audio_flags_mask_t legacyFlag = AUDIO_FLAG_NONE;
+ if (!::android::AudioFlagConverter::fromString(eng_xsd::toString(xsdcFlagType),
+ legacyFlag)) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, "
+ << eng_xsd::toString(xsdcFlagType) << " is not a valid flag.";
+ return unexpected(BAD_VALUE);
+ }
+ legacyFlagMask |= static_cast<int>(legacyFlag);
+ }
+ }
+ ConversionResult<int32_t> result = legacy2aidl_audio_flags_mask_t_int32_t_mask(
+ static_cast<audio_flags_mask_t>(legacyFlagMask));
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyFlagMask
+ << " has invalid flag(s).";
+ return unexpected(BAD_VALUE);
+ }
+ return result;
+}
+
+ConversionResult<AudioStreamType> convertAudioStreamTypeToAidl(const eng_xsd::Stream& xsdcStream) {
+ audio_stream_type_t legacyStreamType;
+ if (!::android::StreamTypeConverter::fromString(eng_xsd::toString(xsdcStream),
+ legacyStreamType)) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, " << eng_xsd::toString(xsdcStream)
+ << " is not a valid audio stream type.";
+ return unexpected(BAD_VALUE);
+ }
+ ConversionResult<AudioStreamType> result =
+ legacy2aidl_audio_stream_type_t_AudioStreamType(legacyStreamType);
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyStreamType
+ << " is not a valid audio stream type.";
+ return unexpected(BAD_VALUE);
+ }
+ return result;
+}
+
+ConversionResult<AudioSource> convertAudioSourceToAidl(
+ const eng_xsd::SourceEnumType& xsdcSourceType) {
+ audio_source_t legacySourceType;
+ if (!::android::SourceTypeConverter::fromString(eng_xsd::toString(xsdcSourceType),
+ legacySourceType)) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, "
+ << eng_xsd::toString(xsdcSourceType) << " is not a valid audio source.";
+ return unexpected(BAD_VALUE);
+ }
+ ConversionResult<AudioSource> result = legacy2aidl_audio_source_t_AudioSource(legacySourceType);
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacySourceType
+ << " is not a valid audio source.";
+ return unexpected(BAD_VALUE);
+ }
+ return result;
+}
+
+ConversionResult<AudioContentType> convertAudioContentTypeToAidl(
+ const eng_xsd::ContentType& xsdcContentType) {
+ audio_content_type_t legacyContentType;
+ if (!::android::AudioContentTypeConverter::fromString(eng_xsd::toString(xsdcContentType),
+ legacyContentType)) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, "
+ << eng_xsd::toString(xsdcContentType) << " is not a valid audio content type.";
+ return unexpected(BAD_VALUE);
+ }
+ ConversionResult<AudioContentType> result =
+ legacy2aidl_audio_content_type_t_AudioContentType(legacyContentType);
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyContentType
+ << " is not a valid audio content type.";
+ return unexpected(BAD_VALUE);
+ }
+ return result;
+}
+
+ConversionResult<AudioUsage> convertAudioUsageToAidl(const eng_xsd::UsageEnumType& xsdcUsage) {
+ audio_usage_t legacyUsage;
+ if (!::android::UsageTypeConverter::fromString(eng_xsd::toString(xsdcUsage), legacyUsage)) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, not a valid audio usage.";
+ return unexpected(BAD_VALUE);
+ }
+ ConversionResult<AudioUsage> result = legacy2aidl_audio_usage_t_AudioUsage(legacyUsage);
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, not a valid audio usage.";
+ return unexpected(BAD_VALUE);
+ }
+ return result;
+}
+
ConversionResult<AudioFormatDescription> convertAudioFormatToAidl(const std::string& xsdcFormat) {
audio_format_t legacyFormat = ::android::formatFromString(xsdcFormat, AUDIO_FORMAT_DEFAULT);
ConversionResult<AudioFormatDescription> result =
@@ -410,32 +531,240 @@
return result;
}
+ConversionResult<AudioPolicyForcedConfig> convertForcedConfigToAidl(
+ const std::string& xsdcForcedConfigCriterionType) {
+ const auto it = std::find_if(
+ kValidAudioPolicyForcedConfig.begin(), kValidAudioPolicyForcedConfig.end(),
+ [&](const auto& config) { return toString(config) == xsdcForcedConfigCriterionType; });
+ if (it == kValidAudioPolicyForcedConfig.end()) {
+ LOG(ERROR) << __func__ << " invalid forced config " << xsdcForcedConfigCriterionType;
+ return unexpected(BAD_VALUE);
+ }
+ return *it;
+}
+
+ConversionResult<AudioMode> convertTelephonyModeToAidl(const std::string& xsdcModeCriterionType) {
+ const auto it = std::find_if(kValidAudioModes.begin(), kValidAudioModes.end(),
+ [&xsdcModeCriterionType](const auto& mode) {
+ return toString(mode) == xsdcModeCriterionType;
+ });
+ if (it == kValidAudioModes.end()) {
+ LOG(ERROR) << __func__ << " invalid mode " << xsdcModeCriterionType;
+ return unexpected(BAD_VALUE);
+ }
+ return *it;
+}
+
+ConversionResult<AudioDeviceAddress> convertDeviceAddressToAidl(const std::string& xsdcAddress) {
+ return AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(xsdcAddress);
+}
+
+ConversionResult<eng_xsd::CriterionTypeType> getCriterionTypeByName(
+ const std::string& name,
+ const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
+ for (const auto& xsdCriterionTypes : xsdcCriterionTypesVec) {
+ for (const auto& xsdcCriterionType : xsdCriterionTypes.getCriterion_type()) {
+ if (xsdcCriterionType.getName() == name) {
+ return xsdcCriterionType;
+ }
+ }
+ }
+ LOG(ERROR) << __func__ << " failed to find criterion type " << name;
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<std::vector<std::optional<AudioHalCapCriterionV2>>>
+convertCapCriteriaCollectionToAidl(
+ const std::vector<eng_xsd::CriteriaType>& xsdcCriteriaVec,
+ const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
+ std::vector<std::optional<AudioHalCapCriterionV2>> resultAidlCriterionVec;
+ if (xsdcCriteriaVec.empty() || xsdcCriterionTypesVec.empty()) {
+ LOG(ERROR) << __func__ << " empty criteria/criterionTypes";
+ return unexpected(BAD_VALUE);
+ }
+ for (const auto& xsdCriteria : xsdcCriteriaVec) {
+ for (const auto& xsdcCriterion : xsdCriteria.getCriterion()) {
+ resultAidlCriterionVec.push_back(
+ std::optional<AudioHalCapCriterionV2>(VALUE_OR_FATAL(
+ convertCapCriterionV2ToAidl(xsdcCriterion, xsdcCriterionTypesVec))));
+ }
+ }
+ return resultAidlCriterionVec;
+}
+
+ConversionResult<std::vector<AudioDeviceDescription>> convertDevicesToAidl(
+ const eng_xsd::CriterionTypeType& xsdcDeviceCriterionType) {
+ if (xsdcDeviceCriterionType.getValues().empty()) {
+ LOG(ERROR) << __func__ << " no values provided";
+ return unexpected(BAD_VALUE);
+ }
+ std::vector<AudioDeviceDescription> aidlDevices;
+ for (eng_xsd::ValuesType xsdcValues : xsdcDeviceCriterionType.getValues()) {
+ aidlDevices.reserve(xsdcValues.getValue().size());
+ for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
+ if (!xsdcValue.hasAndroid_type()) {
+ LOG(ERROR) << __func__ << " empty android type";
+ return unexpected(BAD_VALUE);
+ }
+ uint32_t integerValue;
+ if (!convertTo(xsdcValue.getAndroid_type(), integerValue)) {
+ LOG(ERROR) << __func__ << " failed to convert android type "
+ << xsdcValue.getAndroid_type();
+ return unexpected(BAD_VALUE);
+ }
+ aidlDevices.push_back(
+ VALUE_OR_RETURN(legacy2aidl_audio_devices_t_AudioDeviceDescription(
+ static_cast<audio_devices_t>(integerValue))));
+ }
+ }
+ return aidlDevices;
+}
+
+ConversionResult<std::vector<AudioDeviceAddress>> convertDeviceAddressesToAidl(
+ const eng_xsd::CriterionTypeType& xsdcDeviceAddressesCriterionType) {
+ if (xsdcDeviceAddressesCriterionType.getValues().empty()) {
+ LOG(ERROR) << __func__ << " no values provided";
+ return unexpected(BAD_VALUE);
+ }
+ std::vector<AudioDeviceAddress> aidlDeviceAddresses;
+ for (eng_xsd::ValuesType xsdcValues : xsdcDeviceAddressesCriterionType.getValues()) {
+ aidlDeviceAddresses.reserve(xsdcValues.getValue().size());
+ for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
+ aidlDeviceAddresses.push_back(
+ AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(xsdcValue.getLiteral()));
+ }
+ }
+ return aidlDeviceAddresses;
+}
+
+ConversionResult<std::vector<AudioMode>> convertTelephonyModesToAidl(
+ const eng_xsd::CriterionTypeType& xsdcTelephonyModeCriterionType) {
+ if (xsdcTelephonyModeCriterionType.getValues().empty()) {
+ LOG(ERROR) << __func__ << " no values provided";
+ return unexpected(BAD_VALUE);
+ }
+ std::vector<AudioMode> aidlAudioModes;
+ for (eng_xsd::ValuesType xsdcValues : xsdcTelephonyModeCriterionType.getValues()) {
+ aidlAudioModes.reserve(xsdcValues.getValue().size());
+ for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
+ int integerValue = xsdcValue.getNumerical();
+ if (!isValidAudioMode(AudioMode(integerValue))) {
+ LOG(ERROR) << __func__ << " invalid audio mode " << integerValue;
+ return unexpected(BAD_VALUE);
+ }
+ aidlAudioModes.push_back(AudioMode(integerValue));
+ }
+ }
+ return aidlAudioModes;
+}
+
+ConversionResult<std::vector<AudioPolicyForcedConfig>> convertForcedConfigsToAidl(
+ const eng_xsd::CriterionTypeType& xsdcForcedConfigCriterionType) {
+ if (xsdcForcedConfigCriterionType.getValues().empty()) {
+ LOG(ERROR) << __func__ << " no values provided";
+ return unexpected(BAD_VALUE);
+ }
+ std::vector<AudioPolicyForcedConfig> aidlForcedConfigs;
+ for (eng_xsd::ValuesType xsdcValues : xsdcForcedConfigCriterionType.getValues()) {
+ aidlForcedConfigs.reserve(xsdcValues.getValue().size());
+ for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
+ int integerValue = xsdcValue.getNumerical();
+ if (!isValidAudioPolicyForcedConfig(AudioPolicyForcedConfig(integerValue))) {
+ LOG(ERROR) << __func__ << " invalid forced config mode " << integerValue;
+ return unexpected(BAD_VALUE);
+ }
+ aidlForcedConfigs.push_back(AudioPolicyForcedConfig(integerValue));
+ }
+ }
+ return aidlForcedConfigs;
+}
+
+ConversionResult<AudioPolicyForceUse> convertForceUseCriterionToAidl(
+ const std::string& xsdcCriterionName) {
+ if (!fastcmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForCommunication,
+ strlen(kXsdcForceConfigForCommunication))) {
+ return AudioPolicyForceUse::COMMUNICATION;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForMedia,
+ strlen(kXsdcForceConfigForMedia))) {
+ return AudioPolicyForceUse::MEDIA;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForRecord,
+ strlen(kXsdcForceConfigForRecord))) {
+ return AudioPolicyForceUse::RECORD;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForDock,
+ strlen(kXsdcForceConfigForDock))) {
+ return AudioPolicyForceUse::DOCK;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForSystem,
+ strlen(kXsdcForceConfigForSystem))) {
+ return AudioPolicyForceUse::SYSTEM;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForHdmiSystemAudio,
+ strlen(kXsdcForceConfigForHdmiSystemAudio))) {
+ return AudioPolicyForceUse::HDMI_SYSTEM_AUDIO;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForEncodedSurround,
+ strlen(kXsdcForceConfigForEncodedSurround))) {
+ return AudioPolicyForceUse::ENCODED_SURROUND;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForVibrateRinging,
+ strlen(kXsdcForceConfigForVibrateRinging))) {
+ return AudioPolicyForceUse::VIBRATE_RINGING;
+ }
+ LOG(ERROR) << __func__ << " unrecognized force use " << xsdcCriterionName;
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioHalCapCriterionV2> convertCapCriterionV2ToAidl(
+ const eng_xsd::CriterionType& xsdcCriterion,
+ const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
+ eng_xsd::CriterionTypeType xsdcCriterionType =
+ VALUE_OR_RETURN(getCriterionTypeByName(xsdcCriterion.getType(), xsdcCriterionTypesVec));
+ std::string defaultLiteralValue =
+ xsdcCriterion.has_default() ? xsdcCriterion.get_default() : "";
+ using Tag = AudioHalCapCriterionV2::Tag;
+ if (iequals(xsdcCriterion.getName(), toString(Tag::availableInputDevices))) {
+ return AudioHalCapCriterionV2::make<Tag::availableInputDevices>(
+ VALUE_OR_RETURN(convertDevicesToAidl(xsdcCriterionType)));
+ }
+ if (iequals(xsdcCriterion.getName(), toString(Tag::availableOutputDevices))) {
+ return AudioHalCapCriterionV2::make<Tag::availableOutputDevices>(
+ VALUE_OR_RETURN(convertDevicesToAidl(xsdcCriterionType)));
+ }
+ if (iequals(xsdcCriterion.getName(), toString(Tag::availableInputDevicesAddresses))) {
+ return AudioHalCapCriterionV2::make<Tag::availableInputDevicesAddresses>(
+ VALUE_OR_RETURN(convertDeviceAddressesToAidl(xsdcCriterionType)));
+ }
+ if (iequals(xsdcCriterion.getName(), toString(Tag::availableOutputDevicesAddresses))) {
+ return AudioHalCapCriterionV2::make<Tag::availableOutputDevicesAddresses>(
+ VALUE_OR_RETURN(convertDeviceAddressesToAidl(xsdcCriterionType)));
+ }
+ if (iequals(xsdcCriterion.getName(), toString(Tag::telephonyMode))) {
+ return AudioHalCapCriterionV2::make<Tag::telephonyMode>(
+ VALUE_OR_RETURN(convertTelephonyModesToAidl(xsdcCriterionType)));
+ }
+ if (!fastcmp<strncmp>(xsdcCriterion.getName().c_str(), kXsdcForceConfigForUse,
+ strlen(kXsdcForceConfigForUse))) {
+ return AudioHalCapCriterionV2::make<Tag::forceConfigForUse>(
+ VALUE_OR_RETURN(convertForceUseCriterionToAidl(xsdcCriterion.getName())),
+ VALUE_OR_RETURN(convertForcedConfigsToAidl(xsdcCriterionType)));
+ }
+ LOG(ERROR) << __func__ << " unrecognized criterion " << xsdcCriterion.getName();
+ return unexpected(BAD_VALUE);
+}
+
ConversionResult<AudioHalCapCriterion> convertCapCriterionToAidl(
const eng_xsd::CriterionType& xsdcCriterion) {
AudioHalCapCriterion aidlCapCriterion;
aidlCapCriterion.name = xsdcCriterion.getName();
aidlCapCriterion.criterionTypeName = xsdcCriterion.getType();
- aidlCapCriterion.defaultLiteralValue = xsdcCriterion.get_default();
+ aidlCapCriterion.defaultLiteralValue =
+ xsdcCriterion.has_default() ? xsdcCriterion.get_default() : "";
return aidlCapCriterion;
}
-ConversionResult<std::string> convertCriterionTypeValueToAidl(
- const eng_xsd::ValueType& xsdcCriterionTypeValue) {
- return xsdcCriterionTypeValue.getLiteral();
-}
-
-ConversionResult<AudioHalCapCriterionType> convertCapCriterionTypeToAidl(
- const eng_xsd::CriterionTypeType& xsdcCriterionType) {
- AudioHalCapCriterionType aidlCapCriterionType;
- aidlCapCriterionType.name = xsdcCriterionType.getName();
- aidlCapCriterionType.isInclusive = !(static_cast<bool>(xsdcCriterionType.getType()));
- aidlCapCriterionType.values = VALUE_OR_RETURN(
- (convertWrappedCollectionToAidl<eng_xsd::ValuesType, eng_xsd::ValueType, std::string>(
- xsdcCriterionType.getValues(), &eng_xsd::ValuesType::getValue,
- &convertCriterionTypeValueToAidl)));
- return aidlCapCriterionType;
-}
-
ConversionResult<AudioHalVolumeCurve::CurvePoint> convertCurvePointToAidl(
const std::string& xsdcCurvePoint) {
AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
diff --git a/audio/aidl/default/config/audioPolicy/capengine/Android.bp b/audio/aidl/default/config/audioPolicy/capengine/Android.bp
new file mode 100644
index 0000000..cb99923
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/Android.bp
@@ -0,0 +1,17 @@
+package {
+ default_team: "trendy_team_android_media_audio_framework",
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+ name: "audio_policy_capengine_configuration_aidl_default",
+ srcs: ["PolicyConfigurableDomains.xsd"],
+ package_name: "android.audio.policy.capengine.configuration",
+ nullability: true,
+ root_elements: ["ConfigurableDomains"],
+}
diff --git a/audio/aidl/default/config/audioPolicy/capengine/PolicyConfigurableDomains.xsd b/audio/aidl/default/config/audioPolicy/capengine/PolicyConfigurableDomains.xsd
new file mode 100644
index 0000000..4e7c0bb
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/PolicyConfigurableDomains.xsd
@@ -0,0 +1,467 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <!-- BEGIN W3cXmlAttributes.xsd -->
+ <xs:annotation>
+ <xs:documentation>
+ See http://www.w3.org/XML/1998/namespace.html and
+ http://www.w3.org/TR/REC-xml for information about this namespace.
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+
+ Note that local names in this namespace are intended to be defined
+ only by the World Wide Web Consortium or its subgroups. The
+ following names are currently defined in this namespace and should
+ not be used with conflicting semantics by any Working Group,
+ specification, or document instance:
+
+ base (as an attribute name): denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.
+
+ id (as an attribute name): denotes an attribute whose value
+ should be interpreted as if declared to be of type ID.
+ The xml:id specification is not yet a W3C Recommendation,
+ but this attribute is included here to facilitate experimentation
+ with the mechanisms it proposes. Note that it is _not_ included
+ in the specialAttrs attribute group.
+
+ lang (as an attribute name): denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.
+
+ space (as an attribute name): denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.
+
+ Father (in any context at all): denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+
+ In appreciation for his vision, leadership and dedication
+ the W3C XML Plenary on this 10th day of February, 2000
+ reserves for Jon Bosak in perpetuity the XML name
+ xml:Father
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>This schema defines attributes and an attribute group
+ suitable for use by
+ schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
+ attributes on elements they define.
+
+ To enable this, such a schema must import this schema
+ for the XML namespace, e.g. as follows:
+ <schema . . .>
+ . . .
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2005/08/xml.xsd"/>
+
+ Subsequently, qualified reference to any of the attributes
+ or the group defined below will have the desired effect, e.g.
+
+ <type . . .>
+ . . .
+ <attributeGroup ref="xml:specialAttrs"/>
+
+ will define a type which will schema-validate an instance
+ element with any of those attributes</xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ http://www.w3.org/2005/08/xml.xsd.
+ At the date of issue it can also be found at
+ http://www.w3.org/2001/xml.xsd.
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML Schema
+ itself, or with the XML namespace itself. In other words, if the XML
+ Schema or XML namespaces change, the version of this document at
+ http://www.w3.org/2001/xml.xsd will change
+ accordingly; the version at
+ http://www.w3.org/2005/08/xml.xsd will not change.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+ <xs:annotation>
+ <xs:documentation>Attempting to install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values is probably never
+ going to be a realistic possibility. See
+ RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
+ at http://www.iana.org/assignments/lang-tag-apps.htm for
+ further information.
+
+ The union allows for the 'un-declaration' of xml:lang with
+ the empty string.</xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:union memberTypes="xs:language">
+ <xs:simpleType name="langEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value=""/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+ <xs:simpleType name="spaceEnum">
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+ <xs:annotation>
+ <xs:documentation>See http://www.w3.org/TR/xmlbase/ for
+ information about this attribute.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="id" type="xs:ID">
+ <xs:annotation>
+ <xs:documentation>See http://www.w3.org/TR/xml-id/ for
+ information about this attribute.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+ <!-- END W3cXmlAttributes.xsd -->
+
+ <!-- BEGIN ParameterSettings.xsd -->
+ <!-- BUG b/147297854 - removed "abstract" from type definition -->
+ <xs:complexType name="BooleanParameterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:extension>
+ <!--xs:restriction base="xs:string">
+ <xs:pattern value="([01][\s]*)+"/>
+ <xs:pattern value="((0x0|0x1)[\s]*)+"/>
+ <xs:attribute name="Name" type="xs:string" use="required"/>
+ </xs:restriction-->
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="IntegerParameterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:extension>
+ <!--xs:restriction base="xs:string">
+ <xs:pattern value="(0|([+-]?[1-9][0-9]*))(\s+(0|([+-]?[1-9][0-9]*)))*"/>
+ <xs:pattern value="(0x[0-9a-fA-F]+)(\s+(0x[0-9a-fA-F]+))*"/>
+ <xs:attribute name="Name" type="xs:string" use="required"/>
+ </xs:restriction-->
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="EnumParameterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:extension>
+ <!--xs:extension base="xs:string">
+ <xs:attribute name="Name" type="xs:string" use="required"/>
+ </xs:extension-->
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="PointParameterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:extension>
+ <!--xs:restriction base="xs:string">
+ <xs:pattern value="((0|[+-]?0\.[0-9]+|(([+-]?[1-9][0-9]*)(\.[0-9]+)?))([Ee][+-]?[0-9]+)?)(\s+(0|[+-]?0\.[0-9]+|(([+-]?[1-9][0-9]*)(\.[0-9]+)?))([Ee][+-]?[0-9]+)?)*"/>
+ <xs:pattern value="(0x[0-9a-fA-F]+)(\s+(0x[0-9a-fA-F]+))*"/>
+ <xs:attribute name="Name" type="xs:NMTOKEN" use="required"/>
+ </xs:restriction-->
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="BitParameterBlockType">
+ <xs:sequence>
+ <xs:element name="BitParameter" maxOccurs="unbounded" type="IntegerParameterType"/>
+ </xs:sequence>
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="StringParameterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:group name="ParameterBlockGroup">
+ <xs:choice>
+ <xs:element name="BooleanParameter" type="BooleanParameterType"/>
+ <xs:element name="IntegerParameter" type="IntegerParameterType"/>
+ <xs:element name="EnumParameter" type="EnumParameterType"/>
+ <xs:element name="FixedPointParameter" type="PointParameterType"/>
+ <xs:element name="FloatingPointParameter" type="PointParameterType"/>
+ <xs:element name="BitParameterBlock" type="BitParameterBlockType">
+ <xs:unique name="BitParameterBlockSubElementsUniqueness">
+ <xs:selector xpath="*"/>
+ <xs:field xpath="@Name"/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name="StringParameter" type="StringParameterType"/>
+ <!--xs:element name="Component" type="ParameterBlockType"/-->
+ <xs:element name="ParameterBlock" type="ParameterBlockType">
+ <xs:unique name="ParameterBlockSubElementsUniqueness">
+ <xs:selector xpath="*"/>
+ <xs:field xpath="@Name"/>
+ </xs:unique>
+ </xs:element>
+ </xs:choice>
+ </xs:group>
+ <xs:complexType name="ParameterBlockType">
+ <xs:sequence>
+ <xs:group ref="ParameterBlockGroup" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="Name" type="xs:NMTOKEN" use="required"/>
+ </xs:complexType>
+ <!-- END ParameterSettings.xsd -->
+
+ <!-- BEGIN ConfigurableDomain.xsd -->
+ <xs:complexType name="SelectionCriterionRuleType">
+ <xs:attribute name="SelectionCriterion" type="xs:NMTOKEN" use="required"/>
+ <xs:attribute name="MatchesWhen" use="required">
+ <xs:simpleType name="MatchesWhenEnum">
+ <xs:restriction base="xs:NMTOKEN">
+ <xs:enumeration value="Is"/>
+ <xs:enumeration value="IsNot"/>
+ <xs:enumeration value="Includes"/>
+ <xs:enumeration value="Excludes"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="Value" use="required" type="xs:NMTOKEN"/>
+ </xs:complexType>
+ <xs:group name="RuleGroup">
+ <xs:choice>
+ <xs:element name="CompoundRule" type="CompoundRuleType"/>
+ <xs:element name="SelectionCriterionRule" type="SelectionCriterionRuleType"/>
+ </xs:choice>
+ </xs:group>
+ <xs:complexType name="CompoundRuleType">
+ <xs:sequence>
+ <xs:group ref="RuleGroup" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="Type">
+ <xs:simpleType name="TypeEnum">
+ <xs:restriction base="xs:NMTOKEN">
+ <xs:enumeration value="Any"/>
+ <xs:enumeration value="All"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:complexType name="ConfigurationsType">
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" name="Configuration">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="CompoundRule" type="CompoundRuleType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="Name" use="required" type="xs:NCName"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:group name="ComponentGroup">
+ <xs:sequence>
+ <xs:group ref="ParameterBlockGroup"/>
+ </xs:sequence>
+ </xs:group>
+ <xs:complexType name="ComponentType">
+ <xs:sequence>
+ <xs:choice>
+ <xs:group ref="ComponentGroup" maxOccurs="unbounded"/>
+ <xs:element name="Subsystem" type="ComponentType" maxOccurs="unbounded"/>
+ </xs:choice>
+ </xs:sequence>
+ <xs:attribute name="Name" use="required" type="xs:NCName"/>
+ </xs:complexType>
+ <xs:complexType name="ConfigurableElementsType">
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="ConfigurableElement">
+ <xs:complexType>
+ <xs:attribute name="Path" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:anyURI">
+ <xs:pattern value="/.*[^/]"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ConfigurableElementSettingsType">
+ <xs:choice>
+ <xs:element name="BooleanParameter" type="BooleanParameterType"/>
+ <xs:element name="IntegerParameter" type="IntegerParameterType"/>
+ <xs:element name="EnumParameter" type="EnumParameterType"/>
+ <xs:element name="FixedPointParameter" type="PointParameterType"/>
+ <xs:element name="FloatingPointParameter" type="PointParameterType"/>
+ <xs:element name="BitParameter" type="IntegerParameterType"/>
+ <xs:element name="BitParameterBlock" type="BitParameterBlockType">
+ <xs:unique name="BitParameterBlockSubElementsUniqueness">
+ <xs:selector xpath="*"/>
+ <xs:field xpath="@Name"/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name="StringParameter" type="StringParameterType"/>
+ <!--xs:element name="Component" type="ParameterBlockType"/-->
+ <xs:element name="ParameterBlock" type="ParameterBlockType">
+ <xs:unique name="ParameterBlockSubElementsUniqueness">
+ <xs:selector xpath="*"/>
+ <xs:field xpath="@Name"/>
+ </xs:unique>
+ </xs:element>
+ </xs:choice>
+ <!--xs:choice>
+ <xs:element name="BitParameter" type="IntegerParameterType"/>
+ <xs:group ref="ComponentGroup"/>
+ </xs:choice-->
+ <xs:attribute name="Path" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:anyURI">
+ <xs:pattern value="/.*[^/]"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:complexType name="SettingsType">
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="Configuration">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="ConfigurableElement" minOccurs="0" maxOccurs="unbounded" type="ConfigurableElementSettingsType"/>
+ </xs:sequence>
+ <xs:attribute name="Name" use="required" type="xs:NCName"/>
+ </xs:complexType>
+ <xs:unique name="ConfigurableElementUniqueness">
+ <xs:selector xpath="ConfigurableElement"/>
+ <xs:field xpath="@Path"/>
+ </xs:unique>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ConfigurableDomainType">
+ <xs:sequence>
+ <xs:element name="Configurations" type="ConfigurationsType"/>
+ <xs:element name="ConfigurableElements" type="ConfigurableElementsType"/>
+ <xs:element name="Settings" type="SettingsType" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="Name" use="required" type="xs:NCName"/>
+ <xs:attribute name="SequenceAware" use="optional" type="xs:boolean" default="false"/>
+ </xs:complexType>
+ <xs:element name="ConfigurableDomain" type="ConfigurableDomainType"/>
+ <!-- END ConfigurableDomain.xsd -->
+
+ <!-- BEGIN ConfigurableDomains.xsd -->
+ <xs:element name="ConfigurableDomains">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" name="ConfigurableDomain" type="ConfigurableDomainType">
+ <xs:key name="ConfigurableElementKey">
+ <xs:selector xpath="ConfigurableElements/ConfigurableElement"/>
+ <xs:field xpath="@Path"/>
+ </xs:key>
+ <xs:keyref refer="ConfigurableElementKey" name="ConfigurableDomainReference">
+ <xs:selector xpath="Settings/Configuration/ConfigurableElement"/>
+ <xs:field xpath="@Path"/>
+ </xs:keyref>
+ <xs:key name="ConfigurationKey">
+ <xs:selector xpath="Configurations/Configuration"/>
+ <xs:field xpath="@Name"/>
+ </xs:key>
+ <xs:keyref refer="ConfigurationKey" name="ConfigurationReference2">
+ <xs:selector xpath="ConfigurableElements/ConfigurableElement/Configuration"/>
+ <xs:field xpath="@Name"/>
+ </xs:keyref>
+ <xs:keyref refer="ConfigurationKey" name="ConfigurationReference">
+ <xs:selector xpath="Settings/Configuration"/>
+ <xs:field xpath="@Name"/>
+ </xs:keyref>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="SystemClassName" use="required" type="xs:NCName"/>
+ </xs:complexType>
+ <xs:unique name="ConfigurableDomainUniqueness">
+ <xs:selector xpath="ConfigurableDomain"/>
+ <xs:field xpath="@Name"/>
+ </xs:unique>
+ </xs:element>
+ <!-- END ConfigurableDomains.xsd -->
+
+ <xs:simpleType name="ParameterNameEnumType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="volume_profile"/>
+
+ <xs:enumeration value="communication"/>
+ <xs:enumeration value="ambient"/>
+ <xs:enumeration value="builtin_mic"/>
+ <xs:enumeration value="bluetooth_sco_headset"/>
+ <xs:enumeration value="wired_headset"/>
+ <xs:enumeration value="hdmi"/>
+ <xs:enumeration value="telephony_rx"/>
+ <xs:enumeration value="back_mic"/>
+ <xs:enumeration value="remote_submix"/>
+ <xs:enumeration value="anlg_dock_headset"/>
+ <xs:enumeration value="dgtl_dock_headset"/>
+ <xs:enumeration value="usb_accessory"/>
+ <xs:enumeration value="usb_device"/>
+ <xs:enumeration value="fm_tuner"/>
+ <xs:enumeration value="tv_tuner"/>
+ <xs:enumeration value="line"/>
+ <xs:enumeration value="spdif"/>
+ <xs:enumeration value="bluetooth_a2dp" />
+ <xs:enumeration value="loopback" />
+ <xs:enumeration value="ip" />
+ <xs:enumeration value="bus" />
+ <xs:enumeration value="proxy"/>
+ <xs:enumeration value="usb_headset"/>
+ <xs:enumeration value="bluetooth_ble"/>
+ <xs:enumeration value="hdmi_arc"/>
+ <xs:enumeration value="echo_reference"/>
+ <xs:enumeration value="ble_headset"/>
+ <xs:enumeration value="stub"/>
+ <xs:enumeration value="hdmi_earc"/>
+
+ <xs:enumeration value="device_address"/>
+
+ <xs:enumeration value="earpiece" />
+ <xs:enumeration value="speaker" />
+ <xs:enumeration value="wired_headphone" />
+ <xs:enumeration value="bluetooth_sco" />
+ <xs:enumeration value="bluetooth_sco_carkit"/>
+ <xs:enumeration value="bluetooth_a2dp_headphones"/>
+ <xs:enumeration value="bluetooth_a2dp_speaker"/>
+ <xs:enumeration value="telephony_tx"/>
+ <xs:enumeration value="fm"/>
+ <xs:enumeration value="aux_line"/>
+ <xs:enumeration value="speaker_safe"/>
+ <xs:enumeration value="hearing_aid" />
+ <xs:enumeration value="echo_canceller" />
+ <xs:enumeration value="ble_speaker" />
+ <xs:enumeration value="ble_broadcast" />
+ </xs:restriction>
+ </xs:simpleType>
+</xs:schema>
diff --git a/audio/aidl/default/config/audioPolicy/capengine/api/current.txt b/audio/aidl/default/config/audioPolicy/capengine/api/current.txt
new file mode 100644
index 0000000..481abbf
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/api/current.txt
@@ -0,0 +1,264 @@
+// Signature format: 2.0
+package android.audio.policy.capengine.configuration {
+
+ public class BitParameterBlockType {
+ ctor public BitParameterBlockType();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.IntegerParameterType> getBitParameter();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ }
+
+ public class BooleanParameterType {
+ ctor public BooleanParameterType();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ method public void setValue(@Nullable String);
+ }
+
+ public class ComponentType {
+ ctor public ComponentType();
+ method @Nullable public String getName();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.ComponentType> getSubsystem_optional();
+ method public void setName(@Nullable String);
+ }
+
+ public class CompoundRuleType {
+ ctor public CompoundRuleType();
+ method @Nullable public android.audio.policy.capengine.configuration.CompoundRuleType getCompoundRule_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.SelectionCriterionRuleType getSelectionCriterionRule_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.TypeEnum getType();
+ method public void setCompoundRule_optional(@Nullable android.audio.policy.capengine.configuration.CompoundRuleType);
+ method public void setSelectionCriterionRule_optional(@Nullable android.audio.policy.capengine.configuration.SelectionCriterionRuleType);
+ method public void setType(@Nullable android.audio.policy.capengine.configuration.TypeEnum);
+ }
+
+ public class ConfigurableDomainType {
+ ctor public ConfigurableDomainType();
+ method @Nullable public android.audio.policy.capengine.configuration.ConfigurableElementsType getConfigurableElements();
+ method @Nullable public android.audio.policy.capengine.configuration.ConfigurationsType getConfigurations();
+ method @Nullable public String getName();
+ method @Nullable public boolean getSequenceAware();
+ method @Nullable public android.audio.policy.capengine.configuration.SettingsType getSettings();
+ method public void setConfigurableElements(@Nullable android.audio.policy.capengine.configuration.ConfigurableElementsType);
+ method public void setConfigurations(@Nullable android.audio.policy.capengine.configuration.ConfigurationsType);
+ method public void setName(@Nullable String);
+ method public void setSequenceAware(@Nullable boolean);
+ method public void setSettings(@Nullable android.audio.policy.capengine.configuration.SettingsType);
+ }
+
+ public class ConfigurableDomains {
+ ctor public ConfigurableDomains();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.ConfigurableDomainType> getConfigurableDomain();
+ method @Nullable public String getSystemClassName();
+ method public void setSystemClassName(@Nullable String);
+ }
+
+ public class ConfigurableElementSettingsType {
+ ctor public ConfigurableElementSettingsType();
+ method @Nullable public android.audio.policy.capengine.configuration.BitParameterBlockType getBitParameterBlock_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.IntegerParameterType getBitParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.BooleanParameterType getBooleanParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.EnumParameterType getEnumParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.PointParameterType getFixedPointParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.PointParameterType getFloatingPointParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.IntegerParameterType getIntegerParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterBlockType getParameterBlock_optional();
+ method @Nullable public String getPath();
+ method @Nullable public android.audio.policy.capengine.configuration.StringParameterType getStringParameter_optional();
+ method public void setBitParameterBlock_optional(@Nullable android.audio.policy.capengine.configuration.BitParameterBlockType);
+ method public void setBitParameter_optional(@Nullable android.audio.policy.capengine.configuration.IntegerParameterType);
+ method public void setBooleanParameter_optional(@Nullable android.audio.policy.capengine.configuration.BooleanParameterType);
+ method public void setEnumParameter_optional(@Nullable android.audio.policy.capengine.configuration.EnumParameterType);
+ method public void setFixedPointParameter_optional(@Nullable android.audio.policy.capengine.configuration.PointParameterType);
+ method public void setFloatingPointParameter_optional(@Nullable android.audio.policy.capengine.configuration.PointParameterType);
+ method public void setIntegerParameter_optional(@Nullable android.audio.policy.capengine.configuration.IntegerParameterType);
+ method public void setParameterBlock_optional(@Nullable android.audio.policy.capengine.configuration.ParameterBlockType);
+ method public void setPath(@Nullable String);
+ method public void setStringParameter_optional(@Nullable android.audio.policy.capengine.configuration.StringParameterType);
+ }
+
+ public class ConfigurableElementsType {
+ ctor public ConfigurableElementsType();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.ConfigurableElementsType.ConfigurableElement> getConfigurableElement();
+ }
+
+ public static class ConfigurableElementsType.ConfigurableElement {
+ ctor public ConfigurableElementsType.ConfigurableElement();
+ method @Nullable public String getPath();
+ method public void setPath(@Nullable String);
+ }
+
+ public class ConfigurationsType {
+ ctor public ConfigurationsType();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.ConfigurationsType.Configuration> getConfiguration();
+ }
+
+ public static class ConfigurationsType.Configuration {
+ ctor public ConfigurationsType.Configuration();
+ method @Nullable public android.audio.policy.capengine.configuration.CompoundRuleType getCompoundRule();
+ method @Nullable public String getName();
+ method public void setCompoundRule(@Nullable android.audio.policy.capengine.configuration.CompoundRuleType);
+ method public void setName(@Nullable String);
+ }
+
+ public class EnumParameterType {
+ ctor public EnumParameterType();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ method public void setValue(@Nullable String);
+ }
+
+ public class IntegerParameterType {
+ ctor public IntegerParameterType();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ method public void setValue(@Nullable String);
+ }
+
+ public enum LangEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.capengine.configuration.LangEnum EMPTY;
+ }
+
+ public enum MatchesWhenEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.capengine.configuration.MatchesWhenEnum Excludes;
+ enum_constant public static final android.audio.policy.capengine.configuration.MatchesWhenEnum Includes;
+ enum_constant public static final android.audio.policy.capengine.configuration.MatchesWhenEnum Is;
+ enum_constant public static final android.audio.policy.capengine.configuration.MatchesWhenEnum IsNot;
+ }
+
+ public class ParameterBlockType {
+ ctor public ParameterBlockType();
+ method @Nullable public android.audio.policy.capengine.configuration.BitParameterBlockType getBitParameterBlock_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.BooleanParameterType getBooleanParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.EnumParameterType getEnumParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.PointParameterType getFixedPointParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.PointParameterType getFloatingPointParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.IntegerParameterType getIntegerParameter_optional();
+ method @Nullable public String getName();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterBlockType getParameterBlock_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.StringParameterType getStringParameter_optional();
+ method public void setBitParameterBlock_optional(@Nullable android.audio.policy.capengine.configuration.BitParameterBlockType);
+ method public void setBooleanParameter_optional(@Nullable android.audio.policy.capengine.configuration.BooleanParameterType);
+ method public void setEnumParameter_optional(@Nullable android.audio.policy.capengine.configuration.EnumParameterType);
+ method public void setFixedPointParameter_optional(@Nullable android.audio.policy.capengine.configuration.PointParameterType);
+ method public void setFloatingPointParameter_optional(@Nullable android.audio.policy.capengine.configuration.PointParameterType);
+ method public void setIntegerParameter_optional(@Nullable android.audio.policy.capengine.configuration.IntegerParameterType);
+ method public void setName(@Nullable String);
+ method public void setParameterBlock_optional(@Nullable android.audio.policy.capengine.configuration.ParameterBlockType);
+ method public void setStringParameter_optional(@Nullable android.audio.policy.capengine.configuration.StringParameterType);
+ }
+
+ public enum ParameterNameEnumType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType ambient;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType anlg_dock_headset;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType aux_line;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType back_mic;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType ble_broadcast;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType ble_headset;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType ble_speaker;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_a2dp;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_a2dp_headphones;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_a2dp_speaker;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_ble;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_sco;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_sco_carkit;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_sco_headset;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType builtin_mic;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bus;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType communication;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType device_address;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType dgtl_dock_headset;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType earpiece;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType echo_canceller;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType echo_reference;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType fm;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType fm_tuner;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType hdmi;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType hdmi_arc;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType hdmi_earc;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType hearing_aid;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType ip;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType line;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType loopback;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType proxy;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType remote_submix;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType spdif;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType speaker;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType speaker_safe;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType stub;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType telephony_rx;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType telephony_tx;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType tv_tuner;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType usb_accessory;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType usb_device;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType usb_headset;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType volume_profile;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType wired_headphone;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType wired_headset;
+ }
+
+ public class PointParameterType {
+ ctor public PointParameterType();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ method public void setValue(@Nullable String);
+ }
+
+ public class SelectionCriterionRuleType {
+ ctor public SelectionCriterionRuleType();
+ method @Nullable public android.audio.policy.capengine.configuration.MatchesWhenEnum getMatchesWhen();
+ method @Nullable public String getSelectionCriterion();
+ method @Nullable public String getValue();
+ method public void setMatchesWhen(@Nullable android.audio.policy.capengine.configuration.MatchesWhenEnum);
+ method public void setSelectionCriterion(@Nullable String);
+ method public void setValue(@Nullable String);
+ }
+
+ public class SettingsType {
+ ctor public SettingsType();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.SettingsType.Configuration> getConfiguration();
+ }
+
+ public static class SettingsType.Configuration {
+ ctor public SettingsType.Configuration();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.ConfigurableElementSettingsType> getConfigurableElement();
+ method @Nullable public String getName();
+ method public void setName(@Nullable String);
+ }
+
+ public enum SpaceEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.capengine.configuration.SpaceEnum _default;
+ enum_constant public static final android.audio.policy.capengine.configuration.SpaceEnum preserve;
+ }
+
+ public class StringParameterType {
+ ctor public StringParameterType();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ method public void setValue(@Nullable String);
+ }
+
+ public enum TypeEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.capengine.configuration.TypeEnum All;
+ enum_constant public static final android.audio.policy.capengine.configuration.TypeEnum Any;
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method @Nullable public static android.audio.policy.capengine.configuration.ConfigurableDomains readConfigurableDomains(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/audio/aidl/default/config/audioPolicy/capengine/api/last_current.txt b/audio/aidl/default/config/audioPolicy/capengine/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/api/last_current.txt
diff --git a/audio/aidl/default/config/audioPolicy/capengine/api/last_removed.txt b/audio/aidl/default/config/audioPolicy/capengine/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/api/last_removed.txt
diff --git a/audio/aidl/default/config/audioPolicy/capengine/api/removed.txt b/audio/aidl/default/config/audioPolicy/capengine/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/current.txt b/audio/aidl/default/config/audioPolicy/engine/api/current.txt
index 063b05d..8e0e9a2 100644
--- a/audio/aidl/default/config/audioPolicy/engine/api/current.txt
+++ b/audio/aidl/default/config/audioPolicy/engine/api/current.txt
@@ -162,7 +162,9 @@
public static class ProductStrategies.ProductStrategy {
ctor public ProductStrategies.ProductStrategy();
method @Nullable public java.util.List<android.audio.policy.engine.configuration.AttributesGroup> getAttributesGroup();
+ method @Nullable public int getId();
method @Nullable public String getName();
+ method public void setId(@Nullable int);
method public void setName(@Nullable String);
}
diff --git a/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd b/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
index 40396bb..e2508ea 100644
--- a/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
+++ b/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
@@ -105,6 +105,7 @@
<xs:element name="AttributesGroup" type="AttributesGroup" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="id" type="xs:int" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
@@ -188,6 +189,19 @@
</xs:sequence>
</xs:complexType>
<xs:complexType name="valueType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Criterion type is provided as a tuple of 'human readable' string (referred as the
+ literal part, that will allow to express 'human readable' rules, numerical value
+ associated in order to improve performances of the parameter framework library used,
+ and an optional android type.
+ This android type is reserved for device type mapping with parameter framework
+ representation on a bitfield (Only one bit is expected to represent a device) and
+ android representation of a type that may use several bits.
+ The lookup table will allow wrap android device type to parameter framework device
+ types data model.
+ </xs:documentation>
+ </xs:annotation>
<xs:attribute name="literal" type="xs:string" use="required"/>
<xs:attribute name="numerical" type="xs:long" use="required"/>
<xs:attribute name="android_type" type="longDecimalOrHexType" use="optional"/>
diff --git a/audio/aidl/default/include/core-impl/CapEngineConfigXmlConverter.h b/audio/aidl/default/include/core-impl/CapEngineConfigXmlConverter.h
new file mode 100644
index 0000000..e5da4f4
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/CapEngineConfigXmlConverter.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 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 <aidl/android/hardware/audio/core/BnConfig.h>
+#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+#include <system/audio_config.h>
+
+#include <android_audio_policy_capengine_configuration.h>
+#include <android_audio_policy_capengine_configuration_enums.h>
+
+#include "EngineConfigXmlConverter.h"
+
+namespace aidl::android::hardware::audio::core::internal {
+
+namespace capconfiguration = ::android::audio::policy::capengine::configuration;
+namespace aidlcommon = ::aidl::android::media::audio::common;
+
+class CapEngineConfigXmlConverter {
+ public:
+ explicit CapEngineConfigXmlConverter(const std::string& configFilePath)
+ : mConverter(configFilePath, &capconfiguration::readConfigurableDomains) {
+ if (mConverter.getXsdcConfig()) {
+ init();
+ }
+ }
+ std::string getError() const { return mConverter.getError(); }
+ ::android::status_t getStatus() const { return mConverter.getStatus(); }
+
+ std::optional<
+ std::vector<std::optional<::aidl::android::media::audio::common::AudioHalCapDomain>>>&
+ getAidlCapEngineConfig();
+
+ private:
+ ConversionResult<std::vector<aidlcommon::AudioHalCapParameter>> convertSettingToAidl(
+ const capconfiguration::SettingsType::Configuration& xsdcSetting);
+
+ ConversionResult<std::vector<aidlcommon::AudioHalCapConfiguration>> convertConfigurationsToAidl(
+ const std::vector<capconfiguration::ConfigurationsType>& xsdcConfigurationsVec,
+ const std::vector<capconfiguration::SettingsType>& xsdcSettingsVec);
+
+ ConversionResult<aidlcommon::AudioHalCapConfiguration> convertConfigurationToAidl(
+ const capconfiguration::ConfigurationsType::Configuration& xsdcConfiguration,
+ const capconfiguration::SettingsType::Configuration& xsdcSettingConfiguration);
+
+ ConversionResult<aidlcommon::AudioHalCapParameter> convertParamToAidl(
+ const capconfiguration::ConfigurableElementSettingsType& element);
+
+ ConversionResult<aidlcommon::AudioHalCapConfiguration> convertConfigurationToAidl(
+ const capconfiguration::ConfigurationsType::Configuration& xsdcConfiguration);
+ ConversionResult<aidlcommon::AudioHalCapDomain> convertConfigurableDomainToAidl(
+ const capconfiguration::ConfigurableDomainType& xsdcConfigurableDomain);
+
+ const std::optional<capconfiguration::ConfigurableDomains>& getXsdcConfig() {
+ return mConverter.getXsdcConfig();
+ }
+ void init();
+
+ std::optional<std::vector<std::optional<aidlcommon::AudioHalCapDomain>>> mAidlCapDomains;
+ XmlConverter<capconfiguration::ConfigurableDomains> mConverter;
+};
+} // 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 22ac8cb..211c16f 100644
--- a/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h
+++ b/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h
@@ -59,6 +59,7 @@
ConversionResult<::aidl::android::media::audio::common::AudioHalProductStrategy>
convertProductStrategyToAidl(const ::android::audio::policy::engine::configuration::
ProductStrategies::ProductStrategy& xsdcProductStrategy);
+ ConversionResult<int> convertProductStrategyIdToAidl(int xsdcId);
ConversionResult<int> convertProductStrategyNameToAidl(
const std::string& xsdcProductStrategyName);
ConversionResult<::aidl::android::media::audio::common::AudioHalVolumeCurve>
diff --git a/audio/aidl/default/include/core-impl/XmlConverter.h b/audio/aidl/default/include/core-impl/XmlConverter.h
index 68e6b8e..4b99d72 100644
--- a/audio/aidl/default/include/core-impl/XmlConverter.h
+++ b/audio/aidl/default/include/core-impl/XmlConverter.h
@@ -106,6 +106,19 @@
}
template <typename X, typename A>
+static ConversionResult<std::vector<std::optional<A>>> convertCollectionToAidlOptionalValues(
+ const std::vector<X>& xsdcTypeVec,
+ std::function<ConversionResult<A>(const X&)> convertToAidl) {
+ std::vector<std::optional<A>> resultAidlTypeVec;
+ resultAidlTypeVec.reserve(xsdcTypeVec.size());
+ for (const X& xsdcType : xsdcTypeVec) {
+ resultAidlTypeVec.push_back(
+ std::optional<A>(std::move(VALUE_OR_FATAL(convertToAidl(xsdcType)))));
+ }
+ return resultAidlTypeVec;
+}
+
+template <typename X, typename A>
static ConversionResult<std::vector<A>> convertCollectionToAidl(
const std::vector<X>& xsdcTypeVec,
std::function<ConversionResult<A>(const X&)> convertToAidl) {
diff --git a/audio/aidl/default/include/core-impl/XsdcConversion.h b/audio/aidl/default/include/core-impl/XsdcConversion.h
index 30dc8b6..e855a3e 100644
--- a/audio/aidl/default/include/core-impl/XsdcConversion.h
+++ b/audio/aidl/default/include/core-impl/XsdcConversion.h
@@ -4,6 +4,7 @@
#include <aidl/android/media/audio/common/AudioHalCapCriterion.h>
#include <aidl/android/media/audio/common/AudioHalCapCriterionType.h>
+#include <aidl/android/media/audio/common/AudioHalCapCriterionV2.h>
#include <aidl/android/media/audio/common/AudioHalVolumeCurve.h>
#include <aidl/android/media/audio/common/AudioPort.h>
#include <android_audio_policy_configuration.h>
@@ -15,15 +16,40 @@
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);
+namespace engineconfiguration = ::android::audio::policy::engine::configuration;
+namespace aidlaudiocommon = ::aidl::android::media::audio::common;
+
+static constexpr const char kXsdcForceConfigForUse[] = "ForceUseFor";
+
+ConversionResult<aidlaudiocommon::AudioPolicyForceUse> convertForceUseCriterionToAidl(
+ const std::string& xsdcCriterionName);
+ConversionResult<aidlaudiocommon::AudioPolicyForcedConfig> convertForcedConfigToAidl(
+ const std::string& xsdcForcedConfigCriterionType);
+ConversionResult<aidlaudiocommon::AudioDeviceAddress> convertDeviceAddressToAidl(
+ const std::string& xsdcAddress);
+ConversionResult<aidlaudiocommon::AudioMode> convertTelephonyModeToAidl(
+ const std::string& xsdcModeCriterionType);
+ConversionResult<aidlaudiocommon::AudioDeviceDescription> convertDeviceTypeToAidl(
+ const std::string& xType);
+ConversionResult<std::vector<std::optional<aidlaudiocommon::AudioHalCapCriterionV2>>>
+convertCapCriteriaCollectionToAidl(
+ const std::vector<engineconfiguration::CriteriaType>& xsdcCriteriaVec,
+ const std::vector<engineconfiguration::CriterionTypesType>& xsdcCriterionTypesVec);
+ConversionResult<aidlaudiocommon::AudioHalCapCriterionV2> convertCapCriterionV2ToAidl(
+ const engineconfiguration::CriterionType& xsdcCriterion,
+ const std::vector<engineconfiguration::CriterionTypesType>& xsdcCriterionTypesVec);
+ConversionResult<aidlaudiocommon::AudioHalVolumeCurve::CurvePoint> convertCurvePointToAidl(
+ const std::string& xsdcCurvePoint);
ConversionResult<std::unique_ptr<Module::Configuration>> convertModuleConfigToAidl(
const ::android::audio::policy::configuration::Modules::Module& moduleConfig);
+ConversionResult<aidlaudiocommon::AudioUsage> convertAudioUsageToAidl(
+ const engineconfiguration::UsageEnumType& xsdcUsage);
+ConversionResult<aidlaudiocommon::AudioContentType> convertAudioContentTypeToAidl(
+ const engineconfiguration::ContentType& xsdcContentType);
+ConversionResult<aidlaudiocommon::AudioSource> convertAudioSourceToAidl(
+ const engineconfiguration::SourceEnumType& xsdcSourceType);
+ConversionResult<aidlaudiocommon::AudioStreamType> convertAudioStreamTypeToAidl(
+ const engineconfiguration::Stream& xsdStreamType);
+ConversionResult<int32_t> convertAudioFlagsToAidl(
+ const std::vector<engineconfiguration::FlagType>& xsdcFlagTypeVec);
} // namespace aidl::android::hardware::audio::core::internal