Add libAudioHal AIDL interface placeholder

Add cpp backend only and ndk backend only conversion.
Add placeholder for DeviceHalInterface and EffectHalInterface.
Add several EffectHalInterface test cases to help testing.

Bug: 261129656
Test: Flash to Cuttlefish and run cts
Test: Flash to Panther and run audio use cases.

Merged-In: Ieaf5d7d72bd7d3e1897964b7abe211456766f443
Change-Id: Ieaf5d7d72bd7d3e1897964b7abe211456766f443
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 7d8a859..37887f6 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -29,7 +29,7 @@
 #include <media/stagefright/foundation/MediaDefs.h>
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
-// Utilities
+// AIDL CPP/NDK backend to legacy audio data structure conversion utilities.
 
 #if defined(BACKEND_NDK)
 /* AIDL String generated in NDK is different than CPP */
@@ -846,8 +846,8 @@
         case Tag::indexMask:
             // Index masks do not have pre-defined values.
             if (const int bits = aidl.get<Tag::indexMask>();
-                    __builtin_popcount(bits) != 0 &&
-                    __builtin_popcount(bits) <= AUDIO_CHANNEL_COUNT_MAX) {
+                __builtin_popcount(bits) != 0 &&
+                __builtin_popcount(bits) <= (int)AUDIO_CHANNEL_COUNT_MAX) {
                 return audio_channel_mask_from_representation_and_bits(
                         AUDIO_CHANNEL_REPRESENTATION_INDEX, bits);
             } else {
@@ -1123,7 +1123,7 @@
     for (size_t i = 0; i < numValues; ++i) {
         legacy.values[i] = VALUE_OR_RETURN(convertIntegral<int>(aidl.values[i]));
     }
-    legacy.ramp_duration_ms = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.rampDurationMs));
+    legacy.ramp_duration_ms = VALUE_OR_RETURN(convertIntegral<int>(aidl.rampDurationMs));
     return legacy;
 }
 
@@ -1710,12 +1710,12 @@
     legacy.format = base.format;
     legacy.stream_type = VALUE_OR_RETURN(
             aidl2legacy_AudioStreamType_audio_stream_type_t(aidl.streamType));
-    legacy.bit_rate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.bitRatePerSecond));
+    legacy.bit_rate = VALUE_OR_RETURN(convertIntegral<int32_t>(aidl.bitRatePerSecond));
     legacy.duration_us = VALUE_OR_RETURN(convertIntegral<int64_t>(aidl.durationUs));
     legacy.has_video = aidl.hasVideo;
     legacy.is_streaming = aidl.isStreaming;
-    legacy.bit_width = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.bitWidth));
-    legacy.offload_buffer_size = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.offloadBufferSize));
+    legacy.bit_width = VALUE_OR_RETURN(convertIntegral<int32_t>(aidl.bitWidth));
+    legacy.offload_buffer_size = VALUE_OR_RETURN(convertIntegral<int32_t>(aidl.offloadBufferSize));
     legacy.usage = VALUE_OR_RETURN(aidl2legacy_AudioUsage_audio_usage_t(aidl.usage));
     legacy.encapsulation_mode = VALUE_OR_RETURN(
             aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(aidl.encapsulationMode));
@@ -1789,7 +1789,7 @@
 ConversionResult<audio_config_base_t>
 aidl2legacy_AudioConfigBase_audio_config_base_t(const AudioConfigBase& aidl, bool isInput) {
     audio_config_base_t legacy;
-    legacy.sample_rate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.sampleRate));
+    legacy.sample_rate = VALUE_OR_RETURN(convertIntegral<int>(aidl.sampleRate));
     legacy.channel_mask = VALUE_OR_RETURN(
             aidl2legacy_AudioChannelLayout_audio_channel_mask_t(aidl.channelMask, isInput));
     legacy.format = VALUE_OR_RETURN(aidl2legacy_AudioFormatDescription_audio_format_t(aidl.format));
diff --git a/media/audioaidlconversion/AidlConversionNdk.cpp b/media/audioaidlconversion/AidlConversionNdk.cpp
new file mode 100644
index 0000000..a3e39c7
--- /dev/null
+++ b/media/audioaidlconversion/AidlConversionNdk.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utility>
+
+#define LOG_TAG "AidlConversionNdk"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionNdk.h>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// AIDL NDK backend to legacy audio data structure conversion utilities.
+
+namespace aidl {
+namespace android {
+
+using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::Flags;
+
+using ::android::BAD_VALUE;
+using ::android::base::unexpected;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Converters
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(Flags::Type type) {
+    switch (type) {
+        case Flags::Type::INSERT:
+            return EFFECT_FLAG_TYPE_INSERT;
+        case Flags::Type::AUXILIARY:
+            return EFFECT_FLAG_TYPE_AUXILIARY;
+        case Flags::Type::REPLACE:
+            return EFFECT_FLAG_TYPE_REPLACE;
+        case Flags::Type::PRE_PROC:
+            return EFFECT_FLAG_TYPE_PRE_PROC;
+        case Flags::Type::POST_PROC:
+            return EFFECT_FLAG_TYPE_POST_PROC;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(Flags::Insert insert) {
+    switch (insert) {
+        case Flags::Insert::ANY:
+            return EFFECT_FLAG_INSERT_ANY;
+        case Flags::Insert::FIRST:
+            return EFFECT_FLAG_INSERT_FIRST;
+        case Flags::Insert::LAST:
+            return EFFECT_FLAG_INSERT_LAST;
+        case Flags::Insert::EXCLUSIVE:
+            return EFFECT_FLAG_INSERT_EXCLUSIVE;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Volume_uint32(Flags::Volume volume) {
+    switch (volume) {
+        case Flags::Volume::NONE:
+            return 0;
+        case Flags::Volume::CTRL:
+            return EFFECT_FLAG_VOLUME_CTRL;
+        case Flags::Volume::IND:
+            return EFFECT_FLAG_VOLUME_IND;
+        case Flags::Volume::MONITOR:
+            return EFFECT_FLAG_VOLUME_MONITOR;
+    }
+    return unexpected(BAD_VALUE);
+}
+ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
+        Flags::HardwareAccelerator hwAcceleratorMode) {
+    switch (hwAcceleratorMode) {
+        case Flags::HardwareAccelerator::NONE:
+            return 0;
+        case Flags::HardwareAccelerator::SIMPLE:
+            return EFFECT_FLAG_HW_ACC_SIMPLE;
+        case Flags::HardwareAccelerator::TUNNEL:
+            return EFFECT_FLAG_HW_ACC_TUNNEL;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Flags_uint32(Flags aidl) {
+    uint32_t legacy = 0;
+    legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Type_uint32(aidl.type));
+    legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Insert_uint32(aidl.insert));
+    legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Volume_uint32(aidl.volume));
+    legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_HardwareAccelerator_uint32(aidl.hwAcceleratorMode));
+
+    if (aidl.offloadIndication) {
+        legacy |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
+    }
+    if (aidl.deviceIndication) {
+        legacy |= EFFECT_FLAG_DEVICE_IND;
+    }
+    if (aidl.audioModeIndication) {
+        legacy |= EFFECT_FLAG_AUDIO_MODE_IND;
+    }
+    if (aidl.audioSourceIndication) {
+        legacy |= EFFECT_FLAG_AUDIO_SOURCE_IND;
+    }
+    if (aidl.noProcessing) {
+        legacy |= EFFECT_FLAG_NO_PROCESS;
+    }
+    return legacy;
+}
+
+ConversionResult<Flags::Type> legacy2aidl_uint32_Flags_Type(uint32_t legacy) {
+    switch (legacy & EFFECT_FLAG_TYPE_MASK) {
+        case EFFECT_FLAG_TYPE_INSERT:
+            return Flags::Type::INSERT;
+        case EFFECT_FLAG_TYPE_AUXILIARY:
+            return Flags::Type::AUXILIARY;
+        case EFFECT_FLAG_TYPE_REPLACE:
+            return Flags::Type::REPLACE;
+        case EFFECT_FLAG_TYPE_PRE_PROC:
+            return Flags::Type::PRE_PROC;
+        case EFFECT_FLAG_TYPE_POST_PROC:
+            return Flags::Type::POST_PROC;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::Insert> legacy2aidl_uint32_Flags_Insert(uint32_t legacy) {
+    switch (legacy & EFFECT_FLAG_INSERT_MASK) {
+        case EFFECT_FLAG_INSERT_ANY:
+            return Flags::Insert::ANY;
+        case EFFECT_FLAG_INSERT_FIRST:
+            return Flags::Insert::FIRST;
+        case EFFECT_FLAG_INSERT_LAST:
+            return Flags::Insert::LAST;
+        case EFFECT_FLAG_INSERT_EXCLUSIVE:
+            return Flags::Insert::EXCLUSIVE;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::Volume> legacy2aidl_uint32_Flags_Volume(uint32_t legacy) {
+    switch (legacy & EFFECT_FLAG_VOLUME_MASK) {
+        case EFFECT_FLAG_VOLUME_IND:
+            return Flags::Volume::IND;
+        case EFFECT_FLAG_VOLUME_MONITOR:
+            return Flags::Volume::MONITOR;
+        case EFFECT_FLAG_VOLUME_NONE:
+            return Flags::Volume::NONE;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::HardwareAccelerator> legacy2aidl_uint32_Flags_HardwareAccelerator(
+        uint32_t legacy) {
+    switch (legacy & EFFECT_FLAG_HW_ACC_MASK) {
+        case EFFECT_FLAG_HW_ACC_SIMPLE:
+            return Flags::HardwareAccelerator::SIMPLE;
+        case EFFECT_FLAG_HW_ACC_TUNNEL:
+            return Flags::HardwareAccelerator::TUNNEL;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags> legacy2aidl_uint32_Flags(uint32_t legacy) {
+    Flags aidl;
+
+    aidl.type = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Type(legacy));
+    aidl.insert = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Insert(legacy));
+    aidl.volume = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Volume(legacy));
+    aidl.hwAcceleratorMode = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_HardwareAccelerator(legacy));
+    aidl.offloadIndication = (legacy & EFFECT_FLAG_OFFLOAD_SUPPORTED);
+    aidl.deviceIndication = (legacy & EFFECT_FLAG_DEVICE_IND);
+    aidl.audioModeIndication = (legacy & EFFECT_FLAG_AUDIO_MODE_IND);
+    aidl.audioSourceIndication = (legacy & EFFECT_FLAG_AUDIO_SOURCE_IND);
+    aidl.noProcessing = (legacy & EFFECT_FLAG_NO_PROCESS);
+    return aidl;
+}
+
+ConversionResult<effect_descriptor_t>
+aidl2legacy_Descriptor_effect_descriptor(const Descriptor& aidl) {
+    effect_descriptor_t legacy;
+    legacy.type = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.common.id.type));
+    legacy.uuid = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.common.id.uuid));
+    // legacy descriptor doesn't have proxy information
+    // proxy = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.proxy));
+    legacy.apiVersion = EFFECT_CONTROL_API_VERSION;
+    legacy.flags = VALUE_OR_RETURN(aidl2legacy_Flags_uint32(aidl.common.flags));
+    legacy.cpuLoad = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.common.cpuLoad));
+    legacy.memoryUsage = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.common.memoryUsage));
+    RETURN_IF_ERROR(aidl2legacy_string(aidl.common.name, legacy.name, sizeof(legacy.name)));
+    RETURN_IF_ERROR(aidl2legacy_string(aidl.common.implementor, legacy.implementor,
+                                        sizeof(legacy.implementor)));
+    return legacy;
+}
+
+ConversionResult<Descriptor>
+legacy2aidl_effect_descriptor_Descriptor(const effect_descriptor_t& legacy) {
+    Descriptor aidl;
+    aidl.common.id.type = VALUE_OR_RETURN(legacy2aidl_audio_uuid_t_AudioUuid(legacy.type));
+    aidl.common.id.uuid = VALUE_OR_RETURN(legacy2aidl_audio_uuid_t_AudioUuid(legacy.uuid));
+    // legacy descriptor doesn't have proxy information
+    // aidl.common.id.proxy
+    aidl.common.flags = VALUE_OR_RETURN(legacy2aidl_uint32_Flags(legacy.flags));
+    aidl.common.cpuLoad = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.cpuLoad));
+    aidl.common.memoryUsage = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.memoryUsage));
+    aidl.common.name = VALUE_OR_RETURN(legacy2aidl_string(legacy.name, sizeof(legacy.name)));
+    aidl.common.implementor =
+            VALUE_OR_RETURN(legacy2aidl_string(legacy.implementor, sizeof(legacy.implementor)));
+    return aidl;
+}
+
+ConversionResult<buffer_config_t> aidl2legacy_AudioConfigBase_buffer_config_t(
+        const media::audio::common::AudioConfigBase& aidl, bool isInput) {
+    buffer_config_t legacy;
+
+    legacy.samplingRate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.sampleRate));
+    legacy.mask |= EFFECT_CONFIG_SMP_RATE;
+
+    legacy.channels = VALUE_OR_RETURN(
+            aidl2legacy_AudioChannelLayout_audio_channel_mask_t(aidl.channelMask, isInput));
+    legacy.mask |= EFFECT_CONFIG_CHANNELS;
+
+    legacy.format = VALUE_OR_RETURN(aidl2legacy_AudioFormatDescription_audio_format_t(aidl.format));
+    legacy.mask |= EFFECT_CONFIG_FORMAT;
+
+    return legacy;
+}
+
+ConversionResult<media::audio::common::AudioConfigBase>
+legacy2aidl_AudioConfigBase_buffer_config_t(const buffer_config_t& legacy, bool isInput) {
+    media::audio::common::AudioConfigBase aidl;
+
+    if (legacy.mask & EFFECT_CONFIG_SMP_RATE) {
+        aidl.sampleRate = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.samplingRate));
+    }
+    if (legacy.mask & EFFECT_CONFIG_CHANNELS) {
+        aidl.channelMask = VALUE_OR_RETURN(legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+                static_cast<audio_channel_mask_t>(legacy.channels), isInput));
+    }
+    if (legacy.mask & EFFECT_CONFIG_FORMAT) {
+        aidl.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormatDescription(
+                static_cast<audio_format_t>(legacy.format)));
+    }
+    return aidl;
+}
+
+}  // namespace android
+}  // aidl
diff --git a/media/audioaidlconversion/Android.bp b/media/audioaidlconversion/Android.bp
index 4a1df3a..86f455e 100644
--- a/media/audioaidlconversion/Android.bp
+++ b/media/audioaidlconversion/Android.bp
@@ -61,9 +61,9 @@
     host_supported: true,
     vendor_available: true,
     double_loadable: true,
