Effect AIDL: queryEffect with Descriptor for all effects implementation

Add queryEffect for effect libraries.
Change Descriptor in each effect implementation to be static so
extern C function can access.
Update vts test cases.

Bug: 261646550
Test: atest VtsHalAudioEffectTargetTest
Change-Id: I8e5d7240db31a0d09b17541c39d9e4c15e1eea73
diff --git a/audio/aidl/default/EffectFactory.cpp b/audio/aidl/default/EffectFactory.cpp
index 74ed780..7ae9a66 100644
--- a/audio/aidl/default/EffectFactory.cpp
+++ b/audio/aidl/default/EffectFactory.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+#include <iterator>
+#include <memory>
+#include <tuple>
+#include "include/effect-impl/EffectTypes.h"
 #define LOG_TAG "AHAL_EffectFactory"
 #include <dlfcn.h>
 #include <unordered_set>
@@ -51,15 +55,29 @@
 ndk::ScopedAStatus Factory::queryEffects(const std::optional<AudioUuid>& in_type_uuid,
                                          const std::optional<AudioUuid>& in_impl_uuid,
                                          const std::optional<AudioUuid>& in_proxy_uuid,
-                                         std::vector<Descriptor::Identity>* _aidl_return) {
-    std::copy_if(
-            mIdentitySet.begin(), mIdentitySet.end(), std::back_inserter(*_aidl_return),
-            [&](auto& desc) {
-                return (!in_type_uuid.has_value() || in_type_uuid.value() == desc.type) &&
-                       (!in_impl_uuid.has_value() || in_impl_uuid.value() == desc.uuid) &&
-                       (!in_proxy_uuid.has_value() ||
-                        (desc.proxy.has_value() && in_proxy_uuid.value() == desc.proxy.value()));
-            });
+                                         std::vector<Descriptor>* _aidl_return) {
+    // get the matching list
+    std::vector<Descriptor::Identity> idList;
+    std::copy_if(mIdentitySet.begin(), mIdentitySet.end(), std::back_inserter(idList),
+                 [&](auto& id) {
+                     return (!in_type_uuid.has_value() || in_type_uuid.value() == id.type) &&
+                            (!in_impl_uuid.has_value() || in_impl_uuid.value() == id.uuid) &&
+                            (!in_proxy_uuid.has_value() ||
+                             (id.proxy.has_value() && in_proxy_uuid.value() == id.proxy.value()));
+                 });
+    // query through the matching list
+    for (const auto& id : idList) {
+        if (mEffectLibMap.count(id.uuid)) {
+            Descriptor desc;
+            auto& entry = mEffectLibMap[id.uuid];
+            getDlSyms(entry);
+            auto& libInterface = std::get<kMapEntryInterfaceIndex>(entry);
+            RETURN_IF(!libInterface || !libInterface->queryEffectFunc, EX_NULL_POINTER,
+                      "dlNullQueryEffectFunc");
+            RETURN_IF_BINDER_EXCEPTION(libInterface->queryEffectFunc(&id.uuid, &desc));
+            _aidl_return->emplace_back(std::move(desc));
+        }
+    }
     return ndk::ScopedAStatus::ok();
 }
 
@@ -74,37 +92,16 @@
     return ndk::ScopedAStatus::ok();
 }
 
