Merge "TranscodingSessionControllerTest: Allow extra time to receive onError"
diff --git a/cmds/stagefright/SineSource.cpp b/cmds/stagefright/SineSource.cpp
index 0ecc16c..0656030 100644
--- a/cmds/stagefright/SineSource.cpp
+++ b/cmds/stagefright/SineSource.cpp
@@ -63,12 +63,15 @@
         MediaBufferBase **out, const ReadOptions * /* options */) {
     *out = NULL;
 
-    MediaBufferBase *buffer;
+    MediaBufferBase *buffer = nullptr;
     status_t err = mGroup->acquire_buffer(&buffer);
 
     if (err != OK) {
         return err;
     }
+    if (buffer == nullptr) {
+        return AMEDIA_ERROR_UNKNOWN;
+    }
 
     size_t frameSize = mNumChannels * sizeof(int16_t);
     size_t numFramesPerBuffer = buffer->size() / frameSize;
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 5743ad6..87e8832 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -89,6 +89,9 @@
         if (err != OK) {
             return err;
         }
+        if (buffer == nullptr) {
+            return AMEDIA_ERROR_UNKNOWN;
+        }
 
         char x = (char)((double)rand() / RAND_MAX * 255);
         memset((*buffer)->data(), x, mSize);
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 1e1a49d..7d68c5b 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -36,6 +36,7 @@
         "DrmUtils.cpp",
         "DrmHalListener.cpp",
         "DrmStatus.cpp",
+        "DrmMetricsLogger.cpp",
     ],
 
     local_include_dirs: [
diff --git a/drm/libmediadrm/DrmMetricsLogger.cpp b/drm/libmediadrm/DrmMetricsLogger.cpp
new file mode 100644
index 0000000..9c737a0
--- /dev/null
+++ b/drm/libmediadrm/DrmMetricsLogger.cpp
@@ -0,0 +1,513 @@
+/*
+ * 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_NDEBUG 0
+#define LOG_TAG "DrmMetricsLogger"
+
+#include <media/MediaMetrics.h>
+#include <mediadrm/DrmHal.h>
+#include <mediadrm/DrmMetricsLogger.h>
+#include <mediadrm/DrmUtils.h>
+
+namespace android {
+
+namespace {
+
+std::vector<uint8_t> toStdVec(Vector<uint8_t> const& sessionId) {
+    auto sessionKey = sessionId.array();
+    std::vector<uint8_t> vec(sessionKey, sessionKey + sessionId.size());
+    return vec;
+}
+}  // namespace
+
+DrmMetricsLogger::DrmMetricsLogger(IDrmFrontend frontend)
+    : mImpl(sp<DrmHal>::make()), mUuid(), mObjNonceMsb(0), mObjNonceLsb(0), mFrontend(frontend) {}
+
+DrmMetricsLogger::~DrmMetricsLogger() {}
+
+DrmStatus DrmMetricsLogger::initCheck() const {
+    DrmStatus status = mImpl->initCheck();
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+                                                    DrmPlugin::SecurityLevel securityLevel,
+                                                    bool* result) {
+    DrmStatus status = mImpl->isCryptoSchemeSupported(uuid, mimeType, securityLevel, result);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
+    std::memcpy(mUuid, uuid, sizeof(mUuid));
+    if (checkGetRandom(&mObjNonceMsb, __func__) == OK &&
+        checkGetRandom(&mObjNonceLsb, __func__) == OK) {
+        DrmStatus status = mImpl->createPlugin(uuid, appPackageName);
+        if (status == OK) {
+            reportMediaDrmCreated();
+        } else {
+            reportMediaDrmErrored(status, __func__);
+        }
+        return status;
+    }
+    return ERROR_DRM_RESOURCE_BUSY;
+}
+
+DrmStatus DrmMetricsLogger::destroyPlugin() {
+    DrmStatus status = mImpl->destroyPlugin();
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::openSession(DrmPlugin::SecurityLevel securityLevel,
+                                        Vector<uint8_t>& sessionId) {
+    SessionContext ctx{};
+    if (checkGetRandom(&ctx.mNonceMsb, __func__) == OK &&
+        checkGetRandom(&ctx.mNonceLsb, __func__) == OK) {
+        DrmStatus status = mImpl->openSession(securityLevel, sessionId);
+        if (status == OK) {
+            std::vector<uint8_t> sessionKey = toStdVec(sessionId);
+            ctx.mTargetSecurityLevel = securityLevel;
+            if (getSecurityLevel(sessionId, &ctx.mActualSecurityLevel) != OK) {
+                ctx.mActualSecurityLevel = DrmPlugin::kSecurityLevelUnknown;
+            }
+            {
+                const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+                mSessionMap.insert({sessionKey, ctx});
+            }
+            reportMediaDrmSessionOpened(sessionKey);
+        } else {
+            reportMediaDrmErrored(status, __func__);
+        }
+        return status;
+    }
+    return ERROR_DRM_RESOURCE_BUSY;
+}
+
+DrmStatus DrmMetricsLogger::closeSession(Vector<uint8_t> const& sessionId) {
+    std::vector<uint8_t> sid = toStdVec(sessionId);
+    {
+        const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+        mSessionMap.erase(sid);
+    }
+    DrmStatus status = mImpl->closeSession(sessionId);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, sid);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getKeyRequest(Vector<uint8_t> const& sessionId,
+                                          Vector<uint8_t> const& initData, String8 const& mimeType,
+                                          DrmPlugin::KeyType keyType,
+                                          KeyedVector<String8, String8> const& optionalParameters,
+                                          Vector<uint8_t>& request, String8& defaultUrl,
+                                          DrmPlugin::KeyRequestType* keyRequestType) {
+    DrmStatus status =
+            mImpl->getKeyRequest(sessionId, initData, mimeType, keyType, optionalParameters,
+                                 request, defaultUrl, keyRequestType);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::provideKeyResponse(Vector<uint8_t> const& sessionId,
+                                               Vector<uint8_t> const& response,
+                                               Vector<uint8_t>& keySetId) {
+    DrmStatus status = mImpl->provideKeyResponse(sessionId, response, keySetId);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::removeKeys(Vector<uint8_t> const& keySetId) {
+    DrmStatus status = mImpl->removeKeys(keySetId);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::restoreKeys(Vector<uint8_t> const& sessionId,
+                                        Vector<uint8_t> const& keySetId) {
+    DrmStatus status = mImpl->restoreKeys(sessionId, keySetId);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::queryKeyStatus(Vector<uint8_t> const& sessionId,
+                                           KeyedVector<String8, String8>& infoMap) const {
+    DrmStatus status = mImpl->queryKeyStatus(sessionId, infoMap);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getProvisionRequest(String8 const& certType,
+                                                String8 const& certAuthority,
+                                                Vector<uint8_t>& request, String8& defaultUrl) {
+    DrmStatus status = mImpl->getProvisionRequest(certType, certAuthority, request, defaultUrl);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::provideProvisionResponse(Vector<uint8_t> const& response,
+                                                     Vector<uint8_t>& certificate,
+                                                     Vector<uint8_t>& wrappedKey) {
+    DrmStatus status = mImpl->provideProvisionResponse(response, certificate, wrappedKey);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecureStops(List<Vector<uint8_t>>& secureStops) {
+    DrmStatus status = mImpl->getSecureStops(secureStops);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
+    DrmStatus status = mImpl->getSecureStopIds(secureStopIds);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecureStop(Vector<uint8_t> const& ssid,
+                                          Vector<uint8_t>& secureStop) {
+    DrmStatus status = mImpl->getSecureStop(ssid, secureStop);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
+    DrmStatus status = mImpl->releaseSecureStops(ssRelease);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::removeSecureStop(Vector<uint8_t> const& ssid) {
+    DrmStatus status = mImpl->removeSecureStop(ssid);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::removeAllSecureStops() {
+    DrmStatus status = mImpl->removeAllSecureStops();
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
+                                          DrmPlugin::HdcpLevel* maxLevel) const {
+    DrmStatus status = mImpl->getHdcpLevels(connectedLevel, maxLevel);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getNumberOfSessions(uint32_t* currentSessions,
+                                                uint32_t* maxSessions) const {
+    DrmStatus status = mImpl->getNumberOfSessions(currentSessions, maxSessions);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecurityLevel(Vector<uint8_t> const& sessionId,
+                                             DrmPlugin::SecurityLevel* level) const {
+    DrmStatus status = mImpl->getSecurityLevel(sessionId, level);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
+    DrmStatus status = mImpl->getOfflineLicenseKeySetIds(keySetIds);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
+    DrmStatus status = mImpl->removeOfflineLicense(keySetId);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getOfflineLicenseState(
+        Vector<uint8_t> const& keySetId, DrmPlugin::OfflineLicenseState* licenseState) const {
+    DrmStatus status = mImpl->getOfflineLicenseState(keySetId, licenseState);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getPropertyString(String8 const& name, String8& value) const {
+    DrmStatus status = mImpl->getPropertyString(name, value);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getPropertyByteArray(String8 const& name,
+                                                 Vector<uint8_t>& value) const {
+    DrmStatus status = mImpl->getPropertyByteArray(name, value);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::setPropertyString(String8 const& name, String8 const& value) const {
+    DrmStatus status = mImpl->setPropertyString(name, value);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::setPropertyByteArray(String8 const& name,
+                                                 Vector<uint8_t> const& value) const {
+    DrmStatus status = mImpl->setPropertyByteArray(name, value);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
+    DrmStatus status = mImpl->getMetrics(consumer);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
+                                               String8 const& algorithm) {
+    DrmStatus status = mImpl->setCipherAlgorithm(sessionId, algorithm);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::setMacAlgorithm(Vector<uint8_t> const& sessionId,
+                                            String8 const& algorithm) {
+    DrmStatus status = mImpl->setMacAlgorithm(sessionId, algorithm);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+                                    Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+                                    Vector<uint8_t>& output) {
+    DrmStatus status = mImpl->encrypt(sessionId, keyId, input, iv, output);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+                                    Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+                                    Vector<uint8_t>& output) {
+    DrmStatus status = mImpl->decrypt(sessionId, keyId, input, iv, output);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+                                 Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
+    DrmStatus status = mImpl->sign(sessionId, keyId, message, signature);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+                                   Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
+                                   bool& match) {
+    DrmStatus status = mImpl->verify(sessionId, keyId, message, signature, match);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
+                                    Vector<uint8_t> const& message,
+                                    Vector<uint8_t> const& wrappedKey, Vector<uint8_t>& signature) {
+    DrmStatus status = mImpl->signRSA(sessionId, algorithm, message, wrappedKey, signature);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::setListener(const sp<IDrmClient>& listener) {
+    DrmStatus status = mImpl->setListener(listener);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime, bool* required) const {
+    DrmStatus status = mImpl->requiresSecureDecoder(mime, required);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime,
+                                                  DrmPlugin::SecurityLevel securityLevel,
+                                                  bool* required) const {
+    DrmStatus status = mImpl->requiresSecureDecoder(mime, securityLevel, required);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::setPlaybackId(Vector<uint8_t> const& sessionId,
+                                          const char* playbackId) {
+    DrmStatus status = mImpl->setPlaybackId(sessionId, playbackId);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
+    DrmStatus status = mImpl->getLogMessages(logs);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+DrmStatus DrmMetricsLogger::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
+    DrmStatus status = mImpl->getSupportedSchemes(schemes);
+    if (status != OK) {
+        reportMediaDrmErrored(status, __func__);
+    }
+    return status;
+}
+
+void DrmMetricsLogger::reportMediaDrmCreated() const {
+    mediametrics_handle_t handle(mediametrics_create("mediadrm.created"));
+    mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
+    mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
+    mediametrics_setInt32(handle, "frontend", mFrontend);
+    mediametrics_selfRecord(handle);
+    mediametrics_delete(handle);
+}
+
+void DrmMetricsLogger::reportMediaDrmSessionOpened(const std::vector<uint8_t>& sessionId) const {
+    mediametrics_handle_t handle(mediametrics_create("mediadrm.session_opened"));
+    mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
+    mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
+    const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+    auto it = mSessionMap.find(sessionId);
+    if (it != mSessionMap.end()) {
+        mediametrics_setInt64(handle, "session_nonce_msb", it->second.mNonceMsb);
+        mediametrics_setInt64(handle, "session_nonce_lsb", it->second.mNonceLsb);
+        mediametrics_setInt64(handle, "target_seucrity_level", it->second.mTargetSecurityLevel);
+        mediametrics_setInt64(handle, "actual_seucrity_level", it->second.mActualSecurityLevel);
+    }
+    mediametrics_setInt32(handle, "frontend", mFrontend);
+    mediametrics_selfRecord(handle);
+    mediametrics_delete(handle);
+}
+
+void DrmMetricsLogger::reportMediaDrmErrored(const DrmStatus& error_code, const char* api,
+                                             const std::vector<uint8_t>& sessionId) const {
+    mediametrics_handle_t handle(mediametrics_create("mediadrm.errored"));
+    mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
+    mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
+    if (!sessionId.empty()) {
+        const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+        auto it = mSessionMap.find(sessionId);
+        if (it != mSessionMap.end()) {
+            mediametrics_setInt64(handle, "session_nonce_msb", it->second.mNonceMsb);
+            mediametrics_setInt64(handle, "session_nonce_lsb", it->second.mNonceLsb);
+        }
+    }
+    mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
+    mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
+    mediametrics_setInt32(handle, "error_code", error_code);
+    mediametrics_setInt32(handle, "cdm_err", error_code.getCdmErr());
+    mediametrics_setInt32(handle, "oem_err", error_code.getOemErr());
+    mediametrics_setInt32(handle, "error_context", error_code.getContext());
+    mediametrics_setCString(handle, "api", api);
+    mediametrics_setInt32(handle, "frontend", mFrontend);
+    mediametrics_selfRecord(handle);
+    mediametrics_delete(handle);
+}
+
+DrmStatus DrmMetricsLogger::checkGetRandom(int64_t* nonce, const char* api) {
+    ssize_t bytes = getrandom(nonce, sizeof(int64_t), GRND_NONBLOCK);
+    if (bytes < sizeof(int64_t)) {
+        ALOGE("getrandom failed: %d", errno);
+        reportMediaDrmErrored(ERROR_DRM_RESOURCE_BUSY, api);
+        return ERROR_DRM_RESOURCE_BUSY;
+    }
+    return OK;
+}
+
+}  // namespace android
\ No newline at end of file
diff --git a/drm/libmediadrm/DrmUtils.cpp b/drm/libmediadrm/DrmUtils.cpp
index cb103f7..a99b1d1 100644
--- a/drm/libmediadrm/DrmUtils.cpp
+++ b/drm/libmediadrm/DrmUtils.cpp
@@ -59,11 +59,11 @@
 
 namespace {
 
-template <typename Hal>
-Hal* MakeObject(status_t* pstatus) {
+template <typename Hal, typename... Ts>
+Hal* MakeObject(status_t* pstatus, Ts... args) {
     status_t err = OK;
     status_t& status = pstatus ? *pstatus : err;
-    auto obj = new Hal();
+    auto obj = new Hal(args...);
     status = obj->initCheck();
     if (status != OK && status != NO_INIT) {
         return NULL;
@@ -192,8 +192,8 @@
     return factories;
 }
 
-sp<IDrm> MakeDrm(status_t* pstatus) {
-    return MakeObject<DrmHal>(pstatus);
+sp<IDrm> MakeDrm(IDrmFrontend frontend, status_t* pstatus) {
+    return MakeObject<DrmMetricsLogger>(pstatus, frontend);
 }
 
 sp<ICrypto> MakeCrypto(status_t* pstatus) {
diff --git a/drm/libmediadrm/include/mediadrm/DrmHalHidl.h b/drm/libmediadrm/include/mediadrm/DrmHalHidl.h
index 45764a1..73a9e1d 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHalHidl.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHalHidl.h
@@ -70,7 +70,7 @@
                                               DrmPlugin::SecurityLevel level, bool* isSupported);
 
     virtual DrmStatus createPlugin(const uint8_t uuid[16],
-                                  const String8 &appPackageName);
+                                   const String8 &appPackageName);
 
     virtual DrmStatus destroyPlugin();
 
diff --git a/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h b/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h
new file mode 100644
index 0000000..b618314
--- /dev/null
+++ b/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h
@@ -0,0 +1,167 @@
+/*
+ * 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 <mediadrm/DrmStatus.h>
+#include <mediadrm/IDrm.h>
+#include <sys/random.h>
+#include <map>
+#include <mutex>
+
+#ifndef DRM_METRICS_LOGGER_H
+#define DRM_METRICS_LOGGER_H
+
+namespace android {
+
+struct SessionContext {
+    int64_t mNonceMsb;
+    int64_t mNonceLsb;
+    int64_t mTargetSecurityLevel;
+    DrmPlugin::SecurityLevel mActualSecurityLevel;
+};
+
+class DrmMetricsLogger : public IDrm {
+  public:
+    DrmMetricsLogger(IDrmFrontend);
+
+    virtual ~DrmMetricsLogger();
+
+    virtual DrmStatus initCheck() const;
+
+    virtual DrmStatus isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+                                              DrmPlugin::SecurityLevel securityLevel, bool* result);
+
+    virtual DrmStatus createPlugin(const uint8_t uuid[16], const String8& appPackageName);
+
+    virtual DrmStatus destroyPlugin();
+
+    virtual DrmStatus openSession(DrmPlugin::SecurityLevel securityLevel,
+                                  Vector<uint8_t>& sessionId);
+
+    virtual DrmStatus closeSession(Vector<uint8_t> const& sessionId);
+
+    virtual DrmStatus getKeyRequest(Vector<uint8_t> const& sessionId,
+                                    Vector<uint8_t> const& initData, String8 const& mimeType,
+                                    DrmPlugin::KeyType keyType,
+                                    KeyedVector<String8, String8> const& optionalParameters,
+                                    Vector<uint8_t>& request, String8& defaultUrl,
+                                    DrmPlugin::KeyRequestType* keyRequestType);
+
+    virtual DrmStatus provideKeyResponse(Vector<uint8_t> const& sessionId,
+                                         Vector<uint8_t> const& response,
+                                         Vector<uint8_t>& keySetId);
+
+    virtual DrmStatus removeKeys(Vector<uint8_t> const& keySetId);
+
+    virtual DrmStatus restoreKeys(Vector<uint8_t> const& sessionId,
+                                  Vector<uint8_t> const& keySetId);
+
+    virtual DrmStatus queryKeyStatus(Vector<uint8_t> const& sessionId,
+                                     KeyedVector<String8, String8>& infoMap) const;
+
+    virtual DrmStatus getProvisionRequest(String8 const& certType, String8 const& certAuthority,
+                                          Vector<uint8_t>& request, String8& defaultUrl);
+
+    virtual DrmStatus provideProvisionResponse(Vector<uint8_t> const& response,
+                                               Vector<uint8_t>& certificate,
+                                               Vector<uint8_t>& wrappedKey);
+
+    virtual DrmStatus getSecureStops(List<Vector<uint8_t>>& secureStops);
+    virtual DrmStatus getSecureStopIds(List<Vector<uint8_t>>& secureStopIds);
+    virtual DrmStatus getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop);
+
+    virtual DrmStatus releaseSecureStops(Vector<uint8_t> const& ssRelease);
+    virtual DrmStatus removeSecureStop(Vector<uint8_t> const& ssid);
+    virtual DrmStatus removeAllSecureStops();
+
+    virtual DrmStatus getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
+                                    DrmPlugin::HdcpLevel* maxLevel) const;
+    virtual DrmStatus getNumberOfSessions(uint32_t* currentSessions, uint32_t* maxSessions) const;
+    virtual DrmStatus getSecurityLevel(Vector<uint8_t> const& sessionId,
+                                       DrmPlugin::SecurityLevel* level) const;
+
+    virtual DrmStatus getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const;
+    virtual DrmStatus removeOfflineLicense(Vector<uint8_t> const& keySetId);
+    virtual DrmStatus getOfflineLicenseState(Vector<uint8_t> const& keySetId,
+                                             DrmPlugin::OfflineLicenseState* licenseState) const;
+
+    virtual DrmStatus getPropertyString(String8 const& name, String8& value) const;
+    virtual DrmStatus getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const;
+    virtual DrmStatus setPropertyString(String8 const& name, String8 const& value) const;
+    virtual DrmStatus setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const;
+
+    virtual DrmStatus getMetrics(const sp<IDrmMetricsConsumer>& consumer);
+
+    virtual DrmStatus setCipherAlgorithm(Vector<uint8_t> const& sessionId,
+                                         String8 const& algorithm);
+
+    virtual DrmStatus setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm);
+
+    virtual DrmStatus encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+                              Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+                              Vector<uint8_t>& output);
+
+    virtual DrmStatus decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+                              Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+                              Vector<uint8_t>& output);
+
+    virtual DrmStatus sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+                           Vector<uint8_t> const& message, Vector<uint8_t>& signature);
+
+    virtual DrmStatus verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+                             Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
+                             bool& match);
+
+    virtual DrmStatus signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
+                              Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
+                              Vector<uint8_t>& signature);
+
+    virtual DrmStatus setListener(const sp<IDrmClient>& listener);
+
+    virtual DrmStatus requiresSecureDecoder(const char* mime, bool* required) const;
+
+    virtual DrmStatus requiresSecureDecoder(const char* mime,
+                                            DrmPlugin::SecurityLevel securityLevel,
+                                            bool* required) const;
+
+    virtual DrmStatus setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId);
+
+    virtual DrmStatus getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const;
+
+    virtual DrmStatus getSupportedSchemes(std::vector<uint8_t>& schemes) const;
+
+    void reportMediaDrmCreated() const;
+
+    void reportMediaDrmSessionOpened(const std::vector<uint8_t>& sessionId) const;
+
+    void reportMediaDrmErrored(
+            const DrmStatus& error_code, const char* api,
+            const std::vector<uint8_t>& sessionId = std::vector<uint8_t>()) const;
+
+    DrmStatus checkGetRandom(int64_t* nonce, const char* api);
+
+  private:
+    sp<IDrm> mImpl;
+    int64_t mUuid[2] = {};
+    int64_t mObjNonceMsb, mObjNonceLsb;
+    std::map<std::vector<uint8_t>, SessionContext> mSessionMap;
+    mutable std::mutex mSessionMapMutex;
+    IDrmFrontend mFrontend;
+    DISALLOW_EVIL_CONSTRUCTORS(DrmMetricsLogger);
+};
+
+}  // namespace android
+
+#endif  // DRM_METRICS_LOGGER_H
\ No newline at end of file
diff --git a/drm/libmediadrm/include/mediadrm/IDrm.h b/drm/libmediadrm/include/mediadrm/IDrm.h
index 3dc7485..f37d1d1 100644
--- a/drm/libmediadrm/include/mediadrm/IDrm.h
+++ b/drm/libmediadrm/include/mediadrm/IDrm.h
@@ -33,6 +33,13 @@
 }  // namespace drm
 }  // namespace hardware
 
+enum IDrmFrontend : int32_t {
+    IDRM_UNKNOWN = 0,
+    IDRM_JNI = 1,
+    IDRM_NDK = 2,
+    IDRM_NUPLAYER = 3,
+};
+
 namespace drm = ::android::hardware::drm;
 
 struct AString;
diff --git a/drm/libmediadrm/interface/mediadrm/DrmUtils.h b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
index 2632ebd..94cf743 100644
--- a/drm/libmediadrm/interface/mediadrm/DrmUtils.h
+++ b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
@@ -22,6 +22,7 @@
 #include <android/hardware/drm/1.4/IDrmPlugin.h>
 #include <android/hardware/drm/1.4/types.h>
 #include <media/stagefright/MediaErrors.h>
+#include <mediadrm/DrmMetricsLogger.h>
 #include <mediadrm/DrmStatus.h>
 #include <utils/Errors.h>  // for status_t
 #include <utils/Log.h>
@@ -119,7 +120,7 @@
 
 bool UseDrmService();
 
-sp<IDrm> MakeDrm(status_t *pstatus = nullptr);
+sp<IDrm> MakeDrm(IDrmFrontend frontend = IDRM_JNI, status_t* pstatus = nullptr);
 
 sp<ICrypto> MakeCrypto(status_t *pstatus = nullptr);
 
diff --git a/include/media/MicrophoneInfo.h b/include/media/MicrophoneInfo.h
index a5045b9..6d6c594 100644
--- a/include/media/MicrophoneInfo.h
+++ b/include/media/MicrophoneInfo.h
@@ -70,6 +70,9 @@
     }
 
     virtual status_t writeToParcelable(MicrophoneInfoData* parcelable) const {
+#if defined(BACKEND_NDK)
+        using ::aidl::android::convertReinterpret;
+#endif
         parcelable->deviceId = mDeviceId;
         parcelable->portId = mPortId;
         parcelable->type = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(mType));
@@ -98,6 +101,9 @@
     }
 
     virtual status_t readFromParcelable(const MicrophoneInfoData& parcelable) {
+#if defined(BACKEND_NDK)
+        using ::aidl::android::convertReinterpret;
+#endif
         mDeviceId = parcelable.deviceId;
         mPortId = parcelable.portId;
         mType = VALUE_OR_RETURN_STATUS(convertReinterpret<uint32_t>(parcelable.type));
@@ -208,6 +214,10 @@
     int32_t mDirectionality;
 };
 
+#if defined(BACKEND_NDK)
+using ::aidl::ConversionResult;
+#endif
+
 // Conversion routines, according to AidlConversion.h conventions.
 inline ConversionResult<MicrophoneInfo>
 aidl2legacy_MicrophoneInfo(const media::MicrophoneInfoData& aidl) {
diff --git a/media/audioaidlconversion/AidlConversionNdk.cpp b/media/audioaidlconversion/AidlConversionNdk.cpp
index a3e39c7..9981435 100644
--- a/media/audioaidlconversion/AidlConversionNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionNdk.cpp
@@ -29,13 +29,24 @@
 namespace aidl {
 namespace android {
 
+using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
 using ::aidl::android::hardware::audio::effect::Descriptor;
 using ::aidl::android::hardware::audio::effect::Flags;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
 
 using ::android::BAD_VALUE;
 using ::android::base::unexpected;
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
+// Utils
+
+ConversionResult<AcousticEchoCanceler> getParameterSpecificAec(const Parameter& aidl) {
+    const auto& specific = VALUE_OR_RETURN(UNION_GET(aidl, specific));
+    return VALUE_OR_RETURN(UNION_GET(specific, acousticEchoCanceler));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
 // Converters
 
 ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(Flags::Type type) {
@@ -238,7 +249,7 @@
 }
 
 ConversionResult<media::audio::common::AudioConfigBase>
-legacy2aidl_AudioConfigBase_buffer_config_t(const buffer_config_t& legacy, bool isInput) {
+legacy2aidl_buffer_config_t_AudioConfigBase(const buffer_config_t& legacy, bool isInput) {
     media::audio::common::AudioConfigBase aidl;
 
     if (legacy.mask & EFFECT_CONFIG_SMP_RATE) {
@@ -255,5 +266,35 @@
     return aidl;
 }
 
+ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_echoDelay(const Parameter& aidl) {
+    const auto& aec = VALUE_OR_RETURN(getParameterSpecificAec(aidl));
+    const auto& echoDelay = VALUE_OR_RETURN(UNION_GET(aec, echoDelayUs));
+    return VALUE_OR_RETURN(convertIntegral<uint32_t>(echoDelay));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_echoDelay_Parameter(const uint32_t& legacy) {
+    int delay = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy));
+    AcousticEchoCanceler aec = AcousticEchoCanceler::make<AcousticEchoCanceler::echoDelayUs>(delay);
+    Parameter::Specific specific =
+            Parameter::Specific::make<Parameter::Specific::acousticEchoCanceler>(aec);
+
+    return Parameter::make<Parameter::specific>(specific);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_mobileMode(const Parameter& aidl) {
+    const auto& aec = VALUE_OR_RETURN(getParameterSpecificAec(aidl));
+    const auto& mobileMode = VALUE_OR_RETURN(UNION_GET(aec, mobileMode));
+    return VALUE_OR_RETURN(convertIntegral<uint32_t>(mobileMode));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_mobileMode_Parameter(const uint32_t& legacy) {
+    bool mode = VALUE_OR_RETURN(convertIntegral<bool>(legacy));
+    AcousticEchoCanceler aec = AcousticEchoCanceler::make<AcousticEchoCanceler::mobileMode>(mode);
+    Parameter::Specific specific =
+            Parameter::Specific::make<Parameter::Specific::acousticEchoCanceler>(aec);
+
+    return Parameter::make<Parameter::specific>(specific);
+}
+
 }  // namespace android
 }  // aidl
diff --git a/media/audioaidlconversion/include/media/AidlConversionNdk.h b/media/audioaidlconversion/include/media/AidlConversionNdk.h
index a3176f6..a1c0da7 100644
--- a/media/audioaidlconversion/include/media/AidlConversionNdk.h
+++ b/media/audioaidlconversion/include/media/AidlConversionNdk.h
@@ -32,6 +32,9 @@
 namespace aidl {
 namespace android {
 
+ConversionResult<::aidl::android::hardware::audio::effect::AcousticEchoCanceler>
+getParameterSpecificAec(const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+
 ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(
         ::aidl::android::hardware::audio::effect::Flags::Type type);
 ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(
@@ -61,8 +64,19 @@
 
 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(
+ConversionResult<media::audio::common::AudioConfigBase> legacy2aidl_buffer_config_t_AudioConfigBase(
         const buffer_config_t& legacy, bool isInput);
 
+ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_echoDelay(
+        const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_echoDelay_Parameter(const uint32_t& legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_mobileMode(
+        const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_mobileMode_Parameter(const uint32_t& legacy);
+
+
 }  // namespace android
 }  // namespace aidl
diff --git a/media/audioaidlconversion/include/media/AidlConversionUtil.h b/media/audioaidlconversion/include/media/AidlConversionUtil.h
index 28c7522..a0830fc 100644
--- a/media/audioaidlconversion/include/media/AidlConversionUtil.h
+++ b/media/audioaidlconversion/include/media/AidlConversionUtil.h
@@ -25,6 +25,7 @@
 #include <error/Result.h>
 
 #if defined(BACKEND_NDK)
+#include <android/binder_auto_utils.h>
 #include <android/binder_enums.h>
 #include <android/binder_status.h>
 
@@ -362,6 +363,20 @@
                                                     // standard Java exception (fromExceptionCode)
 }
 
+#if defined(BACKEND_NDK)
+static inline ::android::status_t statusTFromBinderStatus(const ::ndk::ScopedAStatus &status) {
+    // What we want to do is to 'return statusTFromBinderStatus(status.get()->get())'
+    // However, since the definition of AStatus is not exposed, we have to do the same
+    // via methods of ScopedAStatus:
+    return status.isOk() ? ::android::OK // check ::android::OK,
+        : status.getServiceSpecificError() // service-side error, not standard Java exception
+                                           // (fromServiceSpecificError)
+        ?: status.getStatus() // a native binder transaction error (fromStatusT)
+        ?: statusTFromExceptionCode(status.getExceptionCode()); // a service-side error with a
+                                                     // standard Java exception (fromExceptionCode)
+}
+#endif
+
 /**
  * Return a binder::Status from native service status.
  *
@@ -396,11 +411,10 @@
     return Status::fromServiceSpecificError(status, emptyIfNull);
 }
 
-
 } // namespace aidl_utils
 
 }  // namespace android
 
 #if defined(BACKEND_NDK)
 }  // namespace aidl
-#endif
\ No newline at end of file
+#endif
diff --git a/media/codec2/hidl/plugin/samples/Android.bp b/media/codec2/hidl/plugin/samples/Android.bp
index 32b760d..e0f8280 100644
--- a/media/codec2/hidl/plugin/samples/Android.bp
+++ b/media/codec2/hidl/plugin/samples/Android.bp
@@ -28,6 +28,7 @@
         "libGLESv1_CM",
         "libGLESv2",
         "libGLESv3",
+        "libvulkan",
         "libbase",
         "libcodec2",
         "libcutils",
diff --git a/media/libaaudio/tests/test_attributes.cpp b/media/libaaudio/tests/test_attributes.cpp
index b88d562..e5676a7 100644
--- a/media/libaaudio/tests/test_attributes.cpp
+++ b/media/libaaudio/tests/test_attributes.cpp
@@ -20,6 +20,7 @@
 // "test_aaudio_attributes.cpp". That other file is more current.
 // So these tests could be deleted.
 
+#include <memory>
 #include <stdio.h>
 #include <unistd.h>
 
@@ -40,7 +41,7 @@
                             int privacyMode = DONT_SET,
                             aaudio_direction_t direction = AAUDIO_DIRECTION_OUTPUT) {
 
-    float *buffer = new float[kNumFrames * kChannelCount];
+    std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
 
     AAudioStreamBuilder *aaudioBuilder = nullptr;
     AAudioStream *aaudioStream = nullptr;
@@ -109,16 +110,15 @@
 
     if (direction == AAUDIO_DIRECTION_INPUT) {
         EXPECT_EQ(kNumFrames,
-                  AAudioStream_read(aaudioStream, buffer, kNumFrames, kNanosPerSecond));
+                  AAudioStream_read(aaudioStream, buffer.get(), kNumFrames, kNanosPerSecond));
     } else {
         EXPECT_EQ(kNumFrames,
-                  AAudioStream_write(aaudioStream, buffer, kNumFrames, kNanosPerSecond));
+                  AAudioStream_write(aaudioStream, buffer.get(), kNumFrames, kNanosPerSecond));
     }
 
     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
 
     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
-    delete[] buffer;
 }
 
 static const aaudio_usage_t sUsages[] = {
diff --git a/media/libaaudio/tests/test_recovery.cpp b/media/libaaudio/tests/test_recovery.cpp
index 6e89f83..11331af 100644
--- a/media/libaaudio/tests/test_recovery.cpp
+++ b/media/libaaudio/tests/test_recovery.cpp
@@ -16,6 +16,7 @@
 
 // Play silence and recover from dead servers or disconnected devices.
 
+#include <memory>
 #include <stdio.h>
 
 #include <aaudio/AAudio.h>
@@ -32,7 +33,6 @@
     int32_t triesLeft = 3;
     int32_t bufferCapacity;
     int32_t framesPerBurst = 0;
-    float *buffer = nullptr;
 
     int32_t actualChannelCount = 0;
     int32_t actualSampleRate = 0;
@@ -83,7 +83,7 @@
         bufferCapacity, framesPerBurst);
 
         int samplesPerBurst = framesPerBurst * actualChannelCount;
-        buffer = new float[samplesPerBurst];
+        std::unique_ptr<float[]> buffer(new float[samplesPerBurst]);
 
         result = AAudioStream_requestStart(aaudioStream);
         if (result != AAUDIO_OK) {
@@ -98,7 +98,7 @@
         int64_t printAt = actualSampleRate;
         while (result == AAUDIO_OK && framesTotal < framesMax) {
             int32_t framesWritten = AAudioStream_write(aaudioStream,
-                                                       buffer, framesPerBurst,
+                                                       buffer.get(), framesPerBurst,
                                                        DEFAULT_TIMEOUT_NANOS);
             if (framesWritten < 0) {
                 result = framesWritten;
@@ -134,6 +134,5 @@
         AAudioStream_close(aaudioStream);
     }
     AAudioStreamBuilder_delete(aaudioBuilder);
-    delete[] buffer;
     printf("          result = %d = %s\n", result, AAudio_convertResultToText(result));
 }
diff --git a/media/libaaudio/tests/test_session_id.cpp b/media/libaaudio/tests/test_session_id.cpp
index 3f7d4fc..5968b5d 100644
--- a/media/libaaudio/tests/test_session_id.cpp
+++ b/media/libaaudio/tests/test_session_id.cpp
@@ -16,6 +16,7 @@
 
 // Test AAudio SessionId, which is used to associate Effects with a stream
 
+#include <memory>
 #include <stdio.h>
 #include <unistd.h>
 
@@ -29,7 +30,7 @@
 // Test AAUDIO_SESSION_ID_NONE default
 static void checkSessionIdNone(aaudio_performance_mode_t perfMode) {
 
-    float *buffer = new float[kNumFrames * kChannelCount];
+    std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
 
     AAudioStreamBuilder *aaudioBuilder = nullptr;
 
@@ -51,12 +52,12 @@
 
     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream1));
 
-    ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream1, buffer, kNumFrames, kNanosPerSecond));
+    ASSERT_EQ(kNumFrames,
+              AAudioStream_write(aaudioStream1, buffer.get(), kNumFrames, kNanosPerSecond));
 
     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream1));
 
     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream1));
-    delete[] buffer;
     AAudioStreamBuilder_delete(aaudioBuilder);
 }
 
@@ -72,7 +73,7 @@
 static void checkSessionIdAllocate(aaudio_performance_mode_t perfMode,
                                    aaudio_direction_t direction) {
 
-    float *buffer = new float[kNumFrames * kChannelCount];
+    std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
 
     AAudioStreamBuilder *aaudioBuilder = nullptr;
 
@@ -106,10 +107,10 @@
 
     if (direction == AAUDIO_DIRECTION_INPUT) {
         ASSERT_EQ(kNumFrames, AAudioStream_read(aaudioStream1,
-                                                buffer, kNumFrames, kNanosPerSecond));
+                                                buffer.get(), kNumFrames, kNanosPerSecond));
     } else {
         ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream1,
-                                         buffer, kNumFrames, kNanosPerSecond));
+                                         buffer.get(), kNumFrames, kNanosPerSecond));
     }
 
     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream1));
@@ -135,10 +136,10 @@
 
     if (otherDirection == AAUDIO_DIRECTION_INPUT) {
         ASSERT_EQ(kNumFrames, AAudioStream_read(aaudioStream2,
-                                                 buffer, kNumFrames, kNanosPerSecond));
+                                                 buffer.get(), kNumFrames, kNanosPerSecond));
     } else {
         ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream2,
-                                                 buffer, kNumFrames, kNanosPerSecond));
+                                                 buffer.get(), kNumFrames, kNanosPerSecond));
     }
 
     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream2));
@@ -147,7 +148,6 @@
 
 
     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream1));
-    delete[] buffer;
     AAudioStreamBuilder_delete(aaudioBuilder);
 }
 
diff --git a/media/libaudioclient/AidlConversion.cpp b/media/libaudioclient/AidlConversion.cpp
index f75e58d..f65ff18 100644
--- a/media/libaudioclient/AidlConversion.cpp
+++ b/media/libaudioclient/AidlConversion.cpp
@@ -416,8 +416,8 @@
     LOG_ALWAYS_FATAL("Shouldn't get here"); // with -Werror,-Wswitch may compile-time fail
 }
 
-ConversionResult<audio_port_config> aidl2legacy_AudioPortConfig_audio_port_config(
-        const media::AudioPortConfig& aidl) {
+ConversionResult<audio_port_config> aidl2legacy_AudioPortConfigFw_audio_port_config(
+        const media::AudioPortConfigFw& aidl) {
     audio_port_config legacy{};
     legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.hal.id));
     legacy.role = VALUE_OR_RETURN(aidl2legacy_AudioPortRole_audio_port_role_t(aidl.sys.role));
@@ -457,9 +457,9 @@
     return legacy;
 }
 
-ConversionResult<media::AudioPortConfig> legacy2aidl_audio_port_config_AudioPortConfig(
+ConversionResult<media::AudioPortConfigFw> legacy2aidl_audio_port_config_AudioPortConfigFw(
         const audio_port_config& legacy) {
-    media::AudioPortConfig aidl;
+    media::AudioPortConfigFw aidl;
     aidl.hal.id = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(legacy.id));
     aidl.sys.role = VALUE_OR_RETURN(legacy2aidl_audio_port_role_t_AudioPortRole(legacy.role));
     aidl.sys.type = VALUE_OR_RETURN(legacy2aidl_audio_port_type_t_AudioPortType(legacy.type));
@@ -491,8 +491,8 @@
     return aidl;
 }
 
-ConversionResult<struct audio_patch> aidl2legacy_AudioPatch_audio_patch(
-        const media::AudioPatch& aidl) {
+ConversionResult<struct audio_patch> aidl2legacy_AudioPatchFw_audio_patch(
+        const media::AudioPatchFw& aidl) {
     struct audio_patch legacy;
     legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_patch_handle_t(aidl.id));
     legacy.num_sinks = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.sinks.size()));
@@ -501,7 +501,7 @@
     }
     for (size_t i = 0; i < legacy.num_sinks; ++i) {
         legacy.sinks[i] =
-                VALUE_OR_RETURN(aidl2legacy_AudioPortConfig_audio_port_config(aidl.sinks[i]));
+                VALUE_OR_RETURN(aidl2legacy_AudioPortConfigFw_audio_port_config(aidl.sinks[i]));
     }
     legacy.num_sources = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.sources.size()));
     if (legacy.num_sources > AUDIO_PATCH_PORTS_MAX) {
@@ -509,14 +509,14 @@
     }
     for (size_t i = 0; i < legacy.num_sources; ++i) {
         legacy.sources[i] =
-                VALUE_OR_RETURN(aidl2legacy_AudioPortConfig_audio_port_config(aidl.sources[i]));
+                VALUE_OR_RETURN(aidl2legacy_AudioPortConfigFw_audio_port_config(aidl.sources[i]));
     }
     return legacy;
 }
 
-ConversionResult<media::AudioPatch> legacy2aidl_audio_patch_AudioPatch(
+ConversionResult<media::AudioPatchFw> legacy2aidl_audio_patch_AudioPatchFw(
         const struct audio_patch& legacy) {
-    media::AudioPatch aidl;
+    media::AudioPatchFw aidl;
     aidl.id = VALUE_OR_RETURN(legacy2aidl_audio_patch_handle_t_int32_t(legacy.id));
 
     if (legacy.num_sinks > AUDIO_PATCH_PORTS_MAX) {
@@ -524,14 +524,14 @@
     }
     for (unsigned int i = 0; i < legacy.num_sinks; ++i) {
         aidl.sinks.push_back(
-                VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfig(legacy.sinks[i])));
+                VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfigFw(legacy.sinks[i])));
     }
     if (legacy.num_sources > AUDIO_PATCH_PORTS_MAX) {
         return unexpected(BAD_VALUE);
     }
     for (unsigned int i = 0; i < legacy.num_sources; ++i) {
         aidl.sources.push_back(
-                VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfig(legacy.sources[i])));
+                VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfigFw(legacy.sources[i])));
     }
     return aidl;
 }
@@ -541,7 +541,7 @@
     const audio_io_handle_t io_handle = VALUE_OR_RETURN(
             aidl2legacy_int32_t_audio_io_handle_t(aidl.ioHandle));
     const struct audio_patch patch = VALUE_OR_RETURN(
-            aidl2legacy_AudioPatch_audio_patch(aidl.patch));
+            aidl2legacy_AudioPatchFw_audio_patch(aidl.patch));
     const bool isInput = aidl.isInput;
     const uint32_t sampling_rate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.samplingRate));
     const audio_format_t format = VALUE_OR_RETURN(
@@ -561,7 +561,7 @@
         const sp<AudioIoDescriptor>& legacy) {
     media::AudioIoDescriptor aidl;
     aidl.ioHandle = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(legacy->getIoHandle()));
-    aidl.patch = VALUE_OR_RETURN(legacy2aidl_audio_patch_AudioPatch(legacy->getPatch()));
+    aidl.patch = VALUE_OR_RETURN(legacy2aidl_audio_patch_AudioPatchFw(legacy->getPatch()));
     aidl.isInput = legacy->getIsInput();
     aidl.samplingRate = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy->getSamplingRate()));
     aidl.format = VALUE_OR_RETURN(
@@ -930,7 +930,7 @@
 }
 
 ConversionResult<audio_port_v7>
-aidl2legacy_AudioPort_audio_port_v7(const media::AudioPort& aidl) {
+aidl2legacy_AudioPortFw_audio_port_v7(const media::AudioPortFw& aidl) {
     audio_port_v7 legacy;
     legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.hal.id));
     legacy.role = VALUE_OR_RETURN(aidl2legacy_AudioPortRole_audio_port_role_t(aidl.sys.role));
@@ -969,15 +969,15 @@
     legacy.num_gains = aidl.hal.gains.size();
 
     legacy.active_config = VALUE_OR_RETURN(
-            aidl2legacy_AudioPortConfig_audio_port_config(aidl.sys.activeConfig));
+            aidl2legacy_AudioPortConfigFw_audio_port_config(aidl.sys.activeConfig));
     legacy.ext = VALUE_OR_RETURN(
             aidl2legacy_AudioPortExt_audio_port_v7_ext(aidl.hal.ext, aidl.sys.type, aidl.sys.ext));
     return legacy;
 }
 
-ConversionResult<media::AudioPort>
-legacy2aidl_audio_port_v7_AudioPort(const audio_port_v7& legacy) {
-    media::AudioPort aidl;
+ConversionResult<media::AudioPortFw>
+legacy2aidl_audio_port_v7_AudioPortFw(const audio_port_v7& legacy) {
+    media::AudioPortFw aidl;
     aidl.hal.id = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(legacy.id));
     aidl.sys.role = VALUE_OR_RETURN(legacy2aidl_audio_port_role_t_AudioPortRole(legacy.role));
     aidl.sys.type = VALUE_OR_RETURN(legacy2aidl_audio_port_type_t_AudioPortType(legacy.type));
@@ -1016,7 +1016,7 @@
     aidl.sys.gains.resize(legacy.num_gains);
 
     aidl.sys.activeConfig = VALUE_OR_RETURN(
-            legacy2aidl_audio_port_config_AudioPortConfig(legacy.active_config));
+            legacy2aidl_audio_port_config_AudioPortConfigFw(legacy.active_config));
     aidl.sys.activeConfig.hal.portId = aidl.hal.id;
     RETURN_IF_ERROR(
             legacy2aidl_AudioPortExt(legacy.ext, legacy.type, &aidl.hal.ext, &aidl.sys.ext));
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index bcaaa6e..1c0535d 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -287,10 +287,10 @@
         "aidl/android/media/AudioHalVersion.aidl",
         "aidl/android/media/AudioIoConfigEvent.aidl",
         "aidl/android/media/AudioIoDescriptor.aidl",
-        "aidl/android/media/AudioPatch.aidl",
-        "aidl/android/media/AudioPort.aidl",
+        "aidl/android/media/AudioPatchFw.aidl",
+        "aidl/android/media/AudioPortFw.aidl",
         "aidl/android/media/AudioPortSys.aidl",
-        "aidl/android/media/AudioPortConfig.aidl",
+        "aidl/android/media/AudioPortConfigFw.aidl",
         "aidl/android/media/AudioPortConfigSys.aidl",
         "aidl/android/media/AudioPortDeviceExtSys.aidl",
         "aidl/android/media/AudioPortExtSys.aidl",
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 0d16f47..31d95e6 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1532,7 +1532,7 @@
             legacy2aidl_audio_port_type_t_AudioPortType(type));
     Int numPortsAidl;
     numPortsAidl.value = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*num_ports));
-    std::vector<media::AudioPort> portsAidl;
+    std::vector<media::AudioPortFw> portsAidl;
     int32_t generationAidl;
 
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
@@ -1540,7 +1540,7 @@
     *num_ports = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(numPortsAidl.value));
     *generation = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(generationAidl));
     RETURN_STATUS_IF_ERROR(convertRange(portsAidl.begin(), portsAidl.end(), ports,
-                                        aidl2legacy_AudioPort_audio_port_v7));
+                                        aidl2legacy_AudioPortFw_audio_port_v7));
     return OK;
 }
 
@@ -1551,10 +1551,10 @@
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
 
-    media::AudioPort portAidl;
+    media::AudioPortFw portAidl;
     RETURN_STATUS_IF_ERROR(
             statusTFromBinderStatus(aps->getAudioPort(port->id, &portAidl)));
-    *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPort_audio_port_v7(portAidl));
+    *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortFw_audio_port_v7(portAidl));
     return OK;
 }
 
@@ -1567,8 +1567,8 @@
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
 
-    media::AudioPatch patchAidl = VALUE_OR_RETURN_STATUS(
-            legacy2aidl_audio_patch_AudioPatch(*patch));
+    media::AudioPatchFw patchAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_patch_AudioPatchFw(*patch));
     int32_t handleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_handle_t_int32_t(*handle));
     RETURN_STATUS_IF_ERROR(
             statusTFromBinderStatus(aps->createAudioPatch(patchAidl, handleAidl, &handleAidl)));
@@ -1598,7 +1598,7 @@
 
     Int numPatchesAidl;
     numPatchesAidl.value = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*num_patches));
-    std::vector<media::AudioPatch> patchesAidl;
+    std::vector<media::AudioPatchFw> patchesAidl;
     int32_t generationAidl;
 
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
@@ -1606,7 +1606,7 @@
     *num_patches = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(numPatchesAidl.value));
     *generation = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(generationAidl));
     RETURN_STATUS_IF_ERROR(convertRange(patchesAidl.begin(), patchesAidl.end(), patches,
-                                        aidl2legacy_AudioPatch_audio_patch));
+                                        aidl2legacy_AudioPatchFw_audio_patch));
     return OK;
 }
 
@@ -1618,8 +1618,8 @@
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
 
-    media::AudioPortConfig configAidl = VALUE_OR_RETURN_STATUS(
-            legacy2aidl_audio_port_config_AudioPortConfig(*config));
+    media::AudioPortConfigFw configAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_port_config_AudioPortConfigFw(*config));
     return statusTFromBinderStatus(aps->setAudioPortConfig(configAidl));
 }
 
@@ -1839,8 +1839,8 @@
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
 
-    media::AudioPortConfig sourceAidl = VALUE_OR_RETURN_STATUS(
-            legacy2aidl_audio_port_config_AudioPortConfig(*source));
+    media::AudioPortConfigFw sourceAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_port_config_AudioPortConfigFw(*source));
     media::AudioAttributesInternal attributesAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attributes));
     int32_t portIdAidl;
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index b3c9f07..255fd1e 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -666,17 +666,19 @@
 }
 
 status_t AudioFlingerClientAdapter::getAudioPort(struct audio_port_v7* port) {
-    media::AudioPort portAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_v7_AudioPort(*port));
-    media::AudioPort aidlRet;
+    media::AudioPortFw portAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_port_v7_AudioPortFw(*port));
+    media::AudioPortFw aidlRet;
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
             mDelegate->getAudioPort(portAidl, &aidlRet)));
-    *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPort_audio_port_v7(aidlRet));
+    *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortFw_audio_port_v7(aidlRet));
     return OK;
 }
 
 status_t AudioFlingerClientAdapter::createAudioPatch(const struct audio_patch* patch,
                                                      audio_patch_handle_t* handle) {
-    media::AudioPatch patchAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_AudioPatch(*patch));
+    media::AudioPatchFw patchAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_patch_AudioPatchFw(*patch));
     int32_t aidlRet = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_handle_t_int32_t(
                     AUDIO_PATCH_HANDLE_NONE));
     if (handle != nullptr) {
@@ -697,18 +699,18 @@
 
 status_t AudioFlingerClientAdapter::listAudioPatches(unsigned int* num_patches,
                                                      struct audio_patch* patches) {
-    std::vector<media::AudioPatch> aidlRet;
+    std::vector<media::AudioPatchFw> aidlRet;
     int32_t maxPatches = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*num_patches));
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
             mDelegate->listAudioPatches(maxPatches, &aidlRet)));
     *num_patches = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(aidlRet.size()));
     return convertRange(aidlRet.begin(), aidlRet.end(), patches,
-                        aidl2legacy_AudioPatch_audio_patch);
+                        aidl2legacy_AudioPatchFw_audio_patch);
 }
 
 status_t AudioFlingerClientAdapter::setAudioPortConfig(const struct audio_port_config* config) {
-    media::AudioPortConfig configAidl = VALUE_OR_RETURN_STATUS(
-            legacy2aidl_audio_port_config_AudioPortConfig(*config));
+    media::AudioPortConfigFw configAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_port_config_AudioPortConfigFw(*config));
     return statusTFromBinderStatus(mDelegate->setAudioPortConfig(configAidl));
 }
 
@@ -805,8 +807,8 @@
 
 status_t AudioFlingerClientAdapter::setDeviceConnectedState(
         const struct audio_port_v7 *port, bool connected) {
-    media::AudioPort aidlPort = VALUE_OR_RETURN_STATUS(
-            legacy2aidl_audio_port_v7_AudioPort(*port));
+    media::AudioPortFw aidlPort = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_port_v7_AudioPortFw(*port));
     return statusTFromBinderStatus(mDelegate->setDeviceConnectedState(aidlPort, connected));
 }
 
@@ -1237,17 +1239,17 @@
     return Status::fromStatusT(mDelegate->setLowRamDevice(isLowRamDevice, totalMemory));
 }
 
-Status AudioFlingerServerAdapter::getAudioPort(const media::AudioPort& port,
-                                               media::AudioPort* _aidl_return) {
-    audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPort_audio_port_v7(port));
+Status AudioFlingerServerAdapter::getAudioPort(const media::AudioPortFw& port,
+                                               media::AudioPortFw* _aidl_return) {
+    audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPortFw_audio_port_v7(port));
     RETURN_BINDER_IF_ERROR(mDelegate->getAudioPort(&portLegacy));
-    *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_port_v7_AudioPort(portLegacy));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_port_v7_AudioPortFw(portLegacy));
     return Status::ok();
 }
 
-Status AudioFlingerServerAdapter::createAudioPatch(const media::AudioPatch& patch,
+Status AudioFlingerServerAdapter::createAudioPatch(const media::AudioPatchFw& patch,
                                                    int32_t* _aidl_return) {
-    audio_patch patchLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPatch_audio_patch(patch));
+    audio_patch patchLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPatchFw_audio_patch(patch));
     audio_patch_handle_t handleLegacy = VALUE_OR_RETURN_BINDER(
             aidl2legacy_int32_t_audio_patch_handle_t(*_aidl_return));
     RETURN_BINDER_IF_ERROR(mDelegate->createAudioPatch(&patchLegacy, &handleLegacy));
@@ -1262,7 +1264,7 @@
 }
 
 Status AudioFlingerServerAdapter::listAudioPatches(int32_t maxCount,
-                            std::vector<media::AudioPatch>* _aidl_return) {
+                            std::vector<media::AudioPatchFw>* _aidl_return) {
     unsigned int count = VALUE_OR_RETURN_BINDER(convertIntegral<unsigned int>(maxCount));
     count = std::min(count, static_cast<unsigned int>(MAX_ITEMS_PER_LIST));
     std::unique_ptr<audio_patch[]> patchesLegacy(new audio_patch[count]);
@@ -1270,13 +1272,13 @@
     RETURN_BINDER_IF_ERROR(convertRange(&patchesLegacy[0],
                            &patchesLegacy[count],
                            std::back_inserter(*_aidl_return),
-                           legacy2aidl_audio_patch_AudioPatch));
+                           legacy2aidl_audio_patch_AudioPatchFw));
     return Status::ok();
 }
 
-Status AudioFlingerServerAdapter::setAudioPortConfig(const media::AudioPortConfig& config) {
+Status AudioFlingerServerAdapter::setAudioPortConfig(const media::AudioPortConfigFw& config) {
     audio_port_config configLegacy = VALUE_OR_RETURN_BINDER(
-            aidl2legacy_AudioPortConfig_audio_port_config(config));
+            aidl2legacy_AudioPortConfigFw_audio_port_config(config));
     return Status::fromStatusT(mDelegate->setAudioPortConfig(&configLegacy));
 }
 
@@ -1354,8 +1356,8 @@
 }
 
 Status AudioFlingerServerAdapter::setDeviceConnectedState(
-        const media::AudioPort& port, bool connected) {
-    audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPort_audio_port_v7(port));
+        const media::AudioPortFw& port, bool connected) {
+    audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPortFw_audio_port_v7(port));
     return Status::fromStatusT(mDelegate->setDeviceConnectedState(&portLegacy, connected));
 }
 
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index f968a4b..f0b4d11 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -1027,7 +1027,7 @@
     if (property_get("gsm.operator.iso-country", value, "") == 0) {
         property_get("gsm.sim.operator.iso-country", value, "");
     }
-    // If dual sim device has two SIM cards inserted and is not registerd to any network,
+    // If dual sim device has two SIM cards inserted and is not registered to any network,
     // "," is set to "gsm.operator.iso-country" prop.
     // In this case, "gsm.sim.operator.iso-country" prop should be used.
     if (strlen(value) == 1 && strstr(value, ",") != NULL) {
diff --git a/media/libaudioclient/aidl/android/media/AudioIoDescriptor.aidl b/media/libaudioclient/aidl/android/media/AudioIoDescriptor.aidl
index b01f902..5dd898c 100644
--- a/media/libaudioclient/aidl/android/media/AudioIoDescriptor.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioIoDescriptor.aidl
@@ -16,7 +16,7 @@
 
 package android.media;
 
-import android.media.AudioPatch;
+import android.media.AudioPatchFw;
 import android.media.audio.common.AudioChannelLayout;
 import android.media.audio.common.AudioFormatDescription;
 
@@ -26,7 +26,7 @@
 parcelable AudioIoDescriptor {
     /** Interpreted as audio_io_handle_t. */
     int ioHandle;
-    AudioPatch patch;
+    AudioPatchFw patch;
     boolean isInput;
     int samplingRate;
     AudioFormatDescription format;
diff --git a/media/libaudioclient/aidl/android/media/AudioPatch.aidl b/media/libaudioclient/aidl/android/media/AudioPatchFw.aidl
similarity index 74%
rename from media/libaudioclient/aidl/android/media/AudioPatch.aidl
rename to media/libaudioclient/aidl/android/media/AudioPatchFw.aidl
index 8519faf..9ec3fa9 100644
--- a/media/libaudioclient/aidl/android/media/AudioPatch.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPatchFw.aidl
@@ -16,17 +16,19 @@
 
 package android.media;
 
-import android.media.AudioPortConfig;
+import android.media.AudioPortConfigFw;
 
 /**
  * {@hide}
+ * The Fw suffix is used to break a namespace collision with an SDK API.
+ * It contains the framework version of AudioPortConfig.
  */
-parcelable AudioPatch {
+parcelable AudioPatchFw {
     /**
      * Patch unique ID.
      * Interpreted as audio_patch_handle_t.
      */
     int id;
-    AudioPortConfig[] sources;
-    AudioPortConfig[] sinks;
+    AudioPortConfigFw[] sources;
+    AudioPortConfigFw[] sinks;
 }
diff --git a/media/libaudioclient/aidl/android/media/AudioPortConfig.aidl b/media/libaudioclient/aidl/android/media/AudioPortConfigFw.aidl
similarity index 89%
rename from media/libaudioclient/aidl/android/media/AudioPortConfig.aidl
rename to media/libaudioclient/aidl/android/media/AudioPortConfigFw.aidl
index 3a4ca31..e7565d7 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortConfig.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortConfigFw.aidl
@@ -21,8 +21,9 @@
 
 /**
  * {@hide}
+ * Suffixed with Fw to avoid name conflict with SDK class.
  */
-parcelable AudioPortConfig {
+parcelable AudioPortConfigFw {
     AudioPortConfig hal;
     AudioPortConfigSys sys;
 }
diff --git a/media/libaudioclient/aidl/android/media/AudioPort.aidl b/media/libaudioclient/aidl/android/media/AudioPortFw.aidl
similarity index 88%
rename from media/libaudioclient/aidl/android/media/AudioPort.aidl
rename to media/libaudioclient/aidl/android/media/AudioPortFw.aidl
index ff177c0..5580e35 100644
--- a/media/libaudioclient/aidl/android/media/AudioPort.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortFw.aidl
@@ -21,8 +21,9 @@
 
 /**
  * {@hide}
+ * The Fw suffix is used to break a namespace collision with an SDK API.
  */
-parcelable AudioPort {
+parcelable AudioPortFw {
     AudioPort hal;
     AudioPortSys sys;
 }
diff --git a/media/libaudioclient/aidl/android/media/AudioPortSys.aidl b/media/libaudioclient/aidl/android/media/AudioPortSys.aidl
index f3b5c19..756c469 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortSys.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortSys.aidl
@@ -17,7 +17,7 @@
 package android.media;
 
 import android.media.AudioGainSys;
-import android.media.AudioPortConfig;
+import android.media.AudioPortConfigFw;
 import android.media.AudioPortExtSys;
 import android.media.AudioPortRole;
 import android.media.AudioPortType;
@@ -36,7 +36,7 @@
     /** System-only parameters for each AudioGain from 'port.gains'. */
     AudioGainSys[] gains;
     /** Current audio port configuration. */
-    AudioPortConfig activeConfig;
+    AudioPortConfigFw activeConfig;
     /** System-only extra parameters for 'port.ext'. */
     AudioPortExtSys ext;
 }
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index 1111160..51bf05a 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -16,9 +16,9 @@
 
 package android.media;
 
-import android.media.AudioPatch;
-import android.media.AudioPort;
-import android.media.AudioPortConfig;
+import android.media.AudioPatchFw;
+import android.media.AudioPortFw;
+import android.media.AudioPortConfigFw;
 import android.media.AudioUniqueIdUse;
 import android.media.AudioVibratorInfo;
 import android.media.CreateEffectRequest;
@@ -182,18 +182,18 @@
     void setLowRamDevice(boolean isLowRamDevice, long totalMemory);
 
     /* Get attributes for a given audio port */
-    AudioPort getAudioPort(in AudioPort port);
+    AudioPortFw getAudioPort(in AudioPortFw port);
 
     /* Create an audio patch between several source and sink ports */
-    int /* audio_patch_handle_t */ createAudioPatch(in AudioPatch patch);
+    int /* audio_patch_handle_t */ createAudioPatch(in AudioPatchFw patch);
 
     /* Release an audio patch */
     void releaseAudioPatch(int /* audio_patch_handle_t */ handle);
 
     /* List existing audio patches */
-    AudioPatch[] listAudioPatches(int maxCount);
+    AudioPatchFw[] listAudioPatches(int maxCount);
     /* Set audio port configuration */
-    void setAudioPortConfig(in AudioPortConfig config);
+    void setAudioPortConfig(in AudioPortConfigFw config);
 
     /* Get the HW synchronization source used for an audio session */
     int /* audio_hw_sync_t */ getAudioHwSyncForSession(int /* audio_session_t */ sessionId);
@@ -227,7 +227,7 @@
 
     int getAAudioHardwareBurstMinUsec();
 
-    void setDeviceConnectedState(in AudioPort devicePort, boolean connected);
+    void setDeviceConnectedState(in AudioPortFw devicePort, boolean connected);
 
     /**
      * Requests a given latency mode (See AudioLatencyMode.aidl) on an output stream.
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index 8ac89a8..ed7e243 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -23,12 +23,12 @@
 import android.media.AudioDirectMode;
 import android.media.AudioMix;
 import android.media.AudioOffloadMode;
-import android.media.AudioPatch;
+import android.media.AudioPatchFw;
 import android.media.AudioPolicyDeviceState;
 import android.media.AudioPolicyForcedConfig;
 import android.media.AudioPolicyForceUse;
-import android.media.AudioPort;
-import android.media.AudioPortConfig;
+import android.media.AudioPortFw;
+import android.media.AudioPortConfigFw;
 import android.media.AudioPortRole;
 import android.media.AudioPortType;
 import android.media.AudioProductStrategy;
@@ -212,16 +212,16 @@
     int listAudioPorts(AudioPortRole role,
                        AudioPortType type,
                        inout Int count,
-                       out AudioPort[] ports);
+                       out AudioPortFw[] ports);
 
     /** Get attributes for the audio port with the given id (AudioPort.hal.id field). */
-    AudioPort getAudioPort(int /* audio_port_handle_t */ portId);
+    AudioPortFw getAudioPort(int /* audio_port_handle_t */ portId);
 
     /**
      * Create an audio patch between several source and sink ports.
      * The handle argument is used when updating an existing patch.
      */
-    int /* audio_patch_handle_t */ createAudioPatch(in AudioPatch patch, int handle);
+    int /* audio_patch_handle_t */ createAudioPatch(in AudioPatchFw patch, int handle);
 
     /** Release an audio patch. */
     void releaseAudioPatch(int /* audio_patch_handle_t */ handle);
@@ -234,10 +234,10 @@
      * Passing '0' on input and inspecting the value on output is a common way of determining the
      * number of elements without actually retrieving them.
      */
-    int listAudioPatches(inout Int count, out AudioPatch[] patches);
+    int listAudioPatches(inout Int count, out AudioPatchFw[] patches);
 
     /** Set audio port configuration. */
-    void setAudioPortConfig(in AudioPortConfig config);
+    void setAudioPortConfig(in AudioPortConfigFw config);
 
     void registerClient(IAudioPolicyServiceClient client);
 
@@ -261,7 +261,7 @@
 
     void removeUserIdDeviceAffinities(int userId);
 
-    int /* audio_port_handle_t */ startAudioSource(in AudioPortConfig source,
+    int /* audio_port_handle_t */ startAudioSource(in AudioPortConfigFw source,
                                                    in AudioAttributesInternal attributes);
 
     void stopAudioSource(int /* audio_port_handle_t */ portId);
diff --git a/media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl b/media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl
index 90e7ea6..ddda8bb 100644
--- a/media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl
+++ b/media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl
@@ -16,7 +16,7 @@
 
 package android.media;
 
-import android.media.AudioPort;
+import android.media.AudioPortFw;
 import android.media.audio.common.AudioConfig;
 import android.media.audio.common.AudioConfigBase;
 
@@ -29,7 +29,7 @@
     AudioConfig halConfig;
     AudioConfigBase mixerConfig;
     /** Type must be DEVICE. */
-    AudioPort device;
+    AudioPortFw device;
     /** Bitmask, indexed by AudioOutputFlag. */
     int flags;
 }
diff --git a/media/libaudioclient/include/media/AidlConversion.h b/media/libaudioclient/include/media/AidlConversion.h
index b0f84a4..9a88f76 100644
--- a/media/libaudioclient/include/media/AidlConversion.h
+++ b/media/libaudioclient/include/media/AidlConversion.h
@@ -27,8 +27,8 @@
 #include <android/media/AudioFlag.h>
 #include <android/media/AudioIoConfigEvent.h>
 #include <android/media/AudioIoDescriptor.h>
-#include <android/media/AudioPort.h>
-#include <android/media/AudioPortConfig.h>
+#include <android/media/AudioPortFw.h>
+#include <android/media/AudioPortConfigFw.h>
 #include <android/media/AudioPortDeviceExtSys.h>
 #include <android/media/AudioTimestampInternal.h>
 #include <android/media/AudioUniqueIdUse.h>
@@ -88,14 +88,14 @@
 ConversionResult<int32_t> legacy2aidl_audio_port_config_session_ext_AudioPortConfigSessionExt(
         const audio_port_config_session_ext& legacy);
 
-ConversionResult<audio_port_config> aidl2legacy_AudioPortConfig_audio_port_config(
-        const media::AudioPortConfig& aidl);
-ConversionResult<media::AudioPortConfig> legacy2aidl_audio_port_config_AudioPortConfig(
+ConversionResult<audio_port_config> aidl2legacy_AudioPortConfigFw_audio_port_config(
+        const media::AudioPortConfigFw& aidl);
+ConversionResult<media::AudioPortConfigFw> legacy2aidl_audio_port_config_AudioPortConfigFw(
         const audio_port_config& legacy);
 
-ConversionResult<struct audio_patch> aidl2legacy_AudioPatch_audio_patch(
-        const media::AudioPatch& aidl);
-ConversionResult<media::AudioPatch> legacy2aidl_audio_patch_AudioPatch(
+ConversionResult<struct audio_patch> aidl2legacy_AudioPatchFw_audio_patch(
+        const media::AudioPatchFw& aidl);
+ConversionResult<media::AudioPatchFw> legacy2aidl_audio_patch_AudioPatchFw(
         const struct audio_patch& legacy);
 
 ConversionResult<sp<AudioIoDescriptor>> aidl2legacy_AudioIoDescriptor_AudioIoDescriptor(
@@ -167,9 +167,9 @@
 legacy2aidl_audio_port_session_ext_int32_t(const audio_port_session_ext& legacy);
 
 ConversionResult<audio_port_v7>
-aidl2legacy_AudioPort_audio_port_v7(const media::AudioPort& aidl);
-ConversionResult<media::AudioPort>
-legacy2aidl_audio_port_v7_AudioPort(const audio_port_v7& legacy);
+aidl2legacy_AudioPortFw_audio_port_v7(const media::AudioPortFw& aidl);
+ConversionResult<media::AudioPortFw>
+legacy2aidl_audio_port_v7_AudioPortFw(const audio_port_v7& legacy);
 
 ConversionResult<audio_unique_id_use_t>
 aidl2legacy_AudioUniqueIdUse_audio_unique_id_use_t(media::AudioUniqueIdUse aidl);
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 36ee96b..1177e5a 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -678,12 +678,12 @@
     Status getPrimaryOutputSamplingRate(int32_t* _aidl_return) override;
     Status getPrimaryOutputFrameCount(int64_t* _aidl_return) override;
     Status setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) override;
-    Status getAudioPort(const media::AudioPort& port, media::AudioPort* _aidl_return) override;
-    Status createAudioPatch(const media::AudioPatch& patch, int32_t* _aidl_return) override;
+    Status getAudioPort(const media::AudioPortFw& port, media::AudioPortFw* _aidl_return) override;
+    Status createAudioPatch(const media::AudioPatchFw& patch, int32_t* _aidl_return) override;
     Status releaseAudioPatch(int32_t handle) override;
     Status listAudioPatches(int32_t maxCount,
-                            std::vector<media::AudioPatch>* _aidl_return) override;
-    Status setAudioPortConfig(const media::AudioPortConfig& config) override;
+                            std::vector<media::AudioPatchFw>* _aidl_return) override;
+    Status setAudioPortConfig(const media::AudioPortConfigFw& config) override;
     Status getAudioHwSyncForSession(int32_t sessionId, int32_t* _aidl_return) override;
     Status systemReady() override;
     Status audioPolicyReady() override;
@@ -698,7 +698,7 @@
             std::vector<media::audio::common::AudioMMapPolicyInfo> *_aidl_return) override;
     Status getAAudioMixerBurstCount(int32_t* _aidl_return) override;
     Status getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) override;
-    Status setDeviceConnectedState(const media::AudioPort& port, bool connected) override;
+    Status setDeviceConnectedState(const media::AudioPortFw& port, bool connected) override;
     Status setRequestedLatencyMode(
             int output, media::audio::common::AudioLatencyMode mode) override;
     Status getSupportedLatencyModes(int output,
diff --git a/media/libaudiofoundation/AudioPort.cpp b/media/libaudiofoundation/AudioPort.cpp
index 4513323..6e05abc 100644
--- a/media/libaudiofoundation/AudioPort.cpp
+++ b/media/libaudiofoundation/AudioPort.cpp
@@ -222,7 +222,7 @@
            mExtraAudioDescriptors == other->getExtraAudioDescriptors();
 }
 
-status_t AudioPort::writeToParcelable(media::AudioPort* parcelable) const {
+status_t AudioPort::writeToParcelable(media::AudioPortFw* parcelable) const {
     parcelable->hal.name = mName;
     parcelable->sys.type = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_port_type_t_AudioPortType(mType));
@@ -249,7 +249,7 @@
     return OK;
 }
 
-status_t AudioPort::readFromParcelable(const media::AudioPort& parcelable) {
+status_t AudioPort::readFromParcelable(const media::AudioPortFw& parcelable) {
     mName = parcelable.hal.name;
     mType = VALUE_OR_RETURN_STATUS(
             aidl2legacy_AudioPortType_audio_port_type_t(parcelable.sys.type));
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index 5ffbffc..4185b5f 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -174,7 +174,7 @@
     return false;
 }
 
-status_t DeviceDescriptorBase::writeToParcelable(media::AudioPort* parcelable) const {
+status_t DeviceDescriptorBase::writeToParcelable(media::AudioPortFw* parcelable) const {
     AudioPort::writeToParcelable(parcelable);
     AudioPortConfig::writeToParcelable(&parcelable->sys.activeConfig.hal, useInputChannelMask());
     parcelable->hal.id = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(mId));
@@ -196,7 +196,7 @@
     return OK;
 }
 
-status_t DeviceDescriptorBase::readFromParcelable(const media::AudioPort& parcelable) {
+status_t DeviceDescriptorBase::readFromParcelable(const media::AudioPortFw& parcelable) {
     if (parcelable.sys.type != media::AudioPortType::DEVICE) {
         return BAD_VALUE;
     }
@@ -245,7 +245,7 @@
 }
 
 ConversionResult<sp<DeviceDescriptorBase>>
-aidl2legacy_DeviceDescriptorBase(const media::AudioPort& aidl) {
+aidl2legacy_DeviceDescriptorBase(const media::AudioPortFw& aidl) {
     sp<DeviceDescriptorBase> result = new DeviceDescriptorBase(AUDIO_DEVICE_NONE);
     status_t status = result->readFromParcelable(aidl);
     if (status != OK) {
@@ -254,9 +254,9 @@
     return result;
 }
 
-ConversionResult<media::AudioPort>
+ConversionResult<media::AudioPortFw>
 legacy2aidl_DeviceDescriptorBase(const sp<DeviceDescriptorBase>& legacy) {
-    media::AudioPort aidl;
+    media::AudioPortFw aidl;
     status_t status = legacy->writeToParcelable(&aidl);
     if (status != OK) {
         return base::unexpected(status);
diff --git a/media/libaudiofoundation/include/media/AudioPort.h b/media/libaudiofoundation/include/media/AudioPort.h
index b1235f5..77e58ed 100644
--- a/media/libaudiofoundation/include/media/AudioPort.h
+++ b/media/libaudiofoundation/include/media/AudioPort.h
@@ -19,8 +19,8 @@
 #include <string>
 #include <type_traits>
 
-#include <android/media/AudioPort.h>
-#include <android/media/AudioPortConfig.h>
+#include <android/media/AudioPortFw.h>
+#include <android/media/AudioPortConfigFw.h>
 #include <android/media/audio/common/ExtraAudioDescriptor.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
@@ -118,8 +118,8 @@
 
     bool equals(const sp<AudioPort>& other) const;
 
-    status_t writeToParcelable(media::AudioPort* parcelable) const;
-    status_t readFromParcelable(const media::AudioPort& parcelable);
+    status_t writeToParcelable(media::AudioPortFw* parcelable) const;
+    status_t readFromParcelable(const media::AudioPortFw& parcelable);
 
     AudioGains mGains; // gain controllers
     // Maximum number of input or output streams that can be simultaneously
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index dc2899a..501831d 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -18,7 +18,7 @@
 
 #include <vector>
 
-#include <android/media/AudioPort.h>
+#include <android/media/AudioPortFw.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
 #include <media/AudioContainers.h>
@@ -79,8 +79,8 @@
 
     bool equals(const sp<DeviceDescriptorBase>& other) const;
 
-    status_t writeToParcelable(media::AudioPort* parcelable) const;
-    status_t readFromParcelable(const media::AudioPort& parcelable);
+    status_t writeToParcelable(media::AudioPortFw* parcelable) const;
+    status_t readFromParcelable(const media::AudioPortFw& parcelable);
 
 protected:
     AudioDeviceTypeAddr mDeviceTypeAddr;
@@ -116,8 +116,8 @@
 
 // Conversion routines, according to AidlConversion.h conventions.
 ConversionResult<sp<DeviceDescriptorBase>>
-aidl2legacy_DeviceDescriptorBase(const media::AudioPort& aidl);
-ConversionResult<media::AudioPort>
+aidl2legacy_DeviceDescriptorBase(const media::AudioPortFw& aidl);
+ConversionResult<media::AudioPortFw>
 legacy2aidl_DeviceDescriptorBase(const sp<DeviceDescriptorBase>& legacy);
 
 } // namespace android
diff --git a/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp b/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp
index 50d8dc8..e315858 100644
--- a/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp
+++ b/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp
@@ -117,7 +117,7 @@
     audioPort->setGains(getAudioGainsForTest());
     audioPort->setAudioProfiles(getAudioProfileVectorForTest());
 
-    media::AudioPort parcelable;
+    media::AudioPortFw parcelable;
     ASSERT_EQ(NO_ERROR, audioPort->writeToParcelable(&parcelable));
     sp<AudioPort> audioPortFromParcel = new AudioPort(
             "", AUDIO_PORT_TYPE_NONE, AUDIO_PORT_ROLE_NONE);
@@ -152,7 +152,7 @@
     ASSERT_EQ(desc->setEncapsulationMetadataTypes(
             AUDIO_ENCAPSULATION_METADATA_TYPE_ALL_POSITION_BITS), NO_ERROR);
 
-    media::AudioPort parcelable;
+    media::AudioPortFw parcelable;
     ASSERT_EQ(NO_ERROR, desc->writeToParcelable(&parcelable));
     sp<DeviceDescriptorBase> descFromParcel = new DeviceDescriptorBase(AUDIO_DEVICE_NONE);
     ASSERT_EQ(NO_ERROR, descFromParcel->readFromParcelable(parcelable));
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index d151817..829a79a 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -245,12 +245,15 @@
         "latest_android_media_audio_common_types_ndk_shared",
     ],
     srcs: [
+        "DeviceHalAidl.cpp",
         "DevicesFactoryHalEntry.cpp",
         "DevicesFactoryHalAidl.cpp",
+        "EffectConversionHelperAidl.cpp",
         "EffectBufferHalAidl.cpp",
         "EffectHalAidl.cpp",
         "EffectsFactoryHalAidl.cpp",
         "EffectsFactoryHalEntry.cpp",
+        "StreamHalAidl.cpp",
     ],
     static_libs: [
         "android.hardware.common-V2-ndk",
@@ -271,4 +274,4 @@
         "-Wthread-safety",
         "-DBACKEND_NDK",
     ],
-}
\ No newline at end of file
+}
diff --git a/media/libaudiohal/impl/ConversionHelperAidl.h b/media/libaudiohal/impl/ConversionHelperAidl.h
new file mode 100644
index 0000000..db6b6cf
--- /dev/null
+++ b/media/libaudiohal/impl/ConversionHelperAidl.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 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 <string>
+#include <string_view>
+#include <vector>
+
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class Args {
+  public:
+    explicit Args(const Vector<String16>& args)
+            : mValues(args.size()), mPtrs(args.size()) {
+        for (size_t i = 0; i < args.size(); ++i) {
+            mValues[i] = std::string(String8(args[i]));
+            mPtrs[i] = mValues[i].c_str();
+        }
+    }
+    const char** args() { return mPtrs.data(); }
+  private:
+    std::vector<std::string> mValues;
+    std::vector<const char*> mPtrs;
+};
+
+class ConversionHelperAidl {
+  protected:
+    ConversionHelperAidl(std::string_view className) : mClassName(className) {}
+
+    const std::string& getClassName() const {
+        return mClassName;
+    }
+
+    const std::string mClassName;
+};
+
+}  // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index d85d960..179a655 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -16,94 +16,164 @@
 
 #define LOG_TAG "DeviceHalAidl"
 
-#include "DeviceHalAidl.h"
+#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
+#include <error/expected_utils.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionUtil.h>
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
 
-status_t DeviceHalAidl::getSupportedDevices(uint32_t* devices) {
-    ALOGE("%s not implemented yet devices %p", __func__, devices);
-    return OK;
+#include "DeviceHalAidl.h"
+#include "StreamHalAidl.h"
+
+using aidl::android::aidl_utils::statusTFromBinderStatus;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::Float;
+using aidl::android::hardware::audio::core::IModule;
+using aidl::android::hardware::audio::core::ITelephony;
+using aidl::android::hardware::audio::core::StreamDescriptor;
+
+namespace android {
+
+status_t DeviceHalAidl::getSupportedDevices(uint32_t*) {
+    // Obsolete.
+    return INVALID_OPERATION;
 }
 
 status_t DeviceHalAidl::initCheck() {
-    ALOGE("%s not implemented yet", __func__);
+    if (mModule == nullptr) return NO_INIT;
+    // HAL modules are already initialized by the time they are published to the SM.
     return OK;
 }
 
 status_t DeviceHalAidl::setVoiceVolume(float volume) {
-    mVoiceVolume = volume;
-    ALOGE("%s not implemented yet %f", __func__, volume);
-    return OK;
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    std::shared_ptr<ITelephony> telephony;
+    if (ndk::ScopedAStatus status = mModule->getTelephony(&telephony);
+            status.isOk() && telephony != nullptr) {
+        ITelephony::TelecomConfig inConfig{ .voiceVolume = Float{volume} }, outConfig;
+        RETURN_STATUS_IF_ERROR(
+                statusTFromBinderStatus(telephony->setTelecomConfig(inConfig, &outConfig)));
+        ALOGW_IF(outConfig.voiceVolume.has_value() && volume != outConfig.voiceVolume.value().value,
+                "%s: the resulting voice volume %f is not the same as requested %f",
+                __func__, outConfig.voiceVolume.value().value, volume);
+    }
+    return INVALID_OPERATION;
 }
 
 status_t DeviceHalAidl::setMasterVolume(float volume) {
-    mMasterVolume = volume;
-    ALOGE("%s not implemented yet %f", __func__, volume);
-    return OK;
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->setMasterVolume(volume));
 }
 
 status_t DeviceHalAidl::getMasterVolume(float *volume) {
-    *volume = mMasterVolume;
-    ALOGE("%s not implemented yet %f", __func__, *volume);
-    return OK;
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->getMasterVolume(volume));
 }
 
 status_t DeviceHalAidl::setMode(audio_mode_t mode) {
-    ALOGE("%s not implemented yet %u", __func__, mode);
-    return OK;
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    AudioMode audioMode = VALUE_OR_FATAL(::aidl::android::legacy2aidl_audio_mode_t_AudioMode(mode));
+    std::shared_ptr<ITelephony> telephony;
+    if (ndk::ScopedAStatus status = mModule->getTelephony(&telephony);
+            status.isOk() && telephony != nullptr) {
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(telephony->switchAudioMode(audioMode)));
+    }
+    return statusTFromBinderStatus(mModule->updateAudioMode(audioMode));
 }
 
 status_t DeviceHalAidl::setMicMute(bool state) {
-    mMicMute = state;
-    ALOGE("%s not implemented yet %d", __func__, state);
-    return OK;
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->setMicMute(state));
 }
+
 status_t DeviceHalAidl::getMicMute(bool *state) {
-    *state = mMicMute;
-    ALOGE("%s not implemented yet %d", __func__, *state);
-    return OK;
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->getMicMute(state));
 }
