audio: Query minimum buffer size before opening streams

The proper way to obtain the minimum buffer size when
opening a stream is to retrieve it from the patch. Thus,
a patch must be established prior to opening a stream.
This step was often skipped by VTS tests, they were
providing a fixed stream buffer size which might not
work for all HAL module implementations.

Created a helper class `StreamFixture` which handles
all necessary steps for opening a stream. Overhauled
tests to use this class.

Also, remove special treatment of remote submix devices
by ModuleConfig.

Bug: 300735639
Test: atest VtsHalAudioCoreTargetTest
Change-Id: Ic51d603d2bb8ff0fd62434bd16fc02c51326fc42
This commit is contained in:
Mikhail Naganov 2023-10-25 08:44:47 -07:00
parent 49bcb92670
commit 95f2277730
4 changed files with 683 additions and 379 deletions

View file

@ -67,20 +67,7 @@ std::optional<AudioOffloadInfo> ModuleConfig::generateOffloadInfoIfNeeded(
return {};
}
std::vector<aidl::android::media::audio::common::AudioPort>
ModuleConfig::getAudioPortsForDeviceTypes(const std::vector<AudioDeviceType>& deviceTypes,
const std::string& connection) {
return getAudioPortsForDeviceTypes(mPorts, deviceTypes, connection);
}
// static
std::vector<aidl::android::media::audio::common::AudioPort> ModuleConfig::getBuiltInMicPorts(
const std::vector<aidl::android::media::audio::common::AudioPort>& ports) {
return getAudioPortsForDeviceTypes(
ports, std::vector<AudioDeviceType>{AudioDeviceType::IN_MICROPHONE,
AudioDeviceType::IN_MICROPHONE_BACK});
}
std::vector<aidl::android::media::audio::common::AudioPort>
ModuleConfig::getAudioPortsForDeviceTypes(
const std::vector<aidl::android::media::audio::common::AudioPort>& ports,
@ -100,6 +87,14 @@ ModuleConfig::getAudioPortsForDeviceTypes(
return result;
}
// static
std::vector<aidl::android::media::audio::common::AudioPort> ModuleConfig::getBuiltInMicPorts(
const std::vector<aidl::android::media::audio::common::AudioPort>& ports) {
return getAudioPortsForDeviceTypes(
ports, std::vector<AudioDeviceType>{AudioDeviceType::IN_MICROPHONE,
AudioDeviceType::IN_MICROPHONE_BACK});
}
template <typename T>
auto findById(const std::vector<T>& v, int32_t id) {
return std::find_if(v.begin(), v.end(), [&](const auto& p) { return p.id == id; });
@ -119,10 +114,7 @@ ModuleConfig::ModuleConfig(IModule* module) {
} else {
mAttachedSinkDevicePorts.insert(port.id);
}
} else if (devicePort.device.type.connection != AudioDeviceDescription::CONNECTION_VIRTUAL
// The "virtual" connection is used for remote submix which is a dynamic
// device but it can be connected and used w/o external hardware.
&& port.profiles.empty()) {
} else {
mExternalDevicePorts.insert(port.id);
}
}
@ -141,6 +133,12 @@ std::vector<AudioPort> ModuleConfig::getAttachedDevicePorts() const {
return result;
}
std::vector<aidl::android::media::audio::common::AudioPort>
ModuleConfig::getAudioPortsForDeviceTypes(const std::vector<AudioDeviceType>& deviceTypes,
const std::string& connection) const {
return getAudioPortsForDeviceTypes(mPorts, deviceTypes, connection);
}
std::vector<AudioPort> ModuleConfig::getConnectedExternalDevicePorts() const {
std::vector<AudioPort> result;
std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result), [&](const auto& port) {
@ -229,6 +227,16 @@ std::vector<AudioPort> ModuleConfig::getMmapInMixPorts(bool connectedOnly, bool
});
}
std::vector<AudioPort> ModuleConfig::getRemoteSubmixPorts(bool isInput, bool singlePort) const {
AudioDeviceType deviceType = isInput ? AudioDeviceType::IN_SUBMIX : AudioDeviceType::OUT_SUBMIX;
auto ports = getAudioPortsForDeviceTypes(std::vector<AudioDeviceType>{deviceType},
AudioDeviceDescription::CONNECTION_VIRTUAL);
if (singlePort) {
if (!ports.empty()) ports.resize(1);
}
return ports;
}
std::vector<AudioPort> ModuleConfig::getConnectedDevicesPortsForMixPort(
bool isInput, const AudioPortConfig& mixPortConfig) const {
const auto mixPortIt = findById<AudioPort>(mPorts, mixPortConfig.portId);
@ -281,19 +289,29 @@ std::optional<AudioPort> ModuleConfig::getSourceMixPortForConnectedDevice() cons
return {};
}
std::vector<AudioPort> ModuleConfig::getRoutableMixPortsForDevicePort(const AudioPort& port) const {
std::set<int32_t> portIds;
for (const auto& route : mRoutes) {
if (port.id == route.sinkPortId) {
portIds.insert(route.sourcePortIds.begin(), route.sourcePortIds.end());
} else if (auto it = std::find(route.sourcePortIds.begin(), route.sourcePortIds.end(),
port.id);
it != route.sourcePortIds.end()) {
portIds.insert(route.sinkPortId);
}
}
std::vector<AudioPort> ModuleConfig::getRoutableDevicePortsForMixPort(const AudioPort& port,
bool connectedOnly) const {
std::set<int32_t> portIds = findRoutablePortIds(port.id);
const bool isInput = port.flags.getTag() == AudioIoFlags::input;
return findMixPorts(isInput, false /*connectedOnly*/, false /*singlePort*/,
std::set<int32_t> devicePortIds;
if (connectedOnly) {
devicePortIds = isInput ? getConnectedSourceDevicePorts() : getConnectedSinkDevicePorts();
} else {
devicePortIds = portIds;
}
std::vector<AudioPort> result;
std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result), [&](const auto& port) {
return port.ext.getTag() == AudioPortExt::Tag::device && portIds.count(port.id) > 0 &&
devicePortIds.count(port.id) > 0;
});
return result;
}
std::vector<AudioPort> ModuleConfig::getRoutableMixPortsForDevicePort(const AudioPort& port,
bool connectedOnly) const {
std::set<int32_t> portIds = findRoutablePortIds(port.id);
const bool isInput = port.flags.getTag() == AudioIoFlags::input;
return findMixPorts(isInput, connectedOnly, false /*singlePort*/,
[&portIds](const AudioPort& p) { return portIds.count(p.id) > 0; });
}
@ -470,6 +488,20 @@ std::vector<AudioPort> ModuleConfig::findMixPorts(
return result;
}
std::set<int32_t> ModuleConfig::findRoutablePortIds(int32_t portId) const {
std::set<int32_t> portIds;
for (const auto& route : mRoutes) {
if (portId == route.sinkPortId) {
portIds.insert(route.sourcePortIds.begin(), route.sourcePortIds.end());
} else if (auto it = std::find(route.sourcePortIds.begin(), route.sourcePortIds.end(),
portId);
it != route.sourcePortIds.end()) {
portIds.insert(route.sinkPortId);
}
}
return portIds;
}
std::vector<AudioPortConfig> ModuleConfig::generateAudioMixPortConfigs(
const std::vector<AudioPort>& ports, bool isInput, bool singleProfile) const {
std::vector<AudioPortConfig> result;

View file

@ -38,9 +38,6 @@ class ModuleConfig {
generateOffloadInfoIfNeeded(
const aidl::android::media::audio::common::AudioPortConfig& portConfig);
std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes(
const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes,
const std::string& connection = "");
static std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes(
const std::vector<aidl::android::media::audio::common::AudioPort>& ports,
const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes,
@ -53,6 +50,9 @@ class ModuleConfig {
std::string getError() const { return mStatus.getMessage(); }
std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicePorts() const;
std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes(
const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes,
const std::string& connection = "") const;
std::vector<aidl::android::media::audio::common::AudioPort> getConnectedExternalDevicePorts()
const;
std::set<int32_t> getConnectedSinkDevicePorts() const;
@ -85,6 +85,8 @@ class ModuleConfig {
std::vector<aidl::android::media::audio::common::AudioPort> getMmapInMixPorts(
bool connectedOnly /*Permanently attached and connected external devices*/,
bool singlePort) const;
std::vector<aidl::android::media::audio::common::AudioPort> getRemoteSubmixPorts(
bool isInput, bool singlePort) const;
std::vector<aidl::android::media::audio::common::AudioPort> getConnectedDevicesPortsForMixPort(
bool isInput, const aidl::android::media::audio::common::AudioPort& mixPort) const {
@ -103,8 +105,12 @@ class ModuleConfig {
std::optional<aidl::android::media::audio::common::AudioPort>
getSourceMixPortForConnectedDevice() const;
std::vector<aidl::android::media::audio::common::AudioPort> getRoutableDevicePortsForMixPort(
const aidl::android::media::audio::common::AudioPort& port,
bool connectedOnly /*Permanently attached and connected external devices*/) const;
std::vector<aidl::android::media::audio::common::AudioPort> getRoutableMixPortsForDevicePort(
const aidl::android::media::audio::common::AudioPort& port) const;
const aidl::android::media::audio::common::AudioPort& port,
bool connectedOnly /*Permanently attached and connected external devices*/) const;
std::optional<SrcSinkPair> getNonRoutableSrcSinkPair(bool isInput) const;
std::optional<SrcSinkPair> getRoutableSrcSinkPair(bool isInput) const;
@ -176,6 +182,7 @@ class ModuleConfig {
bool isInput, bool connectedOnly, bool singlePort,
const std::function<bool(const aidl::android::media::audio::common::AudioPort&)>& pred)
const;
std::set<int32_t> findRoutablePortIds(int32_t portId) const;
std::vector<aidl::android::media::audio::common::AudioPortConfig> generateAudioMixPortConfigs(
const std::vector<aidl::android::media::audio::common::AudioPort>& ports, bool isInput,
bool singleProfile) const;

View file

@ -18,7 +18,6 @@
#include <algorithm>
#include <initializer_list>
#include <iostream>
#include <android/binder_auto_utils.h>
#include <gtest/gtest.h>
@ -93,4 +92,4 @@ inline ::testing::AssertionResult assertResult(const char* exp_expr, const char*
if ((flags).hwAcceleratorMode == Flags::HardwareAccelerator::TUNNEL || (flags).bypass) { \
GTEST_SKIP() << "Skip data path for offload"; \
} \
})
})

File diff suppressed because it is too large Load diff