audio: Update common types to better match legacy structs
HAL V7 types were updated to better match data structure
definitions from the legacy HAL:
- Added 'AudioConfigBaseOptional' struct to match
legacy structs that have 'mask' field to specify
initialized fields.
- All fields in 'AudioConfigBase' made mandatory.
- Removed 'EffectConfigParameters' in favor of
'AudioConfigBaseOptional' and safe_unions.
- Added missing enum string values to ensure that round-trip
conversions from the legacy HAL to HIDL and back to legacy
preserve enum values.
Bug: 142480271
Test: atest android.hardware.audio.common@7.0-util_tests
Test: atest VtsHalAudioV6_0TargetTest
Test: atest VtsHalAudioV7_0TargetTest
Test: atest VtsHalAudioEffectV7_0TargetTest
Change-Id: If02a81b3f6790a8eb315fa57123141aad2419132
diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal
index ab9aa7d..393e38f 100644
--- a/audio/7.0/IStream.hal
+++ b/audio/7.0/IStream.hal
@@ -73,14 +73,14 @@
/**
* Sets stream parameters. Only sets parameters that are specified.
- * See the description of AudioConfigBase for the details.
*
* Optional method. If implemented, only called on a stopped stream.
*
* @param config basic stream configuration.
* @return retval operation completion status.
*/
- setAudioProperties(AudioConfigBase config) generates (Result retval);
+ setAudioProperties(AudioConfigBaseOptional config)
+ generates (Result retval);
/**
* Applies audio effect to the stream.
diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt
index 1da8b09..8a4662f 100644
--- a/audio/7.0/config/api/current.txt
+++ b/audio/7.0/config/api/current.txt
@@ -198,6 +198,7 @@
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD;
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP;
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT;
+ enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DEFAULT;
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD;
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD;
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS;
diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd
index 56b3a27..685e84a 100644
--- a/audio/7.0/config/audio_policy_configuration.xsd
+++ b/audio/7.0/config/audio_policy_configuration.xsd
@@ -329,6 +329,7 @@
</xs:simpleType>
<xs:simpleType name="audioFormat">
<xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_FORMAT_DEFAULT" />
<xs:enumeration value="AUDIO_FORMAT_PCM_16_BIT" />
<xs:enumeration value="AUDIO_FORMAT_PCM_8_BIT"/>
<xs:enumeration value="AUDIO_FORMAT_PCM_32_BIT"/>
diff --git a/audio/common/7.0/example/Effect.cpp b/audio/common/7.0/example/Effect.cpp
index 27f28c6..5788811 100644
--- a/audio/common/7.0/example/Effect.cpp
+++ b/audio/common/7.0/example/Effect.cpp
@@ -107,14 +107,13 @@
}
Return<void> Effect::getConfig(getConfig_cb _hidl_cb) {
- const EffectConfig config = {
- {} /* inputCfg */,
- // outputCfg
- {{} /* buffer */,
- {toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT), 48000 /* samplingRateHz */,
- toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO)}, /* base */
- EffectBufferAccess::ACCESS_ACCUMULATE,
- 0 /* mask */}};
+ EffectConfig config;
+ // inputCfg left unspecified.
+ config.outputCfg.base.format.value(toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT));
+ config.outputCfg.base.sampleRateHz.value(48000);
+ config.outputCfg.base.channelMask.value(
+ toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO));
+ config.outputCfg.accessMode.value(EffectBufferAccess::ACCESS_ACCUMULATE);
_hidl_cb(Result::OK, config);
return Void();
}
diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal
index ed6d94f..3903a0b 100644
--- a/audio/common/7.0/types.hal
+++ b/audio/common/7.0/types.hal
@@ -118,9 +118,28 @@
* Base configuration attributes applicable to any stream of audio.
*/
struct AudioConfigBase {
- AudioFormat format; // empty means 'unspecified'
- uint32_t sampleRateHz; // 0 means 'unspecified'
- AudioChannelMask channelMask; // empty means 'unspecified'
+ AudioFormat format;
+ uint32_t sampleRateHz;
+ AudioChannelMask channelMask;
+};
+
+/**
+ * Base configuration attributes applicable to any stream of audio.
+ * Any attribute may be left unspecified.
+ */
+struct AudioConfigBaseOptional {
+ safe_union Format {
+ Monostate unspecified;
+ AudioFormat value;
+ } format;
+ safe_union SampleRate {
+ Monostate unspecified;
+ uint32_t value;
+ } sampleRateHz;
+ safe_union ChannelMask {
+ Monostate unspecified;
+ AudioChannelMask value;
+ } channelMask;
};
/**
@@ -439,11 +458,9 @@
*/
AudioPortHandle id;
/**
- * Basic parameters: sampling rate, format, channel mask. Only some of the
- * parameters (or none) may be set. See the documentation of the
- * AudioConfigBase struct.
+ * Basic parameters: sampling rate, format, channel mask.
*/
- AudioConfigBase base;
+ AudioConfigBaseOptional base;
/** Associated gain control. */
safe_union OptionalGain {
Monostate unspecified;
diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp
index de19faf..f09db5e 100644
--- a/audio/common/all-versions/default/7.0/HidlUtils.cpp
+++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp
@@ -147,6 +147,59 @@
return result;
}
+status_t HidlUtils::audioConfigBaseOptionalFromHal(const audio_config_base_t& halConfigBase,
+ bool isInput, bool formatSpecified,
+ bool sampleRateSpecified,
+ bool channelMaskSpecified,
+ AudioConfigBaseOptional* configBase) {
+ status_t result = NO_ERROR;
+ if (formatSpecified) {
+ AudioFormat value;
+ CONVERT_CHECKED(audioFormatFromHal(halConfigBase.format, &value), result);
+ configBase->format.value(std::move(value));
+ } else {
+ configBase->format.unspecified({});
+ }
+ if (sampleRateSpecified) {
+ configBase->sampleRateHz.value(halConfigBase.sample_rate);
+ } else {
+ configBase->sampleRateHz.unspecified({});
+ }
+ if (channelMaskSpecified) {
+ AudioChannelMask value;
+ CONVERT_CHECKED(audioChannelMaskFromHal(halConfigBase.channel_mask, isInput, &value),
+ result);
+ configBase->channelMask.value(std::move(value));
+ }
+ return result;
+}
+
+status_t HidlUtils::audioConfigBaseOptionalToHal(const AudioConfigBaseOptional& configBase,
+ audio_config_base_t* halConfigBase,
+ bool* formatSpecified, bool* sampleRateSpecified,
+ bool* channelMaskSpecified) {
+ status_t result = NO_ERROR;
+ *formatSpecified = configBase.format.getDiscriminator() ==
+ AudioConfigBaseOptional::Format::hidl_discriminator::value;
+ if (*formatSpecified) {
+ CONVERT_CHECKED(audioFormatToHal(configBase.format.value(), &halConfigBase->format),
+ result);
+ }
+ *sampleRateSpecified = configBase.sampleRateHz.getDiscriminator() ==
+ AudioConfigBaseOptional::SampleRate::hidl_discriminator::value;
+ if (*sampleRateSpecified) {
+ halConfigBase->sample_rate = configBase.sampleRateHz.value();
+ }
+ *channelMaskSpecified = configBase.channelMask.getDiscriminator() ==
+ AudioConfigBaseOptional::ChannelMask::hidl_discriminator::value;
+ if (*channelMaskSpecified) {
+ CONVERT_CHECKED(
+ audioChannelMaskToHal(configBase.channelMask.value(), &halConfigBase->channel_mask),
+ result);
+ }
+ return result;
+}
+
status_t HidlUtils::audioContentTypeFromHal(const audio_content_type_t halContentType,
AudioContentType* contentType) {
*contentType = audio_content_type_to_string(halContentType);
@@ -508,23 +561,14 @@
audio_port_config_has_input_direction(&halConfig), isInput);
result = BAD_VALUE;
}
- if (halConfig.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
- config->base.sampleRateHz = halConfig.sample_rate;
- } else {
- config->base.sampleRateHz = {};
- }
- if (halConfig.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
- CONVERT_CHECKED(
- audioChannelMaskFromHal(halConfig.channel_mask, isInput, &config->base.channelMask),
- result);
- } else {
- config->base.channelMask = {};
- }
- if (halConfig.config_mask & AUDIO_PORT_CONFIG_FORMAT) {
- CONVERT_CHECKED(audioFormatFromHal(halConfig.format, &config->base.format), result);
- } else {
- config->base.format = {};
- }
+ audio_config_base_t halConfigBase = {halConfig.sample_rate, halConfig.channel_mask,
+ halConfig.format};
+ CONVERT_CHECKED(
+ audioConfigBaseOptionalFromHal(
+ halConfigBase, isInput, halConfig.config_mask & AUDIO_PORT_CONFIG_FORMAT,
+ halConfig.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE,
+ halConfig.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK, &config->base),
+ result);
if (halConfig.config_mask & AUDIO_PORT_CONFIG_GAIN) {
config->gain.config({});
CONVERT_CHECKED(audioGainConfigFromHal(halConfig.gain, isInput, &config->gain.config()),
@@ -540,19 +584,23 @@
status_t result = NO_ERROR;
memset(halConfig, 0, sizeof(audio_port_config));
halConfig->id = config.id;
- halConfig->config_mask = {};
- if (config.base.sampleRateHz != 0) {
+ halConfig->config_mask = 0;
+ audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
+ bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false;
+ CONVERT_CHECKED(audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified,
+ &sRateSpecified, &channelMaskSpecified),
+ result);
+ if (sRateSpecified) {
halConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
- halConfig->sample_rate = config.base.sampleRateHz;
+ halConfig->sample_rate = halConfigBase.sample_rate;
}
- if (!config.base.channelMask.empty()) {
+ if (channelMaskSpecified) {
halConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
- CONVERT_CHECKED(audioChannelMaskToHal(config.base.channelMask, &halConfig->channel_mask),
- result);
+ halConfig->channel_mask = halConfigBase.channel_mask;
}
- if (!config.base.format.empty()) {
+ if (formatSpecified) {
halConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
- CONVERT_CHECKED(audioFormatToHal(config.base.format, &halConfig->format), result);
+ halConfig->format = halConfigBase.format;
}
if (config.gain.getDiscriminator() ==
AudioPortConfig::OptionalGain::hidl_discriminator::config) {
diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h
index 8e9275c..cc4fbf2 100644
--- a/audio/common/all-versions/default/HidlUtils.h
+++ b/audio/common/all-versions/default/HidlUtils.h
@@ -89,6 +89,15 @@
AudioConfigBase* configBase);
static status_t audioConfigBaseToHal(const AudioConfigBase& configBase,
audio_config_base_t* halConfigBase);
+ static status_t audioConfigBaseOptionalFromHal(const audio_config_base_t& halConfigBase,
+ bool isInput, bool formatSpecified,
+ bool sampleRateSpecified,
+ bool channelMaskSpecified,
+ AudioConfigBaseOptional* configBase);
+ static status_t audioConfigBaseOptionalToHal(const AudioConfigBaseOptional& configBase,
+ audio_config_base_t* halConfigBase,
+ bool* formatSpecified, bool* sampleRateSpecified,
+ bool* channelMaskSpecified);
static status_t audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device);
static status_t audioDeviceTypeToHal(const AudioDevice& device, audio_devices_t* halDevice);
static status_t audioFormatFromHal(audio_format_t halFormat, AudioFormat* format);
diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
index fef88b4..642ece3 100644
--- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
@@ -35,30 +35,27 @@
using namespace ::android::audio::policy::configuration::V7_0;
}
-static constexpr audio_channel_mask_t kInvalidHalChannelMask =
- static_cast<audio_channel_mask_t>(0xFFFFFFFFU);
+static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID;
static constexpr audio_content_type_t kInvalidHalContentType =
static_cast<audio_content_type_t>(0xFFFFFFFFU);
static constexpr audio_devices_t kInvalidHalDevice = static_cast<audio_devices_t>(0xFFFFFFFFU);
-static constexpr audio_format_t kInvalidHalFormat = static_cast<audio_format_t>(0xFFFFFFFFU);
+static constexpr audio_format_t kInvalidHalFormat = AUDIO_FORMAT_INVALID;
static constexpr audio_gain_mode_t kInvalidHalGainMode =
static_cast<audio_gain_mode_t>(0xFFFFFFFFU);
-static constexpr audio_source_t kInvalidHalSource = static_cast<audio_source_t>(0xFFFFFFFFU);
+// AUDIO_SOURCE_INVALID is framework-only.
+static constexpr audio_source_t kInvalidHalSource = static_cast<audio_source_t>(-1);
static constexpr audio_stream_type_t kInvalidHalStreamType =
static_cast<audio_stream_type_t>(0xFFFFFFFFU);
static constexpr audio_usage_t kInvalidHalUsage = static_cast<audio_usage_t>(0xFFFFFFFFU);
TEST(HidlUtils, ConvertInvalidChannelMask) {
AudioChannelMask invalid;
- EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(AUDIO_CHANNEL_INVALID,
- false /*isInput*/, &invalid));
- EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(AUDIO_CHANNEL_INVALID, true /*isInput*/,
- &invalid));
EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(kInvalidHalChannelMask,
false /*isInput*/, &invalid));
EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(kInvalidHalChannelMask,
true /*isInput*/, &invalid));
audio_channel_mask_t halInvalid;
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("", &halInvalid));
// INVALID channel mask is not in XSD thus it's not allowed for transfer over HIDL.
EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("AUDIO_CHANNEL_INVALID", &halInvalid));
EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("random string", &halInvalid));
@@ -148,40 +145,241 @@
}
}
+static AudioConfigBase generateValidConfigBase(bool isInput) {
+ AudioConfigBase configBase;
+ configBase.sampleRateHz = 44100;
+ configBase.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
+ configBase.channelMask = isInput ? toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_STEREO)
+ : toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
+ return configBase;
+}
+
TEST(HidlUtils, ConvertInvalidConfigBase) {
AudioConfigBase invalid;
- EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal({.sample_rate = 0,
- .channel_mask = kInvalidHalChannelMask,
- .format = kInvalidHalFormat},
- false /*isInput*/, &invalid));
- EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal({.sample_rate = 0,
- .channel_mask = kInvalidHalChannelMask,
- .format = kInvalidHalFormat},
- true /*isInput*/, &invalid));
+ audio_config_base_t halInvalidChannelMask = AUDIO_CONFIG_BASE_INITIALIZER;
+ halInvalidChannelMask.channel_mask = kInvalidHalChannelMask;
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal(halInvalidChannelMask, false /*isInput*/,
+ &invalid));
+ EXPECT_EQ(BAD_VALUE,
+ HidlUtils::audioConfigBaseFromHal(halInvalidChannelMask, true /*isInput*/, &invalid));
+ audio_config_base_t halInvalidFormat = AUDIO_CONFIG_BASE_INITIALIZER;
+ halInvalidFormat.format = kInvalidHalFormat;
+ EXPECT_EQ(BAD_VALUE,
+ HidlUtils::audioConfigBaseFromHal(halInvalidFormat, false /*isInput*/, &invalid));
+ EXPECT_EQ(BAD_VALUE,
+ HidlUtils::audioConfigBaseFromHal(halInvalidFormat, true /*isInput*/, &invalid));
+
audio_config_base_t halInvalid;
- invalid.sampleRateHz = 0;
- invalid.channelMask = "random string";
- invalid.format = "random string";
- EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseToHal(invalid, &halInvalid));
+ AudioConfigBase invalidChannelMask = generateValidConfigBase(false /*isInput*/);
+ invalidChannelMask.channelMask = "random string";
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseToHal(invalidChannelMask, &halInvalid));
+ AudioConfigBase invalidFormat = generateValidConfigBase(false /*isInput*/);
+ invalidFormat.format = "random string";
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseToHal(invalidFormat, &halInvalid));
+}
+
+TEST(HidlUtils, ConvertConfigBaseDefault) {
+ audio_config_base_t halBaseDefault = AUDIO_CONFIG_BASE_INITIALIZER;
+ AudioConfigBase baseDefaultOut, baseDefaultIn;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseFromHal(halBaseDefault, false /*isInput*/,
+ &baseDefaultOut));
+ EXPECT_EQ(NO_ERROR,
+ HidlUtils::audioConfigBaseFromHal(halBaseDefault, true /*isInput*/, &baseDefaultIn));
+ EXPECT_EQ(baseDefaultOut, baseDefaultIn);
+ audio_config_base_t halBaseDefaultBack;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(baseDefaultOut, &halBaseDefaultBack));
+ EXPECT_EQ(halBaseDefault.sample_rate, halBaseDefaultBack.sample_rate);
+ EXPECT_EQ(halBaseDefault.channel_mask, halBaseDefaultBack.channel_mask);
+ EXPECT_EQ(halBaseDefault.format, halBaseDefaultBack.format);
}
TEST(HidlUtils, ConvertConfigBase) {
- AudioConfigBase configBase;
- configBase.sampleRateHz = 44100;
- configBase.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
- configBase.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
- audio_config_base_t halConfigBase;
- EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(configBase, &halConfigBase));
- AudioConfigBase configBaseBack;
+ AudioConfigBase configBaseOut = generateValidConfigBase(false /*isInput*/);
+ audio_config_base_t halConfigBaseOut;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(configBaseOut, &halConfigBaseOut));
+ AudioConfigBase configBaseOutBack;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseFromHal(halConfigBaseOut, false /*isInput*/,
+ &configBaseOutBack));
+ EXPECT_EQ(configBaseOut, configBaseOutBack);
+
+ AudioConfigBase configBaseIn = generateValidConfigBase(true /*isInput*/);
+ audio_config_base_t halConfigBaseIn;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(configBaseIn, &halConfigBaseIn));
+ AudioConfigBase configBaseInBack;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseFromHal(halConfigBaseIn, true /*isInput*/,
+ &configBaseInBack));
+ EXPECT_EQ(configBaseIn, configBaseInBack);
+}
+
+TEST(HidlUtils, ConvertInvalidConfigBaseOptional) {
+ AudioConfigBaseOptional invalid;
+ audio_config_base_t halInvalidChannelMask = AUDIO_CONFIG_BASE_INITIALIZER;
+ halInvalidChannelMask.channel_mask = kInvalidHalChannelMask;
+ EXPECT_EQ(BAD_VALUE,
+ HidlUtils::audioConfigBaseOptionalFromHal(
+ halInvalidChannelMask, false /*isInput*/, false /*formatSpecified*/,
+ false /*sampleRateSpecified*/, true /*channelMaskSpecified*/, &invalid));
+ EXPECT_EQ(BAD_VALUE,
+ HidlUtils::audioConfigBaseOptionalFromHal(
+ halInvalidChannelMask, true /*isInput*/, false /*formatSpecified*/,
+ false /*sampleRateSpecified*/, true /*channelMaskSpecified*/, &invalid));
+ // Unspecified invalid values are ignored
+ AudioConfigBaseOptional unspecified;
EXPECT_EQ(NO_ERROR,
- HidlUtils::audioConfigBaseFromHal(halConfigBase, false /*isInput*/, &configBaseBack));
- EXPECT_EQ(configBase, configBaseBack);
+ HidlUtils::audioConfigBaseOptionalFromHal(
+ halInvalidChannelMask, false /*isInput*/, false /*formatSpecified*/,
+ false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified));
+ EXPECT_EQ(NO_ERROR,
+ HidlUtils::audioConfigBaseOptionalFromHal(
+ halInvalidChannelMask, true /*isInput*/, false /*formatSpecified*/,
+ false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified));
+ audio_config_base_t halInvalidFormat = AUDIO_CONFIG_BASE_INITIALIZER;
+ halInvalidFormat.format = kInvalidHalFormat;
+ EXPECT_EQ(BAD_VALUE,
+ HidlUtils::audioConfigBaseOptionalFromHal(
+ halInvalidFormat, false /*isInput*/, true /*formatSpecified*/,
+ false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &invalid));
+ EXPECT_EQ(BAD_VALUE,
+ HidlUtils::audioConfigBaseOptionalFromHal(
+ halInvalidFormat, true /*isInput*/, true /*formatSpecified*/,
+ false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &invalid));
+ EXPECT_EQ(NO_ERROR,
+ HidlUtils::audioConfigBaseOptionalFromHal(
+ halInvalidFormat, false /*isInput*/, false /*formatSpecified*/,
+ false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified));
+ EXPECT_EQ(NO_ERROR,
+ HidlUtils::audioConfigBaseOptionalFromHal(
+ halInvalidFormat, true /*isInput*/, false /*formatSpecified*/,
+ false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified));
+
+ audio_config_base_t halInvalid;
+ AudioConfigBaseOptional invalidChannelMask;
+ bool formatSpecified, sampleRateSpecified, channelMaskSpecified;
+ invalidChannelMask.channelMask.value("random string");
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseOptionalToHal(
+ invalidChannelMask, &halInvalid, &formatSpecified,
+ &sampleRateSpecified, &channelMaskSpecified));
+ AudioConfigBaseOptional invalidFormat;
+ invalidFormat.format.value("random string");
+ EXPECT_EQ(BAD_VALUE,
+ HidlUtils::audioConfigBaseOptionalToHal(invalidFormat, &halInvalid, &formatSpecified,
+ &sampleRateSpecified, &channelMaskSpecified));
+}
+
+TEST(HidlUtils, ConvertConfigBaseOptionalDefault) {
+ audio_config_base_t halBaseDefault = AUDIO_CONFIG_BASE_INITIALIZER;
+ AudioConfigBaseOptional baseDefaultUnspecOut, baseDefaultUnspecIn;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+ halBaseDefault, false /*isInput*/, false /*formatSpecified*/,
+ false /*sampleRateSpecified*/, false /*channelMaskSpecified*/,
+ &baseDefaultUnspecOut));
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+ halBaseDefault, true /*isInput*/, false /*formatSpecified*/,
+ false /*sampleRateSpecified*/, false /*channelMaskSpecified*/,
+ &baseDefaultUnspecIn));
+ EXPECT_EQ(baseDefaultUnspecOut, baseDefaultUnspecIn);
+ audio_config_base_t halBaseDefaultUnspecBack = AUDIO_CONFIG_BASE_INITIALIZER;
+ bool formatSpecified, sampleRateSpecified, channelMaskSpecified;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal(
+ baseDefaultUnspecOut, &halBaseDefaultUnspecBack, &formatSpecified,
+ &sampleRateSpecified, &channelMaskSpecified));
+ EXPECT_FALSE(formatSpecified);
+ EXPECT_FALSE(sampleRateSpecified);
+ EXPECT_FALSE(channelMaskSpecified);
+ EXPECT_EQ(halBaseDefault.sample_rate, halBaseDefaultUnspecBack.sample_rate);
+ EXPECT_EQ(halBaseDefault.channel_mask, halBaseDefaultUnspecBack.channel_mask);
+ EXPECT_EQ(halBaseDefault.format, halBaseDefaultUnspecBack.format);
+
+ AudioConfigBaseOptional baseDefaultSpecOut, baseDefaultSpecIn;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+ halBaseDefault, false /*isInput*/, true /*formatSpecified*/,
+ true /*sampleRateSpecified*/, true /*channelMaskSpecified*/,
+ &baseDefaultSpecOut));
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+ halBaseDefault, true /*isInput*/, true /*formatSpecified*/,
+ true /*sampleRateSpecified*/, true /*channelMaskSpecified*/,
+ &baseDefaultSpecIn));
+ EXPECT_EQ(baseDefaultSpecOut, baseDefaultSpecIn);
+ audio_config_base_t halBaseDefaultSpecBack;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal(
+ baseDefaultSpecOut, &halBaseDefaultSpecBack, &formatSpecified,
+ &sampleRateSpecified, &channelMaskSpecified));
+ EXPECT_TRUE(formatSpecified);
+ EXPECT_TRUE(sampleRateSpecified);
+ EXPECT_TRUE(channelMaskSpecified);
+ EXPECT_EQ(halBaseDefault.sample_rate, halBaseDefaultSpecBack.sample_rate);
+ EXPECT_EQ(halBaseDefault.channel_mask, halBaseDefaultSpecBack.channel_mask);
+ EXPECT_EQ(halBaseDefault.format, halBaseDefaultSpecBack.format);
+}
+
+TEST(HidlUtils, ConvertConfigBaseOptionalEmpty) {
+ AudioConfigBaseOptional empty;
+ bool formatSpecified, sampleRateSpecified, channelMaskSpecified;
+ audio_config_base_t halEmpty = AUDIO_CONFIG_BASE_INITIALIZER;
+ EXPECT_EQ(NO_ERROR,
+ HidlUtils::audioConfigBaseOptionalToHal(empty, &halEmpty, &formatSpecified,
+ &sampleRateSpecified, &channelMaskSpecified));
+ EXPECT_FALSE(formatSpecified);
+ EXPECT_FALSE(sampleRateSpecified);
+ EXPECT_FALSE(channelMaskSpecified);
+ AudioConfigBaseOptional emptyOutBack, emptyInBack;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+ halEmpty, false /*isInput*/, formatSpecified, sampleRateSpecified,
+ channelMaskSpecified, &emptyOutBack));
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+ halEmpty, true /*isInput*/, formatSpecified, sampleRateSpecified,
+ channelMaskSpecified, &emptyInBack));
+ EXPECT_EQ(emptyOutBack, emptyInBack);
+ EXPECT_EQ(empty, emptyOutBack);
+}
+
+TEST(HidlUtils, ConvertConfigBaseOptional) {
+ AudioConfigBase validBaseOut = generateValidConfigBase(false /*isInput*/);
+ AudioConfigBaseOptional configBaseOut;
+ configBaseOut.format.value(validBaseOut.format);
+ configBaseOut.sampleRateHz.value(validBaseOut.sampleRateHz);
+ configBaseOut.channelMask.value(validBaseOut.channelMask);
+ audio_config_base_t halConfigBaseOut;
+ bool formatSpecified, sampleRateSpecified, channelMaskSpecified;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal(
+ configBaseOut, &halConfigBaseOut, &formatSpecified,
+ &sampleRateSpecified, &channelMaskSpecified));
+ EXPECT_TRUE(formatSpecified);
+ EXPECT_TRUE(sampleRateSpecified);
+ EXPECT_TRUE(channelMaskSpecified);
+ AudioConfigBaseOptional configBaseOutBack;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+ halConfigBaseOut, false /*isInput*/, formatSpecified,
+ sampleRateSpecified, channelMaskSpecified, &configBaseOutBack));
+ EXPECT_EQ(configBaseOut, configBaseOutBack);
+
+ AudioConfigBase validBaseIn = generateValidConfigBase(true /*isInput*/);
+ AudioConfigBaseOptional configBaseIn;
+ configBaseIn.format.value(validBaseIn.format);
+ configBaseIn.sampleRateHz.value(validBaseIn.sampleRateHz);
+ configBaseIn.channelMask.value(validBaseIn.channelMask);
+ audio_config_base_t halConfigBaseIn;
+ formatSpecified = false;
+ sampleRateSpecified = false;
+ channelMaskSpecified = false;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal(
+ configBaseIn, &halConfigBaseIn, &formatSpecified,
+ &sampleRateSpecified, &channelMaskSpecified));
+ EXPECT_TRUE(formatSpecified);
+ EXPECT_TRUE(sampleRateSpecified);
+ EXPECT_TRUE(channelMaskSpecified);
+ AudioConfigBaseOptional configBaseInBack;
+ EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal(
+ halConfigBaseIn, true /*isInput*/, formatSpecified,
+ sampleRateSpecified, channelMaskSpecified, &configBaseInBack));
+ EXPECT_EQ(configBaseIn, configBaseInBack);
}
TEST(HidlUtils, ConvertInvalidContentType) {
AudioContentType invalid;
EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeFromHal(kInvalidHalContentType, &invalid));
audio_content_type_t halInvalid;
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeToHal("", &halInvalid));
EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeToHal("random string", &halInvalid));
}
@@ -202,6 +400,7 @@
AudioDevice invalid;
EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeFromHal(kInvalidHalDevice, &invalid));
audio_devices_t halInvalid;
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeToHal("", &halInvalid));
EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeToHal("random string", &halInvalid));
}
@@ -233,6 +432,7 @@
// The enums module is too small to have unit tests on its own.
TEST(HidlUtils, VendorExtension) {
EXPECT_TRUE(xsd::isVendorExtension("VX_GOOGLE_VR_42"));
+ EXPECT_FALSE(xsd::isVendorExtension(""));
EXPECT_FALSE(xsd::isVendorExtension("random string"));
EXPECT_FALSE(xsd::isVendorExtension("VX_"));
EXPECT_FALSE(xsd::isVendorExtension("VX_GOOGLE_$$"));
@@ -347,6 +547,9 @@
AudioFormat invalid;
EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatFromHal(kInvalidHalFormat, &invalid));
audio_format_t halInvalid;
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatToHal("", &halInvalid));
+ // INVALID format is not in XSD thus it's not allowed for transfer over HIDL.
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatToHal("AUDIO_FORMAT_INVALID", &halInvalid));
EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatToHal("random string", &halInvalid));
}
@@ -357,8 +560,9 @@
AudioFormat formatBack;
EXPECT_EQ(NO_ERROR, HidlUtils::audioFormatToHal(format, &halFormat))
<< "Conversion of \"" << format << "\" failed";
- EXPECT_TRUE(audio_is_valid_format(halFormat))
- << "Converted format \"" << format << "\" is invalid";
+ EXPECT_EQ(enumVal != xsd::AudioFormat::AUDIO_FORMAT_DEFAULT,
+ audio_is_valid_format(halFormat))
+ << "Validity of \"" << format << "\" is not as expected";
EXPECT_EQ(NO_ERROR, HidlUtils::audioFormatFromHal(halFormat, &formatBack))
<< "Conversion of format " << halFormat << " failed";
EXPECT_EQ(format, formatBack);
@@ -430,6 +634,9 @@
AudioSource invalid;
EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceFromHal(kInvalidHalSource, &invalid));
audio_source_t halInvalid;
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceToHal("", &halInvalid));
+ // INVALID source is not in XSD thus it's not allowed for transfer over HIDL.
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceToHal("AUDIO_SOURCE_INVALID", &halInvalid));
EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceToHal("random string", &halInvalid));
}
@@ -453,6 +660,7 @@
AudioStreamType invalid;
EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeFromHal(kInvalidHalStreamType, &invalid));
audio_stream_type_t halInvalid;
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeToHal("", &halInvalid));
EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeToHal("random string", &halInvalid));
}
@@ -524,6 +732,7 @@
AudioUsage invalid;
EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageFromHal(kInvalidHalUsage, &invalid));
audio_usage_t halInvalid;
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageToHal("", &halInvalid));
EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageToHal("random string", &halInvalid));
}
@@ -543,7 +752,7 @@
TEST(HidlUtils, ConvertInvalidOffloadInfo) {
AudioOffloadInfo invalid;
audio_offload_info_t halInvalid = AUDIO_INFO_INITIALIZER;
- halInvalid.channel_mask = AUDIO_CHANNEL_INVALID;
+ halInvalid.channel_mask = kInvalidHalChannelMask;
halInvalid.format = kInvalidHalFormat;
EXPECT_EQ(BAD_VALUE, HidlUtils::audioOffloadInfoFromHal(halInvalid, &invalid));
invalid.base.channelMask = "random string";
@@ -575,7 +784,7 @@
TEST(HidlUtils, ConvertInvalidConfig) {
AudioConfig invalid;
audio_config_t halInvalid = AUDIO_CONFIG_INITIALIZER;
- halInvalid.channel_mask = AUDIO_CHANNEL_INVALID;
+ halInvalid.channel_mask = kInvalidHalChannelMask;
halInvalid.format = kInvalidHalFormat;
EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, false /*isInput*/, &invalid));
EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, true /*isInput*/, &invalid));
@@ -655,18 +864,18 @@
halInvalid.type = AUDIO_PORT_TYPE_MIX;
halInvalid.role = AUDIO_PORT_ROLE_NONE; // note: this is valid.
halInvalid.config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK;
- halInvalid.channel_mask = AUDIO_CHANNEL_INVALID;
+ halInvalid.channel_mask = kInvalidHalChannelMask;
EXPECT_EQ(BAD_VALUE, HidlUtils::audioPortConfigFromHal(halInvalid, &invalid));
- invalid.base.channelMask = "random string";
+ invalid.base.channelMask.value("random string");
EXPECT_EQ(BAD_VALUE, HidlUtils::audioPortConfigToHal(invalid, &halInvalid));
}
TEST(HidlUtils, ConvertAudioPortConfig) {
AudioPortConfig config = {};
config.id = 42;
- config.base.sampleRateHz = 44100;
- config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
- config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
+ config.base.sampleRateHz.value(44100);
+ config.base.channelMask.value(toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO));
+ config.base.format.value(toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT));
config.gain.config({});
config.gain.config().channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
config.ext.device({});
@@ -734,7 +943,7 @@
{std::string(AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1, HidlUtils::sAudioTagSeparator)}};
EXPECT_EQ(BAD_VALUE, HidlUtils::audioTagsToHal(tagSeparator, halTag));
- hidl_vec<AudioTag> notExtensions = {{"random string", "VX_", "VX_GOOGLE_$$"}};
+ hidl_vec<AudioTag> notExtensions = {{"", "random string", "VX_", "VX_GOOGLE_$$"}};
EXPECT_EQ(BAD_VALUE, HidlUtils::audioTagsToHal(notExtensions, halTag));
}
diff --git a/audio/core/all-versions/default/Stream.cpp b/audio/core/all-versions/default/Stream.cpp
index f964cbb..3f8efd2 100644
--- a/audio/core/all-versions/default/Stream.cpp
+++ b/audio/core/all-versions/default/Stream.cpp
@@ -278,23 +278,36 @@
return Void();
}
-Return<Result> Stream::setAudioProperties(const AudioConfigBase& config) {
- audio_config_base_t halConfigBase = {};
- status_t status = HidlUtils::audioConfigBaseToHal(config, &halConfigBase);
+Return<Result> Stream::setAudioProperties(const AudioConfigBaseOptional& config) {
+ audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
+ bool formatSpecified, sRateSpecified, channelMaskSpecified;
+ status_t status = HidlUtils::audioConfigBaseOptionalToHal(
+ config, &halConfigBase, &formatSpecified, &sRateSpecified, &channelMaskSpecified);
if (status != NO_ERROR) {
return Stream::analyzeStatus("set_audio_properties", status);
}
- if (Result result = setParam(AudioParameter::keySamplingRate,
- static_cast<int>(halConfigBase.sample_rate));
- result != Result::OK) {
- return result;
+ if (sRateSpecified) {
+ if (Result result = setParam(AudioParameter::keySamplingRate,
+ static_cast<int>(halConfigBase.sample_rate));
+ result != Result::OK) {
+ return result;
+ }
}
- if (Result result =
- setParam(AudioParameter::keyChannels, static_cast<int>(halConfigBase.channel_mask));
- result != Result::OK) {
- return result;
+ if (channelMaskSpecified) {
+ if (Result result = setParam(AudioParameter::keyChannels,
+ static_cast<int>(halConfigBase.channel_mask));
+ result != Result::OK) {
+ return result;
+ }
}
- return setParam(AudioParameter::keyFormat, static_cast<int>(halConfigBase.format));
+ if (formatSpecified) {
+ if (Result result =
+ setParam(AudioParameter::keyFormat, static_cast<int>(halConfigBase.format));
+ result != Result::OK) {
+ return result;
+ }
+ }
+ return Result::OK;
}
#endif // MAJOR_VERSION <= 6
diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp
index 2c5e9f1..c670a4d 100644
--- a/audio/core/all-versions/default/StreamIn.cpp
+++ b/audio/core/all-versions/default/StreamIn.cpp
@@ -233,7 +233,7 @@
return mStreamCommon->getSupportedProfiles(_hidl_cb);
}
-Return<Result> StreamIn::setAudioProperties(const AudioConfigBase& config) {
+Return<Result> StreamIn::setAudioProperties(const AudioConfigBaseOptional& config) {
return mStreamCommon->setAudioProperties(config);
}
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index ffd3b6b..0b9af24 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -239,7 +239,7 @@
return mStreamCommon->getSupportedProfiles(_hidl_cb);
}
-Return<Result> StreamOut::setAudioProperties(const AudioConfigBase& config) {
+Return<Result> StreamOut::setAudioProperties(const AudioConfigBaseOptional& config) {
return mStreamCommon->setAudioProperties(config);
}
diff --git a/audio/core/all-versions/default/include/core/default/Stream.h b/audio/core/all-versions/default/include/core/default/Stream.h
index 0865992..66d60e3 100644
--- a/audio/core/all-versions/default/include/core/default/Stream.h
+++ b/audio/core/all-versions/default/include/core/default/Stream.h
@@ -77,7 +77,7 @@
Return<Result> setFormat(AudioFormat format) override;
#else
Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override;
- Return<Result> setAudioProperties(const AudioConfigBase& config) override;
+ Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override;
#endif // MAJOR_VERSION <= 6
Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override;
Return<Result> addEffect(uint64_t effectId) override;
diff --git a/audio/core/all-versions/default/include/core/default/StreamIn.h b/audio/core/all-versions/default/include/core/default/StreamIn.h
index 651b3a6..a980f3f 100644
--- a/audio/core/all-versions/default/include/core/default/StreamIn.h
+++ b/audio/core/all-versions/default/include/core/default/StreamIn.h
@@ -72,7 +72,7 @@
Return<Result> setFormat(AudioFormat format) override;
#else
Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override;
- Return<Result> setAudioProperties(const AudioConfigBase& config) override;
+ Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override;
#endif // MAJOR_VERSION <= 6
Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override;
Return<Result> addEffect(uint64_t effectId) override;
diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h
index b8e8515..ccc1c1a 100644
--- a/audio/core/all-versions/default/include/core/default/StreamOut.h
+++ b/audio/core/all-versions/default/include/core/default/StreamOut.h
@@ -72,7 +72,7 @@
Return<Result> setFormat(AudioFormat format) override;
#else
Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override;
- Return<Result> setAudioProperties(const AudioConfigBase& config) override;
+ Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override;
#endif // MAJOR_VERSION <= 6
Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override;
Return<Result> addEffect(uint64_t effectId) override;
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 7fca610..be1ffbb 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -367,10 +367,10 @@
static std::vector<AudioPortConfig> invalids = [&] {
std::vector<AudioPortConfig> result;
AudioPortConfig invalidBaseChannelMask = valids[PORT_CONF_MINIMAL];
- invalidBaseChannelMask.base.channelMask = "random_string";
+ invalidBaseChannelMask.base.channelMask.value("random_string");
result.push_back(std::move(invalidBaseChannelMask));
AudioPortConfig invalidBaseFormat = valids[PORT_CONF_MINIMAL];
- invalidBaseFormat.base.format = "random_string";
+ invalidBaseFormat.base.format.value("random_string");
result.push_back(std::move(invalidBaseFormat));
AudioPortConfig invalidGainMode = valids[PORT_CONF_WITH_GAIN];
invalidGainMode.gain.config().mode = {{"random_string"}};
@@ -724,19 +724,19 @@
areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
: testSetDevicesInvalidDeviceAddress(stream.get()));
-static void testSetAudioPropertiesInvalidArguments(IStream* stream, const AudioConfigBase& base) {
- AudioConfigBase invalidFormat = base;
- invalidFormat.format = "random_string";
+static void testSetAudioPropertiesInvalidArguments(IStream* stream) {
+ AudioConfigBaseOptional invalidFormat;
+ invalidFormat.format.value("random_string");
ASSERT_RESULT(invalidArgsOrNotSupported, stream->setAudioProperties(invalidFormat));
- AudioConfigBase invalidChannelMask = base;
- invalidChannelMask.channelMask = "random_string";
+ AudioConfigBaseOptional invalidChannelMask;
+ invalidChannelMask.channelMask.value("random_string");
ASSERT_RESULT(invalidArgsOrNotSupported, stream->setAudioProperties(invalidChannelMask));
}
TEST_SINGLE_CONFIG_IO_STREAM(
SetAudioPropertiesInvalidArguments,
"Verify that invalid arguments are rejected by IStream::setAudioProperties",
- testSetAudioPropertiesInvalidArguments(stream.get(), audioConfig.base));
+ testSetAudioPropertiesInvalidArguments(stream.get()));
TEST_P(SingleConfigOutputStreamTest, UpdateInvalidSourceMetadata) {
doc::test("Verify that invalid metadata is rejected by IStreamOut::updateSourceMetadata");
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index f145b60..2b9e336 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -1155,13 +1155,14 @@
for (const auto& profile : profiles) {
for (const auto& sampleRate : profile.sampleRates) {
for (const auto& channelMask : profile.channelMasks) {
- AudioConfigBase config{.format = profile.format,
- .sampleRateHz = sampleRate,
- .channelMask = {{channelMask}}};
+ AudioConfigBaseOptional config;
+ config.format.value(profile.format);
+ config.sampleRateHz.value(sampleRate);
+ config.channelMask.value(channelMask);
auto ret = stream->setAudioProperties(config);
EXPECT_TRUE(ret.isOk());
- EXPECT_EQ(Result::OK, ret) << config.format << "; " << config.sampleRateHz << "; "
- << toString(config.channelMask);
+ EXPECT_EQ(Result::OK, ret)
+ << profile.format << "; " << sampleRate << "; " << channelMask;
}
}
}
@@ -1169,7 +1170,7 @@
TEST_IO_STREAM(SetAudioProperties, "Call setAudioProperties for all supported profiles",
testSetAudioProperties(stream.get()))
-#endif
+#endif // MAJOR_VERSION <= 6
static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
#if MAJOR_VERSION <= 6
diff --git a/audio/effect/7.0/types.hal b/audio/effect/7.0/types.hal
index c4cb213..bb2d7b3 100644
--- a/audio/effect/7.0/types.hal
+++ b/audio/effect/7.0/types.hal
@@ -17,6 +17,7 @@
package android.hardware.audio.effect@7.0;
import android.hardware.audio.common@7.0;
+import android.hidl.safe_union@1.0;
enum Result : int32_t {
OK,
@@ -248,32 +249,19 @@
};
/**
- * Determines what fields of EffectBufferConfig need to be considered.
- */
-@export(name="", value_prefix="EFFECT_CONFIG_")
-enum EffectConfigParameters : int32_t {
- /** Buffer field. */
- BUFFER = 0x0001,
- /** Sampling rate. */
- SMP_RATE = 0x0002,
- /** Channels. */
- CHANNELS = 0x0004,
- /** Format. */
- FORMAT = 0x0008,
- /** Access mode. */
- ACC_MODE = 0x0010,
- // Note that the 2.0 ALL have been moved to an helper function
-};
-
-/**
* The buffer config structure specifies the input or output audio format
* to be used by the effect engine.
*/
struct EffectBufferConfig {
- AudioBuffer buffer;
- AudioConfigBase base;
- EffectBufferAccess accessMode;
- bitfield<EffectConfigParameters> mask;
+ safe_union OptionalBuffer {
+ Monostate unspecified;
+ AudioBuffer buf;
+ } buffer;
+ AudioConfigBaseOptional base;
+ safe_union OptionalAccessMode {
+ Monostate unspecified;
+ EffectBufferAccess value;
+ } accessMode;
};
struct EffectConfig {
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index edd364c..58f1779 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -249,14 +249,17 @@
void Effect::effectBufferConfigFromHal(const buffer_config_t& halConfig,
EffectBufferConfig* config) {
- config->buffer.id = 0;
- config->buffer.frameCount = 0;
+ config->buffer.unspecified();
audio_config_base_t halConfigBase = {halConfig.samplingRate,
static_cast<audio_channel_mask_t>(halConfig.channels),
static_cast<audio_format_t>(halConfig.format)};
- (void)HidlUtils::audioConfigBaseFromHal(halConfigBase, mIsInput, &config->base);
- config->accessMode = EffectBufferAccess(halConfig.accessMode);
- config->mask = static_cast<decltype(config->mask)>(halConfig.mask);
+ (void)HidlUtils::audioConfigBaseOptionalFromHal(
+ halConfigBase, mIsInput, halConfig.mask & EFFECT_CONFIG_FORMAT,
+ halConfig.mask & EFFECT_CONFIG_SMP_RATE, halConfig.mask & EFFECT_CONFIG_CHANNELS,
+ &config->base);
+ if (halConfig.mask & EFFECT_CONFIG_ACC_MODE) {
+ config->accessMode.value(EffectBufferAccess(halConfig.accessMode));
+ }
}
// static
@@ -265,17 +268,32 @@
// using 'setProcessBuffers'.
halConfig->buffer.frameCount = 0;
halConfig->buffer.raw = nullptr;
- audio_config_base_t halConfigBase;
- (void)HidlUtils::audioConfigBaseToHal(config.base, &halConfigBase);
- halConfig->samplingRate = halConfigBase.sample_rate;
- halConfig->channels = halConfigBase.channel_mask;
- halConfig->format = halConfigBase.format;
+ audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
+ bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false;
+ (void)HidlUtils::audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified,
+ &sRateSpecified, &channelMaskSpecified);
+ halConfig->mask = 0;
+ if (sRateSpecified) {
+ halConfig->mask |= EFFECT_CONFIG_SMP_RATE;
+ halConfig->samplingRate = halConfigBase.sample_rate;
+ }
+ if (channelMaskSpecified) {
+ halConfig->mask |= EFFECT_CONFIG_CHANNELS;
+ halConfig->channels = halConfigBase.channel_mask;
+ }
+ if (formatSpecified) {
+ halConfig->mask |= EFFECT_CONFIG_FORMAT;
+ halConfig->format = halConfigBase.format;
+ }
// Note: The framework code does not use BP.
halConfig->bufferProvider.cookie = nullptr;
halConfig->bufferProvider.getBuffer = nullptr;
halConfig->bufferProvider.releaseBuffer = nullptr;
- halConfig->accessMode = static_cast<uint8_t>(config.accessMode);
- halConfig->mask = static_cast<uint8_t>(config.mask);
+ if (config.accessMode.getDiscriminator() ==
+ EffectBufferConfig::OptionalAccessMode::hidl_discriminator::value) {
+ halConfig->mask |= EFFECT_CONFIG_ACC_MODE;
+ halConfig->accessMode = static_cast<uint8_t>(config.accessMode.value());
+ }
}
#endif // MAJOR_VERSION <= 6
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index 35ff869..15a2fd9 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -264,8 +264,10 @@
*channelCount = audio_channel_count_from_out_mask(
static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels));
#else
+ ASSERT_EQ(AudioConfigBaseOptional::ChannelMask::hidl_discriminator::value,
+ currentConfig.outputCfg.base.channelMask.getDiscriminator());
*channelCount = android::audio::policy::configuration::V7_0::getChannelCount(
- currentConfig.outputCfg.base.channelMask);
+ currentConfig.outputCfg.base.channelMask.value());
ASSERT_NE(*channelCount, 0);
#endif
}
@@ -315,10 +317,10 @@
std::vector<EffectBufferConfig> generateInvalidConfigs(const EffectBufferConfig& src) {
std::vector<EffectBufferConfig> result;
EffectBufferConfig invalidFormat = src;
- invalidFormat.base.format = "random_string";
+ invalidFormat.base.format.value("random_string");
result.push_back(std::move(invalidFormat));
EffectBufferConfig invalidChannelMask = src;
- invalidChannelMask.base.channelMask = "random_string";
+ invalidChannelMask.base.channelMask.value("random_string");
result.push_back(std::move(invalidChannelMask));
return result;
}
@@ -395,17 +397,22 @@
rhs.data.handle() == nullptr;
}
+#if MAJOR_VERSION <= 6
inline bool operator==(const EffectBufferConfig& lhs, const EffectBufferConfig& rhs) {
return lhs.buffer == rhs.buffer &&
-#if MAJOR_VERSION <= 6
lhs.samplingRateHz == rhs.samplingRateHz && lhs.channels == rhs.channels &&
lhs.format == rhs.format &&
-#else
- lhs.base.sampleRateHz == rhs.base.sampleRateHz &&
- lhs.base.channelMask == rhs.base.channelMask && lhs.base.format == rhs.base.format &&
-#endif
lhs.accessMode == rhs.accessMode && lhs.mask == rhs.mask;
}
+#else
+inline bool operator==(const EffectBufferConfig& lhs, const EffectBufferConfig& rhs) {
+ return lhs.buffer.getDiscriminator() == rhs.buffer.getDiscriminator() &&
+ (lhs.buffer.getDiscriminator() ==
+ EffectBufferConfig::OptionalBuffer::hidl_discriminator::unspecified ||
+ lhs.buffer.buf() == rhs.buffer.buf()) &&
+ lhs.base == rhs.base && lhs.accessMode == rhs.accessMode;
+}
+#endif // MAJOR_VERSION <= 6
inline bool operator==(const EffectConfig& lhs, const EffectConfig& rhs) {
return lhs.inputCfg == rhs.inputCfg && lhs.outputCfg == rhs.outputCfg;