+
 status_t DeviceHalAidl::setMasterMute(bool state) {
-    mMasterMute = state;
-    ALOGE("%s not implemented yet %d", __func__, state);
-    return OK;
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->setMasterMute(state));
 }
+
 status_t DeviceHalAidl::getMasterMute(bool *state) {
-    *state = mMasterMute;
-    ALOGE("%s not implemented yet %d", __func__, *state);
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    return statusTFromBinderStatus(mModule->getMasterMute(state));
+}
+
+status_t DeviceHalAidl::setParameters(const String8& kvPairs __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::setParameters(const String8& kvPairs) {
-    ALOGE("%s not implemented yet %s", __func__, kvPairs.c_str());
+status_t DeviceHalAidl::getParameters(const String8& keys __unused, String8 *values) {
+    TIME_CHECK();
+    values->clear();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     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());
+status_t DeviceHalAidl::getInputBufferSize(
+        const struct audio_config* config __unused, size_t* size __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::getInputBufferSize(const struct audio_config* config, size_t* size) {
-    ALOGE("%s not implemented yet %p %zu", __func__, config, *size);
+status_t DeviceHalAidl::openOutputStream(
+        audio_io_handle_t handle __unused, audio_devices_t devices __unused,
+        audio_output_flags_t flags __unused, struct audio_config* config,
+        const char* address __unused,
+        sp<StreamOutHalInterface>* outStream) {
+    if (!outStream || !config) {
+        return BAD_VALUE;
+    }
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    config->sample_rate = 48000;
+    config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+    StreamDescriptor descriptor;
+    descriptor.frameSizeBytes = audio_bytes_per_sample(config->format) *
+            audio_channel_count_from_out_mask(config->channel_mask);
+    descriptor.bufferSizeFrames = 600;
+    *outStream = sp<StreamOutHalAidl>::make(descriptor, nullptr);
     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);
+status_t DeviceHalAidl::openInputStream(
+        audio_io_handle_t handle __unused, audio_devices_t devices __unused,
+        struct audio_config* config, audio_input_flags_t flags __unused,
+        const char* address __unused, audio_source_t source __unused,
+        audio_devices_t outputDevice __unused,
+        const char* outputDeviceAddress __unused,
+        sp<StreamInHalInterface>* inStream) {
+    if (!inStream || !config) {
+        return BAD_VALUE;
+    }
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    config->sample_rate = 48000;
+    config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
+    StreamDescriptor descriptor;
+    descriptor.frameSizeBytes = audio_bytes_per_sample(config->format) *
+            audio_channel_count_from_out_mask(config->channel_mask);
+    descriptor.bufferSizeFrames = 600;
+    *inStream = sp<StreamInHalAidl>::make(descriptor, nullptr);
     return OK;
 }
 
@@ -112,76 +182,108 @@
     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);
+status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources __unused,
+                                         const struct audio_port_config* sources __unused,
+                                         unsigned int num_sinks __unused,
+                                         const struct audio_port_config* sinks __unused,
+                                         audio_patch_handle_t* patch __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch) {
-    ALOGE("%s not implemented yet patch %d", __func__, patch);
+status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config) {
-    ALOGE("%s not implemented yet config %p", __func__, config);
+status_t DeviceHalAidl::getAudioPort(struct audio_port* port __unused) {
+    TIME_CHECK();
+    ALOGE("%s not implemented yet", __func__);
+    return INVALID_OPERATION;
+}
+
+status_t DeviceHalAidl::getAudioPort(struct audio_port_v7 *port __unused) {
+    TIME_CHECK();
+    ALOGE("%s not implemented yet", __func__);
+    return INVALID_OPERATION;
+}
+
+status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 status_t DeviceHalAidl::getMicrophones(
-        std::vector<audio_microphone_characteristic_t>* microphones) {
-    ALOGE("%s not implemented yet microphones %p", __func__, microphones);
+        std::vector<audio_microphone_characteristic_t>* microphones __unused) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
-status_t DeviceHalAidl::addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) {
+status_t DeviceHalAidl::addDeviceEffect(audio_port_handle_t device __unused,
+        sp<EffectHalInterface> effect) {
     if (!effect) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet device %d", __func__, device);
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
-status_t DeviceHalAidl::removeDeviceEffect(audio_port_handle_t device,
+status_t DeviceHalAidl::removeDeviceEffect(audio_port_handle_t device __unused,
                             sp<EffectHalInterface> effect) {
     if (!effect) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet device %d", __func__, device);
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 status_t DeviceHalAidl::getMmapPolicyInfos(
         media::audio::common::AudioMMapPolicyType policyType __unused,
         std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos __unused) {
+    TIME_CHECK();
     ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 int32_t DeviceHalAidl::getAAudioMixerBurstCount() {
+    TIME_CHECK();
     ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 int32_t DeviceHalAidl::getAAudioHardwareBurstMinUsec() {
+    TIME_CHECK();
     ALOGE("%s not implemented yet", __func__);
     return OK;
 }
 
 error::Result<audio_hw_sync_t> DeviceHalAidl::getHwAvSync() {
+    TIME_CHECK();
     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;
+status_t DeviceHalAidl::dump(int fd, const Vector<String16>& args) {
+    TIME_CHECK();
+    if (!mModule) return NO_INIT;
+    return mModule->dump(fd, Args(args).args(), args.size());
 };
 
-int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) override {
+int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) {
+    TIME_CHECK();
     ALOGE("%s not implemented yet", __func__);
     return INVALID_OPERATION;
 }
+
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 5e8a8dd..99e28d8 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -16,14 +16,15 @@
 
 #pragma once
 
+#include <aidl/android/hardware/audio/core/BpModule.h>
 #include <media/audiohal/DeviceHalInterface.h>
 #include <media/audiohal/EffectHalInterface.h>
 
-#include <aidl/android/hardware/audio/core/BpModule.h>
+#include "ConversionHelperAidl.h"
 
 namespace android {
 
-class DeviceHalAidl : public DeviceHalInterface {
+class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl {
   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;
@@ -86,6 +87,12 @@
     // Releases an audio patch.
     status_t releaseAudioPatch(audio_patch_handle_t patch) override;
 
+    // Fills the list of supported attributes for a given audio port.
+    status_t getAudioPort(struct audio_port* port) override;
+
+    // Fills the list of supported attributes for a given audio port.
+    status_t getAudioPort(struct audio_port_v7 *port) override;
+
     // Set audio port configuration.
     status_t setAudioPortConfig(const struct audio_port_config* config) override;
 
@@ -111,20 +118,16 @@
     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;
+    friend class sp<DeviceHalAidl>;
+
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
 
     // Can not be constructed directly by clients.
     explicit DeviceHalAidl(
-            const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& core)
-        : mCore(core) {}
+            const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module)
+            : ConversionHelperAidl("DeviceHalAidl"), mModule(module) {}
 
-    // The destructor automatically closes the device.
-    ~DeviceHalAidl();
+    ~DeviceHalAidl() override = default;
 };
 
 } // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index be063ab..12acebd 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -46,9 +46,6 @@
 using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 
-#define TIME_CHECK() auto timeCheck = \
-        mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
 DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
         : CoreConversionHelperHidl("DeviceHalHidl"), mDevice(device) {
 }
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index b9ca164..78d03e7 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -19,6 +19,7 @@
 
 #include <aidl/android/hardware/audio/core/IModule.h>
 #include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
 #include <memory>
 #include <utils/Log.h>
 
@@ -35,27 +36,28 @@
     ALOG_ASSERT(iconfig != nullptr, "Provided default IConfig service is NULL");
 }
 
-void DevicesFactoryHalAidl::onFirstRef() {
-    ALOGE("%s not implemented yet", __func__);
-}
-
 // Opens a device with the specified name. To close the device, it is
 // necessary to release references to the returned object.
 status_t DevicesFactoryHalAidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
     if (name == nullptr || device == nullptr) {
         return BAD_VALUE;
     }
-    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(
+    std::shared_ptr<IModule> service;
+    // FIXME: Normally we will list available HAL modules and connect to them,
+    // however currently we still get the list of module names from the config.
+    // Since the example service does not have all modules, the SM will wait
+    // for the missing ones forever.
+    if (strcmp(name, "primary") == 0 || strcmp(name, "r_submix") == 0) {
+        if (strcmp(name, "primary") == 0) name = "default";
+        auto serviceName = std::string(IModule::descriptor) + "/" + name;
+        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);
+        ALOGE_IF(service == nullptr, "%s fromBinder %s failed", __func__, serviceName.c_str());
     }
+    // If the service is a nullptr, the device will not be really functional,
+    // but will not crash either.
+    *device = sp<DeviceHalAidl>::make(service);
     return OK;
 }
 
@@ -63,26 +65,45 @@
     if (pids == nullptr) {
         return BAD_VALUE;
     }
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+    // The functionality for retrieving debug infos of services is not exposed via the NDK.
+    sp<IServiceManager> sm = defaultServiceManager();
+    if (sm == nullptr) {
+        return NO_INIT;
+    }
+    std::set<pid_t> pidsSet;
+    const auto moduleServiceName = std::string(IModule::descriptor) + "/";
+    auto debugInfos = sm->getServiceDebugInfo();
+    for (const auto& info : debugInfos) {
+        if (info.pid > 0 &&
+                info.name.size() > moduleServiceName.size() && // '>' as there must be instance name
+                info.name.substr(0, moduleServiceName.size()) == moduleServiceName) {
+            pidsSet.insert(info.pid);
+        }
+    }
+    *pids = {pidsSet.begin(), pidsSet.end()};
+    return NO_ERROR;
 }
 
 status_t DevicesFactoryHalAidl::setCallbackOnce(sp<DevicesFactoryHalCallback> callback) {
-    if (callback == nullptr) {
-        return BAD_VALUE;
+    // Dynamic registration of module instances is not supported. The functionality
+    // in the audio server which is related to this callback can be removed together
+    // with HIDL support.
+    ALOG_ASSERT(callback != nullptr);
+    if (callback != nullptr) {
+        callback->onNewDevicesAvailable();
     }
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+    return NO_ERROR;
 }
 
 AudioHalVersionInfo DevicesFactoryHalAidl::getHalVersion() const {
     int32_t versionNumber = 0;
-    if (mIConfig) {
-        if (!mIConfig->getInterfaceVersion(&versionNumber).isOk()) {
-            ALOGE("%s getInterfaceVersion failed", __func__);
-        } else {
-            ALOGI("%s getInterfaceVersion %d", __func__, versionNumber);
+    if (mIConfig != 0) {
+        if (ndk::ScopedAStatus status = mIConfig->getInterfaceVersion(&versionNumber);
+                !status.isOk()) {
+            ALOGE("%s getInterfaceVersion failed: %s", __func__, status.getDescription().c_str());
         }
+    } else {
+        ALOGW("%s no IConfig instance", __func__);
     }
     // AIDL does not have minor version, fill 0 for all versions
     return AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, versionNumber);
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.h b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
index 71138a0..cb627bc 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
@@ -27,7 +27,6 @@
   public:
     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
     // necessary to release references to the returned object.
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
new file mode 100644
index 0000000..493d1ee
--- /dev/null
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2023 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 <cstdint>
+#include <cstring>
+#define LOG_TAG "EffectConversionHelperAidl"
+//#define LOG_NDEBUG 0
+
+#include <error/expected_utils.h>
+#include <media/audiohal/AudioEffectUuid.h>
+#include <system/audio_effects/audio_effects_utils.h>
+#include <utils/Log.h>
+
+#include "EffectConversionHelperAidl.h"
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using ::aidl::android::hardware::audio::effect::CommandId;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
+using ::aidl::android::media::audio::common::AudioUuid;
+
+using ::android::status_t;
+
+const std::map<uint32_t /* effect_command_e */, EffectConversionHelperAidl::CommandHandler>
+        EffectConversionHelperAidl::mCommandHandlerMap = {
+                {EFFECT_CMD_INIT, &EffectConversionHelperAidl::handleInit},
+                {EFFECT_CMD_SET_PARAM, &EffectConversionHelperAidl::handleSetParameter},
+                {EFFECT_CMD_GET_PARAM, &EffectConversionHelperAidl::handleGetParameter},
+                {EFFECT_CMD_SET_CONFIG, &EffectConversionHelperAidl::handleSetConfig},
+                {EFFECT_CMD_GET_CONFIG, &EffectConversionHelperAidl::handleGetConfig},
+                {EFFECT_CMD_RESET, &EffectConversionHelperAidl::handleReset},
+                {EFFECT_CMD_ENABLE, &EffectConversionHelperAidl::handleEnable},
+                {EFFECT_CMD_DISABLE, &EffectConversionHelperAidl::handleDisable},
+                {EFFECT_CMD_SET_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
+                {EFFECT_CMD_SET_INPUT_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
+                {EFFECT_CMD_SET_VOLUME, &EffectConversionHelperAidl::handleSetVolume},
+                {EFFECT_CMD_OFFLOAD, &EffectConversionHelperAidl::handleSetOffload},
+                {EFFECT_CMD_FIRST_PROPRIETARY, &EffectConversionHelperAidl::handleFirstPriority}};
+
+const std::map<AudioUuid /* TypeUUID */, std::pair<EffectConversionHelperAidl::SetParameter,
+                                                   EffectConversionHelperAidl::GetParameter>>
+        EffectConversionHelperAidl::mParameterHandlerMap = {
+                {kAcousticEchoCancelerTypeUUID,
+                 {&EffectConversionHelperAidl::setAecParameter,
+                  &EffectConversionHelperAidl::getAecParameter}}};
+
+
+status_t EffectConversionHelperAidl::handleCommand(uint32_t cmdCode, uint32_t cmdSize,
+                                                   void* pCmdData, uint32_t* replySize,
+                                                   void* pReplyData) {
+    const auto& handler = mCommandHandlerMap.find(cmdCode);
+    if (handler == mCommandHandlerMap.end() || !handler->second) {
+        ALOGE("%s handler for command %u doesn't exist", __func__, cmdCode);
+        return BAD_VALUE;
+    }
+    return (this->*handler->second)(cmdSize, pCmdData, replySize, pReplyData);
+}
+
+status_t EffectConversionHelperAidl::handleInit(uint32_t cmdSize __unused,
+                                                const void* pCmdData __unused, uint32_t* replySize,
+                                                void* pReplyData) {
+    if (!replySize || *replySize < sizeof(int) || !pReplyData) {
+        return BAD_VALUE;
+    }
+
+    return *(status_t*)pReplyData = OK;
+}
+
+status_t EffectConversionHelperAidl::handleSetParameter(uint32_t cmdSize, const void* pCmdData,
+                                                        uint32_t* replySize, void* pReplyData) {
+    if (cmdSize < kEffectParamSize || !pCmdData || !replySize || *replySize < sizeof(int) ||
+        !pReplyData) {
+        return BAD_VALUE;
+    }
+
+    const effect_param_t* param = (effect_param_t*)pCmdData;
+    if (!validateCommandSize(*param, cmdSize)) {
+        ALOGE("%s illegal param %s size %u", __func__, utils::toString(*param).c_str(), cmdSize);
+        return BAD_VALUE;
+    }
+
+    const auto& handler = mParameterHandlerMap.find(mTypeUuid);
+    if (handler == mParameterHandlerMap.end() || !handler->second.first) {
+        ALOGE("%s handler for uuid %s not found", __func__, mTypeUuid.toString().c_str());
+        return BAD_VALUE;
+    }
+    const SetParameter& functor = handler->second.first;
+    return *(status_t*)pReplyData = (this->*functor)(*(const effect_param_t*)param);
+}
+
+status_t EffectConversionHelperAidl::handleGetParameter(uint32_t cmdSize, const void* pCmdData,
+                                                        uint32_t* replySize, void* pReplyData) {
+    if (cmdSize < kEffectParamSize || !pCmdData || !replySize || !pReplyData) {
+        return BAD_VALUE;
+    }
+
+    const effect_param_t* param = (effect_param_t*)pCmdData;
+    if (!validateCommandSize(*param, *replySize)) {
+        ALOGE("%s illegal param %s, replysize %u", __func__, utils::toString(*param).c_str(),
+              *replySize);
+        return BAD_VALUE;
+    }
+
+    const auto& handler = mParameterHandlerMap.find(mTypeUuid);
+    if (handler == mParameterHandlerMap.end() || !handler->second.second) {
+        ALOGE("%s handler for uuid %s not found", __func__, mTypeUuid.toString().c_str());
+        return BAD_VALUE;
+    }
+    const GetParameter& functor = handler->second.second;
+    memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + param->psize);
+    effect_param_t* reply = (effect_param_t *)pReplyData;
+    (this->*functor)(*reply);
+    *replySize = kEffectParamSize + padding(reply->psize) + reply->vsize;
+    return reply->status;
+}
+
+status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const void* pCmdData,
+                                                     uint32_t* replySize, void* pReplyData) {
+    if (!replySize || *replySize != sizeof(int) || !pReplyData || cmdSize != kEffectConfigSize) {
+        return BAD_VALUE;
+    }
+
+    const auto& legacyConfig = static_cast<const effect_config_t*>(pCmdData);
+    // already open, apply latest settings
+    Parameter::Common common;
+    common.input.base =
+            VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
+                    legacyConfig->inputCfg, true /* isInput */));
+    common.output.base =
+            VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
+                    legacyConfig->outputCfg, false /* isInput */));
+    common.session = mSessionId;
+    common.ioHandle = mIoId;
+    // TODO: add access mode support
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mEffect->setParameter(Parameter::make<Parameter::common>(common))));
+    return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
+                                                     const void* pCmdData __unused,
+                                                     uint32_t* replySize, void* pReplyData) {
+    if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+        ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+        return BAD_VALUE;
+    }
+
+    Parameter param;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(
+            Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common), &param)));
+
+    const auto& common = param.get<Parameter::common>();
+    effect_config_t* pConfig = (effect_config_t*)pReplyData;
+    pConfig->inputCfg = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(common.input.base, true));
+    pConfig->outputCfg =
+            VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(
+                    common.output.base, false));
+    return OK;
+}
+
+status_t EffectConversionHelperAidl::handleReset(uint32_t cmdSize __unused,
+                                                 const void* pCmdData __unused, uint32_t* replySize,
+                                                 void* pReplyData) {
+    if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+        ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+        return BAD_VALUE;
+    }
+
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::RESET)));
+    return OK;
+}
+
+status_t EffectConversionHelperAidl::handleEnable(uint32_t cmdSize __unused,
+                                                 const void* pCmdData __unused, uint32_t* replySize,
+                                                 void* pReplyData) {
+    if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+        ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+        return BAD_VALUE;
+    }
+
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::START)));
+    return OK;
+}
+
+status_t EffectConversionHelperAidl::handleDisable(uint32_t cmdSize __unused,
+                                                   const void* pCmdData __unused,
+                                                   uint32_t* replySize, void* pReplyData) {
+    if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+        ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+        return BAD_VALUE;
+    }
+
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::STOP)));
+    return OK;
+}
+
+status_t EffectConversionHelperAidl::handleSetDevice(uint32_t cmdSize, const void* pCmdData,
+                                                     uint32_t* replySize, void* pReplyData) {
+    if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize || *replySize != kEffectConfigSize ||
+        !pReplyData) {
+        ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+              pReplyData);
+        return BAD_VALUE;
+    }
+    // TODO: convert from audio_devices_t to std::vector<AudioDeviceDescription>
+    // const auto& legacyDevice = *(uint32_t*)(pCmdData);
+    std::vector<AudioDeviceDescription> aidlDevices;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mEffect->setParameter(Parameter::make<Parameter::deviceDescription>(aidlDevices))));
+    return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleSetVolume(uint32_t cmdSize, const void* pCmdData,
+                                                     uint32_t* replySize, void* pReplyData) {
+    if (cmdSize != 2 * sizeof(uint32_t) || !pCmdData || !replySize ||
+        *replySize != kEffectConfigSize || !pReplyData) {
+        ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+              pReplyData);
+        return BAD_VALUE;
+    }
+    Parameter::VolumeStereo volume = {.left = (float)(*(uint32_t*)pCmdData) / (1 << 24),
+                                      .right = (float)(*(uint32_t*)pCmdData + 1) / (1 << 24)};
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mEffect->setParameter(Parameter::make<Parameter::volumeStereo>(volume))));
+    return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleSetOffload(uint32_t cmdSize, const void* pCmdData,
+                                                      uint32_t* replySize, void* pReplyData) {
+    if (cmdSize < sizeof(effect_offload_param_t) || !pCmdData || !replySize ||
+        *replySize != kEffectConfigSize || !pReplyData) {
+        ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+              pReplyData);
+        return BAD_VALUE;
+    }
+    // TODO: handle this after effectproxy implemented in libaudiohal
+    return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleFirstPriority(uint32_t cmdSize __unused,
+                                                         const void* pCmdData __unused,
+                                                         uint32_t* replySize, void* pReplyData) {
+    if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+        ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+        return BAD_VALUE;
+    }
+
+    // TODO
+    return OK;
+}
+
+status_t EffectConversionHelperAidl::setAecParameter(const effect_param_t& param) {
+    const auto psize = sizeof(uint32_t);
+    const auto vsize = sizeof(uint32_t);
+    if (!validatePVsize(param, psize, vsize)) {
+        return BAD_VALUE;
+    }
+
+    const auto& type = *(uint32_t*)param.data;
+    const auto& value = *(uint32_t*)(param.data + psize);
+    Parameter aidlParam;
+    switch (type) {
+        case AEC_PARAM_ECHO_DELAY:
+            FALLTHROUGH_INTENDED;
+        case AEC_PARAM_PROPERTIES: {
+            aidlParam = VALUE_OR_RETURN_STATUS(
+                    aidl::android::legacy2aidl_uint32_echoDelay_Parameter(value));
+            break;
+        }
+        case AEC_PARAM_MOBILE_MODE: {
+            aidlParam = VALUE_OR_RETURN_STATUS(
+                    aidl::android::legacy2aidl_uint32_mobileMode_Parameter(value));
+            break;
+        }
+        default: {
+            ALOGW("%s unknown param %08x value %08x", __func__, type, value);
+            return BAD_VALUE;
+        }
+    }
+
+    return mEffect->setParameter(aidlParam).getStatus();
+}
+
+status_t EffectConversionHelperAidl::getAecParameter(effect_param_t& param) {
+    const auto psize = sizeof(uint32_t);
+    const auto vsize = sizeof(uint32_t);
+    if (!validatePVsize(param, psize, vsize)) {
+        return param.status = BAD_VALUE;
+    }
+
+    uint32_t value = 0;
+    status_t status = BAD_VALUE;
+    const auto& type = *(uint32_t*)param.data;
+    switch (type) {
+        case AEC_PARAM_ECHO_DELAY:
+            FALLTHROUGH_INTENDED;
+        case AEC_PARAM_PROPERTIES: {
+            Parameter aidlParam;
+            Parameter::Id id = Parameter::Id::make<Parameter::Id::acousticEchoCancelerTag>(
+                    AcousticEchoCanceler::Id::make<AcousticEchoCanceler::Id::commonTag>(
+                            AcousticEchoCanceler::echoDelayUs));
+            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+            value = VALUE_OR_RETURN_STATUS(
+                    aidl::android::aidl2legacy_Parameter_uint32_echoDelay(aidlParam));
+            break;
+        }
+        case AEC_PARAM_MOBILE_MODE: {
+            Parameter aidlParam;
+            Parameter::Id id = Parameter::Id::make<Parameter::Id::acousticEchoCancelerTag>(
+                    AcousticEchoCanceler::Id::make<AcousticEchoCanceler::Id::commonTag>(
+                            AcousticEchoCanceler::mobileMode));
+            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+            value = VALUE_OR_RETURN_STATUS(
+                    aidl::android::aidl2legacy_Parameter_uint32_mobileMode(aidlParam));
+            break;
+        }
+        default:
+            ALOGW("%s unknown param %08x", __func__, type);
+            break;
+    }
+
+    *(uint32_t*)(param.data + psize) = value;
+    return param.status = status;
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
new file mode 100644
index 0000000..5d7c1d6
--- /dev/null
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 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 <cstddef>
+#include <map>
+#include <memory>
+#include <utils/Errors.h>
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+
+#include <media/AidlConversionNdk.h>
+#include <system/audio_effect.h>
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_downmix.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
+#include <system/audio_effects/effect_hapticgenerator.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_visualizer.h>
+
+namespace android {
+namespace effect {
+
+static const size_t kEffectParamSize = sizeof(effect_param_t);
+static const size_t kEffectConfigSize = sizeof(effect_config_t);
+
+class EffectConversionHelperAidl {
+  protected:
+    EffectConversionHelperAidl(
+            std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
+            int32_t sessionId, int32_t ioId, ::aidl::android::media::audio::common::AudioUuid uuid)
+        : mSessionId(sessionId),
+          mIoId(ioId),
+          mTypeUuid(std::move(uuid)),
+          mEffect(std::move(effect)) {}
+
+    status_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
+                           void* pReplyData);
+
+  private:
+    const int32_t mSessionId;
+    const int32_t mIoId;
+    ::aidl::android::media::audio::common::AudioUuid mTypeUuid;
+    const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+
+    // command handler map
+    typedef status_t (EffectConversionHelperAidl::*CommandHandler)(uint32_t /* cmdSize */,
+                                                                   const void* /* pCmdData */,
+                                                                   uint32_t* /* replySize */,
+                                                                   void* /* pReplyData */);
+    static const std::map<uint32_t /* effect_command_e */, CommandHandler> mCommandHandlerMap;
+
+    // parameter set/get handler map
+    typedef status_t (EffectConversionHelperAidl::*SetParameter)(const effect_param_t& param);
+    typedef status_t (EffectConversionHelperAidl::*GetParameter)(effect_param_t& param);
+    static const std::map<::aidl::android::media::audio::common::AudioUuid /* TypeUUID */,
+                          std::pair<SetParameter, GetParameter>>
+            mParameterHandlerMap;
+
+    // align to 32 bit boundary
+    static constexpr size_t padding(size_t size) {
+        return ((size - 1) / sizeof(int) + 1) * sizeof(int);
+    }
+    static constexpr bool validatePVsize(const effect_param_t& param, size_t p, size_t v) {
+        return padding(param.psize) == p && param.vsize == v;
+    }
+    static constexpr bool validateCommandSize(const effect_param_t& param, size_t size) {
+        return padding(param.psize) + param.vsize + kEffectParamSize <= size;
+    }
+
+    status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                        void* pReplyData);
+    status_t handleSetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                                void* pReplyData);
+    status_t handleGetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                                void* pReplyData);
+    status_t handleSetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                             void* pReplyData);
+    status_t handleGetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                             void* pReplyData);
+    status_t handleEnable(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                          void* pReplyData);
+    status_t handleDisable(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                           void* pReplyData);
+    status_t handleReset(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                         void* pReplyData);
+    status_t handleSetDevice(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                             void* pReplyData);
+    status_t handleSetVolume(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                             void* pReplyData);
+    status_t handleSetOffload(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                              void* pReplyData);
+    status_t handleFirstPriority(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+                                 void* pReplyData);
+
+    // AEC parameter handler
+    status_t setAecParameter(const effect_param_t& param);
+    status_t getAecParameter(effect_param_t& param);
+};
+
+}  // namespace effect
+}  // namespace android
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index 31c5ca5..3346459 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -17,31 +17,44 @@
 #define LOG_TAG "EffectHalAidl"
 //#define LOG_NDEBUG 0
 
