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
Bug: 174123397
Test: atest AudioPlaybackCaptureTest audiopolicy_tests
Test: repo steps in the bug
Change-Id: I9a47a0a4b37ad3f4a1d554dd726ebffb27325141
(cherry picked from commit 10a03f1713e29eadfa862087e504f9e14964387e)
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 5f052a5..a904321 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_AUDIOPOLICY_INTERFACE_H
#define ANDROID_AUDIOPOLICY_INTERFACE_H
+#include <media/AudioCommonTypes.h>
#include <media/AudioDeviceTypeAddr.h>
#include <media/AudioSystem.h>
#include <media/AudioPolicy.h>
@@ -453,6 +454,9 @@
virtual void setSoundTriggerCaptureState(bool active) = 0;
virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
+
+ virtual status_t updateSecondaryOutputs(
+ const TrackSecondaryOutputsMap& trackSecondaryOutputs) = 0;
};
// These are the signatures of createAudioPolicyManager/destroyAudioPolicyManager
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index 59876c6..74b3405 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -109,6 +109,9 @@
const std::vector<wp<SwAudioOutputDescriptor>>& getSecondaryOutputs() const {
return mSecondaryOutputs;
};
+ void setSecondaryOutputs(std::vector<wp<SwAudioOutputDescriptor>>&& secondaryOutputs) {
+ mSecondaryOutputs = std::move(secondaryOutputs);
+ }
VolumeSource volumeSource() const { return mVolumeSource; }
const sp<AudioPolicyMix> getPrimaryMix() const {
return mPrimaryMix.promote();
@@ -143,7 +146,7 @@
const product_strategy_t mStrategy;
const VolumeSource mVolumeSource;
const audio_output_flags_t mFlags;
- const std::vector<wp<SwAudioOutputDescriptor>> mSecondaryOutputs;
+ std::vector<wp<SwAudioOutputDescriptor>> mSecondaryOutputs;
const wp<AudioPolicyMix> mPrimaryMix;
/**
* required for duplicating thread, prevent from removing active client from an output
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);
}
}
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 77b5200..cd53073 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -291,4 +291,14 @@
return af->getAudioPort(port);
}
+status_t AudioPolicyService::AudioPolicyClient::updateSecondaryOutputs(
+ const TrackSecondaryOutputsMap& trackSecondaryOutputs) {
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) {
+ ALOGW("%s: could not get AudioFlinger", __func__);
+ return PERMISSION_DENIED;
+ }
+ return af->updateSecondaryOutputs(trackSecondaryOutputs);
+}
+
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 00d9670..6eb33f6 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -735,6 +735,9 @@
status_t getAudioPort(struct audio_port_v7 *port) override;
+ status_t updateSecondaryOutputs(
+ const TrackSecondaryOutputsMap& trackSecondaryOutputs) override;
+
private:
AudioPolicyService *mAudioPolicyService;
};
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index e2d7d17..f7b0565 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -134,6 +134,11 @@
size_t getRoutingUpdatedCounter() const {
return mRoutingUpdatedUpdateCount; }
+ status_t updateSecondaryOutputs(
+ const TrackSecondaryOutputsMap& trackSecondaryOutputs __unused) override {
+ return NO_ERROR;
+ }
+
private:
audio_module_handle_t mNextModuleHandle = AUDIO_MODULE_HANDLE_NONE + 1;
audio_io_handle_t mNextIoHandle = AUDIO_IO_HANDLE_NONE + 1;
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index d289e15..1384864 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -91,6 +91,10 @@
status_t getAudioPort(struct audio_port_v7 *port __unused) override {
return INVALID_OPERATION;
};
+ status_t updateSecondaryOutputs(
+ const TrackSecondaryOutputsMap& trackSecondaryOutputs __unused) override {
+ return NO_INIT;
+ }
};
} // namespace android