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

Commit f9c141df authored by Mikhail Naganov's avatar Mikhail Naganov Committed by Automerger Merge Worker
Browse files

Merge changes I19a08bf2,Ibab914e5 into main am: 63f2d84e

parents 2049d48c 63f2d84e
Loading
Loading
Loading
Loading
+17 −22
Original line number Diff line number Diff line
@@ -179,7 +179,7 @@ void StreamRemoteSubmix::shutdown() {
        LOG(ERROR) << __func__ << ": transfer without a pipe!";
        return ::android::UNEXPECTED_NULL;
    }

    mCurrentRoute->exitStandby(mIsInput);
    return (mIsInput ? inRead(buffer, frameCount, actualFrameCount)
                     : outWrite(buffer, frameCount, actualFrameCount));
}
@@ -190,17 +190,14 @@ void StreamRemoteSubmix::shutdown() {
        return ::android::NO_INIT;
    }
    const ssize_t framesInPipe = source->availableToRead();
    if (framesInPipe < 0) {
        return ::android::INVALID_OPERATION;
    if (framesInPipe <= 0) {
        // No need to update the position frames
        return ::android::OK;
    }
    if (mIsInput) {
        position->frames += framesInPipe;
    } else {
        if (position->frames > framesInPipe) {
    } else if (position->frames >= framesInPipe) {
        position->frames -= framesInPipe;
        } else {
            position->frames = 0;
        }
    }
    return ::android::OK;
}
@@ -280,7 +277,6 @@ size_t StreamRemoteSubmix::getStreamPipeSizeInFrames() {
                                               size_t* actualFrameCount) {
    // about to read from audio source
    sp<MonoPipeReader> source = mCurrentRoute->getSource();
    if (source == nullptr || source->availableToRead() == 0) {
    if (source == nullptr) {
        int readErrorCount = mCurrentRoute->notifyReadError();
        if (readErrorCount < kMaxReadErrorLogs) {
@@ -290,9 +286,6 @@ size_t StreamRemoteSubmix::getStreamPipeSizeInFrames() {
        } else {
            LOG(ERROR) << __func__ << ": Read errors " << readErrorCount;
        }
        } else {
            LOG(INFO) << __func__ << ": no data to read yet, providing empty data";
        }
        const size_t delayUs = static_cast<size_t>(
                std::roundf(frameCount * MICROS_PER_SECOND / mStreamConfig.sampleRate));
        usleep(delayUs);
@@ -306,9 +299,10 @@ size_t StreamRemoteSubmix::getStreamPipeSizeInFrames() {
    const size_t delayUs = static_cast<size_t>(std::roundf(kReadAttemptSleepUs));
    char* buff = (char*)buffer;
    size_t remainingFrames = frameCount;
    int availableToRead = source->availableToRead();

    while ((remainingFrames > 0) && (attempts < kMaxReadFailureAttempts)) {
        LOG(VERBOSE) << __func__ << ": frames available to read " << source->availableToRead();
    while ((remainingFrames > 0) && (availableToRead > 0) && (attempts < kMaxReadFailureAttempts)) {
        LOG(VERBOSE) << __func__ << ": frames available to read " << availableToRead;

        ssize_t framesRead = source->read(buff, remainingFrames);

@@ -317,6 +311,7 @@ size_t StreamRemoteSubmix::getStreamPipeSizeInFrames() {
        if (framesRead > 0) {
            remainingFrames -= framesRead;
            buff += framesRead * mStreamConfig.frameSize;
            availableToRead -= framesRead;
            LOG(VERBOSE) << __func__ << ": (attempts = " << attempts << ") got " << framesRead
                         << " frames, remaining=" << remainingFrames;
        } else {
+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.