Merge "Add API to query mmap policy information."

This commit is contained in:
Treehugger Robot 2023-01-14 01:43:09 +00:00 committed by Gerrit Code Review
commit c3a910776f
7 changed files with 125 additions and 0 deletions

View file

@ -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;

View file

@ -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);
}

View file

@ -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<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

View file

@ -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(

View file

@ -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::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<AudioPort> ModuleConfig::getPrimaryMixPorts(bool attachedOnly, bool
});
}
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);

View file

@ -63,6 +63,10 @@ class ModuleConfig {
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 {

View file

@ -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::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<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 {