Disallowed explicit routing for user device affinities conflicts
If user id device affinities for a particular device
disallows playback for a user id, then the explicit audio
routing (#setPreferredDevice) is disallowed. Otherwise,
the explicity routing is allowed.
Bug: 237733218
Test: atest audiopolicy_tests
Change-Id: I823e7e59e86303f80808d4953b52efad5da8e779
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 0f2b34e..e910c3d 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1168,6 +1168,8 @@
ALOGV("%s() attributes=%s stream=%s session %d selectedDeviceId %d", __func__,
toString(*resultAttr).c_str(), toString(*stream).c_str(), session, requestedPortId);
+ bool usePrimaryOutputFromPolicyMixes = false;
+
// The primary output is the explicit routing (eg. setPreferredDevice) if specified,
// otherwise, fallback to the dynamic policies, if none match, query the engine.
// Secondary outputs are always found by dynamic policies as the engine do not support them
@@ -1177,14 +1179,12 @@
.format = config->format,
};
status = mPolicyMixes.getOutputForAttr(*resultAttr, clientConfig, uid, session, *flags,
- primaryMix, secondaryMixes);
+ mAvailableOutputDevices, requestedDevice, primaryMix,
+ secondaryMixes, usePrimaryOutputFromPolicyMixes);
if (status != OK) {
return status;
}
- // Explicit routing is higher priority then any dynamic policy primary output
- bool usePrimaryOutputFromPolicyMixes = requestedDevice == nullptr && primaryMix != nullptr;
-
// FIXME: in case of RENDER policy, the output capabilities should be checked
if ((secondaryMixes != nullptr && !secondaryMixes->empty())
&& !audio_is_linear_pcm(config->format)) {
@@ -6730,6 +6730,7 @@
SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevices(newDevices, mOutputs);
uint32_t maxLatency = 0;
+ bool unneededUsePrimaryOutputFromPolicyMixes = false;
std::vector<sp<SwAudioOutputDescriptor>> invalidatedOutputs;
// take into account dynamic audio policies related changes: if a client is now associated
// to a different policy mix than at creation time, invalidate corresponding stream
@@ -6744,7 +6745,9 @@
}
sp<AudioPolicyMix> primaryMix;
status_t status = mPolicyMixes.getOutputForAttr(client->attributes(), client->config(),
- client->uid(), client->session(), client->flags(), primaryMix, nullptr);
+ client->uid(), client->session(), client->flags(), mAvailableOutputDevices,
+ nullptr /* requestedDevice */, primaryMix, nullptr /* secondaryMixes */,
+ unneededUsePrimaryOutputFromPolicyMixes);
if (status != OK) {
continue;
}
@@ -6842,13 +6845,16 @@
void AudioPolicyManager::checkSecondaryOutputs() {
PortHandleVector clientsToInvalidate;
TrackSecondaryOutputsMap trackSecondaryOutputs;
+ bool unneededUsePrimaryOutputFromPolicyMixes = false;
for (size_t i = 0; i < mOutputs.size(); i++) {
const sp<SwAudioOutputDescriptor>& outputDescriptor = mOutputs[i];
for (const sp<TrackClientDescriptor>& client : outputDescriptor->getClientIterable()) {
sp<AudioPolicyMix> primaryMix;
std::vector<sp<AudioPolicyMix>> secondaryMixes;
status_t status = mPolicyMixes.getOutputForAttr(client->attributes(), client->config(),
- client->uid(), client->session(), client->flags(), primaryMix, &secondaryMixes);
+ client->uid(), client->session(), client->flags(), mAvailableOutputDevices,
+ nullptr /* requestedDevice */, primaryMix, &secondaryMixes,
+ unneededUsePrimaryOutputFromPolicyMixes);
std::vector<sp<SwAudioOutputDescriptor>> secondaryDescs;
for (auto &secondaryMix : secondaryMixes) {
sp<SwAudioOutputDescriptor> outputDesc = secondaryMix->getOutput();
@@ -8282,9 +8288,11 @@
// check dynamic policies but only for primary descriptors (secondary not used for audible
// audio routing, only used for duplication for playback capture)
sp<AudioPolicyMix> policyMix;
+ bool unneededUsePrimaryOutputFromPolicyMixes = false;
status_t status = mPolicyMixes.getOutputForAttr(attr, AUDIO_CONFIG_BASE_INITIALIZER,
- 0 /*uid unknown here*/, AUDIO_SESSION_NONE, AUDIO_OUTPUT_FLAG_NONE, policyMix,
- nullptr /* secondaryMixes */);
+ 0 /*uid unknown here*/, AUDIO_SESSION_NONE, AUDIO_OUTPUT_FLAG_NONE,
+ mAvailableOutputDevices, nullptr /* requestedDevice */, policyMix,
+ nullptr /* secondaryMixes */, unneededUsePrimaryOutputFromPolicyMixes);
if (status != OK) {
return status;
}