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

Commit 95f22777 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audio: Query minimum buffer size before opening streams

The proper way to obtain the minimum buffer size when
opening a stream is to retrieve it from the patch. Thus,
a patch must be established prior to opening a stream.
This step was often skipped by VTS tests, they were
providing a fixed stream buffer size which might not
work for all HAL module implementations.

Created a helper class `StreamFixture` which handles
all necessary steps for opening a stream. Overhauled
tests to use this class.

Also, remove special treatment of remote submix devices
by ModuleConfig.

Bug: 300735639
Test: atest VtsHalAudioCoreTargetTest
Change-Id: Ic51d603d2bb8ff0fd62434bd16fc02c51326fc42
parent 49bcb926
Loading
Loading
Loading
Loading
+60 −28
Original line number Diff line number Diff line
@@ -67,20 +67,7 @@ std::optional<AudioOffloadInfo> ModuleConfig::generateOffloadInfoIfNeeded(
    return {};
}

std::vector<aidl::android::media::audio::common::AudioPort>
ModuleConfig::getAudioPortsForDeviceTypes(const std::vector<AudioDeviceType>& deviceTypes,
                                          const std::string& connection) {
    return getAudioPortsForDeviceTypes(mPorts, deviceTypes, connection);
}

// static
std::vector<aidl::android::media::audio::common::AudioPort> ModuleConfig::getBuiltInMicPorts(
        const std::vector<aidl::android::media::audio::common::AudioPort>& ports) {
    return getAudioPortsForDeviceTypes(
            ports, std::vector<AudioDeviceType>{AudioDeviceType::IN_MICROPHONE,
                                                AudioDeviceType::IN_MICROPHONE_BACK});
}

std::vector<aidl::android::media::audio::common::AudioPort>
ModuleConfig::getAudioPortsForDeviceTypes(
        const std::vector<aidl::android::media::audio::common::AudioPort>& ports,
@@ -100,6 +87,14 @@ ModuleConfig::getAudioPortsForDeviceTypes(
    return result;
}

// static
std::vector<aidl::android::media::audio::common::AudioPort> ModuleConfig::getBuiltInMicPorts(
        const std::vector<aidl::android::media::audio::common::AudioPort>& ports) {
    return getAudioPortsForDeviceTypes(
            ports, std::vector<AudioDeviceType>{AudioDeviceType::IN_MICROPHONE,
                                                AudioDeviceType::IN_MICROPHONE_BACK});
}

template <typename T>
auto findById(const std::vector<T>& v, int32_t id) {
    return std::find_if(v.begin(), v.end(), [&](const auto& p) { return p.id == id; });
@@ -119,10 +114,7 @@ ModuleConfig::ModuleConfig(IModule* module) {
            } else {
                mAttachedSinkDevicePorts.insert(port.id);
            }
        } else if (devicePort.device.type.connection != AudioDeviceDescription::CONNECTION_VIRTUAL
                   // The "virtual" connection is used for remote submix which is a dynamic
                   // device but it can be connected and used w/o external hardware.
                   && port.profiles.empty()) {
        } else {
            mExternalDevicePorts.insert(port.id);
        }
    }
@@ -141,6 +133,12 @@ std::vector<AudioPort> ModuleConfig::getAttachedDevicePorts() const {
    return result;
}

std::vector<aidl::android::media::audio::common::AudioPort>
ModuleConfig::getAudioPortsForDeviceTypes(const std::vector<AudioDeviceType>& deviceTypes,
                                          const std::string& connection) const {
    return getAudioPortsForDeviceTypes(mPorts, deviceTypes, connection);
}

std::vector<AudioPort> ModuleConfig::getConnectedExternalDevicePorts() const {
    std::vector<AudioPort> result;
    std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result), [&](const auto& port) {
@@ -229,6 +227,16 @@ std::vector<AudioPort> ModuleConfig::getMmapInMixPorts(bool connectedOnly, bool
    });
}

std::vector<AudioPort> ModuleConfig::getRemoteSubmixPorts(bool isInput, bool singlePort) const {
    AudioDeviceType deviceType = isInput ? AudioDeviceType::IN_SUBMIX : AudioDeviceType::OUT_SUBMIX;
    auto ports = getAudioPortsForDeviceTypes(std::vector<AudioDeviceType>{deviceType},
                                             AudioDeviceDescription::CONNECTION_VIRTUAL);
    if (singlePort) {
        if (!ports.empty()) ports.resize(1);
    }
    return ports;
}

std::vector<AudioPort> ModuleConfig::getConnectedDevicesPortsForMixPort(
        bool isInput, const AudioPortConfig& mixPortConfig) const {
    const auto mixPortIt = findById<AudioPort>(mPorts, mixPortConfig.portId);
@@ -281,19 +289,29 @@ std::optional<AudioPort> ModuleConfig::getSourceMixPortForConnectedDevice() cons
    return {};
}

