Merge "Support connecting multiple devices to APM."
diff --git a/apex/Android.bp b/apex/Android.bp
index b314e5d..bf91bf7 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -32,15 +32,21 @@
                 "liboggextractor",
                 "libwavextractor",
             ],
+            // Transcoding service only run with primary ABI.
+            binaries: [
+                "mediatranscoding",
+            ],
         },
     },
     // JNI
     native_shared_libs: ["libmediaparser-jni"],
     compile_multilib: "both",
     prebuilts: [
-        "mediaextractor.policy",
         "code_coverage.policy",
+        "com.android.media-mediatranscoding.rc",
         "crash_dump.policy",
+        "mediaextractor.policy",
+        "media-linker-config",
     ],
     key: "com.android.media.key",
     certificate: ":com.android.media.certificate",
@@ -62,9 +68,6 @@
     name: "com.android.media",
     manifest: "manifest.json",
     defaults: ["com.android.media-defaults"],
-    prebuilts: [
-        "media-linker-config",
-    ],
 }
 
 linker_config {
@@ -117,6 +120,13 @@
 }
 
 prebuilt_etc {
+    name: "com.android.media-mediatranscoding.rc",
+    src: "mediatranscoding.rc",
+    filename: "init.rc",
+    installable: false,
+}
+
+prebuilt_etc {
     name: "com.android.media.swcodec-mediaswcodec.rc",
     src: "mediaswcodec.rc",
     filename: "init.rc",
diff --git a/apex/manifest.json b/apex/manifest.json
index f1f69f4..b7d8fc8 100644
--- a/apex/manifest.json
+++ b/apex/manifest.json
@@ -1,4 +1,10 @@
 {
   "name": "com.android.media",
-  "version": 309999900
+  "version": 309999900,
+  "requireNativeLibs": [
+    "libandroid.so",
+    "libbinder_ndk.so",
+    "libmediandk.so",
+    ":sphal"
+  ]
 }
diff --git a/apex/mediatranscoding.rc b/apex/mediatranscoding.rc
new file mode 100644
index 0000000..fa4acf8
--- /dev/null
+++ b/apex/mediatranscoding.rc
@@ -0,0 +1,10 @@
+# media.transcoding service is defined on com.android.media apex which goes back
+# to API29, but we only want it started on API31+ devices. So we declare it as
+# "disabled" and start it explicitly on boot.
+service media.transcoding /apex/com.android.media/bin/mediatranscoding
+    class main
+    user media
+    group media
+    ioprio rt 4
+    task_profiles ProcessCapacityHigh HighPerformance
+    disabled
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 08c88ce..dd652c7 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -1367,31 +1367,11 @@
                 it->second.isSequenceCompleted = true;
             }
 
-            if (it->second.isSequenceCompleted && hasCallback) {
-                auto cbIt = mSequenceCallbackMap.find(sequenceId);
-                CallbackHolder cbh = cbIt->second;
-
-                // send seq complete callback
-                sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
-                msg->setPointer(kContextKey, cbh.mContext);
-                msg->setObject(kSessionSpKey, cbh.mSession);
-                msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
-                msg->setInt32(kSequenceIdKey, sequenceId);
-                msg->setInt64(kFrameNumberKey, lastFrameNumber);
-
-                // Clear the session sp before we send out the message
-                // This will guarantee the rare case where the message is processed
-                // before cbh goes out of scope and causing we call the session
-                // destructor while holding device lock
-                cbh.mSession.clear();
-                postSessionMsgAndCleanup(msg);
-            }
         }
 
         if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
-            if (mSequenceCallbackMap.find(sequenceId) != mSequenceCallbackMap.end()) {
-                mSequenceCallbackMap.erase(sequenceId);
-            }
+            sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
+
             it = mSequenceLastFrameNumberMap.erase(it);
             ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
         } else {
@@ -1418,13 +1398,7 @@
                 lastCompletedRegularFrameNumber);
         if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
             if (it->second.isSequenceCompleted) {
-                // Check if there is callback for this sequence
-                // This should not happen because we always register callback (with nullptr inside)
-                if (mSequenceCallbackMap.count(sequenceId) == 0) {
-                    ALOGW("No callback found for sequenceId %d", sequenceId);
-                } else {
-                    mSequenceCallbackMap.erase(sequenceId);
-                }
+                sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
 
                 it = mSequenceLastFrameNumberMap.erase(it);
                 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
@@ -1715,5 +1689,33 @@
     return ret;
 }
 
+void
+CameraDevice::sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber) {
+    auto cbIt = mSequenceCallbackMap.find(sequenceId);
+    if (cbIt != mSequenceCallbackMap.end()) {
+        CallbackHolder cbh = cbIt->second;
+        mSequenceCallbackMap.erase(cbIt);
+
+        // send seq complete callback
+        sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
+        msg->setPointer(kContextKey, cbh.mContext);
+        msg->setObject(kSessionSpKey, cbh.mSession);
+        msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
+        msg->setInt32(kSequenceIdKey, sequenceId);
+        msg->setInt64(kFrameNumberKey, lastFrameNumber);
+
+        // Clear the session sp before we send out the message
+        // This will guarantee the rare case where the message is processed
+        // before cbh goes out of scope and causing we call the session
+        // destructor while holding device lock
+        cbh.mSession.clear();
+        postSessionMsgAndCleanup(msg);
+    } else {
+        // Check if there is callback for this sequence
+        // This should not happen because we always register callback (with nullptr inside)
+        ALOGW("No callback found for sequenceId %d", sequenceId);
+    }
+}
+
 } // namespace acam
 } // namespace android
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 125e6e3..344d964 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -354,6 +354,7 @@
     void checkRepeatingSequenceCompleteLocked(const int sequenceId, const int64_t lastFrameNumber);
     void checkAndFireSequenceCompleteLocked();
     void removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber);
+    void sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber);
 
     // Misc variables
     int32_t mShadingMapSize[2];   // const after constructor
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 6b912f1..c7c3dd5 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -816,7 +816,7 @@
      * </ul></p>
      *
      * <p>This control is only effective if ACAMERA_CONTROL_MODE is AUTO.</p>
-     * <p>When set to the ON mode, the camera device's auto-white balance
+     * <p>When set to the AUTO mode, the camera device's auto-white balance
      * routine is enabled, overriding the application's selected
      * ACAMERA_COLOR_CORRECTION_TRANSFORM, ACAMERA_COLOR_CORRECTION_GAINS and
      * ACAMERA_COLOR_CORRECTION_MODE. Note that when ACAMERA_CONTROL_AE_MODE
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 1700a95..55a32ae 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -11,7 +11,7 @@
 
 }
 
-cc_library_shared {
+cc_library {
     name: "libmediadrm",
 
     srcs: [
diff --git a/drm/libmediadrm/fuzzer/Android.bp b/drm/libmediadrm/fuzzer/Android.bp
new file mode 100644
index 0000000..6f2d054
--- /dev/null
+++ b/drm/libmediadrm/fuzzer/Android.bp
@@ -0,0 +1,59 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+    name: "mediadrm_fuzzer",
+    srcs: [
+        "mediadrm_fuzzer.cpp",
+    ],
+    static_libs: [
+        "libmediadrm",
+        "liblog",
+        "resourcemanager_aidl_interface-ndk_platform",
+    ],
+    header_libs: [
+        "libmedia_headers",
+        "libmediadrm_headers",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libutils",
+        "libbinder_ndk",
+        "libcutils",
+        "libdl",
+        "libmedia",
+        "libmediadrmmetrics_lite",
+        "libmediametrics#1",
+        "libmediautils",
+        "libstagefright_foundation",
+        "android.hardware.drm@1.0",
+        "android.hardware.drm@1.1",
+        "android.hardware.drm@1.2",
+        "android.hardware.drm@1.3",
+        "libhidlallocatorutils",
+        "libhidlbase",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
diff --git a/drm/libmediadrm/fuzzer/README.md b/drm/libmediadrm/fuzzer/README.md
new file mode 100644
index 0000000..3c95cd7
--- /dev/null
+++ b/drm/libmediadrm/fuzzer/README.md
@@ -0,0 +1,56 @@
+# Fuzzer for libmediadrm
+
+## Plugin Design Considerations
+The fuzzer plugin for libmediadrm is designed based on the understanding of the
+library and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+libmediadrm supports the following parameters:
+1. Security Level (parameter name: `securityLevel`)
+2. Mime Type (parameter name: `mimeType`)
+3. Key Type (parameter name: `keyType`)
+4. Crypto Mode (parameter name: `cryptoMode`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `securityLevel` | 0.`DrmPlugin::kSecurityLevelUnknown` 1.`DrmPlugin::kSecurityLevelMax` 2.`DrmPlugin::kSecurityLevelSwSecureCrypto` 3.`DrmPlugin::kSecurityLevelSwSecureDecode`  4.`DrmPlugin::kSecurityLevelHwSecureCrypto` 5.`DrmPlugin::kSecurityLevelHwSecureDecode` 6.`DrmPlugin::kSecurityLevelHwSecureAll`| Value obtained from FuzzedDataProvider in the range 0 to 6|
+| `mimeType` | 0.`video/mp4` 1.`video/mpeg` 2.`video/x-flv` 3.`video/mj2` 4.`video/3gp2` 5.`video/3gpp` 6.`video/3gpp2` 7.`audio/mp4` 8.`audio/mpeg` 9.`audio/aac` 10.`audio/3gp2` 11.`audio/3gpp` 12.`audio/3gpp2` 13.`video/unknown`| Value obtained from FuzzedDataProvider in the range 0 to 13|
+| `keyType` | 0.`DrmPlugin::kKeyType_Offline` 1.`DrmPlugin::kKeyType_Streaming` 2.`DrmPlugin::kKeyType_Release` | Value obtained from FuzzedDataProvider in the range 0 to 2|
+| `cryptoMode` | 0.`CryptoPlugin::kMode_Unencrypted` 1.`CryptoPlugin::kMode_AES_CTR` 2.`CryptoPlugin::kMode_AES_WV` 3.`CryptoPlugin::kMode_AES_CBC` | Value obtained from FuzzedDataProvider in the range 0 to 3|
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the drm module.
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build mediadrm_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mediadrm_fuzzer
+```
+#### Steps to run
+Create a directory CORPUS_DIR
+```
+  $ adb shell mkdir CORPUS_DIR
+```
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/${TARGET_ARCH}/mediadrm_fuzzer/mediadrm_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/drm/libmediadrm/fuzzer/mediadrm_fuzzer.cpp b/drm/libmediadrm/fuzzer/mediadrm_fuzzer.cpp
new file mode 100644
index 0000000..8df0477
--- /dev/null
+++ b/drm/libmediadrm/fuzzer/mediadrm_fuzzer.cpp
@@ -0,0 +1,458 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <binder/MemoryDealer.h>
+#include <hidlmemory/FrameworkUtils.h>
+#include <mediadrm/CryptoHal.h>
+#include <mediadrm/DrmHal.h>
+#include <utils/String8.h>
+#include "fuzzer/FuzzedDataProvider.h"
+
+#define AES_BLOCK_SIZE 16
+#define UNUSED_PARAM __attribute__((unused))
+
+using namespace std;
+using namespace android;
+using android::hardware::fromHeap;
+using ::android::os::PersistableBundle;
+using drm::V1_0::BufferType;
+
+enum {
+    INVALID_UUID = 0,
+    PSSH_BOX_UUID,
+    CLEARKEY_UUID,
+};
+
+static const uint8_t kInvalidUUID[16] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
+                                         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80};
+
+static const uint8_t kCommonPsshBoxUUID[16] = {0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,
+                                               0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B};
+
+static const uint8_t kClearKeyUUID[16] = {0xE2, 0x71, 0x9D, 0x58, 0xA9, 0x85, 0xB3, 0xC9,
+                                          0x78, 0x1A, 0xB0, 0x30, 0xAF, 0x78, 0xD3, 0x0E};
+
+static const uint32_t kUUID[] = {INVALID_UUID, PSSH_BOX_UUID, CLEARKEY_UUID};
+
+const DrmPlugin::SecurityLevel kSecurityLevel[] = {
+    DrmPlugin::kSecurityLevelUnknown,        DrmPlugin::kSecurityLevelMax,
+    DrmPlugin::kSecurityLevelSwSecureCrypto, DrmPlugin::kSecurityLevelSwSecureDecode,
+    DrmPlugin::kSecurityLevelHwSecureCrypto, DrmPlugin::kSecurityLevelHwSecureDecode,
+    DrmPlugin::kSecurityLevelHwSecureAll};
+
+const char *kMimeType[] = {"video/mp4",   "video/mpeg",    "video/x-flv",  "video/mj2",
+                           "video/3gp2",  "video/3gpp",    "video/3gpp2",  "audio/mp4",
+                           "audio/mpeg",  "audio/aac",     "audio/3gp2",   "audio/3gpp",
+                           "audio/3gpp2", "video/unknown", "audio/unknown"};
+
+const DrmPlugin::KeyType kKeyType[] = {DrmPlugin::kKeyType_Offline, DrmPlugin::kKeyType_Streaming,
+                                       DrmPlugin::kKeyType_Release};
+
+const CryptoPlugin::Mode kCryptoMode[] = {CryptoPlugin::kMode_Unencrypted,
+                                          CryptoPlugin::kMode_AES_CTR, CryptoPlugin::kMode_AES_WV,
+                                          CryptoPlugin::kMode_AES_CBC};
+
+const char *kCipherAlgorithm[] = {"AES/CBC/NoPadding", ""};
+const char *kMacAlgorithm[] = {"HmacSHA256", ""};
+const char *kRSAAlgorithm[] = {"RSASSA-PSS-SHA1", ""};
+const size_t kNumSecurityLevel = size(kSecurityLevel);
+const size_t kNumMimeType = size(kMimeType);
+const size_t kNumKeyType = size(kKeyType);
+const size_t kNumCryptoMode = size(kCryptoMode);
+const size_t kNumUUID = size(kUUID);
+const size_t kMaxStringLength = 100;
+const size_t kMaxSubSamples = 10;
+const size_t kMaxNumBytes = 1000;
+
+struct DrmListener : virtual public IDrmClient {
+   public:
+    void sendEvent(DrmPlugin::EventType eventType UNUSED_PARAM,
+                   const hardware::hidl_vec<uint8_t> &sessionId UNUSED_PARAM,
+                   const hardware::hidl_vec<uint8_t> &data UNUSED_PARAM) override {}
+
+    void sendExpirationUpdate(const hardware::hidl_vec<uint8_t> &sessionId UNUSED_PARAM,
+                              int64_t expiryTimeInMS UNUSED_PARAM) override {}
+
+    void sendKeysChange(const hardware::hidl_vec<uint8_t> &sessionId UNUSED_PARAM,
+                        const std::vector<DrmKeyStatus> &keyStatusList UNUSED_PARAM,
+                        bool hasNewUsableKey UNUSED_PARAM) override {}
+
+    void sendSessionLostState(const hardware::hidl_vec<uint8_t> &) override {}
+    DrmListener() {}
+
+   private:
+    DISALLOW_EVIL_CONSTRUCTORS(DrmListener);
+};
+
+class DrmFuzzer {
+   public:
+    void process(const uint8_t *data, size_t size);
+
+   private:
+    void invokeDrm(const uint8_t *data, size_t size);
+    bool initDrm();
+    void invokeDrmCreatePlugin();
+    void invokeDrmOpenSession();
+    void invokeDrmSetListener();
+    void invokeDrmSetAlgorithmAPI();
+    void invokeDrmPropertyAPI();
+    void invokeDrmDecryptEncryptAPI(const uint8_t *data, size_t size);
+    void invokeDrmSecureStopAPI();
+    void invokeDrmOfflineLicenseAPI();
+    void invokeDrmCloseSession();
+    void invokeDrmDestroyPlugin();
+    void invokeCrypto(const uint8_t *data);
+    bool initCrypto();
+    void invokeCryptoCreatePlugin();
+    void invokeCryptoDecrypt(const uint8_t *data);
+    void invokeCryptoDestroyPlugin();
+    sp<DrmHal> mDrm = nullptr;
+    sp<CryptoHal> mCrypto = nullptr;
+    Vector<uint8_t> mSessionId = {};
+    FuzzedDataProvider *mFuzzedDataProvider = nullptr;
+};
+
+bool DrmFuzzer::initDrm() {
+    mDrm = new DrmHal();
+    if (!mDrm) {
+        return false;
+    }
+    return true;
+}
+
+void DrmFuzzer::invokeDrmCreatePlugin() {
+    mDrm->initCheck();
+    String8 packageName(mFuzzedDataProvider->ConsumeRandomLengthString(kMaxStringLength).c_str());
+    uint32_t uuidEnum = kUUID[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumUUID - 1)];
+    switch (uuidEnum) {
+        case INVALID_UUID:
+            mDrm->createPlugin(kInvalidUUID, packageName);
+            break;
+        case PSSH_BOX_UUID:
+            mDrm->createPlugin(kCommonPsshBoxUUID, packageName);
+            break;
+        case CLEARKEY_UUID:
+            mDrm->createPlugin(kClearKeyUUID, packageName);
+            break;
+        default:
+            break;
+    }
+}
+
+void DrmFuzzer::invokeDrmDestroyPlugin() { mDrm->destroyPlugin(); }
+
+void DrmFuzzer::invokeDrmOpenSession() {
+    DrmPlugin::SecurityLevel securityLevel;
+    bool shouldPassRandomSecurityLevel = mFuzzedDataProvider->ConsumeBool();
+    if (shouldPassRandomSecurityLevel) {
+        securityLevel =
+            static_cast<DrmPlugin::SecurityLevel>(mFuzzedDataProvider->ConsumeIntegral<size_t>());
+    } else {
+        securityLevel = kSecurityLevel[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
+            0, kNumSecurityLevel - 1)];
+    }
+    mDrm->openSession(securityLevel, mSessionId);
+}
+
+void DrmFuzzer::invokeDrmCloseSession() { mDrm->closeSession(mSessionId); }
+
+void DrmFuzzer::invokeDrmSetListener() {
+    sp<DrmListener> listener = new DrmListener();
+    mDrm->setListener(listener);
+}
+
+void DrmFuzzer::invokeDrmSetAlgorithmAPI() {
+    mDrm->setCipherAlgorithm(mSessionId,
+                             String8(kCipherAlgorithm[mFuzzedDataProvider->ConsumeBool()]));
+    mDrm->setMacAlgorithm(mSessionId, String8(kMacAlgorithm[mFuzzedDataProvider->ConsumeBool()]));
+}
+
+void DrmFuzzer::invokeDrmPropertyAPI() {
+    mDrm->setPropertyString(String8("property"), String8("value"));
+    String8 stringValue;
+    mDrm->getPropertyString(String8("property"), stringValue);
+    Vector<uint8_t> value = {};
+    mDrm->setPropertyByteArray(String8("property"), value);
+    Vector<uint8_t> byteValue;
+    mDrm->getPropertyByteArray(String8("property"), byteValue);
+}
+
+void DrmFuzzer::invokeDrmDecryptEncryptAPI(const uint8_t *data, size_t size) {
+    uint32_t openSessions = 0;
+    uint32_t maxSessions = 0;
+    mDrm->getNumberOfSessions(&openSessions, &maxSessions);
+
+    DrmPlugin::HdcpLevel connected;
+    DrmPlugin::HdcpLevel max;
+    mDrm->getHdcpLevels(&connected, &max);
+
+    DrmPlugin::SecurityLevel securityLevel;
+    mDrm->getSecurityLevel(mSessionId, &securityLevel);
+
+    // isCryptoSchemeSupported() shall fill isSupported
+    bool isSupported;
+    String8 mimeType(
+        kMimeType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumMimeType - 1)]);
+    mDrm->isCryptoSchemeSupported(kClearKeyUUID, mimeType, securityLevel, &isSupported);
+
+    // getProvisionRequest() shall fill legacyRequest and legacyDefaultUrl
+    String8 certificateType(
+        mFuzzedDataProvider->ConsumeRandomLengthString(kMaxStringLength).c_str());
+    String8 certAuthority(mFuzzedDataProvider->ConsumeRandomLengthString(kMaxStringLength).c_str());
+    Vector<uint8_t> legacyRequest = {};
+    String8 legacyDefaultUrl;
+    mDrm->getProvisionRequest(certificateType, certAuthority, legacyRequest, legacyDefaultUrl);
+
+    // provideProvisionResponse() shall fill certificate and wrappedKey
+    Vector<uint8_t> provisionResponse = {};
+    Vector<uint8_t> certificate = {};
+    Vector<uint8_t> wrappedKey = {};
+    mDrm->provideProvisionResponse(provisionResponse, certificate, wrappedKey);
+
+    // getKeyRequest() shall fill keyRequest, defaultUrl and keyRequestType
+    Vector<uint8_t> initData = {};
+    initData.appendArray(data, size);
+    DrmPlugin::KeyType keyType;
+    bool shouldPassRandomKeyType = mFuzzedDataProvider->ConsumeBool();
+    if (shouldPassRandomKeyType) {
+        keyType = static_cast<DrmPlugin::KeyType>(mFuzzedDataProvider->ConsumeIntegral<size_t>());
+    } else {
+        keyType = kKeyType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumKeyType - 1)];
+    }
+    KeyedVector<String8, String8> mdOptionalParameters = {};
+    Vector<uint8_t> keyRequest = {};
+    String8 defaultUrl;
+    DrmPlugin::KeyRequestType keyRequestType;
+    mDrm->getKeyRequest(mSessionId, initData, mimeType, keyType, mdOptionalParameters, keyRequest,
+                        defaultUrl, &keyRequestType);
+
+    // provideKeyResponse() shall fill keySetId
+    Vector<uint8_t> keyResponse = {};
+    keyResponse.appendArray(data, size);
+    Vector<uint8_t> keySetId = {};
+    mDrm->provideKeyResponse(mSessionId, keyResponse, keySetId);
+
+    // restoreKeys
+    mDrm->restoreKeys(mSessionId, keySetId);
+
+    // queryKeyStatus() shall fill infoMap
+    KeyedVector<String8, String8> infoMap = {};
+    mDrm->queryKeyStatus(mSessionId, infoMap);
+
+    // decrypt() shall fill outputVec
+    Vector<uint8_t> keyIdVec = {};
+    keyIdVec.appendArray(data, size);
+
+    Vector<uint8_t> inputVec = {};
+    inputVec.appendArray(data, size);
+
+    Vector<uint8_t> ivVec = {};
+    ivVec.appendArray(data, size);
+
+    Vector<uint8_t> outputVec = {};
+    mDrm->decrypt(mSessionId, keyIdVec, inputVec, ivVec, outputVec);
+
+    // encrypt() shall fill outputVec
+    mDrm->encrypt(mSessionId, keyIdVec, inputVec, ivVec, outputVec);
+
+    // sign() shall fill signature
+    Vector<uint8_t> message = {};
+    message.appendArray(data, size);
+    Vector<uint8_t> signature = {};
+    mDrm->sign(mSessionId, keyIdVec, message, signature);
+
+    // verify() shall fill match
+    bool match;
+    mDrm->verify(mSessionId, keyIdVec, message, signature, match);
+
+    // signRSA() shall fill signature
+    mDrm->signRSA(mSessionId, String8(kRSAAlgorithm[mFuzzedDataProvider->ConsumeBool()]), message,
+                  wrappedKey, signature);
+
+    mDrm->removeKeys(mSessionId);
+}
+
+void DrmFuzzer::invokeDrmSecureStopAPI() {
+    // getSecureStops() shall fill secureStops
+    List<Vector<uint8_t>> secureStops = {};
+    mDrm->getSecureStops(secureStops);
+
+    // getSecureStopIds() shall fill secureStopIds
+    List<Vector<uint8_t>> secureStopIds = {};
+    mDrm->getSecureStopIds(secureStopIds);
+
+    // getSecureStop() shall fill secureStop
+    Vector<uint8_t> ssid = {};
+    Vector<uint8_t> secureStop = {};
+    mDrm->getSecureStop(ssid, secureStop);
+
+    mDrm->removeSecureStop(ssid);
+
+    mDrm->releaseSecureStops(ssid);
+
+    mDrm->removeAllSecureStops();
+}
+
+void DrmFuzzer::invokeDrmOfflineLicenseAPI() {
+    // getOfflineLicenseKeySetIds() shall keySetIds
+    List<Vector<uint8_t>> keySetIds = {};
+    mDrm->getOfflineLicenseKeySetIds(keySetIds);
+
+    // getOfflineLicenseState() shall fill state
+    Vector<uint8_t> const keySetIdOfflineLicense = {};
+    DrmPlugin::OfflineLicenseState state;
+    mDrm->getOfflineLicenseState(keySetIdOfflineLicense, &state);
+
+    mDrm->removeOfflineLicense(keySetIdOfflineLicense);
+}
+
+bool DrmFuzzer::initCrypto() {
+    mCrypto = new CryptoHal();
+    if (!mCrypto) {
+        return false;
+    }
+    return true;
+}
+
+void DrmFuzzer::invokeCryptoCreatePlugin() {
+    mCrypto->initCheck();
+
+    mCrypto->isCryptoSchemeSupported(kClearKeyUUID);
+    mCrypto->createPlugin(kClearKeyUUID, NULL, 0);
+}
+
+void DrmFuzzer::invokeCryptoDestroyPlugin() { mCrypto->destroyPlugin(); }
+
+void DrmFuzzer::invokeCryptoDecrypt(const uint8_t *data) {
+    mCrypto->requiresSecureDecoderComponent(
+        kMimeType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumMimeType - 1)]);
+
+    uint32_t width = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
+    uint32_t height = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
+    mCrypto->notifyResolution(width, height);
+
+    mCrypto->setMediaDrmSession(mSessionId);
+
+    const CryptoPlugin::Pattern pattern = {0, 0};
+
+    size_t totalSize = 0;
+    size_t numSubSamples = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(1, kMaxSubSamples);
+
+    CryptoPlugin::SubSample subSamples[numSubSamples];
+
+    for (size_t i = 0; i < numSubSamples; ++i) {
+        uint32_t clearBytes =
+            mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(1, kMaxNumBytes);
+        uint32_t encryptedBytes =
+            mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(1, kMaxNumBytes);
+        subSamples[i].mNumBytesOfClearData = clearBytes;
+        subSamples[i].mNumBytesOfEncryptedData = encryptedBytes;
+        totalSize += subSamples[i].mNumBytesOfClearData;
+        totalSize += subSamples[i].mNumBytesOfEncryptedData;
+    }
+
+    size_t heapSize = totalSize * 2;
+    sp<MemoryDealer> dealer = new MemoryDealer(heapSize, "DrmFuzzerMemory");
+    if (!dealer) {
+        return;
+    }
+
+    sp<HidlMemory> heap = fromHeap(dealer->getMemoryHeap());
+    if (!heap) {
+        return;
+    }
+    int heapSeqNum = mCrypto->setHeap(heap);
+    if (heapSeqNum < 0) {
+        return;
+    }
+
+    const size_t segmentIndex = 0;
+    const uint8_t keyId[AES_BLOCK_SIZE] = {};
+    memcpy((void *)keyId, data, AES_BLOCK_SIZE);
+
+    const uint8_t iv[AES_BLOCK_SIZE] = {};
+    memset((void *)iv, 0, AES_BLOCK_SIZE);
+
+    const SharedBuffer sourceBuffer = {.bufferId = segmentIndex, .offset = 0, .size = totalSize};
+
+    const DestinationBuffer destBuffer = {
+        .type = BufferType::SHARED_MEMORY,
+        {.bufferId = segmentIndex, .offset = totalSize, .size = totalSize},
+        .secureMemory = nullptr};
+
+    const uint64_t offset = 0;
+    AString *errorDetailMsg = nullptr;
+    CryptoPlugin::Mode mode;
+    bool shouldPassRandomCryptoMode = mFuzzedDataProvider->ConsumeBool();
+    if (shouldPassRandomCryptoMode) {
+        mode = static_cast<CryptoPlugin::Mode>(mFuzzedDataProvider->ConsumeIntegral<size_t>());
+    } else {
+        mode =
+            kCryptoMode[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumCryptoMode - 1)];
+    }
+    mCrypto->decrypt(keyId, iv, mode, pattern, sourceBuffer, offset, subSamples, numSubSamples,
+                     destBuffer, errorDetailMsg);
+
+    if (heapSeqNum >= 0) {
+        mCrypto->unsetHeap(heapSeqNum);
+    }
+    heap.clear();
+}
+
+void DrmFuzzer::invokeDrm(const uint8_t *data, size_t size) {
+    if (!initDrm()) {
+        return;
+    }
+    invokeDrmCreatePlugin();
+    invokeDrmOpenSession();
+    invokeDrmSetAlgorithmAPI();
+    invokeDrmSetListener();
+    invokeDrmPropertyAPI();
+    invokeDrmDecryptEncryptAPI(data, size);
+    invokeDrmSecureStopAPI();
+    invokeDrmOfflineLicenseAPI();
+    invokeDrmCloseSession();
+    invokeDrmDestroyPlugin();
+}
+
+void DrmFuzzer::invokeCrypto(const uint8_t *data) {
+    if (!initCrypto()) {
+        return;
+    }
+    invokeCryptoCreatePlugin();
+    invokeCryptoDecrypt(data);
+    invokeCryptoDestroyPlugin();
+}
+
+void DrmFuzzer::process(const uint8_t *data, size_t size) {
+    mFuzzedDataProvider = new FuzzedDataProvider(data, size);
+    invokeDrm(data, size);
+    invokeCrypto(data);
+    delete mFuzzedDataProvider;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+    if (size < AES_BLOCK_SIZE) {
+        return 0;
+    }
+    DrmFuzzer drmFuzzer;
+    drmFuzzer.process(data, size);
+    return 0;
+}
diff --git a/media/bufferpool/2.0/tests/Android.bp b/media/bufferpool/2.0/tests/Android.bp
index 8492939..56bda89 100644
--- a/media/bufferpool/2.0/tests/Android.bp
+++ b/media/bufferpool/2.0/tests/Android.bp
@@ -25,7 +25,7 @@
     static_libs: [
         "android.hardware.media.bufferpool@2.0",
         "libcutils",
-        "libstagefright_bufferpool@2.0",
+        "libstagefright_bufferpool@2.0.1",
     ],
     shared_libs: [
         "libfmq",
@@ -44,10 +44,30 @@
     static_libs: [
         "android.hardware.media.bufferpool@2.0",
         "libcutils",
-        "libstagefright_bufferpool@2.0",
+        "libstagefright_bufferpool@2.0.1",
     ],
     shared_libs: [
         "libfmq",
     ],
     compile_multilib: "both",
 }
+
+cc_test {
+    name: "VtsVndkHidlBufferpoolV2_0TargetCondTest",
+    test_suites: ["device-tests"],
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "cond.cpp",
+    ],
+    static_libs: [
+        "android.hardware.media.bufferpool@2.0",
+        "libcutils",
+        "libstagefright_bufferpool@2.0.1",
+    ],
+    shared_libs: [
+        "libhidlbase",
+        "libfmq",
+    ],
+    compile_multilib: "both",
+}
diff --git a/media/bufferpool/2.0/tests/allocator.cpp b/media/bufferpool/2.0/tests/allocator.cpp
index 843f7ea..25b08ef 100644
--- a/media/bufferpool/2.0/tests/allocator.cpp
+++ b/media/bufferpool/2.0/tests/allocator.cpp
@@ -120,6 +120,24 @@
 
 }
 
+void IpcMutex::init() {
+  pthread_mutexattr_t mattr;
+  pthread_mutexattr_init(&mattr);
+  pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
+  pthread_mutex_init(&lock, &mattr);
+  pthread_mutexattr_destroy(&mattr);
+
+  pthread_condattr_t cattr;
+  pthread_condattr_init(&cattr);
+  pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
+  pthread_cond_init(&cond, &cattr);
+  pthread_condattr_destroy(&cattr);
+}
+
+IpcMutex *IpcMutex::Import(void *pMutex) {
+  return reinterpret_cast<IpcMutex *>(pMutex);
+}
+
 
 ResultStatus TestBufferPoolAllocator::allocate(
     const std::vector<uint8_t> &params,
@@ -201,9 +219,33 @@
   return false;
 }
 
+bool TestBufferPoolAllocator::MapMemoryForMutex(const native_handle_t *handle, void **mem) {
+  if (!HandleAshmem::isValid(handle)) {
+    return false;
+  }
+  const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+  *mem = mmap(
+      NULL, o->size(), PROT_READ|PROT_WRITE, MAP_SHARED, o->ashmemFd(), 0);
+  if (*mem == MAP_FAILED || *mem == nullptr) {
+    return false;
+  }
+  return true;
+}
+
+bool TestBufferPoolAllocator::UnmapMemoryForMutex(void *mem) {
+  munmap(mem, sizeof(IpcMutex));
+  return true;
+}
+
 void getTestAllocatorParams(std::vector<uint8_t> *params) {
   constexpr static int kAllocationSize = 1024 * 10;
   Params ashmemParams(kAllocationSize);
 
   params->assign(ashmemParams.array, ashmemParams.array + sizeof(ashmemParams));
 }
+
+void getIpcMutexParams(std::vector<uint8_t> *params) {
+  Params ashmemParams(sizeof(IpcMutex));
+
+  params->assign(ashmemParams.array, ashmemParams.array + sizeof(ashmemParams));
+}
diff --git a/media/bufferpool/2.0/tests/allocator.h b/media/bufferpool/2.0/tests/allocator.h
index 5281dc3..862d1a5 100644
--- a/media/bufferpool/2.0/tests/allocator.h
+++ b/media/bufferpool/2.0/tests/allocator.h
@@ -17,6 +17,7 @@
 #ifndef VNDK_HIDL_BUFFERPOOL_V2_0_ALLOCATOR_H
 #define VNDK_HIDL_BUFFERPOOL_V2_0_ALLOCATOR_H
 
+#include <pthread.h>
 #include <bufferpool/BufferPoolTypes.h>
 
 using android::hardware::media::bufferpool::V2_0::ResultStatus;
@@ -25,6 +26,17 @@
 using android::hardware::media::bufferpool::V2_0::implementation::
     BufferPoolAllocator;
 
+struct IpcMutex {
+  pthread_mutex_t lock;
+  pthread_cond_t cond;
+  int counter = 0;
+  bool signalled = false;
+
+  void init();
+
+  static IpcMutex *Import(void *mem);
+};
+
 // buffer allocator for the tests
 class TestBufferPoolAllocator : public BufferPoolAllocator {
  public:
@@ -43,9 +55,14 @@
 
   static bool Verify(const native_handle_t *handle, const unsigned char val);
 
+  static bool MapMemoryForMutex(const native_handle_t *handle, void **mem);
+
+  static bool UnmapMemoryForMutex(void *mem);
 };
 
 // retrieve buffer allocator paramters
 void getTestAllocatorParams(std::vector<uint8_t> *params);
 
+void getIpcMutexParams(std::vector<uint8_t> *params);
+
 #endif  // VNDK_HIDL_BUFFERPOOL_V2_0_ALLOCATOR_H
diff --git a/media/bufferpool/2.0/tests/cond.cpp b/media/bufferpool/2.0/tests/cond.cpp
new file mode 100644
index 0000000..21beea8
--- /dev/null
+++ b/media/bufferpool/2.0/tests/cond.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2018 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 "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <bufferpool/ClientManager.h>
+#include <errno.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+#include <hidl/Status.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <iostream>
+#include <memory>
+#include <vector>
+#include "allocator.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::hidl_handle;
+using android::hardware::media::bufferpool::V2_0::IClientManager;
+using android::hardware::media::bufferpool::V2_0::ResultStatus;
+using android::hardware::media::bufferpool::V2_0::implementation::BufferId;
+using android::hardware::media::bufferpool::V2_0::implementation::ClientManager;
+using android::hardware::media::bufferpool::V2_0::implementation::ConnectionId;
+using android::hardware::media::bufferpool::V2_0::implementation::TransactionId;
+using android::hardware::media::bufferpool::BufferPoolData;
+
+namespace {
+
+// communication message types between processes.
+enum PipeCommand : int32_t {
+    INIT_OK = 0,
+    INIT_ERROR,
+    SEND,
+    RECEIVE_OK,
+    RECEIVE_ERROR,
+};
+
+// communication message between processes.
+union PipeMessage {
+    struct  {
+        int32_t command;
+        BufferId bufferId;
+        ConnectionId connectionId;
+        TransactionId transactionId;
+        int64_t  timestampUs;
+    } data;
+    char array[0];
+};
+
+constexpr int kSignalInt = 200;
+
+// media.bufferpool test setup
+class BufferpoolMultiTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    ResultStatus status;
+    mReceiverPid = -1;
+    mConnectionValid = false;
+
+    ASSERT_TRUE(pipe(mCommandPipeFds) == 0);
+    ASSERT_TRUE(pipe(mResultPipeFds) == 0);
+
+    mReceiverPid = fork();
+    ASSERT_TRUE(mReceiverPid >= 0);
+
+    if (mReceiverPid == 0) {
+      doReceiver();
+      // In order to ignore gtest behaviour, wait for being killed from
+      // tearDown
+      pause();
+    }
+
+    mManager = ClientManager::getInstance();
+    ASSERT_NE(mManager, nullptr);
+
+    mAllocator = std::make_shared<TestBufferPoolAllocator>();
+    ASSERT_TRUE((bool)mAllocator);
+
+    status = mManager->create(mAllocator, &mConnectionId);
+    ASSERT_TRUE(status == ResultStatus::OK);
+    mConnectionValid = true;
+  }
+
+  virtual void TearDown() override {
+    if (mReceiverPid > 0) {
+      kill(mReceiverPid, SIGKILL);
+      int wstatus;
+      wait(&wstatus);
+    }
+
+    if (mConnectionValid) {
+      mManager->close(mConnectionId);
+    }
+  }
+
+ protected:
+  static void description(const std::string& description) {
+    RecordProperty("description", description);
+  }
+
+  android::sp<ClientManager> mManager;
+  std::shared_ptr<BufferPoolAllocator> mAllocator;
+  bool mConnectionValid;
+  ConnectionId mConnectionId;
+  pid_t mReceiverPid;
+  int mCommandPipeFds[2];
+  int mResultPipeFds[2];
+
+  bool sendMessage(int *pipes, const PipeMessage &message) {
+    int ret = write(pipes[1], message.array, sizeof(PipeMessage));
+    return ret == sizeof(PipeMessage);
+  }
+
+  bool receiveMessage(int *pipes, PipeMessage *message) {
+    int ret = read(pipes[0], message->array, sizeof(PipeMessage));
+    return ret == sizeof(PipeMessage);
+  }
+
+  void doReceiver() {
+    configureRpcThreadpool(1, false);
+    PipeMessage message;
+    mManager = ClientManager::getInstance();
+    if (!mManager) {
+      message.data.command = PipeCommand::INIT_ERROR;
+      sendMessage(mResultPipeFds, message);
+      return;
+    }
+    android::status_t status = mManager->registerAsService();
+    if (status != android::OK) {
+      message.data.command = PipeCommand::INIT_ERROR;
+      sendMessage(mResultPipeFds, message);
+      return;
+    }
+    message.data.command = PipeCommand::INIT_OK;
+    sendMessage(mResultPipeFds, message);
+
+    int val = 0;
+    receiveMessage(mCommandPipeFds, &message);
+    {
+      native_handle_t *rhandle = nullptr;
+      std::shared_ptr<BufferPoolData> rbuffer;
+      void *mem = nullptr;
+      IpcMutex *mutex = nullptr;
+      ResultStatus status = mManager->receive(
+          message.data.connectionId, message.data.transactionId,
+          message.data.bufferId, message.data.timestampUs, &rhandle, &rbuffer);
+      mManager->close(message.data.connectionId);
+      if (status != ResultStatus::OK) {
+          message.data.command = PipeCommand::RECEIVE_ERROR;
+          sendMessage(mResultPipeFds, message);
+          return;
+      }
+      if (!TestBufferPoolAllocator::MapMemoryForMutex(rhandle, &mem)) {
+          message.data.command = PipeCommand::RECEIVE_ERROR;
+          sendMessage(mResultPipeFds, message);
+          return;
+      }
+      mutex = IpcMutex::Import(mem);
+      pthread_mutex_lock(&(mutex->lock));
+      while (mutex->signalled != true) {
+          pthread_cond_wait(&(mutex->cond), &(mutex->lock));
+      }
+      val = mutex->counter;
+      pthread_mutex_unlock(&(mutex->lock));
+
+      (void)TestBufferPoolAllocator::UnmapMemoryForMutex(mem);
+      if (rhandle) {
+        native_handle_close(rhandle);
+        native_handle_delete(rhandle);
+      }
+    }
+    if (val == kSignalInt) {
+      message.data.command = PipeCommand::RECEIVE_OK;
+    } else {
+      message.data.command = PipeCommand::RECEIVE_ERROR;
+    }
+    sendMessage(mResultPipeFds, message);
+  }
+};
+
+// Buffer transfer test between processes.
+TEST_F(BufferpoolMultiTest, TransferBuffer) {
+  ResultStatus status;
+  PipeMessage message;
+
+  ASSERT_TRUE(receiveMessage(mResultPipeFds, &message));
+
+  android::sp<IClientManager> receiver = IClientManager::getService();
+  ConnectionId receiverId;
+  ASSERT_TRUE((bool)receiver);
+
+  status = mManager->registerSender(receiver, mConnectionId, &receiverId);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  {
+    native_handle_t *shandle = nullptr;
+    std::shared_ptr<BufferPoolData> sbuffer;
+    TransactionId transactionId;
+    int64_t postUs;
+    std::vector<uint8_t> vecParams;
+    void *mem = nullptr;
+    IpcMutex *mutex = nullptr;
+
+    getIpcMutexParams(&vecParams);
+    status = mManager->allocate(mConnectionId, vecParams, &shandle, &sbuffer);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    ASSERT_TRUE(TestBufferPoolAllocator::MapMemoryForMutex(shandle, &mem));
+
+    mutex = new(mem) IpcMutex();
+    mutex->init();
+
+    status = mManager->postSend(receiverId, sbuffer, &transactionId, &postUs);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    message.data.command = PipeCommand::SEND;
+    message.data.bufferId = sbuffer->mId;
+    message.data.connectionId = receiverId;
+    message.data.transactionId = transactionId;
+    message.data.timestampUs = postUs;
+    sendMessage(mCommandPipeFds, message);
+    for (int i=0; i < 200000000; ++i) {
+      // no-op in order to ensure
+      // pthread_cond_wait is called before pthread_cond_signal
+    }
+    pthread_mutex_lock(&(mutex->lock));
+    mutex->counter = kSignalInt;
+    mutex->signalled = true;
+    pthread_cond_signal(&(mutex->cond));
+    pthread_mutex_unlock(&(mutex->lock));
+    (void)TestBufferPoolAllocator::UnmapMemoryForMutex(mem);
+    if (shandle) {
+      native_handle_close(shandle);
+      native_handle_delete(shandle);
+    }
+  }
+  EXPECT_TRUE(receiveMessage(mResultPipeFds, &message));
+  EXPECT_TRUE(message.data.command == PipeCommand::RECEIVE_OK);
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+  android::hardware::details::setTrebleTestingOverride(true);
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
diff --git a/media/bufferpool/2.0/tests/multi.cpp b/media/bufferpool/2.0/tests/multi.cpp
index b40838e..43b0a8c 100644
--- a/media/bufferpool/2.0/tests/multi.cpp
+++ b/media/bufferpool/2.0/tests/multi.cpp
@@ -161,11 +161,18 @@
           message.data.bufferId, message.data.timestampUs, &rhandle, &rbuffer);
       mManager->close(message.data.connectionId);
       if (status != ResultStatus::OK) {
-        if (!TestBufferPoolAllocator::Verify(rhandle, 0x77)) {
-          message.data.command = PipeCommand::RECEIVE_ERROR;
-          sendMessage(mResultPipeFds, message);
-          return;
-        }
+        message.data.command = PipeCommand::RECEIVE_ERROR;
+        sendMessage(mResultPipeFds, message);
+        return;
+      }
+      if (!TestBufferPoolAllocator::Verify(rhandle, 0x77)) {
+        message.data.command = PipeCommand::RECEIVE_ERROR;
+        sendMessage(mResultPipeFds, message);
+        return;
+      }
+      if (rhandle) {
+        native_handle_close(rhandle);
+        native_handle_delete(rhandle);
       }
     }
     message.data.command = PipeCommand::RECEIVE_OK;
@@ -198,6 +205,10 @@
     ASSERT_TRUE(status == ResultStatus::OK);
 
     ASSERT_TRUE(TestBufferPoolAllocator::Fill(shandle, 0x77));
+    if (shandle) {
+        native_handle_close(shandle);
+        native_handle_delete(shandle);
+    }
 
     status = mManager->postSend(receiverId, sbuffer, &transactionId, &postUs);
     ASSERT_TRUE(status == ResultStatus::OK);
@@ -210,6 +221,7 @@
     sendMessage(mCommandPipeFds, message);
   }
   EXPECT_TRUE(receiveMessage(mResultPipeFds, &message));
+  EXPECT_TRUE(message.data.command == PipeCommand::RECEIVE_OK);
 }
 
 }  // anonymous namespace
diff --git a/media/bufferpool/2.0/tests/single.cpp b/media/bufferpool/2.0/tests/single.cpp
index 777edcf..1e9027b 100644
--- a/media/bufferpool/2.0/tests/single.cpp
+++ b/media/bufferpool/2.0/tests/single.cpp
@@ -102,6 +102,10 @@
   for (int i = 0; i < kNumAllocationTest; ++i) {
     status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &buffer[i]);
     ASSERT_TRUE(status == ResultStatus::OK);
+    if (allocHandle) {
+      native_handle_close(allocHandle);
+      native_handle_delete(allocHandle);
+    }
   }
   for (int i = 0; i < kNumAllocationTest; ++i) {
     for (int j = i + 1; j < kNumAllocationTest; ++j) {
@@ -125,6 +129,10 @@
     status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &buffer);
     ASSERT_TRUE(status == ResultStatus::OK);
     bid[i] = buffer->mId;
+    if (allocHandle) {
+      native_handle_close(allocHandle);
+      native_handle_delete(allocHandle);
+    }
   }
   for (int i = 1; i < kNumRecycleTest; ++i) {
     ASSERT_TRUE(bid[i - 1] == bid[i]);
@@ -154,6 +162,15 @@
                              &recvHandle, &rbuffer);
   EXPECT_TRUE(status == ResultStatus::OK);
   ASSERT_TRUE(TestBufferPoolAllocator::Verify(recvHandle, 0x77));
+
+  if (allocHandle) {
+    native_handle_close(allocHandle);
+    native_handle_delete(allocHandle);
+  }
+  if (recvHandle) {
+    native_handle_close(recvHandle);
+    native_handle_delete(recvHandle);
+  }
 }
 
 }  // anonymous namespace
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index 677f316..f3341ab 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -1061,11 +1061,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAacDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
index 2e85915..ea76cbb 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.cpp
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -692,11 +692,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAacEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
index f7943be..c08e02b 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
@@ -420,11 +420,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAMRDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
index e2d8cb6..bb63e1f 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
@@ -337,11 +337,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAmrNbEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
index 84ae4b7..84728ae 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
@@ -411,11 +411,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAmrWbEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/aom/C2SoftAomDec.cpp b/media/codec2/components/aom/C2SoftAomDec.cpp
index 9ba3b697..c08cd59 100644
--- a/media/codec2/components/aom/C2SoftAomDec.cpp
+++ b/media/codec2/components/aom/C2SoftAomDec.cpp
@@ -800,11 +800,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAomFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/avc/Android.bp b/media/codec2/components/avc/Android.bp
index 6b0e363..9f8bc68 100644
--- a/media/codec2/components/avc/Android.bp
+++ b/media/codec2/components/avc/Android.bp
@@ -3,7 +3,8 @@
     defaults: [
         "libcodec2_soft-defaults",
         "libcodec2_soft_sanitize_signed-defaults",
-   ],
+        "libcodec2_soft_sanitize_cfi-defaults",
+    ],
 
     static_libs: ["libavcdec"],
 
@@ -20,7 +21,8 @@
     defaults: [
         "libcodec2_soft-defaults",
         "libcodec2_soft_sanitize_signed-defaults",
-   ],
+        "libcodec2_soft_sanitize_cfi-defaults",
+    ],
 
     static_libs: ["libavcenc"],
 
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index 3afd670..0207311 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -1049,11 +1049,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAvcDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index ab93ce3..cfaeb66 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -1756,11 +1756,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftAvcEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/base/Android.bp b/media/codec2/components/base/Android.bp
index 3712564..0c8f4a4 100644
--- a/media/codec2/components/base/Android.bp
+++ b/media/codec2/components/base/Android.bp
@@ -20,7 +20,7 @@
 
     shared_libs: [
         "libcutils", // for properties
-        "liblog",    // for ALOG
+        "liblog", // for ALOG
         "libsfplugin_ccodec_utils", // for ImageCopy
         "libstagefright_foundation", // for Mutexed
     ],
@@ -38,7 +38,7 @@
 
 filegroup {
     name: "codec2_soft_exports",
-    srcs: [ "exports.lds" ],
+    srcs: ["exports.lds"],
 }
 
 // public dependency for software codec implementation
@@ -91,7 +91,20 @@
         misc_undefined: [
             "signed-integer-overflow",
         ],
+    },
+}
+
+cc_defaults {
+    name: "libcodec2_soft_sanitize_cfi-defaults",
+
+    sanitize: {
         cfi: true,
+        config: {
+            cfi_assembly_support: true,
+        },
+        diag: {
+            cfi: true,
+        },
     },
 }
 
@@ -131,4 +144,3 @@
 
     ldflags: ["-Wl,-Bsymbolic"],
 }
-
diff --git a/media/codec2/components/flac/C2SoftFlacDec.cpp b/media/codec2/components/flac/C2SoftFlacDec.cpp
index 4039b9b..e70c289 100644
--- a/media/codec2/components/flac/C2SoftFlacDec.cpp
+++ b/media/codec2/components/flac/C2SoftFlacDec.cpp
@@ -367,11 +367,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftFlacDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/flac/C2SoftFlacEnc.cpp b/media/codec2/components/flac/C2SoftFlacEnc.cpp
index 72910c5..6fead3a 100644
--- a/media/codec2/components/flac/C2SoftFlacEnc.cpp
+++ b/media/codec2/components/flac/C2SoftFlacEnc.cpp
@@ -482,11 +482,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftFlacEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/g711/C2SoftG711Dec.cpp b/media/codec2/components/g711/C2SoftG711Dec.cpp
index 7f9c34e..f9299af 100644
--- a/media/codec2/components/g711/C2SoftG711Dec.cpp
+++ b/media/codec2/components/g711/C2SoftG711Dec.cpp
@@ -259,11 +259,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftG711DecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index a1929e7..76345ae 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -770,11 +770,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory *CreateCodec2Factory() {
   ALOGV("in %s", __func__);
   return new ::android::C2SoftGav1Factory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory *factory) {
   ALOGV("in %s", __func__);
   delete factory;
diff --git a/media/codec2/components/gsm/C2SoftGsmDec.cpp b/media/codec2/components/gsm/C2SoftGsmDec.cpp
index 287cfc6..977677d 100644
--- a/media/codec2/components/gsm/C2SoftGsmDec.cpp
+++ b/media/codec2/components/gsm/C2SoftGsmDec.cpp
@@ -294,11 +294,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftGSMDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/hevc/Android.bp b/media/codec2/components/hevc/Android.bp
index 2858212..dcd4901 100644
--- a/media/codec2/components/hevc/Android.bp
+++ b/media/codec2/components/hevc/Android.bp
@@ -3,12 +3,12 @@
     defaults: [
         "libcodec2_soft-defaults",
         "libcodec2_soft_sanitize_signed-defaults",
+        "libcodec2_soft_sanitize_cfi-defaults",
     ],
 
     srcs: ["C2SoftHevcDec.cpp"],
 
     static_libs: ["libhevcdec"],
-
 }
 
 cc_library {
@@ -16,10 +16,10 @@
     defaults: [
         "libcodec2_soft-defaults",
         "libcodec2_soft_sanitize_signed-defaults",
+        "libcodec2_soft_sanitize_cfi-defaults",
     ],
 
     srcs: ["C2SoftHevcEnc.cpp"],
 
     static_libs: ["libhevcenc"],
-
 }
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 23104dc..56dd26b 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -1048,11 +1048,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftHevcDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index c2d2540..436a2c4 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -1078,11 +1078,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftHevcEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/mp3/C2SoftMp3Dec.cpp b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
index 5ba7e3d..7137767 100644
--- a/media/codec2/components/mp3/C2SoftMp3Dec.cpp
+++ b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
@@ -539,11 +539,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftMp3DecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index 55dd475..82c061a 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -1113,11 +1113,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftMpeg2DecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
index 13cc0ec..a7cc037 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
@@ -747,11 +747,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftMpeg4DecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
index 54c8c47..e1cc6b3 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
@@ -652,11 +652,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftMpeg4EncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/opus/C2SoftOpusDec.cpp b/media/codec2/components/opus/C2SoftOpusDec.cpp
index b7c1556..d4987c0 100644
--- a/media/codec2/components/opus/C2SoftOpusDec.cpp
+++ b/media/codec2/components/opus/C2SoftOpusDec.cpp
@@ -473,11 +473,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftOpusDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.cpp b/media/codec2/components/opus/C2SoftOpusEnc.cpp
index 70d1965..b47275f 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.cpp
+++ b/media/codec2/components/opus/C2SoftOpusEnc.cpp
@@ -626,11 +626,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftOpusEncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/raw/C2SoftRawDec.cpp b/media/codec2/components/raw/C2SoftRawDec.cpp
index 7b6f21a..31ca705 100644
--- a/media/codec2/components/raw/C2SoftRawDec.cpp
+++ b/media/codec2/components/raw/C2SoftRawDec.cpp
@@ -215,11 +215,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftRawDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
index d3b6e31..899fe9b 100644
--- a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
+++ b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
@@ -359,10 +359,6 @@
     }
     memcpy(&numPageFrames, data + inSize - sizeof(numPageFrames), sizeof(numPageFrames));
     inSize -= sizeof(numPageFrames);
-    if (inSize == 0) {
-        // empty buffer, ignore
-        return;
-    }
     if (numPageFrames >= 0) {
         mNumFramesLeftOnPage = numPageFrames;
     }
@@ -413,7 +409,7 @@
                 mState,  reinterpret_cast<int16_t *> (wView.data()),
                 kMaxNumSamplesPerChannel);
         if (numFrames < 0) {
-            ALOGD("vorbis_dsp_pcmout returned %d frames", numFrames);
+            ALOGD("vorbis_dsp_pcmout returned %d", numFrames);
             numFrames = 0;
         }
     }
@@ -481,11 +477,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftVorbisDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/vpx/C2SoftVp8Enc.cpp b/media/codec2/components/vpx/C2SoftVp8Enc.cpp
index f18f5d0..049ec38 100644
--- a/media/codec2/components/vpx/C2SoftVp8Enc.cpp
+++ b/media/codec2/components/vpx/C2SoftVp8Enc.cpp
@@ -101,11 +101,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftVp8EncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/vpx/C2SoftVp9Enc.cpp b/media/codec2/components/vpx/C2SoftVp9Enc.cpp
index 740dbda..6401521 100644
--- a/media/codec2/components/vpx/C2SoftVp9Enc.cpp
+++ b/media/codec2/components/vpx/C2SoftVp9Enc.cpp
@@ -131,11 +131,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftVp9EncFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index 91238e8..2953d90 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -948,11 +948,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftVpxFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/components/xaac/Android.bp b/media/codec2/components/xaac/Android.bp
index 4889d78..9b7e2de 100644
--- a/media/codec2/components/xaac/Android.bp
+++ b/media/codec2/components/xaac/Android.bp
@@ -3,6 +3,7 @@
     defaults: [
         "libcodec2_soft-defaults",
         "libcodec2_soft_sanitize_all-defaults",
+	"libcodec2_soft_sanitize_cfi-defaults",
     ],
 
     srcs: ["C2SoftXaacDec.cpp"],
diff --git a/media/codec2/components/xaac/C2SoftXaacDec.cpp b/media/codec2/components/xaac/C2SoftXaacDec.cpp
index 951d058..6deafda 100644
--- a/media/codec2/components/xaac/C2SoftXaacDec.cpp
+++ b/media/codec2/components/xaac/C2SoftXaacDec.cpp
@@ -1600,11 +1600,13 @@
 
 }  // namespace android
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
     ALOGV("in %s", __func__);
     return new ::android::C2SoftXaacDecFactory();
 }
 
+__attribute__((cfi_canonical_jump_table))
 extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
     ALOGV("in %s", __func__);
     delete factory;
diff --git a/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp b/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
index fb1c291..47ceed5 100644
--- a/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
@@ -73,9 +73,10 @@
             ASSERT_NE(listener, nullptr);
 
             // Create component from all known services
-            component =
-                    mClient->CreateComponentByName(listTraits[i].name.c_str(), listener, &mClient);
-            ASSERT_NE(component, nullptr)
+            const c2_status_t status =
+                    android::Codec2Client::CreateComponentByName(
+                            listTraits[i].name.c_str(), listener, &component, &mClient);
+            ASSERT_EQ(status, C2_OK)
                     << "Create component failed for " << listTraits[i].name.c_str();
         }
     }
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index 4650672..341a577 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -1008,6 +1008,8 @@
                 std::scoped_lock lock{key2IndexMutex};
                 key2Index[key] = index; // update last known client index
                 return C2_OK;
+            } else if (status == C2_NO_MEMORY) {
+                return C2_NO_MEMORY;
             } else if (status == C2_TRANSACTION_FAILED) {
                 LOG(WARNING) << "\"" << key << "\" failed for service \""
                              << client->getName()
@@ -1028,24 +1030,23 @@
     return status; // return the last status from a valid client
 }
 
-std::shared_ptr<Codec2Client::Component>
-        Codec2Client::CreateComponentByName(
+c2_status_t Codec2Client::CreateComponentByName(
         const char* componentName,
         const std::shared_ptr<Listener>& listener,
+        std::shared_ptr<Component>* component,
         std::shared_ptr<Codec2Client>* owner,
         size_t numberOfAttempts) {
     std::string key{"create:"};
     key.append(componentName);
-    std::shared_ptr<Component> component;
     c2_status_t status = ForAllServices(
             key,
             numberOfAttempts,
-            [owner, &component, componentName, &listener](
+            [owner, component, componentName, &listener](
                     const std::shared_ptr<Codec2Client> &client)
                         -> c2_status_t {
                 c2_status_t status = client->createComponent(componentName,
                                                              listener,
-                                                             &component);
+                                                             component);
                 if (status == C2_OK) {
                     if (owner) {
                         *owner = client;
@@ -1064,7 +1065,7 @@
                    << "\" from all known services. "
                       "Last returned status = " << status << ".";
     }
-    return component;
+    return status;
 }
 
 std::shared_ptr<Codec2Client::Interface>
diff --git a/media/codec2/hidl/client/include/codec2/hidl/client.h b/media/codec2/hidl/client/include/codec2/hidl/client.h
index ffd194a..bbb2b96 100644
--- a/media/codec2/hidl/client/include/codec2/hidl/client.h
+++ b/media/codec2/hidl/client/include/codec2/hidl/client.h
@@ -200,9 +200,10 @@
     // Try to create a component with a given name from all known
     // IComponentStore services. numberOfAttempts determines the number of times
     // to retry the HIDL call if the transaction fails.
-    static std::shared_ptr<Component> CreateComponentByName(
+    static c2_status_t CreateComponentByName(
             char const* componentName,
             std::shared_ptr<Listener> const& listener,
+            std::shared_ptr<Component>* component,
             std::shared_ptr<Codec2Client>* owner = nullptr,
             size_t numberOfAttempts = 10);
 
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 9c1df71..5de4d7f 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -247,15 +247,20 @@
             return NO_INIT;
         }
 
-        size_t numSlots = 4;
-        constexpr OMX_U32 kPortIndexInput = 0;
+        size_t numSlots = 16;
+        // WORKAROUND: having more slots improve performance while consuming
+        // more memory. This is a temporary workaround to reduce memory for
+        // larger-than-4K scenario.
+        if (mWidth * mHeight > 4096 * 2340) {
+            constexpr OMX_U32 kPortIndexInput = 0;
 
-        OMX_PARAM_PORTDEFINITIONTYPE param;
-        param.nPortIndex = kPortIndexInput;
-        status_t err = mNode->getParameter(OMX_IndexParamPortDefinition,
-                                           &param, sizeof(param));
-        if (err == OK) {
-            numSlots = param.nBufferCountActual;
+            OMX_PARAM_PORTDEFINITIONTYPE param;
+            param.nPortIndex = kPortIndexInput;
+            status_t err = mNode->getParameter(OMX_IndexParamPortDefinition,
+                                               &param, sizeof(param));
+            if (err == OK) {
+                numSlots = param.nBufferCountActual;
+            }
         }
 
         for (size_t i = 0; i < numSlots; ++i) {
@@ -645,17 +650,18 @@
                 std::make_shared<Codec2ClientInterfaceWrapper>(client));
     }
 
-    std::shared_ptr<Codec2Client::Component> comp =
-            Codec2Client::CreateComponentByName(
+    std::shared_ptr<Codec2Client::Component> comp;
+    c2_status_t status = Codec2Client::CreateComponentByName(
             componentName.c_str(),
             mClientListener,
+            &comp,
             &client);
-    if (!comp) {
-        ALOGE("Failed Create component: %s", componentName.c_str());
+    if (status != C2_OK) {
+        ALOGE("Failed Create component: %s, error=%d", componentName.c_str(), status);
         Mutexed<State>::Locked state(mState);
         state->set(RELEASED);
         state.unlock();
-        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        mCallback->onError((status == C2_NO_MEMORY ? NO_MEMORY : UNKNOWN_ERROR), ACTION_CODE_FATAL);
         state.lock();
         return;
     }
@@ -967,6 +973,7 @@
                 C2AndroidMemoryUsage androidUsage(C2MemoryUsage(usage.value));
                 config->mISConfig->mUsage = androidUsage.asGrallocUsage();
             }
+            config->mInputFormat->setInt64("android._C2MemoryUsage", usage.value);
         }
 
         // NOTE: we don't blindly use client specified input size if specified as clients
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index 566a18f..dd28b6a 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -807,8 +807,9 @@
         capacity = kMaxLinearBufferSize;
     }
 
-    // TODO: read usage from intf
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    int64_t usageValue = 0;
+    (void)format->findInt64("android._C2MemoryUsage", &usageValue);
+    C2MemoryUsage usage{usageValue | C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE};
     std::shared_ptr<C2LinearBlock> block;
 
     c2_status_t err = pool->fetchLinearBlock(capacity, usage, &block);
@@ -1040,8 +1041,9 @@
 }
 
 sp<Codec2Buffer> GraphicInputBuffers::createNewBuffer() {
-    // TODO: read usage from intf
-    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+    int64_t usageValue = 0;
+    (void)mFormat->findInt64("android._C2MemoryUsage", &usageValue);
+    C2MemoryUsage usage{usageValue | C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE};
     return AllocateGraphicBuffer(
             mPool, mFormat, HAL_PIXEL_FORMAT_YV12, usage, mLocalBufferPool);
 }
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index 62f0808..eb2246d 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -43,9 +43,6 @@
     long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
 }
 
-static constexpr int OGG_PAGE_FLAG_CONTINUED_PACKET = 1;
-static constexpr int OGG_PAGE_FLAG_END_OF_STREAM = 4;
-
 namespace android {
 
 struct OggSource : public MediaTrackHelper {
@@ -300,8 +297,7 @@
     AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
 
     *out = packet;
-    ALOGV("returning buffer %p, size %zu, length %zu",
-          packet, packet->size(), packet->range_length());
+    ALOGV("returning buffer %p", packet);
     return AMEDIA_OK;
 }
 
@@ -362,10 +358,10 @@
 
         if (!memcmp(signature, "OggS", 4)) {
             if (*pageOffset > startOffset) {
-                ALOGV("skipped %lld bytes of junk at %lld to reach next frame",
-                     (long long)(*pageOffset - startOffset), (long long)(startOffset));
+                ALOGV("skipped %lld bytes of junk to reach next frame",
+                     (long long)(*pageOffset - startOffset));
             }
-            ALOGV("found frame at %lld", (long long)(*pageOffset));
+
             return OK;
         }
 
@@ -633,8 +629,7 @@
     // Calculate timestamps by accumulating durations starting from the first sample of a page;
     // We assume that we only seek to page boundaries.
     AMediaFormat *meta = (*out)->meta_data();
-    if (AMediaFormat_getInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, &currentPageSamples) &&
-            (mCurrentPage.mFlags & OGG_PAGE_FLAG_END_OF_STREAM)) {
+    if (AMediaFormat_getInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, &currentPageSamples)) {
         // first packet in page
         if (mOffset == mFirstDataOffset) {
             currentPageSamples -= mStartGranulePosition;
@@ -817,7 +812,6 @@
             }
             buffer = tmp;
 
-            ALOGV("reading %zu bytes @ %zu", packetSize, size_t(dataOffset));
             ssize_t n = mSource->readAt(
                     dataOffset,
                     (uint8_t *)buffer->data() + buffer->range_length(),
@@ -836,9 +830,8 @@
 
             if (gotFullPacket) {
                 // We've just read the entire packet.
-                ALOGV("got full packet, size %zu", fullSize);
 
-                if (mFirstPacketInPage && (mCurrentPage.mFlags & OGG_PAGE_FLAG_END_OF_STREAM)) {
+                if (mFirstPacketInPage) {
                     AMediaFormat *meta = buffer->meta_data();
                     AMediaFormat_setInt32(
                             meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
@@ -871,9 +864,6 @@
             }
 
             // fall through, the buffer now contains the start of the packet.
-            ALOGV("have start of packet, getting rest");
-        } else {
-            ALOGV("moving to next page");
         }
 
         CHECK_EQ(mNextLaceIndex, mCurrentPage.mNumSegments);
@@ -909,10 +899,9 @@
         mNextLaceIndex = 0;
 
         if (buffer != NULL) {
-            if ((mCurrentPage.mFlags & OGG_PAGE_FLAG_CONTINUED_PACKET) == 0) {
+            if ((mCurrentPage.mFlags & 1) == 0) {
                 // This page does not continue the packet, i.e. the packet
                 // is already complete.
-                ALOGV("packet was already complete?!");
 
                 if (timeUs >= 0) {
                     AMediaFormat *meta = buffer->meta_data();
@@ -920,10 +909,8 @@
                 }
 
                 AMediaFormat *meta = buffer->meta_data();
-                if (mCurrentPage.mFlags & OGG_PAGE_FLAG_END_OF_STREAM) {
-                    AMediaFormat_setInt32(
-                            meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
-                }
+                AMediaFormat_setInt32(
+                        meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
                 mFirstPacketInPage = false;
 
                 *out = buffer;
@@ -942,7 +929,6 @@
     for (size_t i = 0; i < mNumHeaders; ++i) {
         // ignore timestamp for configuration packets
         if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != AMEDIA_OK) {
-            ALOGV("readNextPacket failed");
             return err;
         }
         ALOGV("read packet of size %zu\n", packet->range_length());
@@ -1022,10 +1008,6 @@
 
     size_t size = buffer->range_length();
 
-    if (size == 0) {
-        return 0;
-    }
-
     ogg_buffer buf;
     buf.data = (uint8_t *)data;
     buf.size = size;
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 84a75dd..2187635 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -53,6 +53,7 @@
 std::set<audio_error_callback> AudioSystem::gAudioErrorCallbacks;
 dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
 record_config_callback AudioSystem::gRecordConfigCallback = NULL;
+routing_callback AudioSystem::gRoutingCallback = NULL;
 
 // Required to be held while calling into gSoundTriggerCaptureStateListener.
 class CaptureStateListenerImpl;
@@ -771,6 +772,12 @@
     gRecordConfigCallback = cb;
 }
 
+/*static*/ void AudioSystem::setRoutingCallback(routing_callback cb)
+{
+    Mutex::Autolock _l(gLock);
+    gRoutingCallback = cb;
+}
+
 // client singleton for AudioPolicyService binder interface
 // protected by gLockAPS
 sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;
@@ -1914,6 +1921,19 @@
     return Status::ok();
 }
 
+Status AudioSystem::AudioPolicyServiceClient::onRoutingUpdated() {
+    routing_callback cb = NULL;
+    {
+        Mutex::Autolock _l(AudioSystem::gLock);
+        cb = gRoutingCallback;
+    }
+
+    if (cb != NULL) {
+        cb();
+    }
+    return Status::ok();
+}
+
 void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)
 {
     {
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 1b1e143..d4cbbc3 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1609,9 +1609,11 @@
 
     media::CreateTrackResponse response;
     status = audioFlinger->createTrack(VALUE_OR_FATAL(input.toAidl()), response);
-    IAudioFlinger::CreateTrackOutput output = VALUE_OR_FATAL(
-            IAudioFlinger::CreateTrackOutput::fromAidl(
-                    response));
+
+    IAudioFlinger::CreateTrackOutput output{};
+    if (status == NO_ERROR) {
+        output = VALUE_OR_FATAL(IAudioFlinger::CreateTrackOutput::fromAidl(response));
+    }
 
     if (status != NO_ERROR || output.outputId == AUDIO_IO_HANDLE_NONE) {
         ALOGE("%s(%d): AudioFlinger could not create track, status: %d output %d",
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyServiceClient.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyServiceClient.aidl
index a8d79b5..a7782b8 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyServiceClient.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyServiceClient.aidl
@@ -44,4 +44,6 @@
                                         in EffectDescriptor[] effects,
                                         int /* audio_patch_handle_t */ patchHandle,
                                         AudioSourceType source);
+     /** Notifies a change of audio routing */
+     void onRoutingUpdated();
 }
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 17ce56e..71b1e33 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -65,6 +65,7 @@
                                        std::vector<effect_descriptor_t> effects,
                                        audio_patch_handle_t patchHandle,
                                        audio_source_t source);
+typedef void (*routing_callback)();
 
 class IAudioFlinger;
 class IAudioPolicyService;
@@ -138,6 +139,7 @@
 
     static void setDynPolicyCallback(dynamic_policy_callback cb);
     static void setRecordConfigCallback(record_config_callback);
+    static void setRoutingCallback(routing_callback cb);
 
     // helper function to obtain AudioFlinger service handle
     static const sp<IAudioFlinger> get_audio_flinger();
@@ -630,6 +632,7 @@
                 const std::vector<media::EffectDescriptor>& effects,
                 int32_t patchHandle,
                 media::AudioSourceType source) override;
+        binder::Status onRoutingUpdated();
 
     private:
         Mutex                               mLock;
@@ -656,6 +659,7 @@
     static std::set<audio_error_callback> gAudioErrorCallbacks;
     static dynamic_policy_callback gDynPolicyCallback;
     static record_config_callback gRecordConfigCallback;
+    static routing_callback gRoutingCallback;
 
     static size_t gInBuffSize;
     // previous parameters for recording buffer size queries
diff --git a/media/libaudiohal/impl/DeviceHalLocal.h b/media/libaudiohal/impl/DeviceHalLocal.h
index 195204b..46b510b 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.h
+++ b/media/libaudiohal/impl/DeviceHalLocal.h
@@ -117,6 +117,8 @@
     void closeOutputStream(struct audio_stream_out *stream_out);
     void closeInputStream(struct audio_stream_in *stream_in);
 
+    uint32_t version() const { return mDev->common.version; }
+
   private:
     audio_hw_device_t *mDev;
 
@@ -127,8 +129,6 @@
 
     // The destructor automatically closes the device.
     virtual ~DeviceHalLocal();
-
-    uint32_t version() const { return mDev->common.version; }
 };
 
 } // namespace CPP_VERSION
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 2726e36..09a7c1c 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -25,6 +25,7 @@
 
 #include "DeviceHalHidl.h"
 #include "EffectHalHidl.h"
+#include "HidlUtils.h"
 #include "StreamHalHidl.h"
 #include "VersionUtils.h"
 
@@ -610,12 +611,25 @@
         const StreamOutHalInterface::SourceMetadata& sourceMetadata) {
     CPP_VERSION::SourceMetadata halMetadata = {
         .tracks = transformToHidlVec(sourceMetadata.tracks,
-              [](const playback_track_metadata& metadata) -> PlaybackTrackMetadata {
-                  return {
-                    .usage=static_cast<AudioUsage>(metadata.usage),
-                    .contentType=static_cast<AudioContentType>(metadata.content_type),
-                    .gain=metadata.gain,
+              [](const playback_track_metadata_v7& metadata) -> PlaybackTrackMetadata {
+                  PlaybackTrackMetadata halTrackMetadata = {
+                      .usage=static_cast<AudioUsage>(metadata.base.usage),
+                      .contentType=static_cast<AudioContentType>(metadata.base.content_type),
+                      .gain=metadata.base.gain,
                   };
+#if MAJOR_VERSION >= 7
+                  HidlUtils::audioChannelMaskFromHal(metadata.channel_mask, false /*isInput*/,
+                                                    &halTrackMetadata.channelMask);
+
+                  std::istringstream tags{metadata.tags};
+                  std::string tag;
+                  while (std::getline(tags, tag, HidlUtils::sAudioTagSeparator)) {
+                      if (!tag.empty()) {
+                          halTrackMetadata.tags.push_back(tag);
+                      }
+                  }
+#endif
+                  return halTrackMetadata;
               })};
     return processReturn("updateSourceMetadata", mStream->updateSourceMetadata(halMetadata));
 }
@@ -902,11 +916,23 @@
         StreamInHalInterface::SinkMetadata& sinkMetadata) {
     CPP_VERSION::SinkMetadata halMetadata = {
         .tracks = transformToHidlVec(sinkMetadata.tracks,
-              [](const record_track_metadata& metadata) -> RecordTrackMetadata {
-                  return {
-                    .source=static_cast<AudioSource>(metadata.source),
-                    .gain=metadata.gain,
+              [](const record_track_metadata_v7& metadata) -> RecordTrackMetadata {
+                  RecordTrackMetadata halTrackMetadata = {
+                      .source=static_cast<AudioSource>(metadata.base.source),
+                      .gain=metadata.base.gain,
                   };
+#if MAJOR_VERSION >= 7
+                  HidlUtils::audioChannelMaskFromHal(metadata.channel_mask, true /*isInput*/,
+                                                    &halTrackMetadata.channelMask);
+                  std::istringstream tags{metadata.tags};
+                  std::string tag;
+                  while (std::getline(tags, tag, HidlUtils::sAudioTagSeparator)) {
+                      if (!tag.empty()) {
+                          halTrackMetadata.tags.push_back(tag);
+                      }
+                  }
+#endif
+                  return halTrackMetadata;
               })};
     return processReturn("updateSinkMetadata", mStream->updateSinkMetadata(halMetadata));
 }
diff --git a/media/libaudiohal/impl/StreamHalLocal.cpp b/media/libaudiohal/impl/StreamHalLocal.cpp
index 69be303..f544e06 100644
--- a/media/libaudiohal/impl/StreamHalLocal.cpp
+++ b/media/libaudiohal/impl/StreamHalLocal.cpp
@@ -241,19 +241,55 @@
     return mStream->get_presentation_position(mStream, frames, timestamp);
 }
 
-status_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
-    if (mStream->update_source_metadata == nullptr) {
-        return INVALID_OPERATION;
+void StreamOutHalLocal::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) {
+    std::vector<playback_track_metadata> halTracks;
+    halTracks.reserve(sourceMetadata.tracks.size());
+    for (auto& metadata : sourceMetadata.tracks) {
+        playback_track_metadata halTrackMetadata;
+        playback_track_metadata_from_v7(&halTrackMetadata, &metadata);
+        halTracks.push_back(halTrackMetadata);
     }
+    const source_metadata_t halMetadata = {
+        .track_count = halTracks.size(),
+        .tracks = halTracks.data(),
+    };
+    mStream->update_source_metadata(mStream, &halMetadata);
+}
+
+#if MAJOR_VERSION >= 7
+void StreamOutHalLocal::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) {
     const source_metadata_t metadata {
         .track_count = sourceMetadata.tracks.size(),
         // const cast is fine as it is in a const structure
-        .tracks = const_cast<playback_track_metadata*>(sourceMetadata.tracks.data()),
+        .tracks = const_cast<playback_track_metadata_v7*>(sourceMetadata.tracks.data()),
     };
-    mStream->update_source_metadata(mStream, &metadata);
+    mStream->update_source_metadata_v7(mStream, &metadata);
+}
+#endif
+
+status_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
+#if MAJOR_VERSION < 7
+    if (mStream->update_source_metadata == nullptr) {
+        return INVALID_OPERATION;
+    }
+    doUpdateSourceMetadata(sourceMetadata);
+#else
+    if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2)
+        if (mStream->update_source_metadata == nullptr) {
+            return INVALID_OPERATION;
+        }
+        doUpdateSourceMetadata(sourceMetadata);
+    } else {
+        if (mStream->update_source_metadata_v7 == nullptr) {
+            return INVALID_OPERATION;
+        }
+        doUpdateSourceMetadataV7(sourceMetadata);
+    }
+#endif
     return OK;
 }
 
+
 status_t StreamOutHalLocal::start() {
     if (mStream->start == NULL) return INVALID_OPERATION;
     return mStream->start(mStream);
@@ -352,16 +388,52 @@
     return mStream->get_capture_position(mStream, frames, time);
 }
 
-status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
-    if (mStream->update_sink_metadata == nullptr) {
-        return INVALID_OPERATION;
+void StreamInHalLocal::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) {
+    std::vector<record_track_metadata> halTracks;
+    halTracks.reserve(sinkMetadata.tracks.size());
+    for (auto& metadata : sinkMetadata.tracks) {
+        record_track_metadata halTrackMetadata;
+        record_track_metadata_from_v7(&halTrackMetadata, &metadata);
+        halTracks.push_back(halTrackMetadata);
     }
-    const sink_metadata_t metadata {
+    const sink_metadata_t halMetadata = {
+        .track_count = halTracks.size(),
+        .tracks = halTracks.data(),
+    };
+    mStream->update_sink_metadata(mStream, &halMetadata);
+}
+
+#if MAJOR_VERSION >= 7
+void StreamInHalLocal::doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata) {
+    const sink_metadata_v7_t halMetadata {
         .track_count = sinkMetadata.tracks.size(),
         // const cast is fine as it is in a const structure
-        .tracks = const_cast<record_track_metadata*>(sinkMetadata.tracks.data()),
+        .tracks = const_cast<record_track_metadata_v7*>(sinkMetadata.tracks.data()),
     };
-    mStream->update_sink_metadata(mStream, &metadata);
+    mStream->update_sink_metadata_v7(mStream, &halMetadata);
+}
+#endif
+
+status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
+#if MAJOR_VERSION < 7
+
+    if (mStream->update_sink_metadata == nullptr) {
+        return INVALID_OPERATION;  // not supported by the HAL
+    }
+    doUpdateSinkMetadata(sinkMetadata);
+#else
+    if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2)
+        if (mStream->update_sink_metadata == nullptr) {
+            return INVALID_OPERATION;  // not supported by the HAL
+        }
+        doUpdateSinkMetadata(sinkMetadata);
+    } else {
+        if (mStream->update_sink_metadata_v7 == nullptr) {
+            return INVALID_OPERATION;  // not supported by the HAL
+        }
+        doUpdateSinkMetadataV7(sinkMetadata);
+    }
+#endif
     return OK;
 }
 
diff --git a/media/libaudiohal/impl/StreamHalLocal.h b/media/libaudiohal/impl/StreamHalLocal.h
index d17f9f3..8e5180f 100644
--- a/media/libaudiohal/impl/StreamHalLocal.h
+++ b/media/libaudiohal/impl/StreamHalLocal.h
@@ -173,6 +173,9 @@
     static int asyncCallback(stream_callback_event_t event, void *param, void *cookie);
 
     static int asyncEventCallback(stream_event_callback_type_t event, void *param, void *cookie);
+
+    void doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata);
+    void doUpdateSourceMetadata(const SourceMetadata& sourceMetadata);
 };
 
 class StreamInHalLocal : public StreamInHalInterface, public StreamHalLocal {
@@ -227,6 +230,9 @@
     StreamInHalLocal(audio_stream_in_t *stream, sp<DeviceHalLocal> device);
 
     virtual ~StreamInHalLocal();
+
+    void doUpdateSinkMetadata(const SinkMetadata& sinkMetadata);
+    void doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata);
 };
 
 } // namespace CPP_VERSION
diff --git a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
index e30cb72..523705e 100644
--- a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
@@ -158,7 +158,7 @@
     virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) = 0;
 
     struct SourceMetadata {
-        std::vector<playback_track_metadata_t> tracks;
+        std::vector<playback_track_metadata_v7_t> tracks;
     };
     /**
      * Called when the metadata of the stream's source has been changed.
@@ -197,7 +197,7 @@
     virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
 
     struct SinkMetadata {
-        std::vector<record_track_metadata_t> tracks;
+        std::vector<record_track_metadata_v7_t> tracks;
     };
     /**
      * Called when the metadata of the stream's sink has been changed.
diff --git a/media/libeffects/lvm/benchmarks/Android.bp b/media/libeffects/lvm/benchmarks/Android.bp
index 420e172..930292f 100644
--- a/media/libeffects/lvm/benchmarks/Android.bp
+++ b/media/libeffects/lvm/benchmarks/Android.bp
@@ -14,3 +14,24 @@
         "libhardware_headers",
     ],
 }
+
+cc_benchmark {
+    name: "reverb_benchmark",
+    vendor: true,
+    include_dirs: [
+        "frameworks/av/media/libeffects/lvm/wrapper/Reverb",
+    ],
+    srcs: ["reverb_benchmark.cpp"],
+    static_libs: [
+        "libreverb",
+        "libreverbwrapper",
+    ],
+    shared_libs: [
+        "libaudioutils",
+        "liblog",
+    ],
+    header_libs: [
+        "libaudioeffects",
+        "libhardware_headers",
+    ],
+}
diff --git a/media/libeffects/lvm/benchmarks/reverb_benchmark.cpp b/media/libeffects/lvm/benchmarks/reverb_benchmark.cpp
new file mode 100644
index 0000000..00a7ff2
--- /dev/null
+++ b/media/libeffects/lvm/benchmarks/reverb_benchmark.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2020 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 <array>
+#include <climits>
+#include <cstdlib>
+#include <random>
+#include <vector>
+#include <log/log.h>
+#include <benchmark/benchmark.h>
+#include <hardware/audio_effect.h>
+#include <system/audio.h>
+#include "EffectReverb.h"
+
+extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
+constexpr effect_uuid_t kEffectUuids[] = {
+        {0x172cdf00,
+         0xa3bc,
+         0x11df,
+         0xa72f,
+         {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // preset-insert mode
+        {0xf29a1400,
+         0xa3bb,
+         0x11df,
+         0x8ddc,
+         {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // preset-aux mode
+};
+
+constexpr size_t kNumEffectUuids = std::size(kEffectUuids);
+
+constexpr size_t kFrameCount = 2048;
+
+constexpr int kPresets[] = {
+        REVERB_PRESET_NONE,      REVERB_PRESET_SMALLROOM,  REVERB_PRESET_MEDIUMROOM,
+        REVERB_PRESET_LARGEROOM, REVERB_PRESET_MEDIUMHALL, REVERB_PRESET_LARGEHALL,
+        REVERB_PRESET_PLATE,
+};
+
+constexpr size_t kNumPresets = std::size(kPresets);
+
+constexpr int kSampleRate = 44100;
+
+int reverbSetConfigParam(uint32_t paramType, uint32_t paramValue, effect_handle_t effectHandle) {
+    int reply = 0;
+    uint32_t replySize = sizeof(reply);
+    uint32_t paramData[2] = {paramType, paramValue};
+    auto effectParam = (effect_param_t*)malloc(sizeof(effect_param_t) + sizeof(paramData));
+    memcpy(&effectParam->data[0], &paramData[0], sizeof(paramData));
+    effectParam->psize = sizeof(paramData[0]);
+    effectParam->vsize = sizeof(paramData[1]);
+    int status = (*effectHandle)
+                         ->command(effectHandle, EFFECT_CMD_SET_PARAM,
+                                   sizeof(effect_param_t) + sizeof(paramData), effectParam,
+                                   &replySize, &reply);
+    free(effectParam);
+    if (status != 0) {
+        ALOGE("Reverb set config returned an error = %d\n", status);
+        return status;
+    }
+    return reply;
+}
+
+/*******************************************************************
+ * A test result running on Pixel 3 with for comparison.
+ * The first parameter indicates the preset level id.
+ * The second parameter indicates the effect.
+ * 0: preset-insert mode, 1: preset-aux mode
+ * --------------------------------------------------------
+ * Benchmark              Time             CPU   Iterations
+ * --------------------------------------------------------
+ * BM_REVERB/0/0      19312 ns        19249 ns        36282
+ * BM_REVERB/0/1       5613 ns         5596 ns       125032
+ * BM_REVERB/1/0     605453 ns       603714 ns         1131
+ * BM_REVERB/1/1     589421 ns       587758 ns         1161
+ * BM_REVERB/2/0     605760 ns       604006 ns         1131
+ * BM_REVERB/2/1     589434 ns       587777 ns         1161
+ * BM_REVERB/3/0     605574 ns       603828 ns         1131
+ * BM_REVERB/3/1     589566 ns       587862 ns         1162
+ * BM_REVERB/4/0     605634 ns       603894 ns         1131
+ * BM_REVERB/4/1     589506 ns       587856 ns         1161
+ * BM_REVERB/5/0     605644 ns       603929 ns         1131
+ * BM_REVERB/5/1     589592 ns       587863 ns         1161
+ * BM_REVERB/6/0     610544 ns       608561 ns         1131
+ * BM_REVERB/6/1     589686 ns       587871 ns         1161
+ *******************************************************************/
+
+static void BM_REVERB(benchmark::State& state) {
+    const size_t chMask = AUDIO_CHANNEL_OUT_STEREO;
+    const size_t preset = kPresets[state.range(0)];
+    const effect_uuid_t uuid = kEffectUuids[state.range(1)];
+    const size_t channelCount = audio_channel_count_from_out_mask(chMask);
+
+    // Initialize input buffer with deterministic pseudo-random values
+    std::minstd_rand gen(chMask);
+    std::uniform_real_distribution<> dis(-1.0f, 1.0f);
+    std::vector<float> input(kFrameCount * channelCount);
+    std::vector<float> output(kFrameCount * channelCount);
+    for (auto& in : input) {
+        in = dis(gen);
+    }
+
+    effect_handle_t effectHandle = nullptr;
+    if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&uuid, 1, 1, &effectHandle);
+        status != 0) {
+        ALOGE("create_effect returned an error = %d\n", status);
+        return;
+    }
+
+    effect_config_t config{};
+    config.inputCfg.samplingRate = config.outputCfg.samplingRate = kSampleRate;
+    config.inputCfg.channels = config.outputCfg.channels = chMask;
+    config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
+
+    int reply = 0;
+    uint32_t replySize = sizeof(reply);
+    if (int status = (*effectHandle)
+                             ->command(effectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t),
+                                       &config, &replySize, &reply);
+        status != 0) {
+        ALOGE("command returned an error = %d\n", status);
+        return;
+    }
+
+    if (int status =
+                (*effectHandle)
+                        ->command(effectHandle, EFFECT_CMD_ENABLE, 0, nullptr, &replySize, &reply);
+        status != 0) {
+        ALOGE("Command enable call returned error %d\n", reply);
+        return;
+    }
+
+    if (int status = reverbSetConfigParam(REVERB_PARAM_PRESET, preset, effectHandle); status != 0) {
+        ALOGE("Invalid reverb preset. Error %d\n", status);
+        return;
+    }
+
+    // Run the test
+    for (auto _ : state) {
+        benchmark::DoNotOptimize(input.data());
+        benchmark::DoNotOptimize(output.data());
+
+        audio_buffer_t inBuffer = {.frameCount = kFrameCount, .f32 = input.data()};
+        audio_buffer_t outBuffer = {.frameCount = kFrameCount, .f32 = output.data()};
+        (*effectHandle)->process(effectHandle, &inBuffer, &outBuffer);
+
+        benchmark::ClobberMemory();
+    }
+
+    state.SetComplexityN(state.range(0));
+
+    if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle); status != 0) {
+        ALOGE("release_effect returned an error = %d\n", status);
+        return;
+    }
+}
+
+static void REVERBArgs(benchmark::internal::Benchmark* b) {
+    for (int i = 0; i < kNumPresets; i++) {
+        for (int j = 0; j < kNumEffectUuids; ++j) {
+            b->Args({i, j});
+        }
+    }
+}
+
+BENCHMARK(BM_REVERB)->Apply(REVERBArgs);
+
+BENCHMARK_MAIN();
diff --git a/media/libeffects/lvm/lib/Android.bp b/media/libeffects/lvm/lib/Android.bp
index dbe0d62..8a37afa 100644
--- a/media/libeffects/lvm/lib/Android.bp
+++ b/media/libeffects/lvm/lib/Android.bp
@@ -69,28 +69,20 @@
         "Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp",
         "Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp",
         "Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.cpp",
-        "Common/src/Int16LShiftToInt32_16x32.cpp",
-        "Common/src/From2iToMono_16.cpp",
         "Common/src/Copy_16.cpp",
-        "Common/src/MonoTo2I_16.cpp",
         "Common/src/MonoTo2I_32.cpp",
-        "Common/src/LoadConst_16.cpp",
         "Common/src/LoadConst_32.cpp",
         "Common/src/dB_to_Lin32.cpp",
         "Common/src/Shift_Sat_v16xv16.cpp",
         "Common/src/Shift_Sat_v32xv32.cpp",
         "Common/src/Abs_32.cpp",
-        "Common/src/Int32RShiftToInt16_Sat_32x16.cpp",
         "Common/src/From2iToMono_32.cpp",
-        "Common/src/mult3s_16x16.cpp",
         "Common/src/Mult3s_32x16.cpp",
         "Common/src/NonLinComp_D16.cpp",
         "Common/src/DelayMix_16x16.cpp",
         "Common/src/MSTo2i_Sat_16x16.cpp",
         "Common/src/From2iToMS_16x16.cpp",
-        "Common/src/Mac3s_Sat_16x16.cpp",
         "Common/src/Mac3s_Sat_32x16.cpp",
-        "Common/src/Add2_Sat_16x16.cpp",
         "Common/src/Add2_Sat_32x32.cpp",
         "Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp",
         "Common/src/LVC_MixSoft_1St_D16C31_SAT.cpp",
@@ -168,16 +160,13 @@
         "Reverb/src/LVREV_Tables.cpp",
         "Common/src/Abs_32.cpp",
         "Common/src/InstAlloc.cpp",
-        "Common/src/LoadConst_16.cpp",
         "Common/src/LoadConst_32.cpp",
         "Common/src/From2iToMono_32.cpp",
         "Common/src/Mult3s_32x16.cpp",
         "Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp",
         "Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp",
-        "Common/src/DelayAllPass_Sat_32x16To32.cpp",
         "Common/src/Copy_16.cpp",
         "Common/src/Mac3s_Sat_32x16.cpp",
-        "Common/src/DelayWrite_32.cpp",
         "Common/src/Shift_Sat_v32xv32.cpp",
         "Common/src/Add2_Sat_32x32.cpp",
         "Common/src/JoinTo2i_32x32.cpp",
@@ -204,10 +193,12 @@
         "Reverb/lib",
         "Common/lib",
     ],
-
+    static_libs: [
+        "libaudioutils",
+    ],
     cppflags: [
+        "-DBIQUAD_OPT",
         "-fvisibility=hidden",
-
         "-Wall",
         "-Werror",
     ],
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.cpp b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.cpp
index 1f0b459..814280f 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.cpp
@@ -23,6 +23,7 @@
 
 #ifdef BIQUAD_OPT
 #include <audio_utils/BiquadFilter.h>
+#include <system/audio.h>
 #endif
 #include "LVDBE.h"
 #include "LVDBE_Private.h"
@@ -114,7 +115,7 @@
     std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
             LVDBE_HPF_Table[Offset].A0, LVDBE_HPF_Table[Offset].A1, LVDBE_HPF_Table[Offset].A2,
             -(LVDBE_HPF_Table[Offset].B1), -(LVDBE_HPF_Table[Offset].B2)};
-    pInstance->pBqInstance
+    pInstance->pHPFBiquad
             ->setCoefficients<std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(coefs);
 #else
     LoadConst_Float(0,                                      /* Clear the history, value 0 */
@@ -128,12 +129,19 @@
     /*
      * Setup the band pass filter
      */
+#ifdef BIQUAD_OPT
+    coefs = {LVDBE_BPF_Table[Offset].A0, 0.0, -(LVDBE_BPF_Table[Offset].A0),
+             -(LVDBE_BPF_Table[Offset].B1), -(LVDBE_BPF_Table[Offset].B2)};
+    pInstance->pBPFBiquad
+            ->setCoefficients<std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(coefs);
+#else
     LoadConst_Float(0,                                      /* Clear the history, value 0 */
                     (LVM_FLOAT*)&pInstance->pData->BPFTaps, /* Destination */
                     sizeof(pInstance->pData->BPFTaps) / sizeof(LVM_FLOAT)); /* Number of words */
     BP_1I_D32F32Cll_TRC_WRA_02_Init(&pInstance->pCoef->BPFInstance, /* Initialise the filter */
                                     &pInstance->pData->BPFTaps,
                                     (BP_FLOAT_Coefs_t*)&LVDBE_BPF_Table[Offset]);
+#endif
 }
 
 /************************************************************************************/
@@ -290,9 +298,8 @@
     /*
      * Create biquad instance
      */
-    pInstance->pBqInstance.reset(
-            new android::audio_utils::BiquadFilter<LVM_FLOAT>(pParams->NrChannels));
-    pInstance->pBqInstance->clear();
+    pInstance->pHPFBiquad.reset(new android::audio_utils::BiquadFilter<LVM_FLOAT>(
+            (FCC_1 == pParams->NrChannels) ? FCC_2 : pParams->NrChannels));
 #endif
 
     /*
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
index 611b762..6bdb7fe 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
@@ -20,8 +20,11 @@
 /*    Includes                                                                          */
 /*                                                                                      */
 /****************************************************************************************/
-#include <stdlib.h>
 
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
+#include <stdlib.h>
 #include "LVDBE.h"
 #include "LVDBE_Private.h"
 
@@ -89,17 +92,18 @@
     if (pInstance->pData == NULL) {
         return LVDBE_NULLADDRESS;
     }
-    pInstance->pCoef = (LVDBE_Coef_FLOAT_t*)calloc(1, sizeof(*(pInstance->pCoef)));
-    if (pInstance->pCoef == NULL) {
-        return LVDBE_NULLADDRESS;
-    }
-
 #ifdef BIQUAD_OPT
     /*
      * Create biquad instance
      */
-    pInstance->pBqInstance.reset(
+    pInstance->pHPFBiquad.reset(
             new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+    pInstance->pBPFBiquad.reset(new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1));
+#else
+    pInstance->pCoef = (LVDBE_Coef_FLOAT_t*)calloc(1, sizeof(*(pInstance->pCoef)));
+    if (pInstance->pCoef == NULL) {
+        return LVDBE_NULLADDRESS;
+    }
 #endif
 
     /*
@@ -190,10 +194,12 @@
         free(pInstance->pData);
         pInstance->pData = LVM_NULL;
     }
+#ifndef BIQUAD_OPT
     if (pInstance->pCoef != LVM_NULL) {
         free(pInstance->pCoef);
         pInstance->pCoef = LVM_NULL;
     }
+#endif
     free(pInstance);
     *phInstance = LVM_NULL;
 }
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
index fa85638..23be2aa 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
@@ -68,21 +68,22 @@
     /* Process variables */
 #ifndef BIQUAD_OPT
     Biquad_2I_Order2_FLOAT_Taps_t HPFTaps; /* High pass filter taps */
-#endif
     Biquad_1I_Order2_FLOAT_Taps_t BPFTaps; /* Band pass filter taps */
+#endif
     LVMixer3_1St_FLOAT_st BypassVolume;    /* Bypass volume scaler */
     LVMixer3_2St_FLOAT_st BypassMixer;     /* Bypass Mixer for Click Removal */
 
 } LVDBE_Data_FLOAT_t;
 
+#ifndef BIQUAD_OPT
 /* Coefs structure */
 typedef struct {
     /* Process variables */
-#ifndef BIQUAD_OPT
     Biquad_FLOAT_Instance_t HPFInstance; /* High pass filter instance */
-#endif
     Biquad_FLOAT_Instance_t BPFInstance; /* Band pass filter instance */
 } LVDBE_Coef_FLOAT_t;
+#endif
+
 /* Instance structure */
 typedef struct {
     /* Public parameters */
@@ -91,11 +92,15 @@
 
     /* Data and coefficient pointers */
     LVDBE_Data_FLOAT_t* pData; /* Instance data */
+#ifndef BIQUAD_OPT
     LVDBE_Coef_FLOAT_t* pCoef; /* Instance coefficients */
+#endif
     void* pScratch;            /* scratch pointer */
 #ifdef BIQUAD_OPT
     std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
-            pBqInstance; /* Biquad filter instance */
+            pHPFBiquad; /* Biquad filter instance for HPF */
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pBPFBiquad; /* Biquad filter instance for BPF */
 #endif
 } LVDBE_Instance_t;
 
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
index bd04a02..4a72834 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
@@ -129,7 +129,7 @@
          */
         if (pInstance->Params.HPFSelect == LVDBE_HPF_ON) {
 #ifdef BIQUAD_OPT
-            pInstance->pBqInstance->process(pScratch, pScratch, NrFrames);
+            pInstance->pHPFBiquad->process(pScratch, pScratch, NrFrames);
 #else
             BQ_MC_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance, /* Filter instance      */
                                        pScratch,                       /* Source               */
@@ -149,10 +149,14 @@
         /*
          * Apply the band pass filter
          */
+#ifdef BIQUAD_OPT
+        pInstance->pBPFBiquad->process(pMono, pMono, NrFrames);
+#else
         BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance       */
                                    pMono,                          /* Source                */
                                    pMono,                          /* Destination           */
                                    (LVM_INT16)NrFrames);
+#endif
 
         /*
          * Apply the AGC and mix
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp
index 3118e77..7e8664a 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.cpp
@@ -276,6 +276,16 @@
              */
             Offset = (LVM_INT16)(EffectLevel - 1 +
                                  TrebleBoostSteps * (pParams->SampleRate - TrebleBoostMinRate));
+#ifdef BIQUAD_OPT
+            /*
+             * Create biquad instance
+             */
+            std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                    LVM_TrebleBoostCoefs[Offset].A0, LVM_TrebleBoostCoefs[Offset].A1, 0.0,
+                    -(LVM_TrebleBoostCoefs[Offset].B1), 0.0};
+            pInstance->pTEBiquad.reset(
+                    new android::audio_utils::BiquadFilter<LVM_FLOAT>(pParams->NrChannels, coefs));
+#else
             FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(&pInstance->pTE_State->TrebleBoost_State,
                                                  &pInstance->pTE_Taps->TrebleBoost_Taps,
                                                  &LVM_TrebleBoostCoefs[Offset]);
@@ -288,6 +298,7 @@
                                                    Cast to void: no dereferencing in function */
                             (LVM_UINT16)(sizeof(pInstance->pTE_Taps->TrebleBoost_Taps) /
                                          sizeof(LVM_FLOAT))); /* Number of words */
+#endif
         }
     } else {
         /*
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp
index bb962df..bbfa0dc 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.cpp
@@ -174,6 +174,7 @@
     /*
      * Treble Enhancement
      */
+#ifndef BIQUAD_OPT
     pInstance->pTE_Taps = (LVM_TE_Data_t*)calloc(1, sizeof(*(pInstance->pTE_Taps)));
     if (pInstance->pTE_Taps == LVM_NULL) {
         return LVM_NULLADDRESS;
@@ -182,6 +183,7 @@
     if (pInstance->pTE_State == LVM_NULL) {
         return LVM_NULLADDRESS;
     }
+#endif
     pInstance->Params.TE_OperatingMode = LVM_TE_OFF;
     pInstance->Params.TE_EffectLevel = 0;
     pInstance->TE_Active = LVM_FALSE;
@@ -494,6 +496,7 @@
     /*
      * Treble Enhancement
      */
+#ifndef BIQUAD_OPT
     if (pInstance->pTE_Taps != LVM_NULL) {
         free(pInstance->pTE_Taps);
         pInstance->pTE_Taps = LVM_NULL;
@@ -502,6 +505,7 @@
         free(pInstance->pTE_State);
         pInstance->pTE_State = LVM_NULL;
     }
+#endif
 
     /*
      * Free the default EQNB pre-gain and pointer to the band definitions
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
index 90a1f19..56bbfd1 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
@@ -33,6 +33,9 @@
 /*                                                                                  */
 /************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVM.h"            /* LifeVibes */
 #include "LVM_Common.h"     /* LifeVibes common */
 #include "BIQUAD.h"         /* Biquad library */
@@ -127,6 +130,7 @@
     LVM_INT16 SamplesToOutput; /* Samples to write to the output */
 } LVM_Buffer_t;
 
+#ifndef BIQUAD_OPT
 /* Filter taps */
 typedef struct {
     Biquad_2I_Order1_FLOAT_Taps_t TrebleBoost_Taps; /* Treble boost Taps */
@@ -136,6 +140,7 @@
 typedef struct {
     Biquad_FLOAT_Instance_t TrebleBoost_State; /* State for the treble boost filter */
 } LVM_TE_Coefs_t;
+#endif
 
 typedef struct {
     /* Public parameters */
@@ -185,8 +190,13 @@
     LVM_INT16 VC_AVLFixedVolume;         /* AVL fixed volume */
 
     /* Treble Enhancement */
+#ifdef BIQUAD_OPT
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pTEBiquad; /* Biquad filter instance */
+#else
     LVM_TE_Data_t* pTE_Taps;   /* Treble boost Taps */
     LVM_TE_Coefs_t* pTE_State; /* State for the treble boost filter */
+#endif
     LVM_INT16 TE_Active;       /* Control flag */
 
     /* Headroom */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
index c94c469..acd594f 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
@@ -190,9 +190,13 @@
                 /*
                  * Apply the filter
                  */
+#ifdef BIQUAD_OPT
+                pInstance->pTEBiquad->process(pProcessed, pProcessed, NrFrames);
+#else
                 FO_Mc_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
                                                 pProcessed, pProcessed, (LVM_INT16)NrFrames,
                                                 (LVM_INT16)NrChannels);
+#endif
             }
             /*
              * Volume balance
diff --git a/media/libeffects/lvm/lib/Common/lib/AGC.h b/media/libeffects/lvm/lib/Common/lib/AGC.h
index c20b49a..31c8200 100644
--- a/media/libeffects/lvm/lib/Common/lib/AGC.h
+++ b/media/libeffects/lvm/lib/Common/lib/AGC.h
@@ -48,11 +48,6 @@
 /*    Function Prototypes                                                              */
 /*                                                                                */
 /**********************************************************************************/
-void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t* pInstance, /* Instance pointer */
-                                 const LVM_FLOAT* pStSrc,                /* Stereo source */
-                                 const LVM_FLOAT* pMonoSrc,              /* Mono source */
-                                 LVM_FLOAT* pDst,                        /* Stereo destination */
-                                 LVM_UINT16 n);                          /* Number of samples */
 void AGC_MIX_VOL_Mc1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t* pInstance,  /* Instance pointer */
                                 const LVM_FLOAT* pStSrc,                 /* Source */
                                 const LVM_FLOAT* pMonoSrc,               /* Mono source */
diff --git a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
index b38e9fb..1c36bab 100644
--- a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
+++ b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
@@ -161,8 +161,6 @@
                                           Biquad_2I_Order1_FLOAT_Taps_t* pTaps,
                                           FO_FLOAT_LShx_Coefs_t* pCoef);
 
-void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
-                                     LVM_FLOAT* pDataOut, LVM_INT16 NrSamples);
 /*** 32 bit data path *************************************************************/
 void FO_1I_D32F32Cll_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance,
                                      Biquad_1I_Order1_FLOAT_Taps_t* pTaps, FO_FLOAT_Coefs_t* pCoef);
@@ -193,8 +191,6 @@
 void PK_2I_D32F32CssGss_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance,
                                         Biquad_2I_Order2_FLOAT_Taps_t* pTaps,
                                         PK_FLOAT_Coefs_t* pCoef);
-void PK_2I_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
-                                   LVM_FLOAT* pDataOut, LVM_INT16 NrSamples);
 void PK_Mc_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
                                    LVM_FLOAT* pDataOut, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
 
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
index 66e3e79..281d941 100644
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -32,45 +32,16 @@
 void Copy_Float_Stereo_Mc(const LVM_FLOAT* src, LVM_FLOAT* StereoOut, LVM_FLOAT* dst,
                           LVM_INT16 NrFrames, LVM_INT32 NrChannels);
 
-/*********************************************************************************
- * note: In Mult3s_16x16() saturation of result is not taken care when           *
- *       overflow occurs.                                                        *
- *       For example when *src = 0x8000, val = *0x8000                           *
- *       The function gives the output as 0x8000 instead of 0x7fff               *
- *       This is the only case which will give wrong result.                     *
- *       For more information refer to Vector_Arithmetic.doc in /doc folder      *
- *********************************************************************************/
 void Mult3s_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n);
 
-/*********************************************************************************
- * note: In Mult3s_32x16() saturation of result is not taken care when           *
- *       overflow occurs.                                                        *
- *       For example when *src = 0x8000000, val = *0x8000                        *
- *       The function gives the output as 0x8000000 instead of 0x7fffffff        *
- *       This is the only extreme condition which is giving unexpected result    *
- *       For more information refer to Vector_Arithmetic.doc in /doc folder      *
- *********************************************************************************/
-void Mult3s_32x16(const LVM_INT32* src, const LVM_INT16 val, LVM_INT32* dst, LVM_INT16 n);
 void DelayMix_Float(const LVM_FLOAT* src, /* Source 1, to be delayed */
                     LVM_FLOAT* delay,     /* Delay buffer */
                     LVM_INT16 size,       /* Delay size */
                     LVM_FLOAT* dst,       /* Source/destination */
                     LVM_INT16* pOffset,   /* Delay offset */
                     LVM_INT16 n);         /* Number of stereo samples */
-void DelayWrite_32(const LVM_INT32* src,  /* Source 1, to be delayed */
-                   LVM_INT32* delay,      /* Delay buffer */
-                   LVM_UINT16 size,       /* Delay size */
-                   LVM_UINT16* pOffset,   /* Delay offset */
-                   LVM_INT16 n);
 void Add2_Sat_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n);
 void Mac3s_Sat_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n);
-void DelayAllPass_Sat_32x16To32(LVM_INT32* delay,           /* Delay buffer */
-                                LVM_UINT16 size,            /* Delay size */
-                                LVM_INT16 coeff,            /* All pass filter coefficient */
-                                LVM_UINT16 DelayOffset,     /* Simple delay offset */
-                                LVM_UINT16* pAllPassOffset, /* All pass filter delay offset */
-                                LVM_INT32* dst,             /* Source/destination */
-                                LVM_INT16 n);
 
 /**********************************************************************************
     SHIFT FUNCTIONS
@@ -87,15 +58,6 @@
 void From2iToMS_Float(const LVM_FLOAT* src, LVM_FLOAT* dstM, LVM_FLOAT* dstS, LVM_INT16 n);
 void JoinTo2i_Float(const LVM_FLOAT* srcL, const LVM_FLOAT* srcR, LVM_FLOAT* dst, LVM_INT16 n);
 
-/**********************************************************************************
-    DATA TYPE CONVERSION FUNCTIONS
-***********************************************************************************/
-
-void Int16LShiftToInt32_16x32(const LVM_INT16* src, LVM_INT32* dst, LVM_INT16 n, LVM_INT16 shift);
-
-void Int32RShiftToInt16_Sat_32x16(const LVM_INT32* src, LVM_INT16* dst, LVM_INT16 n,
-                                  LVM_INT16 shift);
-
 /**********************************************************************************/
 
 #endif /* _VECTOR_ARITHMETIC_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
index ae8cdad..8739aad 100644
--- a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
@@ -37,135 +37,6 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/* FUNCTION:                  AGC_MIX_VOL_2St1Mon_D32_WRA                               */
-/*                                                                                      */
-/* DESCRIPTION:                                                                         */
-/*    Apply AGC and mix signals                                                         */
-/*                                                                                      */
-/*                                                                                      */
-/*  StSrc   ------------------|                                                         */
-/*                            |                                                         */
-/*              ______       _|_        ________                                        */
-/*             |      |     |   |      |        |                                       */
-/*  MonoSrc -->| AGC  |---->| + |----->| Volume |------------------------------+--->    */
-/*             | Gain |     |___|      | Gain   |                              |        */
-/*             |______|                |________|                              |        */
-/*                /|\                               __________     ________    |        */
-/*                 |                               |          |   |        |   |        */
-/*                 |-------------------------------| AGC Gain |<--| Peak   |<--|        */
-/*                                                 | Update   |   | Detect |            */
-/*                                                 |__________|   |________|            */
-/*                                                                                      */
-/*                                                                                      */
-/* PARAMETERS:                                                                          */
-/*  pInstance               Instance pointer                                            */
-/*  pStereoIn               Stereo source                                               */
-/*  pMonoIn                 Mono band pass source                                       */
-/*  pStereoOut              Stereo destination                                          */
-/*                                                                                      */
-/* RETURNS:                                                                             */
-/*  Void                                                                                */
-/*                                                                                      */
-/* NOTES:                                                                               */
-/*                                                                                      */
-/****************************************************************************************/
-void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t* pInstance, /* Instance pointer */
-                                 const LVM_FLOAT* pStSrc,                /* Stereo source */
-                                 const LVM_FLOAT* pMonoSrc,              /* Mono source */
-                                 LVM_FLOAT* pDst,                        /* Stereo destination */
-                                 LVM_UINT16 NumSamples)                  /* Number of samples */
-{
-    /*
-     * General variables
-     */
-    LVM_UINT16 i;       /* Sample index */
-    LVM_FLOAT Left;     /* Left sample */
-    LVM_FLOAT Right;    /* Right sample */
-    LVM_FLOAT Mono;     /* Mono sample */
-    LVM_FLOAT AbsPeak;  /* Absolute peak signal */
-    LVM_FLOAT AGC_Mult; /* Short AGC gain */
-    LVM_FLOAT Vol_Mult; /* Short volume */
-
-    /*
-     * Instance control variables
-     */
-    LVM_FLOAT AGC_Gain = pInstance->AGC_Gain;       /* Get the current AGC gain */
-    LVM_FLOAT AGC_MaxGain = pInstance->AGC_MaxGain; /* Get maximum AGC gain */
-    LVM_FLOAT AGC_Attack = pInstance->AGC_Attack;   /* Attack scaler */
-    LVM_FLOAT AGC_Decay = (pInstance->AGC_Decay * (1 << (DECAY_SHIFT))); /* Decay scaler */
-    LVM_FLOAT AGC_Target = pInstance->AGC_Target;                        /* Get the target level */
-    LVM_FLOAT Vol_Current = pInstance->Volume;                           /* Actual volume setting */
-    LVM_FLOAT Vol_Target = pInstance->Target;                            /* Target volume setting */
-    LVM_FLOAT Vol_TC = pInstance->VolumeTC;                              /* Time constant */
-
-    /*
-     * Process on a sample by sample basis
-     */
-    for (i = 0; i < NumSamples; i++) /* For each sample */
-    {
-        /*
-         * Get the short scalers
-         */
-        AGC_Mult = (LVM_FLOAT)(AGC_Gain);    /* Get the short AGC gain */
-        Vol_Mult = (LVM_FLOAT)(Vol_Current); /* Get the short volume gain */
-
-        /*
-         * Get the input samples
-         */
-        Left = *pStSrc++;   /* Get the left sample */
-        Right = *pStSrc++;  /* Get the right sample */
-        Mono = *pMonoSrc++; /* Get the mono sample */
-
-        /*
-         * Apply the AGC gain to the mono input and mix with the stereo signal
-         */
-        Left += (Mono * AGC_Mult); /* Mix in the mono signal */
-        Right += (Mono * AGC_Mult);
-
-        /*
-         * Apply the volume and write to the output stream
-         */
-        Left = Left * Vol_Mult;
-        Right = Right * Vol_Mult;
-        *pDst++ = Left; /* Save the results */
-        *pDst++ = Right;
-
-        /*
-         * Update the AGC gain
-         */
-        AbsPeak = Abs_Float(Left) > Abs_Float(Right) ? Abs_Float(Left) : Abs_Float(Right);
-        if (AbsPeak > AGC_Target) {
-            /*
-             * The signal is too large so decrease the gain
-             */
-            AGC_Gain = AGC_Gain * AGC_Attack;
-        } else {
-            /*
-             * The signal is too small so increase the gain
-             */
-            if (AGC_Gain > AGC_MaxGain) {
-                AGC_Gain -= (AGC_Decay);
-            } else {
-                AGC_Gain += (AGC_Decay);
-            }
-        }
-
-        /*
-         * Update the gain
-         */
-        Vol_Current += (Vol_Target - Vol_Current) * ((LVM_FLOAT)Vol_TC / VOL_TC_FLOAT);
-    }
-
-    /*
-     * Update the parameters
-     */
-    pInstance->Volume = Vol_Current; /* Actual volume setting */
-    pInstance->AGC_Gain = AGC_Gain;
-
-    return;
-}
-/****************************************************************************************/
-/*                                                                                      */
 /* FUNCTION:                  AGC_MIX_VOL_Mc1Mon_D32_WRA                                */
 /*                                                                                      */
 /* DESCRIPTION:                                                                         */
diff --git a/media/libeffects/lvm/lib/Common/src/Abs_32.cpp b/media/libeffects/lvm/lib/Common/src/Abs_32.cpp
index 3e37d89..a79b973 100644
--- a/media/libeffects/lvm/lib/Common/src/Abs_32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Abs_32.cpp
@@ -21,27 +21,6 @@
 
 #include "ScalarArithmetic.h"
 
-/****************************************************************************************
- *  Name        : Abs_32()
- *  Input       : Signed 32-bit integer
- *  Output      :
- *  Returns     : Absolute value
- *  Description : Absolute value with maximum negative value corner case
- *  Remarks     :
- ****************************************************************************************/
-
-LVM_INT32 Abs_32(LVM_INT32 input) {
-    if (input < 0) {
-        if (input == (LVM_INT32)(0x80000000U)) {
-            /* The corner case, so set to the maximum positive value */
-            input = (LVM_INT32)0x7fffffff;
-        } else {
-            /* Negative input, so invert */
-            input = (LVM_INT32)(-input);
-        }
-    }
-    return input;
-}
 LVM_FLOAT Abs_Float(LVM_FLOAT input) {
     if (input < 0) {
         /* Negative input, so invert */
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.cpp b/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.cpp
deleted file mode 100644
index be20521..0000000
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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 FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION ADD2_SAT_16X16
-***********************************************************************************/
-
-void Add2_Sat_16x16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT32 Temp;
-    LVM_INT16 ii;
-    for (ii = n; ii != 0; ii--) {
-        Temp = ((LVM_INT32)*src) + ((LVM_INT32)*dst);
-        src++;
-
-        if (Temp > 0x00007FFF) {
-            *dst = 0x7FFF;
-        } else if (Temp < -0x00008000) {
-            *dst = -0x8000;
-        } else {
-            *dst = (LVM_INT16)Temp;
-        }
-        dst++;
-    }
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp
index 420f93e..5502e11 100644
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp
@@ -21,34 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION ADD2_SAT_32X32
-***********************************************************************************/
-
-void Add2_Sat_32x32(const LVM_INT32* src, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT32 a, b, c;
-    LVM_INT16 ii;
-    for (ii = n; ii != 0; ii--) {
-        a = *src;
-        src++;
-
-        b = *dst;
-        c = a + b;
-        if ((((c ^ a) & (c ^ b)) >> 31) != 0) /* overflow / underflow */
-        {
-            if (a < 0) {
-                c = 0x80000000L;
-            } else {
-                c = 0x7FFFFFFFL;
-            }
-        }
-
-        *dst = c;
-        dst++;
-    }
-    return;
-}
-
 void Add2_Sat_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_FLOAT Temp;
     LVM_INT16 ii;
@@ -67,4 +39,3 @@
     }
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
index 8887890..7046a94 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
@@ -18,53 +18,11 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
+#include <string.h>
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION COPY_16
-***********************************************************************************/
-
-void Copy_16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-
-    if (src > dst) {
-        for (ii = n; ii != 0; ii--) {
-            *dst = *src;
-            dst++;
-            src++;
-        }
-    } else {
-        src += n - 1;
-        dst += n - 1;
-        for (ii = n; ii != 0; ii--) {
-            *dst = *src;
-            dst--;
-            src--;
-        }
-    }
-
-    return;
-}
 void Copy_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-
-    if (src > dst) {
-        for (ii = n; ii != 0; ii--) {
-            *dst = *src;
-            dst++;
-            src++;
-        }
-    } else {
-        src += n - 1;
-        dst += n - 1;
-        for (ii = n; ii != 0; ii--) {
-            *dst = *src;
-            dst--;
-            src--;
-        }
-    }
-
+    memmove(dst, src, n * sizeof(LVM_FLOAT));
     return;
 }
 // Extract out the stereo channel pair from multichannel source.
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
index 2861be6..6e59fd9 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
@@ -18,47 +18,6 @@
 #include "BIQUAD.h"
 #include "DC_2I_D16_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
-void DC_2I_D16_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
-                          LVM_FLOAT* pDataOut, LVM_INT16 NrSamples) {
-    LVM_FLOAT LeftDC, RightDC;
-    LVM_FLOAT Diff;
-    LVM_INT32 j;
-    PFilter_FLOAT_State pBiquadState = (PFilter_FLOAT_State)pInstance;
-
-    LeftDC = pBiquadState->LeftDC;
-    RightDC = pBiquadState->RightDC;
-    for (j = NrSamples - 1; j >= 0; j--) {
-        /* Subtract DC and saturate */
-        Diff = *(pDataIn++) - (LeftDC);
-        if (Diff > 1.0f) {
-            Diff = 1.0f;
-        } else if (Diff < -1.0f) {
-            Diff = -1.0f;
-        }
-        *(pDataOut++) = (LVM_FLOAT)Diff;
-        if (Diff < 0) {
-            LeftDC -= DC_FLOAT_STEP;
-        } else {
-            LeftDC += DC_FLOAT_STEP;
-        }
-
-        /* Subtract DC an saturate */
-        Diff = *(pDataIn++) - (RightDC);
-        if (Diff > 1.0f) {
-            Diff = 1.0f;
-        } else if (Diff < -1.0f) {
-            Diff = -1.0f;
-        }
-        *(pDataOut++) = (LVM_FLOAT)Diff;
-        if (Diff < 0) {
-            RightDC -= DC_FLOAT_STEP;
-        } else {
-            RightDC += DC_FLOAT_STEP;
-        }
-    }
-    pBiquadState->LeftDC = LeftDC;
-    pBiquadState->RightDC = RightDC;
-}
 /*
  * FUNCTION:       DC_Mc_D16_TRC_WRA_01
  *
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
index 2828cb3..c16718c 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
@@ -17,11 +17,6 @@
 
 #include "BIQUAD.h"
 #include "DC_2I_D16_TRC_WRA_01_Private.h"
-void DC_2I_D16_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance) {
-    PFilter_FLOAT_State pBiquadState = (PFilter_FLOAT_State)pInstance;
-    pBiquadState->LeftDC = 0.0f;
-    pBiquadState->RightDC = 0.0f;
-}
 void DC_Mc_D16_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance) {
     PFilter_FLOAT_State_Mc pBiquadState = (PFilter_FLOAT_State_Mc)pInstance;
     LVM_INT32 i;
diff --git a/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.cpp b/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.cpp
deleted file mode 100644
index 5daef59..0000000
--- a/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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 FILES
-***********************************************************************************/
-
-#include "LVM_Types.h"
-#include "LVM_Macros.h"
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION DelayAllPass_32x32
-***********************************************************************************/
-
-void DelayAllPass_Sat_32x16To32(LVM_INT32* delay,           /* Delay buffer */
-                                LVM_UINT16 size,            /* Delay size */
-                                LVM_INT16 coeff,            /* All pass filter coefficient */
-                                LVM_UINT16 DelayOffset,     /* Simple delay offset */
-                                LVM_UINT16* pAllPassOffset, /* All pass filter delay offset */
-                                LVM_INT32* dst,             /* Source/destination */
-                                LVM_INT16 n)                /* Number of  samples */
-{
-    LVM_INT16 i;
-    LVM_UINT16 AllPassOffset = *pAllPassOffset;
-    LVM_INT32 temp;
-    LVM_INT32 a, b, c;
-
-    for (i = 0; i < n; i++) {
-        MUL32x16INTO32(delay[AllPassOffset], coeff, temp, 15) a = temp;
-        b = delay[DelayOffset];
-        DelayOffset++;
-
-        c = a + b;
-        if ((((c ^ a) & (c ^ b)) >> 31) != 0) /* overflow / underflow */
-        {
-            if (a < 0) {
-                c = 0x80000000L;
-            } else {
-                c = 0x7FFFFFFFL;
-            }
-        }
-        *dst = c;
-        dst++;
-
-        MUL32x16INTO32(c, -coeff, temp, 15) a = temp;
-        b = delay[AllPassOffset];
-        c = a + b;
-        if ((((c ^ a) & (c ^ b)) >> 31) != 0) /* overflow / underflow */
-        {
-            if (a < 0) {
-                c = 0x80000000L;
-            } else {
-                c = 0x7FFFFFFFL;
-            }
-        }
-        delay[AllPassOffset] = c;
-        AllPassOffset++;
-
-        /* Make the delay buffer a circular buffer */
-        if (DelayOffset >= size) {
-            DelayOffset = 0;
-        }
-
-        if (AllPassOffset >= size) {
-            AllPassOffset = 0;
-        }
-    }
-
-    /* Update the offset */
-    *pAllPassOffset = AllPassOffset;
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp
index da75982..d2537eb 100644
--- a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp
@@ -21,51 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION DelayMix_16x16
-***********************************************************************************/
-
-void DelayMix_16x16(const LVM_INT16* src, /* Source 1, to be delayed */
-                    LVM_INT16* delay,     /* Delay buffer */
-                    LVM_INT16 size,       /* Delay size */
-                    LVM_INT16* dst,       /* Source/destination */
-                    LVM_INT16* pOffset,   /* Delay offset */
-                    LVM_INT16 n)          /* Number of stereo samples */
-{
-    LVM_INT16 i;
-    LVM_INT16 Offset = *pOffset;
-    LVM_INT16 temp;
-
-    for (i = 0; i < n; i++) {
-        /* Left channel */
-        temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) + (LVM_INT32)delay[Offset]) >> 1);
-        *dst = temp;
-        dst++;
-
-        delay[Offset] = *src;
-        Offset++;
-        src++;
-
-        /* Right channel */
-        temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) - (LVM_INT32)delay[Offset]) >> 1);
-        *dst = temp;
-        dst++;
-
-        delay[Offset] = *src;
-        Offset++;
-        src++;
-
-        /* Make the reverb delay buffer a circular buffer */
-        if (Offset >= size) {
-            Offset = 0;
-        }
-    }
-
-    /* Update the offset */
-    *pOffset = Offset;
-
-    return;
-}
 void DelayMix_Float(const LVM_FLOAT* src, /* Source 1, to be delayed */
                     LVM_FLOAT* delay,     /* Delay buffer */
                     LVM_INT16 size,       /* Delay size */
@@ -107,4 +62,3 @@
 
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DelayWrite_32.cpp b/media/libeffects/lvm/lib/Common/src/DelayWrite_32.cpp
deleted file mode 100644
index 47cffbf..0000000
--- a/media/libeffects/lvm/lib/Common/src/DelayWrite_32.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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 FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION DelayMix_16x16
-***********************************************************************************/
-
-void DelayWrite_32(const LVM_INT32* src, /* Source 1, to be delayed */
-                   LVM_INT32* delay,     /* Delay buffer */
-                   LVM_UINT16 size,      /* Delay size */
-                   LVM_UINT16* pOffset,  /* Delay offset */
-                   LVM_INT16 n)          /* Number of samples */
-{
-    LVM_INT16 i;
-    LVM_INT16 Offset = (LVM_INT16)*pOffset;
-
-    for (i = 0; i < n; i++) {
-        delay[Offset] = *src;
-        Offset++;
-        src++;
-
-        /* Make the delay buffer a circular buffer */
-        if (Offset >= size) {
-            Offset = 0;
-        }
-    }
-
-    /* Update the offset */
-    *pOffset = (LVM_UINT16)Offset;
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
index dad070b..be26d1e 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
@@ -24,86 +24,6 @@
 COEFS-
 pBiquadState->coefs[0] is A1,
 pBiquadState->coefs[1] is A0,
-pBiquadState->coefs[2] is -B1, these are in Q15 format
-pBiquadState->Shift    is Shift value
-DELAYS-
-pBiquadState->pDelays[0] is x(n-1)L in Q15 format
-pBiquadState->pDelays[1] is y(n-1)L in Q30 format
-pBiquadState->pDelays[2] is x(n-1)R in Q15 format
-pBiquadState->pDelays[3] is y(n-1)R in Q30 format
-***************************************************************************/
-void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
-                                     LVM_FLOAT* pDataOut, LVM_INT16 NrSamples) {
-    LVM_FLOAT ynL, ynR;
-    LVM_FLOAT Temp;
-    LVM_FLOAT NegSatValue;
-    LVM_INT16 ii;
-
-    PFilter_Float_State pBiquadState = (PFilter_Float_State)pInstance;
-
-    NegSatValue = -1.0f;
-
-    for (ii = NrSamples; ii != 0; ii--) {
-        /**************************************************************************
-                        PROCESSING OF THE LEFT CHANNEL
-        ***************************************************************************/
-
-        // ynL =A1  * x(n-1)L
-        ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[0];
-        // ynR =A1  * x(n-1)R
-        ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
-
-        // ynL+=A0  * x(n)L
-        ynL += (LVM_FLOAT)pBiquadState->coefs[1] * (*pDataIn);
-        // ynR+=A0  * x(n)L
-        ynR += (LVM_FLOAT)pBiquadState->coefs[1] * (*(pDataIn + 1));
-
-        // ynL +=  (-B1  * y(n-1)L  )
-        Temp = pBiquadState->pDelays[1] * pBiquadState->coefs[2];
-        ynL += Temp;
-        // ynR +=  (-B1  * y(n-1)R ) )
-        Temp = pBiquadState->pDelays[3] * pBiquadState->coefs[2];
-        ynR += Temp;
-
-        /**************************************************************************
-                        UPDATING THE DELAYS
-        ***************************************************************************/
-        pBiquadState->pDelays[1] = ynL;           // Update y(n-1)L
-        pBiquadState->pDelays[0] = (*pDataIn++);  // Update x(n-1)L
-
-        pBiquadState->pDelays[3] = ynR;           // Update y(n-1)R
-        pBiquadState->pDelays[2] = (*pDataIn++);  // Update x(n-1)R
-
-        /**************************************************************************
-                        WRITING THE OUTPUT
-        ***************************************************************************/
-
-        /*Saturate results*/
-        if (ynL > 1.0f) {
-            ynL = 1.0f;
-        } else {
-            if (ynL < NegSatValue) {
-                ynL = NegSatValue;
-            }
-        }
-
-        if (ynR > 1.0f) {
-            ynR = 1.0f;
-        } else {
-            if (ynR < NegSatValue) {
-                ynR = NegSatValue;
-            }
-        }
-
-        *pDataOut++ = (LVM_FLOAT)ynL;
-        *pDataOut++ = (LVM_FLOAT)ynR;
-    }
-}
-/**************************************************************************
-ASSUMPTIONS:
-COEFS-
-pBiquadState->coefs[0] is A1,
-pBiquadState->coefs[1] is A0,
 pBiquadState->coefs[2] is -B1,
 DELAYS-
 pBiquadState->pDelays[2*ch + 0] is x(n-1) of the 'ch' - channel
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp
index b050267..e2f8c67 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp
@@ -21,33 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION  From2iToMS_16x16
-***********************************************************************************/
-
-void From2iToMS_16x16(const LVM_INT16* src, LVM_INT16* dstM, LVM_INT16* dstS, LVM_INT16 n) {
-    LVM_INT32 temp1, left, right;
-    LVM_INT16 ii;
-    for (ii = n; ii != 0; ii--) {
-        left = (LVM_INT32)*src;
-        src++;
-
-        right = (LVM_INT32)*src;
-        src++;
-
-        /* Compute M signal*/
-        temp1 = (left + right) >> 1;
-        *dstM = (LVM_INT16)temp1;
-        dstM++;
-
-        /* Compute S signal*/
-        temp1 = (left - right) >> 1;
-        *dstS = (LVM_INT16)temp1;
-        dstS++;
-    }
-
-    return;
-}
 void From2iToMS_Float(const LVM_FLOAT* src, LVM_FLOAT* dstM, LVM_FLOAT* dstS, LVM_INT16 n) {
     LVM_FLOAT temp1, left, right;
     LVM_INT16 ii;
@@ -71,4 +44,3 @@
 
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_16.cpp b/media/libeffects/lvm/lib/Common/src/From2iToMono_16.cpp
deleted file mode 100644
index 9a54ee4..0000000
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_16.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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 FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION From2iToMono_16
-***********************************************************************************/
-
-void From2iToMono_16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT32 Temp;
-    for (ii = n; ii != 0; ii--) {
-        Temp = (LVM_INT32)*src;
-        src++;
-
-        Temp += (LVM_INT32)*src;
-        src++;
-
-        *dst = (LVM_INT16)(Temp >> 1);
-        dst++;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
index 6ede958..039ee14 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
@@ -21,27 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION From2iToMono_32
-***********************************************************************************/
-
-void From2iToMono_32(const LVM_INT32* src, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT32 Temp;
-
-    for (ii = n; ii != 0; ii--) {
-        Temp = (*src >> 1);
-        src++;
-
-        Temp += (*src >> 1);
-        src++;
-
-        *dst = Temp;
-        dst++;
-    }
-
-    return;
-}
 void From2iToMono_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_INT16 ii;
     LVM_FLOAT Temp;
@@ -93,5 +72,3 @@
 
     return;
 }
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.cpp b/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.cpp
deleted file mode 100644
index 9ddcbe4..0000000
--- a/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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 FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION INT16LSHIFTTOINT32_16X32
-***********************************************************************************/
-
-void Int16LShiftToInt32_16x32(const LVM_INT16* src, LVM_INT32* dst, LVM_INT16 n, LVM_INT16 shift) {
-    LVM_INT16 ii;
-
-    src += n - 1;
-    dst += n - 1;
-
-    for (ii = n; ii != 0; ii--) {
-        *dst = (((LVM_INT32)*src) << shift);
-        src--;
-        dst--;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.cpp b/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.cpp
deleted file mode 100644
index 2584117..0000000
--- a/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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 FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION INT32RSHIFTTOINT16_SAT_32X16
-***********************************************************************************/
-
-void Int32RShiftToInt16_Sat_32x16(const LVM_INT32* src, LVM_INT16* dst, LVM_INT16 n,
-                                  LVM_INT16 shift) {
-    LVM_INT32 temp;
-    LVM_INT16 ii;
-
-    for (ii = n; ii != 0; ii--) {
-        temp = *src >> shift;
-        src++;
-
-        if (temp > 0x00007FFF) {
-            *dst = 0x7FFF;
-        } else if (temp < -0x00008000) {
-            *dst = -0x8000;
-        } else {
-            *dst = (LVM_INT16)temp;
-        }
-
-        dst++;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp
index 0721b76..6c7c8ae 100644
--- a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp
@@ -21,29 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION JoinTo2i_32x32
-***********************************************************************************/
-
-void JoinTo2i_32x32(const LVM_INT32* srcL, const LVM_INT32* srcR, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-
-    srcL += n - 1;
-    srcR += n - 1;
-    dst += ((2 * n) - 1);
-
-    for (ii = n; ii != 0; ii--) {
-        *dst = *srcR;
-        dst--;
-        srcR--;
-
-        *dst = *srcL;
-        dst--;
-        srcL--;
-    }
-
-    return;
-}
 void JoinTo2i_Float(const LVM_FLOAT* srcL, const LVM_FLOAT* srcR, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_INT16 ii;
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
index 8b00925..36f0e1f 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
@@ -23,34 +23,6 @@
 #include "LVM_Macros.h"
 #include "ScalarArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION LVC_Core_MixHard_1St_2i_D16C31_SAT
-***********************************************************************************/
-void LVC_Core_MixHard_1St_2i_D16C31_SAT(LVMixer3_FLOAT_st* ptrInstance1,
-                                        LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
-                                        LVM_FLOAT* dst, LVM_INT16 n) {
-    LVM_FLOAT Temp;
-    LVM_INT16 ii;
-    Mix_Private_FLOAT_st* pInstance1 = (Mix_Private_FLOAT_st*)(ptrInstance1->PrivateParams);
-    Mix_Private_FLOAT_st* pInstance2 = (Mix_Private_FLOAT_st*)(ptrInstance2->PrivateParams);
-    for (ii = n; ii != 0; ii--) {
-        Temp = ((LVM_FLOAT) * (src++) * (LVM_FLOAT)pInstance1->Current);
-        if (Temp > 1.0f)
-            *dst++ = 1.0f;
-        else if (Temp < -1.0f)
-            *dst++ = -1.0f;
-        else
-            *dst++ = (LVM_FLOAT)Temp;
-
-        Temp = ((LVM_FLOAT) * (src++) * (LVM_FLOAT)pInstance2->Current);
-        if (Temp > 1.0f)
-            *dst++ = 1.0f;
-        else if (Temp < -1.0f)
-            *dst++ = -1.0f;
-        else
-            *dst++ = (LVM_FLOAT)Temp;
-    }
-}
 void LVC_Core_MixHard_1St_MC_float_SAT(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
                                        LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels) {
     LVM_FLOAT Temp;
@@ -68,4 +40,3 @@
         }
     }
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
index d45845a..4e5d324 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
@@ -18,107 +18,17 @@
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
-
+#include <algorithm>
 #include "LVC_Mixer_Private.h"
 #include "ScalarArithmetic.h"
 #include "LVM_Macros.h"
 
-/**********************************************************************************
-   FUNCTION LVC_Core_MixSoft_1St_2i_D16C31_WRA
-***********************************************************************************/
-static LVM_FLOAT ADD2_SAT_FLOAT(LVM_FLOAT a, LVM_FLOAT b, LVM_FLOAT c) {
-    LVM_FLOAT temp;
-    temp = a + b;
-    if (temp < -1.0f)
-        c = -1.0f;
-    else if (temp > 1.0f)
-        c = 1.0f;
-    else
-        c = temp;
-    return c;
-}
-void LVC_Core_MixSoft_1St_2i_D16C31_WRA(LVMixer3_FLOAT_st* ptrInstance1,
-                                        LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
-                                        LVM_FLOAT* dst, LVM_INT16 n) {
-    LVM_INT16 OutLoop;
-    LVM_INT16 InLoop;
-    LVM_INT32 ii;
-    Mix_Private_FLOAT_st* pInstanceL = (Mix_Private_FLOAT_st*)(ptrInstance1->PrivateParams);
-    Mix_Private_FLOAT_st* pInstanceR = (Mix_Private_FLOAT_st*)(ptrInstance2->PrivateParams);
-
-    LVM_FLOAT DeltaL = pInstanceL->Delta;
-    LVM_FLOAT CurrentL = pInstanceL->Current;
-    LVM_FLOAT TargetL = pInstanceL->Target;
-
-    LVM_FLOAT DeltaR = pInstanceR->Delta;
-    LVM_FLOAT CurrentR = pInstanceR->Current;
-    LVM_FLOAT TargetR = pInstanceR->Target;
-
-    LVM_FLOAT Temp = 0;
-
-    InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
-    OutLoop = (LVM_INT16)(n - (InLoop << 2));
-
-    if (OutLoop) {
-        if (CurrentL < TargetL) {
-            ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp);
-            CurrentL = Temp;
-            if (CurrentL > TargetL) CurrentL = TargetL;
-        } else {
-            CurrentL -= DeltaL;
-            if (CurrentL < TargetL) CurrentL = TargetL;
-        }
-
-        if (CurrentR < TargetR) {
-            ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp);
-            CurrentR = Temp;
-            if (CurrentR > TargetR) CurrentR = TargetR;
-        } else {
-            CurrentR -= DeltaR;
-            if (CurrentR < TargetR) CurrentR = TargetR;
-        }
-
-        for (ii = OutLoop * 2; ii != 0; ii -= 2) {
-            *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
-            *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
-        }
-    }
-
-    for (ii = InLoop * 2; ii != 0; ii -= 2) {
-        if (CurrentL < TargetL) {
-            ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp);
-            CurrentL = Temp;
-            if (CurrentL > TargetL) CurrentL = TargetL;
-        } else {
-            CurrentL -= DeltaL;
-            if (CurrentL < TargetL) CurrentL = TargetL;
-        }
-
-        if (CurrentR < TargetR) {
-            ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp);
-            CurrentR = Temp;
-            if (CurrentR > TargetR) CurrentR = TargetR;
-        } else {
-            CurrentR -= DeltaR;
-            if (CurrentR < TargetR) CurrentR = TargetR;
-        }
-
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
-        *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
-    }
-    pInstanceL->Current = CurrentL;
-    pInstanceR->Current = CurrentR;
+static inline LVM_FLOAT ADD2_SAT_FLOAT(LVM_FLOAT a, LVM_FLOAT b) {
+    return std::clamp(a + b, -1.0f, 1.0f);
 }
 void LVC_Core_MixSoft_1St_MC_float_WRA(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
                                        LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels) {
     LVM_INT32 ii, ch;
-    LVM_FLOAT Temp = 0.0f;
     LVM_FLOAT tempCurrent[NrChannels];
     for (ch = 0; ch < NrChannels; ch++) {
         tempCurrent[ch] = ptrInstance[ch]->Current;
@@ -130,8 +40,7 @@
             LVM_FLOAT Current = tempCurrent[ch];
             const LVM_FLOAT Target = pInstance->Target;
             if (Current < Target) {
-                ADD2_SAT_FLOAT(Current, Delta, Temp);
-                Current = Temp;
+                Current = ADD2_SAT_FLOAT(Current, Delta);
                 if (Current > Target) Current = Target;
             } else {
                 Current -= Delta;
@@ -145,4 +54,3 @@
         ptrInstance[ch]->Current = tempCurrent[ch];
     }
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
index c74c8c6..58bc06e 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
@@ -35,7 +35,7 @@
 #define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(*(a))))
 
 /**********************************************************************************
-   FUNCTION LVC_MixSoft_1St_2i_D16C31_SAT
+   FUNCTION LVC_MixSoft_1St_MC_float_SAT
 ***********************************************************************************/
 /* This threshold is used to decide on the processing to be applied on
  * front center and back center channels
@@ -192,106 +192,3 @@
         }
     }
 }
-void LVC_MixSoft_1St_2i_D16C31_SAT(LVMixer3_2St_FLOAT_st* ptrInstance, const LVM_FLOAT* src,
-                                   LVM_FLOAT* dst, LVM_INT16 n) {
-    char HardMixing = TRUE;
-    LVM_FLOAT TargetGain;
-    Mix_Private_FLOAT_st* pInstance1 =
-            (Mix_Private_FLOAT_st*)(ptrInstance->MixerStream[0].PrivateParams);
-    Mix_Private_FLOAT_st* pInstance2 =
-            (Mix_Private_FLOAT_st*)(ptrInstance->MixerStream[1].PrivateParams);
-
-    if (n <= 0) return;
-
-    /******************************************************************************
-       SOFT MIXING
-    *******************************************************************************/
-    if ((pInstance1->Current != pInstance1->Target) ||
-        (pInstance2->Current != pInstance2->Target)) {
-        if (pInstance1->Delta == 1.0f) {
-            pInstance1->Current = pInstance1->Target;
-            TargetGain = pInstance1->Target;
-            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
-        } else if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta) {
-            pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
-                                                         Make them equal. */
-            TargetGain = pInstance1->Target;
-            LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
-        } else {
-            /* Soft mixing has to be applied */
-            HardMixing = FALSE;
-        }
-
-        if (HardMixing == TRUE) {
-            if (pInstance2->Delta == 1.0f) {
-                pInstance2->Current = pInstance2->Target;
-                TargetGain = pInstance2->Target;
-                LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
-            } else if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta) {
-                pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore.
-                                                             \ Make them equal. */
-                TargetGain = pInstance2->Target;
-                LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
-            } else {
-                /* Soft mixing has to be applied */
-                HardMixing = FALSE;
-            }
-        }
-
-        if (HardMixing == FALSE) {
-            LVC_Core_MixSoft_1St_2i_D16C31_WRA(&(ptrInstance->MixerStream[0]),
-                                               &(ptrInstance->MixerStream[1]), src, dst, n);
-        }
-    }
-
-    /******************************************************************************
-       HARD MIXING
-    *******************************************************************************/
-
-    if (HardMixing) {
-        if ((pInstance1->Target == 1.0f) && (pInstance2->Target == 1.0f)) {
-            if (src != dst) {
-                Copy_Float(src, dst, n);
-            }
-        } else {
-            LVC_Core_MixHard_1St_2i_D16C31_SAT(&(ptrInstance->MixerStream[0]),
-                                               &(ptrInstance->MixerStream[1]), src, dst, n);
-        }
-    }
-
-    /******************************************************************************
-       CALL BACK
-    *******************************************************************************/
-
-    if (ptrInstance->MixerStream[0].CallbackSet) {
-        if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta) {
-            pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
-                                                         Make them equal. */
-            TargetGain = pInstance1->Target;
-            LVC_Mixer_SetTarget(&ptrInstance->MixerStream[0], TargetGain);
-            ptrInstance->MixerStream[0].CallbackSet = FALSE;
-            if (ptrInstance->MixerStream[0].pCallBack != 0) {
-                (*ptrInstance->MixerStream[0].pCallBack)(
-                        ptrInstance->MixerStream[0].pCallbackHandle,
-                        ptrInstance->MixerStream[0].pGeneralPurpose,
-                        ptrInstance->MixerStream[0].CallbackParam);
-            }
-        }
-    }
-    if (ptrInstance->MixerStream[1].CallbackSet) {
-        if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta) {
-            pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore.
-                                                         Make them equal. */
-            TargetGain = pInstance2->Target;
-            LVC_Mixer_SetTarget(&ptrInstance->MixerStream[1], TargetGain);
-            ptrInstance->MixerStream[1].CallbackSet = FALSE;
-            if (ptrInstance->MixerStream[1].pCallBack != 0) {
-                (*ptrInstance->MixerStream[1].pCallBack)(
-                        ptrInstance->MixerStream[1].pCallbackHandle,
-                        ptrInstance->MixerStream[1].pGeneralPurpose,
-                        ptrInstance->MixerStream[1].CallbackParam);
-            }
-        }
-    }
-}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
index 55255a6..1eb2dea 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
@@ -101,9 +101,6 @@
 void LVC_MixSoft_1St_MC_float_SAT(LVMixer3_2St_FLOAT_st* pInstance, const LVM_FLOAT* src,
                                   LVM_FLOAT* dst, /* dst can be equal to src */
                                   LVM_INT16 NrFrames, LVM_INT32 NrChannels, LVM_INT32 ChMask);
-void LVC_MixSoft_1St_2i_D16C31_SAT(LVMixer3_2St_FLOAT_st* pInstance, const LVM_FLOAT* src,
-                                   LVM_FLOAT* dst, /* dst can be equal to src */
-                                   LVM_INT16 n);   /* Number of stereo samples */
 
 /**********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
index 5f22d77..9206fae 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
@@ -65,9 +65,6 @@
 /**********************************************************************************/
 void LVC_Core_MixSoft_1St_MC_float_WRA(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
                                        LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
-void LVC_Core_MixSoft_1St_2i_D16C31_WRA(LVMixer3_FLOAT_st* ptrInstance1,
-                                        LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
-                                        LVM_FLOAT* dst, LVM_INT16 n);
 
 /**********************************************************************************/
 /* For applying different gains to Left and right chennals                        */
@@ -77,11 +74,5 @@
 /**********************************************************************************/
 void LVC_Core_MixHard_1St_MC_float_SAT(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
                                        LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
-void LVC_Core_MixHard_1St_2i_D16C31_SAT(LVMixer3_FLOAT_st* ptrInstance1,
-                                        LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
-                                        LVM_FLOAT* dst, LVM_INT16 n);
-
-/*** 32 bit functions *************************************************************/
-/**********************************************************************************/
 
 #endif  //#ifndef __LVC_MIXER_PRIVATE_H__
diff --git a/media/libeffects/lvm/lib/Common/src/LoadConst_16.cpp b/media/libeffects/lvm/lib/Common/src/LoadConst_16.cpp
deleted file mode 100644
index a39fa2f..0000000
--- a/media/libeffects/lvm/lib/Common/src/LoadConst_16.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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 FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION LoadConst_16
-***********************************************************************************/
-
-void LoadConst_16(const LVM_INT16 val, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-
-    for (ii = n; ii != 0; ii--) {
-        *dst = val;
-        dst++;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp
index a19e66f..95a444a 100644
--- a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp
@@ -21,46 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION  MSTO2I_SAT_16X16
-***********************************************************************************/
-
-void MSTo2i_Sat_16x16(const LVM_INT16* srcM, const LVM_INT16* srcS, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT32 temp, mVal, sVal;
-    LVM_INT16 ii;
-
-    for (ii = n; ii != 0; ii--) {
-        mVal = (LVM_INT32)*srcM;
-        srcM++;
-
-        sVal = (LVM_INT32)*srcS;
-        srcS++;
-
-        temp = mVal + sVal;
-
-        if (temp > 0x00007FFF) {
-            *dst = 0x7FFF;
-        } else if (temp < -0x00008000) {
-            *dst = -0x8000;
-        } else {
-            *dst = (LVM_INT16)temp;
-        }
-        dst++;
-
-        temp = mVal - sVal;
-
-        if (temp > 0x00007FFF) {
-            *dst = 0x7FFF;
-        } else if (temp < -0x00008000) {
-            *dst = -0x8000;
-        } else {
-            *dst = (LVM_INT16)temp;
-        }
-        dst++;
-    }
-
-    return;
-}
 void MSTo2i_Sat_Float(const LVM_FLOAT* srcM, const LVM_FLOAT* srcS, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_FLOAT temp, mVal, sVal;
     LVM_INT16 ii;
@@ -97,4 +57,3 @@
 
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.cpp b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.cpp
deleted file mode 100644
index 1d450b0..0000000
--- a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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.
- */
-
-/**********************************************************************************
-
-     %created_by:    sra % (CM/S)
-     %name:          Mac3s_Sat_16x16.c % (CM/S)
-     %version:       1 % (CM/S)
-     %date_created:  Fri Nov 13 12:07:13 2009 % (CM/S)
-
-***********************************************************************************/
-
-/**********************************************************************************
-   INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-#include "LVM_Macros.h"
-
-/**********************************************************************************
-   FUNCTION Mac3S_16X16
-***********************************************************************************/
-
-void Mac3s_Sat_16x16(const LVM_INT16* src, const LVM_INT16 val, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT16 srcval;
-    LVM_INT32 Temp, dInVal;
-
-    for (ii = n; ii != 0; ii--) {
-        srcval = *src;
-        src++;
-
-        Temp = (srcval * val) >> 15;
-
-        dInVal = (LVM_INT32)*dst;
-
-        Temp = Temp + dInVal;
-
-        if (Temp > 0x00007FFF) {
-            *dst = 0x7FFF;
-        } else if (Temp < -0x00008000) {
-            *dst = -0x8000;
-        } else {
-            *dst = (LVM_INT16)Temp;
-        }
-
-        dst++;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp
index 0fe9fef..dc57022 100644
--- a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp
@@ -22,38 +22,6 @@
 #include "VectorArithmetic.h"
 #include "LVM_Macros.h"
 
-/**********************************************************************************
-   FUNCTION MAC3S_16X16
-***********************************************************************************/
-
-void Mac3s_Sat_32x16(const LVM_INT32* src, const LVM_INT16 val, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT32 srcval, temp, dInVal, dOutVal;
-
-    for (ii = n; ii != 0; ii--) {
-        srcval = *src;
-        src++;
-
-        MUL32x16INTO32(srcval, val, temp, 15)
-
-                dInVal = *dst;
-        dOutVal = temp + dInVal;
-
-        if ((((dOutVal ^ temp) & (dOutVal ^ dInVal)) >> 31) != 0) /* overflow / underflow */
-        {
-            if (temp < 0) {
-                dOutVal = 0x80000000L;
-            } else {
-                dOutVal = 0x7FFFFFFFL;
-            }
-        }
-
-        *dst = dOutVal;
-        dst++;
-    }
-
-    return;
-}
 void Mac3s_Sat_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_INT16 ii;
     LVM_FLOAT srcval;
@@ -80,4 +48,3 @@
 
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.cpp b/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.cpp
deleted file mode 100644
index 7ab5d49..0000000
--- a/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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 FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION MonoTo2I_16
-***********************************************************************************/
-
-void MonoTo2I_16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    src += (n - 1);
-    dst += ((n * 2) - 1);
-
-    for (ii = n; ii != 0; ii--) {
-        *dst = *src;
-        dst--;
-
-        *dst = *src;
-        dst--;
-        src--;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp
index 1ba669f..ef3e633 100644
--- a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp
@@ -21,26 +21,6 @@
 
 #include "VectorArithmetic.h"
 
-/**********************************************************************************
-   FUNCTION MonoTo2I_32
-***********************************************************************************/
-
-void MonoTo2I_32(const LVM_INT32* src, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    src += (n - 1);
-    dst += ((n * 2) - 1);
-
-    for (ii = n; ii != 0; ii--) {
-        *dst = *src;
-        dst--;
-
-        *dst = *src;
-        dst--;
-        src--;
-    }
-
-    return;
-}
 void MonoTo2I_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_INT16 ii;
     src += (n - 1);
@@ -57,4 +37,3 @@
 
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp
index 4589703..babfef3 100644
--- a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp
@@ -22,26 +22,6 @@
 #include "VectorArithmetic.h"
 #include "LVM_Macros.h"
 
-/**********************************************************************************
-FUNCTION MULT3S_16X16
-***********************************************************************************/
-
-void Mult3s_32x16(const LVM_INT32* src, const LVM_INT16 val, LVM_INT32* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT32 srcval, temp;
-
-    for (ii = n; ii != 0; ii--) {
-        srcval = *src;
-        src++;
-
-        MUL32x16INTO32(srcval, val, temp, 15)
-
-                * dst = temp;
-        dst++;
-    }
-
-    return;
-}
 void Mult3s_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n) {
     LVM_INT16 ii;
     LVM_FLOAT temp;
@@ -54,4 +34,3 @@
     }
     return;
 }
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp
index fba0666..f3a1a67 100644
--- a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp
@@ -61,43 +61,6 @@
 /*                                                                                      */
 /****************************************************************************************/
 
-void NonLinComp_D16(LVM_INT16 Gain, LVM_INT16* pDataIn, LVM_INT16* pDataOut,
-                    LVM_INT32 BlockLength) {
-    LVM_INT16 Sample;   /* Input samples */
-    LVM_INT32 SampleNo; /* Sample index */
-    LVM_INT16 Temp;
-
-    /*
-     * Process a block of samples
-     */
-    for (SampleNo = 0; SampleNo < BlockLength; SampleNo++) {
-        /*
-         * Read the input
-         */
-        Sample = *pDataIn;
-        pDataIn++;
-
-        /*
-         * Apply the compander, this compresses the signal at the expense of
-         * harmonic distortion. The amount of compression is control by the
-         * gain factor
-         */
-        if ((LVM_INT32)Sample != -32768) {
-            Temp = (LVM_INT16)((Sample * Sample) >> 15);
-            if (Sample > 0) {
-                Sample = (LVM_INT16)(Sample + ((Gain * (Sample - Temp)) >> 15));
-            } else {
-                Sample = (LVM_INT16)(Sample + ((Gain * (Sample + Temp)) >> 15));
-            }
-        }
-
-        /*
-         * Save the output
-         */
-        *pDataOut = Sample;
-        pDataOut++;
-    }
-}
 void NonLinComp_Float(LVM_FLOAT Gain, LVM_FLOAT* pDataIn, LVM_FLOAT* pDataOut,
                       LVM_INT32 BlockLength) {
     LVM_FLOAT Sample;   /* Input samples */
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
index 0afaad2..b843980 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
@@ -20,97 +20,6 @@
 #include "LVM_Macros.h"
 
 /**************************************************************************
- ASSUMPTIONS:
- COEFS-
- pBiquadState->coefs[0] is A0,
- pBiquadState->coefs[1] is -B2,
- pBiquadState->coefs[2] is -B1, these are in Q14 format
- pBiquadState->coefs[3] is Gain, in Q11 format
-
- DELAYS-
- pBiquadState->pDelays[0] is x(n-1)L in Q0 format
- pBiquadState->pDelays[1] is x(n-1)R in Q0 format
- pBiquadState->pDelays[2] is x(n-2)L in Q0 format
- pBiquadState->pDelays[3] is x(n-2)R in Q0 format
- pBiquadState->pDelays[4] is y(n-1)L in Q0 format
- pBiquadState->pDelays[5] is y(n-1)R in Q0 format
- pBiquadState->pDelays[6] is y(n-2)L in Q0 format
- pBiquadState->pDelays[7] is y(n-2)R in Q0 format
-***************************************************************************/
-void PK_2I_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
-                                   LVM_FLOAT* pDataOut, LVM_INT16 NrSamples) {
-    LVM_FLOAT ynL, ynR, ynLO, ynRO, templ;
-    LVM_INT16 ii;
-    PFilter_State_Float pBiquadState = (PFilter_State_Float)pInstance;
-
-    for (ii = NrSamples; ii != 0; ii--) {
-        /**************************************************************************
-                        PROCESSING OF THE LEFT CHANNEL
-        ***************************************************************************/
-        /* ynL= (A0  * (x(n)L - x(n-2)L  ) )*/
-        templ = (*pDataIn) - pBiquadState->pDelays[2];
-        ynL = templ * pBiquadState->coefs[0];
-
-        /* ynL+= ((-B2  * y(n-2)L  )) */
-        templ = pBiquadState->pDelays[6] * pBiquadState->coefs[1];
-        ynL += templ;
-
-        /* ynL+= ((-B1 * y(n-1)L  ) ) */
-        templ = pBiquadState->pDelays[4] * pBiquadState->coefs[2];
-        ynL += templ;
-
-        /* ynLO= ((Gain * ynL )) */
-        ynLO = ynL * pBiquadState->coefs[3];
-
-        /* ynLO=( ynLO + x(n)L  )*/
-        ynLO += (*pDataIn);
-
-        /**************************************************************************
-                        PROCESSING OF THE RIGHT CHANNEL
-        ***************************************************************************/
-        /* ynR= (A0  * (x(n)R  - x(n-2)R  ) ) */
-        templ = (*(pDataIn + 1)) - pBiquadState->pDelays[3];
-        ynR = templ * pBiquadState->coefs[0];
-
-        /* ynR+= ((-B2  * y(n-2)R  ) )  */
-        templ = pBiquadState->pDelays[7] * pBiquadState->coefs[1];
-        ynR += templ;
-
-        /* ynR+= ((-B1  * y(n-1)R  ) )   */
-        templ = pBiquadState->pDelays[5] * pBiquadState->coefs[2];
-        ynR += templ;
-
-        /* ynRO= ((Gain  * ynR )) */
-        ynRO = ynR * pBiquadState->coefs[3];
-
-        /* ynRO=( ynRO + x(n)R  )*/
-        ynRO += (*(pDataIn + 1));
-
-        /**************************************************************************
-                        UPDATING THE DELAYS
-        ***************************************************************************/
-        pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
-        pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
-        pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
-        pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
-        pBiquadState->pDelays[5] = ynR;                      /* Update y(n-1)R */
-        pBiquadState->pDelays[4] = ynL;                      /* Update y(n-1)L */
-        pBiquadState->pDelays[0] = (*pDataIn);               /* Update x(n-1)L */
-        pDataIn++;
-        pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R */
-        pDataIn++;
-
-        /**************************************************************************
-                        WRITING THE OUTPUT
-        ***************************************************************************/
-        *pDataOut = ynLO; /* Write Left output*/
-        pDataOut++;
-        *pDataOut = ynRO; /* Write Right output*/
-        pDataOut++;
-    }
-}
-
-/**************************************************************************
 DELAYS-
 pBiquadState->pDelays[0] to
 pBiquadState->pDelays[NrChannels - 1] is x(n-1) for all NrChannels
diff --git a/media/libeffects/lvm/lib/Common/src/mult3s_16x16.cpp b/media/libeffects/lvm/lib/Common/src/mult3s_16x16.cpp
deleted file mode 100644
index 66f9132..0000000
--- a/media/libeffects/lvm/lib/Common/src/mult3s_16x16.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * Copyright (C) 2010 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 FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
-   FUNCTION MULT3S_16X16
-***********************************************************************************/
-
-void Mult3s_16x16(const LVM_INT16* src, const LVM_INT16 val, LVM_INT16* dst, LVM_INT16 n) {
-    LVM_INT16 ii;
-    LVM_INT32 temp;
-
-    for (ii = n; ii != 0; ii--) {
-        temp = (LVM_INT32)(*src) * (LVM_INT32)val;
-        src++;
-
-        *dst = (LVM_INT16)(temp >> 15);
-        dst++;
-    }
-
-    return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
index bccbe86..f4e625f 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
@@ -21,6 +21,9 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include "LVEQNB.h"
 #include "LVEQNB_Private.h"
 #include "VectorArithmetic.h"
@@ -179,6 +182,9 @@
     LVM_UINT16 i;                    /* Filter band index */
     LVEQNB_BiquadType_en BiquadType; /* Filter biquad type */
 
+#ifdef BIQUAD_OPT
+    pInstance->gain.resize(pInstance->Params.NBands);
+#endif
     /*
      * Set the coefficients for each band by the init function
      */
@@ -198,8 +204,19 @@
                 /*
                  * Set the coefficients
                  */
+#ifdef BIQUAD_OPT
+                pInstance->gain[i] = Coefficients.G;
+                std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                        Coefficients.A0, 0.0, -(Coefficients.A0), -(Coefficients.B1),
+                        -(Coefficients.B2)};
+                pInstance->eqBiquad[i]
+                        .setCoefficients<
+                                std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(
+                                coefs);
+#else
                 PK_2I_D32F32CssGss_TRC_WRA_01_Init(&pInstance->pEQNB_FilterState_Float[i],
                                                    &pInstance->pEQNB_Taps_Float[i], &Coefficients);
+#endif
                 break;
             }
             default:
@@ -220,6 +237,11 @@
 /*                                                                                  */
 /************************************************************************************/
 void LVEQNB_ClearFilterHistory(LVEQNB_Instance_t* pInstance) {
+#ifdef BIQUAD_OPT
+    for (size_t i = 0; i < pInstance->eqBiquad.size(); i++) {
+        pInstance->eqBiquad[i].clear();
+    }
+#else
     LVM_FLOAT* pTapAddress;
     LVM_INT16 NumTaps;
 
@@ -233,6 +255,7 @@
                         pTapAddress, /* Destination */
                         NumTaps);    /* Number of words */
     }
+#endif
 }
 /****************************************************************************************/
 /*                                                                                      */
@@ -310,6 +333,16 @@
             (OperatingModeSave == LVEQNB_ON && pInstance->bInOperatingModeTransition &&
              LVC_Mixer_GetTarget(&pInstance->BypassMixer.MixerStream[0]) == 0);
 
+#ifdef BIQUAD_OPT
+    /*
+     * Create biquad instance
+     */
+    pInstance->eqBiquad.resize(
+            pParams->NBands, android::audio_utils::BiquadFilter<LVM_FLOAT>(
+                                     (FCC_1 == pParams->NrChannels) ? FCC_2 : pParams->NrChannels));
+    LVEQNB_ClearFilterHistory(pInstance);
+#endif
+
     if (bChange || modeChange) {
         /*
          * If the sample rate has changed clear the history
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
index 1d2a5f5..57df4db 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
@@ -62,6 +62,9 @@
     pInstance->pScratch = pScratch;
 
     /* Equaliser Biquad Instance */
+#ifdef BIQUAD_OPT
+    LVM_UINT32 MemSize = pCapabilities->MaxBands * sizeof(*(pInstance->pBandDefinitions));
+#else
     LVM_UINT32 MemSize = pCapabilities->MaxBands * sizeof(*(pInstance->pEQNB_FilterState_Float));
     pInstance->pEQNB_FilterState_Float = (Biquad_FLOAT_Instance_t*)calloc(1, MemSize);
     if (pInstance->pEQNB_FilterState_Float == LVM_NULL) {
@@ -75,6 +78,7 @@
     }
 
     MemSize = (pCapabilities->MaxBands * sizeof(*(pInstance->pBandDefinitions)));
+#endif
     pInstance->pBandDefinitions = (LVEQNB_BandDef_t*)calloc(1, MemSize);
     if (pInstance->pBandDefinitions == LVM_NULL) {
         return LVEQNB_NULLADDRESS;
@@ -105,10 +109,11 @@
      */
     LVEQNB_SetFilters(pInstance, /* Set the filter types */
                       &pInstance->Params);
-
+#ifndef BIQUAD_OPT
     LVEQNB_SetCoefficients(pInstance); /* Set the filter coefficients */
 
     LVEQNB_ClearFilterHistory(pInstance); /* Clear the filter history */
+#endif
 
     /*
      * Initialise the bypass variables
@@ -154,6 +159,7 @@
     }
     pInstance = (LVEQNB_Instance_t*)*phInstance;
 
+#ifndef BIQUAD_OPT
     /* Equaliser Biquad Instance */
     if (pInstance->pEQNB_FilterState_Float != LVM_NULL) {
         free(pInstance->pEQNB_FilterState_Float);
@@ -163,6 +169,7 @@
         free(pInstance->pEQNB_Taps_Float);
         pInstance->pEQNB_Taps_Float = LVM_NULL;
     }
+#endif
     if (pInstance->pBandDefinitions != LVM_NULL) {
         free(pInstance->pBandDefinitions);
         pInstance->pBandDefinitions = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
index 83a3449..32bad29 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
@@ -24,6 +24,9 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVEQNB.h" /* Calling or Application layer definitions */
 #include "BIQUAD.h"
 #include "LVC_Mixer.h"
@@ -69,8 +72,14 @@
     /* Aligned memory pointers */
     LVM_FLOAT* pFastTemporary; /* Fast temporary data base address */
 
+#ifdef BIQUAD_OPT
+    std::vector<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            eqBiquad;            /* Biquad filter instances */
+    std::vector<LVM_FLOAT> gain; /* Gain values for all bands*/
+#else
     Biquad_2I_Order2_FLOAT_Taps_t* pEQNB_Taps_Float;  /* Equaliser Taps */
     Biquad_FLOAT_Instance_t* pEQNB_FilterState_Float; /* State for each filter band */
+#endif
 
     /* Filter definitions and call back */
     LVM_UINT16 NBands;                  /* Number of bands */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
index d2a26db..3f0be7c 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
@@ -104,19 +104,30 @@
                  * Check if band is non-zero dB gain
                  */
                 if (pInstance->pBandDefinitions[i].Gain != 0) {
+#ifndef BIQUAD_OPT
                     /*
                      * Get the address of the biquad instance
                      */
                     Biquad_FLOAT_Instance_t* pBiquad = &pInstance->pEQNB_FilterState_Float[i];
+#endif
 
                     /*
                      * Select single or double precision as required
                      */
                     switch (pInstance->pBiquadType[i]) {
                         case LVEQNB_SinglePrecision_Float: {
+#ifdef BIQUAD_OPT
+                            LVM_FLOAT* pTemp = pScratch + NrSamples;
+                            pInstance->eqBiquad[i].process(pTemp, pScratch, NrFrames);
+                            const auto gain = pInstance->gain[i];
+                            for (unsigned j = 0; j < NrSamples; ++j) {
+                                pScratch[j] += pTemp[j] * gain;
+                            }
+#else
                             PK_Mc_D32F32C14G11_TRC_WRA_01(pBiquad, pScratch, pScratch,
                                                           (LVM_INT16)NrFrames,
                                                           (LVM_INT16)NrChannels);
+#endif
                             break;
                         }
                         default:
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
index 737ef01..a744339 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
@@ -20,6 +20,10 @@
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
+
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include "LVREV_Private.h"
 #include "Filter.h"
 
@@ -71,10 +75,17 @@
 
         Omega = LVM_GetOmega(pPrivate->NewParams.HPF, pPrivate->NewParams.SampleRate);
         LVM_FO_HPF(Omega, &Coeffs);
+#ifdef BIQUAD_OPT
+        const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                Coeffs.A0, Coeffs.A1, 0.0, -(Coeffs.B1), 0.0};
+        pPrivate->pRevHPFBiquad.reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
         FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->HPCoefs, &pPrivate->pFastData->HPTaps,
                                         &Coeffs);
         LoadConst_Float(0, (LVM_FLOAT*)&pPrivate->pFastData->HPTaps,
                         sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
+#endif
     }
 
     /*
@@ -99,10 +110,17 @@
                 LVM_FO_LPF(Omega, &Coeffs);
             }
         }
+#ifdef BIQUAD_OPT
+        const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                Coeffs.A0, Coeffs.A1, 0.0, -(Coeffs.B1), 0.0};
+        pPrivate->pRevLPFBiquad.reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
         FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->LPCoefs, &pPrivate->pFastData->LPTaps,
                                         &Coeffs);
         LoadConst_Float(0, (LVM_FLOAT*)&pPrivate->pFastData->LPTaps,
                         sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
+#endif
     }
 
     /*
@@ -130,10 +148,6 @@
         LVM_INT16 i;
         LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4,
                                   LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
-        LVM_INT16 MaxT_Delay[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, LVREV_MAX_T2_DELAY,
-                                  LVREV_MAX_T3_DELAY};
-        LVM_INT16 MaxAP_Delay[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY, LVREV_MAX_AP2_DELAY,
-                                   LVREV_MAX_AP3_DELAY};
 
         /*
          * For each delay line
@@ -153,7 +167,7 @@
              * Set the fixed delay
              */
 
-            Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 192000;
+            Temp = (LVREV_MAX_T_DELAY[i] - LVREV_MAX_AP_DELAY[i]) * Fs / 192000;
             pPrivate->Delay_AP[i] = pPrivate->T[i] - Temp;
 
             /*
@@ -231,8 +245,15 @@
                 Coeffs.A1 = 0;
                 Coeffs.B1 = 0;
             }
+#ifdef BIQUAD_OPT
+            const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                    Coeffs.A0, Coeffs.A1, 0.0, -(Coeffs.B1), 0.0};
+            pPrivate->revLPFBiquad[i].reset(
+                    new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
             FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->RevLPCoefs[i],
                                             &pPrivate->pFastData->RevLPTaps[i], &Coeffs);
+#endif
         }
     }
 
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
index 5c83ce5..61b3732 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
@@ -56,31 +56,20 @@
      * Clear all filter tap data, delay-lines and other signal related data
      */
 
+#ifdef BIQUAD_OPT
+    pLVREV_Private->pRevHPFBiquad->clear();
+    pLVREV_Private->pRevLPFBiquad->clear();
+#else
     LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->HPTaps, 2);
     LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->LPTaps, 2);
-    if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays == LVREV_DELAYLINES_4) {
-        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[3], 2);
-        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[2], 2);
-        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
-        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
-
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
-    }
-
-    if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_2) {
-        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
-        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
-
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
-    }
-
-    if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_1) {
-        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+#endif
+    for (size_t i = 0; i < pLVREV_Private->InstanceParams.NumDelays; i++) {
+#ifdef BIQUAD_OPT
+        pLVREV_Private->revLPFBiquad[i]->clear();
+#else
+        LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[i], 2);
+#endif
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[i], LVREV_MAX_T_DELAY[i]);
     }
     return LVREV_SUCCESS;
 }
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
index b5db23b..fa96e52 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
@@ -120,11 +120,11 @@
     pLVREV_Private->MemoryTable = *pMemoryTable;
 
     if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
-        MaxBlockSize = LVREV_MAX_AP3_DELAY;
+        MaxBlockSize = LVREV_MAX_AP_DELAY[3];
     } else if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
-        MaxBlockSize = LVREV_MAX_AP1_DELAY;
+        MaxBlockSize = LVREV_MAX_AP_DELAY[1];
     } else {
-        MaxBlockSize = LVREV_MAX_AP0_DELAY;
+        MaxBlockSize = LVREV_MAX_AP_DELAY[0];
     }
 
     if (MaxBlockSize > pInstanceParams->MaxBlockSize) {
@@ -134,69 +134,30 @@
     /*
      * Set the data, coefficient and temporary memory pointers
      */
+#ifndef BIQUAD_OPT
     /* Fast data memory base address */
     pLVREV_Private->pFastData =
             (LVREV_FastData_st*)InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
-    if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
-        pLVREV_Private->pDelay_T[3] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
-        pLVREV_Private->pDelay_T[2] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * sizeof(LVM_FLOAT));
-        pLVREV_Private->pDelay_T[1] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
-        pLVREV_Private->pDelay_T[0] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-
-        for (i = 0; i < 4; i++) {
-            /* Scratch for each delay line output */
-            pLVREV_Private->pScratchDelayLine[i] =
-                    (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-        }
-
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
-    }
-
-    if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
-        pLVREV_Private->pDelay_T[1] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
-        pLVREV_Private->pDelay_T[0] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-
-        for (i = 0; i < 2; i++) {
-            /* Scratch for each delay line output */
-            pLVREV_Private->pScratchDelayLine[i] =
-                    (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-        }
-
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[1], (LVM_INT16)LVREV_MAX_T1_DELAY);
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
-    }
-
-    if (pInstanceParams->NumDelays == LVREV_DELAYLINES_1) {
-        pLVREV_Private->pDelay_T[0] =
-                (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-
-        for (i = 0; i < 1; i++) {
-            /* Scratch for each delay line output */
-            pLVREV_Private->pScratchDelayLine[i] =
-                    (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-        }
-
-        LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+#endif
+    for (size_t i = 0; i < pInstanceParams->NumDelays; i++) {
+        pLVREV_Private->pDelay_T[i] = (LVM_FLOAT*)InstAlloc_AddMember(
+                &FastData, LVREV_MAX_T_DELAY[i] * sizeof(LVM_FLOAT));
+        /* Scratch for each delay line output */
+        pLVREV_Private->pScratchDelayLine[i] =
+                (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+        LoadConst_Float(0, pLVREV_Private->pDelay_T[i], LVREV_MAX_T_DELAY[i]);
     }
     /* All-pass delay buffer addresses and sizes */
-    pLVREV_Private->T[0] = LVREV_MAX_T0_DELAY;
-    pLVREV_Private->T[1] = LVREV_MAX_T1_DELAY;
-    pLVREV_Private->T[2] = LVREV_MAX_T2_DELAY;
-    pLVREV_Private->T[3] = LVREV_MAX_T3_DELAY;
+    for (size_t i = 0; i < LVREV_DELAYLINES_4; i++) {
+        pLVREV_Private->T[i] = LVREV_MAX_T_DELAY[i];
+    }
     pLVREV_Private->AB_Selection = 1; /* Select smoothing A to B */
 
+#ifndef BIQUAD_OPT
     /* Fast coefficient memory base address */
     pLVREV_Private->pFastCoef =
             (LVREV_FastCoef_st*)InstAlloc_AddMember(&FastCoef, sizeof(LVREV_FastCoef_st));
+#endif
     /* General purpose scratch */
     pLVREV_Private->pScratch =
             (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
@@ -299,14 +260,21 @@
         pLVREV_Private->FeedbackMixer[i].Target = 0;
     }
     /* Delay tap index */
-    pLVREV_Private->A_DelaySize[0] = LVREV_MAX_AP0_DELAY;
-    pLVREV_Private->B_DelaySize[0] = LVREV_MAX_AP0_DELAY;
-    pLVREV_Private->A_DelaySize[1] = LVREV_MAX_AP1_DELAY;
-    pLVREV_Private->B_DelaySize[1] = LVREV_MAX_AP1_DELAY;
-    pLVREV_Private->A_DelaySize[2] = LVREV_MAX_AP2_DELAY;
-    pLVREV_Private->B_DelaySize[2] = LVREV_MAX_AP2_DELAY;
-    pLVREV_Private->A_DelaySize[3] = LVREV_MAX_AP3_DELAY;
-    pLVREV_Private->B_DelaySize[3] = LVREV_MAX_AP3_DELAY;
+    for (size_t i = 0; i < LVREV_DELAYLINES_4; i++) {
+        pLVREV_Private->A_DelaySize[i] = LVREV_MAX_AP_DELAY[i];
+        pLVREV_Private->B_DelaySize[i] = LVREV_MAX_AP_DELAY[i];
+    }
+
+#ifdef BIQUAD_OPT
+    pLVREV_Private->pRevHPFBiquad.reset(
+            new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+    pLVREV_Private->pRevLPFBiquad.reset(
+            new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+    for (int i = 0; i < LVREV_DELAYLINES_4; i++) {
+        pLVREV_Private->revLPFBiquad[i].reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+    }
+#endif
 
     LVREV_ClearAudioBuffers(*phInstance);
 
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
index 2c1e04d..b344b20 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
@@ -63,7 +63,6 @@
     INST_ALLOC FastData;
     INST_ALLOC FastCoef;
     INST_ALLOC Temporary;
-    LVM_INT16 i;
     LVM_UINT16 MaxBlockSize;
 
     /*
@@ -117,11 +116,11 @@
          * Select the maximum internal block size
          */
         if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
-            MaxBlockSize = LVREV_MAX_AP3_DELAY;
+            MaxBlockSize = LVREV_MAX_AP_DELAY[3];
         } else if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
-            MaxBlockSize = LVREV_MAX_AP1_DELAY;
+            MaxBlockSize = LVREV_MAX_AP_DELAY[1];
         } else {
-            MaxBlockSize = LVREV_MAX_AP0_DELAY;
+            MaxBlockSize = LVREV_MAX_AP_DELAY[0];
         }
 
         if (MaxBlockSize > pInstanceParams->MaxBlockSize) {
@@ -139,21 +138,11 @@
         /*
          * Persistent fast data memory
          */
+#ifndef BIQUAD_OPT
         InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * sizeof(LVM_FLOAT));
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-        }
-
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-        }
-
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_1) {
-            InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+#endif
+        for (size_t i = 0; i < pInstanceParams->NumDelays; i++) {
+            InstAlloc_AddMember(&FastData, LVREV_MAX_T_DELAY[i] * sizeof(LVM_FLOAT));
         }
 
         pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size = InstAlloc_GetTotal(&FastData);
@@ -163,7 +152,9 @@
         /*
          * Persistent fast coefficient memory
          */
+#ifndef BIQUAD_OPT
         InstAlloc_AddMember(&FastCoef, sizeof(LVREV_FastCoef_st));
+#endif
         pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Size = InstAlloc_GetTotal(&FastCoef);
         pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Type = LVM_PERSISTENT_FAST_COEF;
         pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress = LVM_NULL;
@@ -175,25 +166,9 @@
         InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
         /* Mono->stereo input saved for end mix */
         InstAlloc_AddMember(&Temporary, 2 * sizeof(LVM_FLOAT) * MaxBlockSize);
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
-            for (i = 0; i < 4; i++) {
-                /* A Scratch buffer for each delay line */
-                InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-            }
-        }
-
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
-            for (i = 0; i < 2; i++) {
-                /* A Scratch buffer for each delay line */
-                InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-            }
-        }
-
-        if (pInstanceParams->NumDelays == LVREV_DELAYLINES_1) {
-            for (i = 0; i < 1; i++) {
-                /* A Scratch buffer for each delay line */
-                InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
-            }
+        for (size_t i = 0; i < pInstanceParams->NumDelays; i++) {
+            /* A Scratch buffer for each delay line */
+            InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
         }
 
         pMemoryTable->Region[LVM_TEMPORARY_FAST].Size = InstAlloc_GetTotal(&Temporary);
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
index b6edb03..c62ad1e 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
@@ -23,6 +23,10 @@
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
+
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVREV.h"
 #include "LVREV_Tables.h"
 #include "BIQUAD.h"
@@ -101,21 +105,23 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifndef BIQUAD_OPT
 /* Fast data structure */
 typedef struct {
     Biquad_1I_Order1_FLOAT_Taps_t HPTaps;       /* High pass filter taps */
     Biquad_1I_Order1_FLOAT_Taps_t LPTaps;       /* Low pass filter taps */
-    Biquad_1I_Order1_FLOAT_Taps_t RevLPTaps[4]; /* Reverb low pass filters taps */
-
+    Biquad_1I_Order1_FLOAT_Taps_t RevLPTaps[LVREV_DELAYLINES_4]; /* Reverb low pass filters taps */
 } LVREV_FastData_st;
 
 /* Fast coefficient structure */
 typedef struct {
     Biquad_FLOAT_Instance_t HPCoefs;       /* High pass filter coefficients */
     Biquad_FLOAT_Instance_t LPCoefs;       /* Low pass filter coefficients */
-    Biquad_FLOAT_Instance_t RevLPCoefs[4]; /* Reverb low pass filters coefficients */
-
+    Biquad_FLOAT_Instance_t
+            RevLPCoefs[LVREV_DELAYLINES_4]; /* Reverb low pass filters coefficients */
 } LVREV_FastCoef_st;
+#endif
+
 typedef struct {
     /* General */
     LVREV_InstanceParams_st InstanceParams; /* Initialisation time instance parameters */
@@ -134,30 +140,39 @@
                                                processing */
 
     /* Aligned memory pointers */
-    LVREV_FastData_st* pFastData;    /* Fast data memory base address */
-    LVREV_FastCoef_st* pFastCoef;    /* Fast coefficient memory base address */
-    LVM_FLOAT* pScratchDelayLine[4]; /* Delay line scratch memory */
+#ifdef BIQUAD_OPT
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pRevHPFBiquad; /* Biquad filter instance for HPF */
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pRevLPFBiquad; /* Biquad filter instance for LPF */
+    std::array<std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>, LVREV_DELAYLINES_4>
+            revLPFBiquad; /* Biquad filter instance for Reverb LPF */
+#else
+    LVREV_FastData_st* pFastData; /* Fast data memory base address */
+    LVREV_FastCoef_st* pFastCoef; /* Fast coefficient memory base address */
+#endif
+    LVM_FLOAT* pScratchDelayLine[LVREV_DELAYLINES_4]; /* Delay line scratch memory */
     LVM_FLOAT* pScratch;             /* Multi ussge scratch */
     LVM_FLOAT* pInputSave;           /* Reverb block input save for dry/wet
                                         mixing*/
 
     /* Feedback matrix */
-    Mix_1St_Cll_FLOAT_t FeedbackMixer[4]; /* Mixer for Pop and Click Suppression \
+    Mix_1St_Cll_FLOAT_t FeedbackMixer[LVREV_DELAYLINES_4]; /* Mixer for Pop and Click Suppression \
                                              caused by feedback Gain */
 
     /* All-Pass Filter */
-    LVM_INT32 T[4];                             /* Maximum delay size of buffer */
-    LVM_FLOAT* pDelay_T[4];                     /* Pointer to delay buffers */
-    LVM_INT32 Delay_AP[4];                      /* Offset to AP delay buffer start */
+    LVM_INT32 T[LVREV_DELAYLINES_4];                          /* Maximum delay size of buffer */
+    LVM_FLOAT* pDelay_T[LVREV_DELAYLINES_4];                  /* Pointer to delay buffers */
+    LVM_INT32 Delay_AP[LVREV_DELAYLINES_4];                   /* Offset to AP delay buffer start */
     LVM_INT16 AB_Selection;                     /* Smooth from tap A to B when 1 \
                                                    otherwise B to A */
-    LVM_INT32 A_DelaySize[4];                   /* A delay length in samples */
-    LVM_INT32 B_DelaySize[4];                   /* B delay length in samples */
-    LVM_FLOAT* pOffsetA[4];                     /* Offset for the A delay tap */
-    LVM_FLOAT* pOffsetB[4];                     /* Offset for the B delay tap */
-    Mix_2St_Cll_FLOAT_t Mixer_APTaps[4];        /* Smoothed AP delay mixer */
-    Mix_1St_Cll_FLOAT_t Mixer_SGFeedback[4];    /* Smoothed SAfeedback gain */
-    Mix_1St_Cll_FLOAT_t Mixer_SGFeedforward[4]; /* Smoothed AP feedforward gain */
+    LVM_INT32 A_DelaySize[LVREV_DELAYLINES_4];                /* A delay length in samples */
+    LVM_INT32 B_DelaySize[LVREV_DELAYLINES_4];                /* B delay length in samples */
+    LVM_FLOAT* pOffsetA[LVREV_DELAYLINES_4];                  /* Offset for the A delay tap */
+    LVM_FLOAT* pOffsetB[LVREV_DELAYLINES_4];                  /* Offset for the B delay tap */
+    Mix_2St_Cll_FLOAT_t Mixer_APTaps[LVREV_DELAYLINES_4];     /* Smoothed AP delay mixer */
+    Mix_1St_Cll_FLOAT_t Mixer_SGFeedback[LVREV_DELAYLINES_4]; /* Smoothed SAfeedback gain */
+    Mix_1St_Cll_FLOAT_t Mixer_SGFeedforward[LVREV_DELAYLINES_4]; /* Smoothed AP feedforward gain */
 
     /* Output gain */
     Mix_2St_Cll_FLOAT_t BypassMixer; /* Dry/wet mixer */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp
index ed3b89c..e4f939f 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp
@@ -204,11 +204,20 @@
     /*
      *  High pass filter
      */
+#ifdef BIQUAD_OPT
+    pPrivate->pRevHPFBiquad->process(pTemp, pTemp, NumSamples);
+#else
     FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->HPCoefs, pTemp, pTemp, (LVM_INT16)NumSamples);
+#endif
+
     /*
      *  Low pass filter
      */
+#ifdef BIQUAD_OPT
+    pPrivate->pRevLPFBiquad->process(pTemp, pTemp, NumSamples);
+#else
     FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->LPCoefs, pTemp, pTemp, (LVM_INT16)NumSamples);
+#endif
 
     /*
      *  Process all delay lines
@@ -253,8 +262,12 @@
         /*
          *  Low pass filter
          */
+#ifdef BIQUAD_OPT
+        pPrivate->revLPFBiquad[j]->process(pDelayLine, pDelayLine, NumSamples);
+#else
         FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->RevLPCoefs[j], pDelayLine, pDelayLine,
                                    (LVM_INT16)NumSamples);
+#endif
     }
 
     /*
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp
index 35a6522..bb6cf12 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp
@@ -29,6 +29,11 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+const LVM_INT16 LVREV_MAX_T_DELAY[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, LVREV_MAX_T2_DELAY,
+                                       LVREV_MAX_T3_DELAY};
+const LVM_INT16 LVREV_MAX_AP_DELAY[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY,
+                                        LVREV_MAX_AP2_DELAY, LVREV_MAX_AP3_DELAY};
+
 /* Table with supported sampling rates.  The table can be indexed using LVM_Fs_en       */
 const LVM_UINT32 LVM_FsTable[] = {8000,  11025, 12000, 16000, 22050,  24000, 32000,
                                   44100, 48000, 88200, 96000, 176400, 192000};
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
index 4b0dcca..723d1ff 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
@@ -35,6 +35,8 @@
 extern LVM_UINT32 LVM_GetFsFromTable(LVM_Fs_en FsIndex);
 
 extern const LVM_FLOAT LVREV_GainPolyTable[24][5];
+extern const LVM_INT16 LVREV_MAX_T_DELAY[];
+extern const LVM_INT16 LVREV_MAX_AP_DELAY[];
 
 #endif /** _LVREV_TABLES_H_ **/
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
index 4e90a42..436e7cb 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
@@ -15,6 +15,9 @@
  * limitations under the License.
  */
 
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include "LVPSA.h"
 #include "LVPSA_Private.h"
 #include "VectorArithmetic.h"
@@ -182,6 +185,13 @@
                 break;
             }
         }
+#ifdef BIQUAD_OPT
+        /*
+         * Create biquad instance
+         */
+        pInst->specBiquad.resize(pInst->nRelevantFilters,
+                                 android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1));
+#endif
         LVPSA_SetBPFiltersType(pInst, &Params);
         LVPSA_SetBPFCoefficients(pInst, &Params);
         LVPSA_SetQPFCoefficients(pInst, &Params);
@@ -302,8 +312,18 @@
                 /*
                  * Set the coefficients
                  */
+#ifdef BIQUAD_OPT
+                const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                        Coefficients.A0, 0.0, -(Coefficients.A0), -(Coefficients.B1),
+                        -(Coefficients.B2)};
+                pInst->specBiquad[ii]
+                        .setCoefficients<
+                                std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(
+                                coefs);
+#else
                 BP_1I_D16F32Cll_TRC_WRA_01_Init(&pInst->pBP_Instances[ii], &pInst->pBP_Taps[ii],
                                                 &Coefficients);
+#endif
                 break;
             }
 
@@ -319,8 +339,18 @@
                 /*
                  * Set the coefficients
                  */
+#ifdef BIQUAD_OPT
+                const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                        Coefficients.A0, 0.0, -(Coefficients.A0), -(Coefficients.B1),
+                        -(Coefficients.B2)};
+                pInst->specBiquad[ii]
+                        .setCoefficients<
+                                std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(
+                                coefs);
+#else
                 BP_1I_D16F16Css_TRC_WRA_01_Init(&pInst->pBP_Instances[ii], &pInst->pBP_Taps[ii],
                                                 &Coefficients);
+#endif
                 break;
             }
         }
@@ -604,6 +634,11 @@
 /*                                                                                  */
 /************************************************************************************/
 LVPSA_RETURN LVPSA_ClearFilterHistory(LVPSA_InstancePr_t* pInst) {
+#ifdef BIQUAD_OPT
+    for (size_t i = 0; i < pInst->specBiquad.size(); i++) {
+        pInst->specBiquad[i].clear();
+    }
+#else
     LVM_INT8* pTapAddress;
     LVM_UINT32 i;
 
@@ -617,6 +652,7 @@
     for (i = 0; i < pInst->nBands * sizeof(QPD_Taps_t); i++) {
         pTapAddress[i] = 0;
     }
+#endif
 
     return (LVPSA_OK);
 }
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
index 9a2b29f..f77460b 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
@@ -108,21 +108,25 @@
     if (pLVPSA_Inst->pBPFiltersPrecision == LVM_NULL) {
         return LVPSA_ERROR_NULLADDRESS;
     }
+#ifndef BIQUAD_OPT
     pLVPSA_Inst->pBP_Instances = (Biquad_FLOAT_Instance_t*)calloc(
             pInitParams->nBands, sizeof(*(pLVPSA_Inst->pBP_Instances)));
     if (pLVPSA_Inst->pBP_Instances == LVM_NULL) {
         return LVPSA_ERROR_NULLADDRESS;
     }
+#endif
     pLVPSA_Inst->pQPD_States =
             (QPD_FLOAT_State_t*)calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pQPD_States)));
     if (pLVPSA_Inst->pQPD_States == LVM_NULL) {
         return LVPSA_ERROR_NULLADDRESS;
     }
+#ifndef BIQUAD_OPT
     pLVPSA_Inst->pBP_Taps = (Biquad_1I_Order2_FLOAT_Taps_t*)calloc(
             pInitParams->nBands, sizeof(*(pLVPSA_Inst->pBP_Taps)));
     if (pLVPSA_Inst->pBP_Taps == LVM_NULL) {
         return LVPSA_ERROR_NULLADDRESS;
     }
+#endif
     pLVPSA_Inst->pQPD_Taps =
             (QPD_FLOAT_Taps_t*)calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pQPD_Taps)));
     if (pLVPSA_Inst->pQPD_Taps == LVM_NULL) {
@@ -193,18 +197,22 @@
         free(pLVPSA_Inst->pBPFiltersPrecision);
         pLVPSA_Inst->pBPFiltersPrecision = LVM_NULL;
     }
+#ifndef BIQUAD_OPT
     if (pLVPSA_Inst->pBP_Instances != LVM_NULL) {
         free(pLVPSA_Inst->pBP_Instances);
         pLVPSA_Inst->pBP_Instances = LVM_NULL;
     }
+#endif
     if (pLVPSA_Inst->pQPD_States != LVM_NULL) {
         free(pLVPSA_Inst->pQPD_States);
         pLVPSA_Inst->pQPD_States = LVM_NULL;
     }
+#ifndef BIQUAD_OPT
     if (pLVPSA_Inst->pBP_Taps != LVM_NULL) {
         free(pLVPSA_Inst->pBP_Taps);
         pLVPSA_Inst->pBP_Taps = LVM_NULL;
     }
+#endif
     if (pLVPSA_Inst->pQPD_Taps != LVM_NULL) {
         free(pLVPSA_Inst->pQPD_Taps);
         pLVPSA_Inst->pQPD_Taps = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
index e00c11c..553156f 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
@@ -18,6 +18,9 @@
 #ifndef _LVPSA_PRIVATE_H_
 #define _LVPSA_PRIVATE_H_
 
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVPSA.h"
 #include "BIQUAD.h"
 #include "LVPSA_QPD.h"
@@ -82,9 +85,14 @@
 
     LVPSA_BPFilterPrecision_en* pBPFiltersPrecision; /* Points a nBands elements array that contains
                                                         the filter precision for each band */
+#ifdef BIQUAD_OPT
+    std::vector<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            specBiquad; /* Biquad filter instances */
+#else
     Biquad_FLOAT_Instance_t* pBP_Instances;
     /* Points a nBands elements array that contains the band pass filter taps for each band */
     Biquad_1I_Order2_FLOAT_Taps_t* pBP_Taps;
+#endif
     /* Points a nBands elements array that contains the QPD filter instance for each band */
     QPD_FLOAT_State_t* pQPD_States;
     /* Points a nBands elements array that contains the QPD filter taps for each band */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
index 299dfd2..148b21f 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
@@ -96,13 +96,23 @@
     for (ii = 0; ii < pLVPSA_Inst->nRelevantFilters; ii++) {
         switch (pLVPSA_Inst->pBPFiltersPrecision[ii]) {
             case LVPSA_SimplePrecisionFilter:
+#ifdef BIQUAD_OPT
+                pLVPSA_Inst->specBiquad[ii].process(pScratch + InputBlockSize, pScratch,
+                                                    (LVM_INT16)InputBlockSize);
+#else
                 BP_1I_D16F16C14_TRC_WRA_01(&pLVPSA_Inst->pBP_Instances[ii], pScratch,
                                            pScratch + InputBlockSize, (LVM_INT16)InputBlockSize);
+#endif
                 break;
 
             case LVPSA_DoublePrecisionFilter:
+#ifdef BIQUAD_OPT
+                pLVPSA_Inst->specBiquad[ii].process(pScratch + InputBlockSize, pScratch,
+                                                    (LVM_INT16)InputBlockSize);
+#else
                 BP_1I_D16F32C30_TRC_WRA_01(&pLVPSA_Inst->pBP_Instances[ii], pScratch,
                                            pScratch + InputBlockSize, (LVM_INT16)InputBlockSize);
+#endif
                 break;
             default:
                 break;
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp
index bad9aef..a5952fb 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.cpp
@@ -21,6 +21,9 @@
 /*                                                                                  */
 /************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include "LVCS.h"
 #include "LVCS_Private.h"
 #include "LVCS_Equaliser.h"
@@ -56,14 +59,18 @@
 LVCS_ReturnStatus_en LVCS_EqualiserInit(LVCS_Handle_t hInstance, LVCS_Params_t* pParams) {
     LVM_UINT16 Offset;
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
+#ifndef BIQUAD_OPT
     LVCS_Equaliser_t* pConfig = (LVCS_Equaliser_t*)&pInstance->Equaliser;
     LVCS_Data_t* pData;
     LVCS_Coefficient_t* pCoefficients;
     BQ_FLOAT_Coefs_t Coeffs;
+#endif
     const BiquadA012B12CoefsSP_t* pEqualiserCoefTable;
 
+#ifndef BIQUAD_OPT
     pData = (LVCS_Data_t*)pInstance->pData;
     pCoefficients = (LVCS_Coefficient_t*)pInstance->pCoeff;
+#endif
     /*
      * If the sample rate changes re-initialise the filters
      */
@@ -75,6 +82,13 @@
         Offset = (LVM_UINT16)(pParams->SampleRate + (pParams->SpeakerType * (1 + LVM_FS_48000)));
         pEqualiserCoefTable = (BiquadA012B12CoefsSP_t*)&LVCS_EqualiserCoefTable[0];
 
+#ifdef BIQUAD_OPT
+        std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                pEqualiserCoefTable[Offset].A0, pEqualiserCoefTable[Offset].A1,
+                pEqualiserCoefTable[Offset].A2, -(pEqualiserCoefTable[Offset].B1),
+                -(pEqualiserCoefTable[Offset].B2)};
+        pInstance->pEqBiquad.reset(new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_2, coefs));
+#else
         /* Left and right filters */
         /* Convert incoming coefficients to the required format/ordering */
         Coeffs.A0 = (LVM_FLOAT)pEqualiserCoefTable[Offset].A0;
@@ -103,6 +117,7 @@
                 pConfig->pBiquadCallBack = BQ_2I_D16F32C15_TRC_WRA_01;
                 break;
         }
+#endif
     }
 
     return (LVCS_SUCCESS);
@@ -129,19 +144,25 @@
 LVCS_ReturnStatus_en LVCS_Equaliser(LVCS_Handle_t hInstance, LVM_FLOAT* pInputOutput,
                                     LVM_UINT16 NumSamples) {
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
+#ifndef BIQUAD_OPT
     LVCS_Equaliser_t* pConfig = (LVCS_Equaliser_t*)&pInstance->Equaliser;
     LVCS_Coefficient_t* pCoefficients;
 
     pCoefficients = (LVCS_Coefficient_t*)pInstance->pCoeff;
+#endif
 
     /*
      * Check if the equaliser is required
      */
     if ((pInstance->Params.OperatingMode & LVCS_EQUALISERSWITCH) != 0) {
         /* Apply filter to the left and right channels */
+#ifdef BIQUAD_OPT
+        pInstance->pEqBiquad->process(pInputOutput, pInputOutput, NumSamples);
+#else
         (pConfig->pBiquadCallBack)(
                 (Biquad_FLOAT_Instance_t*)&pCoefficients->EqualiserBiquadInstance,
                 (LVM_FLOAT*)pInputOutput, (LVM_FLOAT*)pInputOutput, (LVM_INT16)NumSamples);
+#endif
     }
 
     return (LVCS_SUCCESS);
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp
index 5c8f1ae..f23261f 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.cpp
@@ -123,6 +123,7 @@
     if (pInstance == LVM_NULL) {
         return;
     }
+#ifndef BIQUAD_OPT
     if (pInstance->pCoeff != LVM_NULL) {
         free(pInstance->pCoeff);
         pInstance->pCoeff = LVM_NULL;
@@ -131,6 +132,7 @@
         free(pInstance->pData);
         pInstance->pData = LVM_NULL;
     }
+#endif
     free(pInstance);
     *phInstance = LVM_NULL;
     return;
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
index f9c23b3..a150e90 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -33,6 +33,9 @@
 /*                                                                                  */
 /************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVCS.h"                 /* Calling or Application layer definitions */
 #include "LVCS_StereoEnhancer.h"  /* Stereo enhancer module definitions */
 #include "LVCS_ReverbGenerator.h" /* Reverberation module definitions */
@@ -120,12 +123,24 @@
     LVM_INT16 bTimerDone;                 /* Timer completion flag */
     LVM_Timer_Params_t TimerParams;       /* Timer parameters */
     LVM_Timer_Instance_t TimerInstance;   /* Timer instance */
+#ifdef BIQUAD_OPT
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pEqBiquad; /* Biquad filter instance for Equaliser */
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pRevBiquad; /* Biquad filter instance for Reverberation */
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pSEMidBiquad; /* Biquad filter instance for Stereo enhancement mid */
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pSESideBiquad; /* Biquad filter instance for Stereo enhancement side */
+#else
     void* pCoeff;                         /* pointer to buffer for equaliser filter coeffs */
     void* pData;                          /* pointer to buffer for equaliser filter states */
+#endif
     void* pScratch;                       /* Pointer to bundle scratch buffer */
 
 } LVCS_Instance_t;
 
+#ifndef BIQUAD_OPT
 /* Coefficient Structure */
 typedef struct {
     Biquad_FLOAT_Instance_t EqualiserBiquadInstance;
@@ -141,6 +156,7 @@
     Biquad_1I_Order1_FLOAT_Taps_t SEBiquadTapsMid;
     Biquad_1I_Order2_FLOAT_Taps_t SEBiquadTapsSide;
 } LVCS_Data_t;
+#endif
 
 void LVCS_TimerCallBack(void* hInstance, void* pCallBackParams, LVM_INT32 CallbackParam);
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp
index f6d2453..82a3a43 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.cpp
@@ -20,6 +20,9 @@
 /*  Includes                                                                        */
 /*                                                                                  */
 /************************************************************************************/
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include <stdlib.h>
 #include "LVCS.h"
 #include "LVCS_Private.h"
@@ -62,11 +65,14 @@
     LVM_UINT16 Offset;
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
     LVCS_ReverbGenerator_t* pConfig = (LVCS_ReverbGenerator_t*)&pInstance->Reverberation;
+#ifndef BIQUAD_OPT
     LVCS_Data_t* pData;
     LVCS_Coefficient_t* pCoefficients;
     BQ_FLOAT_Coefs_t Coeffs;
+#endif
     const BiquadA012B12CoefsSP_t* pReverbCoefTable;
 
+#ifndef BIQUAD_OPT
     if (pInstance->pData == LVM_NULL) {
         pInstance->pData = pData = (LVCS_Data_t*)calloc(1, sizeof(*pData));
         if (pData == LVM_NULL) {
@@ -83,6 +89,7 @@
     } else {
         pCoefficients = (LVCS_Coefficient_t*)pInstance->pCoeff;
     }
+#endif
 
     /*
      * Initialise the delay and filters if:
@@ -109,6 +116,14 @@
         Offset = (LVM_UINT16)pParams->SampleRate;
         pReverbCoefTable = (BiquadA012B12CoefsSP_t*)&LVCS_ReverbCoefTable[0];
 
+#ifdef BIQUAD_OPT
+        std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                pReverbCoefTable[Offset].A0, pReverbCoefTable[Offset].A1,
+                pReverbCoefTable[Offset].A2, -(pReverbCoefTable[Offset].B1),
+                -(pReverbCoefTable[Offset].B2)};
+        pInstance->pRevBiquad.reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_2, coefs));
+#else
         /* Convert incoming coefficients to the required format/ordering */
         Coeffs.A0 = (LVM_FLOAT)pReverbCoefTable[Offset].A0;
         Coeffs.A1 = (LVM_FLOAT)pReverbCoefTable[Offset].A1;
@@ -133,6 +148,7 @@
                 pConfig->pBiquadCallBack = BQ_2I_D16F16C15_TRC_WRA_01;
                 break;
         }
+#endif
 
         /*
          * Setup the mixer
@@ -190,10 +206,14 @@
                                           LVM_FLOAT* pOutData, LVM_UINT16 NumSamples) {
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
     LVCS_ReverbGenerator_t* pConfig = (LVCS_ReverbGenerator_t*)&pInstance->Reverberation;
+#ifndef BIQUAD_OPT
     LVCS_Coefficient_t* pCoefficients;
+#endif
     LVM_FLOAT* pScratch;
 
+#ifndef BIQUAD_OPT
     pCoefficients = (LVCS_Coefficient_t*)pInstance->pCoeff;
+#endif
     pScratch = (LVM_FLOAT*)pInstance->pScratch;
 
     /*
@@ -233,9 +253,13 @@
         /*
          * Filter the data
          */
+#ifdef BIQUAD_OPT
+        pInstance->pRevBiquad->process(pScratch, pScratch, NumSamples);
+#else
         (pConfig->pBiquadCallBack)((Biquad_FLOAT_Instance_t*)&pCoefficients->ReverbBiquadInstance,
                                    (LVM_FLOAT*)pScratch, (LVM_FLOAT*)pScratch,
                                    (LVM_INT16)NumSamples);
+#endif
 
         Mult3s_Float((LVM_FLOAT*)pScratch, pConfig->ReverbLevel, (LVM_FLOAT*)pScratch,
                      (LVM_INT16)(2 * NumSamples));
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp
index ffa9c9b..0e488f5 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.cpp
@@ -21,6 +21,9 @@
 /*                                                                                  */
 /************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
 #include "LVCS.h"
 #include "LVCS_Private.h"
 #include "LVCS_StereoEnhancer.h"
@@ -52,15 +55,19 @@
 LVCS_ReturnStatus_en LVCS_SEnhancerInit(LVCS_Handle_t hInstance, LVCS_Params_t* pParams) {
     LVM_UINT16 Offset;
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
+#ifndef BIQUAD_OPT
     LVCS_StereoEnhancer_t* pConfig = (LVCS_StereoEnhancer_t*)&pInstance->StereoEnhancer;
     LVCS_Data_t* pData;
     LVCS_Coefficient_t* pCoefficient;
     FO_FLOAT_Coefs_t CoeffsMid;
     BQ_FLOAT_Coefs_t CoeffsSide;
+#endif
     const BiquadA012B12CoefsSP_t* pSESideCoefs;
 
+#ifndef BIQUAD_OPT
     pData = (LVCS_Data_t*)pInstance->pData;
     pCoefficient = (LVCS_Coefficient_t*)pInstance->pCoeff;
+#endif
 
     /*
      * If the sample rate or speaker type has changed update the filters
@@ -73,6 +80,13 @@
         /* Mid filter */
         Offset = (LVM_UINT16)pParams->SampleRate;
 
+#ifdef BIQUAD_OPT
+        std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+                LVCS_SEMidCoefTable[Offset].A0, LVCS_SEMidCoefTable[Offset].A1, 0.0,
+                -(LVCS_SEMidCoefTable[Offset].B1), 0.0};
+        pInstance->pSEMidBiquad.reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
         /* Convert incoming coefficients to the required format/ordering */
         CoeffsMid.A0 = (LVM_FLOAT)LVCS_SEMidCoefTable[Offset].A0;
         CoeffsMid.A1 = (LVM_FLOAT)LVCS_SEMidCoefTable[Offset].A1;
@@ -91,11 +105,18 @@
         if (LVCS_SEMidCoefTable[Offset].Scale == 15) {
             pConfig->pBiquadCallBack_Mid = FO_1I_D16F16C15_TRC_WRA_01;
         }
+#endif
 
         Offset = (LVM_UINT16)(pParams->SampleRate);
         pSESideCoefs = (BiquadA012B12CoefsSP_t*)&LVCS_SESideCoefTable[0];
 
         /* Side filter */
+#ifdef BIQUAD_OPT
+        coefs = {pSESideCoefs[Offset].A0, pSESideCoefs[Offset].A1, pSESideCoefs[Offset].A2,
+                 -(pSESideCoefs[Offset].B1), -(pSESideCoefs[Offset].B2)};
+        pInstance->pSESideBiquad.reset(
+                new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
         /* Convert incoming coefficients to the required format/ordering */
         CoeffsSide.A0 = (LVM_FLOAT)pSESideCoefs[Offset].A0;
         CoeffsSide.A1 = (LVM_FLOAT)pSESideCoefs[Offset].A1;
@@ -123,6 +144,7 @@
                 pConfig->pBiquadCallBack_Side = BQ_1I_D16F16C15_TRC_WRA_01;
                 break;
         }
+#endif
     }
 
     return (LVCS_SUCCESS);
@@ -169,9 +191,13 @@
                                          LVM_FLOAT* pOutData, LVM_UINT16 NumSamples) {
     LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
     LVCS_StereoEnhancer_t* pConfig = (LVCS_StereoEnhancer_t*)&pInstance->StereoEnhancer;
+#ifndef BIQUAD_OPT
     LVCS_Coefficient_t* pCoefficient;
+#endif
     LVM_FLOAT* pScratch;
+#ifndef BIQUAD_OPT
     pCoefficient = (LVCS_Coefficient_t*)pInstance->pCoeff;
+#endif
     pScratch = (LVM_FLOAT*)pInstance->pScratch;
     /*
      * Check if the Stereo Enhancer is enabled
@@ -186,9 +212,13 @@
          * Apply filter to the middle signal
          */
         if (pInstance->OutputDevice == LVCS_HEADPHONE) {
+#ifdef BIQUAD_OPT
+            pInstance->pSEMidBiquad->process(pScratch, pScratch, NumSamples);
+#else
             (pConfig->pBiquadCallBack_Mid)(
                     (Biquad_FLOAT_Instance_t*)&pCoefficient->SEBiquadInstanceMid,
                     (LVM_FLOAT*)pScratch, (LVM_FLOAT*)pScratch, (LVM_INT16)NumSamples);
+#endif
         } else {
             Mult3s_Float(pScratch,                    /* Source */
                          (LVM_FLOAT)pConfig->MidGain, /* Gain */
@@ -201,10 +231,15 @@
          * and in all modes for mobile speakers
          */
         if (pInstance->Params.SourceFormat == LVCS_STEREO) {
+#ifdef BIQUAD_OPT
+            pInstance->pSESideBiquad->process(pScratch + NumSamples, pScratch + NumSamples,
+                                              NumSamples);
+#else
             (pConfig->pBiquadCallBack_Side)(
                     (Biquad_FLOAT_Instance_t*)&pCoefficient->SEBiquadInstanceSide,
                     (LVM_FLOAT*)(pScratch + NumSamples), (LVM_FLOAT*)(pScratch + NumSamples),
                     (LVM_INT16)NumSamples);
+#endif
         }
 
         /*
diff --git a/media/libeffects/lvm/tests/Android.bp b/media/libeffects/lvm/tests/Android.bp
index d026ab6..abacc94 100644
--- a/media/libeffects/lvm/tests/Android.bp
+++ b/media/libeffects/lvm/tests/Android.bp
@@ -59,9 +59,12 @@
     shared_libs: [
         "libaudioutils",
         "liblog",
-        "libreverbwrapper",
     ],
 
+    static_libs: [
+        "libreverb",
+        "libreverbwrapper",
+    ],
     srcs: [
         "reverb_test.cpp",
     ],
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
index 86b21ae..627af21 100755
--- a/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
@@ -61,7 +61,7 @@
             do
                 for chMask in {0..22}
                 do
-                    adb shell LD_LIBRARY_PATH=/system/vendor/lib/soundfx $testdir/reverb_test \
+                    adb shell $testdir/reverb_test \
                         --input $testdir/sinesweepraw.raw \
                         --output $testdir/sinesweep_$((chMask))_$((fs)).raw \
                         --chMask $chMask $flags --fs $fs --preset $preset_val
diff --git a/media/libeffects/lvm/tests/reverb_test.cpp b/media/libeffects/lvm/tests/reverb_test.cpp
index 7cbca9b..b7704ff 100644
--- a/media/libeffects/lvm/tests/reverb_test.cpp
+++ b/media/libeffects/lvm/tests/reverb_test.cpp
@@ -340,7 +340,7 @@
     const int outChannelCount = (channelCount == 1 ? 2 : channelCount);
 
     std::vector<short> in(frameLength * maxChannelCount);
-    std::vector<short> out(frameLength * maxChannelCount);
+    std::vector<short> out(frameLength * outChannelCount);
     std::vector<float> floatIn(frameLength * channelCount);
     std::vector<float> floatOut(frameLength * outChannelCount);
 
diff --git a/media/libeffects/lvm/wrapper/Android.bp b/media/libeffects/lvm/wrapper/Android.bp
index be60aae..f96928b 100644
--- a/media/libeffects/lvm/wrapper/Android.bp
+++ b/media/libeffects/lvm/wrapper/Android.bp
@@ -38,7 +38,7 @@
 }
 
 // reverb wrapper
-cc_library_shared {
+cc_library {
     name: "libreverbwrapper",
 
     arch: {
diff --git a/media/libmedia/MidiIoWrapper.cpp b/media/libmedia/MidiIoWrapper.cpp
index da272e3..f682b6e 100644
--- a/media/libmedia/MidiIoWrapper.cpp
+++ b/media/libmedia/MidiIoWrapper.cpp
@@ -21,6 +21,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <algorithm>
 
 #include <media/MidiIoWrapper.h>
 #include <media/MediaExtractorPluginApi.h>
@@ -33,6 +34,8 @@
 }
 
 namespace android {
+int MidiIoWrapper::sCacheBufferSize = 0;
+Mutex MidiIoWrapper::mCacheLock;
 
 MidiIoWrapper::MidiIoWrapper(const char *path) {
     ALOGV("MidiIoWrapper(%s)", path);
@@ -40,6 +43,8 @@
     mBase = 0;
     mLength = lseek(mFd, 0, SEEK_END);
     mDataSource = nullptr;
+    mCacheBuffer = NULL;
+    mCacheBufRangeLength = 0;
 }
 
 MidiIoWrapper::MidiIoWrapper(int fd, off64_t offset, int64_t size) {
@@ -48,6 +53,8 @@
     mBase = offset;
     mLength = size;
     mDataSource = nullptr;
+    mCacheBuffer = NULL;
+    mCacheBufRangeLength = 0;
 }
 
 class MidiIoWrapper::DataSourceUnwrapper {
@@ -97,6 +104,8 @@
     } else {
         mLength = 0;
     }
+    mCacheBuffer = NULL;
+    mCacheBufRangeLength = 0;
 }
 
 MidiIoWrapper::~MidiIoWrapper() {
@@ -105,11 +114,80 @@
         close(mFd);
     }
     delete mDataSource;
+
+    if (NULL != mCacheBuffer) {
+        delete [] mCacheBuffer;
+        mCacheBuffer = NULL;
+        {
+            Mutex::Autolock _l(mCacheLock);
+            sCacheBufferSize -= mLength;
+        }
+    }
 }
 
 int MidiIoWrapper::readAt(void *buffer, int offset, int size) {
     ALOGV("readAt(%p, %d, %d)", buffer, offset, size);
 
+    if (offset < 0) {
+        return UNKNOWN_ERROR;
+    }
+
+    if (offset + size > mLength) {
+        size = mLength - offset;
+    }
+
+    if (mCacheBuffer == NULL) {
+        Mutex::Autolock _l(mCacheLock);
+        if (sCacheBufferSize + mLength <= kTotalCacheSize) {
+            mCacheBuffer = new (std::nothrow) unsigned char[mLength];
+            if (NULL != mCacheBuffer) {
+                sCacheBufferSize += mLength;
+                ALOGV("sCacheBufferSize : %d", sCacheBufferSize);
+            } else {
+                ALOGE("failed to allocate memory for mCacheBuffer");
+            }
+        } else {
+            ALOGV("not allocate memory for mCacheBuffer");
+        }
+    }
+
+    if (mCacheBuffer != NULL) {
+        if (mCacheBufRangeLength > 0 && mCacheBufRangeLength >= (offset + size)) {
+            /* Use buffered data */
+            memcpy(buffer, (void*)(mCacheBuffer + offset), size);
+            return size;
+        } else {
+            /* Buffer new data */
+            int64_t beyondCacheBufRangeLength = (offset + size) - mCacheBufRangeLength;
+            int64_t numRequiredBytesToCache =
+                  std::max((int64_t)kSingleCacheSize, beyondCacheBufRangeLength);
+            int64_t availableReadLength = mLength - mCacheBufRangeLength;
+            int64_t readSize = std::min(availableReadLength, numRequiredBytesToCache);
+            int actualNumBytesRead =
+                unbufferedReadAt(mCacheBuffer + mCacheBufRangeLength,
+                        mCacheBufRangeLength, readSize);
+            if(actualNumBytesRead > 0) {
+                mCacheBufRangeLength += actualNumBytesRead;
+                if (offset >= mCacheBufRangeLength) {
+                    return 0;
+                } else if (offset + size >= mCacheBufRangeLength) {
+                    memcpy(buffer, (void*)(mCacheBuffer + offset), mCacheBufRangeLength - offset);
+                    return mCacheBufRangeLength - offset;
+                } else {
+                    memcpy(buffer, (void*)(mCacheBuffer + offset), size);
+                    return size;
+                }
+            } else {
+                return actualNumBytesRead;
+            }
+        }
+    } else {
+        return unbufferedReadAt(buffer, offset, size);
+    }
+}
+
+int MidiIoWrapper::unbufferedReadAt(void *buffer, int offset, int size) {
+    ALOGV("unbufferedReadAt(%p, %d, %d)", buffer, offset, size);
     if (mDataSource != NULL) {
         return mDataSource->readAt(offset, buffer, size);
     }
diff --git a/media/libmedia/include/media/MidiIoWrapper.h b/media/libmedia/include/media/MidiIoWrapper.h
index 0cdd4ad..5fa745c 100644
--- a/media/libmedia/include/media/MidiIoWrapper.h
+++ b/media/libmedia/include/media/MidiIoWrapper.h
@@ -18,6 +18,7 @@
 #define MIDI_IO_WRAPPER_H_
 
 #include <libsonivox/eas_types.h>
+#include <utils/Mutex.h>
 
 namespace android {
 
@@ -32,17 +33,27 @@
     ~MidiIoWrapper();
 
     int readAt(void *buffer, int offset, int size);
+    int unbufferedReadAt(void *buffer, int offset, int size);
     int size();
 
     EAS_FILE_LOCATOR getLocator();
 
 private:
+    enum {
+        kTotalCacheSize      = 1024 * 1024 + 512 * 1024,
+        kSingleCacheSize     = 65536,
+    };
+
     int mFd;
     off64_t mBase;
     int64_t  mLength;
     class DataSourceUnwrapper;
     DataSourceUnwrapper *mDataSource;
     EAS_FILE mEasFile;
+    unsigned char *mCacheBuffer;
+    int64_t mCacheBufRangeLength;
+    static int sCacheBufferSize;
+    static Mutex mCacheLock;
 };
 
 
diff --git a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
index 93e03ee..6dc3e3f 100644
--- a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
@@ -638,7 +638,8 @@
     }
 
     // The duration value is a string representing the duration in ms.
-    sprintf(tmp, "%" PRId64, (maxDurationUs + 500) / 1000);
+    sprintf(tmp, "%" PRId64,
+           (maxDurationUs > (INT64_MAX - 500) ? INT64_MAX : (maxDurationUs + 500)) / 1000);
     mMetaData.add(METADATA_KEY_DURATION, String8(tmp));
 
     if (hasAudio) {
diff --git a/media/libmediatranscoding/Android.bp b/media/libmediatranscoding/Android.bp
index 1934820..094d7c3 100644
--- a/media/libmediatranscoding/Android.bp
+++ b/media/libmediatranscoding/Android.bp
@@ -44,6 +44,19 @@
     {
         java: {
             enabled: true,
+            apex_available: [
+                "com.android.media",
+                "test_com.android.media",
+            ],
+            min_sdk_version: "29",
+        },
+        ndk: {
+            enabled: true,
+            apex_available: [
+                "com.android.media",
+                "test_com.android.media",
+            ],
+            min_sdk_version: "29",
         },
     },
 }
@@ -51,6 +64,12 @@
 cc_library {
     name: "libmediatranscoding",
 
+    min_sdk_version: "29",
+    apex_available: [
+        "com.android.media",
+        "test_com.android.media",
+    ],
+
     srcs: [
         "TranscodingClientManager.cpp",
         "TranscodingSessionController.cpp",
@@ -60,7 +79,7 @@
     ],
 
     shared_libs: [
-        "libandroid",
+        "libandroid#31",
         "libbinder_ndk",
         "libcutils",
         "liblog",
diff --git a/media/libmediatranscoding/include/media/TranscoderWrapper.h b/media/libmediatranscoding/include/media/TranscoderWrapper.h
index 9ec32d7..02beede 100644
--- a/media/libmediatranscoding/include/media/TranscoderWrapper.h
+++ b/media/libmediatranscoding/include/media/TranscoderWrapper.h
@@ -17,7 +17,6 @@
 #ifndef ANDROID_TRANSCODER_WRAPPER_H
 #define ANDROID_TRANSCODER_WRAPPER_H
 
-#include <android-base/thread_annotations.h>
 #include <media/NdkMediaError.h>
 #include <media/TranscoderInterface.h>
 
diff --git a/media/libmediatranscoding/transcoder/Android.bp b/media/libmediatranscoding/transcoder/Android.bp
index aa7cdde..bebe6b1 100644
--- a/media/libmediatranscoding/transcoder/Android.bp
+++ b/media/libmediatranscoding/transcoder/Android.bp
@@ -28,6 +28,14 @@
         "VideoTrackTranscoder.cpp",
     ],
 
+    min_sdk_version: "29",
+    apex_available: [
+        "com.android.media",
+        "test_com.android.media",
+    ],
+
+    //header_libs: [ "libarect_headers", "libarect_headers_for_ndk" ],
+    static_libs: [ "libarect" ],
     shared_libs: [
         "libbase",
         "libcutils",
diff --git a/media/libmediatranscoding/transcoder/benchmark/Android.bp b/media/libmediatranscoding/transcoder/benchmark/Android.bp
index 6c87233..74f65b9 100644
--- a/media/libmediatranscoding/transcoder/benchmark/Android.bp
+++ b/media/libmediatranscoding/transcoder/benchmark/Android.bp
@@ -1,6 +1,13 @@
 cc_defaults {
     name: "benchmarkdefaults",
-    shared_libs: ["libmediandk", "libbase", "libbinder_ndk", "libutils", "libnativewindow"],
+    shared_libs: [
+        "libmediandk",
+        "libbase",
+        "libbinder_ndk",
+        "libbinder",
+        "libutils",
+        "libnativewindow",
+    ],
     static_libs: ["libmediatranscoder", "libgoogle-benchmark"],
     test_config_template: "AndroidTestTemplate.xml",
     test_suites: ["device-tests", "TranscoderBenchmarks"],
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
index 9ee55e5..d47a30c 100644
--- a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
+++ b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
@@ -30,6 +30,7 @@
  */
 
 #include <benchmark/benchmark.h>
+#include <binder/ProcessState.h>
 #include <fcntl.h>
 #include <media/MediaTranscoder.h>
 #include <iostream>
@@ -113,7 +114,6 @@
     std::string srcPath = kAssetDirectory + srcFileName;
     std::string dstPath = kAssetDirectory + dstFileName;
 
-    auto callbacks = std::make_shared<TranscoderCallbacks>();
     media_status_t status = AMEDIA_OK;
 
     if ((srcFd = open(srcPath.c_str(), O_RDONLY)) < 0) {
@@ -126,6 +126,7 @@
     }
 
     for (auto _ : state) {
+        auto callbacks = std::make_shared<TranscoderCallbacks>();
         auto transcoder = MediaTranscoder::create(callbacks);
 
         status = transcoder->configureSource(srcFd);
@@ -154,8 +155,8 @@
             if (strncmp(mime, "video/", 6) == 0) {
                 int32_t frameCount;
                 if (AMediaFormat_getInt32(srcFormat, AMEDIAFORMAT_KEY_FRAME_COUNT, &frameCount)) {
-                    state.counters[PARAM_VIDEO_FRAME_RATE] =
-                            benchmark::Counter(frameCount, benchmark::Counter::kIsRate);
+                    state.counters[PARAM_VIDEO_FRAME_RATE] = benchmark::Counter(
+                            frameCount, benchmark::Counter::kIsIterationInvariantRate);
                 }
             }
 
@@ -390,6 +391,7 @@
 }
 
 int main(int argc, char** argv) {
+    android::ProcessState::self()->startThreadPool();
     std::unique_ptr<benchmark::BenchmarkReporter> fileReporter;
     for (int i = 1; i < argc; ++i) {
         if (std::string(argv[i]).find("--benchmark_out") != std::string::npos) {
diff --git a/media/libmediatranscoding/transcoder/tests/fuzzer/Android.bp b/media/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
new file mode 100644
index 0000000..3ae349b
--- /dev/null
+++ b/media/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+    name: "media_transcoder_fuzzer",
+    srcs: [
+        "media_transcoder_fuzzer.cpp",
+    ],
+    static_libs: [
+        "liblog",
+        "libmediatranscoder",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libmediandk",
+        "libnativewindow",
+        "libutils",
+    ],
+    header_libs: [
+        "libcodec2_headers",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
diff --git a/media/libmediatranscoding/transcoder/tests/fuzzer/README.md b/media/libmediatranscoding/transcoder/tests/fuzzer/README.md
new file mode 100644
index 0000000..d376a20
--- /dev/null
+++ b/media/libmediatranscoding/transcoder/tests/fuzzer/README.md
@@ -0,0 +1,59 @@
+# Fuzzer for libmediatranscoder
+
+## Plugin Design Considerations
+The fuzzer plugin for libmediatranscoder is designed based on the understanding of the
+transcoder and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+Transcoder supports the following parameters:
+1. Destination Mime Type (parameter name: `dstMime`)
+2. AVC Profile (parameter name: `profile`)
+3. HEVC Profile (parameter name: `profile`)
+4. AVC Level (parameter name: `level`)
+5. HEVC Level (parameter name: `level`)
+6. Bitrate (parameter name: `bitrate`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `dstMime` | 0. `AMEDIA_MIMETYPE_VIDEO_AVC` 1. `AMEDIA_MIMETYPE_VIDEO_HEVC` | Bit 0 (LSB) of 1st byte of data |
+| `profile` for AVC | 0. `PROFILE_AVC_BASELINE` 1. `PROFILE_AVC_CONSTRAINED_BASELINE` 2. `PROFILE_AVC_MAIN`| All bits of 2nd byte of data modulus 3 |
+| `profile` for HEVC | 0. `PROFILE_HEVC_MAIN` 1. `PROFILE_HEVC_MAIN_STILL` | All bits of 2nd byte of data modulus 2 |
+| `level` for AVC | 0. `LEVEL_AVC_1` 1. `LEVEL_AVC_1B` 2. `LEVEL_AVC_1_1` 3. `LEVEL_AVC_1_2` 4. `LEVEL_AVC_1_3` 5. `LEVEL_AVC_2` 6. `LEVEL_AVC_2_1` 7. `LEVEL_AVC_2_2` 8. `LEVEL_AVC_3` 9. `LEVEL_AVC_3_1` 10. `LEVEL_AVC_3_2` 11. `LEVEL_AVC_4` 12. `LEVEL_AVC_4_1` 13. `LEVEL_AVC_4_2` 14. `LEVEL_AVC_5`| All bits of 3rd byte of data modulus 15 |
+| `level` for HEVC | 0. `LEVEL_HEVC_MAIN_1` 1. `LEVEL_HEVC_MAIN_2` 2. `LEVEL_HEVC_MAIN_2_1` 3. `LEVEL_HEVC_MAIN_3` 4. `LEVEL_HEVC_MAIN_3_1` 5. `LEVEL_HEVC_MAIN_4` 6. `LEVEL_HEVC_MAIN_4_1` 7. `LEVEL_HEVC_MAIN_5` 8. `LEVEL_HEVC_MAIN_5_1` 9. `LEVEL_HEVC_MAIN_5_2` | All bits of 3rd byte of data modulus 10 |
+| `bitrate` | In the range `0` to `500000000` | All bits of 4th and 5th byte of data |
+
+This also ensures that the plugin is always deterministic for any given input.
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the transcoder.
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build media_transcoder_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) media_transcoder_fuzzer
+```
+#### Steps to run
+Create a directory CORPUS_DIR
+```
+  $ adb shell mkdir CORPUS_DIR
+```
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/${TARGET_ARCH}/media_transcoder_fuzzer/media_transcoder_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp b/media/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp
new file mode 100644
index 0000000..48d3406
--- /dev/null
+++ b/media/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp
@@ -0,0 +1,209 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <C2Config.h>
+#include <android/binder_process.h>
+#include <fcntl.h>
+#include <media/MediaTranscoder.h>
+#include <media/NdkCommon.h>
+#include <stdio.h>
+
+#define UNUSED_PARAM __attribute__((unused))
+#define SRC_FILE "sourceTranscodingFile"
+#define DEST_FILE "destTranscodingFile"
+
+using namespace std;
+using namespace android;
+
+const char* kMimeType[] = {AMEDIA_MIMETYPE_VIDEO_AVC, AMEDIA_MIMETYPE_VIDEO_HEVC};
+const C2Config::profile_t kAvcProfile[] = {C2Config::PROFILE_AVC_BASELINE,
+                                           C2Config::PROFILE_AVC_CONSTRAINED_BASELINE,
+                                           C2Config::PROFILE_AVC_MAIN};
+const C2Config::level_t kAvcLevel[] = {
+        C2Config::LEVEL_AVC_1,   C2Config::LEVEL_AVC_1B,  C2Config::LEVEL_AVC_1_1,
+        C2Config::LEVEL_AVC_1_2, C2Config::LEVEL_AVC_1_3, C2Config::LEVEL_AVC_2,
+        C2Config::LEVEL_AVC_2_1, C2Config::LEVEL_AVC_2_2, C2Config::LEVEL_AVC_3,
+        C2Config::LEVEL_AVC_3_1, C2Config::LEVEL_AVC_3_2, C2Config::LEVEL_AVC_4,
+        C2Config::LEVEL_AVC_4_1, C2Config::LEVEL_AVC_4_2, C2Config::LEVEL_AVC_5,
+};
+const C2Config::profile_t kHevcProfile[] = {C2Config::PROFILE_HEVC_MAIN,
+                                            C2Config::PROFILE_HEVC_MAIN_STILL};
+const C2Config::level_t kHevcLevel[] = {
+        C2Config::LEVEL_HEVC_MAIN_1,   C2Config::LEVEL_HEVC_MAIN_2,   C2Config::LEVEL_HEVC_MAIN_2_1,
+        C2Config::LEVEL_HEVC_MAIN_3,   C2Config::LEVEL_HEVC_MAIN_3_1, C2Config::LEVEL_HEVC_MAIN_4,
+        C2Config::LEVEL_HEVC_MAIN_4_1, C2Config::LEVEL_HEVC_MAIN_5,   C2Config::LEVEL_HEVC_MAIN_5_1,
+        C2Config::LEVEL_HEVC_MAIN_5_2};
+const size_t kNumAvcProfile = size(kAvcProfile);
+const size_t kNumAvcLevel = size(kAvcLevel);
+const size_t kNumHevcProfile = size(kHevcProfile);
+const size_t kNumHevcLevel = size(kHevcLevel);
+const size_t kMaxBitrate = 500000000;
+
+enum {
+    IDX_MIME_TYPE = 0,
+    IDX_PROFILE,
+    IDX_LEVEL,
+    IDX_BITRATE_BYTE_1,
+    IDX_BITRATE_BYTE_2,
+    IDX_LAST
+};
+
+class TestCallbacks : public MediaTranscoder::CallbackInterface {
+public:
+    virtual void onFinished(const MediaTranscoder* transcoder UNUSED_PARAM) override {
+        unique_lock<mutex> lock(mMutex);
+        mFinished = true;
+        mCondition.notify_all();
+    }
+
+    virtual void onError(const MediaTranscoder* transcoder UNUSED_PARAM,
+                         media_status_t error UNUSED_PARAM) override {
+        unique_lock<mutex> lock(mMutex);
+        mFinished = true;
+        mCondition.notify_all();
+    }
+
+    virtual void onProgressUpdate(const MediaTranscoder* transcoder UNUSED_PARAM,
+                                  int32_t progress) override {
+        unique_lock<mutex> lock(mMutex);
+        if (progress > 0 && !mProgressMade) {
+            mProgressMade = true;
+            mCondition.notify_all();
+        }
+    }
+
+    virtual void onCodecResourceLost(const MediaTranscoder* transcoder UNUSED_PARAM,
+                                     const shared_ptr<ndk::ScopedAParcel>& pausedState
+                                             UNUSED_PARAM) override {}
+
+    void waitForTranscodingFinished() {
+        unique_lock<mutex> lock(mMutex);
+        while (!mFinished) {
+            mCondition.wait(lock);
+        }
+    }
+
+private:
+    mutex mMutex;
+    condition_variable mCondition;
+    bool mFinished = false;
+    bool mProgressMade = false;
+};
+
+class MediaTranscoderFuzzer {
+public:
+    void init();
+    void invokeTranscoder(const uint8_t* data, size_t size);
+    void deInit();
+
+private:
+    AMediaFormat* getFormat(AMediaFormat* sourceFormat) {
+        AMediaFormat* format = nullptr;
+        const char* mime = nullptr;
+        AMediaFormat_getString(sourceFormat, AMEDIAFORMAT_KEY_MIME, &mime);
+        if (mime != nullptr) {
+            if (strncmp(mime, "video/", 6) == 0 && (mDestMime != nullptr)) {
+                format = AMediaFormat_new();
+                AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mDestMime);
+                AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_PROFILE, mProfile);
+                AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_LEVEL, mLevel);
+                AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, mBitrate);
+                AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
+                AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_PRIORITY, 1);
+            }
+        }
+        return format;
+    }
+
+    shared_ptr<TestCallbacks> mCallbacks;
+    int mSrcFd = 0;
+    int mDestFd = 0;
+    const char* mDestMime;
+    C2Config::profile_t mProfile;
+    C2Config::level_t mLevel;
+    uint64_t mBitrate = 0;
+};
+
+void MediaTranscoderFuzzer::init() {
+    mCallbacks = make_shared<TestCallbacks>();
+    ABinderProcess_startThreadPool();
+}
+
+void MediaTranscoderFuzzer::deInit() {
+    mCallbacks.reset();
+    if (mSrcFd) {
+        close(mSrcFd);
+    }
+    if (mDestFd) {
+        close(mDestFd);
+    }
+}
+
+void MediaTranscoderFuzzer::invokeTranscoder(const uint8_t* data, size_t size) {
+    auto transcoder = MediaTranscoder::create(mCallbacks);
+    if (transcoder == nullptr) {
+        return;
+    }
+
+    mDestMime = kMimeType[data[IDX_MIME_TYPE] & 0x01];
+    mBitrate = (((data[IDX_BITRATE_BYTE_1] << 8) | data[IDX_BITRATE_BYTE_2]) * 1000) % kMaxBitrate;
+    if (mDestMime == AMEDIA_MIMETYPE_VIDEO_AVC) {
+        mProfile = kAvcProfile[data[IDX_PROFILE] % kNumAvcProfile];
+        mLevel = kAvcLevel[data[IDX_LEVEL] % kNumAvcLevel];
+    } else {
+        mProfile = kHevcProfile[data[IDX_PROFILE] % kNumHevcProfile];
+        mLevel = kHevcLevel[data[IDX_LEVEL] % kNumHevcLevel];
+    }
+
+    data += IDX_LAST;
+    size -= IDX_LAST;
+
+    mSrcFd = memfd_create(SRC_FILE, MFD_ALLOW_SEALING);
+    write(mSrcFd, data, size);
+
+    transcoder->configureSource(mSrcFd);
+    vector<shared_ptr<AMediaFormat>> trackFormats = transcoder->getTrackFormats();
+    for (int i = 0; i < trackFormats.size(); ++i) {
+        AMediaFormat* format = getFormat(trackFormats[i].get());
+        transcoder->configureTrackFormat(i, format);
+
+        if (format != nullptr) {
+            AMediaFormat_delete(format);
+        }
+    }
+    mDestFd = memfd_create(DEST_FILE, MFD_ALLOW_SEALING);
+    transcoder->configureDestination(mDestFd);
+    if (transcoder->start() == AMEDIA_OK) {
+        mCallbacks->waitForTranscodingFinished();
+        transcoder->cancel();
+    }
+    close(mSrcFd);
+    close(mDestFd);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    if (size < IDX_LAST + 1) {
+        return 0;
+    }
+    MediaTranscoderFuzzer transcoderFuzzer;
+    transcoderFuzzer.init();
+    transcoderFuzzer.invokeTranscoder(data, size);
+    transcoderFuzzer.deInit();
+    return 0;
+}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index da8f024..358c5e3 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -19,6 +19,8 @@
 #define LOG_TAG "MediaCodec"
 #include <utils/Log.h>
 
+#include <set>
+
 #include <inttypes.h>
 #include <stdlib.h>
 
@@ -202,6 +204,10 @@
     // implements DeathRecipient
     static void BinderDiedCallback(void* cookie);
     void binderDied();
+    static Mutex sLockCookies;
+    static std::set<void*> sCookies;
+    static void addCookie(void* cookie);
+    static void removeCookie(void* cookie);
 
     void addResource(const MediaResourceParcel &resource);
     void removeResource(const MediaResourceParcel &resource);
@@ -228,8 +234,15 @@
 }
 
 MediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
+
+    // remove the cookie, so any in-flight death notification will get dropped
+    // by our handler.
+    removeCookie(this);
+
+    Mutex::Autolock _l(mLock);
     if (mService != nullptr) {
         AIBinder_unlinkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
+        mService = nullptr;
     }
 }
 
@@ -241,16 +254,39 @@
         return;
     }
 
-    AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
-
     // Kill clients pending removal.
     mService->reclaimResourcesFromClientsPendingRemoval(mPid);
+
+    // so our handler will process the death notifications
+    addCookie(this);
+
+    // after this, require mLock whenever using mService
+    AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
+}
+
+//static
+Mutex MediaCodec::ResourceManagerServiceProxy::sLockCookies;
+std::set<void*> MediaCodec::ResourceManagerServiceProxy::sCookies;
+
+//static
+void MediaCodec::ResourceManagerServiceProxy::addCookie(void* cookie) {
+    Mutex::Autolock _l(sLockCookies);
+    sCookies.insert(cookie);
+}
+
+//static
+void MediaCodec::ResourceManagerServiceProxy::removeCookie(void* cookie) {
+    Mutex::Autolock _l(sLockCookies);
+    sCookies.erase(cookie);
 }
 
 //static
 void MediaCodec::ResourceManagerServiceProxy::BinderDiedCallback(void* cookie) {
-    auto thiz = static_cast<ResourceManagerServiceProxy*>(cookie);
-    thiz->binderDied();
+    Mutex::Autolock _l(sLockCookies);
+    if (sCookies.find(cookie) != sCookies.end()) {
+        auto thiz = static_cast<ResourceManagerServiceProxy*>(cookie);
+        thiz->binderDied();
+    }
 }
 
 void MediaCodec::ResourceManagerServiceProxy::binderDied() {
@@ -4094,7 +4130,15 @@
                 }
             }
         }
-        mBufferChannel->renderOutputBuffer(buffer, renderTimeNs);
+        status_t err = mBufferChannel->renderOutputBuffer(buffer, renderTimeNs);
+
+        if (err == NO_INIT) {
+            ALOGE("rendering to non-initilized(obsolete) surface");
+            return err;
+        }
+        if (err != OK) {
+            ALOGI("rendring output error %d", err);
+        }
     } else {
         mBufferChannel->discardBuffer(buffer);
     }
diff --git a/media/libstagefright/codecs/avcdec/Android.bp b/media/libstagefright/codecs/avcdec/Android.bp
index 0bb6bb0..61379d2 100644
--- a/media/libstagefright/codecs/avcdec/Android.bp
+++ b/media/libstagefright/codecs/avcdec/Android.bp
@@ -16,6 +16,12 @@
             "signed-integer-overflow",
         ],
         cfi: true,
+        diag: {
+            cfi: true,
+        },
+        config: {
+            cfi_assembly_support: true,
+        },
     },
 
     ldflags: ["-Wl,-Bsymbolic"],
diff --git a/media/libstagefright/codecs/avcenc/Android.bp b/media/libstagefright/codecs/avcenc/Android.bp
index 980261c..aceaebf 100644
--- a/media/libstagefright/codecs/avcenc/Android.bp
+++ b/media/libstagefright/codecs/avcenc/Android.bp
@@ -10,6 +10,12 @@
             "signed-integer-overflow",
         ],
         cfi: true,
+        diag: {
+            cfi: true,
+        },
+        config: {
+            cfi_assembly_support: true,
+        },
     },
 
     cflags: [
diff --git a/media/libstagefright/codecs/hevcdec/Android.bp b/media/libstagefright/codecs/hevcdec/Android.bp
index ec436ce..392396c 100644
--- a/media/libstagefright/codecs/hevcdec/Android.bp
+++ b/media/libstagefright/codecs/hevcdec/Android.bp
@@ -17,6 +17,13 @@
             "signed-integer-overflow",
         ],
         cfi: true,
+        diag: {
+            cfi: true,
+        },
+        config: {
+            cfi_assembly_support: true,
+        },
+
     },
 
     // We need this because the current asm generates the following link error:
diff --git a/media/libstagefright/codecs/xaacdec/Android.bp b/media/libstagefright/codecs/xaacdec/Android.bp
index 5385dbc..2d90910 100644
--- a/media/libstagefright/codecs/xaacdec/Android.bp
+++ b/media/libstagefright/codecs/xaacdec/Android.bp
@@ -14,6 +14,12 @@
         // integer_overflow: true,
         misc_undefined: [ "signed-integer-overflow", "unsigned-integer-overflow", ],
         cfi: true,
+	diag: {
+            cfi: true,
+        },
+        config: {
+            cfi_assembly_support: true,
+        },
     },
 
     static_libs: ["libxaacdec"],
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 5509512..e97f6eb 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -813,6 +813,10 @@
                 baseSize = U32_AT(&mParent.mData[mOffset + 4]);
             }
 
+            if (baseSize == 0) {
+                return;
+            }
+
             // Prevent integer overflow when adding
             if (SIZE_MAX - 10 <= baseSize) {
                 return;
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 62e3a4b..27a94fd 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -60,21 +60,23 @@
 
     mIsAudio = false;
     mIsVideo = false;
+    const char *mime;
 
-    if (meta == NULL) {
+    // Do not use meta if no mime.
+    if (meta == NULL || !meta->findCString(kKeyMIMEType, &mime)) {
         return;
     }
 
     mFormat = meta;
-    const char *mime;
-    CHECK(meta->findCString(kKeyMIMEType, &mime));
 
     if (!strncasecmp("audio/", mime, 6)) {
         mIsAudio = true;
-    } else  if (!strncasecmp("video/", mime, 6)) {
+    } else if (!strncasecmp("video/", mime, 6)) {
         mIsVideo = true;
+    } else if (!strncasecmp("text/", mime, 5) || !strncasecmp("application/", mime, 12)) {
+        return;
     } else {
-        CHECK(!strncasecmp("text/", mime, 5) || !strncasecmp("application/", mime, 12));
+        ALOGW("Unsupported mime type: %s", mime);
     }
 }
 
diff --git a/media/libstagefright/renderfright/tests/RenderEngineTest.cpp b/media/libstagefright/renderfright/tests/RenderEngineTest.cpp
index 730f606..2697ff4 100644
--- a/media/libstagefright/renderfright/tests/RenderEngineTest.cpp
+++ b/media/libstagefright/renderfright/tests/RenderEngineTest.cpp
@@ -111,9 +111,9 @@
         std::vector<uint8_t> outBuffer(mBuffer->getWidth() * mBuffer->getHeight() * 3);
         auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
 
-        for (int32_t j = 0; j < mBuffer->getHeight(); j++) {
+        for (uint32_t j = 0; j < mBuffer->getHeight(); j++) {
             const uint8_t* src = pixels + (mBuffer->getStride() * j) * 4;
-            for (int32_t i = 0; i < mBuffer->getWidth(); i++) {
+            for (uint32_t i = 0; i < mBuffer->getWidth(); i++) {
                 // Only copy R, G and B components
                 outPtr[0] = src[0];
                 outPtr[1] = src[1];
@@ -419,9 +419,9 @@
         buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                   reinterpret_cast<void**>(&pixels));
 
-        for (int32_t j = 0; j < buf->getHeight(); j++) {
+        for (uint32_t j = 0; j < buf->getHeight(); j++) {
             uint8_t* iter = pixels + (buf->getStride() * j) * 4;
-            for (int32_t i = 0; i < buf->getWidth(); i++) {
+            for (uint32_t i = 0; i < buf->getWidth(); i++) {
                 iter[0] = uint8_t(r * 255);
                 iter[1] = uint8_t(g * 255);
                 iter[2] = uint8_t(b * 255);
diff --git a/media/mediaserver/mediaserver.rc b/media/mediaserver/mediaserver.rc
index 05373c9..c82e532 100644
--- a/media/mediaserver/mediaserver.rc
+++ b/media/mediaserver/mediaserver.rc
@@ -7,3 +7,9 @@
     group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
     ioprio rt 4
     task_profiles ProcessCapacityHigh HighPerformance
+
+# media.transcoding service is defined on com.android.media apex which goes back
+# to API29, but we only want it started on API31+ devices. So we declare it as
+# "disabled" and start it explicitly on boot.
+on boot
+    start media.transcoding
diff --git a/media/ndk/NdkImage.cpp b/media/ndk/NdkImage.cpp
index 1145b7b..5fdd45a 100644
--- a/media/ndk/NdkImage.cpp
+++ b/media/ndk/NdkImage.cpp
@@ -58,7 +58,7 @@
     if (mIsClosed) {
         return;
     }
-    if (!mReader->mIsClosed) {
+    if (mReader->mIsOpen) {
         mReader->releaseImageLocked(this, releaseFenceFd);
     }
     // Should have been set to nullptr in releaseImageLocked
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index 5d8f0b8..b75901a 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -273,7 +273,7 @@
 
 AImageReader::~AImageReader() {
     Mutex::Autolock _l(mLock);
-    LOG_FATAL_IF("AImageReader not closed before destruction", mIsClosed != true);
+    LOG_FATAL_IF(mIsOpen, "AImageReader not closed before destruction");
 }
 
 media_status_t
@@ -347,16 +347,16 @@
     }
     mHandler = new CallbackHandler(this);
     mCbLooper->registerHandler(mHandler);
-
+    mIsOpen = true;
     return AMEDIA_OK;
 }
 
 void AImageReader::close() {
     Mutex::Autolock _l(mLock);
-    if (mIsClosed) {
+    if (!mIsOpen) {
         return;
     }
-    mIsClosed = true;
+    mIsOpen = false;
     AImageReader_ImageListener nullListener = {nullptr, nullptr};
     setImageListenerLocked(&nullListener);
 
diff --git a/media/ndk/NdkImageReaderPriv.h b/media/ndk/NdkImageReaderPriv.h
index 0779a71..37c606e 100644
--- a/media/ndk/NdkImageReaderPriv.h
+++ b/media/ndk/NdkImageReaderPriv.h
@@ -166,7 +166,7 @@
     native_handle_t*           mWindowHandle = nullptr;
 
     List<AImage*>              mAcquiredImages;
-    bool                       mIsClosed = false;
+    bool                       mIsOpen = false;
 
     Mutex                      mLock;
 };
diff --git a/media/tests/benchmark/src/native/decoder/C2Decoder.cpp b/media/tests/benchmark/src/native/decoder/C2Decoder.cpp
index 46c4a7c..6539f24 100644
--- a/media/tests/benchmark/src/native/decoder/C2Decoder.cpp
+++ b/media/tests/benchmark/src/native/decoder/C2Decoder.cpp
@@ -53,8 +53,8 @@
     }
 
     int64_t sTime = mStats->getCurTime();
-    mComponent = mClient->CreateComponentByName(compName.c_str(), mListener, &mClient);
-    if (mComponent == nullptr) {
+    if (mClient->CreateComponentByName(compName.c_str(), mListener, &mComponent, &mClient) !=
+        C2_OK) {
         ALOGE("Create component failed for %s", compName.c_str());
         return -1;
     }
diff --git a/media/tests/benchmark/src/native/encoder/C2Encoder.cpp b/media/tests/benchmark/src/native/encoder/C2Encoder.cpp
index 6a50d40..ca79881 100644
--- a/media/tests/benchmark/src/native/encoder/C2Encoder.cpp
+++ b/media/tests/benchmark/src/native/encoder/C2Encoder.cpp
@@ -68,8 +68,8 @@
     }
 
     int64_t sTime = mStats->getCurTime();
-    mComponent = mClient->CreateComponentByName(compName.c_str(), mListener, &mClient);
-    if (mComponent == nullptr) {
+    if (mClient->CreateComponentByName(compName.c_str(), mListener, &mComponent, &mClient) !=
+        C2_OK) {
         ALOGE("Create component failed for %s", compName.c_str());
         return -1;
     }
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 7d7433a..2c8a452 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -286,7 +286,7 @@
     return NO_ERROR;
 }
 
-sp<content::pm::IPackageManagerNative> MediaPackageManager::retreivePackageManager() {
+sp<content::pm::IPackageManagerNative> MediaPackageManager::retrievePackageManager() {
     const sp<IServiceManager> sm = defaultServiceManager();
     if (sm == nullptr) {
         ALOGW("%s: failed to retrieve defaultServiceManager", __func__);
@@ -303,27 +303,27 @@
 std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) {
     if (mPackageManager == nullptr) {
         /** Can not fetch package manager at construction it may not yet be registered. */
-        mPackageManager = retreivePackageManager();
+        mPackageManager = retrievePackageManager();
         if (mPackageManager == nullptr) {
             ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
             return std::nullopt;
         }
     }
 
+    // Retrieve package names for the UID and transform to a std::vector<std::string>.
+    Vector<String16> str16PackageNames;
+    PermissionController{}.getPackagesForUid(uid, str16PackageNames);
     std::vector<std::string> packageNames;
-    auto status = mPackageManager->getNamesForUids({(int32_t)uid}, &packageNames);
-    if (!status.isOk()) {
-        ALOGW("%s: Playback capture is denied for uid %u as the package names could not be "
-              "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str());
-        return std::nullopt;
+    for (const auto& str16PackageName : str16PackageNames) {
+        packageNames.emplace_back(String8(str16PackageName).string());
     }
     if (packageNames.empty()) {
         ALOGW("%s: Playback capture for uid %u is denied as no package name could be retrieved "
-              "from the package manager: %s", __func__, uid, status.toString8().c_str());
+              "from the package manager.", __func__, uid);
         return std::nullopt;
     }
     std::vector<bool> isAllowed;
-    status = mPackageManager->isAudioPlaybackCaptureAllowed(packageNames, &isAllowed);
+    auto status = mPackageManager->isAudioPlaybackCaptureAllowed(packageNames, &isAllowed);
     if (!status.isOk()) {
         ALOGW("%s: Playback capture is denied for uid %u as the manifest property could not be "
               "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str());
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 276b471..03965db 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -112,7 +112,7 @@
 private:
     static constexpr const char* nativePackageManagerName = "package_native";
     std::optional<bool> doIsAllowed(uid_t uid);
-    sp<content::pm::IPackageManagerNative> retreivePackageManager();
+    sp<content::pm::IPackageManagerNative> retrievePackageManager();
     sp<content::pm::IPackageManagerNative> mPackageManager; // To check apps manifest
     uint_t mPackageManagerErrors = 0;
     struct Package {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 78ad467..a6f0953 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1492,6 +1492,20 @@
     }
 }
 
+// Update downstream patches for all playback threads attached to an MSD module
+void AudioFlinger::updateDownStreamPatches_l(const struct audio_patch *patch,
+                                             const std::set<audio_io_handle_t> streams)
+{
+    for (const audio_io_handle_t stream : streams) {
+        PlaybackThread *playbackThread = checkPlaybackThread_l(stream);
+        if (playbackThread == nullptr || !playbackThread->isMsdDevice()) {
+            continue;
+        }
+        playbackThread->setDownStreamPatch(patch);
+        playbackThread->sendIoConfigEvent(AUDIO_OUTPUT_CONFIG_CHANGED);
+    }
+}
+
 // Filter reserved keys from setParameters() before forwarding to audio HAL or acting upon.
 // Some keys are used for audio routing and audio path configuration and should be reserved for use
 // by audio policy and audio flinger for functional, privacy and security reasons.
@@ -2575,7 +2589,11 @@
                       *output, thread.get());
             }
             mPlaybackThreads.add(*output, thread);
-            mPatchPanel.notifyStreamOpened(outHwDev, *output);
+            struct audio_patch patch;
+            mPatchPanel.notifyStreamOpened(outHwDev, *output, &patch);
+            if (thread->isMsdDevice()) {
+                thread->setDownStreamPatch(&patch);
+            }
             return thread;
         }
     }
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 1cf1e67..1c6f57c 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -292,6 +292,9 @@
     status_t removeEffectFromHal(audio_port_handle_t deviceId,
             audio_module_handle_t hwModuleId, sp<EffectHalInterface> effect);
 
+    void updateDownStreamPatches_l(const struct audio_patch *patch,
+                                   const std::set<audio_io_handle_t> streams);
+
 private:
     // FIXME The 400 is temporarily too high until a leak of writers in media.log is fixed.
     static const size_t kLogMemorySize = 400 * 1024;
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 03bdc60..89321f9 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -373,8 +373,8 @@
     DISALLOW_COPY_AND_ASSIGN(EffectHandle);
 
     Mutex mLock;                             // protects IEffect method calls
-    wp<EffectBase> mEffect;                  // pointer to controlled EffectModule
-    sp<media::IEffectClient> mEffectClient;  // callback interface for client notifications
+    const wp<EffectBase> mEffect;            // pointer to controlled EffectModule
+    const sp<media::IEffectClient> mEffectClient;  // callback interface for client notifications
     /*const*/ sp<Client> mClient;            // client for shared memory allocation, see
                                              //   disconnect()
     sp<IMemory> mCblkMemory;                 // shared memory for control block
@@ -558,6 +558,8 @@
 
         wp<ThreadBase> thread() { return mThread; }
 
+        // TODO(b/161341295) secure this against concurrent access to mThread
+        // by other callers.
         void setThread(const wp<ThreadBase>& thread) {
             mThread = thread;
             sp<ThreadBase> p = thread.promote();
@@ -565,9 +567,9 @@
         }
 
     private:
-        wp<EffectChain> mChain;
-        wp<ThreadBase> mThread;
-        wp<AudioFlinger> mAudioFlinger;
+        const wp<EffectChain> mChain;
+        wp<ThreadBase> mThread;         // TODO(b/161341295) protect against concurrent access
+        wp<AudioFlinger> mAudioFlinger; // this could be const with some rearrangement.
     };
 
     friend class AudioFlinger;  // for mThread, mEffects
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 1e11660..806cd86 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -435,10 +435,10 @@
         *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
         newPatch.mHalHandle = halHandle;
         mAudioFlinger.mDeviceEffectManager.createAudioPatch(*handle, newPatch);
-        mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
         if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
-            addSoftwarePatchToInsertedModules(insertedModule, *handle);
+            addSoftwarePatchToInsertedModules(insertedModule, *handle, &newPatch.mAudioPatch);
         }
+        mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
     } else {
         newPatch.clearConnections(this);
     }
@@ -803,10 +803,20 @@
 }
 
 void AudioFlinger::PatchPanel::notifyStreamOpened(
-        AudioHwDevice *audioHwDevice, audio_io_handle_t stream)
+        AudioHwDevice *audioHwDevice, audio_io_handle_t stream, struct audio_patch *patch)
 {
     if (audioHwDevice->isInsert()) {
         mInsertedModules[audioHwDevice->handle()].streams.insert(stream);
+        if (patch != nullptr) {
+            std::vector <SoftwarePatch> swPatches;
+            getDownstreamSoftwarePatches(stream, &swPatches);
+            if (swPatches.size() > 0) {
+                auto iter = mPatches.find(swPatches[0].getPatchHandle());
+                if (iter != mPatches.end()) {
+                    *patch = iter->second.mAudioPatch;
+                }
+            }
+        }
     }
 }
 
@@ -835,9 +845,13 @@
 }
 
 void AudioFlinger::PatchPanel::addSoftwarePatchToInsertedModules(
-        audio_module_handle_t module, audio_patch_handle_t handle)
+        audio_module_handle_t module, audio_patch_handle_t handle,
+        const struct audio_patch *patch)
 {
     mInsertedModules[module].sw_patches.insert(handle);
+    if (!mInsertedModules[module].streams.empty()) {
+        mAudioFlinger.updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
+    }
 }
 
 void AudioFlinger::PatchPanel::removeSoftwarePatchFromInsertedModules(
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 2568dd3..c4c28fa 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -71,7 +71,8 @@
             std::vector<SoftwarePatch> *patches) const;
 
     // Notifies patch panel about all opened and closed streams.
-    void notifyStreamOpened(AudioHwDevice *audioHwDevice, audio_io_handle_t stream);
+    void notifyStreamOpened(AudioHwDevice *audioHwDevice, audio_io_handle_t stream,
+                            struct audio_patch *patch);
     void notifyStreamClosed(audio_io_handle_t stream);
 
     void dump(int fd) const;
@@ -226,7 +227,8 @@
     AudioHwDevice* findAudioHwDeviceByModule(audio_module_handle_t module);
     sp<DeviceHalInterface> findHwDeviceByModule(audio_module_handle_t module);
     void addSoftwarePatchToInsertedModules(
-            audio_module_handle_t module, audio_patch_handle_t handle);
+            audio_module_handle_t module, audio_patch_handle_t handle,
+            const struct audio_patch *patch);
     void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle);
     void erasePatch(audio_patch_handle_t handle);
 
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index a4b8650..dbc190c 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -148,7 +148,7 @@
      */
     bool            readAndClearHasChanged() { return !mChangeNotified.test_and_set(); }
 
-    using SourceMetadatas = std::vector<playback_track_metadata_t>;
+    using SourceMetadatas = std::vector<playback_track_metadata_v7_t>;
     using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
     /** Copy the track metadata in the provided iterator. Thread safe. */
     virtual void    copyMetadataTo(MetadataInserter& backInserter) const;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index ab2bc32..7e1c67e 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1876,7 +1876,8 @@
         // index 0 is reserved for normal mixer's submix
         mFastTrackAvailMask(((1 << FastMixerState::sMaxFastTracks) - 1) & ~1),
         mHwSupportsPause(false), mHwPaused(false), mFlushPending(false),
-        mLeftVolFloat(-1.0), mRightVolFloat(-1.0)
+        mLeftVolFloat(-1.0), mRightVolFloat(-1.0),
+        mDownStreamPatch{}
 {
     snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
     mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
@@ -2660,12 +2661,16 @@
     ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event);
 
     desc->mIoHandle = mId;
+    struct audio_patch patch = mPatch;
+    if (isMsdDevice()) {
+        patch = mDownStreamPatch;
+    }
 
     switch (event) {
     case AUDIO_OUTPUT_OPENED:
     case AUDIO_OUTPUT_REGISTERED:
     case AUDIO_OUTPUT_CONFIG_CHANGED:
-        desc->mPatch = mPatch;
+        desc->mPatch = patch;
         desc->mChannelMask = mChannelMask;
         desc->mSamplingRate = mSampleRate;
         desc->mFormat = mFormat;
@@ -2675,7 +2680,7 @@
         desc->mLatency = latency_l();
         break;
     case AUDIO_CLIENT_STARTED:
-        desc->mPatch = mPatch;
+        desc->mPatch = patch;
         desc->mPortId = portId;
         break;
     case AUDIO_OUTPUT_CLOSED:
@@ -8097,10 +8102,15 @@
     StreamInHalInterface::SinkMetadata metadata;
     for (const sp<RecordTrack> &track : mActiveTracks) {
         // No track is invalid as this is called after prepareTrack_l in the same critical section
-        metadata.tracks.push_back({
+        record_track_metadata_v7_t trackMetadata;
+        trackMetadata.base = {
                 .source = track->attributes().source,
                 .gain = 1, // capture tracks do not have volumes
-        });
+        };
+        trackMetadata.channel_mask = track->channelMask(),
+        strncpy(trackMetadata.tags, track->attributes().tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
+
+        metadata.tracks.push_back(trackMetadata);
     }
     mInput->stream->updateSinkMetadata(metadata);
 }
@@ -9675,11 +9685,15 @@
     StreamOutHalInterface::SourceMetadata metadata;
     for (const sp<MmapTrack> &track : mActiveTracks) {
         // No track is invalid as this is called after prepareTrack_l in the same critical section
-        metadata.tracks.push_back({
+        playback_track_metadata_v7_t trackMetadata;
+        trackMetadata.base = {
                 .usage = track->attributes().usage,
                 .content_type = track->attributes().content_type,
                 .gain = mHalVolFloat, // TODO: propagate from aaudio pre-mix volume
-        });
+        };
+        trackMetadata.channel_mask = track->channelMask(),
+        strncpy(trackMetadata.tags, track->attributes().tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
+        metadata.tracks.push_back(trackMetadata);
     }
     mOutput->stream->updateSourceMetadata(metadata);
 }
@@ -9800,10 +9814,14 @@
     StreamInHalInterface::SinkMetadata metadata;
     for (const sp<MmapTrack> &track : mActiveTracks) {
         // No track is invalid as this is called after prepareTrack_l in the same critical section
-        metadata.tracks.push_back({
+        record_track_metadata_v7_t trackMetadata;
+        trackMetadata.base = {
                 .source = track->attributes().source,
                 .gain = 1, // capture tracks do not have volumes
-        });
+        };
+        trackMetadata.channel_mask = track->channelMask(),
+        strncpy(trackMetadata.tags, track->attributes().tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
+        metadata.tracks.push_back(trackMetadata);
     }
     mInput->stream->updateSinkMetadata(metadata);
 }
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 014f2d7..cf4bb8a 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -967,6 +967,11 @@
                     return (mHapticChannelMask & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE;
                 }
 
+                void setDownStreamPatch(const struct audio_patch *patch) {
+                    Mutex::Autolock _l(mLock);
+                    mDownStreamPatch = *patch;
+                }
+
 protected:
     // updated by readOutputParameters_l()
     size_t                          mNormalFrameCount;  // normal mixer and effects
@@ -1250,6 +1255,10 @@
                 // volumes last sent to audio HAL with stream->setVolume()
                 float mLeftVolFloat;
                 float mRightVolFloat;
+
+                // audio patch used by the downstream software patch.
+                // Only used if ThreadBase::mIsMsdDevice is true.
+                struct audio_patch mDownStreamPatch;
 };
 
 class MixerThread : public PlaybackThread {
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 01d5345..38dab5b 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -253,6 +253,8 @@
     // Called to tally underrun frames in playback.
     virtual void tallyUnderrunFrames(size_t /* frames */) {}
 
+    audio_channel_mask_t channelMask() const { return mChannelMask; }
+
 protected:
     DISALLOW_COPY_AND_ASSIGN(TrackBase);
 
@@ -278,8 +280,6 @@
 
     size_t frameSize() const { return mFrameSize; }
 
-    audio_channel_mask_t channelMask() const { return mChannelMask; }
-
     virtual uint32_t sampleRate() const { return mSampleRate; }
 
     bool isStopped() const {
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 6049f62..06cbe87 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1310,11 +1310,15 @@
 
 void AudioFlinger::PlaybackThread::Track::copyMetadataTo(MetadataInserter& backInserter) const
 {
-    *backInserter++ = {
+    playback_track_metadata_v7_t metadata;
+    metadata.base = {
             .usage = mAttr.usage,
             .content_type = mAttr.content_type,
             .gain = mFinalVolume,
     };
+    metadata.channel_mask = mChannelMask,
+    strncpy(metadata.tags, mAttr.tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
+    *backInserter++ = metadata;
 }
 
 void AudioFlinger::PlaybackThread::Track::setTeePatches(TeePatches teePatches) {
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index bd6cc96..e52ad5e 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -439,6 +439,8 @@
                                                 audio_patch_handle_t patchHandle,
                                                 audio_source_t source) = 0;
 
+    virtual void onRoutingUpdated() = 0;
+
     // Used to notify the sound trigger module that an audio capture is about to
     // take place. This should typically result in any active recognition
     // sessions to be preempted on modules that do not support sound trigger
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 159ca08..d038ce5 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -459,7 +459,7 @@
         device = availableDevices.getFirstExistingDevice({
                 AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET,
                 AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
-                AUDIO_DEVICE_IN_BUILTIN_MIC});
+                AUDIO_DEVICE_IN_BLUETOOTH_BLE, AUDIO_DEVICE_IN_BUILTIN_MIC});
         break;
 
     case AUDIO_SOURCE_VOICE_COMMUNICATION:
@@ -493,7 +493,8 @@
         default:    // FORCE_NONE
             device = availableDevices.getFirstExistingDevice({
                     AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
-                    AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
+                    AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BLUETOOTH_BLE,
+                    AUDIO_DEVICE_IN_BUILTIN_MIC});
             break;
 
         }
@@ -501,13 +502,25 @@
 
     case AUDIO_SOURCE_VOICE_RECOGNITION:
     case AUDIO_SOURCE_UNPROCESSED:
-    case AUDIO_SOURCE_HOTWORD:
-        if (inputSource == AUDIO_SOURCE_HOTWORD) {
-            // We should not use primary output criteria for Hotword but rather limit
-            // to devices attached to the same HW module as the build in mic
-            LOG_ALWAYS_FATAL_IF(availablePrimaryDevices.isEmpty(), "Primary devices not found");
-            availableDevices = availablePrimaryDevices;
+        if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
+            device = availableDevices.getDevice(
+                    AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
+            if (device != nullptr) break;
         }
+        // we need to make BLUETOOTH_BLE has higher priority than BUILTIN_MIC,
+        // because sometimes user want to do voice search by bt remote
+        // even if BUILDIN_MIC is available.
+        device = availableDevices.getFirstExistingDevice({
+                AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET,
+                AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
+                AUDIO_DEVICE_IN_BLUETOOTH_BLE, AUDIO_DEVICE_IN_BUILTIN_MIC});
+
+        break;
+    case AUDIO_SOURCE_HOTWORD:
+        // We should not use primary output criteria for Hotword but rather limit
+        // to devices attached to the same HW module as the build in mic
+        LOG_ALWAYS_FATAL_IF(availablePrimaryDevices.isEmpty(), "Primary devices not found");
+        availableDevices = availablePrimaryDevices;
         if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
             device = availableDevices.getDevice(
                     AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
@@ -533,7 +546,8 @@
     case AUDIO_SOURCE_VOICE_PERFORMANCE:
         device = availableDevices.getFirstExistingDevice({
                 AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
-                AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
+                AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BLUETOOTH_BLE,
+                AUDIO_DEVICE_IN_BUILTIN_MIC});
         break;
     case AUDIO_SOURCE_REMOTE_SUBMIX:
         device = availableDevices.getDevice(
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index aac244c..a1bdf37 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1053,7 +1053,6 @@
         if (*output != AUDIO_IO_HANDLE_NONE && setMsdPatch(device) == NO_ERROR) {
             ALOGV("%s() Using MSD devices %s instead of devices %s",
                   __func__, msdDevices.toString().c_str(), outputDevices.toString().c_str());
-            outputDevices = msdDevices;
         } else {
             *output = AUDIO_IO_HANDLE_NONE;
         }
@@ -5350,6 +5349,8 @@
     if (mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD) != 0) {
         setMsdPatch();
     }
+    // an event that changed routing likely occurred, inform upper layers
+    mpClientInterface->onRoutingUpdated();
 }
 
 bool AudioPolicyManager::followsSameRouting(const audio_attributes_t &lAttr,
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 90b93e2..77b5200 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -266,6 +266,11 @@
     mAudioPolicyService->onAudioVolumeGroupChanged(group, flags);
 }
 
+void AudioPolicyService::AudioPolicyClient::onRoutingUpdated()
+{
+    mAudioPolicyService->onRoutingUpdated();
+}
+
 audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId(audio_unique_id_use_t use)
 {
     return AudioSystem::newAudioUniqueId(use);
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index d71a317..a898dff 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -275,6 +275,19 @@
     }
 }
 
+void AudioPolicyService::onRoutingUpdated()
+{
+    mOutputCommandThread->routingChangedCommand();
+}
+
+void AudioPolicyService::doOnRoutingUpdated()
+{
+  Mutex::Autolock _l(mNotificationClientsLock);
+    for (size_t i = 0; i < mNotificationClients.size(); i++) {
+        mNotificationClients.valueAt(i)->onRoutingUpdated();
+    }
+}
+
 status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
                                                 audio_patch_handle_t *handle,
                                                 int delayMs)
@@ -404,6 +417,13 @@
     mAudioVolumeGroupCallbacksEnabled = enabled;
 }
 
+void AudioPolicyService::NotificationClient::onRoutingUpdated()
+{
+    if (mAudioPolicyServiceClient != 0 && isServiceUid(mUid)) {
+        mAudioPolicyServiceClient->onRoutingUpdated();
+    }
+}
+
 void AudioPolicyService::binderDied(const wp<IBinder>& who) {
     ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
             IPCThreadState::self()->getCallingPid());
@@ -1414,6 +1434,16 @@
                     svc->doOnNewAudioModulesAvailable();
                     mLock.lock();
                     } break;
+                case ROUTING_UPDATED: {
+                    ALOGV("AudioCommandThread() processing routing update");
+                    svc = mService.promote();
+                    if (svc == 0) {
+                        break;
+                    }
+                    mLock.unlock();
+                    svc->doOnRoutingUpdated();
+                    mLock.lock();
+                    } break;
 
                 default:
                     ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
@@ -1710,6 +1740,14 @@
     sendCommand(command);
 }
 
+void AudioPolicyService::AudioCommandThread::routingChangedCommand()
+{
+    sp<AudioCommand>command = new AudioCommand();
+    command->mCommand = ROUTING_UPDATED;
+    ALOGV("AudioCommandThread() adding routing update");
+    sendCommand(command);
+}
+
 status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
 {
     {
@@ -1873,6 +1911,10 @@
 
         } break;
 
+        case ROUTING_UPDATED: {
+
+        } break;
+
         default:
             break;
         }
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index c0e29ee..db84d54 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -345,6 +345,10 @@
 
             void onAudioVolumeGroupChanged(volume_group_t group, int flags);
             void doOnAudioVolumeGroupChanged(volume_group_t group, int flags);
+
+            void onRoutingUpdated();
+            void doOnRoutingUpdated();
+
             void setEffectSuspended(int effectId,
                                     audio_session_t sessionId,
                                     bool suspended);
@@ -497,6 +501,7 @@
             RECORDING_CONFIGURATION_UPDATE,
             SET_EFFECT_SUSPENDED,
             AUDIO_MODULES_UPDATE,
+            ROUTING_UPDATED,
         };
 
         AudioCommandThread (String8 name, const wp<AudioPolicyService>& service);
@@ -543,6 +548,7 @@
                                                           audio_session_t sessionId,
                                                           bool suspended);
                     void        audioModulesUpdateCommand();
+                    void        routingChangedCommand();
                     void        insertCommand_l(AudioCommand *command, int delayMs = 0);
     private:
         class AudioCommandData;
@@ -761,6 +767,8 @@
 
         virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags);
 
+        virtual void onRoutingUpdated();
+
         virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
 
         void setSoundTriggerCaptureState(bool active) override;
@@ -793,6 +801,7 @@
                                                     std::vector<effect_descriptor_t> effects,
                                                     audio_patch_handle_t patchHandle,
                                                     audio_source_t source);
+                            void      onRoutingUpdated();
                             void      setAudioPortCallbacksEnabled(bool enabled);
                             void setAudioVolumeGroupCallbacksEnabled(bool enabled);
 
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index 433a6ff..e2d7d17 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -123,6 +123,17 @@
 
     virtual void addSupportedFormat(audio_format_t /* format */) {}
 
+    void onRoutingUpdated() override {
+        mRoutingUpdatedUpdateCount++;
+    }
+
+    void resetRoutingUpdatedCounter() {
+        mRoutingUpdatedUpdateCount = 0;
+    }
+
+    size_t getRoutingUpdatedCounter() const {
+        return mRoutingUpdatedUpdateCount; }
+
 private:
     audio_module_handle_t mNextModuleHandle = AUDIO_MODULE_HANDLE_NONE + 1;
     audio_io_handle_t mNextIoHandle = AUDIO_IO_HANDLE_NONE + 1;
@@ -130,6 +141,7 @@
     std::map<audio_patch_handle_t, struct audio_patch> mActivePatches;
     std::set<std::string> mAllowedModuleNames;
     size_t mAudioPortListUpdateCount = 0;
+    size_t mRoutingUpdatedUpdateCount = 0;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index fa6b90f..d289e15 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -83,6 +83,7 @@
                                         std::vector<effect_descriptor_t> effects __unused,
                                         audio_patch_handle_t patchHandle __unused,
                                         audio_source_t source __unused) override { }
+    void onRoutingUpdated() override { }
     void setEffectSuspended(int effectId __unused,
                             audio_session_t sessionId __unused,
                             bool suspended __unused) {}
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 889efac..3032589 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -356,6 +356,7 @@
 
     sp<DeviceDescriptor> mMsdOutputDevice;
     sp<DeviceDescriptor> mMsdInputDevice;
+    sp<DeviceDescriptor> mDefaultOutputDevice;
 };
 
 void AudioPolicyManagerTestMsd::SetUpManagerConfig() {
@@ -410,17 +411,21 @@
     primaryEncodedOutputProfile->addSupportedDevice(config.getDefaultOutputDevice());
     config.getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
             addOutputProfile(primaryEncodedOutputProfile);
+
+    mDefaultOutputDevice = config.getDefaultOutputDevice();
 }
 
 void AudioPolicyManagerTestMsd::TearDown() {
     mMsdOutputDevice.clear();
     mMsdInputDevice.clear();
+    mDefaultOutputDevice.clear();
     AudioPolicyManagerTest::TearDown();
 }
 
 TEST_F(AudioPolicyManagerTestMsd, InitSuccess) {
     ASSERT_TRUE(mMsdOutputDevice);
     ASSERT_TRUE(mMsdInputDevice);
+    ASSERT_TRUE(mDefaultOutputDevice);
 }
 
 TEST_F(AudioPolicyManagerTestMsd, Dump) {
@@ -439,7 +444,7 @@
     audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
     getOutputForAttr(&selectedDeviceId,
             AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
-    ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+    ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
     ASSERT_EQ(1, patchCount.deltaFromSnapshot());
 }
 
@@ -448,7 +453,7 @@
     audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
     getOutputForAttr(&selectedDeviceId,
             AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
-    ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+    ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
     ASSERT_EQ(1, patchCount.deltaFromSnapshot());
 }
 
@@ -457,11 +462,11 @@
     audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
     getOutputForAttr(&selectedDeviceId,
             AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
-    ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+    ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
     ASSERT_EQ(1, patchCount.deltaFromSnapshot());
     getOutputForAttr(&selectedDeviceId,
             AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
-    ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+    ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
     ASSERT_EQ(1, patchCount.deltaFromSnapshot());
 }
 
@@ -483,7 +488,7 @@
         getOutputForAttr(&selectedDeviceId,
                 AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT,
                 nullptr /*output*/, &portId);
-        ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+        ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
         ASSERT_EQ(1, patchCount.deltaFromSnapshot());
         mManager->releaseOutput(portId);
         ASSERT_EQ(1, patchCount.deltaFromSnapshot());
@@ -505,7 +510,7 @@
         audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
         getOutputForAttr(&selectedDeviceId,
                 AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
-        ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+        ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
         ASSERT_EQ(0, patchCount.deltaFromSnapshot());
     }
 }
@@ -1184,6 +1189,34 @@
     dumpToLog();
 }
 
+TEST_F(AudioPolicyManagerTestDeviceConnection, RoutingUpdate) {
+    mClient->resetRoutingUpdatedCounter();
+    // Connecting a valid output device with valid parameters should trigger a routing update
+    ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
+            AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+            "a", "b", AUDIO_FORMAT_DEFAULT));
+    ASSERT_EQ(1, mClient->getRoutingUpdatedCounter());
+
+    // Disconnecting a connected device should succeed and trigger a routing update
+    ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
+            AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+            "a", "b", AUDIO_FORMAT_DEFAULT));
+    ASSERT_EQ(2, mClient->getRoutingUpdatedCounter());
+
+    // Disconnecting a disconnected device should fail and not trigger a routing update
+    ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
+            AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+            "a", "b",  AUDIO_FORMAT_DEFAULT));
+    ASSERT_EQ(2, mClient->getRoutingUpdatedCounter());
+
+    // Changing force use should trigger an update
+    auto config = mManager->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA);
+    auto newConfig = config == AUDIO_POLICY_FORCE_BT_A2DP ?
+            AUDIO_POLICY_FORCE_NONE : AUDIO_POLICY_FORCE_BT_A2DP;
+    mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA, newConfig);
+    ASSERT_EQ(3, mClient->getRoutingUpdatedCounter());
+}
+
 TEST_P(AudioPolicyManagerTestDeviceConnection, SetDeviceConnectionState) {
     const audio_devices_t type = std::get<0>(GetParam());
     const std::string name = std::get<1>(GetParam());
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 662b58f..2494302 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -76,7 +76,8 @@
 bool Camera2Client::isZslEnabledInStillTemplate() {
     bool zslEnabled = false;
     CameraMetadata stillTemplate;
-    status_t res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE, &stillTemplate);
+    status_t res = mDevice->createDefaultRequest(
+            camera_request_template_t::CAMERA_TEMPLATE_STILL_CAPTURE, &stillTemplate);
     if (res == OK) {
         camera_metadata_entry_t enableZsl = stillTemplate.find(ANDROID_CONTROL_ENABLE_ZSL);
         if (enableZsl.count == 1) {
diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
index a71a732..744aaee 100644
--- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
@@ -31,6 +31,8 @@
 namespace android {
 namespace camera2 {
 
+using android::camera3::CAMERA_STREAM_ROTATION_0;
+
 CallbackProcessor::CallbackProcessor(sp<Camera2Client> client):
         Thread(false),
         mClient(client),
@@ -154,7 +156,7 @@
                 callbackFormat, params.previewFormat);
         res = device->createStream(mCallbackWindow,
                 params.previewWidth, params.previewHeight, callbackFormat,
-                HAL_DATASPACE_V0_JFIF, CAMERA3_STREAM_ROTATION_0, &mCallbackStreamId,
+                HAL_DATASPACE_V0_JFIF, CAMERA_STREAM_ROTATION_0, &mCallbackStreamId,
                 String8());
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index 0c01a91..4c9b7ed 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -706,7 +706,7 @@
 
     if (mCaptureRequest.entryCount() == 0) {
         res = client->getCameraDevice()->createDefaultRequest(
-                CAMERA2_TEMPLATE_STILL_CAPTURE,
+                camera_request_template_t::CAMERA_TEMPLATE_STILL_CAPTURE,
                 &mCaptureRequest);
         if (res != OK) {
             ALOGE("%s: Camera %d: Unable to create default still image request:"
diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
index ddfe5e3..ff2e398 100755
--- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
@@ -35,6 +35,8 @@
 namespace android {
 namespace camera2 {
 
+using android::camera3::CAMERA_STREAM_ROTATION_0;
+
 JpegProcessor::JpegProcessor(
     sp<Camera2Client> client,
     wp<CaptureSequencer> sequencer):
@@ -148,7 +150,7 @@
         res = device->createStream(mCaptureWindow,
                 params.pictureWidth, params.pictureHeight,
                 HAL_PIXEL_FORMAT_BLOB, HAL_DATASPACE_V0_JFIF,
-                CAMERA3_STREAM_ROTATION_0, &mCaptureStreamId,
+                CAMERA_STREAM_ROTATION_0, &mCaptureStreamId,
                 String8());
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't create output stream for capture: "
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index d543cab..e062c14 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -37,6 +37,8 @@
 namespace android {
 namespace camera2 {
 
+using android::camera3::CAMERA_TEMPLATE_PREVIEW;
+
 Parameters::Parameters(int cameraId,
         int cameraFacing) :
         cameraId(cameraId),
@@ -2468,7 +2470,7 @@
 
         // Use focal length in preview template if it exists
         CameraMetadata previewTemplate;
-        status_t res = device->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW, &previewTemplate);
+        status_t res = device->createDefaultRequest(CAMERA_TEMPLATE_PREVIEW, &previewTemplate);
         if (res != OK) {
             ALOGE("%s: Failed to create default PREVIEW request: %s (%d)",
                     __FUNCTION__, strerror(-res), res);
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
index 0786f53..8b1eb28 100644
--- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
@@ -40,6 +40,10 @@
 namespace android {
 namespace camera2 {
 
+using android::camera3::CAMERA_STREAM_ROTATION_0;
+using android::camera3::CAMERA_TEMPLATE_PREVIEW;
+using android::camera3::CAMERA_TEMPLATE_ZERO_SHUTTER_LAG;
+
 StreamingProcessor::StreamingProcessor(sp<Camera2Client> client):
         mClient(client),
         mDevice(client->getCameraDevice()),
@@ -113,12 +117,12 @@
             return INVALID_OPERATION;
         }
 
-        // Use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG for ZSL streaming case.
+        // Use CAMERA_TEMPLATE_ZERO_SHUTTER_LAG for ZSL streaming case.
         if (params.useZeroShutterLag() && !params.recordingHint) {
             res = device->createDefaultRequest(
-                    CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG, &mPreviewRequest);
+                    CAMERA_TEMPLATE_ZERO_SHUTTER_LAG, &mPreviewRequest);
         } else {
-            res = device->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW,
+            res = device->createDefaultRequest(CAMERA_TEMPLATE_PREVIEW,
                     &mPreviewRequest);
         }
 
@@ -194,7 +198,7 @@
         res = device->createStream(mPreviewWindow,
                 params.previewWidth, params.previewHeight,
                 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_UNKNOWN,
-                CAMERA3_STREAM_ROTATION_0, &mPreviewStreamId, String8());
+                CAMERA_STREAM_ROTATION_0, &mPreviewStreamId, String8());
         if (res != OK) {
             ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
                     __FUNCTION__, mId, strerror(-res), res);
@@ -263,7 +267,7 @@
     }
 
     if (mRecordingRequest.entryCount() == 0) {
-        res = device->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
+        res = device->createDefaultRequest(camera_request_template_t::CAMERA_TEMPLATE_VIDEO_RECORD,
                 &mRecordingRequest);
         if (res != OK) {
             ALOGE("%s: Camera %d: Unable to create default recording request:"
@@ -379,7 +383,7 @@
         res = device->createStream(mRecordingWindow,
                 params.videoWidth, params.videoHeight,
                 params.videoFormat, params.videoDataSpace,
-                CAMERA3_STREAM_ROTATION_0, &mRecordingStreamId,
+                CAMERA_STREAM_ROTATION_0, &mRecordingStreamId,
                 String8());
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't create output stream for recording: "
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
index 8753dcf..0701b6f 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
@@ -42,6 +42,9 @@
 namespace android {
 namespace camera2 {
 
+using android::camera3::CAMERA_STREAM_ROTATION_0;
+using android::camera3::CAMERA_TEMPLATE_STILL_CAPTURE;
+
 namespace {
 struct TimestampFinder : public RingBufferConsumer::RingBufferComparator {
     typedef RingBufferConsumer::BufferInfo BufferInfo;
@@ -257,7 +260,7 @@
 
         res = device->createStream(outSurface, params.fastInfo.maxZslSize.width,
             params.fastInfo.maxZslSize.height, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
-            HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0, &mZslStreamId,
+            HAL_DATASPACE_UNKNOWN, CAMERA_STREAM_ROTATION_0, &mZslStreamId,
             String8());
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't create ZSL stream: "
@@ -348,7 +351,7 @@
     }
 
     CameraMetadata stillTemplate;
-    device->createDefaultRequest(CAMERA3_TEMPLATE_STILL_CAPTURE, &stillTemplate);
+    device->createDefaultRequest(CAMERA_TEMPLATE_STILL_CAPTURE, &stillTemplate);
 
     // Find some of the post-processing tags, and assign the value from template to the request.
     // Only check the aberration mode and noise reduction mode for now, as they are very important
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 66eda5d..6e1aba9 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -51,6 +51,7 @@
 
 namespace android {
 using namespace camera2;
+using camera3::camera_stream_rotation_t::CAMERA_STREAM_ROTATION_0;
 
 CameraDeviceClientBase::CameraDeviceClientBase(
         const sp<CameraService>& cameraService,
@@ -170,7 +171,6 @@
 
     const StreamSurfaceId& streamSurfaceId = mStreamMap.valueAt(idx);
     if (outSurfaceMap->find(streamSurfaceId.streamId()) == outSurfaceMap->end()) {
-        (*outSurfaceMap)[streamSurfaceId.streamId()] = std::vector<size_t>();
         outputStreamIds->push_back(streamSurfaceId.streamId());
     }
     (*outSurfaceMap)[streamSurfaceId.streamId()].push_back(streamSurfaceId.surfaceId());
@@ -807,7 +807,7 @@
 
         err = compositeStream->createStream(surfaces, deferredConsumer, streamInfo.width,
                 streamInfo.height, streamInfo.format,
-                static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
+                static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
                 &streamId, physicalCameraId, &surfaceIds, outputConfiguration.getSurfaceSetID(),
                 isShared);
         if (err == OK) {
@@ -817,7 +817,7 @@
     } else {
         err = mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
                 streamInfo.height, streamInfo.format, streamInfo.dataSpace,
-                static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
+                static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
                 &streamId, physicalCameraId, &surfaceIds, outputConfiguration.getSurfaceSetID(),
                 isShared);
     }
@@ -885,7 +885,7 @@
     String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
     err = mDevice->createStream(noSurface, /*hasDeferredConsumer*/true, width,
             height, format, dataSpace,
-            static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
+            static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
             &streamId, physicalCameraId, &surfaceIds,
             outputConfiguration.getSurfaceSetID(), isShared,
             consumerUsage);
@@ -1152,9 +1152,12 @@
         return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
     }
 
-    CameraMetadata metadata;
     status_t err;
-    if ( (err = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
+    camera_request_template_t tempId = camera_request_template_t::CAMERA_TEMPLATE_COUNT;
+    if (!(res = mapRequestTemplate(templateId, &tempId)).isOk()) return res;
+
+    CameraMetadata metadata;
+    if ( (err = mDevice->createDefaultRequest(tempId, &metadata) ) == OK &&
         request != NULL) {
 
         request->swap(metadata);
@@ -1886,4 +1889,41 @@
     return CameraUtils::getRotationTransform(staticInfo, transform);
 }
 
+binder::Status CameraDeviceClient::mapRequestTemplate(int templateId,
+        camera_request_template_t* tempId /*out*/) {
+    binder::Status ret = binder::Status::ok();
+
+    if (tempId == nullptr) {
+        ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
+                "Camera %s: Invalid template argument", mCameraIdStr.string());
+        return ret;
+    }
+    switch(templateId) {
+        case ICameraDeviceUser::TEMPLATE_PREVIEW:
+            *tempId = camera_request_template_t::CAMERA_TEMPLATE_PREVIEW;
+            break;
+        case ICameraDeviceUser::TEMPLATE_RECORD:
+            *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_RECORD;
+            break;
+        case ICameraDeviceUser::TEMPLATE_STILL_CAPTURE:
+            *tempId = camera_request_template_t::CAMERA_TEMPLATE_STILL_CAPTURE;
+            break;
+        case ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT:
+            *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_SNAPSHOT;
+            break;
+        case ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG:
+            *tempId = camera_request_template_t::CAMERA_TEMPLATE_ZERO_SHUTTER_LAG;
+            break;
+        case ICameraDeviceUser::TEMPLATE_MANUAL:
+            *tempId = camera_request_template_t::CAMERA_TEMPLATE_MANUAL;
+            break;
+        default:
+            ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
+                    "Camera %s: Template ID %d is invalid or not supported",
+                    mCameraIdStr.string(), templateId);
+            return ret;
+    }
+
+    return ret;
+}
 } // namespace android
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 3f72eca..57688a0 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -276,6 +276,10 @@
             /*out*/SurfaceMap* surfaceMap, /*out*/Vector<int32_t>* streamIds,
             /*out*/int32_t*  currentStreamId);
 
+    // Utility method that maps AIDL request templates.
+    binder::Status mapRequestTemplate(int templateId,
+            camera_request_template_t* tempId /*out*/);
+
     // IGraphicsBufferProducer binder -> Stream ID + Surface ID for output streams
     KeyedVector<sp<IBinder>, StreamSurfaceId> mStreamMap;
 
diff --git a/services/camera/libcameraservice/api2/CompositeStream.cpp b/services/camera/libcameraservice/api2/CompositeStream.cpp
index a61dac7..2f8ca6b 100644
--- a/services/camera/libcameraservice/api2/CompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/CompositeStream.cpp
@@ -46,7 +46,7 @@
 
 status_t CompositeStream::createStream(const std::vector<sp<Surface>>& consumers,
         bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-        camera3_stream_rotation_t rotation, int * id, const String8& physicalCameraId,
+        camera_stream_rotation_t rotation, int * id, const String8& physicalCameraId,
         std::vector<int> * surfaceIds, int streamSetId, bool isShared) {
     if (hasDeferredConsumer) {
         ALOGE("%s: Deferred consumers not supported in case of composite streams!",
diff --git a/services/camera/libcameraservice/api2/CompositeStream.h b/services/camera/libcameraservice/api2/CompositeStream.h
index 5f62d47..2a934df 100644
--- a/services/camera/libcameraservice/api2/CompositeStream.h
+++ b/services/camera/libcameraservice/api2/CompositeStream.h
@@ -43,7 +43,7 @@
 
     status_t createStream(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
             std::vector<int> *surfaceIds, int streamSetId, bool isShared);
 
     status_t deleteStream();
@@ -54,7 +54,7 @@
     // Create and register all internal camera streams.
     virtual status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
             std::vector<int> *surfaceIds, int streamSetId, bool isShared) = 0;
 
     // Release all internal streams and corresponding resources.
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
index c6859be..2c553f3 100644
--- a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
@@ -341,7 +341,7 @@
         return res;
     }
 
-    size_t finalJpegSize = actualJpegSize + sizeof(struct camera3_jpeg_blob);
+    size_t finalJpegSize = actualJpegSize + sizeof(struct camera_jpeg_blob);
     if (finalJpegSize > finalJpegBufferSize) {
         ALOGE("%s: Final jpeg buffer not large enough for the jpeg blob header", __FUNCTION__);
         outputANW->cancelBuffer(mOutputSurface.get(), anb, /*fence*/ -1);
@@ -357,9 +357,9 @@
 
     ALOGV("%s: Final jpeg size: %zu", __func__, finalJpegSize);
     uint8_t* header = static_cast<uint8_t *> (dstBuffer) +
-        (gb->getWidth() - sizeof(struct camera3_jpeg_blob));
-    struct camera3_jpeg_blob *blob = reinterpret_cast<struct camera3_jpeg_blob*> (header);
-    blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
+        (gb->getWidth() - sizeof(struct camera_jpeg_blob));
+    struct camera_jpeg_blob *blob = reinterpret_cast<struct camera_jpeg_blob*> (header);
+    blob->jpeg_blob_id = CAMERA_JPEG_BLOB_ID;
     blob->jpeg_size = actualJpegSize;
     outputANW->queueBuffer(mOutputSurface.get(), anb, /*fence*/ -1);
 
@@ -486,7 +486,7 @@
 
 status_t DepthCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
         bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
-        camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+        camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
         std::vector<int> *surfaceIds, int /*streamSetId*/, bool /*isShared*/) {
     if (mSupportedDepthSizes.empty()) {
         ALOGE("%s: This camera device doesn't support any depth map streams!", __FUNCTION__);
@@ -666,13 +666,11 @@
 status_t DepthCompositeStream::insertGbp(SurfaceMap* /*out*/outSurfaceMap,
         Vector<int32_t> * /*out*/outputStreamIds, int32_t* /*out*/currentStreamId) {
     if (outSurfaceMap->find(mDepthStreamId) == outSurfaceMap->end()) {
-        (*outSurfaceMap)[mDepthStreamId] = std::vector<size_t>();
         outputStreamIds->push_back(mDepthStreamId);
     }
     (*outSurfaceMap)[mDepthStreamId].push_back(mDepthSurfaceId);
 
     if (outSurfaceMap->find(mBlobStreamId) == outSurfaceMap->end()) {
-        (*outSurfaceMap)[mBlobStreamId] = std::vector<size_t>();
         outputStreamIds->push_back(mBlobStreamId);
     }
     (*outSurfaceMap)[mBlobStreamId].push_back(mBlobSurfaceId);
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.h b/services/camera/libcameraservice/api2/DepthCompositeStream.h
index cab52b6..05bc504 100644
--- a/services/camera/libcameraservice/api2/DepthCompositeStream.h
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.h
@@ -50,7 +50,7 @@
     // CompositeStream overrides
     status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
             std::vector<int> *surfaceIds, int streamSetId, bool isShared) override;
     status_t deleteInternalStreams() override;
     status_t configureStream() override;
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index a7173d1..7d68485 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -114,7 +114,7 @@
 
 status_t HeicCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
         bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
-        camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+        camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
         std::vector<int> *surfaceIds, int /*streamSetId*/, bool /*isShared*/) {
 
     sp<CameraDeviceBase> device = mDevice.promote();
@@ -521,13 +521,11 @@
 status_t HeicCompositeStream::insertGbp(SurfaceMap* /*out*/outSurfaceMap,
         Vector<int32_t>* /*out*/outputStreamIds, int32_t* /*out*/currentStreamId) {
     if (outSurfaceMap->find(mAppSegmentStreamId) == outSurfaceMap->end()) {
-        (*outSurfaceMap)[mAppSegmentStreamId] = std::vector<size_t>();
         outputStreamIds->push_back(mAppSegmentStreamId);
     }
     (*outSurfaceMap)[mAppSegmentStreamId].push_back(mAppSegmentSurfaceId);
 
     if (outSurfaceMap->find(mMainImageStreamId) == outSurfaceMap->end()) {
-        (*outSurfaceMap)[mMainImageStreamId] = std::vector<size_t>();
         outputStreamIds->push_back(mMainImageStreamId);
     }
     (*outSurfaceMap)[mMainImageStreamId].push_back(mMainImageSurfaceId);
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.h b/services/camera/libcameraservice/api2/HeicCompositeStream.h
index a373127..cbd9d21 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.h
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.h
@@ -45,7 +45,7 @@
 
     status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            camera3_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
+            camera_stream_rotation_t rotation, int *id, const String8& physicalCameraId,
             std::vector<int> *surfaceIds, int streamSetId, bool isShared) override;
 
     status_t deleteInternalStreams() override;
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 77e660f..5e46f08 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -28,7 +28,6 @@
 #include <utils/List.h>
 
 #include "hardware/camera2.h"
-#include "hardware/camera3.h"
 #include "camera/CameraMetadata.h"
 #include "camera/CaptureResult.h"
 #include "gui/IGraphicBufferProducer.h"
@@ -41,6 +40,41 @@
 
 namespace android {
 
+namespace camera3 {
+
+typedef enum camera_request_template {
+    CAMERA_TEMPLATE_PREVIEW = 1,
+    CAMERA_TEMPLATE_STILL_CAPTURE = 2,
+    CAMERA_TEMPLATE_VIDEO_RECORD = 3,
+    CAMERA_TEMPLATE_VIDEO_SNAPSHOT = 4,
+    CAMERA_TEMPLATE_ZERO_SHUTTER_LAG = 5,
+    CAMERA_TEMPLATE_MANUAL = 6,
+    CAMERA_TEMPLATE_COUNT,
+    CAMERA_VENDOR_TEMPLATE_START = 0x40000000
+} camera_request_template_t;
+
+typedef enum camera_stream_configuration_mode {
+    CAMERA_STREAM_CONFIGURATION_NORMAL_MODE = 0,
+    CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE = 1,
+    CAMERA_VENDOR_STREAM_CONFIGURATION_MODE_START = 0x8000
+} camera_stream_configuration_mode_t;
+
+typedef struct camera_jpeg_blob {
+    uint16_t jpeg_blob_id;
+    uint32_t jpeg_size;
+} camera_jpeg_blob_t;
+
+enum {
+    CAMERA_JPEG_BLOB_ID = 0x00FF,
+    CAMERA_JPEG_APP_SEGMENTS_BLOB_ID = 0x0100,
+};
+
+} // namespace camera3
+
+using camera3::camera_request_template_t;;
+using camera3::camera_stream_configuration_mode_t;
+using camera3::camera_stream_rotation_t;
+
 class CameraProviderManager;
 
 // Mapping of output stream index to surface ids
@@ -128,7 +162,7 @@
      */
     virtual status_t createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
-            android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
+            android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
             const String8& physicalCameraId,
             std::vector<int> *surfaceIds = nullptr,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -143,7 +177,7 @@
      */
     virtual status_t createStream(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
+            android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
             const String8& physicalCameraId,
             std::vector<int> *surfaceIds = nullptr,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -225,7 +259,8 @@
      * - INVALID_OPERATION if the device was in the wrong state
      */
     virtual status_t configureStreams(const CameraMetadata& sessionParams,
-            int operatingMode = 0) = 0;
+            int operatingMode =
+            camera_stream_configuration_mode_t::CAMERA_STREAM_CONFIGURATION_NORMAL_MODE) = 0;
 
     /**
      * Retrieve a list of all stream ids that were advertised as capable of
@@ -241,7 +276,7 @@
      * Create a metadata buffer with fields that the HAL device believes are
      * best for the given use case
      */
-    virtual status_t createDefaultRequest(int templateId,
+    virtual status_t createDefaultRequest(camera_request_template_t templateId,
             CameraMetadata *request) = 0;
 
     /**
diff --git a/services/camera/libcameraservice/device3/BufferUtils.cpp b/services/camera/libcameraservice/device3/BufferUtils.cpp
index cc29390..f3adf20 100644
--- a/services/camera/libcameraservice/device3/BufferUtils.cpp
+++ b/services/camera/libcameraservice/device3/BufferUtils.cpp
@@ -28,14 +28,14 @@
 namespace android {
 namespace camera3 {
 
-camera3_buffer_status_t mapHidlBufferStatus(hardware::camera::device::V3_2::BufferStatus status) {
+camera_buffer_status_t mapHidlBufferStatus(hardware::camera::device::V3_2::BufferStatus status) {
     using hardware::camera::device::V3_2::BufferStatus;
 
     switch (status) {
-        case BufferStatus::OK: return CAMERA3_BUFFER_STATUS_OK;
-        case BufferStatus::ERROR: return CAMERA3_BUFFER_STATUS_ERROR;
+        case BufferStatus::OK: return CAMERA_BUFFER_STATUS_OK;
+        case BufferStatus::ERROR: return CAMERA_BUFFER_STATUS_ERROR;
     }
-    return CAMERA3_BUFFER_STATUS_ERROR;
+    return CAMERA_BUFFER_STATUS_ERROR;
 }
 
 void BufferRecords::takeInflightBufferMap(BufferRecords& other) {
diff --git a/services/camera/libcameraservice/device3/BufferUtils.h b/services/camera/libcameraservice/device3/BufferUtils.h
index 452a908..1e1cd60 100644
--- a/services/camera/libcameraservice/device3/BufferUtils.h
+++ b/services/camera/libcameraservice/device3/BufferUtils.h
@@ -25,9 +25,6 @@
 
 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
 
-// TODO: remove legacy camera3.h references
-#include "hardware/camera3.h"
-
 #include <device3/Camera3OutputInterface.h>
 
 namespace android {
@@ -158,7 +155,7 @@
 
     static const uint64_t BUFFER_ID_NO_BUFFER = 0;
 
-    camera3_buffer_status_t mapHidlBufferStatus(
+    camera_buffer_status_t mapHidlBufferStatus(
             hardware::camera::device::V3_2::BufferStatus status);
 } // namespace camera3
 
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 8754ad3..92c8e30 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -547,15 +547,15 @@
     return usage;
 }
 
-StreamRotation Camera3Device::mapToStreamRotation(camera3_stream_rotation_t rotation) {
+StreamRotation Camera3Device::mapToStreamRotation(camera_stream_rotation_t rotation) {
     switch (rotation) {
-        case CAMERA3_STREAM_ROTATION_0:
+        case CAMERA_STREAM_ROTATION_0:
             return StreamRotation::ROTATION_0;
-        case CAMERA3_STREAM_ROTATION_90:
+        case CAMERA_STREAM_ROTATION_90:
             return StreamRotation::ROTATION_90;
-        case CAMERA3_STREAM_ROTATION_180:
+        case CAMERA_STREAM_ROTATION_180:
             return StreamRotation::ROTATION_180;
-        case CAMERA3_STREAM_ROTATION_270:
+        case CAMERA_STREAM_ROTATION_270:
             return StreamRotation::ROTATION_270;
     }
     ALOGE("%s: Unknown stream rotation %d", __FUNCTION__, rotation);
@@ -563,14 +563,14 @@
 }
 
 status_t Camera3Device::mapToStreamConfigurationMode(
-        camera3_stream_configuration_mode_t operationMode, StreamConfigurationMode *mode) {
+        camera_stream_configuration_mode_t operationMode, StreamConfigurationMode *mode) {
     if (mode == nullptr) return BAD_VALUE;
-    if (operationMode < CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START) {
+    if (operationMode < CAMERA_VENDOR_STREAM_CONFIGURATION_MODE_START) {
         switch(operationMode) {
-            case CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE:
+            case CAMERA_STREAM_CONFIGURATION_NORMAL_MODE:
                 *mode = StreamConfigurationMode::NORMAL_MODE;
                 break;
-            case CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
+            case CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
                 *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
                 break;
             default:
@@ -779,7 +779,7 @@
     }
 
     if (dumpTemplates) {
-        const char *templateNames[CAMERA3_TEMPLATE_COUNT] = {
+        const char *templateNames[CAMERA_TEMPLATE_COUNT] = {
             "TEMPLATE_PREVIEW",
             "TEMPLATE_STILL_CAPTURE",
             "TEMPLATE_VIDEO_RECORD",
@@ -788,10 +788,10 @@
             "TEMPLATE_MANUAL",
         };
 
-        for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; i++) {
+        for (int i = 1; i < CAMERA_TEMPLATE_COUNT; i++) {
             camera_metadata_t *templateRequest = nullptr;
             mInterface->constructDefaultRequestSettings(
-                    (camera3_request_template_t) i, &templateRequest);
+                    (camera_request_template_t) i, &templateRequest);
             lines = String8::format("    HAL Request %s:\n", templateNames[i-1]);
             if (templateRequest == nullptr) {
                 lines.append("       Not supported\n");
@@ -1203,7 +1203,7 @@
         // This point should only be reached via API1 (API2 must explicitly call configureStreams)
         // so unilaterally select normal operating mode.
         res = filterParamsAndConfigureLocked(request.begin()->metadata,
-                CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
+                CAMERA_STREAM_CONFIGURATION_NORMAL_MODE);
         // Stream configuration failed. Client might try other configuraitons.
         if (res != OK) {
             CLOGE("Can't set up streams: %s (%d)", strerror(-res), res);
@@ -1322,7 +1322,7 @@
 
 status_t Camera3Device::createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
-            android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
+            android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
             const String8& physicalCameraId,
             std::vector<int> *surfaceIds, int streamSetId, bool isShared, uint64_t consumerUsage) {
     ATRACE_CALL();
@@ -1342,7 +1342,7 @@
 
 status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
         bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-        android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
+        android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
         const String8& physicalCameraId,
         std::vector<int> *surfaceIds, int streamSetId, bool isShared, uint64_t consumerUsage) {
     ATRACE_CALL();
@@ -1621,7 +1621,7 @@
     // speculative configuration using the values from the last cached
     // default request.
     if (sessionParams.isEmpty() &&
-            ((mLastTemplateId > 0) && (mLastTemplateId < CAMERA3_TEMPLATE_COUNT)) &&
+            ((mLastTemplateId > 0) && (mLastTemplateId < CAMERA_TEMPLATE_COUNT)) &&
             (!mRequestTemplateCache[mLastTemplateId].isEmpty())) {
         ALOGV("%s: Speculative session param configuration with template id: %d", __func__,
                 mLastTemplateId);
@@ -1671,12 +1671,12 @@
     return mInputStream->getInputBufferProducer(producer);
 }
 
-status_t Camera3Device::createDefaultRequest(int templateId,
+status_t Camera3Device::createDefaultRequest(camera_request_template_t templateId,
         CameraMetadata *request) {
     ATRACE_CALL();
     ALOGV("%s: for template %d", __FUNCTION__, templateId);
 
-    if (templateId <= 0 || templateId >= CAMERA3_TEMPLATE_COUNT) {
+    if (templateId <= 0 || templateId >= CAMERA_TEMPLATE_COUNT) {
         android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26866110",
                 CameraThreadState::getCallingUid(), nullptr, 0);
         return BAD_VALUE;
@@ -1712,7 +1712,7 @@
 
     camera_metadata_t *rawRequest;
     status_t res = mInterface->constructDefaultRequestSettings(
-            (camera3_request_template_t) templateId, &rawRequest);
+            (camera_request_template_t) templateId, &rawRequest);
 
     {
         Mutex::Autolock l(mLock);
@@ -2521,7 +2521,7 @@
     // any pending requests.
     if (mInputStream != NULL && notifyRequestThread) {
         while (true) {
-            camera3_stream_buffer_t inputBuffer;
+            camera_stream_buffer_t inputBuffer;
             status_t res = mInputStream->getInputBuffer(&inputBuffer,
                     /*respectHalLimit*/ false);
             if (res != OK) {
@@ -2529,7 +2529,7 @@
                 break;
             }
 
-            inputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+            inputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
             res = mInputStream->returnInputBuffer(inputBuffer);
             if (res != OK) {
                 ALOGE("%s: %d: couldn't return input buffer while clearing input queue: "
@@ -2557,17 +2557,17 @@
 
     mPreparerThread->pause();
 
-    camera3_stream_configuration config;
+    camera_stream_configuration config;
     config.operation_mode = mOperatingMode;
     config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
 
-    Vector<camera3_stream_t*> streams;
+    Vector<camera3::camera_stream_t*> streams;
     streams.setCapacity(config.num_streams);
     std::vector<uint32_t> bufferSizes(config.num_streams, 0);
 
 
     if (mInputStream != NULL) {
-        camera3_stream_t *inputStream;
+        camera3::camera_stream_t *inputStream;
         inputStream = mInputStream->startConfiguration();
         if (inputStream == NULL) {
             CLOGE("Can't start input stream configuration");
@@ -2587,7 +2587,7 @@
             continue;
         }
 
-        camera3_stream_t *outputStream;
+        camera3::camera_stream_t *outputStream;
         outputStream = mOutputStreams[i]->startConfiguration();
         if (outputStream == NULL) {
             CLOGE("Can't start output stream configuration");
@@ -3013,7 +3013,7 @@
 }
 
 status_t Camera3Device::HalInterface::constructDefaultRequestSettings(
-        camera3_request_template_t templateId,
+        camera_request_template_t templateId,
         /*out*/ camera_metadata_t **requestTemplate) {
     ATRACE_NAME("CameraHal::constructDefaultRequestSettings");
     if (!valid()) return INVALID_OPERATION;
@@ -3045,22 +3045,22 @@
     hardware::Return<void> err;
     RequestTemplate id;
     switch (templateId) {
-        case CAMERA3_TEMPLATE_PREVIEW:
+        case CAMERA_TEMPLATE_PREVIEW:
             id = RequestTemplate::PREVIEW;
             break;
-        case CAMERA3_TEMPLATE_STILL_CAPTURE:
+        case CAMERA_TEMPLATE_STILL_CAPTURE:
             id = RequestTemplate::STILL_CAPTURE;
             break;
-        case CAMERA3_TEMPLATE_VIDEO_RECORD:
+        case CAMERA_TEMPLATE_VIDEO_RECORD:
             id = RequestTemplate::VIDEO_RECORD;
             break;
-        case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
+        case CAMERA_TEMPLATE_VIDEO_SNAPSHOT:
             id = RequestTemplate::VIDEO_SNAPSHOT;
             break;
-        case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
+        case CAMERA_TEMPLATE_ZERO_SHUTTER_LAG:
             id = RequestTemplate::ZERO_SHUTTER_LAG;
             break;
-        case CAMERA3_TEMPLATE_MANUAL:
+        case CAMERA_TEMPLATE_MANUAL:
             id = RequestTemplate::MANUAL;
             break;
         default:
@@ -3126,7 +3126,7 @@
 }
 
 status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t *sessionParams,
-        camera3_stream_configuration *config, const std::vector<uint32_t>& bufferSizes) {
+        camera_stream_configuration *config, const std::vector<uint32_t>& bufferSizes) {
     ATRACE_NAME("CameraHal::configureStreams");
     if (!valid()) return INVALID_OPERATION;
     status_t res = OK;
@@ -3140,17 +3140,17 @@
     for (size_t i = 0; i < config->num_streams; i++) {
         device::V3_2::Stream &dst3_2 = requestedConfiguration3_2.streams[i];
         device::V3_4::Stream &dst3_4 = requestedConfiguration3_4.streams[i];
-        camera3_stream_t *src = config->streams[i];
+        camera3::camera_stream_t *src = config->streams[i];
 
         Camera3Stream* cam3stream = Camera3Stream::cast(src);
         cam3stream->setBufferFreedListener(this);
         int streamId = cam3stream->getId();
         StreamType streamType;
         switch (src->stream_type) {
-            case CAMERA3_STREAM_OUTPUT:
+            case CAMERA_STREAM_OUTPUT:
                 streamType = StreamType::OUTPUT;
                 break;
-            case CAMERA3_STREAM_INPUT:
+            case CAMERA_STREAM_INPUT:
                 streamType = StreamType::INPUT;
                 break;
             default:
@@ -3163,7 +3163,7 @@
         dst3_2.width = src->width;
         dst3_2.height = src->height;
         dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
-        dst3_2.rotation = mapToStreamRotation((camera3_stream_rotation_t) src->rotation);
+        dst3_2.rotation = mapToStreamRotation((camera_stream_rotation_t) src->rotation);
         // For HidlSession version 3.5 or newer, the format and dataSpace sent
         // to HAL are original, not the overriden ones.
         if (mHidlSession_3_5 != nullptr) {
@@ -3190,7 +3190,7 @@
 
     StreamConfigurationMode operationMode;
     res = mapToStreamConfigurationMode(
-            (camera3_stream_configuration_mode_t) config->operation_mode,
+            (camera_stream_configuration_mode_t) config->operation_mode,
             /*out*/ &operationMode);
     if (res != OK) {
         return res;
@@ -3319,7 +3319,7 @@
     // And convert output stream configuration from HIDL
 
     for (size_t i = 0; i < config->num_streams; i++) {
-        camera3_stream_t *dst = config->streams[i];
+        camera3::camera_stream_t *dst = config->streams[i];
         int streamId = Camera3Stream::cast(dst)->getId();
 
         // Start scan at i, with the assumption that the stream order matches
@@ -3372,7 +3372,7 @@
             dst->data_space = overrideDataSpace;
         }
 
-        if (dst->stream_type == CAMERA3_STREAM_INPUT) {
+        if (dst->stream_type == CAMERA_STREAM_INPUT) {
             if (src.v3_2.producerUsage != 0) {
                 ALOGE("%s: Stream %d: INPUT streams must have 0 for producer usage",
                         __FUNCTION__, streamId);
@@ -3396,7 +3396,7 @@
     return res;
 }
 
-status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera3_capture_request_t* request,
+status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera_capture_request_t* request,
         /*out*/device::V3_2::CaptureRequest* captureRequest,
         /*out*/std::vector<native_handle_t*>* handlesCreated,
         /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
@@ -3441,7 +3441,7 @@
 
         captureRequest->outputBuffers.resize(request->num_output_buffers);
         for (size_t i = 0; i < request->num_output_buffers; i++) {
-            const camera3_stream_buffer_t *src = request->output_buffers + i;
+            const camera_stream_buffer_t *src = request->output_buffers + i;
             StreamBuffer &dst = captureRequest->outputBuffers[i];
             int32_t streamId = Camera3Stream::cast(src->stream)->getId();
             if (src->buffer != nullptr) {
@@ -3499,7 +3499,7 @@
 }
 
 status_t Camera3Device::HalInterface::processBatchCaptureRequests(
-        std::vector<camera3_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
+        std::vector<camera_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
     ATRACE_NAME("CameraHal::processBatchCaptureRequests");
     if (!valid()) return INVALID_OPERATION;
 
@@ -3553,7 +3553,7 @@
 
     // Write metadata to FMQ.
     for (size_t i = 0; i < batchSize; i++) {
-        camera3_capture_request_t* request = requests[i];
+        camera_capture_request_t* request = requests[i];
         device::V3_2::CaptureRequest* captureRequest;
         if (hidlSession_3_4 != nullptr) {
             captureRequest = &captureRequests_3_4[i].v3_2;
@@ -4025,14 +4025,14 @@
                  it != mRequestQueue.end(); ++it) {
             // Abort the input buffers for reprocess requests.
             if ((*it)->mInputStream != NULL) {
-                camera3_stream_buffer_t inputBuffer;
+                camera_stream_buffer_t inputBuffer;
                 status_t res = (*it)->mInputStream->getInputBuffer(&inputBuffer,
                         /*respectHalLimit*/ false);
                 if (res != OK) {
                     ALOGW("%s: %d: couldn't get input buffer while clearing the request "
                             "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
                 } else {
-                    inputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+                    inputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
                     res = (*it)->mInputStream->returnInputBuffer(inputBuffer);
                     if (res != OK) {
                         ALOGE("%s: %d: couldn't return input buffer while clearing the request "
@@ -4136,7 +4136,7 @@
     ATRACE_CALL();
     status_t res;
     size_t batchSize = mNextRequests.size();
-    std::vector<camera3_capture_request_t*> requests(batchSize);
+    std::vector<camera_capture_request_t*> requests(batchSize);
     uint32_t numRequestProcessed = 0;
     for (size_t i = 0; i < batchSize; i++) {
         requests[i] = &mNextRequests.editItemAt(i).halRequest;
@@ -4455,8 +4455,8 @@
     for (size_t i = 0; i < mNextRequests.size(); i++) {
         auto& nextRequest = mNextRequests.editItemAt(i);
         sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
-        camera3_capture_request_t* halRequest = &nextRequest.halRequest;
-        Vector<camera3_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
+        camera_capture_request_t* halRequest = &nextRequest.halRequest;
+        Vector<camera_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
 
         // Prepare a request to HAL
         halRequest->frame_number = captureRequest->mResultExtras.frameNumber;
@@ -4624,7 +4624,7 @@
             halRequest->input_buffer = NULL;
         }
 
-        outputBuffers->insertAt(camera3_stream_buffer_t(), 0,
+        outputBuffers->insertAt(camera_stream_buffer_t(), 0,
                 captureRequest->mOutputStreams.size());
         halRequest->output_buffers = outputBuffers->array();
         std::set<String8> requestedPhysicalCameras;
@@ -4680,10 +4680,10 @@
                     return TIMED_OUT;
                 }
                 // HAL will request buffer through requestStreamBuffer API
-                camera3_stream_buffer_t& buffer = outputBuffers->editItemAt(j);
+                camera_stream_buffer_t& buffer = outputBuffers->editItemAt(j);
                 buffer.stream = outputStream->asHalStream();
                 buffer.buffer = nullptr;
-                buffer.status = CAMERA3_BUFFER_STATUS_OK;
+                buffer.status = CAMERA_BUFFER_STATUS_OK;
                 buffer.acquire_fence = -1;
                 buffer.release_fence = -1;
             } else {
@@ -4936,7 +4936,7 @@
 }
 
 void Camera3Device::RequestThread::cleanupPhysicalSettings(sp<CaptureRequest> request,
-        camera3_capture_request_t *halRequest) {
+        camera_capture_request_t *halRequest) {
     if ((request == nullptr) || (halRequest == nullptr)) {
         ALOGE("%s: Invalid request!", __FUNCTION__);
         return;
@@ -4971,8 +4971,8 @@
         }
 
         sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
-        camera3_capture_request_t* halRequest = &nextRequest.halRequest;
-        Vector<camera3_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
+        camera_capture_request_t* halRequest = &nextRequest.halRequest;
+        Vector<camera_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
 
         if (halRequest->settings != NULL) {
             captureRequest->mSettingsList.begin()->metadata.unlock(halRequest->settings);
@@ -4981,7 +4981,7 @@
         cleanupPhysicalSettings(captureRequest, halRequest);
 
         if (captureRequest->mInputStream != NULL) {
-            captureRequest->mInputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+            captureRequest->mInputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
             captureRequest->mInputStream->returnInputBuffer(captureRequest->mInputBuffer);
         }
 
@@ -4995,7 +4995,7 @@
                     close(acquireFence);
                     outputBuffers->editItemAt(i).acquire_fence = -1;
                 }
-                outputBuffers->editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
+                outputBuffers->editItemAt(i).status = CAMERA_BUFFER_STATUS_ERROR;
                 captureRequest->mOutputStreams.editItemAt(i)->returnBuffer((*outputBuffers)[i], 0,
                         /*timestampIncreasing*/true, std::vector<size_t> (),
                         captureRequest->mResultExtras.frameNumber);
@@ -5045,7 +5045,7 @@
         return;
     }
 
-    nextRequest.halRequest = camera3_capture_request_t();
+    nextRequest.halRequest = camera_capture_request_t();
     nextRequest.submitted = false;
     mNextRequests.add(nextRequest);
 
@@ -5059,7 +5059,7 @@
             break;
         }
 
-        additionalRequest.halRequest = camera3_capture_request_t();
+        additionalRequest.halRequest = camera_capture_request_t();
         additionalRequest.submitted = false;
         mNextRequests.add(additionalRequest);
     }
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index de7df81..b06ce45 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -56,6 +56,13 @@
 #include "utils/LatencyHistogram.h"
 #include <camera_metadata_hidden.h>
 
+using android::camera3::camera_capture_request_t;
+using android::camera3::camera_jpeg_blob_t;
+using android::camera3::camera_request_template;
+using android::camera3::camera_stream_buffer_t;
+using android::camera3::camera_stream_configuration_t;
+using android::camera3::camera_stream_configuration_mode_t;
+using android::camera3::CAMERA_TEMPLATE_COUNT;
 using android::camera3::OutputStreamInfo;
 
 namespace android {
@@ -122,14 +129,14 @@
     // and finish the stream configuration before starting output streaming.
     status_t createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
-            android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
+            android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
             const String8& physicalCameraId,
             std::vector<int> *surfaceIds = nullptr,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
             bool isShared = false, uint64_t consumerUsage = 0) override;
     status_t createStream(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
-            android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
+            android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
             const String8& physicalCameraId,
             std::vector<int> *surfaceIds = nullptr,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
@@ -146,14 +153,14 @@
 
     status_t configureStreams(const CameraMetadata& sessionParams,
             int operatingMode =
-            static_cast<int>(hardware::camera::device::V3_2::StreamConfigurationMode::NORMAL_MODE))
-            override;
+            camera_stream_configuration_mode_t::CAMERA_STREAM_CONFIGURATION_NORMAL_MODE) override;
     status_t getInputBufferProducer(
             sp<IGraphicBufferProducer> *producer) override;
 
     void getOfflineStreamIds(std::vector<int> *offlineStreamIds) override;
 
-    status_t createDefaultRequest(int templateId, CameraMetadata *request) override;
+    status_t createDefaultRequest(camera_request_template_t templateId,
+            CameraMetadata *request) override;
 
     // Transitions to the idle state on success
     status_t waitUntilDrained() override;
@@ -242,9 +249,9 @@
             android_dataspace dataSpace);
     static hardware::camera::device::V3_2::BufferUsageFlags mapToConsumerUsage(uint64_t usage);
     static hardware::camera::device::V3_2::StreamRotation mapToStreamRotation(
-            camera3_stream_rotation_t rotation);
+            camera_stream_rotation_t rotation);
     // Returns a negative error code if the passed-in operation mode is not valid.
-    static status_t mapToStreamConfigurationMode(camera3_stream_configuration_mode_t operationMode,
+    static status_t mapToStreamConfigurationMode(camera_stream_configuration_mode_t operationMode,
             /*out*/ hardware::camera::device::V3_2::StreamConfigurationMode *mode);
     static int mapToFrameworkFormat(hardware::graphics::common::V1_0::PixelFormat pixelFormat);
     static android_dataspace mapToFrameworkDataspace(
@@ -255,7 +262,6 @@
             hardware::camera::device::V3_2::BufferUsageFlags usage);
 
   private:
-
     status_t disconnectImpl();
 
     // internal typedefs
@@ -275,7 +281,7 @@
 
     struct                     RequestTrigger;
     // minimal jpeg buffer size: 256KB + blob header
-    static const ssize_t       kMinJpegBufferSize = 256 * 1024 + sizeof(camera3_jpeg_blob);
+    static const ssize_t       kMinJpegBufferSize = 256 * 1024 + sizeof(camera_jpeg_blob_t);
     // Constant to use for stream ID when one doesn't exist
     static const int           NO_STREAM = -1;
 
@@ -330,10 +336,10 @@
         // Calls into the HAL interface
 
         // Caller takes ownership of requestTemplate
-        status_t constructDefaultRequestSettings(camera3_request_template_t templateId,
+        status_t constructDefaultRequestSettings(camera_request_template templateId,
                 /*out*/ camera_metadata_t **requestTemplate);
         status_t configureStreams(const camera_metadata_t *sessionParams,
-                /*inout*/ camera3_stream_configuration *config,
+                /*inout*/ camera_stream_configuration_t *config,
                 const std::vector<uint32_t>& bufferSizes);
 
         // When the call succeeds, the ownership of acquire fences in requests is transferred to
@@ -341,7 +347,7 @@
         // HAL process and close the FD in cameraserver process. When the call fails, the ownership
         // of the acquire fence still belongs to the caller.
         status_t processBatchCaptureRequests(
-                std::vector<camera3_capture_request_t*>& requests,
+                std::vector<camera_capture_request_t*>& requests,
                 /*out*/uint32_t* numRequestProcessed);
         status_t flush();
         status_t dump(int fd);
@@ -400,9 +406,9 @@
 
         std::shared_ptr<RequestMetadataQueue> mRequestMetadataQueue;
 
-        // The output HIDL request still depends on input camera3_capture_request_t
-        // Do not free input camera3_capture_request_t before output HIDL request
-        status_t wrapAsHidlRequest(camera3_capture_request_t* in,
+        // The output HIDL request still depends on input camera_capture_request_t
+        // Do not free input camera_capture_request_t before output HIDL request
+        status_t wrapAsHidlRequest(camera_capture_request_t* in,
                 /*out*/hardware::camera::device::V3_2::CaptureRequest* out,
                 /*out*/std::vector<native_handle_t*>* handlesCreated,
                 /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers);
@@ -442,7 +448,7 @@
     bool                       mSupportNativeZoomRatio;
     std::unordered_map<std::string, CameraMetadata> mPhysicalDeviceInfoMap;
 
-    CameraMetadata             mRequestTemplateCache[CAMERA3_TEMPLATE_COUNT];
+    CameraMetadata             mRequestTemplateCache[CAMERA_TEMPLATE_COUNT];
 
     struct Size {
         uint32_t width;
@@ -503,7 +509,7 @@
       public:
         PhysicalCameraSettingsList          mSettingsList;
         sp<camera3::Camera3Stream>          mInputStream;
-        camera3_stream_buffer_t             mInputBuffer;
+        camera_stream_buffer_t              mInputBuffer;
         Vector<sp<camera3::Camera3OutputStreamInterface> >
                                             mOutputStreams;
         SurfaceMap                          mOutputSurfaces;
@@ -891,8 +897,8 @@
         // Used to prepare a batch of requests.
         struct NextRequest {
             sp<CaptureRequest>              captureRequest;
-            camera3_capture_request_t       halRequest;
-            Vector<camera3_stream_buffer_t> outputBuffers;
+            camera_capture_request_t       halRequest;
+            Vector<camera_stream_buffer_t> outputBuffers;
             bool                            submitted;
         };
 
@@ -918,7 +924,7 @@
 
         // Release physical camera settings and camera id resources.
         void cleanupPhysicalSettings(sp<CaptureRequest> request,
-                /*out*/camera3_capture_request_t *halRequest);
+                /*out*/camera_capture_request_t *halRequest);
 
         // Pause handling
         bool               waitIfPaused();
diff --git a/services/camera/libcameraservice/device3/Camera3FakeStream.cpp b/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
index 230512a..ab5084e 100644
--- a/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
@@ -29,7 +29,7 @@
 const String8 Camera3FakeStream::FAKE_ID;
 
 Camera3FakeStream::Camera3FakeStream(int id) :
-        Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, FAKE_WIDTH, FAKE_HEIGHT,
+        Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, FAKE_WIDTH, FAKE_HEIGHT,
                 /*maxSize*/0, FAKE_FORMAT, FAKE_DATASPACE, FAKE_ROTATION,
                 FAKE_ID) {
 
@@ -39,7 +39,7 @@
 
 }
 
-status_t Camera3FakeStream::getBufferLocked(camera3_stream_buffer *,
+status_t Camera3FakeStream::getBufferLocked(camera_stream_buffer *,
         const std::vector<size_t>&) {
     ATRACE_CALL();
     ALOGE("%s: Stream %d: Fake stream cannot produce buffers!", __FUNCTION__, mId);
@@ -47,7 +47,7 @@
 }
 
 status_t Camera3FakeStream::returnBufferLocked(
-        const camera3_stream_buffer &,
+        const camera_stream_buffer &,
         nsecs_t, const std::vector<size_t>&) {
     ATRACE_CALL();
     ALOGE("%s: Stream %d: Fake stream cannot return buffers!", __FUNCTION__, mId);
@@ -55,7 +55,7 @@
 }
 
 status_t Camera3FakeStream::returnBufferCheckedLocked(
-            const camera3_stream_buffer &,
+            const camera_stream_buffer &,
             nsecs_t,
             bool,
             const std::vector<size_t>&,
diff --git a/services/camera/libcameraservice/device3/Camera3FakeStream.h b/services/camera/libcameraservice/device3/Camera3FakeStream.h
index fbf37e6..4a99079 100644
--- a/services/camera/libcameraservice/device3/Camera3FakeStream.h
+++ b/services/camera/libcameraservice/device3/Camera3FakeStream.h
@@ -104,7 +104,7 @@
      * Note that we release the lock briefly in this function
      */
     virtual status_t returnBufferCheckedLocked(
-            const camera3_stream_buffer &buffer,
+            const camera_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
             const std::vector<size_t>& surface_ids,
@@ -121,17 +121,17 @@
     static const int FAKE_HEIGHT = 240;
     static const int FAKE_FORMAT = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
     static const android_dataspace FAKE_DATASPACE = HAL_DATASPACE_UNKNOWN;
-    static const camera3_stream_rotation_t FAKE_ROTATION = CAMERA3_STREAM_ROTATION_0;
+    static const camera_stream_rotation_t FAKE_ROTATION = CAMERA_STREAM_ROTATION_0;
     static const uint64_t FAKE_USAGE = GRALLOC_USAGE_HW_COMPOSER;
     static const String8 FAKE_ID;
 
     /**
      * Internal Camera3Stream interface
      */
-    virtual status_t getBufferLocked(camera3_stream_buffer *buffer,
+    virtual status_t getBufferLocked(camera_stream_buffer *buffer,
             const std::vector<size_t>& surface_ids = std::vector<size_t>());
     virtual status_t returnBufferLocked(
-            const camera3_stream_buffer &buffer,
+            const camera_stream_buffer &buffer,
             nsecs_t timestamp, const std::vector<size_t>& surface_ids);
 
     virtual status_t configureQueueLocked();
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index bda2961..f6acda8 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -29,9 +29,9 @@
 
 namespace camera3 {
 
-Camera3IOStreamBase::Camera3IOStreamBase(int id, camera3_stream_type_t type,
+Camera3IOStreamBase::Camera3IOStreamBase(int id, camera_stream_type_t type,
         uint32_t width, uint32_t height, size_t maxSize, int format,
-        android_dataspace dataSpace, camera3_stream_rotation_t rotation,
+        android_dataspace dataSpace, camera_stream_rotation_t rotation,
         const String8& physicalCameraId, int setId) :
         Camera3Stream(id, type,
                 width, height, maxSize, format, dataSpace, rotation,
@@ -77,13 +77,13 @@
 
     lines.appendFormat("      State: %d\n", mState);
     lines.appendFormat("      Dims: %d x %d, format 0x%x, dataspace 0x%x\n",
-            camera3_stream::width, camera3_stream::height,
-            camera3_stream::format, camera3_stream::data_space);
+            camera_stream::width, camera_stream::height,
+            camera_stream::format, camera_stream::data_space);
     lines.appendFormat("      Max size: %zu\n", mMaxSize);
     lines.appendFormat("      Combined usage: %" PRIu64 ", max HAL buffers: %d\n",
-            mUsage | consumerUsage, camera3_stream::max_buffers);
-    if (strlen(camera3_stream::physical_camera_id) > 0) {
-        lines.appendFormat("      Physical camera id: %s\n", camera3_stream::physical_camera_id);
+            mUsage | consumerUsage, camera_stream::max_buffers);
+    if (strlen(camera_stream::physical_camera_id) > 0) {
+        lines.appendFormat("      Physical camera id: %s\n", camera_stream::physical_camera_id);
     }
     lines.appendFormat("      Frames produced: %d, last timestamp: %" PRId64 " ns\n",
             mFrameCount, mLastTimestamp);
@@ -150,11 +150,11 @@
    return OK;
 }
 
-void Camera3IOStreamBase::handoutBufferLocked(camera3_stream_buffer &buffer,
+void Camera3IOStreamBase::handoutBufferLocked(camera_stream_buffer &buffer,
                                               buffer_handle_t *handle,
                                               int acquireFence,
                                               int releaseFence,
-                                              camera3_buffer_status_t status,
+                                              camera_buffer_status_t status,
                                               bool output) {
     /**
      * Note that all fences are now owned by HAL.
@@ -220,7 +220,7 @@
 }
 
 status_t Camera3IOStreamBase::returnAnyBufferLocked(
-        const camera3_stream_buffer &buffer,
+        const camera_stream_buffer &buffer,
         nsecs_t timestamp,
         bool output,
         const std::vector<size_t>& surface_ids) {
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index ca62239..719fa14 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -32,9 +32,9 @@
 class Camera3IOStreamBase :
         public Camera3Stream {
   protected:
-    Camera3IOStreamBase(int id, camera3_stream_type_t type,
+    Camera3IOStreamBase(int id, camera_stream_type_t type,
             uint32_t width, uint32_t height, size_t maxSize, int format,
-            android_dataspace dataSpace, camera3_stream_rotation_t rotation,
+            android_dataspace dataSpace, camera_stream_rotation_t rotation,
             const String8& physicalCameraId,
             int setId = CAMERA3_STREAM_SET_ID_INVALID);
 
@@ -64,13 +64,13 @@
     sp<Fence>         mCombinedFence;
 
     status_t         returnAnyBufferLocked(
-            const camera3_stream_buffer &buffer,
+            const camera_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
             const std::vector<size_t>& surface_ids = std::vector<size_t>());
 
     virtual status_t returnBufferCheckedLocked(
-            const camera3_stream_buffer &buffer,
+            const camera_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
             const std::vector<size_t>& surface_ids,
@@ -100,11 +100,11 @@
 
     // Hand out the buffer to a native location,
     //   incrementing the internal refcount and dequeued buffer count
-    void handoutBufferLocked(camera3_stream_buffer &buffer,
+    void handoutBufferLocked(camera_stream_buffer &buffer,
                              buffer_handle_t *handle,
                              int acquire_fence,
                              int release_fence,
-                             camera3_buffer_status_t status,
+                             camera_buffer_status_t status,
                              bool output);
 
 }; // class Camera3IOStreamBase
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
index ebd33e9..ad70a3a 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
@@ -31,8 +31,8 @@
 
 Camera3InputStream::Camera3InputStream(int id,
         uint32_t width, uint32_t height, int format) :
-        Camera3IOStreamBase(id, CAMERA3_STREAM_INPUT, width, height, /*maxSize*/0,
-                            format, HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0,
+        Camera3IOStreamBase(id, CAMERA_STREAM_INPUT, width, height, /*maxSize*/0,
+                            format, HAL_DATASPACE_UNKNOWN, CAMERA_STREAM_ROTATION_0,
                             FAKE_ID) {
 
     if (format == HAL_PIXEL_FORMAT_BLOB) {
@@ -46,7 +46,7 @@
 }
 
 status_t Camera3InputStream::getInputBufferLocked(
-        camera3_stream_buffer *buffer) {
+        camera_stream_buffer *buffer) {
     ATRACE_CALL();
     status_t res;
 
@@ -86,7 +86,7 @@
      * in which case we reassign it to acquire_fence
      */
     handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
-                        /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/false);
+                        /*releaseFence*/-1, CAMERA_BUFFER_STATUS_OK, /*output*/false);
     mBuffersInFlight.push_back(bufferItem);
 
     mFrameCount++;
@@ -96,7 +96,7 @@
 }
 
 status_t Camera3InputStream::returnBufferCheckedLocked(
-            const camera3_stream_buffer &buffer,
+            const camera_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
             const std::vector<size_t>&,
@@ -134,7 +134,7 @@
         return INVALID_OPERATION;
     }
 
-    if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
+    if (buffer.status == CAMERA_BUFFER_STATUS_ERROR) {
         if (buffer.release_fence != -1) {
             ALOGE("%s: Stream %d: HAL should not set release_fence(%d) when "
                   "there is an error", __FUNCTION__, mId, buffer.release_fence);
@@ -144,7 +144,7 @@
         /**
          * Reassign release fence as the acquire fence incase of error
          */
-        const_cast<camera3_stream_buffer*>(&buffer)->release_fence =
+        const_cast<camera_stream_buffer*>(&buffer)->release_fence =
                 buffer.acquire_fence;
     }
 
@@ -165,7 +165,7 @@
 }
 
 status_t Camera3InputStream::returnInputBufferLocked(
-        const camera3_stream_buffer &buffer) {
+        const camera_stream_buffer &buffer) {
     ATRACE_CALL();
 
     return returnAnyBufferLocked(buffer, /*timestamp*/0, /*output*/false);
@@ -224,7 +224,7 @@
     }
 
     assert(mMaxSize == 0);
-    assert(camera3_stream::format != HAL_PIXEL_FORMAT_BLOB);
+    assert(camera_stream::format != HAL_PIXEL_FORMAT_BLOB);
 
     mHandoutTotalBufferCount = 0;
     mFrameCount = 0;
@@ -244,14 +244,14 @@
         }
         size_t minBufs = static_cast<size_t>(minUndequeuedBuffers);
 
-        if (camera3_stream::max_buffers == 0) {
+        if (camera_stream::max_buffers == 0) {
             ALOGE("%s: %d: HAL sets max_buffer to 0. Must be at least 1.",
                     __FUNCTION__, __LINE__);
             return INVALID_OPERATION;
         }
 
         /*
-         * We promise never to 'acquire' more than camera3_stream::max_buffers
+         * We promise never to 'acquire' more than camera_stream::max_buffers
          * at any one time.
          *
          * Boost the number up to meet the minimum required buffer count.
@@ -259,8 +259,8 @@
          * (Note that this sets consumer-side buffer count only,
          * and not the sum of producer+consumer side as in other camera streams).
          */
-        mTotalBufferCount = camera3_stream::max_buffers > minBufs ?
-            camera3_stream::max_buffers : minBufs;
+        mTotalBufferCount = camera_stream::max_buffers > minBufs ?
+            camera_stream::max_buffers : minBufs;
         // TODO: somehow set the total buffer count when producer connects?
 
         mConsumer = new BufferItemConsumer(consumer, mUsage,
@@ -272,17 +272,17 @@
         mConsumer->setBufferFreedListener(this);
     }
 
-    res = mConsumer->setDefaultBufferSize(camera3_stream::width,
-                                          camera3_stream::height);
+    res = mConsumer->setDefaultBufferSize(camera_stream::width,
+                                          camera_stream::height);
     if (res != OK) {
         ALOGE("%s: Stream %d: Could not set buffer dimensions %dx%d",
-              __FUNCTION__, mId, camera3_stream::width, camera3_stream::height);
+              __FUNCTION__, mId, camera_stream::width, camera_stream::height);
         return res;
     }
-    res = mConsumer->setDefaultBufferFormat(camera3_stream::format);
+    res = mConsumer->setDefaultBufferFormat(camera_stream::format);
     if (res != OK) {
         ALOGE("%s: Stream %d: Could not set buffer format %d",
-              __FUNCTION__, mId, camera3_stream::format);
+              __FUNCTION__, mId, camera_stream::format);
         return res;
     }
 
@@ -298,8 +298,8 @@
 void Camera3InputStream::onBufferFreed(const wp<GraphicBuffer>& gb) {
     const sp<GraphicBuffer> buffer = gb.promote();
     if (buffer != nullptr) {
-        camera3_stream_buffer streamBuffer =
-                {nullptr, &buffer->handle, 0, -1, -1};
+        camera_stream_buffer streamBuffer =
+                {nullptr, &buffer->handle, CAMERA_BUFFER_STATUS_OK, -1, -1};
         // Check if this buffer is outstanding.
         if (isOutstandingBuffer(streamBuffer)) {
             ALOGV("%s: Stream %d: Trying to free a buffer that is still being "
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.h b/services/camera/libcameraservice/device3/Camera3InputStream.h
index 22697b7..03afa17 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.h
@@ -59,7 +59,7 @@
      * Camera3IOStreamBase
      */
     virtual status_t returnBufferCheckedLocked(
-            const camera3_stream_buffer &buffer,
+            const camera_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
             const std::vector<size_t>& surface_ids,
@@ -70,9 +70,9 @@
      * Camera3Stream interface
      */
 
-    virtual status_t getInputBufferLocked(camera3_stream_buffer *buffer);
+    virtual status_t getInputBufferLocked(camera_stream_buffer *buffer);
     virtual status_t returnInputBufferLocked(
-            const camera3_stream_buffer &buffer);
+            const camera_stream_buffer &buffer);
     virtual status_t getInputBufferProducerLocked(
             sp<IGraphicBufferProducer> *producer);
     virtual status_t disconnectLocked();
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 6dfc838..4b5889c 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -42,10 +42,10 @@
 Camera3OutputStream::Camera3OutputStream(int id,
         sp<Surface> consumer,
         uint32_t width, uint32_t height, int format,
-        android_dataspace dataSpace, camera3_stream_rotation_t rotation,
+        android_dataspace dataSpace, camera_stream_rotation_t rotation,
         nsecs_t timestampOffset, const String8& physicalCameraId,
         int setId) :
-        Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height,
+        Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
                             /*maxSize*/0, format, dataSpace, rotation,
                             physicalCameraId, setId),
         mConsumer(consumer),
@@ -69,9 +69,9 @@
 Camera3OutputStream::Camera3OutputStream(int id,
         sp<Surface> consumer,
         uint32_t width, uint32_t height, size_t maxSize, int format,
-        android_dataspace dataSpace, camera3_stream_rotation_t rotation,
+        android_dataspace dataSpace, camera_stream_rotation_t rotation,
         nsecs_t timestampOffset, const String8& physicalCameraId, int setId) :
-        Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize,
+        Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height, maxSize,
                             format, dataSpace, rotation, physicalCameraId, setId),
         mConsumer(consumer),
         mTransform(0),
@@ -101,9 +101,9 @@
 Camera3OutputStream::Camera3OutputStream(int id,
         uint32_t width, uint32_t height, int format,
         uint64_t consumerUsage, android_dataspace dataSpace,
-        camera3_stream_rotation_t rotation, nsecs_t timestampOffset,
+        camera_stream_rotation_t rotation, nsecs_t timestampOffset,
         const String8& physicalCameraId, int setId) :
-        Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height,
+        Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
                             /*maxSize*/0, format, dataSpace, rotation,
                             physicalCameraId, setId),
         mConsumer(nullptr),
@@ -134,11 +134,11 @@
     mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
 }
 
-Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type,
+Camera3OutputStream::Camera3OutputStream(int id, camera_stream_type_t type,
                                          uint32_t width, uint32_t height,
                                          int format,
                                          android_dataspace dataSpace,
-                                         camera3_stream_rotation_t rotation,
+                                         camera_stream_rotation_t rotation,
                                          const String8& physicalCameraId,
                                          uint64_t consumerUsage, nsecs_t timestampOffset,
                                          int setId) :
@@ -166,7 +166,7 @@
     disconnectLocked();
 }
 
-status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer,
+status_t Camera3OutputStream::getBufferLocked(camera_stream_buffer *buffer,
         const std::vector<size_t>&) {
     ATRACE_HFR_CALL();
 
@@ -184,7 +184,7 @@
      * in which case we reassign it to acquire_fence
      */
     handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
-                        /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true);
+                        /*releaseFence*/-1, CAMERA_BUFFER_STATUS_OK, /*output*/true);
 
     return OK;
 }
@@ -196,7 +196,7 @@
 }
 
 status_t Camera3OutputStream::returnBufferLocked(
-        const camera3_stream_buffer &buffer,
+        const camera_stream_buffer &buffer,
         nsecs_t timestamp, const std::vector<size_t>& surface_ids) {
     ATRACE_HFR_CALL();
 
@@ -213,7 +213,7 @@
 }
 
 status_t Camera3OutputStream::returnBufferCheckedLocked(
-            const camera3_stream_buffer &buffer,
+            const camera_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
             const std::vector<size_t>& surface_ids,
@@ -243,11 +243,11 @@
     /**
      * Return buffer back to ANativeWindow
      */
-    if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR || mDropBuffers || timestamp == 0) {
+    if (buffer.status == CAMERA_BUFFER_STATUS_ERROR || mDropBuffers || timestamp == 0) {
         // Cancel buffer
         if (mDropBuffers) {
             ALOGV("%s: Dropping a frame for stream %d.", __FUNCTION__, mId);
-        } else if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
+        } else if (buffer.status == CAMERA_BUFFER_STATUS_ERROR) {
             ALOGV("%s: A frame is dropped for stream %d due to buffer error.", __FUNCTION__, mId);
         } else {
             ALOGE("%s: Stream %d: timestamp shouldn't be 0", __FUNCTION__, mId);
@@ -267,7 +267,7 @@
             mBufferProducerListener->onBufferReleased();
         }
     } else {
-        if (mTraceFirstBuffer && (stream_type == CAMERA3_STREAM_OUTPUT)) {
+        if (mTraceFirstBuffer && (stream_type == CAMERA_STREAM_OUTPUT)) {
             {
                 char traceLog[48];
                 snprintf(traceLog, sizeof(traceLog), "Stream %d: first full buffer\n", mId);
@@ -303,7 +303,7 @@
 
     // Once a valid buffer has been returned to the queue, can no longer
     // dequeue all buffers for preallocation.
-    if (buffer.status != CAMERA3_BUFFER_STATUS_ERROR) {
+    if (buffer.status != CAMERA_BUFFER_STATUS_ERROR) {
         mStreamUnpreparable = true;
     }
 
@@ -424,7 +424,7 @@
     if (mMaxSize == 0) {
         // For buffers of known size
         res = native_window_set_buffers_dimensions(mConsumer.get(),
-                camera3_stream::width, camera3_stream::height);
+                camera_stream::width, camera_stream::height);
     } else {
         // For buffers with bounded size
         res = native_window_set_buffers_dimensions(mConsumer.get(),
@@ -433,23 +433,23 @@
     if (res != OK) {
         ALOGE("%s: Unable to configure stream buffer dimensions"
                 " %d x %d (maxSize %zu) for stream %d",
-                __FUNCTION__, camera3_stream::width, camera3_stream::height,
+                __FUNCTION__, camera_stream::width, camera_stream::height,
                 mMaxSize, mId);
         return res;
     }
     res = native_window_set_buffers_format(mConsumer.get(),
-            camera3_stream::format);
+            camera_stream::format);
     if (res != OK) {
         ALOGE("%s: Unable to configure stream buffer format %#x for stream %d",
-                __FUNCTION__, camera3_stream::format, mId);
+                __FUNCTION__, camera_stream::format, mId);
         return res;
     }
 
     res = native_window_set_buffers_data_space(mConsumer.get(),
-            camera3_stream::data_space);
+            camera_stream::data_space);
     if (res != OK) {
         ALOGE("%s: Unable to configure stream dataspace %#x for stream %d",
-                __FUNCTION__, camera3_stream::data_space, mId);
+                __FUNCTION__, camera_stream::data_space, mId);
         return res;
     }
 
@@ -464,14 +464,14 @@
     }
 
     ALOGV("%s: Consumer wants %d buffers, HAL wants %d", __FUNCTION__,
-            maxConsumerBuffers, camera3_stream::max_buffers);
-    if (camera3_stream::max_buffers == 0) {
+            maxConsumerBuffers, camera_stream::max_buffers);
+    if (camera_stream::max_buffers == 0) {
         ALOGE("%s: Camera HAL requested max_buffer count: %d, requires at least 1",
-                __FUNCTION__, camera3_stream::max_buffers);
+                __FUNCTION__, camera_stream::max_buffers);
         return INVALID_OPERATION;
     }
 
-    mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers;
+    mTotalBufferCount = maxConsumerBuffers + camera_stream::max_buffers;
     mHandoutTotalBufferCount = 0;
     mFrameCount = 0;
     mLastTimestamp = 0;
@@ -763,7 +763,7 @@
     uint64_t u = 0;
 
     res = native_window_get_consumer_usage(static_cast<ANativeWindow*>(surface.get()), &u);
-    applyZSLUsageQuirk(camera3_stream::format, &u);
+    applyZSLUsageQuirk(camera_stream::format, &u);
     *usage = u;
     return res;
 }
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 55f0d41..f504171 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -81,7 +81,7 @@
      */
     Camera3OutputStream(int id, sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
-            android_dataspace dataSpace, camera3_stream_rotation_t rotation,
+            android_dataspace dataSpace, camera_stream_rotation_t rotation,
             nsecs_t timestampOffset, const String8& physicalCameraId,
             int setId = CAMERA3_STREAM_SET_ID_INVALID);
 
@@ -93,7 +93,7 @@
      */
     Camera3OutputStream(int id, sp<Surface> consumer,
             uint32_t width, uint32_t height, size_t maxSize, int format,
-            android_dataspace dataSpace, camera3_stream_rotation_t rotation,
+            android_dataspace dataSpace, camera_stream_rotation_t rotation,
             nsecs_t timestampOffset, const String8& physicalCameraId,
             int setId = CAMERA3_STREAM_SET_ID_INVALID);
 
@@ -104,7 +104,7 @@
      */
     Camera3OutputStream(int id, uint32_t width, uint32_t height, int format,
             uint64_t consumerUsage, android_dataspace dataSpace,
-            camera3_stream_rotation_t rotation, nsecs_t timestampOffset,
+            camera_stream_rotation_t rotation, nsecs_t timestampOffset,
             const String8& physicalCameraId,
             int setId = CAMERA3_STREAM_SET_ID_INVALID);
 
@@ -213,9 +213,9 @@
     void setImageDumpMask(int mask) { mImageDumpMask = mask; }
 
   protected:
-    Camera3OutputStream(int id, camera3_stream_type_t type,
+    Camera3OutputStream(int id, camera_stream_type_t type,
             uint32_t width, uint32_t height, int format,
-            android_dataspace dataSpace, camera3_stream_rotation_t rotation,
+            android_dataspace dataSpace, camera_stream_rotation_t rotation,
             const String8& physicalCameraId,
             uint64_t consumerUsage = 0, nsecs_t timestampOffset = 0,
             int setId = CAMERA3_STREAM_SET_ID_INVALID);
@@ -224,7 +224,7 @@
      * Note that we release the lock briefly in this function
      */
     virtual status_t returnBufferCheckedLocked(
-            const camera3_stream_buffer &buffer,
+            const camera_stream_buffer &buffer,
             nsecs_t timestamp,
             bool output,
             const std::vector<size_t>& surface_ids,
@@ -295,11 +295,11 @@
     /**
      * Internal Camera3Stream interface
      */
-    virtual status_t getBufferLocked(camera3_stream_buffer *buffer,
+    virtual status_t getBufferLocked(camera_stream_buffer *buffer,
             const std::vector<size_t>& surface_ids);
 
     virtual status_t returnBufferLocked(
-            const camera3_stream_buffer &buffer,
+            const camera_stream_buffer &buffer,
             nsecs_t timestamp, const std::vector<size_t>& surface_ids);
 
     virtual status_t queueBufferToConsumer(sp<ANativeWindow>& consumer,
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index f88b062..384c2c6 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -484,7 +484,7 @@
     states.inflightIntf.checkInflightMapLengthLocked();
 }
 
-void processCaptureResult(CaptureOutputStates& states, const camera3_capture_result *result) {
+void processCaptureResult(CaptureOutputStates& states, const camera_capture_result *result) {
     ATRACE_CALL();
 
     status_t res;
@@ -688,7 +688,7 @@
     using hardware::camera::device::V3_2::BufferStatus;
     std::unique_ptr<ResultMetadataQueue>& fmq = states.fmq;
     BufferRecordsInterface& bufferRecords = states.bufferRecordsIntf;
-    camera3_capture_result r;
+    camera_capture_result r;
     status_t res;
     r.frame_number = result.frameNumber;
 
@@ -727,7 +727,7 @@
     r.physcam_ids = physCamIds.data();
     r.physcam_metadata = phyCamMetadatas.data();
 
-    std::vector<camera3_stream_buffer_t> outputBuffers(result.outputBuffers.size());
+    std::vector<camera_stream_buffer_t> outputBuffers(result.outputBuffers.size());
     std::vector<buffer_handle_t> outputBufferHandles(result.outputBuffers.size());
     for (size_t i = 0; i < result.outputBuffers.size(); i++) {
         auto& bDst = outputBuffers[i];
@@ -788,7 +788,7 @@
     r.num_output_buffers = outputBuffers.size();
     r.output_buffers = outputBuffers.data();
 
-    camera3_stream_buffer_t inputBuffer;
+    camera_stream_buffer_t inputBuffer;
     if (result.inputBuffer.streamId == -1) {
         r.input_buffer = nullptr;
     } else {
@@ -829,7 +829,7 @@
 void returnOutputBuffers(
         bool useHalBufManager,
         sp<NotificationListener> listener,
-        const camera3_stream_buffer_t *outputBuffers, size_t numBuffers,
+        const camera_stream_buffer_t *outputBuffers, size_t numBuffers,
         nsecs_t timestamp, bool requested, nsecs_t requestTimeNs,
         SessionStatsBuilder& sessionStatsBuilder, bool timestampIncreasing,
         const SurfaceMap& outputSurfaces,
@@ -842,7 +842,7 @@
         int streamId = stream->getId();
 
         // Call notify(ERROR_BUFFER) if necessary.
-        if (outputBuffers[i].status == CAMERA3_BUFFER_STATUS_ERROR &&
+        if (outputBuffers[i].status == CAMERA_BUFFER_STATUS_ERROR &&
                 errorBufStrategy == ERROR_BUF_RETURN_NOTIFY) {
             if (listener != nullptr) {
                 CaptureResultExtras extras = inResultExtras;
@@ -872,7 +872,7 @@
 
         // Do not return the buffer if the buffer status is error, and the error
         // buffer strategy is CACHE.
-        if (outputBuffers[i].status != CAMERA3_BUFFER_STATUS_ERROR ||
+        if (outputBuffers[i].status != CAMERA_BUFFER_STATUS_ERROR ||
                 errorBufStrategy != ERROR_BUF_CACHE) {
             if (it != outputSurfaces.end()) {
                 res = stream->returnBuffer(
@@ -894,7 +894,7 @@
             ALOGE("Can't return buffer to its stream: %s (%d)", strerror(-res), res);
             dropped = true;
         } else {
-            if (outputBuffers[i].status == CAMERA3_BUFFER_STATUS_ERROR || timestamp == 0) {
+            if (outputBuffers[i].status == CAMERA_BUFFER_STATUS_ERROR || timestamp == 0) {
                 dropped = true;
             }
         }
@@ -907,10 +907,10 @@
         // Long processing consumers can cause returnBuffer timeout for shared stream
         // If that happens, cancel the buffer and send a buffer error to client
         if (it != outputSurfaces.end() && res == TIMED_OUT &&
-                outputBuffers[i].status == CAMERA3_BUFFER_STATUS_OK) {
+                outputBuffers[i].status == CAMERA_BUFFER_STATUS_OK) {
             // cancel the buffer
-            camera3_stream_buffer_t sb = outputBuffers[i];
-            sb.status = CAMERA3_BUFFER_STATUS_ERROR;
+            camera_stream_buffer_t sb = outputBuffers[i];
+            sb.status = CAMERA_BUFFER_STATUS_ERROR;
             stream->returnBuffer(sb, /*timestamp*/0,
                     timestampIncreasing, std::vector<size_t> (),
                     inResultExtras.frameNumber);
@@ -942,7 +942,7 @@
     for (auto iter = request.pendingOutputBuffers.begin();
             iter != request.pendingOutputBuffers.end(); ) {
         if (request.errorBufStrategy != ERROR_BUF_CACHE ||
-                iter->status != CAMERA3_BUFFER_STATUS_ERROR) {
+                iter->status != CAMERA_BUFFER_STATUS_ERROR) {
             iter = request.pendingOutputBuffers.erase(iter);
         } else {
             iter++;
@@ -950,7 +950,7 @@
     }
 }
 
-void notifyShutter(CaptureOutputStates& states, const camera3_shutter_msg_t &msg) {
+void notifyShutter(CaptureOutputStates& states, const camera_shutter_msg_t &msg) {
     ATRACE_CALL();
     ssize_t idx;
 
@@ -1028,26 +1028,26 @@
     }
 }
 
-void notifyError(CaptureOutputStates& states, const camera3_error_msg_t &msg) {
+void notifyError(CaptureOutputStates& states, const camera_error_msg_t &msg) {
     ATRACE_CALL();
     // Map camera HAL error codes to ICameraDeviceCallback error codes
     // Index into this with the HAL error code
-    static const int32_t halErrorMap[CAMERA3_MSG_NUM_ERRORS] = {
+    static const int32_t halErrorMap[CAMERA_MSG_NUM_ERRORS] = {
         // 0 = Unused error code
         hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR,
-        // 1 = CAMERA3_MSG_ERROR_DEVICE
+        // 1 = CAMERA_MSG_ERROR_DEVICE
         hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
-        // 2 = CAMERA3_MSG_ERROR_REQUEST
+        // 2 = CAMERA_MSG_ERROR_REQUEST
         hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
-        // 3 = CAMERA3_MSG_ERROR_RESULT
+        // 3 = CAMERA_MSG_ERROR_RESULT
         hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT,
-        // 4 = CAMERA3_MSG_ERROR_BUFFER
+        // 4 = CAMERA_MSG_ERROR_BUFFER
         hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER
     };
 
     int32_t errorCode =
             ((msg.error_code >= 0) &&
-                    (msg.error_code < CAMERA3_MSG_NUM_ERRORS)) ?
+                    (msg.error_code < CAMERA_MSG_NUM_ERRORS)) ?
             halErrorMap[msg.error_code] :
             hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR;
 
@@ -1136,13 +1136,13 @@
     }
 }
 
-void notify(CaptureOutputStates& states, const camera3_notify_msg *msg) {
+void notify(CaptureOutputStates& states, const camera_notify_msg *msg) {
     switch (msg->type) {
-        case CAMERA3_MSG_ERROR: {
+        case CAMERA_MSG_ERROR: {
             notifyError(states, msg->message.error);
             break;
         }
-        case CAMERA3_MSG_SHUTTER: {
+        case CAMERA_MSG_SHUTTER: {
             notifyShutter(states, msg->message.shutter);
             break;
         }
@@ -1158,10 +1158,10 @@
     using android::hardware::camera::device::V3_2::ErrorCode;
 
     ATRACE_CALL();
-    camera3_notify_msg m;
+    camera_notify_msg m;
     switch (msg.type) {
         case MsgType::ERROR:
-            m.type = CAMERA3_MSG_ERROR;
+            m.type = CAMERA_MSG_ERROR;
             m.message.error.frame_number = msg.msg.error.frameNumber;
             if (msg.msg.error.errorStreamId >= 0) {
                 sp<Camera3StreamInterface> stream =
@@ -1177,21 +1177,21 @@
             }
             switch (msg.msg.error.errorCode) {
                 case ErrorCode::ERROR_DEVICE:
-                    m.message.error.error_code = CAMERA3_MSG_ERROR_DEVICE;
+                    m.message.error.error_code = CAMERA_MSG_ERROR_DEVICE;
                     break;
                 case ErrorCode::ERROR_REQUEST:
-                    m.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
+                    m.message.error.error_code = CAMERA_MSG_ERROR_REQUEST;
                     break;
                 case ErrorCode::ERROR_RESULT:
-                    m.message.error.error_code = CAMERA3_MSG_ERROR_RESULT;
+                    m.message.error.error_code = CAMERA_MSG_ERROR_RESULT;
                     break;
                 case ErrorCode::ERROR_BUFFER:
-                    m.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER;
+                    m.message.error.error_code = CAMERA_MSG_ERROR_BUFFER;
                     break;
             }
             break;
         case MsgType::SHUTTER:
-            m.type = CAMERA3_MSG_SHUTTER;
+            m.type = CAMERA_MSG_SHUTTER;
             m.message.shutter.frame_number = msg.msg.shutter.frameNumber;
             m.message.shutter.timestamp = msg.msg.shutter.timestamp;
             break;
@@ -1292,11 +1292,11 @@
 
         hardware::hidl_vec<StreamBuffer> tmpRetBuffers(numBuffersRequested);
         bool currentReqSucceeds = true;
-        std::vector<camera3_stream_buffer_t> streamBuffers(numBuffersRequested);
+        std::vector<camera_stream_buffer_t> streamBuffers(numBuffersRequested);
         size_t numAllocatedBuffers = 0;
         size_t numPushedInflightBuffers = 0;
         for (size_t b = 0; b < numBuffersRequested; b++) {
-            camera3_stream_buffer_t& sb = streamBuffers[b];
+            camera_stream_buffer_t& sb = streamBuffers[b];
             // Since this method can run concurrently with request thread
             // We need to update the wait duration everytime we call getbuffer
             nsecs_t waitDuration =  states.reqBufferIntf.getWaitDuration();
@@ -1367,9 +1367,9 @@
                 }
             }
             for (size_t b = 0; b < numAllocatedBuffers; b++) {
-                camera3_stream_buffer_t& sb = streamBuffers[b];
+                camera_stream_buffer_t& sb = streamBuffers[b];
                 sb.acquire_fence = -1;
-                sb.status = CAMERA3_BUFFER_STATUS_ERROR;
+                sb.status = CAMERA_BUFFER_STATUS_ERROR;
             }
             returnOutputBuffers(states.useHalBufManager, /*listener*/nullptr,
                     streamBuffers.data(), numAllocatedBuffers, 0, /*requested*/false,
@@ -1407,9 +1407,9 @@
             continue;
         }
 
-        camera3_stream_buffer_t streamBuffer;
+        camera_stream_buffer_t streamBuffer;
         streamBuffer.buffer = buffer;
-        streamBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+        streamBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
         streamBuffer.acquire_fence = -1;
         streamBuffer.release_fence = -1;
 
@@ -1504,19 +1504,19 @@
         int32_t frameNumber = std::get<1>(tuple);
         buffer_handle_t* buffer = std::get<2>(tuple);
 
-        camera3_stream_buffer_t streamBuffer;
+        camera_stream_buffer_t streamBuffer;
         streamBuffer.buffer = buffer;
-        streamBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+        streamBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
         streamBuffer.acquire_fence = -1;
         streamBuffer.release_fence = -1;
 
         for (auto& stream : streams) {
             if (streamId == stream->getId()) {
                 // Return buffer to deleted stream
-                camera3_stream* halStream = stream->asHalStream();
+                camera_stream* halStream = stream->asHalStream();
                 streamBuffer.stream = halStream;
                 switch (halStream->stream_type) {
-                    case CAMERA3_STREAM_OUTPUT:
+                    case CAMERA_STREAM_OUTPUT:
                         res = stream->returnBuffer(streamBuffer, /*timestamp*/ 0,
                                 /*timestampIncreasing*/true,
                                 std::vector<size_t> (), frameNumber);
@@ -1526,7 +1526,7 @@
                                   frameNumber, streamId, strerror(-res), res);
                         }
                         break;
-                    case CAMERA3_STREAM_INPUT:
+                    case CAMERA_STREAM_INPUT:
                         res = stream->returnInputBuffer(streamBuffer);
                         if (res != OK) {
                             ALOGE("%s: Can't return input buffer for frame %d to"
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.h b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
index 45c8a43..772fe6e 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
@@ -42,6 +42,63 @@
 
 namespace camera3 {
 
+    typedef struct camera_stream_configuration {
+        uint32_t num_streams;
+        camera_stream_t **streams;
+        uint32_t operation_mode;
+    } camera_stream_configuration_t;
+
+    typedef struct camera_capture_request {
+        uint32_t frame_number;
+        const camera_metadata_t *settings;
+        camera_stream_buffer_t *input_buffer;
+        uint32_t num_output_buffers;
+        const camera_stream_buffer_t *output_buffers;
+        uint32_t num_physcam_settings;
+        const char **physcam_id;
+        const camera_metadata_t **physcam_settings;
+    } camera_capture_request_t;
+
+    typedef struct camera_capture_result {
+        uint32_t frame_number;
+        const camera_metadata_t *result;
+        uint32_t num_output_buffers;
+        const camera_stream_buffer_t *output_buffers;
+        const camera_stream_buffer_t *input_buffer;
+        uint32_t partial_result;
+        uint32_t num_physcam_metadata;
+        const char **physcam_ids;
+        const camera_metadata_t **physcam_metadata;
+    } camera_capture_result_t;
+
+    typedef struct camera_shutter_msg {
+        uint32_t frame_number;
+        uint64_t timestamp;
+    } camera_shutter_msg_t;
+
+    typedef struct camera_error_msg {
+        uint32_t frame_number;
+        camera_stream_t *error_stream;
+        int error_code;
+    } camera_error_msg_t;
+
+    typedef enum camera_error_msg_code {
+        CAMERA_MSG_ERROR_DEVICE = 1,
+        CAMERA_MSG_ERROR_REQUEST = 2,
+        CAMERA_MSG_ERROR_RESULT = 3,
+        CAMERA_MSG_ERROR_BUFFER = 4,
+        CAMERA_MSG_NUM_ERRORS
+    } camera_error_msg_code_t;
+
+    typedef struct camera_notify_msg {
+        int type;
+
+        union {
+            camera_error_msg_t error;
+            camera_shutter_msg_t shutter;
+        } message;
+    } camera_notify_msg_t;
+
     /**
      * Helper methods shared between Camera3Device/Camera3OfflineSession for HAL callbacks
      */
@@ -51,7 +108,7 @@
     void returnOutputBuffers(
             bool useHalBufManager,
             sp<NotificationListener> listener, // Only needed when outputSurfaces is not empty
-            const camera3_stream_buffer_t *outputBuffers,
+            const camera_stream_buffer_t *outputBuffers,
             size_t numBuffers, nsecs_t timestamp, bool requested, nsecs_t requestTimeNs,
             SessionStatsBuilder& sessionStatsBuilder, bool timestampIncreasing = true,
             // The following arguments are only meant for surface sharing use case
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index 86b45cb..8aa5f1a 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -30,10 +30,10 @@
         const std::vector<sp<Surface>>& surfaces,
         uint32_t width, uint32_t height, int format,
         uint64_t consumerUsage, android_dataspace dataSpace,
-        camera3_stream_rotation_t rotation,
+        camera_stream_rotation_t rotation,
         nsecs_t timestampOffset, const String8& physicalCameraId,
         int setId, bool useHalBufManager) :
-        Camera3OutputStream(id, CAMERA3_STREAM_OUTPUT, width, height,
+        Camera3OutputStream(id, CAMERA_STREAM_OUTPUT, width, height,
                             format, dataSpace, rotation, physicalCameraId,
                             consumerUsage, timestampOffset, setId),
         mUseHalBufManager(useHalBufManager) {
@@ -65,7 +65,7 @@
         }
     }
 
-    res = mStreamSplitter->connect(initialSurfaces, usage, mUsage, camera3_stream::max_buffers,
+    res = mStreamSplitter->connect(initialSurfaces, usage, mUsage, camera_stream::max_buffers,
             getWidth(), getHeight(), getFormat(), &mConsumer);
     if (res != OK) {
         ALOGE("%s: Failed to connect to stream splitter: %s(%d)",
@@ -157,7 +157,7 @@
     return ret;
 }
 
-status_t Camera3SharedOutputStream::getBufferLocked(camera3_stream_buffer *buffer,
+status_t Camera3SharedOutputStream::getBufferLocked(camera_stream_buffer *buffer,
         const std::vector<size_t>& surfaceIds) {
     ANativeWindowBuffer* anb;
     int fenceFd = -1;
@@ -180,7 +180,7 @@
      * in which case we reassign it to acquire_fence
      */
     handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
-                        /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true);
+                        /*releaseFence*/-1, CAMERA_BUFFER_STATUS_OK, /*output*/true);
 
     return OK;
 }
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index e645e05..a61316c 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -36,7 +36,7 @@
     Camera3SharedOutputStream(int id, const std::vector<sp<Surface>>& surfaces,
             uint32_t width, uint32_t height, int format,
             uint64_t consumerUsage, android_dataspace dataSpace,
-            camera3_stream_rotation_t rotation, nsecs_t timestampOffset,
+            camera_stream_rotation_t rotation, nsecs_t timestampOffset,
             const String8& physicalCameraId,
             int setId = CAMERA3_STREAM_SET_ID_INVALID,
             bool useHalBufManager = false);
@@ -116,7 +116,7 @@
     /**
      * Internal Camera3Stream interface
      */
-    virtual status_t getBufferLocked(camera3_stream_buffer *buffer,
+    virtual status_t getBufferLocked(camera_stream_buffer *buffer,
             const std::vector<size_t>& surface_ids);
 
     virtual status_t queueBufferToConsumer(sp<ANativeWindow>& consumer,
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 9a8f6fe..8d72b4c 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -37,20 +37,20 @@
     }
 }
 
-Camera3Stream* Camera3Stream::cast(camera3_stream *stream) {
+Camera3Stream* Camera3Stream::cast(camera_stream *stream) {
     return static_cast<Camera3Stream*>(stream);
 }
 
-const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) {
+const Camera3Stream* Camera3Stream::cast(const camera_stream *stream) {
     return static_cast<const Camera3Stream*>(stream);
 }
 
 Camera3Stream::Camera3Stream(int id,
-        camera3_stream_type type,
+        camera_stream_type type,
         uint32_t width, uint32_t height, size_t maxSize, int format,
-        android_dataspace dataSpace, camera3_stream_rotation_t rotation,
+        android_dataspace dataSpace, camera_stream_rotation_t rotation,
         const String8& physicalCameraId, int setId) :
-    camera3_stream(),
+    camera_stream(),
     mId(id),
     mSetId(setId),
     mName(String8::format("Camera3Stream[%d]", id)),
@@ -75,15 +75,14 @@
     mPhysicalCameraId(physicalCameraId),
     mLastTimestamp(0) {
 
-    camera3_stream::stream_type = type;
-    camera3_stream::width = width;
-    camera3_stream::height = height;
-    camera3_stream::format = format;
-    camera3_stream::data_space = dataSpace;
-    camera3_stream::rotation = rotation;
-    camera3_stream::max_buffers = 0;
-    camera3_stream::priv = NULL;
-    camera3_stream::physical_camera_id = mPhysicalCameraId.string();
+    camera_stream::stream_type = type;
+    camera_stream::width = width;
+    camera_stream::height = height;
+    camera_stream::format = format;
+    camera_stream::data_space = dataSpace;
+    camera_stream::rotation = rotation;
+    camera_stream::max_buffers = 0;
+    camera_stream::physical_camera_id = mPhysicalCameraId.string();
 
     if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) &&
             maxSize == 0) {
@@ -101,19 +100,19 @@
 }
 
 uint32_t Camera3Stream::getWidth() const {
-    return camera3_stream::width;
+    return camera_stream::width;
 }
 
 uint32_t Camera3Stream::getHeight() const {
-    return camera3_stream::height;
+    return camera_stream::height;
 }
 
 int Camera3Stream::getFormat() const {
-    return camera3_stream::format;
+    return camera_stream::format;
 }
 
 android_dataspace Camera3Stream::getDataSpace() const {
-    return camera3_stream::data_space;
+    return camera_stream::data_space;
 }
 
 uint64_t Camera3Stream::getUsage() const {
@@ -153,7 +152,7 @@
 }
 
 int Camera3Stream::getMaxHalBuffers() const {
-    return camera3_stream::max_buffers;
+    return camera_stream::max_buffers;
 }
 
 void Camera3Stream::setOfflineProcessingSupport(bool support) {
@@ -233,7 +232,7 @@
     return res;
 }
 
-camera3_stream* Camera3Stream::startConfiguration() {
+camera_stream* Camera3Stream::startConfiguration() {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
     status_t res;
@@ -264,9 +263,9 @@
     }
 
     mOldUsage = mUsage;
-    mOldMaxBuffers = camera3_stream::max_buffers;
-    mOldFormat = camera3_stream::format;
-    mOldDataSpace = camera3_stream::data_space;
+    mOldMaxBuffers = camera_stream::max_buffers;
+    mOldFormat = camera_stream::format;
+    mOldDataSpace = camera_stream::data_space;
 
     res = getEndpointUsage(&mUsage);
     if (res != OK) {
@@ -339,12 +338,12 @@
     }
 
     // Check if the stream configuration is unchanged, and skip reallocation if
-    // so. As documented in hardware/camera3.h:configure_streams().
+    // so.
     if (mState == STATE_IN_RECONFIG &&
             mOldUsage == mUsage &&
-            mOldMaxBuffers == camera3_stream::max_buffers &&
-            mOldDataSpace == camera3_stream::data_space &&
-            mOldFormat == camera3_stream::format) {
+            mOldMaxBuffers == camera_stream::max_buffers &&
+            mOldDataSpace == camera_stream::data_space &&
+            mOldFormat == camera_stream::format) {
         mState = STATE_CONFIGURED;
         return OK;
     }
@@ -403,7 +402,7 @@
     }
 
     mUsage = mOldUsage;
-    camera3_stream::max_buffers = mOldMaxBuffers;
+    camera_stream::max_buffers = mOldMaxBuffers;
 
     mState = ((mState == STATE_IN_RECONFIG) || (mState == STATE_IN_IDLE)) ? STATE_CONFIGURED :
             STATE_CONSTRUCTED;
@@ -463,7 +462,7 @@
 
     mLastMaxCount = bufferCount;
 
-    mPreparedBuffers.insertAt(camera3_stream_buffer_t(), /*index*/0, bufferCount);
+    mPreparedBuffers.insertAt(camera_stream_buffer_t(), /*index*/0, bufferCount);
     mPreparedBufferIdx = 0;
 
     mState = STATE_PREPARING;
@@ -538,7 +537,7 @@
     // they weren't filled.
     for (size_t i = 0; i < mPreparedBufferIdx; i++) {
         mPreparedBuffers.editItemAt(i).release_fence = -1;
-        mPreparedBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
+        mPreparedBuffers.editItemAt(i).status = CAMERA_BUFFER_STATUS_ERROR;
         returnBufferLocked(mPreparedBuffers[i], 0);
     }
     mPreparedBuffers.clear();
@@ -604,7 +603,7 @@
     return OK;
 }
 
-status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer,
+status_t Camera3Stream::getBuffer(camera_stream_buffer *buffer,
         nsecs_t waitBufferTimeout,
         const std::vector<size_t>& surface_ids) {
     ATRACE_HFR_CALL();
@@ -623,9 +622,9 @@
     }
 
     // Wait for new buffer returned back if we are running into the limit.
-    if (getHandoutOutputBufferCountLocked() == camera3_stream::max_buffers) {
+    if (getHandoutOutputBufferCountLocked() == camera_stream::max_buffers) {
         ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.",
-                        __FUNCTION__, camera3_stream::max_buffers);
+                        __FUNCTION__, camera_stream::max_buffers);
         nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
         if (waitBufferTimeout < kWaitForBufferDuration) {
             waitBufferTimeout = kWaitForBufferDuration;
@@ -637,7 +636,7 @@
             if (res == TIMED_OUT) {
                 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
                         __FUNCTION__, waitBufferTimeout / 1000000LL,
-                        camera3_stream::max_buffers);
+                        camera_stream::max_buffers);
             }
             return res;
         }
@@ -655,7 +654,7 @@
     return res;
 }
 
-bool Camera3Stream::isOutstandingBuffer(const camera3_stream_buffer &buffer) const{
+bool Camera3Stream::isOutstandingBuffer(const camera_stream_buffer &buffer) const{
     if (buffer.buffer == nullptr) {
         return false;
     }
@@ -670,7 +669,7 @@
     return false;
 }
 
-void Camera3Stream::removeOutstandingBuffer(const camera3_stream_buffer &buffer) {
+void Camera3Stream::removeOutstandingBuffer(const camera_stream_buffer &buffer) {
     if (buffer.buffer == nullptr) {
         return;
     }
@@ -685,7 +684,7 @@
     }
 }
 
-status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
+status_t Camera3Stream::returnBuffer(const camera_stream_buffer &buffer,
         nsecs_t timestamp, bool timestampIncreasing,
          const std::vector<size_t>& surface_ids, uint64_t frameNumber) {
     ATRACE_HFR_CALL();
@@ -700,11 +699,11 @@
     removeOutstandingBuffer(buffer);
 
     // Buffer status may be changed, so make a copy of the stream_buffer struct.
-    camera3_stream_buffer b = buffer;
+    camera_stream_buffer b = buffer;
     if (timestampIncreasing && timestamp != 0 && timestamp <= mLastTimestamp) {
         ALOGE("%s: Stream %d: timestamp %" PRId64 " is not increasing. Prev timestamp %" PRId64,
                 __FUNCTION__, mId, timestamp, mLastTimestamp);
-        b.status = CAMERA3_BUFFER_STATUS_ERROR;
+        b.status = CAMERA_BUFFER_STATUS_ERROR;
     }
     mLastTimestamp = timestamp;
 
@@ -728,7 +727,7 @@
     return res;
 }
 
-status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer, bool respectHalLimit) {
+status_t Camera3Stream::getInputBuffer(camera_stream_buffer *buffer, bool respectHalLimit) {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
     status_t res = OK;
@@ -741,9 +740,9 @@
     }
 
     // Wait for new buffer returned back if we are running into the limit.
-    if (getHandoutInputBufferCountLocked() == camera3_stream::max_buffers && respectHalLimit) {
+    if (getHandoutInputBufferCountLocked() == camera_stream::max_buffers && respectHalLimit) {
         ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.",
-                __FUNCTION__, camera3_stream::max_buffers);
+                __FUNCTION__, camera_stream::max_buffers);
         res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
         if (res != OK) {
             if (res == TIMED_OUT) {
@@ -766,7 +765,7 @@
     return res;
 }
 
-status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) {
+status_t Camera3Stream::returnInputBuffer(const camera_stream_buffer &buffer) {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
 
@@ -808,7 +807,7 @@
 }
 
 void Camera3Stream::fireBufferListenersLocked(
-        const camera3_stream_buffer& buffer, bool acquired, bool output, nsecs_t timestamp,
+        const camera_stream_buffer& buffer, bool acquired, bool output, nsecs_t timestamp,
         uint64_t frameNumber) {
     List<wp<Camera3StreamBufferListener> >::iterator it, end;
 
@@ -817,7 +816,7 @@
     Camera3StreamBufferListener::BufferInfo info =
         Camera3StreamBufferListener::BufferInfo();
     info.mOutput = output;
-    info.mError = (buffer.status == CAMERA3_BUFFER_STATUS_ERROR);
+    info.mError = (buffer.status == CAMERA_BUFFER_STATUS_ERROR);
     info.mFrameNumber = frameNumber;
     info.mTimestamp = timestamp;
     info.mStreamId = getId();
@@ -887,22 +886,22 @@
             "      Latency histogram for wait on max_buffers");
 }
 
-status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *,
+status_t Camera3Stream::getBufferLocked(camera_stream_buffer *,
         const std::vector<size_t>&) {
     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
     return INVALID_OPERATION;
 }
-status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &,
+status_t Camera3Stream::returnBufferLocked(const camera_stream_buffer &,
                                            nsecs_t, const std::vector<size_t>&) {
     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
     return INVALID_OPERATION;
 }
-status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) {
+status_t Camera3Stream::getInputBufferLocked(camera_stream_buffer *) {
     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
     return INVALID_OPERATION;
 }
 status_t Camera3Stream::returnInputBufferLocked(
-        const camera3_stream_buffer &) {
+        const camera_stream_buffer &) {
     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
     return INVALID_OPERATION;
 }
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 3654f89..47dc252 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -23,8 +23,6 @@
 #include <utils/String16.h>
 #include <utils/List.h>
 
-#include "hardware/camera3.h"
-
 #include "utils/LatencyHistogram.h"
 #include "Camera3StreamBufferListener.h"
 #include "Camera3StreamInterface.h"
@@ -50,7 +48,7 @@
  *    with the HAL.
  *
  *  STATE_IN_CONFIG: Configuration has started, but not yet concluded. During this
- *    time, the usage, max_buffers, and priv fields of camera3_stream returned by
+ *    time, the usage, max_buffers, and priv fields of camera_stream returned by
  *    startConfiguration() may be modified.
  *
  *  STATE_IN_RE_CONFIG: Configuration has started, and the stream has been
@@ -130,15 +128,15 @@
  *
  */
 class Camera3Stream :
-        protected camera3_stream,
+        protected camera_stream,
         public virtual Camera3StreamInterface,
         public virtual RefBase {
   public:
 
     virtual ~Camera3Stream();
 
-    static Camera3Stream*       cast(camera3_stream *stream);
-    static const Camera3Stream* cast(const camera3_stream *stream);
+    static Camera3Stream*       cast(camera_stream *stream);
+    static const Camera3Stream* cast(const camera_stream *stream);
 
     /**
      * Get the stream's ID
@@ -171,7 +169,7 @@
     void              setOfflineProcessingSupport(bool) override;
     bool              getOfflineProcessingSupport() const override;
 
-    camera3_stream*   asHalStream() override {
+    camera_stream*   asHalStream() override {
         return this;
     }
 
@@ -180,14 +178,12 @@
      * information to be passed into the HAL device's configure_streams call.
      *
      * Until finishConfiguration() is called, no other methods on the stream may be
-     * called. The usage and max_buffers fields of camera3_stream may be modified
+     * called. The usage and max_buffers fields of camera_stream may be modified
      * between start/finishConfiguration, but may not be changed after that.
-     * The priv field of camera3_stream may be modified at any time after
-     * startConfiguration.
      *
      * Returns NULL in case of error starting configuration.
      */
-    camera3_stream*  startConfiguration();
+    camera_stream*  startConfiguration();
 
     /**
      * Check if the stream is mid-configuration (start has been called, but not
@@ -308,7 +304,7 @@
     status_t       tearDown();
 
     /**
-     * Fill in the camera3_stream_buffer with the next valid buffer for this
+     * Fill in the camera_stream_buffer with the next valid buffer for this
      * stream, to hand over to the HAL.
      *
      * Multiple surfaces could share the same HAL stream, but a request may
@@ -321,7 +317,7 @@
      * buffers.
      *
      */
-    status_t         getBuffer(camera3_stream_buffer *buffer,
+    status_t         getBuffer(camera_stream_buffer *buffer,
             nsecs_t waitBufferTimeout,
             const std::vector<size_t>& surface_ids = std::vector<size_t>());
 
@@ -336,13 +332,13 @@
      * This method may only be called for buffers provided by getBuffer().
      * For bidirectional streams, this method applies to the output-side buffers
      */
-    status_t         returnBuffer(const camera3_stream_buffer &buffer,
+    status_t         returnBuffer(const camera_stream_buffer &buffer,
             nsecs_t timestamp, bool timestampIncreasing,
             const std::vector<size_t>& surface_ids = std::vector<size_t>(),
             uint64_t frameNumber = 0);
 
     /**
-     * Fill in the camera3_stream_buffer with the next valid buffer for this
+     * Fill in the camera_stream_buffer with the next valid buffer for this
      * stream, to hand over to the HAL.
      *
      * This method may only be called once finishConfiguration has been called.
@@ -352,7 +348,7 @@
      * Normally this call will block until the handed out buffer count is less than the stream
      * max buffer count; if respectHalLimit is set to false, this is ignored.
      */
-    status_t         getInputBuffer(camera3_stream_buffer *buffer, bool respectHalLimit = true);
+    status_t         getInputBuffer(camera_stream_buffer *buffer, bool respectHalLimit = true);
 
     /**
      * Return a buffer to the stream after use by the HAL.
@@ -360,7 +356,7 @@
      * This method may only be called for buffers provided by getBuffer().
      * For bidirectional streams, this method applies to the input-side buffers
      */
-    status_t         returnInputBuffer(const camera3_stream_buffer &buffer);
+    status_t         returnInputBuffer(const camera_stream_buffer &buffer);
 
     // get the buffer producer of the input buffer queue.
     // only apply to input streams.
@@ -477,9 +473,9 @@
 
     mutable Mutex mLock;
 
-    Camera3Stream(int id, camera3_stream_type type,
+    Camera3Stream(int id, camera_stream_type type,
             uint32_t width, uint32_t height, size_t maxSize, int format,
-            android_dataspace dataSpace, camera3_stream_rotation_t rotation,
+            android_dataspace dataSpace, camera_stream_rotation_t rotation,
             const String8& physicalCameraId, int setId);
 
     wp<Camera3StreamBufferFreedListener> mBufferFreedListener;
@@ -490,18 +486,18 @@
 
     // getBuffer / returnBuffer implementations
 
-    // Since camera3_stream_buffer includes a raw pointer to the stream,
-    // cast to camera3_stream*, implementations must increment the
+    // Since camera_stream_buffer includes a raw pointer to the stream,
+    // cast to camera_stream*, implementations must increment the
     // refcount of the stream manually in getBufferLocked, and decrement it in
     // returnBufferLocked.
-    virtual status_t getBufferLocked(camera3_stream_buffer *buffer,
+    virtual status_t getBufferLocked(camera_stream_buffer *buffer,
             const std::vector<size_t>& surface_ids = std::vector<size_t>());
-    virtual status_t returnBufferLocked(const camera3_stream_buffer &buffer,
+    virtual status_t returnBufferLocked(const camera_stream_buffer &buffer,
             nsecs_t timestamp,
             const std::vector<size_t>& surface_ids = std::vector<size_t>());
-    virtual status_t getInputBufferLocked(camera3_stream_buffer *buffer);
+    virtual status_t getInputBufferLocked(camera_stream_buffer *buffer);
     virtual status_t returnInputBufferLocked(
-            const camera3_stream_buffer &buffer);
+            const camera_stream_buffer &buffer);
     virtual bool     hasOutstandingBuffersLocked() const = 0;
     // Get the buffer producer of the input buffer queue. Only apply to input streams.
     virtual status_t getInputBufferProducerLocked(sp<IGraphicBufferProducer> *producer);
@@ -530,7 +526,7 @@
     virtual status_t getEndpointUsage(uint64_t *usage) const = 0;
 
     // Return whether the buffer is in the list of outstanding buffers.
-    bool isOutstandingBuffer(const camera3_stream_buffer& buffer) const;
+    bool isOutstandingBuffer(const camera_stream_buffer& buffer) const;
 
     // Tracking for idle state
     wp<StatusTracker> mStatusTracker;
@@ -554,14 +550,14 @@
     Condition mInputBufferReturnedSignal;
     static const nsecs_t kWaitForBufferDuration = 3000000000LL; // 3000 ms
 
-    void fireBufferListenersLocked(const camera3_stream_buffer& buffer,
+    void fireBufferListenersLocked(const camera_stream_buffer& buffer,
             bool acquired, bool output, nsecs_t timestamp = 0, uint64_t frameNumber = 0);
     List<wp<Camera3StreamBufferListener> > mBufferListenerList;
 
     status_t        cancelPrepareLocked();
 
     // Remove the buffer from the list of outstanding buffers.
-    void removeOutstandingBuffer(const camera3_stream_buffer& buffer);
+    void removeOutstandingBuffer(const camera_stream_buffer& buffer);
 
     // Tracking for PREPARING state
 
@@ -571,7 +567,7 @@
     bool mPrepared;
     bool mPrepareBlockRequest;
 
-    Vector<camera3_stream_buffer_t> mPreparedBuffers;
+    Vector<camera_stream_buffer_t> mPreparedBuffers;
     size_t mPreparedBufferIdx;
 
     // Number of buffers allocated on last prepare call.
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index a053262..b48636e 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -23,13 +23,55 @@
 #include "Camera3StreamBufferListener.h"
 #include "Camera3StreamBufferFreedListener.h"
 
-struct camera3_stream;
-struct camera3_stream_buffer;
-
 namespace android {
 
 namespace camera3 {
 
+typedef enum camera_buffer_status {
+    CAMERA_BUFFER_STATUS_OK = 0,
+    CAMERA_BUFFER_STATUS_ERROR = 1
+} camera_buffer_status_t;
+
+typedef enum camera_stream_type {
+    CAMERA_STREAM_OUTPUT = 0,
+    CAMERA_STREAM_INPUT = 1,
+    CAMERA_NUM_STREAM_TYPES
+} camera_stream_type_t;
+
+typedef enum camera_stream_rotation {
+    /* No rotation */
+    CAMERA_STREAM_ROTATION_0 = 0,
+
+    /* Rotate by 90 degree counterclockwise */
+    CAMERA_STREAM_ROTATION_90 = 1,
+
+    /* Rotate by 180 degree counterclockwise */
+    CAMERA_STREAM_ROTATION_180 = 2,
+
+    /* Rotate by 270 degree counterclockwise */
+    CAMERA_STREAM_ROTATION_270 = 3
+} camera_stream_rotation_t;
+
+typedef struct camera_stream {
+    camera_stream_type_t stream_type;
+    uint32_t width;
+    uint32_t height;
+    int format;
+    uint32_t usage;
+    uint32_t max_buffers;
+    android_dataspace_t data_space;
+    camera_stream_rotation_t rotation;
+    const char* physical_camera_id;
+} camera_stream_t;
+
+typedef struct camera_stream_buffer {
+    camera_stream_t *stream;
+    buffer_handle_t *buffer;
+    camera_buffer_status_t status;
+    int acquire_fence;
+    int release_fence;
+} camera_stream_buffer_t;
+
 enum {
     /**
      * This stream set ID indicates that the set ID is invalid, and this stream doesn't intend to
@@ -109,23 +151,23 @@
     virtual bool getOfflineProcessingSupport() const = 0;
 
     /**
-     * Get a HAL3 handle for the stream, without starting stream configuration.
+     * Get a handle for the stream, without starting stream configuration.
      */
-    virtual camera3_stream* asHalStream() = 0;
+    virtual camera_stream* asHalStream() = 0;
 
     /**
      * Start the stream configuration process. Returns a handle to the stream's
-     * information to be passed into the HAL device's configure_streams call.
+     * information to be passed into the device's configure_streams call.
      *
      * Until finishConfiguration() is called, no other methods on the stream may
-     * be called. The usage and max_buffers fields of camera3_stream may be
+     * be called. The usage and max_buffers fields of camera_stream may be
      * modified between start/finishConfiguration, but may not be changed after
-     * that. The priv field of camera3_stream may be modified at any time after
+     * that. The priv field of camera_stream may be modified at any time after
      * startConfiguration.
      *
      * Returns NULL in case of error starting configuration.
      */
-    virtual camera3_stream* startConfiguration() = 0;
+    virtual camera_stream* startConfiguration() = 0;
 
     /**
      * Check if the stream is mid-configuration (start has been called, but not
@@ -241,7 +283,7 @@
     virtual status_t tearDown() = 0;
 
     /**
-     * Fill in the camera3_stream_buffer with the next valid buffer for this
+     * Fill in the camera_stream_buffer with the next valid buffer for this
      * stream, to hand over to the HAL.
      *
      * Multiple surfaces could share the same HAL stream, but a request may
@@ -255,7 +297,7 @@
      * buffers.
      *
      */
-    virtual status_t getBuffer(camera3_stream_buffer *buffer,
+    virtual status_t getBuffer(camera_stream_buffer *buffer,
             nsecs_t waitBufferTimeout,
             const std::vector<size_t>& surface_ids = std::vector<size_t>()) = 0;
 
@@ -271,13 +313,13 @@
      * This method may only be called for buffers provided by getBuffer().
      * For bidirectional streams, this method applies to the output-side buffers
      */
-    virtual status_t returnBuffer(const camera3_stream_buffer &buffer,
+    virtual status_t returnBuffer(const camera_stream_buffer &buffer,
             nsecs_t timestamp, bool timestampIncreasing = true,
             const std::vector<size_t>& surface_ids = std::vector<size_t>(),
             uint64_t frameNumber = 0) = 0;
 
     /**
-     * Fill in the camera3_stream_buffer with the next valid buffer for this
+     * Fill in the camera_stream_buffer with the next valid buffer for this
      * stream, to hand over to the HAL.
      *
      * This method may only be called once finishConfiguration has been called.
@@ -287,7 +329,7 @@
      * Normally this call will block until the handed out buffer count is less than the stream
      * max buffer count; if respectHalLimit is set to false, this is ignored.
      */
-    virtual status_t getInputBuffer(camera3_stream_buffer *buffer, bool respectHalLimit = true) = 0;
+    virtual status_t getInputBuffer(camera_stream_buffer *buffer, bool respectHalLimit = true) = 0;
 
     /**
      * Return a buffer to the stream after use by the HAL.
@@ -295,7 +337,7 @@
      * This method may only be called for buffers provided by getBuffer().
      * For bidirectional streams, this method applies to the input-side buffers
      */
-    virtual status_t returnInputBuffer(const camera3_stream_buffer &buffer) = 0;
+    virtual status_t returnInputBuffer(const camera_stream_buffer &buffer) = 0;
 
     /**
      * Get the buffer producer of the input buffer queue.
diff --git a/services/camera/libcameraservice/device3/InFlightRequest.h b/services/camera/libcameraservice/device3/InFlightRequest.h
index c7b7475..e3aaf44 100644
--- a/services/camera/libcameraservice/device3/InFlightRequest.h
+++ b/services/camera/libcameraservice/device3/InFlightRequest.h
@@ -24,8 +24,6 @@
 #include <utils/String8.h>
 #include <utils/Timers.h>
 
-#include "hardware/camera3.h"
-
 #include "common/CameraDeviceBase.h"
 
 namespace android {
@@ -75,7 +73,7 @@
     // return from HAL but framework has not yet received the shutter
     // event. They will be returned to the streams when framework receives
     // the shutter event.
-    Vector<camera3_stream_buffer_t> pendingOutputBuffers;
+    Vector<camera_stream_buffer_t> pendingOutputBuffers;
 
     // Whether this inflight request's shutter and result callback are to be
     // called. The policy is that if the request is the last one in the constrained
diff --git a/services/camera/libcameraservice/device3/StatusTracker.h b/services/camera/libcameraservice/device3/StatusTracker.h
index 3741cce..069bff6 100644
--- a/services/camera/libcameraservice/device3/StatusTracker.h
+++ b/services/camera/libcameraservice/device3/StatusTracker.h
@@ -24,7 +24,6 @@
 #include <utils/Mutex.h>
 #include <utils/Thread.h>
 #include <utils/KeyedVector.h>
-#include <hardware/camera3.h>
 
 #include "common/CameraDeviceBase.h"
 
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index ba68a63..c28f427 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -261,7 +261,7 @@
 
 
 void SessionConfigurationUtils::mapStreamInfo(const OutputStreamInfo &streamInfo,
-            camera3_stream_rotation_t rotation, String8 physicalId,
+            camera3::camera_stream_rotation_t rotation, String8 physicalId,
             hardware::camera::device::V3_4::Stream *stream /*out*/) {
     if (stream == nullptr) {
         return;
@@ -373,7 +373,7 @@
     }
     *earlyExit = false;
     auto ret = Camera3Device::mapToStreamConfigurationMode(
-            static_cast<camera3_stream_configuration_mode_t> (operatingMode),
+            static_cast<camera_stream_configuration_mode_t> (operatingMode),
             /*out*/ &streamConfiguration.operationMode);
     if (ret != OK) {
         String8 msg = String8::format(
@@ -432,7 +432,7 @@
             if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
                 streamInfo.consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
             }
-            mapStreamInfo(streamInfo, CAMERA3_STREAM_ROTATION_0, physicalCameraId,
+            mapStreamInfo(streamInfo, camera3::CAMERA_STREAM_ROTATION_0, physicalCameraId,
                     &streamConfiguration.streams[streamIdx++]);
             isStreamInfoValid = true;
 
@@ -487,12 +487,12 @@
 
                     for (const auto& compositeStream : compositeStreams) {
                         mapStreamInfo(compositeStream,
-                                static_cast<camera3_stream_rotation_t> (it.getRotation()),
+                                static_cast<camera_stream_rotation_t> (it.getRotation()),
                                 physicalCameraId, &streamConfiguration.streams[streamIdx++]);
                     }
                 } else {
                     mapStreamInfo(streamInfo,
-                            static_cast<camera3_stream_rotation_t> (it.getRotation()),
+                            static_cast<camera_stream_rotation_t> (it.getRotation()),
                             physicalCameraId, &streamConfiguration.streams[streamIdx++]);
                 }
                 isStreamInfoValid = true;
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 6ce2cd7..6ac7ab4 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -23,7 +23,6 @@
 #include <camera/camera2/SubmitInfo.h>
 #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
 
-#include <hardware/camera3.h>
 #include <device3/Camera3StreamInterface.h>
 
 #include <stdint.h>
@@ -54,7 +53,7 @@
         const String8 &cameraId, const CameraMetadata &physicalCameraMetadata);
 
     static void mapStreamInfo(const camera3::OutputStreamInfo &streamInfo,
-            camera3_stream_rotation_t rotation, String8 physicalId,
+            camera3::camera_stream_rotation_t rotation, String8 physicalId,
             hardware::camera::device::V3_4::Stream *stream /*out*/);
 
     // Check that the physicalCameraId passed in is spported by the camera
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86.policy b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
index a9d32d6..4bcc077 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
@@ -27,6 +27,7 @@
 mmap: 1
 fstat64: 1
 fstat: 1
+stat: 1
 stat64: 1
 statfs64: 1
 madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy b/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
index a9d32d6..4bcc077 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
@@ -27,6 +27,7 @@
 mmap: 1
 fstat64: 1
 fstat: 1
+stat: 1
 stat64: 1
 statfs64: 1
 madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy b/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
index eb71e28..9bafe7b 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
@@ -27,6 +27,7 @@
 mmap: 1
 fstat64: 1
 fstat: 1
+stat: 1
 stat64: 1
 statfs64: 1
 madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
index e72d4db..b0ed040 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
@@ -27,6 +27,7 @@
 mmap: 1
 fstat64: 1
 fstat: 1
+stat: 1
 stat64: 1
 statfs64: 1
 madvise: 1
diff --git a/services/mediaresourcemanager/Android.bp b/services/mediaresourcemanager/Android.bp
index cdf5a4e..83a139b 100644
--- a/services/mediaresourcemanager/Android.bp
+++ b/services/mediaresourcemanager/Android.bp
@@ -35,11 +35,27 @@
 
 aidl_interface {
     name: "resourceobserver_aidl_interface",
-    unstable: true,
     local_include_dir: "aidl",
     srcs: [
         ":resourceobserver_aidl",
     ],
+    backend: {
+        java: {
+            enabled: false,
+        },
+        cpp: {
+            enabled: false,
+        },
+        ndk: {
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.media",
+                "test_com.android.media",
+            ],
+            min_sdk_version: "29",
+            enabled: true,
+        },
+    },
 }
 
 cc_library {
diff --git a/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/IResourceObserver.aidl b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/IResourceObserver.aidl
new file mode 100644
index 0000000..402704b
--- /dev/null
+++ b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/IResourceObserver.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+/* @hide */
+interface IResourceObserver {
+  oneway void onStatusChanged(android.media.MediaObservableEvent event, int uid, int pid, in android.media.MediaObservableParcel[] observables);
+}
diff --git a/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/IResourceObserverService.aidl b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/IResourceObserverService.aidl
new file mode 100644
index 0000000..a0ef761
--- /dev/null
+++ b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/IResourceObserverService.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+/* @hide */
+interface IResourceObserverService {
+  void registerObserver(android.media.IResourceObserver observer, in android.media.MediaObservableFilter[] filters);
+  void unregisterObserver(android.media.IResourceObserver observer);
+}
diff --git a/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableEvent.aidl b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableEvent.aidl
new file mode 100644
index 0000000..fd60bea
--- /dev/null
+++ b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableEvent.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+/* @hide */
+@Backing(type="long")
+enum MediaObservableEvent {
+  kBusy = 1,
+  kIdle = 2,
+  kAll = -1,
+}
diff --git a/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableFilter.aidl b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableFilter.aidl
new file mode 100644
index 0000000..4045ae0
--- /dev/null
+++ b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableFilter.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+/* @hide */
+parcelable MediaObservableFilter {
+  android.media.MediaObservableType type;
+  android.media.MediaObservableEvent eventFilter;
+}
diff --git a/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableParcel.aidl b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableParcel.aidl
new file mode 100644
index 0000000..ff5a8e8
--- /dev/null
+++ b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableParcel.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+/* @hide */
+parcelable MediaObservableParcel {
+  android.media.MediaObservableType type;
+  long value = 0;
+}
diff --git a/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableType.aidl b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableType.aidl
new file mode 100644
index 0000000..ebb8d8e
--- /dev/null
+++ b/services/mediaresourcemanager/aidl_api/resourceobserver_aidl_interface/current/android/media/MediaObservableType.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.media;
+/* @hide */
+@Backing(type="int")
+enum MediaObservableType {
+  kInvalid = 0,
+  kVideoSecureCodec = 1000,
+  kVideoNonSecureCodec = 1001,
+}
diff --git a/services/mediatranscoding/Android.bp b/services/mediatranscoding/Android.bp
index 3d6821b..48c2584 100644
--- a/services/mediatranscoding/Android.bp
+++ b/services/mediatranscoding/Android.bp
@@ -7,8 +7,14 @@
         "SimulatedTranscoder.cpp",
     ],
 
+    min_sdk_version: "29",
+    apex_available: [
+        "com.android.media",
+        "test_com.android.media",
+    ],
+
     shared_libs: [
-        "libandroid",
+        "libandroid#31",
         "libbase",
         "libbinder_ndk",
         "libcutils",
@@ -48,12 +54,16 @@
         "libmediatranscodingservice",
     ],
 
+    min_sdk_version: "29",
+    apex_available: [
+        "com.android.media",
+        "test_com.android.media",
+    ],
+
     static_libs: [
         "mediatranscoding_aidl_interface-ndk_platform",
     ],
 
-    init_rc: ["mediatranscoding.rc"],
-
     cflags: [
         "-Werror",
         "-Wall",
diff --git a/services/mediatranscoding/mediatranscoding.rc b/services/mediatranscoding/mediatranscoding.rc
deleted file mode 100644
index 5bfef59..0000000
--- a/services/mediatranscoding/mediatranscoding.rc
+++ /dev/null
@@ -1,6 +0,0 @@
-service media.transcoding /system/bin/mediatranscoding
-    class main
-    user media
-    group media
-    ioprio rt 4
-    task_profiles ProcessCapacityHigh HighPerformance