Loading media/libaudioclient/tests/audiosystem_tests.cpp +28 −19 Original line number Diff line number Diff line Loading @@ -615,10 +615,18 @@ class WithSimulatedDeviceConnections { android::media::audio::common::AudioPort GenerateUniqueDeviceAddress( const android::media::audio::common::AudioPort& port) { // Point-to-point connections do not use addresses. static const std::set<std::string> kPointToPointConnections = { AudioDeviceDescription::CONNECTION_ANALOG(), AudioDeviceDescription::CONNECTION_HDMI(), AudioDeviceDescription::CONNECTION_HDMI_ARC(), AudioDeviceDescription::CONNECTION_HDMI_EARC(), AudioDeviceDescription::CONNECTION_SPDIF()}; static int nextId = 0; using Tag = AudioDeviceAddress::Tag; const auto& deviceDescription = port.ext.get<AudioPortExt::Tag::device>().device.type; AudioDeviceAddress address; switch (suggestDeviceAddressTag(port.ext.get<AudioPortExt::Tag::device>().device.type)) { if (kPointToPointConnections.count(deviceDescription.connection) == 0) { switch (suggestDeviceAddressTag(deviceDescription)) { case Tag::id: address = AudioDeviceAddress::make<Tag::id>(std::to_string(++nextId)); break; Loading @@ -638,6 +646,7 @@ android::media::audio::common::AudioPort GenerateUniqueDeviceAddress( address = AudioDeviceAddress::make<Tag::alsa>(std::vector<int32_t>{1, ++nextId}); break; } } android::media::audio::common::AudioPort result = port; result.ext.get<AudioPortExt::Tag::device>().device.address = std::move(address); return result; Loading media/libaudiohal/impl/DeviceHalAidl.cpp +25 −5 Original line number Diff line number Diff line Loading @@ -1080,6 +1080,7 @@ status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool "%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); Loading @@ -1099,10 +1100,11 @@ status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool 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(); Loading Loading @@ -1601,9 +1603,26 @@ DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(const AudioDevice& device } else if (device.type.type == AudioDeviceType::OUT_DEFAULT) { return mPorts.find(mDefaultOutputPortId); } 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( const AudioConfig& config, const AudioIoFlags& flags, Loading Loading @@ -1765,7 +1784,8 @@ void DeviceHalAidl::resetUnusedPortConfigs() { 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); } } Loading @@ -1774,7 +1794,7 @@ void DeviceHalAidl::resetUnusedPortConfigs() { 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); } Loading media/libaudiohal/impl/DeviceHalAidl.h +3 −1 Original line number Diff line number Diff line Loading @@ -187,6 +187,8 @@ class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl, Status status = Status::UNKNOWN; MicrophoneInfoProvider::Info info; }; // IDs of ports for connected external devices, and whether they are held by streams. using ConnectedPorts = std::map<int32_t /*port ID*/, bool>; using Patches = std::map<int32_t /*patch ID*/, ::aidl::android::hardware::audio::core::AudioPatch>; using PortConfigs = std::map<int32_t /*port config ID*/, Loading Loading @@ -313,7 +315,7 @@ class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl, std::mutex mLock; std::map<void*, Callbacks> mCallbacks GUARDED_BY(mLock); std::set<audio_port_handle_t> mDeviceDisconnectionNotified; std::set<int32_t> mConnectedPortIdsHeldByStreams; ConnectedPorts mConnectedPorts; }; } // namespace android Loading
media/libaudioclient/tests/audiosystem_tests.cpp +28 −19 Original line number Diff line number Diff line Loading @@ -615,10 +615,18 @@ class WithSimulatedDeviceConnections { android::media::audio::common::AudioPort GenerateUniqueDeviceAddress( const android::media::audio::common::AudioPort& port) { // Point-to-point connections do not use addresses. static const std::set<std::string> kPointToPointConnections = { AudioDeviceDescription::CONNECTION_ANALOG(), AudioDeviceDescription::CONNECTION_HDMI(), AudioDeviceDescription::CONNECTION_HDMI_ARC(), AudioDeviceDescription::CONNECTION_HDMI_EARC(), AudioDeviceDescription::CONNECTION_SPDIF()}; static int nextId = 0; using Tag = AudioDeviceAddress::Tag; const auto& deviceDescription = port.ext.get<AudioPortExt::Tag::device>().device.type; AudioDeviceAddress address; switch (suggestDeviceAddressTag(port.ext.get<AudioPortExt::Tag::device>().device.type)) { if (kPointToPointConnections.count(deviceDescription.connection) == 0) { switch (suggestDeviceAddressTag(deviceDescription)) { case Tag::id: address = AudioDeviceAddress::make<Tag::id>(std::to_string(++nextId)); break; Loading @@ -638,6 +646,7 @@ android::media::audio::common::AudioPort GenerateUniqueDeviceAddress( address = AudioDeviceAddress::make<Tag::alsa>(std::vector<int32_t>{1, ++nextId}); break; } } android::media::audio::common::AudioPort result = port; result.ext.get<AudioPortExt::Tag::device>().device.address = std::move(address); return result; Loading
media/libaudiohal/impl/DeviceHalAidl.cpp +25 −5 Original line number Diff line number Diff line Loading @@ -1080,6 +1080,7 @@ status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool "%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); Loading @@ -1099,10 +1100,11 @@ status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool 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(); Loading Loading @@ -1601,9 +1603,26 @@ DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(const AudioDevice& device } else if (device.type.type == AudioDeviceType::OUT_DEFAULT) { return mPorts.find(mDefaultOutputPortId); } 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( const AudioConfig& config, const AudioIoFlags& flags, Loading Loading @@ -1765,7 +1784,8 @@ void DeviceHalAidl::resetUnusedPortConfigs() { 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); } } Loading @@ -1774,7 +1794,7 @@ void DeviceHalAidl::resetUnusedPortConfigs() { 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); } Loading
media/libaudiohal/impl/DeviceHalAidl.h +3 −1 Original line number Diff line number Diff line Loading @@ -187,6 +187,8 @@ class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl, Status status = Status::UNKNOWN; MicrophoneInfoProvider::Info info; }; // IDs of ports for connected external devices, and whether they are held by streams. using ConnectedPorts = std::map<int32_t /*port ID*/, bool>; using Patches = std::map<int32_t /*patch ID*/, ::aidl::android::hardware::audio::core::AudioPatch>; using PortConfigs = std::map<int32_t /*port config ID*/, Loading Loading @@ -313,7 +315,7 @@ class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl, std::mutex mLock; std::map<void*, Callbacks> mCallbacks GUARDED_BY(mLock); std::set<audio_port_handle_t> mDeviceDisconnectionNotified; std::set<int32_t> mConnectedPortIdsHeldByStreams; ConnectedPorts mConnectedPorts; }; } // namespace android