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

Commit a39e854e authored by Mikhail Naganov's avatar Mikhail Naganov Committed by Gerrit Code Review
Browse files

Merge "audio: Fix handling of external devices disconnection" into main

parents 02b33df6 0e128dd3
Loading
Loading
Loading
Loading
+25 −6
Original line number Diff line number Diff line
@@ -517,7 +517,7 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA

    connectedPort.id = ++getConfig().nextPortId;
    auto [connectedPortsIt, _] =
            mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::vector<int32_t>()));
            mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::set<int32_t>()));
    LOG(DEBUG) << __func__ << ": template port " << templateId << " external device connected, "
               << "connected port ID " << connectedPort.id;
    ports.push_back(connectedPort);
@@ -550,9 +550,21 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA
    // of all profiles from all routable dynamic device ports would be more involved.
    for (const auto mixPortId : routablePortIds) {
        auto portsIt = findById<AudioPort>(ports, mixPortId);
        if (portsIt != ports.end() && portsIt->profiles.empty()) {
        if (portsIt != ports.end()) {
            if (portsIt->profiles.empty()) {
                portsIt->profiles = connectedPort.profiles;
            connectedPortsIt->second.push_back(portsIt->id);
                connectedPortsIt->second.insert(portsIt->id);
            } else {
                // Check if profiles are non empty because they were populated by
                // a previous connection. Otherwise, it means that they are not empty because
                // the mix port has static profiles.
                for (const auto cp : mConnectedDevicePorts) {
                    if (cp.second.count(portsIt->id) > 0) {
                        connectedPortsIt->second.insert(portsIt->id);
                        break;
                    }
                }
            }
        }
    }
    *_aidl_return = std::move(connectedPort);
@@ -607,13 +619,20 @@ ndk::ScopedAStatus Module::disconnectExternalDevice(int32_t in_portId) {
        }
    }

    for (const auto mixPortId : connectedPortsIt->second) {
    // Clear profiles for mix ports that are not connected to any other ports.
    std::set<int32_t> mixPortsToClear = std::move(connectedPortsIt->second);
    mConnectedDevicePorts.erase(connectedPortsIt);
    for (const auto& connectedPort : mConnectedDevicePorts) {
        for (int32_t mixPortId : connectedPort.second) {
            mixPortsToClear.erase(mixPortId);
        }
    }
    for (int32_t mixPortId : mixPortsToClear) {
        auto mixPortIt = findById<AudioPort>(ports, mixPortId);
        if (mixPortIt != ports.end()) {
            mixPortIt->profiles = {};
        }
    }
    mConnectedDevicePorts.erase(connectedPortsIt);

    return ndk::ScopedAStatus::ok();
}
+1 −1
Original line number Diff line number Diff line
@@ -142,7 +142,7 @@ class Module : public BnModule {
    // ids of device ports created at runtime via 'connectExternalDevice'.
    // Also stores a list of ids of mix ports with dynamic profiles that were populated from
    // the connected port. This list can be empty, thus an int->int multimap can't be used.
    using ConnectedDevicePorts = std::map<int32_t, std::vector<int32_t>>;
    using ConnectedDevicePorts = std::map<int32_t, std::set<int32_t>>;
    // Maps port ids and port config ids to patch ids.
    // Multimap because both ports and configs can be used by multiple patches.
    using Patches = std::multimap<int32_t, int32_t>;
+4 −1
Original line number Diff line number Diff line
@@ -26,7 +26,10 @@ cc_defaults {
        "libaudioaidlcommon",
        "libaidlcommonsupport",
    ],
    header_libs: ["libaudioaidl_headers"],
    header_libs: [
        "libaudioaidl_headers",
        "libexpectedutils_headers",
    ],
    cflags: [
        "-Wall",
        "-Wextra",
+11 −18
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <aidl/android/media/audio/common/AudioInputFlags.h>
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
#include <error/expected_utils.h>

#include "ModuleConfig.h"

@@ -499,18 +500,13 @@ 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;
ndk::ScopedAStatus ModuleConfig::onExternalDeviceConnected(IModule* module, const AudioPort& port) {
    RETURN_STATUS_IF_ERROR(module->getAudioPorts(&mPorts));
    RETURN_STATUS_IF_ERROR(module->getAudioRoutes(&mRoutes));

    // 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;
        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
    }

    if (port.flags.getTag() == aidl::android::media::audio::common::AudioIoFlags::Tag::input) {
@@ -518,23 +514,20 @@ const ndk::ScopedAStatus& ModuleConfig::onExternalDeviceConnected(IModule* modul
    } else {
        mConnectedExternalSinkDevicePorts.insert(port.id);
    }
    return mStatus;
    return ndk::ScopedAStatus::ok();
}

const ndk::ScopedAStatus& ModuleConfig::onExternalDeviceDisconnected(IModule* module,
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;
    RETURN_STATUS_IF_ERROR(module->getAudioPorts(&mPorts));
    RETURN_STATUS_IF_ERROR(module->getAudioRoutes(&mRoutes));

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

bool ModuleConfig::isMmapSupported() const {
+2 −2
Original line number Diff line number Diff line
@@ -157,10 +157,10 @@ class ModuleConfig {
        return *config.begin();
    }

    const ndk::ScopedAStatus& onExternalDeviceConnected(
    ndk::ScopedAStatus onExternalDeviceConnected(
            aidl::android::hardware::audio::core::IModule* module,
            const aidl::android::media::audio::common::AudioPort& port);
    const ndk::ScopedAStatus& onExternalDeviceDisconnected(
    ndk::ScopedAStatus onExternalDeviceDisconnected(
            aidl::android::hardware::audio::core::IModule* module,
            const aidl::android::media::audio::common::AudioPort& port);

Loading