mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 22:04:26 +00:00
audio: Propagate errors from Driver::setConnectedDevices
Plumb propagation of errors reported by the implementations of DriverInterface::setConnectedDevices up to the Module. This allows returning the reported errors from the corresponding IModule interface methods. Implement handling of errors from connection state update by the Module implementation. When updating streams about the connection status ensure that the list of connected devices is not empty. Also, add an extra check to AudioStreamIn#ActiveMicrophones to validate the size of the returned active microphones list. Bug: 282568751 Test: atest VtsHalAudioCoreTargetTest Change-Id: I62a422d95c37a672fce4ad221bea435cc7b4ebfa
This commit is contained in:
@@ -340,30 +340,61 @@ void Module::registerPatch(const AudioPatch& patch) {
|
||||
do_insert(patch.sinkPortConfigIds);
|
||||
}
|
||||
|
||||
void Module::updateStreamsConnectedState(const AudioPatch& oldPatch, const AudioPatch& newPatch) {
|
||||
ndk::ScopedAStatus Module::updateStreamsConnectedState(const AudioPatch& oldPatch,
|
||||
const AudioPatch& newPatch) {
|
||||
// Streams from the old patch need to be disconnected, streams from the new
|
||||
// patch need to be connected. If the stream belongs to both patches, no need
|
||||
// to update it.
|
||||
std::set<int32_t> idsToDisconnect, idsToConnect;
|
||||
auto maybeFailure = ndk::ScopedAStatus::ok();
|
||||
std::set<int32_t> idsToDisconnect, idsToConnect, idsToDisconnectOnFailure;
|
||||
idsToDisconnect.insert(oldPatch.sourcePortConfigIds.begin(),
|
||||
oldPatch.sourcePortConfigIds.end());
|
||||
idsToDisconnect.insert(oldPatch.sinkPortConfigIds.begin(), oldPatch.sinkPortConfigIds.end());
|
||||
idsToConnect.insert(newPatch.sourcePortConfigIds.begin(), newPatch.sourcePortConfigIds.end());
|
||||
idsToConnect.insert(newPatch.sinkPortConfigIds.begin(), newPatch.sinkPortConfigIds.end());
|
||||
std::for_each(idsToDisconnect.begin(), idsToDisconnect.end(), [&](const auto& portConfigId) {
|
||||
if (idsToConnect.count(portConfigId) == 0) {
|
||||
LOG(DEBUG) << "The stream on port config id " << portConfigId << " is not connected";
|
||||
mStreams.setStreamIsConnected(portConfigId, {});
|
||||
if (idsToConnect.count(portConfigId) == 0 && mStreams.count(portConfigId) != 0) {
|
||||
if (auto status = mStreams.setStreamConnectedDevices(portConfigId, {}); status.isOk()) {
|
||||
LOG(DEBUG) << "updateStreamsConnectedState: The stream on port config id "
|
||||
<< portConfigId << " has been disconnected";
|
||||
} else {
|
||||
// Disconnection is tricky to roll back, just register a failure.
|
||||
maybeFailure = std::move(status);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!maybeFailure.isOk()) return maybeFailure;
|
||||
std::for_each(idsToConnect.begin(), idsToConnect.end(), [&](const auto& portConfigId) {
|
||||
if (idsToDisconnect.count(portConfigId) == 0) {
|
||||
if (idsToDisconnect.count(portConfigId) == 0 && mStreams.count(portConfigId) != 0) {
|
||||
const auto connectedDevices = findConnectedDevices(portConfigId);
|
||||
LOG(DEBUG) << "The stream on port config id " << portConfigId
|
||||
<< " is connected to: " << ::android::internal::ToString(connectedDevices);
|
||||
mStreams.setStreamIsConnected(portConfigId, connectedDevices);
|
||||
if (connectedDevices.empty()) {
|
||||
// This is important as workers use the vector size to derive the connection status.
|
||||
LOG(FATAL) << "updateStreamsConnectedState: No connected devices found for port "
|
||||
"config id "
|
||||
<< portConfigId;
|
||||
}
|
||||
if (auto status = mStreams.setStreamConnectedDevices(portConfigId, connectedDevices);
|
||||
status.isOk()) {
|
||||
LOG(DEBUG) << "updateStreamsConnectedState: The stream on port config id "
|
||||
<< portConfigId << " has been connected to: "
|
||||
<< ::android::internal::ToString(connectedDevices);
|
||||
} else {
|
||||
maybeFailure = std::move(status);
|
||||
idsToDisconnectOnFailure.insert(portConfigId);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!maybeFailure.isOk()) {
|
||||
LOG(WARNING) << __func__ << ": Due to a failure, disconnecting streams on port config ids "
|
||||
<< ::android::internal::ToString(idsToDisconnectOnFailure);
|
||||
std::for_each(idsToDisconnectOnFailure.begin(), idsToDisconnectOnFailure.end(),
|
||||
[&](const auto& portConfigId) {
|
||||
auto status = mStreams.setStreamConnectedDevices(portConfigId, {});
|
||||
(void)status.isOk(); // Can't do much about a failure here.
|
||||
});
|
||||
return maybeFailure;
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::setModuleDebug(
|
||||
@@ -659,12 +690,12 @@ ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_ar
|
||||
RETURN_STATUS_IF_ERROR(getStreamInCreator(mType)(in_args.sinkMetadata, std::move(context),
|
||||
mConfig->microphones, &stream));
|
||||
StreamWrapper streamWrapper(stream);
|
||||
if (auto patchIt = mPatches.find(in_args.portConfigId); patchIt != mPatches.end()) {
|
||||
RETURN_STATUS_IF_ERROR(
|
||||
streamWrapper.setConnectedDevices(findConnectedDevices(in_args.portConfigId)));
|
||||
}
|
||||
AIBinder_setMinSchedulerPolicy(streamWrapper.getBinder().get(), SCHED_NORMAL,
|
||||
ANDROID_PRIORITY_AUDIO);
|
||||
auto patchIt = mPatches.find(in_args.portConfigId);
|
||||
if (patchIt != mPatches.end()) {
|
||||
streamWrapper.setStreamIsConnected(findConnectedDevices(in_args.portConfigId));
|
||||
}
|
||||
mStreams.insert(port->id, in_args.portConfigId, std::move(streamWrapper));
|
||||
_aidl_return->stream = std::move(stream);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
@@ -705,12 +736,12 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_
|
||||
RETURN_STATUS_IF_ERROR(getStreamOutCreator(mType)(in_args.sourceMetadata, std::move(context),
|
||||
in_args.offloadInfo, &stream));
|
||||
StreamWrapper streamWrapper(stream);
|
||||
if (auto patchIt = mPatches.find(in_args.portConfigId); patchIt != mPatches.end()) {
|
||||
RETURN_STATUS_IF_ERROR(
|
||||
streamWrapper.setConnectedDevices(findConnectedDevices(in_args.portConfigId)));
|
||||
}
|
||||
AIBinder_setMinSchedulerPolicy(streamWrapper.getBinder().get(), SCHED_NORMAL,
|
||||
ANDROID_PRIORITY_AUDIO);
|
||||
auto patchIt = mPatches.find(in_args.portConfigId);
|
||||
if (patchIt != mPatches.end()) {
|
||||
streamWrapper.setStreamIsConnected(findConnectedDevices(in_args.portConfigId));
|
||||
}
|
||||
mStreams.insert(port->id, in_args.portConfigId, std::move(streamWrapper));
|
||||
_aidl_return->stream = std::move(stream);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
@@ -813,13 +844,20 @@ ndk::ScopedAStatus Module::setAudioPatch(const AudioPatch& in_requested, AudioPa
|
||||
if (existing == patches.end()) {
|
||||
_aidl_return->id = getConfig().nextPatchId++;
|
||||
patches.push_back(*_aidl_return);
|
||||
existing = patches.begin() + (patches.size() - 1);
|
||||
} else {
|
||||
oldPatch = *existing;
|
||||
*existing = *_aidl_return;
|
||||
}
|
||||
registerPatch(*existing);
|
||||
updateStreamsConnectedState(oldPatch, *_aidl_return);
|
||||
patchesBackup = mPatches;
|
||||
registerPatch(*_aidl_return);
|
||||
if (auto status = updateStreamsConnectedState(oldPatch, *_aidl_return); !status.isOk()) {
|
||||
mPatches = std::move(*patchesBackup);
|
||||
if (existing == patches.end()) {
|
||||
patches.pop_back();
|
||||
} else {
|
||||
*existing = oldPatch;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LOG(DEBUG) << __func__ << ": " << (oldPatch.id == 0 ? "created" : "updated") << " patch "
|
||||
<< _aidl_return->toString();
|
||||
@@ -971,8 +1009,12 @@ ndk::ScopedAStatus Module::resetAudioPatch(int32_t in_patchId) {
|
||||
auto& patches = getConfig().patches;
|
||||
auto patchIt = findById<AudioPatch>(patches, in_patchId);
|
||||
if (patchIt != patches.end()) {
|
||||
auto patchesBackup = mPatches;
|
||||
cleanUpPatch(patchIt->id);
|
||||
updateStreamsConnectedState(*patchIt, AudioPatch{});
|
||||
if (auto status = updateStreamsConnectedState(*patchIt, AudioPatch{}); !status.isOk()) {
|
||||
mPatches = std::move(patchesBackup);
|
||||
return status;
|
||||
}
|
||||
patches.erase(patchIt);
|
||||
LOG(DEBUG) << __func__ << ": erased patch " << in_patchId;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
|
||||
Reference in New Issue
Block a user