audio: Implement VTS tests for V7.0 am: d72a7c27ab am: c70238a35b

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

Change-Id: If805eb94f5b0fee507186dc303b8e61a38ef2b11
This commit is contained in:
Mikhail Naganov
2020-11-23 20:18:49 +00:00
committed by Automerger Merge Worker
14 changed files with 856 additions and 185 deletions

View File

@@ -16,9 +16,12 @@ hidl_interface {
cc_library {
name: "android.hardware.audio.common@7.0-enums",
vendor_available: true,
generated_sources: ["audio_policy_configuration_V7_0"],
generated_headers: ["audio_policy_configuration_V7_0"],
generated_sources: ["audio_policy_configuration_V7_0"],
header_libs: ["libxsdc-utils"],
export_generated_headers: ["audio_policy_configuration_V7_0"],
export_header_lib_headers: ["libxsdc-utils"],
export_include_dirs: ["enums/include"],
shared_libs: [
"libbase",
"liblog",

View File

@@ -0,0 +1,207 @@
/*
* Copyright (C) 2020 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.
*/
#ifndef AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H
#define AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H
#include <sys/types.h>
#include <audio_policy_configuration_V7_0.h>
namespace audio::policy::configuration::V7_0 {
static inline size_t getChannelCount(AudioChannelMask mask) {
switch (mask) {
case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO:
case AudioChannelMask::AUDIO_CHANNEL_IN_MONO:
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_1:
return 1;
case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO:
case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_A:
case AudioChannelMask::AUDIO_CHANNEL_OUT_HAPTIC_AB:
case AudioChannelMask::AUDIO_CHANNEL_IN_STEREO:
case AudioChannelMask::AUDIO_CHANNEL_IN_FRONT_BACK:
case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO:
case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO:
case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_CALL_MONO:
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_2:
return 2;
case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1:
case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A:
case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB:
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_3:
return 3;
case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT0POINT2:
case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD:
case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_BACK:
case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_SIDE:
case AudioChannelMask::AUDIO_CHANNEL_OUT_SURROUND:
case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB:
case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT0POINT2:
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_4:
return 4;
case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1POINT2:
case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT0POINT2:
case AudioChannelMask::AUDIO_CHANNEL_OUT_PENTA:
case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT1POINT2:
case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT0POINT2:
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_5:
return 5;
case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1POINT2:
case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1:
case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_BACK:
case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_SIDE:
case AudioChannelMask::AUDIO_CHANNEL_IN_6:
case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT1POINT2:
case AudioChannelMask::AUDIO_CHANNEL_IN_5POINT1:
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_6:
return 6;
case AudioChannelMask::AUDIO_CHANNEL_OUT_6POINT1:
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_7:
return 7;
case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT2:
case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1:
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_8:
return 8;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_9:
return 9;
case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT4:
case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT2:
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_10:
return 10;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_11:
return 11;
case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT4:
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_12:
return 12;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_13:
return 13;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_14:
return 14;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_15:
return 15;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_16:
return 16;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_17:
return 17;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_18:
return 18;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_19:
return 19;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_20:
return 20;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_21:
return 21;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_22:
return 22;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_23:
return 23;
case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_24:
return 24;
case AudioChannelMask::UNKNOWN:
return 0;
// No default to make sure all cases are covered.
}
// This is to avoid undefined behavior if 'mask' isn't a valid enum value.
return 0;
}
static inline ssize_t getChannelCount(const std::string& mask) {
return getChannelCount(stringToAudioChannelMask(mask));
}
static inline bool isOutputDevice(AudioDevice device) {
switch (device) {
case AudioDevice::UNKNOWN:
case AudioDevice::AUDIO_DEVICE_NONE:
return false;
case AudioDevice::AUDIO_DEVICE_OUT_EARPIECE:
case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER:
case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADSET:
case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
case AudioDevice::AUDIO_DEVICE_OUT_AUX_DIGITAL:
case AudioDevice::AUDIO_DEVICE_OUT_HDMI:
case AudioDevice::AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET:
case AudioDevice::AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET:
case AudioDevice::AUDIO_DEVICE_OUT_USB_ACCESSORY:
case AudioDevice::AUDIO_DEVICE_OUT_USB_DEVICE:
case AudioDevice::AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
case AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX:
case AudioDevice::AUDIO_DEVICE_OUT_LINE:
case AudioDevice::AUDIO_DEVICE_OUT_HDMI_ARC:
case AudioDevice::AUDIO_DEVICE_OUT_SPDIF:
case AudioDevice::AUDIO_DEVICE_OUT_FM:
case AudioDevice::AUDIO_DEVICE_OUT_AUX_LINE:
case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER_SAFE:
case AudioDevice::AUDIO_DEVICE_OUT_IP:
case AudioDevice::AUDIO_DEVICE_OUT_BUS:
case AudioDevice::AUDIO_DEVICE_OUT_PROXY:
case AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET:
case AudioDevice::AUDIO_DEVICE_OUT_HEARING_AID:
case AudioDevice::AUDIO_DEVICE_OUT_ECHO_CANCELLER:
case AudioDevice::AUDIO_DEVICE_OUT_DEFAULT:
case AudioDevice::AUDIO_DEVICE_OUT_STUB:
return true;
case AudioDevice::AUDIO_DEVICE_IN_COMMUNICATION:
case AudioDevice::AUDIO_DEVICE_IN_AMBIENT:
case AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC:
case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET:
case AudioDevice::AUDIO_DEVICE_IN_WIRED_HEADSET:
case AudioDevice::AUDIO_DEVICE_IN_AUX_DIGITAL:
case AudioDevice::AUDIO_DEVICE_IN_HDMI:
case AudioDevice::AUDIO_DEVICE_IN_VOICE_CALL:
case AudioDevice::AUDIO_DEVICE_IN_TELEPHONY_RX:
case AudioDevice::AUDIO_DEVICE_IN_BACK_MIC:
case AudioDevice::AUDIO_DEVICE_IN_REMOTE_SUBMIX:
case AudioDevice::AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET:
case AudioDevice::AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET:
case AudioDevice::AUDIO_DEVICE_IN_USB_ACCESSORY:
case AudioDevice::AUDIO_DEVICE_IN_USB_DEVICE:
case AudioDevice::AUDIO_DEVICE_IN_FM_TUNER:
case AudioDevice::AUDIO_DEVICE_IN_TV_TUNER:
case AudioDevice::AUDIO_DEVICE_IN_LINE:
case AudioDevice::AUDIO_DEVICE_IN_SPDIF:
case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_A2DP:
case AudioDevice::AUDIO_DEVICE_IN_LOOPBACK:
case AudioDevice::AUDIO_DEVICE_IN_IP:
case AudioDevice::AUDIO_DEVICE_IN_BUS:
case AudioDevice::AUDIO_DEVICE_IN_PROXY:
case AudioDevice::AUDIO_DEVICE_IN_USB_HEADSET:
case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE:
case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC:
case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE:
case AudioDevice::AUDIO_DEVICE_IN_DEFAULT:
case AudioDevice::AUDIO_DEVICE_IN_STUB:
return false;
// No default to make sure all cases are covered.
}
// This is to avoid undefined behavior if 'device' isn't a valid enum value.
return false;
}
static inline bool isOutputDevice(const std::string& device) {
return isOutputDevice(stringToAudioDevice(device));
}
} // namespace audio::policy::configuration::V7_0
#endif // AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H

View File

@@ -16,6 +16,13 @@
#include "AudioPrimaryHidlHalTest.h"
#if MAJOR_VERSION >= 7
#include <audio_policy_configuration_V7_0.h>
#include <xsdc/XsdcSupport.h>
using android::xsdc_enum_range;
#endif
TEST_P(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
doc::test("Calling openDevice(\"primary\") should return the primary device.");
if (getDeviceName() != DeviceManager::kPrimaryDevice) {
@@ -53,14 +60,29 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) {
"Make sure getMicrophones always succeeds"
"and getActiveMicrophones always succeeds when recording from these microphones.");
AudioConfig config{};
#if MAJOR_VERSION <= 6
config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO);
config.sampleRateHz = 8000;
config.format = AudioFormat::PCM_16_BIT;
auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
#elif MAJOR_VERSION >= 7
config.base.channelMask.resize(1);
config.base.channelMask[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO);
config.base.sampleRateHz = 8000;
config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
hidl_vec<hidl_string> flags;
const SinkMetadata initMetadata = {
{{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}};
#endif
EventFlag* efGroup;
for (auto microphone : microphones) {
#if MAJOR_VERSION <= 6
if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) {
#elif MAJOR_VERSION >= 7
if (xsd::stringToAudioDevice(microphone.deviceAddress.deviceType) !=
xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC) {
#endif
continue;
}
sp<IStreamIn> stream;
@@ -81,16 +103,16 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) {
size_t frameSize = stream->getFrameSize();
size_t frameCount = stream->getBufferSize() / frameSize;
ASSERT_OK(stream->prepareForReading(
frameSize, frameCount, [&](auto r, auto& c, auto& d, auto&, auto&) {
readRes = r;
if (readRes == Result::OK) {
commandMQ.reset(new CommandMQ(c));
dataMQ.reset(new DataMQ(d));
if (dataMQ->isValid() && dataMQ->getEventFlagWord()) {
EventFlag::createEventFlag(dataMQ->getEventFlagWord(), &efGroup);
frameSize, frameCount, [&](auto r, auto& c, auto& d, auto&, auto) {
readRes = r;
if (readRes == Result::OK) {
commandMQ.reset(new CommandMQ(c));
dataMQ.reset(new DataMQ(d));
if (dataMQ->isValid() && dataMQ->getEventFlagWord()) {
EventFlag::createEventFlag(dataMQ->getEventFlagWord(), &efGroup);
}
}
}
}));
}));
ASSERT_OK(readRes);
IStreamIn::ReadParameters params;
params.command = IStreamIn::ReadCommand::READ;
@@ -116,13 +138,24 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) {
TEST_P(AudioHidlDeviceTest, SetConnectedState) {
doc::test("Check that the HAL can be notified of device connection and deconnection");
#if MAJOR_VERSION <= 6
using AD = AudioDevice;
for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
#elif MAJOR_VERSION >= 7
using AD = xsd::AudioDevice;
for (auto deviceType :
{toString(AD::AUDIO_DEVICE_OUT_HDMI), toString(AD::AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
toString(AD::AUDIO_DEVICE_IN_USB_HEADSET)}) {
#endif
SCOPED_TRACE("device=" + ::testing::PrintToString(deviceType));
for (bool state : {true, false}) {
SCOPED_TRACE("state=" + ::testing::PrintToString(state));
DeviceAddress address = {};
#if MAJOR_VERSION <= 6
address.device = deviceType;
#elif MAJOR_VERSION >= 7
address.deviceType = deviceType;
#endif
auto ret = getDevice()->setConnectedState(address, state);
ASSERT_TRUE(ret.isOk());
if (ret == Result::NOT_SUPPORTED) {
@@ -148,7 +181,11 @@ static void testGetDevices(IStream* stream, AudioDevice expectedDevice) {
}
// The stream was constructed with one device, thus getDevices must only return one
ASSERT_EQ(1U, devices.size());
#if MAJOR_VERSION <= 6
AudioDevice device = devices[0].device;
#elif MAJOR_VERSION >= 7
auto device = devices[0].deviceType;
#endif
ASSERT_TRUE(device == expectedDevice)
<< "Expected: " << ::testing::PrintToString(expectedDevice)
<< "\n Actual: " << ::testing::PrintToString(device);
@@ -156,12 +193,22 @@ static void testGetDevices(IStream* stream, AudioDevice expectedDevice) {
TEST_IO_STREAM(GetDevices, "Check that the stream device == the one it was opened with",
areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
#if MAJOR_VERSION <= 6
: testGetDevices(stream.get(), address.device))
#elif MAJOR_VERSION >= 7
: testGetDevices(stream.get(), address.deviceType))
#endif
static void testSetDevices(IStream* stream, const DeviceAddress& address) {
DeviceAddress otherAddress = address;
#if MAJOR_VERSION <= 6
otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ? AudioDevice::OUT_SPEAKER
: AudioDevice::IN_BUILTIN_MIC;
#elif MAJOR_VERSION >= 7
otherAddress.deviceType = xsd::isOutputDevice(address.deviceType)
? toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER)
: toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC);
#endif
EXPECT_RESULT(okOrNotSupported, stream->setDevices({otherAddress}));
ASSERT_RESULT(okOrNotSupported,
@@ -186,11 +233,19 @@ TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", checkGetHwAVSync(g
TEST_P(InputStreamTest, updateSinkMetadata) {
doc::test("The HAL should not crash on metadata change");
#if MAJOR_VERSION <= 6
hidl_enum_range<AudioSource> range;
#elif MAJOR_VERSION >= 7
xsdc_enum_range<audio::policy::configuration::V7_0::AudioSource> range;
#endif
// Test all possible track configuration
for (AudioSource source : range) {
for (auto source : range) {
for (float volume : {0.0, 0.5, 1.0}) {
#if MAJOR_VERSION <= 6
const SinkMetadata metadata = {{{.source = source, .gain = volume}}};
#elif MAJOR_VERSION >= 7
const SinkMetadata metadata = {{{.source = toString(source), .gain = volume}}};
#endif
ASSERT_OK(stream->updateSinkMetadata(metadata))
<< "source=" << toString(source) << ", volume=" << volume;
}
@@ -213,13 +268,22 @@ TEST_P(OutputStreamTest, SelectPresentation) {
TEST_P(OutputStreamTest, updateSourceMetadata) {
doc::test("The HAL should not crash on metadata change");
#if MAJOR_VERSION <= 6
hidl_enum_range<AudioUsage> usageRange;
hidl_enum_range<AudioContentType> contentRange;
#elif MAJOR_VERSION >= 7
xsdc_enum_range<audio::policy::configuration::V7_0::AudioUsage> usageRange;
xsdc_enum_range<audio::policy::configuration::V7_0::AudioContentType> contentRange;
#endif
// Test all possible track configuration
for (auto usage : usageRange) {
for (auto content : contentRange) {
for (float volume : {0.0, 0.5, 1.0}) {
#if MAJOR_VERSION <= 6
const SourceMetadata metadata = {{{usage, content, volume}}};
#elif MAJOR_VERSION >= 7
const SourceMetadata metadata = {{{toString(usage), toString(content), volume}}};
#endif
ASSERT_OK(stream->updateSourceMetadata(metadata))
<< "usage=" << toString(usage) << ", content=" << toString(content)
<< ", volume=" << volume;
@@ -227,12 +291,26 @@ TEST_P(OutputStreamTest, updateSourceMetadata) {
}
}
// clang-format off
// Set many track of different configuration
ASSERT_OK(stream->updateSourceMetadata(
#if MAJOR_VERSION <= 6
{{{AudioUsage::MEDIA, AudioContentType::MUSIC, 0.1},
{AudioUsage::VOICE_COMMUNICATION, AudioContentType::SPEECH, 1.0},
{AudioUsage::ALARM, AudioContentType::SONIFICATION, 0.0},
{AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}}));
{AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}}
#elif MAJOR_VERSION >= 7
{{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 0.1},
{toString(xsd::AudioUsage::AUDIO_USAGE_VOICE_COMMUNICATION),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), 1.0},
{toString(xsd::AudioUsage::AUDIO_USAGE_ALARM),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), 0.0},
{toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANT),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), 0.3}}}
#endif
));
// clang-format on
// Set no metadata as if all stream track had stopped
ASSERT_OK(stream->updateSourceMetadata({}));

View File

@@ -56,6 +56,7 @@ struct Parameters {
}
};
#if MAJOR_VERSION <= 6
struct GetSupported {
static auto getFormat(IStream* stream) {
auto ret = stream->getFormat();
@@ -80,7 +81,7 @@ struct GetSupported {
EXPECT_OK(stream->getSupportedFormats(returnIn(capabilities)));
return Result::OK;
}
#elif MAJOR_VERSION >= 6
#else // MAJOR_VERSION == 6
static Result formats(IStream* stream, hidl_vec<AudioFormat>& capabilities) {
Result res;
EXPECT_OK(stream->getSupportedFormats(returnIn(res, capabilities)));
@@ -88,6 +89,7 @@ struct GetSupported {
}
#endif
};
#endif // MAJOR_VERSION <= 6
template <class T>
auto dump(T t, hidl_handle handle) {

View File

@@ -17,6 +17,7 @@
// pull in all the <= 5.0 tests
#include "5.0/AudioPrimaryHidlHalTest.cpp"
#if MAJOR_VERSION <= 6
const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters = [] {
std::vector<DeviceConfigParameter> result;
@@ -28,8 +29,8 @@ const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
auto configs = ConfigHelper::combineAudioConfig(
vector<audio_channel_mask_t>(channels.begin(), channels.end()),
vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
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) {
@@ -46,8 +47,8 @@ const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
config.offloadInfo.bufferSize = 256; // arbitrary value
config.offloadInfo.usage = AudioUsage::MEDIA;
result.emplace_back(device, config,
AudioOutputFlag(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
AUDIO_OUTPUT_FLAG_DIRECT));
AudioOutputFlag(AudioOutputFlag::COMPRESS_OFFLOAD |
AudioOutputFlag::DIRECT));
} else {
if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
@@ -74,8 +75,8 @@ const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
auto configs = ConfigHelper::combineAudioConfig(
vector<audio_channel_mask_t>(channels.begin(), channels.end()),
vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
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()));
@@ -87,13 +88,22 @@ const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
}();
return parameters;
}
#endif // MAJOR_VERSION <= 6
TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) {
doc::test("Verify that a device can't be closed if there are streams opened");
#if MAJOR_VERSION <= 6
DeviceAddress address{.device = AudioDevice::OUT_DEFAULT};
AudioConfig config{};
auto flags = hidl_bitfield<AudioOutputFlag>(AudioOutputFlag::NONE);
SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}};
auto flags = hidl_bitfield<AudioOutputFlag>(AudioOutputFlag::NONE);
#elif MAJOR_VERSION >= 7
DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT)};
SourceMetadata initMetadata = {
{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 1 /* gain */}}};
hidl_vec<AudioInOutFlag> flags;
#endif
AudioConfig config{};
sp<IStreamOut> stream;
StreamHelper<IStreamOut> helper(stream);
AudioConfig suggestedConfig{};
@@ -111,14 +121,20 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) {
TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) {
doc::test("Verify that a device can't be closed if there are streams opened");
auto module = getCachedPolicyConfig().getModuleFromName(getDeviceName());
if (module->getInputProfiles().empty()) {
if (!getCachedPolicyConfig().haveInputProfilesInModule(getDeviceName())) {
GTEST_SKIP() << "Device doesn't have input profiles";
}
#if MAJOR_VERSION <= 6
DeviceAddress address{.device = AudioDevice::IN_DEFAULT};
AudioConfig config{};
auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
#elif MAJOR_VERSION >= 7
DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT)};
SinkMetadata initMetadata = {
{{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}};
hidl_vec<AudioInOutFlag> flags;
#endif
AudioConfig config{};
sp<IStreamIn> stream;
StreamHelper<IStreamIn> helper(stream);
AudioConfig suggestedConfig{};
@@ -137,9 +153,8 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) {
TEST_P(AudioPatchHidlTest, UpdatePatchInvalidHandle) {
doc::test("Verify that passing an invalid handle to updateAudioPatch is checked");
AudioPatchHandle ignored;
ASSERT_OK(getDevice()->updateAudioPatch(
static_cast<int32_t>(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE),
hidl_vec<AudioPortConfig>(), hidl_vec<AudioPortConfig>(), returnIn(res, ignored)));
ASSERT_OK(getDevice()->updateAudioPatch(AudioPatchHandle{}, hidl_vec<AudioPortConfig>(),
hidl_vec<AudioPortConfig>(), returnIn(res, ignored)));
ASSERT_RESULT(Result::INVALID_ARGUMENTS, res);
}

View File

@@ -16,3 +16,101 @@
// 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{};
// leave offloadInfo to 0
config.base.channelMask.resize(1);
config.base.channelMask[0] = toString(channelMask);
config.base.sampleRateHz = sampleRate;
config.base.format = format;
configs.push_back(config);
}
}
return configs;
}
const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters = [] {
std::vector<DeviceConfigParameter> result;
const std::vector<AudioInOutFlag> offloadFlags = {
toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)};
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
auto xsdFlags = mixPort.getFlags();
const bool isOffload =
std::find(xsdFlags.begin(), xsdFlags.end(),
xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
xsdFlags.end();
std::vector<AudioInOutFlag> flags;
if (!isOffload) {
for (auto flag : xsdFlags) {
if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
flags.push_back(toString(flag));
}
}
} else {
flags = offloadFlags;
}
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.base = config.base;
config.offloadInfo.streamType =
toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC);
config.offloadInfo.usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA);
config.offloadInfo.bitRatePerSecond = 320;
config.offloadInfo.durationMicroseconds = -1;
config.offloadInfo.bitWidth = 16;
config.offloadInfo.bufferSize = 256; // arbitrary value
}
result.emplace_back(device, config, flags);
}
}
}
}
return result;
}();
return parameters;
}
const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters = [] {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
auto module =
getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
std::vector<AudioInOutFlag> flags;
std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(), flags.begin(),
[](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);
}
}
}
}
return result;
}();
return parameters;
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2020 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
// 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.
namespace xsd {
using Module = Modules::Module;
}
class PolicyConfig {
public:
explicit PolicyConfig(const std::string& configFileName)
: mConfigFileName{configFileName},
mFilePath{findExistingConfigurationFile(mConfigFileName)},
mConfig{xsd::read(mFilePath.c_str())} {
if (mConfig) {
mStatus = OK;
mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
for (const auto& module : mConfig->getFirstModules()->get_module()) {
auto attachedDevices = module.getFirstAttachedDevices()->getItem();
if (!attachedDevices.empty()) {
mModulesWithDevicesNames.insert(module.getName());
}
}
}
}
status_t getStatus() const { return mStatus; }
std::string getError() const {
if (mFilePath.empty()) {
return std::string{"Could not find "} + mConfigFileName +
" file in: " + testing::PrintToString(android::audio_get_configuration_paths());
} else {
return "Invalid config file: " + mFilePath;
}
}
const std::string& getFilePath() const { return mFilePath; }
const xsd::Module* getModuleFromName(const std::string& name) const {
if (mConfig) {
for (const auto& module : mConfig->getFirstModules()->get_module()) {
if (module.getName() == name) return &module;
}
}
return nullptr;
}
const xsd::Module* getPrimaryModule() const { return mPrimaryModule; }
const std::set<std::string>& getModulesWithDevicesNames() const {
return mModulesWithDevicesNames;
}
bool haveInputProfilesInModule(const std::string& name) const {
auto module = getModuleFromName(name);
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() == xsd::Role::sink) return true;
}
return false;
}
private:
static std::string findExistingConfigurationFile(const std::string& fileName) {
for (const auto& location : android::audio_get_configuration_paths()) {
std::string path = location + '/' + fileName;
if (access(path.c_str(), F_OK) == 0) {
return path;
}
}
return std::string{};
}
const std::string mConfigFileName;
const std::string mFilePath;
std::optional<xsd::AudioPolicyConfiguration> mConfig;
status_t mStatus = NO_INIT;
const xsd::Module* mPrimaryModule;
std::set<std::string> mModulesWithDevicesNames;
};

