Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e703f18 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audio VTS: Refactor test parameter generation for I/O streams

Two changes that are necessary to test offloaded output:

1. Pass all mix port flags specified in the config to HAL when
   opening an output stream. Previously the generator was
   omitting the 'NON_BLOCKING' flag, however it is necessary
   for offloaded output to work. This also now passes
   the 'GAPLESS_OFFLOAD' flag to the stream opening call site.

2. Provide the DeviceAddress of the attached source/sink
   device to tests that use mix ports. Some tests were looking
   up the device address anyway. Also, HAL implementations
   seem to prefer to have the actual output device instead
   of 'DEFAULT' when opening offload streams.

Bug: 219767875
Test: atest VtsHalAudioV7_0TargetTest
Test: atest VtsHalAudioV7_1TargetTest
Test: atest HalAudioV7_0GeneratorTest
Change-Id: I0482376ecc7d6964f45f508a80716ffab18044b4
Merged-In: I0482376ecc7d6964f45f508a80716ffab18044b4
(cherry picked from commit 713d2c55)
parent 73e015a7
Loading
Loading
Loading
Loading
+7 −43
Original line number Diff line number Diff line
@@ -517,20 +517,10 @@ class PcmOnlyConfigOutputStreamTest : public OutputStreamTest {
    }

    bool canQueryPresentationPosition() const {
        auto maybeSinkAddress =
                getCachedPolicyConfig().getSinkDeviceForMixPort(getDeviceName(), getMixPortName());
        // Returning 'true' when no sink is found so the test can fail later with a more clear
        // problem description.
        return !maybeSinkAddress.has_value() ||
               !xsd::isTelephonyDevice(maybeSinkAddress.value().deviceType);
        return !xsd::isTelephonyDevice(address.deviceType);
    }

    void createPatchIfNeeded() {
        auto maybeSinkAddress =
                getCachedPolicyConfig().getSinkDeviceForMixPort(getDeviceName(), getMixPortName());
        ASSERT_TRUE(maybeSinkAddress.has_value())
                << "No sink device found for mix port " << getMixPortName() << " (module "
                << getDeviceName() << ")";
        if (areAudioPatchesSupported()) {
            AudioPortConfig source;
            source.base.format.value(getConfig().base.format);
@@ -540,13 +530,13 @@ class PcmOnlyConfigOutputStreamTest : public OutputStreamTest {
            source.ext.mix().ioHandle = helper.getIoHandle();
            source.ext.mix().useCase.stream({});
            AudioPortConfig sink;
            sink.ext.device(maybeSinkAddress.value());
            sink.ext.device(address);
            EXPECT_OK(getDevice()->createAudioPatch(hidl_vec<AudioPortConfig>{source},
                                                    hidl_vec<AudioPortConfig>{sink},
                                                    returnIn(res, mPatchHandle)));
            mHasPatch = res == Result::OK;
        } else {
            EXPECT_OK(stream->setDevices({maybeSinkAddress.value()}));
            EXPECT_OK(stream->setDevices({address}));
        }
    }

@@ -556,10 +546,6 @@ class PcmOnlyConfigOutputStreamTest : public OutputStreamTest {
                EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
                mHasPatch = false;
            }
        } else {
            if (stream) {
                EXPECT_OK(stream->setDevices({address}));
            }
        }
    }

@@ -691,24 +677,12 @@ class PcmOnlyConfigInputStreamTest : public InputStreamTest {
        InputStreamTest::TearDown();
    }

    bool canQueryCapturePosition() const {
        auto maybeSourceAddress = getCachedPolicyConfig().getSourceDeviceForMixPort(
                getDeviceName(), getMixPortName());
        // Returning 'true' when no source is found so the test can fail later with a more clear
        // problem description.
        return !maybeSourceAddress.has_value() ||
               !xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType);
    }
    bool canQueryCapturePosition() const { return !xsd::isTelephonyDevice(address.deviceType); }

    void createPatchIfNeeded() {
        auto maybeSourceAddress = getCachedPolicyConfig().getSourceDeviceForMixPort(
                getDeviceName(), getMixPortName());
        ASSERT_TRUE(maybeSourceAddress.has_value())
                << "No source device found for mix port " << getMixPortName() << " (module "
                << getDeviceName() << ")";
        if (areAudioPatchesSupported()) {
            AudioPortConfig source;
            source.ext.device(maybeSourceAddress.value());
            source.ext.device(address);
            AudioPortConfig sink;
            sink.base.format.value(getConfig().base.format);
            sink.base.sampleRateHz.value(getConfig().base.sampleRateHz);
@@ -721,7 +695,7 @@ class PcmOnlyConfigInputStreamTest : public InputStreamTest {
                                                    returnIn(res, mPatchHandle)));
            mHasPatch = res == Result::OK;
        } else {
            EXPECT_OK(stream->setDevices({maybeSourceAddress.value()}));
            EXPECT_OK(stream->setDevices({address}));
        }
    }

