libaudiohal@aidl: Fix handling of point-to-point connections
Point-to-point connections (analog, HDMI, SPDIF) do not use
a device address. Reflect that in `GenerateUniqueDeviceAddress`.
When looking for a device port by address, check if there is
a connected device, and use the connected device port.
Bug: 300648357
Test: atest audiosystem_tests
Change-Id: Ic89fe25f1b757d8d95da0cbef09aa55887e62f4f
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 362f373..131684c 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -1080,6 +1080,7 @@
"%s: module %s, duplicate port ID received from HAL: %s, existing port: %s",
__func__, mInstance.c_str(), connectedPort.toString().c_str(),
it->second.toString().c_str());
+ mConnectedPorts[connectedPort.id] = false;
} else { // !connected
AudioDevice matchDevice = aidlPort.ext.get<AudioPortExt::device>().device;
auto portsIt = findPort(matchDevice);
@@ -1099,10 +1100,11 @@
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
mModule->disconnectExternalDevice(portId)));
mPorts.erase(portsIt);
+ mConnectedPorts.erase(portId);
} else {
ALOGD("%s: since device port ID %d is used by a stream, "
"external device disconnection postponed", __func__, portId);
- mConnectedPortIdsHeldByStreams.insert(portId);
+ mConnectedPorts[portId] = true;
}
}
return updateRoutes();
@@ -1601,8 +1603,25 @@
} else if (device.type.type == AudioDeviceType::OUT_DEFAULT) {
return mPorts.find(mDefaultOutputPortId);
}
- return std::find_if(mPorts.begin(), mPorts.end(),
- [&](const auto& pair) { return audioDeviceMatches(device, pair.second); });
+ if (device.address.getTag() != AudioDeviceAddress::id ||
+ !device.address.get<AudioDeviceAddress::id>().empty()) {
+ return std::find_if(mPorts.begin(), mPorts.end(),
+ [&](const auto& pair) { return audioDeviceMatches(device, pair.second); });
+ }
+ // For connection w/o an address, two ports can be found: the template port,
+ // and a connected port (if exists). Make sure we return the connected port.
+ DeviceHalAidl::Ports::iterator portIt = mPorts.end();
+ for (auto it = mPorts.begin(); it != mPorts.end(); ++it) {
+ if (audioDeviceMatches(device, it->second)) {
+ if (mConnectedPorts.find(it->first) != mConnectedPorts.end()) {
+ return it;
+ } else {
+ // Will return 'it' if there is no connected port.
+ portIt = it;
+ }
+ }
+ }
+ return portIt;
}
DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(
@@ -1765,7 +1784,8 @@
std::set<int32_t> retryDeviceDisconnection;
for (const auto& portConfigAndIdPair : portConfigIds) {
resetPortConfig(portConfigAndIdPair.first);
- if (mConnectedPortIdsHeldByStreams.count(portConfigAndIdPair.second) != 0) {
+ if (const auto it = mConnectedPorts.find(portConfigAndIdPair.second);
+ it != mConnectedPorts.end() && it->second) {
retryDeviceDisconnection.insert(portConfigAndIdPair.second);
}
}
@@ -1774,7 +1794,7 @@
TIME_CHECK();
if (auto status = mModule->disconnectExternalDevice(portId); status.isOk()) {
mPorts.erase(portId);
- mConnectedPortIdsHeldByStreams.erase(portId);
+ mConnectedPorts.erase(portId);
ALOGD("%s: executed postponed external device disconnection for port ID %d",
__func__, portId);
}