+#include <error/expected_utils.h>
 #include <media/AidlConversionCppNdk.h>
 #include <media/AidlConversionNdk.h>
-#include <media/audiohal/AudioHalUtils.h>
+#include <media/AidlConversionUtil.h>
 #include <media/EffectsFactoryApi.h>
 #include <mediautils/TimeCheck.h>
 #include <utils/Log.h>
 
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_downmix.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
+#include <system/audio_effects/effect_hapticgenerator.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <system/audio_effects/effect_visualizer.h>
+
 #include "EffectHalAidl.h"
 
 #include <system/audio.h>
-
 #include <aidl/android/hardware/audio/effect/IEffect.h>
 
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
 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) {}
+                             int32_t sessionId, int32_t ioId, const Descriptor& desc)
+    : EffectConversionHelperAidl(effect, sessionId, ioId, desc.common.id.type),
+      mEffectId(effectId),
+      mSessionId(sessionId),
+      mIoId(ioId),
+      mEffect(effect),
+      mDesc(desc) {}
 
 EffectHalAidl::~EffectHalAidl() {}
 
@@ -63,7 +76,7 @@
 
 status_t EffectHalAidl::process() {
     ALOGW("%s not implemented yet", __func__);
-    // write to input FMQ here?
+    // write to input FMQ here, and wait for statusMQ STATUS_OK
     return OK;
 }
 
