Add API to query mmap policy information.
Bug: 193275465
Test: atest VtsHalAudioCoreTargetTest
Change-Id: I8374a6e7942d68259d820b5de1f4ec597f1b6473
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 960e69f..1e798e1 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 @@
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 2c478f2..7d17099 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.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 @@
* @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 a6e1d0d..9ca26d2 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -41,6 +41,9 @@
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 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
+ndk::ScopedAStatus Module::getMmapPolicyInfos(AudioMMapPolicyType mmapPolicyType,
+ std::vector<AudioMMapPolicyInfo>* _aidl_return) {
+ LOG(DEBUG) << __func__ << ": mmap policy type " << toString(mmapPolicyType);
+ std::set<int32_t> mmapSinks;
+ std::set<int32_t> mmapSources;
+ auto& ports = getConfig().ports;
+ for (const auto& port : ports) {
+ if (port.flags.getTag() == AudioIoFlags::Tag::input &&
+ isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::input>(),
+ AudioInputFlags::MMAP_NOIRQ)) {
+ mmapSinks.insert(port.id);
+ } else if (port.flags.getTag() == AudioIoFlags::Tag::output &&
+ isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
+ 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<AudioPort>(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<AudioPortExt::Tag::device>().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<AudioPort>(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<AudioPortExt::Tag::device>().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 3cce769..555506a 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -110,6 +110,10 @@
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 7e4b148..b48d1ba 100644
--- a/audio/aidl/vts/ModuleConfig.cpp
+++ b/audio/aidl/vts/ModuleConfig.cpp
@@ -18,6 +18,7 @@
#include <chrono>
#include <Utils.h>
+#include <aidl/android/media/audio/common/AudioInputFlags.h>
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
@@ -32,6 +33,7 @@
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<AudioPort> ModuleConfig::getMmapOutMixPorts(bool attachedOnly, bool singlePort) const {
+ return findMixPorts(false /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
+ return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
+ AudioOutputFlags::MMAP_NOIRQ);
+ });
+}
+
+std::vector<AudioPort> ModuleConfig::getMmapInMixPorts(bool attachedOnly, bool singlePort) const {
+ return findMixPorts(true /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
+ return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::input>(),
+ AudioInputFlags::MMAP_NOIRQ);
+ });
+}
+
std::vector<AudioPort> ModuleConfig::getAttachedDevicesPortsForMixPort(
bool isInput, const AudioPortConfig& mixPortConfig) const {
const auto mixPortIt = findById<AudioPort>(mPorts, mixPortConfig.portId);
diff --git a/audio/aidl/vts/ModuleConfig.h b/audio/aidl/vts/ModuleConfig.h
index 7247f3b..8a55754 100644
--- a/audio/aidl/vts/ModuleConfig.h
+++ b/audio/aidl/vts/ModuleConfig.h
@@ -63,6 +63,10 @@
bool attachedOnly, bool singlePort) const;
std::vector<aidl::android::media::audio::common::AudioPort> getPrimaryMixPorts(
bool attachedOnly, bool singlePort) const;
+ std::vector<aidl::android::media::audio::common::AudioPort> getMmapOutMixPorts(
+ bool attachedOnly, bool singlePort) const;
+ std::vector<aidl::android::media::audio::common::AudioPort> getMmapInMixPorts(
+ bool attachedOnly, bool singlePort) const;
std::vector<aidl::android::media::audio::common::AudioPort> 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 a8febc5..21ad0e6 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -40,6 +40,8 @@
#include <aidl/android/hardware/audio/core/ITelephony.h>
#include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h>
#include <aidl/android/media/audio/common/AudioIoFlags.h>
+#include <aidl/android/media/audio/common/AudioMMapPolicyInfo.h>
+#include <aidl/android/media/audio/common/AudioMMapPolicyType.h>
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
#include <android-base/chrono_utils.h>
#include <android/binder_enums.h>
@@ -77,6 +79,8 @@
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, GetMmapPolicyInfos) {
+ ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+ const std::vector<AudioPort> mmapOutMixPorts =
+ moduleConfig->getMmapOutMixPorts(false /*attachedOnly*/, false /*singlePort*/);
+ const std::vector<AudioPort> mmapInMixPorts =
+ moduleConfig->getMmapInMixPorts(false /*attachedOnly*/, false /*singlePort*/);
+ const bool mmapSupported = (!mmapOutMixPorts.empty() || !mmapInMixPorts.empty());
+ for (const auto mmapPolicyType :
+ {AudioMMapPolicyType::DEFAULT, AudioMMapPolicyType::EXCLUSIVE}) {
+ std::vector<AudioMMapPolicyInfo> policyInfos;
+ EXPECT_IS_OK(module->getMmapPolicyInfos(mmapPolicyType, &policyInfos))
+ << toString(mmapPolicyType);
+ EXPECT_EQ(mmapSupported, !policyInfos.empty());
+ }
+}
+
class AudioCoreBluetooth : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
public:
void SetUp() override {