@@ -731,10 +705,6 @@ class PcmOnlyConfigInputStreamTest : public InputStreamTest {
                EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
                mHasPatch = false;
            }
        } else {
            if (stream) {
                EXPECT_OK(stream->setDevices({address}));
            }
        }
    }

@@ -864,14 +834,8 @@ TEST_P(MicrophoneInfoInputStreamTest, GetActiveMicrophones) {
    }
    ASSERT_OK(res);

    auto maybeSourceAddress =
            getCachedPolicyConfig().getSourceDeviceForMixPort(getDeviceName(), getMixPortName());
    ASSERT_TRUE(maybeSourceAddress.has_value())
            << "No source device found for mix port " << getMixPortName() << " (module "
            << getDeviceName() << ")";

    for (auto microphone : microphones) {
        if (microphone.deviceAddress == maybeSourceAddress.value()) {
        if (microphone.deviceAddress == address) {
            StreamReader reader(stream.get(), stream->getBufferSize());
            ASSERT_TRUE(reader.start());
            reader.pause();  // This ensures that at least one read has happened.
+39 −32
Original line number Diff line number Diff line
@@ -57,9 +57,6 @@ static std::vector<AudioConfig> combineAudioConfig(std::vector<xsd::AudioChannel

static std::tuple<std::vector<AudioInOutFlag>, bool> generateOutFlags(
        const xsd::MixPorts::MixPort& mixPort) {
    static const std::vector<AudioInOutFlag> offloadFlags = {
            toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
            toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)};
    std::vector<AudioInOutFlag> flags;
    bool isOffload = false;
    if (mixPort.hasFlags()) {
@@ -67,15 +64,11 @@ static std::tuple<std::vector<AudioInOutFlag>, bool> generateOutFlags(
        isOffload = std::find(xsdFlags.begin(), xsdFlags.end(),
                              xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
                    xsdFlags.end();
        if (!isOffload) {
        for (auto flag : xsdFlags) {
            if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
                flags.push_back(toString(flag));
            }
        }
        } else {
            flags = offloadFlags;
        }
    }
    return {flags, isOffload};
}
@@ -100,11 +93,10 @@ std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool one
        if (!module || !module->getFirstMixPorts()) break;
        for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
            if (mixPort.getRole() != xsd::Role::source) continue;  // not an output profile
            if (getCachedPolicyConfig()
                        .getAttachedSinkDeviceForMixPort(moduleName, mixPort.getName())
                        .empty()) {
                continue;  // no attached device
            }
            const auto attachedDeviceAddress =
                    getCachedPolicyConfig().getDeviceAddressOfSinkDeviceAttachedToMixPort(
                            moduleName, mixPort.getName());
            if (!attachedDeviceAddress.has_value()) continue;
            auto [flags, isOffload] = generateOutFlags(mixPort);
            for (const auto& profile : mixPort.getProfile()) {
                if (!profile.hasFormat() || !profile.hasSamplingRates() ||
@@ -118,7 +110,8 @@ std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool one
                    if (isOffload) {
                        config.offloadInfo.info(generateOffloadInfo(config.base));
                    }
                    result.emplace_back(device, mixPort.getName(), config, flags);
                    result.emplace_back(device, mixPort.getName(), attachedDeviceAddress.value(),
                                        config, flags);
                    if (oneProfilePerDevice) break;
                }
                if (oneProfilePerDevice) break;
@@ -162,13 +155,16 @@ const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters
                            profile.getFormat(),
                            static_cast<uint32_t>(profile.getSamplingRates()[0]),
                            toString(profile.getChannelMasks()[0])};
                    DeviceAddress defaultDevice = {
                            toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT), {}};
                    {
                        AudioConfig config{.base = validBase};
                        config.base.channelMask = "random_string";
                        if (isOffload) {
                            config.offloadInfo.info(generateOffloadInfo(validBase));
                        }
                        result.emplace_back(device, mixPort.getName(), config, validFlags);
                        result.emplace_back(device, mixPort.getName(), defaultDevice, config,
                                            validFlags);
                    }
                    {
                        AudioConfig config{.base = validBase};
@@ -176,7 +172,8 @@ const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters
                        if (isOffload) {
                            config.offloadInfo.info(generateOffloadInfo(validBase));
                        }
                        result.emplace_back(device, mixPort.getName(), config, validFlags);
                        result.emplace_back(device, mixPort.getName(), defaultDevice, config,
                                            validFlags);
                    }
                    if (generateInvalidFlags) {
                        AudioConfig config{.base = validBase};
@@ -184,32 +181,37 @@ const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters
                            config.offloadInfo.info(generateOffloadInfo(validBase));
                        }
                        std::vector<AudioInOutFlag> flags = {"random_string", ""};
                        result.emplace_back(device, mixPort.getName(), config, flags);
                        result.emplace_back(device, mixPort.getName(), defaultDevice, config,
                                            flags);
                    }
                    if (isOffload) {
                        {
                            AudioConfig config{.base = validBase};
                            config.offloadInfo.info(generateOffloadInfo(validBase));
                            config.offloadInfo.info().base.channelMask = "random_string";
                            result.emplace_back(device, mixPort.getName(), config, validFlags);
                            result.emplace_back(device, mixPort.getName(), defaultDevice, config,
                                                validFlags);
                        }
                        {
                            AudioConfig config{.base = validBase};
                            config.offloadInfo.info(generateOffloadInfo(validBase));
                            config.offloadInfo.info().base.format = "random_string";
                            result.emplace_back(device, mixPort.getName(), config, validFlags);
                            result.emplace_back(device, mixPort.getName(), defaultDevice, config,
                                                validFlags);
                        }
                        {
                            AudioConfig config{.base = validBase};
                            config.offloadInfo.info(generateOffloadInfo(validBase));
                            config.offloadInfo.info().streamType = "random_string";
                            result.emplace_back(device, mixPort.getName(), config, validFlags);
                            result.emplace_back(device, mixPort.getName(), defaultDevice, config,
                                                validFlags);
                        }
                        {
                            AudioConfig config{.base = validBase};
                            config.offloadInfo.info(generateOffloadInfo(validBase));
                            config.offloadInfo.info().usage = "random_string";
                            result.emplace_back(device, mixPort.getName(), config, validFlags);
                            result.emplace_back(device, mixPort.getName(), defaultDevice, config,
                                                validFlags);
                        }
                        hasOffloadConfig = true;
                    } else {
@@ -233,11 +235,10 @@ std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneP
        if (!module || !module->getFirstMixPorts()) break;
        for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
            if (mixPort.getRole() != xsd::Role::sink) continue;  // not an input profile
            if (getCachedPolicyConfig()
                        .getAttachedSourceDeviceForMixPort(moduleName, mixPort.getName())
                        .empty()) {
                continue;  // no attached device
            }
            const auto attachedDeviceAddress =
                    getCachedPolicyConfig().getDeviceAddressOfSourceDeviceAttachedToMixPort(
                            moduleName, mixPort.getName());
            if (!attachedDeviceAddress.has_value()) continue;
            std::vector<AudioInOutFlag> flags;
            if (mixPort.hasFlags()) {
                std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
@@ -250,7 +251,8 @@ std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneP
                auto configs = combineAudioConfig(profile.getChannelMasks(),
                                                  profile.getSamplingRates(), profile.getFormat());
                for (const auto& config : configs) {
                    result.emplace_back(device, mixPort.getName(), config, flags);
                    result.emplace_back(device, mixPort.getName(), attachedDeviceAddress.value(),
                                        config, flags);
                    if (oneProfilePerDevice) break;
                }
                if (oneProfilePerDevice) break;
@@ -298,20 +300,25 @@ const std::vector<DeviceConfigParameter>& getInputDeviceInvalidConfigParameters(
                            profile.getFormat(),
                            static_cast<uint32_t>(profile.getSamplingRates()[0]),
                            toString(profile.getChannelMasks()[0])};
                    DeviceAddress defaultDevice = {
                            toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT), {}};
                    {
                        AudioConfig config{.base = validBase};
                        config.base.channelMask = "random_string";
                        result.emplace_back(device, mixPort.getName(), config, validFlags);
                        result.emplace_back(device, mixPort.getName(), defaultDevice, config,
                                            validFlags);
                    }
                    {
                        AudioConfig config{.base = validBase};
                        config.base.format = "random_string";
                        result.emplace_back(device, mixPort.getName(), config, validFlags);
                        result.emplace_back(device, mixPort.getName(), defaultDevice, config,
                                            validFlags);
                    }
                    if (generateInvalidFlags) {
                        AudioConfig config{.base = validBase};
                        std::vector<AudioInOutFlag> flags = {"random_string", ""};
                        result.emplace_back(device, mixPort.getName(), config, flags);
                        result.emplace_back(device, mixPort.getName(), defaultDevice, config,
                                            flags);
                    }
                    hasConfig = true;
                    break;
+12 −2
Original line number Diff line number Diff line
@@ -61,6 +61,18 @@ class PolicyConfig {
    const std::set<std::string>& getModulesWithDevicesNames() const {
        return mModulesWithDevicesNames;
    }
    std::optional<DeviceAddress> getDeviceAddressOfSinkDeviceAttachedToMixPort(
            const std::string& moduleName, const std::string& mixPortName) const {
        const auto attachedDevicePort = getAttachedSinkDeviceForMixPort(moduleName, mixPortName);
        if (attachedDevicePort.empty()) return {};
        return getDeviceAddressOfDevicePort(moduleName, attachedDevicePort);
    }
    std::optional<DeviceAddress> getDeviceAddressOfSourceDeviceAttachedToMixPort(
            const std::string& moduleName, const std::string& mixPortName) const {
        const auto attachedDevicePort = getAttachedSourceDeviceForMixPort(moduleName, mixPortName);
        if (attachedDevicePort.empty()) return {};
        return getDeviceAddressOfDevicePort(moduleName, attachedDevicePort);
    }
    std::string getAttachedSinkDeviceForMixPort(const std::string& moduleName,
                                                const std::string& mixPortName) const {
        return findAttachedDevice(getAttachedDevices(moduleName),
@@ -84,8 +96,6 @@ class PolicyConfig {
    const std::vector<std::string>& getAttachedDevices(const std::string& moduleName) const;
    std::optional<DeviceAddress> getDeviceAddressOfDevicePort(
            const std::string& moduleName, const std::string& devicePortName) const;
    std::string getDevicePortTagNameFromType(const std::string& moduleName,
                                             const AudioDevice& deviceType) const;
    std::set<std::string> getSinkDevicesForMixPort(const std::string& moduleName,
                                                   const std::string& mixPortName) const;
    std::set<std::string> getSourceDevicesForMixPort(const std::string& moduleName,
+8 −9
Original line number Diff line number Diff line
@@ -617,7 +617,8 @@ static std::string DeviceConfigParameterToString(
                    std::get<PARAM_FLAGS>(info.param)));
#elif MAJOR_VERSION >= 7
    const auto configPart =
            std::to_string(config.base.sampleRateHz) + "_" +
            ::testing::PrintToString(std::get<PARAM_ATTACHED_DEV_ADDR>(info.param).deviceType) +
            "_" + 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)));
@@ -658,6 +659,9 @@ class AudioHidlTestWithDeviceConfigParameter
                std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam())));
    }
