diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index ed56c7320f..b14ebd48d9 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -274,10 +274,21 @@ struct AudioConfig { uint64_t frameCount; }; +/** + * AudioTag is an additional use case qualifier complementing + * AudioUsage and AudioContentType. Tags are set by vendor specific applications + * and must be prefixed by "VX_". Vendor must namespace their tag + * names to avoid conflicts. + */ +typedef string AudioTag; + /** Metadata of a playback track for a StreamOut. */ struct PlaybackTrackMetadata { AudioUsage usage; AudioContentType contentType; + /** Tags from AudioTrack audio atttributes */ + vec tags; + AudioChannelMask channelMask; /** * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation, * 2 means double amplification... @@ -294,6 +305,9 @@ struct SourceMetadata { /** Metadata of a record track for a StreamIn. */ struct RecordTrackMetadata { AudioSource source; + /** Tags from AudioTrack audio atttributes */ + vec tags; + AudioChannelMask channelMask; /** * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation, * 2 means double amplification... diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h index a0bd1bc27e..d8b7ba419e 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -77,6 +77,8 @@ struct HidlUtils { #endif #if MAJOR_VERSION >= 7 + static constexpr char sAudioTagSeparator = ';'; + static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput, AudioChannelMask* channelMask); static status_t audioChannelMasksFromHal(const std::vector& halChannelMasks, @@ -126,6 +128,7 @@ struct HidlUtils { struct audio_port_config_device_ext* device, struct audio_port_config_mix_ext* mix, struct audio_port_config_session_ext* session); + #endif // MAJOR_VERSION >= 7 // V4 and below have DeviceAddress defined in the 'core' interface. diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp index ead7204712..a6735546f3 100644 --- a/audio/core/all-versions/default/StreamIn.cpp +++ b/audio/core/all-versions/default/StreamIn.cpp @@ -478,29 +478,85 @@ Return StreamIn::debug(const hidl_handle& fd, const hidl_vec& } #if MAJOR_VERSION >= 4 -Return StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) { - if (mStream->update_sink_metadata == nullptr) { - return Void(); // not supported by the HAL + +record_track_metadata StreamIn::convertRecordTrackMetadata( + const RecordTrackMetadata& trackMetadata) { + record_track_metadata halTrackMetadata = {.gain = trackMetadata.gain}; + (void)HidlUtils::audioSourceToHal(trackMetadata.source, &halTrackMetadata.source); +#if MAJOR_VERSION >= 5 + if (trackMetadata.destination.getDiscriminator() == + RecordTrackMetadata::Destination::hidl_discriminator::device) { + (void)deviceAddressToHal(trackMetadata.destination.device(), &halTrackMetadata.dest_device, + halTrackMetadata.dest_device_address); } +#endif + return halTrackMetadata; +} + +void StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) { std::vector halTracks; halTracks.reserve(sinkMetadata.tracks.size()); for (auto& metadata : sinkMetadata.tracks) { - record_track_metadata halTrackMetadata = {.gain = metadata.gain}; - (void)HidlUtils::audioSourceToHal(metadata.source, &halTrackMetadata.source); -#if MAJOR_VERSION >= 5 - if (metadata.destination.getDiscriminator() == - RecordTrackMetadata::Destination::hidl_discriminator::device) { - (void)deviceAddressToHal(metadata.destination.device(), &halTrackMetadata.dest_device, - halTrackMetadata.dest_device_address); - } -#endif - halTracks.push_back(halTrackMetadata); + halTracks.push_back(convertRecordTrackMetadata(metadata)); } const sink_metadata_t halMetadata = { .track_count = halTracks.size(), .tracks = halTracks.data(), }; mStream->update_sink_metadata(mStream, &halMetadata); +} + +#if MAJOR_VERSION >= 7 +record_track_metadata_v7 StreamIn::convertRecordTrackMetadataV7( + const RecordTrackMetadata& trackMetadata) { + record_track_metadata_v7 halTrackMetadata; + halTrackMetadata.base = convertRecordTrackMetadata(trackMetadata); + (void)HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask, + &halTrackMetadata.channel_mask); + std::string halTags; + for (const auto& tag : trackMetadata.tags) { + if (&tag != &trackMetadata.tags[0]) { + halTags += HidlUtils::sAudioTagSeparator; + } + halTags += tag.c_str(); + } + strncpy(halTrackMetadata.tags, halTags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE); + return halTrackMetadata; +} + +void StreamIn::doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata) { + std::vector halTracks; + halTracks.reserve(sinkMetadata.tracks.size()); + for (auto& metadata : sinkMetadata.tracks) { + halTracks.push_back(convertRecordTrackMetadataV7(metadata)); + } + const sink_metadata_v7_t halMetadata = { + .track_count = halTracks.size(), + .tracks = halTracks.data(), + }; + mStream->update_sink_metadata_v7(mStream, &halMetadata); +} +#endif // MAJOR_VERSION >= 7 + +Return StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) { +#if MAJOR_VERSION < 7 + if (mStream->update_sink_metadata == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSinkMetadata(sinkMetadata); +#else + if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) { + if (mStream->update_sink_metadata == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSinkMetadata(sinkMetadata); + } else { + if (mStream->update_sink_metadata_v7 == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSinkMetadataV7(sinkMetadata); + } +#endif // MAJOR_VERSION < 7 return Void(); } diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index 5633cbb4b7..2451b9eb3a 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -585,26 +585,82 @@ Return StreamOut::debug(const hidl_handle& fd, const hidl_vec } #if MAJOR_VERSION >= 4 -Return StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) { - if (mStream->update_source_metadata == nullptr) { - return Void(); // not supported by the HAL - } +playback_track_metadata StreamOut::convertPlaybackTrackMetadata( + const PlaybackTrackMetadata& trackMetadata) { + playback_track_metadata_t halTrackMetadata = {.gain = trackMetadata.gain}; + (void)HidlUtils::audioUsageToHal(trackMetadata.usage, &halTrackMetadata.usage); + (void)HidlUtils::audioContentTypeToHal(trackMetadata.contentType, + &halTrackMetadata.content_type); + return halTrackMetadata; +} + +void StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) { std::vector halTracks; halTracks.reserve(sourceMetadata.tracks.size()); for (auto& metadata : sourceMetadata.tracks) { - playback_track_metadata_t halTrackMetadata = {.gain = metadata.gain}; - (void)HidlUtils::audioUsageToHal(metadata.usage, &halTrackMetadata.usage); - (void)HidlUtils::audioContentTypeToHal(metadata.contentType, - &halTrackMetadata.content_type); - halTracks.push_back(std::move(halTrackMetadata)); + halTracks.push_back(convertPlaybackTrackMetadata(metadata)); } const source_metadata_t halMetadata = { .track_count = halTracks.size(), .tracks = halTracks.data(), }; mStream->update_source_metadata(mStream, &halMetadata); +} + +#if MAJOR_VERSION >= 7 +playback_track_metadata_v7 StreamOut::convertPlaybackTrackMetadataV7( + const PlaybackTrackMetadata& trackMetadata) { + playback_track_metadata_v7 halTrackMetadata; + halTrackMetadata.base = convertPlaybackTrackMetadata(trackMetadata); + (void)HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask, + &halTrackMetadata.channel_mask); + std::string halTags; + for (const auto& tag : trackMetadata.tags) { + if (&tag != &trackMetadata.tags[0]) { + halTags += HidlUtils::sAudioTagSeparator; + } + halTags += tag.c_str(); + } + strncpy(halTrackMetadata.tags, halTags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE); + return halTrackMetadata; +} + +void StreamOut::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) { + std::vector halTracks; + halTracks.reserve(sourceMetadata.tracks.size()); + for (auto& metadata : sourceMetadata.tracks) { + halTracks.push_back(convertPlaybackTrackMetadataV7(metadata)); + } + const source_metadata_v7_t halMetadata = { + .track_count = halTracks.size(), + .tracks = halTracks.data(), + }; + mStream->update_source_metadata_v7(mStream, &halMetadata); +} +#endif // MAJOR_VERSION >= 7 + +Return StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) { +#if MAJOR_VERSION < 7 + if (mStream->update_source_metadata == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSourceMetadata(sourceMetadata); +#else + if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) { + if (mStream->update_source_metadata == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSourceMetadata(sourceMetadata); + } else { + if (mStream->update_source_metadata_v7 == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSourceMetadataV7(sourceMetadata); + } +#endif // MAJOR_VERSION < 7 return Void(); } + Return StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t /*programId*/) { return Result::NOT_SUPPORTED; // TODO: propagate to legacy } diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h index 461c253768..2a4d22651a 100644 --- a/audio/core/all-versions/default/include/core/default/Device.h +++ b/audio/core/all-versions/default/include/core/default/Device.h @@ -146,6 +146,8 @@ struct Device : public IDevice, public ParametersUtil { void closeOutputStream(audio_stream_out_t* stream); audio_hw_device_t* device() const { return mDevice; } + uint32_t version() const { return mDevice->common.version; } + private: bool mIsClosed; audio_hw_device_t* mDevice; @@ -161,8 +163,6 @@ struct Device : public IDevice, public ParametersUtil { // Methods from ParametersUtil. char* halGetParameters(const char* keys) override; int halSetParameters(const char* keysAndValues) override; - - uint32_t version() const { return mDevice->common.version; } }; } // namespace implementation 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 b861c6cc2b..512da559bf 100644 --- a/audio/core/all-versions/default/include/core/default/StreamIn.h +++ b/audio/core/all-versions/default/include/core/default/StreamIn.h @@ -124,7 +124,16 @@ struct StreamIn : public IStreamIn { static Result getCapturePositionImpl(audio_stream_in_t* stream, uint64_t* frames, uint64_t* time); - private: + private: +#if MAJOR_VERSION >= 4 + record_track_metadata convertRecordTrackMetadata(const RecordTrackMetadata& trackMetadata); + void doUpdateSinkMetadata(const SinkMetadata& sinkMetadata); +#if MAJOR_VERSION >= 7 + record_track_metadata_v7 convertRecordTrackMetadataV7(const RecordTrackMetadata& trackMetadata); + void doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata); +#endif +#endif + const sp mDevice; audio_stream_in_t* mStream; const sp mStreamCommon; 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 9f64e3e77d..8da940d846 100644 --- a/audio/core/all-versions/default/include/core/default/StreamOut.h +++ b/audio/core/all-versions/default/include/core/default/StreamOut.h @@ -143,6 +143,17 @@ struct StreamOut : public IStreamOut { #endif private: +#if MAJOR_VERSION >= 4 + playback_track_metadata convertPlaybackTrackMetadata( + const PlaybackTrackMetadata& trackMetadata); + void doUpdateSourceMetadata(const SourceMetadata& sourceMetadata); +#if MAJOR_VERSION >= 7 + playback_track_metadata_v7 convertPlaybackTrackMetadataV7( + const PlaybackTrackMetadata& trackMetadata); + void doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata); +#endif +#endif + const sp mDevice; audio_stream_out_t* mStream; const sp mStreamCommon; diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index 9a4a8b23a8..c53ae8dfb4 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -72,7 +72,10 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); hidl_vec flags; const SinkMetadata initMetadata = { - {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}}; + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), + .gain = 1, + .tags = {}, + .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}}; #endif EventFlag* efGroup; for (auto microphone : microphones) { @@ -246,7 +249,11 @@ TEST_P(InputStreamTest, updateSinkMetadata) { #if MAJOR_VERSION <= 6 const SinkMetadata metadata = {{{.source = source, .gain = volume}}}; #elif MAJOR_VERSION >= 7 - const SinkMetadata metadata = {{{.source = toString(source), .gain = volume}}}; + const SinkMetadata metadata = { + {{.source = toString(source), + .gain = volume, + .tags = {}, + .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}}; #endif ASSERT_OK(stream->updateSinkMetadata(metadata)) << "source=" << toString(source) << ", volume=" << volume; @@ -284,7 +291,12 @@ TEST_P(OutputStreamTest, updateSourceMetadata) { #if MAJOR_VERSION <= 6 const SourceMetadata metadata = {{{usage, content, volume}}}; #elif MAJOR_VERSION >= 7 - const SourceMetadata metadata = {{{toString(usage), toString(content), volume}}}; + const SourceMetadata metadata = { + {{toString(usage), + toString(content), + {} /* tags */, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), + volume}}}; #endif ASSERT_OK(stream->updateSourceMetadata(metadata)) << "usage=" << toString(usage) << ", content=" << toString(content) @@ -303,13 +315,25 @@ TEST_P(OutputStreamTest, updateSourceMetadata) { {AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}} #elif MAJOR_VERSION >= 7 {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), - toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 0.1}, + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), + {}, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), + 0.1}, {toString(xsd::AudioUsage::AUDIO_USAGE_VOICE_COMMUNICATION), - toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), 1.0}, + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), + {}, // tags + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO), + 1.0}, {toString(xsd::AudioUsage::AUDIO_USAGE_ALARM), - toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), 0.0}, + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), + {}, // tags + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), + 0.0}, {toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANT), - toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), 0.3}}} + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), + {}, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO), + 0.3}}} #endif )); // clang-format on diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp index bd8de2d0e6..5ad38de412 100644 --- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp @@ -98,9 +98,11 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) { auto flags = hidl_bitfield(AudioOutputFlag::NONE); #elif MAJOR_VERSION >= 7 DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT)}; - SourceMetadata initMetadata = { - {{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), - toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 1 /* gain */}}}; + SourceMetadata initMetadata = {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), + {} /* tags */, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), + 1 /* gain */}}}; hidl_vec flags; #endif AudioConfig config{}; @@ -131,7 +133,10 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) { #elif MAJOR_VERSION >= 7 DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT)}; SinkMetadata initMetadata = { - {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}}; + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), + .gain = 1, + .tags = {}, + .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}}; hidl_vec flags; #endif AudioConfig config{}; diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 43c44cbd8d..a16a0fb4d3 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -926,6 +926,8 @@ class OutputStreamTest : public OpenStreamTest { const SourceMetadata initMetadata = { { { toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), + {}, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), 1 /* gain */ } }}; #endif }; @@ -991,7 +993,10 @@ class InputStreamTest : public OpenStreamTest { const SinkMetadata initMetadata = {{ {.source = AudioSource::DEFAULT, .gain = 1 } }}; #elif MAJOR_VERSION >= 7 const SinkMetadata initMetadata = { - {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), .gain = 1}}}; + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), + .gain = 1, + .tags = {}, + .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}}; #endif };