-    min_sdk_version: "29",
     header_libs: [
         "libaudio_system_headers",
+        "libhardware_headers",
     ],
     shared_libs: [
         "libbase",
@@ -102,7 +102,9 @@
  */
 cc_library {
     name: "libaudio_aidl_conversion_common_cpp",
-    srcs: ["AidlConversionCppNdk.cpp"],
+    srcs: [
+        "AidlConversionCppNdk.cpp",
+    ],
     header_libs: [
         "libaudio_aidl_conversion_common_util_cpp",
     ],
@@ -113,6 +115,7 @@
         "audio_aidl_conversion_common_default",
         "latest_android_media_audio_common_types_cpp_export_shared",
     ],
+    min_sdk_version: "29",
 }
 
 /**
@@ -120,7 +123,10 @@
  */
 cc_library {
     name: "libaudio_aidl_conversion_common_ndk",
-    srcs: ["AidlConversionCppNdk.cpp"],
+    srcs: [
+        "AidlConversionCppNdk.cpp",
+        "AidlConversionNdk.cpp",
+    ],
     header_libs: [
         "libaudio_aidl_conversion_common_util_ndk",
     ],
@@ -129,12 +135,16 @@
     ],
     defaults: [
         "audio_aidl_conversion_common_default",
+        "latest_android_hardware_audio_common_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
         "latest_android_media_audio_common_types_ndk_shared",
     ],
     shared_libs: [
         "libbinder_ndk",
+        "libbase",
     ],
     cflags: [
         "-DBACKEND_NDK",
     ],
+    min_sdk_version: "31", //AParcelableHolder has been introduced in 31
 }