@@ -73,137 +86,9 @@
     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;
+    return handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
 }
 
 status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
@@ -212,7 +97,7 @@
         return BAD_VALUE;
     }
     Descriptor aidlDesc;
-    RETURN_IF_BINDER_FAIL(mEffect->getDescriptor(&aidlDesc));
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getDescriptor(&aidlDesc)));
 
     *pDescriptor = VALUE_OR_RETURN_STATUS(
             ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(aidlDesc));
@@ -220,9 +105,8 @@
 }
 
 status_t EffectHalAidl::close() {
-    auto ret = mEffect->close();
-    ALOGI("%s %s", __func__, ret.getMessage());
-    return ret.getStatus();
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->close()));
+    return OK;
 }
 
 status_t EffectHalAidl::dump(int fd) {
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
index 76bb240..1ba262c 100644
--- a/media/libaudiohal/impl/EffectHalAidl.h
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -20,10 +20,12 @@
 #include <media/audiohal/EffectHalInterface.h>
 #include <system/audio_effect.h>
 
+#include "EffectConversionHelperAidl.h"
+
 namespace android {
 namespace effect {
 
-class EffectHalAidl : public EffectHalInterface {
+class EffectHalAidl : public EffectHalInterface, public EffectConversionHelperAidl {
   public:
     // Set the input buffer.
     status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer) override;
@@ -55,28 +57,27 @@
 
     uint64_t effectId() const override { return mEffectId; }
 
+    const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> getIEffect() const {
+        return mEffect;
+    }
+
   private:
-    friend class EffectsFactoryHalAidl;
+    friend class sp<EffectHalAidl>;
 
     const uint64_t mEffectId;
     const int32_t mSessionId;
     const int32_t mIoId;
+    const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+    const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
+
     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);
+                  uint64_t effectId, int32_t sessionId, int32_t ioId,
+                  const ::aidl::android::hardware::audio::effect::Descriptor& desc);
+    bool setEffectReverse(bool reverse);
 
     // The destructor automatically releases the effect.
     virtual ~EffectHalAidl();
diff --git a/media/libaudiohal/impl/EffectHalHidl.cpp b/media/libaudiohal/impl/EffectHalHidl.cpp
index 3956a6c..ed952a3 100644
--- a/media/libaudiohal/impl/EffectHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectHalHidl.cpp
@@ -46,9 +46,6 @@
 using namespace ::android::hardware::audio::common::CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
-#define TIME_CHECK() auto timeCheck = \
-        mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
 EffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId)
         : EffectConversionHelperHidl("EffectHalHidl"),
           mEffect(effect), mEffectId(effectId), mBuffersChanged(true), mEfGroup(nullptr) {
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 0039c86..96ea861 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -21,16 +21,19 @@
 //#define LOG_NDEBUG 0
 
 #include <aidl/android/hardware/audio/effect/IFactory.h>
+#include <error/expected_utils.h>
 #include <android/binder_manager.h>
 #include <media/AidlConversionCppNdk.h>
 #include <media/AidlConversionNdk.h>
-#include <media/audiohal/AudioHalUtils.h>
+#include <system/audio.h>
 #include <utils/Log.h>
 
 #include "EffectBufferHalAidl.h"
 #include "EffectHalAidl.h"
 #include "EffectsFactoryHalAidl.h"
 
+using ::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid;
+using aidl::android::aidl_utils::statusTFromBinderStatus;
 using aidl::android::hardware::audio::effect::IFactory;
 using aidl::android::media::audio::common::AudioUuid;
 using android::detail::AudioHalVersionInfo;
@@ -55,7 +58,7 @@
 
     {
         std::lock_guard lg(mLock);
-        RETURN_IF_NOT_OK(queryEffectList_l());
+        RETURN_STATUS_IF_ERROR(queryEffectList_l());
         *pNumEffects = mDescList->size();
     }
     ALOGI("%s %d", __func__, *pNumEffects);
@@ -68,7 +71,7 @@
     }
 
     std::lock_guard lg(mLock);
-    RETURN_IF_NOT_OK(queryEffectList_l());
+    RETURN_STATUS_IF_ERROR(queryEffectList_l());
 
     auto listSize = mDescList->size();
     if (index >= listSize) {
@@ -87,8 +90,7 @@
         return BAD_VALUE;
     }
 
-    AudioUuid uuid =
-            VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*halUuid));
+    AudioUuid uuid = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(*halUuid));
     std::lock_guard lg(mLock);
     return getHalDescriptorWithImplUuid_l(uuid, pDescriptor);
 }
