Do not invalidate stream when the secondary outputs are changed.
When a dynamic policy is registered, the secondary outputs may be
changed. Instead of tearing down the tracks, only tracks whose secondary
outputs are changed will be updated with the new secondary outputs.
Bug: 181582467
Test: atest AudioPlaybackCaptureTest audiopolicy_tests
Test: repo steps in the bug
Change-Id: I9a47a0a4b37ad3f4a1d554dd726ebffb27325141
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 7185435..c8ddbc6 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -31,6 +31,7 @@
#include <algorithm>
#include <inttypes.h>
+#include <map>
#include <math.h>
#include <set>
#include <unordered_set>
@@ -5694,6 +5695,7 @@
void AudioPolicyManager::checkSecondaryOutputs() {
std::set<audio_stream_type_t> streamsToInvalidate;
+ TrackSecondaryOutputsMap trackSecondaryOutputs;
for (size_t i = 0; i < mOutputs.size(); i++) {
const sp<SwAudioOutputDescriptor>& outputDescriptor = mOutputs[i];
for (const sp<TrackClientDescriptor>& client : outputDescriptor->getClientIterable()) {
@@ -5710,16 +5712,28 @@
}
}
- if (status != OK ||
- !std::equal(client->getSecondaryOutputs().begin(),
- client->getSecondaryOutputs().end(),
- secondaryDescs.begin(), secondaryDescs.end())) {
+ if (status != OK) {
streamsToInvalidate.insert(client->stream());
+ } else if (!std::equal(
+ client->getSecondaryOutputs().begin(),
+ client->getSecondaryOutputs().end(),
+ secondaryDescs.begin(), secondaryDescs.end())) {
+ std::vector<wp<SwAudioOutputDescriptor>> weakSecondaryDescs;
+ std::vector<audio_io_handle_t> secondaryOutputIds;
+ for (const auto& secondaryDesc : secondaryDescs) {
+ secondaryOutputIds.push_back(secondaryDesc->mIoHandle);
+ weakSecondaryDescs.push_back(secondaryDesc);
+ }
+ trackSecondaryOutputs.emplace(client->portId(), secondaryOutputIds);
+ client->setSecondaryOutputs(std::move(weakSecondaryDescs));
}
}
}
+ if (!trackSecondaryOutputs.empty()) {
+ mpClientInterface->updateSecondaryOutputs(trackSecondaryOutputs);
+ }
for (audio_stream_type_t stream : streamsToInvalidate) {
- ALOGD("%s Invalidate stream %d due to secondary output change", __func__, stream);
+ ALOGD("%s Invalidate stream %d due to fail getting output for attr", __func__, stream);
mpClientInterface->invalidateStream(stream);
}
}