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:
commit
a40f50ddc0
21 changed files with 1247 additions and 440 deletions
|
@ -2,6 +2,12 @@
|
|||
"presubmit": [
|
||||
{
|
||||
"name": "android.hardware.audio@7.0-util_tests"
|
||||
},
|
||||
{
|
||||
"name": "HalAudioV6_0GeneratorTest"
|
||||
},
|
||||
{
|
||||
"name": "HalAudioV7_0GeneratorTest"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
129
audio/core/all-versions/vts/functional/6.0/Generators.cpp
Normal file
129
audio/core/all-versions/vts/functional/6.0/Generators.cpp
Normal 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;
|
||||
}
|
30
audio/core/all-versions/vts/functional/6.0/Generators.h
Normal file
30
audio/core/all-versions/vts/functional/6.0/Generators.h
Normal 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);
|
|
@ -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.");
|
||||
|
|
309
audio/core/all-versions/vts/functional/7.0/Generators.cpp
Normal file
309
audio/core/all-versions/vts/functional/7.0/Generators.cpp
Normal 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;
|
||||
}
|
34
audio/core/all-versions/vts/functional/7.0/Generators.h
Normal file
34
audio/core/all-versions/vts/functional/7.0/Generators.h
Normal 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);
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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"));
|
Loading…
Reference in a new issue