@@ -99,8 +101,7 @@
         return BAD_VALUE;
     }
 
-    AudioUuid type =
-            VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*halType));
+    AudioUuid type = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(*halType));
     std::lock_guard lg(mLock);
     return getHalDescriptorWithTypeUuid_l(type, descriptors);
 }
@@ -111,24 +112,29 @@
     if (uuid == nullptr || effect == nullptr) {
         return BAD_VALUE;
     }
-    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());
+    if (sessionId == AUDIO_SESSION_DEVICE && ioId == AUDIO_IO_HANDLE_NONE) {
         return INVALID_OPERATION;
     }
+
+    ALOGI("%s session %d ioId %d", __func__, sessionId, ioId);
+
+    AudioUuid aidlUuid = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(*uuid));
+    std::shared_ptr<IEffect> aidlEffect;
+    Descriptor desc;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mFactory->createEffect(aidlUuid, &aidlEffect)));
+    if (aidlEffect == nullptr) {
+        ALOGE("%s IFactory::createFactory failed UUID %s", __func__, aidlUuid.toString().c_str());
+        return NAME_NOT_FOUND;
+    }
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(aidlEffect->getDescriptor(&desc)));
+
     uint64_t effectId;
     {
         std::lock_guard lg(mLock);
         effectId = ++mEffectIdCounter;
     }
 
-    *effect = new EffectHalAidl(aidlEffect, effectId, sessionId, ioId);
+    *effect = sp<EffectHalAidl>::make(aidlEffect, effectId, sessionId, ioId, desc);
     return OK;
 }
 