-#define RETURN_IF_BINDER_EXCEPTION(functor)                                 \
-    {                                                                       \
-        binder_exception_t exception = functor;                             \
-        if (EX_NONE != exception) {                                         \
-            LOG(ERROR) << #functor << ":  failed with error " << exception; \
-            return ndk::ScopedAStatus::fromExceptionCode(exception);        \
-        }                                                                   \
-    }
-
 ndk::ScopedAStatus Factory::createEffect(const AudioUuid& in_impl_uuid,
                                          std::shared_ptr<IEffect>* _aidl_return) {
     LOG(DEBUG) << __func__ << ": UUID " << in_impl_uuid.toString();
     if (mEffectLibMap.count(in_impl_uuid)) {
-        auto& lib = mEffectLibMap[in_impl_uuid];
-        // didn't do dlsym yet
-        if (nullptr == lib.second) {
-            void* libHandle = lib.first.get();
-            auto dlInterface = std::make_unique<struct effect_dl_interface_s>();
-            dlInterface->createEffectFunc = (EffectCreateFunctor)dlsym(libHandle, "createEffect");
-            dlInterface->destroyEffectFunc =
-                    (EffectDestroyFunctor)dlsym(libHandle, "destroyEffect");
-            if (!dlInterface->createEffectFunc || !dlInterface->destroyEffectFunc) {
-                LOG(ERROR) << __func__
-                           << ": create or destroy symbol not exist in library: " << libHandle
-                           << " with dlerror: " << dlerror();
-                return ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
-            }
-            lib.second = std::move(dlInterface);
-        }
+        auto& entry = mEffectLibMap[in_impl_uuid];
+        getDlSyms(entry);
 
-        auto& libInterface = lib.second;
+        auto& libInterface = std::get<kMapEntryInterfaceIndex>(entry);
+        RETURN_IF(!libInterface || !libInterface->createEffectFunc, EX_NULL_POINTER,
+                  "dlNullcreateEffectFunc");
         std::shared_ptr<IEffect> effectSp;
         RETURN_IF_BINDER_EXCEPTION(libInterface->createEffectFunc(&in_impl_uuid, &effectSp));
         if (!effectSp) {
@@ -131,9 +128,10 @@
         auto& uuid = uuidIt->second;
         // find implementation library with UUID
         if (auto libIt = mEffectLibMap.find(uuid); libIt != mEffectLibMap.end()) {
-            if (libIt->second.second->destroyEffectFunc) {
-                RETURN_IF_BINDER_EXCEPTION(libIt->second.second->destroyEffectFunc(in_handle));
-            }
+            auto& interface = std::get<kMapEntryInterfaceIndex>(libIt->second);
+            RETURN_IF(!interface || !interface->destroyEffectFunc, EX_NULL_POINTER,
+                      "dlNulldestroyEffectFunc");
+            RETURN_IF_BINDER_EXCEPTION(interface->destroyEffectFunc(in_handle));
         } else {
             LOG(ERROR) << __func__ << ": UUID " << uuid.toString() << " does not exist in libMap!";
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
@@ -179,9 +177,13 @@
         return;
     }
 
-    LOG(DEBUG) << __func__ << " dlopen lib:" << libName << "\nimpl:" << impl.toString()
-               << "\nhandle:" << libHandle;
-    mEffectLibMap.insert({impl, std::make_pair(std::move(libHandle), nullptr)});
+    LOG(INFO) << __func__ << " dlopen lib:" << libName << "\nimpl:" << impl.toString()
+              << "\nhandle:" << libHandle;
+    auto interface = new effect_dl_interface_s{nullptr, nullptr, nullptr};
+    mEffectLibMap.insert(
+            {impl,
+             std::make_tuple(std::move(libHandle),
+                             std::unique_ptr<struct effect_dl_interface_s>(interface), libName)});
 }
 
 void Factory::createIdentityWithConfig(const EffectConfig::LibraryUuid& configLib,
@@ -226,4 +228,32 @@
     }
 }
 
+void Factory::getDlSyms(DlEntry& entry) {
+    auto& dlHandle = std::get<kMapEntryHandleIndex>(entry);
+    RETURN_VALUE_IF(!dlHandle, void(), "dlNullHandle");
+    // Get the reference of the DL interfaces in library map tuple.
+    auto& dlInterface = std::get<kMapEntryInterfaceIndex>(entry);
+    // return if interface already exist
+    if (!dlInterface->createEffectFunc) {
+        dlInterface->createEffectFunc = (EffectCreateFunctor)dlsym(dlHandle.get(), "createEffect");
+    }
+    if (!dlInterface->queryEffectFunc) {
+        dlInterface->queryEffectFunc = (EffectQueryFunctor)dlsym(dlHandle.get(), "queryEffect");
+    }
+    if (!dlInterface->destroyEffectFunc) {
+        dlInterface->destroyEffectFunc =
+                (EffectDestroyFunctor)dlsym(dlHandle.get(), "destroyEffect");
+    }
+
+    if (!dlInterface->createEffectFunc || !dlInterface->destroyEffectFunc ||
+        !dlInterface->queryEffectFunc) {
+        LOG(ERROR) << __func__ << ": create (" << dlInterface->createEffectFunc << "), query ("
+                   << dlInterface->queryEffectFunc << "), or destroy ("
+                   << dlInterface->destroyEffectFunc
+                   << ") not exist in library: " << std::get<kMapEntryLibNameIndex>(entry)
+                   << " handle: " << dlHandle << " with dlerror: " << dlerror();
+        return;
+    }
+}
+
 }  // namespace aidl::android::hardware::audio::effect