Add MSD support in getDirectProfilesForAttributes

Enabled an AudioProfile equality comparison that
can ignore the dynamic flags.

Add unit tests for the MSD cases.

Bug: 214971780
Test: atest audiopolicy_tests
Test: atest android.media.audio.cts.DirectAudioProfilesForAttributesTest
Change-Id: Ic72048c9d134c02a79678b8b41f1fb1201ae7086
diff --git a/media/libaudiofoundation/AudioProfile.cpp b/media/libaudiofoundation/AudioProfile.cpp
index 734fa9c..2170cd8 100644
--- a/media/libaudiofoundation/AudioProfile.cpp
+++ b/media/libaudiofoundation/AudioProfile.cpp
@@ -127,16 +127,17 @@
              "%*s%s\n", spaces, "", audio_encapsulation_type_to_string(mEncapsulationType)));
 }
 
-bool AudioProfile::equals(const sp<AudioProfile>& other) const
+bool AudioProfile::equals(const sp<AudioProfile>& other, bool ignoreDynamicFlags) const
 {
     return other != nullptr &&
            mName.compare(other->mName) == 0 &&
            mFormat == other->getFormat() &&
            mChannelMasks == other->getChannels() &&
            mSamplingRates == other->getSampleRates() &&
-           mIsDynamicFormat == other->isDynamicFormat() &&
-           mIsDynamicChannels == other->isDynamicChannels() &&
-           mIsDynamicRate == other->isDynamicRate() &&
+           (ignoreDynamicFlags ||
+               (mIsDynamicFormat == other->isDynamicFormat() &&
+               mIsDynamicChannels == other->isDynamicChannels() &&
+               mIsDynamicRate == other->isDynamicRate())) &&
            mEncapsulationType == other->getEncapsulationType();
 }
 
@@ -326,10 +327,10 @@
     return false;
 }
 
-bool AudioProfileVector::contains(const sp<AudioProfile>& profile) const
+bool AudioProfileVector::contains(const sp<AudioProfile>& profile, bool ignoreDynamicFlags) const
 {
     for (const auto& audioProfile : *this) {
-        if (audioProfile->equals(profile)) {
+        if (audioProfile->equals(profile, ignoreDynamicFlags)) {
             return true;
         }
     }
@@ -356,6 +357,14 @@
                       });
 }
 
+void AudioProfileVector::addAllValidProfiles(const AudioProfileVector& audioProfiles) {
+    for (const auto& audioProfile : audioProfiles) {
+        if (audioProfile->isValid() && !contains(audioProfile, true /*ignoreDynamicFlags*/)) {
+            add(audioProfile);
+        }
+    }
+}
+
 ConversionResult<AudioProfileVector>
 aidl2legacy_AudioProfileVector(const AudioProfileVector::Aidl& aidl, bool isInput) {
     return convertContainers<AudioProfileVector>(aidl.first, aidl.second,
diff --git a/media/libaudiofoundation/include/media/AudioProfile.h b/media/libaudiofoundation/include/media/AudioProfile.h
index c3a0fb2..79dfd12 100644
--- a/media/libaudiofoundation/include/media/AudioProfile.h
+++ b/media/libaudiofoundation/include/media/AudioProfile.h
@@ -78,7 +78,7 @@
 
     void dump(std::string *dst, int spaces) const;
 
-    bool equals(const sp<AudioProfile>& other) const;
+    bool equals(const sp<AudioProfile>& other, bool ignoreDynamicFlags = false) const;
 
     using Aidl = std::pair<media::audio::common::AudioProfile, media::AudioProfileSys>;
     ConversionResult<Aidl> toParcelable(bool isInput) const;
@@ -139,11 +139,12 @@
     bool hasDynamicProfile() const;
     bool hasDynamicRateFor(audio_format_t format) const;
 
-    bool contains(const sp<AudioProfile>& profile) const;
+    bool contains(const sp<AudioProfile>& profile, bool ignoreDynamicFlags = false) const;
 
     virtual void dump(std::string *dst, int spaces) const;
 
     bool equals(const AudioProfileVector& other) const;
+    void addAllValidProfiles(const AudioProfileVector& audioProfiles);
 
     using Aidl = std::pair<
             std::vector<media::audio::common::AudioProfile>,