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