std::vector<AudioPort> ModuleConfig::getRoutableMixPortsForDevicePort(const AudioPort& port) const {
    std::set<int32_t> portIds;
    for (const auto& route : mRoutes) {
        if (port.id == route.sinkPortId) {
            portIds.insert(route.sourcePortIds.begin(), route.sourcePortIds.end());
        } else if (auto it = std::find(route.sourcePortIds.begin(), route.sourcePortIds.end(),
                                       port.id);
                   it != route.sourcePortIds.end()) {
            portIds.insert(route.sinkPortId);
std::vector<AudioPort> ModuleConfig::getRoutableDevicePortsForMixPort(const AudioPort& port,
                                                                      bool connectedOnly) const {
    std::set<int32_t> portIds = findRoutablePortIds(port.id);
    const bool isInput = port.flags.getTag() == AudioIoFlags::input;
    std::set<int32_t> devicePortIds;
    if (connectedOnly) {
        devicePortIds = isInput ? getConnectedSourceDevicePorts() : getConnectedSinkDevicePorts();
    } else {
        devicePortIds = portIds;
    }
    std::vector<AudioPort> result;
    std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result), [&](const auto& port) {
        return port.ext.getTag() == AudioPortExt::Tag::device && portIds.count(port.id) > 0 &&
               devicePortIds.count(port.id) > 0;
    });
    return result;
}

std::vector<AudioPort> ModuleConfig::getRoutableMixPortsForDevicePort(const AudioPort& port,
                                                                      bool connectedOnly) const {
    std::set<int32_t> portIds = findRoutablePortIds(port.id);
    const bool isInput = port.flags.getTag() == AudioIoFlags::input;
    return findMixPorts(isInput, false /*connectedOnly*/, false /*singlePort*/,
    return findMixPorts(isInput, connectedOnly, false /*singlePort*/,
                        [&portIds](const AudioPort& p) { return portIds.count(p.id) > 0; });
}

@@ -470,6 +488,20 @@ std::vector<AudioPort> ModuleConfig::findMixPorts(
    return result;
}

std::set<int32_t> ModuleConfig::findRoutablePortIds(int32_t portId) const {
    std::set<int32_t> portIds;
    for (const auto& route : mRoutes) {
        if (portId == route.sinkPortId) {
            portIds.insert(route.sourcePortIds.begin(), route.sourcePortIds.end());
        } else if (auto it = std::find(route.sourcePortIds.begin(), route.sourcePortIds.end(),
                                       portId);
                   it != route.sourcePortIds.end()) {
            portIds.insert(route.sinkPortId);
        }
    }
    return portIds;
}

std::vector<AudioPortConfig> ModuleConfig::generateAudioMixPortConfigs(
        const std::vector<AudioPort>& ports, bool isInput, bool singleProfile) const {
    std::vector<AudioPortConfig> result;
+11 −4
Original line number Diff line number Diff line
@@ -38,9 +38,6 @@ class ModuleConfig {
    generateOffloadInfoIfNeeded(
            const aidl::android::media::audio::common::AudioPortConfig& portConfig);

    std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes(
            const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes,
            const std::string& connection = "");
    static std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes(
            const std::vector<aidl::android::media::audio::common::AudioPort>& ports,
            const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes,
@@ -53,6 +50,9 @@ class ModuleConfig {
    std::string getError() const { return mStatus.getMessage(); }

    std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicePorts() const;
    std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes(
            const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes,
            const std::string& connection = "") const;
    std::vector<aidl::android::media::audio::common::AudioPort> getConnectedExternalDevicePorts()
            const;
    std::set<int32_t> getConnectedSinkDevicePorts() const;
@@ -85,6 +85,8 @@ class ModuleConfig {
    std::vector<aidl::android::media::audio::common::AudioPort> getMmapInMixPorts(
            bool connectedOnly /*Permanently attached and connected external devices*/,
            bool singlePort) const;
    std::vector<aidl::android::media::audio::common::AudioPort> getRemoteSubmixPorts(
            bool isInput, bool singlePort) const;

    std::vector<aidl::android::media::audio::common::AudioPort> getConnectedDevicesPortsForMixPort(
            bool isInput, const aidl::android::media::audio::common::AudioPort& mixPort) const {
@@ -103,8 +105,12 @@ class ModuleConfig {
    std::optional<aidl::android::media::audio::common::AudioPort>
    getSourceMixPortForConnectedDevice() const;

    std::vector<aidl::android::media::audio::common::AudioPort> getRoutableDevicePortsForMixPort(
            const aidl::android::media::audio::common::AudioPort& port,
            bool connectedOnly /*Permanently attached and connected external devices*/) const;
    std::vector<aidl::android::media::audio::common::AudioPort> getRoutableMixPortsForDevicePort(
            const aidl::android::media::audio::common::AudioPort& port) const;
            const aidl::android::media::audio::common::AudioPort& port,
            bool connectedOnly /*Permanently attached and connected external devices*/) const;

    std::optional<SrcSinkPair> getNonRoutableSrcSinkPair(bool isInput) const;
    std::optional<SrcSinkPair> getRoutableSrcSinkPair(bool isInput) const;
@@ -176,6 +182,7 @@ class ModuleConfig {
            bool isInput, bool connectedOnly, bool singlePort,
            const std::function<bool(const aidl::android::media::audio::common::AudioPort&)>& pred)
            const;
    std::set<int32_t> findRoutablePortIds(int32_t portId) const;
    std::vector<aidl::android::media::audio::common::AudioPortConfig> generateAudioMixPortConfigs(
            const std::vector<aidl::android::media::audio::common::AudioPort>& ports, bool isInput,
            bool singleProfile) const;
+1 −2
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@

#include <algorithm>
#include <initializer_list>
#include <iostream>

#include <android/binder_auto_utils.h>
#include <gtest/gtest.h>
+611 −345

File changed.

Preview size limit exceeded, changes collapsed.