Merge "audio: Verify that VTS tests can work with vendor extensions" am: a8b93afc00

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1612588

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I3c7849b16ecaff6a0b5b3e1f99e879dd2ce0c951
This commit is contained in:
Treehugger Robot 2021-03-03 20:17:13 +00:00 committed by Automerger Merge Worker
commit a40f50ddc0
21 changed files with 1247 additions and 440 deletions

View file

@ -2,6 +2,12 @@
"presubmit": [
{
"name": "android.hardware.audio@7.0-util_tests"
},
{
"name": "HalAudioV6_0GeneratorTest"
},
{
"name": "HalAudioV7_0GeneratorTest"
}
]
}

View file

@ -17,105 +17,6 @@
// pull in all the <= 5.0 tests
#include "5.0/AudioPrimaryHidlHalTest.cpp"
#if MAJOR_VERSION <= 6
static std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(
bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
for (const auto& ioProfile : module->getOutputProfiles()) {
for (const auto& profile : ioProfile->getAudioProfiles()) {
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
auto configs = ConfigHelper::combineAudioConfig(
std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
profile->getFormat());
auto flags = ioProfile->getFlags();
for (auto& config : configs) {
// Some combinations of flags declared in the config file require special
// treatment.
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
config.offloadInfo.sampleRateHz = config.sampleRateHz;
config.offloadInfo.channelMask = config.channelMask;
config.offloadInfo.format = config.format;
config.offloadInfo.streamType = AudioStreamType::MUSIC;
config.offloadInfo.bitRatePerSecond = 320;
config.offloadInfo.durationMicroseconds = -1;
config.offloadInfo.bitWidth = 16;
config.offloadInfo.bufferSize = 256; // arbitrary value
config.offloadInfo.usage = AudioUsage::MEDIA;
result.emplace_back(device, config,
AudioOutputFlag(AudioOutputFlag::COMPRESS_OFFLOAD |
AudioOutputFlag::DIRECT));
} else {
if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
}
result.emplace_back(device, config, AudioOutputFlag(flags));
}
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
}
return result;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateOutputDeviceConfigParameters(false);
return parameters;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateOutputDeviceConfigParameters(true);
return parameters;
}
static std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(
bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
for (const auto& ioProfile : module->getInputProfiles()) {
for (const auto& profile : ioProfile->getAudioProfiles()) {
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
auto configs = ConfigHelper::combineAudioConfig(
std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
profile->getFormat());
for (const auto& config : configs) {
result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags()));
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
}
return result;
}
const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateInputDeviceConfigParameters(false);
return parameters;
}
const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateInputDeviceConfigParameters(true);
return parameters;
}
#endif // MAJOR_VERSION <= 6
class SingleConfigOutputStreamTest : public OutputStreamTest {};
TEST_P(SingleConfigOutputStreamTest, CloseDeviceWithOpenedOutputStreams) {
doc::test("Verify that a device can't be closed if there are output streams opened");

View file

@ -0,0 +1,129 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <android-base/macros.h>
#include "6.0/Generators.h"
#include "ConfigHelper.h"
#include "PolicyConfig.h"
// clang-format off
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
// clang-format on
// Forward declaration for functions that are substituted
// in generator unit tests.
const PolicyConfig& getCachedPolicyConfig();
const std::vector<DeviceParameter>& getDeviceParameters();
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
for (const auto& ioProfile : module->getOutputProfiles()) {
for (const auto& profile : ioProfile->getAudioProfiles()) {
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
auto configs = ConfigHelper::combineAudioConfig(
std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
profile->getFormat());
auto flags = ioProfile->getFlags();
for (auto& config : configs) {
// Some combinations of flags declared in the config file require special
// treatment.
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
config.offloadInfo.sampleRateHz = config.sampleRateHz;
config.offloadInfo.channelMask = config.channelMask;
config.offloadInfo.format = config.format;
config.offloadInfo.streamType = AudioStreamType::MUSIC;
config.offloadInfo.bitRatePerSecond = 320;
config.offloadInfo.durationMicroseconds = -1;
config.offloadInfo.bitWidth = 16;
config.offloadInfo.bufferSize = 256; // arbitrary value
config.offloadInfo.usage = AudioUsage::MEDIA;
result.emplace_back(device, config,
AudioOutputFlag(AudioOutputFlag::COMPRESS_OFFLOAD |
AudioOutputFlag::DIRECT));
} else {
if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
}
result.emplace_back(device, config, AudioOutputFlag(flags));
}
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
}
return result;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateOutputDeviceConfigParameters(false);
return parameters;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateOutputDeviceConfigParameters(true);
return parameters;
}
std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
for (const auto& ioProfile : module->getInputProfiles()) {
for (const auto& profile : ioProfile->getAudioProfiles()) {
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
auto configs = ConfigHelper::combineAudioConfig(
std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
profile->getFormat());
for (const auto& config : configs) {
result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags()));
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
}
return result;
}
const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateInputDeviceConfigParameters(false);
return parameters;
}
const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateInputDeviceConfigParameters(true);
return parameters;
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <vector>
#include "AudioTestDefinitions.h"
const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters();
const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters();
// For unit tests
std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice);
std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice);

View file

