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

Commit 15520da1 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

libaudiohal@aidl: Fix setDevicePortConnectedState

`setDevicePortConnectedState` stores iterators on `mPorts`
and then calls `resetUnusedPortConfigs` which can also
invalidate `mPorts`. This becomes more obvious after
renaming `resetUnusedPortConfigs` to `resetUnusedPortConfigsAndPorts`.
This call needs to be moved to the beginning of
`setDevicePortConnectedState` so that iterators on `mPorts`
remain valid.

Bug: 320628427
Test: atest audiosystem_tests audiorouting_tests
Change-Id: Ia187798a815305434c82b1a3e5c54cd81cfbb8c0
parent d85f7841
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -974,7 +974,7 @@ status_t DeviceHalAidl::setSimulateDeviceConnections(bool enabled) {
    if (mModule == nullptr) return NO_INIT;
    {
        std::lock_guard l(mLock);
        mMapper.resetUnusedPatchesAndPortConfigs();
        mMapper.resetUnusedPatchesPortConfigsAndPorts();
    }
    ModuleDebug debug{ .simulateDeviceConnections = enabled };
    status_t status = statusTFromBinderStatus(mModule->setModuleDebug(debug));
+6 −7
Original line number Diff line number Diff line
@@ -704,7 +704,7 @@ status_t Hal2AidlMapper::prepareToOpenStream(
            this, __func__, ioHandle, device.toString().c_str(),
            flags.toString().c_str(), toString(source).c_str(),
            config->toString().c_str(), mixPortConfig->toString().c_str());
    resetUnusedPatchesAndPortConfigs();
    resetUnusedPatchesPortConfigsAndPorts();
    const AudioConfig initialConfig = *config;
    // Find / create AudioPortConfigs for the device port and the mix port,
    // then find / create a patch between them, and open a stream on the mix port.
@@ -832,7 +832,7 @@ status_t Hal2AidlMapper::releaseAudioPatches(const std::set<int32_t>& patchIds)
            result = BAD_VALUE;
        }
    }
    resetUnusedPortConfigs();
    resetUnusedPortConfigsAndPorts();
    return result;
}

@@ -849,7 +849,7 @@ void Hal2AidlMapper::resetPortConfig(int32_t portConfigId) {
    ALOGE("%s: port config id %d not found", __func__, portConfigId);
}

void Hal2AidlMapper::resetUnusedPatchesAndPortConfigs() {
void Hal2AidlMapper::resetUnusedPatchesPortConfigsAndPorts() {
    // Since patches can be created independently of streams via 'createOrUpdatePatch',
    // here we only clean up patches for released streams.
    std::set<int32_t> patchesToRelease;
@@ -863,11 +863,11 @@ void Hal2AidlMapper::resetUnusedPatchesAndPortConfigs() {
            it = mStreams.erase(it);
        }
    }
    // 'releaseAudioPatches' also resets unused port configs.
    // 'releaseAudioPatches' also resets unused port configs and ports.
    releaseAudioPatches(patchesToRelease);
}

void Hal2AidlMapper::resetUnusedPortConfigs() {
void Hal2AidlMapper::resetUnusedPortConfigsAndPorts() {
    // The assumption is that port configs are used to create patches
    // (or to open streams, but that involves creation of patches, too). Thus,
    // orphaned port configs can and should be reset.
@@ -908,6 +908,7 @@ void Hal2AidlMapper::resetUnusedPortConfigs() {
}

status_t Hal2AidlMapper::setDevicePortConnectedState(const AudioPort& devicePort, bool connected) {
    resetUnusedPatchesPortConfigsAndPorts();
    if (connected) {
        AudioDevice matchDevice = devicePort.ext.get<AudioPortExt::device>().device;
        std::optional<AudioPort> templatePort;
@@ -942,7 +943,6 @@ status_t Hal2AidlMapper::setDevicePortConnectedState(const AudioPort& devicePort
            }
            templatePort = portsIt->second;
        }
        resetUnusedPatchesAndPortConfigs();

        // Use the ID of the "template" port, use all the information from the provided port.
        AudioPort connectedPort = devicePort;
@@ -969,7 +969,6 @@ status_t Hal2AidlMapper::setDevicePortConnectedState(const AudioPort& devicePort
            ALOGD("%s: device port for device %s found in the module %s",
                    __func__, matchDevice.toString().c_str(), mInstance.c_str());
        }
        resetUnusedPatchesAndPortConfigs();

        // Disconnection of remote submix out with address "0" is a special case. We need to replace
        // the connected port entry with the "augmented template".
+2 −2
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ class Hal2AidlMapper {
        ::aidl::android::media::audio::common::AudioPortConfig* portConfig,
        Cleanups* cleanups = nullptr);
    status_t releaseAudioPatch(int32_t patchId);
    void resetUnusedPatchesAndPortConfigs();
    void resetUnusedPatchesPortConfigsAndPorts();
    status_t setDevicePortConnectedState(
            const ::aidl::android::media::audio::common::AudioPort& devicePort, bool connected);

@@ -181,7 +181,7 @@ class Hal2AidlMapper {
    status_t releaseAudioPatches(const std::set<int32_t>& patchIds);
    void resetPatch(int32_t patchId) { (void)releaseAudioPatch(patchId); }
    void resetPortConfig(int32_t portConfigId);
    void resetUnusedPortConfigs();
    void resetUnusedPortConfigsAndPorts();
    status_t updateAudioPort(
            int32_t portId, ::aidl::android::media::audio::common::AudioPort* port);
    status_t updateRoutes();