Support non PCM output requests with dynamic policy active
The audio policy previously failed to find available non PCM output
routes if any dynamic policy primary mixes were found. That
implementation failed the promise of fallback to the engine if there
are no output matches through explicit routing or dynamic policy.
Bug: 238286324
Test: atest audiopolicy_tests
Change-Id: I9420d3a4aceaa6cf874461b82f358032ee994949
Merged-In: I9420d3a4aceaa6cf874461b82f358032ee994949
(cherry picked from commit d082f477c2089e68c061badb3e6ce55ec950ba96)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 8eae84c..07adcb6 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1161,7 +1161,12 @@
// 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
sp<AudioPolicyMix> primaryMix;
- status = mPolicyMixes.getOutputForAttr(*resultAttr, uid, *flags, primaryMix, secondaryMixes);
+ const audio_config_base_t clientConfig = {.sample_rate = config->sample_rate,
+ .channel_mask = config->channel_mask,
+ .format = config->format,
+ };
+ status = mPolicyMixes.getOutputForAttr(*resultAttr, clientConfig, uid, *flags, primaryMix,
+ secondaryMixes);
if (status != OK) {
return status;
}
@@ -1170,10 +1175,9 @@
bool usePrimaryOutputFromPolicyMixes = requestedDevice == nullptr && primaryMix != nullptr;
// FIXME: in case of RENDER policy, the output capabilities should be checked
- if ((usePrimaryOutputFromPolicyMixes
- || (secondaryMixes != nullptr && !secondaryMixes->empty()))
- && !audio_is_linear_pcm(config->format)) {
- ALOGD("%s: rejecting request as dynamic audio policy only support pcm", __func__);
+ if ((secondaryMixes != nullptr && !secondaryMixes->empty())
+ && !audio_is_linear_pcm(config->format)) {
+ ALOGD("%s: rejecting request as secondary mixes only support pcm", __func__);
return BAD_VALUE;
}
if (usePrimaryOutputFromPolicyMixes) {
@@ -6330,8 +6334,8 @@
continue;
}
sp<AudioPolicyMix> primaryMix;
- status_t status = mPolicyMixes.getOutputForAttr(client->attributes(), client->uid(),
- client->flags(), primaryMix, nullptr);
+ status_t status = mPolicyMixes.getOutputForAttr(client->attributes(), client->config(),
+ client->uid(), client->flags(), primaryMix, nullptr);
if (status != OK) {
continue;
}
@@ -6443,8 +6447,8 @@
for (const sp<TrackClientDescriptor>& client : outputDescriptor->getClientIterable()) {
sp<AudioPolicyMix> primaryMix;
std::vector<sp<AudioPolicyMix>> secondaryMixes;
- status_t status = mPolicyMixes.getOutputForAttr(client->attributes(), client->uid(),
- client->flags(), primaryMix, &secondaryMixes);
+ status_t status = mPolicyMixes.getOutputForAttr(client->attributes(), client->config(),
+ client->uid(), client->flags(), primaryMix, &secondaryMixes);
std::vector<sp<SwAudioOutputDescriptor>> secondaryDescs;
for (auto &secondaryMix : secondaryMixes) {
sp<SwAudioOutputDescriptor> outputDesc = secondaryMix->getOutput();
@@ -6702,8 +6706,8 @@
// 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;
- status_t status = mPolicyMixes.getOutputForAttr(attr, 0 /*uid unknown here*/,
- AUDIO_OUTPUT_FLAG_NONE, policyMix, nullptr /* secondaryMixes */);
+ status_t status = mPolicyMixes.getOutputForAttr(attr, AUDIO_CONFIG_BASE_INITIALIZER,
+ 0 /*uid unknown here*/, AUDIO_OUTPUT_FLAG_NONE, policyMix, nullptr);
if (status != OK) {
return status;
}