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

Commit 343db5e8 authored by Shraddha Basantwani's avatar Shraddha Basantwani
Browse files

Audio : Add 3 VTS test cases for remote submix module

1. OutputDoesNotBlockWhenNoInput
2. OutputDoesNotBlockWhenInputStuck
3. OutputAndInput

Bug: 286914845
Test: atest AudioModuleRemoteSubmix

Change-Id: I19a08bf2bf39131a70a867280c758b5ef001c024
parent 95f92329
Loading
Loading
Loading
Loading
+132 −38
Original line number Diff line number Diff line
@@ -66,15 +66,36 @@ 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,
        const std::vector<AudioDeviceType>& deviceTypes, const std::string& connection) {
    std::vector<AudioPort> result;
    std::copy_if(ports.begin(), ports.end(), std::back_inserter(result), [](const auto& port) {
        const auto type = port.ext.template get<AudioPortExt::Tag::device>().device.type;
        return type.connection.empty() && (type.type == AudioDeviceType::IN_MICROPHONE ||
                                           type.type == AudioDeviceType::IN_MICROPHONE_BACK);
    });
    for (const auto& port : ports) {
        if (port.ext.getTag() != AudioPortExt::Tag::device) continue;
        const auto type = port.ext.get<AudioPortExt::Tag::device>().device.type;
        if (type.connection == connection) {
            for (auto deviceType : deviceTypes) {
                if (type.type == deviceType) {
                    result.push_back(port);
                }
            }
        }
    }
    return result;
}

@@ -119,6 +140,31 @@ std::vector<AudioPort> ModuleConfig::getAttachedDevicePorts() const {
    return result;
}

std::vector<AudioPort> ModuleConfig::getConnectedExternalDevicePorts() const {
    std::vector<AudioPort> result;
    std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result), [&](const auto& port) {
        return mConnectedExternalSinkDevicePorts.count(port.id) != 0 ||
               mConnectedExternalSourceDevicePorts.count(port.id) != 0;
    });
    return result;
}

std::set<int32_t> ModuleConfig::getConnectedSinkDevicePorts() const {
    std::set<int32_t> result;
    result.insert(mAttachedSinkDevicePorts.begin(), mAttachedSinkDevicePorts.end());
    result.insert(mConnectedExternalSinkDevicePorts.begin(),
                  mConnectedExternalSinkDevicePorts.end());
    return result;
}

std::set<int32_t> ModuleConfig::getConnectedSourceDevicePorts() const {
    std::set<int32_t> result;
    result.insert(mAttachedSourceDevicePorts.begin(), mAttachedSourceDevicePorts.end());
    result.insert(mConnectedExternalSourceDevicePorts.begin(),
                  mConnectedExternalSourceDevicePorts.end());
    return result;
}

std::vector<AudioPort> ModuleConfig::getExternalDevicePorts() const {
    std::vector<AudioPort> result;
    std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result),
@@ -126,76 +172,77 @@ std::vector<AudioPort> ModuleConfig::getExternalDevicePorts() const {
    return result;
}

std::vector<AudioPort> ModuleConfig::getInputMixPorts(bool attachedOnly) const {
std::vector<AudioPort> ModuleConfig::getInputMixPorts(bool connectedOnly) const {
    std::vector<AudioPort> result;
    std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result), [&](const auto& port) {
        return port.ext.getTag() == AudioPortExt::Tag::mix &&
               port.flags.getTag() == AudioIoFlags::Tag::input &&
               (!attachedOnly || !getAttachedSourceDevicesPortsForMixPort(port).empty());
               (!connectedOnly || !getConnectedSourceDevicesPortsForMixPort(port).empty());
    });
    return result;
}

std::vector<AudioPort> ModuleConfig::getOutputMixPorts(bool attachedOnly) const {
std::vector<AudioPort> ModuleConfig::getOutputMixPorts(bool connectedOnly) const {
    std::vector<AudioPort> result;
    std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result), [&](const auto& port) {
        return port.ext.getTag() == AudioPortExt::Tag::mix &&
               port.flags.getTag() == AudioIoFlags::Tag::output &&
               (!attachedOnly || !getAttachedSinkDevicesPortsForMixPort(port).empty());
               (!connectedOnly || !getConnectedSinkDevicesPortsForMixPort(port).empty());
    });
    return result;
}

