audio: Add support for dumping info from effect HAL modules

The implementation uses IBase::debug() method which can write
debugging info into the provided file descriptor (same model
as used for devices and streams).

Bug: 69939533
Test: adb shell dumpsys media.audio_flinger
Change-Id: I02a74b51977d105edf6f7e624ea26f866c965708
diff --git a/media/libaudiohal/impl/EffectHalHidl.cpp b/media/libaudiohal/impl/EffectHalHidl.cpp
index b0597b3..caf575c 100644
--- a/media/libaudiohal/impl/EffectHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectHalHidl.cpp
@@ -18,6 +18,7 @@
 //#define LOG_NDEBUG 0
 
 #include <common/all-versions/VersionUtils.h>
+#include <cutils/native_handle.h>
 #include <hwbinder/IPCThreadState.h>
 #include <media/EffectsFactoryApi.h>
 #include <utils/Log.h>
@@ -280,6 +281,15 @@
     return ret.isOk() ? analyzeResult(ret) : FAILED_TRANSACTION;
 }
 
+status_t EffectHalHidl::dump(int fd) {
+    if (mEffect == 0) return NO_INIT;
+    native_handle_t* hidlHandle = native_handle_create(1, 0);
+    hidlHandle->data[0] = fd;
+    Return<void> ret = mEffect->debug(hidlHandle, {} /* options */);
+    native_handle_delete(hidlHandle);
+    return ret.isOk() ? OK : FAILED_TRANSACTION;
+}
+
 status_t EffectHalHidl::getConfigImpl(
         uint32_t cmdCode, uint32_t *replySize, void *pReplyData) {
     if (replySize == NULL || *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
diff --git a/media/libaudiohal/impl/EffectHalHidl.h b/media/libaudiohal/impl/EffectHalHidl.h
index 9d9f707..1f238c0 100644
--- a/media/libaudiohal/impl/EffectHalHidl.h
+++ b/media/libaudiohal/impl/EffectHalHidl.h
@@ -61,6 +61,8 @@
     // Whether it's a local implementation.
     virtual bool isLocal() const { return false; }
 
+    virtual status_t dump(int fd);
+
     uint64_t effectId() const { return mEffectId; }
 
     static void effectDescriptorToHal(
diff --git a/media/libaudiohal/include/media/audiohal/EffectHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
index 92622aa..03165bd 100644
--- a/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
@@ -55,6 +55,8 @@
     // Whether it's a local implementation.
     virtual bool isLocal() const = 0;
 
+    virtual status_t dump(int fd) = 0;
+
   protected:
     // Subclasses can not be constructed directly by clients.
     EffectHalInterface() {}
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 8455e54..ecaeb52 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1500,6 +1500,11 @@
 
     write(fd, result.string(), result.length());
 
+    if (mEffectInterface != 0) {
+        dprintf(fd, "\tEffect ID %d HAL dump:\n", mId);
+        (void)mEffectInterface->dump(fd);
+    }
+
     if (locked) {
         mLock.unlock();
     }