@@ -174,7 +180,7 @@
         return BAD_VALUE;
     }
     if (!mDescList) {
-        RETURN_IF_NOT_OK(queryEffectList_l());
+        RETURN_STATUS_IF_ERROR(queryEffectList_l());
     }
 
     auto matchIt = std::find_if(mDescList->begin(), mDescList->end(),
@@ -195,7 +201,7 @@
         return BAD_VALUE;
     }
     if (!mDescList) {
-        RETURN_IF_NOT_OK(queryEffectList_l());
+        RETURN_STATUS_IF_ERROR(queryEffectList_l());
     }
     std::vector<Descriptor> result;
     std::copy_if(mDescList->begin(), mDescList->end(), std::back_inserter(result),
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
new file mode 100644
index 0000000..1c6a014
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -0,0 +1,517 @@
+/*
+ * Copyright (C) 2023 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 "StreamHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <aidl/android/hardware/audio/core/BnStreamCallback.h>
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
+
+#include "DeviceHalAidl.h"
+#include "StreamHalAidl.h"
+
+using ::aidl::android::hardware::audio::core::IStreamCommon;
+using ::aidl::android::hardware::audio::core::IStreamIn;
+using ::aidl::android::hardware::audio::core::IStreamOut;
+using ::aidl::android::hardware::audio::core::StreamDescriptor;
+
+namespace android {
+
+// static
+template<class T>
+std::shared_ptr<IStreamCommon> StreamHalAidl::getStreamCommon(const std::shared_ptr<T>& stream) {
+    std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> streamCommon;
+    if (stream != nullptr) {
+        if (ndk::ScopedAStatus status = stream->getStreamCommon(&streamCommon);
+                !status.isOk()) {
+            ALOGE("%s: failed to retrieve IStreamCommon instance: %s", __func__,
+                    status.getDescription().c_str());
+        }
+    }
+    return streamCommon;
+}
+
+StreamHalAidl::StreamHalAidl(
+        std::string_view className, bool isInput, const StreamDescriptor& descriptor,
+        const std::shared_ptr<IStreamCommon>& stream)
+        : ConversionHelperAidl(className),
+          mIsInput(isInput),
+          mFrameSizeBytes(descriptor.frameSizeBytes),
+          mBufferSizeFrames(descriptor.bufferSizeFrames),
+          mCommandMQ(new CommandMQ(descriptor.command)),
+          mReplyMQ(new ReplyMQ(descriptor.reply)),
+          mDataMQ(maybeCreateDataMQ(descriptor)),
+          mStream(stream) {
+    // Instrument audio signal power logging.
+    // Note: This assumes channel mask, format, and sample rate do not change after creation.
+    if (audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
+            /* mStreamPowerLog.isUserDebugOrEngBuild() && */
+            StreamHalAidl::getAudioProperties(&config) == NO_ERROR) {
+        mStreamPowerLog.init(config.sample_rate, config.channel_mask, config.format);
+    }
+}
+
+StreamHalAidl::~StreamHalAidl() {
+    if (mStream != nullptr) {
+        ndk::ScopedAStatus status = mStream->close();
+        ALOGE_IF(!status.isOk(), "%s: status %s", __func__, status.getDescription().c_str());
+    }
+}
+
+status_t StreamHalAidl::getBufferSize(size_t *size) {
+    if (size == nullptr) {
+        return BAD_VALUE;
+    }
+    if (mFrameSizeBytes == 0 || mBufferSizeFrames == 0) {
+        return NO_INIT;
+    }
+    *size = mFrameSizeBytes * mBufferSizeFrames;
+    return OK;
+}
+
+status_t StreamHalAidl::getAudioProperties(audio_config_base_t *configBase) {
+    if (configBase == nullptr) {
+        return BAD_VALUE;
+    }
+    TIME_CHECK();
+    *configBase = AUDIO_CONFIG_BASE_INITIALIZER;
+    configBase->sample_rate = 48000;
+    configBase->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    configBase->channel_mask = mIsInput ? AUDIO_CHANNEL_IN_STEREO : AUDIO_CHANNEL_OUT_STEREO;
+    // if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::setParameters(const String8& kvPairs __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::getParameters(const String8& keys __unused, String8 *values) {
+    TIME_CHECK();
+    values->clear();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::getFrameSize(size_t *size) {
+    if (size == nullptr) {
+        return BAD_VALUE;
+    }
+    if (mFrameSizeBytes == 0) {
+        return NO_INIT;
+    }
+    *size = mFrameSizeBytes;
+    return OK;
+}
+
+status_t StreamHalAidl::addEffect(sp<EffectHalInterface> effect __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::removeEffect(sp<EffectHalInterface> effect __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::standby() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::dump(int fd, const Vector<String16>& args) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    return mStream->dump(fd, Args(args).args(), args.size());
+}
+
+status_t StreamHalAidl::start() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::stop() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::createMmapBuffer(int32_t minSizeFrames __unused,
+                                  struct audio_mmap_buffer_info *info __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::getMmapPosition(struct audio_mmap_position *position __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::setHalThreadPriority(int priority __unused) {
+    mHalThreadPriority = priority;
+    return OK;
+}
+
+status_t StreamHalAidl::getHalPid(pid_t *pid __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+bool StreamHalAidl::requestHalThreadPriority(pid_t threadPid __unused, pid_t threadId __unused) {
+    if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
+        return true;
+    }
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamHalAidl::legacyCreateAudioPatch(const struct audio_port_config& port __unused,
+                                               std::optional<audio_source_t> source __unused,
+                                               audio_devices_t type __unused) {
+    // Obsolete since 'DeviceHalAidl.supportsAudioPatches' always returns 'true'.
+    return INVALID_OPERATION;
+}
+
+status_t StreamHalAidl::legacyReleaseAudioPatch() {
+    // Obsolete since 'DeviceHalAidl.supportsAudioPatches' always returns 'true'.
+    return INVALID_OPERATION;
+}
+
+namespace {
+
+/* Notes on callback ownership.
+
+This is how Binder ownership model looks like. The server implementation
+is owned by Binder framework (via sp<>). Proxies are owned by clients.
+When the last proxy disappears, Binder framework releases the server impl.
+
+Thus, it is not needed to keep any references to StreamCallback (this is
+the server impl) -- it will live as long as HAL server holds a strong ref to
+IStreamCallback proxy.
+
+The callback only keeps a weak reference to the stream. The stream is owned
+by AudioFlinger.
+
+*/
+
+class StreamCallback : public ::aidl::android::hardware::audio::core::BnStreamCallback {
+    ndk::ScopedAStatus onTransferReady() override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus onError() override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus onDrainReady() override {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
+}  // namespace
+
+StreamOutHalAidl::StreamOutHalAidl(
+        const StreamDescriptor& descriptor, const std::shared_ptr<IStreamOut>& stream)
+        : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, descriptor, getStreamCommon(stream)),
+          mStream(stream) {}
+
+status_t StreamOutHalAidl::getLatency(uint32_t *latency) {
+    TIME_CHECK();
+    *latency = 0;
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::setVolume(float left __unused, float right __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::selectPresentation(int presentationId __unused, int programId __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::write(
+        const void *buffer __unused, size_t bytes __unused, size_t *written __unused) {
+    // TIME_CHECK();  // TODO(b/238654698) reenable only when optimized.
+    if (!mStream) return NO_INIT;
+    *written = 0;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::getRenderPosition(uint32_t *dspFrames __unused) {
+    // TIME_CHECK();  // TODO(b/238654698) reenable only when optimized.
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::getNextWriteTimestamp(int64_t *timestamp __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::setCallback(wp<StreamOutHalInterfaceCallback> callback __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::supportsPauseAndResume(
+        bool *supportsPause __unused, bool *supportsResume __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::pause() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::resume() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::supportsDrain(bool *supportsDrain __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::drain(bool earlyNotify __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::flush() {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::getPresentationPosition(
+        uint64_t *frames __unused, struct timespec *timestamp __unused) {
+    // TIME_CHECK();  // TODO(b/238654698) reenable only when optimized.
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::updateSourceMetadata(
+        const StreamOutHalInterface::SourceMetadata& sourceMetadata __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamOutHalAidl::getDualMonoMode(audio_dual_mono_mode_t* mode __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setDualMonoMode(audio_dual_mono_mode_t mode __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::getAudioDescriptionMixLevel(float* leveldB __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setAudioDescriptionMixLevel(float leveldB __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::getPlaybackRateParameters(
+        audio_playback_rate_t* playbackRate __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setPlaybackRateParameters(
+        const audio_playback_rate_t& playbackRate __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setEventCallback(
+        const sp<StreamOutHalInterfaceEventCallback>& callback __unused) {
+    return INVALID_OPERATION;
+}
+
+namespace {
+
+struct StreamOutEventCallback {
+    StreamOutEventCallback(const wp<StreamOutHalAidl>& stream) : mStream(stream) {}
+  private:
+    wp<StreamOutHalAidl> mStream;
+};
+
+}  // namespace
+
+status_t StreamOutHalAidl::setLatencyMode(audio_latency_mode_t mode __unused) {
+    return INVALID_OPERATION;
+};
+
+status_t StreamOutHalAidl::getRecommendedLatencyModes(
+        std::vector<audio_latency_mode_t> *modes __unused) {
+    return INVALID_OPERATION;
+};
+
+status_t StreamOutHalAidl::setLatencyModeCallback(
+        const sp<StreamOutHalInterfaceLatencyModeCallback>& callback __unused) {
+    return INVALID_OPERATION;
+};
+
+void StreamOutHalAidl::onWriteReady() {
+    sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+    if (callback == 0) return;
+    ALOGV("asyncCallback onWriteReady");
+    callback->onWriteReady();
+}
+
+void StreamOutHalAidl::onDrainReady() {
+    sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+    if (callback == 0) return;
+    ALOGV("asyncCallback onDrainReady");
+    callback->onDrainReady();
+}
+
+void StreamOutHalAidl::onError() {
+    sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+    if (callback == 0) return;
+    ALOGV("asyncCallback onError");
+    callback->onError();
+}
+
+void StreamOutHalAidl::onCodecFormatChanged(const std::basic_string<uint8_t>& metadataBs __unused) {
+    sp<StreamOutHalInterfaceEventCallback> callback = mEventCallback.load().promote();
+    if (callback == nullptr) return;
+    ALOGV("asyncCodecFormatCallback %s", __func__);
+    callback->onCodecFormatChanged(metadataBs);
+}
+
+void StreamOutHalAidl::onRecommendedLatencyModeChanged(
+        const std::vector<audio_latency_mode_t>& modes __unused) {
+    sp<StreamOutHalInterfaceLatencyModeCallback> callback = mLatencyModeCallback.load().promote();
+    if (callback == nullptr) return;
+    callback->onRecommendedLatencyModeChanged(modes);
+}
+
+status_t StreamOutHalAidl::exit() {
+    // FIXME this is using hard-coded strings but in the future, this functionality will be
+    //       converted to use audio HAL extensions required to support tunneling
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+StreamInHalAidl::StreamInHalAidl(
+        const StreamDescriptor& descriptor, const std::shared_ptr<IStreamIn>& stream)
+        : StreamHalAidl("StreamInHalAidl", true /*isInput*/, descriptor, getStreamCommon(stream)),
+          mStream(stream) {}
+
+status_t StreamInHalAidl::setGain(float gain __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamInHalAidl::read(
+        void *buffer __unused, size_t bytes __unused, size_t *read __unused) {
+    // TIME_CHECK();  // TODO(b/238654698) reenable only when optimized.
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    // FIXME: Don't forget to update mPowerLog
+    return OK;
+}
+
+status_t StreamInHalAidl::getInputFramesLost(uint32_t *framesLost __unused) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamInHalAidl::getCapturePosition(int64_t *frames __unused, int64_t *time __unused) {
+    // TIME_CHECK();  // TODO(b/238654698) reenable only when optimized.
+    if (!mStream) return NO_INIT;
+    ALOGE("%s not implemented yet", __func__);
+    return OK;
+}
+
+status_t StreamInHalAidl::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::updateSinkMetadata(
+        const StreamInHalInterface::SinkMetadata& sinkMetadata  __unused) {
+    return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::setPreferredMicrophoneDirection(
+            audio_microphone_direction_t direction __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::setPreferredMicrophoneFieldDimension(float zoom __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
+} // namespace android
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
new file mode 100644
index 0000000..c56d5e3
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2023 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 <memory>
+#include <string_view>
+
+#include <aidl/android/hardware/audio/core/BpStreamCommon.h>
+#include <aidl/android/hardware/audio/core/BpStreamIn.h>
+#include <aidl/android/hardware/audio/core/BpStreamOut.h>
+#include <fmq/AidlMessageQueue.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
+#include <mediautils/Synchronization.h>
+
+#include "ConversionHelperAidl.h"
+#include "StreamPowerLog.h"
+
+namespace android {
+
+class DeviceHalAidl;
+
+class StreamHalAidl : public virtual StreamHalInterface, public ConversionHelperAidl {
+  public:
+    // Return size of input/output buffer in bytes for this stream - eg. 4800.
+    status_t getBufferSize(size_t *size) override;
+
+    // Return the base configuration of the stream:
+    //   - channel mask;
+    //   - format - e.g. AUDIO_FORMAT_PCM_16_BIT;
+    //   - sampling rate in Hz - eg. 44100.
+    status_t getAudioProperties(audio_config_base_t *configBase) override;
+
+    // Set audio stream parameters.
+    status_t setParameters(const String8& kvPairs) override;
+
+    // Get audio stream parameters.
+    status_t getParameters(const String8& keys, String8 *values) override;
+
+    // Return the frame size (number of bytes per sample) of a stream.
+    status_t getFrameSize(size_t *size) override;
+
+    // Add or remove the effect on the stream.
+    status_t addEffect(sp<EffectHalInterface> effect) override;
+    status_t removeEffect(sp<EffectHalInterface> effect) override;
+
+    // Put the audio hardware input/output into standby mode.
+    status_t standby() override;
+
+    status_t dump(int fd, const Vector<String16>& args) override;
+
+    // Start a stream operating in mmap mode.
+    status_t start() override;
+
+    // Stop a stream operating in mmap mode.
+    status_t stop() override;
+
+    // Retrieve information on the data buffer in mmap mode.
+    status_t createMmapBuffer(int32_t minSizeFrames,
+            struct audio_mmap_buffer_info *info) override;
+
+    // Get current read/write position in the mmap buffer
+    status_t getMmapPosition(struct audio_mmap_position *position) override;
+
+    // Set the priority of the thread that interacts with the HAL
+    // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
+    status_t setHalThreadPriority(int priority) override;
+
+    status_t legacyCreateAudioPatch(const struct audio_port_config& port,
+            std::optional<audio_source_t> source,
+            audio_devices_t type) override;
+
+    status_t legacyReleaseAudioPatch() override;
+
+  protected:
+    typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Command,
+          ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> CommandMQ;
+    typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Reply,
+            ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> ReplyMQ;
+    typedef AidlMessageQueue<int8_t,
+            ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ;
+
+    template<class T>
+    static std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> getStreamCommon(
+            const std::shared_ptr<T>& stream);
+
+    // Subclasses can not be constructed directly by clients.
+    StreamHalAidl(std::string_view className,
+            bool isInput,
+            const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+            const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>& stream);
+
+    ~StreamHalAidl() override;
+
+    status_t getHalPid(pid_t *pid);
+
+    bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
+
+    const bool mIsInput;
+    const size_t mFrameSizeBytes;
+    const size_t mBufferSizeFrames;
+    const std::unique_ptr<CommandMQ> mCommandMQ;
+    const std::unique_ptr<ReplyMQ> mReplyMQ;
+    const std::unique_ptr<DataMQ> mDataMQ;
+    // mStreamPowerLog is used for audio signal power logging.
+    StreamPowerLog mStreamPowerLog;
+
+  private:
+    static std::unique_ptr<DataMQ> maybeCreateDataMQ(
+            const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) {
+        using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag;
+        if (descriptor.audio.getTag() == Tag::fmq) {
+            return std::make_unique<DataMQ>(descriptor.audio.get<Tag::fmq>());
+        }
+        return nullptr;
+    }
+
+    const int HAL_THREAD_PRIORITY_DEFAULT = -1;
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> mStream;
+    int mHalThreadPriority = HAL_THREAD_PRIORITY_DEFAULT;
+};
+
+class StreamOutHalAidl : public StreamOutHalInterface, public StreamHalAidl {
+  public:
+    // Return the audio hardware driver estimated latency in milliseconds.
+    status_t getLatency(uint32_t *latency) override;
+
+    // Use this method in situations where audio mixing is done in the hardware.
+    status_t setVolume(float left, float right) override;
+
+    // Selects the audio presentation (if available).
+    status_t selectPresentation(int presentationId, int programId) override;
+
+    // Write audio buffer to driver.
+    status_t write(const void *buffer, size_t bytes, size_t *written) override;
+
+    // Return the number of audio frames written by the audio dsp to DAC since
+    // the output has exited standby.
+    status_t getRenderPosition(uint32_t *dspFrames) override;
+
+    // Get the local time at which the next write to the audio driver will be presented.
+    status_t getNextWriteTimestamp(int64_t *timestamp) override;
+
+    // Set the callback for notifying completion of non-blocking write and drain.
+    status_t setCallback(wp<StreamOutHalInterfaceCallback> callback) override;
+
+    // Returns whether pause and resume operations are supported.
+    status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume) override;
+
+    // Notifies to the audio driver to resume playback following a pause.
+    status_t pause() override;
+
+    // Notifies to the audio driver to resume playback following a pause.
+    status_t resume() override;
+
+    // Returns whether drain operation is supported.
+    status_t supportsDrain(bool *supportsDrain) override;
+
+    // Requests notification when data buffered by the driver/hardware has been played.
+    status_t drain(bool earlyNotify) override;
+
+    // Notifies to the audio driver to flush the queued data.
+    status_t flush() override;
+
+    // Return a recent count of the number of audio frames presented to an external observer.
+    status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) override;
+
+    // Called when the metadata of the stream's source has been changed.
+    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+
+    // Returns the Dual Mono mode presentation setting.
+    status_t getDualMonoMode(audio_dual_mono_mode_t* mode) override;
+
+    // Sets the Dual Mono mode presentation on the output device.
+    status_t setDualMonoMode(audio_dual_mono_mode_t mode) override;
+
+    // Returns the Audio Description Mix level in dB.
+    status_t getAudioDescriptionMixLevel(float* leveldB) override;
+
+    // Sets the Audio Description Mix level in dB.
+    status_t setAudioDescriptionMixLevel(float leveldB) override;
+
+    // Retrieves current playback rate parameters.
+    status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate) override;
+
+    // Sets the playback rate parameters that control playback behavior.
+    status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) override;
+
+    status_t setEventCallback(const sp<StreamOutHalInterfaceEventCallback>& callback) override;
+
+    status_t setLatencyMode(audio_latency_mode_t mode) override;
+    status_t getRecommendedLatencyModes(std::vector<audio_latency_mode_t> *modes) override;
+    status_t setLatencyModeCallback(
+            const sp<StreamOutHalInterfaceLatencyModeCallback>& callback) override;
+
+    void onRecommendedLatencyModeChanged(const std::vector<audio_latency_mode_t>& modes);
+
+    status_t exit() override;
+
+    void onCodecFormatChanged(const std::basic_string<uint8_t>& metadataBs);
+
+    // Methods used by StreamOutCallback ().
+    // FIXME: Consider the required visibility.
+    void onWriteReady();
+    void onDrainReady();
+    void onError();
+
+  private:
+    friend class sp<StreamOutHalAidl>;
+
+    mediautils::atomic_wp<StreamOutHalInterfaceCallback> mCallback;
+    mediautils::atomic_wp<StreamOutHalInterfaceEventCallback> mEventCallback;
+    mediautils::atomic_wp<StreamOutHalInterfaceLatencyModeCallback> mLatencyModeCallback;
+
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut> mStream;
+
+    // Can not be constructed directly by clients.
+    StreamOutHalAidl(
+            const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+            const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut>& stream);
+
+    ~StreamOutHalAidl() override = default;
+};
+
+class StreamInHalAidl : public StreamInHalInterface, public StreamHalAidl {
+  public:
+    // Set the input gain for the audio driver.
+    status_t setGain(float gain) override;
+
+    // Read audio buffer in from driver.
+    status_t read(void *buffer, size_t bytes, size_t *read) override;
+
+    // Return the amount of input frames lost in the audio driver.
+    status_t getInputFramesLost(uint32_t *framesLost) override;
+
+    // Return a recent count of the number of audio frames received and
+    // the clock time associated with that frame count.
+    status_t getCapturePosition(int64_t *frames, int64_t *time) override;
+
+    // Get active microphones
+    status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) override;
+
+    // Set microphone direction (for processing)
+    status_t setPreferredMicrophoneDirection(
+                            audio_microphone_direction_t direction) override;
+
+    // Set microphone zoom (for processing)
+    status_t setPreferredMicrophoneFieldDimension(float zoom) override;
+
+    // Called when the metadata of the stream's sink has been changed.
+    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+
+  private:
+    friend class sp<StreamInHalAidl>;
+
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn> mStream;
+
+    // Can not be constructed directly by clients.
+    StreamInHalAidl(
+            const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+            const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn>& stream);
+
+    ~StreamInHalAidl() override = default;
+};
+
+} // namespace android
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 76f9a60..2c289e1 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -46,9 +46,6 @@
 using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
 using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
 
-#define TIME_CHECK() auto TimeCheck = \
-       mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
 StreamHalHidl::StreamHalHidl(std::string_view className, IStream *stream)
         : CoreConversionHelperHidl(className),
           mStream(stream),
diff --git a/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
new file mode 100644
index 0000000..20a10f6
--- /dev/null
+++ b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2023 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/media/audio/common/AudioUuid.h>
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::media::audio::common::AudioUuid;
+
+// 7b491460-8d4d-11e0-bd61-0002a5d5c51b.
+static const AudioUuid kAcousticEchoCancelerTypeUUID = {static_cast<int32_t>(0x7b491460),
+                                                        0x8d4d,
+                                                        0x11e0,
+                                                        0xbd61,
+                                                        {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 0xae3c653b-be18-4ab8-8938-418f0a7f06ac
+static const AudioUuid kAutomaticGainControlTypeUUID = {static_cast<int32_t>(0xae3c653b),
+                                                        0xbe18,
+                                                        0x4ab8,
+                                                        0x8938,
+                                                        {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}};
+// 0634f220-ddd4-11db-a0fc-0002a5d5c51b
+static const AudioUuid kBassBoostTypeUUID = {static_cast<int32_t>(0x0634f220),
+                                             0xddd4,
+                                             0x11db,
+                                             0xa0fc,
+                                             {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// fa81862a-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kDownmixTypeUUID = {static_cast<int32_t>(0xfa81862a),
+                                           0x588b,
+                                           0x11ed,
+                                           0x9b6a,
+                                           {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 0bed4300-ddd6-11db-8f34-0002a5d5c51b.
+static const AudioUuid kEqualizerTypeUUID = {static_cast<int32_t>(0x0bed4300),
+                                             0xddd6,
+                                             0x11db,
+                                             0x8f34,
+                                             {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 7261676f-6d75-7369-6364-28e2fd3ac39e
+static const AudioUuid kDynamicsProcessingTypeUUID = {static_cast<int32_t>(0x7261676f),
+                                                      0x6d75,
+                                                      0x7369,
+                                                      0x6364,
+                                                      {0x28, 0xe2, 0xfd, 0x3a, 0xc3, 0x9e}};
+// 1411e6d6-aecd-4021-a1cf-a6aceb0d71e5
+static const AudioUuid kHapticGeneratorTypeUUID = {static_cast<int32_t>(0x1411e6d6),
+                                                   0xaecd,
+                                                   0x4021,
+                                                   0xa1cf,
+                                                   {0xa6, 0xac, 0xeb, 0x0d, 0x71, 0xe5}};
+// fe3199be-aed0-413f-87bb-11260eb63cf1
+static const AudioUuid kLoudnessEnhancerTypeUUID = {static_cast<int32_t>(0xfe3199be),
+                                                    0xaed0,
+                                                    0x413f,
+                                                    0x87bb,
+                                                    {0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}};
+// c2e5d5f0-94bd-4763-9cac-4e234d06839e
+static const AudioUuid kEnvReverbTypeUUID = {static_cast<int32_t>(0xc2e5d5f0),
+                                             0x94bd,
+                                             0x4763,
+                                             0x9cac,
+                                             {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}};
+// 58b4b260-8e06-11e0-aa8e-0002a5d5c51b
+static const AudioUuid kNoiseSuppressionTypeUUID = {static_cast<int32_t>(0x58b4b260),
+                                                    0x8e06,
+                                                    0x11e0,
+                                                    0xaa8e,
+                                                    {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 47382d60-ddd8-11db-bf3a-0002a5d5c51b
+static const AudioUuid kPresetReverbTypeUUID = {static_cast<int32_t>(0x47382d60),
+                                                0xddd8,
+                                                0x11db,
+                                                0xbf3a,
+                                                {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 37cc2c00-dddd-11db-8577-0002a5d5c51b
+static const AudioUuid kVirtualizerTypeUUID = {static_cast<int32_t>(0x37cc2c00),
+                                               0xdddd,
+                                               0x11db,
+                                               0x8577,
+                                               {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// fa819f3e-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVisualizerTypeUUID = {static_cast<int32_t>(0xfa819f3e),
+                                              0x588b,
+                                              0x11ed,
+                                              0x9b6a,
+                                              {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// fa81a2b8-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVolumeTypeUUID = {static_cast<int32_t>(0xfa81a2b8),
+                                          0x588b,
+                                          0x11ed,
+                                          0x9b6a,
+                                          {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+
+}  // namespace effect
+}  // namespace android
diff --git a/media/libaudiohal/include/media/audiohal/AudioHalUtils.h b/media/libaudiohal/include/media/audiohal/AudioHalUtils.h
deleted file mode 100644
index 4862cba..0000000
--- a/media/libaudiohal/include/media/audiohal/AudioHalUtils.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 2c8219e..094b415 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -106,16 +106,10 @@
     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) {
-        ALOGE("%s override me port %p", __func__, port);
-        return OK;
-    }
+    virtual status_t getAudioPort(struct audio_port* port) = 0;
 
     // Fills the list of supported attributes for a given audio port.
-    virtual status_t getAudioPort(struct audio_port_v7 *port) {
-        ALOGE("%s override me port %p", __func__, port);
-        return OK;
-    }
+    virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
 
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
diff --git a/media/libeffects/downmix/aidl/DownmixContext.cpp b/media/libeffects/downmix/aidl/DownmixContext.cpp
index 6869689..43bfeed 100644
--- a/media/libeffects/downmix/aidl/DownmixContext.cpp
+++ b/media/libeffects/downmix/aidl/DownmixContext.cpp
@@ -21,6 +21,7 @@
 #include "DownmixContext.h"
 
 using aidl::android::hardware::audio::effect::IEffect;
+using ::aidl::android::media::audio::common::AudioChannelLayout;
 using ::android::hardware::audio::common::getChannelCount;
 
 namespace aidl::android::hardware::audio::effect {
diff --git a/media/libeffects/downmix/aidl/DownmixContext.h b/media/libeffects/downmix/aidl/DownmixContext.h
index 8a244ac..9a9f2da 100644
--- a/media/libeffects/downmix/aidl/DownmixContext.h
+++ b/media/libeffects/downmix/aidl/DownmixContext.h
@@ -22,9 +22,6 @@
 
 namespace aidl::android::hardware::audio::effect {
 
-using media::audio::common::AudioChannelLayout;
-using media::audio::common::AudioDeviceDescription;
-
 enum DownmixState {
     DOWNMIX_STATE_UNINITIALIZED,
     DOWNMIX_STATE_INITIALIZED,
@@ -45,34 +42,25 @@
     }
     Downmix::Type getDmType() const { return mType; }
 
-    RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) override {
-        // FIXME change volume
-        mVolumeStereo = volumeStereo;
-        return RetCode::SUCCESS;
-    }
-    Parameter::VolumeStereo getVolumeStereo() override { return mVolumeStereo; }
-
-    RetCode setOutputDevice(const AudioDeviceDescription& device) override {
+    RetCode setOutputDevice(
+            const std::vector<::aidl::android::media::audio::common::AudioDeviceDescription>&
+                    device) override {
         // FIXME change type if playing on headset vs speaker
         mOutputDevice = device;
         return RetCode::SUCCESS;
     }
-    AudioDeviceDescription getOutputDevice() { return mOutputDevice; }
 
     IEffect::Status lvmProcess(float* in, float* out, int samples);
 
   private:
     DownmixState mState;
     Downmix::Type mType;
-    AudioChannelLayout mChMask;
+    ::aidl::android::media::audio::common::AudioChannelLayout mChMask;
     ::android::audio_utils::channels::ChannelMix mChannelMix;
 
     // Common Params
-    AudioDeviceDescription mOutputDevice;
-    Parameter::VolumeStereo mVolumeStereo;
-
     void init_params(const Parameter::Common& common);
-    bool isChannelMaskValid(AudioChannelLayout channelMask);
+    bool isChannelMaskValid(::aidl::android::media::audio::common::AudioChannelLayout channelMask);
 };
 
 }  // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
index 3aee721..c601c38 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -287,32 +287,42 @@
 }
 
 bool BundleContext::isDeviceSupportedBassBoost(
-        const aidl::android::media::audio::common::AudioDeviceDescription& device) {
-    return (device == AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER, ""} ||
-            device == AudioDeviceDescription{AudioDeviceType::OUT_CARKIT,
-                                             AudioDeviceDescription::CONNECTION_BT_SCO} ||
-            device == AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER,
-                                             AudioDeviceDescription::CONNECTION_BT_A2DP});
+        const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
+    for (const auto& device : devices) {
+        if (device != AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER, ""} &&
+            device != AudioDeviceDescription{AudioDeviceType::OUT_CARKIT,
+                                             AudioDeviceDescription::CONNECTION_BT_SCO} &&
+            device != AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER,
+                                             AudioDeviceDescription::CONNECTION_BT_A2DP}) {
+            return false;
+        }
+    }
+    return true;
 }
 
 bool BundleContext::isDeviceSupportedVirtualizer(
-        const aidl::android::media::audio::common::AudioDeviceDescription& device) {
-    return (device == AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
-                                             AudioDeviceDescription::CONNECTION_ANALOG} ||
-            device == AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
-                                             AudioDeviceDescription::CONNECTION_ANALOG} ||
-            device == AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
-                                             AudioDeviceDescription::CONNECTION_BT_A2DP} ||
-            device == AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
-                                             AudioDeviceDescription::CONNECTION_USB});
+        const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
+    for (const auto& device : devices) {
+        if (device != AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
+                                             AudioDeviceDescription::CONNECTION_ANALOG} &&
+            device != AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
+                                             AudioDeviceDescription::CONNECTION_ANALOG} &&
+            device != AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
+                                             AudioDeviceDescription::CONNECTION_BT_A2DP} &&
+            device != AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
+                                             AudioDeviceDescription::CONNECTION_USB}) {
+            return false;
+        }
+    }
+    return true;
 }
 
 RetCode BundleContext::setOutputDevice(
-        const aidl::android::media::audio::common::AudioDeviceDescription& device) {
-    mOutputDevice = device;
+        const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
+    mOutputDevice = devices;
     switch (mType) {
         case lvm::BundleEffectType::BASS_BOOST:
-            if (isDeviceSupportedBassBoost(device)) {
+            if (!isDeviceSupportedBassBoost(devices)) {
                 // If a device doesn't support bass boost, the effect must be temporarily disabled.
                 // The effect must still report its original state as this can only be changed by
                 // the start/stop commands.
@@ -330,7 +340,7 @@
             }
             break;
         case lvm::BundleEffectType::VIRTUALIZER:
-            if (isDeviceSupportedVirtualizer(device)) {
+            if (!isDeviceSupportedVirtualizer(devices)) {
                 if (mEnabled) {
                     disableOperatingMode();
                 }
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
index be723f7..1f328fc 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
@@ -57,11 +57,14 @@
         return mChMask;
     }
     bool isDeviceSupportedBassBoost(
-            const aidl::android::media::audio::common::AudioDeviceDescription& device);
+            const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
+                    devices);
     bool isDeviceSupportedVirtualizer(
-            const aidl::android::media::audio::common::AudioDeviceDescription& device);
+            const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
+                    devices);
     RetCode setOutputDevice(
-            const aidl::android::media::audio::common::AudioDeviceDescription& device) override;
+            const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices)
+            override;
 
     RetCode setEqualizerPreset(const std::size_t presetIdx);
     int getEqualizerPreset() const { return mCurPresetIdx; }
diff --git a/media/libeffects/lvm/wrapper/Android.bp b/media/libeffects/lvm/wrapper/Android.bp
index aef9295..bc19379 100644
--- a/media/libeffects/lvm/wrapper/Android.bp
+++ b/media/libeffects/lvm/wrapper/Android.bp
@@ -128,4 +128,36 @@
     visibility: [
         "//hardware/interfaces/audio/aidl/default",
     ],
-}
\ No newline at end of file
+}
+
+cc_library_shared {
+    name: "libreverbaidl",
+    srcs: [
+        "Reverb/aidl/ReverbContext.cpp",
+        "Reverb/aidl/EffectReverb.cpp",
+        ":effectCommonFile",
+    ],
+    static_libs: ["libreverb"],
+    defaults: [
+        "aidlaudioservice_defaults",
+        "latest_android_hardware_audio_effect_ndk_shared",
+        "latest_android_media_audio_common_types_ndk_shared",
+    ],
+    local_include_dirs: ["Reverb/aidl"],
+    header_libs: [
+        "libaudioeffects",
+        "libhardware_headers",
+    ],
+    shared_libs: [
+        "libbase",
+        "libaudioutils",
+        "libcutils",
+        "liblog",
+    ],
+    cflags: [
+        "-Wthread-safety",
+    ],
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
new file mode 100644
index 0000000..51825ca
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2023 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 "EffectReverb"
+#include <Utils.h>
+#include <algorithm>
+#include <unordered_set>
+
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <audio_effects/effect_bassboost.h>
+#include <audio_effects/effect_equalizer.h>
+#include <audio_effects/effect_virtualizer.h>
+
+#include "EffectReverb.h"
+#include <limits.h>
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::EffectReverb;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kAuxEnvReverbImplUUID;
+using aidl::android::hardware::audio::effect::kAuxPresetReverbImplUUID;
+using aidl::android::hardware::audio::effect::kInsertEnvReverbImplUUID;
+using aidl::android::hardware::audio::effect::kInsertPresetReverbImplUUID;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+bool isReverbUuidSupported(const AudioUuid* uuid) {
+    return (*uuid == kAuxEnvReverbImplUUID || *uuid == kInsertEnvReverbImplUUID ||
+            *uuid == kAuxPresetReverbImplUUID || *uuid == kInsertPresetReverbImplUUID);
+}
+
+extern "C" binder_exception_t createEffect(const AudioUuid* uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (uuid == nullptr || !isReverbUuidSupported(uuid)) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<EffectReverb>(*uuid);
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || !isReverbUuidSupported(in_impl_uuid)) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (*in_impl_uuid == kAuxEnvReverbImplUUID) {
+        *_aidl_return = aidl::android::hardware::audio::effect::lvm::kAuxEnvReverbDesc;
+    } else if (*in_impl_uuid == kInsertEnvReverbImplUUID) {
+        *_aidl_return = aidl::android::hardware::audio::effect::lvm::kInsertEnvReverbDesc;
+    } else if (*in_impl_uuid == kAuxPresetReverbImplUUID) {
+        *_aidl_return = aidl::android::hardware::audio::effect::lvm::kAuxPresetReverbDesc;
+    } else if (*in_impl_uuid == kInsertPresetReverbImplUUID) {
+        *_aidl_return = aidl::android::hardware::audio::effect::lvm::kInsertPresetReverbDesc;
+    }
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+EffectReverb::EffectReverb(const AudioUuid& uuid) {
+    LOG(DEBUG) << __func__ << uuid.toString();
+    if (uuid == kAuxEnvReverbImplUUID) {
+        mType = lvm::ReverbEffectType::AUX_ENV;
+        mDescriptor = &lvm::kAuxEnvReverbDesc;
+        mEffectName = &lvm::kAuxEnvReverbEffectName;
+    } else if (uuid == kInsertEnvReverbImplUUID) {
+        mType = lvm::ReverbEffectType::INSERT_ENV;
+        mDescriptor = &lvm::kInsertEnvReverbDesc;
+        mEffectName = &lvm::kInsertEnvReverbEffectName;
+    } else if (uuid == kAuxPresetReverbImplUUID) {
+        mType = lvm::ReverbEffectType::AUX_PRESET;
+        mDescriptor = &lvm::kAuxPresetReverbDesc;
+        mEffectName = &lvm::kAuxPresetReverbEffectName;
+    } else if (uuid == kInsertPresetReverbImplUUID) {
+        mType = lvm::ReverbEffectType::INSERT_PRESET;
+        mDescriptor = &lvm::kInsertPresetReverbDesc;
+        mEffectName = &lvm::kInsertPresetReverbEffectName;
+    } else {
+        LOG(ERROR) << __func__ << uuid.toString() << " not supported!";
+    }
+}
+
+EffectReverb::~EffectReverb() {
+    cleanUp();
+    LOG(DEBUG) << __func__;
+}
+
+ndk::ScopedAStatus EffectReverb::getDescriptor(Descriptor* _aidl_return) {
+    RETURN_IF(!_aidl_return, EX_ILLEGAL_ARGUMENT, "Parameter:nullptr");
+    LOG(DEBUG) << _aidl_return->toString();
+    *_aidl_return = *mDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectReverb::setParameterSpecific(const Parameter::Specific& specific) {
+    LOG(DEBUG) << __func__ << " specific " << specific.toString();
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto tag = specific.getTag();
+    switch (tag) {
+        case Parameter::Specific::presetReverb:
+            return setParameterPresetReverb(specific);
+        case Parameter::Specific::environmentalReverb:
+            return setParameterEnvironmentalReverb(specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "specificParamNotSupported");
+    }
+}
+
+ndk::ScopedAStatus EffectReverb::setParameterPresetReverb(const Parameter::Specific& specific) {
+    auto& prParam = specific.get<Parameter::Specific::presetReverb>();
+    auto tag = prParam.getTag();
+
+    switch (tag) {
+        case PresetReverb::preset: {
+            RETURN_IF(mContext->setPresetReverbPreset(prParam.get<PresetReverb::preset>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setPresetFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "PresetReverbTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus EffectReverb::setParameterEnvironmentalReverb(
+        const Parameter::Specific& specific) {
+    auto& erParam = specific.get<Parameter::Specific::environmentalReverb>();
+    auto tag = erParam.getTag();
+
+    switch (tag) {
+        case EnvironmentalReverb::roomLevelMb: {
+            RETURN_IF(mContext->setEnvironmentalReverbRoomLevel(
+                              erParam.get<EnvironmentalReverb::roomLevelMb>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setRoomLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::roomHfLevelMb: {
+            RETURN_IF(
+                    mContext->setEnvironmentalReverbRoomHfLevel(
+                            erParam.get<EnvironmentalReverb::roomHfLevelMb>()) != RetCode::SUCCESS,
+                    EX_ILLEGAL_ARGUMENT, "setRoomHfLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::decayTimeMs: {
+            RETURN_IF(mContext->setEnvironmentalReverbDecayTime(
+                              erParam.get<EnvironmentalReverb::decayTimeMs>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDecayTimeFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::decayHfRatioPm: {
+            RETURN_IF(
+                    mContext->setEnvironmentalReverbDecayHfRatio(
+                            erParam.get<EnvironmentalReverb::decayHfRatioPm>()) != RetCode::SUCCESS,
+                    EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::levelMb: {
+            RETURN_IF(mContext->setEnvironmentalReverbLevel(
+                              erParam.get<EnvironmentalReverb::levelMb>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::delayMs: {
+            RETURN_IF(mContext->setEnvironmentalReverbDelay(
+                              erParam.get<EnvironmentalReverb::delayMs>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDelayFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::diffusionPm: {
+            RETURN_IF(mContext->setEnvironmentalReverbDiffusion(
+                              erParam.get<EnvironmentalReverb::diffusionPm>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDiffusionFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::densityPm: {
+            RETURN_IF(mContext->setEnvironmentalReverbDensity(
+                              erParam.get<EnvironmentalReverb::densityPm>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDensityFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::bypass: {
+            RETURN_IF(mContext->setEnvironmentalReverbBypass(
+                              erParam.get<EnvironmentalReverb::bypass>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setBypassFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus EffectReverb::getParameterSpecific(const Parameter::Id& id,
+                                                      Parameter::Specific* specific) {
+    RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
+    auto tag = id.getTag();
+
+    switch (tag) {
+        case Parameter::Id::presetReverbTag:
+            return getParameterPresetReverb(id.get<Parameter::Id::presetReverbTag>(), specific);
+        case Parameter::Id::environmentalReverbTag:
+            return getParameterEnvironmentalReverb(id.get<Parameter::Id::environmentalReverbTag>(),
+                                                   specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "wrongIdTag");
+    }
+}
+
+ndk::ScopedAStatus EffectReverb::getParameterPresetReverb(const PresetReverb::Id& id,
+                                                          Parameter::Specific* specific) {
+    RETURN_IF(id.getTag() != PresetReverb::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+              "PresetReverbTagNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    PresetReverb prParam;
+    auto tag = id.get<PresetReverb::Id::commonTag>();
+    switch (tag) {
+        case PresetReverb::preset: {
+            prParam.set<PresetReverb::preset>(mContext->getPresetReverbPreset());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "PresetReverbTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::presetReverb>(prParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectReverb::getParameterEnvironmentalReverb(const EnvironmentalReverb::Id& id,
+                                                                 Parameter::Specific* specific) {
+    RETURN_IF(id.getTag() != EnvironmentalReverb::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+              "EnvironmentalReverbTagNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    EnvironmentalReverb erParam;
+
+    auto tag = id.get<EnvironmentalReverb::Id::commonTag>();
+    switch (tag) {
+        case EnvironmentalReverb::roomLevelMb: {
+            erParam.set<EnvironmentalReverb::roomLevelMb>(
+                    mContext->getEnvironmentalReverbRoomLevel());
+            break;
+        }
+        case EnvironmentalReverb::roomHfLevelMb: {
+            erParam.set<EnvironmentalReverb::roomHfLevelMb>(
+                    mContext->getEnvironmentalReverbRoomHfLevel());
+            break;
+        }
+        case EnvironmentalReverb::decayTimeMs: {
+            erParam.set<EnvironmentalReverb::decayTimeMs>(
+                    mContext->getEnvironmentalReverbDecayTime());
+            break;
+        }
+        case EnvironmentalReverb::decayHfRatioPm: {
+            erParam.set<EnvironmentalReverb::decayHfRatioPm>(
+                    mContext->getEnvironmentalReverbDecayHfRatio());
+            break;
+        }
+        case EnvironmentalReverb::levelMb: {
+            erParam.set<EnvironmentalReverb::levelMb>(mContext->getEnvironmentalReverbLevel());
+            break;
+        }
+        case EnvironmentalReverb::delayMs: {
+            erParam.set<EnvironmentalReverb::delayMs>(mContext->getEnvironmentalReverbDelay());
+            break;
+        }
+        case EnvironmentalReverb::diffusionPm: {
+            erParam.set<EnvironmentalReverb::diffusionPm>(
+                    mContext->getEnvironmentalReverbDiffusion());
+            break;
+        }
+        case EnvironmentalReverb::densityPm: {
+            erParam.set<EnvironmentalReverb::densityPm>(mContext->getEnvironmentalReverbDensity());
+            break;
+        }
+        case EnvironmentalReverb::bypass: {
+            erParam.set<EnvironmentalReverb::bypass>(mContext->getEnvironmentalReverbBypass());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::environmentalReverb>(erParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> EffectReverb::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<ReverbContext>(1 /* statusFmqDepth */, common, mType);
+    }
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> EffectReverb::getContext() {
+    return mContext;
+}
+
+RetCode EffectReverb::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+ndk::ScopedAStatus EffectReverb::commandImpl(CommandId command) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    switch (command) {
+        case CommandId::START:
+            mContext->enable();
+            break;
+        case CommandId::STOP:
+            mContext->disable();
+            break;
+        case CommandId::RESET:
+            mContext->disable();
+            mContext->resetBuffer();
+            break;
+        default:
+            LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "commandIdNotSupported");
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status EffectReverb::effectProcessImpl(float* in, float* out, int sampleToProcess) {
+    IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+    RETURN_VALUE_IF(!mContext, status, "nullContext");
+    return mContext->lvmProcess(in, out, sampleToProcess);
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h
new file mode 100644
index 0000000..d7d2bbd
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 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/BnEffect.h>
+
+#include "effect-impl/EffectImpl.h"
+#include "ReverbContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class EffectReverb final : public EffectImpl {
+  public:
+    explicit EffectReverb(const AudioUuid& uuid);
+    ~EffectReverb() override;
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+    ndk::ScopedAStatus commandImpl(CommandId command) override;
+
+    std::string getEffectName() override { return *mEffectName; }
+
+  private:
+    std::shared_ptr<ReverbContext> mContext;
+    const Descriptor* mDescriptor;
+    const std::string* mEffectName;
+    lvm::ReverbEffectType mType;
+
+    IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
+
+    ndk::ScopedAStatus setParameterPresetReverb(const Parameter::Specific& specific);
+    ndk::ScopedAStatus getParameterPresetReverb(const PresetReverb::Id& id,
+                                                Parameter::Specific* specific);
+
+    ndk::ScopedAStatus setParameterEnvironmentalReverb(const Parameter::Specific& specific);
+    ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Id& id,
+                                                       Parameter::Specific* specific);
+};
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp
new file mode 100644
index 0000000..d35c22b
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2023 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 <cstddef>
+#define LOG_TAG "ReverbContext"
+#include <Utils.h>
+
+#include "ReverbContext.h"
+#include "VectorArithmetic.h"
+#include "math.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+
+#define GOTO_IF_LVREV_ERROR(status, tag, log)                                     \
+    do {                                                                          \
+        LVREV_ReturnStatus_en temp = (status);                                    \
+        if (temp != LVREV_SUCCESS) {                                              \
+            LOG(ERROR) << __func__ << " return status: " << temp << " " << (log); \
+            goto tag;                                                             \
+        }                                                                         \
+    } while (0)
+
+RetCode ReverbContext::init() {
+    if (isPreset()) {
+        // force reloading preset at first call to process()
+        mPreset = PresetReverb::Presets::NONE;
+        mNextPreset = PresetReverb::Presets::NONE;
+    }
+
+    mVolume.left = kUnitVolume;
+    mVolume.right = kUnitVolume;
+    mPrevVolume.left = kUnitVolume;
+    mPrevVolume.right = kUnitVolume;
+    volumeMode = VOLUME_FLAT;
+
+    mSamplesToExitCount = kDefaultDecayTime * mCommon.input.base.sampleRate / 1000;
+
+    /* Saved strength is used to return the exact strength that was used in the set to the get
+     * because we map the original strength range of 0:1000 to 1:15, and this will avoid
+     * quantisation like effect when returning
+     */
+    mRoomLevel = lvm::kMinLevel;
+    mRoomHfLevel = 0;
+    mEnabled = LVM_FALSE;
+    mDecayTime = kDefaultDecayTime;
+    mDecayHfRatio = kDefaultDamping * 20;
+    mDensity = kDefaultRoomSize * 10;
+    mDiffusion = kDefaultDensity * 10;
+    mLevel = lvm::kMinLevel;
+
+    // allocate lvm reverb instance
+    LVREV_ReturnStatus_en status = LVREV_SUCCESS;
+    {
+        std::lock_guard lg(mMutex);
+        LVREV_InstanceParams_st params = {
+                .MaxBlockSize = lvm::kMaxCallSize,
+                // Max format, could be mono during process
+                .SourceFormat = LVM_STEREO,
+                .NumDelays = LVREV_DELAYLINES_4,
+        };
+        /* Init sets the instance handle */
+        status = LVREV_GetInstanceHandle(&mInstance, &params);
+        GOTO_IF_LVREV_ERROR(status, deinit, "LVREV_GetInstanceHandleFailed");
+
+        // set control
+        LVREV_ControlParams_st controlParams;
+        initControlParameter(controlParams);
+        status = LVREV_SetControlParameters(mInstance, &controlParams);
+        GOTO_IF_LVREV_ERROR(status, deinit, "LVREV_SetControlParametersFailed");
+    }
+
+    return RetCode::SUCCESS;
+
+deinit:
+    deInit();
+    return RetCode::ERROR_EFFECT_LIB_ERROR;
+}
+
+void ReverbContext::deInit() {
+    std::lock_guard lg(mMutex);
+    if (mInstance) {
+        LVREV_FreeInstance(mInstance);
+        mInstance = nullptr;
+    }
+}
+
+RetCode ReverbContext::enable() {
+    if (mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
+    mEnabled = true;
+    mSamplesToExitCount = (mDecayTime * mCommon.input.base.sampleRate) / 1000;
+    // force no volume ramp for first buffer processed after enabling the effect
+    volumeMode = VOLUME_FLAT;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::disable() {
+    if (!mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
+    mEnabled = false;
+    return RetCode::SUCCESS;
+}
+
+bool ReverbContext::isAuxiliary() {
+    return (mType == lvm::ReverbEffectType::AUX_ENV || mType == lvm::ReverbEffectType::AUX_PRESET);
+}
+
+bool ReverbContext::isPreset() {
+    return (mType == lvm::ReverbEffectType::AUX_PRESET ||
+            mType == lvm::ReverbEffectType::INSERT_PRESET);
+}
+
+RetCode ReverbContext::setVolumeStereo(const Parameter::VolumeStereo& volume) {
+    if (volumeMode == VOLUME_OFF) {
+        // force no volume ramp for first buffer processed after getting volume control
+        volumeMode = VOLUME_FLAT;
+    }
+    mVolumeStereo = volume;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setPresetReverbPreset(const PresetReverb::Presets& preset) {
+    mNextPreset = preset;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbRoomLevel(int roomLevel) {
+    if (roomLevel < lvm::kEnvReverbCap.minRoomLevelMb ||
+        roomLevel > lvm::kEnvReverbCap.maxRoomLevelMb) {
+        LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+
+    // Update Control Parameter
+    LVREV_ControlParams_st params;
+    {
+        std::lock_guard lg(mMutex);
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+        // Sum of room and reverb level controls
+        // needs to subtract max levels for both room level and reverb level
+        int combinedLevel = (roomLevel + mLevel) - lvm::kMaxReverbLevel;
+        params.Level = convertLevel(combinedLevel);
+
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+    }
+    mRoomLevel = roomLevel;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbRoomHfLevel(int roomHfLevel) {
+    if (roomHfLevel < lvm::kEnvReverbCap.minRoomHfLevelMb ||
+        roomHfLevel > lvm::kEnvReverbCap.maxRoomHfLevelMb) {
+        LOG(ERROR) << __func__ << " invalid roomHfLevel: " << roomHfLevel;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+
+    // Update Control Parameter
+    LVREV_ControlParams_st params;
+    {
+        std::lock_guard lg(mMutex);
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+        params.LPF = convertHfLevel(roomHfLevel);
+
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+    }
+    mRoomHfLevel = roomHfLevel;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDecayTime(int decayTime) {
+    if (decayTime < 0 || decayTime > lvm::kEnvReverbCap.maxDecayTimeMs) {
+        LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+    int time = decayTime;
+    if (time > lvm::kMaxT60) {
+        time = lvm::kMaxT60;
+    }
+
+    // Update Control Parameter
+    LVREV_ControlParams_st params;
+    {
+        std::lock_guard lg(mMutex);
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+        params.T60 = (LVM_UINT16)time;
+        mSamplesToExitCount = (params.T60 * mCommon.input.base.sampleRate) / 1000;
+
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+    }
+    mDecayTime = time;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDecayHfRatio(int decayHfRatio) {
+    if (decayHfRatio < lvm::kEnvReverbCap.minDecayHfRatioPm ||
+        decayHfRatio > lvm::kEnvReverbCap.maxDecayHfRatioPm) {
+        LOG(ERROR) << __func__ << " invalid decayHfRatio: " << decayHfRatio;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+
+    // Update Control Parameter
+    LVREV_ControlParams_st params;
+    {
+        std::lock_guard lg(mMutex);
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+        params.Damping = (LVM_INT16)(decayHfRatio / 20);
+
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+    }
+    mDecayHfRatio = decayHfRatio;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbLevel(int level) {
+    if (level < lvm::kEnvReverbCap.minLevelMb || level > lvm::kEnvReverbCap.maxLevelMb) {
+        LOG(ERROR) << __func__ << " invalid level: " << level;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+
+    // Update Control Parameter
+    LVREV_ControlParams_st params;
+    {
+        std::lock_guard lg(mMutex);
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+        // Sum of room and reverb level controls
+        // needs to subtract max levels for both room level and level
+        int combinedLevel = (level + mRoomLevel) - lvm::kMaxReverbLevel;
+        params.Level = convertLevel(combinedLevel);
+
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+    }
+    mLevel = level;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDelay(int delay) {
+    if (delay < 0 || delay > lvm::kEnvReverbCap.maxDelayMs) {
+        LOG(ERROR) << __func__ << " invalid delay: " << delay;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+    mDelay = delay;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDiffusion(int diffusion) {
+    if (diffusion < 0 || diffusion > lvm::kEnvReverbCap.maxDiffusionPm) {
+        LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+
+    // Update Control Parameter
+    LVREV_ControlParams_st params;
+    {
+        std::lock_guard lg(mMutex);
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+        params.Density = (LVM_INT16)(diffusion / 10);
+
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+    }
+    mDiffusion = diffusion;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDensity(int density) {
+    if (density < 0 || density > lvm::kEnvReverbCap.maxDensityPm) {
+        LOG(ERROR) << __func__ << " invalid density: " << density;
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+
+    // Update Control Parameter
+    LVREV_ControlParams_st params;
+    {
+        std::lock_guard lg(mMutex);
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+        params.RoomSize = (LVM_INT16)(((density * 99) / 1000) + 1);
+
+        RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, &params),
+                        RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+    }
+    mDensity = density;
+    return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbBypass(bool bypass) {
+    mBypass = bypass;
+    return RetCode::SUCCESS;
+}
+
+void ReverbContext::loadPreset() {
+    // TODO: add delay when early reflections are implemented
+    mPreset = mNextPreset;
+
+    if (mPreset != PresetReverb::Presets::NONE) {
+        const t_reverb_settings preset = mReverbPresets[mPreset];
+        setEnvironmentalReverbRoomLevel(preset.roomLevel);
+        setEnvironmentalReverbRoomHfLevel(preset.roomHFLevel);
+        setEnvironmentalReverbDecayTime(preset.decayTime);
+        setEnvironmentalReverbDecayHfRatio(preset.decayHFRatio);
+        setEnvironmentalReverbLevel(preset.reverbLevel);
+        // reverbDelay
+        setEnvironmentalReverbDiffusion(preset.diffusion);
+        setEnvironmentalReverbDensity(preset.density);
+    }
+}
+
+void ReverbContext::initControlParameter(LVREV_ControlParams_st& params) {
+    /* Set the initial process parameters */
+    /* General parameters */
+    params.OperatingMode = LVM_MODE_ON;
+    params.SampleRate = LVM_FS_44100;
+    params.SourceFormat = (::android::hardware::audio::common::getChannelCount(
+                                   mCommon.input.base.channelMask) == 1
+                                   ? LVM_MONO
+                                   : LVM_STEREO);
+
+    if (!isAuxiliary() && params.SourceFormat == LVM_MONO) {
+        params.SourceFormat = LVM_STEREO;
+    }
+
+    /* Reverb parameters */
+    params.Level = kDefaultLevel;
+    params.LPF = kDefaultLPF;
+    params.HPF = kDefaultHPF;
+    params.T60 = kDefaultDecayTime;
+    params.Density = kDefaultDensity;
+    params.Damping = kDefaultDamping;
+    params.RoomSize = kDefaultRoomSize;
+}
+
+/*
+ * Convert level from OpenSL ES format to LVM format
+ *
+ *  @param level : level to be applied
+ */
+
+int ReverbContext::convertLevel(int level) {
+    for (int i = 0; i < kLevelMapping.size(); i++) {
+        if (level <= kLevelMapping[i]) {
+            return i;
+        }
+    }
+    return kDefaultLevel;
+}
+
+/*
+ * Convert level HF from OpenSL ES format to LVM format
+ *
+ * @param hfLevel : level to be applied
+ */
+
+int16_t ReverbContext::convertHfLevel(int hfLevel) {
+    for (auto lpfPair : kLPFMapping) {
+        if (hfLevel <= lpfPair.roomHf) {
+            return lpfPair.lpf;
+        }
+    }
+    return kDefaultLPF;
+}
+
+IEffect::Status ReverbContext::lvmProcess(float* in, float* out, int samples) {
+    IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+    RETURN_VALUE_IF(!in, status, "nullInput");
+    RETURN_VALUE_IF(!out, status, "nullOutput");
+    status = {EX_ILLEGAL_STATE, 0, 0};
+    int64_t inputFrameCount = getCommon().input.frameCount;
+    int64_t outputFrameCount = getCommon().output.frameCount;
+    RETURN_VALUE_IF(inputFrameCount != outputFrameCount, status, "FrameCountMismatch");
+    RETURN_VALUE_IF(0 == getInputFrameSize(), status, "zeroFrameSize");
+
+    LOG(DEBUG) << __func__ << " start processing";
+    std::lock_guard lg(mMutex);
+
+    int channels =
+            ::android::hardware::audio::common::getChannelCount(mCommon.input.base.channelMask);
+    int outChannels =
+            ::android::hardware::audio::common::getChannelCount(mCommon.output.base.channelMask);
+    int frameCount = mCommon.input.frameCount;
+
+    // Reverb only effects the stereo channels in multichannel source.
+    if (channels < 1 || channels > LVM_MAX_CHANNELS) {
+        LOG(ERROR) << __func__ << " process invalid PCM channels " << channels;
+        return status;
+    }
+
+    std::vector<float> inFrames(samples);
+    std::vector<float> outFrames(frameCount * FCC_2);
+
+    if (isPreset() && mNextPreset != mPreset) {
+        loadPreset();
+    }
+
+    if (isAuxiliary()) {
+        inFrames.assign(in, in + samples);
+    } else {
+        // mono input is duplicated
+        if (channels >= FCC_2) {
+            for (int i = 0; i < frameCount; i++) {
+                inFrames[FCC_2 * i] = in[channels * i] * kSendLevel;
+                inFrames[FCC_2 * i + 1] = in[channels * i + 1] * kSendLevel;
+            }
+        } else {
+            for (int i = 0; i < frameCount; i++) {
+                inFrames[FCC_2 * i] = inFrames[FCC_2 * i + 1] = in[i] * kSendLevel;
+            }
+        }
+    }
+
+    if (isPreset() && mPreset == PresetReverb::Presets::NONE) {
+        std::fill(outFrames.begin(), outFrames.end(), 0);  // always stereo here
+    } else {
+        if (!mEnabled && mSamplesToExitCount > 0) {
+            std::fill(outFrames.begin(), outFrames.end(), 0);
+            LOG(VERBOSE) << "Zeroing " << channels << " samples per frame at the end of call ";
+        }
+
+        /* Process the samples, producing a stereo output */
+        LVREV_ReturnStatus_en lvrevStatus =
+                LVREV_Process(mInstance,        /* Instance handle */
+                              inFrames.data(),  /* Input buffer */
+                              outFrames.data(), /* Output buffer */
+                              frameCount);      /* Number of samples to read */
+        if (lvrevStatus != LVREV_SUCCESS) {
+            LOG(ERROR) << __func__ << lvrevStatus;
+            return {EX_UNSUPPORTED_OPERATION, 0, 0};
+        }
+    }
+    // Convert to 16 bits
+    if (isAuxiliary()) {
+        // nothing to do here
+    } else {
+        if (channels >= FCC_2) {
+            for (int i = 0; i < frameCount; i++) {
+                // Mix with dry input
+                outFrames[FCC_2 * i] += in[channels * i];
+                outFrames[FCC_2 * i + 1] += in[channels * i + 1];
+            }
+        } else {
+            for (int i = 0; i < frameCount; i++) {
+                // Mix with dry input
+                outFrames[FCC_2 * i] += in[i];
+                outFrames[FCC_2 * i + 1] += in[i];
+            }
+        }
+
+        // apply volume with ramp if needed
+        if (mVolume != mPrevVolume && volumeMode == VOLUME_RAMP) {
+            float vl = mPrevVolume.left;
+            float incl = (mVolume.left - vl) / frameCount;
+            float vr = mPrevVolume.right;
+            float incr = (mVolume.right - vr) / frameCount;
+
+            for (int i = 0; i < frameCount; i++) {
+                outFrames[FCC_2 * i] *= vl;
+                outFrames[FCC_2 * i + 1] *= vr;
+
+                vl += incl;
+                vr += incr;
+            }
+            mPrevVolume = mVolume;
+        } else if (volumeMode != VOLUME_OFF) {
+            if (mVolume.left != kUnitVolume || mVolume.right != kUnitVolume) {
+                for (int i = 0; i < frameCount; i++) {
+                    outFrames[FCC_2 * i] *= mVolume.left;
+                    outFrames[FCC_2 * i + 1] *= mVolume.right;
+                }
+            }
+            mPrevVolume = mVolume;
+            volumeMode = VOLUME_RAMP;
+        }
+    }
+
+    bool accumulate = false;
+    if (outChannels > 2) {
+        // Accumulate if required
+        if (accumulate) {
+            for (int i = 0; i < frameCount; i++) {
+                out[outChannels * i] += outFrames[FCC_2 * i];
+                out[outChannels * i + 1] += outFrames[FCC_2 * i + 1];
+            }
+        } else {
+            for (int i = 0; i < frameCount; i++) {
+                out[outChannels * i] = outFrames[FCC_2 * i];
+                out[outChannels * i + 1] = outFrames[FCC_2 * i + 1];
+            }
+        }
+        if (!isAuxiliary()) {
+            for (int i = 0; i < frameCount; i++) {
+                // channels and outChannels are expected to be same.
+                for (int j = FCC_2; j < outChannels; j++) {
+                    out[outChannels * i + j] = in[outChannels * i + j];
+                }
+            }
+        }
+    } else {
+        if (accumulate) {
+            if (outChannels == FCC_1) {
+                for (int i = 0; i < frameCount; i++) {
+                    out[i] += ((outFrames[i * FCC_2] + outFrames[i * FCC_2 + 1]) * 0.5f);
+                }
+            } else {
+                for (int i = 0; i < frameCount * FCC_2; i++) {
+                    out[i] += outFrames[i];
+                }
+            }
+        } else {
+            if (outChannels == FCC_1) {
+                From2iToMono_Float(outFrames.data(), out, frameCount);
+            } else {
+                for (int i = 0; i < frameCount * FCC_2; i++) {
+                    out[i] = outFrames[i];
+                }
+            }
+        }
+    }
+
+    LOG(DEBUG) << __func__ << " done processing";
+
+    if (!mEnabled && mSamplesToExitCount > 0) {
+        // signed - unsigned will trigger integer overflow if result becomes negative.
+        mSamplesToExitCount -= samples;
+    }
+
+    return {STATUS_OK, samples, outChannels * frameCount};
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
new file mode 100644
index 0000000..af49a25
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2023 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-base/logging.h>
+#include <android-base/thread_annotations.h>
+#include <unordered_map>
+
+#include "ReverbTypes.h"
+#include "effect-impl/EffectContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+enum VolumeMode {
+    VOLUME_OFF,
+    VOLUME_FLAT,
+    VOLUME_RAMP,
+};
+
+struct LPFPair {
+    int roomHf;
+    int lpf;
+};
+
+class ReverbContext final : public EffectContext {
+  public:
+    ReverbContext(int statusDepth, const Parameter::Common& common,
+                  const lvm::ReverbEffectType& type)
+        : EffectContext(statusDepth, common), mType(type) {
+        LOG(DEBUG) << __func__ << type;
+        init();
+    }
+    ~ReverbContext() override {
+        LOG(DEBUG) << __func__;
+        deInit();
+    }
+
+    RetCode init();
+    void deInit();
+
+    RetCode enable();
+    RetCode disable();
+
+    bool isAuxiliary();
+    bool isPreset();
+
+    RetCode setPresetReverbPreset(const PresetReverb::Presets& preset);
+    PresetReverb::Presets getPresetReverbPreset() const { return mNextPreset; }
+
+    RetCode setEnvironmentalReverbRoomLevel(int roomLevel);
+    int getEnvironmentalReverbRoomLevel() const { return mRoomLevel; }
+    RetCode setEnvironmentalReverbRoomHfLevel(int roomHfLevel);
+    int getEnvironmentalReverbRoomHfLevel() const { return mRoomHfLevel; }
+    RetCode setEnvironmentalReverbDecayTime(int decayTime);
+    int getEnvironmentalReverbDecayTime() const { return mDecayTime; }
+    RetCode setEnvironmentalReverbDecayHfRatio(int decayHfRatio);
+    int getEnvironmentalReverbDecayHfRatio() const { return mDecayHfRatio; }
+    RetCode setEnvironmentalReverbLevel(int level);
+    int getEnvironmentalReverbLevel() const { return mLevel; }
+    RetCode setEnvironmentalReverbDelay(int delay);
+    int getEnvironmentalReverbDelay() const { return mDelay; }
+    RetCode setEnvironmentalReverbDiffusion(int diffusion);
+    int getEnvironmentalReverbDiffusion() const { return mDiffusion; }
+    RetCode setEnvironmentalReverbDensity(int density);
+    int getEnvironmentalReverbDensity() const { return mDensity; }
+    RetCode setEnvironmentalReverbBypass(bool bypass);
+    bool getEnvironmentalReverbBypass() const { return mBypass; }
+
+    RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) override;
+    Parameter::VolumeStereo getVolumeStereo() override { return mVolumeStereo; }
+
+    IEffect::Status lvmProcess(float* in, float* out, int samples);
+
+  private:
+    static constexpr inline float kUnitVolume = 1;
+    static constexpr inline float kSendLevel = 0.75f;
+    static constexpr inline int kDefaultLevel = 0;
+    static constexpr inline int kDefaultLPF = 23999;      /* Default low pass filter, in Hz */
+    static constexpr inline int kDefaultHPF = 50;         /* Default high pass filter, in Hz */
+    static constexpr inline int kDefaultDecayTime = 1490; /* Default Decay time, in ms */
+    static constexpr inline int kDefaultDensity = 100;    /* Default Echo density */
+    static constexpr inline int kDefaultDamping = 21;
+    static constexpr inline int kDefaultRoomSize = 100;
+
+    static inline const std::vector<LPFPair> kLPFMapping = {
+            // Limit range to 50 for LVREV parameter range
+            {-10000, 50}, {-5000, 50},  {-4000, 50},  {-3000, 158}, {-2000, 502}, {-1000, 1666},
+            {-900, 1897}, {-800, 2169}, {-700, 2496}, {-600, 2895}, {-500, 3400}, {-400, 4066},
+            {-300, 5011}, {-200, 6537}, {-100, 9826}, {-99, 9881},  {-98, 9937},  {-97, 9994},
+            {-96, 10052}, {-95, 10111}, {-94, 10171}, {-93, 10231}, {-92, 10293}, {-91, 10356},
+            {-90, 10419}, {-89, 10484}, {-88, 10549}, {-87, 10616}, {-86, 10684}, {-85, 10753},
+            {-84, 10823}, {-83, 10895}, {-82, 10968}, {-81, 11042}, {-80, 11117}, {-79, 11194},
+            {-78, 11272}, {-77, 11352}, {-76, 11433}, {-75, 11516}, {-74, 11600}, {-73, 11686},
+            {-72, 11774}, {-71, 11864}, {-70, 11955}, {-69, 12049}, {-68, 12144}, {-67, 12242},
+            {-66, 12341}, {-65, 12443}, {-64, 12548}, {-63, 12654}, {-62, 12763}, {-61, 12875},
+            {-60, 12990}, {-59, 13107}, {-58, 13227}, {-57, 13351}, {-56, 13477}, {-55, 13607},
+            {-54, 13741}, {-53, 13878}, {-52, 14019}, {-51, 14164}, {-50, 14313}, {-49, 14467},
+            {-48, 14626}, {-47, 14789}, {-46, 14958}, {-45, 15132}, {-44, 15312}, {-43, 15498},
+            {-42, 15691}, {-41, 15890}, {-40, 16097}, {-39, 16311}, {-38, 16534}, {-37, 16766},
+            {-36, 17007}, {-35, 17259}, {-34, 17521}, {-33, 17795}, {-32, 18081}, {-31, 18381},
+            {-30, 18696}, {-29, 19027}, {-28, 19375}, {-27, 19742}, {-26, 20129}, {-25, 20540},
+            {-24, 20976}, {-23, 21439}, {-22, 21934}, {-21, 22463}, {-20, 23031}, {-19, 23643},
+            {-18, 23999}};
+
+    static inline const std::vector<int> kLevelMapping = {
+            -12000, -4000, -3398, -3046, -2796, -2603, -2444, -2310, -2194, -2092, -2000, -1918,
+            -1842,  -1773, -1708, -1648, -1592, -1540, -1490, -1443, -1398, -1356, -1316, -1277,
+            -1240,  -1205, -1171, -1138, -1106, -1076, -1046, -1018, -990,  -963,  -938,  -912,
+            -888,   -864,  -841,  -818,  -796,  -775,  -754,  -734,  -714,  -694,  -675,  -656,
+            -638,   -620,  -603,  -585,  -568,  -552,  -536,  -520,  -504,  -489,  -474,  -459,
+            -444,   -430,  -416,  -402,  -388,  -375,  -361,  -348,  -335,  -323,  -310,  -298,
+            -286,   -274,  -262,  -250,  -239,  -228,  -216,  -205,  -194,  -184,  -173,  -162,
+            -152,   -142,  -132,  -121,  -112,  -102,  -92,   -82,   -73,   -64,   -54,   -45,
+            -36,    -27,   -18,   -9,    0};
+
+    static inline std::unordered_map<PresetReverb::Presets, t_reverb_settings> mReverbPresets = {
+            {PresetReverb::Presets::NONE, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+            {PresetReverb::Presets::SMALLROOM,
+             {-400, -600, 1100, 830, -400, 5, 500, 10, 1000, 1000}},
+            {PresetReverb::Presets::MEDIUMROOM,
+             {-400, -600, 1300, 830, -1000, 20, -200, 20, 1000, 1000}},
+            {PresetReverb::Presets::LARGEROOM,
+             {-400, -600, 1500, 830, -1600, 5, -1000, 40, 1000, 1000}},
+            {PresetReverb::Presets::MEDIUMHALL,
+             {-400, -600, 1800, 700, -1300, 15, -800, 30, 1000, 1000}},
+            {PresetReverb::Presets::LARGEHALL,
+             {-400, -600, 1800, 700, -2000, 30, -1400, 60, 1000, 1000}},
+            {PresetReverb::Presets::PLATE, {-400, -200, 1300, 900, 0, 2, 0, 10, 1000, 750}}};
+
+    std::mutex mMutex;
+    const lvm::ReverbEffectType mType;
+    bool mEnabled = false;
+    LVREV_Handle_t mInstance GUARDED_BY(mMutex);
+
+    int mRoomLevel;
+    int mRoomHfLevel;
+    int mDecayTime;
+    int mDecayHfRatio;
+    int mLevel;
+    int mDelay;
+    int mDiffusion;
+    int mDensity;
+    bool mBypass;
+
+    PresetReverb::Presets mPreset;
+    PresetReverb::Presets mNextPreset;
+
+    int mSamplesToExitCount;
+
+    Parameter::VolumeStereo mVolume;
+    Parameter::VolumeStereo mPrevVolume;
+    VolumeMode volumeMode;
+
+    void initControlParameter(LVREV_ControlParams_st& params);
+    int16_t convertHfLevel(int hfLevel);
+    int convertLevel(int level);
+    void loadPreset();
+};
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h
new file mode 100644
index 0000000..e37602c
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2023 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/BnEffect.h>
+#include <android/binder_enums.h>
+#include <audio_effects/effect_environmentalreverb.h>
+#include <audio_effects/effect_presetreverb.h>
+#include "effect-impl/EffectUUID.h"
+// from Reverb/lib
+#include "LVREV.h"
+
+namespace aidl::android::hardware::audio::effect {
+namespace lvm {
+
+constexpr inline int kMaxCallSize = 256;
+constexpr inline int kMinLevel = -6000;
+constexpr inline int kMaxT60 = 7000; /* Maximum decay time */
+constexpr inline int kMaxReverbLevel = 2000;
+constexpr inline int kMaxFrameSize = 2560;
+constexpr inline int kCpuLoadARM9E = 470;                      // Expressed in 0.1 MIPS
+constexpr inline int kMemUsage = (71 + (kMaxFrameSize >> 7));  // Expressed in kB
+
+static const EnvironmentalReverb::Capability kEnvReverbCap = {.minRoomLevelMb = lvm::kMinLevel,
+                                                              .maxRoomLevelMb = 0,
+                                                              .minRoomHfLevelMb = -4000,
+                                                              .maxRoomHfLevelMb = 0,
+                                                              .maxDecayTimeMs = lvm::kMaxT60,
+                                                              .minDecayHfRatioPm = 100,
+                                                              .maxDecayHfRatioPm = 2000,
+                                                              .minLevelMb = lvm::kMinLevel,
+                                                              .maxLevelMb = 0,
+                                                              .maxDelayMs = 65,
+                                                              .maxDiffusionPm = 1000,
+                                                              .maxDensityPm = 1000};
+
+// NXP SW auxiliary environmental reverb
+static const std::string kAuxEnvReverbEffectName = "Auxiliary Environmental Reverb";
+static const Descriptor kAuxEnvReverbDesc = {
+        .common = {.id = {.type = kEnvReverbTypeUUID,
+                          .uuid = kAuxEnvReverbImplUUID,
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::AUXILIARY},
+                   .cpuLoad = kCpuLoadARM9E,
+                   .memoryUsage = kMemUsage,
+                   .name = kAuxEnvReverbEffectName,
+                   .implementor = "NXP Software Ltd."},
+        .capability = Capability::make<Capability::environmentalReverb>(kEnvReverbCap)};
+
+// NXP SW insert environmental reverb
+static const std::string kInsertEnvReverbEffectName = "Insert Environmental Reverb";
+static const Descriptor kInsertEnvReverbDesc = {
+        .common = {.id = {.type = kEnvReverbTypeUUID,
+                          .uuid = kInsertEnvReverbImplUUID,
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .cpuLoad = kCpuLoadARM9E,
+                   .memoryUsage = kMemUsage,
+                   .name = kInsertEnvReverbEffectName,
+                   .implementor = "NXP Software Ltd."},
+        .capability = Capability::make<Capability::environmentalReverb>(kEnvReverbCap)};
+
+static const std::vector<PresetReverb::Presets> kSupportedPresets{
+        ndk::enum_range<PresetReverb::Presets>().begin(),
+        ndk::enum_range<PresetReverb::Presets>().end()};
+static const PresetReverb::Capability kPresetReverbCap = {.supportedPresets = kSupportedPresets};
+
+// NXP SW auxiliary preset reverb
+static const std::string kAuxPresetReverbEffectName = "Auxiliary Preset Reverb";
+static const Descriptor kAuxPresetReverbDesc = {
+        .common = {.id = {.type = kPresetReverbTypeUUID,
+                          .uuid = kAuxPresetReverbImplUUID,
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::AUXILIARY},
+                   .cpuLoad = kCpuLoadARM9E,
+                   .memoryUsage = kMemUsage,
+                   .name = kAuxPresetReverbEffectName,
+                   .implementor = "NXP Software Ltd."},
+        .capability = Capability::make<Capability::presetReverb>(kPresetReverbCap)};
+
+// NXP SW insert preset reverb
+static const std::string kInsertPresetReverbEffectName = "Insert Preset Reverb";
+static const Descriptor kInsertPresetReverbDesc = {
+        .common = {.id = {.type = kPresetReverbTypeUUID,
+                          .uuid = kInsertPresetReverbImplUUID,
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .cpuLoad = kCpuLoadARM9E,
+                   .memoryUsage = kMemUsage,
+                   .name = kInsertPresetReverbEffectName,
+                   .implementor = "NXP Software Ltd."},
+        .capability = Capability::make<Capability::presetReverb>(kPresetReverbCap)};
+
+enum class ReverbEffectType {
+    AUX_ENV,
+    INSERT_ENV,
+    AUX_PRESET,
+    INSERT_PRESET,
+};
+
+inline std::ostream& operator<<(std::ostream& out, const ReverbEffectType& type) {
+    switch (type) {
+        case ReverbEffectType::AUX_ENV:
+            return out << kAuxEnvReverbEffectName;
+        case ReverbEffectType::INSERT_ENV:
+            return out << kInsertEnvReverbEffectName;
+        case ReverbEffectType::AUX_PRESET:
+            return out << kAuxPresetReverbEffectName;
+        case ReverbEffectType::INSERT_PRESET:
+            return out << kInsertPresetReverbEffectName;
+    }
+    return out << "EnumReverbEffectTypeError";
+}
+
+inline std::ostream& operator<<(std::ostream& out, const LVREV_ReturnStatus_en& status) {
+    switch (status) {
+        case LVREV_SUCCESS:
+            return out << "LVREV_SUCCESS";
+        case LVREV_NULLADDRESS:
+            return out << "LVREV_NULLADDRESS";
+        case LVREV_OUTOFRANGE:
+            return out << "LVREV_OUTOFRANGE";
+        case LVREV_INVALIDNUMSAMPLES:
+            return out << "LVREV_INVALIDNUMSAMPLES";
+        case LVREV_RETURNSTATUS_DUMMY:
+            return out << "LVREV_RETURNSTATUS_DUMMY";
+    }
+    return out << "EnumLvrevRetStatusError";
+}
+
+}  // namespace lvm
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
index 5e29b3f..a964d4f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
@@ -22,14 +22,13 @@
 #include <mediadrm/DrmUtils.h>
 #include <utils/Log.h>
 
-
 namespace android {
 
 // static helpers - internal
 
 sp<IDrm> NuPlayerDrm::CreateDrm(status_t *pstatus)
 {
-    return DrmUtils::MakeDrm(pstatus);
+    return DrmUtils::MakeDrm(IDRM_NUPLAYER, pstatus);
 }
 
 sp<ICrypto> NuPlayerDrm::createCrypto(status_t *pstatus)
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 8c469df..ccd3a54 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -155,6 +155,7 @@
         "libEGL",
         "libGLESv1_CM",
         "libGLESv2",
+        "libvulkan",
         "libgui",
         "liblog",
         "libprocessgroup",
diff --git a/media/libstagefright/renderfright/Android.bp b/media/libstagefright/renderfright/Android.bp
index 3c00a1c..3598e8d 100644
--- a/media/libstagefright/renderfright/Android.bp
+++ b/media/libstagefright/renderfright/Android.bp
@@ -32,6 +32,7 @@
         "libEGL",
         "libGLESv1_CM",
         "libGLESv2",
+        "libvulkan",
         "liblog",
         "libnativewindow",
         "libprocessgroup",
diff --git a/media/module/extractors/aac/AACExtractor.cpp b/media/module/extractors/aac/AACExtractor.cpp
index 2fc4584..a44fb61 100644
--- a/media/module/extractors/aac/AACExtractor.cpp
+++ b/media/module/extractors/aac/AACExtractor.cpp
@@ -310,9 +310,9 @@
         return AMEDIA_ERROR_END_OF_STREAM;
     }
 
-    MediaBufferHelper *buffer;
+    MediaBufferHelper *buffer = nullptr;
     status_t err = mBufferGroup->acquire_buffer(&buffer);
-    if (err != OK) {
+    if (err != OK || buffer == nullptr) {
         return AMEDIA_ERROR_UNKNOWN;
     }
 
diff --git a/media/module/extractors/amr/AMRExtractor.cpp b/media/module/extractors/amr/AMRExtractor.cpp
index e26ff0a..b0f69ce 100644
--- a/media/module/extractors/amr/AMRExtractor.cpp
+++ b/media/module/extractors/amr/AMRExtractor.cpp
@@ -341,9 +341,9 @@
         return AMEDIA_ERROR_MALFORMED;
     }
 
-    MediaBufferHelper *buffer;
+    MediaBufferHelper *buffer = nullptr;
     status_t err = mBufferGroup->acquire_buffer(&buffer);
-    if (err != OK) {
+    if (err != OK || buffer == nullptr) {
         return AMEDIA_ERROR_UNKNOWN;
     }
 
diff --git a/media/module/extractors/flac/FLACExtractor.cpp b/media/module/extractors/flac/FLACExtractor.cpp
index ec7cb24..2434e41 100644
--- a/media/module/extractors/flac/FLACExtractor.cpp
+++ b/media/module/extractors/flac/FLACExtractor.cpp
@@ -614,9 +614,9 @@
     }
     // acquire a media buffer
     CHECK(mGroup != NULL);
-    MediaBufferHelper *buffer;
+    MediaBufferHelper *buffer = nullptr;
     status_t err = mGroup->acquire_buffer(&buffer);
-    if (err != OK) {
+    if (err != OK || buffer == nullptr) {
         return NULL;
     }
     const size_t bufferSize = blocksize * getChannels() * getOutputSampleSize();
diff --git a/media/module/extractors/midi/MidiExtractor.cpp b/media/module/extractors/midi/MidiExtractor.cpp
index d0efb2f..167cc40 100644
--- a/media/module/extractors/midi/MidiExtractor.cpp
+++ b/media/module/extractors/midi/MidiExtractor.cpp
@@ -240,9 +240,9 @@
     if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) {
         return NULL;
     }
-    MediaBufferHelper *buffer;
+    MediaBufferHelper *buffer = nullptr;
     status_t err = mGroup->acquire_buffer(&buffer);
-    if (err != OK) {
+    if (err != OK || buffer == nullptr) {
         ALOGE("readBuffer: no buffer");
         return NULL;
     }
diff --git a/media/module/extractors/mkv/MatroskaExtractor.cpp b/media/module/extractors/mkv/MatroskaExtractor.cpp
index 443e26c..2b72387 100644
--- a/media/module/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/module/extractors/mkv/MatroskaExtractor.cpp
@@ -790,6 +790,7 @@
     int64_t timeUs = mBlockIter.blockTimeUs();
 
     for (int i = 0; i < block->GetFrameCount(); ++i) {
+        status_t err;
         MatroskaExtractor::TrackInfo *trackInfo = &mExtractor->mTracks.editItemAt(mTrackIndex);
         const mkvparser::Block::Frame &frame = block->GetFrame(i);
         size_t len = frame.len;
@@ -798,8 +799,13 @@
         }
 
         len += trackInfo->mHeaderLen;
-        MediaBufferHelper *mbuf;
-        mBufferGroup->acquire_buffer(&mbuf, false /* nonblocking */, len /* requested size */);
+        MediaBufferHelper *mbuf = nullptr;
+        err = mBufferGroup->acquire_buffer(&mbuf, false /* nonblocking */,
+                                           len /* requested size */);
+        if (err != OK || mbuf == nullptr) {
+            ALOGE("readBlock: no buffer");
+            return AMEDIA_ERROR_UNKNOWN;
+        }
         mbuf->set_range(0, len);
         uint8_t *data = static_cast<uint8_t *>(mbuf->data());
         if (trackInfo->mHeader) {
@@ -832,7 +838,7 @@
             }
         }
 
-        status_t err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen);
+        err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen);
         if (err == OK
                 && mExtractor->mIsWebm
                 && trackInfo->mEncrypted) {
diff --git a/media/module/extractors/mp3/MP3Extractor.cpp b/media/module/extractors/mp3/MP3Extractor.cpp
index 248a39c..328b790 100644
--- a/media/module/extractors/mp3/MP3Extractor.cpp
+++ b/media/module/extractors/mp3/MP3Extractor.cpp
@@ -521,9 +521,9 @@
         mSamplesRead = 0;
     }
 
-    MediaBufferHelper *buffer;
+    MediaBufferHelper *buffer = nullptr;
     status_t err = mBufferGroup->acquire_buffer(&buffer);
-    if (err != OK) {
+    if (err != OK || buffer == nullptr) {
         return AMEDIA_ERROR_UNKNOWN;
     }
 
diff --git a/media/module/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
index 3a5a869..1d88785 100644
--- a/media/module/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -6337,7 +6337,7 @@
 
         err = mBufferGroup->acquire_buffer(&mBuffer);
 
-        if (err != OK) {
+        if (err != OK || mBuffer == nullptr) {
             CHECK(mBuffer == NULL);
             return AMEDIA_ERROR_UNKNOWN;
         }
diff --git a/media/module/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/module/extractors/mpeg2/MPEG2PSExtractor.cpp
index afd28ef..44c8937 100644
--- a/media/module/extractors/mpeg2/MPEG2PSExtractor.cpp
+++ b/media/module/extractors/mpeg2/MPEG2PSExtractor.cpp
@@ -699,11 +699,26 @@
         }
     }
 
-    MediaBufferBase *mbuf;
-    mSource->read(&mbuf, (MediaTrack::ReadOptions*) options);
+    MediaBufferBase *mbuf = nullptr;
+    status_t err_read = mSource->read(&mbuf, (MediaTrack::ReadOptions*) options);
+    if (mbuf == nullptr) {
+        ALOGE("Track::read: null buffer read from source");
+        return AMEDIA_ERROR_UNKNOWN;
+    }
+    if (err_read != OK) {
+        ALOGE("Track::read: no buffer read from source");
+        mbuf->release();
+        return AMEDIA_ERROR_UNKNOWN;
+    }
+
     size_t length = mbuf->range_length();
-    MediaBufferHelper *outbuf;
-    mBufferGroup->acquire_buffer(&outbuf, false, length);
+    MediaBufferHelper *outbuf = nullptr;
+    status_t err = mBufferGroup->acquire_buffer(&outbuf, false, length);
+    if (err != OK || outbuf == nullptr) {
+        ALOGE("Track::read: no buffer");
+        mbuf->release();
+        return AMEDIA_ERROR_UNKNOWN;
+    }
     memcpy(outbuf->data(), mbuf->data(), length);
     outbuf->set_range(0, length);
     *buffer = outbuf;
diff --git a/media/module/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/module/extractors/mpeg2/MPEG2TSExtractor.cpp
index 9a3cd92..736b817 100644
--- a/media/module/extractors/mpeg2/MPEG2TSExtractor.cpp
+++ b/media/module/extractors/mpeg2/MPEG2TSExtractor.cpp
@@ -182,11 +182,26 @@
         return AMEDIA_ERROR_END_OF_STREAM;
     }
 
-    MediaBufferBase *mbuf;
-    mImpl->read(&mbuf, (MediaTrack::ReadOptions*) options);
+    MediaBufferBase *mbuf = nullptr;
+    status_t err_read = mImpl->read(&mbuf, (MediaTrack::ReadOptions*) options);
+    if (mbuf == nullptr) {
+        ALOGE("Track::read: null buffer read from source");
+        return AMEDIA_ERROR_UNKNOWN;
+    }
+    if (err_read != OK) {
+        ALOGE("Track::read: no buffer read from source");
+        mbuf->release();
+        return AMEDIA_ERROR_UNKNOWN;
+    }
+
     size_t length = mbuf->range_length();
-    MediaBufferHelper *outbuf;
-    mBufferGroup->acquire_buffer(&outbuf, false, length);
+    MediaBufferHelper *outbuf = nullptr;
+    status_t err = mBufferGroup->acquire_buffer(&outbuf, false, length);
+    if (err != OK || outbuf == nullptr) {
+        ALOGE("read: no buffer");
+        mbuf->release();
+        return AMEDIA_ERROR_UNKNOWN;
+    }
     memcpy(outbuf->data(), mbuf->data(), length);
     outbuf->set_range(0, length);
     *out = outbuf;
diff --git a/media/module/extractors/ogg/OggExtractor.cpp b/media/module/extractors/ogg/OggExtractor.cpp
index eb2246d..1c6f516 100644
--- a/media/module/extractors/ogg/OggExtractor.cpp
+++ b/media/module/extractors/ogg/OggExtractor.cpp
@@ -790,7 +790,8 @@
             }
             MediaBufferHelper *tmp;
             if (mBufferGroup) {
-                mBufferGroup->acquire_buffer(&tmp, false, fullSize);
+                // ignore return code here. instead, check tmp below.
+                (void) mBufferGroup->acquire_buffer(&tmp, false, fullSize);
                 ALOGV("acquired buffer %p from group", tmp);
             } else {
                 tmp = new StandAloneMediaBuffer(fullSize);
@@ -924,13 +925,16 @@
 status_t MyOggExtractor::init() {
     AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME, mMimeType);
 
-    media_status_t err;
-    MediaBufferHelper *packet;
     for (size_t i = 0; i < mNumHeaders; ++i) {
+        media_status_t err;
+        MediaBufferHelper *packet = nullptr;
         // ignore timestamp for configuration packets
         if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != AMEDIA_OK) {
             return err;
         }
+        if (packet == nullptr) {
+            return AMEDIA_ERROR_UNKNOWN;
+        }
         ALOGV("read packet of size %zu\n", packet->range_length());
         err = verifyHeader(packet, /* type = */ i * 2 + 1);
         packet->release();
diff --git a/media/module/extractors/wav/WAVExtractor.cpp b/media/module/extractors/wav/WAVExtractor.cpp
index 9e94587..9c3bac6 100644
--- a/media/module/extractors/wav/WAVExtractor.cpp
+++ b/media/module/extractors/wav/WAVExtractor.cpp
@@ -459,11 +459,15 @@
         mCurrentPos = pos + mOffset;
     }
 
-    MediaBufferHelper *buffer;
+    MediaBufferHelper *buffer = nullptr;
     media_status_t err = mBufferGroup->acquire_buffer(&buffer);
     if (err != OK) {
         return err;
     }
+    if (buffer == nullptr) {
+        ALOGE("acquire_buffer OK, but no buffer");
+        return AMEDIA_ERROR_UNKNOWN;
+    }
 
     // maxBytesToRead may be reduced so that in-place data conversion will fit in buffer size.
     const size_t bufferSize = std::min(buffer->size(), kMaxFrameSize);
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index f4674de..5005365 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -253,7 +253,7 @@
 }
 
 static sp<IDrm> CreateDrm() {
-    return DrmUtils::MakeDrm();
+    return DrmUtils::MakeDrm(IDRM_NDK);
 }
 
 
diff --git a/media/ndk/include/media/NdkMediaDrm.h b/media/ndk/include/media/NdkMediaDrm.h
index 4eca3d7..8044140 100644
--- a/media/ndk/include/media/NdkMediaDrm.h
+++ b/media/ndk/include/media/NdkMediaDrm.h
@@ -261,8 +261,8 @@
 /**
  * Open a new session with the MediaDrm object.  A session ID is returned.
  *
- * Returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed.
- * Returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use.
+ * Returns AMEDIA_DRM_NOT_PROVISIONED if provisioning is needed.
+ * Returns AMEDIA_DRM_RESOURCE_BUSY if required resources are in use.
  *
  * Available since API level 21.
  */
@@ -327,7 +327,7 @@
  *   2. keyRequestSize will be set to the size of the request
  *   If this does not return AMEDIA_OK, value of these parameters should not be used.
  *
- * Returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
+ * Returns AMEDIA_DRM_NOT_PROVISIONED if reprovisioning is needed, due to a
  * problem with the device certificate.
  *
  * Available since API level 21.
@@ -390,7 +390,7 @@
  *   4. keyRequestType will be set to the key request type. Passing in NULL means
 *       you don't need it to be reported.
  *
- * Returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
+ * Returns AMEDIA_DRM_NOT_PROVISIONED if reprovisioning is needed, due to a
  * problem with the device certificate.
  *
  * Available since API level 33.
@@ -457,7 +457,7 @@
  * On entry, numPairs should be set by the caller to the maximum number of pairs
  * that can be returned (the size of the array).  On exit, numPairs will be set
  * to the number of entries written to the array.  If the number of {key, value} pairs
- * to be returned is greater than *numPairs, MEDIADRM_SHORT_BUFFER will be returned
+ * to be returned is greater than *numPairs, AMEDIA_DRM_SHORT_BUFFER will be returned
  * and numPairs will be set to the number of pairs available.
  *
  * Available since API level 21.
@@ -495,7 +495,7 @@
  *   DRM engine plugin.
  * responseSize is the length of the provisioning response in bytes.
  *
- * Returns MEDIADRM_DEVICE_REVOKED_ERROR if the response indicates that the
+ * Returns AMEDIA_DRM_DEVICE_REVOKED if the response indicates that the
  * server rejected the request
  *
  * Available since API level 21.
@@ -522,7 +522,7 @@
  * numSecureStops is set by the caller to the maximum number of secure stops to
  * return.  On exit, *numSecureStops will be set to the number actually returned.
  * If *numSecureStops is too small for the number of secure stops available,
- * MEDIADRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
+ * AMEDIA_DRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
  * number required.
  *
  * Available since API level 21.
@@ -657,7 +657,7 @@
  * Generate a signature using the specified macAlgorithm over the message data
  * referenced by message of size messageSize and store the signature in the
  * buffer referenced signature of max size *signatureSize.  If the buffer is not
- * large enough to hold the signature, MEDIADRM_SHORT_BUFFER is returned and
+ * large enough to hold the signature, AMEDIA_DRM_SHORT_BUFFER is returned and
  * *signatureSize is set to the buffer size required.  The key to use is identified
  * by the 16 byte keyId.  The key must have been loaded into the session using
  * provideKeyResponse.
@@ -670,7 +670,7 @@
 
 /*
  * Perform a signature verification using the specified macAlgorithm over the message
- * data referenced by the message parameter of size messageSize. Returns MEDIADRM_OK
+ * data referenced by the message parameter of size messageSize. Returns AMEDIA_OK
  * if the signature matches, otherwise MEDAIDRM_VERIFY_FAILED is returned. The key to
  * use is identified by the 16 byte keyId.  The key must have been loaded into the
  * session using provideKeyResponse.
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index 6823f4f..65b2c52 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -283,7 +283,7 @@
 }
 
 // Automatically create a TimeCheck class for a class and method.
-// This is used for Audio HIDL support.
+// This is used for Audio HAL support.
 mediautils::TimeCheck makeTimeCheckStatsForClassMethod(
         std::string_view className, std::string_view methodName) {
     std::shared_ptr<MethodStatistics<std::string>> statistics =
diff --git a/media/utils/include/mediautils/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
index bdb5337..0823669 100644
--- a/media/utils/include/mediautils/TimeCheck.h
+++ b/media/utils/include/mediautils/TimeCheck.h
@@ -148,4 +148,9 @@
 TimeCheck makeTimeCheckStatsForClassMethod(
         std::string_view className, std::string_view methodName);
 
+// A handy statement-like macro to put at the beginning of almost every method
+// which calls into HAL. Note that it requires the class to implement 'getClassName'.
+#define TIME_CHECK() auto timeCheck = \
+            mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
+
 }  // namespace android::mediautils
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 3518037..8c8278c 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -104,7 +104,7 @@
                                                       const char* device_address,
                                                       const char* device_name,
                                                       audio_format_t encodedFormat) {
-    media::AudioPort aidlPort;
+    media::AudioPortFw aidlPort;
     if (status_t status = deviceToAudioPort(device, device_address, device_name, &aidlPort);
         status == OK) {
         return setDeviceConnectionState(state, aidlPort.hal, encodedFormat);
@@ -162,7 +162,7 @@
                                                          const char* device_address,
                                                          const char* device_name,
                                                          audio_format_t encodedFormat) {
-    media::AudioPort aidlPort;
+    media::AudioPortFw aidlPort;
     if (status_t status = deviceToAudioPort(deviceType, device_address, device_name, &aidlPort);
         status == OK) {
         return setDeviceConnectionStateInt(state, aidlPort.hal, encodedFormat);
@@ -444,7 +444,7 @@
 
 status_t AudioPolicyManager::deviceToAudioPort(audio_devices_t device, const char* device_address,
                                                const char* device_name,
-                                               media::AudioPort* aidlPort) {
+                                               media::AudioPortFw* aidlPort) {
     DeviceDescriptorBase devDescr(device, device_address);
     devDescr.setName(device_name);
     return devDescr.writeToParcelable(aidlPort);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 87e6974..2159257 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -1010,7 +1010,7 @@
 
         // Called by setDeviceConnectionState()
         status_t deviceToAudioPort(audio_devices_t deviceType, const char* device_address,
-                                   const char* device_name, media::AudioPort* aidPort);
+                                   const char* device_name, media::AudioPortFw* aidPort);
         bool isMsdPatch(const audio_patch_handle_t &handle) const;
 
 private:
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index df49bba..4212c1c 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1521,7 +1521,7 @@
 
 Status AudioPolicyService::listAudioPorts(media::AudioPortRole roleAidl,
                                           media::AudioPortType typeAidl, Int* count,
-                                          std::vector<media::AudioPort>* portsAidl,
+                                          std::vector<media::AudioPortFw>* portsAidl,
                                           int32_t* _aidl_return) {
     audio_port_role_t role = VALUE_OR_RETURN_BINDER_STATUS(
             aidl2legacy_AudioPortRole_audio_port_role_t(roleAidl));
@@ -1546,14 +1546,14 @@
     numPortsReq = std::min(numPortsReq, num_ports);
     RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
             convertRange(ports.get(), ports.get() + numPortsReq, std::back_inserter(*portsAidl),
-                         legacy2aidl_audio_port_v7_AudioPort)));
+                         legacy2aidl_audio_port_v7_AudioPortFw)));
     count->value = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(num_ports));
     *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(generation));
     return Status::ok();
 }
 
 Status AudioPolicyService::getAudioPort(int portId,
-                                        media::AudioPort* _aidl_return) {
+                                        media::AudioPortFw* _aidl_return) {
     audio_port_v7 port{ .id = portId };
     Mutex::Autolock _l(mLock);
     if (mAudioPolicyManager == NULL) {
@@ -1561,14 +1561,15 @@
     }
     AutoCallerClear acc;
     RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(mAudioPolicyManager->getAudioPort(&port)));
-    *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_port_v7_AudioPort(port));
+    *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_port_v7_AudioPortFw(port));
     return Status::ok();
 }
 
-Status AudioPolicyService::createAudioPatch(const media::AudioPatch& patchAidl, int32_t handleAidl,
+Status AudioPolicyService::createAudioPatch(const media::AudioPatchFw& patchAidl,
+                                            int32_t handleAidl,
                                             int32_t* _aidl_return) {
     audio_patch patch = VALUE_OR_RETURN_BINDER_STATUS(
-            aidl2legacy_AudioPatch_audio_patch(patchAidl));
+            aidl2legacy_AudioPatchFw_audio_patch(patchAidl));
     audio_patch_handle_t handle = VALUE_OR_RETURN_BINDER_STATUS(
             aidl2legacy_int32_t_audio_port_handle_t(handleAidl));
     RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(AudioValidator::validateAudioPatch(patch)));
@@ -1606,7 +1607,7 @@
 }
 
 Status AudioPolicyService::listAudioPatches(Int* count,
-                                            std::vector<media::AudioPatch>* patchesAidl,
+                                            std::vector<media::AudioPatchFw>* patchesAidl,
                                             int32_t* _aidl_return) {
     unsigned int num_patches = VALUE_OR_RETURN_BINDER_STATUS(
             convertIntegral<unsigned int>(count->value));
@@ -1627,16 +1628,16 @@
     numPatchesReq = std::min(numPatchesReq, num_patches);
     RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
             convertRange(patches.get(), patches.get() + numPatchesReq,
-                         std::back_inserter(*patchesAidl), legacy2aidl_audio_patch_AudioPatch)));
+                         std::back_inserter(*patchesAidl), legacy2aidl_audio_patch_AudioPatchFw)));
     count->value = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(num_patches));
     *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(generation));
     return Status::ok();
 }
 
-Status AudioPolicyService::setAudioPortConfig(const media::AudioPortConfig& configAidl)
+Status AudioPolicyService::setAudioPortConfig(const media::AudioPortConfigFw& configAidl)
 {
     audio_port_config config = VALUE_OR_RETURN_BINDER_STATUS(
-            aidl2legacy_AudioPortConfig_audio_port_config(configAidl));
+            aidl2legacy_AudioPortConfigFw_audio_port_config(configAidl));
     RETURN_IF_BINDER_ERROR(
             binderStatusFromStatusT(AudioValidator::validateAudioPortConfig(config)));
 
@@ -1806,11 +1807,11 @@
     return binderStatusFromStatusT(mAudioPolicyManager->removeUserIdDeviceAffinities(userId));
 }
 
-Status AudioPolicyService::startAudioSource(const media::AudioPortConfig& sourceAidl,
+Status AudioPolicyService::startAudioSource(const media::AudioPortConfigFw& sourceAidl,
                                             const media::AudioAttributesInternal& attributesAidl,
                                             int32_t* _aidl_return) {
     audio_port_config source = VALUE_OR_RETURN_BINDER_STATUS(
-            aidl2legacy_AudioPortConfig_audio_port_config(sourceAidl));
+            aidl2legacy_AudioPortConfigFw_audio_port_config(sourceAidl));
     audio_attributes_t attributes = VALUE_OR_RETURN_BINDER_STATUS(
             aidl2legacy_AudioAttributesInternal_audio_attributes_t(attributesAidl));
     audio_port_handle_t portId;
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 5c37f99..860bd18 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -172,16 +172,16 @@
                                            const media::AudioAttributesInternal& attributes,
                                            bool* _aidl_return) override;
     binder::Status listAudioPorts(media::AudioPortRole role, media::AudioPortType type,
-                                  Int* count, std::vector<media::AudioPort>* ports,
+                                  Int* count, std::vector<media::AudioPortFw>* ports,
                                   int32_t* _aidl_return) override;
     binder::Status getAudioPort(int portId,
-                                media::AudioPort* _aidl_return) override;
-    binder::Status createAudioPatch(const media::AudioPatch& patch, int32_t handle,
+                                media::AudioPortFw* _aidl_return) override;
+    binder::Status createAudioPatch(const media::AudioPatchFw& patch, int32_t handle,
                                     int32_t* _aidl_return) override;
     binder::Status releaseAudioPatch(int32_t handle) override;
-    binder::Status listAudioPatches(Int* count, std::vector<media::AudioPatch>* patches,
+    binder::Status listAudioPatches(Int* count, std::vector<media::AudioPatchFw>* patches,
                                     int32_t* _aidl_return) override;
-    binder::Status setAudioPortConfig(const media::AudioPortConfig& config) override;
+    binder::Status setAudioPortConfig(const media::AudioPortConfigFw& config) override;
     binder::Status registerClient(const sp<media::IAudioPolicyServiceClient>& client) override;
     binder::Status setAudioPortCallbacksEnabled(bool enabled) override;
     binder::Status setAudioVolumeGroupCallbacksEnabled(bool enabled) override;
@@ -197,7 +197,7 @@
             int32_t userId,
             const std::vector<AudioDevice>& devices) override;
     binder::Status removeUserIdDeviceAffinities(int32_t userId) override;
-    binder::Status startAudioSource(const media::AudioPortConfig& source,
+    binder::Status startAudioSource(const media::AudioPortConfigFw& source,
                                     const media::AudioAttributesInternal& attributes,
                                     int32_t* _aidl_return) override;
     binder::Status stopAudioSource(int32_t portId) override;
diff --git a/services/audiopolicy/tests/audio_health_tests.cpp b/services/audiopolicy/tests/audio_health_tests.cpp
index 10f8dc0..798332c 100644
--- a/services/audiopolicy/tests/audio_health_tests.cpp
+++ b/services/audiopolicy/tests/audio_health_tests.cpp
@@ -111,7 +111,7 @@
             continue;
         }
         std::string address = "11:22:33:44:55:66";
-        media::AudioPort aidlPort;
+        media::AudioPortFw aidlPort;
         ASSERT_EQ(OK, manager.deviceToAudioPort(device->type(), address.c_str(), "" /*name*/,
                                                  &aidlPort));
         ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index c341b32..1c40cfd 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -1790,7 +1790,7 @@
     }
     const std::string name = std::get<1>(GetParam());
     const std::string address = std::get<2>(GetParam());
-    android::media::AudioPort audioPort;
+    android::media::AudioPortFw audioPort;
     ASSERT_EQ(NO_ERROR,
             mManager->deviceToAudioPort(type, address.c_str(), name.c_str(), &audioPort));
     android::media::audio::common::AudioPort& port = audioPort.hal;
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 71965f2..7a93cc7 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -1599,7 +1599,7 @@
     return OK;
 }
 
-void HeicCompositeStream::initCopyRowFunction(int32_t width)
+void HeicCompositeStream::initCopyRowFunction([[maybe_unused]] int32_t width)
 {
     using namespace libyuv;
 
diff --git a/services/mediacodec/Android.bp b/services/mediacodec/Android.bp
index 3222950..a2f17c2 100644
--- a/services/mediacodec/Android.bp
+++ b/services/mediacodec/Android.bp
@@ -147,6 +147,9 @@
         arm64: {
             src: "seccomp_policy/mediacodec-arm64.policy",
         },
+        riscv64: {
+            enabled: false,
+        },
         x86: {
             src: "seccomp_policy/mediacodec-x86.policy",
         },
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index ceb3e6a..18c0b50 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -511,6 +511,8 @@
     const std::string &key = item->getKey();
     if (startsWith(key, "audio.")) return true;
     if (startsWith(key, "drm.vendor.")) return true;
+    if (startsWith(key, "mediadrm.")) return true;
+
     // the list of allowedKey uses statsd_handlers
     // in iface_statsd.cpp as reference
     // drmmanager is from a trusted uid, therefore not needed here