audiopolicy: Match DIRECT and MMAP_NOIRQ flags exactly in IOProfile

Prevent selection of DIRECT and MMAP_NOIRQ output profiles
if these flags were not requested.

Update the test APM configuration to use PCM16 on all outputs,
so they are all equivalent in terms of format and only differ in flags.

Test: atest audiopolicy_tests
Change-Id: I6940caed519b6237ea3038e646a84e4403a0c1ed
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index c74bd84..bf1a0f7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -78,7 +78,8 @@
         }
     }
 
-    const uint32_t mustMatchOutputFlags = AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
+    const uint32_t mustMatchOutputFlags =
+            AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
     if (isPlaybackThread && (((getFlags() ^ flags) & mustMatchOutputFlags)
                     || (getFlags() & flags) != flags)) {
         return false;
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 737d3cc..d3d839e 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -1164,7 +1164,7 @@
     audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
     audio_io_handle_t output;
     audio_port_handle_t portId;
-    getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_STEREO, 48000,
+    getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000,
             flags, &output, &portId);
     sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
     ASSERT_NE(nullptr, outDesc.get());
@@ -1187,13 +1187,23 @@
     dumpToLog();
 }
 
-TEST_F(AudioPolicyManagerTVTest, MatchOutputNoHwAvSync) {
+TEST_F(AudioPolicyManagerTVTest, MatchNoFlags) {
+    testHDMIPortSelection(AUDIO_OUTPUT_FLAG_NONE, "primary output");
+}
+
+TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectNoHwAvSync) {
     // b/140447125: The selected port must not have HW AV Sync flag (see the config file).
     testHDMIPortSelection(AUDIO_OUTPUT_FLAG_DIRECT, "direct");
 }
 
-TEST_F(AudioPolicyManagerTVTest, MatchOutputHwAvSync) {
+TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectHwAvSync) {
     testHDMIPortSelection(static_cast<audio_output_flags_t>(
                     AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
             "tunnel");
 }
+
+TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectMMapNoIrq) {
+    testHDMIPortSelection(static_cast<audio_output_flags_t>(
+                    AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
+            "low latency");
+}
diff --git a/services/audiopolicy/tests/resources/test_tv_apm_configuration.xml b/services/audiopolicy/tests/resources/test_tv_apm_configuration.xml
index 37178a0..f1638f3 100644
--- a/services/audiopolicy/tests/resources/test_tv_apm_configuration.xml
+++ b/services/audiopolicy/tests/resources/test_tv_apm_configuration.xml
@@ -23,30 +23,35 @@
             </attachedDevices>
             <defaultOutputDevice>Speaker</defaultOutputDevice>
             <mixPorts>
-                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                <!-- Profiles on the HDMI port are explicit for simplicity. In reality they are dynamic -->
+                <!-- Note: ports are intentionally arranged from more specific to less
+                     specific in order to test b/140447125 for HW AV Sync, and similar "explicit matches" -->
+                <mixPort name="tunnel" role="source"
+                         flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </mixPort>
-                <!-- Profiles on the HDMI port are explicit for simplicity. In reality they are dynamic -->
-                <!-- Note: a HW AV Sync port is declared before non-Sync port to test b/140447125 -->
-                <mixPort name="tunnel" role="source"
-                         flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC">
-                    <profile name="" format="AUDIO_FORMAT_AC3"
+                <mixPort name="low latency" 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>
                 <mixPort name="direct" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT">
-                    <profile name="" format="AUDIO_FORMAT_AC3"
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <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" />
-                <devicePort tagName="Out Aux Digital" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink"
-                            encodedFormats="AUDIO_FORMAT_AC3 AUDIO_FORMAT_IEC61937" />
+                <devicePort tagName="Out Aux Digital" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink" />
             </devicePorts>
             <routes>
                 <route type="mix" sink="Speaker" sources="primary output"/>
-                <route type="mix" sink="Out Aux Digital" sources="primary output,tunnel,direct"/>
+                <route type="mix" sink="Out Aux Digital" sources="primary output,tunnel,direct,low latency"/>
             </routes>
         </module>
     </modules>