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
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index fc3f699..2af18cc 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -974,7 +974,7 @@
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));
diff --git a/media/libaudiohal/impl/Hal2AidlMapper.cpp b/media/libaudiohal/impl/Hal2AidlMapper.cpp
index 63ace8c..a0aca15 100644
--- a/media/libaudiohal/impl/Hal2AidlMapper.cpp
+++ b/media/libaudiohal/impl/Hal2AidlMapper.cpp
@@ -704,7 +704,7 @@
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 @@
result = BAD_VALUE;
}
}
- resetUnusedPortConfigs();
+ resetUnusedPortConfigsAndPorts();
return result;
}
@@ -849,7 +849,7 @@
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 @@
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 @@
}
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 @@
}
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 @@
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".
diff --git a/media/libaudiohal/impl/Hal2AidlMapper.h b/media/libaudiohal/impl/Hal2AidlMapper.h
index 21cfd5a..ba26e60 100644
--- a/media/libaudiohal/impl/Hal2AidlMapper.h
+++ b/media/libaudiohal/impl/Hal2AidlMapper.h
@@ -91,7 +91,7 @@
::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 @@
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();