From d72a7c27ab130415a92ee15009990c7fc1740615 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Fri, 14 Aug 2020 00:16:09 +0000 Subject: [PATCH] audio: Implement VTS tests for V7.0 The major change in V7.0 is use of enum values defined in the Audio Policy Configuration XSD schema. This allows decoupling types used at the HIDL layer from system/audio.h. Added a header audio_policy_configuration_V7_0-enums.h with utility functions analogous to ones from system/audio.h but defined for the types generated from XSD schema. Since the code of VTS tests is shared between versions, ensured that the VTS tests for the previous HAL versions didn't regress. Bug: 142480271 Test: atest VtsHalAudioV6_0TargetTest atest VtsHalAudioEffectV6_0TargetTest atest VtsHalAudioV7_0TargetTest atest VtsHalAudioEffectV7_0TargetTest Change-Id: Ia7c2d49a02783725080c8fed6a25853e91bba487 Merged-In: Ia7c2d49a02783725080c8fed6a25853e91bba487 --- audio/common/7.0/Android.bp | 5 +- .../audio_policy_configuration_V7_0-enums.h | 207 ++++++++++++ .../4.0/AudioPrimaryHidlHalTest.cpp | 100 +++++- .../functional/4.0/AudioPrimaryHidlHalUtils.h | 4 +- .../6.0/AudioPrimaryHidlHalTest.cpp | 45 ++- .../7.0/AudioPrimaryHidlHalTest.cpp | 98 ++++++ .../vts/functional/7.0/PolicyConfig.h | 91 ++++++ .../all-versions/vts/functional/Android.bp | 17 +- .../vts/functional/AudioPrimaryHidlHalTest.h | 300 ++++++++++-------- .../vts/functional/ConfigHelper.h | 26 +- .../vts/functional/DeviceManager.h | 9 +- .../vts/functional/PolicyConfig.h | 96 ++++++ .../all-versions/vts/functional/Android.bp | 2 +- .../VtsHalAudioEffectTargetTest.cpp | 41 ++- 14 files changed, 856 insertions(+), 185 deletions(-) create mode 100644 audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h create mode 100644 audio/core/all-versions/vts/functional/7.0/PolicyConfig.h create mode 100644 audio/core/all-versions/vts/functional/PolicyConfig.h diff --git a/audio/common/7.0/Android.bp b/audio/common/7.0/Android.bp index e24871c8b5..1c016b401b 100644 --- a/audio/common/7.0/Android.bp +++ b/audio/common/7.0/Android.bp @@ -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", diff --git a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h new file mode 100644 index 0000000000..d5fedce100 --- /dev/null +++ b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h @@ -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 + +#include + +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 diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index b0eb2e0cfb..2466fd120a 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -16,6 +16,13 @@ #include "AudioPrimaryHidlHalTest.h" +#if MAJOR_VERSION >= 7 +#include +#include + +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::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 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 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 range; +#elif MAJOR_VERSION >= 7 + xsdc_enum_range 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 usageRange; hidl_enum_range contentRange; +#elif MAJOR_VERSION >= 7 + xsdc_enum_range usageRange; + xsdc_enum_range 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({})); diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h index 7a52d0e364..81a1f7b4b7 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h @@ -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& capabilities) { Result res; EXPECT_OK(stream->getSupportedFormats(returnIn(res, capabilities))); @@ -88,6 +89,7 @@ struct GetSupported { } #endif }; +#endif // MAJOR_VERSION <= 6 template auto dump(T t, hidl_handle handle) { diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp index 54d4bbd2cc..bd8de2d0e6 100644 --- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp @@ -17,6 +17,7 @@ // pull in all the <= 5.0 tests #include "5.0/AudioPrimaryHidlHalTest.cpp" +#if MAJOR_VERSION <= 6 const std::vector& getOutputDeviceConfigParameters() { static std::vector parameters = [] { std::vector result; @@ -28,8 +29,8 @@ const std::vector& getOutputDeviceConfigParameters() { const auto& channels = profile->getChannels(); const auto& sampleRates = profile->getSampleRates(); auto configs = ConfigHelper::combineAudioConfig( - vector(channels.begin(), channels.end()), - vector(sampleRates.begin(), sampleRates.end()), + std::vector(channels.begin(), channels.end()), + std::vector(sampleRates.begin(), sampleRates.end()), profile->getFormat()); auto flags = ioProfile->getFlags(); for (auto& config : configs) { @@ -46,8 +47,8 @@ const std::vector& 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& getInputDeviceConfigParameters() { const auto& channels = profile->getChannels(); const auto& sampleRates = profile->getSampleRates(); auto configs = ConfigHelper::combineAudioConfig( - vector(channels.begin(), channels.end()), - vector(sampleRates.begin(), sampleRates.end()), + std::vector(channels.begin(), channels.end()), + std::vector(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& 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::NONE); SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}}; + auto flags = hidl_bitfield(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 flags; +#endif + AudioConfig config{}; sp stream; StreamHelper 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::NONE); SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}}; + auto flags = hidl_bitfield(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 flags; +#endif + AudioConfig config{}; sp stream; StreamHelper 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(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE), - hidl_vec(), hidl_vec(), returnIn(res, ignored))); + ASSERT_OK(getDevice()->updateAudioPatch(AudioPatchHandle{}, hidl_vec(), + hidl_vec(), returnIn(res, ignored))); ASSERT_RESULT(Result::INVALID_ARGUMENTS, res); } diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp index 33efa6f4d6..63eaea8acc 100644 --- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp @@ -16,3 +16,101 @@ // pull in all the <= 6.0 tests #include "6.0/AudioPrimaryHidlHalTest.cpp" + +static std::vector combineAudioConfig(std::vector channelMasks, + std::vector sampleRates, + const std::string& format) { + std::vector 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& getOutputDeviceConfigParameters() { + static std::vector parameters = [] { + std::vector result; + const std::vector 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(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 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& getInputDeviceConfigParameters() { + static std::vector parameters = [] { + std::vector result; + for (const auto& device : getDeviceParameters()) { + auto module = + getCachedPolicyConfig().getModuleFromName(std::get(device)); + for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) { + if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile + std::vector 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; +} diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h new file mode 100644 index 0000000000..d790b34c46 --- /dev/null +++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h @@ -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& 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 mConfig; + status_t mStatus = NO_INIT; + const xsd::Module* mPrimaryModule; + std::set mModulesWithDevicesNames; +}; diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index 6ac9b20f95..c7bfe08889 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -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", diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 01bdd69408..5e4b414d29 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -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 +#include +#endif -#include #include #include #include @@ -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 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 getModuleFromName(const std::string& name) const { - return getHwModules().getModuleFromName(name.c_str()); - } - sp getPrimaryModule() const { return mPrimaryModule; } - const std::set& getModulesWithDevicesNames() const { - return mModulesWithDevicesNames; - } - - private: - status_t mStatus = NO_INIT; - std::string mFilePath; - sp mPrimaryModule = nullptr; - std::set 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 = [] { - auto config = std::make_unique(); + auto config = std::make_unique(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 - void testAccessors(IUTGetter iutGetter, const string& propertyName, - const Initial expectedInitial, list valuesToTest, Setter setter, - Getter getter, const vector& invalidValues = {}) { + void testAccessors(IUTGetter iutGetter, const std::string& propertyName, + const Initial expectedInitial, std::list valuesToTest, + Setter setter, Getter getter, + const std::vector& 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 - void testAccessors(const string& propertyName, const Initial expectedInitial, - list valuesToTest, Setter setter, Getter getter, - const vector& invalidValues = {}) { + void testAccessors(const std::string& propertyName, const Initial expectedInitial, + std::list valuesToTest, Setter setter, Getter getter, + const std::vector& invalidValues = {}) { testAccessors(&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>; +#elif MAJOR_VERSION >= 7 +using DeviceConfigParameter = std::tuple>; +#endif #if MAJOR_VERSION >= 6 const std::vector& getInputDeviceConfigParameters(); @@ -583,8 +526,8 @@ const std::vector& 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& info) { const AudioConfig& config = std::get(info.param); const auto deviceName = DeviceParameterToString(::testing::TestParamInfo{ std::get(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(info.param)); -#elif MAJOR_VERSION >= 4 - SanitizeStringForGTestName(std::visit( - [](auto&& arg) -> std::string { - using T = std::decay_t; - // Need to use FQN of toString to avoid confusing the compiler - return ::android::hardware::audio::common::CPP_VERSION::toString( - hidl_bitfield(arg)); - }, - std::get(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(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; + // Need to use FQN of toString to avoid confusing the compiler + return ::android::hardware::audio::common::CPP_VERSION::toString( + hidl_bitfield(arg)); + }, + std::get(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(info.param))); #endif + return devicePart + "__" + configPart; } class AudioHidlTestWithDeviceConfigParameter @@ -660,7 +617,7 @@ class AudioHidlTestWithDeviceConfigParameter AudioOutputFlag getOutputFlags() const { return std::get(std::get(GetParam())); } -#elif MAJOR_VERSION >= 4 +#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 hidl_bitfield getInputFlags() const { return hidl_bitfield( std::get(std::get(GetParam()))); @@ -669,10 +626,17 @@ class AudioHidlTestWithDeviceConfigParameter return hidl_bitfield( std::get(std::get(GetParam()))); } +#elif MAJOR_VERSION >= 7 + hidl_vec getInputFlags() const { return std::get(GetParam()); } + hidl_vec getOutputFlags() const { return std::get(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 { 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 { }, 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 { 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 { 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 -static void testCapabilityGetter(const string& name, IStream* stream, +static void testCapabilityGetter(const std::string& name, IStream* stream, CapabilityGetter capabilityGetter, Return (IStream::*getter)(), Return (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 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 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({}); 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 keys, - initializer_list expectedResults) { + std::initializer_list expectedResults) { hidl_vec 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(float)> setGain) { @@ -1286,7 +1326,7 @@ static void testUnitaryGain(std::function(float)> setGain) { } static void testOptionalUnitaryGain(std::function(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); } diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h index 8ef2b436bb..1a1dbea939 100644 --- a/audio/core/all-versions/vts/functional/ConfigHelper.h +++ b/audio/core/all-versions/vts/functional/ConfigHelper.h @@ -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 getRequiredSupportPlaybackAudioConfig() { + static const std::vector getRequiredSupportPlaybackAudioConfig() { return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO}, {8000, 11025, 16000, 22050, 32000, 44100}, {AudioFormat::PCM_16_BIT}); } - static const vector getRecommendedSupportPlaybackAudioConfig() { + static const std::vector getRecommendedSupportPlaybackAudioConfig() { return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO}, {24000, 48000}, {AudioFormat::PCM_16_BIT}); } - static const vector getRequiredSupportCaptureAudioConfig() { + static const std::vector getRequiredSupportCaptureAudioConfig() { if (!primaryHasMic()) return {}; return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100}, {AudioFormat::PCM_16_BIT}); } - static const vector getRecommendedSupportCaptureAudioConfig() { + static const std::vector getRecommendedSupportCaptureAudioConfig() { if (!primaryHasMic()) return {}; return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000}, {AudioFormat::PCM_16_BIT}); } - static vector combineAudioConfig(vector channelMasks, - vector sampleRates, - audio_format_t format) { - vector configs; + static std::vector combineAudioConfig( + std::vector channelMasks, std::vector sampleRates, + audio_format_t format) { + std::vector 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 combineAudioConfig(vector channelMasks, - vector sampleRates, - vector formats) { - vector configs; + static std::vector combineAudioConfig(std::vector channelMasks, + std::vector sampleRates, + std::vector formats) { + std::vector configs; configs.reserve(channelMasks.size() * sampleRates.size() * formats.size()); for (auto channelMask : channelMasks) { for (auto sampleRate : sampleRates) { diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h index 0c0727f283..6efed7991e 100644 --- a/audio/core/all-versions/vts/functional/DeviceManager.h +++ b/audio/core/all-versions/vts/functional/DeviceManager.h @@ -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 InterfaceManager { diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h new file mode 100644 index 0000000000..c9e0c0dd5a --- /dev/null +++ b/audio/core/all-versions/vts/functional/PolicyConfig.h @@ -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 + +struct PolicyConfigData { + android::HwModuleCollection hwModules; + android::DeviceVector availableOutputDevices; + android::DeviceVector availableInputDevices; + sp 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 getModuleFromName(const std::string& name) const { + return getHwModules().getModuleFromName(name.c_str()); + } + sp getPrimaryModule() const { return mPrimaryModule; } + const std::set& 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 mPrimaryModule = nullptr; + std::set mModulesWithDevicesNames; +}; diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp index 7cdb18f95f..f4a72834d5 100644 --- a/audio/effect/all-versions/vts/functional/Android.bp +++ b/audio/effect/all-versions/vts/functional/Android.bp @@ -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: [ diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp index 4787c091b2..b64f105eb4 100644 --- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp +++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp @@ -16,7 +16,9 @@ #define LOG_TAG "AudioEffectHidlHalTest" #include +#if MAJOR_VERSION <= 6 #include +#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 #include +#if MAJOR_VERSION >= 7 +#include +#include +#endif #include @@ -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 { effectsFactory = IEffectsFactory::getService(std::get(GetParam())); ASSERT_NE(nullptr, effectsFactory.get()); - findAndCreateEffect(getEffectType()); + ASSERT_NO_FATAL_FAILURE(findAndCreateEffect(getEffectType())); ASSERT_NE(nullptr, effect.get()); Return ret = effect->init(); @@ -201,7 +213,7 @@ class AudioEffectHidlTest : public ::testing::TestWithParam { void AudioEffectHidlTest::findAndCreateEffect(const Uuid& type) { Uuid effectUuid; - findEffectInstance(type, &effectUuid); + ASSERT_NO_FATAL_FAILURE(findEffectInstance(type, &effectUuid)); Return 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(currentConfig.outputCfg.channels))); *channelCount = audio_channel_count_from_out_mask( static_cast(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 ret = effect->setDevice(mkEnumBitfield(AudioDevice::OUT_SPEAKER)); +#else + DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER)}; + Return 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 ret = effect->setInputDevice(mkEnumBitfield(AudioDevice::IN_BUILTIN_MIC)); +#else + DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC)}; + Return 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 ret = effect->setAudioSource(AudioSource::MIC); +#else + Return 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(AudioHandleConsts::AUDIO_IO_HANDLE_NONE); - Return ret = effect->offload(offloadParam); + Return ret = effect->offload(EffectOffloadParameter{}); EXPECT_TRUE(ret.isOk()); }