Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 697f5d9a authored by Jan Sebechlebsky's avatar Jan Sebechlebsky
Browse files

Fail if DAP render-only attempts to redirect mmaped stream

... to non-capable mmap device  / mix port.

Bug: 293611855
Test: atest audiopolicy_tests
Change-Id: I8c8b4827633ba09af849c84e27332edbae1feaba
parent 57c8ffbc
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -289,13 +289,21 @@ status_t AudioPolicyMixCollection::getOutputForAttr(
            continue; // skip the mix
        }

        if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) && is_mix_loopback(policyMix->mRouteFlags)) {
        if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
            if (is_mix_loopback(policyMix->mRouteFlags)) {
                // AAudio MMAP_NOIRQ streams cannot be routed to loopback/loopback+render
                // using dynamic audio policy.
            ALOGD("%s: Rejecting MMAP_NOIRQ request matched to loopback dynamic audio policy mix.",
                __func__);
                ALOGD("%s: Rejecting MMAP_NOIRQ request matched to loopback dynamic "
                      "audio policy mix.", __func__);
                return INVALID_OPERATION;
            }
            if (mixDevice != nullptr && !mixDevice->isMmap()) {
                ALOGD("%s: Rejecting MMAP_NOIRQ request matched to dynamic audio policy "
                      "mix pointing to device %s which doesn't support mmap", __func__,
                      mixDevice->toString(false).c_str());
                return INVALID_OPERATION;
            }
        }

        if (mixDevice != nullptr && mixDevice->equals(requestedDevice)) {
            ALOGV("%s: Mix %zu: requested device mathches", __func__, i);
+29 −5
Original line number Diff line number Diff line
@@ -1948,14 +1948,18 @@ TEST_P(AudioPolicyManagerTestMMapPlaybackRerouting,
}

TEST_F(AudioPolicyManagerTestMMapPlaybackRerouting,
        MmapPlaybackStreamMatchingRenderDapMixSucceeds) {
        MmapPlaybackStreamMatchingRenderDapMixSupportingMmapSucceeds) {
    // Add render-only mix matching the test uid.
    const int testUid = 12345;
    status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER, AUDIO_DEVICE_OUT_SPEAKER,
                                /*mixAddress=*/"", audioConfig, {createUidCriterion(testUid)});
    // test_audio_policy_configuration.xml declares mmap-capable mix port
    // for AUDIO_DEVICE_OUT_USB_DEVICE.
    status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
                                AUDIO_DEVICE_OUT_USB_DEVICE, /*mixAddress=*/"",
                                audioConfig, {createUidCriterion(testUid)});
    ASSERT_EQ(NO_ERROR, ret);

    // Geting output for matching uid should succeed for mmaped stream.
    // Geting output for matching uid should succeed for mmaped stream, because matched mix
    // redirects to mmap capable device.
    audio_output_flags_t outputFlags = AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
    ASSERT_EQ(NO_ERROR,
              mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
@@ -1964,6 +1968,26 @@ TEST_F(AudioPolicyManagerTestMMapPlaybackRerouting,
                                         &mOutputType, &mIsSpatialized, &mIsBitPerfect));
}

TEST_F(AudioPolicyManagerTestMMapPlaybackRerouting,
        MmapPlaybackStreamMatchingRenderDapMixNotSupportingMmapFails) {
    // Add render-only mix matching the test uid.
    const int testUid = 12345;
    // Per test_audio_policy_configuration.xml AUDIO_DEVICE_OUT_SPEAKER doesn't support mmap.
    status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
                                AUDIO_DEVICE_OUT_SPEAKER, /*mixAddress=*/"", audioConfig,
                                {createUidCriterion(testUid)});
    ASSERT_EQ(NO_ERROR, ret);

    // Geting output for matching uid should fail for mmaped stream, because
    // matched mix redirects to device which doesn't support mmap.
    audio_output_flags_t outputFlags = AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
    ASSERT_EQ(INVALID_OPERATION,
              mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
                                         createAttributionSourceState(testUid), &audioConfig,
                                         &outputFlags, &mSelectedDeviceId, &mPortId, {},
                                         &mOutputType, &mIsSpatialized, &mIsBitPerfect));
}

INSTANTIATE_TEST_SUITE_P(
        MmapPlaybackRerouting, AudioPolicyManagerTestMMapPlaybackRerouting,
        testing::Values(DPMmapTestParam(MIX_ROUTE_FLAG_LOOP_BACK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+6 −1
Original line number Diff line number Diff line
@@ -55,6 +55,11 @@
                           samplingRates="8000 16000 32000 48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
                <mixPort name="hifi_output" role="source" flags="AUDIO_OUTPUT_FLAG_BIT_PERFECT"/>
                <mixPort name="mmap_no_irq_out" role="source"
                         flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink">
@@ -96,7 +101,7 @@
                <route type="mix" sink="BT A2DP Out"
                       sources="primary output,hifi_output"/>
                <route type="mix" sink="USB Device Out"
                       sources="primary output,hifi_output"/>
                       sources="primary output,hifi_output,mmap_no_irq_out"/>
            </routes>
        </module>