audio: Add support for compressed offload

- Add compressed offload mix port into default implementation.
- Require AudioOffloadInfo to be passed to IModule.openOutputStream
  for compressed offload port configs.
- Update VTS to handle compressed offload.

Bug: 205884982
Test: atest VtsHalAudioCoreTargetTest
Merged-In: I118b2c04bff12b64a7cac4dc2c88217a6a270046
Change-Id: I118b2c04bff12b64a7cac4dc2c88217a6a270046
(cherry picked from commit 975ea3ae8959b1d9502290ebd5c71fba68645c64)
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 4728a89..ad1d9c7 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -13,6 +13,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
+        "libstagefright_foundation",
         "android.media.audio.common.types-V1-ndk",
         "android.hardware.audio.core-V1-ndk",
     ],
@@ -37,6 +38,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
+        "libstagefright_foundation",
         "android.media.audio.common.types-V1-ndk",
         "android.hardware.audio.core-V1-ndk",
     ],
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index 19d0b3c..f5d679b 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -20,6 +20,7 @@
 #include <aidl/android/media/audio/common/AudioFormatType.h>
 #include <aidl/android/media/audio/common/AudioIoFlags.h>
 #include <aidl/android/media/audio/common/AudioOutputFlags.h>
+#include <media/stagefright/foundation/MediaDefs.h>
 
 #include "core-impl/Configuration.h"
 
@@ -42,16 +43,30 @@
 
 namespace aidl::android::hardware::audio::core::internal {
 
+static void fillProfile(AudioProfile* profile, const std::vector<int32_t>& channelLayouts,
+                        const std::vector<int32_t>& sampleRates) {
+    for (auto layout : channelLayouts) {
+        profile->channelMasks.push_back(
+                AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout));
+    }
+    profile->sampleRates.insert(profile->sampleRates.end(), sampleRates.begin(), sampleRates.end());
+}
+
 static AudioProfile createProfile(PcmType pcmType, const std::vector<int32_t>& channelLayouts,
                                   const std::vector<int32_t>& sampleRates) {
     AudioProfile profile;
     profile.format.type = AudioFormatType::PCM;
     profile.format.pcm = pcmType;
-    for (auto layout : channelLayouts) {
-        profile.channelMasks.push_back(
-                AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout));
-    }
-    profile.sampleRates.insert(profile.sampleRates.end(), sampleRates.begin(), sampleRates.end());
+    fillProfile(&profile, channelLayouts, sampleRates);
+    return profile;
+}
+
+static AudioProfile createProfile(const std::string& encodingType,
+                                  const std::vector<int32_t>& channelLayouts,
+                                  const std::vector<int32_t>& sampleRates) {
+    AudioProfile profile;
+    profile.format.encoding = encodingType;
+    fillProfile(&profile, channelLayouts, sampleRates);
     return profile;
 }
 
@@ -125,6 +140,8 @@
 //  * "primary output", PRIMARY, 1 max open, 1 max active stream
 //    - profile PCM 16-bit; MONO, STEREO; 44100, 48000
 //    - profile PCM 24-bit; MONO, STEREO; 44100, 48000
+//  * "compressed offload", DIRECT|COMPRESS_OFFLOAD|NON_BLOCKING, 1 max open, 1 max active stream
+//    - profile MP3; MONO, STEREO; 44100, 48000
 //  * "loopback output", stream count unlimited
 //    - profile PCM 24-bit; STEREO; 48000
 //  * "primary input", 2 max open, 2 max active streams
@@ -136,8 +153,8 @@
 //    - profile PCM 24-bit; STEREO; 48000
 //
 // Routes:
-//  "primary out" -> "Null"
-//  "primary out" -> "USB Out"
+//  "primary out", "compressed offload" -> "Null"
+//  "primary out", "compressed offload" -> "USB Out"
 //  "loopback out" -> "Loopback Out"
 //  "Zero", "USB In" -> "primary input"
 //  "Loopback In" -> "loopback input"
@@ -183,6 +200,18 @@
                                       standardPcmAudioProfiles.end());
         c.ports.push_back(primaryOutMix);
 
+        AudioPort compressedOffloadOutMix =
+                createPort(c.nextPortId++, "compressed offload",
+                           1 << static_cast<int32_t>(AudioOutputFlags::DIRECT) |
+                                   1 << static_cast<int32_t>(AudioOutputFlags::COMPRESS_OFFLOAD) |
+                                   1 << static_cast<int32_t>(AudioOutputFlags::NON_BLOCKING),
+                           false, createPortMixExt(1, 1));
+        compressedOffloadOutMix.profiles.push_back(
+                createProfile(::android::MEDIA_MIMETYPE_AUDIO_MPEG,
+                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
+                              {44100, 48000}));
+        c.ports.push_back(compressedOffloadOutMix);
+
         AudioPort loopOutDevice = createPort(c.nextPortId++, "Loopback Out", 0, false,
                                              createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0));
         loopOutDevice.profiles.push_back(
@@ -244,8 +273,10 @@
         c.ports.push_back(usbInDevice);
         c.connectedProfiles[usbInDevice.id] = standardPcmAudioProfiles;
 
-        c.routes.push_back(createRoute({primaryOutMix.id}, nullOutDevice.id));
-        c.routes.push_back(createRoute({primaryOutMix.id}, usbOutDevice.id));
+        c.routes.push_back(
+                createRoute({primaryOutMix.id, compressedOffloadOutMix.id}, nullOutDevice.id));
+        c.routes.push_back(
+                createRoute({primaryOutMix.id, compressedOffloadOutMix.id}, usbOutDevice.id));
         c.routes.push_back(createRoute({loopOutMix.id}, loopOutDevice.id));
         c.routes.push_back(createRoute({zeroInDevice.id, usbInDevice.id}, primaryInMix.id));
         c.routes.push_back(createRoute({loopInDevice.id}, loopInMix.id));
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 1bf7321..5b4d48a 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -405,6 +405,14 @@
                    << " does not correspond to an output mix port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
+    if (portConfigIt->flags.has_value() &&
+        ((portConfigIt->flags.value().get<AudioIoFlags::Tag::output>() &
+          1 << static_cast<int32_t>(AudioOutputFlags::COMPRESS_OFFLOAD)) != 0) &&
+        !in_offloadInfo.has_value()) {
+        LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+                   << " has COMPRESS_OFFLOAD flag set, requires offload info";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
     if (mStreams.count(in_portConfigId) != 0) {
         LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
                    << " already has a stream opened on it";