std::vector<AudioPort> ModuleConfig::getNonBlockingMixPorts(bool attachedOnly,
std::vector<AudioPort> ModuleConfig::getNonBlockingMixPorts(bool connectedOnly,
                                                            bool singlePort) const {
    return findMixPorts(false /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
    return findMixPorts(false /*isInput*/, connectedOnly, singlePort, [&](const AudioPort& port) {
        return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
                                    AudioOutputFlags::NON_BLOCKING);
    });
}

std::vector<AudioPort> ModuleConfig::getOffloadMixPorts(bool attachedOnly, bool singlePort) const {
    return findMixPorts(false /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
std::vector<AudioPort> ModuleConfig::getOffloadMixPorts(bool connectedOnly, bool singlePort) const {
    return findMixPorts(false /*isInput*/, connectedOnly, singlePort, [&](const AudioPort& port) {
        return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
                                    AudioOutputFlags::COMPRESS_OFFLOAD);
    });
}

std::vector<AudioPort> ModuleConfig::getPrimaryMixPorts(bool attachedOnly, bool singlePort) const {
    return findMixPorts(false /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
std::vector<AudioPort> ModuleConfig::getPrimaryMixPorts(bool connectedOnly, bool singlePort) const {
    return findMixPorts(false /*isInput*/, connectedOnly, singlePort, [&](const AudioPort& port) {
        return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
                                    AudioOutputFlags::PRIMARY);
    });
}

std::vector<AudioPort> ModuleConfig::getMmapOutMixPorts(bool attachedOnly, bool singlePort) const {
    return findMixPorts(false /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
std::vector<AudioPort> ModuleConfig::getMmapOutMixPorts(bool connectedOnly, bool singlePort) const {
    return findMixPorts(false /*isInput*/, connectedOnly, singlePort, [&](const AudioPort& port) {
        return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
                                    AudioOutputFlags::MMAP_NOIRQ);
    });
}

std::vector<AudioPort> ModuleConfig::getMmapInMixPorts(bool attachedOnly, bool singlePort) const {
    return findMixPorts(true /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
std::vector<AudioPort> ModuleConfig::getMmapInMixPorts(bool connectedOnly, bool singlePort) const {
    return findMixPorts(true /*isInput*/, connectedOnly, singlePort, [&](const AudioPort& port) {
        return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::input>(),
                                    AudioInputFlags::MMAP_NOIRQ);
    });
}

std::vector<AudioPort> ModuleConfig::getAttachedDevicesPortsForMixPort(
std::vector<AudioPort> ModuleConfig::getConnectedDevicesPortsForMixPort(
        bool isInput, const AudioPortConfig& mixPortConfig) const {
    const auto mixPortIt = findById<AudioPort>(mPorts, mixPortConfig.portId);
    if (mixPortIt != mPorts.end()) {
        return getAttachedDevicesPortsForMixPort(isInput, *mixPortIt);
        return getConnectedDevicesPortsForMixPort(isInput, *mixPortIt);
    }
    return {};
}

std::vector<AudioPort> ModuleConfig::getAttachedSinkDevicesPortsForMixPort(
std::vector<AudioPort> ModuleConfig::getConnectedSinkDevicesPortsForMixPort(
        const AudioPort& mixPort) const {
    std::vector<AudioPort> result;
    std::set<int32_t> connectedSinkDevicePorts = getConnectedSinkDevicePorts();
    for (const auto& route : mRoutes) {
        if (mAttachedSinkDevicePorts.count(route.sinkPortId) != 0 &&
        if ((connectedSinkDevicePorts.count(route.sinkPortId) != 0) &&
            std::find(route.sourcePortIds.begin(), route.sourcePortIds.end(), mixPort.id) !=
                    route.sourcePortIds.end()) {
            const auto devicePortIt = findById<AudioPort>(mPorts, route.sinkPortId);
@@ -205,13 +252,14 @@ std::vector<AudioPort> ModuleConfig::getAttachedSinkDevicesPortsForMixPort(
    return result;
}

std::vector<AudioPort> ModuleConfig::getAttachedSourceDevicesPortsForMixPort(
std::vector<AudioPort> ModuleConfig::getConnectedSourceDevicesPortsForMixPort(
        const AudioPort& mixPort) const {
    std::vector<AudioPort> result;
    std::set<int32_t> connectedSourceDevicePorts = getConnectedSourceDevicePorts();
    for (const auto& route : mRoutes) {
        if (route.sinkPortId == mixPort.id) {
            for (const auto srcId : route.sourcePortIds) {
                if (mAttachedSourceDevicePorts.count(srcId) != 0) {
                if (connectedSourceDevicePorts.count(srcId) != 0) {
                    const auto devicePortIt = findById<AudioPort>(mPorts, srcId);
                    if (devicePortIt != mPorts.end()) result.push_back(*devicePortIt);
                }
@@ -221,9 +269,10 @@ std::vector<AudioPort> ModuleConfig::getAttachedSourceDevicesPortsForMixPort(
    return result;
}

std::optional<AudioPort> ModuleConfig::getSourceMixPortForAttachedDevice() const {
std::optional<AudioPort> ModuleConfig::getSourceMixPortForConnectedDevice() const {
    std::set<int32_t> connectedSinkDevicePorts = getConnectedSinkDevicePorts();
    for (const auto& route : mRoutes) {
        if (mAttachedSinkDevicePorts.count(route.sinkPortId) != 0) {
        if (connectedSinkDevicePorts.count(route.sinkPortId) != 0) {
            const auto mixPortIt = findById<AudioPort>(mPorts, route.sourcePortIds[0]);
            if (mixPortIt != mPorts.end()) return *mixPortIt;
        }
@@ -233,7 +282,7 @@ std::optional<AudioPort> ModuleConfig::getSourceMixPortForAttachedDevice() const

std::optional<ModuleConfig::SrcSinkPair> ModuleConfig::getNonRoutableSrcSinkPair(
        bool isInput) const {
    const auto mixPorts = getMixPorts(isInput, false /*attachedOnly*/);
    const auto mixPorts = getMixPorts(isInput, false /*connectedOnly*/);
    std::set<std::pair<int32_t, int32_t>> allowedRoutes;
    for (const auto& route : mRoutes) {
        for (const auto srcPortId : route.sourcePortIds) {
@@ -243,7 +292,8 @@ std::optional<ModuleConfig::SrcSinkPair> ModuleConfig::getNonRoutableSrcSinkPair
    auto make_pair = [isInput](auto& device, auto& mix) {
        return isInput ? std::make_pair(device, mix) : std::make_pair(mix, device);
    };
    for (const auto portId : isInput ? mAttachedSourceDevicePorts : mAttachedSinkDevicePorts) {
    for (const auto portId :
         isInput ? getConnectedSourceDevicePorts() : getConnectedSinkDevicePorts()) {
        const auto devicePortIt = findById<AudioPort>(mPorts, portId);
        if (devicePortIt == mPorts.end()) continue;
        auto devicePortConfig = getSingleConfigForDevicePort(*devicePortIt);
@@ -262,10 +312,11 @@ std::optional<ModuleConfig::SrcSinkPair> ModuleConfig::getNonRoutableSrcSinkPair

std::optional<ModuleConfig::SrcSinkPair> ModuleConfig::getRoutableSrcSinkPair(bool isInput) const {
    if (isInput) {
        std::set<int32_t> connectedSourceDevicePorts = getConnectedSourceDevicePorts();
        for (const auto& route : mRoutes) {
            auto srcPortIdIt = std::find_if(
                    route.sourcePortIds.begin(), route.sourcePortIds.end(),
                    [&](const auto& portId) { return mAttachedSourceDevicePorts.count(portId); });
                    [&](const auto& portId) { return connectedSourceDevicePorts.count(portId); });
            if (srcPortIdIt == route.sourcePortIds.end()) continue;
            const auto devicePortIt = findById<AudioPort>(mPorts, *srcPortIdIt);
            const auto mixPortIt = findById<AudioPort>(mPorts, route.sinkPortId);
@@ -276,8 +327,9 @@ std::optional<ModuleConfig::SrcSinkPair> ModuleConfig::getRoutableSrcSinkPair(bo
            return std::make_pair(devicePortConfig, mixPortConfig.value());
        }
    } else {
        std::set<int32_t> connectedSinkDevicePorts = getConnectedSinkDevicePorts();
        for (const auto& route : mRoutes) {
            if (mAttachedSinkDevicePorts.count(route.sinkPortId) == 0) continue;
            if (connectedSinkDevicePorts.count(route.sinkPortId) == 0) continue;
            const auto mixPortIt = findById<AudioPort>(mPorts, route.sourcePortIds[0]);
            const auto devicePortIt = findById<AudioPort>(mPorts, route.sinkPortId);
            if (devicePortIt == mPorts.end() || mixPortIt == mPorts.end()) continue;
@@ -293,11 +345,12 @@ std::optional<ModuleConfig::SrcSinkPair> ModuleConfig::getRoutableSrcSinkPair(bo
std::vector<ModuleConfig::SrcSinkGroup> ModuleConfig::getRoutableSrcSinkGroups(bool isInput) const {
    std::vector<SrcSinkGroup> result;
    if (isInput) {
        std::set<int32_t> connectedSourceDevicePorts = getConnectedSourceDevicePorts();
        for (const auto& route : mRoutes) {
            std::vector<int32_t> srcPortIds;
            std::copy_if(route.sourcePortIds.begin(), route.sourcePortIds.end(),
                         std::back_inserter(srcPortIds), [&](const auto& portId) {
                             return mAttachedSourceDevicePorts.count(portId);
                             return connectedSourceDevicePorts.count(portId);
                         });
            if (srcPortIds.empty()) continue;
            const auto mixPortIt = findById<AudioPort>(mPorts, route.sinkPortId);
@@ -317,8 +370,9 @@ std::vector<ModuleConfig::SrcSinkGroup> ModuleConfig::getRoutableSrcSinkGroups(b
            }
        }
    } else {
        std::set<int32_t> connectedSinkDevicePorts = getConnectedSinkDevicePorts();
        for (const auto& route : mRoutes) {
            if (mAttachedSinkDevicePorts.count(route.sinkPortId) == 0) continue;
            if (connectedSinkDevicePorts.count(route.sinkPortId) == 0) continue;
            const auto devicePortIt = findById<AudioPort>(mPorts, route.sinkPortId);
            if (devicePortIt == mPorts.end()) continue;
            auto devicePortConfig = getSingleConfigForDevicePort(*devicePortIt);
@@ -352,6 +406,8 @@ std::string ModuleConfig::toString() const {
    result.append(android::internal::ToString(mAttachedSourceDevicePorts));
    result.append("\nExternal device ports: ");
    result.append(android::internal::ToString(mExternalDevicePorts));
    result.append("\nConnected external device ports: ");
    result.append(android::internal::ToString(getConnectedExternalDevicePorts()));
    result.append("\nRoutes: ");
    result.append(android::internal::ToString(mRoutes));
    return result;
@@ -384,10 +440,10 @@ static bool isDynamicProfile(const AudioProfile& profile) {
}

std::vector<AudioPort> ModuleConfig::findMixPorts(
        bool isInput, bool attachedOnly, bool singlePort,
        bool isInput, bool connectedOnly, bool singlePort,
        const std::function<bool(const AudioPort&)>& pred) const {
    std::vector<AudioPort> result;
    const auto mixPorts = getMixPorts(isInput, attachedOnly);
    const auto mixPorts = getMixPorts(isInput, connectedOnly);
    for (auto mixPortIt = mixPorts.begin(); mixPortIt != mixPorts.end();) {
        mixPortIt = std::find_if(mixPortIt, mixPorts.end(), pred);
        if (mixPortIt == mixPorts.end()) break;
@@ -401,7 +457,7 @@ std::vector<AudioPortConfig> ModuleConfig::generateAudioMixPortConfigs(
        const std::vector<AudioPort>& ports, bool isInput, bool singleProfile) const {
    std::vector<AudioPortConfig> result;
    for (const auto& mixPort : ports) {
        if (getAttachedDevicesPortsForMixPort(isInput, mixPort).empty()) {
        if (getConnectedDevicesPortsForMixPort(isInput, mixPort).empty()) {
            continue;
        }
        for (const auto& profile : mixPort.profiles) {
@@ -443,10 +499,48 @@ std::vector<AudioPortConfig> ModuleConfig::generateAudioDevicePortConfigs(
    return result;
}

const ndk::ScopedAStatus& ModuleConfig::onExternalDeviceConnected(IModule* module,
                                                                  const AudioPort& port) {
    // Update ports and routes
    mStatus = module->getAudioPorts(&mPorts);
    if (!mStatus.isOk()) return mStatus;
    mStatus = module->getAudioRoutes(&mRoutes);
    if (!mStatus.isOk()) return mStatus;

    // Validate port is present in module
    if (std::find(mPorts.begin(), mPorts.end(), port) == mPorts.end()) {
        mStatus = ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
        return mStatus;
    }

    if (port.flags.getTag() == aidl::android::media::audio::common::AudioIoFlags::Tag::input) {
        mConnectedExternalSourceDevicePorts.insert(port.id);
    } else {
        mConnectedExternalSinkDevicePorts.insert(port.id);
    }
    return mStatus;
}

const ndk::ScopedAStatus& ModuleConfig::onExternalDeviceDisconnected(IModule* module,
                                                                     const AudioPort& port) {
    // Update ports and routes
    mStatus = module->getAudioPorts(&mPorts);
    if (!mStatus.isOk()) return mStatus;
    mStatus = module->getAudioRoutes(&mRoutes);
    if (!mStatus.isOk()) return mStatus;

    if (port.flags.getTag() == aidl::android::media::audio::common::AudioIoFlags::Tag::input) {
        mConnectedExternalSourceDevicePorts.erase(port.id);
    } else {
        mConnectedExternalSinkDevicePorts.erase(port.id);
    }
    return mStatus;
}

bool ModuleConfig::isMmapSupported() const {
    const std::vector<AudioPort> mmapOutMixPorts =
            getMmapOutMixPorts(false /*attachedOnly*/, false /*singlePort*/);
            getMmapOutMixPorts(false /*connectedOnly*/, false /*singlePort*/);
    const std::vector<AudioPort> mmapInMixPorts =
            getMmapInMixPorts(false /*attachedOnly*/, false /*singlePort*/);
            getMmapInMixPorts(false /*connectedOnly*/, false /*singlePort*/);
    return !mmapOutMixPorts.empty() || !mmapInMixPorts.empty();
}
+49 −22

File changed.

Preview size limit exceeded, changes collapsed.

+202 −27

File changed.

Preview size limit exceeded, changes collapsed.