audio: Fix some VTS issues on real devices

1. Skip testing of stream I/O on certain types of mix ports.

2. Skip testing of connection of BT SCO device.

Bug: 300735639
Bug: 326888356
Bug: 328010709
Bug: 331516432
Test: atest VtsHalAudioCoreTargetTest
Change-Id: I9b8bbf2014e223375c8f8400ff2af32268803706
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index ef312d5..a1008a4 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -174,6 +174,12 @@
     return result;
 }
 
+template <typename E, typename U = std::underlying_type_t<E>,
+          typename = std::enable_if_t<is_bit_position_enum<E>::value>>
+constexpr bool isAnyBitPositionFlagSet(U mask, std::initializer_list<E> flags) {
+    return (mask & makeBitPositionFlagMask<E>(flags)) != 0;
+}
+
 constexpr int32_t frameCountFromDurationUs(long durationUs, int32_t sampleRateHz) {
     return (static_cast<long long>(durationUs) * sampleRateHz) / 1000000LL;
 }
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 7373073..4a7bfbd 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -56,6 +56,7 @@
 using namespace android;
 using aidl::android::hardware::audio::common::AudioOffloadMetadata;
 using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::common::isAnyBitPositionFlagSet;
 using aidl::android::hardware::audio::common::isBitPositionFlagSet;
 using aidl::android::hardware::audio::common::isTelephonyDeviceType;
 using aidl::android::hardware::audio::common::isValidAudioMode;
@@ -85,6 +86,7 @@
 using aidl::android::media::audio::common::AudioDeviceType;
 using aidl::android::media::audio::common::AudioDualMonoMode;
 using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioInputFlags;
 using aidl::android::media::audio::common::AudioIoFlags;
 using aidl::android::media::audio::common::AudioLatencyMode;
 using aidl::android::media::audio::common::AudioMMapPolicy;
@@ -1749,8 +1751,13 @@
     for (const auto& port : ports) {
         // Virtual devices may not require external hardware and thus can always be connected.
         if (port.ext.get<AudioPortExt::device>().device.type.connection ==
-            AudioDeviceDescription::CONNECTION_VIRTUAL)
+                    AudioDeviceDescription::CONNECTION_VIRTUAL ||
+            // SCO devices are handled at low level by DSP, may not be able to check actual
+            // connection.
+            port.ext.get<AudioPortExt::device>().device.type.connection ==
+                    AudioDeviceDescription::CONNECTION_BT_SCO) {
             continue;
+        }
         AudioPort portWithData = GenerateUniqueDeviceAddress(port), connectedPort;
         ScopedAStatus status = module->connectExternalDevice(portWithData, &connectedPort);
         EXPECT_STATUS(EX_ILLEGAL_STATE, status) << "static port " << portWithData.toString();
@@ -3780,6 +3787,19 @@
         }
         for (const auto& portConfig : allPortConfigs) {
             SCOPED_TRACE(portConfig.toString());
+            // Certain types of ports can not be used without special preconditions.
+            if ((IOTraits<Stream>::is_input &&
+                 isAnyBitPositionFlagSet(
+                         portConfig.flags.value().template get<AudioIoFlags::Tag::input>(),
+                         {AudioInputFlags::MMAP_NOIRQ, AudioInputFlags::VOIP_TX,
+                          AudioInputFlags::HW_HOTWORD})) ||
+                (!IOTraits<Stream>::is_input &&
+                 isAnyBitPositionFlagSet(
+                         portConfig.flags.value().template get<AudioIoFlags::Tag::output>(),
+                         {AudioOutputFlags::MMAP_NOIRQ, AudioOutputFlags::VOIP_RX,
+                          AudioOutputFlags::COMPRESS_OFFLOAD, AudioOutputFlags::INCALL_MUSIC}))) {
+                continue;
+            }
             const bool isNonBlocking =
                     IOTraits<Stream>::is_input
                             ? false