Loading services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h +5 −2 Original line number Diff line number Diff line Loading @@ -65,8 +65,11 @@ public: * @param[in] attributes to consider fowr the research of output descriptor. * @param[out] desc to return if an primary output could be found. * @param[out] secondaryDesc other desc that the audio should be routed to. * @return OK if the request is valid * otherwise if the request is not supported */ status_t getOutputForAttr(const audio_attributes_t& attributes, uid_t uid, audio_output_flags_t flags, sp<SwAudioOutputDescriptor> &primaryDesc, std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs); Loading services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp +16 −4 Original line number Diff line number Diff line Loading @@ -126,21 +126,33 @@ void AudioPolicyMixCollection::closeOutput(sp<SwAudioOutputDescriptor> &desc) } status_t AudioPolicyMixCollection::getOutputForAttr( const audio_attributes_t& attributes, uid_t uid, sp<SwAudioOutputDescriptor> &primaryDesc, const audio_attributes_t& attributes, uid_t uid, audio_output_flags_t flags, sp<SwAudioOutputDescriptor> &primaryDesc, std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs) { ALOGV("getOutputForAttr() querying %zu mixes:", size()); primaryDesc = 0; for (size_t i = 0; i < size(); i++) { sp<AudioPolicyMix> policyMix = valueAt(i); const bool primaryOutputMix = !is_mix_loopback_render(policyMix->mRouteFlags); if (!primaryOutputMix && (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)) { // AAudio does not support MMAP_NO_IRQ loopback render, and there is no way with // the current MmapStreamInterface::start to reject a specific client added to a shared // mmap stream. // As a result all MMAP_NOIRQ requests have to be rejected when an loopback render // policy is present. That ensures no shared mmap stream is used when an loopback // render policy is registered. ALOGD("%s: Rejecting MMAP_NOIRQ request due to LOOPBACK|RENDER mix present.", __func__); return INVALID_OPERATION; } sp<SwAudioOutputDescriptor> policyDesc = policyMix->getOutput(); if (!policyDesc) { ALOGV("%s: Skiping %zu: Mix has no output", __func__, i); continue; } const bool primaryOutputMix = !is_mix_loopback_render(policyMix->mRouteFlags); if (primaryOutputMix && primaryDesc != 0) { ALOGV("%s: Skiping %zu: Primary output already found", __func__, i); continue; // Primary output already found Loading Loading @@ -170,7 +182,7 @@ status_t AudioPolicyMixCollection::getOutputForAttr( } } } return (primaryDesc == nullptr && secondaryDescs->empty()) ? BAD_VALUE : NO_ERROR; return NO_ERROR; } AudioPolicyMixCollection::MixMatchStatus AudioPolicyMixCollection::mixMatch( Loading services/audiopolicy/managerdefault/AudioPolicyManager.cpp +8 −7 Original line number Diff line number Diff line Loading @@ -963,10 +963,11 @@ status_t AudioPolicyManager::getOutputForAttrInt( // 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<SwAudioOutputDescriptor> policyDesc; if (mPolicyMixes.getOutputForAttr(*resultAttr, uid, policyDesc, secondaryDescs) != NO_ERROR) { policyDesc = nullptr; // reset getOutputForAttr in case of failure secondaryDescs->clear(); status = mPolicyMixes.getOutputForAttr(*resultAttr, uid, *flags, policyDesc, secondaryDescs); if (status != OK) { return status; } // Explicit routing is higher priority then any dynamic policy primary output bool usePrimaryOutputFromPolicyMixes = requestedDevice == nullptr && policyDesc != nullptr; Loading Loading @@ -5069,12 +5070,12 @@ void AudioPolicyManager::checkSecondaryOutputs() { for (size_t i = 0; i < mOutputs.size(); i++) { const sp<SwAudioOutputDescriptor>& outputDescriptor = mOutputs[i]; for (const sp<TrackClientDescriptor>& client : outputDescriptor->getClientIterable()) { // FIXME code duplicated from getOutputForAttrInt sp<SwAudioOutputDescriptor> desc; std::vector<sp<SwAudioOutputDescriptor>> secondaryDescs; mPolicyMixes.getOutputForAttr(client->attributes(), client->uid(), desc, &secondaryDescs); if (!std::equal(client->getSecondaryOutputs().begin(), status_t status = mPolicyMixes.getOutputForAttr(client->attributes(), client->uid(), client->flags(), desc, &secondaryDescs); if (status != OK || !std::equal(client->getSecondaryOutputs().begin(), client->getSecondaryOutputs().end(), secondaryDescs.begin(), secondaryDescs.end())) { streamsToInvalidate.insert(client->stream()); Loading Loading
services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h +5 −2 Original line number Diff line number Diff line Loading @@ -65,8 +65,11 @@ public: * @param[in] attributes to consider fowr the research of output descriptor. * @param[out] desc to return if an primary output could be found. * @param[out] secondaryDesc other desc that the audio should be routed to. * @return OK if the request is valid * otherwise if the request is not supported */ status_t getOutputForAttr(const audio_attributes_t& attributes, uid_t uid, audio_output_flags_t flags, sp<SwAudioOutputDescriptor> &primaryDesc, std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs); Loading
services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp +16 −4 Original line number Diff line number Diff line Loading @@ -126,21 +126,33 @@ void AudioPolicyMixCollection::closeOutput(sp<SwAudioOutputDescriptor> &desc) } status_t AudioPolicyMixCollection::getOutputForAttr( const audio_attributes_t& attributes, uid_t uid, sp<SwAudioOutputDescriptor> &primaryDesc, const audio_attributes_t& attributes, uid_t uid, audio_output_flags_t flags, sp<SwAudioOutputDescriptor> &primaryDesc, std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs) { ALOGV("getOutputForAttr() querying %zu mixes:", size()); primaryDesc = 0; for (size_t i = 0; i < size(); i++) { sp<AudioPolicyMix> policyMix = valueAt(i); const bool primaryOutputMix = !is_mix_loopback_render(policyMix->mRouteFlags); if (!primaryOutputMix && (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)) { // AAudio does not support MMAP_NO_IRQ loopback render, and there is no way with // the current MmapStreamInterface::start to reject a specific client added to a shared // mmap stream. // As a result all MMAP_NOIRQ requests have to be rejected when an loopback render // policy is present. That ensures no shared mmap stream is used when an loopback // render policy is registered. ALOGD("%s: Rejecting MMAP_NOIRQ request due to LOOPBACK|RENDER mix present.", __func__); return INVALID_OPERATION; } sp<SwAudioOutputDescriptor> policyDesc = policyMix->getOutput(); if (!policyDesc) { ALOGV("%s: Skiping %zu: Mix has no output", __func__, i); continue; } const bool primaryOutputMix = !is_mix_loopback_render(policyMix->mRouteFlags); if (primaryOutputMix && primaryDesc != 0) { ALOGV("%s: Skiping %zu: Primary output already found", __func__, i); continue; // Primary output already found Loading Loading @@ -170,7 +182,7 @@ status_t AudioPolicyMixCollection::getOutputForAttr( } } } return (primaryDesc == nullptr && secondaryDescs->empty()) ? BAD_VALUE : NO_ERROR; return NO_ERROR; } AudioPolicyMixCollection::MixMatchStatus AudioPolicyMixCollection::mixMatch( Loading
services/audiopolicy/managerdefault/AudioPolicyManager.cpp +8 −7 Original line number Diff line number Diff line Loading @@ -963,10 +963,11 @@ status_t AudioPolicyManager::getOutputForAttrInt( // 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<SwAudioOutputDescriptor> policyDesc; if (mPolicyMixes.getOutputForAttr(*resultAttr, uid, policyDesc, secondaryDescs) != NO_ERROR) { policyDesc = nullptr; // reset getOutputForAttr in case of failure secondaryDescs->clear(); status = mPolicyMixes.getOutputForAttr(*resultAttr, uid, *flags, policyDesc, secondaryDescs); if (status != OK) { return status; } // Explicit routing is higher priority then any dynamic policy primary output bool usePrimaryOutputFromPolicyMixes = requestedDevice == nullptr && policyDesc != nullptr; Loading Loading @@ -5069,12 +5070,12 @@ void AudioPolicyManager::checkSecondaryOutputs() { for (size_t i = 0; i < mOutputs.size(); i++) { const sp<SwAudioOutputDescriptor>& outputDescriptor = mOutputs[i]; for (const sp<TrackClientDescriptor>& client : outputDescriptor->getClientIterable()) { // FIXME code duplicated from getOutputForAttrInt sp<SwAudioOutputDescriptor> desc; std::vector<sp<SwAudioOutputDescriptor>> secondaryDescs; mPolicyMixes.getOutputForAttr(client->attributes(), client->uid(), desc, &secondaryDescs); if (!std::equal(client->getSecondaryOutputs().begin(), status_t status = mPolicyMixes.getOutputForAttr(client->attributes(), client->uid(), client->flags(), desc, &secondaryDescs); if (status != OK || !std::equal(client->getSecondaryOutputs().begin(), client->getSecondaryOutputs().end(), secondaryDescs.begin(), secondaryDescs.end())) { streamsToInvalidate.insert(client->stream()); Loading