Restore Default Device Effects support with AIDL AudioHAL

Bug: 329395147
Test: atest CtsMediaAudioTestCases
Test: atest --test-mapping hardware/interfaces/audio/aidl/vts:presubmit

Change-Id: I0f4f680b4db4eaa69d6c6e9e7b897631ed94928b
Signed-off-by: François Gaffie <francois.gaffie@renault.com>
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl
index f6d6ee2..96d57d8 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl
@@ -40,5 +40,6 @@
   union Type {
     android.media.audio.common.AudioStreamType streamType = android.media.audio.common.AudioStreamType.INVALID;
     android.media.audio.common.AudioSource source;
+    android.media.audio.common.AudioDevice device;
   }
 }
diff --git a/audio/aidl/android/hardware/audio/effect/Processing.aidl b/audio/aidl/android/hardware/audio/effect/Processing.aidl
index cb77350..928ce16 100644
--- a/audio/aidl/android/hardware/audio/effect/Processing.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Processing.aidl
@@ -17,6 +17,7 @@
 package android.hardware.audio.effect;
 
 import android.hardware.audio.effect.Descriptor;
+import android.media.audio.common.AudioDevice;
 import android.media.audio.common.AudioSource;
 import android.media.audio.common.AudioStreamType;
 import android.media.audio.common.AudioUuid;