diff --git a/media/audioaidlconversion/include/media/AidlConversionNdk.h b/media/audioaidlconversion/include/media/AidlConversionNdk.h
new file mode 100644
index 0000000..a3176f6
--- /dev/null
+++ b/media/audioaidlconversion/include/media/AidlConversionNdk.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+/**
+ * Can only handle conversion between AIDL (NDK backend) and legacy type.
+ */
+#include <hardware/audio_effect.h>
+#include <media/AidlConversionUtil.h>
+#include <system/audio_effect.h>
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+
+namespace aidl {
+namespace android {
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(
+        ::aidl::android::hardware::audio::effect::Flags::Type type);
+ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(
+        ::aidl::android::hardware::audio::effect::Flags::Insert insert);
+ConversionResult<uint32_t> aidl2legacy_Flags_Volume_uint32(
+        ::aidl::android::hardware::audio::effect::Flags::Volume volume);
+ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
+        ::aidl::android::hardware::audio::effect::Flags::HardwareAccelerator hwAcceleratorMode);
+ConversionResult<uint32_t> aidl2legacy_Flags_uint32(
+        const ::aidl::android::hardware::audio::effect::Flags aidl);
+
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::Type>
+legacy2aidl_uint32_Flags_Type(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::Insert>
+legacy2aidl_uint32_Flags_Insert(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::Volume>
+legacy2aidl_uint32_Flags_Volume(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::HardwareAccelerator>
+legacy2aidl_uint32_Flags_HardwareAccelerator(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags> legacy2aidl_uint32_Flags(
+        uint32_t hal);
+
+ConversionResult<effect_descriptor_t> aidl2legacy_Descriptor_effect_descriptor(
+        const ::aidl::android::hardware::audio::effect::Descriptor& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Descriptor>
+legacy2aidl_effect_descriptor_Descriptor(const effect_descriptor_t& hal);
+
+ConversionResult<buffer_config_t> aidl2legacy_AudioConfigBase_buffer_config_t(
+        const media::audio::common::AudioConfigBase& aidl, bool isInput);
+ConversionResult<media::audio::common::AudioConfigBase> legacy2aidl_AudioConfigBase_buffer_config_t(
+        const buffer_config_t& legacy, bool isInput);
+
+}  // namespace android
+}  // namespace aidl
diff --git a/media/audioaidlconversion/include/media/AidlConversionUtil.h b/media/audioaidlconversion/include/media/AidlConversionUtil.h
index 95daa4a..28c7522 100644
--- a/media/audioaidlconversion/include/media/AidlConversionUtil.h
+++ b/media/audioaidlconversion/include/media/AidlConversionUtil.h
@@ -25,7 +25,9 @@
 #include <error/Result.h>
 
 #if defined(BACKEND_NDK)
+#include <android/binder_enums.h>
 #include <android/binder_status.h>
+
 namespace aidl {
 #else
 #include <binder/Enums.h>
diff --git a/media/libaaudio/fuzzer/Android.bp b/media/libaaudio/fuzzer/Android.bp
index f5d2939..3393930 100644
--- a/media/libaaudio/fuzzer/Android.bp
+++ b/media/libaaudio/fuzzer/Android.bp
@@ -39,6 +39,7 @@
         "libaudiomanager",
         "libaudiopolicy",
         "libaudioclient_aidl_conversion",
+        "libaudio_aidl_conversion_common_cpp",
         "libutils",
     ],
     static_libs: [
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index d51fedb..bcaaa6e 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -128,6 +128,7 @@
         "audiopolicy-types-aidl-cpp",
         "av-types-aidl-cpp",
         "capture_state_listener-aidl-cpp",
+        "libaudio_aidl_conversion_common_cpp",
         "libaudioclient_aidl_conversion",
         "libaudiofoundation",
         "libaudioutils",
diff --git a/media/libaudioclient/fuzzer/Android.bp b/media/libaudioclient/fuzzer/Android.bp
index dd3e3ba..b1feb60 100644
--- a/media/libaudioclient/fuzzer/Android.bp
+++ b/media/libaudioclient/fuzzer/Android.bp
@@ -56,6 +56,7 @@
         "av-types-aidl-cpp",
         "capture_state_listener-aidl-cpp",
         "libaudioclient_aidl_conversion",
+        "libaudio_aidl_conversion_common_cpp",
         "libaudioflinger",
         "libaudiofoundation",
         "libaudiomanager",
diff --git a/media/libaudioclient/tests/Android.bp b/media/libaudioclient/tests/Android.bp
index cbcef12..dcb6c25 100644
--- a/media/libaudioclient/tests/Android.bp
+++ b/media/libaudioclient/tests/Android.bp
@@ -110,6 +110,7 @@
         "capture_state_listener-aidl-cpp",
         "framework-permission-aidl-cpp",
         "libaudioclient_aidl_conversion",
+        "libaudio_aidl_conversion_common_cpp",
         "libbase",
         "libbinder",
         "libcgrouprc",
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 320c639..f47dd0b 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -43,6 +43,7 @@
     header_libs: [
         "libaudiohal_headers",
         "libbase_headers",
+        "liberror_headers",
         "libmediautils_headers",
     ]
 }
@@ -74,8 +75,4 @@
     name: "libaudiohal_headers",
 
     export_include_dirs: ["include"],
-
-    // This is needed because the stream interface includes media/MicrophoneInfo.h
-    header_libs: ["av-headers"],
-    export_header_lib_headers: ["av-headers"],
 }
diff --git a/media/libaudiohal/FactoryHal.cpp b/media/libaudiohal/FactoryHal.cpp
index 16d591c..84ac64c 100644
--- a/media/libaudiohal/FactoryHal.cpp
+++ b/media/libaudiohal/FactoryHal.cpp
@@ -141,7 +141,7 @@
     auto halType = version.getType();
     if (halType == AudioHalVersionInfo::Type::AIDL) {
         return hasAidlHalService(interface, version);
-    } else if (version.getType() == AudioHalVersionInfo::Type::HIDL) {
+    } else if (halType == AudioHalVersionInfo::Type::HIDL) {
         return hasHidlHalService(interface, version);
     } else {
         ALOGE("HalType not supported %s", version.toString().c_str());
@@ -164,9 +164,9 @@
     auto siblingInterfaceMap = isDevice ? sEffectsHALInterfaces : sDevicesHALInterfaces;
     auto ifaceVersionIt = findMostRecentVersion(interfaceMap);
     auto siblingVersionIt = findMostRecentVersion(siblingInterfaceMap);
-    if (ifaceVersionIt != sAudioHALVersions.end() &&
-        siblingVersionIt != sAudioHALVersions.end() &&
-        // same major version
+    if (ifaceVersionIt != sAudioHALVersions.end() && siblingVersionIt != sAudioHALVersions.end() &&
+        // same HAL type (HIDL/AIDL) and same major version
+        ifaceVersionIt->getType() == siblingVersionIt->getType() &&
         ifaceVersionIt->getMajorVersion() == siblingVersionIt->getMajorVersion()) {
         void* rawInterface;
         if (createHalService(std::max(*ifaceVersionIt, *siblingVersionIt), isDevice,
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index bb5601f..d151817 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -241,15 +241,34 @@
         "libaudiohal_default",
         "latest_android_hardware_audio_common_ndk_shared",
         "latest_android_hardware_audio_core_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_static",
+        "latest_android_media_audio_common_types_ndk_shared",
     ],
     srcs: [
         "DevicesFactoryHalEntry.cpp",
         "DevicesFactoryHalAidl.cpp",
+        "EffectBufferHalAidl.cpp",
+        "EffectHalAidl.cpp",
         "EffectsFactoryHalAidl.cpp",
         "EffectsFactoryHalEntry.cpp",
     ],
+    static_libs: [
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
+    ],
     shared_libs: [
         "libbinder_ndk",
-    ]
+        "libaudio_aidl_conversion_common_ndk",
+    ],
+    header_libs: [
+        "libaudio_aidl_conversion_common_util_ndk",
+        "libaudio_system_headers",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+        "-DBACKEND_NDK",
+    ],
 }
\ No newline at end of file
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
new file mode 100644
index 0000000..d85d960
--- /dev/null
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DeviceHalAidl"
+
+#include "DeviceHalAidl.h"
+
+status_t DeviceHalAidl::getSupportedDevices(uint32_t* devices) {
+    ALOGE("%s not implemented yet devices %p", __func__, devices);
+    return OK;
+}
+
+status_t DeviceHalAidl::initCheck() {
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t DeviceHalAidl::setVoiceVolume(float volume) {
+    mVoiceVolume = volume;
+    ALOGE("%s not implemented yet %f", __func__, volume);
+    return OK;
+}
+
+status_t DeviceHalAidl::setMasterVolume(float volume) {
+    mMasterVolume = volume;
+    ALOGE("%s not implemented yet %f", __func__, volume);
+    return OK;
+}
+
+status_t DeviceHalAidl::getMasterVolume(float *volume) {
+    *volume = mMasterVolume;
+    ALOGE("%s not implemented yet %f", __func__, *volume);
+    return OK;
+}
+
+status_t DeviceHalAidl::setMode(audio_mode_t mode) {
+    ALOGE("%s not implemented yet %u", __func__, mode);
+    return OK;
+}
+
+status_t DeviceHalAidl::setMicMute(bool state) {
+    mMicMute = state;
+    ALOGE("%s not implemented yet %d", __func__, state);
+    return OK;
+}
+status_t DeviceHalAidl::getMicMute(bool *state) {
+    *state = mMicMute;
+    ALOGE("%s not implemented yet %d", __func__, *state);
+    return OK;
+}
+status_t DeviceHalAidl::setMasterMute(bool state) {
+    mMasterMute = state;
+    ALOGE("%s not implemented yet %d", __func__, state);
+    return OK;
+}
+status_t DeviceHalAidl::getMasterMute(bool *state) {
+    *state = mMasterMute;
+    ALOGE("%s not implemented yet %d", __func__, *state);
+    return OK;
+}
+
+status_t DeviceHalAidl::setParameters(const String8& kvPairs) {
+    ALOGE("%s not implemented yet %s", __func__, kvPairs.c_str());
+    return OK;
+}
+
+status_t DeviceHalAidl::getParameters(const String8& keys, String8 *values) {
+    ALOGE("%s not implemented yet %s %s", __func__, keys.c_str(), values->c_str());
+    return OK;
+}
+
+status_t DeviceHalAidl::getInputBufferSize(const struct audio_config* config, size_t* size) {
+    ALOGE("%s not implemented yet %p %zu", __func__, config, *size);
+    return OK;
+}
+
+status_t DeviceHalAidl::openOutputStream(audio_io_handle_t handle, audio_devices_t devices,
+                                         audio_output_flags_t flags, struct audio_config* config,
+                                         const char* address,
+                                         sp<StreamOutHalInterface>* outStream) {
+    ALOGE("%s not implemented yet %d %u %u %p %s %p", __func__, handle, devices, flags, config,
+          address, outStream);
+    return OK;
+}
+
+status_t DeviceHalAidl::openInputStream(audio_io_handle_t handle, audio_devices_t devices,
+                                        struct audio_config* config, audio_input_flags_t flags,
+                                        const char* address, audio_source_t source,
+                                        audio_devices_t outputDevice,
+                                        const char* outputDeviceAddress,
+                                        sp<StreamInHalInterface>* inStream) {
+    ALOGE("%s not implemented yet %d %u %u %u %p %s %s %p %d", __func__, handle, devices,
+          outputDevice, flags, config, address, outputDeviceAddress, inStream, source);
+    return OK;
+}
+
+status_t DeviceHalAidl::supportsAudioPatches(bool* supportsPatches) {
+    *supportsPatches = true;
+    return OK;
+}
+
+status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources,
+                                         const struct audio_port_config* sources,
+                                         unsigned int num_sinks,
+                                         const struct audio_port_config* sinks,
+                                         audio_patch_handle_t* patch) {
+    ALOGE("%s not implemented yet %d %p %d %p %p", __func__, num_sources, sources, num_sinks,
+            sinks, patch);
+    return OK;
+}
+
+status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch) {
+    ALOGE("%s not implemented yet patch %d", __func__, patch);
+    return OK;
+}
+
+status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config) {
+    ALOGE("%s not implemented yet config %p", __func__, config);
+    return OK;
+}
+
+status_t DeviceHalAidl::getMicrophones(
+        std::vector<audio_microphone_characteristic_t>* microphones) {
+    ALOGE("%s not implemented yet microphones %p", __func__, microphones);
+    return OK;
+}
+
+status_t DeviceHalAidl::addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) {
+    if (!effect) {
+        return BAD_VALUE;
+    }
+    ALOGE("%s not implemented yet device %d", __func__, device);
+    return OK;
+}
+status_t DeviceHalAidl::removeDeviceEffect(audio_port_handle_t device,
+                            sp<EffectHalInterface> effect) {
+    if (!effect) {
+        return BAD_VALUE;
+    }
+    ALOGE("%s not implemented yet device %d", __func__, device);
+    return OK;
+}
+
+status_t DeviceHalAidl::getMmapPolicyInfos(
+        media::audio::common::AudioMMapPolicyType policyType __unused,
+        std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos __unused) {
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+int32_t DeviceHalAidl::getAAudioMixerBurstCount() {
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+int32_t DeviceHalAidl::getAAudioHardwareBurstMinUsec() {
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+error::Result<audio_hw_sync_t> DeviceHalAidl::getHwAvSync() {
+    ALOGE("%s not implemented yet", __func__);
+    return base::unexpected(INVALID_OPERATION);
+}
+
+status_t DeviceHalAidl::dump(int __unused, const Vector<String16>& __unused) {
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+};
+
+int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) override {
+    ALOGE("%s not implemented yet", __func__);
+    return INVALID_OPERATION;
+}
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
new file mode 100644
index 0000000..5e8a8dd
--- /dev/null
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <media/audiohal/DeviceHalInterface.h>
+#include <media/audiohal/EffectHalInterface.h>
+
+#include <aidl/android/hardware/audio/core/BpModule.h>
+
+namespace android {
+
+class DeviceHalAidl : public DeviceHalInterface {
+  public:
+    // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
+    status_t getSupportedDevices(uint32_t *devices) override;
+
+    // Check to see if the audio hardware interface has been initialized.
+    status_t initCheck() override;
+
+    // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
+    status_t setVoiceVolume(float volume) override;
+
+    // Set the audio volume for all audio activities other than voice call.
+    status_t setMasterVolume(float volume) override;
+
+    // Get the current master volume value for the HAL.
+    status_t getMasterVolume(float *volume) override;
+
+    // Called when the audio mode changes.
+    status_t setMode(audio_mode_t mode) override;
+
+    // Muting control.
+    status_t setMicMute(bool state) override;
+
+    status_t getMicMute(bool* state) override;
+
+    status_t setMasterMute(bool state) override;
+
+    status_t getMasterMute(bool *state) override;
+
+    // Set global audio parameters.
+    status_t setParameters(const String8& kvPairs) override;
+
+    // Get global audio parameters.
+    status_t getParameters(const String8& keys, String8 *values) override;
+
+    // Returns audio input buffer size according to parameters passed.
+    status_t getInputBufferSize(const struct audio_config* config, size_t* size) override;
+
+    // Creates and opens the audio hardware output stream. The stream is closed
+    // by releasing all references to the returned object.
+    status_t openOutputStream(audio_io_handle_t handle, audio_devices_t devices,
+                              audio_output_flags_t flags, struct audio_config* config,
+                              const char* address, sp<StreamOutHalInterface>* outStream) override;
+
+    // Creates and opens the audio hardware input stream. The stream is closed
+    // by releasing all references to the returned object.
+    status_t openInputStream(audio_io_handle_t handle, audio_devices_t devices,
+                             struct audio_config* config, audio_input_flags_t flags,
+                             const char* address, audio_source_t source,
+                             audio_devices_t outputDevice, const char* outputDeviceAddress,
+                             sp<StreamInHalInterface>* inStream) override;
+
+    // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
+    status_t supportsAudioPatches(bool* supportsPatches) override;
+
+    // Creates an audio patch between several source and sink ports.
+    status_t createAudioPatch(unsigned int num_sources, const struct audio_port_config* sources,
+                              unsigned int num_sinks, const struct audio_port_config* sinks,
+                              audio_patch_handle_t* patch) override;
+
+    // Releases an audio patch.
+    status_t releaseAudioPatch(audio_patch_handle_t patch) override;
+
+    // Set audio port configuration.
+    status_t setAudioPortConfig(const struct audio_port_config* config) override;
+
+    // List microphones
+    status_t getMicrophones(std::vector<audio_microphone_characteristic_t>* microphones);
+
+    status_t addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+
+    status_t removeDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+
+    status_t getMmapPolicyInfos(media::audio::common::AudioMMapPolicyType policyType __unused,
+                                std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos
+                                        __unused) override;
+
+    int32_t getAAudioMixerBurstCount() override;
+
+    int32_t getAAudioHardwareBurstMinUsec() override;
+
+    error::Result<audio_hw_sync_t> getHwAvSync() override;
+
+    status_t dump(int __unused, const Vector<String16>& __unused) override;
+
+    int32_t supportsBluetoothVariableLatency(bool* supports __unused) override;
+
+  private:
+    friend class DevicesFactoryHalAidl;
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mCore;
+    float mMasterVolume = 0.0f;
+    float mVoiceVolume = 0.0f;
+    bool mMasterMute = false;
+    bool mMicMute = false;
+
+    // Can not be constructed directly by clients.
+    explicit DeviceHalAidl(
+            const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& core)
+        : mCore(core) {}
+
+    // The destructor automatically closes the device.
+    ~DeviceHalAidl();
+};
+
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 0cdf621..be063ab 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -459,12 +459,13 @@
 
 #if MAJOR_VERSION == 2
 status_t DeviceHalHidl::getMicrophones(
-        std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
+        std::vector<audio_microphone_characteristic_t> *microphonesInfo __unused) {
     if (mDevice == 0) return NO_INIT;
     return INVALID_OPERATION;
 }
 #elif MAJOR_VERSION >= 4
-status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
+status_t DeviceHalHidl::getMicrophones(
+        std::vector<audio_microphone_characteristic_t> *microphonesInfo) {
     TIME_CHECK();
     if (mDevice == 0) return NO_INIT;
     Result retval;
@@ -475,8 +476,7 @@
             audio_microphone_characteristic_t dst;
             //convert
             (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
-            media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
-            microphonesInfo->push_back(microphone);
+            microphonesInfo->push_back(dst);
         }
     });
     return processReturn("getMicrophones", ret, retval);
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index 3e33609..052eb65 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -30,87 +30,74 @@
 {
   public:
     // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
-    virtual status_t getSupportedDevices(uint32_t *devices);
+    status_t getSupportedDevices(uint32_t *devices) override;
 
     // Check to see if the audio hardware interface has been initialized.
-    virtual status_t initCheck();
+    status_t initCheck() override;
 
     // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
-    virtual status_t setVoiceVolume(float volume);
+    status_t setVoiceVolume(float volume) override;
 
     // Set the audio volume for all audio activities other than voice call.
-    virtual status_t setMasterVolume(float volume);
+    status_t setMasterVolume(float volume) override;
 
     // Get the current master volume value for the HAL.
-    virtual status_t getMasterVolume(float *volume);
+    status_t getMasterVolume(float *volume) override;
 
     // Called when the audio mode changes.
-    virtual status_t setMode(audio_mode_t mode);
+    status_t setMode(audio_mode_t mode) override;
 
     // Muting control.
-    virtual status_t setMicMute(bool state);
-    virtual status_t getMicMute(bool *state);
-    virtual status_t setMasterMute(bool state);
-    virtual status_t getMasterMute(bool *state);
+    status_t setMicMute(bool state) override;
+    status_t getMicMute(bool *state) override;
+    status_t setMasterMute(bool state) override;
+    status_t getMasterMute(bool *state) override;
 
     // Set global audio parameters.
-    virtual status_t setParameters(const String8& kvPairs);
+    status_t setParameters(const String8& kvPairs) override;
 
     // Get global audio parameters.
-    virtual status_t getParameters(const String8& keys, String8 *values);
+    status_t getParameters(const String8& keys, String8 *values) override;
 
     // Returns audio input buffer size according to parameters passed.
-    virtual status_t getInputBufferSize(const struct audio_config *config,
-            size_t *size);
+    status_t getInputBufferSize(const struct audio_config* config, size_t* size) override;
 
     // Creates and opens the audio hardware output stream. The stream is closed
     // by releasing all references to the returned object.
-    virtual status_t openOutputStream(
-            audio_io_handle_t handle,
-            audio_devices_t devices,
-            audio_output_flags_t flags,
-            struct audio_config *config,
-            const char *address,
-            sp<StreamOutHalInterface> *outStream);
+    status_t openOutputStream(audio_io_handle_t handle, audio_devices_t devices,
+                              audio_output_flags_t flags, struct audio_config* config,
+                              const char* address, sp<StreamOutHalInterface>* outStream) override;
 
     // Creates and opens the audio hardware input stream. The stream is closed
     // by releasing all references to the returned object.
-    virtual status_t openInputStream(
-            audio_io_handle_t handle,
-            audio_devices_t devices,
-            struct audio_config *config,
-            audio_input_flags_t flags,
-            const char *address,
-            audio_source_t source,
-            audio_devices_t outputDevice,
-            const char *outputDeviceAddress,
-            sp<StreamInHalInterface> *inStream);
+    status_t openInputStream(audio_io_handle_t handle, audio_devices_t devices,
+                             struct audio_config* config, audio_input_flags_t flags,
+                             const char* address, audio_source_t source,
+                             audio_devices_t outputDevice, const char* outputDeviceAddress,
+                             sp<StreamInHalInterface>* inStream) override;
 
     // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
-    virtual status_t supportsAudioPatches(bool *supportsPatches);
+    status_t supportsAudioPatches(bool* supportsPatches) override;
 
     // Creates an audio patch between several source and sink ports.
-    virtual status_t createAudioPatch(
-            unsigned int num_sources,
-            const struct audio_port_config *sources,
-            unsigned int num_sinks,
-            const struct audio_port_config *sinks,
-            audio_patch_handle_t *patch);
+    status_t createAudioPatch(unsigned int num_sources, const struct audio_port_config* sources,
+                              unsigned int num_sinks, const struct audio_port_config* sinks,
+                              audio_patch_handle_t* patch) override;
 
     // Releases an audio patch.
-    virtual status_t releaseAudioPatch(audio_patch_handle_t patch);
+    status_t releaseAudioPatch(audio_patch_handle_t patch) override;
 
     // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port *port);
+    status_t getAudioPort(struct audio_port *port) override;
 
     // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port_v7 *port);
+    status_t getAudioPort(struct audio_port_v7 *port) override;
 
     // Set audio port configuration.
-    virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+    status_t setAudioPortConfig(const struct audio_port_config *config) override;
 
     // List microphones
-    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+    status_t getMicrophones(std::vector<audio_microphone_characteristic_t>* microphones) override;
 
     status_t addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
     status_t removeDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index 29fb558..b9ca164 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -17,18 +17,22 @@
 #define LOG_TAG "DevicesFactoryHalAidl"
 //#define LOG_NDEBUG 0
 
+#include <aidl/android/hardware/audio/core/IModule.h>
 #include <android/binder_manager.h>
+#include <memory>
 #include <utils/Log.h>
 
+#include "DeviceHalAidl.h"
 #include "DevicesFactoryHalAidl.h"
 
+using namespace ::aidl::android::hardware::audio::core;
 using ::android::detail::AudioHalVersionInfo;
 
 namespace android {
 
-DevicesFactoryHalAidl::DevicesFactoryHalAidl(std::shared_ptr<IConfig> iconfig) {
+DevicesFactoryHalAidl::DevicesFactoryHalAidl(std::shared_ptr<IConfig> iconfig)
+    : mIConfig(std::move(iconfig)) {
     ALOG_ASSERT(iconfig != nullptr, "Provided default IConfig service is NULL");
-    mIConfig = std::move(iconfig);
 }
 
 void DevicesFactoryHalAidl::onFirstRef() {
@@ -41,8 +45,18 @@
     if (name == nullptr || device == nullptr) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet", __func__);
+    ALOGE("%s not implemented yet %s", __func__, name);
     return INVALID_OPERATION;
+
+    // TODO: only support primary now ("default" means "primary")
+    if (strcmp(name, "primary") != 0) {
+        auto serviceName = std::string() + IModule::descriptor + "/default";
+        auto service = IModule::fromBinder(
+                ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+        ALOGW("%s fromBinder %s %s", __func__, IModule::descriptor, service ? "succ" : "fail");
+        *device = new DeviceHalAidl(service);
+    }
+    return OK;
 }
 
 status_t DevicesFactoryHalAidl::getHalPids(std::vector<pid_t> *pids) {
@@ -76,9 +90,14 @@
 
 // Main entry-point to the shared library.
 extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
+    auto serviceName = std::string(IConfig::descriptor) + "/default";
     auto service = IConfig::fromBinder(
-            ndk::SpAIBinder(AServiceManager_waitForService(IConfig::descriptor)));
-    return service ? new DevicesFactoryHalAidl(service) : nullptr;
+            ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+    if (!service) {
+        ALOGE("%s binder service %s not exist", __func__, serviceName.c_str());
+        return nullptr;
+    }
+    return new DevicesFactoryHalAidl(service);
 }
 
 } // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.h b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
index f4812af..71138a0 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
@@ -20,14 +20,13 @@
 #include <media/audiohal/DevicesFactoryHalInterface.h>
 #include <utils/RefBase.h>
 
-using namespace ::aidl::android::hardware::audio::core;
-
 namespace android {
 
 class DevicesFactoryHalAidl : public DevicesFactoryHalInterface
 {
   public:
-    explicit DevicesFactoryHalAidl(std::shared_ptr<IConfig> iConfig);
+    explicit DevicesFactoryHalAidl(
+            std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> iConfig);
     void onFirstRef() override;
 
     // Opens a device with the specified name. To close the device, it is
@@ -41,8 +40,8 @@
     android::detail::AudioHalVersionInfo getHalVersion() const override;
 
   private:
-    std::shared_ptr<IConfig> mIConfig;
-    virtual ~DevicesFactoryHalAidl() = default;
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> mIConfig;
+    ~DevicesFactoryHalAidl() = default;
 };
 
 } // namespace android
diff --git a/media/libaudiohal/impl/EffectBufferHalAidl.cpp b/media/libaudiohal/impl/EffectBufferHalAidl.cpp
new file mode 100644
index 0000000..5af8e24
--- /dev/null
+++ b/media/libaudiohal/impl/EffectBufferHalAidl.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectBufferHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include "EffectBufferHalAidl.h"
+
+namespace android {
+namespace effect {
+
+// static
+status_t EffectBufferHalAidl::allocate(size_t size, sp<EffectBufferHalInterface>* buffer) {
+    ALOGE("%s not implemented yet %zu %p", __func__, size, buffer);
+    return mirror(nullptr, size, buffer);
+}
+
+status_t EffectBufferHalAidl::mirror(void* external, size_t size,
+                                     sp<EffectBufferHalInterface>* buffer) {
+    // buffer->setExternalData(external);
+    ALOGW("%s not implemented yet %p %zu %p", __func__, external, size, buffer);
+    return OK;
+}
+
+EffectBufferHalAidl::EffectBufferHalAidl(size_t size)
+    : mBufferSize(size),
+      mFrameCountChanged(false),
+      mExternalData(nullptr),
+      mAudioBuffer{0, {nullptr}} {
+}
+
+EffectBufferHalAidl::~EffectBufferHalAidl() {
+}
+
+status_t EffectBufferHalAidl::init() {
+    ALOGW("%s not implemented yet", __func__);
+    return OK;
+}
+
+audio_buffer_t* EffectBufferHalAidl::audioBuffer() {
+    return &mAudioBuffer;
+}
+
+void* EffectBufferHalAidl::externalData() const {
+    return mExternalData;
+}
+
+void EffectBufferHalAidl::setFrameCount(size_t frameCount) {
+    mAudioBuffer.frameCount = frameCount;
+    mFrameCountChanged = true;
+}
+
+bool EffectBufferHalAidl::checkFrameCountChange() {
+    bool result = mFrameCountChanged;
+    mFrameCountChanged = false;
+    return result;
+}
+
+void EffectBufferHalAidl::setExternalData(void* external) {
+    mExternalData = external;
+}
+
+void EffectBufferHalAidl::update() {
+    ALOGW("%s not implemented yet", __func__);
+}
+
+void EffectBufferHalAidl::commit() {
+    ALOGW("%s not implemented yet", __func__);
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectBufferHalAidl.h b/media/libaudiohal/impl/EffectBufferHalAidl.h
new file mode 100644
index 0000000..f488708
--- /dev/null
+++ b/media/libaudiohal/impl/EffectBufferHalAidl.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <media/audiohal/EffectBufferHalInterface.h>
+#include <system/audio_effect.h>
+
+namespace android {
+namespace effect {
+
+class EffectBufferHalAidl : public EffectBufferHalInterface {
+  public:
+    static status_t allocate(size_t size, sp<EffectBufferHalInterface>* buffer);
+    static status_t mirror(void* external, size_t size, sp<EffectBufferHalInterface>* buffer);
+
+    audio_buffer_t* audioBuffer() override;
+    void* externalData() const override;
+
+    size_t getSize() const override { return mBufferSize; }
+
+    void setExternalData(void* external) override;
+    void setFrameCount(size_t frameCount) override;
+    bool checkFrameCountChange() override;
+
+    void update() override;
+    void commit() override;
+    void update(size_t size) override;
+    void commit(size_t size) override;
+
+  private:
+    friend class EffectBufferHalInterface;
+
+    const size_t mBufferSize;
+    bool mFrameCountChanged;
+    void* mExternalData;
+    audio_buffer_t mAudioBuffer;
+
+    // Can not be constructed directly by clients.
+    explicit EffectBufferHalAidl(size_t size);
+
+    ~EffectBufferHalAidl();
+
+    status_t init();
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
new file mode 100644
index 0000000..31c5ca5
--- /dev/null
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EffectHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionNdk.h>
+#include <media/audiohal/AudioHalUtils.h>
+#include <media/EffectsFactoryApi.h>
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
+
+#include "EffectHalAidl.h"
+
+#include <system/audio.h>
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+
+using ::aidl::android::hardware::audio::effect::CommandId;
+using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::IEffect;
+using ::aidl::android::hardware::audio::effect::State;
+using ::aidl::android::hardware::audio::effect::Parameter;
+
+namespace android {
+namespace effect {
+
+EffectHalAidl::EffectHalAidl(const std::shared_ptr<IEffect>& effect, uint64_t effectId,
+                             int32_t sessionId, int32_t ioId)
+    : mEffectId(effectId), mSessionId(sessionId), mIoId(ioId), mEffect(effect) {}
+
+EffectHalAidl::~EffectHalAidl() {}
+
+status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
+    if (buffer == nullptr) {
+        return BAD_VALUE;
+    }
+    ALOGW("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t EffectHalAidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
+    if (buffer == nullptr) {
+        return BAD_VALUE;
+    }
+    ALOGW("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t EffectHalAidl::process() {
+    ALOGW("%s not implemented yet", __func__);
+    // write to input FMQ here?
+    return OK;
+}
+
+// TODO: no one using, maybe deprecate this interface
+status_t EffectHalAidl::processReverse() {
+    ALOGW("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t EffectHalAidl::handleSetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+                                        uint32_t* replySize, void* pReplyData) {
+    if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || replySize == NULL ||
+        *replySize != sizeof(int32_t) || pReplyData == NULL) {
+        ALOGE("%s parameter error code %u", __func__, cmdCode);
+        return BAD_VALUE;
+    }
+
+    *static_cast<int32_t*>(pReplyData) = FAILED_TRANSACTION;
+    memcpy(&mConfig, pCmdData, cmdSize);
+
+    State state;
+    RETURN_IF_BINDER_FAIL(mEffect->getState(&state));
+    // effect not open yet, save settings locally
+    if (state != State::INIT) {
+        effect_config_t* legacyConfig = static_cast<effect_config_t*>(pCmdData);
+        // already open, apply latest settings
+        Parameter aidlParam;
+        Parameter::Common aidlCommon;
+        aidlCommon.input.base =
+                VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_AudioConfigBase_buffer_config_t(
+                        legacyConfig->inputCfg, true /* isInput */));
+        aidlCommon.output.base =
+                VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_AudioConfigBase_buffer_config_t(
+                        legacyConfig->outputCfg, false /* isInput */));
+        aidlCommon.session = mSessionId;
+        aidlCommon.ioHandle = mIoId;
+        Parameter::Id id;
+        id.set<Parameter::Id::commonTag>(Parameter::common);
+        aidlParam.set<Parameter::common>(aidlCommon);
+        RETURN_IF_BINDER_FAIL(mEffect->setParameter(aidlParam));
+    }
+    *(int*)pReplyData = 0;
+    *static_cast<int32_t*>(pReplyData) = OK;
+    return OK;
+}
+
+status_t EffectHalAidl::handleGetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+                                        uint32_t* replySize, void* pReplyData) {
+    if (pCmdData == NULL || cmdSize == 0 || replySize == NULL ||
+        *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
+        ALOGE("%s parameter error with cmdCode %d", __func__, cmdCode);
+        return BAD_VALUE;
+    }
+
+    *(effect_config_t*)pReplyData = mConfig;
+    return OK;
+}
+
+status_t EffectHalAidl::handleSetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+                                           uint32_t* replySize, void* pReplyData) {
+    ALOGW("%s not implemented yet", __func__);
+    if (pCmdData == NULL || cmdSize == 0 || replySize == NULL ||
+        *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
+        ALOGE("%s parameter error with cmdCode %d", __func__, cmdCode);
+        return BAD_VALUE;
+    }
+    return OK;
+}
+
+status_t EffectHalAidl::handleGetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+                                           uint32_t* replySize, void* pReplyData) {
+    ALOGW("%s not implemented yet", __func__);
+    if (pCmdData == NULL || cmdSize == 0 || replySize == NULL ||
+        *replySize != sizeof(effect_config_t) || pReplyData == NULL) {
+        ALOGE("%s parameter error with cmdCode %d", __func__, cmdCode);
+        return BAD_VALUE;
+    }
+    return OK;
+}
+
+status_t EffectHalAidl::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+                                uint32_t* replySize, void* pReplyData) {
+    ALOGW("%s code %d not implemented yet", __func__, cmdCode);
+    ::ndk::ScopedAStatus status;
+    switch (cmdCode) {
+        case EFFECT_CMD_INIT: {
+            // open with default effect_config_t (convert to Parameter.Common)
+            IEffect::OpenEffectReturn ret;
+            Parameter::Common common;
+            RETURN_IF_BINDER_FAIL(mEffect->open(common, std::nullopt, &ret));
+            return OK;
+        }
+        case EFFECT_CMD_SET_CONFIG:
+            return handleSetConfig(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+        case EFFECT_CMD_GET_CONFIG:
+            return handleGetConfig(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+        case EFFECT_CMD_RESET:
+            return mEffect->command(CommandId::RESET).getStatus();
+        case EFFECT_CMD_ENABLE:
+            return mEffect->command(CommandId::START).getStatus();
+        case EFFECT_CMD_DISABLE:
+            return mEffect->command(CommandId::STOP).getStatus();
+        case EFFECT_CMD_SET_PARAM:
+            return handleSetParameter(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+        case EFFECT_CMD_SET_PARAM_DEFERRED:
+        case EFFECT_CMD_SET_PARAM_COMMIT:
+            // TODO
+            return OK;
+        case EFFECT_CMD_GET_PARAM:
+            return handleGetParameter(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+        case EFFECT_CMD_SET_DEVICE:
+            return OK;
+        case EFFECT_CMD_SET_VOLUME:
+            return OK;
+        case EFFECT_CMD_SET_AUDIO_MODE:
+            return OK;
+        case EFFECT_CMD_SET_CONFIG_REVERSE:
+            return OK;
+        case EFFECT_CMD_SET_INPUT_DEVICE:
+            return OK;
+        case EFFECT_CMD_GET_CONFIG_REVERSE:
+            return OK;
+        case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS:
+            return OK;
+        case EFFECT_CMD_GET_FEATURE_CONFIG:
+            return OK;
+        case EFFECT_CMD_SET_FEATURE_CONFIG:
+            return OK;
+        case EFFECT_CMD_SET_AUDIO_SOURCE:
+            return OK;
+        case EFFECT_CMD_OFFLOAD:
+            return OK;
+        case EFFECT_CMD_DUMP:
+            return OK;
+        case EFFECT_CMD_FIRST_PROPRIETARY:
+            return OK;
+        default:
+            return INVALID_OPERATION;
+    }
+    return INVALID_OPERATION;
+}
+
+status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
+    ALOGW("%s %p", __func__, pDescriptor);
+    if (pDescriptor == nullptr) {
+        return BAD_VALUE;
+    }
+    Descriptor aidlDesc;
+    RETURN_IF_BINDER_FAIL(mEffect->getDescriptor(&aidlDesc));
+
+    *pDescriptor = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(aidlDesc));
+    return OK;
+}
+
+status_t EffectHalAidl::close() {
+    auto ret = mEffect->close();
+    ALOGI("%s %s", __func__, ret.getMessage());
+    return ret.getStatus();
+}
+
+status_t EffectHalAidl::dump(int fd) {
+    ALOGW("%s not implemented yet, fd %d", __func__, fd);
+    return OK;
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
new file mode 100644
index 0000000..76bb240
--- /dev/null
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <system/audio_effect.h>
+
+namespace android {
+namespace effect {
+
+class EffectHalAidl : public EffectHalInterface {
+  public:
+    // Set the input buffer.
+    status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer) override;
+
+    // Set the output buffer.
+    status_t setOutBuffer(const sp<EffectBufferHalInterface>& buffer) override;
+
+    // Effect process function.
+    status_t process() override;
+
+    // Process reverse stream function. This function is used to pass
+    // a reference stream to the effect engine.
+    status_t processReverse() override;
+
+    // Send a command and receive a response to/from effect engine.
+    status_t command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
+                     void* pReplyData) override;
+
+    // Returns the effect descriptor.
+    status_t getDescriptor(effect_descriptor_t *pDescriptor) override;
+
+    // Free resources on the remote side.
+    status_t close() override;
+
+    // Whether it's a local implementation.
+    bool isLocal() const override { return false; }
+
+    status_t dump(int fd) override;
+
+    uint64_t effectId() const override { return mEffectId; }
+
+  private:
+    friend class EffectsFactoryHalAidl;
+
+    const uint64_t mEffectId;
+    const int32_t mSessionId;
+    const int32_t mIoId;
+    sp<EffectBufferHalInterface> mInBuffer, mOutBuffer;
+    effect_config_t mConfig;
+    std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+
+    // Can not be constructed directly by clients.
+    EffectHalAidl(const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
+                  uint64_t effectId, int32_t sessionId, int32_t ioId);
+
+    status_t handleSetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+                             uint32_t* replySize, void* pReplyData);
+    status_t handleGetConfig(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+                             uint32_t* replySize, void* pReplyData);
+    status_t handleSetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+                                uint32_t* replySize, void* pReplyData);
+    status_t handleGetParameter(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+                                uint32_t* replySize, void* pReplyData);
+
+    // The destructor automatically releases the effect.
+    virtual ~EffectHalAidl();
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 7aec859..0039c86 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -14,69 +14,122 @@
  * limitations under the License.
  */
 
-#include <random>
+#include <algorithm>
+#include <cstdint>
+#include <memory>
 #define LOG_TAG "EffectsFactoryHalAidl"
 //#define LOG_NDEBUG 0
 
 #include <aidl/android/hardware/audio/effect/IFactory.h>
 #include <android/binder_manager.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionNdk.h>
+#include <media/audiohal/AudioHalUtils.h>
 #include <utils/Log.h>
 
+#include "EffectBufferHalAidl.h"
+#include "EffectHalAidl.h"
 #include "EffectsFactoryHalAidl.h"
 
 using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::media::audio::common::AudioUuid;
 using android::detail::AudioHalVersionInfo;
 
 namespace android {
 namespace effect {
 
-EffectsFactoryHalAidl::EffectsFactoryHalAidl(std::shared_ptr<IFactory> effectsFactory) {
+EffectsFactoryHalAidl::EffectsFactoryHalAidl(std::shared_ptr<IFactory> effectsFactory)
+    : mFactory(effectsFactory),
+      mHalVersion(AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, [this]() {
+          int32_t majorVersion = 0;
+          return (mFactory && mFactory->getInterfaceVersion(&majorVersion).isOk()) ? majorVersion
+                                                                                   : 0;
+      }())) {
     ALOG_ASSERT(effectsFactory != nullptr, "Provided IEffectsFactory service is NULL");
-    mEffectsFactory = effectsFactory;
 }
 
 status_t EffectsFactoryHalAidl::queryNumberEffects(uint32_t *pNumEffects) {
     if (pNumEffects == nullptr) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+
+    {
+        std::lock_guard lg(mLock);
+        RETURN_IF_NOT_OK(queryEffectList_l());
+        *pNumEffects = mDescList->size();
+    }
+    ALOGI("%s %d", __func__, *pNumEffects);
+    return OK;
 }
 
 status_t EffectsFactoryHalAidl::getDescriptor(uint32_t index, effect_descriptor_t* pDescriptor) {
-    if (index < 0 || pDescriptor == nullptr) {
+    if (pDescriptor == nullptr) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+
+    std::lock_guard lg(mLock);
+    RETURN_IF_NOT_OK(queryEffectList_l());
+
+    auto listSize = mDescList->size();
+    if (index >= listSize) {
+        ALOGE("%s index %d exceed size DescList %zd", __func__, index, listSize);
+        return INVALID_OPERATION;
+    }
+
+    *pDescriptor = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(mDescList->at(index)));
+    return OK;
 }
 
-status_t EffectsFactoryHalAidl::getDescriptor(const effect_uuid_t* pEffectUuid,
+status_t EffectsFactoryHalAidl::getDescriptor(const effect_uuid_t* halUuid,
                                               effect_descriptor_t* pDescriptor) {
-    if (pEffectUuid == nullptr || pDescriptor == nullptr) {
+    if (halUuid == nullptr || pDescriptor == nullptr) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+
+    AudioUuid uuid =
+            VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*halUuid));
+    std::lock_guard lg(mLock);
+    return getHalDescriptorWithImplUuid_l(uuid, pDescriptor);
 }
 
-status_t EffectsFactoryHalAidl::getDescriptors(const effect_uuid_t* pEffectType,
+status_t EffectsFactoryHalAidl::getDescriptors(const effect_uuid_t* halType,
                                                std::vector<effect_descriptor_t>* descriptors) {
-    if (pEffectType == nullptr || descriptors == nullptr) {
+    if (halType == nullptr || descriptors == nullptr) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+
+    AudioUuid type =
+            VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*halType));
+    std::lock_guard lg(mLock);
+    return getHalDescriptorWithTypeUuid_l(type, descriptors);
 }
 
-status_t EffectsFactoryHalAidl::createEffect(const effect_uuid_t* pEffectUuid, int32_t sessionId,
+status_t EffectsFactoryHalAidl::createEffect(const effect_uuid_t* uuid, int32_t sessionId,
                                              int32_t ioId, int32_t deviceId __unused,
                                              sp<EffectHalInterface>* effect) {
-    if (pEffectUuid == nullptr || effect == nullptr) {
+    if (uuid == nullptr || effect == nullptr) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet %d %d", __func__, sessionId, ioId);
-    return INVALID_OPERATION;
+    ALOGI("%s session %d ioId %d", __func__, sessionId, ioId);
+
+    AudioUuid aidlUuid =
+            VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*uuid));
+    std::shared_ptr<IEffect> aidlEffect;
+    ndk::ScopedAStatus status = mFactory->createEffect(aidlUuid, &aidlEffect);
+    if (!status.isOk() || aidlEffect == nullptr) {
+        ALOGE("%s IFactory::createFactory failed %s UUID %s", __func__,
+              status.getDescription().c_str(), aidlUuid.toString().c_str());
+        return INVALID_OPERATION;
+    }
+    uint64_t effectId;
+    {
+        std::lock_guard lg(mLock);
+        effectId = ++mEffectIdCounter;
+    }
+
+    *effect = new EffectHalAidl(aidlEffect, effectId, sessionId, ioId);
+    return OK;
 }
 
 status_t EffectsFactoryHalAidl::dumpEffects(int fd) {
@@ -85,33 +138,77 @@
 }
 
 status_t EffectsFactoryHalAidl::allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) {
-    if (size <= 0 || buffer == nullptr) {
-        return BAD_VALUE;
-    }
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+    ALOGI("%s size %zu buffer %p", __func__, size, buffer);
+    // Buffer doesn't allocated here for AIDL, instead each effect open will return I/O data FMQ.
+    return EffectBufferHalAidl::allocate(size, buffer);
 }
 
 status_t EffectsFactoryHalAidl::mirrorBuffer(void* external, size_t size,
                                              sp<EffectBufferHalInterface>* buffer) {
-    if (external == nullptr || size <= 0 || buffer == nullptr) {
-        return BAD_VALUE;
-    }
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+    ALOGI("%s extern %p size %zu buffer %p", __func__, external, size, buffer);
+    // TODO: implement with FMQ
+    return EffectBufferHalAidl::mirror(external, size, buffer);
 }
 
 AudioHalVersionInfo EffectsFactoryHalAidl::getHalVersion() const {
-    int32_t versionNumber = 0;
-    if (mEffectsFactory) {
-        if (!mEffectsFactory->getInterfaceVersion(&versionNumber).isOk()) {
-            ALOGE("%s getInterfaceVersion failed", __func__);
-        } else {
-            ALOGI("%s getInterfaceVersion %d", __func__, versionNumber);
+    return mHalVersion;
+}
+
+status_t EffectsFactoryHalAidl::queryEffectList_l() {
+    if (!mDescList) {
+        std::vector<Descriptor> list;
+        auto status = mFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &list);
+        if (!status.isOk()) {
+            ALOGE("%s IFactory::queryEffects failed %s", __func__, status.getDescription().c_str());
+            return status.getStatus();
         }
+
+        mDescList = std::make_unique<std::vector<Descriptor>>(list);
     }
-    // AIDL does not have minor version, fill 0 for all versions
-    return AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, versionNumber);
+    return OK;
+}
+
+status_t EffectsFactoryHalAidl::getHalDescriptorWithImplUuid_l(const AudioUuid& uuid,
+                                                               effect_descriptor_t* pDescriptor) {
+    if (pDescriptor == nullptr) {
+        return BAD_VALUE;
+    }
+    if (!mDescList) {
+        RETURN_IF_NOT_OK(queryEffectList_l());
+    }
+
+    auto matchIt = std::find_if(mDescList->begin(), mDescList->end(),
+                                 [&](const auto& desc) { return desc.common.id.uuid == uuid; });
+    if (matchIt == mDescList->end()) {
+        ALOGE("%s UUID %s not found", __func__, uuid.toString().c_str());
+        return BAD_VALUE;
+    }
+
+    *pDescriptor = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(*matchIt));
+    return OK;
+}
+
+status_t EffectsFactoryHalAidl::getHalDescriptorWithTypeUuid_l(
+        const AudioUuid& type, std::vector<effect_descriptor_t>* descriptors) {
+    if (descriptors == nullptr) {
+        return BAD_VALUE;
+    }
+    if (!mDescList) {
+        RETURN_IF_NOT_OK(queryEffectList_l());
+    }
+    std::vector<Descriptor> result;
+    std::copy_if(mDescList->begin(), mDescList->end(), std::back_inserter(result),
+                 [&](auto& desc) { return desc.common.id.type == type; });
+    if (result.size() == 0) {
+        ALOGE("%s type UUID %s not found", __func__, type.toString().c_str());
+        return BAD_VALUE;
+    }
+
+    *descriptors = VALUE_OR_RETURN_STATUS(
+            aidl::android::convertContainer<std::vector<effect_descriptor_t>>(
+                    result, ::aidl::android::aidl2legacy_Descriptor_effect_descriptor));
+    return OK;
 }
 
 } // namespace effect
@@ -120,9 +217,14 @@
 // exports from a static library are optimized out unless actually used by
 // the shared library. See EffectsFactoryHalEntry.cpp.
 extern "C" void* createIEffectsFactoryImpl() {
-    auto factory = IFactory::fromBinder(
-            ndk::SpAIBinder(AServiceManager_waitForService(IFactory::descriptor)));
-    return factory ? new effect::EffectsFactoryHalAidl(factory) : nullptr;
+    auto serviceName = std::string(IFactory::descriptor) + "/default";
+    auto service = IFactory::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+    if (!service) {
+        ALOGE("%s binder service %s not exist", __func__, serviceName.c_str());
+        return nullptr;
+    }
+    return new effect::EffectsFactoryHalAidl(service);
 }
 
 } // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.h b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
index d6b5684..1e85da9 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
@@ -16,7 +16,13 @@
 
 #pragma once
 
+#include <cstddef>
+#include <memory>
+#include <mutex>
+
+#include <android-base/thread_annotations.h>
 #include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <system/thread_defs.h>
 
 namespace android {
 namespace effect {
@@ -40,8 +46,8 @@
                             std::vector<effect_descriptor_t>* descriptors) override;
 
     // Creates an effect engine of the specified type.
-    // To release the effect engine, it is necessary to release references
-    // to the returned effect object.
+    // To release the effect engine, it is necessary to release references to the returned effect
+    // object.
     status_t createEffect(const effect_uuid_t* pEffectUuid, int32_t sessionId, int32_t ioId,
                           int32_t deviceId, sp<EffectHalInterface>* effect) override;
 
@@ -51,11 +57,23 @@
     status_t mirrorBuffer(void* external, size_t size,
                           sp<EffectBufferHalInterface>* buffer) override;
 
-    android::detail::AudioHalVersionInfo getHalVersion() const override;
+    detail::AudioHalVersionInfo getHalVersion() const override;
 
   private:
-    std::shared_ptr<IFactory> mEffectsFactory;
+    std::mutex mLock;
+    const std::shared_ptr<IFactory> mFactory;
+    uint64_t mEffectIdCounter GUARDED_BY(mLock) = 0; // Align with HIDL (0 is INVALID_ID)
+    std::unique_ptr<std::vector<Descriptor>> mDescList GUARDED_BY(mLock) = nullptr;
+    const detail::AudioHalVersionInfo mHalVersion;
+
     virtual ~EffectsFactoryHalAidl() = default;
+    status_t queryEffectList_l() REQUIRES(mLock);
+    status_t getHalDescriptorWithImplUuid_l(
+            const aidl::android::media::audio::common::AudioUuid& uuid,
+            effect_descriptor_t* pDescriptor) REQUIRES(mLock);
+    status_t getHalDescriptorWithTypeUuid_l(
+            const aidl::android::media::audio::common::AudioUuid& type,
+            std::vector<effect_descriptor_t>* descriptors) REQUIRES(mLock);
 };
 
 } // namespace effect
diff --git a/media/libaudiohal/include/media/audiohal/AudioHalUtils.h b/media/libaudiohal/include/media/audiohal/AudioHalUtils.h
new file mode 100644
index 0000000..4862cba
--- /dev/null
+++ b/media/libaudiohal/include/media/audiohal/AudioHalUtils.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#define RETURN_IF_BINDER_FAIL(expr)                                              \
+    do {                                                                         \
+        const ::ndk::ScopedAStatus _temp_status_ = (expr);                       \
+        if (!_temp_status_.isOk()) {                                             \
+            ALOGE("%s:%d return with expr %s msg %s", __func__, __LINE__, #expr, \
+                  _temp_status_.getMessage());                                   \
+            return _temp_status_.getStatus();                                    \
+        }                                                                        \
+    } while (false)
+
+#define RETURN_IF_NOT_OK(statement) \
+    do {                            \
+        auto tmp = (statement);     \
+        if (tmp != OK) {            \
+            return tmp;             \
+        }                           \
+    } while (false)
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 3858607..2c8219e 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -21,7 +21,6 @@
 #include <android/media/audio/common/AudioMMapPolicyType.h>
 #include <error/Result.h>
 #include <media/audiohal/EffectHalInterface.h>
-#include <media/MicrophoneInfo.h>
 #include <system/audio.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
@@ -107,16 +106,23 @@
     virtual status_t releaseAudioPatch(audio_patch_handle_t patch) = 0;
 
     // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port *port) = 0;
+    virtual status_t getAudioPort(struct audio_port* port) {
+        ALOGE("%s override me port %p", __func__, port);
+        return OK;
+    }
 
     // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
+    virtual status_t getAudioPort(struct audio_port_v7 *port) {
+        ALOGE("%s override me port %p", __func__, port);
+        return OK;
+    }
 
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
 
     // List microphones
-    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
+    virtual status_t getMicrophones(
+            std::vector<audio_microphone_characteristic_t>* microphones) = 0;
 
     virtual status_t addDeviceEffect(
             audio_port_handle_t device, sp<EffectHalInterface> effect) = 0;
@@ -125,13 +131,16 @@
 
     virtual status_t getMmapPolicyInfos(
             media::audio::common::AudioMMapPolicyType policyType,
-            std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos)  = 0;
+            std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) = 0;
     virtual int32_t getAAudioMixerBurstCount() = 0;
     virtual int32_t getAAudioHardwareBurstMinUsec() = 0;
     virtual int32_t supportsBluetoothVariableLatency(bool* supports) = 0;
 
     // Update the connection status of an external device.
-    virtual status_t setConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
+    virtual status_t setConnectedState(const struct audio_port_v7* port, bool connected) {
+        ALOGE("%s override me port %p connected %d", __func__, port, connected);
+        return OK;
+    }
 
     virtual error::Result<audio_hw_sync_t> getHwAvSync() = 0;
 
diff --git a/media/libaudiohal/tests/Android.bp b/media/libaudiohal/tests/Android.bp
new file mode 100644
index 0000000..e20f74c
--- /dev/null
+++ b/media/libaudiohal/tests/Android.bp
@@ -0,0 +1,51 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Headers module is in frameworks/av/Android.bp because modules are not allowed
+// to refer to headers in parent directories and the headers live in
+// frameworks/av/include.
+
+package {
+    default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_test {
+    name: "EffectsFactoryHalInterfaceTest",
+    test_suites: ["device-tests"],
+
+    srcs: [
+        "EffectsFactoryHalInterface_test.cpp",
+    ],
+
+    defaults: [
+        "latest_android_media_audio_common_types_cpp_shared",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+    ],
+
+    shared_libs: [
+        "audioclient-types-aidl-cpp",
+        "libaudiohal",
+        "libutils",
+    ],
+
+    header_libs: [
+        "libaudiohal_headers",
+    ],
+}
diff --git a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
new file mode 100644
index 0000000..83c7809
--- /dev/null
+++ b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#include <cstdint>
+#define LOG_TAG "EffectsFactoryHalInterfaceTest"
+
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+
+#include <gtest/gtest.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+// EffectsFactoryHalInterface
+TEST(libAudioHalTest, createEffectsFactoryHalInterface) {
+    ASSERT_NE(nullptr, EffectsFactoryHalInterface::create());
+}
+
+TEST(libAudioHalTest, queryNumberEffects) {
+    auto factory = EffectsFactoryHalInterface::create();
+    ASSERT_NE(nullptr, factory);
+
+    uint32_t numEffects = 0;
+    EXPECT_EQ(OK, factory->queryNumberEffects(&numEffects));
+    EXPECT_NE(0ul, numEffects);
+}
+
+TEST(libAudioHalTest, getDescriptorByNumber) {
+    auto factory = EffectsFactoryHalInterface::create();
+    ASSERT_NE(nullptr, factory);
+
+    uint32_t numEffects = 0;
+    EXPECT_EQ(OK, factory->queryNumberEffects(&numEffects));
+    EXPECT_NE(0ul, numEffects);
+
+    effect_descriptor_t desc;
+    for (uint32_t i = 0; i < numEffects; i++) {
+        EXPECT_EQ(OK, factory->getDescriptor(i, &desc));
+    }
+}
+
+TEST(libAudioHalTest, createEffect) {
+    auto factory = EffectsFactoryHalInterface::create();
+    ASSERT_NE(nullptr, factory);
+
+    uint32_t numEffects = 0;
+    EXPECT_EQ(OK, factory->queryNumberEffects(&numEffects));
+    EXPECT_NE(0ul, numEffects);
+
+    effect_descriptor_t desc;
+    for (uint32_t i = 0; i < numEffects; i++) {
+        sp<EffectHalInterface> interface;
+        EXPECT_EQ(OK, factory->getDescriptor(i, &desc));
+        EXPECT_EQ(OK, factory->createEffect(&desc.uuid, 1 /* sessionId */, 1 /* ioId */,
+                                            1 /* deviceId */, &interface));
+    }
+}
+
+TEST(libAudioHalTest, getHalVersion) {
+    auto factory = EffectsFactoryHalInterface::create();
+    ASSERT_NE(nullptr, factory);
+
+    auto version = factory->getHalVersion();
+    EXPECT_NE(0, version.getMajorVersion());
+}
+
+// TODO: b/263986405 Add multi-thread testing
+
+} // namespace android
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 4a8b678..e4c4107 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2776,14 +2776,15 @@
     status_t status = INVALID_OPERATION;
 
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
-        std::vector<media::MicrophoneInfo> mics;
+        std::vector<audio_microphone_characteristic_t> mics;
         AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
         mHardwareStatus = AUDIO_HW_GET_MICROPHONES;
         status_t devStatus = dev->hwDevice()->getMicrophones(&mics);
         mHardwareStatus = AUDIO_HW_IDLE;
         if (devStatus == NO_ERROR) {
-            microphones->insert(microphones->begin(), mics.begin(), mics.end());
             // report success if at least one HW module supports the function.
+            std::transform(mics.begin(), mics.end(), std::back_inserter(*microphones),
+                           [](auto& mic) { return media::MicrophoneInfo(mic); });
             status = NO_ERROR;
         }
     }