diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2021-01-30 01:00:44 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-01-30 01:00:44 +0000 |
commit | d5200fcdbae5e0a3c812a6f73448c607b19f5dbf (patch) | |
tree | b82aeb7a554bc429f3f1e520c0352b79ca65673a | |
parent | 8d17bb783b57aa15e22f5cdd8824236ef6369194 (diff) | |
parent | 418ad80fee08d05896081b9cd0daf95bc1a289c6 (diff) |
Merge "audio: Update common types to better match legacy structs" am: 39059ed17f am: 418ad80fee
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1562143
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I3a66c407a59a4df246ed2be195664465de18c23b
19 files changed, 465 insertions, 154 deletions
diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal index ab9aa7dae3..393e38f6a0 100644 --- a/audio/7.0/IStream.hal +++ b/audio/7.0/IStream.hal @@ -73,14 +73,14 @@ interface IStream { /** * 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 1da8b095bc..8a4662f0e6 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -198,6 +198,7 @@ package android.audio.policy.configuration.V7_0 { 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 56b3a27161..685e84a1af 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 27f28c6ea6..578881148a 100644 --- a/audio/common/7.0/example/Effect.cpp +++ b/audio/common/7.0/example/Effect.cpp @@ -107,14 +107,13 @@ Return<Result> Effect::setInputDevice(const DeviceAddress& device) { } 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 ed6d94f988..3903a0b2ce 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -118,9 +118,28 @@ typedef string AudioChannelMask; * 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 @@ struct AudioPortConfig { */ 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 de19faf153..f09db5ed98 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 @@ status_t HidlUtils::audioConfigBaseToHal(const AudioConfigBase& configBase, 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 @@ status_t HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halCo 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 HidlUtils::audioPortConfigToHal(const AudioPortConfig& config, 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 8e9275c441..cc4fbf2f15 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -89,6 +89,15 @@ struct HidlUtils { 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 fef88b450b..642ece3255 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 @@ namespace xsd { 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 @@ TEST(HidlUtils, ConvertChannelMasksFromHal) { } } +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::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::audioConfigBaseFromHal(halConfigBase, false /*isInput*/, &configBaseBack)); - EXPECT_EQ(configBase, configBaseBack); + 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 @@ TEST(HidlUtils, ConvertInvalidDeviceType) { 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 @@ TEST(HidlUtils, ConvertDeviceType) { // 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 @@ TEST(HidlUtils, ConvertInvalidFormat) { 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 @@ TEST(HidlUtils, ConvertFormat) { 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 @@ TEST(HidlUtils, ConvertInvalidSource) { 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 @@ TEST(HidlUtils, ConvertInvalidStreamType) { 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 @@ TEST(HidlUtils, ConvertInvalidUsage) { 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, ConvertUsage) { 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, ConvertOffloadInfo) { 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 @@ TEST(HidlUtils, ConvertInvalidAudioPortConfig) { 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 @@ TEST(HidlUtils, ConvertInvalidAudioTags) { {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 f964cbb804..3f8efd231f 100644 --- a/audio/core/all-versions/default/Stream.cpp +++ b/audio/core/all-versions/default/Stream.cpp @@ -278,23 +278,36 @@ Return<void> Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) { 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 (channelMaskSpecified) { + if (Result result = setParam(AudioParameter::keyChannels, + static_cast<int>(halConfigBase.channel_mask)); + result != Result::OK) { + return result; + } } - if (Result result = - setParam(AudioParameter::keyChannels, static_cast<int>(halConfigBase.channel_mask)); - result != Result::OK) { - return result; + if (formatSpecified) { + if (Result result = + setParam(AudioParameter::keyFormat, static_cast<int>(halConfigBase.format)); + result != Result::OK) { + return result; + } } - return setParam(AudioParameter::keyFormat, static_cast<int>(halConfigBase.format)); + 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 2c5e9f1521..c670a4da73 100644 --- a/audio/core/all-versions/default/StreamIn.cpp +++ b/audio/core/all-versions/default/StreamIn.cpp @@ -233,7 +233,7 @@ Return<void> StreamIn::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { 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 21d439c25d..233575c891 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -239,7 +239,7 @@ Return<void> StreamOut::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { 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 0865992f95..66d60e3aa7 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 @@ struct Stream : public IStream, public ParametersUtil { 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 651b3a6ae1..a980f3f999 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 @@ struct StreamIn : public IStreamIn { 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 b8e8515739..ccc1c1a3f8 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 @@ struct StreamOut : public IStreamOut { 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 7fca61036d..be1ffbbcfe 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>& generatePortConfigs(bool valid) { 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 @@ TEST_SINGLE_CONFIG_IO_STREAM( 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 f145b606de..2b9e336c2d 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -1155,13 +1155,14 @@ static void testSetAudioProperties(IStream* stream) { 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 @@ static void testSetAudioProperties(IStream* stream) { 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 c4cb213a86..bb2d7b3d06 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 @@ enum EffectBufferAccess : int32_t { }; /** - * 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 edd364cd9b..58f1779ffd 100644 --- a/audio/effect/all-versions/default/Effect.cpp +++ b/audio/effect/all-versions/default/Effect.cpp @@ -249,14 +249,17 @@ void Effect::effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config, 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 @@ void Effect::effectBufferConfigToHal(const EffectBufferConfig& config, buffer_co // 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 35ff8693a4..15a2fd928c 100644 --- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp +++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp @@ -264,8 +264,10 @@ void AudioEffectHidlTest::getChannelCount(uint32_t* channelCount) { *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 @@ TEST_P(AudioEffectHidlTest, GetSetConfig) { 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 @@ inline bool operator==(const AudioBuffer& lhs, const AudioBuffer& rhs) { 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; |