#elif MAJOR_VERSION >= 7
    DeviceAddress getAttachedDeviceAddress() const {
        return std::get<PARAM_ATTACHED_DEV_ADDR>(GetParam());
    }
    hidl_vec<AudioInOutFlag> getInputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
    hidl_vec<AudioInOutFlag> getOutputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
#endif
@@ -1047,7 +1051,7 @@ class OutputStreamTest
#if MAJOR_VERSION <= 6
        address.device = AudioDevice::OUT_DEFAULT;
#elif MAJOR_VERSION >= 7
        address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT);
        address = getAttachedDeviceAddress();
#endif
        const AudioConfig& config = getConfig();
        auto flags = getOutputFlags();
@@ -1243,16 +1247,11 @@ class InputStreamTest
#if MAJOR_VERSION <= 6
        address.device = AudioDevice::IN_DEFAULT;
#elif MAJOR_VERSION >= 7
        auto maybeSourceAddress = getCachedPolicyConfig().getSourceDeviceForMixPort(
                getDeviceName(), getMixPortName());
        address = getAttachedDeviceAddress();
        auto& metadata = initMetadata.tracks[0];
        if (maybeSourceAddress.has_value() &&
            !xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType)) {
            address = maybeSourceAddress.value();
        if (!xsd::isTelephonyDevice(address.deviceType)) {
            metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_UNPROCESSED);
            metadata.channelMask = getConfig().base.channelMask;
        } else {
            address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT);
        }
#if MAJOR_VERSION == 7 && MINOR_VERSION >= 1
        auto flagsIt = std::find(flags.begin(), flags.end(),
+2 −1
Original line number Diff line number Diff line
@@ -39,9 +39,10 @@ using DeviceConfigParameter = std::tuple<
        std::variant<android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioInputFlag,
                     android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioOutputFlag>>;
#elif MAJOR_VERSION >= 7
enum { PARAM_DEVICE, PARAM_PORT_NAME, PARAM_CONFIG, PARAM_FLAGS };
enum { PARAM_DEVICE, PARAM_PORT_NAME, PARAM_ATTACHED_DEV_ADDR, PARAM_CONFIG, PARAM_FLAGS };
using DeviceConfigParameter =
        std::tuple<DeviceParameter, std::string,
                   android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::DeviceAddress,
                   android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioConfig,
                   std::vector<android::hardware::audio::CORE_TYPES_CPP_VERSION::AudioInOutFlag>>;
#endif