@ -14,277 +14,11 @@
* limitations under the License.
*/
#include "Generators.h"
// pull in all the <= 6.0 tests
#include "6.0/AudioPrimaryHidlHalTest.cpp"
static std::vector<AudioConfig> combineAudioConfig(std::vector<xsd::AudioChannelMask> channelMasks,
std::vector<int64_t> sampleRates,
const std::string& format) {
std::vector<AudioConfig> configs;
configs.reserve(channelMasks.size() * sampleRates.size());
for (auto channelMask : channelMasks) {
for (auto sampleRate : sampleRates) {
AudioConfig config{};
config.base.channelMask = toString(channelMask);
config.base.sampleRateHz = sampleRate;
config.base.format = format;
configs.push_back(config);
}
}
return configs;
}
static std::tuple<std::vector<AudioInOutFlag>, bool> generateOutFlags(
const xsd::MixPorts::MixPort& mixPort) {
static const std::vector<AudioInOutFlag> offloadFlags = {
toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)};
std::vector<AudioInOutFlag> flags;
bool isOffload = false;
if (mixPort.hasFlags()) {
auto xsdFlags = mixPort.getFlags();
isOffload = std::find(xsdFlags.begin(), xsdFlags.end(),
xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
xsdFlags.end();
if (!isOffload) {
for (auto flag : xsdFlags) {
if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
flags.push_back(toString(flag));
}
}
} else {
flags = offloadFlags;
}
}
return {flags, isOffload};
}
static AudioOffloadInfo generateOffloadInfo(const AudioConfigBase& base) {
return AudioOffloadInfo{
.base = base,
.streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC),
.usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
.bitRatePerSecond = 320,
.durationMicroseconds = -1,
.bitWidth = 16,
.bufferSize = 256 // arbitrary value
};
}
static std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(
bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
if (!module || !module->getFirstMixPorts()) break;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
auto [flags, isOffload] = generateOutFlags(mixPort);
for (const auto& profile : mixPort.getProfile()) {
auto configs = combineAudioConfig(profile.getChannelMasks(),
profile.getSamplingRates(), profile.getFormat());
for (auto& config : configs) {
// Some combinations of flags declared in the config file require special
// treatment.
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(config.base));
}
result.emplace_back(device, config, flags);
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
}
return result;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateOutputDeviceConfigParameters(false);
return parameters;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateOutputDeviceConfigParameters(true);
return parameters;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters(
bool generateInvalidFlags = true) {
static std::vector<DeviceConfigParameter> parameters = [&] {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
if (!module || !module->getFirstMixPorts()) break;
bool hasRegularConfig = false, hasOffloadConfig = false;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
auto [validFlags, isOffload] = generateOutFlags(mixPort);
if ((!isOffload && hasRegularConfig) || (isOffload && hasOffloadConfig)) continue;
for (const auto& profile : mixPort.getProfile()) {
if (!profile.hasFormat() || !profile.hasSamplingRates() ||
!profile.hasChannelMasks())
continue;
AudioConfigBase validBase = {
profile.getFormat(),
static_cast<uint32_t>(profile.getSamplingRates()[0]),
toString(profile.getChannelMasks()[0])};
{
AudioConfig config{.base = validBase};
config.base.channelMask = "random_string";
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(validBase));
}
result.emplace_back(device, config, validFlags);
}
{
AudioConfig config{.base = validBase};
config.base.format = "random_string";
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(validBase));
}
result.emplace_back(device, config, validFlags);
}
if (generateInvalidFlags) {
AudioConfig config{.base = validBase};
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(validBase));
}
std::vector<AudioInOutFlag> flags = {"random_string", ""};
result.emplace_back(device, config, flags);
}
if (isOffload) {
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().base.channelMask = "random_string";
}
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().base.format = "random_string";
}
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().streamType = "random_string";
}
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().usage = "random_string";
}
hasOffloadConfig = true;
} else {
hasRegularConfig = true;
}
break;
}
if (hasOffloadConfig && hasRegularConfig) break;
}
}
return result;
}();
return parameters;
}
static std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(
bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
if (!module || !module->getFirstMixPorts()) break;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
std::vector<AudioInOutFlag> flags;
if (mixPort.hasFlags()) {
std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
std::back_inserter(flags), [](auto flag) { return toString(flag); });
}
for (const auto& profile : mixPort.getProfile()) {
auto configs = combineAudioConfig(profile.getChannelMasks(),
profile.getSamplingRates(), profile.getFormat());
for (const auto& config : configs) {
result.emplace_back(device, config, flags);
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
}
return result;
}
const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateInputDeviceConfigParameters(false);
return parameters;
}
const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateInputDeviceConfigParameters(true);
return parameters;
}
const std::vector<DeviceConfigParameter>& getInputDeviceInvalidConfigParameters(
bool generateInvalidFlags = true) {
static std::vector<DeviceConfigParameter> parameters = [&] {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
if (!module || !module->getFirstMixPorts()) break;
bool hasConfig = false;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
std::vector<AudioInOutFlag> validFlags;
if (mixPort.hasFlags()) {
std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
std::back_inserter(validFlags),
[](auto flag) { return toString(flag); });
}
for (const auto& profile : mixPort.getProfile()) {
if (!profile.hasFormat() || !profile.hasSamplingRates() ||
!profile.hasChannelMasks())
continue;
AudioConfigBase validBase = {
profile.getFormat(),
static_cast<uint32_t>(profile.getSamplingRates()[0]),
toString(profile.getChannelMasks()[0])};
{
AudioConfig config{.base = validBase};
config.base.channelMask = "random_string";
result.emplace_back(device, config, validFlags);
}
{
AudioConfig config{.base = validBase};
config.base.format = "random_string";
result.emplace_back(device, config, validFlags);
}
if (generateInvalidFlags) {
AudioConfig config{.base = validBase};
std::vector<AudioInOutFlag> flags = {"random_string", ""};
result.emplace_back(device, config, flags);
}
hasConfig = true;
break;
}
if (hasConfig) break;
}
}
return result;
}();
return parameters;
}
class InvalidInputConfigNoFlagsTest : public AudioHidlTestWithDeviceConfigParameter {};
TEST_P(InvalidInputConfigNoFlagsTest, InputBufferSizeTest) {
doc::test("Verify that invalid config is rejected by IDevice::getInputBufferSize method.");

View file

@ -0,0 +1,309 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <android-base/macros.h>
#include "7.0/Generators.h"
#include "7.0/PolicyConfig.h"
// clang-format off
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
// clang-format on
#include <android_audio_policy_configuration_V7_0-enums.h>
#include <android_audio_policy_configuration_V7_0.h>
// Forward declaration for functions that are substituted
// in generator unit tests.
const PolicyConfig& getCachedPolicyConfig();
const std::vector<DeviceParameter>& getDeviceParameters();
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
namespace xsd {
using namespace ::android::audio::policy::configuration::CPP_VERSION;
}
static std::vector<AudioConfig> combineAudioConfig(std::vector<xsd::AudioChannelMask> channelMasks,
std::vector<int64_t> sampleRates,
const std::string& format) {
std::vector<AudioConfig> configs;
configs.reserve(channelMasks.size() * sampleRates.size());
for (auto channelMask : channelMasks) {
for (auto sampleRate : sampleRates) {
AudioConfig config{};
config.base.channelMask = toString(channelMask);
config.base.sampleRateHz = sampleRate;
config.base.format = format;
configs.push_back(config);
}
}
return configs;
}
static std::tuple<std::vector<AudioInOutFlag>, bool> generateOutFlags(
const xsd::MixPorts::MixPort& mixPort) {
static const std::vector<AudioInOutFlag> offloadFlags = {
toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)};
std::vector<AudioInOutFlag> flags;
bool isOffload = false;
if (mixPort.hasFlags()) {
auto xsdFlags = mixPort.getFlags();
isOffload = std::find(xsdFlags.begin(), xsdFlags.end(),
xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
xsdFlags.end();
if (!isOffload) {
for (auto flag : xsdFlags) {
if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
flags.push_back(toString(flag));
}
}
} else {
flags = offloadFlags;
}
}
return {flags, isOffload};
}
static AudioOffloadInfo generateOffloadInfo(const AudioConfigBase& base) {
return AudioOffloadInfo{
.base = base,
.streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC),
.usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
.bitRatePerSecond = 320,
.durationMicroseconds = -1,
.bitWidth = 16,
.bufferSize = 256 // arbitrary value
};
}
std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
if (!module || !module->getFirstMixPorts()) break;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
auto [flags, isOffload] = generateOutFlags(mixPort);
for (const auto& profile : mixPort.getProfile()) {
auto configs = combineAudioConfig(profile.getChannelMasks(),
profile.getSamplingRates(), profile.getFormat());
for (auto& config : configs) {
// Some combinations of flags declared in the config file require special
// treatment.
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(config.base));
}
result.emplace_back(device, config, flags);
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
}
return result;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateOutputDeviceConfigParameters(false);
return parameters;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateOutputDeviceConfigParameters(true);
return parameters;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters(
bool generateInvalidFlags) {
static std::vector<DeviceConfigParameter> parameters = [&] {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
if (!module || !module->getFirstMixPorts()) break;
bool hasRegularConfig = false, hasOffloadConfig = false;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
auto [validFlags, isOffload] = generateOutFlags(mixPort);
if ((!isOffload && hasRegularConfig) || (isOffload && hasOffloadConfig)) continue;
for (const auto& profile : mixPort.getProfile()) {
if (!profile.hasFormat() || !profile.hasSamplingRates() ||
!profile.hasChannelMasks())
continue;
AudioConfigBase validBase = {
profile.getFormat(),
static_cast<uint32_t>(profile.getSamplingRates()[0]),
toString(profile.getChannelMasks()[0])};
{
AudioConfig config{.base = validBase};
config.base.channelMask = "random_string";
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(validBase));
}
result.emplace_back(device, config, validFlags);
}
{
AudioConfig config{.base = validBase};
config.base.format = "random_string";
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(validBase));
}
result.emplace_back(device, config, validFlags);
}
if (generateInvalidFlags) {
AudioConfig config{.base = validBase};
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(validBase));
}
std::vector<AudioInOutFlag> flags = {"random_string", ""};
result.emplace_back(device, config, flags);
}
if (isOffload) {
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().base.channelMask = "random_string";
result.emplace_back(device, config, validFlags);
}
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().base.format = "random_string";
result.emplace_back(device, config, validFlags);
}
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().streamType = "random_string";
result.emplace_back(device, config, validFlags);
}
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().usage = "random_string";
result.emplace_back(device, config, validFlags);
}
hasOffloadConfig = true;
} else {
hasRegularConfig = true;
}
break;
}
if (hasOffloadConfig && hasRegularConfig) break;
}
}
return result;
}();
return parameters;
}
std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
if (!module || !module->getFirstMixPorts()) break;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
std::vector<AudioInOutFlag> flags;
if (mixPort.hasFlags()) {
std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
std::back_inserter(flags), [](auto flag) { return toString(flag); });
}
for (const auto& profile : mixPort.getProfile()) {
auto configs = combineAudioConfig(profile.getChannelMasks(),
profile.getSamplingRates(), profile.getFormat());
for (const auto& config : configs) {
result.emplace_back(device, config, flags);
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
}
}
return result;
}
const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateInputDeviceConfigParameters(false);
return parameters;
}
const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
static std::vector<DeviceConfigParameter> parameters =
generateInputDeviceConfigParameters(true);
return parameters;
}
const std::vector<DeviceConfigParameter>& getInputDeviceInvalidConfigParameters(
bool generateInvalidFlags) {
static std::vector<DeviceConfigParameter> parameters = [&] {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
if (!module || !module->getFirstMixPorts()) break;
bool hasConfig = false;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
std::vector<AudioInOutFlag> validFlags;
if (mixPort.hasFlags()) {
std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
std::back_inserter(validFlags),
[](auto flag) { return toString(flag); });
}
for (const auto& profile : mixPort.getProfile()) {
if (!profile.hasFormat() || !profile.hasSamplingRates() ||
!profile.hasChannelMasks())
continue;
AudioConfigBase validBase = {
profile.getFormat(),
static_cast<uint32_t>(profile.getSamplingRates()[0]),
toString(profile.getChannelMasks()[0])};
{
AudioConfig config{.base = validBase};
config.base.channelMask = "random_string";
result.emplace_back(device, config, validFlags);
}
{
AudioConfig config{.base = validBase};
config.base.format = "random_string";
result.emplace_back(device, config, validFlags);
}
if (generateInvalidFlags) {
AudioConfig config{.base = validBase};
std::vector<AudioInOutFlag> flags = {"random_string", ""};
result.emplace_back(device, config, flags);
}
hasConfig = true;
break;
}
if (hasConfig) break;
}
}
return result;
}();
return parameters;
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <vector>
#include "AudioTestDefinitions.h"
const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters();
const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters(
bool generateInvalidFlags = true);
const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters();
const std::vector<DeviceConfigParameter>& getInputDeviceInvalidConfigParameters(
bool generateInvalidFlags = true);
// For unit tests
std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice);
std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice);

