From 9a8e6866288e14527dec43d657921f4d58b24186 Mon Sep 17 00:00:00 2001 From: jiabin Date: Thu, 12 Jan 2023 23:06:37 +0000 Subject: [PATCH] Add API to query mmap policy information. Bug: 193275465 Test: atest VtsHalAudioCoreTargetTest Change-Id: I8374a6e7942d68259d820b5de1f4ec597f1b6473 --- .../android/hardware/audio/core/IModule.aidl | 1 + .../android/hardware/audio/core/IModule.aidl | 15 +++++ audio/aidl/default/Module.cpp | 65 +++++++++++++++++++ audio/aidl/default/include/core-impl/Module.h | 4 ++ audio/aidl/vts/ModuleConfig.cpp | 16 +++++ audio/aidl/vts/ModuleConfig.h | 4 ++ .../vts/VtsHalAudioCoreModuleTargetTest.cpp | 20 ++++++ 7 files changed, 125 insertions(+) diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl index 960e69fa41..1e798e16f8 100644 --- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl +++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl @@ -68,6 +68,7 @@ interface IModule { void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async); void addDeviceEffect(int portConfigId, in android.hardware.audio.effect.IEffect effect); void removeDeviceEffect(int portConfigId, in android.hardware.audio.effect.IEffect effect); + android.media.audio.common.AudioMMapPolicyInfo[] getMmapPolicyInfos(android.media.audio.common.AudioMMapPolicyType mmapPolicyType); @VintfStability parcelable OpenInputStreamArguments { int portConfigId; diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl index 2c478f2951..7d170992e3 100644 --- a/audio/aidl/android/hardware/audio/core/IModule.aidl +++ b/audio/aidl/android/hardware/audio/core/IModule.aidl @@ -32,6 +32,8 @@ import android.hardware.audio.core.StreamDescriptor; import android.hardware.audio.core.VendorParameter; import android.hardware.audio.core.sounddose.ISoundDose; import android.hardware.audio.effect.IEffect; +import android.media.audio.common.AudioMMapPolicyInfo; +import android.media.audio.common.AudioMMapPolicyType; import android.media.audio.common.AudioMode; import android.media.audio.common.AudioOffloadInfo; import android.media.audio.common.AudioPort; @@ -807,4 +809,17 @@ interface IModule { * @throws EX_UNSUPPORTED_OPERATION If the module does not support device port effects. */ void removeDeviceEffect(int portConfigId, in IEffect effect); + + /** + * Provide information describing how aaudio MMAP is supported per queried aaudio + * MMAP policy type. + * + * If there are no devices that support aaudio MMAP for the queried aaudio MMAP policy + * type in the HAL module, it must return an empty vector. Otherwise, return a vector + * describing how the devices support aaudio MMAP. + * + * @param mmapPolicyType the aaudio mmap policy type to query. + * @return The vector with mmap policy information. + */ + AudioMMapPolicyInfo[] getMmapPolicyInfos(AudioMMapPolicyType mmapPolicyType); } diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp index a6e1d0dcd8..9ca26d2ba7 100644 --- a/audio/aidl/default/Module.cpp +++ b/audio/aidl/default/Module.cpp @@ -41,6 +41,9 @@ using aidl::android::media::audio::common::AudioFormatDescription; using aidl::android::media::audio::common::AudioFormatType; using aidl::android::media::audio::common::AudioInputFlags; using aidl::android::media::audio::common::AudioIoFlags; +using aidl::android::media::audio::common::AudioMMapPolicy; +using aidl::android::media::audio::common::AudioMMapPolicyInfo; +using aidl::android::media::audio::common::AudioMMapPolicyType; using aidl::android::media::audio::common::AudioMode; using aidl::android::media::audio::common::AudioOffloadInfo; using aidl::android::media::audio::common::AudioOutputFlags; @@ -1080,4 +1083,66 @@ ndk::ScopedAStatus Module::removeDeviceEffect( return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } +ndk::ScopedAStatus Module::getMmapPolicyInfos(AudioMMapPolicyType mmapPolicyType, + std::vector* _aidl_return) { + LOG(DEBUG) << __func__ << ": mmap policy type " << toString(mmapPolicyType); + std::set mmapSinks; + std::set mmapSources; + auto& ports = getConfig().ports; + for (const auto& port : ports) { + if (port.flags.getTag() == AudioIoFlags::Tag::input && + isBitPositionFlagSet(port.flags.get(), + AudioInputFlags::MMAP_NOIRQ)) { + mmapSinks.insert(port.id); + } else if (port.flags.getTag() == AudioIoFlags::Tag::output && + isBitPositionFlagSet(port.flags.get(), + AudioOutputFlags::MMAP_NOIRQ)) { + mmapSources.insert(port.id); + } + } + for (const auto& route : getConfig().routes) { + if (mmapSinks.count(route.sinkPortId) != 0) { + // The sink is a mix port, add the sources if they are device ports. + for (int sourcePortId : route.sourcePortIds) { + auto sourcePortIt = findById(ports, sourcePortId); + if (sourcePortIt == ports.end()) { + // This must not happen + LOG(ERROR) << __func__ << ": port id " << sourcePortId << " cannot be found"; + continue; + } + if (sourcePortIt->ext.getTag() != AudioPortExt::Tag::device) { + // The source is not a device port, skip + continue; + } + AudioMMapPolicyInfo policyInfo; + policyInfo.device = sourcePortIt->ext.get().device; + // Always return AudioMMapPolicy.AUTO if the device supports mmap for + // default implementation. + policyInfo.mmapPolicy = AudioMMapPolicy::AUTO; + _aidl_return->push_back(policyInfo); + } + } else { + auto sinkPortIt = findById(ports, route.sinkPortId); + if (sinkPortIt == ports.end()) { + // This must not happen + LOG(ERROR) << __func__ << ": port id " << route.sinkPortId << " cannot be found"; + continue; + } + if (sinkPortIt->ext.getTag() != AudioPortExt::Tag::device) { + // The sink is not a device port, skip + continue; + } + if (count_any(mmapSources, route.sourcePortIds)) { + AudioMMapPolicyInfo policyInfo; + policyInfo.device = sinkPortIt->ext.get().device; + // Always return AudioMMapPolicy.AUTO if the device supports mmap for + // default implementation. + policyInfo.mmapPolicy = AudioMMapPolicy::AUTO; + _aidl_return->push_back(policyInfo); + } + } + } + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h index 3cce7692bb..555506a9ba 100644 --- a/audio/aidl/default/include/core-impl/Module.h +++ b/audio/aidl/default/include/core-impl/Module.h @@ -110,6 +110,10 @@ class Module : public BnModule { int32_t in_portConfigId, const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) override; + ndk::ScopedAStatus getMmapPolicyInfos( + ::aidl::android::media::audio::common::AudioMMapPolicyType mmapPolicyType, + std::vector<::aidl::android::media::audio::common::AudioMMapPolicyInfo>* _aidl_return) + override; void cleanUpPatch(int32_t patchId); ndk::ScopedAStatus createStreamContext( diff --git a/audio/aidl/vts/ModuleConfig.cpp b/audio/aidl/vts/ModuleConfig.cpp index 7e4b148259..b48d1ba263 100644 --- a/audio/aidl/vts/ModuleConfig.cpp +++ b/audio/aidl/vts/ModuleConfig.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -32,6 +33,7 @@ using aidl::android::media::audio::common::AudioDeviceType; using aidl::android::media::audio::common::AudioEncapsulationMode; using aidl::android::media::audio::common::AudioFormatDescription; using aidl::android::media::audio::common::AudioFormatType; +using aidl::android::media::audio::common::AudioInputFlags; using aidl::android::media::audio::common::AudioIoFlags; using aidl::android::media::audio::common::AudioOffloadInfo; using aidl::android::media::audio::common::AudioOutputFlags; @@ -162,6 +164,20 @@ std::vector ModuleConfig::getPrimaryMixPorts(bool attachedOnly, bool }); } +std::vector ModuleConfig::getMmapOutMixPorts(bool attachedOnly, bool singlePort) const { + return findMixPorts(false /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) { + return isBitPositionFlagSet(port.flags.get(), + AudioOutputFlags::MMAP_NOIRQ); + }); +} + +std::vector ModuleConfig::getMmapInMixPorts(bool attachedOnly, bool singlePort) const { + return findMixPorts(true /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) { + return isBitPositionFlagSet(port.flags.get(), + AudioInputFlags::MMAP_NOIRQ); + }); +} + std::vector ModuleConfig::getAttachedDevicesPortsForMixPort( bool isInput, const AudioPortConfig& mixPortConfig) const { const auto mixPortIt = findById(mPorts, mixPortConfig.portId); diff --git a/audio/aidl/vts/ModuleConfig.h b/audio/aidl/vts/ModuleConfig.h index 7247f3b582..8a557540b2 100644 --- a/audio/aidl/vts/ModuleConfig.h +++ b/audio/aidl/vts/ModuleConfig.h @@ -63,6 +63,10 @@ class ModuleConfig { bool attachedOnly, bool singlePort) const; std::vector getPrimaryMixPorts( bool attachedOnly, bool singlePort) const; + std::vector getMmapOutMixPorts( + bool attachedOnly, bool singlePort) const; + std::vector getMmapInMixPorts( + bool attachedOnly, bool singlePort) const; std::vector getAttachedDevicesPortsForMixPort( bool isInput, const aidl::android::media::audio::common::AudioPort& mixPort) const { diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp index a8febc5b57..21ad0e642d 100644 --- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp +++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include #include @@ -77,6 +79,8 @@ using aidl::android::media::audio::common::AudioDualMonoMode; using aidl::android::media::audio::common::AudioFormatType; using aidl::android::media::audio::common::AudioIoFlags; using aidl::android::media::audio::common::AudioLatencyMode; +using aidl::android::media::audio::common::AudioMMapPolicyInfo; +using aidl::android::media::audio::common::AudioMMapPolicyType; using aidl::android::media::audio::common::AudioMode; using aidl::android::media::audio::common::AudioOutputFlags; using aidl::android::media::audio::common::AudioPlaybackRate; @@ -1887,6 +1891,22 @@ TEST_P(AudioCoreModule, AddRemoveEffectInvalidArguments) { } } +TEST_P(AudioCoreModule, GetMmapPolicyInfos) { + ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig()); + const std::vector mmapOutMixPorts = + moduleConfig->getMmapOutMixPorts(false /*attachedOnly*/, false /*singlePort*/); + const std::vector mmapInMixPorts = + moduleConfig->getMmapInMixPorts(false /*attachedOnly*/, false /*singlePort*/); + const bool mmapSupported = (!mmapOutMixPorts.empty() || !mmapInMixPorts.empty()); + for (const auto mmapPolicyType : + {AudioMMapPolicyType::DEFAULT, AudioMMapPolicyType::EXCLUSIVE}) { + std::vector policyInfos; + EXPECT_IS_OK(module->getMmapPolicyInfos(mmapPolicyType, &policyInfos)) + << toString(mmapPolicyType); + EXPECT_EQ(mmapSupported, !policyInfos.empty()); + } +} + class AudioCoreBluetooth : public AudioCoreModuleBase, public testing::TestWithParam { public: void SetUp() override {