View File

@@ -19,9 +19,6 @@ cc_defaults {
defaults: ["VtsHalTargetTestDefaults"],
static_libs: [
"android.hardware.audio.common.test.utility",
"libaudiofoundation",
"libaudiopolicycomponents",
"libmedia_helper",
"libxml2",
],
shared_libs: [
@@ -44,6 +41,9 @@ cc_test {
"2.0/AudioPrimaryHidlHalTest.cpp",
],
static_libs: [
"libaudiofoundation",
"libaudiopolicycomponents",
"libmedia_helper",
"android.hardware.audio@2.0",
"android.hardware.audio.common@2.0",
],
@@ -67,6 +67,9 @@ cc_test {
"4.0/AudioPrimaryHidlHalTest.cpp",
],
static_libs: [
"libaudiofoundation",
"libaudiopolicycomponents",
"libmedia_helper",
"android.hardware.audio@4.0",
"android.hardware.audio.common@4.0",
],
@@ -90,6 +93,9 @@ cc_test {
"5.0/AudioPrimaryHidlHalTest.cpp",
],
static_libs: [
"libaudiofoundation",
"libaudiopolicycomponents",
"libmedia_helper",
"android.hardware.audio@5.0",
"android.hardware.audio.common@5.0",
],
@@ -113,6 +119,9 @@ cc_test {
"6.0/AudioPrimaryHidlHalTest.cpp",
],
static_libs: [
"libaudiofoundation",
"libaudiopolicycomponents",
"libmedia_helper",
"android.hardware.audio@6.0",
"android.hardware.audio.common@6.0",
],
@@ -130,7 +139,6 @@ cc_test {
}
cc_test {
enabled: false,
name: "VtsHalAudioV7_0TargetTest",
defaults: ["VtsHalAudioTargetTest_defaults"],
srcs: [
@@ -139,6 +147,7 @@ cc_test {
static_libs: [
"android.hardware.audio@7.0",
"android.hardware.audio.common@7.0",
"android.hardware.audio.common@7.0-enums",
],
cflags: [
"-DMAJOR_VERSION=7",

View File

@@ -42,8 +42,11 @@
#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)
#if MAJOR_VERSION >= 7
#include <audio_policy_configuration_V7_0-enums.h>
#include <audio_policy_configuration_V7_0.h>
#endif
#include <Serializer.h>
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
#include <hidl/GtestPrinter.h>
@@ -63,14 +66,6 @@
#include "4.0/AudioPrimaryHidlHalUtils.h"
#endif
using std::initializer_list;
using std::list;
using std::string;
using std::to_string;
using std::vector;
using ::android::AudioPolicyConfig;
using ::android::HwModule;
using ::android::NO_INIT;
using ::android::OK;
using ::android::sp;
@@ -93,6 +88,12 @@ using ::android::hardware::details::toHexString;
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::common::test::utility;
using namespace ::android::hardware::audio::CPP_VERSION;
#if MAJOR_VERSION >= 7
// Make an alias for enumerations generated from the APM config XSD.
namespace xsd {
using namespace ::audio::policy::configuration::CPP_VERSION;
}
#endif
// Typical accepted results from interface methods
static auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
@@ -103,8 +104,12 @@ static auto okOrInvalidStateOrNotSupported = {Result::OK, Result::INVALID_STATE,
static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
static auto invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED};
#define AUDIO_PRIMARY_HIDL_HAL_TEST
#include "DeviceManager.h"
#if MAJOR_VERSION <= 6
#include "PolicyConfig.h"
#elif MAJOR_VERSION >= 7
#include "7.0/PolicyConfig.h"
#endif
class HidlTest : public ::testing::Test {
public:
@@ -136,83 +141,16 @@ class HidlTest : public ::testing::Test {
////////////////////////// Audio policy configuration ////////////////////////
//////////////////////////////////////////////////////////////////////////////
static constexpr char kConfigFileName[] = "audio_policy_configuration.xml";
// Stringify the argument.
#define QUOTE(x) #x
#define STRINGIFY(x) QUOTE(x)
struct PolicyConfigData {
android::HwModuleCollection hwModules;
android::DeviceVector availableOutputDevices;
android::DeviceVector availableInputDevices;
sp<android::DeviceDescriptor> defaultOutputDevice;
};
class PolicyConfig : private PolicyConfigData, public AudioPolicyConfig {
public:
PolicyConfig()
: AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
defaultOutputDevice) {
for (const auto& location : android::audio_get_configuration_paths()) {
std::string path = location + '/' + kConfigFileName;
if (access(path.c_str(), F_OK) == 0) {
mFilePath = path;
break;
}
}
mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this);
if (mStatus == OK) {
mPrimaryModule = getHwModules().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;
}
}
}
}
}
status_t getStatus() const { return mStatus; }
std::string getError() const {
if (mFilePath.empty()) {
return std::string{"Could not find "} + kConfigFileName +
" file in: " + testing::PrintToString(android::audio_get_configuration_paths());
} else {
return "Invalid config file: " + mFilePath;
}
}
const std::string& getFilePath() const { return mFilePath; }
sp<const HwModule> getModuleFromName(const std::string& name) const {
return getHwModules().getModuleFromName(name.c_str());
}
sp<const HwModule> getPrimaryModule() const { return mPrimaryModule; }
const std::set<std::string>& getModulesWithDevicesNames() const {
return mModulesWithDevicesNames;
}
private:
status_t mStatus = NO_INIT;
std::string mFilePath;
sp<HwModule> mPrimaryModule = nullptr;
std::set<std::string> mModulesWithDevicesNames;
};
static constexpr char kConfigFileName[] = "audio_policy_configuration.xml";
// Cached policy config after parsing for faster test startup
const PolicyConfig& getCachedPolicyConfig() {
static std::unique_ptr<PolicyConfig> policyConfig = [] {
auto config = std::make_unique<PolicyConfig>();
auto config = std::make_unique<PolicyConfig>(kConfigFileName);
return config;
}();
return *policyConfig;
@@ -449,9 +387,10 @@ class AccessorHidlTest : public BaseTestClass {
* The getter and/or the setter may return NOT_SUPPORTED if optionality == OPTIONAL.
*/
template <Optionality optionality = REQUIRED, class IUTGetter, class Getter, class Setter>
void testAccessors(IUTGetter iutGetter, const string& propertyName,
const Initial expectedInitial, list<Property> valuesToTest, Setter setter,
Getter getter, const vector<Property>& invalidValues = {}) {
void testAccessors(IUTGetter iutGetter, const std::string& propertyName,
const Initial expectedInitial, std::list<Property> valuesToTest,
Setter setter, Getter getter,
const std::vector<Property>& invalidValues = {}) {
const auto expectedResults = {Result::OK,
optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK};
@@ -495,9 +434,9 @@ class AccessorHidlTest : public BaseTestClass {
EXPECT_RESULT(expectedResults, ((this->*iutGetter)().get()->*setter)(initialValue));
}
template <Optionality optionality = REQUIRED, class Getter, class Setter>
void testAccessors(const string& propertyName, const Initial expectedInitial,
list<Property> valuesToTest, Setter setter, Getter getter,
const vector<Property>& invalidValues = {}) {
void testAccessors(const std::string& propertyName, const Initial expectedInitial,
std::list<Property> valuesToTest, Setter setter, Getter getter,
const std::vector<Property>& invalidValues = {}) {
testAccessors<optionality>(&BaseTestClass::getDevice, propertyName, expectedInitial,
valuesToTest, setter, getter, invalidValues);
}
@@ -573,9 +512,13 @@ 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();
@@ -583,8 +526,8 @@ const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
#endif
#if MAJOR_VERSION >= 4
static string SanitizeStringForGTestName(const string& s) {
string result = s;
static std::string SanitizeStringForGTestName(const std::string& s) {
std::string result = s;
for (size_t i = 0; i < result.size(); i++) {
// gtest test names must only contain alphanumeric characters
if (!std::isalnum(result[i])) result[i] = '_';
@@ -598,43 +541,57 @@ static string SanitizeStringForGTestName(const string& s) {
* As the only parameter changing are channel mask and sample rate,
* only print those ones in the test name.
*/
static string DeviceConfigParameterToString(
static std::string DeviceConfigParameterToString(
const testing::TestParamInfo<DeviceConfigParameter>& info) {
const AudioConfig& config = std::get<PARAM_CONFIG>(info.param);
const auto deviceName = DeviceParameterToString(::testing::TestParamInfo<DeviceParameter>{
std::get<PARAM_DEVICE>(info.param), info.index});
return (deviceName.empty() ? "" : deviceName + "_") + to_string(info.index) + "__" +
to_string(config.sampleRateHz) + "_" +
// "MONO" is more clear than "FRONT_LEFT"
((config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) ||
config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO))
? "MONO"
const auto devicePart =
(deviceName.empty() ? "" : deviceName + "_") + std::to_string(info.index);
// The types had changed a lot between versions 2, 4..6 and 7. Use separate
// code sections for easier understanding.
#if MAJOR_VERSION == 2
: ::testing::PrintToString(config.channelMask)
#elif MAJOR_VERSION >= 4
// In V4 and above the channel mask is a bitfield.
// Printing its value using HIDL's toString for a bitfield emits a lot of extra
// text due to overlapping constant values. Instead, we print the bitfield value
// as if it was a single value + its hex representation
: SanitizeStringForGTestName(
::testing::PrintToString(AudioChannelMask(config.channelMask)) + "_" +
toHexString(config.channelMask))
#endif
) +
"_" +
#if MAJOR_VERSION == 2
std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); },
std::get<PARAM_FLAGS>(info.param));
#elif MAJOR_VERSION >= 4
SanitizeStringForGTestName(std::visit(
[](auto&& arg) -> std::string {
using T = std::decay_t<decltype(arg)>;
// Need to use FQN of toString to avoid confusing the compiler
return ::android::hardware::audio::common::CPP_VERSION::toString<T>(
hidl_bitfield<T>(arg));
},
std::get<PARAM_FLAGS>(info.param)));
const auto configPart =
std::to_string(config.sampleRateHz) + "_" +
// "MONO" is more clear than "FRONT_LEFT"
(config.channelMask == AudioChannelMask::OUT_MONO ||
config.channelMask == AudioChannelMask::IN_MONO
? "MONO"
: ::testing::PrintToString(config.channelMask)) +
"_" +
std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); },
std::get<PARAM_FLAGS>(info.param));
#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
const auto configPart =
std::to_string(config.sampleRateHz) + "_" +
// "MONO" is more clear than "FRONT_LEFT"
(config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) ||
config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO)
? "MONO"
// In V4 and above the channel mask is a bitfield.
// Printing its value using HIDL's toString for a bitfield emits a lot of extra
// text due to overlapping constant values. Instead, we print the bitfield
// value as if it was a single value + its hex representation
: SanitizeStringForGTestName(
::testing::PrintToString(AudioChannelMask(config.channelMask)) +
"_" + toHexString(config.channelMask))) +
"_" +
SanitizeStringForGTestName(std::visit(
[](auto&& arg) -> std::string {
using T = std::decay_t<decltype(arg)>;
// Need to use FQN of toString to avoid confusing the compiler
return ::android::hardware::audio::common::CPP_VERSION::toString<T>(
hidl_bitfield<T>(arg));
},
std::get<PARAM_FLAGS>(info.param)));
#elif MAJOR_VERSION >= 7
const auto configPart =
std::to_string(config.base.sampleRateHz) + "_" +
// The channel masks and flags are vectors of strings, just need to sanitize them.
SanitizeStringForGTestName(::testing::PrintToString(config.base.channelMask)) + "_" +
SanitizeStringForGTestName(::testing::PrintToString(std::get<PARAM_FLAGS>(info.param)));
#endif
return devicePart + "__" + configPart;
}
class AudioHidlTestWithDeviceConfigParameter
@@ -660,7 +617,7 @@ class AudioHidlTestWithDeviceConfigParameter
AudioOutputFlag getOutputFlags() const {
return std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam()));
}
#elif MAJOR_VERSION >= 4
#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
hidl_bitfield<AudioInputFlag> getInputFlags() const {
return hidl_bitfield<AudioInputFlag>(
std::get<INDEX_INPUT>(std::get<PARAM_FLAGS>(GetParam())));
@@ -669,10 +626,17 @@ class AudioHidlTestWithDeviceConfigParameter
return hidl_bitfield<AudioOutputFlag>(
std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam())));
}
#elif MAJOR_VERSION >= 7
hidl_vec<AudioInOutFlag> getInputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
hidl_vec<AudioInOutFlag> getOutputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
#endif
};
#if MAJOR_VERSION <= 6
#define AUDIO_PRIMARY_HIDL_HAL_TEST
#include "ConfigHelper.h"
#undef AUDIO_PRIMARY_HIDL_HAL_TEST
#endif
//////////////////////////////////////////////////////////////////////////////
///////////////////////////// getInputBufferSize /////////////////////////////
@@ -839,7 +803,7 @@ class StreamHelper {
AudioConfig* suggestedConfigPtr) {
// FIXME: Open a stream without an IOHandle
// This is not required to be accepted by hal implementations
AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
AudioIoHandle ioHandle{};
AudioConfig suggestedConfig{};
bool retryWithSuggestedConfig = true;
if (suggestedConfigPtr == nullptr) {
@@ -932,7 +896,11 @@ class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter {
class OutputStreamTest : public OpenStreamTest<IStreamOut> {
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
#if MAJOR_VERSION <= 6
address.device = AudioDevice::OUT_DEFAULT;
#elif MAJOR_VERSION >= 7
address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT);
#endif
const AudioConfig& config = getConfig();
auto flags = getOutputFlags();
testOpen(
@@ -946,13 +914,19 @@ class OutputStreamTest : public OpenStreamTest<IStreamOut> {
},
config);
}
#if MAJOR_VERSION >= 4
#if MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
protected:
protected:
const SourceMetadata initMetadata = {
{ { AudioUsage::MEDIA,
AudioContentType::MUSIC,
1 /* gain */ } }};
#elif MAJOR_VERSION >= 7
protected:
const SourceMetadata initMetadata = {
{ { toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC),
1 /* gain */ } }};
#endif
};
TEST_P(OutputStreamTest, OpenOutputStreamTest) {
@@ -995,7 +969,11 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OutputStreamTest);
class InputStreamTest : public OpenStreamTest<IStreamIn> {
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
#if MAJOR_VERSION <= 6
address.device = AudioDevice::IN_DEFAULT;
#elif MAJOR_VERSION <= 7
address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT);
#endif
const AudioConfig& config = getConfig();
auto flags = getInputFlags();
testOpen(
@@ -1009,8 +987,11 @@ class InputStreamTest : public OpenStreamTest<IStreamIn> {
protected:
#if MAJOR_VERSION == 2
const AudioSource initMetadata = AudioSource::DEFAULT;
#elif MAJOR_VERSION >= 4
const SinkMetadata initMetadata = {{{.source = AudioSource::DEFAULT, .gain = 1}}};
#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
const SinkMetadata initMetadata = {{ {.source = AudioSource::DEFAULT, .gain = 1 } }};
#elif MAJOR_VERSION >= 7
const SinkMetadata initMetadata = {
{{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), .gain = 1}}};
#endif
};
@@ -1067,6 +1048,7 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputStreamTest);
TEST_IO_STREAM(GetFrameCount, "Check that getting stream frame count does not crash the HAL.",
ASSERT_TRUE(stream->getFrameCount().isOk()))
#if MAJOR_VERSION <= 6
TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
@@ -1075,6 +1057,7 @@ TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it
TEST_IO_STREAM(GetFormat, "Check that the stream format == the one it was opened with",
ASSERT_EQ(audioConfig.format, extract(stream->getFormat())))
#endif
// TODO: for now only check that the framesize is not incoherent
TEST_IO_STREAM(GetFrameSize, "Check that the stream frame size == the one it was opened with",
@@ -1084,7 +1067,7 @@ TEST_IO_STREAM(GetBufferSize, "Check that the stream buffer size== the one it wa
ASSERT_GE(extract(stream->getBufferSize()), extract(stream->getFrameSize())));
template <class Property, class CapabilityGetter>
static void testCapabilityGetter(const string& name, IStream* stream,
static void testCapabilityGetter(const std::string& name, IStream* stream,
CapabilityGetter capabilityGetter,
Return<Property> (IStream::*getter)(),
Return<Result> (IStream::*setter)(Property),
@@ -1120,6 +1103,7 @@ static void testCapabilityGetter(const string& name, IStream* stream,
}
}
#if MAJOR_VERSION <= 6
TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported",
testCapabilityGetter("getSupportedSampleRate", stream.get(),
&GetSupported::sampleRates, &IStream::getSampleRate,
@@ -1137,19 +1121,71 @@ TEST_IO_STREAM(SupportedChannelMask, "Check that the stream channel mask is decl
TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported",
testCapabilityGetter("getSupportedFormat", stream.get(), &GetSupported::formats,
&IStream::getFormat, &IStream::setFormat))
#else
static void testGetSupportedProfiles(IStream* stream) {
Result res;
hidl_vec<AudioProfile> profiles;
auto ret = stream->getSupportedProfiles(returnIn(res, profiles));
EXPECT_TRUE(ret.isOk());
if (res == Result::OK) {
EXPECT_GT(profiles.size(), 0);
} else {
EXPECT_EQ(Result::NOT_SUPPORTED, res);
}
}
TEST_IO_STREAM(GetSupportedProfiles, "Try to call optional method GetSupportedProfiles",
testGetSupportedProfiles(stream.get()))
static void testSetAudioProperties(IStream* stream) {
Result res;
hidl_vec<AudioProfile> profiles;
auto ret = stream->getSupportedProfiles(returnIn(res, profiles));
EXPECT_TRUE(ret.isOk());
if (res == Result::NOT_SUPPORTED) {
GTEST_SKIP() << "Retrieving supported profiles is not implemented";
}
for (const auto& profile : profiles) {
for (const auto& sampleRate : profile.sampleRates) {
for (const auto& channelMask : profile.channelMasks) {
AudioConfigBase config{.format = profile.format,
.sampleRateHz = sampleRate,
.channelMask = channelMask};
auto ret = stream->setAudioProperties(config);
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(Result::OK, ret) << config.format << "; " << config.sampleRateHz << "; "
<< toString(config.channelMask);
}
}
}
}
TEST_IO_STREAM(SetAudioProperties, "Call setAudioProperties for all supported profiles",
testSetAudioProperties(stream.get()))
#endif
static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
#if MAJOR_VERSION <= 6
uint32_t sampleRateHz;
auto mask = mkEnumBitfield<AudioChannelMask>({});
AudioFormat format;
stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
auto ret = stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
EXPECT_TRUE(ret.isOk());
// FIXME: the qcom hal it does not currently negotiate the sampleRate &
// channel mask
EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
EXPECT_EQ(expectedConfig.channelMask, mask);
EXPECT_EQ(expectedConfig.format, format);
#elif MAJOR_VERSION >= 7
AudioConfigBase actualConfig{};
auto ret = stream->getAudioProperties(returnIn(actualConfig));
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(expectedConfig.base.sampleRateHz, actualConfig.sampleRateHz);
EXPECT_EQ(expectedConfig.base.channelMask, actualConfig.channelMask);
EXPECT_EQ(expectedConfig.base.format, actualConfig.format);
#endif
}
TEST_IO_STREAM(GetAudioProperties,
@@ -1160,7 +1196,7 @@ TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, stream->setHwAvSync(666)))
static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
initializer_list<Result> expectedResults) {
std::initializer_list<Result> expectedResults) {
hidl_vec<ParameterValue> parameters;
Result res;
ASSERT_OK(Parameters::get(stream, keys, returnIn(res, parameters)));
@@ -1271,7 +1307,11 @@ TEST_P(InputStreamTest, GetAudioSource) {
return;
}
ASSERT_OK(res);
#if MAJOR_VERSION <= 6
ASSERT_EQ(AudioSource::DEFAULT, source);
#elif MAJOR_VERSION >= 7
ASSERT_EQ(xsd::AudioSource::AUDIO_SOURCE_DEFAULT, xsd::stringToAudioSource(source));
#endif
}
static void testUnitaryGain(std::function<Return<Result>(float)> setGain) {
@@ -1286,7 +1326,7 @@ static void testUnitaryGain(std::function<Return<Result>(float)> setGain) {
}
static void testOptionalUnitaryGain(std::function<Return<Result>(float)> setGain,
string debugName) {
std::string debugName) {
auto result = setGain(1);
ASSERT_IS_OK(result);
if (result == Result::NOT_SUPPORTED) {
@@ -1306,7 +1346,7 @@ static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_
Result res;
// Ignore output parameters as the call should fail
ASSERT_OK(stream->prepareForReading(frameSize, framesCount,
[&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
[&res](auto r, auto&, auto&, auto&, auto) { res = r; }));
EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
}
@@ -1371,7 +1411,7 @@ static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32
Result res;
// Ignore output parameters as the call should fail
ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
[&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
[&res](auto r, auto&, auto&, auto&, auto) { res = r; }));
EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
}

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
#pragma once
// Code in this file uses 'getCachedPolicyConfig'
#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST
#error Must be included from AudioPrimaryHidlTest.h
@@ -46,32 +48,32 @@ struct ConfigHelper {
}
// Cache result ?
static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
static const std::vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
{8000, 11025, 16000, 22050, 32000, 44100},
{AudioFormat::PCM_16_BIT});
}
static const vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
static const std::vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
{24000, 48000}, {AudioFormat::PCM_16_BIT});
}
static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
static const std::vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
if (!primaryHasMic()) return {};
return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100},
{AudioFormat::PCM_16_BIT});
}
static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
static const std::vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
if (!primaryHasMic()) return {};
return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
{AudioFormat::PCM_16_BIT});
}
static vector<AudioConfig> combineAudioConfig(vector<audio_channel_mask_t> channelMasks,
vector<uint32_t> sampleRates,
audio_format_t format) {
vector<AudioConfig> configs;
static std::vector<AudioConfig> combineAudioConfig(
std::vector<audio_channel_mask_t> channelMasks, std::vector<uint32_t> sampleRates,
audio_format_t format) {
std::vector<AudioConfig> configs;
configs.reserve(channelMasks.size() * sampleRates.size());
for (auto channelMask : channelMasks) {
for (auto sampleRate : sampleRates) {
@@ -86,10 +88,10 @@ struct ConfigHelper {
return configs;
}
static vector<AudioConfig> combineAudioConfig(vector<AudioChannelMask> channelMasks,
vector<uint32_t> sampleRates,
vector<AudioFormat> formats) {
vector<AudioConfig> configs;
static std::vector<AudioConfig> combineAudioConfig(std::vector<AudioChannelMask> channelMasks,
std::vector<uint32_t> sampleRates,
std::vector<AudioFormat> formats) {
std::vector<AudioConfig> configs;
configs.reserve(channelMasks.size() * sampleRates.size() * formats.size());
for (auto channelMask : channelMasks) {
for (auto sampleRate : sampleRates) {

View File

@@ -14,10 +14,11 @@
* limitations under the License.
*/
// Code in this file uses 'environment'
#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST
#error Must be included from AudioPrimaryHidlTest.h
#endif
#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.
template <class Derived, class Key, class Interface>
class InterfaceManager {

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2020 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
// 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 <Serializer.h>
struct PolicyConfigData {
android::HwModuleCollection hwModules;
android::DeviceVector availableOutputDevices;
android::DeviceVector availableInputDevices;
sp<android::DeviceDescriptor> defaultOutputDevice;
};
class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig {
public:
explicit PolicyConfig(const std::string& configFileName)
: android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
defaultOutputDevice),
mConfigFileName{configFileName} {
for (const auto& location : android::audio_get_configuration_paths()) {
std::string path = location + '/' + mConfigFileName;
if (access(path.c_str(), F_OK) == 0) {
mFilePath = path;
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;
}
}
}
}
}
status_t getStatus() const { return mStatus; }
std::string getError() const {
if (mFilePath.empty()) {
return std::string{"Could not find "} + mConfigFileName +
" file in: " + testing::PrintToString(android::audio_get_configuration_paths());
} else {
return "Invalid config file: " + mFilePath;
}
}
const std::string& getFilePath() const { return mFilePath; }
sp<const android::HwModule> getModuleFromName(const std::string& name) const {
return getHwModules().getModuleFromName(name.c_str());
}
sp<const android::HwModule> getPrimaryModule() const { return mPrimaryModule; }
const std::set<std::string>& getModulesWithDevicesNames() const {
return mModulesWithDevicesNames;
}
bool haveInputProfilesInModule(const std::string& name) const {
auto module = getModuleFromName(name);
return module && !module->getInputProfiles().empty();
}
private:
const std::string mConfigFileName;
status_t mStatus = NO_INIT;
std::string mFilePath;
sp<const android::HwModule> mPrimaryModule = nullptr;
std::set<std::string> mModulesWithDevicesNames;
};

View File

@@ -118,7 +118,6 @@ cc_test {
}
cc_test {
enabled: false,
name: "VtsHalAudioEffectV7_0TargetTest",
defaults: ["VtsHalAudioEffectTargetTest_default"],
// Use test_config for vts suite.
@@ -126,6 +125,7 @@ cc_test {
test_config: "VtsHalAudioEffectV7_0TargetTest.xml",
static_libs: [
"android.hardware.audio.common@7.0",
"android.hardware.audio.common@7.0-enums",
"android.hardware.audio.effect@7.0",
],
data: [

View File

@@ -16,7 +16,9 @@
#define LOG_TAG "AudioEffectHidlHalTest"
#include <android-base/logging.h>
#if MAJOR_VERSION <= 6
#include <system/audio.h>
#endif
#include PATH(android/hardware/audio/effect/FILE_VERSION/IEffect.h)
#include PATH(android/hardware/audio/effect/FILE_VERSION/IEffectsFactory.h)
@@ -25,6 +27,10 @@
#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h)
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
#if MAJOR_VERSION >= 7
#include <audio_policy_configuration_V7_0-enums.h>
#include <audio_policy_configuration_V7_0.h>
#endif
#include <common/all-versions/VersionUtils.h>
@@ -45,6 +51,12 @@ using ::android::hidl::allocator::V1_0::IAllocator;
using ::android::hidl::memory::V1_0::IMemory;
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
#if MAJOR_VERSION >= 7
// Make an alias for enumerations generated from the APM config XSD.
namespace xsd {
using namespace ::audio::policy::configuration::CPP_VERSION;
}
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
@@ -171,7 +183,7 @@ class AudioEffectHidlTest : public ::testing::TestWithParam<EffectParameter> {
effectsFactory = IEffectsFactory::getService(std::get<PARAM_FACTORY_NAME>(GetParam()));
ASSERT_NE(nullptr, effectsFactory.get());
findAndCreateEffect(getEffectType());
ASSERT_NO_FATAL_FAILURE(findAndCreateEffect(getEffectType()));
ASSERT_NE(nullptr, effect.get());
Return<Result> ret = effect->init();
@@ -201,7 +213,7 @@ class AudioEffectHidlTest : public ::testing::TestWithParam<EffectParameter> {
void AudioEffectHidlTest::findAndCreateEffect(const Uuid& type) {
Uuid effectUuid;
findEffectInstance(type, &effectUuid);
ASSERT_NO_FATAL_FAILURE(findEffectInstance(type, &effectUuid));
Return<void> ret = effectsFactory->createEffect(
effectUuid, 1 /*session*/, 1 /*ioHandle*/,
#if MAJOR_VERSION >= 6
@@ -244,10 +256,16 @@ void AudioEffectHidlTest::getChannelCount(uint32_t* channelCount) {
});
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(Result::OK, retval);
#if MAJOR_VERSION <= 6
ASSERT_TRUE(audio_channel_mask_is_valid(
static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels)));
*channelCount = audio_channel_count_from_out_mask(
static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels));
#else
*channelCount =
audio::policy::configuration::V7_0::getChannelCount(currentConfig.outputCfg.channels);
ASSERT_NE(*channelCount, 0);
#endif
}
TEST_P(AudioEffectHidlTest, Close) {
@@ -391,7 +409,12 @@ TEST_P(AudioEffectHidlTest, DisableEnableDisable) {
TEST_P(AudioEffectHidlTest, SetDevice) {
description("Verify that SetDevice works for an output chain effect");
#if MAJOR_VERSION <= 6
Return<Result> ret = effect->setDevice(mkEnumBitfield(AudioDevice::OUT_SPEAKER));
#else
DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER)};
Return<Result> ret = effect->setDevice(device);
#endif
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(Result::OK, ret);
}
@@ -441,22 +464,28 @@ TEST_P(AudioEffectHidlTest, SetConfigReverse) {
TEST_P(AudioEffectHidlTest, SetInputDevice) {
description("Verify that SetInputDevice does not crash");
#if MAJOR_VERSION <= 6
Return<Result> ret = effect->setInputDevice(mkEnumBitfield(AudioDevice::IN_BUILTIN_MIC));
#else
DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC)};
Return<Result> ret = effect->setInputDevice(device);
#endif
EXPECT_TRUE(ret.isOk());
}
TEST_P(AudioEffectHidlTest, SetAudioSource) {
description("Verify that SetAudioSource does not crash");
#if MAJOR_VERSION <= 6
Return<Result> ret = effect->setAudioSource(AudioSource::MIC);
#else
Return<Result> ret = effect->setAudioSource(toString(xsd::AudioSource::AUDIO_SOURCE_MIC));
#endif
EXPECT_TRUE(ret.isOk());
}
TEST_P(AudioEffectHidlTest, Offload) {
description("Verify that calling Offload method does not crash");
EffectOffloadParameter offloadParam;
offloadParam.isOffload = false;
offloadParam.ioHandle = static_cast<int>(AudioHandleConsts::AUDIO_IO_HANDLE_NONE);
Return<Result> ret = effect->offload(offloadParam);
Return<Result> ret = effect->offload(EffectOffloadParameter{});
EXPECT_TRUE(ret.isOk());
}