@@ -30,6 +31,7 @@
     union Type {
         AudioStreamType streamType = AudioStreamType.INVALID;
         AudioSource source;
+        AudioDevice device;
     }
 
     /**
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 844f1e9..f5b590b 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -203,6 +203,7 @@
     ],
     vendor: true,
     shared_libs: [
+        "libaudio_aidl_conversion_common_ndk",
         "libaudioaidlcommon",
         "libaudioutils",
         "libbase",
@@ -224,6 +225,7 @@
         "-Wextra",
         "-Werror",
         "-Wthread-safety",
+        "-DBACKEND_NDK",
     ],
 }
 
diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp
index eb0c015..9c335ba 100644
--- a/audio/aidl/default/EffectConfig.cpp
+++ b/audio/aidl/default/EffectConfig.cpp
@@ -18,6 +18,8 @@
 #include <string>
 #define LOG_TAG "AHAL_EffectConfig"
 #include <android-base/logging.h>
+#include <media/AidlConversionCppNdk.h>
+#include <system/audio.h>
 #include <system/audio_aidl_utils.h>
 #include <system/audio_effects/audio_effects_conf.h>
 #include <system/audio_effects/effect_uuid.h>
@@ -28,6 +30,10 @@
 #include <android/apexsupport.h>
 #endif
 
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
 using aidl::android::media::audio::common::AudioSource;
 using aidl::android::media::audio::common::AudioStreamType;
 using aidl::android::media::audio::common::AudioUuid;
@@ -76,6 +82,14 @@
                 registerFailure(parseProcessing(Processing::Type::streamType, xmlStream));
             }
         }
+
+        // Parse device effect chains
+        for (auto& xmlDeviceEffects : getChildren(xmlConfig, "deviceEffects")) {
+            for (auto& xmlDevice : getChildren(xmlDeviceEffects, "device")) {
+                // AudioDevice
+                registerFailure(parseProcessing(Processing::Type::device, xmlDevice));
+            }
+        }
     }
     LOG(DEBUG) << __func__ << " successfully parsed " << file << ", skipping " << mSkippedElements
                << " element(s)";
@@ -195,7 +209,8 @@
 }
 
 std::optional<Processing::Type> EffectConfig::stringToProcessingType(Processing::Type::Tag typeTag,
-                                                                     const std::string& type) {
+                                                                     const std::string& type,
+                                                                     const std::string& address) {
     // see list of audio stream types in audio_stream_type_t:
     // system/media/audio/include/system/audio_effects/audio_effects_conf.h
     // AUDIO_STREAM_DEFAULT_TAG is not listed here because according to SYS_RESERVED_DEFAULT in
@@ -238,6 +253,19 @@
         if (typeIter != sAudioSourceTable.end()) {
             return typeIter->second;
         }
+    } else if (typeTag == Processing::Type::device) {
+        audio_devices_t deviceType;
+        if (!audio_device_from_string(type.c_str(), &deviceType)) {
+            LOG(ERROR) << __func__ << "DeviceEffect: invalid type " << type;
+            return std::nullopt;
+        }
+        auto ret = ::aidl::android::legacy2aidl_audio_device_AudioDevice(deviceType, address);
+        if (!ret.ok()) {
+            LOG(ERROR) << __func__ << "DeviceEffect: Failed to get AudioDevice from type "
+                    << deviceType << ", address " << address;
+            return std::nullopt;
+        }
+        return ret.value();
     }
 
     return std::nullopt;
@@ -246,7 +274,10 @@
 bool EffectConfig::parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml) {
     LOG(VERBOSE) << __func__ << dump(xml);
     const char* typeStr = xml.Attribute("type");
-    auto aidlType = stringToProcessingType(typeTag, typeStr);
+    const char* addressStr = xml.Attribute("address");
+    // For device effect, device address is optional, match will be done for the given device type
+    // with empty address.
+    auto aidlType = stringToProcessingType(typeTag, typeStr, addressStr ? addressStr : "");
     RETURN_VALUE_IF(!aidlType.has_value(), false, "illegalStreamType");
     RETURN_VALUE_IF(0 != mProcessingMap.count(aidlType.value()), false, "duplicateStreamType");
 
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index 11683d2..a54f4db 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -140,4 +140,37 @@
         </postprocess>
     -->
 
+    <!-- Device pre/post processor configurations.
+         The device pre/post processor configuration is described in a deviceEffects element and
+         consists in a list of elements each describing pre/post processor settings for a given
+         device.
+         Each device element has a "type" attribute corresponding to the device type (e.g.
+         speaker, bus), an "address" attribute corresponding to the device address and contains a
+         list of "apply" elements indicating one effect to apply.
+         If the device is a source, only pre processing effects are expected, if the
+         device is a sink, only post processing effects are expected.
+         The effect to apply is designated by its name in the "effects" elements.
+         The effect will be enabled by default and the audio framework will automatically add
+         and activate the effect if the given port is involved in an audio patch.
+         If the patch is "HW", the effect must be HW accelerated.
+         Note:
+         -Device are not expected to be always attached. It may be loaded dynamically. As the device
+         effect manager is getting called on any audio patch operation, it will ensure if the given
+         device is involved in an audio patch and attach the requested effect.
+         -Address is optional. If not set, the match to instantiate the device effect will be done
+         using the given type and device (of this type) with empty address only.
+
+       <deviceEffects>
+           <device type="AUDIO_DEVICE_OUT_BUS" address="BUS00_USAGE_MAIN">
+               <apply effect="equalizer"/>
+           </device>
+           <device type="AUDIO_DEVICE_OUT_BUS" address="BUS04_USAGE_VOICE">
+               <apply effect="volume"/>
+           </device>
+           <device type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="bottom">
+               <apply effect="agc"/>
+           </device>
+       </deviceEffects>
+   -->
+
 </audio_effects_conf>
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
index 7456b99..60bb9be 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
@@ -81,7 +81,7 @@
     /* Parsed Effects result */
     std::unordered_map<std::string, struct EffectLibraries> mEffectsMap;
     /**
-     * For parsed pre/post processing result: {key: AudioStreamType/AudioSource, value:
+     * For parsed pre/post processing result: {key: AudioStreamType/AudioSource/AudioDevice, value:
      * EffectLibraries}
      */
     ProcessingLibrariesMap mProcessingMap;
@@ -110,7 +110,8 @@
     bool resolveLibrary(const std::string& path, std::string* resolvedPath);
 
     std::optional<Processing::Type> stringToProcessingType(Processing::Type::Tag typeTag,
-                                                           const std::string& type);
+                                                           const std::string& type,
+                                                           const std::string& address);
 };
 
 }  // namespace aidl::android::hardware::audio::effect