View file

@ -16,11 +16,35 @@
#pragma once
// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
// and thus it doesn't have all '#include' and 'using' directives required
// for a standalone compilation.
#include <fcntl.h>
#include <unistd.h>
#include <optional>
#include <set>
#include <string>
#include <gtest/gtest.h>
#include <system/audio_config.h>
#include <utils/Errors.h>
// clang-format off
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
// clang-format on
#include <android_audio_policy_configuration_V7_0-enums.h>
#include <android_audio_policy_configuration_V7_0.h>
#include "DeviceManager.h"
using ::android::NO_INIT;
using ::android::OK;
using ::android::status_t;
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::CPP_VERSION;
namespace xsd {
using namespace ::android::audio::policy::configuration::CPP_VERSION;
using Module = Modules::Module;
}
@ -30,20 +54,13 @@ class PolicyConfig {
: mConfigFileName{configFileName},
mFilePath{findExistingConfigurationFile(mConfigFileName)},
mConfig{xsd::read(mFilePath.c_str())} {
if (mConfig) {
mStatus = OK;
mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
if (mConfig->getFirstModules()) {
for (const auto& module : mConfig->getFirstModules()->get_module()) {
if (module.getFirstAttachedDevices()) {
auto attachedDevices = module.getFirstAttachedDevices()->getItem();
if (!attachedDevices.empty()) {
mModulesWithDevicesNames.insert(module.getName());
}
}
}
}
}
init();
}
PolicyConfig(const std::string& configPath, const std::string& configFileName)
: mConfigFileName{configFileName},
mFilePath{configPath + "/" + mConfigFileName},
mConfig{xsd::read(mFilePath.c_str())} {
init();
}
status_t getStatus() const { return mStatus; }
std::string getError() const {
@ -87,6 +104,22 @@ class PolicyConfig {
}
return std::string{};
}
void init() {
if (mConfig) {
mStatus = OK;
mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
if (mConfig->getFirstModules()) {
for (const auto& module : mConfig->getFirstModules()->get_module()) {
if (module.getFirstAttachedDevices()) {
auto attachedDevices = module.getFirstAttachedDevices()->getItem();
if (!attachedDevices.empty()) {
mModulesWithDevicesNames.insert(module.getName());
}
}
}
}
}
}
const std::string mConfigFileName;
const std::string mFilePath;

View file

@ -126,6 +126,7 @@ cc_test {
defaults: ["VtsHalAudioTargetTest_defaults"],
srcs: [
"6.0/AudioPrimaryHidlHalTest.cpp",
"6.0/Generators.cpp",
],
static_libs: [
"libaudiofoundation",
@ -152,6 +153,7 @@ cc_test {
defaults: ["VtsHalAudioTargetTest_defaults"],
srcs: [
"7.0/AudioPrimaryHidlHalTest.cpp",
"7.0/Generators.cpp",
],
generated_headers: ["audio_policy_configuration_V7_0_parser"],
generated_sources: ["audio_policy_configuration_V7_0_parser"],
@ -172,3 +174,57 @@ cc_test {
// TODO(b/146104851): Add auto-gen rules and remove it.
test_config: "VtsHalAudioV7_0TargetTest.xml",
}
// Note: the following aren't VTS tests, but rather unit tests
// to verify correctness of test parameter generator utilities.
cc_test {
name: "HalAudioV6_0GeneratorTest",
defaults: ["VtsHalAudioTargetTest_defaults"],
srcs: [
"6.0/Generators.cpp",
"tests/generators_tests.cpp",
],
static_libs: [
"android.hardware.audio@6.0",
"android.hardware.audio.common@6.0",
"libaudiofoundation",
"libaudiopolicycomponents",
"libmedia_helper",
],
cflags: [
"-DMAJOR_VERSION=6",
"-DMINOR_VERSION=0",
"-include common/all-versions/VersionMacro.h",
],
data: [
"tests/apm_config_no_vx.xml",
"tests/apm_config_with_vx.xml",
],
test_config: "tests/HalAudioV6_0GeneratorTest.xml",
}
cc_test {
name: "HalAudioV7_0GeneratorTest",
defaults: ["VtsHalAudioTargetTest_defaults"],
srcs: [
"7.0/Generators.cpp",
"tests/generators_tests.cpp",
],
generated_headers: ["audio_policy_configuration_V7_0_parser"],
generated_sources: ["audio_policy_configuration_V7_0_parser"],
static_libs: [
"android.hardware.audio@7.0",
"android.hardware.audio.common@7.0",
"android.hardware.audio.common@7.0-enums",
],
cflags: [
"-DMAJOR_VERSION=7",
"-DMINOR_VERSION=0",
"-include common/all-versions/VersionMacro.h",
],
data: [
"tests/apm_config_no_vx_7_0.xml",
"tests/apm_config_with_vx_7_0.xml",
],
test_config: "tests/HalAudioV7_0GeneratorTest.xml",
}

View file

@ -59,6 +59,7 @@
#include "utility/ReturnIn.h"
#include "utility/ValidateXml.h"
#include "AudioTestDefinitions.h"
/** Provide version specific functions that are used in the generic tests */
#if MAJOR_VERSION == 2
#include "2.0/AudioPrimaryHidlHalUtils.h"
@ -107,7 +108,11 @@ static auto invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUP
#include "DeviceManager.h"
#if MAJOR_VERSION <= 6
#include "PolicyConfig.h"
#if MAJOR_VERSION == 6
#include "6.0/Generators.h"
#endif
#elif MAJOR_VERSION >= 7
#include "7.0/Generators.h"
#include "7.0/PolicyConfig.h"
#endif
@ -175,9 +180,6 @@ TEST(CheckConfig, audioPolicyConfigurationValidation) {
//////////////////// Test parameter types and definitions ////////////////////
//////////////////////////////////////////////////////////////////////////////
enum { PARAM_FACTORY_NAME, PARAM_DEVICE_NAME };
using DeviceParameter = std::tuple<std::string, std::string>;
static inline std::string DeviceParameterToString(
const ::testing::TestParamInfo<DeviceParameter>& info) {
const auto& deviceName = std::get<PARAM_DEVICE_NAME>(info.param);
@ -509,24 +511,6 @@ INSTANTIATE_TEST_CASE_P(AudioPatchHidl, AudioPatchHidlTest,
// list is empty, this isn't a problem.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioPatchHidlTest);
// Nesting a tuple in another tuple allows to use GTest Combine function to generate
// all combinations of devices and configs.
enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS };
#if MAJOR_VERSION <= 6
enum { INDEX_INPUT, INDEX_OUTPUT };
using DeviceConfigParameter =
std::tuple<DeviceParameter, AudioConfig, std::variant<AudioInputFlag, AudioOutputFlag>>;
#elif MAJOR_VERSION >= 7
using DeviceConfigParameter = std::tuple<DeviceParameter, AudioConfig, std::vector<AudioInOutFlag>>;
#endif
#if MAJOR_VERSION >= 6
const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters();
const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters();
#endif
#if MAJOR_VERSION >= 4
static std::string SanitizeStringForGTestName(const std::string& s) {
std::string result = s;

View file

@ -0,0 +1,45 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
#include <tuple>
#include <variant>
#include <vector>
// clang-format off
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
// clang-format on
enum { PARAM_FACTORY_NAME, PARAM_DEVICE_NAME };
using DeviceParameter = std::tuple<std::string, std::string>;
// Nesting a tuple in another tuple allows to use GTest Combine function to generate
// all combinations of devices and configs.
enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS };
#if MAJOR_VERSION <= 6
enum { INDEX_INPUT, INDEX_OUTPUT };
using DeviceConfigParameter =
std::tuple<DeviceParameter, android::hardware::audio::common::CPP_VERSION::AudioConfig,
std::variant<android::hardware::audio::common::CPP_VERSION::AudioInputFlag,
android::hardware::audio::common::CPP_VERSION::AudioOutputFlag>>;
#elif MAJOR_VERSION >= 7
using DeviceConfigParameter =
std::tuple<DeviceParameter, android::hardware::audio::common::CPP_VERSION::AudioConfig,
std::vector<android::hardware::audio::CPP_VERSION::AudioInOutFlag>>;
#endif

View file

@ -16,10 +16,21 @@
#pragma once
// Code in this file uses 'getCachedPolicyConfig'
#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST
#error Must be included from AudioPrimaryHidlTest.h
#endif
#include <common/all-versions/VersionUtils.h>
#include "PolicyConfig.h"
// clang-format off
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
// clang-format on
using ::android::hardware::audio::common::utils::EnumBitfield;
using ::android::hardware::audio::common::utils::mkEnumBitfield;
// Forward declaration for functions that are substituted
// in generator unit tests.
const PolicyConfig& getCachedPolicyConfig();
//////////////////////////////////////////////////////////////////////////////
//////////////// Required and recommended audio format support ///////////////
@ -35,7 +46,7 @@ struct ConfigHelper {
// FIXME: in the next audio HAL version, test all available devices
static bool primaryHasMic() {
auto& policyConfig = getCachedPolicyConfig();
if (policyConfig.getStatus() != OK || policyConfig.getPrimaryModule() == nullptr) {
if (policyConfig.getStatus() != android::OK || policyConfig.getPrimaryModule() == nullptr) {
return true; // Could not get the information, run all tests
}
auto getMic = [](auto& devs) {

View file

@ -16,9 +16,27 @@
#pragma once
// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
// and thus it doesn't have all '#include' and 'using' directives required
// for a standalone compilation.
#include <unistd.h>
#include <map>
#include <android-base/logging.h>
#include <hwbinder/IPCThreadState.h>
// clang-format off
#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
// clang-format on
#include "utility/ReturnIn.h"
using ::android::sp;
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::common::test::utility;
using namespace ::android::hardware::audio::CPP_VERSION;
template <class Derived, class Key, class Interface>
class InterfaceManager {
@ -56,7 +74,7 @@ class InterfaceManager {
// the remote device has the time to be destroyed.
// flushCommand makes sure all local command are sent, thus should reduce
// the latency between local and remote destruction.
IPCThreadState::self()->flushCommands();
::android::hardware::IPCThreadState::self()->flushCommands();
usleep(100 * 1000);
}

View file

@ -16,11 +16,19 @@
#pragma once
// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
// and thus it doesn't have all '#include' and 'using' directives required
// for a standalone compilation.
#include <set>
#include <string>
#include <DeviceDescriptor.h>
#include <HwModule.h>
#include <Serializer.h>
#include <gtest/gtest.h>
#include <system/audio_config.h>
#include "DeviceManager.h"
using ::android::sp;
using ::android::status_t;
struct PolicyConfigData {
android::HwModuleCollection hwModules;
@ -42,28 +50,14 @@ class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig
break;
}
}
mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this);
if (mStatus == OK) {
mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
// Available devices are not 'attached' to modules at this moment.
// Need to go over available devices and find their module.
for (const auto& device : availableOutputDevices) {
for (const auto& module : hwModules) {
if (module->getDeclaredDevices().indexOf(device) >= 0) {
mModulesWithDevicesNames.insert(module->getName());
break;
}
}
}
for (const auto& device : availableInputDevices) {
for (const auto& module : hwModules) {
if (module->getDeclaredDevices().indexOf(device) >= 0) {
mModulesWithDevicesNames.insert(module->getName());
break;
}
}
}
}
init();
}
PolicyConfig(const std::string& configPath, const std::string& configFileName)
: android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
defaultOutputDevice),
mConfigFileName{configFileName},
mFilePath{configPath + "/" + mConfigFileName} {
init();
}
status_t getStatus() const { return mStatus; }
std::string getError() const {
@ -88,8 +82,33 @@ class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig
}
private:
void init() {
mStatus = android::deserializeAudioPolicyFileForVts(mFilePath.c_str(), this);
if (mStatus == android::OK) {
mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
// Available devices are not 'attached' to modules at this moment.
// Need to go over available devices and find their module.
for (const auto& device : availableOutputDevices) {
for (const auto& module : hwModules) {
if (module->getDeclaredDevices().indexOf(device) >= 0) {
mModulesWithDevicesNames.insert(module->getName());
break;
}
}
}
for (const auto& device : availableInputDevices) {
for (const auto& module : hwModules) {
if (module->getDeclaredDevices().indexOf(device) >= 0) {
mModulesWithDevicesNames.insert(module->getName());
break;
}
}
}
}
}
const std::string mConfigFileName;
status_t mStatus = NO_INIT;
status_t mStatus = android::NO_INIT;
std::string mFilePath;
sp<const android::HwModule> mPrimaryModule = nullptr;
std::set<std::string> mModulesWithDevicesNames;

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<configuration description="Runs HalAudioV6_0GeneratorTest.">
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-native" />
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="cleanup" value="true" />
<option name="push" value="apm_config_no_vx.xml->/data/local/tmp/apm_config_no_vx.xml" />
<option name="push" value="apm_config_with_vx.xml->/data/local/tmp/apm_config_with_vx.xml" />
<option name="push" value="HalAudioV6_0GeneratorTest->/data/local/tmp/HalAudioV6_0GeneratorTest" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="HalAudioV6_0GeneratorTest" />
</test>
</configuration>

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<configuration description="Runs HalAudioV7_0GeneratorTest.">
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-native" />
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="cleanup" value="true" />
<option name="push" value="apm_config_no_vx_7_0.xml->/data/local/tmp/apm_config_no_vx.xml" />
<option name="push" value="apm_config_with_vx_7_0.xml->/data/local/tmp/apm_config_with_vx.xml" />
<option name="push" value="HalAudioV7_0GeneratorTest->/data/local/tmp/HalAudioV7_0GeneratorTest" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="HalAudioV7_0GeneratorTest" />
</test>
</configuration>

View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<globalConfiguration speaker_drc_enabled="true"/>
<modules>
<module name="primary" halVersion="3.0">
<attachedDevices>
<item>Speaker</item>
<item>Built-In Mic</item>
</attachedDevices>
<defaultOutputDevice>Speaker</defaultOutputDevice>
<mixPorts>
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="primary input" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</mixPort>
</mixPorts>
<devicePorts>
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
minValueMB="-8400"
maxValueMB="4000"
defaultValueMB="0"
stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
</devicePorts>
<routes>
<route type="mix" sink="Speaker" sources="primary output"/>
<route type="mix" sink="primary input" sources="Built-In Mic"/>
</routes>
</module>
</modules>
<volumes/>
<surroundSound>
<formats>
<format name="AUDIO_FORMAT_AC3" />
<format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
</formats>
</surroundSound>
</audioPolicyConfiguration>

View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<globalConfiguration speaker_drc_enabled="true"/>
<modules>
<module name="primary" halVersion="3.0">
<attachedDevices>
<item>Speaker</item>
<item>Built-In Mic</item>
</attachedDevices>
<defaultOutputDevice>Speaker</defaultOutputDevice>
<mixPorts>
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="primary input" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
</mixPort>
</mixPorts>
<devicePorts>
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
minValueMB="-8400"
maxValueMB="4000"
defaultValueMB="0"
stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
</devicePorts>
<routes>
<route type="mix" sink="Speaker" sources="primary output"/>
<route type="mix" sink="primary input" sources="Built-In Mic"/>
</routes>
</module>
</modules>
<volumes/>
<surroundSound>
<formats>
<format name="AUDIO_FORMAT_AC3" />
<format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
</formats>
</surroundSound>
</audioPolicyConfiguration>

View file

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<globalConfiguration speaker_drc_enabled="true"/>
<modules>
<module name="primary" halVersion="3.0">
<attachedDevices>
<item>Speaker</item>
<item>Built-In Mic</item>
</attachedDevices>
<defaultOutputDevice>Speaker</defaultOutputDevice>
<mixPorts>
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="primary input" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
<profile name="" format="VX_GOOGLE_B_FORMAT"
samplingRates="192000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</mixPort>
</mixPorts>
<devicePorts>
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
minValueMB="-8400"
maxValueMB="4000"
defaultValueMB="0"
stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
<profile name="" format="VX_GOOGLE_B_FORMAT"
samplingRates="192000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
<devicePort tagName="Ambient Mic" type="VX_GOOGLE_AUDIO_DEVICE_AMBIENT_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
</devicePorts>
<routes>
<route type="mix" sink="Speaker" sources="primary output"/>
<route type="mix" sink="primary input" sources="Built-In Mic,Ambient Mic"/>
</routes>
</module>
</modules>
<volumes/>
<surroundSound>
<formats>
<format name="AUDIO_FORMAT_AC3" />
<format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
<format name="VX_GOOGLE_B_FORMAT" />
<format name="AUDIO_FORMAT_AC4" subformats="VX_GOOGLE_B_FORMAT" />
</formats>
</surroundSound>
</audioPolicyConfiguration>

View file

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<globalConfiguration speaker_drc_enabled="true"/>
<modules>
<module name="primary" halVersion="3.0">
<attachedDevices>
<item>Speaker</item>
<item>Built-In Mic</item>
</attachedDevices>
<defaultOutputDevice>Speaker</defaultOutputDevice>
<mixPorts>
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="primary input" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
<profile name="" format="VX_GOOGLE_B_FORMAT"
samplingRates="192000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
</mixPort>
</mixPorts>
<devicePorts>
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
minValueMB="-8400"
maxValueMB="4000"
defaultValueMB="0"
stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
<profile name="" format="VX_GOOGLE_B_FORMAT"
samplingRates="192000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
<devicePort tagName="Ambient Mic" type="VX_GOOGLE_AUDIO_DEVICE_AMBIENT_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
</devicePorts>
<routes>
<route type="mix" sink="Speaker" sources="primary output"/>
<route type="mix" sink="primary input" sources="Built-In Mic,Ambient Mic"/>
</routes>
</module>
</modules>
<volumes/>
<surroundSound>
<formats>
<format name="AUDIO_FORMAT_AC3" />
<format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
<format name="VX_GOOGLE_B_FORMAT" />
<format name="AUDIO_FORMAT_AC4" subformats="VX_GOOGLE_B_FORMAT" />
</formats>
</surroundSound>
</audioPolicyConfiguration>

View file

@ -0,0 +1,132 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <memory>
#include <string>
#include <vector>
#include <android-base/macros.h>
#include <gtest/gtest.h>
#define LOG_TAG "Generators_Test"
#include <log/log.h>
#if MAJOR_VERSION == 6
#include <system/audio.h>
#include "6.0/Generators.h"
#include "PolicyConfig.h"
#elif MAJOR_VERSION == 7
#include "7.0/Generators.h"
#include "7.0/PolicyConfig.h"
#endif
using namespace android;
using namespace ::android::hardware::audio::common::CPP_VERSION;
#if MAJOR_VERSION == 7
namespace xsd {
using namespace ::android::audio::policy::configuration::CPP_VERSION;
}
#endif
// Stringify the argument.
#define QUOTE(x) #x
#define STRINGIFY(x) QUOTE(x)
struct PolicyConfigManager {
static PolicyConfigManager& getInstance() {
static PolicyConfigManager instance;
return instance;
}
bool init(const std::string& filePath, const std::string& fileName) {
mConfig = std::make_unique<PolicyConfig>(filePath, fileName);
mDeviceParameters.clear();
if (mConfig->getStatus() == OK) {
const auto devices = mConfig->getModulesWithDevicesNames();
mDeviceParameters.reserve(devices.size());
for (const auto& deviceName : devices) {
mDeviceParameters.emplace_back(
"android.hardware.audio.IDevicesFactory@" STRINGIFY(FILE_VERSION),
deviceName);
}
return true;
} else {
ALOGE("%s", mConfig->getError().c_str());
return false;
}
}
const PolicyConfig& getConfig() { return *mConfig; }
const std::vector<DeviceParameter>& getDeviceParameters() { return mDeviceParameters; }
private:
std::unique_ptr<PolicyConfig> mConfig;
std::vector<DeviceParameter> mDeviceParameters;
};
// Test implementations
const PolicyConfig& getCachedPolicyConfig() {
return PolicyConfigManager::getInstance().getConfig();
}
const std::vector<DeviceParameter>& getDeviceParameters() {
return PolicyConfigManager::getInstance().getDeviceParameters();
}
static const std::string kDataDir = "/data/local/tmp";
class GeneratorsTest : public ::testing::TestWithParam<std::string> {
public:
static void validateConfig(const AudioConfig& config) {
#if MAJOR_VERSION == 6
ASSERT_TRUE(audio_is_valid_format(static_cast<audio_format_t>(config.format)))
<< "Audio format is invalid " << ::testing::PrintToString(config.format);
ASSERT_TRUE(
audio_channel_mask_is_valid(static_cast<audio_channel_mask_t>(config.channelMask)))
<< "Audio channel mask is invalid " << ::testing::PrintToString(config.channelMask);
#elif MAJOR_VERSION == 7
ASSERT_FALSE(xsd::isUnknownAudioFormat(config.base.format))
<< "Audio format is invalid " << ::testing::PrintToString(config.base.format);
ASSERT_FALSE(xsd::isUnknownAudioChannelMask(config.base.channelMask))
<< "Audio channel mask is invalid "
<< ::testing::PrintToString(config.base.channelMask);
#endif
}
static void validateDeviceConfigs(const std::vector<DeviceConfigParameter>& params) {
for (const auto& param : params) {
ASSERT_NO_FATAL_FAILURE(validateConfig(std::get<PARAM_CONFIG>(param)));
}
}
};
TEST_P(GeneratorsTest, ValidateConfigs) {
ASSERT_TRUE(PolicyConfigManager::getInstance().init(kDataDir, GetParam()));
EXPECT_NE(nullptr, getCachedPolicyConfig().getPrimaryModule());
EXPECT_FALSE(getCachedPolicyConfig().getModulesWithDevicesNames().empty());
const auto allOutConfigs = generateOutputDeviceConfigParameters(false /*oneProfilePerDevice*/);
EXPECT_FALSE(allOutConfigs.empty());
EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(allOutConfigs));
const auto singleOutConfig = generateOutputDeviceConfigParameters(true /*oneProfilePerDevice*/);
EXPECT_FALSE(singleOutConfig.empty());
EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(singleOutConfig));
const auto allInConfigs = generateInputDeviceConfigParameters(false /*oneProfilePerDevice*/);
EXPECT_FALSE(allInConfigs.empty());
EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(allInConfigs));
const auto singleInConfig = generateInputDeviceConfigParameters(true /*oneProfilePerDevice*/);
EXPECT_FALSE(singleInConfig.empty());
EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(singleInConfig));
}
// Target file names are the same for all versions, see 'HalAudioVx_0GeneratorTest.xml' test configs
INSTANTIATE_TEST_SUITE_P(Generators, GeneratorsTest,
::testing::Values("apm_config_no_vx.xml", "apm_config_with_vx.xml"));