Merge "Transcoder: Fix codec config error with single frame video"
diff --git a/Android.bp b/Android.bp
index 87a8f41..a7cf3e5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -8,6 +8,7 @@
     srcs: [
         "aidl/android/media/InterpolatorConfig.aidl",
         "aidl/android/media/InterpolatorType.aidl",
+        "aidl/android/media/MicrophoneInfoData.aidl",
         "aidl/android/media/VolumeShaperConfiguration.aidl",
         "aidl/android/media/VolumeShaperConfigurationOptionFlag.aidl",
         "aidl/android/media/VolumeShaperConfigurationType.aidl",
@@ -20,8 +21,42 @@
             min_sdk_version: "29",
             apex_available: [
                 "//apex_available:platform",
+                "com.android.bluetooth.updatable",
                 "com.android.media",
+                "com.android.media.swcodec",
             ],
         },
     },
 }
+
+cc_library_headers {
+    name: "av-headers",
+    export_include_dirs: ["include"],
+    static_libs: [
+        "av-types-aidl-unstable-cpp",
+    ],
+    export_static_lib_headers: [
+        "av-types-aidl-unstable-cpp",
+    ],
+    header_libs: [
+        "libaudioclient_aidl_conversion_util",
+    ],
+    export_header_lib_headers: [
+        "libaudioclient_aidl_conversion_util",
+    ],
+    host_supported: true,
+    vendor_available: true,
+    double_loadable: true,
+    min_sdk_version: "29",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.bluetooth.updatable",
+        "com.android.media",
+        "com.android.media.swcodec",
+    ],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
diff --git a/OWNERS b/OWNERS
index 8f405e9..7f523a2 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,10 @@
+chz@google.com
 elaurent@google.com
 etalvala@google.com
+hkuang@google.com
 lajos@google.com
 marcone@google.com
+
+# LON
+olly@google.com
+andrewlewis@google.com
diff --git a/aidl/android/media/MicrophoneInfoData.aidl b/aidl/android/media/MicrophoneInfoData.aidl
new file mode 100644
index 0000000..747bfa5
--- /dev/null
+++ b/aidl/android/media/MicrophoneInfoData.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+/**
+ * {@hide}
+ */
+parcelable MicrophoneInfoData {
+    @utf8InCpp String deviceId;
+    int portId;
+    int type;
+    @utf8InCpp String address;
+    int deviceLocation;
+    int deviceGroup;
+    int indexInTheGroup;
+    float[] geometricLocation;
+    float[] orientation;
+    float[] frequencies;
+    float[] frequencyResponses;
+    int[] channelMapping;
+    float sensitivity;
+    float maxSpl;
+    float minSpl;
+    int directionality;
+}
diff --git a/apex/Android.bp b/apex/Android.bp
index fac3831..6ba9cb9 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -31,11 +31,12 @@
                 "libmpeg2extractor",
                 "liboggextractor",
                 "libwavextractor",
-                // JNI
-                "libmediaparser-jni"
             ],
         },
     },
+    // JNI
+    native_shared_libs: ["libmediaparser-jni"],
+    compile_multilib: "both",
     prebuilts: [
         "mediaextractor.policy",
         "code_coverage.policy",
diff --git a/camera/Android.bp b/camera/Android.bp
index b777d74..a9e00d0 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -35,6 +35,7 @@
         "CameraParameters.cpp",
         "CaptureResult.cpp",
         "CameraParameters2.cpp",
+        "CameraSessionStats.cpp",
         "ICamera.cpp",
         "ICameraClient.cpp",
         "ICameraRecordingProxy.cpp",
diff --git a/camera/CameraSessionStats.cpp b/camera/CameraSessionStats.cpp
new file mode 100644
index 0000000..818b4d0
--- /dev/null
+++ b/camera/CameraSessionStats.cpp
@@ -0,0 +1,392 @@
+/*
+ * 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.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "CameraSessionStats"
+#include <utils/Log.h>
+#include <utils/String16.h>
+
+#include <camera/CameraSessionStats.h>
+
+#include <binder/Parcel.h>
+
+namespace android {
+namespace hardware {
+
+status_t CameraStreamStats::readFromParcel(const android::Parcel* parcel) {
+    if (parcel == NULL) {
+        ALOGE("%s: Null parcel", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    status_t err = OK;
+
+    int width = 0;
+    if ((err = parcel->readInt32(&width)) != OK) {
+        ALOGE("%s: Failed to read width from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int height = 0;
+    if ((err = parcel->readInt32(&height)) != OK) {
+        ALOGE("%s: Failed to read height from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int format = 0;
+    if ((err = parcel->readInt32(&format)) != OK) {
+        ALOGE("%s: Failed to read format from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int dataSpace = 0;
+    if ((err = parcel->readInt32(&dataSpace)) != OK) {
+        ALOGE("%s: Failed to read dataSpace from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int64_t usage = 0;
+    if ((err = parcel->readInt64(&usage)) != OK) {
+        ALOGE("%s: Failed to read usage from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int64_t requestCount = 0;
+    if ((err = parcel->readInt64(&requestCount)) != OK) {
+        ALOGE("%s: Failed to read request count from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int64_t errorCount = 0;
+    if ((err = parcel->readInt64(&errorCount)) != OK) {
+        ALOGE("%s: Failed to read error count from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int startLatencyMs = 0;
+    if ((err = parcel->readInt32(&startLatencyMs)) != OK) {
+        ALOGE("%s: Failed to read start latency from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int maxHalBuffers = 0;
+    if ((err = parcel->readInt32(&maxHalBuffers)) != OK) {
+        ALOGE("%s: Failed to read max Hal buffers from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int maxAppBuffers = 0;
+    if ((err = parcel->readInt32(&maxAppBuffers)) != OK) {
+        ALOGE("%s: Failed to read max app buffers from parcel", __FUNCTION__);
+        return err;
+    }
+
+    mWidth = width;
+    mHeight = height;
+    mFormat = format;
+    mDataSpace = dataSpace;
+    mUsage = usage;
+    mRequestCount = requestCount;
+    mErrorCount = errorCount;
+    mStartLatencyMs = startLatencyMs;
+    mMaxHalBuffers = maxHalBuffers;
+    mMaxAppBuffers = maxAppBuffers;
+
+    return OK;
+}
+
+status_t CameraStreamStats::writeToParcel(android::Parcel* parcel) const {
+    if (parcel == NULL) {
+        ALOGE("%s: Null parcel", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    status_t err = OK;
+
+    if ((err = parcel->writeInt32(mWidth)) != OK) {
+        ALOGE("%s: Failed to write stream width!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mHeight)) != OK) {
+        ALOGE("%s: Failed to write stream height!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mFormat)) != OK) {
+        ALOGE("%s: Failed to write stream format!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mDataSpace)) != OK) {
+        ALOGE("%s: Failed to write stream dataSpace!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt64(mUsage)) != OK) {
+        ALOGE("%s: Failed to write stream usage!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt64(mRequestCount)) != OK) {
+        ALOGE("%s: Failed to write stream request count!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt64(mErrorCount)) != OK) {
+        ALOGE("%s: Failed to write stream error count!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mStartLatencyMs)) != OK) {
+        ALOGE("%s: Failed to write stream start latency!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mMaxHalBuffers)) != OK) {
+        ALOGE("%s: Failed to write max hal buffers", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mMaxAppBuffers)) != OK) {
+        ALOGE("%s: Failed to write max app buffers", __FUNCTION__);
+        return err;
+    }
+
+    return OK;
+}
+
+const int CameraSessionStats::CAMERA_STATE_OPEN = 0;
+const int CameraSessionStats::CAMERA_STATE_ACTIVE = 1;
+const int CameraSessionStats::CAMERA_STATE_IDLE = 2;
+const int CameraSessionStats::CAMERA_STATE_CLOSED = 3;
+
+const int CameraSessionStats::CAMERA_FACING_BACK = 0;
+const int CameraSessionStats::CAMERA_FACING_FRONT = 1;
+const int CameraSessionStats::CAMERA_FACING_EXTERNAL = 2;
+
+const int CameraSessionStats::CAMERA_API_LEVEL_1 = 1;
+const int CameraSessionStats::CAMERA_API_LEVEL_2 = 2;
+
+CameraSessionStats::CameraSessionStats() :
+        mFacing(CAMERA_FACING_BACK),
+        mNewCameraState(CAMERA_STATE_CLOSED),
+        mApiLevel(0),
+        mIsNdk(false),
+        mLatencyMs(-1),
+        mSessionType(0),
+        mInternalReconfigure(0),
+        mRequestCount(0),
+        mResultErrorCount(0),
+        mDeviceError(false) {}
+
+CameraSessionStats::CameraSessionStats(const String16& cameraId,
+        int facing, int newCameraState, const String16& clientName,
+        int apiLevel, bool isNdk, int32_t latencyMs) :
+                mCameraId(cameraId),
+                mFacing(facing),
+                mNewCameraState(newCameraState),
+                mClientName(clientName),
+                mApiLevel(apiLevel),
+                mIsNdk(isNdk),
+                mLatencyMs(latencyMs),
+                mSessionType(0),
+                mInternalReconfigure(0),
+                mRequestCount(0),
+                mResultErrorCount(0),
+                mDeviceError(0) {}
+
+status_t CameraSessionStats::readFromParcel(const android::Parcel* parcel) {
+    if (parcel == NULL) {
+        ALOGE("%s: Null parcel", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    status_t err = OK;
+
+    String16 id;
+    if ((err = parcel->readString16(&id)) != OK) {
+        ALOGE("%s: Failed to read camera id!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    int facing = 0;
+    if ((err = parcel->readInt32(&facing)) != OK) {
+        ALOGE("%s: Failed to read camera facing from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int32_t newCameraState;
+    if ((err = parcel->readInt32(&newCameraState)) != OK) {
+        ALOGE("%s: Failed to read new camera state from parcel", __FUNCTION__);
+        return err;
+    }
+
+    String16 clientName;
+    if ((err = parcel->readString16(&clientName)) != OK) {
+        ALOGE("%s: Failed to read client name!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    int32_t apiLevel;
+    if ((err = parcel->readInt32(&apiLevel)) != OK) {
+        ALOGE("%s: Failed to read api level from parcel", __FUNCTION__);
+        return err;
+    }
+
+    bool isNdk;
+    if ((err = parcel->readBool(&isNdk)) != OK) {
+        ALOGE("%s: Failed to read isNdk flag from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int32_t latencyMs;
+    if ((err = parcel->readInt32(&latencyMs)) != OK) {
+        ALOGE("%s: Failed to read latencyMs from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int32_t sessionType;
+    if ((err = parcel->readInt32(&sessionType)) != OK) {
+        ALOGE("%s: Failed to read session type from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int32_t internalReconfigure;
+    if ((err = parcel->readInt32(&internalReconfigure)) != OK) {
+        ALOGE("%s: Failed to read internal reconfigure count from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int64_t requestCount;
+    if ((err = parcel->readInt64(&requestCount)) != OK) {
+        ALOGE("%s: Failed to read request count from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int64_t resultErrorCount;
+    if ((err = parcel->readInt64(&resultErrorCount)) != OK) {
+        ALOGE("%s: Failed to read result error count from parcel", __FUNCTION__);
+        return err;
+    }
+
+    bool deviceError;
+    if ((err = parcel->readBool(&deviceError)) != OK) {
+        ALOGE("%s: Failed to read device error flag from parcel", __FUNCTION__);
+        return err;
+    }
+
+    std::vector<CameraStreamStats> streamStats;
+    if ((err = parcel->readParcelableVector(&streamStats)) != OK) {
+        ALOGE("%s: Failed to read stream state from parcel", __FUNCTION__);
+        return err;
+    }
+
+    mCameraId = id;
+    mFacing = facing;
+    mNewCameraState = newCameraState;
+    mClientName = clientName;
+    mApiLevel = apiLevel;
+    mIsNdk = isNdk;
+    mLatencyMs = latencyMs;
+    mSessionType = sessionType;
+    mInternalReconfigure = internalReconfigure;
+    mRequestCount = requestCount;
+    mResultErrorCount = resultErrorCount;
+    mDeviceError = deviceError;
+    mStreamStats = std::move(streamStats);
+
+    return OK;
+}
+
+status_t CameraSessionStats::writeToParcel(android::Parcel* parcel) const {
+    if (parcel == NULL) {
+        ALOGE("%s: Null parcel", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    status_t err = OK;
+
+    if ((err = parcel->writeString16(mCameraId)) != OK) {
+        ALOGE("%s: Failed to write camera id!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mFacing)) != OK) {
+        ALOGE("%s: Failed to write camera facing!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mNewCameraState)) != OK) {
+        ALOGE("%s: Failed to write new camera state!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeString16(mClientName)) != OK) {
+        ALOGE("%s: Failed to write client name!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mApiLevel)) != OK) {
+        ALOGE("%s: Failed to write api level!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeBool(mIsNdk)) != OK) {
+        ALOGE("%s: Failed to write isNdk flag!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mLatencyMs)) != OK) {
+        ALOGE("%s: Failed to write latency in Ms!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mSessionType)) != OK) {
+        ALOGE("%s: Failed to write session type!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt32(mInternalReconfigure)) != OK) {
+        ALOGE("%s: Failed to write internal reconfigure count!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt64(mRequestCount)) != OK) {
+        ALOGE("%s: Failed to write request count!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeInt64(mResultErrorCount)) != OK) {
+        ALOGE("%s: Failed to write result error count!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeBool(mDeviceError)) != OK) {
+        ALOGE("%s: Failed to write device error flag!", __FUNCTION__);
+        return err;
+    }
+
+    if ((err = parcel->writeParcelableVector(mStreamStats)) != OK) {
+        ALOGE("%s: Failed to write stream states!", __FUNCTION__);
+        return err;
+    }
+
+    return OK;
+}
+
+} // namespace hardware
+} // namesmpace android
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/camera/aidl/android/hardware/CameraSessionStats.aidl
similarity index 76%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to camera/aidl/android/hardware/CameraSessionStats.aidl
index d6e46cb..a8e6774 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/camera/aidl/android/hardware/CameraSessionStats.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.hardware;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/** @hide */
+parcelable CameraSessionStats cpp_header "camera/CameraSessionStats.h";
diff --git a/camera/aidl/android/hardware/ICameraServiceProxy.aidl b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
index 7575948..d428b4e 100644
--- a/camera/aidl/android/hardware/ICameraServiceProxy.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
@@ -16,11 +16,11 @@
 
 package android.hardware;
 
+import android.hardware.CameraSessionStats;
+
 /**
  * Binder interface for the camera service proxy running in system_server.
  *
- * Keep in sync with frameworks/av/include/camera/ICameraServiceProxy.h
- *
  * @hide
  */
 interface ICameraServiceProxy
@@ -30,30 +30,9 @@
      */
     oneway void pingForUserUpdate();
 
-    /**
-     * Values for notifyCameraState newCameraState
-     */
-    const int CAMERA_STATE_OPEN = 0;
-    const int CAMERA_STATE_ACTIVE = 1;
-    const int CAMERA_STATE_IDLE = 2;
-    const int CAMERA_STATE_CLOSED = 3;
-
-    /**
-     * Values for notifyCameraState facing
-     */
-    const int CAMERA_FACING_BACK = 0;
-    const int CAMERA_FACING_FRONT = 1;
-    const int CAMERA_FACING_EXTERNAL = 2;
-
-    /**
-     * Values for notifyCameraState api level
-     */
-     const int CAMERA_API_LEVEL_1 = 1;
-     const int CAMERA_API_LEVEL_2 = 2;
 
     /**
      * Update the status of a camera device.
      */
-    oneway void notifyCameraState(String cameraId, int facing, int newCameraState,
-            String clientName, int apiLevel);
+    oneway void notifyCameraState(in CameraSessionStats cameraSessionStats);
 }
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
index b183ccc..28a57bd 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -83,9 +83,11 @@
      * @param operatingMode The kind of session to create; either NORMAL_MODE or
      *     CONSTRAINED_HIGH_SPEED_MODE. Must be a non-negative value.
      * @param sessionParams Session wide camera parameters
+     * @param startTimeMs The timestamp of session creation start, measured by
+     *                    SystemClock.uptimeMillis.
      * @return a list of stream ids that can be used in offline mode via "switchToOffline"
      */
-    int[] endConfigure(int operatingMode, in CameraMetadataNative sessionParams);
+    int[] endConfigure(int operatingMode, in CameraMetadataNative sessionParams, long startTimeMs);
 
     /**
       * Check whether a particular session configuration has camera device
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index 09a333b..5c3e3b0 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -37,7 +37,7 @@
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.4",
     ],
-    compile_multilib: "prefer32",
+    compile_multilib: "first",
     cflags: [
         "-Wall",
         "-Wextra",
@@ -48,6 +48,6 @@
     init_rc: ["cameraserver.rc"],
 
     vintf_fragments: [
-        "manifest_android.frameworks.cameraservice.service@2.1.xml",
+        "manifest_android.frameworks.cameraservice.service@2.2.xml",
     ],
 }
diff --git a/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.1.xml b/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.2.xml
similarity index 90%
rename from camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.1.xml
rename to camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.2.xml
index 5a15b35..eeafc91 100644
--- a/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.1.xml
+++ b/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.2.xml
@@ -2,7 +2,7 @@
     <hal>
         <name>android.frameworks.cameraservice.service</name>
         <transport>hwbinder</transport>
-        <version>2.1</version>
+        <version>2.2</version>
         <interface>
             <name>ICameraService</name>
             <instance>default</instance>
diff --git a/camera/include/camera/CameraSessionStats.h b/camera/include/camera/CameraSessionStats.h
new file mode 100644
index 0000000..27a756f
--- /dev/null
+++ b/camera/include/camera/CameraSessionStats.h
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA_SERVICE_SESSION_STATS_H
+#define ANDROID_HARDWARE_CAMERA_SERVICE_SESSION_STATS_H
+
+#include <binder/Parcelable.h>
+
+namespace android {
+namespace hardware {
+
+/**
+ * Camera stream info and statistics
+ */
+class CameraStreamStats : public android::Parcelable {
+public:
+    int mWidth;
+    int mHeight;
+    int mFormat;
+    int mDataSpace;
+    int64_t mUsage;
+
+    // The number of requested buffers
+    int64_t mRequestCount;
+    // The number of buffer errors
+    int64_t mErrorCount;
+
+    // The capture latency of 1st request for this stream
+    int32_t mStartLatencyMs;
+
+    // Buffer count info
+    int mMaxHalBuffers;
+    int mMaxAppBuffers;
+
+    CameraStreamStats() :
+            mWidth(0), mHeight(0), mFormat(0), mDataSpace(0), mUsage(0),
+            mRequestCount(0), mErrorCount(0), mStartLatencyMs(0),
+            mMaxHalBuffers(0), mMaxAppBuffers(0) {}
+    CameraStreamStats(int width, int height, int format, int dataSpace, int64_t usage,
+            int maxHalBuffers, int maxAppBuffers)
+            : mWidth(width), mHeight(height), mFormat(format), mDataSpace(dataSpace),
+              mUsage(usage), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0),
+              mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers) {}
+
+    virtual status_t readFromParcel(const android::Parcel* parcel) override;
+    virtual status_t writeToParcel(android::Parcel* parcel) const override;
+};
+
+/**
+ * Camera session statistics
+ *
+ * This includes session wide info and stream statistics.
+ */
+class CameraSessionStats : public android::Parcelable {
+public:
+    /**
+     * Values for notifyCameraState newCameraState
+     */
+    static const int CAMERA_STATE_OPEN;
+    static const int CAMERA_STATE_ACTIVE;
+    static const int CAMERA_STATE_IDLE;
+    static const int CAMERA_STATE_CLOSED;
+
+    /**
+     * Values for notifyCameraState facing
+     */
+    static const int CAMERA_FACING_BACK;
+    static const int CAMERA_FACING_FRONT;
+    static const int CAMERA_FACING_EXTERNAL;
+
+    /**
+     * Values for notifyCameraState api level
+     */
+    static const int CAMERA_API_LEVEL_1;
+    static const int CAMERA_API_LEVEL_2;
+
+    String16 mCameraId;
+    int mFacing;
+    int mNewCameraState;
+    String16 mClientName;
+    int mApiLevel;
+    bool mIsNdk;
+    // latency in ms for camera open, close, or session creation.
+    int mLatencyMs;
+
+    // Session info and statistics
+    int mSessionType;
+    int mInternalReconfigure;
+    // The number of capture requests
+    int64_t mRequestCount;
+    // The number of result error
+    int64_t mResultErrorCount;
+    // Whether the device runs into an error state
+    bool mDeviceError;
+    std::vector<CameraStreamStats> mStreamStats;
+
+    // Constructors
+    CameraSessionStats();
+    CameraSessionStats(const String16& cameraId, int facing, int newCameraState,
+            const String16& clientName, int apiLevel, bool isNdk, int32_t latencyMs);
+
+    virtual status_t readFromParcel(const android::Parcel* parcel) override;
+    virtual status_t writeToParcel(android::Parcel* parcel) const override;
+};
+
+}; // namespace hardware
+}; // namespace android
+
+#endif // ANDROID_HARDWARE_CAMERA_SERVICE_SESSION_STATS_H
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 7ba82c1..3cf94d0 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -121,9 +121,11 @@
         "libcamera_metadata",
         "libmediandk",
         "android.frameworks.cameraservice.device@2.0",
+        "android.frameworks.cameraservice.device@2.1",
         "android.frameworks.cameraservice.common@2.0",
         "android.frameworks.cameraservice.service@2.0",
         "android.frameworks.cameraservice.service@2.1",
+        "android.frameworks.cameraservice.service@2.2",
     ],
     static_libs: [
         "android.hardware.camera.common@1.0-helper",
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index c15c5a5..08c88ce 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -186,6 +186,7 @@
         const ACaptureRequest* sessionParameters,
         const ACameraCaptureSession_stateCallbacks* callbacks,
         /*out*/ACameraCaptureSession** session) {
+    nsecs_t startTimeNs = systemTime();
     sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
     Mutex::Autolock _l(mDeviceLock);
     camera_status_t ret = checkCameraClosedOrErrorLocked();
@@ -199,7 +200,7 @@
     }
 
     // Create new session
-    ret = configureStreamsLocked(outputs, sessionParameters);
+    ret = configureStreamsLocked(outputs, sessionParameters, startTimeNs);
     if (ret != ACAMERA_OK) {
         ALOGE("Fail to create new session. cannot configure streams");
         return ret;
@@ -450,7 +451,11 @@
     }
 
     // No new session, unconfigure now
-    camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
+    // Note: The unconfiguration of session won't be accounted for session
+    // latency because a stream configuration with 0 streams won't ever become
+    // active.
+    nsecs_t startTimeNs = systemTime();
+    camera_status_t ret = configureStreamsLocked(nullptr, nullptr, startTimeNs);
     if (ret != ACAMERA_OK) {
         ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
     }
@@ -609,7 +614,7 @@
 
 camera_status_t
 CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
-        const ACaptureRequest* sessionParameters) {
+        const ACaptureRequest* sessionParameters, nsecs_t startTimeNs) {
     ACaptureSessionOutputContainer emptyOutput;
     if (outputs == nullptr) {
         outputs = &emptyOutput;
@@ -711,7 +716,8 @@
         params.append(sessionParameters->settings->getInternalData());
     }
     std::vector<int> offlineStreamIds;
-    remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params, &offlineStreamIds);
+    remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params,
+            ns2ms(startTimeNs), &offlineStreamIds);
     if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
         ALOGE("Camera device %s cannnot support app output configuration: %s", getId(),
                 remoteRet.toString8().string());
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index d937865..125e6e3 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -167,7 +167,7 @@
     void notifySessionEndOfLifeLocked(ACameraCaptureSession* session);
 
     camera_status_t configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
-           const ACaptureRequest* sessionParameters);
+           const ACaptureRequest* sessionParameters, nsecs_t startTimeNs);
 
     // Input message will be posted and cleared after this returns
     void postSessionMsgAndCleanup(sp<AMessage>& msg);
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 2d54bd1..6b912f1 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -1957,7 +1957,10 @@
      * explicitly set ACAMERA_CONTROL_ZOOM_RATIO, its value defaults to 1.0.</p>
      * <p>One limitation of controlling zoom using zoomRatio is that the ACAMERA_SCALER_CROP_REGION
      * must only be used for letterboxing or pillarboxing of the sensor active array, and no
-     * FREEFORM cropping can be used with ACAMERA_CONTROL_ZOOM_RATIO other than 1.0.</p>
+     * FREEFORM cropping can be used with ACAMERA_CONTROL_ZOOM_RATIO other than 1.0. If
+     * ACAMERA_CONTROL_ZOOM_RATIO is not 1.0, and ACAMERA_SCALER_CROP_REGION is set to be
+     * windowboxing, the camera framework will override the ACAMERA_SCALER_CROP_REGION to be
+     * the active array.</p>
      *
      * @see ACAMERA_CONTROL_AE_REGIONS
      * @see ACAMERA_CONTROL_ZOOM_RATIO
@@ -3651,7 +3654,9 @@
      * </ol>
      * </li>
      * <li>Setting ACAMERA_CONTROL_ZOOM_RATIO to values different than 1.0 and
-     * ACAMERA_SCALER_CROP_REGION to be windowboxing at the same time is undefined behavior.</li>
+     * ACAMERA_SCALER_CROP_REGION to be windowboxing at the same time are not supported. In this
+     * case, the camera framework will override the ACAMERA_SCALER_CROP_REGION to be the active
+     * array.</li>
      * </ul>
      * <p>LEGACY capability devices will only support CENTER_ONLY cropping.</p>
      *
@@ -8517,10 +8522,10 @@
      * respective color channel provided in
      * ACAMERA_SENSOR_TEST_PATTERN_DATA.</p>
      * <p>For example:</p>
-     * <pre><code>android.testPatternData = [0, 0xFFFFFFFF, 0xFFFFFFFF, 0]
+     * <pre><code>android.control.testPatternData = [0, 0xFFFFFFFF, 0xFFFFFFFF, 0]
      * </code></pre>
      * <p>All green pixels are 100% green. All red/blue pixels are black.</p>
-     * <pre><code>android.testPatternData = [0xFFFFFFFF, 0, 0xFFFFFFFF, 0]
+     * <pre><code>android.control.testPatternData = [0xFFFFFFFF, 0, 0xFFFFFFFF, 0]
      * </code></pre>
      * <p>All red pixels are 100% red. Only the odd green pixels
      * are 100% green. All blue pixels are 100% black.</p>
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index 0fcb700..9f63099 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -180,6 +180,7 @@
         const ACaptureRequest* sessionParameters,
         const ACameraCaptureSession_stateCallbacks* callbacks,
         /*out*/ACameraCaptureSession** session) {
+    nsecs_t startTimeNs = systemTime();
     sp<ACameraCaptureSession> currentSession = mCurrentSession.promote();
     Mutex::Autolock _l(mDeviceLock);
     camera_status_t ret = checkCameraClosedOrErrorLocked();
@@ -193,7 +194,7 @@
     }
 
     // Create new session
-    ret = configureStreamsLocked(outputs, sessionParameters);
+    ret = configureStreamsLocked(outputs, sessionParameters, startTimeNs);
     if (ret != ACAMERA_OK) {
         ALOGE("Fail to create new session. cannot configure streams");
         return ret;
@@ -472,7 +473,11 @@
     }
 
     // No new session, unconfigure now
-    camera_status_t ret = configureStreamsLocked(nullptr, nullptr);
+    // Note: The unconfiguration of session won't be accounted for session
+    // latency because a stream configuration with 0 streams won't ever become
+    // active.
+    nsecs_t startTimeNs = systemTime();
+    camera_status_t ret = configureStreamsLocked(nullptr, nullptr, startTimeNs);
     if (ret != ACAMERA_OK) {
         ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret);
     }
@@ -598,7 +603,7 @@
 
 camera_status_t
 CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
-        const ACaptureRequest* sessionParameters) {
+        const ACaptureRequest* sessionParameters, nsecs_t startTimeNs) {
     ACaptureSessionOutputContainer emptyOutput;
     if (outputs == nullptr) {
         outputs = &emptyOutput;
@@ -697,7 +702,8 @@
         utils::convertToHidl(params_metadata, &hidlParams);
         params.unlock(params_metadata);
     }
-    remoteRet = mRemote->endConfigure(StreamConfigurationMode::NORMAL_MODE, hidlParams);
+    remoteRet = mRemote->endConfigure_2_1(StreamConfigurationMode::NORMAL_MODE,
+                                          hidlParams, startTimeNs);
     CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "endConfigure()")
     return ACAMERA_OK;
 }
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.h b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
index 7fc699e..0b6c7c8 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
@@ -26,7 +26,7 @@
 #include <utils/Mutex.h>
 #include <utils/List.h>
 #include <utils/Vector.h>
-#include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
+#include <android/frameworks/cameraservice/device/2.1/ICameraDeviceUser.h>
 #include <android/frameworks/cameraservice/device/2.0/ICameraDeviceCallback.h>
 #include <android/frameworks/cameraservice/device/2.0/types.h>
 #include <fmq/MessageQueue.h>
@@ -44,7 +44,8 @@
 namespace acam {
 
 using ICameraDeviceCallback = frameworks::cameraservice::device::V2_0::ICameraDeviceCallback;
-using ICameraDeviceUser = frameworks::cameraservice::device::V2_0::ICameraDeviceUser;
+using ICameraDeviceUser_2_0 = frameworks::cameraservice::device::V2_0::ICameraDeviceUser;
+using ICameraDeviceUser = frameworks::cameraservice::device::V2_1::ICameraDeviceUser;
 using CaptureResultExtras = frameworks::cameraservice::device::V2_0::CaptureResultExtras;
 using PhysicalCaptureResultInfo = frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo;
 using PhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
@@ -201,7 +202,7 @@
     void notifySessionEndOfLifeLocked(ACameraCaptureSession* session);
 
     camera_status_t configureStreamsLocked(const ACaptureSessionOutputContainer* outputs,
-           const ACaptureRequest* sessionParameters);
+           const ACaptureRequest* sessionParameters, nsecs_t startTimeNs);
 
     // Input message will be posted and cleared after this returns
     void postSessionMsgAndCleanup(sp<AMessage>& msg);
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index 5aa9c46..77c934a 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -764,15 +764,15 @@
     }
 
     sp<ICameraDeviceCallback> callbacks = device->getServiceCallback();
-    sp<ICameraDeviceUser> deviceRemote;
+    sp<ICameraDeviceUser_2_0> deviceRemote_2_0;
 
     // No way to get package name from native.
     // Send a zero length package name and let camera service figure it out from UID
     Status status = Status::NO_ERROR;
     auto serviceRet = cs->connectDevice(
-            callbacks, cameraId, [&status, &deviceRemote](auto s, auto &device) {
+            callbacks, cameraId, [&status, &deviceRemote_2_0](auto s, auto &device) {
                                      status = s;
-                                     deviceRemote = device;
+                                     deviceRemote_2_0 = device;
                                  });
 
     if (!serviceRet.isOk() || status != Status::NO_ERROR) {
@@ -780,11 +780,18 @@
         delete device;
         return utils::convertFromHidl(status);
     }
-    if (deviceRemote == nullptr) {
+    if (deviceRemote_2_0 == nullptr) {
         ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
         delete device;
         return ACAMERA_ERROR_CAMERA_DISCONNECTED;
     }
+    auto castResult = ICameraDeviceUser::castFrom(deviceRemote_2_0);
+    if (!castResult.isOk()) {
+        ALOGE("%s: failed to cast remote device to version 2.1", __FUNCTION__);
+        delete device;
+        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
+    }
+    sp<ICameraDeviceUser> deviceRemote = castResult;
     device->setRemoteDevice(deviceRemote);
     device->setDeviceMetadataQueues();
     *outDevice = device;
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index 85da3e9..8359bb1 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -22,6 +22,7 @@
 #include <android-base/parseint.h>
 #include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
 #include <android/frameworks/cameraservice/service/2.1/ICameraService.h>
+#include <android/frameworks/cameraservice/service/2.2/ICameraService.h>
 #include <android/frameworks/cameraservice/service/2.1/ICameraServiceListener.h>
 
 #include <CameraMetadata.h>
@@ -38,7 +39,7 @@
 namespace android {
 namespace acam {
 
-using ICameraService = frameworks::cameraservice::service::V2_1::ICameraService;
+using ICameraService = frameworks::cameraservice::service::V2_2::ICameraService;
 using CameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
 using ICameraServiceListener = frameworks::cameraservice::service::V2_1::ICameraServiceListener;
 using PhysicalCameraStatusAndId = frameworks::cameraservice::service::V2_1::PhysicalCameraStatusAndId;
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index eee05ff..0cf390f 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -517,7 +517,7 @@
         CameraMetadata sessionParams;
         std::vector<int> offlineStreamIds;
         res = device->endConfigure(/*isConstrainedHighSpeed*/ false, sessionParams,
-                &offlineStreamIds);
+                ns2ms(systemTime()), &offlineStreamIds);
         EXPECT_TRUE(res.isOk()) << res;
         EXPECT_FALSE(callbacks->hadError());
 
@@ -629,7 +629,7 @@
         res = device->deleteStream(streamId);
         EXPECT_TRUE(res.isOk()) << res;
         res = device->endConfigure(/*isConstrainedHighSpeed*/ false, sessionParams,
-                &offlineStreamIds);
+                ns2ms(systemTime()), &offlineStreamIds);
         EXPECT_TRUE(res.isOk()) << res;
 
         sleep(/*second*/1); // allow some time for errors to show up, if any
diff --git a/cmds/stagefright/SimplePlayer.cpp b/cmds/stagefright/SimplePlayer.cpp
index f4b8164..e000633 100644
--- a/cmds/stagefright/SimplePlayer.cpp
+++ b/cmds/stagefright/SimplePlayer.cpp
@@ -272,7 +272,7 @@
 status_t SimplePlayer::onPrepare() {
     CHECK_EQ(mState, UNPREPARED);
 
-    mExtractor = new NuMediaExtractor;
+    mExtractor = new NuMediaExtractor(NuMediaExtractor::EntryPoint::OTHER);
 
     status_t err = mExtractor->setDataSource(
             NULL /* httpService */, mPath.c_str());
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index c26e0b9..33c4663 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -79,7 +79,7 @@
 
     static int64_t kTimeout = 500ll;
 
-    sp<NuMediaExtractor> extractor = new NuMediaExtractor;
+    sp<NuMediaExtractor> extractor = new NuMediaExtractor(NuMediaExtractor::EntryPoint::OTHER);
     if (extractor->setDataSource(NULL /* httpService */, path) != OK) {
         fprintf(stderr, "unable to instantiate extractor.\n");
         return 1;
diff --git a/cmds/stagefright/mediafilter.cpp b/cmds/stagefright/mediafilter.cpp
index b894545..ca058ab 100644
--- a/cmds/stagefright/mediafilter.cpp
+++ b/cmds/stagefright/mediafilter.cpp
@@ -319,7 +319,8 @@
 
     static int64_t kTimeout = 500ll;
 
-    sp<NuMediaExtractor> extractor = new NuMediaExtractor;
+    sp<NuMediaExtractor> extractor = new NuMediaExtractor(NuMediaExtractor::EntryPoint::OTHER);
+
     if (extractor->setDataSource(NULL /* httpService */, path) != OK) {
         fprintf(stderr, "unable to instantiate extractor.\n");
         return 1;
diff --git a/cmds/stagefright/muxer.cpp b/cmds/stagefright/muxer.cpp
index 4a83a4a..bc7e41e 100644
--- a/cmds/stagefright/muxer.cpp
+++ b/cmds/stagefright/muxer.cpp
@@ -62,7 +62,7 @@
         int trimEndTimeMs,
         int rotationDegrees,
         MediaMuxer::OutputFormat container = MediaMuxer::OUTPUT_FORMAT_MPEG_4) {
-    sp<NuMediaExtractor> extractor = new NuMediaExtractor;
+    sp<NuMediaExtractor> extractor = new NuMediaExtractor(NuMediaExtractor::EntryPoint::OTHER);
     if (extractor->setDataSource(NULL /* httpService */, path) != OK) {
         fprintf(stderr, "unable to instantiate extractor. %s\n", path);
         return 1;
diff --git a/drm/TEST_MAPPING b/drm/TEST_MAPPING
index 9f6a532..aa8a7d8 100644
--- a/drm/TEST_MAPPING
+++ b/drm/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     // The following tests validate codec and drm path.
     {
       "name": "GtsMediaTestCases",
diff --git a/drm/libmediadrm/protos/Android.bp b/drm/libmediadrm/protos/Android.bp
new file mode 100644
index 0000000..b26cda4
--- /dev/null
+++ b/drm/libmediadrm/protos/Android.bp
@@ -0,0 +1,38 @@
+// 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.
+
+// This is the version of the drm metrics configured for protobuf full on host.
+// It is used by the metrics_dump tool.
+
+cc_library_host_shared {
+    name: "libdrm_metrics_protos_full_host",
+    vendor_available: true,
+
+    include_dirs: ["external/protobuf/src"],
+
+    srcs: [
+        "metrics.proto",
+    ],
+
+    proto: {
+        export_proto_headers: true,
+        type: "full",
+    },
+
+    cflags: [
+        // Suppress unused parameter error. This error occurs
+        // when using the map type in a proto definition.
+        "-Wno-unused-parameter",
+    ],
+}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp b/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp
index 2dcd00f..051a968 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp
@@ -15,7 +15,7 @@
 namespace clearkey {
 
 std::string MemoryFileSystem::GetFileName(const std::string& path) {
-    size_t index = path.find_last_of("/");
+    size_t index = path.find_last_of('/');
     if (index != std::string::npos) {
         return path.substr(index+1);
     } else {
diff --git a/include/media/MicrophoneInfo.h b/include/media/MicrophoneInfo.h
index 2287aca..a5045b9 100644
--- a/include/media/MicrophoneInfo.h
+++ b/include/media/MicrophoneInfo.h
@@ -17,33 +17,24 @@
 #ifndef ANDROID_MICROPHONE_INFO_H
 #define ANDROID_MICROPHONE_INFO_H
 
+#include <android/media/MicrophoneInfoData.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
+#include <media/AidlConversionUtil.h>
 #include <system/audio.h>
-#include <utils/String16.h>
-#include <utils/Vector.h>
 
 namespace android {
 namespace media {
 
-#define RETURN_IF_FAILED(calledOnce)                                     \
-    {                                                                    \
-        status_t returnStatus = calledOnce;                              \
-        if (returnStatus) {                                              \
-            ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
-            return returnStatus;                                         \
-         }                                                               \
-    }
-
 class MicrophoneInfo : public Parcelable {
 public:
     MicrophoneInfo() = default;
     MicrophoneInfo(const MicrophoneInfo& microphoneInfo) = default;
     MicrophoneInfo(audio_microphone_characteristic_t& characteristic) {
-        mDeviceId = String16(&characteristic.device_id[0]);
+        mDeviceId = std::string(&characteristic.device_id[0]);
         mPortId = characteristic.id;
         mType = characteristic.device;
-        mAddress = String16(&characteristic.address[0]);
+        mAddress = std::string(&characteristic.address[0]);
         mDeviceLocation = characteristic.location;
         mDeviceGroup = characteristic.group;
         mIndexInTheGroup = characteristic.index_in_the_group;
@@ -53,8 +44,8 @@
         mOrientation.push_back(characteristic.orientation.x);
         mOrientation.push_back(characteristic.orientation.y);
         mOrientation.push_back(characteristic.orientation.z);
-        Vector<float> frequencies;
-        Vector<float> responses;
+        std::vector<float> frequencies;
+        std::vector<float> responses;
         for (size_t i = 0; i < characteristic.num_frequency_responses; i++) {
             frequencies.push_back(characteristic.frequency_responses[0][i]);
             responses.push_back(characteristic.frequency_responses[1][i]);
@@ -73,76 +64,73 @@
     virtual ~MicrophoneInfo() = default;
 
     virtual status_t writeToParcel(Parcel* parcel) const {
-        RETURN_IF_FAILED(parcel->writeString16(mDeviceId));
-        RETURN_IF_FAILED(parcel->writeInt32(mPortId));
-        RETURN_IF_FAILED(parcel->writeUint32(mType));
-        RETURN_IF_FAILED(parcel->writeString16(mAddress));
-        RETURN_IF_FAILED(parcel->writeInt32(mDeviceLocation));
-        RETURN_IF_FAILED(parcel->writeInt32(mDeviceGroup));
-        RETURN_IF_FAILED(parcel->writeInt32(mIndexInTheGroup));
-        RETURN_IF_FAILED(writeFloatVector(parcel, mGeometricLocation));
-        RETURN_IF_FAILED(writeFloatVector(parcel, mOrientation));
+        MicrophoneInfoData parcelable;
+        return writeToParcelable(&parcelable)
+               ?: parcelable.writeToParcel(parcel);
+    }
+
+    virtual status_t writeToParcelable(MicrophoneInfoData* parcelable) const {
+        parcelable->deviceId = mDeviceId;
+        parcelable->portId = mPortId;
+        parcelable->type = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(mType));
+        parcelable->address = mAddress;
+        parcelable->deviceGroup = mDeviceGroup;
+        parcelable->indexInTheGroup = mIndexInTheGroup;
+        parcelable->geometricLocation = mGeometricLocation;
+        parcelable->orientation = mOrientation;
         if (mFrequencyResponses.size() != 2) {
             return BAD_VALUE;
         }
-        for (size_t i = 0; i < mFrequencyResponses.size(); i++) {
-            RETURN_IF_FAILED(parcel->writeInt32(mFrequencyResponses[i].size()));
-            RETURN_IF_FAILED(writeFloatVector(parcel, mFrequencyResponses[i]));
-        }
-        std::vector<int> channelMapping;
-        for (size_t i = 0; i < mChannelMapping.size(); ++i) {
-            channelMapping.push_back(mChannelMapping[i]);
-        }
-        RETURN_IF_FAILED(parcel->writeInt32Vector(channelMapping));
-        RETURN_IF_FAILED(parcel->writeFloat(mSensitivity));
-        RETURN_IF_FAILED(parcel->writeFloat(mMaxSpl));
-        RETURN_IF_FAILED(parcel->writeFloat(mMinSpl));
-        RETURN_IF_FAILED(parcel->writeInt32(mDirectionality));
+        parcelable->frequencies = mFrequencyResponses[0];
+        parcelable->frequencyResponses = mFrequencyResponses[1];
+        parcelable->channelMapping = mChannelMapping;
+        parcelable->sensitivity = mSensitivity;
+        parcelable->maxSpl = mMaxSpl;
+        parcelable->minSpl = mMinSpl;
+        parcelable->directionality = mDirectionality;
         return OK;
     }
 
     virtual status_t readFromParcel(const Parcel* parcel) {
-        RETURN_IF_FAILED(parcel->readString16(&mDeviceId));
-        RETURN_IF_FAILED(parcel->readInt32(&mPortId));
-        RETURN_IF_FAILED(parcel->readUint32(&mType));
-        RETURN_IF_FAILED(parcel->readString16(&mAddress));
-        RETURN_IF_FAILED(parcel->readInt32(&mDeviceLocation));
-        RETURN_IF_FAILED(parcel->readInt32(&mDeviceGroup));
-        RETURN_IF_FAILED(parcel->readInt32(&mIndexInTheGroup));
-        RETURN_IF_FAILED(readFloatVector(parcel, &mGeometricLocation, 3));
-        RETURN_IF_FAILED(readFloatVector(parcel, &mOrientation, 3));
-        int32_t frequenciesNum;
-        RETURN_IF_FAILED(parcel->readInt32(&frequenciesNum));
-        Vector<float> frequencies;
-        RETURN_IF_FAILED(readFloatVector(parcel, &frequencies, frequenciesNum));
-        int32_t responsesNum;
-        RETURN_IF_FAILED(parcel->readInt32(&responsesNum));
-        Vector<float> responses;
-        RETURN_IF_FAILED(readFloatVector(parcel, &responses, responsesNum));
-        if (frequencies.size() != responses.size()) {
+        MicrophoneInfoData data;
+        return data.readFromParcel(parcel)
+            ?: readFromParcelable(data);
+    }
+
+    virtual status_t readFromParcelable(const MicrophoneInfoData& parcelable) {
+        mDeviceId = parcelable.deviceId;
+        mPortId = parcelable.portId;
+        mType = VALUE_OR_RETURN_STATUS(convertReinterpret<uint32_t>(parcelable.type));
+        mAddress = parcelable.address;
+        mDeviceLocation = parcelable.deviceLocation;
+        mDeviceGroup = parcelable.deviceGroup;
+        mIndexInTheGroup = parcelable.indexInTheGroup;
+        if (parcelable.geometricLocation.size() != 3) {
             return BAD_VALUE;
         }
-        mFrequencyResponses.push_back(frequencies);
-        mFrequencyResponses.push_back(responses);
-        std::vector<int> channelMapping;
-        status_t result = parcel->readInt32Vector(&channelMapping);
-        if (result != OK) {
-            return result;
-        }
-        if (channelMapping.size() != AUDIO_CHANNEL_COUNT_MAX) {
+        mGeometricLocation = parcelable.geometricLocation;
+        if (parcelable.orientation.size() != 3) {
             return BAD_VALUE;
         }
-        for (size_t i = 0; i < channelMapping.size(); i++) {
-            mChannelMapping.push_back(channelMapping[i]);
+        mOrientation = parcelable.orientation;
+        if (parcelable.frequencies.size() != parcelable.frequencyResponses.size()) {
+            return BAD_VALUE;
         }
-        RETURN_IF_FAILED(parcel->readFloat(&mSensitivity));
-        RETURN_IF_FAILED(parcel->readFloat(&mMaxSpl));
-        RETURN_IF_FAILED(parcel->readFloat(&mMinSpl));
-        RETURN_IF_FAILED(parcel->readInt32(&mDirectionality));
+
+        mFrequencyResponses.push_back(parcelable.frequencies);
+        mFrequencyResponses.push_back(parcelable.frequencyResponses);
+        if (parcelable.channelMapping.size() != AUDIO_CHANNEL_COUNT_MAX) {
+            return BAD_VALUE;
+        }
+        mChannelMapping = parcelable.channelMapping;
+        mSensitivity = parcelable.sensitivity;
+        mMaxSpl = parcelable.maxSpl;
+        mMinSpl = parcelable.minSpl;
+        mDirectionality = parcelable.directionality;
         return OK;
     }
 
-    String16 getDeviceId() const {
+    std::string getDeviceId() const {
         return mDeviceId;
     }
 
@@ -154,7 +142,7 @@
         return mType;
     }
 
-    String16 getAddress() const {
+    std::string getAddress() const {
         return mAddress;
     }
 
@@ -170,19 +158,19 @@
         return mIndexInTheGroup;
     }
 
-    const Vector<float>& getGeometricLocation() const {
+    const std::vector<float>& getGeometricLocation() const {
         return mGeometricLocation;
     }
 
-    const Vector<float>& getOrientation() const {
+    const std::vector<float>& getOrientation() const {
         return mOrientation;
     }
 
-    const Vector<Vector<float>>& getFrequencyResponses() const {
+    const std::vector<std::vector<float>>& getFrequencyResponses() const {
         return mFrequencyResponses;
     }
 
-    const Vector<int>& getChannelMapping() const {
+    const std::vector<int>& getChannelMapping() const {
         return mChannelMapping;
     }
 
@@ -203,46 +191,38 @@
     }
 
 private:
-    status_t readFloatVector(
-            const Parcel* parcel, Vector<float> *vectorPtr, size_t defaultLength) {
-        std::unique_ptr<std::vector<float>> v;
-        status_t result = parcel->readFloatVector(&v);
-        if (result != OK) return result;
-        vectorPtr->clear();
-        if (v.get() != nullptr) {
-            for (const auto& iter : *v) {
-                vectorPtr->push_back(iter);
-            }
-        } else {
-            vectorPtr->resize(defaultLength);
-        }
-        return OK;
-    }
-    status_t writeFloatVector(Parcel* parcel, const Vector<float>& vector) const {
-        std::vector<float> v;
-        for (size_t i = 0; i < vector.size(); i++) {
-            v.push_back(vector[i]);
-        }
-        return parcel->writeFloatVector(v);
-    }
-
-    String16 mDeviceId;
+    std::string mDeviceId;
     int32_t mPortId;
     uint32_t mType;
-    String16 mAddress;
+    std::string mAddress;
     int32_t mDeviceLocation;
     int32_t mDeviceGroup;
     int32_t mIndexInTheGroup;
-    Vector<float> mGeometricLocation;
-    Vector<float> mOrientation;
-    Vector<Vector<float>> mFrequencyResponses;
-    Vector<int> mChannelMapping;
+    std::vector<float> mGeometricLocation;
+    std::vector<float> mOrientation;
+    std::vector<std::vector<float>> mFrequencyResponses;
+    std::vector<int> mChannelMapping;
     float mSensitivity;
     float mMaxSpl;
     float mMinSpl;
     int32_t mDirectionality;
 };
 
+// Conversion routines, according to AidlConversion.h conventions.
+inline ConversionResult<MicrophoneInfo>
+aidl2legacy_MicrophoneInfo(const media::MicrophoneInfoData& aidl) {
+    MicrophoneInfo legacy;
+    RETURN_IF_ERROR(legacy.readFromParcelable(aidl));
+    return legacy;
+}
+
+inline ConversionResult<media::MicrophoneInfoData>
+legacy2aidl_MicrophoneInfo(const MicrophoneInfo& legacy) {
+    media::MicrophoneInfoData aidl;
+    RETURN_IF_ERROR(legacy.writeToParcelable(&aidl));
+    return aidl;
+}
+
 } // namespace media
 } // namespace android
 
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index 50facfb..80e0924 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -1,6 +1,6 @@
 // for frameworks/av/media
 {
-    "presubmit": [
+    "presubmit-large": [
         // runs whenever we change something in this tree
         {
             "name": "CtsMediaTestCases",
@@ -17,7 +17,9 @@
                     "include-filter": "android.media.cts.DecodeEditEncodeTest"
                 }
             ]
-        },
+        }
+    ],
+    "presubmit": [
         {
             "name": "GtsMediaTestCases",
             "options" : [
diff --git a/media/bufferpool/2.0/AccessorImpl.cpp b/media/bufferpool/2.0/AccessorImpl.cpp
index 6111fea..1d2562e 100644
--- a/media/bufferpool/2.0/AccessorImpl.cpp
+++ b/media/bufferpool/2.0/AccessorImpl.cpp
@@ -39,6 +39,8 @@
 
     static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15;
     static constexpr size_t kMinBufferCountForEviction = 25;
+    static constexpr size_t kMaxUnusedBufferCount = 64;
+    static constexpr size_t kUnusedBufferCountTarget = kMaxUnusedBufferCount - 16;
 
     static constexpr nsecs_t kEvictGranularityNs = 1000000000; // 1 sec
     static constexpr nsecs_t kEvictDurationNs = 5000000000; // 5 secs
@@ -724,9 +726,11 @@
 }
 
 void Accessor::Impl::BufferPool::cleanUp(bool clearCache) {
-    if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs) {
+    if (clearCache || mTimestampUs > mLastCleanUpUs + kCleanUpDurationUs ||
+            mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
         mLastCleanUpUs = mTimestampUs;
-        if (mTimestampUs > mLastLogUs + kLogDurationUs) {
+        if (mTimestampUs > mLastLogUs + kLogDurationUs ||
+                mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
             mLastLogUs = mTimestampUs;
             ALOGD("bufferpool2 %p : %zu(%zu size) total buffers - "
                   "%zu(%zu size) used buffers - %zu/%zu (recycle/alloc) - "
@@ -737,8 +741,9 @@
                   mStats.mTotalFetches, mStats.mTotalTransfers);
         }
         for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
-            if (!clearCache && (mStats.mSizeCached < kMinAllocBytesForEviction
-                    || mBuffers.size() < kMinBufferCountForEviction)) {
+            if (!clearCache && mStats.buffersNotInUse() <= kUnusedBufferCountTarget &&
+                    (mStats.mSizeCached < kMinAllocBytesForEviction ||
+                     mBuffers.size() < kMinBufferCountForEviction)) {
                 break;
             }
             auto it = mBuffers.find(*freeIt);
diff --git a/media/bufferpool/2.0/AccessorImpl.h b/media/bufferpool/2.0/AccessorImpl.h
index cd1b4d0..3d39941 100644
--- a/media/bufferpool/2.0/AccessorImpl.h
+++ b/media/bufferpool/2.0/AccessorImpl.h
@@ -193,6 +193,12 @@
                 : mSizeCached(0), mBuffersCached(0), mSizeInUse(0), mBuffersInUse(0),
                   mTotalAllocations(0), mTotalRecycles(0), mTotalTransfers(0), mTotalFetches(0) {}
 
+            /// # of currently unused buffers
+            size_t buffersNotInUse() const {
+                ALOG_ASSERT(mBuffersCached >= mBuffersInUse);
+                return mBuffersCached - mBuffersInUse;
+            }
+
             /// A new buffer is allocated on an allocation request.
             void onBufferAllocated(size_t allocSize) {
                 mSizeCached += allocSize;
diff --git a/media/bufferpool/2.0/BufferPoolClient.cpp b/media/bufferpool/2.0/BufferPoolClient.cpp
index 342fef6..9308b81 100644
--- a/media/bufferpool/2.0/BufferPoolClient.cpp
+++ b/media/bufferpool/2.0/BufferPoolClient.cpp
@@ -32,6 +32,8 @@
 static constexpr int64_t kReceiveTimeoutUs = 1000000; // 100ms
 static constexpr int kPostMaxRetry = 3;
 static constexpr int kCacheTtlUs = 1000000; // TODO: tune
+static constexpr size_t kMaxCachedBufferCount = 64;
+static constexpr size_t kCachedBufferCountTarget = kMaxCachedBufferCount - 16;
 
 class BufferPoolClient::Impl
         : public std::enable_shared_from_this<BufferPoolClient::Impl> {
@@ -136,6 +138,10 @@
             --mActive;
             mLastChangeUs = getTimestampNow();
         }
+
+        int cachedBufferCount() const {
+            return mBuffers.size() - mActive;
+        }
     } mCache;
 
     // FMQ - release notifier
@@ -668,10 +674,12 @@
 // should have mCache.mLock
 void BufferPoolClient::Impl::evictCaches(bool clearCache) {
     int64_t now = getTimestampNow();
-    if (now >= mLastEvictCacheUs + kCacheTtlUs || clearCache) {
+    if (now >= mLastEvictCacheUs + kCacheTtlUs ||
+            clearCache || mCache.cachedBufferCount() > kMaxCachedBufferCount) {
         size_t evicted = 0;
         for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
-            if (!it->second->hasCache() && (it->second->expire() || clearCache)) {
+            if (!it->second->hasCache() && (it->second->expire() ||
+                        clearCache || mCache.cachedBufferCount() > kCachedBufferCountTarget)) {
                 it = mCache.mBuffers.erase(it);
                 ++evicted;
             } else {
diff --git a/media/codec2/TEST_MAPPING b/media/codec2/TEST_MAPPING
index fca3477..6ac4210 100644
--- a/media/codec2/TEST_MAPPING
+++ b/media/codec2/TEST_MAPPING
@@ -4,7 +4,9 @@
     // { "name": "codec2_core_param_test"},
     // TODO(b/155516524)
     // { "name": "codec2_vndk_interface_test"},
-    { "name": "codec2_vndk_test"},
+    { "name": "codec2_vndk_test"}
+  ],
+  "presubmit-large": [
     {
       "name": "CtsMediaTestCases",
       "options": [
diff --git a/media/codec2/components/aac/Android.bp b/media/codec2/components/aac/Android.bp
index 9eca585..50495a9 100644
--- a/media/codec2/components/aac/Android.bp
+++ b/media/codec2/components/aac/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_aacdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -15,7 +15,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_aacenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/amr_nb_wb/Android.bp b/media/codec2/components/amr_nb_wb/Android.bp
index ce25bc9..b09a505 100644
--- a/media/codec2/components/amr_nb_wb/Android.bp
+++ b/media/codec2/components/amr_nb_wb/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_amrnbdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -21,7 +21,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_amrwbdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -40,7 +40,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_amrnbenc",
     defaults: [
         "libcodec2_soft-defaults",
@@ -58,7 +58,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_amrwbenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/aom/Android.bp b/media/codec2/components/aom/Android.bp
index 61dbd4c..fcc4552 100644
--- a/media/codec2/components/aom/Android.bp
+++ b/media/codec2/components/aom/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_av1dec_aom",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/avc/Android.bp b/media/codec2/components/avc/Android.bp
index 4021444..6b0e363 100644
--- a/media/codec2/components/avc/Android.bp
+++ b/media/codec2/components/avc/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_avcdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -15,7 +15,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_avcenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/base/Android.bp b/media/codec2/components/base/Android.bp
index f10835f..3712564 100644
--- a/media/codec2/components/base/Android.bp
+++ b/media/codec2/components/base/Android.bp
@@ -1,6 +1,6 @@
 // DO NOT DEPEND ON THIS DIRECTLY
 // use libcodec2_soft-defaults instead
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_common",
     defaults: ["libcodec2-impl-defaults"],
     vendor_available: true,
@@ -96,7 +96,7 @@
 }
 
 // TEMP: used by cheets2 project - remove when no longer used
-cc_library_shared {
+cc_library {
     name: "libcodec2_simple_component",
     vendor_available: true,
 
diff --git a/media/codec2/components/flac/Android.bp b/media/codec2/components/flac/Android.bp
index 48cc51b..603c412 100644
--- a/media/codec2/components/flac/Android.bp
+++ b/media/codec2/components/flac/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_flacdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -14,7 +14,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_flacenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/g711/Android.bp b/media/codec2/components/g711/Android.bp
index 0101b1a..c39df7b 100644
--- a/media/codec2/components/g711/Android.bp
+++ b/media/codec2/components/g711/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_g711alawdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -14,7 +14,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_g711mlawdec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/gav1/Android.bp b/media/codec2/components/gav1/Android.bp
index f374089..32aa98d 100644
--- a/media/codec2/components/gav1/Android.bp
+++ b/media/codec2/components/gav1/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_av1dec_gav1",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/gsm/Android.bp b/media/codec2/components/gsm/Android.bp
index 9330c01..7f54af8 100644
--- a/media/codec2/components/gsm/Android.bp
+++ b/media/codec2/components/gsm/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_gsmdec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/hevc/Android.bp b/media/codec2/components/hevc/Android.bp
index 369bd78..2858212 100644
--- a/media/codec2/components/hevc/Android.bp
+++ b/media/codec2/components/hevc/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_hevcdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -11,7 +11,7 @@
 
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_hevcenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/mp3/Android.bp b/media/codec2/components/mp3/Android.bp
index 66665ed..b4fb1b0 100644
--- a/media/codec2/components/mp3/Android.bp
+++ b/media/codec2/components/mp3/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_mp3dec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/mpeg2/Android.bp b/media/codec2/components/mpeg2/Android.bp
index 841f0a9..666e697 100644
--- a/media/codec2/components/mpeg2/Android.bp
+++ b/media/codec2/components/mpeg2/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_mpeg2dec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/mpeg4_h263/Android.bp b/media/codec2/components/mpeg4_h263/Android.bp
index 41e4f44..0673709 100644
--- a/media/codec2/components/mpeg4_h263/Android.bp
+++ b/media/codec2/components/mpeg4_h263/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_mpeg4dec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -15,7 +15,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_h263dec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -31,7 +31,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_mpeg4enc",
     defaults: [
         "libcodec2_soft-defaults",
@@ -49,7 +49,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_h263enc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/opus/Android.bp b/media/codec2/components/opus/Android.bp
index 0ed141b..32e2bf8 100644
--- a/media/codec2/components/opus/Android.bp
+++ b/media/codec2/components/opus/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_opusdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -9,7 +9,7 @@
 
     shared_libs: ["libopus"],
 }
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_opusenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/raw/Android.bp b/media/codec2/components/raw/Android.bp
index dc944da..d4fb8f8 100644
--- a/media/codec2/components/raw/Android.bp
+++ b/media/codec2/components/raw/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_rawdec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/vorbis/Android.bp b/media/codec2/components/vorbis/Android.bp
index bc1c380..ff1183f 100644
--- a/media/codec2/components/vorbis/Android.bp
+++ b/media/codec2/components/vorbis/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_vorbisdec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/vpx/Android.bp b/media/codec2/components/vpx/Android.bp
index 34f5753..72178aa 100644
--- a/media/codec2/components/vpx/Android.bp
+++ b/media/codec2/components/vpx/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_vp9dec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -14,7 +14,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_vp8dec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -26,7 +26,7 @@
     shared_libs: ["libvpx"],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_vp9enc",
     defaults: [
         "libcodec2_soft-defaults",
@@ -43,7 +43,7 @@
     cflags: ["-DVP9"],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_vp8enc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/xaac/Android.bp b/media/codec2/components/xaac/Android.bp
index 7795cc1..4889d78 100644
--- a/media/codec2/components/xaac/Android.bp
+++ b/media/codec2/components/xaac/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_xaacdec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/core/Android.bp b/media/codec2/core/Android.bp
index 33fafa7..beeadb8 100644
--- a/media/codec2/core/Android.bp
+++ b/media/codec2/core/Android.bp
@@ -5,7 +5,7 @@
     export_include_dirs: ["include"],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2",
     vendor_available: true,
     min_sdk_version: "29",
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
index 12ed725..b520c17 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -734,7 +734,7 @@
             }
             if (timestampMax < timestamp) timestampMax = timestamp;
         }
-        timestampOffset = timestampMax;
+        timestampOffset = timestampMax + 33333;
         eleInfo.close();
 
         // Reset Total frames before second decode loop
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
index ecaf3a8..5bcea5b 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
@@ -107,6 +107,13 @@
         mOutputSize = 0u;
         mTimestampDevTest = false;
         if (mCompName == unknown_comp) mDisableTest = true;
+
+        C2SecureModeTuning secureModeTuning{};
+        mComponent->query({&secureModeTuning}, {}, C2_MAY_BLOCK, nullptr);
+        if (secureModeTuning.value == C2Config::SM_READ_PROTECTED) {
+            mDisableTest = true;
+        }
+
         if (mDisableTest) std::cout << "[   WARN   ] Test Disabled \n";
     }
 
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index 7e4352d..4650672 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -843,6 +843,11 @@
                             return;
                         }
                     });
+            if (!transStatus.isOk()) {
+                LOG(DEBUG) << "SimpleParamReflector -- transaction failed: "
+                           << transStatus.description();
+                descriptor.reset();
+            }
             return descriptor;
         }
 
diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp
index c7588e9..dd1f485 100644
--- a/media/codec2/sfplugin/C2OMXNode.cpp
+++ b/media/codec2/sfplugin/C2OMXNode.cpp
@@ -25,6 +25,7 @@
 #include <C2AllocatorGralloc.h>
 #include <C2BlockInternal.h>
 #include <C2Component.h>
+#include <C2Config.h>
 #include <C2PlatformSupport.h>
 
 #include <OMX_Component.h>
@@ -44,6 +45,8 @@
 
 namespace {
 
+constexpr OMX_U32 kPortIndexInput = 0;
+
 class Buffer2D : public C2Buffer {
 public:
     explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {}
@@ -200,11 +203,27 @@
                 return BAD_VALUE;
             }
             OMX_PARAM_PORTDEFINITIONTYPE *pDef = (OMX_PARAM_PORTDEFINITIONTYPE *)params;
-            // TODO: read these from intf()
+            if (pDef->nPortIndex != kPortIndexInput) {
+                break;
+            }
+
             pDef->nBufferCountActual = 16;
+
+            std::shared_ptr<Codec2Client::Component> comp = mComp.lock();
+            C2PortActualDelayTuning::input inputDelay(0);
+            C2ActualPipelineDelayTuning pipelineDelay(0);
+            c2_status_t c2err = comp->query(
+                    {&inputDelay, &pipelineDelay}, {}, C2_DONT_BLOCK, nullptr);
+            if (c2err == C2_OK || c2err == C2_BAD_INDEX) {
+                pDef->nBufferCountActual = 4;
+                pDef->nBufferCountActual += (inputDelay ? inputDelay.value : 0u);
+                pDef->nBufferCountActual += (pipelineDelay ? pipelineDelay.value : 0u);
+            }
+
             pDef->eDomain = OMX_PortDomainVideo;
             pDef->format.video.nFrameWidth = mWidth;
             pDef->format.video.nFrameHeight = mHeight;
+            pDef->format.video.eColorFormat = OMX_COLOR_FormatAndroidOpaque;
             err = OK;
             break;
         }
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index f816778..9c1df71 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -246,8 +246,19 @@
         if (source == nullptr) {
             return NO_INIT;
         }
-        constexpr size_t kNumSlots = 16;
-        for (size_t i = 0; i < kNumSlots; ++i) {
+
+        size_t numSlots = 4;
+        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;
+        }
+
+        for (size_t i = 0; i < numSlots; ++i) {
             source->onInputBufferAdded(i);
         }
 
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 97145c3..06464b5 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -625,21 +625,19 @@
         Mutexed<Output>::Locked output(mOutput);
         if (!output->buffers ||
                 output->buffers->hasPending() ||
-                output->buffers->numClientBuffers() >= output->numSlots) {
+                output->buffers->numActiveSlots() >= output->numSlots) {
             return;
         }
     }
-    size_t numInputSlots = mInput.lock()->numSlots;
-    for (size_t i = 0; i < numInputSlots; ++i) {
-        if (mPipelineWatcher.lock()->pipelineFull()) {
-            return;
-        }
+    size_t numActiveSlots = 0;
+    while (!mPipelineWatcher.lock()->pipelineFull()) {
         sp<MediaCodecBuffer> inBuffer;
         size_t index;
         {
             Mutexed<Input>::Locked input(mInput);
-            if (input->buffers->numClientBuffers() >= input->numSlots) {
-                return;
+            numActiveSlots = input->buffers->numActiveSlots();
+            if (numActiveSlots >= input->numSlots) {
+                break;
             }
             if (!input->buffers->requestNewBuffer(&index, &inBuffer)) {
                 ALOGV("[%s] no new buffer available", mName);
@@ -649,6 +647,7 @@
         ALOGV("[%s] new input index = %zu [%p]", mName, index, inBuffer.get());
         mCallback->onInputBufferAvailable(index, inBuffer);
     }
+    ALOGV("[%s] # active slots after feedInputBufferIfAvailable = %zu", mName, numActiveSlots);
 }
 
 status_t CCodecBufferChannel::renderOutputBuffer(
@@ -817,6 +816,9 @@
     status_t result = mComponent->queueToOutputSurface(block, qbi, &qbo);
     if (result != OK) {
         ALOGI("[%s] queueBuffer failed: %d", mName, result);
+        if (result == NO_INIT) {
+            mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
+        }
         return result;
     }
     ALOGV("[%s] queue buffer successful", mName);
@@ -1064,9 +1066,6 @@
             Mutexed<OutputSurface>::Locked output(mOutputSurface);
             output->maxDequeueBuffers = numOutputSlots +
                     reorderDepth.value + kRenderingDepth;
-            if (!secure) {
-                output->maxDequeueBuffers += numInputSlots;
-            }
             outputSurface = output->surface ?
                     output->surface->getIGraphicBufferProducer() : nullptr;
             if (outputSurface) {
@@ -1404,6 +1403,7 @@
                 continue;
             }
             if (work->input.buffers.empty()
+                    || work->input.buffers.front() == nullptr
                     || work->input.buffers.front()->data().linearBlocks().empty()) {
                 ALOGD("[%s] no linear codec config data found", mName);
                 continue;
@@ -1527,6 +1527,7 @@
     }
 
     std::optional<uint32_t> newInputDelay, newPipelineDelay;
+    bool needMaxDequeueBufferCountUpdate = false;
     while (!worklet->output.configUpdate.empty()) {
         std::unique_ptr<C2Param> param;
         worklet->output.configUpdate.back().swap(param);
@@ -1535,24 +1536,10 @@
             case C2PortReorderBufferDepthTuning::CORE_INDEX: {
                 C2PortReorderBufferDepthTuning::output reorderDepth;
                 if (reorderDepth.updateFrom(*param)) {
-                    bool secure = mComponent->getName().find(".secure") !=
-                                  std::string::npos;
-                    mOutput.lock()->buffers->setReorderDepth(
-                            reorderDepth.value);
                     ALOGV("[%s] onWorkDone: updated reorder depth to %u",
                           mName, reorderDepth.value);
-                    size_t numOutputSlots = mOutput.lock()->numSlots;
-                    size_t numInputSlots = mInput.lock()->numSlots;
-                    Mutexed<OutputSurface>::Locked output(mOutputSurface);
-                    output->maxDequeueBuffers = numOutputSlots +
-                            reorderDepth.value + kRenderingDepth;
-                    if (!secure) {
-                        output->maxDequeueBuffers += numInputSlots;
-                    }
-                    if (output->surface) {
-                        output->surface->setMaxDequeuedBufferCount(
-                                output->maxDequeueBuffers);
-                    }
+                    mOutput.lock()->buffers->setReorderDepth(reorderDepth.value);
+                    needMaxDequeueBufferCountUpdate = true;
                 } else {
                     ALOGD("[%s] onWorkDone: failed to read reorder depth",
                           mName);
@@ -1596,14 +1583,11 @@
                     if (outputDelay.updateFrom(*param)) {
                         ALOGV("[%s] onWorkDone: updating output delay %u",
                               mName, outputDelay.value);
-                        bool secure = mComponent->getName().find(".secure") !=
-                                      std::string::npos;
-                        (void)mPipelineWatcher.lock()->outputDelay(
-                                outputDelay.value);
+                        (void)mPipelineWatcher.lock()->outputDelay(outputDelay.value);
+                        needMaxDequeueBufferCountUpdate = true;
 
                         bool outputBuffersChanged = false;
                         size_t numOutputSlots = 0;
-                        size_t numInputSlots = mInput.lock()->numSlots;
                         {
                             Mutexed<Output>::Locked output(mOutput);
                             if (!output->buffers) {
@@ -1629,16 +1613,6 @@
                         if (outputBuffersChanged) {
                             mCCodecCallback->onOutputBuffersChanged();
                         }
-
-                        uint32_t depth = mOutput.lock()->buffers->getReorderDepth();
-                        Mutexed<OutputSurface>::Locked output(mOutputSurface);
-                        output->maxDequeueBuffers = numOutputSlots + depth + kRenderingDepth;
-                        if (!secure) {
-                            output->maxDequeueBuffers += numInputSlots;
-                        }
-                        if (output->surface) {
-                            output->surface->setMaxDequeuedBufferCount(output->maxDequeueBuffers);
-                        }
                     }
                 }
                 break;
@@ -1667,6 +1641,20 @@
             input->numSlots = newNumSlots;
         }
     }
+    if (needMaxDequeueBufferCountUpdate) {
+        size_t numOutputSlots = 0;
+        uint32_t reorderDepth = 0;
+        {
+            Mutexed<Output>::Locked output(mOutput);
+            numOutputSlots = output->numSlots;
+            reorderDepth = output->buffers->getReorderDepth();
+        }
+        Mutexed<OutputSurface>::Locked output(mOutputSurface);
+        output->maxDequeueBuffers = numOutputSlots + reorderDepth + kRenderingDepth;
+        if (output->surface) {
+            output->surface->setMaxDequeuedBufferCount(output->maxDequeueBuffers);
+        }
+    }
 
     int32_t flags = 0;
     if (worklet->output.flags & C2FrameData::FLAG_END_OF_STREAM) {
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index 3c99bf6..566a18f 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -96,6 +96,9 @@
                 int32_t vstride = int32_t(offsetDelta / stride);
                 newFormat->setInt32(KEY_SLICE_HEIGHT, vstride);
                 ALOGD("[%s] updating vstride = %d", mName, vstride);
+                buffer->setRange(
+                        img->mPlane[0].mOffset,
+                        buffer->size() - img->mPlane[0].mOffset);
             }
         }
         setFormat(newFormat);
@@ -495,11 +498,12 @@
     mBuffers.clear();
 }
 
-size_t FlexBuffersImpl::numClientBuffers() const {
+size_t FlexBuffersImpl::numActiveSlots() const {
     return std::count_if(
             mBuffers.begin(), mBuffers.end(),
             [](const Entry &entry) {
-                return (entry.clientBuffer != nullptr);
+                return (entry.clientBuffer != nullptr
+                        || !entry.compBuffer.expired());
             });
 }
 
@@ -645,11 +649,11 @@
     }
 }
 
-size_t BuffersArrayImpl::numClientBuffers() const {
+size_t BuffersArrayImpl::numActiveSlots() const {
     return std::count_if(
             mBuffers.begin(), mBuffers.end(),
             [](const Entry &entry) {
-                return entry.ownedByClient;
+                return entry.ownedByClient || !entry.compBuffer.expired();
             });
 }
 
@@ -699,8 +703,8 @@
     mImpl.flush();
 }
 
-size_t InputBuffersArray::numClientBuffers() const {
-    return mImpl.numClientBuffers();
+size_t InputBuffersArray::numActiveSlots() const {
+    return mImpl.numActiveSlots();
 }
 
 sp<Codec2Buffer> InputBuffersArray::createNewBuffer() {
@@ -737,8 +741,8 @@
     return nullptr;
 }
 
-size_t SlotInputBuffers::numClientBuffers() const {
-    return mImpl.numClientBuffers();
+size_t SlotInputBuffers::numActiveSlots() const {
+    return mImpl.numActiveSlots();
 }
 
 sp<Codec2Buffer> SlotInputBuffers::createNewBuffer() {
@@ -789,8 +793,8 @@
     return std::move(array);
 }
 
-size_t LinearInputBuffers::numClientBuffers() const {
-    return mImpl.numClientBuffers();
+size_t LinearInputBuffers::numActiveSlots() const {
+    return mImpl.numActiveSlots();
 }
 
 // static
@@ -966,8 +970,8 @@
     return std::move(array);
 }
 
-size_t GraphicMetadataInputBuffers::numClientBuffers() const {
-    return mImpl.numClientBuffers();
+size_t GraphicMetadataInputBuffers::numActiveSlots() const {
+    return mImpl.numActiveSlots();
 }
 
 sp<Codec2Buffer> GraphicMetadataInputBuffers::createNewBuffer() {
@@ -1031,8 +1035,8 @@
     return std::move(array);
 }
 
-size_t GraphicInputBuffers::numClientBuffers() const {
-    return mImpl.numClientBuffers();
+size_t GraphicInputBuffers::numActiveSlots() const {
+    return mImpl.numActiveSlots();
 }
 
 sp<Codec2Buffer> GraphicInputBuffers::createNewBuffer() {
@@ -1121,8 +1125,8 @@
     mImpl.getArray(array);
 }
 
-size_t OutputBuffersArray::numClientBuffers() const {
-    return mImpl.numClientBuffers();
+size_t OutputBuffersArray::numActiveSlots() const {
+    return mImpl.numActiveSlots();
 }
 
 void OutputBuffersArray::realloc(const std::shared_ptr<C2Buffer> &c2buffer) {
@@ -1232,8 +1236,8 @@
     return array;
 }
 
-size_t FlexOutputBuffers::numClientBuffers() const {
-    return mImpl.numClientBuffers();
+size_t FlexOutputBuffers::numActiveSlots() const {
+    return mImpl.numActiveSlots();
 }
 
 // LinearOutputBuffers
diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h
index 0d4fa81..c383a7c 100644
--- a/media/codec2/sfplugin/CCodecBuffers.h
+++ b/media/codec2/sfplugin/CCodecBuffers.h
@@ -33,8 +33,8 @@
 class SkipCutBuffer;
 
 constexpr size_t kLinearBufferSize = 1048576;
-// This can fit 4K RGBA frame, and most likely client won't need more than this.
-constexpr size_t kMaxLinearBufferSize = 4096 * 2304 * 4;
+// This can fit an 8K frame.
+constexpr size_t kMaxLinearBufferSize = 7680 * 4320 * 2;
 
 /**
  * Base class for representation of buffers at one port.
@@ -72,7 +72,7 @@
     /**
      * Return number of buffers the client owns.
      */
-    virtual size_t numClientBuffers() const = 0;
+    virtual size_t numActiveSlots() const = 0;
 
     /**
      * Examine image data from the buffer and update the format if necessary.
@@ -584,7 +584,7 @@
      * Return the number of buffers that are sent to the client but not released
      * yet.
      */
-    size_t numClientBuffers() const;
+    size_t numActiveSlots() const;
 
     /**
      * Return the number of buffers that are sent to the component but not
@@ -705,7 +705,7 @@
      * Return the number of buffers that are sent to the client but not released
      * yet.
      */
-    size_t numClientBuffers() const;
+    size_t numActiveSlots() const;
 
     /**
      * Return the size of the array.
@@ -765,7 +765,7 @@
 
     void flush() override;
 
-    size_t numClientBuffers() const final;
+    size_t numActiveSlots() const final;
 
 protected:
     sp<Codec2Buffer> createNewBuffer() override;
@@ -796,7 +796,7 @@
 
     std::unique_ptr<InputBuffers> toArrayMode(size_t size) final;
 
-    size_t numClientBuffers() const final;
+    size_t numActiveSlots() const final;
 
 protected:
     sp<Codec2Buffer> createNewBuffer() final;
@@ -826,7 +826,7 @@
 
     std::unique_ptr<InputBuffers> toArrayMode(size_t size) override;
 
-    size_t numClientBuffers() const final;
+    size_t numActiveSlots() const final;
 
 protected:
     sp<Codec2Buffer> createNewBuffer() override;
@@ -894,7 +894,7 @@
 
     std::unique_ptr<InputBuffers> toArrayMode(size_t size) final;
 
-    size_t numClientBuffers() const final;
+    size_t numActiveSlots() const final;
 
 protected:
     sp<Codec2Buffer> createNewBuffer() override;
@@ -924,7 +924,7 @@
     std::unique_ptr<InputBuffers> toArrayMode(
             size_t size) final;
 
-    size_t numClientBuffers() const final;
+    size_t numActiveSlots() const final;
 
 protected:
     sp<Codec2Buffer> createNewBuffer() override;
@@ -965,7 +965,7 @@
         array->clear();
     }
 
-    size_t numClientBuffers() const final {
+    size_t numActiveSlots() const final {
         return 0u;
     }
 
@@ -1019,7 +1019,7 @@
 
     void getArray(Vector<sp<MediaCodecBuffer>> *array) const final;
 
-    size_t numClientBuffers() const final;
+    size_t numActiveSlots() const final;
 
     /**
      * Reallocate the array, filled with buffers with the same size as given
@@ -1073,7 +1073,7 @@
 
     std::unique_ptr<OutputBuffersArray> toArrayMode(size_t size) override;
 
-    size_t numClientBuffers() const final;
+    size_t numActiveSlots() const final;
 
     /**
      * Return an appropriate Codec2Buffer object for the type of buffers.
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index 96f86e8..79c6227 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -1151,14 +1151,11 @@
 
     bool changed = false;
     if (domain & mInputDomain) {
-        sp<AMessage> oldFormat = mInputFormat;
-        mInputFormat = mInputFormat->dup(); // trigger format changed
+        sp<AMessage> oldFormat = mInputFormat->dup();
         mInputFormat->extend(getFormatForDomain(reflected, mInputDomain));
         if (mInputFormat->countEntries() != oldFormat->countEntries()
                 || mInputFormat->changesFrom(oldFormat)->countEntries() > 0) {
             changed = true;
-        } else {
-            mInputFormat = oldFormat; // no change
         }
     }
     if (domain & mOutputDomain) {
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index 25e7da9..19414a0 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -276,20 +276,22 @@
                             int32_t planeSize = 0;
                             for (uint32_t i = 0; i < layout.numPlanes; ++i) {
                                 const C2PlaneInfo &plane = layout.planes[i];
-                                ssize_t minOffset = plane.minOffset(mWidth, mHeight);
-                                ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
+                                int64_t planeStride = std::abs(plane.rowInc / plane.colInc);
+                                ssize_t minOffset = plane.minOffset(
+                                        mWidth / plane.colSampling, mHeight / plane.rowSampling);
+                                ssize_t maxOffset = plane.maxOffset(
+                                        mWidth / plane.colSampling, mHeight / plane.rowSampling);
                                 if (minPtr > mView.data()[i] + minOffset) {
                                     minPtr = mView.data()[i] + minOffset;
                                 }
                                 if (maxPtr < mView.data()[i] + maxOffset) {
                                     maxPtr = mView.data()[i] + maxOffset;
                                 }
-                                planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
-                                        / plane.rowSampling / plane.colSampling
-                                        * divUp(mAllocatedDepth, 8u);
+                                planeSize += planeStride * divUp(mAllocatedDepth, 8u)
+                                        * align(mHeight, 64) / plane.rowSampling;
                             }
 
-                            if ((maxPtr - minPtr + 1) <= planeSize) {
+                            if (minPtr == mView.data()[0] && (maxPtr - minPtr + 1) <= planeSize) {
                                 // FIXME: this is risky as reading/writing data out of bound results
                                 //        in an undefined behavior, but gralloc does assume a
                                 //        contiguous mapping
diff --git a/media/codec2/sfplugin/InputSurfaceWrapper.h b/media/codec2/sfplugin/InputSurfaceWrapper.h
index bb35763..479acb1 100644
--- a/media/codec2/sfplugin/InputSurfaceWrapper.h
+++ b/media/codec2/sfplugin/InputSurfaceWrapper.h
@@ -61,24 +61,24 @@
     /// Input Surface configuration
     struct Config {
         // IN PARAMS (GBS)
-        float mMinFps; // minimum fps (repeat frame to achieve this)
-        float mMaxFps; // max fps (via frame drop)
-        float mCaptureFps; // capture fps
-        float mCodedFps;   // coded fps
-        bool mSuspended; // suspended
-        int64_t mTimeOffsetUs; // time offset (input => codec)
-        int64_t mSuspendAtUs; // suspend/resume time
-        int64_t mStartAtUs; // start time
-        bool mStopped; // stopped
-        int64_t mStopAtUs; // stop time
+        float mMinFps = 0.0; // minimum fps (repeat frame to achieve this)
+        float mMaxFps = 0.0; // max fps (via frame drop)
+        float mCaptureFps = 0.0; // capture fps
+        float mCodedFps = 0.0;   // coded fps
+        bool mSuspended = false; // suspended
+        int64_t mTimeOffsetUs = 0; // time offset (input => codec)
+        int64_t mSuspendAtUs = 0; // suspend/resume time
+        int64_t mStartAtUs = 0; // start time
+        bool mStopped = false; // stopped
+        int64_t mStopAtUs = 0; // stop time
 
         // OUT PARAMS (GBS)
-        int64_t mInputDelayUs; // delay between encoder input and surface input
+        int64_t mInputDelayUs = 0; // delay between encoder input and surface input
 
         // IN PARAMS (CODEC WRAPPER)
-        float mFixedAdjustedFps; // fixed fps via PTS manipulation
-        float mMinAdjustedFps; // minimum fps via PTS manipulation
-        uint64_t mUsage; // consumer usage
+        float mFixedAdjustedFps = 0.0; // fixed fps via PTS manipulation
+        float mMinAdjustedFps = 0.0; // minimum fps via PTS manipulation
+        uint64_t mUsage = 0; // consumer usage
     };
 
     /**
diff --git a/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp b/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
index 5bee605..ad8f6e5 100644
--- a/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
+++ b/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
@@ -18,22 +18,31 @@
 
 #include <gtest/gtest.h>
 
+#include <media/stagefright/foundation/AString.h>
 #include <media/stagefright/MediaCodecConstants.h>
 
+#include <C2BlockInternal.h>
 #include <C2PlatformSupport.h>
 
 namespace android {
 
+static std::shared_ptr<RawGraphicOutputBuffers> GetRawGraphicOutputBuffers(
+        int32_t width, int32_t height) {
+    std::shared_ptr<RawGraphicOutputBuffers> buffers =
+        std::make_shared<RawGraphicOutputBuffers>("test");
+    sp<AMessage> format{new AMessage};
+    format->setInt32(KEY_WIDTH, width);
+    format->setInt32(KEY_HEIGHT, height);
+    buffers->setFormat(format);
+    return buffers;
+}
+
 TEST(RawGraphicOutputBuffersTest, ChangeNumSlots) {
     constexpr int32_t kWidth = 3840;
     constexpr int32_t kHeight = 2160;
 
     std::shared_ptr<RawGraphicOutputBuffers> buffers =
-        std::make_shared<RawGraphicOutputBuffers>("test");
-    sp<AMessage> format{new AMessage};
-    format->setInt32("width", kWidth);
-    format->setInt32("height", kHeight);
-    buffers->setFormat(format);
+        GetRawGraphicOutputBuffers(kWidth, kHeight);
 
     std::shared_ptr<C2BlockPool> pool;
     ASSERT_EQ(OK, GetCodec2BlockPool(C2BlockPool::BASIC_GRAPHIC, nullptr, &pool));
@@ -96,4 +105,435 @@
     }
 }
 
+class TestGraphicAllocation : public C2GraphicAllocation {
+public:
+    TestGraphicAllocation(
+            uint32_t width,
+            uint32_t height,
+            const C2PlanarLayout &layout,
+            size_t capacity,
+            std::vector<size_t> offsets)
+        : C2GraphicAllocation(width, height),
+          mLayout(layout),
+          mMemory(capacity, 0xAA),
+          mOffsets(offsets) {
+    }
+
+    c2_status_t map(
+            C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
+            C2PlanarLayout *layout, uint8_t **addr) override {
+        (void)rect;
+        (void)usage;
+        (void)fence;
+        *layout = mLayout;
+        for (size_t i = 0; i < mLayout.numPlanes; ++i) {
+            addr[i] = mMemory.data() + mOffsets[i];
+        }
+        return C2_OK;
+    }
+
+    c2_status_t unmap(uint8_t **, C2Rect, C2Fence *) override { return C2_OK; }
+
+    C2Allocator::id_t getAllocatorId() const override { return -1; }
+
+    const C2Handle *handle() const override { return nullptr; }
+
+    bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override {
+        return other.get() == this;
+    }
+
+private:
+    C2PlanarLayout mLayout;
+    std::vector<uint8_t> mMemory;
+    std::vector<uint8_t *> mAddr;
+    std::vector<size_t> mOffsets;
+};
+
+class LayoutTest : public ::testing::TestWithParam<std::tuple<bool, std::string, bool, int32_t>> {
+private:
+    static C2PlanarLayout YUVPlanarLayout(int32_t stride) {
+        C2PlanarLayout layout = {
+            C2PlanarLayout::TYPE_YUV,
+            3,  /* numPlanes */
+            3,  /* rootPlanes */
+            {},  /* planes --- to be filled below */
+        };
+        layout.planes[C2PlanarLayout::PLANE_Y] = {
+            C2PlaneInfo::CHANNEL_Y,
+            1,  /* colInc */
+            stride,  /* rowInc */
+            1,  /* colSampling */
+            1,  /* rowSampling */
+            8,  /* allocatedDepth */
+            8,  /* bitDepth */
+            0,  /* rightShift */
+            C2PlaneInfo::NATIVE,
+            C2PlanarLayout::PLANE_Y,  /* rootIx */
+            0,  /* offset */
+        };
+        layout.planes[C2PlanarLayout::PLANE_U] = {
+            C2PlaneInfo::CHANNEL_CB,
+            1,  /* colInc */
+            stride / 2,  /* rowInc */
+            2,  /* colSampling */
+            2,  /* rowSampling */
+            8,  /* allocatedDepth */
+            8,  /* bitDepth */
+            0,  /* rightShift */
+            C2PlaneInfo::NATIVE,
+            C2PlanarLayout::PLANE_U,  /* rootIx */
+            0,  /* offset */
+        };
+        layout.planes[C2PlanarLayout::PLANE_V] = {
+            C2PlaneInfo::CHANNEL_CR,
+            1,  /* colInc */
+            stride / 2,  /* rowInc */
+            2,  /* colSampling */
+            2,  /* rowSampling */
+            8,  /* allocatedDepth */
+            8,  /* bitDepth */
+            0,  /* rightShift */
+            C2PlaneInfo::NATIVE,
+            C2PlanarLayout::PLANE_V,  /* rootIx */
+            0,  /* offset */
+        };
+        return layout;
+    }
+
+    static C2PlanarLayout YUVSemiPlanarLayout(int32_t stride) {
+        C2PlanarLayout layout = {
+            C2PlanarLayout::TYPE_YUV,
+            3,  /* numPlanes */
+            2,  /* rootPlanes */
+            {},  /* planes --- to be filled below */
+        };
+        layout.planes[C2PlanarLayout::PLANE_Y] = {
+            C2PlaneInfo::CHANNEL_Y,
+            1,  /* colInc */
+            stride,  /* rowInc */
+            1,  /* colSampling */
+            1,  /* rowSampling */
+            8,  /* allocatedDepth */
+            8,  /* bitDepth */
+            0,  /* rightShift */
+            C2PlaneInfo::NATIVE,
+            C2PlanarLayout::PLANE_Y,  /* rootIx */
+            0,  /* offset */
+        };
+        layout.planes[C2PlanarLayout::PLANE_U] = {
+            C2PlaneInfo::CHANNEL_CB,
+            2,  /* colInc */
+            stride,  /* rowInc */
+            2,  /* colSampling */
+            2,  /* rowSampling */
+            8,  /* allocatedDepth */
+            8,  /* bitDepth */
+            0,  /* rightShift */
+            C2PlaneInfo::NATIVE,
+            C2PlanarLayout::PLANE_U,  /* rootIx */
+            0,  /* offset */
+        };
+        layout.planes[C2PlanarLayout::PLANE_V] = {
+            C2PlaneInfo::CHANNEL_CR,
+            2,  /* colInc */
+            stride,  /* rowInc */
+            2,  /* colSampling */
+            2,  /* rowSampling */
+            8,  /* allocatedDepth */
+            8,  /* bitDepth */
+            0,  /* rightShift */
+            C2PlaneInfo::NATIVE,
+            C2PlanarLayout::PLANE_U,  /* rootIx */
+            1,  /* offset */
+        };
+        return layout;
+    }
+
+    static C2PlanarLayout YVUSemiPlanarLayout(int32_t stride) {
+        C2PlanarLayout layout = {
+            C2PlanarLayout::TYPE_YUV,
+            3,  /* numPlanes */
+            2,  /* rootPlanes */
+            {},  /* planes --- to be filled below */
+        };
+        layout.planes[C2PlanarLayout::PLANE_Y] = {
+            C2PlaneInfo::CHANNEL_Y,
+            1,  /* colInc */
+            stride,  /* rowInc */
+            1,  /* colSampling */
+            1,  /* rowSampling */
+            8,  /* allocatedDepth */
+            8,  /* bitDepth */
+            0,  /* rightShift */
+            C2PlaneInfo::NATIVE,
+            C2PlanarLayout::PLANE_Y,  /* rootIx */
+            0,  /* offset */
+        };
+        layout.planes[C2PlanarLayout::PLANE_U] = {
+            C2PlaneInfo::CHANNEL_CB,
+            2,  /* colInc */
+            stride,  /* rowInc */
+            2,  /* colSampling */
+            2,  /* rowSampling */
+            8,  /* allocatedDepth */
+            8,  /* bitDepth */
+            0,  /* rightShift */
+            C2PlaneInfo::NATIVE,
+            C2PlanarLayout::PLANE_V,  /* rootIx */
+            1,  /* offset */
+        };
+        layout.planes[C2PlanarLayout::PLANE_V] = {
+            C2PlaneInfo::CHANNEL_CR,
+            2,  /* colInc */
+            stride,  /* rowInc */
+            2,  /* colSampling */
+            2,  /* rowSampling */
+            8,  /* allocatedDepth */
+            8,  /* bitDepth */
+            0,  /* rightShift */
+            C2PlaneInfo::NATIVE,
+            C2PlanarLayout::PLANE_V,  /* rootIx */
+            0,  /* offset */
+        };
+        return layout;
+    }
+
+    static std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(
+            uint32_t width,
+            uint32_t height,
+            const C2PlanarLayout &layout,
+            size_t capacity,
+            std::vector<size_t> offsets) {
+        std::shared_ptr<C2GraphicAllocation> alloc = std::make_shared<TestGraphicAllocation>(
+                width,
+                height,
+                layout,
+                capacity,
+                offsets);
+
+        return _C2BlockFactory::CreateGraphicBlock(alloc);
+    }
+
+    static constexpr uint8_t GetPixelValue(uint8_t value, uint32_t row, uint32_t col) {
+        return (uint32_t(value) * row + col) & 0xFF;
+    }
+
+    static void FillPlane(C2GraphicView &view, size_t index, uint8_t value) {
+        C2PlanarLayout layout = view.layout();
+
+        uint8_t *rowPtr = view.data()[index];
+        C2PlaneInfo plane = layout.planes[index];
+        for (uint32_t row = 0; row < view.height() / plane.rowSampling; ++row) {
+            uint8_t *colPtr = rowPtr;
+            for (uint32_t col = 0; col < view.width() / plane.colSampling; ++col) {
+                *colPtr = GetPixelValue(value, row, col);
+                colPtr += plane.colInc;
+            }
+            rowPtr += plane.rowInc;
+        }
+    }
+
+    static void FillBlock(const std::shared_ptr<C2GraphicBlock> &block) {
+        C2GraphicView view = block->map().get();
+
+        FillPlane(view, C2PlanarLayout::PLANE_Y, 'Y');
+        FillPlane(view, C2PlanarLayout::PLANE_U, 'U');
+        FillPlane(view, C2PlanarLayout::PLANE_V, 'V');
+    }
+
+    static bool VerifyPlane(
+            const MediaImage2 *mediaImage,
+            const uint8_t *base,
+            uint32_t index,
+            uint8_t value,
+            std::string *errorMsg) {
+        *errorMsg = "";
+        MediaImage2::PlaneInfo plane = mediaImage->mPlane[index];
+        const uint8_t *rowPtr = base + plane.mOffset;
+        for (uint32_t row = 0; row < mediaImage->mHeight / plane.mVertSubsampling; ++row) {
+            const uint8_t *colPtr = rowPtr;
+            for (uint32_t col = 0; col < mediaImage->mWidth / plane.mHorizSubsampling; ++col) {
+                if (GetPixelValue(value, row, col) != *colPtr) {
+                    *errorMsg = AStringPrintf("row=%u col=%u expected=%02x actual=%02x",
+                            row, col, GetPixelValue(value, row, col), *colPtr).c_str();
+                    return false;
+                }
+                colPtr += plane.mColInc;
+            }
+            rowPtr += plane.mRowInc;
+        }
+        return true;
+    }
+
+public:
+    static constexpr int32_t kWidth = 320;
+    static constexpr int32_t kHeight = 240;
+    static constexpr int32_t kGapLength = kWidth * kHeight * 10;
+
+    static std::shared_ptr<C2Buffer> CreateAndFillBufferFromParam(const ParamType &param) {
+        bool contiguous = std::get<0>(param);
+        std::string planeOrderStr = std::get<1>(param);
+        bool planar = std::get<2>(param);
+        int32_t stride = std::get<3>(param);
+
+        C2PlanarLayout::plane_index_t planeOrder[3];
+        C2PlanarLayout layout;
+
+        if (planeOrderStr.size() != 3) {
+            return nullptr;
+        }
+        for (size_t i = 0; i < 3; ++i) {
+            C2PlanarLayout::plane_index_t planeIndex;
+            switch (planeOrderStr[i]) {
+                case 'Y': planeIndex = C2PlanarLayout::PLANE_Y; break;
+                case 'U': planeIndex = C2PlanarLayout::PLANE_U; break;
+                case 'V': planeIndex = C2PlanarLayout::PLANE_V; break;
+                default:  return nullptr;
+            }
+            planeOrder[i] = planeIndex;
+        }
+
+        if (planar) {
+            layout = YUVPlanarLayout(stride);
+        } else {  // semi-planar
+            for (size_t i = 0; i < 3; ++i) {
+                if (planeOrder[i] == C2PlanarLayout::PLANE_U) {
+                    layout = YUVSemiPlanarLayout(stride);
+                    break;
+                }
+                if (planeOrder[i] == C2PlanarLayout::PLANE_V) {
+                    layout = YVUSemiPlanarLayout(stride);
+                    break;
+                }
+            }
+        }
+
+        size_t yPlaneSize = stride * kHeight;
+        size_t uvPlaneSize = stride * kHeight / 4;
+        size_t capacity = yPlaneSize + uvPlaneSize * 2;
+        std::vector<size_t> offsets(3);
+
+        if (!contiguous) {
+            if (planar) {
+                capacity += kGapLength * 2;
+            } else {  // semi-planar
+                capacity += kGapLength;
+            }
+        }
+
+        offsets[planeOrder[0]] = 0;
+        size_t planeSize = (planeOrder[0] == C2PlanarLayout::PLANE_Y) ? yPlaneSize : uvPlaneSize;
+        for (size_t i = 1; i < 3; ++i) {
+            offsets[planeOrder[i]] = offsets[planeOrder[i - 1]] + planeSize;
+            if (!contiguous) {
+                offsets[planeOrder[i]] += kGapLength;
+            }
+            planeSize = (planeOrder[i] == C2PlanarLayout::PLANE_Y) ? yPlaneSize : uvPlaneSize;
+            if (!planar  // semi-planar
+                    && planeOrder[i - 1] != C2PlanarLayout::PLANE_Y
+                    && planeOrder[i] != C2PlanarLayout::PLANE_Y) {
+                offsets[planeOrder[i]] = offsets[planeOrder[i - 1]] + 1;
+                planeSize = uvPlaneSize * 2 - 1;
+            }
+        }
+
+        std::shared_ptr<C2GraphicBlock> block = CreateGraphicBlock(
+                kWidth,
+                kHeight,
+                layout,
+                capacity,
+                offsets);
+        FillBlock(block);
+        return C2Buffer::CreateGraphicBuffer(
+                block->share(block->crop(), C2Fence()));
+    }
+
+    static bool VerifyClientBuffer(
+            const sp<MediaCodecBuffer> &buffer, std::string *errorMsg) {
+        *errorMsg = "";
+        sp<ABuffer> imageData;
+        if (!buffer->format()->findBuffer("image-data", &imageData)) {
+            *errorMsg = "Missing image data";
+            return false;
+        }
+        MediaImage2 *mediaImage = (MediaImage2 *)imageData->data();
+        if (mediaImage->mType != MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
+            *errorMsg = AStringPrintf("Unexpected type: %d", mediaImage->mType).c_str();
+            return false;
+        }
+        std::string planeErrorMsg;
+        if (!VerifyPlane(mediaImage, buffer->base(), MediaImage2::Y, 'Y', &planeErrorMsg)) {
+            *errorMsg = "Y plane does not match: " + planeErrorMsg;
+            return false;
+        }
+        if (!VerifyPlane(mediaImage, buffer->base(), MediaImage2::U, 'U', &planeErrorMsg)) {
+            *errorMsg = "U plane does not match: " + planeErrorMsg;
+            return false;
+        }
+        if (!VerifyPlane(mediaImage, buffer->base(), MediaImage2::V, 'V', &planeErrorMsg)) {
+            *errorMsg = "V plane does not match: " + planeErrorMsg;
+            return false;
+        }
+
+        int32_t width, height, stride;
+        buffer->format()->findInt32(KEY_WIDTH, &width);
+        buffer->format()->findInt32(KEY_HEIGHT, &height);
+        buffer->format()->findInt32(KEY_STRIDE, &stride);
+
+        MediaImage2 legacyYLayout = {
+            MediaImage2::MEDIA_IMAGE_TYPE_Y,
+            1,  // mNumPlanes
+            uint32_t(width),
+            uint32_t(height),
+            8,
+            8,
+            {},  // mPlane
+        };
+        legacyYLayout.mPlane[MediaImage2::Y] = {
+            0,  // mOffset
+            1,  // mColInc
+            stride,  // mRowInc
+            1,  // mHorizSubsampling
+            1,  // mVertSubsampling
+        };
+        if (!VerifyPlane(&legacyYLayout, buffer->data(), MediaImage2::Y, 'Y', &planeErrorMsg)) {
+            *errorMsg = "Y plane by legacy layout does not match: " + planeErrorMsg;
+            return false;
+        }
+        return true;
+    }
+
+};
+
+TEST_P(LayoutTest, VerifyLayout) {
+    std::shared_ptr<RawGraphicOutputBuffers> buffers =
+        GetRawGraphicOutputBuffers(kWidth, kHeight);
+
+    std::shared_ptr<C2Buffer> c2Buffer = CreateAndFillBufferFromParam(GetParam());
+    ASSERT_NE(nullptr, c2Buffer);
+    sp<MediaCodecBuffer> clientBuffer;
+    size_t index;
+    ASSERT_EQ(OK, buffers->registerBuffer(c2Buffer, &index, &clientBuffer));
+    ASSERT_NE(nullptr, clientBuffer);
+    std::string errorMsg;
+    ASSERT_TRUE(VerifyClientBuffer(clientBuffer, &errorMsg)) << errorMsg;
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        RawGraphicOutputBuffersTest,
+        LayoutTest,
+        ::testing::Combine(
+            ::testing::Bool(),  /* contiguous */
+            ::testing::Values("YUV", "YVU", "UVY", "VUY"),
+            ::testing::Bool(),  /* planar */
+            ::testing::Values(320, 512)),
+        [](const ::testing::TestParamInfo<LayoutTest::ParamType> &info) {
+            std::string contiguous = std::get<0>(info.param) ? "Contiguous" : "Noncontiguous";
+            std::string planar = std::get<2>(info.param) ? "Planar" : "SemiPlanar";
+            return contiguous
+                    + std::get<1>(info.param)
+                    + planar
+                    + std::to_string(std::get<3>(info.param));
+        });
+
 } // namespace android
diff --git a/media/codec2/sfplugin/utils/Android.bp b/media/codec2/sfplugin/utils/Android.bp
index 6287221..e7dc92a 100644
--- a/media/codec2/sfplugin/utils/Android.bp
+++ b/media/codec2/sfplugin/utils/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libsfplugin_ccodec_utils",
     vendor_available: true,
     min_sdk_version: "29",
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index 60f4736..19afccf 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -13,7 +13,7 @@
 
 // !!!DO NOT DEPEND ON THIS SHARED LIBRARY DIRECTLY!!!
 // use libcodec2-impl-defaults instead
-cc_library_shared {
+cc_library {
     name: "libcodec2_vndk",
     vendor_available: true,
     min_sdk_version: "29",
diff --git a/media/codec2/vndk/C2AllocatorBlob.cpp b/media/codec2/vndk/C2AllocatorBlob.cpp
index 565137c..6340cba 100644
--- a/media/codec2/vndk/C2AllocatorBlob.cpp
+++ b/media/codec2/vndk/C2AllocatorBlob.cpp
@@ -17,6 +17,8 @@
 // #define LOG_NDEBUG 0
 #define LOG_TAG "C2AllocatorBlob"
 
+#include <set>
+
 #include <C2AllocatorBlob.h>
 #include <C2PlatformSupport.h>
 
@@ -67,6 +69,10 @@
 private:
     const std::shared_ptr<C2GraphicAllocation> mGraphicAllocation;
     const C2Allocator::id_t mAllocatorId;
+
+    std::mutex mMapLock;
+    std::multiset<std::pair<size_t, size_t>> mMappedOffsetSize;
+    uint8_t *mMappedAddr;
 };
 
 C2AllocationBlob::C2AllocationBlob(
@@ -74,20 +80,74 @@
         C2Allocator::id_t allocatorId)
       : C2LinearAllocation(capacity),
         mGraphicAllocation(std::move(graphicAllocation)),
-        mAllocatorId(allocatorId) {}
+        mAllocatorId(allocatorId),
+        mMappedAddr(nullptr) {}
 
-C2AllocationBlob::~C2AllocationBlob() {}
+C2AllocationBlob::~C2AllocationBlob() {
+    if (mMappedAddr) {
+        C2Rect rect(capacity(), kLinearBufferHeight);
+        mGraphicAllocation->unmap(&mMappedAddr, rect, nullptr);
+    }
+}
 
 c2_status_t C2AllocationBlob::map(size_t offset, size_t size, C2MemoryUsage usage,
                                   C2Fence* fence, void** addr /* nonnull */) {
+    *addr = nullptr;
+    if (size > capacity() || offset > capacity() || offset > capacity() - size) {
+        ALOGV("C2AllocationBlob: map: bad offset / size: offset=%zu size=%zu capacity=%u",
+                offset, size, capacity());
+        return C2_BAD_VALUE;
+    }
+    std::unique_lock<std::mutex> lock(mMapLock);
+    if (mMappedAddr) {
+        *addr = mMappedAddr + offset;
+        mMappedOffsetSize.insert({offset, size});
+        ALOGV("C2AllocationBlob: mapped from existing mapping: offset=%zu size=%zu capacity=%u",
+                offset, size, capacity());
+        return C2_OK;
+    }
     C2PlanarLayout layout;
-    C2Rect rect = C2Rect(size, kLinearBufferHeight).at(offset, 0u);
-    return mGraphicAllocation->map(rect, usage, fence, &layout, reinterpret_cast<uint8_t**>(addr));
+    C2Rect rect = C2Rect(capacity(), kLinearBufferHeight);
+    c2_status_t err = mGraphicAllocation->map(rect, usage, fence, &layout, &mMappedAddr);
+    if (err != C2_OK) {
+        ALOGV("C2AllocationBlob: map failed: offset=%zu size=%zu capacity=%u err=%d",
+                offset, size, capacity(), err);
+        mMappedAddr = nullptr;
+        return err;
+    }
+    *addr = mMappedAddr + offset;
+    mMappedOffsetSize.insert({offset, size});
+    ALOGV("C2AllocationBlob: new map succeeded: offset=%zu size=%zu capacity=%u",
+            offset, size, capacity());
+    return C2_OK;
 }
 
 c2_status_t C2AllocationBlob::unmap(void* addr, size_t size, C2Fence* fenceFd) {
-    C2Rect rect(size, kLinearBufferHeight);
-    return mGraphicAllocation->unmap(reinterpret_cast<uint8_t**>(&addr), rect, fenceFd);
+    std::unique_lock<std::mutex> lock(mMapLock);
+    uint8_t *u8Addr = static_cast<uint8_t *>(addr);
+    if (u8Addr < mMappedAddr || mMappedAddr + capacity() < u8Addr + size) {
+        ALOGV("C2AllocationBlob: unmap: Bad addr / size: addr=%p size=%zu capacity=%u",
+                addr, size, capacity());
+        return C2_BAD_VALUE;
+    }
+    auto it = mMappedOffsetSize.find(std::make_pair(u8Addr - mMappedAddr, size));
+    if (it == mMappedOffsetSize.end()) {
+        ALOGV("C2AllocationBlob: unrecognized map: addr=%p size=%zu capacity=%u",
+                addr, size, capacity());
+        return C2_BAD_VALUE;
+    }
+    mMappedOffsetSize.erase(it);
+    if (!mMappedOffsetSize.empty()) {
+        ALOGV("C2AllocationBlob: still maintain mapping: addr=%p size=%zu capacity=%u",
+                addr, size, capacity());
+        return C2_OK;
+    }
+    C2Rect rect(capacity(), kLinearBufferHeight);
+    c2_status_t err = mGraphicAllocation->unmap(&mMappedAddr, rect, fenceFd);
+    ALOGV("C2AllocationBlob: last unmap: addr=%p size=%zu capacity=%u err=%d",
+            addr, size, capacity(), err);
+    mMappedAddr = nullptr;
+    return err;
 }
 
 /* ====================================== BLOB ALLOCATOR ====================================== */
diff --git a/media/libstagefright/codecs/amrnb/TEST_MAPPING b/media/codecs/amrnb/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/codecs/amrnb/TEST_MAPPING
rename to media/codecs/amrnb/TEST_MAPPING
diff --git a/media/libstagefright/codecs/amrnb/common/Android.bp b/media/codecs/amrnb/common/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/Android.bp
rename to media/codecs/amrnb/common/Android.bp
diff --git a/media/libstagefright/codecs/amrnb/common/MODULE_LICENSE_APACHE2 b/media/codecs/amrnb/common/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/MODULE_LICENSE_APACHE2
rename to media/codecs/amrnb/common/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrnb/common/NOTICE b/media/codecs/amrnb/common/NOTICE
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/NOTICE
rename to media/codecs/amrnb/common/NOTICE
diff --git a/media/libstagefright/codecs/amrnb/common/include/abs_s.h b/media/codecs/amrnb/common/include/abs_s.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/abs_s.h
rename to media/codecs/amrnb/common/include/abs_s.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/add.h b/media/codecs/amrnb/common/include/add.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/add.h
rename to media/codecs/amrnb/common/include/add.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/az_lsp.h b/media/codecs/amrnb/common/include/az_lsp.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/az_lsp.h
rename to media/codecs/amrnb/common/include/az_lsp.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/basic_op.h b/media/codecs/amrnb/common/include/basic_op.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/basic_op.h
rename to media/codecs/amrnb/common/include/basic_op.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h b/media/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h
rename to media/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/basic_op_arm_v5.h b/media/codecs/amrnb/common/include/basic_op_arm_v5.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/basic_op_arm_v5.h
rename to media/codecs/amrnb/common/include/basic_op_arm_v5.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/basic_op_c_equivalent.h b/media/codecs/amrnb/common/include/basic_op_c_equivalent.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/basic_op_c_equivalent.h
rename to media/codecs/amrnb/common/include/basic_op_c_equivalent.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/basicop_malloc.h b/media/codecs/amrnb/common/include/basicop_malloc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/basicop_malloc.h
rename to media/codecs/amrnb/common/include/basicop_malloc.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/bitno_tab.h b/media/codecs/amrnb/common/include/bitno_tab.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/bitno_tab.h
rename to media/codecs/amrnb/common/include/bitno_tab.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/bitreorder_tab.h b/media/codecs/amrnb/common/include/bitreorder_tab.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/bitreorder_tab.h
rename to media/codecs/amrnb/common/include/bitreorder_tab.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/bits2prm.h b/media/codecs/amrnb/common/include/bits2prm.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/bits2prm.h
rename to media/codecs/amrnb/common/include/bits2prm.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/cnst.h b/media/codecs/amrnb/common/include/cnst.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/cnst.h
rename to media/codecs/amrnb/common/include/cnst.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/cnst_vad.h b/media/codecs/amrnb/common/include/cnst_vad.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/cnst_vad.h
rename to media/codecs/amrnb/common/include/cnst_vad.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/copy.h b/media/codecs/amrnb/common/include/copy.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/copy.h
rename to media/codecs/amrnb/common/include/copy.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/d_gain_c.h b/media/codecs/amrnb/common/include/d_gain_c.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/d_gain_c.h
rename to media/codecs/amrnb/common/include/d_gain_c.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/d_gain_p.h b/media/codecs/amrnb/common/include/d_gain_p.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/d_gain_p.h
rename to media/codecs/amrnb/common/include/d_gain_p.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/d_plsf.h b/media/codecs/amrnb/common/include/d_plsf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/d_plsf.h
rename to media/codecs/amrnb/common/include/d_plsf.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/div_32.h b/media/codecs/amrnb/common/include/div_32.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/div_32.h
rename to media/codecs/amrnb/common/include/div_32.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/div_s.h b/media/codecs/amrnb/common/include/div_s.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/div_s.h
rename to media/codecs/amrnb/common/include/div_s.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/dtx_common_def.h b/media/codecs/amrnb/common/include/dtx_common_def.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/dtx_common_def.h
rename to media/codecs/amrnb/common/include/dtx_common_def.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/extract_h.h b/media/codecs/amrnb/common/include/extract_h.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/extract_h.h
rename to media/codecs/amrnb/common/include/extract_h.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/extract_l.h b/media/codecs/amrnb/common/include/extract_l.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/extract_l.h
rename to media/codecs/amrnb/common/include/extract_l.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/frame.h b/media/codecs/amrnb/common/include/frame.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/frame.h
rename to media/codecs/amrnb/common/include/frame.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/frame_type_3gpp.h b/media/codecs/amrnb/common/include/frame_type_3gpp.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/frame_type_3gpp.h
rename to media/codecs/amrnb/common/include/frame_type_3gpp.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/gc_pred.h b/media/codecs/amrnb/common/include/gc_pred.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/gc_pred.h
rename to media/codecs/amrnb/common/include/gc_pred.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/gmed_n.h b/media/codecs/amrnb/common/include/gmed_n.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/gmed_n.h
rename to media/codecs/amrnb/common/include/gmed_n.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/gsm_amr_typedefs.h b/media/codecs/amrnb/common/include/gsm_amr_typedefs.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/gsm_amr_typedefs.h
rename to media/codecs/amrnb/common/include/gsm_amr_typedefs.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/int_lpc.h b/media/codecs/amrnb/common/include/int_lpc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/int_lpc.h
rename to media/codecs/amrnb/common/include/int_lpc.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/int_lsf.h b/media/codecs/amrnb/common/include/int_lsf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/int_lsf.h
rename to media/codecs/amrnb/common/include/int_lsf.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h b/media/codecs/amrnb/common/include/inv_sqrt.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h
rename to media/codecs/amrnb/common/include/inv_sqrt.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_abs.h b/media/codecs/amrnb/common/include/l_abs.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_abs.h
rename to media/codecs/amrnb/common/include/l_abs.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_add.h b/media/codecs/amrnb/common/include/l_add.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_add.h
rename to media/codecs/amrnb/common/include/l_add.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_add_c.h b/media/codecs/amrnb/common/include/l_add_c.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_add_c.h
rename to media/codecs/amrnb/common/include/l_add_c.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_comp.h b/media/codecs/amrnb/common/include/l_comp.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_comp.h
rename to media/codecs/amrnb/common/include/l_comp.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_deposit_h.h b/media/codecs/amrnb/common/include/l_deposit_h.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_deposit_h.h
rename to media/codecs/amrnb/common/include/l_deposit_h.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_deposit_l.h b/media/codecs/amrnb/common/include/l_deposit_l.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_deposit_l.h
rename to media/codecs/amrnb/common/include/l_deposit_l.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_extract.h b/media/codecs/amrnb/common/include/l_extract.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_extract.h
rename to media/codecs/amrnb/common/include/l_extract.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_mac.h b/media/codecs/amrnb/common/include/l_mac.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_mac.h
rename to media/codecs/amrnb/common/include/l_mac.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_msu.h b/media/codecs/amrnb/common/include/l_msu.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_msu.h
rename to media/codecs/amrnb/common/include/l_msu.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_mult.h b/media/codecs/amrnb/common/include/l_mult.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_mult.h
rename to media/codecs/amrnb/common/include/l_mult.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_negate.h b/media/codecs/amrnb/common/include/l_negate.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_negate.h
rename to media/codecs/amrnb/common/include/l_negate.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_shl.h b/media/codecs/amrnb/common/include/l_shl.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_shl.h
rename to media/codecs/amrnb/common/include/l_shl.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_shr.h b/media/codecs/amrnb/common/include/l_shr.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_shr.h
rename to media/codecs/amrnb/common/include/l_shr.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_shr_r.h b/media/codecs/amrnb/common/include/l_shr_r.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_shr_r.h
rename to media/codecs/amrnb/common/include/l_shr_r.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/l_sub.h b/media/codecs/amrnb/common/include/l_sub.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/l_sub.h
rename to media/codecs/amrnb/common/include/l_sub.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/log2.h b/media/codecs/amrnb/common/include/log2.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/log2.h
rename to media/codecs/amrnb/common/include/log2.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/log2_norm.h b/media/codecs/amrnb/common/include/log2_norm.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/log2_norm.h
rename to media/codecs/amrnb/common/include/log2_norm.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/lsfwt.h b/media/codecs/amrnb/common/include/lsfwt.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/lsfwt.h
rename to media/codecs/amrnb/common/include/lsfwt.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/lsp.h b/media/codecs/amrnb/common/include/lsp.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/lsp.h
rename to media/codecs/amrnb/common/include/lsp.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/lsp_az.h b/media/codecs/amrnb/common/include/lsp_az.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/lsp_az.h
rename to media/codecs/amrnb/common/include/lsp_az.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/lsp_lsf.h b/media/codecs/amrnb/common/include/lsp_lsf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/lsp_lsf.h
rename to media/codecs/amrnb/common/include/lsp_lsf.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/lsp_tab.h b/media/codecs/amrnb/common/include/lsp_tab.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/lsp_tab.h
rename to media/codecs/amrnb/common/include/lsp_tab.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/mac_32.h b/media/codecs/amrnb/common/include/mac_32.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/mac_32.h
rename to media/codecs/amrnb/common/include/mac_32.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/mode.h b/media/codecs/amrnb/common/include/mode.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/mode.h
rename to media/codecs/amrnb/common/include/mode.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/mpy_32.h b/media/codecs/amrnb/common/include/mpy_32.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/mpy_32.h
rename to media/codecs/amrnb/common/include/mpy_32.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/mpy_32_16.h b/media/codecs/amrnb/common/include/mpy_32_16.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/mpy_32_16.h
rename to media/codecs/amrnb/common/include/mpy_32_16.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/mult.h b/media/codecs/amrnb/common/include/mult.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/mult.h
rename to media/codecs/amrnb/common/include/mult.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/mult_r.h b/media/codecs/amrnb/common/include/mult_r.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/mult_r.h
rename to media/codecs/amrnb/common/include/mult_r.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/n_proc.h b/media/codecs/amrnb/common/include/n_proc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/n_proc.h
rename to media/codecs/amrnb/common/include/n_proc.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/negate.h b/media/codecs/amrnb/common/include/negate.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/negate.h
rename to media/codecs/amrnb/common/include/negate.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/norm_l.h b/media/codecs/amrnb/common/include/norm_l.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/norm_l.h
rename to media/codecs/amrnb/common/include/norm_l.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/norm_s.h b/media/codecs/amrnb/common/include/norm_s.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/norm_s.h
rename to media/codecs/amrnb/common/include/norm_s.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/oper_32b.h b/media/codecs/amrnb/common/include/oper_32b.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/oper_32b.h
rename to media/codecs/amrnb/common/include/oper_32b.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/p_ol_wgh.h b/media/codecs/amrnb/common/include/p_ol_wgh.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/p_ol_wgh.h
rename to media/codecs/amrnb/common/include/p_ol_wgh.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/pow2.h b/media/codecs/amrnb/common/include/pow2.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/pow2.h
rename to media/codecs/amrnb/common/include/pow2.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/pred_lt.h b/media/codecs/amrnb/common/include/pred_lt.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/pred_lt.h
rename to media/codecs/amrnb/common/include/pred_lt.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/q_plsf.h b/media/codecs/amrnb/common/include/q_plsf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/q_plsf.h
rename to media/codecs/amrnb/common/include/q_plsf.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/q_plsf_3_tbl.h b/media/codecs/amrnb/common/include/q_plsf_3_tbl.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/q_plsf_3_tbl.h
rename to media/codecs/amrnb/common/include/q_plsf_3_tbl.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/q_plsf_5_tbl.h b/media/codecs/amrnb/common/include/q_plsf_5_tbl.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/q_plsf_5_tbl.h
rename to media/codecs/amrnb/common/include/q_plsf_5_tbl.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/qgain475_tab.h b/media/codecs/amrnb/common/include/qgain475_tab.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/qgain475_tab.h
rename to media/codecs/amrnb/common/include/qgain475_tab.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/qua_gain.h b/media/codecs/amrnb/common/include/qua_gain.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/qua_gain.h
rename to media/codecs/amrnb/common/include/qua_gain.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/qua_gain_tbl.h b/media/codecs/amrnb/common/include/qua_gain_tbl.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/qua_gain_tbl.h
rename to media/codecs/amrnb/common/include/qua_gain_tbl.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/reorder.h b/media/codecs/amrnb/common/include/reorder.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/reorder.h
rename to media/codecs/amrnb/common/include/reorder.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/residu.h b/media/codecs/amrnb/common/include/residu.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/residu.h
rename to media/codecs/amrnb/common/include/residu.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/reverse_bits.h b/media/codecs/amrnb/common/include/reverse_bits.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/reverse_bits.h
rename to media/codecs/amrnb/common/include/reverse_bits.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/round.h b/media/codecs/amrnb/common/include/round.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/round.h
rename to media/codecs/amrnb/common/include/round.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/set_zero.h b/media/codecs/amrnb/common/include/set_zero.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/set_zero.h
rename to media/codecs/amrnb/common/include/set_zero.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/shl.h b/media/codecs/amrnb/common/include/shl.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/shl.h
rename to media/codecs/amrnb/common/include/shl.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/shr.h b/media/codecs/amrnb/common/include/shr.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/shr.h
rename to media/codecs/amrnb/common/include/shr.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/shr_r.h b/media/codecs/amrnb/common/include/shr_r.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/shr_r.h
rename to media/codecs/amrnb/common/include/shr_r.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/sqrt_l.h b/media/codecs/amrnb/common/include/sqrt_l.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/sqrt_l.h
rename to media/codecs/amrnb/common/include/sqrt_l.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/sub.h b/media/codecs/amrnb/common/include/sub.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/sub.h
rename to media/codecs/amrnb/common/include/sub.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/syn_filt.h b/media/codecs/amrnb/common/include/syn_filt.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/syn_filt.h
rename to media/codecs/amrnb/common/include/syn_filt.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/typedef.h b/media/codecs/amrnb/common/include/typedef.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/typedef.h
rename to media/codecs/amrnb/common/include/typedef.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/vad.h b/media/codecs/amrnb/common/include/vad.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/vad.h
rename to media/codecs/amrnb/common/include/vad.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/vad1.h b/media/codecs/amrnb/common/include/vad1.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/vad1.h
rename to media/codecs/amrnb/common/include/vad1.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/vad2.h b/media/codecs/amrnb/common/include/vad2.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/vad2.h
rename to media/codecs/amrnb/common/include/vad2.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/weight_a.h b/media/codecs/amrnb/common/include/weight_a.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/weight_a.h
rename to media/codecs/amrnb/common/include/weight_a.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/window_tab.h b/media/codecs/amrnb/common/include/window_tab.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/window_tab.h
rename to media/codecs/amrnb/common/include/window_tab.h
diff --git a/media/libstagefright/codecs/amrnb/common/include/wmf_to_ets.h b/media/codecs/amrnb/common/include/wmf_to_ets.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/include/wmf_to_ets.h
rename to media/codecs/amrnb/common/include/wmf_to_ets.h
diff --git a/media/libstagefright/codecs/amrnb/common/src/add.cpp b/media/codecs/amrnb/common/src/add.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/add.cpp
rename to media/codecs/amrnb/common/src/add.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/az_lsp.cpp b/media/codecs/amrnb/common/src/az_lsp.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/az_lsp.cpp
rename to media/codecs/amrnb/common/src/az_lsp.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp b/media/codecs/amrnb/common/src/bitno_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp
rename to media/codecs/amrnb/common/src/bitno_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp b/media/codecs/amrnb/common/src/bitreorder_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp
rename to media/codecs/amrnb/common/src/bitreorder_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/bits2prm.cpp b/media/codecs/amrnb/common/src/bits2prm.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/bits2prm.cpp
rename to media/codecs/amrnb/common/src/bits2prm.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp b/media/codecs/amrnb/common/src/c2_9pf_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp
rename to media/codecs/amrnb/common/src/c2_9pf_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/copy.cpp b/media/codecs/amrnb/common/src/copy.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/copy.cpp
rename to media/codecs/amrnb/common/src/copy.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/div_32.cpp b/media/codecs/amrnb/common/src/div_32.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/div_32.cpp
rename to media/codecs/amrnb/common/src/div_32.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/div_s.cpp b/media/codecs/amrnb/common/src/div_s.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/div_s.cpp
rename to media/codecs/amrnb/common/src/div_s.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/extract_h.cpp b/media/codecs/amrnb/common/src/extract_h.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/extract_h.cpp
rename to media/codecs/amrnb/common/src/extract_h.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/extract_l.cpp b/media/codecs/amrnb/common/src/extract_l.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/extract_l.cpp
rename to media/codecs/amrnb/common/src/extract_l.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp b/media/codecs/amrnb/common/src/gains_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp
rename to media/codecs/amrnb/common/src/gains_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/gc_pred.cpp b/media/codecs/amrnb/common/src/gc_pred.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/gc_pred.cpp
rename to media/codecs/amrnb/common/src/gc_pred.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/gmed_n.cpp b/media/codecs/amrnb/common/src/gmed_n.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/gmed_n.cpp
rename to media/codecs/amrnb/common/src/gmed_n.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp b/media/codecs/amrnb/common/src/gray_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp
rename to media/codecs/amrnb/common/src/gray_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp b/media/codecs/amrnb/common/src/grid_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp
rename to media/codecs/amrnb/common/src/grid_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/int_lpc.cpp b/media/codecs/amrnb/common/src/int_lpc.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/int_lpc.cpp
rename to media/codecs/amrnb/common/src/int_lpc.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/inv_sqrt.cpp b/media/codecs/amrnb/common/src/inv_sqrt.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/inv_sqrt.cpp
rename to media/codecs/amrnb/common/src/inv_sqrt.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp b/media/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
rename to media/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/l_abs.cpp b/media/codecs/amrnb/common/src/l_abs.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/l_abs.cpp
rename to media/codecs/amrnb/common/src/l_abs.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/l_deposit_h.cpp b/media/codecs/amrnb/common/src/l_deposit_h.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/l_deposit_h.cpp
rename to media/codecs/amrnb/common/src/l_deposit_h.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/l_deposit_l.cpp b/media/codecs/amrnb/common/src/l_deposit_l.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/l_deposit_l.cpp
rename to media/codecs/amrnb/common/src/l_deposit_l.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/l_shr_r.cpp b/media/codecs/amrnb/common/src/l_shr_r.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/l_shr_r.cpp
rename to media/codecs/amrnb/common/src/l_shr_r.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/log2.cpp b/media/codecs/amrnb/common/src/log2.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/log2.cpp
rename to media/codecs/amrnb/common/src/log2.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/log2_norm.cpp b/media/codecs/amrnb/common/src/log2_norm.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/log2_norm.cpp
rename to media/codecs/amrnb/common/src/log2_norm.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp b/media/codecs/amrnb/common/src/log2_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp
rename to media/codecs/amrnb/common/src/log2_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsfwt.cpp b/media/codecs/amrnb/common/src/lsfwt.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/lsfwt.cpp
rename to media/codecs/amrnb/common/src/lsfwt.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp.cpp b/media/codecs/amrnb/common/src/lsp.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/lsp.cpp
rename to media/codecs/amrnb/common/src/lsp.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp_az.cpp b/media/codecs/amrnb/common/src/lsp_az.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/lsp_az.cpp
rename to media/codecs/amrnb/common/src/lsp_az.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp_lsf.cpp b/media/codecs/amrnb/common/src/lsp_lsf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/lsp_lsf.cpp
rename to media/codecs/amrnb/common/src/lsp_lsf.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp b/media/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
rename to media/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp b/media/codecs/amrnb/common/src/lsp_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp
rename to media/codecs/amrnb/common/src/lsp_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/mult_r.cpp b/media/codecs/amrnb/common/src/mult_r.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/mult_r.cpp
rename to media/codecs/amrnb/common/src/mult_r.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/negate.cpp b/media/codecs/amrnb/common/src/negate.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/negate.cpp
rename to media/codecs/amrnb/common/src/negate.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/norm_l.cpp b/media/codecs/amrnb/common/src/norm_l.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/norm_l.cpp
rename to media/codecs/amrnb/common/src/norm_l.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/norm_s.cpp b/media/codecs/amrnb/common/src/norm_s.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/norm_s.cpp
rename to media/codecs/amrnb/common/src/norm_s.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp b/media/codecs/amrnb/common/src/ph_disp_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp
rename to media/codecs/amrnb/common/src/ph_disp_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/pow2.cpp b/media/codecs/amrnb/common/src/pow2.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/pow2.cpp
rename to media/codecs/amrnb/common/src/pow2.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp b/media/codecs/amrnb/common/src/pow2_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp
rename to media/codecs/amrnb/common/src/pow2_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/pred_lt.cpp b/media/codecs/amrnb/common/src/pred_lt.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/pred_lt.cpp
rename to media/codecs/amrnb/common/src/pred_lt.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/q_plsf.cpp b/media/codecs/amrnb/common/src/q_plsf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/q_plsf.cpp
rename to media/codecs/amrnb/common/src/q_plsf.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/q_plsf_3.cpp b/media/codecs/amrnb/common/src/q_plsf_3.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/q_plsf_3.cpp
rename to media/codecs/amrnb/common/src/q_plsf_3.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/q_plsf_3_tbl.cpp b/media/codecs/amrnb/common/src/q_plsf_3_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/q_plsf_3_tbl.cpp
rename to media/codecs/amrnb/common/src/q_plsf_3_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/q_plsf_5.cpp b/media/codecs/amrnb/common/src/q_plsf_5.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/q_plsf_5.cpp
rename to media/codecs/amrnb/common/src/q_plsf_5.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp b/media/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
rename to media/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp b/media/codecs/amrnb/common/src/qua_gain_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp
rename to media/codecs/amrnb/common/src/qua_gain_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/reorder.cpp b/media/codecs/amrnb/common/src/reorder.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/reorder.cpp
rename to media/codecs/amrnb/common/src/reorder.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/residu.cpp b/media/codecs/amrnb/common/src/residu.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/residu.cpp
rename to media/codecs/amrnb/common/src/residu.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/round.cpp b/media/codecs/amrnb/common/src/round.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/round.cpp
rename to media/codecs/amrnb/common/src/round.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/set_zero.cpp b/media/codecs/amrnb/common/src/set_zero.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/set_zero.cpp
rename to media/codecs/amrnb/common/src/set_zero.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/shr.cpp b/media/codecs/amrnb/common/src/shr.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/shr.cpp
rename to media/codecs/amrnb/common/src/shr.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/shr_r.cpp b/media/codecs/amrnb/common/src/shr_r.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/shr_r.cpp
rename to media/codecs/amrnb/common/src/shr_r.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/sqrt_l.cpp b/media/codecs/amrnb/common/src/sqrt_l.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/sqrt_l.cpp
rename to media/codecs/amrnb/common/src/sqrt_l.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp b/media/codecs/amrnb/common/src/sqrt_l_tbl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp
rename to media/codecs/amrnb/common/src/sqrt_l_tbl.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/sub.cpp b/media/codecs/amrnb/common/src/sub.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/sub.cpp
rename to media/codecs/amrnb/common/src/sub.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/syn_filt.cpp b/media/codecs/amrnb/common/src/syn_filt.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/syn_filt.cpp
rename to media/codecs/amrnb/common/src/syn_filt.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/vad1.cpp b/media/codecs/amrnb/common/src/vad1.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/vad1.cpp
rename to media/codecs/amrnb/common/src/vad1.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/weight_a.cpp b/media/codecs/amrnb/common/src/weight_a.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/weight_a.cpp
rename to media/codecs/amrnb/common/src/weight_a.cpp
diff --git a/media/libstagefright/codecs/amrnb/common/src/window_tab.cpp b/media/codecs/amrnb/common/src/window_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/common/src/window_tab.cpp
rename to media/codecs/amrnb/common/src/window_tab.cpp
diff --git a/media/codecs/amrnb/dec/Android.bp b/media/codecs/amrnb/dec/Android.bp
new file mode 100644
index 0000000..944ff75
--- /dev/null
+++ b/media/codecs/amrnb/dec/Android.bp
@@ -0,0 +1,106 @@
+cc_library_static {
+    name: "libstagefright_amrnbdec",
+    vendor_available: true,
+    host_supported: true,
+    min_sdk_version: "29",
+
+    srcs: [
+        "src/a_refl.cpp",
+        "src/agc.cpp",
+        "src/amrdecode.cpp",
+        "src/b_cn_cod.cpp",
+        "src/bgnscd.cpp",
+        "src/c_g_aver.cpp",
+        "src/d1035pf.cpp",
+        "src/d2_11pf.cpp",
+        "src/d2_9pf.cpp",
+        "src/d3_14pf.cpp",
+        "src/d4_17pf.cpp",
+        "src/d8_31pf.cpp",
+        "src/d_gain_c.cpp",
+        "src/d_gain_p.cpp",
+        "src/d_plsf.cpp",
+        "src/d_plsf_3.cpp",
+        "src/d_plsf_5.cpp",
+        "src/dec_amr.cpp",
+        "src/dec_gain.cpp",
+        "src/dec_input_format_tab.cpp",
+        "src/dec_lag3.cpp",
+        "src/dec_lag6.cpp",
+        "src/dtx_dec.cpp",
+        "src/ec_gains.cpp",
+        "src/ex_ctrl.cpp",
+        "src/if2_to_ets.cpp",
+        "src/int_lsf.cpp",
+        "src/lsp_avg.cpp",
+        "src/ph_disp.cpp",
+        "src/post_pro.cpp",
+        "src/preemph.cpp",
+        "src/pstfilt.cpp",
+        "src/qgain475_tab.cpp",
+        "src/sp_dec.cpp",
+        "src/wmf_to_ets.cpp",
+    ],
+
+    export_include_dirs: ["src"],
+
+    cflags: [
+        "-DOSCL_UNUSED_ARG(x)=(void)(x)",
+        "-DOSCL_IMPORT_REF=",
+
+        "-Werror",
+    ],
+
+    //sanitize: {
+    //    misc_undefined: [
+    //        "signed-integer-overflow",
+    //    ],
+    //},
+
+    shared_libs: [
+        "libstagefright_amrnb_common",
+        "liblog",
+    ],
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+//###############################################################################
+cc_test {
+    name: "libstagefright_amrnbdec_test",
+    gtest: false,
+    host_supported: true,
+
+    srcs: ["test/amrnbdec_test.cpp"],
+
+    cflags: ["-Wall", "-Werror"],
+
+    local_include_dirs: ["src"],
+
+    static_libs: [
+        "libstagefright_amrnbdec",
+        "libsndfile",
+    ],
+
+    shared_libs: [
+        "libstagefright_amrnb_common",
+        "libaudioutils",
+        "liblog",
+    ],
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+
+    //sanitize: {
+    //    misc_undefined: [
+    //        "signed-integer-overflow",
+    //    ],
+    //},
+}
diff --git a/media/libstagefright/codecs/amrnb/dec/MODULE_LICENSE_APACHE2 b/media/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
rename to media/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrnb/dec/NOTICE b/media/codecs/amrnb/dec/NOTICE
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/NOTICE
rename to media/codecs/amrnb/dec/NOTICE
diff --git a/media/libstagefright/codecs/amrnb/dec/src/a_refl.cpp b/media/codecs/amrnb/dec/src/a_refl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/a_refl.cpp
rename to media/codecs/amrnb/dec/src/a_refl.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/a_refl.h b/media/codecs/amrnb/dec/src/a_refl.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/a_refl.h
rename to media/codecs/amrnb/dec/src/a_refl.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/agc.cpp b/media/codecs/amrnb/dec/src/agc.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/agc.cpp
rename to media/codecs/amrnb/dec/src/agc.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/agc.h b/media/codecs/amrnb/dec/src/agc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/agc.h
rename to media/codecs/amrnb/dec/src/agc.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/amrdecode.cpp b/media/codecs/amrnb/dec/src/amrdecode.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/amrdecode.cpp
rename to media/codecs/amrnb/dec/src/amrdecode.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/amrdecode.h b/media/codecs/amrnb/dec/src/amrdecode.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/amrdecode.h
rename to media/codecs/amrnb/dec/src/amrdecode.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/b_cn_cod.cpp b/media/codecs/amrnb/dec/src/b_cn_cod.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/b_cn_cod.cpp
rename to media/codecs/amrnb/dec/src/b_cn_cod.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/b_cn_cod.h b/media/codecs/amrnb/dec/src/b_cn_cod.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/b_cn_cod.h
rename to media/codecs/amrnb/dec/src/b_cn_cod.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/bgnscd.cpp b/media/codecs/amrnb/dec/src/bgnscd.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/bgnscd.cpp
rename to media/codecs/amrnb/dec/src/bgnscd.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/bgnscd.h b/media/codecs/amrnb/dec/src/bgnscd.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/bgnscd.h
rename to media/codecs/amrnb/dec/src/bgnscd.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/c_g_aver.cpp b/media/codecs/amrnb/dec/src/c_g_aver.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/c_g_aver.cpp
rename to media/codecs/amrnb/dec/src/c_g_aver.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/c_g_aver.h b/media/codecs/amrnb/dec/src/c_g_aver.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/c_g_aver.h
rename to media/codecs/amrnb/dec/src/c_g_aver.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d1035pf.cpp b/media/codecs/amrnb/dec/src/d1035pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d1035pf.cpp
rename to media/codecs/amrnb/dec/src/d1035pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d1035pf.h b/media/codecs/amrnb/dec/src/d1035pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d1035pf.h
rename to media/codecs/amrnb/dec/src/d1035pf.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d2_11pf.cpp b/media/codecs/amrnb/dec/src/d2_11pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d2_11pf.cpp
rename to media/codecs/amrnb/dec/src/d2_11pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d2_11pf.h b/media/codecs/amrnb/dec/src/d2_11pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d2_11pf.h
rename to media/codecs/amrnb/dec/src/d2_11pf.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d2_9pf.cpp b/media/codecs/amrnb/dec/src/d2_9pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d2_9pf.cpp
rename to media/codecs/amrnb/dec/src/d2_9pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d2_9pf.h b/media/codecs/amrnb/dec/src/d2_9pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d2_9pf.h
rename to media/codecs/amrnb/dec/src/d2_9pf.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d3_14pf.cpp b/media/codecs/amrnb/dec/src/d3_14pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d3_14pf.cpp
rename to media/codecs/amrnb/dec/src/d3_14pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d3_14pf.h b/media/codecs/amrnb/dec/src/d3_14pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d3_14pf.h
rename to media/codecs/amrnb/dec/src/d3_14pf.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d4_17pf.cpp b/media/codecs/amrnb/dec/src/d4_17pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d4_17pf.cpp
rename to media/codecs/amrnb/dec/src/d4_17pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d4_17pf.h b/media/codecs/amrnb/dec/src/d4_17pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d4_17pf.h
rename to media/codecs/amrnb/dec/src/d4_17pf.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d8_31pf.cpp b/media/codecs/amrnb/dec/src/d8_31pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d8_31pf.cpp
rename to media/codecs/amrnb/dec/src/d8_31pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d8_31pf.h b/media/codecs/amrnb/dec/src/d8_31pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d8_31pf.h
rename to media/codecs/amrnb/dec/src/d8_31pf.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d_gain_c.cpp b/media/codecs/amrnb/dec/src/d_gain_c.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d_gain_c.cpp
rename to media/codecs/amrnb/dec/src/d_gain_c.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d_gain_p.cpp b/media/codecs/amrnb/dec/src/d_gain_p.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d_gain_p.cpp
rename to media/codecs/amrnb/dec/src/d_gain_p.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d_plsf.cpp b/media/codecs/amrnb/dec/src/d_plsf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d_plsf.cpp
rename to media/codecs/amrnb/dec/src/d_plsf.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d_plsf_3.cpp b/media/codecs/amrnb/dec/src/d_plsf_3.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d_plsf_3.cpp
rename to media/codecs/amrnb/dec/src/d_plsf_3.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/d_plsf_5.cpp b/media/codecs/amrnb/dec/src/d_plsf_5.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/d_plsf_5.cpp
rename to media/codecs/amrnb/dec/src/d_plsf_5.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_amr.cpp b/media/codecs/amrnb/dec/src/dec_amr.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dec_amr.cpp
rename to media/codecs/amrnb/dec/src/dec_amr.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_amr.h b/media/codecs/amrnb/dec/src/dec_amr.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dec_amr.h
rename to media/codecs/amrnb/dec/src/dec_amr.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_gain.cpp b/media/codecs/amrnb/dec/src/dec_gain.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dec_gain.cpp
rename to media/codecs/amrnb/dec/src/dec_gain.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_gain.h b/media/codecs/amrnb/dec/src/dec_gain.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dec_gain.h
rename to media/codecs/amrnb/dec/src/dec_gain.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp b/media/codecs/amrnb/dec/src/dec_input_format_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp
rename to media/codecs/amrnb/dec/src/dec_input_format_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_lag3.cpp b/media/codecs/amrnb/dec/src/dec_lag3.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dec_lag3.cpp
rename to media/codecs/amrnb/dec/src/dec_lag3.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_lag3.h b/media/codecs/amrnb/dec/src/dec_lag3.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dec_lag3.h
rename to media/codecs/amrnb/dec/src/dec_lag3.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_lag6.cpp b/media/codecs/amrnb/dec/src/dec_lag6.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dec_lag6.cpp
rename to media/codecs/amrnb/dec/src/dec_lag6.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_lag6.h b/media/codecs/amrnb/dec/src/dec_lag6.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dec_lag6.h
rename to media/codecs/amrnb/dec/src/dec_lag6.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dtx_dec.cpp b/media/codecs/amrnb/dec/src/dtx_dec.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dtx_dec.cpp
rename to media/codecs/amrnb/dec/src/dtx_dec.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dtx_dec.h b/media/codecs/amrnb/dec/src/dtx_dec.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/dtx_dec.h
rename to media/codecs/amrnb/dec/src/dtx_dec.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/ec_gains.cpp b/media/codecs/amrnb/dec/src/ec_gains.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/ec_gains.cpp
rename to media/codecs/amrnb/dec/src/ec_gains.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/ec_gains.h b/media/codecs/amrnb/dec/src/ec_gains.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/ec_gains.h
rename to media/codecs/amrnb/dec/src/ec_gains.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/ex_ctrl.cpp b/media/codecs/amrnb/dec/src/ex_ctrl.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/ex_ctrl.cpp
rename to media/codecs/amrnb/dec/src/ex_ctrl.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/ex_ctrl.h b/media/codecs/amrnb/dec/src/ex_ctrl.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/ex_ctrl.h
rename to media/codecs/amrnb/dec/src/ex_ctrl.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/gsmamr_dec.h b/media/codecs/amrnb/dec/src/gsmamr_dec.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/gsmamr_dec.h
rename to media/codecs/amrnb/dec/src/gsmamr_dec.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/if2_to_ets.cpp b/media/codecs/amrnb/dec/src/if2_to_ets.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/if2_to_ets.cpp
rename to media/codecs/amrnb/dec/src/if2_to_ets.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/if2_to_ets.h b/media/codecs/amrnb/dec/src/if2_to_ets.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/if2_to_ets.h
rename to media/codecs/amrnb/dec/src/if2_to_ets.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/int_lsf.cpp b/media/codecs/amrnb/dec/src/int_lsf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/int_lsf.cpp
rename to media/codecs/amrnb/dec/src/int_lsf.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/lsp_avg.cpp b/media/codecs/amrnb/dec/src/lsp_avg.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/lsp_avg.cpp
rename to media/codecs/amrnb/dec/src/lsp_avg.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/lsp_avg.h b/media/codecs/amrnb/dec/src/lsp_avg.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/lsp_avg.h
rename to media/codecs/amrnb/dec/src/lsp_avg.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/ph_disp.cpp b/media/codecs/amrnb/dec/src/ph_disp.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/ph_disp.cpp
rename to media/codecs/amrnb/dec/src/ph_disp.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/ph_disp.h b/media/codecs/amrnb/dec/src/ph_disp.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/ph_disp.h
rename to media/codecs/amrnb/dec/src/ph_disp.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/post_pro.cpp b/media/codecs/amrnb/dec/src/post_pro.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/post_pro.cpp
rename to media/codecs/amrnb/dec/src/post_pro.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/post_pro.h b/media/codecs/amrnb/dec/src/post_pro.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/post_pro.h
rename to media/codecs/amrnb/dec/src/post_pro.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/preemph.cpp b/media/codecs/amrnb/dec/src/preemph.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/preemph.cpp
rename to media/codecs/amrnb/dec/src/preemph.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/preemph.h b/media/codecs/amrnb/dec/src/preemph.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/preemph.h
rename to media/codecs/amrnb/dec/src/preemph.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/pstfilt.cpp b/media/codecs/amrnb/dec/src/pstfilt.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/pstfilt.cpp
rename to media/codecs/amrnb/dec/src/pstfilt.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/pstfilt.h b/media/codecs/amrnb/dec/src/pstfilt.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/pstfilt.h
rename to media/codecs/amrnb/dec/src/pstfilt.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp b/media/codecs/amrnb/dec/src/qgain475_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp
rename to media/codecs/amrnb/dec/src/qgain475_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/sp_dec.cpp b/media/codecs/amrnb/dec/src/sp_dec.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/sp_dec.cpp
rename to media/codecs/amrnb/dec/src/sp_dec.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/src/sp_dec.h b/media/codecs/amrnb/dec/src/sp_dec.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/sp_dec.h
rename to media/codecs/amrnb/dec/src/sp_dec.h
diff --git a/media/libstagefright/codecs/amrnb/dec/src/wmf_to_ets.cpp b/media/codecs/amrnb/dec/src/wmf_to_ets.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/src/wmf_to_ets.cpp
rename to media/codecs/amrnb/dec/src/wmf_to_ets.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h b/media/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h
rename to media/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h
diff --git a/media/libstagefright/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp b/media/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp
rename to media/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp
diff --git a/media/libstagefright/codecs/amrnb/dec/test/Android.bp b/media/codecs/amrnb/dec/test/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/test/Android.bp
rename to media/codecs/amrnb/dec/test/Android.bp
diff --git a/media/libstagefright/codecs/amrnb/dec/test/AndroidTest.xml b/media/codecs/amrnb/dec/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/test/AndroidTest.xml
rename to media/codecs/amrnb/dec/test/AndroidTest.xml
diff --git a/media/libstagefright/codecs/amrnb/dec/test/README.md b/media/codecs/amrnb/dec/test/README.md
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/test/README.md
rename to media/codecs/amrnb/dec/test/README.md
diff --git a/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp b/media/codecs/amrnb/dec/test/amrnbdec_test.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp
rename to media/codecs/amrnb/dec/test/amrnbdec_test.cpp
diff --git a/media/codecs/amrnb/enc/Android.bp b/media/codecs/amrnb/enc/Android.bp
new file mode 100644
index 0000000..534ce04
--- /dev/null
+++ b/media/codecs/amrnb/enc/Android.bp
@@ -0,0 +1,113 @@
+cc_library_static {
+    name: "libstagefright_amrnbenc",
+    vendor_available: true,
+    min_sdk_version: "29",
+
+    srcs: [
+        "src/amrencode.cpp",
+        "src/autocorr.cpp",
+        "src/c1035pf.cpp",
+        "src/c2_11pf.cpp",
+        "src/c2_9pf.cpp",
+        "src/c3_14pf.cpp",
+        "src/c4_17pf.cpp",
+        "src/c8_31pf.cpp",
+        "src/calc_cor.cpp",
+        "src/calc_en.cpp",
+        "src/cbsearch.cpp",
+        "src/cl_ltp.cpp",
+        "src/cod_amr.cpp",
+        "src/convolve.cpp",
+        "src/cor_h.cpp",
+        "src/cor_h_x.cpp",
+        "src/cor_h_x2.cpp",
+        "src/corrwght_tab.cpp",
+        "src/dtx_enc.cpp",
+        "src/enc_lag3.cpp",
+        "src/enc_lag6.cpp",
+        "src/enc_output_format_tab.cpp",
+        "src/ets_to_if2.cpp",
+        "src/ets_to_wmf.cpp",
+        "src/g_adapt.cpp",
+        "src/g_code.cpp",
+        "src/g_pitch.cpp",
+        "src/gain_q.cpp",
+        "src/hp_max.cpp",
+        "src/inter_36.cpp",
+        "src/inter_36_tab.cpp",
+        "src/l_comp.cpp",
+        "src/l_extract.cpp",
+        "src/l_negate.cpp",
+        "src/lag_wind.cpp",
+        "src/lag_wind_tab.cpp",
+        "src/levinson.cpp",
+        "src/lpc.cpp",
+        "src/ol_ltp.cpp",
+        "src/p_ol_wgh.cpp",
+        "src/pitch_fr.cpp",
+        "src/pitch_ol.cpp",
+        "src/pre_big.cpp",
+        "src/pre_proc.cpp",
+        "src/prm2bits.cpp",
+        "src/q_gain_c.cpp",
+        "src/q_gain_p.cpp",
+        "src/qgain475.cpp",
+        "src/qgain795.cpp",
+        "src/qua_gain.cpp",
+        "src/s10_8pf.cpp",
+        "src/set_sign.cpp",
+        "src/sid_sync.cpp",
+        "src/sp_enc.cpp",
+        "src/spreproc.cpp",
+        "src/spstproc.cpp",
+        "src/ton_stab.cpp",
+    ],
+
+    header_libs: ["libstagefright_headers"],
+    export_include_dirs: ["src"],
+
+    cflags: [
+        "-DOSCL_UNUSED_ARG(x)=(void)(x)",
+        "-Werror",
+    ],
+
+    //addressing b/25409744
+    //sanitize: {
+    //    misc_undefined: [
+    //        "signed-integer-overflow",
+    //    ],
+    //},
+
+    shared_libs: ["libstagefright_amrnb_common"],
+
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+//###############################################################################
+
+cc_test {
+    name: "libstagefright_amrnbenc_test",
+    gtest: false,
+
+    srcs: ["test/amrnb_enc_test.cpp"],
+
+    cflags: ["-Wall", "-Werror"],
+
+    local_include_dirs: ["src"],
+
+    static_libs: ["libstagefright_amrnbenc"],
+
+    shared_libs: ["libstagefright_amrnb_common"],
+
+    //addressing b/25409744
+    //sanitize: {
+    //    misc_undefined: [
+    //        "signed-integer-overflow",
+    //    ],
+    //},
+}
diff --git a/media/libstagefright/codecs/amrnb/enc/MODULE_LICENSE_APACHE2 b/media/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
rename to media/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrnb/enc/NOTICE b/media/codecs/amrnb/enc/NOTICE
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/NOTICE
rename to media/codecs/amrnb/enc/NOTICE
diff --git a/media/libstagefright/codecs/amrnb/enc/fuzzer/Android.bp b/media/codecs/amrnb/enc/fuzzer/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/fuzzer/Android.bp
rename to media/codecs/amrnb/enc/fuzzer/Android.bp
diff --git a/media/libstagefright/codecs/amrnb/enc/fuzzer/README.md b/media/codecs/amrnb/enc/fuzzer/README.md
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/fuzzer/README.md
rename to media/codecs/amrnb/enc/fuzzer/README.md
diff --git a/media/libstagefright/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp b/media/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp
rename to media/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/amrencode.cpp b/media/codecs/amrnb/enc/src/amrencode.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/amrencode.cpp
rename to media/codecs/amrnb/enc/src/amrencode.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/amrencode.h b/media/codecs/amrnb/enc/src/amrencode.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/amrencode.h
rename to media/codecs/amrnb/enc/src/amrencode.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/autocorr.cpp b/media/codecs/amrnb/enc/src/autocorr.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/autocorr.cpp
rename to media/codecs/amrnb/enc/src/autocorr.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/autocorr.h b/media/codecs/amrnb/enc/src/autocorr.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/autocorr.h
rename to media/codecs/amrnb/enc/src/autocorr.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c1035pf.cpp b/media/codecs/amrnb/enc/src/c1035pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c1035pf.cpp
rename to media/codecs/amrnb/enc/src/c1035pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c1035pf.h b/media/codecs/amrnb/enc/src/c1035pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c1035pf.h
rename to media/codecs/amrnb/enc/src/c1035pf.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c2_11pf.cpp b/media/codecs/amrnb/enc/src/c2_11pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c2_11pf.cpp
rename to media/codecs/amrnb/enc/src/c2_11pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c2_11pf.h b/media/codecs/amrnb/enc/src/c2_11pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c2_11pf.h
rename to media/codecs/amrnb/enc/src/c2_11pf.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c2_9pf.cpp b/media/codecs/amrnb/enc/src/c2_9pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c2_9pf.cpp
rename to media/codecs/amrnb/enc/src/c2_9pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c2_9pf.h b/media/codecs/amrnb/enc/src/c2_9pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c2_9pf.h
rename to media/codecs/amrnb/enc/src/c2_9pf.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c3_14pf.cpp b/media/codecs/amrnb/enc/src/c3_14pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c3_14pf.cpp
rename to media/codecs/amrnb/enc/src/c3_14pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c3_14pf.h b/media/codecs/amrnb/enc/src/c3_14pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c3_14pf.h
rename to media/codecs/amrnb/enc/src/c3_14pf.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c4_17pf.cpp b/media/codecs/amrnb/enc/src/c4_17pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c4_17pf.cpp
rename to media/codecs/amrnb/enc/src/c4_17pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c4_17pf.h b/media/codecs/amrnb/enc/src/c4_17pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c4_17pf.h
rename to media/codecs/amrnb/enc/src/c4_17pf.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c8_31pf.cpp b/media/codecs/amrnb/enc/src/c8_31pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c8_31pf.cpp
rename to media/codecs/amrnb/enc/src/c8_31pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c8_31pf.h b/media/codecs/amrnb/enc/src/c8_31pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/c8_31pf.h
rename to media/codecs/amrnb/enc/src/c8_31pf.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/calc_cor.cpp b/media/codecs/amrnb/enc/src/calc_cor.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/calc_cor.cpp
rename to media/codecs/amrnb/enc/src/calc_cor.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/calc_cor.h b/media/codecs/amrnb/enc/src/calc_cor.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/calc_cor.h
rename to media/codecs/amrnb/enc/src/calc_cor.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/calc_en.cpp b/media/codecs/amrnb/enc/src/calc_en.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/calc_en.cpp
rename to media/codecs/amrnb/enc/src/calc_en.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/calc_en.h b/media/codecs/amrnb/enc/src/calc_en.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/calc_en.h
rename to media/codecs/amrnb/enc/src/calc_en.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cbsearch.cpp b/media/codecs/amrnb/enc/src/cbsearch.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cbsearch.cpp
rename to media/codecs/amrnb/enc/src/cbsearch.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cbsearch.h b/media/codecs/amrnb/enc/src/cbsearch.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cbsearch.h
rename to media/codecs/amrnb/enc/src/cbsearch.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cl_ltp.cpp b/media/codecs/amrnb/enc/src/cl_ltp.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cl_ltp.cpp
rename to media/codecs/amrnb/enc/src/cl_ltp.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cl_ltp.h b/media/codecs/amrnb/enc/src/cl_ltp.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cl_ltp.h
rename to media/codecs/amrnb/enc/src/cl_ltp.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cod_amr.cpp b/media/codecs/amrnb/enc/src/cod_amr.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cod_amr.cpp
rename to media/codecs/amrnb/enc/src/cod_amr.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cod_amr.h b/media/codecs/amrnb/enc/src/cod_amr.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cod_amr.h
rename to media/codecs/amrnb/enc/src/cod_amr.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/convolve.cpp b/media/codecs/amrnb/enc/src/convolve.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/convolve.cpp
rename to media/codecs/amrnb/enc/src/convolve.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/convolve.h b/media/codecs/amrnb/enc/src/convolve.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/convolve.h
rename to media/codecs/amrnb/enc/src/convolve.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cor_h.cpp b/media/codecs/amrnb/enc/src/cor_h.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cor_h.cpp
rename to media/codecs/amrnb/enc/src/cor_h.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cor_h.h b/media/codecs/amrnb/enc/src/cor_h.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cor_h.h
rename to media/codecs/amrnb/enc/src/cor_h.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cor_h_x.cpp b/media/codecs/amrnb/enc/src/cor_h_x.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cor_h_x.cpp
rename to media/codecs/amrnb/enc/src/cor_h_x.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cor_h_x.h b/media/codecs/amrnb/enc/src/cor_h_x.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cor_h_x.h
rename to media/codecs/amrnb/enc/src/cor_h_x.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cor_h_x2.cpp b/media/codecs/amrnb/enc/src/cor_h_x2.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cor_h_x2.cpp
rename to media/codecs/amrnb/enc/src/cor_h_x2.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/cor_h_x2.h b/media/codecs/amrnb/enc/src/cor_h_x2.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/cor_h_x2.h
rename to media/codecs/amrnb/enc/src/cor_h_x2.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp b/media/codecs/amrnb/enc/src/corrwght_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp
rename to media/codecs/amrnb/enc/src/corrwght_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/dtx_enc.cpp b/media/codecs/amrnb/enc/src/dtx_enc.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/dtx_enc.cpp
rename to media/codecs/amrnb/enc/src/dtx_enc.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/dtx_enc.h b/media/codecs/amrnb/enc/src/dtx_enc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/dtx_enc.h
rename to media/codecs/amrnb/enc/src/dtx_enc.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/enc_lag3.cpp b/media/codecs/amrnb/enc/src/enc_lag3.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/enc_lag3.cpp
rename to media/codecs/amrnb/enc/src/enc_lag3.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/enc_lag3.h b/media/codecs/amrnb/enc/src/enc_lag3.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/enc_lag3.h
rename to media/codecs/amrnb/enc/src/enc_lag3.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/enc_lag6.cpp b/media/codecs/amrnb/enc/src/enc_lag6.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/enc_lag6.cpp
rename to media/codecs/amrnb/enc/src/enc_lag6.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/enc_lag6.h b/media/codecs/amrnb/enc/src/enc_lag6.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/enc_lag6.h
rename to media/codecs/amrnb/enc/src/enc_lag6.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp b/media/codecs/amrnb/enc/src/enc_output_format_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp
rename to media/codecs/amrnb/enc/src/enc_output_format_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/ets_to_if2.cpp b/media/codecs/amrnb/enc/src/ets_to_if2.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/ets_to_if2.cpp
rename to media/codecs/amrnb/enc/src/ets_to_if2.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/ets_to_if2.h b/media/codecs/amrnb/enc/src/ets_to_if2.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/ets_to_if2.h
rename to media/codecs/amrnb/enc/src/ets_to_if2.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/ets_to_wmf.cpp b/media/codecs/amrnb/enc/src/ets_to_wmf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/ets_to_wmf.cpp
rename to media/codecs/amrnb/enc/src/ets_to_wmf.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/ets_to_wmf.h b/media/codecs/amrnb/enc/src/ets_to_wmf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/ets_to_wmf.h
rename to media/codecs/amrnb/enc/src/ets_to_wmf.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/g_adapt.cpp b/media/codecs/amrnb/enc/src/g_adapt.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/g_adapt.cpp
rename to media/codecs/amrnb/enc/src/g_adapt.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/g_adapt.h b/media/codecs/amrnb/enc/src/g_adapt.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/g_adapt.h
rename to media/codecs/amrnb/enc/src/g_adapt.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/g_code.cpp b/media/codecs/amrnb/enc/src/g_code.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/g_code.cpp
rename to media/codecs/amrnb/enc/src/g_code.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/g_code.h b/media/codecs/amrnb/enc/src/g_code.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/g_code.h
rename to media/codecs/amrnb/enc/src/g_code.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/g_pitch.cpp b/media/codecs/amrnb/enc/src/g_pitch.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/g_pitch.cpp
rename to media/codecs/amrnb/enc/src/g_pitch.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/g_pitch.h b/media/codecs/amrnb/enc/src/g_pitch.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/g_pitch.h
rename to media/codecs/amrnb/enc/src/g_pitch.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/gain_q.cpp b/media/codecs/amrnb/enc/src/gain_q.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/gain_q.cpp
rename to media/codecs/amrnb/enc/src/gain_q.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/gain_q.h b/media/codecs/amrnb/enc/src/gain_q.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/gain_q.h
rename to media/codecs/amrnb/enc/src/gain_q.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/gsmamr_enc.h b/media/codecs/amrnb/enc/src/gsmamr_enc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/gsmamr_enc.h
rename to media/codecs/amrnb/enc/src/gsmamr_enc.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/hp_max.cpp b/media/codecs/amrnb/enc/src/hp_max.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/hp_max.cpp
rename to media/codecs/amrnb/enc/src/hp_max.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/hp_max.h b/media/codecs/amrnb/enc/src/hp_max.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/hp_max.h
rename to media/codecs/amrnb/enc/src/hp_max.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/inter_36.cpp b/media/codecs/amrnb/enc/src/inter_36.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/inter_36.cpp
rename to media/codecs/amrnb/enc/src/inter_36.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/inter_36.h b/media/codecs/amrnb/enc/src/inter_36.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/inter_36.h
rename to media/codecs/amrnb/enc/src/inter_36.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp b/media/codecs/amrnb/enc/src/inter_36_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp
rename to media/codecs/amrnb/enc/src/inter_36_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.h b/media/codecs/amrnb/enc/src/inter_36_tab.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.h
rename to media/codecs/amrnb/enc/src/inter_36_tab.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/l_comp.cpp b/media/codecs/amrnb/enc/src/l_comp.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/l_comp.cpp
rename to media/codecs/amrnb/enc/src/l_comp.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/l_extract.cpp b/media/codecs/amrnb/enc/src/l_extract.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/l_extract.cpp
rename to media/codecs/amrnb/enc/src/l_extract.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/l_negate.cpp b/media/codecs/amrnb/enc/src/l_negate.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/l_negate.cpp
rename to media/codecs/amrnb/enc/src/l_negate.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/lag_wind.cpp b/media/codecs/amrnb/enc/src/lag_wind.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/lag_wind.cpp
rename to media/codecs/amrnb/enc/src/lag_wind.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/lag_wind.h b/media/codecs/amrnb/enc/src/lag_wind.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/lag_wind.h
rename to media/codecs/amrnb/enc/src/lag_wind.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp b/media/codecs/amrnb/enc/src/lag_wind_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp
rename to media/codecs/amrnb/enc/src/lag_wind_tab.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.h b/media/codecs/amrnb/enc/src/lag_wind_tab.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.h
rename to media/codecs/amrnb/enc/src/lag_wind_tab.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/levinson.cpp b/media/codecs/amrnb/enc/src/levinson.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/levinson.cpp
rename to media/codecs/amrnb/enc/src/levinson.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/levinson.h b/media/codecs/amrnb/enc/src/levinson.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/levinson.h
rename to media/codecs/amrnb/enc/src/levinson.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/lpc.cpp b/media/codecs/amrnb/enc/src/lpc.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/lpc.cpp
rename to media/codecs/amrnb/enc/src/lpc.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/lpc.h b/media/codecs/amrnb/enc/src/lpc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/lpc.h
rename to media/codecs/amrnb/enc/src/lpc.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/ol_ltp.cpp b/media/codecs/amrnb/enc/src/ol_ltp.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/ol_ltp.cpp
rename to media/codecs/amrnb/enc/src/ol_ltp.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/ol_ltp.h b/media/codecs/amrnb/enc/src/ol_ltp.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/ol_ltp.h
rename to media/codecs/amrnb/enc/src/ol_ltp.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/p_ol_wgh.cpp b/media/codecs/amrnb/enc/src/p_ol_wgh.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/p_ol_wgh.cpp
rename to media/codecs/amrnb/enc/src/p_ol_wgh.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/pitch_fr.cpp b/media/codecs/amrnb/enc/src/pitch_fr.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/pitch_fr.cpp
rename to media/codecs/amrnb/enc/src/pitch_fr.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/pitch_fr.h b/media/codecs/amrnb/enc/src/pitch_fr.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/pitch_fr.h
rename to media/codecs/amrnb/enc/src/pitch_fr.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/pitch_ol.cpp b/media/codecs/amrnb/enc/src/pitch_ol.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/pitch_ol.cpp
rename to media/codecs/amrnb/enc/src/pitch_ol.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/pitch_ol.h b/media/codecs/amrnb/enc/src/pitch_ol.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/pitch_ol.h
rename to media/codecs/amrnb/enc/src/pitch_ol.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/pre_big.cpp b/media/codecs/amrnb/enc/src/pre_big.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/pre_big.cpp
rename to media/codecs/amrnb/enc/src/pre_big.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/pre_big.h b/media/codecs/amrnb/enc/src/pre_big.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/pre_big.h
rename to media/codecs/amrnb/enc/src/pre_big.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/pre_proc.cpp b/media/codecs/amrnb/enc/src/pre_proc.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/pre_proc.cpp
rename to media/codecs/amrnb/enc/src/pre_proc.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/pre_proc.h b/media/codecs/amrnb/enc/src/pre_proc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/pre_proc.h
rename to media/codecs/amrnb/enc/src/pre_proc.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/prm2bits.cpp b/media/codecs/amrnb/enc/src/prm2bits.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/prm2bits.cpp
rename to media/codecs/amrnb/enc/src/prm2bits.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/prm2bits.h b/media/codecs/amrnb/enc/src/prm2bits.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/prm2bits.h
rename to media/codecs/amrnb/enc/src/prm2bits.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/q_gain_c.cpp b/media/codecs/amrnb/enc/src/q_gain_c.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/q_gain_c.cpp
rename to media/codecs/amrnb/enc/src/q_gain_c.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/q_gain_c.h b/media/codecs/amrnb/enc/src/q_gain_c.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/q_gain_c.h
rename to media/codecs/amrnb/enc/src/q_gain_c.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/q_gain_p.cpp b/media/codecs/amrnb/enc/src/q_gain_p.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/q_gain_p.cpp
rename to media/codecs/amrnb/enc/src/q_gain_p.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/q_gain_p.h b/media/codecs/amrnb/enc/src/q_gain_p.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/q_gain_p.h
rename to media/codecs/amrnb/enc/src/q_gain_p.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/qgain475.cpp b/media/codecs/amrnb/enc/src/qgain475.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/qgain475.cpp
rename to media/codecs/amrnb/enc/src/qgain475.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/qgain475.h b/media/codecs/amrnb/enc/src/qgain475.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/qgain475.h
rename to media/codecs/amrnb/enc/src/qgain475.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/qgain795.cpp b/media/codecs/amrnb/enc/src/qgain795.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/qgain795.cpp
rename to media/codecs/amrnb/enc/src/qgain795.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/qgain795.h b/media/codecs/amrnb/enc/src/qgain795.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/qgain795.h
rename to media/codecs/amrnb/enc/src/qgain795.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/qua_gain.cpp b/media/codecs/amrnb/enc/src/qua_gain.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/qua_gain.cpp
rename to media/codecs/amrnb/enc/src/qua_gain.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/s10_8pf.cpp b/media/codecs/amrnb/enc/src/s10_8pf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/s10_8pf.cpp
rename to media/codecs/amrnb/enc/src/s10_8pf.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/s10_8pf.h b/media/codecs/amrnb/enc/src/s10_8pf.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/s10_8pf.h
rename to media/codecs/amrnb/enc/src/s10_8pf.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/set_sign.cpp b/media/codecs/amrnb/enc/src/set_sign.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/set_sign.cpp
rename to media/codecs/amrnb/enc/src/set_sign.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/set_sign.h b/media/codecs/amrnb/enc/src/set_sign.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/set_sign.h
rename to media/codecs/amrnb/enc/src/set_sign.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/sid_sync.cpp b/media/codecs/amrnb/enc/src/sid_sync.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/sid_sync.cpp
rename to media/codecs/amrnb/enc/src/sid_sync.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/sid_sync.h b/media/codecs/amrnb/enc/src/sid_sync.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/sid_sync.h
rename to media/codecs/amrnb/enc/src/sid_sync.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/sp_enc.cpp b/media/codecs/amrnb/enc/src/sp_enc.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/sp_enc.cpp
rename to media/codecs/amrnb/enc/src/sp_enc.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/sp_enc.h b/media/codecs/amrnb/enc/src/sp_enc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/sp_enc.h
rename to media/codecs/amrnb/enc/src/sp_enc.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/spreproc.cpp b/media/codecs/amrnb/enc/src/spreproc.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/spreproc.cpp
rename to media/codecs/amrnb/enc/src/spreproc.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/spreproc.h b/media/codecs/amrnb/enc/src/spreproc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/spreproc.h
rename to media/codecs/amrnb/enc/src/spreproc.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/spstproc.cpp b/media/codecs/amrnb/enc/src/spstproc.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/spstproc.cpp
rename to media/codecs/amrnb/enc/src/spstproc.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/spstproc.h b/media/codecs/amrnb/enc/src/spstproc.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/spstproc.h
rename to media/codecs/amrnb/enc/src/spstproc.h
diff --git a/media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp b/media/codecs/amrnb/enc/src/ton_stab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp
rename to media/codecs/amrnb/enc/src/ton_stab.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/src/ton_stab.h b/media/codecs/amrnb/enc/src/ton_stab.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/src/ton_stab.h
rename to media/codecs/amrnb/enc/src/ton_stab.h
diff --git a/media/libstagefright/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h b/media/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h
rename to media/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h
diff --git a/media/libstagefright/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp b/media/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp
rename to media/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp
diff --git a/media/libstagefright/codecs/amrnb/enc/test/Android.bp b/media/codecs/amrnb/enc/test/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/test/Android.bp
rename to media/codecs/amrnb/enc/test/Android.bp
diff --git a/media/libstagefright/codecs/amrnb/enc/test/AndroidTest.xml b/media/codecs/amrnb/enc/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/test/AndroidTest.xml
rename to media/codecs/amrnb/enc/test/AndroidTest.xml
diff --git a/media/libstagefright/codecs/amrnb/enc/test/README.md b/media/codecs/amrnb/enc/test/README.md
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/test/README.md
rename to media/codecs/amrnb/enc/test/README.md
diff --git a/media/libstagefright/codecs/amrnb/enc/test/amrnb_enc_test.cpp b/media/codecs/amrnb/enc/test/amrnb_enc_test.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/enc/test/amrnb_enc_test.cpp
rename to media/codecs/amrnb/enc/test/amrnb_enc_test.cpp
diff --git a/media/libstagefright/codecs/amrnb/fuzzer/Android.bp b/media/codecs/amrnb/fuzzer/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/fuzzer/Android.bp
rename to media/codecs/amrnb/fuzzer/Android.bp
diff --git a/media/libstagefright/codecs/amrnb/fuzzer/README.md b/media/codecs/amrnb/fuzzer/README.md
similarity index 100%
rename from media/libstagefright/codecs/amrnb/fuzzer/README.md
rename to media/codecs/amrnb/fuzzer/README.md
diff --git a/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp b/media/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
rename to media/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
diff --git a/media/libstagefright/codecs/amrnb/patent_disclaimer.txt b/media/codecs/amrnb/patent_disclaimer.txt
similarity index 100%
rename from media/libstagefright/codecs/amrnb/patent_disclaimer.txt
rename to media/codecs/amrnb/patent_disclaimer.txt
diff --git a/media/libstagefright/codecs/amrwb/Android.bp b/media/codecs/amrwb/dec/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/Android.bp
rename to media/codecs/amrwb/dec/Android.bp
diff --git a/media/libstagefright/codecs/amrnb/dec/MODULE_LICENSE_APACHE2 b/media/codecs/amrwb/dec/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/libstagefright/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
copy to media/codecs/amrwb/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrnb/dec/NOTICE b/media/codecs/amrwb/dec/NOTICE
similarity index 100%
copy from media/libstagefright/codecs/amrnb/dec/NOTICE
copy to media/codecs/amrwb/dec/NOTICE
diff --git a/media/libstagefright/codecs/amrwb/TEST_MAPPING b/media/codecs/amrwb/dec/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/codecs/amrwb/TEST_MAPPING
rename to media/codecs/amrwb/dec/TEST_MAPPING
diff --git a/media/libstagefright/codecs/amrwb/fuzzer/Android.bp b/media/codecs/amrwb/dec/fuzzer/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/fuzzer/Android.bp
rename to media/codecs/amrwb/dec/fuzzer/Android.bp
diff --git a/media/libstagefright/codecs/amrwb/fuzzer/README.md b/media/codecs/amrwb/dec/fuzzer/README.md
similarity index 100%
rename from media/libstagefright/codecs/amrwb/fuzzer/README.md
rename to media/codecs/amrwb/dec/fuzzer/README.md
diff --git a/media/libstagefright/codecs/amrwb/fuzzer/amrwb_dec_fuzzer.cpp b/media/codecs/amrwb/dec/fuzzer/amrwb_dec_fuzzer.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/fuzzer/amrwb_dec_fuzzer.cpp
rename to media/codecs/amrwb/dec/fuzzer/amrwb_dec_fuzzer.cpp
diff --git a/media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h b/media/codecs/amrwb/dec/include/pvamrwbdecoder_api.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h
rename to media/codecs/amrwb/dec/include/pvamrwbdecoder_api.h
diff --git a/media/libstagefright/codecs/mp3dec/patent_disclaimer.txt b/media/codecs/amrwb/dec/patent_disclaimer.txt
similarity index 100%
copy from media/libstagefright/codecs/mp3dec/patent_disclaimer.txt
copy to media/codecs/amrwb/dec/patent_disclaimer.txt
diff --git a/media/libstagefright/codecs/amrwb/src/agc2_amr_wb.cpp b/media/codecs/amrwb/dec/src/agc2_amr_wb.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/agc2_amr_wb.cpp
rename to media/codecs/amrwb/dec/src/agc2_amr_wb.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/band_pass_6k_7k.cpp b/media/codecs/amrwb/dec/src/band_pass_6k_7k.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/band_pass_6k_7k.cpp
rename to media/codecs/amrwb/dec/src/band_pass_6k_7k.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/dec_acelp_2p_in_64.cpp b/media/codecs/amrwb/dec/src/dec_acelp_2p_in_64.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/dec_acelp_2p_in_64.cpp
rename to media/codecs/amrwb/dec/src/dec_acelp_2p_in_64.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/dec_acelp_4p_in_64.cpp b/media/codecs/amrwb/dec/src/dec_acelp_4p_in_64.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/dec_acelp_4p_in_64.cpp
rename to media/codecs/amrwb/dec/src/dec_acelp_4p_in_64.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/dec_alg_codebook.cpp b/media/codecs/amrwb/dec/src/dec_alg_codebook.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/dec_alg_codebook.cpp
rename to media/codecs/amrwb/dec/src/dec_alg_codebook.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/dec_gain2_amr_wb.cpp b/media/codecs/amrwb/dec/src/dec_gain2_amr_wb.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/dec_gain2_amr_wb.cpp
rename to media/codecs/amrwb/dec/src/dec_gain2_amr_wb.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/deemphasis_32.cpp b/media/codecs/amrwb/dec/src/deemphasis_32.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/deemphasis_32.cpp
rename to media/codecs/amrwb/dec/src/deemphasis_32.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/dtx.h b/media/codecs/amrwb/dec/src/dtx.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/dtx.h
rename to media/codecs/amrwb/dec/src/dtx.h
diff --git a/media/libstagefright/codecs/amrwb/src/dtx_decoder_amr_wb.cpp b/media/codecs/amrwb/dec/src/dtx_decoder_amr_wb.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/dtx_decoder_amr_wb.cpp
rename to media/codecs/amrwb/dec/src/dtx_decoder_amr_wb.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/e_pv_amrwbdec.h b/media/codecs/amrwb/dec/src/e_pv_amrwbdec.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/e_pv_amrwbdec.h
rename to media/codecs/amrwb/dec/src/e_pv_amrwbdec.h
diff --git a/media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp b/media/codecs/amrwb/dec/src/get_amr_wb_bits.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp
rename to media/codecs/amrwb/dec/src/get_amr_wb_bits.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.h b/media/codecs/amrwb/dec/src/get_amr_wb_bits.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.h
rename to media/codecs/amrwb/dec/src/get_amr_wb_bits.h
diff --git a/media/libstagefright/codecs/amrwb/src/highpass_400hz_at_12k8.cpp b/media/codecs/amrwb/dec/src/highpass_400hz_at_12k8.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/highpass_400hz_at_12k8.cpp
rename to media/codecs/amrwb/dec/src/highpass_400hz_at_12k8.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/highpass_50hz_at_12k8.cpp b/media/codecs/amrwb/dec/src/highpass_50hz_at_12k8.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/highpass_50hz_at_12k8.cpp
rename to media/codecs/amrwb/dec/src/highpass_50hz_at_12k8.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp b/media/codecs/amrwb/dec/src/homing_amr_wb_dec.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp
rename to media/codecs/amrwb/dec/src/homing_amr_wb_dec.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/interpolate_isp.cpp b/media/codecs/amrwb/dec/src/interpolate_isp.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/interpolate_isp.cpp
rename to media/codecs/amrwb/dec/src/interpolate_isp.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/isf_extrapolation.cpp b/media/codecs/amrwb/dec/src/isf_extrapolation.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/isf_extrapolation.cpp
rename to media/codecs/amrwb/dec/src/isf_extrapolation.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/isp_az.cpp b/media/codecs/amrwb/dec/src/isp_az.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/isp_az.cpp
rename to media/codecs/amrwb/dec/src/isp_az.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/isp_isf.cpp b/media/codecs/amrwb/dec/src/isp_isf.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/isp_isf.cpp
rename to media/codecs/amrwb/dec/src/isp_isf.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/lagconceal.cpp b/media/codecs/amrwb/dec/src/lagconceal.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/lagconceal.cpp
rename to media/codecs/amrwb/dec/src/lagconceal.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/low_pass_filt_7k.cpp b/media/codecs/amrwb/dec/src/low_pass_filt_7k.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/low_pass_filt_7k.cpp
rename to media/codecs/amrwb/dec/src/low_pass_filt_7k.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/median5.cpp b/media/codecs/amrwb/dec/src/median5.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/median5.cpp
rename to media/codecs/amrwb/dec/src/median5.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/mime_io.cpp b/media/codecs/amrwb/dec/src/mime_io.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/mime_io.cpp
rename to media/codecs/amrwb/dec/src/mime_io.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/mime_io.h b/media/codecs/amrwb/dec/src/mime_io.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/mime_io.h
rename to media/codecs/amrwb/dec/src/mime_io.h
diff --git a/media/libstagefright/codecs/amrwb/src/noise_gen_amrwb.cpp b/media/codecs/amrwb/dec/src/noise_gen_amrwb.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/noise_gen_amrwb.cpp
rename to media/codecs/amrwb/dec/src/noise_gen_amrwb.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/normalize_amr_wb.cpp b/media/codecs/amrwb/dec/src/normalize_amr_wb.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/normalize_amr_wb.cpp
rename to media/codecs/amrwb/dec/src/normalize_amr_wb.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/normalize_amr_wb.h b/media/codecs/amrwb/dec/src/normalize_amr_wb.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/normalize_amr_wb.h
rename to media/codecs/amrwb/dec/src/normalize_amr_wb.h
diff --git a/media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp b/media/codecs/amrwb/dec/src/oversamp_12k8_to_16k.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp
rename to media/codecs/amrwb/dec/src/oversamp_12k8_to_16k.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp b/media/codecs/amrwb/dec/src/phase_dispersion.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp
rename to media/codecs/amrwb/dec/src/phase_dispersion.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/pit_shrp.cpp b/media/codecs/amrwb/dec/src/pit_shrp.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pit_shrp.cpp
rename to media/codecs/amrwb/dec/src/pit_shrp.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/pred_lt4.cpp b/media/codecs/amrwb/dec/src/pred_lt4.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pred_lt4.cpp
rename to media/codecs/amrwb/dec/src/pred_lt4.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/preemph_amrwb_dec.cpp b/media/codecs/amrwb/dec/src/preemph_amrwb_dec.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/preemph_amrwb_dec.cpp
rename to media/codecs/amrwb/dec/src/preemph_amrwb_dec.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/pv_amr_wb_type_defs.h b/media/codecs/amrwb/dec/src/pv_amr_wb_type_defs.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pv_amr_wb_type_defs.h
rename to media/codecs/amrwb/dec/src/pv_amr_wb_type_defs.h
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwb_math_op.cpp b/media/codecs/amrwb/dec/src/pvamrwb_math_op.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwb_math_op.cpp
rename to media/codecs/amrwb/dec/src/pvamrwb_math_op.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwb_math_op.h b/media/codecs/amrwb/dec/src/pvamrwb_math_op.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwb_math_op.h
rename to media/codecs/amrwb/dec/src/pvamrwb_math_op.h
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.cpp b/media/codecs/amrwb/dec/src/pvamrwbdecoder.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.cpp
rename to media/codecs/amrwb/dec/src/pvamrwbdecoder.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.h b/media/codecs/amrwb/dec/src/pvamrwbdecoder.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.h
rename to media/codecs/amrwb/dec/src/pvamrwbdecoder.h
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_acelp.h b/media/codecs/amrwb/dec/src/pvamrwbdecoder_acelp.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_acelp.h
rename to media/codecs/amrwb/dec/src/pvamrwbdecoder_acelp.h
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op.h b/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op.h
rename to media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op.h
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_armv5.h b/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_armv5.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_armv5.h
rename to media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_armv5.h
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_cequivalent.h b/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_cequivalent.h
rename to media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_gcc_armv5.h b/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_gcc_armv5.h
rename to media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_cnst.h b/media/codecs/amrwb/dec/src/pvamrwbdecoder_cnst.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_cnst.h
rename to media/codecs/amrwb/dec/src/pvamrwbdecoder_cnst.h
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_mem_funcs.h b/media/codecs/amrwb/dec/src/pvamrwbdecoder_mem_funcs.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_mem_funcs.h
rename to media/codecs/amrwb/dec/src/pvamrwbdecoder_mem_funcs.h
diff --git a/media/libstagefright/codecs/amrwb/src/q_gain2_tab.cpp b/media/codecs/amrwb/dec/src/q_gain2_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/q_gain2_tab.cpp
rename to media/codecs/amrwb/dec/src/q_gain2_tab.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/q_pulse.h b/media/codecs/amrwb/dec/src/q_pulse.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/q_pulse.h
rename to media/codecs/amrwb/dec/src/q_pulse.h
diff --git a/media/libstagefright/codecs/amrwb/src/qisf_ns.cpp b/media/codecs/amrwb/dec/src/qisf_ns.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/qisf_ns.cpp
rename to media/codecs/amrwb/dec/src/qisf_ns.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/qisf_ns.h b/media/codecs/amrwb/dec/src/qisf_ns.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/qisf_ns.h
rename to media/codecs/amrwb/dec/src/qisf_ns.h
diff --git a/media/libstagefright/codecs/amrwb/src/qisf_ns_tab.cpp b/media/codecs/amrwb/dec/src/qisf_ns_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/qisf_ns_tab.cpp
rename to media/codecs/amrwb/dec/src/qisf_ns_tab.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/qpisf_2s.cpp b/media/codecs/amrwb/dec/src/qpisf_2s.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/qpisf_2s.cpp
rename to media/codecs/amrwb/dec/src/qpisf_2s.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/qpisf_2s.h b/media/codecs/amrwb/dec/src/qpisf_2s.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/qpisf_2s.h
rename to media/codecs/amrwb/dec/src/qpisf_2s.h
diff --git a/media/libstagefright/codecs/amrwb/src/qpisf_2s_tab.cpp b/media/codecs/amrwb/dec/src/qpisf_2s_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/qpisf_2s_tab.cpp
rename to media/codecs/amrwb/dec/src/qpisf_2s_tab.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/scale_signal.cpp b/media/codecs/amrwb/dec/src/scale_signal.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/scale_signal.cpp
rename to media/codecs/amrwb/dec/src/scale_signal.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/synthesis_amr_wb.cpp b/media/codecs/amrwb/dec/src/synthesis_amr_wb.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/synthesis_amr_wb.cpp
rename to media/codecs/amrwb/dec/src/synthesis_amr_wb.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/synthesis_amr_wb.h b/media/codecs/amrwb/dec/src/synthesis_amr_wb.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/synthesis_amr_wb.h
rename to media/codecs/amrwb/dec/src/synthesis_amr_wb.h
diff --git a/media/libstagefright/codecs/amrwb/src/voice_factor.cpp b/media/codecs/amrwb/dec/src/voice_factor.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/voice_factor.cpp
rename to media/codecs/amrwb/dec/src/voice_factor.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/wb_syn_filt.cpp b/media/codecs/amrwb/dec/src/wb_syn_filt.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/wb_syn_filt.cpp
rename to media/codecs/amrwb/dec/src/wb_syn_filt.cpp
diff --git a/media/libstagefright/codecs/amrwb/src/weight_amrwb_lpc.cpp b/media/codecs/amrwb/dec/src/weight_amrwb_lpc.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/src/weight_amrwb_lpc.cpp
rename to media/codecs/amrwb/dec/src/weight_amrwb_lpc.cpp
diff --git a/media/libstagefright/codecs/amrwb/test/AmrwbDecTestEnvironment.h b/media/codecs/amrwb/dec/test/AmrwbDecTestEnvironment.h
similarity index 100%
rename from media/libstagefright/codecs/amrwb/test/AmrwbDecTestEnvironment.h
rename to media/codecs/amrwb/dec/test/AmrwbDecTestEnvironment.h
diff --git a/media/libstagefright/codecs/amrwb/test/AmrwbDecoderTest.cpp b/media/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/test/AmrwbDecoderTest.cpp
rename to media/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp
diff --git a/media/libstagefright/codecs/amrwb/test/Android.bp b/media/codecs/amrwb/dec/test/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/test/Android.bp
rename to media/codecs/amrwb/dec/test/Android.bp
diff --git a/media/libstagefright/codecs/amrwb/test/AndroidTest.xml b/media/codecs/amrwb/dec/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/codecs/amrwb/test/AndroidTest.xml
rename to media/codecs/amrwb/dec/test/AndroidTest.xml
diff --git a/media/libstagefright/codecs/amrwb/test/README.md b/media/codecs/amrwb/dec/test/README.md
similarity index 100%
rename from media/libstagefright/codecs/amrwb/test/README.md
rename to media/codecs/amrwb/dec/test/README.md
diff --git a/media/libstagefright/codecs/amrwb/test/amrwbdec_test.cpp b/media/codecs/amrwb/dec/test/amrwbdec_test.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwb/test/amrwbdec_test.cpp
rename to media/codecs/amrwb/dec/test/amrwbdec_test.cpp
diff --git a/media/codecs/amrwb/enc/Android.bp b/media/codecs/amrwb/enc/Android.bp
new file mode 100644
index 0000000..1521a45
--- /dev/null
+++ b/media/codecs/amrwb/enc/Android.bp
@@ -0,0 +1,149 @@
+cc_library_static {
+    name: "libstagefright_amrwbenc",
+    vendor_available: true,
+    min_sdk_version: "29",
+
+    srcs: [
+        "src/autocorr.c",
+        "src/az_isp.c",
+        "src/bits.c",
+        "src/c2t64fx.c",
+        "src/c4t64fx.c",
+        "src/convolve.c",
+        "src/cor_h_x.c",
+        "src/decim54.c",
+        "src/deemph.c",
+        "src/dtx.c",
+        "src/g_pitch.c",
+        "src/gpclip.c",
+        "src/homing.c",
+        "src/hp400.c",
+        "src/hp50.c",
+        "src/hp6k.c",
+        "src/hp_wsp.c",
+        "src/int_lpc.c",
+        "src/isp_az.c",
+        "src/isp_isf.c",
+        "src/lag_wind.c",
+        "src/levinson.c",
+        "src/log2.c",
+        "src/lp_dec2.c",
+        "src/math_op.c",
+        "src/oper_32b.c",
+        "src/p_med_ol.c",
+        "src/pit_shrp.c",
+        "src/pitch_f4.c",
+        "src/pred_lt4.c",
+        "src/preemph.c",
+        "src/q_gain2.c",
+        "src/q_pulse.c",
+        "src/qisf_ns.c",
+        "src/qpisf_2s.c",
+        "src/random.c",
+        "src/residu.c",
+        "src/scale.c",
+        "src/stream.c",
+        "src/syn_filt.c",
+        "src/updt_tar.c",
+        "src/util.c",
+        "src/voAMRWBEnc.c",
+        "src/voicefac.c",
+        "src/wb_vad.c",
+        "src/weight_a.c",
+        "src/mem_align.c",
+    ],
+
+    arch: {
+        arm: {
+            srcs: [
+                "src/asm/ARMV5E/convolve_opt.s",
+                "src/asm/ARMV5E/cor_h_vec_opt.s",
+                "src/asm/ARMV5E/Deemph_32_opt.s",
+                "src/asm/ARMV5E/Dot_p_opt.s",
+                "src/asm/ARMV5E/Filt_6k_7k_opt.s",
+                "src/asm/ARMV5E/Norm_Corr_opt.s",
+                "src/asm/ARMV5E/pred_lt4_1_opt.s",
+                "src/asm/ARMV5E/residu_asm_opt.s",
+                "src/asm/ARMV5E/scale_sig_opt.s",
+                "src/asm/ARMV5E/Syn_filt_32_opt.s",
+                "src/asm/ARMV5E/syn_filt_opt.s",
+            ],
+
+            cflags: [
+                "-DARM",
+                "-DASM_OPT",
+            ],
+            local_include_dirs: ["src/asm/ARMV5E"],
+
+            instruction_set: "arm",
+
+            neon: {
+                exclude_srcs: [
+                    "src/asm/ARMV5E/convolve_opt.s",
+                    "src/asm/ARMV5E/cor_h_vec_opt.s",
+                    "src/asm/ARMV5E/Deemph_32_opt.s",
+                    "src/asm/ARMV5E/Dot_p_opt.s",
+                    "src/asm/ARMV5E/Filt_6k_7k_opt.s",
+                    "src/asm/ARMV5E/Norm_Corr_opt.s",
+                    "src/asm/ARMV5E/pred_lt4_1_opt.s",
+                    "src/asm/ARMV5E/residu_asm_opt.s",
+                    "src/asm/ARMV5E/scale_sig_opt.s",
+                    "src/asm/ARMV5E/Syn_filt_32_opt.s",
+                    "src/asm/ARMV5E/syn_filt_opt.s",
+                ],
+
+                srcs: [
+                    "src/asm/ARMV7/convolve_neon.s",
+                    "src/asm/ARMV7/cor_h_vec_neon.s",
+                    "src/asm/ARMV7/Deemph_32_neon.s",
+                    "src/asm/ARMV7/Dot_p_neon.s",
+                    "src/asm/ARMV7/Filt_6k_7k_neon.s",
+                    "src/asm/ARMV7/Norm_Corr_neon.s",
+                    "src/asm/ARMV7/pred_lt4_1_neon.s",
+                    "src/asm/ARMV7/residu_asm_neon.s",
+                    "src/asm/ARMV7/scale_sig_neon.s",
+                    "src/asm/ARMV7/Syn_filt_32_neon.s",
+                    "src/asm/ARMV7/syn_filt_neon.s",
+                ],
+
+                // don't actually generate neon instructions, see bug 26932980
+                cflags: [
+                    "-DARMV7",
+                    "-mfpu=vfpv3",
+                ],
+                local_include_dirs: [
+                    "src/asm/ARMV5E",
+                    "src/asm/ARMV7",
+                ],
+            },
+
+        },
+    },
+
+    include_dirs: [
+        "frameworks/av/include",
+        "frameworks/av/media/libstagefright/include",
+    ],
+
+    local_include_dirs: ["src"],
+    export_include_dirs: ["inc"],
+
+    shared_libs: [
+        "libstagefright_enc_common",
+        "liblog",
+    ],
+
+    cflags: ["-Werror"],
+    sanitize: {
+        cfi: true,
+    },
+
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+
diff --git a/media/libstagefright/codecs/amrnb/enc/MODULE_LICENSE_APACHE2 b/media/codecs/amrwb/enc/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/libstagefright/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
copy to media/codecs/amrwb/enc/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrnb/enc/NOTICE b/media/codecs/amrwb/enc/NOTICE
similarity index 100%
copy from media/libstagefright/codecs/amrnb/enc/NOTICE
copy to media/codecs/amrwb/enc/NOTICE
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c b/media/codecs/amrwb/enc/SampleCode/AMRWB_E_SAMPLE.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
rename to media/codecs/amrwb/enc/SampleCode/AMRWB_E_SAMPLE.c
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp b/media/codecs/amrwb/enc/SampleCode/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
rename to media/codecs/amrwb/enc/SampleCode/Android.bp
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/MODULE_LICENSE_APACHE2 b/media/codecs/amrwb/enc/SampleCode/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/SampleCode/MODULE_LICENSE_APACHE2
rename to media/codecs/amrwb/enc/SampleCode/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/NOTICE b/media/codecs/amrwb/enc/SampleCode/NOTICE
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/SampleCode/NOTICE
rename to media/codecs/amrwb/enc/SampleCode/NOTICE
diff --git a/media/libstagefright/codecs/amrwbenc/TEST_MAPPING b/media/codecs/amrwb/enc/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/TEST_MAPPING
rename to media/codecs/amrwb/enc/TEST_MAPPING
diff --git a/media/libstagefright/codecs/amrwbenc/doc/voAMRWBEncoderSDK.pdf b/media/codecs/amrwb/enc/doc/voAMRWBEncoderSDK.pdf
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/doc/voAMRWBEncoderSDK.pdf
rename to media/codecs/amrwb/enc/doc/voAMRWBEncoderSDK.pdf
Binary files differ
diff --git a/media/libstagefright/codecs/amrwbenc/fuzzer/Android.bp b/media/codecs/amrwb/enc/fuzzer/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/fuzzer/Android.bp
rename to media/codecs/amrwb/enc/fuzzer/Android.bp
diff --git a/media/libstagefright/codecs/amrwbenc/fuzzer/README.md b/media/codecs/amrwb/enc/fuzzer/README.md
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/fuzzer/README.md
rename to media/codecs/amrwb/enc/fuzzer/README.md
diff --git a/media/libstagefright/codecs/amrwbenc/fuzzer/amrwb_enc_fuzzer.cpp b/media/codecs/amrwb/enc/fuzzer/amrwb_enc_fuzzer.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/fuzzer/amrwb_enc_fuzzer.cpp
rename to media/codecs/amrwb/enc/fuzzer/amrwb_enc_fuzzer.cpp
diff --git a/media/libstagefright/codecs/amrwbenc/inc/acelp.h b/media/codecs/amrwb/enc/inc/acelp.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/acelp.h
rename to media/codecs/amrwb/enc/inc/acelp.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h b/media/codecs/amrwb/enc/inc/basic_op.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/basic_op.h
rename to media/codecs/amrwb/enc/inc/basic_op.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/bits.h b/media/codecs/amrwb/enc/inc/bits.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/bits.h
rename to media/codecs/amrwb/enc/inc/bits.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/cnst.h b/media/codecs/amrwb/enc/inc/cnst.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/cnst.h
rename to media/codecs/amrwb/enc/inc/cnst.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/cod_main.h b/media/codecs/amrwb/enc/inc/cod_main.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/cod_main.h
rename to media/codecs/amrwb/enc/inc/cod_main.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/dtx.h b/media/codecs/amrwb/enc/inc/dtx.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/dtx.h
rename to media/codecs/amrwb/enc/inc/dtx.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/grid100.tab b/media/codecs/amrwb/enc/inc/grid100.tab
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/grid100.tab
rename to media/codecs/amrwb/enc/inc/grid100.tab
diff --git a/media/libstagefright/codecs/amrwbenc/inc/ham_wind.tab b/media/codecs/amrwb/enc/inc/ham_wind.tab
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/ham_wind.tab
rename to media/codecs/amrwb/enc/inc/ham_wind.tab
diff --git a/media/libstagefright/codecs/amrwbenc/inc/homing.tab b/media/codecs/amrwb/enc/inc/homing.tab
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/homing.tab
rename to media/codecs/amrwb/enc/inc/homing.tab
diff --git a/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab b/media/codecs/amrwb/enc/inc/isp_isf.tab
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab
rename to media/codecs/amrwb/enc/inc/isp_isf.tab
diff --git a/media/libstagefright/codecs/amrwbenc/inc/lag_wind.tab b/media/codecs/amrwb/enc/inc/lag_wind.tab
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/lag_wind.tab
rename to media/codecs/amrwb/enc/inc/lag_wind.tab
diff --git a/media/libstagefright/codecs/amrwbenc/inc/log2.h b/media/codecs/amrwb/enc/inc/log2.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/log2.h
rename to media/codecs/amrwb/enc/inc/log2.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/log2_tab.h b/media/codecs/amrwb/enc/inc/log2_tab.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/log2_tab.h
rename to media/codecs/amrwb/enc/inc/log2_tab.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/main.h b/media/codecs/amrwb/enc/inc/main.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/main.h
rename to media/codecs/amrwb/enc/inc/main.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/math_op.h b/media/codecs/amrwb/enc/inc/math_op.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/math_op.h
rename to media/codecs/amrwb/enc/inc/math_op.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/mem_align.h b/media/codecs/amrwb/enc/inc/mem_align.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/mem_align.h
rename to media/codecs/amrwb/enc/inc/mem_align.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/mime_io.tab b/media/codecs/amrwb/enc/inc/mime_io.tab
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/mime_io.tab
rename to media/codecs/amrwb/enc/inc/mime_io.tab
diff --git a/media/libstagefright/codecs/amrwbenc/inc/oper_32b.h b/media/codecs/amrwb/enc/inc/oper_32b.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/oper_32b.h
rename to media/codecs/amrwb/enc/inc/oper_32b.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/p_med_o.h b/media/codecs/amrwb/enc/inc/p_med_o.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/p_med_o.h
rename to media/codecs/amrwb/enc/inc/p_med_o.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/p_med_ol.tab b/media/codecs/amrwb/enc/inc/p_med_ol.tab
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/p_med_ol.tab
rename to media/codecs/amrwb/enc/inc/p_med_ol.tab
diff --git a/media/libstagefright/codecs/amrwbenc/inc/q_gain2.tab b/media/codecs/amrwb/enc/inc/q_gain2.tab
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/q_gain2.tab
rename to media/codecs/amrwb/enc/inc/q_gain2.tab
diff --git a/media/libstagefright/codecs/amrwbenc/inc/q_pulse.h b/media/codecs/amrwb/enc/inc/q_pulse.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/q_pulse.h
rename to media/codecs/amrwb/enc/inc/q_pulse.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/qisf_ns.tab b/media/codecs/amrwb/enc/inc/qisf_ns.tab
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/qisf_ns.tab
rename to media/codecs/amrwb/enc/inc/qisf_ns.tab
diff --git a/media/libstagefright/codecs/amrwbenc/inc/qpisf_2s.tab b/media/codecs/amrwb/enc/inc/qpisf_2s.tab
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/qpisf_2s.tab
rename to media/codecs/amrwb/enc/inc/qpisf_2s.tab
diff --git a/media/libstagefright/codecs/amrwbenc/inc/stream.h b/media/codecs/amrwb/enc/inc/stream.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/stream.h
rename to media/codecs/amrwb/enc/inc/stream.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/typedef.h b/media/codecs/amrwb/enc/inc/typedef.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/typedef.h
rename to media/codecs/amrwb/enc/inc/typedef.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/typedefs.h b/media/codecs/amrwb/enc/inc/typedefs.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/typedefs.h
rename to media/codecs/amrwb/enc/inc/typedefs.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/wb_vad.h b/media/codecs/amrwb/enc/inc/wb_vad.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/wb_vad.h
rename to media/codecs/amrwb/enc/inc/wb_vad.h
diff --git a/media/libstagefright/codecs/amrwbenc/inc/wb_vad_c.h b/media/codecs/amrwb/enc/inc/wb_vad_c.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/inc/wb_vad_c.h
rename to media/codecs/amrwb/enc/inc/wb_vad_c.h
diff --git a/media/libstagefright/codecs/amrwbenc/patent_disclaimer.txt b/media/codecs/amrwb/enc/patent_disclaimer.txt
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/patent_disclaimer.txt
rename to media/codecs/amrwb/enc/patent_disclaimer.txt
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/Deemph_32_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/Deemph_32_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/Dot_p_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/Dot_p_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/Filt_6k_7k_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/Filt_6k_7k_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/Norm_Corr_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/Norm_Corr_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/Syn_filt_32_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/Syn_filt_32_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/convolve_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/convolve_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/cor_h_vec_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/cor_h_vec_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/pred_lt4_1_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/pred_lt4_1_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/residu_asm_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/residu_asm_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/scale_sig_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/scale_sig_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s b/media/codecs/amrwb/enc/src/asm/ARMV5E/syn_filt_opt.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
rename to media/codecs/amrwb/enc/src/asm/ARMV5E/syn_filt_opt.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/Deemph_32_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/Deemph_32_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/Dot_p_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/Dot_p_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/Filt_6k_7k_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/Filt_6k_7k_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/Norm_Corr_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/Norm_Corr_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/Syn_filt_32_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/Syn_filt_32_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/convolve_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/convolve_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/cor_h_vec_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/cor_h_vec_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/pred_lt4_1_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/pred_lt4_1_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/residu_asm_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/residu_asm_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/scale_sig_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/scale_sig_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s b/media/codecs/amrwb/enc/src/asm/ARMV7/syn_filt_neon.s
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
rename to media/codecs/amrwb/enc/src/asm/ARMV7/syn_filt_neon.s
diff --git a/media/libstagefright/codecs/amrwbenc/src/autocorr.c b/media/codecs/amrwb/enc/src/autocorr.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/autocorr.c
rename to media/codecs/amrwb/enc/src/autocorr.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/az_isp.c b/media/codecs/amrwb/enc/src/az_isp.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/az_isp.c
rename to media/codecs/amrwb/enc/src/az_isp.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/bits.c b/media/codecs/amrwb/enc/src/bits.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/bits.c
rename to media/codecs/amrwb/enc/src/bits.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c b/media/codecs/amrwb/enc/src/c2t64fx.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/c2t64fx.c
rename to media/codecs/amrwb/enc/src/c2t64fx.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c b/media/codecs/amrwb/enc/src/c4t64fx.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
rename to media/codecs/amrwb/enc/src/c4t64fx.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/convolve.c b/media/codecs/amrwb/enc/src/convolve.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/convolve.c
rename to media/codecs/amrwb/enc/src/convolve.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c b/media/codecs/amrwb/enc/src/cor_h_x.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/cor_h_x.c
rename to media/codecs/amrwb/enc/src/cor_h_x.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/decim54.c b/media/codecs/amrwb/enc/src/decim54.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/decim54.c
rename to media/codecs/amrwb/enc/src/decim54.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/deemph.c b/media/codecs/amrwb/enc/src/deemph.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/deemph.c
rename to media/codecs/amrwb/enc/src/deemph.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/dtx.c b/media/codecs/amrwb/enc/src/dtx.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/dtx.c
rename to media/codecs/amrwb/enc/src/dtx.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/g_pitch.c b/media/codecs/amrwb/enc/src/g_pitch.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/g_pitch.c
rename to media/codecs/amrwb/enc/src/g_pitch.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/gpclip.c b/media/codecs/amrwb/enc/src/gpclip.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/gpclip.c
rename to media/codecs/amrwb/enc/src/gpclip.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/homing.c b/media/codecs/amrwb/enc/src/homing.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/homing.c
rename to media/codecs/amrwb/enc/src/homing.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp400.c b/media/codecs/amrwb/enc/src/hp400.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/hp400.c
rename to media/codecs/amrwb/enc/src/hp400.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp50.c b/media/codecs/amrwb/enc/src/hp50.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/hp50.c
rename to media/codecs/amrwb/enc/src/hp50.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp6k.c b/media/codecs/amrwb/enc/src/hp6k.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/hp6k.c
rename to media/codecs/amrwb/enc/src/hp6k.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/hp_wsp.c b/media/codecs/amrwb/enc/src/hp_wsp.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/hp_wsp.c
rename to media/codecs/amrwb/enc/src/hp_wsp.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/int_lpc.c b/media/codecs/amrwb/enc/src/int_lpc.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/int_lpc.c
rename to media/codecs/amrwb/enc/src/int_lpc.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/isp_az.c b/media/codecs/amrwb/enc/src/isp_az.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/isp_az.c
rename to media/codecs/amrwb/enc/src/isp_az.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/isp_isf.c b/media/codecs/amrwb/enc/src/isp_isf.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/isp_isf.c
rename to media/codecs/amrwb/enc/src/isp_isf.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/lag_wind.c b/media/codecs/amrwb/enc/src/lag_wind.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/lag_wind.c
rename to media/codecs/amrwb/enc/src/lag_wind.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/levinson.c b/media/codecs/amrwb/enc/src/levinson.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/levinson.c
rename to media/codecs/amrwb/enc/src/levinson.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/log2.c b/media/codecs/amrwb/enc/src/log2.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/log2.c
rename to media/codecs/amrwb/enc/src/log2.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/lp_dec2.c b/media/codecs/amrwb/enc/src/lp_dec2.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/lp_dec2.c
rename to media/codecs/amrwb/enc/src/lp_dec2.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/math_op.c b/media/codecs/amrwb/enc/src/math_op.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/math_op.c
rename to media/codecs/amrwb/enc/src/math_op.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/mem_align.c b/media/codecs/amrwb/enc/src/mem_align.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/mem_align.c
rename to media/codecs/amrwb/enc/src/mem_align.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/oper_32b.c b/media/codecs/amrwb/enc/src/oper_32b.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/oper_32b.c
rename to media/codecs/amrwb/enc/src/oper_32b.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c b/media/codecs/amrwb/enc/src/p_med_ol.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/p_med_ol.c
rename to media/codecs/amrwb/enc/src/p_med_ol.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/pit_shrp.c b/media/codecs/amrwb/enc/src/pit_shrp.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/pit_shrp.c
rename to media/codecs/amrwb/enc/src/pit_shrp.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c b/media/codecs/amrwb/enc/src/pitch_f4.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
rename to media/codecs/amrwb/enc/src/pitch_f4.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/pred_lt4.c b/media/codecs/amrwb/enc/src/pred_lt4.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/pred_lt4.c
rename to media/codecs/amrwb/enc/src/pred_lt4.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/preemph.c b/media/codecs/amrwb/enc/src/preemph.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/preemph.c
rename to media/codecs/amrwb/enc/src/preemph.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/q_gain2.c b/media/codecs/amrwb/enc/src/q_gain2.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/q_gain2.c
rename to media/codecs/amrwb/enc/src/q_gain2.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/q_pulse.c b/media/codecs/amrwb/enc/src/q_pulse.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/q_pulse.c
rename to media/codecs/amrwb/enc/src/q_pulse.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/qisf_ns.c b/media/codecs/amrwb/enc/src/qisf_ns.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/qisf_ns.c
rename to media/codecs/amrwb/enc/src/qisf_ns.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c b/media/codecs/amrwb/enc/src/qpisf_2s.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/qpisf_2s.c
rename to media/codecs/amrwb/enc/src/qpisf_2s.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/random.c b/media/codecs/amrwb/enc/src/random.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/random.c
rename to media/codecs/amrwb/enc/src/random.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/residu.c b/media/codecs/amrwb/enc/src/residu.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/residu.c
rename to media/codecs/amrwb/enc/src/residu.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/scale.c b/media/codecs/amrwb/enc/src/scale.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/scale.c
rename to media/codecs/amrwb/enc/src/scale.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/stream.c b/media/codecs/amrwb/enc/src/stream.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/stream.c
rename to media/codecs/amrwb/enc/src/stream.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/syn_filt.c b/media/codecs/amrwb/enc/src/syn_filt.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/syn_filt.c
rename to media/codecs/amrwb/enc/src/syn_filt.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/updt_tar.c b/media/codecs/amrwb/enc/src/updt_tar.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/updt_tar.c
rename to media/codecs/amrwb/enc/src/updt_tar.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/util.c b/media/codecs/amrwb/enc/src/util.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/util.c
rename to media/codecs/amrwb/enc/src/util.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c b/media/codecs/amrwb/enc/src/voAMRWBEnc.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
rename to media/codecs/amrwb/enc/src/voAMRWBEnc.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/voicefac.c b/media/codecs/amrwb/enc/src/voicefac.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/voicefac.c
rename to media/codecs/amrwb/enc/src/voicefac.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/wb_vad.c b/media/codecs/amrwb/enc/src/wb_vad.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/wb_vad.c
rename to media/codecs/amrwb/enc/src/wb_vad.c
diff --git a/media/libstagefright/codecs/amrwbenc/src/weight_a.c b/media/codecs/amrwb/enc/src/weight_a.c
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/src/weight_a.c
rename to media/codecs/amrwb/enc/src/weight_a.c
diff --git a/media/libstagefright/codecs/amrwbenc/test/AmrwbEncTestEnvironment.h b/media/codecs/amrwb/enc/test/AmrwbEncTestEnvironment.h
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/test/AmrwbEncTestEnvironment.h
rename to media/codecs/amrwb/enc/test/AmrwbEncTestEnvironment.h
diff --git a/media/libstagefright/codecs/amrwbenc/test/AmrwbEncoderTest.cpp b/media/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/test/AmrwbEncoderTest.cpp
rename to media/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp
diff --git a/media/libstagefright/codecs/amrwbenc/test/Android.bp b/media/codecs/amrwb/enc/test/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/test/Android.bp
rename to media/codecs/amrwb/enc/test/Android.bp
diff --git a/media/libstagefright/codecs/amrwbenc/test/AndroidTest.xml b/media/codecs/amrwb/enc/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/test/AndroidTest.xml
rename to media/codecs/amrwb/enc/test/AndroidTest.xml
diff --git a/media/libstagefright/codecs/amrwbenc/test/README.md b/media/codecs/amrwb/enc/test/README.md
similarity index 100%
rename from media/libstagefright/codecs/amrwbenc/test/README.md
rename to media/codecs/amrwb/enc/test/README.md
diff --git a/media/libstagefright/codecs/m4v_h263/TEST_MAPPING b/media/codecs/m4v_h263/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/TEST_MAPPING
rename to media/codecs/m4v_h263/TEST_MAPPING
diff --git a/media/codecs/m4v_h263/dec/Android.bp b/media/codecs/m4v_h263/dec/Android.bp
new file mode 100644
index 0000000..b40745a
--- /dev/null
+++ b/media/codecs/m4v_h263/dec/Android.bp
@@ -0,0 +1,58 @@
+cc_library_static {
+    name: "libstagefright_m4vh263dec",
+    vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
+    host_supported: true,
+    shared_libs: ["liblog"],
+
+    srcs: [
+        "src/bitstream.cpp",
+        "src/block_idct.cpp",
+        "src/cal_dc_scaler.cpp",
+        "src/combined_decode.cpp",
+        "src/conceal.cpp",
+        "src/datapart_decode.cpp",
+        "src/dcac_prediction.cpp",
+        "src/dec_pred_intra_dc.cpp",
+        "src/get_pred_adv_b_add.cpp",
+        "src/get_pred_outside.cpp",
+        "src/idct.cpp",
+        "src/idct_vca.cpp",
+        "src/mb_motion_comp.cpp",
+        "src/mb_utils.cpp",
+        "src/packet_util.cpp",
+        "src/post_filter.cpp",
+        "src/pvdec_api.cpp",
+        "src/scaling_tab.cpp",
+        "src/vlc_decode.cpp",
+        "src/vlc_dequant.cpp",
+        "src/vlc_tab.cpp",
+        "src/vop.cpp",
+        "src/zigzag_tab.cpp",
+    ],
+
+    local_include_dirs: ["src"],
+    export_include_dirs: ["include"],
+
+    cflags: [
+        "-Werror",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2 b/media/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
rename to media/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/m4v_h263/dec/NOTICE b/media/codecs/m4v_h263/dec/NOTICE
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/NOTICE
rename to media/codecs/m4v_h263/dec/NOTICE
diff --git a/media/libstagefright/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h b/media/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
rename to media/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h b/media/codecs/m4v_h263/dec/include/mp4dec_api.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
rename to media/codecs/m4v_h263/dec/include/mp4dec_api.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/include/visual_header.h b/media/codecs/m4v_h263/dec/include/visual_header.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/include/visual_header.h
rename to media/codecs/m4v_h263/dec/include/visual_header.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.cpp b/media/codecs/m4v_h263/dec/src/bitstream.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/bitstream.cpp
rename to media/codecs/m4v_h263/dec/src/bitstream.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.h b/media/codecs/m4v_h263/dec/src/bitstream.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/bitstream.h
rename to media/codecs/m4v_h263/dec/src/bitstream.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp b/media/codecs/m4v_h263/dec/src/block_idct.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
rename to media/codecs/m4v_h263/dec/src/block_idct.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp b/media/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
rename to media/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp b/media/codecs/m4v_h263/dec/src/combined_decode.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp
rename to media/codecs/m4v_h263/dec/src/combined_decode.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp b/media/codecs/m4v_h263/dec/src/conceal.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp
rename to media/codecs/m4v_h263/dec/src/conceal.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp b/media/codecs/m4v_h263/dec/src/datapart_decode.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp
rename to media/codecs/m4v_h263/dec/src/datapart_decode.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/dcac_prediction.cpp b/media/codecs/m4v_h263/dec/src/dcac_prediction.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/dcac_prediction.cpp
rename to media/codecs/m4v_h263/dec/src/dcac_prediction.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp b/media/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
rename to media/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp b/media/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
rename to media/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp b/media/codecs/m4v_h263/dec/src/get_pred_outside.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp
rename to media/codecs/m4v_h263/dec/src/get_pred_outside.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/idct.cpp b/media/codecs/m4v_h263/dec/src/idct.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/idct.cpp
rename to media/codecs/m4v_h263/dec/src/idct.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/idct.h b/media/codecs/m4v_h263/dec/src/idct.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/idct.h
rename to media/codecs/m4v_h263/dec/src/idct.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/idct_vca.cpp b/media/codecs/m4v_h263/dec/src/idct_vca.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/idct_vca.cpp
rename to media/codecs/m4v_h263/dec/src/idct_vca.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/max_level.h b/media/codecs/m4v_h263/dec/src/max_level.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/max_level.h
rename to media/codecs/m4v_h263/dec/src/max_level.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp b/media/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
rename to media/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mb_utils.cpp b/media/codecs/m4v_h263/dec/src/mb_utils.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/mb_utils.cpp
rename to media/codecs/m4v_h263/dec/src/mb_utils.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mbtype_mode.h b/media/codecs/m4v_h263/dec/src/mbtype_mode.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/mbtype_mode.h
rename to media/codecs/m4v_h263/dec/src/mbtype_mode.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/motion_comp.h b/media/codecs/m4v_h263/dec/src/motion_comp.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/motion_comp.h
rename to media/codecs/m4v_h263/dec/src/motion_comp.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h b/media/codecs/m4v_h263/dec/src/mp4dec_lib.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h
rename to media/codecs/m4v_h263/dec/src/mp4dec_lib.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mp4def.h b/media/codecs/m4v_h263/dec/src/mp4def.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/mp4def.h
rename to media/codecs/m4v_h263/dec/src/mp4def.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mp4lib_int.h b/media/codecs/m4v_h263/dec/src/mp4lib_int.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/mp4lib_int.h
rename to media/codecs/m4v_h263/dec/src/mp4lib_int.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp b/media/codecs/m4v_h263/dec/src/packet_util.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp
rename to media/codecs/m4v_h263/dec/src/packet_util.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp b/media/codecs/m4v_h263/dec/src/post_filter.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
rename to media/codecs/m4v_h263/dec/src/post_filter.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/post_proc.h b/media/codecs/m4v_h263/dec/src/post_proc.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/post_proc.h
rename to media/codecs/m4v_h263/dec/src/post_proc.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/codecs/m4v_h263/dec/src/pvdec_api.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
rename to media/codecs/m4v_h263/dec/src/pvdec_api.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/scaling.h b/media/codecs/m4v_h263/dec/src/scaling.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/scaling.h
rename to media/codecs/m4v_h263/dec/src/scaling.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/scaling_tab.cpp b/media/codecs/m4v_h263/dec/src/scaling_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/scaling_tab.cpp
rename to media/codecs/m4v_h263/dec/src/scaling_tab.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dec_tab.h b/media/codecs/m4v_h263/dec/src/vlc_dec_tab.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/vlc_dec_tab.h
rename to media/codecs/m4v_h263/dec/src/vlc_dec_tab.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp b/media/codecs/m4v_h263/dec/src/vlc_decode.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
rename to media/codecs/m4v_h263/dec/src/vlc_decode.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.h b/media/codecs/m4v_h263/dec/src/vlc_decode.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.h
rename to media/codecs/m4v_h263/dec/src/vlc_decode.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp b/media/codecs/m4v_h263/dec/src/vlc_dequant.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp
rename to media/codecs/m4v_h263/dec/src/vlc_dequant.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_tab.cpp b/media/codecs/m4v_h263/dec/src/vlc_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/vlc_tab.cpp
rename to media/codecs/m4v_h263/dec/src/vlc_tab.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp b/media/codecs/m4v_h263/dec/src/vop.cpp
similarity index 98%
rename from media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
rename to media/codecs/m4v_h263/dec/src/vop.cpp
index a11f55e..7b32498 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
+++ b/media/codecs/m4v_h263/dec/src/vop.cpp
@@ -24,7 +24,6 @@
 
 #define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
 
-#ifdef PV_SUPPORT_MAIN_PROFILE
 /* INTRA */
 const static int mpeg_iqmat_def[NCOEFF_BLOCK] =
 {
@@ -50,7 +49,6 @@
     22, 23, 24, 26, 27, 28, 30, 31,
     23, 24, 25, 27, 28, 30, 31, 33
 };
-#endif
 
 /* ======================================================================== */
 /*  Function : CalcNumBits()                                                */
@@ -86,9 +84,7 @@
     BitstreamDecVideo *stream;
     uint32 tmpvar, vol_shape;
     uint32 startCode;
-#ifdef PV_SUPPORT_MAIN_PROFILE
     int *qmat, i, j;
-#endif
     int version_id = 1;
 #ifdef PV_TOLERATE_VOL_ERRORS
     uint32 profile = 0x01;
@@ -317,7 +313,8 @@
         }
         else
         {
-            if (tmpvar != 0x01) return PV_FAIL;
+            // Simple and advanced simple (for quant-type 1)
+            if (tmpvar != 0x01 && tmpvar != 0x11) return PV_FAIL;
         }
 
         /* version id specified? */
@@ -486,7 +483,6 @@
         currVol->quantType = BitstreamRead1Bits(stream);
         if (currVol->quantType)
         {
-#ifdef PV_SUPPORT_MAIN_PROFILE
             /* load quantization matrices.   5/22/2000 */
             /* load_intra_quant_mat (1 bit) */
             qmat = currVol->iqmat;
@@ -501,6 +497,13 @@
                 }
                 while ((qmat[*(zigzag_inv+i)] != 0) && (++i < 64));
 
+                /* qmatrix must have at least one non-zero value, which means
+                   i would be non-zero in valid cases */
+                if (i == 0)
+                {
+                    return PV_FAIL;
+                }
+
                 for (j = i; j < 64; j++)
                     qmat[*(zigzag_inv+j)] = qmat[*(zigzag_inv+i-1)];
             }
@@ -524,6 +527,13 @@
                 }
                 while ((qmat[*(zigzag_inv+i)] != 0) && (++i < 64));
 
+                /* qmatrix must have at least one non-zero value, which means
+                   i would be non-zero in valid cases */
+                if (i == 0)
+                {
+                    return PV_FAIL;
+                }
+
                 for (j = i; j < 64; j++)
                     qmat[*(zigzag_inv+j)] = qmat[*(zigzag_inv+i-1)];
             }
@@ -531,9 +541,6 @@
             {
                 oscl_memcpy(qmat, mpeg_nqmat_def, 64*sizeof(int));
             }
-#else
-            return PV_FAIL;
-#endif
         }
 
         if (version_id != 1)
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/zigzag.h b/media/codecs/m4v_h263/dec/src/zigzag.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/zigzag.h
rename to media/codecs/m4v_h263/dec/src/zigzag.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/zigzag_tab.cpp b/media/codecs/m4v_h263/dec/src/zigzag_tab.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/src/zigzag_tab.cpp
rename to media/codecs/m4v_h263/dec/src/zigzag_tab.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp b/media/codecs/m4v_h263/dec/test/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
rename to media/codecs/m4v_h263/dec/test/Android.bp
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/AndroidTest.xml b/media/codecs/m4v_h263/dec/test/AndroidTest.xml
similarity index 97%
rename from media/libstagefright/codecs/m4v_h263/dec/test/AndroidTest.xml
rename to media/codecs/m4v_h263/dec/test/AndroidTest.xml
index 47e10ca..f572b0c 100755
--- a/media/libstagefright/codecs/m4v_h263/dec/test/AndroidTest.xml
+++ b/media/codecs/m4v_h263/dec/test/AndroidTest.xml
@@ -19,7 +19,7 @@
         <option name="cleanup" value="true" />
         <option name="push" value="Mpeg4H263DecoderTest->/data/local/tmp/Mpeg4H263DecoderTest" />
         <option name="push-file"
-            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263Decoder.zip?unzip=true"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263Decoder-1.1.zip?unzip=true"
             value="/data/local/tmp/Mpeg4H263DecoderTestRes/" />
     </target_preparer>
 
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp b/media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
similarity index 97%
rename from media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
rename to media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
index 967c1ea..53d66ea 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
+++ b/media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
@@ -404,6 +404,9 @@
                           make_tuple("swirl_352x288_h263.h263", "swirl_352x288_h263.info", false),
                           make_tuple("bbb_352x288_h263.h263", "bbb_352x288_h263.info", false),
                           make_tuple("bbb_352x288_mpeg4.m4v", "bbb_352x288_mpeg4.info", true),
+                          make_tuple("qtype0_mpeg4.m4v", "qtype0_mpeg4.info", true),
+                          make_tuple("qtype1_mpeg4.m4v", "qtype1_mpeg4.info", true),
+                          make_tuple("qtype1_qmatrix_mpeg4.m4v", "qtype1_qmatrix_mpeg4.info", true),
                           make_tuple("swirl_128x128_mpeg4.m4v", "swirl_128x128_mpeg4.info", true),
                           make_tuple("swirl_130x132_mpeg4.m4v", "swirl_130x132_mpeg4.info", true),
                           make_tuple("swirl_132x130_mpeg4.m4v", "swirl_132x130_mpeg4.info", true),
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h b/media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
rename to media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/README.md b/media/codecs/m4v_h263/dec/test/README.md
similarity index 90%
rename from media/libstagefright/codecs/m4v_h263/dec/test/README.md
rename to media/codecs/m4v_h263/dec/test/README.md
index 7e4aea1..38ac567 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/test/README.md
+++ b/media/codecs/m4v_h263/dec/test/README.md
@@ -22,7 +22,8 @@
 adb push ${OUT}/data/nativetest/Mpeg4H263DecoderTest/Mpeg4H263DecoderTest /data/local/tmp/
 ```
 
-The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263Decoder.zip). Download, unzip and push these files into device for testing.
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263Decoder-1.1.zip).
+Download, unzip and push these files into device for testing.
 
 ```
 adb push Mpeg4H263Decoder /data/local/tmp/
diff --git a/media/codecs/m4v_h263/enc/Android.bp b/media/codecs/m4v_h263/enc/Android.bp
new file mode 100644
index 0000000..dd7f005
--- /dev/null
+++ b/media/codecs/m4v_h263/enc/Android.bp
@@ -0,0 +1,75 @@
+cc_library_static {
+    name: "libstagefright_m4vh263enc",
+    vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+
+    srcs: [
+        "src/bitstream_io.cpp",
+        "src/combined_encode.cpp", "src/datapart_encode.cpp",
+        "src/dct.cpp",
+        "src/findhalfpel.cpp",
+        "src/fastcodemb.cpp",
+        "src/fastidct.cpp",
+        "src/fastquant.cpp",
+        "src/me_utils.cpp",
+        "src/mp4enc_api.cpp",
+        "src/rate_control.cpp",
+        "src/motion_est.cpp",
+        "src/motion_comp.cpp",
+        "src/sad.cpp",
+        "src/sad_halfpel.cpp",
+        "src/vlc_encode.cpp",
+        "src/vop.cpp",
+    ],
+
+    cflags: [
+        "-DBX_RC",
+        "-Werror",
+    ],
+
+    local_include_dirs: ["src"],
+    export_include_dirs: ["include"],
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
+
+//###############################################################################
+
+cc_test {
+    name: "libstagefright_m4vh263enc_test",
+    gtest: false,
+
+    srcs: ["test/m4v_h263_enc_test.cpp"],
+
+    local_include_dirs: ["src"],
+
+    cflags: [
+        "-DBX_RC",
+        "-Wall",
+        "-Werror",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+
+    static_libs: ["libstagefright_m4vh263enc"],
+}
diff --git a/media/libstagefright/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2 b/media/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
rename to media/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/m4v_h263/enc/NOTICE b/media/codecs/m4v_h263/enc/NOTICE
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/NOTICE
rename to media/codecs/m4v_h263/enc/NOTICE
diff --git a/media/libstagefright/codecs/m4v_h263/enc/include/cvei.h b/media/codecs/m4v_h263/enc/include/cvei.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/include/cvei.h
rename to media/codecs/m4v_h263/enc/include/cvei.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h b/media/codecs/m4v_h263/enc/include/mp4enc_api.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
rename to media/codecs/m4v_h263/enc/include/mp4enc_api.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/bitstream_io.cpp b/media/codecs/m4v_h263/enc/src/bitstream_io.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/bitstream_io.cpp
rename to media/codecs/m4v_h263/enc/src/bitstream_io.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/bitstream_io.h b/media/codecs/m4v_h263/enc/src/bitstream_io.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/bitstream_io.h
rename to media/codecs/m4v_h263/enc/src/bitstream_io.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/combined_encode.cpp b/media/codecs/m4v_h263/enc/src/combined_encode.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/combined_encode.cpp
rename to media/codecs/m4v_h263/enc/src/combined_encode.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/datapart_encode.cpp b/media/codecs/m4v_h263/enc/src/datapart_encode.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/datapart_encode.cpp
rename to media/codecs/m4v_h263/enc/src/datapart_encode.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp b/media/codecs/m4v_h263/enc/src/dct.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp
rename to media/codecs/m4v_h263/enc/src/dct.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/dct.h b/media/codecs/m4v_h263/enc/src/dct.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/dct.h
rename to media/codecs/m4v_h263/enc/src/dct.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/dct_inline.h b/media/codecs/m4v_h263/enc/src/dct_inline.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/dct_inline.h
rename to media/codecs/m4v_h263/enc/src/dct_inline.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp b/media/codecs/m4v_h263/enc/src/fastcodemb.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp
rename to media/codecs/m4v_h263/enc/src/fastcodemb.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.h b/media/codecs/m4v_h263/enc/src/fastcodemb.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.h
rename to media/codecs/m4v_h263/enc/src/fastcodemb.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/fastidct.cpp b/media/codecs/m4v_h263/enc/src/fastidct.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/fastidct.cpp
rename to media/codecs/m4v_h263/enc/src/fastidct.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/fastquant.cpp b/media/codecs/m4v_h263/enc/src/fastquant.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/fastquant.cpp
rename to media/codecs/m4v_h263/enc/src/fastquant.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/fastquant_inline.h b/media/codecs/m4v_h263/enc/src/fastquant_inline.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/fastquant_inline.h
rename to media/codecs/m4v_h263/enc/src/fastquant_inline.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/findhalfpel.cpp b/media/codecs/m4v_h263/enc/src/findhalfpel.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/findhalfpel.cpp
rename to media/codecs/m4v_h263/enc/src/findhalfpel.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/m4venc_oscl.h b/media/codecs/m4v_h263/enc/src/m4venc_oscl.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/m4venc_oscl.h
rename to media/codecs/m4v_h263/enc/src/m4venc_oscl.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/me_utils.cpp b/media/codecs/m4v_h263/enc/src/me_utils.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/me_utils.cpp
rename to media/codecs/m4v_h263/enc/src/me_utils.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp b/media/codecs/m4v_h263/enc/src/motion_comp.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp
rename to media/codecs/m4v_h263/enc/src/motion_comp.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/motion_est.cpp b/media/codecs/m4v_h263/enc/src/motion_est.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/motion_est.cpp
rename to media/codecs/m4v_h263/enc/src/motion_est.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h b/media/codecs/m4v_h263/enc/src/mp4def.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
rename to media/codecs/m4v_h263/enc/src/mp4def.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4enc_api.cpp b/media/codecs/m4v_h263/enc/src/mp4enc_api.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/mp4enc_api.cpp
rename to media/codecs/m4v_h263/enc/src/mp4enc_api.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4enc_lib.h b/media/codecs/m4v_h263/enc/src/mp4enc_lib.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/mp4enc_lib.h
rename to media/codecs/m4v_h263/enc/src/mp4enc_lib.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4lib_int.h b/media/codecs/m4v_h263/enc/src/mp4lib_int.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/mp4lib_int.h
rename to media/codecs/m4v_h263/enc/src/mp4lib_int.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/rate_control.cpp b/media/codecs/m4v_h263/enc/src/rate_control.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/rate_control.cpp
rename to media/codecs/m4v_h263/enc/src/rate_control.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/rate_control.h b/media/codecs/m4v_h263/enc/src/rate_control.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/rate_control.h
rename to media/codecs/m4v_h263/enc/src/rate_control.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/sad.cpp b/media/codecs/m4v_h263/enc/src/sad.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/sad.cpp
rename to media/codecs/m4v_h263/enc/src/sad.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/sad_halfpel.cpp b/media/codecs/m4v_h263/enc/src/sad_halfpel.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/sad_halfpel.cpp
rename to media/codecs/m4v_h263/enc/src/sad_halfpel.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/sad_halfpel_inline.h b/media/codecs/m4v_h263/enc/src/sad_halfpel_inline.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/sad_halfpel_inline.h
rename to media/codecs/m4v_h263/enc/src/sad_halfpel_inline.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h b/media/codecs/m4v_h263/enc/src/sad_inline.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h
rename to media/codecs/m4v_h263/enc/src/sad_inline.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/sad_mb_offset.h b/media/codecs/m4v_h263/enc/src/sad_mb_offset.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/sad_mb_offset.h
rename to media/codecs/m4v_h263/enc/src/sad_mb_offset.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/vlc_enc_tab.h b/media/codecs/m4v_h263/enc/src/vlc_enc_tab.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/vlc_enc_tab.h
rename to media/codecs/m4v_h263/enc/src/vlc_enc_tab.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/vlc_encode.cpp b/media/codecs/m4v_h263/enc/src/vlc_encode.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/vlc_encode.cpp
rename to media/codecs/m4v_h263/enc/src/vlc_encode.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/vlc_encode.h b/media/codecs/m4v_h263/enc/src/vlc_encode.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/vlc_encode.h
rename to media/codecs/m4v_h263/enc/src/vlc_encode.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/vlc_encode_inline.h b/media/codecs/m4v_h263/enc/src/vlc_encode_inline.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/vlc_encode_inline.h
rename to media/codecs/m4v_h263/enc/src/vlc_encode_inline.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/vop.cpp b/media/codecs/m4v_h263/enc/src/vop.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/src/vop.cpp
rename to media/codecs/m4v_h263/enc/src/vop.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/test/Android.bp b/media/codecs/m4v_h263/enc/test/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/test/Android.bp
rename to media/codecs/m4v_h263/enc/test/Android.bp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/test/AndroidTest.xml b/media/codecs/m4v_h263/enc/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/test/AndroidTest.xml
rename to media/codecs/m4v_h263/enc/test/AndroidTest.xml
diff --git a/media/libstagefright/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp b/media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp
rename to media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h b/media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h
rename to media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h
diff --git a/media/libstagefright/codecs/m4v_h263/enc/test/README.md b/media/codecs/m4v_h263/enc/test/README.md
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/test/README.md
rename to media/codecs/m4v_h263/enc/test/README.md
diff --git a/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp b/media/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
rename to media/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
diff --git a/media/libstagefright/codecs/m4v_h263/fuzzer/Android.bp b/media/codecs/m4v_h263/fuzzer/Android.bp
similarity index 69%
rename from media/libstagefright/codecs/m4v_h263/fuzzer/Android.bp
rename to media/codecs/m4v_h263/fuzzer/Android.bp
index 56fc782..778dafb 100644
--- a/media/libstagefright/codecs/m4v_h263/fuzzer/Android.bp
+++ b/media/codecs/m4v_h263/fuzzer/Android.bp
@@ -18,25 +18,24 @@
  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
  */
 
-cc_fuzz {
-    name: "mpeg4_dec_fuzzer",
+cc_defaults {
+    name: "mpeg4_h263_dec_fuzz_defaults",
+
     host_supported: true,
+
     srcs: [
         "mpeg4_h263_dec_fuzzer.cpp",
     ],
+
     static_libs: [
         "libstagefright_m4vh263dec",
         "liblog",
     ],
+
     cflags: [
         "-DOSCL_IMPORT_REF=",
-        "-DMPEG4",
     ],
-    target: {
-        darwin: {
-            enabled: false,
-        },
-    },
+
     fuzz_config: {
         cc: [
             "android-media-fuzzing-reports@google.com",
@@ -46,23 +45,45 @@
 }
 
 cc_fuzz {
-    name: "h263_dec_fuzzer",
-    host_supported: true,
-    srcs: [
-        "mpeg4_h263_dec_fuzzer.cpp",
+    name: "mpeg4_dec_fuzzer",
+
+    defaults: [
+        "mpeg4_h263_dec_fuzz_defaults",
     ],
-    static_libs: [
-        "libstagefright_m4vh263dec",
+
+    cflags: [
+        "-DMPEG4",
+    ],
+}
+
+cc_fuzz {
+    name: "h263_dec_fuzzer",
+
+    defaults: [
+        "mpeg4_h263_dec_fuzz_defaults",
+    ],
+}
+
+cc_defaults {
+    name: "mpeg4_h263_enc_fuzz_defaults",
+
+    host_supported: true,
+
+    srcs: ["mpeg4_h263_enc_fuzzer.cpp"],
+
+    shared_libs: [
+        "libutils",
         "liblog",
     ],
-    cflags: [
-        "-DOSCL_IMPORT_REF=",
+
+    static_libs: [
+        "libstagefright_m4vh263enc",
     ],
-    target: {
-        darwin: {
-            enabled: false,
-        },
-    },
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
     fuzz_config: {
         cc: [
             "android-media-fuzzing-reports@google.com",
@@ -70,3 +91,21 @@
         componentid: 155276,
     },
 }
+
+cc_fuzz {
+    name: "mpeg4_enc_fuzzer",
+
+    defaults: [
+        "mpeg4_h263_enc_fuzz_defaults",
+    ],
+
+    cflags: ["-DMPEG4"],
+}
+
+cc_fuzz {
+    name: "h263_enc_fuzzer",
+
+    defaults: [
+        "mpeg4_h263_enc_fuzz_defaults",
+    ],
+}
diff --git a/media/codecs/m4v_h263/fuzzer/README.md b/media/codecs/m4v_h263/fuzzer/README.md
new file mode 100644
index 0000000..ad4ff97
--- /dev/null
+++ b/media/codecs/m4v_h263/fuzzer/README.md
@@ -0,0 +1,158 @@
+# Fuzzer for libstagefright_m4vh263dec decoder
+
+## Plugin Design Considerations
+The fuzzer plugin for MPEG4/H263 is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+Dict files (dictionary files) are created for MPEG4 and H263 to ensure that the required start
+bytes are present in every input file that goes to the fuzzer.
+This ensures that decoder does not reject any input file in the first check
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec using a loop.
+ * If the decode operation was successful, the input is advanced by the number of bytes consumed
+   in the decode call.
+ * If the decode operation was un-successful, the input is advanced by 1 byte so that the fuzzer
+   can proceed to feed the next frame.
+
+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.
+
+##### Other considerations
+ * Two fuzzer binaries - mpeg4_dec_fuzzer and h263_dec_fuzzer are generated based on the presence
+   of a flag - 'MPEG4'
+ * The number of decode calls are kept to a maximum of 100 so that the fuzzer does not timeout.
+
+## Build
+
+This describes steps to build mpeg4_dec_fuzzer and h263_dec_fuzzer binary.
+
+### Android
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mpeg4_dec_fuzzer
+  $ mm -j$(nproc) h263_dec_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some MPEG4 or H263 files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mpeg4_dec_fuzzer/mpeg4_dec_fuzzer CORPUS_DIR
+  $ adb shell /data/fuzz/arm64/h263_dec_fuzzer/h263_dec_fuzzer CORPUS_DIR
+```
+To run on host
+```
+  $ $ANDROID_HOST_OUT/fuzz/x86_64/mpeg4_dec_fuzzer/mpeg4_dec_fuzzer CORPUS_DIR
+  $ $ANDROID_HOST_OUT/fuzz/x86_64/h263_dec_fuzzer/h263_dec_fuzzer CORPUS_DIR
+```
+
+# Fuzzer for libstagefright_m4vh263enc encoder
+
+## Plugin Design Considerations
+The fuzzer plugin for MPEG4/H263 is designed based on the understanding of the
+codec 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.
+
+MPEG4/H263 supports the following parameters:
+1. Frame Width (parameter name: `encWidth`)
+2. Frame Height (parameter name: `encHeight`)
+3. Rate control mode (parameter name: `rcType`)
+4. Number of bytes per packet (parameter name: `packetSize`)
+5. Qp for I-Vop(parameter name: `iQuant`)
+6. Qp for P-Vop (parameter name: `pQuant`)
+7. Enable RVLC mode (parameter name: `rvlcEnable`)
+8. Quantization mode (parameter name: `quantType`)
+9. Disable frame skipping (parameter name: `noFrameSkipped`)
+10. Enable scene change detection (parameter name: `sceneDetect`)
+11. Number of intra MBs in P-frame(parameter name: `numIntraMB`)
+12. Search range of ME (parameter name: `searchRange`)
+13. Enable 8x8 ME and MC (parameter name: `mv8x8Enable`)
+14. Enable AC prediction (parameter name: `useACPred`)
+15. Threshold for intra DC VLC (parameter name: `intraDCVlcTh`)
+16. Encoding Mode (parameter name: `encMode`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `rcType` | 0. `CONSTANT_Q` 1. `CBR_1` 2. `VBR_1` 3. `CBR_2` 4. `VBR_2` 5. `CBR_LOWDELAY` | All the bits of 6th byte of data modulus 6 |
+| `packetSize` | In the range `0 to 255` | All the bits of 7th byte of data |
+| `iQuant` | In the range `1 to 31` | All the bits of 8th byte of data |
+| `pQuant` | In the range `1 to 31` | All the bits of 9th byte of data |
+| `rvlcEnable` | 0. `PV_OFF` 1. `PV_ON` | bit 0 of 10th byte of data |
+| `quantType` | 0. `0` 1. `1` | bit 0 of 11th byte of data |
+| `noFrameSkipped` | 0. `PV_OFF` 1. `PV_ON` | bit 0 of 12th byte of data |
+| `sceneDetect` | 0. `PV_OFF` 1. `PV_ON` | bit 0 of 13th byte of data |
+| `numIntraMB` | In the range `0 to 7` | bit 0, 1 and 2 of 14th byte of data |
+| `searchRange` | In the range `0 to 31` | bit 0, 1, 2, 3 and 4 of 15th byte of data |
+| `mv8x8Enable` | 0. `PV_OFF` 1. `PV_ON` | bit 0 of 16th byte of data |
+| `useACPred` | 0. `PV_OFF` 1. `PV_ON` | bit 0 of 17th byte of data |
+| `intraDCVlcTh` | In the range `0 to 7` | bit 0, 1 and 2 of 18th byte of data |
+
+Following parameters are only for mpeg4_enc_fuzzer
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `encWidth` | In the range `0 to 10239` | All the bits of 1st and 2nd byte of data |
+| `encHeight` | In the range `0 to 10239` | All the bits of 3rd and 4th byte of data |
+| `encMode` | 0. `H263_MODE` 1. `H263_MODE_WITH_ERR_RES` 2. `DATA_PARTITIONING_MODE` 3. `COMBINE_MODE_NO_ERR_RES` 4. `COMBINE_MODE_WITH_ERR_RES` | All the bits of 19th byte of data modulus 5 |
+
+Following parameters are only for h263_enc_fuzzer
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `encWidth` | 0. `128` 1. `176` 2. `352` 3. `704` 4. `1408` | All the bits of 1st byte of data modulus 5|
+| `encHeight` | 0. `96` 1. `144` 2. `288` 3. `576` 4. `1152 ` | All the bits of 3rd byte of data modulus 5|
+| `encMode` | 0. `SHORT_HEADER` 1. `SHORT_HEADER_WITH_ERR_RES` | All the bits of 19th byte of data modulus 2 |
+
+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 codec using a loop.
+If the encode operation was successful, the input is advanced by the frame size.
+If the encode operation was un-successful, the input is still advanced by frame size so
+that the fuzzer can proceed to feed the next frame.
+
+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 mpeg4_enc_fuzzer and h263_enc_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mpeg4_enc_fuzzer
+  $ mm -j$(nproc) h263_enc_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some yuv files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/m4v_h263_enc_fuzzer/m4v_h263_enc_fuzzer CORPUS_DIR
+  $ adb shell /data/fuzz/arm64/h263_enc_fuzzer/h263_enc_fuzzer CORPUS_DIR
+```
+To run on host
+```
+  $ $ANDROID_HOST_OUT/fuzz/x86_64/mpeg4_enc_fuzzer/mpeg4_enc_fuzzer CORPUS_DIR
+  $ $ANDROID_HOST_OUT/fuzz/x86_64/h263_enc_fuzzer/h263_enc_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/libstagefright/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict b/media/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
rename to media/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
diff --git a/media/libstagefright/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict b/media/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
rename to media/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
diff --git a/media/libstagefright/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp b/media/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
rename to media/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
diff --git a/media/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp b/media/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp
new file mode 100644
index 0000000..423325d
--- /dev/null
+++ b/media/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp
@@ -0,0 +1,192 @@
+/*
+ * 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.
+ */
+#include <algorithm>
+#include "mp4enc_api.h"
+
+constexpr int8_t kIDRFrameRefreshIntervalInSec = 1;
+constexpr MP4RateControlType krcType[] = {CONSTANT_Q, CBR_1, VBR_1, CBR_2, VBR_2, CBR_LOWDELAY};
+#ifdef MPEG4
+constexpr MP4EncodingMode kEncodingMode[] = {SHORT_HEADER, SHORT_HEADER_WITH_ERR_RES,
+                                             DATA_PARTITIONING_MODE, COMBINE_MODE_NO_ERR_RES,
+                                             COMBINE_MODE_WITH_ERR_RES};
+constexpr size_t kMaxWidth = 10240;
+constexpr size_t kMaxHeight = 10240;
+#else
+constexpr MP4EncodingMode kEncodingMode[] = {H263_MODE, H263_MODE_WITH_ERR_RES};
+constexpr int kWidth[] = {128, 176, 352, 704, 1408};
+constexpr int kHeight[] = {96, 144, 288, 576, 1152};
+constexpr size_t kWidthNum = std::size(kWidth);
+constexpr size_t kHeightNum = std::size(kHeight);
+#endif
+
+constexpr size_t krcTypeNum = std::size(krcType);
+constexpr size_t kEncodingModeNum = std::size(kEncodingMode);
+constexpr size_t kMaxQP = 51;
+
+enum {
+    IDX_WD_BYTE_1,
+    IDX_WD_BYTE_2,
+    IDX_HT_BYTE_1,
+    IDX_HT_BYTE_2,
+    IDX_FRAME_RATE,
+    IDX_RC_TYPE,
+    IDX_PACKET_SIZE,
+    IDX_I_FRAME_QP,
+    IDX_P_FRAME_QP,
+    IDX_ENABLE_RVLC,
+    IDX_QUANT_TYPE,
+    IDX_NO_FRAME_SKIPPED_FLAG,
+    IDX_ENABLE_SCENE_DETECT,
+    IDX_NUM_INTRA_MB,
+    IDX_SEARCH_RANGE,
+    IDX_ENABLE_MV_8x8,
+    IDX_USE_AC_PRED,
+    IDX_INTRA_DC_VLC_THRESHOLD,
+    IDX_ENC_MODE,
+    IDX_LAST
+};
+
+class Codec {
+   public:
+    Codec() = default;
+    ~Codec() { deInitEncoder(); }
+    bool initEncoder(const uint8_t *data);
+    void encodeFrames(const uint8_t *data, size_t size);
+    void deInitEncoder();
+
+   private:
+    int32_t mFrameWidth = 352;
+    int32_t mFrameHeight = 288;
+    float mFrameRate = 25.0f;
+    VideoEncOptions *mEncodeHandle = nullptr;
+    VideoEncControls *mEncodeControl = nullptr;
+};
+
+bool Codec::initEncoder(const uint8_t *data) {
+    mEncodeHandle = new VideoEncOptions;
+    if (!mEncodeHandle) {
+        return false;
+    }
+    memset(mEncodeHandle, 0, sizeof(VideoEncOptions));
+    mEncodeControl = new VideoEncControls;
+    if (!mEncodeControl) {
+        return false;
+    }
+    memset(mEncodeControl, 0, sizeof(VideoEncControls));
+    PVGetDefaultEncOption(mEncodeHandle, 0);
+
+#ifdef MPEG4
+    mFrameWidth = ((data[IDX_WD_BYTE_1] << 8) | data[IDX_WD_BYTE_2]) % kMaxWidth;
+    mFrameHeight = ((data[IDX_HT_BYTE_1] << 8) | data[IDX_HT_BYTE_2]) % kMaxHeight;
+#else
+    mFrameWidth = kWidth[data[IDX_WD_BYTE_1] % kWidthNum];
+    mFrameHeight = kHeight[data[IDX_HT_BYTE_1] % kHeightNum];
+#endif
+    mFrameRate = data[IDX_FRAME_RATE];
+    mEncodeHandle->rcType = krcType[data[IDX_RC_TYPE] % krcTypeNum];
+    mEncodeHandle->profile_level = CORE_PROFILE_LEVEL2;
+    mEncodeHandle->packetSize = data[IDX_PACKET_SIZE];
+    mEncodeHandle->iQuant[0] = (data[IDX_I_FRAME_QP] % kMaxQP) + 1;
+    mEncodeHandle->pQuant[0] = (data[IDX_P_FRAME_QP] % kMaxQP) + 1;
+    mEncodeHandle->rvlcEnable = (data[IDX_ENABLE_RVLC] & 0x01) ? PV_OFF : PV_ON;
+    mEncodeHandle->quantType[0] = (data[IDX_QUANT_TYPE] & 0x01) ? 0 : 1;
+    mEncodeHandle->noFrameSkipped = (data[IDX_NO_FRAME_SKIPPED_FLAG] & 0x01) ? PV_OFF : PV_ON;
+    mEncodeHandle->sceneDetect = (data[IDX_ENABLE_SCENE_DETECT] & 0x01) ? PV_OFF : PV_ON;
+    mEncodeHandle->numIntraMB = data[IDX_NUM_INTRA_MB] & 0x07;
+    mEncodeHandle->searchRange = data[IDX_SEARCH_RANGE] & 0x1F;
+    mEncodeHandle->mv8x8Enable = (data[IDX_ENABLE_MV_8x8] & 0x01) ? PV_OFF : PV_ON;
+    mEncodeHandle->useACPred = (data[IDX_USE_AC_PRED] & 0x01) ? PV_OFF : PV_ON;
+    mEncodeHandle->intraDCVlcTh = data[IDX_INTRA_DC_VLC_THRESHOLD] & 0x07;
+    mEncodeHandle->encMode = kEncodingMode[data[IDX_ENC_MODE] % kEncodingModeNum];
+    mEncodeHandle->encWidth[0] = mFrameWidth;
+    mEncodeHandle->encHeight[0] = mFrameHeight;
+    mEncodeHandle->encFrameRate[0] = mFrameRate;
+    mEncodeHandle->tickPerSrc = mEncodeHandle->timeIncRes / mFrameRate;
+    mEncodeHandle->intraPeriod = (kIDRFrameRefreshIntervalInSec * mFrameRate);
+    if (!PVInitVideoEncoder(mEncodeControl, mEncodeHandle)) {
+        return false;
+    }
+    return true;
+}
+
+void Codec::deInitEncoder() {
+    if (mEncodeControl) {
+        PVCleanUpVideoEncoder(mEncodeControl);
+        delete mEncodeControl;
+        mEncodeControl = nullptr;
+    }
+    if (mEncodeHandle) {
+        delete mEncodeHandle;
+        mEncodeHandle = nullptr;
+    }
+}
+
+void Codec::encodeFrames(const uint8_t *data, size_t size) {
+    size_t inputBufferSize = (mFrameWidth * mFrameHeight * 3) / 2;
+    size_t outputBufferSize = inputBufferSize * 2;
+    uint8_t *outputBuffer = new uint8_t[outputBufferSize];
+    uint8_t *inputBuffer = new uint8_t[inputBufferSize];
+
+    // Get VOL header.
+    int32_t sizeOutputBuffer = outputBufferSize;
+    PVGetVolHeader(mEncodeControl, outputBuffer, &sizeOutputBuffer, 0);
+
+    size_t numFrame = 0;
+    while (size > 0) {
+        size_t bytesConsumed = std::min(size, inputBufferSize);
+        memcpy(inputBuffer, data, bytesConsumed);
+        if (bytesConsumed < inputBufferSize) {
+            memset(inputBuffer + bytesConsumed, data[0], inputBufferSize - bytesConsumed);
+        }
+        VideoEncFrameIO videoIn{}, videoOut{};
+        videoIn.height = mFrameHeight;
+        videoIn.pitch = mFrameWidth;
+        videoIn.timestamp = (numFrame * 1000) / mFrameRate;
+        videoIn.yChan = inputBuffer;
+        videoIn.uChan = videoIn.yChan + videoIn.height * videoIn.pitch;
+        videoIn.vChan = videoIn.uChan + ((videoIn.height * videoIn.pitch) >> 2);
+        uint32_t modTimeMs = 0;
+        int32_t dataLength = outputBufferSize;
+        int32_t nLayer = 0;
+        PVEncodeVideoFrame(mEncodeControl, &videoIn, &videoOut, &modTimeMs, outputBuffer,
+                           &dataLength, &nLayer);
+        MP4HintTrack hintTrack;
+        PVGetHintTrack(mEncodeControl, &hintTrack);
+        PVGetOverrunBuffer(mEncodeControl);
+        ++numFrame;
+        data += bytesConsumed;
+        size -= bytesConsumed;
+    }
+    delete[] inputBuffer;
+    delete[] outputBuffer;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+    if (size < IDX_LAST) {
+        return 0;
+    }
+    Codec *codec = new Codec();
+    if (!codec) {
+        return 0;
+    }
+    if (codec->initEncoder(data)) {
+        data += IDX_LAST;
+        size -= IDX_LAST;
+        codec->encodeFrames(data, size);
+    }
+    delete codec;
+    return 0;
+}
diff --git a/media/libstagefright/codecs/m4v_h263/patent_disclaimer.txt b/media/codecs/m4v_h263/patent_disclaimer.txt
similarity index 100%
rename from media/libstagefright/codecs/m4v_h263/patent_disclaimer.txt
rename to media/codecs/m4v_h263/patent_disclaimer.txt
diff --git a/media/codecs/mp3dec/Android.bp b/media/codecs/mp3dec/Android.bp
new file mode 100644
index 0000000..f84da21
--- /dev/null
+++ b/media/codecs/mp3dec/Android.bp
@@ -0,0 +1,128 @@
+cc_library_headers {
+    name: "libstagefright_mp3dec_headers",
+    vendor_available: true,
+    min_sdk_version: "29",
+    host_supported:true,
+    export_include_dirs: [
+        "include",
+        "src",
+    ],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+    ],
+}
+
+cc_library_static {
+    name: "libstagefright_mp3dec",
+    vendor_available: true,
+    min_sdk_version: "29",
+
+    host_supported:true,
+    srcs: [
+        "src/pvmp3_normalize.cpp",
+        "src/pvmp3_alias_reduction.cpp",
+        "src/pvmp3_crc.cpp",
+        "src/pvmp3_decode_header.cpp",
+        "src/pvmp3_decode_huff_cw.cpp",
+        "src/pvmp3_getbits.cpp",
+        "src/pvmp3_dequantize_sample.cpp",
+        "src/pvmp3_framedecoder.cpp",
+        "src/pvmp3_get_main_data_size.cpp",
+        "src/pvmp3_get_side_info.cpp",
+        "src/pvmp3_get_scale_factors.cpp",
+        "src/pvmp3_mpeg2_get_scale_data.cpp",
+        "src/pvmp3_mpeg2_get_scale_factors.cpp",
+        "src/pvmp3_mpeg2_stereo_proc.cpp",
+        "src/pvmp3_huffman_decoding.cpp",
+        "src/pvmp3_huffman_parsing.cpp",
+        "src/pvmp3_tables.cpp",
+        "src/pvmp3_imdct_synth.cpp",
+        "src/pvmp3_mdct_6.cpp",
+        "src/pvmp3_dct_6.cpp",
+        "src/pvmp3_poly_phase_synthesis.cpp",
+        "src/pvmp3_equalizer.cpp",
+        "src/pvmp3_seek_synch.cpp",
+        "src/pvmp3_stereo_proc.cpp",
+        "src/pvmp3_reorder.cpp",
+
+        "src/pvmp3_polyphase_filter_window.cpp",
+        "src/pvmp3_mdct_18.cpp",
+        "src/pvmp3_dct_9.cpp",
+        "src/pvmp3_dct_16.cpp",
+    ],
+
+    arch: {
+        arm: {
+            exclude_srcs: [
+                "src/pvmp3_polyphase_filter_window.cpp",
+                "src/pvmp3_mdct_18.cpp",
+                "src/pvmp3_dct_9.cpp",
+                "src/pvmp3_dct_16.cpp",
+            ],
+            srcs: [
+                "src/asm/pvmp3_polyphase_filter_window_gcc.s",
+                "src/asm/pvmp3_mdct_18_gcc.s",
+                "src/asm/pvmp3_dct_9_gcc.s",
+                "src/asm/pvmp3_dct_16_gcc.s",
+            ],
+
+            instruction_set: "arm",
+        },
+    },
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+
+    include_dirs: ["frameworks/av/media/libstagefright/include"],
+
+    header_libs: ["libstagefright_mp3dec_headers"],
+    export_header_lib_headers: ["libstagefright_mp3dec_headers"],
+
+    cflags: [
+        "-DOSCL_UNUSED_ARG(x)=(void)(x)",
+        "-Werror",
+    ],
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+//###############################################################################
+cc_test {
+    name: "libstagefright_mp3dec_test",
+    gtest: false,
+
+    srcs: [
+        "test/mp3dec_test.cpp",
+        "test/mp3reader.cpp",
+    ],
+
+    cflags: ["-Wall", "-Werror"],
+
+    local_include_dirs: [
+        "src",
+        "include",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+
+    static_libs: [
+        "libstagefright_mp3dec",
+        "libsndfile",
+    ],
+
+    shared_libs: ["libaudioutils"],
+}
diff --git a/media/libstagefright/codecs/mp3dec/MODULE_LICENSE_APACHE2 b/media/codecs/mp3dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/MODULE_LICENSE_APACHE2
rename to media/codecs/mp3dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/mp3dec/NOTICE b/media/codecs/mp3dec/NOTICE
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/NOTICE
rename to media/codecs/mp3dec/NOTICE
diff --git a/media/libstagefright/codecs/mp3dec/TEST_MAPPING b/media/codecs/mp3dec/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/TEST_MAPPING
rename to media/codecs/mp3dec/TEST_MAPPING
diff --git a/media/libstagefright/codecs/mp3dec/fuzzer/Android.bp b/media/codecs/mp3dec/fuzzer/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/fuzzer/Android.bp
rename to media/codecs/mp3dec/fuzzer/Android.bp
diff --git a/media/libstagefright/codecs/mp3dec/fuzzer/README.md b/media/codecs/mp3dec/fuzzer/README.md
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/fuzzer/README.md
rename to media/codecs/mp3dec/fuzzer/README.md
diff --git a/media/libstagefright/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp b/media/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
rename to media/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
diff --git a/media/libstagefright/codecs/mp3dec/include/mp3_decoder_selection.h b/media/codecs/mp3dec/include/mp3_decoder_selection.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/include/mp3_decoder_selection.h
rename to media/codecs/mp3dec/include/mp3_decoder_selection.h
diff --git a/media/libstagefright/codecs/mp3dec/include/pvmp3_audio_type_defs.h b/media/codecs/mp3dec/include/pvmp3_audio_type_defs.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/include/pvmp3_audio_type_defs.h
rename to media/codecs/mp3dec/include/pvmp3_audio_type_defs.h
diff --git a/media/libstagefright/codecs/mp3dec/include/pvmp3decoder_api.h b/media/codecs/mp3dec/include/pvmp3decoder_api.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/include/pvmp3decoder_api.h
rename to media/codecs/mp3dec/include/pvmp3decoder_api.h
diff --git a/media/libstagefright/codecs/mp3dec/patent_disclaimer.txt b/media/codecs/mp3dec/patent_disclaimer.txt
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/patent_disclaimer.txt
rename to media/codecs/mp3dec/patent_disclaimer.txt
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s b/media/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s
rename to media/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s b/media/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s
rename to media/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s b/media/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s
rename to media/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s b/media/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
rename to media/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
diff --git a/media/libstagefright/codecs/mp3dec/src/mp3_mem_funcs.h b/media/codecs/mp3dec/src/mp3_mem_funcs.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/mp3_mem_funcs.h
rename to media/codecs/mp3dec/src/mp3_mem_funcs.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pv_mp3_huffman.h b/media/codecs/mp3dec/src/pv_mp3_huffman.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pv_mp3_huffman.h
rename to media/codecs/mp3dec/src/pv_mp3_huffman.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op.h b/media/codecs/mp3dec/src/pv_mp3dec_fxd_op.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op.h
rename to media/codecs/mp3dec/src/pv_mp3dec_fxd_op.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h b/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h
rename to media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h b/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h
rename to media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h b/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
rename to media/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h b/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h
rename to media/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_alias_reduction.cpp b/media/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
rename to media/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_alias_reduction.h b/media/codecs/mp3dec/src/pvmp3_alias_reduction.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_alias_reduction.h
rename to media/codecs/mp3dec/src/pvmp3_alias_reduction.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_crc.cpp b/media/codecs/mp3dec/src/pvmp3_crc.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_crc.cpp
rename to media/codecs/mp3dec/src/pvmp3_crc.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_crc.h b/media/codecs/mp3dec/src/pvmp3_crc.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_crc.h
rename to media/codecs/mp3dec/src/pvmp3_crc.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_16.cpp b/media/codecs/mp3dec/src/pvmp3_dct_16.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_dct_16.cpp
rename to media/codecs/mp3dec/src/pvmp3_dct_16.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_16.h b/media/codecs/mp3dec/src/pvmp3_dct_16.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_dct_16.h
rename to media/codecs/mp3dec/src/pvmp3_dct_16.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_6.cpp b/media/codecs/mp3dec/src/pvmp3_dct_6.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_dct_6.cpp
rename to media/codecs/mp3dec/src/pvmp3_dct_6.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_9.cpp b/media/codecs/mp3dec/src/pvmp3_dct_9.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_dct_9.cpp
rename to media/codecs/mp3dec/src/pvmp3_dct_9.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_dec_defs.h b/media/codecs/mp3dec/src/pvmp3_dec_defs.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_dec_defs.h
rename to media/codecs/mp3dec/src/pvmp3_dec_defs.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp b/media/codecs/mp3dec/src/pvmp3_decode_header.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
rename to media/codecs/mp3dec/src/pvmp3_decode_header.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.h b/media/codecs/mp3dec/src/pvmp3_decode_header.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.h
rename to media/codecs/mp3dec/src/pvmp3_decode_header.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp b/media/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp
rename to media/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_huff_cw.h b/media/codecs/mp3dec/src/pvmp3_decode_huff_cw.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_decode_huff_cw.h
rename to media/codecs/mp3dec/src/pvmp3_decode_huff_cw.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp b/media/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp
rename to media/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_dequantize_sample.h b/media/codecs/mp3dec/src/pvmp3_dequantize_sample.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_dequantize_sample.h
rename to media/codecs/mp3dec/src/pvmp3_dequantize_sample.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_equalizer.cpp b/media/codecs/mp3dec/src/pvmp3_equalizer.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_equalizer.cpp
rename to media/codecs/mp3dec/src/pvmp3_equalizer.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_equalizer.h b/media/codecs/mp3dec/src/pvmp3_equalizer.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_equalizer.h
rename to media/codecs/mp3dec/src/pvmp3_equalizer.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp b/media/codecs/mp3dec/src/pvmp3_framedecoder.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp
rename to media/codecs/mp3dec/src/pvmp3_framedecoder.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.h b/media/codecs/mp3dec/src/pvmp3_framedecoder.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.h
rename to media/codecs/mp3dec/src/pvmp3_framedecoder.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp b/media/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp
rename to media/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_main_data_size.h b/media/codecs/mp3dec/src/pvmp3_get_main_data_size.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_get_main_data_size.h
rename to media/codecs/mp3dec/src/pvmp3_get_main_data_size.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp b/media/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp
rename to media/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_scale_factors.h b/media/codecs/mp3dec/src/pvmp3_get_scale_factors.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_get_scale_factors.h
rename to media/codecs/mp3dec/src/pvmp3_get_scale_factors.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp b/media/codecs/mp3dec/src/pvmp3_get_side_info.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp
rename to media/codecs/mp3dec/src/pvmp3_get_side_info.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.h b/media/codecs/mp3dec/src/pvmp3_get_side_info.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.h
rename to media/codecs/mp3dec/src/pvmp3_get_side_info.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.cpp b/media/codecs/mp3dec/src/pvmp3_getbits.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.cpp
rename to media/codecs/mp3dec/src/pvmp3_getbits.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.h b/media/codecs/mp3dec/src/pvmp3_getbits.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.h
rename to media/codecs/mp3dec/src/pvmp3_getbits.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp b/media/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp
rename to media/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp b/media/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp
rename to media/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_imdct_synth.cpp b/media/codecs/mp3dec/src/pvmp3_imdct_synth.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_imdct_synth.cpp
rename to media/codecs/mp3dec/src/pvmp3_imdct_synth.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_imdct_synth.h b/media/codecs/mp3dec/src/pvmp3_imdct_synth.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_imdct_synth.h
rename to media/codecs/mp3dec/src/pvmp3_imdct_synth.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_18.cpp b/media/codecs/mp3dec/src/pvmp3_mdct_18.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_18.cpp
rename to media/codecs/mp3dec/src/pvmp3_mdct_18.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_18.h b/media/codecs/mp3dec/src/pvmp3_mdct_18.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_18.h
rename to media/codecs/mp3dec/src/pvmp3_mdct_18.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.cpp b/media/codecs/mp3dec/src/pvmp3_mdct_6.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.cpp
rename to media/codecs/mp3dec/src/pvmp3_mdct_6.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.h b/media/codecs/mp3dec/src/pvmp3_mdct_6.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_mdct_6.h
rename to media/codecs/mp3dec/src/pvmp3_mdct_6.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp b/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
rename to media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h b/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h
rename to media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp b/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp
rename to media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h b/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h
rename to media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp b/media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp
rename to media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h b/media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h
rename to media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_normalize.cpp b/media/codecs/mp3dec/src/pvmp3_normalize.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_normalize.cpp
rename to media/codecs/mp3dec/src/pvmp3_normalize.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_normalize.h b/media/codecs/mp3dec/src/pvmp3_normalize.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_normalize.h
rename to media/codecs/mp3dec/src/pvmp3_normalize.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp b/media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp
rename to media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h b/media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h
rename to media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp b/media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp
rename to media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h b/media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h
rename to media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_reorder.cpp b/media/codecs/mp3dec/src/pvmp3_reorder.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_reorder.cpp
rename to media/codecs/mp3dec/src/pvmp3_reorder.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_reorder.h b/media/codecs/mp3dec/src/pvmp3_reorder.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_reorder.h
rename to media/codecs/mp3dec/src/pvmp3_reorder.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_seek_synch.cpp b/media/codecs/mp3dec/src/pvmp3_seek_synch.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_seek_synch.cpp
rename to media/codecs/mp3dec/src/pvmp3_seek_synch.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_seek_synch.h b/media/codecs/mp3dec/src/pvmp3_seek_synch.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_seek_synch.h
rename to media/codecs/mp3dec/src/pvmp3_seek_synch.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_stereo_proc.cpp b/media/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
rename to media/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_stereo_proc.h b/media/codecs/mp3dec/src/pvmp3_stereo_proc.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_stereo_proc.h
rename to media/codecs/mp3dec/src/pvmp3_stereo_proc.h
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_tables.cpp b/media/codecs/mp3dec/src/pvmp3_tables.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_tables.cpp
rename to media/codecs/mp3dec/src/pvmp3_tables.cpp
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_tables.h b/media/codecs/mp3dec/src/pvmp3_tables.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/pvmp3_tables.h
rename to media/codecs/mp3dec/src/pvmp3_tables.h
diff --git a/media/libstagefright/codecs/mp3dec/src/s_huffcodetab.h b/media/codecs/mp3dec/src/s_huffcodetab.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/s_huffcodetab.h
rename to media/codecs/mp3dec/src/s_huffcodetab.h
diff --git a/media/libstagefright/codecs/mp3dec/src/s_mp3bits.h b/media/codecs/mp3dec/src/s_mp3bits.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/s_mp3bits.h
rename to media/codecs/mp3dec/src/s_mp3bits.h
diff --git a/media/libstagefright/codecs/mp3dec/src/s_tmp3dec_chan.h b/media/codecs/mp3dec/src/s_tmp3dec_chan.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/s_tmp3dec_chan.h
rename to media/codecs/mp3dec/src/s_tmp3dec_chan.h
diff --git a/media/libstagefright/codecs/mp3dec/src/s_tmp3dec_file.h b/media/codecs/mp3dec/src/s_tmp3dec_file.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/src/s_tmp3dec_file.h
rename to media/codecs/mp3dec/src/s_tmp3dec_file.h
diff --git a/media/libstagefright/codecs/mp3dec/test/Android.bp b/media/codecs/mp3dec/test/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/test/Android.bp
rename to media/codecs/mp3dec/test/Android.bp
diff --git a/media/libstagefright/codecs/mp3dec/test/AndroidTest.xml b/media/codecs/mp3dec/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/test/AndroidTest.xml
rename to media/codecs/mp3dec/test/AndroidTest.xml
diff --git a/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp b/media/codecs/mp3dec/test/Mp3DecoderTest.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/test/Mp3DecoderTest.cpp
rename to media/codecs/mp3dec/test/Mp3DecoderTest.cpp
diff --git a/media/libstagefright/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h b/media/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h
rename to media/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h
diff --git a/media/libstagefright/codecs/mp3dec/test/README.md b/media/codecs/mp3dec/test/README.md
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/test/README.md
rename to media/codecs/mp3dec/test/README.md
diff --git a/media/libstagefright/codecs/mp3dec/test/mp3dec_test.cpp b/media/codecs/mp3dec/test/mp3dec_test.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/test/mp3dec_test.cpp
rename to media/codecs/mp3dec/test/mp3dec_test.cpp
diff --git a/media/libstagefright/codecs/mp3dec/test/mp3reader.cpp b/media/codecs/mp3dec/test/mp3reader.cpp
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/test/mp3reader.cpp
rename to media/codecs/mp3dec/test/mp3reader.cpp
diff --git a/media/libstagefright/codecs/mp3dec/test/mp3reader.h b/media/codecs/mp3dec/test/mp3reader.h
similarity index 100%
rename from media/libstagefright/codecs/mp3dec/test/mp3reader.h
rename to media/codecs/mp3dec/test/mp3reader.h
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp
index 0617e88..ec7cb24 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/extractors/flac/FLACExtractor.cpp
@@ -561,6 +561,8 @@
         AMediaFormat_setString(mFileMetadata,
                 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_FLAC);
     }
+    mMaxBufferSize = getMaxBlockSize() * getChannels() * getOutputSampleSize();
+    AMediaFormat_setInt32(mTrackMetadata, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, mMaxBufferSize);
     return OK;
 }
 
@@ -568,8 +570,6 @@
 {
     CHECK(mGroup == NULL);
     mGroup = group;
-    mMaxBufferSize = getMaxBlockSize() * getChannels() * getOutputSampleSize();
-    AMediaFormat_setInt32(mTrackMetadata, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, mMaxBufferSize);
     mGroup->add_buffer(mMaxBufferSize);
 }
 
diff --git a/media/extractors/mp4/ItemTable.cpp b/media/extractors/mp4/ItemTable.cpp
index 0b1cfa0..ded3d1a 100644
--- a/media/extractors/mp4/ItemTable.cpp
+++ b/media/extractors/mp4/ItemTable.cpp
@@ -1582,15 +1582,24 @@
         ssize_t thumbItemIndex = mItemIdToItemMap.indexOfKey(image->thumbnails[0]);
         if (thumbItemIndex >= 0) {
             const ImageItem &thumbnail = mItemIdToItemMap[thumbItemIndex];
-            // TODO(vigneshv): Handle thumbnail for AVIF.
-            if (thumbnail.hvcc != NULL) {
+            if (thumbnail.hvcc != NULL || thumbnail.av1c != NULL) {
                 AMediaFormat_setInt32(meta,
                         AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH, thumbnail.width);
                 AMediaFormat_setInt32(meta,
                         AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT, thumbnail.height);
-                AMediaFormat_setBuffer(meta,
-                        AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC,
-                        thumbnail.hvcc->data(), thumbnail.hvcc->size());
+                if (thumbnail.hvcc != NULL) {
+                    AMediaFormat_setBuffer(meta,
+                            AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC,
+                            thumbnail.hvcc->data(), thumbnail.hvcc->size());
+                } else {
+                    // We use a hard-coded string here instead of
+                    // AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C. The key is available only from SDK 31.
+                    // The mp4 extractor is part of mainline and builds against SDK 29 as of
+                    // writing. This hard-coded string can be replaced with the named constant once
+                    // the mp4 extractor is built against SDK >= 31.
+                    AMediaFormat_setBuffer(meta,
+                            "thumbnail-csd-av1c", thumbnail.av1c->data(), thumbnail.av1c->size());
+                }
                 ALOGV("image[%u]: thumbnail: size %dx%d, item index %zd",
                         imageIndex, thumbnail.width, thumbnail.height, thumbItemIndex);
             } else {
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index cd70869..7989d4b 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -203,8 +203,8 @@
         uint32_t duration;
         int32_t compositionOffset;
         uint8_t iv[16];
-        Vector<size_t> clearsizes;
-        Vector<size_t> encryptedsizes;
+        Vector<uint32_t> clearsizes;
+        Vector<uint32_t> encryptedsizes;
     };
     Vector<Sample> mCurrentSamples;
     std::map<off64_t, uint32_t> mDrmOffsets;
@@ -6556,9 +6556,9 @@
     if (smpl->encryptedsizes.size()) {
         // store clear/encrypted lengths in metadata
         AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
-                smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
+                smpl->clearsizes.array(), smpl->clearsizes.size() * sizeof(uint32_t));
         AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
-                smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
+                smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * sizeof(uint32_t));
         AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, mDefaultIVSize);
         AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, mCryptoMode);
         AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, mCryptoKey, 16);
diff --git a/media/libaaudio/Android.bp b/media/libaaudio/Android.bp
index e81ab06..7796ed5 100644
--- a/media/libaaudio/Android.bp
+++ b/media/libaaudio/Android.bp
@@ -32,6 +32,6 @@
 cc_library_headers {
     name: "libaaudio_headers",
     export_include_dirs: ["include"],
-    export_header_lib_headers: ["aaudio-aidl-cpp"],
-    header_libs: ["aaudio-aidl-cpp"],
+    export_shared_lib_headers: ["aaudio-aidl-cpp"],
+    shared_libs: ["aaudio-aidl-cpp"],
 }
diff --git a/media/libaaudio/examples/utils/AAudioArgsParser.h b/media/libaaudio/examples/utils/AAudioArgsParser.h
index 4bba436..e670642 100644
--- a/media/libaaudio/examples/utils/AAudioArgsParser.h
+++ b/media/libaaudio/examples/utils/AAudioArgsParser.h
@@ -421,7 +421,9 @@
         printf("      -f{0|1|2} set format\n");
         printf("          0 = UNSPECIFIED\n");
         printf("          1 = PCM_I16\n");
-        printf("          2 = FLOAT\n");
+        printf("          2 = PCM_FLOAT\n");
+        printf("          3 = PCM_I24_PACKED\n");
+        printf("          4 = PCM_I32\n");
         printf("      -i{inputPreset} eg. 5 for AAUDIO_INPUT_PRESET_CAMCORDER\n");
         printf("      -m{0|1|2|3} set MMAP policy\n");
         printf("          0 = _UNSPECIFIED, use aaudio.mmap_policy system property, default\n");
diff --git a/media/libaaudio/examples/utils/AAudioExampleUtils.h b/media/libaaudio/examples/utils/AAudioExampleUtils.h
index 46b8895..5819dfd 100644
--- a/media/libaaudio/examples/utils/AAudioExampleUtils.h
+++ b/media/libaaudio/examples/utils/AAudioExampleUtils.h
@@ -32,6 +32,7 @@
 #define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000)
 #define NANOS_PER_SECOND      (NANOS_PER_MILLISECOND * 1000)
 
+// Use template functions to avoid warning of unused static functions.
 template <class T = aaudio_sharing_mode_t>
 const char *getSharingModeText(aaudio_sharing_mode_t mode) {
     const char *text = "unknown";
@@ -48,6 +49,7 @@
     return text;
 }
 
+template <class T = aaudio_performance_mode_t>
 const char *getPerformanceModeText(aaudio_performance_mode_t mode) {
     const char *text = "unknown";
     switch (mode) {
@@ -66,6 +68,7 @@
     return text;
 }
 
+template <class T = aaudio_direction_t>
 const char *getDirectionText(aaudio_direction_t direction) {
     const char *text = "unknown";
     switch (direction) {
@@ -81,6 +84,29 @@
     return text;
 }
 
+template <class T = aaudio_direction_t>
+constexpr int32_t getBytesPerSample(aaudio_format_t format) {
+    switch (format) {
+        case AAUDIO_FORMAT_PCM_I16:
+            return 2;
+        case AAUDIO_FORMAT_PCM_FLOAT:
+            return 4;
+        case AAUDIO_FORMAT_PCM_I24_PACKED:
+            return 3;
+        case AAUDIO_FORMAT_PCM_I32:
+            return 4;
+        default:
+            return -1;
+    }
+}
+
+// Return true if CPU is native Little Endian
+inline bool isNativeLittleEndian() {
+    // If the first byte of the data word in memory is 1 then Little Endian.
+    constexpr union { unsigned u; unsigned char c[sizeof(unsigned)]; } one = {1};
+    return one.c[0] != 0;
+}
+
 template <class T = int64_t>
 void convertNanosecondsToTimespec(int64_t nanoseconds, struct timespec *time) {
     time->tv_sec = nanoseconds / NANOS_PER_SECOND;
diff --git a/media/libaaudio/examples/utils/AAudioSimplePlayer.h b/media/libaaudio/examples/utils/AAudioSimplePlayer.h
index fd1fc45..7daac20 100644
--- a/media/libaaudio/examples/utils/AAudioSimplePlayer.h
+++ b/media/libaaudio/examples/utils/AAudioSimplePlayer.h
@@ -359,22 +359,38 @@
 
     int32_t samplesPerFrame = AAudioStream_getChannelCount(stream);
 
-
-    int numActiveOscilators = (samplesPerFrame > MAX_CHANNELS) ? MAX_CHANNELS : samplesPerFrame;
+    int numActiveOscillators = std::min(samplesPerFrame, MAX_CHANNELS);
     switch (AAudioStream_getFormat(stream)) {
         case AAUDIO_FORMAT_PCM_I16: {
             int16_t *audioBuffer = (int16_t *) audioData;
-            for (int i = 0; i < numActiveOscilators; ++i) {
-                sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame,
-                                                    numFrames);
+            for (int i = 0; i < numActiveOscillators; ++i) {
+                sineData->sineOscillators[i].render(&audioBuffer[i],
+                                                    samplesPerFrame, numFrames);
             }
         }
             break;
         case AAUDIO_FORMAT_PCM_FLOAT: {
             float *audioBuffer = (float *) audioData;
-            for (int i = 0; i < numActiveOscilators; ++i) {
-                sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame,
-                                                    numFrames);
+            for (int i = 0; i < numActiveOscillators; ++i) {
+                sineData->sineOscillators[i].render(&audioBuffer[i],
+                                                    samplesPerFrame, numFrames);
+            }
+        }
+            break;
+        case AAUDIO_FORMAT_PCM_I24_PACKED: {
+            uint8_t *audioBuffer = (uint8_t *) audioData;
+            for (int i = 0; i < numActiveOscillators; ++i) {
+                static const int bytesPerSample = getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED);
+                sineData->sineOscillators[i].render24(&audioBuffer[i * bytesPerSample],
+                                                      samplesPerFrame, numFrames);
+            }
+        }
+            break;
+        case AAUDIO_FORMAT_PCM_I32: {
+            int32_t *audioBuffer = (int32_t *) audioData;
+            for (int i = 0; i < numActiveOscillators; ++i) {
+                sineData->sineOscillators[i].render(&audioBuffer[i],
+                                                    samplesPerFrame, numFrames);
             }
         }
             break;
diff --git a/media/libaaudio/examples/utils/SineGenerator.h b/media/libaaudio/examples/utils/SineGenerator.h
index 9e6d46d..66a08fd 100644
--- a/media/libaaudio/examples/utils/SineGenerator.h
+++ b/media/libaaudio/examples/utils/SineGenerator.h
@@ -41,20 +41,54 @@
         }
     }
 
+    float next() {
+        float value = sinf(mPhase) * mAmplitude;
+        advancePhase();
+        return value;
+    }
+
     void render(int16_t *buffer, int32_t channelStride, int32_t numFrames) {
         int sampleIndex = 0;
         for (int i = 0; i < numFrames; i++) {
-            buffer[sampleIndex] = (int16_t) (INT16_MAX * sin(mPhase) * mAmplitude);
+            buffer[sampleIndex] = (int16_t) (INT16_MAX * next());
             sampleIndex += channelStride;
-            advancePhase();
         }
     }
+
     void render(float *buffer, int32_t channelStride, int32_t numFrames) {
         int sampleIndex = 0;
         for (int i = 0; i < numFrames; i++) {
-            buffer[sampleIndex] = sin(mPhase) * mAmplitude;
+            buffer[sampleIndex] = next();
             sampleIndex += channelStride;
-            advancePhase();
+        }
+    }
+
+    void render(int32_t *buffer, int32_t channelStride, int32_t numFrames) {
+        int sampleIndex = 0;
+        for (int i = 0; i < numFrames; i++) {
+            buffer[sampleIndex] = (int32_t) (INT32_MAX * next());
+            sampleIndex += channelStride;
+        }
+    }
+
+    void render24(uint8_t *buffer, int32_t channelStride, int32_t numFrames) {
+        int sampleIndex = 0;
+        constexpr int32_t INT24_MAX = (1 << 23) - 1;
+        constexpr int bytesPerSample = getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED);
+        const bool isLittleEndian = isNativeLittleEndian();
+        for (int i = 0; i < numFrames; i++) {
+            int32_t sample = (int32_t) (INT24_MAX * next());
+            uint32_t usample = (uint32_t) sample;
+            if (isLittleEndian) {
+                buffer[sampleIndex] = usample; // little end first
+                buffer[sampleIndex + 1] = usample >> 8;
+                buffer[sampleIndex + 2] = usample >> 16;
+            } else {
+                buffer[sampleIndex] = usample >> 16; // big end first
+                buffer[sampleIndex + 1] = usample >> 8;
+                buffer[sampleIndex + 2] = usample;
+            }
+            sampleIndex += channelStride * bytesPerSample;
         }
     }
 
@@ -100,4 +134,3 @@
 };
 
 #endif /* SINE_GENERATOR_H */
-
diff --git a/media/libaaudio/examples/write_sine/src/write_sine.cpp b/media/libaaudio/examples/write_sine/src/write_sine.cpp
index 8e33a31..33d07f0 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine.cpp
@@ -47,9 +47,11 @@
     int32_t  framesToPlay = 0;
     int32_t  framesLeft = 0;
     int32_t  xRunCount = 0;
-    int      numActiveOscilators = 0;
+    int      numActiveOscillators = 0;
     float   *floatData = nullptr;
     int16_t *shortData = nullptr;
+    int32_t *int32Data = nullptr;
+    uint8_t *byteData = nullptr;
 
     int      testFd = -1;
 
@@ -57,7 +59,7 @@
     // in a buffer if we hang or crash.
     setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
 
-    printf("%s - Play a sine wave using AAudio V0.1.3\n", argv[0]);
+    printf("%s - Play a sine wave using AAudio V0.1.4\n", argv[0]);
 
     if (argParser.parseArgs(argc, argv)) {
         return EXIT_FAILURE;
@@ -91,13 +93,23 @@
     printf("Buffer: framesPerWrite = %d\n",framesPerWrite);
 
     // Allocate a buffer for the audio data.
-    if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) {
-        floatData = new float[framesPerWrite * actualChannelCount];
-    } else if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) {
-        shortData = new int16_t[framesPerWrite * actualChannelCount];
-    } else {
-        printf("ERROR Unsupported data format!\n");
-        goto finish;
+    switch (actualDataFormat) {
+        case AAUDIO_FORMAT_PCM_FLOAT:
+            floatData = new float[framesPerWrite * actualChannelCount];
+            break;
+        case AAUDIO_FORMAT_PCM_I16:
+            shortData = new int16_t[framesPerWrite * actualChannelCount];
+            break;
+        case AAUDIO_FORMAT_PCM_I24_PACKED:
+            byteData = new uint8_t[framesPerWrite * actualChannelCount
+                                   * getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED)];
+            break;
+        case AAUDIO_FORMAT_PCM_I32:
+            int32Data = new int32_t[framesPerWrite * actualChannelCount];
+            break;
+        default:
+            printf("ERROR Unsupported data format!\n");
+            goto finish;
     }
 
     testFd = open("/data/aaudio_temp.raw", O_CREAT | O_RDWR, S_IRWXU);
@@ -117,29 +129,56 @@
     // Play for a while.
     framesToPlay = actualSampleRate * argParser.getDurationSeconds();
     framesLeft = framesToPlay;
-    numActiveOscilators = (actualChannelCount > MAX_CHANNELS) ? MAX_CHANNELS : actualChannelCount;
+    numActiveOscillators = (actualChannelCount > MAX_CHANNELS) ? MAX_CHANNELS : actualChannelCount;
     while (framesLeft > 0) {
         // Render as FLOAT or PCM
-        if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) {
-            for (int i = 0; i < numActiveOscilators; ++i) {
-                myData.sineOscillators[i].render(&floatData[i], actualChannelCount,
-                                                  framesPerWrite);
-            }
-        } else if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) {
-            for (int i = 0; i < numActiveOscilators; ++i) {
-                myData.sineOscillators[i].render(&shortData[i], actualChannelCount,
-                                                  framesPerWrite);
-            }
+        switch (actualDataFormat) {
+            case AAUDIO_FORMAT_PCM_FLOAT:
+                for (int i = 0; i < numActiveOscillators; ++i) {
+                    myData.sineOscillators[i].render(&floatData[i], actualChannelCount,
+                                                     framesPerWrite);
+                }
+                break;
+            case AAUDIO_FORMAT_PCM_I16:
+                for (int i = 0; i < numActiveOscillators; ++i) {
+                    myData.sineOscillators[i].render(&shortData[i], actualChannelCount,
+                                                     framesPerWrite);
+                }
+                break;
+            case AAUDIO_FORMAT_PCM_I32:
+                for (int i = 0; i < numActiveOscillators; ++i) {
+                    myData.sineOscillators[i].render(&int32Data[i], actualChannelCount,
+                                                     framesPerWrite);
+                }
+                break;
+            case AAUDIO_FORMAT_PCM_I24_PACKED:
+                for (int i = 0; i < numActiveOscillators; ++i) {
+                    static const int
+                        bytesPerSample = getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED);
+                    myData.sineOscillators[i].render24(&byteData[i * bytesPerSample],
+                                                       actualChannelCount,
+                                                       framesPerWrite);
+                }
+                break;
         }
 
         // Write audio data to the stream.
         int64_t timeoutNanos = 1000 * NANOS_PER_MILLISECOND;
         int32_t minFrames = (framesToPlay < framesPerWrite) ? framesToPlay : framesPerWrite;
         int32_t actual = 0;
-        if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) {
-            actual = AAudioStream_write(aaudioStream, floatData, minFrames, timeoutNanos);
-        } else if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) {
-            actual = AAudioStream_write(aaudioStream, shortData, minFrames, timeoutNanos);
+        switch (actualDataFormat) {
+            case AAUDIO_FORMAT_PCM_FLOAT:
+                actual = AAudioStream_write(aaudioStream, floatData, minFrames, timeoutNanos);
+                break;
+            case AAUDIO_FORMAT_PCM_I16:
+                actual = AAudioStream_write(aaudioStream, shortData, minFrames, timeoutNanos);
+                break;
+            case AAUDIO_FORMAT_PCM_I32:
+                actual = AAudioStream_write(aaudioStream, int32Data, minFrames, timeoutNanos);
+                break;
+            case AAUDIO_FORMAT_PCM_I24_PACKED:
+                actual = AAudioStream_write(aaudioStream, byteData, minFrames, timeoutNanos);
+                break;
         }
         if (actual < 0) {
             fprintf(stderr, "ERROR - AAudioStream_write() returned %d\n", actual);
@@ -196,6 +235,8 @@
 
     delete[] floatData;
     delete[] shortData;
+    delete[] int32Data;
+    delete[] byteData;
     printf("exiting - AAudio result = %d = %s\n", result, AAudio_convertResultToText(result));
     return (result != AAUDIO_OK) ? EXIT_FAILURE : EXIT_SUCCESS;
 }
diff --git a/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp b/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp
index ca60233..cdc987b 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp
@@ -31,7 +31,7 @@
 #include "AAudioSimplePlayer.h"
 #include "AAudioArgsParser.h"
 
-#define APP_VERSION  "0.1.7"
+#define APP_VERSION  "0.1.8"
 
 constexpr int32_t kDefaultHangTimeMSec = 10;
 
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 6666788..ea4fe04 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -65,7 +65,7 @@
 
     /**
      * This format uses the int16_t data type.
-     * The maximum range of the data is -32768 to 32767.
+     * The maximum range of the data is -32768 (0x8000) to 32767 (0x7FFF).
      */
     AAUDIO_FORMAT_PCM_I16,
 
@@ -77,7 +77,31 @@
      * See also 'floatData' at
      * https://developer.android.com/reference/android/media/AudioTrack#write(float[],%20int,%20int,%20int)
      */
-    AAUDIO_FORMAT_PCM_FLOAT
+    AAUDIO_FORMAT_PCM_FLOAT,
+
+    /**
+     * This format uses 24-bit samples packed into 3 bytes.
+     * The bytes are in the native endian order.
+     * The maximum range of the data is -8388608 (0x800000)
+     * to 8388607 (0x7FFFFF).
+     *
+     * Note that the lower precision bits may be ignored by the device.
+     *
+     * Available since API level 31.
+     */
+    AAUDIO_FORMAT_PCM_I24_PACKED,
+
+    /**
+     * This format uses 32-bit samples stored in an int32_t data type.
+     * The maximum range of the data is -2147483648 (0x80000000)
+     * to 2147483647 (0x7FFFFFFF).
+     *
+     * Note that the lower precision bits may be ignored by the device.
+     *
+     * Available since API level 31.
+     */
+    AAUDIO_FORMAT_PCM_I32
+
 };
 typedef int32_t aaudio_format_t;
 
@@ -896,8 +920,9 @@
  * It will stop being called after AAudioStream_requestPause() or
  * AAudioStream_requestStop() is called.
  *
- * This callback function will be called on a real-time thread owned by AAudio. See
- * {@link #AAudioStream_dataCallback} for more information.
+ * This callback function will be called on a real-time thread owned by AAudio.
+ * The low latency streams may have callback threads with higher priority than normal streams.
+ * See {@link #AAudioStream_dataCallback} for more information.
  *
  * Note that the AAudio callbacks will never be called simultaneously from multiple threads.
  *
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index aafcccc..d02d1b6 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -130,9 +130,11 @@
         "flowgraph/SinkFloat.cpp",
         "flowgraph/SinkI16.cpp",
         "flowgraph/SinkI24.cpp",
+        "flowgraph/SinkI32.cpp",
         "flowgraph/SourceFloat.cpp",
         "flowgraph/SourceI16.cpp",
         "flowgraph/SourceI24.cpp",
+        "flowgraph/SourceI32.cpp",
     ],
     sanitize: {
         integer_overflow: true,
diff --git a/media/libaaudio/src/binding/AAudioBinderAdapter.cpp b/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
index 2b2fe6d..6e3a1c8 100644
--- a/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
+++ b/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
@@ -15,10 +15,12 @@
  */
 
 #include <binding/AAudioBinderAdapter.h>
+#include <media/AidlConversionUtil.h>
 #include <utility/AAudioUtilities.h>
 
 namespace aaudio {
 
+using android::aidl_utils::statusTFromBinderStatus;
 using android::binder::Status;
 
 AAudioBinderAdapter::AAudioBinderAdapter(IAAudioService* delegate)
@@ -36,7 +38,7 @@
                                           &params,
                                           &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     config = params;
     return result;
@@ -46,7 +48,7 @@
     aaudio_result_t result;
     Status status = mDelegate->closeStream(streamHandle, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -59,7 +61,7 @@
                                                     &endpoint,
                                                     &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     endpointOut = std::move(endpoint);
     return result;
@@ -69,7 +71,7 @@
     aaudio_result_t result;
     Status status = mDelegate->startStream(streamHandle, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -78,7 +80,7 @@
     aaudio_result_t result;
     Status status = mDelegate->pauseStream(streamHandle, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -87,7 +89,7 @@
     aaudio_result_t result;
     Status status = mDelegate->stopStream(streamHandle, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -96,7 +98,7 @@
     aaudio_result_t result;
     Status status = mDelegate->flushStream(streamHandle, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -107,7 +109,7 @@
     aaudio_result_t result;
     Status status = mDelegate->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
@@ -117,7 +119,7 @@
     aaudio_result_t result;
     Status status = mDelegate->unregisterAudioThread(streamHandle, clientThreadId, &result);
     if (!status.isOk()) {
-        result = AAudioConvert_androidToAAudioResult(status.transactionError());
+        result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
     }
     return result;
 }
diff --git a/media/libaaudio/src/client/AAudioFlowGraph.cpp b/media/libaaudio/src/client/AAudioFlowGraph.cpp
index 8f2c488..61b50f3 100644
--- a/media/libaaudio/src/client/AAudioFlowGraph.cpp
+++ b/media/libaaudio/src/client/AAudioFlowGraph.cpp
@@ -26,9 +26,11 @@
 #include <flowgraph/SinkFloat.h>
 #include <flowgraph/SinkI16.h>
 #include <flowgraph/SinkI24.h>
+#include <flowgraph/SinkI32.h>
 #include <flowgraph/SourceFloat.h>
 #include <flowgraph/SourceI16.h>
 #include <flowgraph/SourceI24.h>
+#include <flowgraph/SourceI32.h>
 
 using namespace flowgraph;
 
@@ -38,7 +40,8 @@
                           int32_t sinkChannelCount) {
     AudioFloatOutputPort *lastOutput = nullptr;
 
-    ALOGV("%s() source format = 0x%08x, channels = %d, sink format = 0x%08x, channels = %d",
+    // TODO change back to ALOGD
+    ALOGI("%s() source format = 0x%08x, channels = %d, sink format = 0x%08x, channels = %d",
           __func__, sourceFormat, sourceChannelCount, sinkFormat, sinkChannelCount);
 
     switch (sourceFormat) {
@@ -51,7 +54,10 @@
         case AUDIO_FORMAT_PCM_24_BIT_PACKED:
             mSource = std::make_unique<SourceI24>(sourceChannelCount);
             break;
-        default: // TODO add I32
+        case AUDIO_FORMAT_PCM_32_BIT:
+            mSource = std::make_unique<SourceI32>(sourceChannelCount);
+            break;
+        default:
             ALOGE("%s() Unsupported source format = %d", __func__, sourceFormat);
             return AAUDIO_ERROR_UNIMPLEMENTED;
     }
@@ -90,7 +96,10 @@
         case AUDIO_FORMAT_PCM_24_BIT_PACKED:
             mSink = std::make_unique<SinkI24>(sinkChannelCount);
             break;
-        default: // TODO add I32
+        case AUDIO_FORMAT_PCM_32_BIT:
+            mSink = std::make_unique<SinkI32>(sinkChannelCount);
+            break;
+        default:
             ALOGE("%s() Unsupported sink format = %d", __func__, sinkFormat);
             return AAUDIO_ERROR_UNIMPLEMENTED;
     }
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 809c76e..2815c6a 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -104,7 +104,7 @@
     if (getFormat() == AUDIO_FORMAT_DEFAULT) {
         setFormat(AUDIO_FORMAT_PCM_FLOAT);
     }
-    // Request FLOAT for the shared mixer.
+    // Request FLOAT for the shared mixer or the device.
     request.getConfiguration().setFormat(AUDIO_FORMAT_PCM_FLOAT);
 
     // Build the request to send to the server.
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index 5f45261..2c81c91 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -54,7 +54,9 @@
     switch (format) {
         case AUDIO_FORMAT_DEFAULT:
         case AUDIO_FORMAT_PCM_16_BIT:
+        case AUDIO_FORMAT_PCM_32_BIT:
         case AUDIO_FORMAT_PCM_FLOAT:
+        case AUDIO_FORMAT_PCM_24_BIT_PACKED:
             break; // valid
         default:
             ALOGD("audioFormat not valid, audio_format_t = 0x%08x", format);
diff --git a/media/libaaudio/src/core/AudioGlobal.cpp b/media/libaaudio/src/core/AudioGlobal.cpp
index 7f5d8d5..0e5b8be 100644
--- a/media/libaaudio/src/core/AudioGlobal.cpp
+++ b/media/libaaudio/src/core/AudioGlobal.cpp
@@ -80,6 +80,8 @@
         AAUDIO_CASE_ENUM(AAUDIO_FORMAT_INVALID);
         AAUDIO_CASE_ENUM(AAUDIO_FORMAT_PCM_I16);
         AAUDIO_CASE_ENUM(AAUDIO_FORMAT_PCM_FLOAT);
+        AAUDIO_CASE_ENUM(AAUDIO_FORMAT_PCM_I24_PACKED);
+        AAUDIO_CASE_ENUM(AAUDIO_FORMAT_PCM_I32);
     }
     return "Unrecognized";
 }
diff --git a/media/libaaudio/src/flowgraph/FlowgraphUtilities.h b/media/libaaudio/src/flowgraph/FlowgraphUtilities.h
new file mode 100644
index 0000000..b750410
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/FlowgraphUtilities.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#ifndef FLOWGRAPH_UTILITIES_H
+#define FLOWGRAPH_UTILITIES_H
+
+#include <unistd.h>
+
+using namespace flowgraph;
+
+class FlowgraphUtilities {
+public:
+// This was copied from audio_utils/primitives.h
+/**
+ * Convert a single-precision floating point value to a Q0.31 integer value.
+ * Rounds to nearest, ties away from 0.
+ *
+ * Values outside the range [-1.0, 1.0) are properly clamped to -2147483648 and 2147483647,
+ * including -Inf and +Inf. NaN values are considered undefined, and behavior may change
+ * depending on hardware and future implementation of this function.
+ */
+static int32_t clamp32FromFloat(float f)
+{
+    static const float scale = (float)(1UL << 31);
+    static const float limpos = 1.;
+    static const float limneg = -1.;
+
+    if (f <= limneg) {
+        return -0x80000000; /* or 0x80000000 */
+    } else if (f >= limpos) {
+        return 0x7fffffff;
+    }
+    f *= scale;
+    /* integer conversion is through truncation (though int to float is not).
+     * ensure that we round to nearest, ties away from 0.
+     */
+    return f > 0 ? f + 0.5 : f - 0.5;
+}
+
+};
+
+#endif // FLOWGRAPH_UTILITIES_H
diff --git a/media/libaaudio/src/flowgraph/SinkI24.cpp b/media/libaaudio/src/flowgraph/SinkI24.cpp
index 6592828..0cb077d 100644
--- a/media/libaaudio/src/flowgraph/SinkI24.cpp
+++ b/media/libaaudio/src/flowgraph/SinkI24.cpp
@@ -15,7 +15,7 @@
  */
 
 #include <algorithm>
-#include <unistd.h>
+#include <stdint.h>
 
 #ifdef __ANDROID__
 #include <audio_utils/primitives.h>
@@ -26,7 +26,6 @@
 
 using namespace flowgraph;
 
-
 SinkI24::SinkI24(int32_t channelCount)
         : AudioSink(channelCount) {}
 
diff --git a/media/libaaudio/src/flowgraph/SinkI32.cpp b/media/libaaudio/src/flowgraph/SinkI32.cpp
new file mode 100644
index 0000000..eab863d
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SinkI32.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#ifdef __ANDROID__
+#include <audio_utils/primitives.h>
+#endif
+
+#include "AudioProcessorBase.h"
+#include "FlowgraphUtilities.h"
+#include "SinkI32.h"
+
+using namespace flowgraph;
+
+SinkI32::SinkI32(int32_t channelCount)
+        : AudioSink(channelCount) {}
+
+int32_t SinkI32::read(void *data, int32_t numFrames) {
+    int32_t *intData = (int32_t *) data;
+    const int32_t channelCount = input.getSamplesPerFrame();
+
+    int32_t framesLeft = numFrames;
+    while (framesLeft > 0) {
+        // Run the graph and pull data through the input port.
+        int32_t framesRead = pull(framesLeft);
+        if (framesRead <= 0) {
+            break;
+        }
+        const float *signal = input.getBlock();
+        int32_t numSamples = framesRead * channelCount;
+#ifdef __ANDROID__
+        memcpy_to_i32_from_float(intData, signal, numSamples);
+        intData += numSamples;
+        signal += numSamples;
+#else
+        for (int i = 0; i < numSamples; i++) {
+            *intData++ = FlowgraphUtilities::clamp32FromFloat(*signal++);
+        }
+#endif
+        framesLeft -= framesRead;
+    }
+    return numFrames - framesLeft;
+}
diff --git a/media/libaaudio/src/flowgraph/SinkI32.h b/media/libaaudio/src/flowgraph/SinkI32.h
new file mode 100644
index 0000000..09d23b7
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SinkI32.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifndef FLOWGRAPH_SINK_I32_H
+#define FLOWGRAPH_SINK_I32_H
+
+#include <stdint.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+class SinkI32 : public AudioSink {
+public:
+    explicit SinkI32(int32_t channelCount);
+    ~SinkI32() override = default;
+
+    int32_t read(void *data, int32_t numFrames) override;
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_SINK_I32_H
diff --git a/media/libaaudio/src/flowgraph/SourceI24.cpp b/media/libaaudio/src/flowgraph/SourceI24.cpp
index f319880..097954e 100644
--- a/media/libaaudio/src/flowgraph/SourceI24.cpp
+++ b/media/libaaudio/src/flowgraph/SourceI24.cpp
@@ -15,7 +15,7 @@
  */
 
 #include <algorithm>
-#include <unistd.h>
+#include <stdint.h>
 
 #ifdef __ANDROID__
 #include <audio_utils/primitives.h>
diff --git a/media/libaaudio/src/flowgraph/SourceI24.h b/media/libaaudio/src/flowgraph/SourceI24.h
index 39f14da..2ed6f18 100644
--- a/media/libaaudio/src/flowgraph/SourceI24.h
+++ b/media/libaaudio/src/flowgraph/SourceI24.h
@@ -17,8 +17,7 @@
 #ifndef FLOWGRAPH_SOURCE_I24_H
 #define FLOWGRAPH_SOURCE_I24_H
 
-#include <unistd.h>
-#include <sys/types.h>
+#include <stdint.h>
 
 #include "AudioProcessorBase.h"
 
diff --git a/media/libaaudio/src/flowgraph/SourceI32.cpp b/media/libaaudio/src/flowgraph/SourceI32.cpp
new file mode 100644
index 0000000..e8177ad
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SourceI32.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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 <algorithm>
+#include <unistd.h>
+
+#ifdef __ANDROID__
+#include <audio_utils/primitives.h>
+#endif
+
+#include "AudioProcessorBase.h"
+#include "SourceI32.h"
+
+using namespace flowgraph;
+
+SourceI32::SourceI32(int32_t channelCount)
+        : AudioSource(channelCount) {
+}
+
+int32_t SourceI32::onProcess(int64_t framePosition, int32_t numFrames) {
+    float *floatData = output.getBlock();
+    int32_t channelCount = output.getSamplesPerFrame();
+
+    int32_t framesLeft = mSizeInFrames - mFrameIndex;
+    int32_t framesToProcess = std::min(numFrames, framesLeft);
+    int32_t numSamples = framesToProcess * channelCount;
+
+    const int32_t *intBase = static_cast<const int32_t *>(mData);
+    const int32_t *intData = &intBase[mFrameIndex * channelCount];
+
+#ifdef __ANDROID__
+    memcpy_to_float_from_i32(floatData, intData, numSamples);
+#else
+    for (int i = 0; i < numSamples; i++) {
+        *floatData++ = *intData++ * kScale;
+    }
+#endif
+
+    mFrameIndex += framesToProcess;
+    return framesToProcess;
+}
diff --git a/media/libaaudio/src/flowgraph/SourceI32.h b/media/libaaudio/src/flowgraph/SourceI32.h
new file mode 100644
index 0000000..e50f9be
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/SourceI32.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef FLOWGRAPH_SOURCE_I32_H
+#define FLOWGRAPH_SOURCE_I32_H
+
+#include <stdint.h>
+
+#include "AudioProcessorBase.h"
+
+namespace flowgraph {
+
+class SourceI32 : public AudioSource {
+public:
+    explicit SourceI32(int32_t channelCount);
+    ~SourceI32() override = default;
+
+    int32_t onProcess(int64_t framePosition, int32_t numFrames) override;
+
+private:
+    static constexpr float kScale = 1.0 / (1UL << 31);
+};
+
+} /* namespace flowgraph */
+
+#endif //FLOWGRAPH_SOURCE_I32_H
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 1d036d0..af8ff19 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -558,7 +558,7 @@
         if (status < 0) { // a non-negative value is the volume shaper id.
             ALOGE("applyVolumeShaper() failed with status %d", status);
         }
-        return binder::Status::fromStatusT(status);
+        return aidl_utils::binderStatusFromStatusT(status);
     } else {
         ALOGD("applyVolumeShaper()"
                       " no AudioTrack for volume control from IPlayer");
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 3dfb801..d795725 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -134,6 +134,12 @@
     case AAUDIO_FORMAT_PCM_FLOAT:
         androidFormat = AUDIO_FORMAT_PCM_FLOAT;
         break;
+    case AAUDIO_FORMAT_PCM_I24_PACKED:
+        androidFormat = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+        break;
+    case AAUDIO_FORMAT_PCM_I32:
+        androidFormat = AUDIO_FORMAT_PCM_32_BIT;
+        break;
     default:
         androidFormat = AUDIO_FORMAT_INVALID;
         ALOGE("%s() 0x%08X unrecognized", __func__, aaudioFormat);
@@ -154,6 +160,12 @@
     case AUDIO_FORMAT_PCM_FLOAT:
         aaudioFormat = AAUDIO_FORMAT_PCM_FLOAT;
         break;
+    case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+        aaudioFormat = AAUDIO_FORMAT_PCM_I24_PACKED;
+        break;
+    case AUDIO_FORMAT_PCM_32_BIT:
+        aaudioFormat = AAUDIO_FORMAT_PCM_I32;
+        break;
     default:
         aaudioFormat = AAUDIO_FORMAT_INVALID;
         ALOGE("%s() 0x%08X unrecognized", __func__, androidFormat);
diff --git a/media/libaudioclient/AidlConversion.cpp b/media/libaudioclient/AidlConversion.cpp
index d362d8f..7e5eba3 100644
--- a/media/libaudioclient/AidlConversion.cpp
+++ b/media/libaudioclient/AidlConversion.cpp
@@ -16,7 +16,6 @@
 
 #define LOG_TAG "AidlConversion"
 //#define LOG_NDEBUG 0
-#include <system/audio.h>
 #include <utils/Log.h>
 
 #include "media/AidlConversion.h"
@@ -111,35 +110,6 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
-// Utilities for working with AIDL unions.
-// UNION_GET(obj, fieldname) returns a ConversionResult<T> containing either the strongly-typed
-//   value of the respective field, or BAD_VALUE if the union is not set to the requested field.
-// UNION_SET(obj, fieldname, value) sets the requested field to the given value.
-
-template<typename T, typename T::Tag tag>
-using UnionFieldType = std::decay_t<decltype(std::declval<T>().template get<tag>())>;
-
-template<typename T, typename T::Tag tag>
-ConversionResult<UnionFieldType<T, tag>> unionGetField(const T& u) {
-    if (u.getTag() != tag) {
-        return unexpected(BAD_VALUE);
-    }
-    return u.template get<tag>();
-}
-
-#define UNION_GET(u, field) \
-    unionGetField<std::decay_t<decltype(u)>, std::decay_t<decltype(u)>::Tag::field>(u)
-
-#define UNION_SET(u, field, value) \
-    (u).set<std::decay_t<decltype(u)>::Tag::field>(value)
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template<typename To, typename From>
-ConversionResult<To> convertReinterpret(From from) {
-    static_assert(sizeof(From) == sizeof(To));
-    return static_cast<To>(from);
-}
 
 enum class Direction {
     INPUT, OUTPUT
@@ -147,56 +117,58 @@
 
 ConversionResult<Direction> direction(media::AudioPortRole role, media::AudioPortType type) {
     switch (type) {
+        case media::AudioPortType::NONE:
+        case media::AudioPortType::SESSION:
+            break;  // must be listed  -Werror,-Wswitch
         case media::AudioPortType::DEVICE:
             switch (role) {
+                case media::AudioPortRole::NONE:
+                     break;  // must be listed  -Werror,-Wswitch
                 case media::AudioPortRole::SOURCE:
                     return Direction::INPUT;
                 case media::AudioPortRole::SINK:
                     return Direction::OUTPUT;
-                default:
-                    break;
             }
             break;
         case media::AudioPortType::MIX:
             switch (role) {
+                case media::AudioPortRole::NONE:
+                     break;  // must be listed  -Werror,-Wswitch
                 case media::AudioPortRole::SOURCE:
                     return Direction::OUTPUT;
                 case media::AudioPortRole::SINK:
                     return Direction::INPUT;
-                default:
-                    break;
             }
             break;
-        default:
-            break;
     }
     return unexpected(BAD_VALUE);
 }
 
 ConversionResult<Direction> direction(audio_port_role_t role, audio_port_type_t type) {
     switch (type) {
+        case AUDIO_PORT_TYPE_NONE:
+        case AUDIO_PORT_TYPE_SESSION:
+            break;  // must be listed  -Werror,-Wswitch
         case AUDIO_PORT_TYPE_DEVICE:
             switch (role) {
+                case AUDIO_PORT_ROLE_NONE:
+                     break;  // must be listed  -Werror,-Wswitch
                 case AUDIO_PORT_ROLE_SOURCE:
                     return Direction::INPUT;
                 case AUDIO_PORT_ROLE_SINK:
                     return Direction::OUTPUT;
-                default:
-                    break;
             }
             break;
         case AUDIO_PORT_TYPE_MIX:
             switch (role) {
+                case AUDIO_PORT_ROLE_NONE:
+                     break;  // must be listed  -Werror,-Wswitch
                 case AUDIO_PORT_ROLE_SOURCE:
                     return Direction::OUTPUT;
                 case AUDIO_PORT_ROLE_SINK:
                     return Direction::INPUT;
-                default:
-                    break;
             }
             break;
-        default:
-            break;
     }
     return unexpected(BAD_VALUE);
 }
@@ -266,6 +238,14 @@
     return convertReinterpret<int32_t>(legacy);
 }
 
+ConversionResult<audio_hw_sync_t> aidl2legacy_int32_t_audio_hw_sync_t(int32_t aidl) {
+    return convertReinterpret<audio_hw_sync_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_hw_sync_t_int32_t(audio_hw_sync_t legacy) {
+    return convertReinterpret<int32_t>(legacy);
+}
+
 ConversionResult<pid_t> aidl2legacy_int32_t_pid_t(int32_t aidl) {
     return convertReinterpret<pid_t>(aidl);
 }
@@ -290,8 +270,17 @@
     return std::string(String8(legacy).c_str());
 }
 
-// The legacy enum is unnamed. Thus, we use int.
-ConversionResult<int> aidl2legacy_AudioPortConfigType(media::AudioPortConfigType aidl) {
+ConversionResult<String8> aidl2legacy_string_view_String8(std::string_view aidl) {
+    return String8(aidl.data(), aidl.size());
+}
+
+ConversionResult<std::string> legacy2aidl_String8_string(const String8& legacy) {
+    return std::string(legacy.c_str());
+}
+
+// The legacy enum is unnamed. Thus, we use int32_t.
+ConversionResult<int32_t> aidl2legacy_AudioPortConfigType_int32_t(
+        media::AudioPortConfigType aidl) {
     switch (aidl) {
         case media::AudioPortConfigType::SAMPLE_RATE:
             return AUDIO_PORT_CONFIG_SAMPLE_RATE;
@@ -299,15 +288,17 @@
             return AUDIO_PORT_CONFIG_CHANNEL_MASK;
         case media::AudioPortConfigType::FORMAT:
             return AUDIO_PORT_CONFIG_FORMAT;
+        case media::AudioPortConfigType::GAIN:
+            return AUDIO_PORT_CONFIG_GAIN;
         case media::AudioPortConfigType::FLAGS:
             return AUDIO_PORT_CONFIG_FLAGS;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
-// The legacy enum is unnamed. Thus, we use int.
-ConversionResult<media::AudioPortConfigType> legacy2aidl_AudioPortConfigType(int legacy) {
+// The legacy enum is unnamed. Thus, we use int32_t.
+ConversionResult<media::AudioPortConfigType> legacy2aidl_int32_t_AudioPortConfigType(
+        int32_t legacy) {
     switch (legacy) {
         case AUDIO_PORT_CONFIG_SAMPLE_RATE:
             return media::AudioPortConfigType::SAMPLE_RATE;
@@ -315,16 +306,17 @@
             return media::AudioPortConfigType::CHANNEL_MASK;
         case AUDIO_PORT_CONFIG_FORMAT:
             return media::AudioPortConfigType::FORMAT;
+        case AUDIO_PORT_CONFIG_GAIN:
+            return media::AudioPortConfigType::GAIN;
         case AUDIO_PORT_CONFIG_FLAGS:
             return media::AudioPortConfigType::FLAGS;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<unsigned int> aidl2legacy_int32_t_config_mask(int32_t aidl) {
     return convertBitmask<unsigned int, int32_t, int, media::AudioPortConfigType>(
-            aidl, aidl2legacy_AudioPortConfigType,
+            aidl, aidl2legacy_AudioPortConfigType_int32_t,
             // AudioPortConfigType enum is index-based.
             index2enum_index<media::AudioPortConfigType>,
             // AUDIO_PORT_CONFIG_* flags are mask-based.
@@ -333,7 +325,7 @@
 
 ConversionResult<int32_t> legacy2aidl_config_mask_int32_t(unsigned int legacy) {
     return convertBitmask<int32_t, unsigned int, media::AudioPortConfigType, int>(
-            legacy, legacy2aidl_AudioPortConfigType,
+            legacy, legacy2aidl_int32_t_AudioPortConfigType,
             // AUDIO_PORT_CONFIG_* flags are mask-based.
             index2enum_bitmask<unsigned>,
             // AudioPortConfigType enum is index-based.
@@ -375,9 +367,8 @@
             return AUDIO_INPUT_CONFIG_CHANGED;
         case media::AudioIoConfigEvent::CLIENT_STARTED:
             return AUDIO_CLIENT_STARTED;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<media::AudioIoConfigEvent> legacy2aidl_audio_io_config_event_AudioIoConfigEvent(
@@ -401,9 +392,8 @@
             return media::AudioIoConfigEvent::INPUT_CONFIG_CHANGED;
         case AUDIO_CLIENT_STARTED:
             return media::AudioIoConfigEvent::CLIENT_STARTED;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<audio_port_role_t> aidl2legacy_AudioPortRole_audio_port_role_t(
@@ -415,9 +405,8 @@
             return AUDIO_PORT_ROLE_SOURCE;
         case media::AudioPortRole::SINK:
             return AUDIO_PORT_ROLE_SINK;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<media::AudioPortRole> legacy2aidl_audio_port_role_t_AudioPortRole(
@@ -429,9 +418,8 @@
             return media::AudioPortRole::SOURCE;
         case AUDIO_PORT_ROLE_SINK:
             return media::AudioPortRole::SINK;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<audio_port_type_t> aidl2legacy_AudioPortType_audio_port_type_t(
@@ -445,9 +433,8 @@
             return AUDIO_PORT_TYPE_MIX;
         case media::AudioPortType::SESSION:
             return AUDIO_PORT_TYPE_SESSION;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<media::AudioPortType> legacy2aidl_audio_port_type_t_AudioPortType(
@@ -461,9 +448,8 @@
             return media::AudioPortType::MIX;
         case AUDIO_PORT_TYPE_SESSION:
             return media::AudioPortType::SESSION;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<audio_format_t> aidl2legacy_AudioFormat_audio_format_t(
@@ -480,7 +466,7 @@
     return static_cast<media::audio::common::AudioFormat>(legacy);
 }
 
-ConversionResult<int> aidl2legacy_AudioGainMode_int(media::AudioGainMode aidl) {
+ConversionResult<audio_gain_mode_t> aidl2legacy_AudioGainMode_audio_gain_mode_t(media::AudioGainMode aidl) {
     switch (aidl) {
         case media::AudioGainMode::JOINT:
             return AUDIO_GAIN_MODE_JOINT;
@@ -488,12 +474,11 @@
             return AUDIO_GAIN_MODE_CHANNELS;
         case media::AudioGainMode::RAMP:
             return AUDIO_GAIN_MODE_RAMP;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
-ConversionResult<media::AudioGainMode> legacy2aidl_int_AudioGainMode(int legacy) {
+ConversionResult<media::AudioGainMode> legacy2aidl_audio_gain_mode_t_AudioGainMode(audio_gain_mode_t legacy) {
     switch (legacy) {
         case AUDIO_GAIN_MODE_JOINT:
             return media::AudioGainMode::JOINT;
@@ -501,25 +486,24 @@
             return media::AudioGainMode::CHANNELS;
         case AUDIO_GAIN_MODE_RAMP:
             return media::AudioGainMode::RAMP;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
-ConversionResult<audio_gain_mode_t> aidl2legacy_int32_t_audio_gain_mode_t(int32_t aidl) {
-    return convertBitmask<audio_gain_mode_t, int32_t, int, media::AudioGainMode>(
-            aidl, aidl2legacy_AudioGainMode_int,
+ConversionResult<audio_gain_mode_t> aidl2legacy_int32_t_audio_gain_mode_t_mask(int32_t aidl) {
+    return convertBitmask<audio_gain_mode_t, int32_t, audio_gain_mode_t, media::AudioGainMode>(
+            aidl, aidl2legacy_AudioGainMode_audio_gain_mode_t,
             // AudioGainMode is index-based.
             index2enum_index<media::AudioGainMode>,
             // AUDIO_GAIN_MODE_* constants are mask-based.
-            enumToMask_bitmask<audio_gain_mode_t, int>);
+            enumToMask_bitmask<audio_gain_mode_t, audio_gain_mode_t>);
 }
 
-ConversionResult<int32_t> legacy2aidl_audio_gain_mode_t_int32_t(audio_gain_mode_t legacy) {
-    return convertBitmask<int32_t, audio_gain_mode_t, media::AudioGainMode, int>(
-            legacy, legacy2aidl_int_AudioGainMode,
+ConversionResult<int32_t> legacy2aidl_audio_gain_mode_t_int32_t_mask(audio_gain_mode_t legacy) {
+    return convertBitmask<int32_t, audio_gain_mode_t, media::AudioGainMode, audio_gain_mode_t>(
+            legacy, legacy2aidl_audio_gain_mode_t_AudioGainMode,
             // AUDIO_GAIN_MODE_* constants are mask-based.
-            index2enum_bitmask<int>,
+            index2enum_bitmask<audio_gain_mode_t>,
             // AudioGainMode is index-based.
             enumToMask_index<int32_t, media::AudioGainMode>);
 }
@@ -538,7 +522,7 @@
         const media::AudioGainConfig& aidl, media::AudioPortRole role, media::AudioPortType type) {
     audio_gain_config legacy;
     legacy.index = VALUE_OR_RETURN(convertIntegral<int>(aidl.index));
-    legacy.mode = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_gain_mode_t(aidl.mode));
+    legacy.mode = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_gain_mode_t_mask(aidl.mode));
     legacy.channel_mask =
             VALUE_OR_RETURN(aidl2legacy_int32_t_audio_channel_mask_t(aidl.channelMask));
     const bool isInput = VALUE_OR_RETURN(direction(role, type)) == Direction::INPUT;
@@ -560,7 +544,7 @@
         const audio_gain_config& legacy, audio_port_role_t role, audio_port_type_t type) {
     media::AudioGainConfig aidl;
     aidl.index = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.index));
-    aidl.mode = VALUE_OR_RETURN(legacy2aidl_audio_gain_mode_t_int32_t(legacy.mode));
+    aidl.mode = VALUE_OR_RETURN(legacy2aidl_audio_gain_mode_t_int32_t_mask(legacy.mode));
     aidl.channelMask =
             VALUE_OR_RETURN(legacy2aidl_audio_channel_mask_t_int32_t(legacy.channel_mask));
     const bool isInput = VALUE_OR_RETURN(direction(role, type)) == Direction::INPUT;
@@ -595,14 +579,15 @@
             return AUDIO_INPUT_FLAG_HW_AV_SYNC;
         case media::AudioInputFlags::DIRECT:
             return AUDIO_INPUT_FLAG_DIRECT;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<media::AudioInputFlags> legacy2aidl_audio_input_flags_t_AudioInputFlags(
         audio_input_flags_t legacy) {
     switch (legacy) {
+        case AUDIO_INPUT_FLAG_NONE:
+            break; // shouldn't get here. must be listed  -Werror,-Wswitch
         case AUDIO_INPUT_FLAG_FAST:
             return media::AudioInputFlags::FAST;
         case AUDIO_INPUT_FLAG_HW_HOTWORD:
@@ -619,9 +604,8 @@
             return media::AudioInputFlags::HW_AV_SYNC;
         case AUDIO_INPUT_FLAG_DIRECT:
             return media::AudioInputFlags::DIRECT;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<audio_output_flags_t> aidl2legacy_AudioOutputFlags_audio_output_flags_t(
@@ -657,14 +641,17 @@
             return AUDIO_OUTPUT_FLAG_VOIP_RX;
         case media::AudioOutputFlags::INCALL_MUSIC:
             return AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
-        default:
-            return unexpected(BAD_VALUE);
+        case media::AudioOutputFlags::GAPLESS_OFFLOAD:
+            return AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD;
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<media::AudioOutputFlags> legacy2aidl_audio_output_flags_t_AudioOutputFlags(
         audio_output_flags_t legacy) {
     switch (legacy) {
+        case AUDIO_OUTPUT_FLAG_NONE:
+            break; // shouldn't get here. must be listed  -Werror,-Wswitch
         case AUDIO_OUTPUT_FLAG_DIRECT:
             return media::AudioOutputFlags::DIRECT;
         case AUDIO_OUTPUT_FLAG_PRIMARY:
@@ -695,12 +682,14 @@
             return media::AudioOutputFlags::VOIP_RX;
         case AUDIO_OUTPUT_FLAG_INCALL_MUSIC:
             return media::AudioOutputFlags::INCALL_MUSIC;
-        default:
-            return unexpected(BAD_VALUE);
+        case AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD:
+            return media::AudioOutputFlags::GAPLESS_OFFLOAD;
     }
+    return unexpected(BAD_VALUE);
 }
 
-ConversionResult<audio_input_flags_t> aidl2legacy_audio_input_flags_mask(int32_t aidl) {
+ConversionResult<audio_input_flags_t> aidl2legacy_int32_t_audio_input_flags_t_mask(
+        int32_t aidl) {
     using LegacyMask = std::underlying_type_t<audio_input_flags_t>;
 
     LegacyMask converted = VALUE_OR_RETURN(
@@ -711,7 +700,8 @@
     return static_cast<audio_input_flags_t>(converted);
 }
 
-ConversionResult<int32_t> legacy2aidl_audio_input_flags_mask(audio_input_flags_t legacy) {
+ConversionResult<int32_t> legacy2aidl_audio_input_flags_t_int32_t_mask(
+        audio_input_flags_t legacy) {
     using LegacyMask = std::underlying_type_t<audio_input_flags_t>;
 
     LegacyMask legacyMask = static_cast<LegacyMask>(legacy);
@@ -721,7 +711,8 @@
             enumToMask_index<int32_t, media::AudioInputFlags>);
 }
 
-ConversionResult<audio_output_flags_t> aidl2legacy_audio_output_flags_mask(int32_t aidl) {
+ConversionResult<audio_output_flags_t> aidl2legacy_int32_t_audio_output_flags_t_mask(
+        int32_t aidl) {
     return convertBitmask<audio_output_flags_t,
                           int32_t,
                           audio_output_flags_t,
@@ -731,7 +722,8 @@
             enumToMask_bitmask<audio_output_flags_t, audio_output_flags_t>);
 }
 
-ConversionResult<int32_t> legacy2aidl_audio_output_flags_mask(audio_output_flags_t legacy) {
+ConversionResult<int32_t> legacy2aidl_audio_output_flags_t_int32_t_mask(
+        audio_output_flags_t legacy) {
     using LegacyMask = std::underlying_type_t<audio_output_flags_t>;
 
     LegacyMask legacyMask = static_cast<LegacyMask>(legacy);
@@ -748,13 +740,15 @@
     switch (dir) {
         case Direction::INPUT: {
             legacy.input = VALUE_OR_RETURN(
-                    aidl2legacy_audio_input_flags_mask(VALUE_OR_RETURN(UNION_GET(aidl, input))));
+                    aidl2legacy_int32_t_audio_input_flags_t_mask(
+                            VALUE_OR_RETURN(UNION_GET(aidl, input))));
         }
             break;
 
         case Direction::OUTPUT: {
             legacy.output = VALUE_OR_RETURN(
-                    aidl2legacy_audio_output_flags_mask(VALUE_OR_RETURN(UNION_GET(aidl, output))));
+                    aidl2legacy_int32_t_audio_output_flags_t_mask(
+                            VALUE_OR_RETURN(UNION_GET(aidl, output))));
         }
             break;
     }
@@ -770,17 +764,20 @@
     switch (dir) {
         case Direction::INPUT:
             UNION_SET(aidl, input,
-                      VALUE_OR_RETURN(legacy2aidl_audio_input_flags_mask(legacy.input)));
+                      VALUE_OR_RETURN(legacy2aidl_audio_input_flags_t_int32_t_mask(
+                              legacy.input)));
             break;
         case Direction::OUTPUT:
             UNION_SET(aidl, output,
-                      VALUE_OR_RETURN(legacy2aidl_audio_output_flags_mask(legacy.output)));
+                      VALUE_OR_RETURN(legacy2aidl_audio_output_flags_t_int32_t_mask(
+                              legacy.output)));
             break;
     }
     return aidl;
 }
 
-ConversionResult<audio_port_config_device_ext> aidl2legacy_AudioPortConfigDeviceExt(
+ConversionResult<audio_port_config_device_ext>
+aidl2legacy_AudioPortConfigDeviceExt_audio_port_config_device_ext(
         const media::AudioPortConfigDeviceExt& aidl) {
     audio_port_config_device_ext legacy;
     legacy.hw_module = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_module_handle_t(aidl.hwModule));
@@ -789,7 +786,8 @@
     return legacy;
 }
 
-ConversionResult<media::AudioPortConfigDeviceExt> legacy2aidl_AudioPortConfigDeviceExt(
+ConversionResult<media::AudioPortConfigDeviceExt>
+legacy2aidl_audio_port_config_device_ext_AudioPortConfigDeviceExt(
         const audio_port_config_device_ext& legacy) {
     media::AudioPortConfigDeviceExt aidl;
     aidl.hwModule = VALUE_OR_RETURN(legacy2aidl_audio_module_handle_t_int32_t(legacy.hw_module));
@@ -834,9 +832,8 @@
             return AUDIO_STREAM_PATCH;
         case media::AudioStreamType::CALL_ASSISTANT:
             return AUDIO_STREAM_CALL_ASSISTANT;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<media::AudioStreamType> legacy2aidl_audio_stream_type_t_AudioStreamType(
@@ -874,9 +871,8 @@
             return media::AudioStreamType::PATCH;
         case AUDIO_STREAM_CALL_ASSISTANT:
             return media::AudioStreamType::CALL_ASSISTANT;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<audio_source_t> aidl2legacy_AudioSourceType_audio_source_t(
@@ -913,9 +909,8 @@
             return AUDIO_SOURCE_FM_TUNER;
         case media::AudioSourceType::HOTWORD:
             return AUDIO_SOURCE_HOTWORD;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<media::AudioSourceType> legacy2aidl_audio_source_t_AudioSourceType(
@@ -951,9 +946,8 @@
             return media::AudioSourceType::FM_TUNER;
         case AUDIO_SOURCE_HOTWORD:
             return media::AudioSourceType::HOTWORD;
-        default:
-            return unexpected(BAD_VALUE);
     }
+    return unexpected(BAD_VALUE);
 }
 
 ConversionResult<audio_session_t> aidl2legacy_int32_t_audio_session_t(int32_t aidl) {
@@ -974,25 +968,22 @@
     switch (role) {
         case media::AudioPortRole::NONE:
             // Just verify that the union is empty.
-            VALUE_OR_RETURN(UNION_GET(aidl, nothing));
-            break;
+            VALUE_OR_RETURN(UNION_GET(aidl, unspecified));
+            return legacy;
 
         case media::AudioPortRole::SOURCE:
             // This is not a bug. A SOURCE role corresponds to the stream field.
             legacy.stream = VALUE_OR_RETURN(aidl2legacy_AudioStreamType_audio_stream_type_t(
                     VALUE_OR_RETURN(UNION_GET(aidl, stream))));
-            break;
+            return legacy;
 
         case media::AudioPortRole::SINK:
             // This is not a bug. A SINK role corresponds to the source field.
             legacy.source = VALUE_OR_RETURN(aidl2legacy_AudioSourceType_audio_source_t(
                     VALUE_OR_RETURN(UNION_GET(aidl, source))));
-            break;
-
-        default:
-            LOG_ALWAYS_FATAL("Shouldn't get here");
+            return legacy;
     }
-    return legacy;
+    LOG_ALWAYS_FATAL("Shouldn't get here"); // with -Werror,-Wswitch may compile-time fail
 }
 
 ConversionResult<media::AudioPortConfigMixExtUseCase> legacy2aidl_AudioPortConfigMixExtUseCase(
@@ -1001,22 +992,20 @@
 
     switch (role) {
         case AUDIO_PORT_ROLE_NONE:
-            UNION_SET(aidl, nothing, false);
-            break;
+            UNION_SET(aidl, unspecified, false);
+            return aidl;
         case AUDIO_PORT_ROLE_SOURCE:
             // This is not a bug. A SOURCE role corresponds to the stream field.
             UNION_SET(aidl, stream, VALUE_OR_RETURN(
                     legacy2aidl_audio_stream_type_t_AudioStreamType(legacy.stream)));
-            break;
+            return aidl;
         case AUDIO_PORT_ROLE_SINK:
             // This is not a bug. A SINK role corresponds to the source field.
             UNION_SET(aidl, source,
                       VALUE_OR_RETURN(legacy2aidl_audio_source_t_AudioSourceType(legacy.source)));
-            break;
-        default:
-            LOG_ALWAYS_FATAL("Shouldn't get here");
+            return aidl;
     }
-    return aidl;
+    LOG_ALWAYS_FATAL("Shouldn't get here"); // with -Werror,-Wswitch may compile-time fail
 }
 
 ConversionResult<audio_port_config_mix_ext> aidl2legacy_AudioPortConfigMixExt(
@@ -1037,14 +1026,16 @@
     return aidl;
 }
 
-ConversionResult<audio_port_config_session_ext> aidl2legacy_AudioPortConfigSessionExt(
+ConversionResult<audio_port_config_session_ext>
+aidl2legacy_AudioPortConfigSessionExt_audio_port_config_session_ext(
         const media::AudioPortConfigSessionExt& aidl) {
     audio_port_config_session_ext legacy;
     legacy.session = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_session_t(aidl.session));
     return legacy;
 }
 
-ConversionResult<media::AudioPortConfigSessionExt> legacy2aidl_AudioPortConfigSessionExt(
+ConversionResult<media::AudioPortConfigSessionExt>
+legacy2aidl_audio_port_config_session_ext_AudioPortConfigSessionExt(
         const audio_port_config_session_ext& legacy) {
     media::AudioPortConfigSessionExt aidl;
     aidl.session = VALUE_OR_RETURN(legacy2aidl_audio_session_t_int32_t(legacy.session));
@@ -1058,29 +1049,28 @@
         const media::AudioPortConfigExt& aidl, media::AudioPortType type,
         media::AudioPortRole role) {
     audio_port_config_ext legacy;
-    // Our way of representing a union in AIDL is to have multiple vectors and require that at most
-    // one of the them has size 1 and the rest are empty.
     switch (type) {
         case media::AudioPortType::NONE:
             // Just verify that the union is empty.
-            VALUE_OR_RETURN(UNION_GET(aidl, nothing));
-            break;
+            VALUE_OR_RETURN(UNION_GET(aidl, unspecified));
+            return legacy;
         case media::AudioPortType::DEVICE:
             legacy.device = VALUE_OR_RETURN(
-                    aidl2legacy_AudioPortConfigDeviceExt(VALUE_OR_RETURN(UNION_GET(aidl, device))));
-            break;
+                    aidl2legacy_AudioPortConfigDeviceExt_audio_port_config_device_ext(
+                            VALUE_OR_RETURN(UNION_GET(aidl, device))));
+            return legacy;
         case media::AudioPortType::MIX:
             legacy.mix = VALUE_OR_RETURN(
                     aidl2legacy_AudioPortConfigMixExt(VALUE_OR_RETURN(UNION_GET(aidl, mix)), role));
-            break;
+            return legacy;
         case media::AudioPortType::SESSION:
-            legacy.session = VALUE_OR_RETURN(aidl2legacy_AudioPortConfigSessionExt(
-                    VALUE_OR_RETURN(UNION_GET(aidl, session))));
-            break;
-        default:
-            LOG_ALWAYS_FATAL("Shouldn't get here");
+            legacy.session = VALUE_OR_RETURN(
+                    aidl2legacy_AudioPortConfigSessionExt_audio_port_config_session_ext(
+                            VALUE_OR_RETURN(UNION_GET(aidl, session))));
+            return legacy;
+
     }
-    return legacy;
+    LOG_ALWAYS_FATAL("Shouldn't get here"); // with -Werror,-Wswitch may compile-time fail
 }
 
 ConversionResult<media::AudioPortConfigExt> legacy2aidl_AudioPortConfigExt(
@@ -1089,24 +1079,26 @@
 
     switch (type) {
         case AUDIO_PORT_TYPE_NONE:
-            UNION_SET(aidl, nothing, false);
-            break;
+            UNION_SET(aidl, unspecified, false);
+            return aidl;
         case AUDIO_PORT_TYPE_DEVICE:
             UNION_SET(aidl, device,
-                      VALUE_OR_RETURN(legacy2aidl_AudioPortConfigDeviceExt(legacy.device)));
-            break;
+                      VALUE_OR_RETURN(
+                        legacy2aidl_audio_port_config_device_ext_AudioPortConfigDeviceExt(
+                          legacy.device)));
+            return aidl;
         case AUDIO_PORT_TYPE_MIX:
             UNION_SET(aidl, mix,
                       VALUE_OR_RETURN(legacy2aidl_AudioPortConfigMixExt(legacy.mix, role)));
-            break;
+            return aidl;
         case AUDIO_PORT_TYPE_SESSION:
             UNION_SET(aidl, session,
-                      VALUE_OR_RETURN(legacy2aidl_AudioPortConfigSessionExt(legacy.session)));
-            break;
-        default:
-            LOG_ALWAYS_FATAL("Shouldn't get here");
+                      VALUE_OR_RETURN(
+                        legacy2aidl_audio_port_config_session_ext_AudioPortConfigSessionExt(
+                          legacy.session)));
+            return aidl;
     }
-    return aidl;
+    LOG_ALWAYS_FATAL("Shouldn't get here"); // with -Werror,-Wswitch may compile-time fail
 }
 
 ConversionResult<audio_port_config> aidl2legacy_AudioPortConfig_audio_port_config(
@@ -1245,7 +1237,8 @@
     return aidl;
 }
 
-ConversionResult<AudioClient> aidl2legacy_AudioClient(const media::AudioClient& aidl) {
+ConversionResult<AudioClient> aidl2legacy_AudioClient_AudioClient(
+        const media::AudioClient& aidl) {
     AudioClient legacy;
     legacy.clientUid = VALUE_OR_RETURN(aidl2legacy_int32_t_uid_t(aidl.clientUid));
     legacy.clientPid = VALUE_OR_RETURN(aidl2legacy_int32_t_pid_t(aidl.clientPid));
@@ -1254,7 +1247,8 @@
     return legacy;
 }
 
-ConversionResult<media::AudioClient> legacy2aidl_AudioClient(const AudioClient& legacy) {
+ConversionResult<media::AudioClient> legacy2aidl_AudioClient_AudioClient(
+        const AudioClient& legacy) {
     media::AudioClient aidl;
     aidl.clientUid = VALUE_OR_RETURN(legacy2aidl_uid_t_int32_t(legacy.clientUid));
     aidl.clientPid = VALUE_OR_RETURN(legacy2aidl_pid_t_int32_t(legacy.clientPid));
@@ -1511,7 +1505,7 @@
 }
 
 ConversionResult<audio_encapsulation_mode_t>
-aidl2legacy_audio_encapsulation_mode_t_AudioEncapsulationMode(media::AudioEncapsulationMode aidl) {
+aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(media::AudioEncapsulationMode aidl) {
     switch (aidl) {
         case media::AudioEncapsulationMode::NONE:
             return AUDIO_ENCAPSULATION_MODE_NONE;
@@ -1524,7 +1518,7 @@
 }
 
 ConversionResult<media::AudioEncapsulationMode>
-legacy2aidl_AudioEncapsulationMode_audio_encapsulation_mode_t(audio_encapsulation_mode_t legacy) {
+legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(audio_encapsulation_mode_t legacy) {
     switch (legacy) {
         case AUDIO_ENCAPSULATION_MODE_NONE:
             return media::AudioEncapsulationMode::NONE;
@@ -1556,7 +1550,7 @@
     legacy.offload_buffer_size = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.offloadBufferSize));
     legacy.usage = VALUE_OR_RETURN(aidl2legacy_AudioUsage_audio_usage_t(aidl.usage));
     legacy.encapsulation_mode = VALUE_OR_RETURN(
-            aidl2legacy_audio_encapsulation_mode_t_AudioEncapsulationMode(aidl.encapsulationMode));
+            aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(aidl.encapsulationMode));
     legacy.content_id = VALUE_OR_RETURN(convertReinterpret<int32_t>(aidl.contentId));
     legacy.sync_id = VALUE_OR_RETURN(convertReinterpret<int32_t>(aidl.syncId));
     return legacy;
@@ -1591,7 +1585,7 @@
             return unexpected(BAD_VALUE);
         }
         aidl.encapsulationMode = VALUE_OR_RETURN(
-                legacy2aidl_AudioEncapsulationMode_audio_encapsulation_mode_t(
+                legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(
                         legacy.encapsulation_mode));
         aidl.contentId = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.content_id));
         aidl.syncId = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.sync_id));
@@ -1681,4 +1675,516 @@
     return aidl;
 }
 
+ConversionResult<AudioTimestamp>
+aidl2legacy_AudioTimestampInternal_AudioTimestamp(const media::AudioTimestampInternal& aidl) {
+    AudioTimestamp legacy;
+    legacy.mPosition = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.position));
+    legacy.mTime.tv_sec = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.sec));
+    legacy.mTime.tv_nsec = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.nsec));
+    return legacy;
+}
+
+ConversionResult<media::AudioTimestampInternal>
+legacy2aidl_AudioTimestamp_AudioTimestampInternal(const AudioTimestamp& legacy) {
+    media::AudioTimestampInternal aidl;
+    aidl.position = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.mPosition));
+    aidl.sec = VALUE_OR_RETURN(convertIntegral<int64_t>(legacy.mTime.tv_sec));
+    aidl.nsec = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.mTime.tv_nsec));
+    return aidl;
+}
+
+ConversionResult<audio_uuid_t>
+aidl2legacy_AudioUuid_audio_uuid_t(const media::AudioUuid& aidl) {
+    audio_uuid_t legacy;
+    legacy.timeLow = VALUE_OR_RETURN(convertReinterpret<uint32_t>(aidl.timeLow));
+    legacy.timeMid = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.timeMid));
+    legacy.timeHiAndVersion = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.timeHiAndVersion));
+    legacy.clockSeq = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.clockSeq));
+    if (aidl.node.size() != std::size(legacy.node)) {
+        return unexpected(BAD_VALUE);
+    }
+    std::copy(aidl.node.begin(), aidl.node.end(), legacy.node);
+    return legacy;
+}
+
+ConversionResult<media::AudioUuid>
+legacy2aidl_audio_uuid_t_AudioUuid(const audio_uuid_t& legacy) {
+    media::AudioUuid aidl;
+    aidl.timeLow = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.timeLow));
+    aidl.timeMid = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.timeMid));
+    aidl.timeHiAndVersion = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.timeHiAndVersion));
+    aidl.clockSeq = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.clockSeq));
+    std::copy(legacy.node, legacy.node + std::size(legacy.node), std::back_inserter(aidl.node));
+    return aidl;
+}
+
+ConversionResult<effect_descriptor_t>
+aidl2legacy_EffectDescriptor_effect_descriptor_t(const media::EffectDescriptor& aidl) {
+    effect_descriptor_t legacy;
+    legacy.type = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.type));
+    legacy.uuid = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.uuid));
+    legacy.apiVersion = VALUE_OR_RETURN(convertReinterpret<uint32_t>(aidl.apiVersion));
+    legacy.flags = VALUE_OR_RETURN(convertReinterpret<uint32_t>(aidl.flags));
+    legacy.cpuLoad = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.cpuLoad));
+    legacy.memoryUsage = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.memoryUsage));
+    RETURN_IF_ERROR(aidl2legacy_string(aidl.name, legacy.name, sizeof(legacy.name)));
+    RETURN_IF_ERROR(
+            aidl2legacy_string(aidl.implementor, legacy.implementor, sizeof(legacy.implementor)));
+    return legacy;
+}
+
+ConversionResult<media::EffectDescriptor>
+legacy2aidl_effect_descriptor_t_EffectDescriptor(const effect_descriptor_t& legacy) {
+    media::EffectDescriptor aidl;
+    aidl.type = VALUE_OR_RETURN(legacy2aidl_audio_uuid_t_AudioUuid(legacy.type));
+    aidl.uuid = VALUE_OR_RETURN(legacy2aidl_audio_uuid_t_AudioUuid(legacy.uuid));
+    aidl.apiVersion = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.apiVersion));
+    aidl.flags = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.flags));
+    aidl.cpuLoad = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.cpuLoad));
+    aidl.memoryUsage = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.memoryUsage));
+    aidl.name = VALUE_OR_RETURN(legacy2aidl_string(legacy.name, sizeof(legacy.name)));
+    aidl.implementor = VALUE_OR_RETURN(
+            legacy2aidl_string(legacy.implementor, sizeof(legacy.implementor)));
+    return aidl;
+}
+
+ConversionResult<audio_encapsulation_metadata_type_t>
+aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t(
+        media::AudioEncapsulationMetadataType aidl) {
+    switch (aidl) {
+        case media::AudioEncapsulationMetadataType::NONE:
+            return AUDIO_ENCAPSULATION_METADATA_TYPE_NONE;
+        case media::AudioEncapsulationMetadataType::FRAMEWORK_TUNER:
+            return AUDIO_ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER;
+        case media::AudioEncapsulationMetadataType::DVB_AD_DESCRIPTOR:
+            return AUDIO_ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<media::AudioEncapsulationMetadataType>
+legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType(
+        audio_encapsulation_metadata_type_t legacy) {
+    switch (legacy) {
+        case AUDIO_ENCAPSULATION_METADATA_TYPE_NONE:
+            return media::AudioEncapsulationMetadataType::NONE;
+        case AUDIO_ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER:
+            return media::AudioEncapsulationMetadataType::FRAMEWORK_TUNER;
+        case AUDIO_ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR:
+            return media::AudioEncapsulationMetadataType::DVB_AD_DESCRIPTOR;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t>
+aidl2legacy_AudioEncapsulationMode_mask(int32_t aidl) {
+    return convertBitmask<uint32_t,
+                          int32_t,
+                          audio_encapsulation_mode_t,
+                          media::AudioEncapsulationMode>(
+            aidl, aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t,
+            index2enum_index<media::AudioEncapsulationMode>,
+            enumToMask_index<uint32_t, audio_encapsulation_mode_t>);
+}
+
+ConversionResult<int32_t>
+legacy2aidl_AudioEncapsulationMode_mask(uint32_t legacy) {
+    return convertBitmask<int32_t,
+                          uint32_t,
+                          media::AudioEncapsulationMode,
+                          audio_encapsulation_mode_t>(
+            legacy, legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode,
+            index2enum_index<audio_encapsulation_mode_t>,
+            enumToMask_index<int32_t, media::AudioEncapsulationMode>);
+}
+
+ConversionResult<uint32_t>
+aidl2legacy_AudioEncapsulationMetadataType_mask(int32_t aidl) {
+    return convertBitmask<uint32_t,
+                          int32_t,
+                          audio_encapsulation_metadata_type_t,
+                          media::AudioEncapsulationMetadataType>(
+            aidl, aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t,
+            index2enum_index<media::AudioEncapsulationMetadataType>,
+            enumToMask_index<uint32_t, audio_encapsulation_metadata_type_t>);
+}
+
+ConversionResult<int32_t>
+legacy2aidl_AudioEncapsulationMetadataType_mask(uint32_t legacy) {
+    return convertBitmask<int32_t,
+                          uint32_t,
+                          media::AudioEncapsulationMetadataType,
+                          audio_encapsulation_metadata_type_t>(
+            legacy, legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType,
+            index2enum_index<audio_encapsulation_metadata_type_t>,
+            enumToMask_index<int32_t, media::AudioEncapsulationMetadataType>);
+}
+
+ConversionResult<audio_mix_latency_class_t>
+aidl2legacy_AudioMixLatencyClass_audio_mix_latency_class_t(
+        media::AudioMixLatencyClass aidl) {
+    switch (aidl) {
+        case media::AudioMixLatencyClass::LOW:
+            return AUDIO_LATENCY_LOW;
+        case media::AudioMixLatencyClass::NORMAL:
+            return AUDIO_LATENCY_NORMAL;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<media::AudioMixLatencyClass>
+legacy2aidl_audio_mix_latency_class_t_AudioMixLatencyClass(
+        audio_mix_latency_class_t legacy) {
+    switch (legacy) {
+        case AUDIO_LATENCY_LOW:
+            return media::AudioMixLatencyClass::LOW;
+        case AUDIO_LATENCY_NORMAL:
+            return media::AudioMixLatencyClass::NORMAL;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_port_device_ext>
+aidl2legacy_AudioPortDeviceExt_audio_port_device_ext(const media::AudioPortDeviceExt& aidl) {
+    audio_port_device_ext legacy;
+    legacy.hw_module = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_module_handle_t(aidl.hwModule));
+    legacy.type = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_devices_t(aidl.device.type));
+    RETURN_IF_ERROR(
+            aidl2legacy_string(aidl.device.address, legacy.address, sizeof(legacy.address)));
+    legacy.encapsulation_modes = VALUE_OR_RETURN(
+            aidl2legacy_AudioEncapsulationMode_mask(aidl.encapsulationModes));
+    legacy.encapsulation_metadata_types = VALUE_OR_RETURN(
+            aidl2legacy_AudioEncapsulationMetadataType_mask(aidl.encapsulationMetadataTypes));
+    return legacy;
+}
+
+ConversionResult<media::AudioPortDeviceExt>
+legacy2aidl_audio_port_device_ext_AudioPortDeviceExt(const audio_port_device_ext& legacy) {
+    media::AudioPortDeviceExt aidl;
+    aidl.hwModule = VALUE_OR_RETURN(legacy2aidl_audio_module_handle_t_int32_t(legacy.hw_module));
+    aidl.device.type = VALUE_OR_RETURN(legacy2aidl_audio_devices_t_int32_t(legacy.type));
+    aidl.device.address = VALUE_OR_RETURN(
+            legacy2aidl_string(legacy.address, sizeof(legacy.address)));
+    aidl.encapsulationModes = VALUE_OR_RETURN(
+            legacy2aidl_AudioEncapsulationMode_mask(legacy.encapsulation_modes));
+    aidl.encapsulationMetadataTypes = VALUE_OR_RETURN(
+            legacy2aidl_AudioEncapsulationMetadataType_mask(legacy.encapsulation_metadata_types));
+    return aidl;
+}
+
+ConversionResult<audio_port_mix_ext>
+aidl2legacy_AudioPortMixExt_audio_port_mix_ext(const media::AudioPortMixExt& aidl) {
+    audio_port_mix_ext legacy;
+    legacy.hw_module = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_module_handle_t(aidl.hwModule));
+    legacy.handle = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_io_handle_t(aidl.handle));
+    legacy.latency_class = VALUE_OR_RETURN(
+            aidl2legacy_AudioMixLatencyClass_audio_mix_latency_class_t(aidl.latencyClass));
+    return legacy;
+}
+
+ConversionResult<media::AudioPortMixExt>
+legacy2aidl_audio_port_mix_ext_AudioPortMixExt(const audio_port_mix_ext& legacy) {
+    media::AudioPortMixExt aidl;
+    aidl.hwModule = VALUE_OR_RETURN(legacy2aidl_audio_module_handle_t_int32_t(legacy.hw_module));
+    aidl.handle = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(legacy.handle));
+    aidl.latencyClass = VALUE_OR_RETURN(
+            legacy2aidl_audio_mix_latency_class_t_AudioMixLatencyClass(legacy.latency_class));
+    return aidl;
+}
+
+ConversionResult<audio_port_session_ext>
+aidl2legacy_AudioPortSessionExt_audio_port_session_ext(const media::AudioPortSessionExt& aidl) {
+    audio_port_session_ext legacy;
+    legacy.session = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_session_t(aidl.session));
+    return legacy;
+}
+
+ConversionResult<media::AudioPortSessionExt>
+legacy2aidl_audio_port_session_ext_AudioPortSessionExt(const audio_port_session_ext& legacy) {
+    media::AudioPortSessionExt aidl;
+    aidl.session = VALUE_OR_RETURN(legacy2aidl_audio_session_t_int32_t(legacy.session));
+    return aidl;
+}
+
+// This type is unnamed in the original definition, thus we name it here.
+using audio_port_v7_ext = decltype(audio_port_v7::ext);
+
+ConversionResult<audio_port_v7_ext> aidl2legacy_AudioPortExt(
+        const media::AudioPortExt& aidl, media::AudioPortType type) {
+    audio_port_v7_ext legacy;
+    switch (type) {
+        case media::AudioPortType::NONE:
+            // Just verify that the union is empty.
+            VALUE_OR_RETURN(UNION_GET(aidl, unspecified));
+            return legacy;
+        case media::AudioPortType::DEVICE:
+            legacy.device = VALUE_OR_RETURN(
+                    aidl2legacy_AudioPortDeviceExt_audio_port_device_ext(
+                            VALUE_OR_RETURN(UNION_GET(aidl, device))));
+            return legacy;
+        case media::AudioPortType::MIX:
+            legacy.mix = VALUE_OR_RETURN(
+                    aidl2legacy_AudioPortMixExt_audio_port_mix_ext(
+                            VALUE_OR_RETURN(UNION_GET(aidl, mix))));
+            return legacy;
+        case media::AudioPortType::SESSION:
+            legacy.session = VALUE_OR_RETURN(aidl2legacy_AudioPortSessionExt_audio_port_session_ext(
+                    VALUE_OR_RETURN(UNION_GET(aidl, session))));
+            return legacy;
+
+    }
+    LOG_ALWAYS_FATAL("Shouldn't get here"); // with -Werror,-Wswitch may compile-time fail
+}
+
+ConversionResult<media::AudioPortExt> legacy2aidl_AudioPortExt(
+        const audio_port_v7_ext& legacy, audio_port_type_t type) {
+    media::AudioPortExt aidl;
+    switch (type) {
+        case AUDIO_PORT_TYPE_NONE:
+            UNION_SET(aidl, unspecified, false);
+            return aidl;
+        case AUDIO_PORT_TYPE_DEVICE:
+            UNION_SET(aidl, device,
+                      VALUE_OR_RETURN(
+                              legacy2aidl_audio_port_device_ext_AudioPortDeviceExt(legacy.device)));
+            return aidl;
+        case AUDIO_PORT_TYPE_MIX:
+            UNION_SET(aidl, mix,
+                      VALUE_OR_RETURN(legacy2aidl_audio_port_mix_ext_AudioPortMixExt(legacy.mix)));
+            return aidl;
+        case AUDIO_PORT_TYPE_SESSION:
+            UNION_SET(aidl, session,
+                      VALUE_OR_RETURN(legacy2aidl_audio_port_session_ext_AudioPortSessionExt(
+                              legacy.session)));
+            return aidl;
+    }
+    LOG_ALWAYS_FATAL("Shouldn't get here"); // with -Werror,-Wswitch may compile-time fail
+}
+
+ConversionResult<audio_profile>
+aidl2legacy_AudioProfile_audio_profile(const media::AudioProfile& aidl) {
+    audio_profile legacy;
+    legacy.format = VALUE_OR_RETURN(aidl2legacy_AudioFormat_audio_format_t(aidl.format));
+
+    if (aidl.samplingRates.size() > std::size(legacy.sample_rates)) {
+        return unexpected(BAD_VALUE);
+    }
+    RETURN_IF_ERROR(
+            convertRange(aidl.samplingRates.begin(), aidl.samplingRates.end(), legacy.sample_rates,
+                         convertIntegral<int32_t, unsigned int>));
+    legacy.num_sample_rates = aidl.samplingRates.size();
+
+    if (aidl.channelMasks.size() > std::size(legacy.channel_masks)) {
+        return unexpected(BAD_VALUE);
+    }
+    RETURN_IF_ERROR(
+            convertRange(aidl.channelMasks.begin(), aidl.channelMasks.end(), legacy.channel_masks,
+                         aidl2legacy_int32_t_audio_channel_mask_t));
+    legacy.num_channel_masks = aidl.channelMasks.size();
+    return legacy;
+}
+
+ConversionResult<media::AudioProfile>
+legacy2aidl_audio_profile_AudioProfile(const audio_profile& legacy) {
+    media::AudioProfile aidl;
+    aidl.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormat(legacy.format));
+
+    if (legacy.num_sample_rates > std::size(legacy.sample_rates)) {
+        return unexpected(BAD_VALUE);
+    }
+    RETURN_IF_ERROR(
+            convertRange(legacy.sample_rates, legacy.sample_rates + legacy.num_sample_rates,
+                         std::back_inserter(aidl.samplingRates),
+                         convertIntegral<unsigned int, int32_t>));
+
+    if (legacy.num_channel_masks > std::size(legacy.channel_masks)) {
+        return unexpected(BAD_VALUE);
+    }
+    RETURN_IF_ERROR(
+            convertRange(legacy.channel_masks, legacy.channel_masks + legacy.num_channel_masks,
+                         std::back_inserter(aidl.channelMasks),
+                         legacy2aidl_audio_channel_mask_t_int32_t));
+    return aidl;
+}
+
+ConversionResult<audio_gain>
+aidl2legacy_AudioGain_audio_gain(const media::AudioGain& aidl) {
+    audio_gain legacy;
+    legacy.mode = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_gain_mode_t_mask(aidl.mode));
+    legacy.channel_mask = VALUE_OR_RETURN(
+            aidl2legacy_int32_t_audio_channel_mask_t(aidl.channelMask));
+    legacy.min_value = VALUE_OR_RETURN(convertIntegral<int>(aidl.minValue));
+    legacy.max_value = VALUE_OR_RETURN(convertIntegral<int>(aidl.maxValue));
+    legacy.default_value = VALUE_OR_RETURN(convertIntegral<int>(aidl.defaultValue));
+    legacy.step_value = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.stepValue));
+    legacy.min_ramp_ms = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.minRampMs));
+    legacy.max_ramp_ms = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.maxRampMs));
+    return legacy;
+}
+
+ConversionResult<media::AudioGain>
+legacy2aidl_audio_gain_AudioGain(const audio_gain& legacy) {
+    media::AudioGain aidl;
+    aidl.mode = VALUE_OR_RETURN(legacy2aidl_audio_gain_mode_t_int32_t_mask(legacy.mode));
+    aidl.channelMask = VALUE_OR_RETURN(
+            legacy2aidl_audio_channel_mask_t_int32_t(legacy.channel_mask));
+    aidl.minValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.min_value));
+    aidl.maxValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.max_value));
+    aidl.defaultValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.default_value));
+    aidl.stepValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.step_value));
+    aidl.minRampMs = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.min_ramp_ms));
+    aidl.maxRampMs = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.max_ramp_ms));
+    return aidl;
+}
+
+ConversionResult<audio_port_v7>
+aidl2legacy_AudioPort_audio_port_v7(const media::AudioPort& aidl) {
+    audio_port_v7 legacy;
+    legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.id));
+    legacy.role = VALUE_OR_RETURN(aidl2legacy_AudioPortRole_audio_port_role_t(aidl.role));
+    legacy.type = VALUE_OR_RETURN(aidl2legacy_AudioPortType_audio_port_type_t(aidl.type));
+    RETURN_IF_ERROR(aidl2legacy_string(aidl.name, legacy.name, sizeof(legacy.name)));
+
+    if (aidl.profiles.size() > std::size(legacy.audio_profiles)) {
+        return unexpected(BAD_VALUE);
+    }
+    RETURN_IF_ERROR(convertRange(aidl.profiles.begin(), aidl.profiles.end(), legacy.audio_profiles,
+                                 aidl2legacy_AudioProfile_audio_profile));
+    legacy.num_audio_profiles = aidl.profiles.size();
+
+    if (aidl.gains.size() > std::size(legacy.gains)) {
+        return unexpected(BAD_VALUE);
+    }
+    RETURN_IF_ERROR(convertRange(aidl.gains.begin(), aidl.gains.end(), legacy.gains,
+                                 aidl2legacy_AudioGain_audio_gain));
+    legacy.num_gains = aidl.gains.size();
+
+    legacy.active_config = VALUE_OR_RETURN(
+            aidl2legacy_AudioPortConfig_audio_port_config(aidl.activeConfig));
+    legacy.ext = VALUE_OR_RETURN(aidl2legacy_AudioPortExt(aidl.ext, aidl.type));
+    return legacy;
+}
+
+ConversionResult<media::AudioPort>
+legacy2aidl_audio_port_v7_AudioPort(const audio_port_v7& legacy) {
+    media::AudioPort aidl;
+    aidl.id = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(legacy.id));
+    aidl.role = VALUE_OR_RETURN(legacy2aidl_audio_port_role_t_AudioPortRole(legacy.role));
+    aidl.type = VALUE_OR_RETURN(legacy2aidl_audio_port_type_t_AudioPortType(legacy.type));
+    aidl.name = VALUE_OR_RETURN(legacy2aidl_string(legacy.name, sizeof(legacy.name)));
+
+    if (legacy.num_audio_profiles > std::size(legacy.audio_profiles)) {
+        return unexpected(BAD_VALUE);
+    }
+    RETURN_IF_ERROR(
+            convertRange(legacy.audio_profiles, legacy.audio_profiles + legacy.num_audio_profiles,
+                         std::back_inserter(aidl.profiles),
+                         legacy2aidl_audio_profile_AudioProfile));
+
+    if (legacy.num_gains > std::size(legacy.gains)) {
+        return unexpected(BAD_VALUE);
+    }
+    RETURN_IF_ERROR(
+            convertRange(legacy.gains, legacy.gains + legacy.num_gains,
+                         std::back_inserter(aidl.gains),
+                         legacy2aidl_audio_gain_AudioGain));
+
+    aidl.activeConfig = VALUE_OR_RETURN(
+            legacy2aidl_audio_port_config_AudioPortConfig(legacy.active_config));
+    aidl.ext = VALUE_OR_RETURN(legacy2aidl_AudioPortExt(legacy.ext, legacy.type));
+    return aidl;
+}
+
+ConversionResult<audio_mode_t>
+aidl2legacy_AudioMode_audio_mode_t(media::AudioMode aidl) {
+    switch (aidl) {
+        case media::AudioMode::INVALID:
+            return AUDIO_MODE_INVALID;
+        case media::AudioMode::CURRENT:
+            return AUDIO_MODE_CURRENT;
+        case media::AudioMode::NORMAL:
+            return AUDIO_MODE_NORMAL;
+        case media::AudioMode::RINGTONE:
+            return AUDIO_MODE_RINGTONE;
+        case media::AudioMode::IN_CALL:
+            return AUDIO_MODE_IN_CALL;
+        case media::AudioMode::IN_COMMUNICATION:
+            return AUDIO_MODE_IN_COMMUNICATION;
+        case media::AudioMode::CALL_SCREEN:
+            return AUDIO_MODE_CALL_SCREEN;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<media::AudioMode>
+legacy2aidl_audio_mode_t_AudioMode(audio_mode_t legacy) {
+    switch (legacy) {
+        case AUDIO_MODE_INVALID:
+            return media::AudioMode::INVALID;
+        case AUDIO_MODE_CURRENT:
+            return media::AudioMode::CURRENT;
+        case AUDIO_MODE_NORMAL:
+            return media::AudioMode::NORMAL;
+        case AUDIO_MODE_RINGTONE:
+            return media::AudioMode::RINGTONE;
+        case AUDIO_MODE_IN_CALL:
+            return media::AudioMode::IN_CALL;
+        case AUDIO_MODE_IN_COMMUNICATION:
+            return media::AudioMode::IN_COMMUNICATION;
+        case AUDIO_MODE_CALL_SCREEN:
+            return media::AudioMode::CALL_SCREEN;
+        case AUDIO_MODE_CNT:
+            break;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_unique_id_use_t>
+aidl2legacy_AudioUniqueIdUse_audio_unique_id_use_t(media::AudioUniqueIdUse aidl) {
+    switch (aidl) {
+        case media::AudioUniqueIdUse::UNSPECIFIED:
+            return AUDIO_UNIQUE_ID_USE_UNSPECIFIED;
+        case media::AudioUniqueIdUse::SESSION:
+            return AUDIO_UNIQUE_ID_USE_SESSION;
+        case media::AudioUniqueIdUse::MODULE:
+            return AUDIO_UNIQUE_ID_USE_MODULE;
+        case media::AudioUniqueIdUse::EFFECT:
+            return AUDIO_UNIQUE_ID_USE_EFFECT;
+        case media::AudioUniqueIdUse::PATCH:
+            return AUDIO_UNIQUE_ID_USE_PATCH;
+        case media::AudioUniqueIdUse::OUTPUT:
+            return AUDIO_UNIQUE_ID_USE_OUTPUT;
+        case media::AudioUniqueIdUse::INPUT:
+            return AUDIO_UNIQUE_ID_USE_INPUT;
+        case media::AudioUniqueIdUse::CLIENT:
+            return AUDIO_UNIQUE_ID_USE_CLIENT;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<media::AudioUniqueIdUse>
+legacy2aidl_audio_unique_id_use_t_AudioUniqueIdUse(audio_unique_id_use_t legacy) {
+    switch (legacy) {
+        case AUDIO_UNIQUE_ID_USE_UNSPECIFIED:
+            return media::AudioUniqueIdUse::UNSPECIFIED;
+        case AUDIO_UNIQUE_ID_USE_SESSION:
+            return media::AudioUniqueIdUse::SESSION;
+        case AUDIO_UNIQUE_ID_USE_MODULE:
+            return media::AudioUniqueIdUse::MODULE;
+        case AUDIO_UNIQUE_ID_USE_EFFECT:
+            return media::AudioUniqueIdUse::EFFECT;
+        case AUDIO_UNIQUE_ID_USE_PATCH:
+            return media::AudioUniqueIdUse::PATCH;
+        case AUDIO_UNIQUE_ID_USE_OUTPUT:
+            return media::AudioUniqueIdUse::OUTPUT;
+        case AUDIO_UNIQUE_ID_USE_INPUT:
+            return media::AudioUniqueIdUse::INPUT;
+        case AUDIO_UNIQUE_ID_USE_CLIENT:
+            return media::AudioUniqueIdUse::CLIENT;
+        case AUDIO_UNIQUE_ID_USE_MAX:
+            break;
+    }
+    return unexpected(BAD_VALUE);
+}
+
 }  // namespace android
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index c23c38c..64ec145 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -73,7 +73,6 @@
         // AIDL files for audioclient interfaces
         // The headers for these interfaces will be available to any modules that
         // include libaudioclient, at the path "aidl/package/path/BnFoo.h"
-        ":libaudioclient_aidl_private",
         ":libaudioclient_aidl",
 
         "AudioEffect.cpp",
@@ -84,7 +83,6 @@
         "IAudioFlinger.cpp",
         "IAudioPolicyService.cpp",
         "IAudioPolicyServiceClient.cpp",
-        "IAudioTrack.cpp",
         "ToneGenerator.cpp",
         "PlayerBase.cpp",
         "RecordingActivityTracker.cpp",
@@ -132,12 +130,12 @@
     ],
     export_header_lib_headers: ["libaudioclient_headers"],
     export_static_lib_headers: [
-        "effect-aidl-cpp",
+        "effect-aidl-unstable-cpp",
         "shared-file-region-aidl-unstable-cpp",
     ],
 
     static_libs: [
-        "effect-aidl-cpp",
+        "effect-aidl-unstable-cpp",
         // for memory heap analysis
         "libc_malloc_debug_backtrace",
         "shared-file-region-aidl-unstable-cpp",
@@ -155,10 +153,51 @@
     },
 }
 
-cc_library_shared {
+// This is intended for clients needing to include AidlConversionUtil.h, without dragging in a lot of extra
+// dependencies.
+cc_library_headers {
+    name: "libaudioclient_aidl_conversion_util",
+    host_supported: true,
+    vendor_available: true,
+    double_loadable: true,
+    min_sdk_version: "29",
+    export_include_dirs: [
+        "include",
+    ],
+    header_libs: [
+        "libbase_headers",
+    ],
+    export_header_lib_headers: [
+        "libbase_headers",
+    ],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.bluetooth.updatable",
+        "com.android.media",
+        "com.android.media.swcodec",
+    ],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+cc_library {
     name: "libaudioclient_aidl_conversion",
     srcs: ["AidlConversion.cpp"],
-    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    host_supported: true,
+    vendor_available: true,
+    double_loadable: true,
+    min_sdk_version: "29",
+    header_libs: [
+        "libaudioclient_aidl_conversion_util",
+        "libaudio_system_headers",
+    ],
+    export_header_lib_headers: [
+        "libaudioclient_aidl_conversion_util",
+    ],
     shared_libs: [
         "audioclient-types-aidl-unstable-cpp",
         "libbase",
@@ -184,6 +223,11 @@
             "signed-integer-overflow",
         ],
     },
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 // AIDL interface between libaudioclient and framework.jar
@@ -195,16 +239,6 @@
     path: "aidl",
 }
 
-// Used to strip the "aidl/" from the path, so the build system can predict the
-// output filename.
-filegroup {
-    name: "libaudioclient_aidl_private",
-    srcs: [
-        "aidl/android/media/IAudioRecord.aidl",
-    ],
-    path: "aidl",
-}
-
 aidl_interface {
     name: "capture_state_listener-aidl",
     unstable: true,
@@ -218,6 +252,9 @@
     name: "effect-aidl",
     unstable: true,
     local_include_dir: "aidl",
+    host_supported: true,
+    double_loadable: true,
+    vendor_available: true,
     srcs: [
         "aidl/android/media/IEffect.aidl",
         "aidl/android/media/IEffectClient.aidl",
@@ -240,17 +277,23 @@
         "aidl/android/media/AudioConfig.aidl",
         "aidl/android/media/AudioConfigBase.aidl",
         "aidl/android/media/AudioContentType.aidl",
+        "aidl/android/media/AudioDevice.aidl",
         "aidl/android/media/AudioEncapsulationMode.aidl",
+        "aidl/android/media/AudioEncapsulationMetadataType.aidl",
         "aidl/android/media/AudioFlag.aidl",
+        "aidl/android/media/AudioGain.aidl",
         "aidl/android/media/AudioGainConfig.aidl",
         "aidl/android/media/AudioGainMode.aidl",
         "aidl/android/media/AudioInputFlags.aidl",
         "aidl/android/media/AudioIoConfigEvent.aidl",
         "aidl/android/media/AudioIoDescriptor.aidl",
         "aidl/android/media/AudioIoFlags.aidl",
+        "aidl/android/media/AudioMixLatencyClass.aidl",
+        "aidl/android/media/AudioMode.aidl",
         "aidl/android/media/AudioOffloadInfo.aidl",
         "aidl/android/media/AudioOutputFlags.aidl",
         "aidl/android/media/AudioPatch.aidl",
+        "aidl/android/media/AudioPort.aidl",
         "aidl/android/media/AudioPortConfig.aidl",
         "aidl/android/media/AudioPortConfigType.aidl",
         "aidl/android/media/AudioPortConfigDeviceExt.aidl",
@@ -258,12 +301,21 @@
         "aidl/android/media/AudioPortConfigMixExt.aidl",
         "aidl/android/media/AudioPortConfigMixExtUseCase.aidl",
         "aidl/android/media/AudioPortConfigSessionExt.aidl",
+        "aidl/android/media/AudioPortDeviceExt.aidl",
+        "aidl/android/media/AudioPortExt.aidl",
+        "aidl/android/media/AudioPortMixExt.aidl",
         "aidl/android/media/AudioPortRole.aidl",
+        "aidl/android/media/AudioPortSessionExt.aidl",
         "aidl/android/media/AudioPortType.aidl",
+        "aidl/android/media/AudioProfile.aidl",
         "aidl/android/media/AudioSourceType.aidl",
         "aidl/android/media/AudioStreamType.aidl",
+        "aidl/android/media/AudioTimestampInternal.aidl",
+        "aidl/android/media/AudioUniqueIdUse.aidl",
         "aidl/android/media/AudioUsage.aidl",
-     ],
+        "aidl/android/media/AudioUuid.aidl",
+        "aidl/android/media/EffectDescriptor.aidl",
+    ],
     imports: [
         "audio_common-aidl",
     ],
@@ -285,16 +337,29 @@
     host_supported: true,
     vendor_available: true,
     srcs: [
+        "aidl/android/media/CreateEffectRequest.aidl",
+        "aidl/android/media/CreateEffectResponse.aidl",
         "aidl/android/media/CreateRecordRequest.aidl",
         "aidl/android/media/CreateRecordResponse.aidl",
         "aidl/android/media/CreateTrackRequest.aidl",
         "aidl/android/media/CreateTrackResponse.aidl",
+        "aidl/android/media/OpenInputRequest.aidl",
+        "aidl/android/media/OpenInputResponse.aidl",
+        "aidl/android/media/OpenOutputRequest.aidl",
+        "aidl/android/media/OpenOutputResponse.aidl",
+        "aidl/android/media/RenderPosition.aidl",
 
+        "aidl/android/media/IAudioFlingerService.aidl",
         "aidl/android/media/IAudioFlingerClient.aidl",
+        "aidl/android/media/IAudioRecord.aidl",
+        "aidl/android/media/IAudioTrack.aidl",
         "aidl/android/media/IAudioTrackCallback.aidl",
     ],
     imports: [
+        "audio_common-aidl",
         "audioclient-types-aidl",
+        "av-types-aidl",
+        "effect-aidl",
         "shared-file-region-aidl",
     ],
     double_loadable: true,
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index 1282474..79ea1bb 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -30,7 +30,7 @@
 #include <utils/Log.h>
 
 namespace android {
-
+using aidl_utils::statusTFromBinderStatus;
 using binder::Status;
 
 namespace {
@@ -101,9 +101,29 @@
     mClientPid = IPCThreadState::self()->getCallingPid();
     mClientUid = IPCThreadState::self()->getCallingUid();
 
-    iEffect = audioFlinger->createEffect((effect_descriptor_t *)&mDescriptor,
-            mIEffectClient, priority, io, mSessionId, device, mOpPackageName, mClientPid,
-            probe, &mStatus, &mId, &enabled);
+    media::CreateEffectRequest request;
+    request.desc = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_effect_descriptor_t_EffectDescriptor(mDescriptor));
+    request.client = mIEffectClient;
+    request.priority = priority;
+    request.output = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(io));
+    request.sessionId = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_session_t_int32_t(mSessionId));
+    request.device = VALUE_OR_RETURN_STATUS(legacy2aidl_AudioDeviceTypeAddress(device));
+    request.opPackageName = VALUE_OR_RETURN_STATUS(legacy2aidl_String16_string(mOpPackageName));
+    request.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(mClientPid));
+    request.probe = probe;
+
+    media::CreateEffectResponse response;
+
+    mStatus = audioFlinger->createEffect(request, &response);
+
+    if (mStatus == OK) {
+        mId = response.id;
+        enabled = response.enabled;
+        iEffect = response.effect;
+        mDescriptor = VALUE_OR_RETURN_STATUS(
+                aidl2legacy_EffectDescriptor_effect_descriptor_t(response.desc));
+    }
 
     // In probe mode, we stop here and return the status: the IEffect interface to
     // audio flinger will not be retained. initCheck() will return the creation status
@@ -242,7 +262,7 @@
             bs = mIEffect->disable(&status);
         }
         if (!bs.isOk()) {
-            status = bs.transactionError();
+            status = statusTFromBinderStatus(bs);
         }
         if (status == NO_ERROR) {
             mEnabled = enabled;
@@ -283,7 +303,7 @@
 
     Status bs = mIEffect->command(cmdCode, data, *replySize, &response, &status);
     if (!bs.isOk()) {
-        status = bs.transactionError();
+        status = statusTFromBinderStatus(bs);
     }
     if (status == NO_ERROR) {
         memcpy(replyData, response.data(), response.size());
@@ -331,7 +351,7 @@
                                   &response,
                                   &status);
     if (!bs.isOk()) {
-        status = bs.transactionError();
+        status = statusTFromBinderStatus(bs);
         return status;
     }
     assert(response.size() == sizeof(int));
@@ -390,7 +410,7 @@
                                   &response,
                                   &status);
     if (!bs.isOk()) {
-        status = bs.transactionError();
+        status = statusTFromBinderStatus(bs);
     }
     return status;
 }
@@ -421,7 +441,7 @@
 
     Status bs = mIEffect->command(EFFECT_CMD_GET_PARAM, cmd, psize, &response, &status);
     if (!bs.isOk()) {
-        status = bs.transactionError();
+        status = statusTFromBinderStatus(bs);
         return status;
     }
     memcpy(param, response.data(), response.size());
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 4d9fbb0..112cb67 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -47,6 +47,8 @@
 #define WAIT_PERIOD_MS          10
 
 namespace android {
+using aidl_utils::statusTFromBinderStatus;
+
 // ---------------------------------------------------------------------------
 
 // static
@@ -450,7 +452,7 @@
     mActive = true;
 
     if (!(flags & CBLK_INVALID)) {
-        status = mAudioRecord->start(event, triggerSession).transactionError();
+        status = statusTFromBinderStatus(mAudioRecord->start(event, triggerSession));
         if (status == DEAD_OBJECT) {
             flags |= CBLK_INVALID;
         }
@@ -748,7 +750,6 @@
     IAudioFlinger::CreateRecordInput input;
     IAudioFlinger::CreateRecordOutput output;
     audio_session_t originalSessionId;
-    sp<media::IAudioRecord> record;
     void *iMemPointer;
     audio_track_cblk_t* cblk;
     status_t status;
@@ -817,7 +818,7 @@
 
     do {
         media::CreateRecordResponse response;
-        record = audioFlinger->createRecord(VALUE_OR_FATAL(input.toAidl()), response, &status);
+        status = audioFlinger->createRecord(VALUE_OR_FATAL(input.toAidl()), response);
         output = VALUE_OR_FATAL(IAudioFlinger::CreateRecordOutput::fromAidl(response));
         if (status == NO_ERROR) {
             break;
@@ -893,7 +894,7 @@
         IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
         mDeathNotifier.clear();
     }
-    mAudioRecord = record;
+    mAudioRecord = output.audioRecord;
     mCblkMemory = output.cblk;
     mBufferMemory = output.buffers;
     IPCThreadState::self()->flushCommands();
@@ -1440,8 +1441,8 @@
         if (mActive) {
             // callback thread or sync event hasn't changed
             // FIXME this fails if we have a new AudioFlinger instance
-            result = mAudioRecord->start(
-                AudioSystem::SYNC_EVENT_SAME, AUDIO_SESSION_NONE).transactionError();
+            result = statusTFromBinderStatus(mAudioRecord->start(
+                AudioSystem::SYNC_EVENT_SAME, AUDIO_SESSION_NONE));
         }
         mFramesReadServerOffset = mFramesRead; // server resets to zero so we need an offset.
     }
@@ -1531,7 +1532,13 @@
 status_t AudioRecord::getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones)
 {
     AutoMutex lock(mLock);
-    return mAudioRecord->getActiveMicrophones(activeMicrophones).transactionError();
+    std::vector<media::MicrophoneInfoData> mics;
+    status_t status = statusTFromBinderStatus(mAudioRecord->getActiveMicrophones(&mics));
+    activeMicrophones->resize(mics.size());
+    for (size_t i = 0; status == OK && i < mics.size(); ++i) {
+        status = activeMicrophones->at(i).readFromParcelable(mics[i]);
+    }
+    return status;
 }
 
 status_t AudioRecord::setPreferredMicrophoneDirection(audio_microphone_direction_t direction)
@@ -1547,7 +1554,7 @@
         // the internal AudioRecord hasn't be created yet, so just stash the attribute.
         return OK;
     } else {
-        return mAudioRecord->setPreferredMicrophoneDirection(direction).transactionError();
+        return statusTFromBinderStatus(mAudioRecord->setPreferredMicrophoneDirection(direction));
     }
 }
 
@@ -1563,7 +1570,7 @@
         // the internal AudioRecord hasn't be created yet, so just stash the attribute.
         return OK;
     } else {
-        return mAudioRecord->setPreferredMicrophoneFieldDimension(zoom).transactionError();
+        return statusTFromBinderStatus(mAudioRecord->setPreferredMicrophoneFieldDimension(zoom));
     }
 }
 
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index cfe5f3a..09fcc66 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -33,9 +33,9 @@
 
 #include <system/audio.h>
 
-#define VALUE_OR_RETURN_STATUS(x) \
+#define VALUE_OR_RETURN_BINDER_STATUS(x) \
     ({ auto _tmp = (x); \
-       if (!_tmp.ok()) return Status::fromStatusT(_tmp.error()); \
+       if (!_tmp.ok()) return aidl_utils::binderStatusFromStatusT(_tmp.error()); \
        std::move(_tmp.value()); })
 
 // ----------------------------------------------------------------------------
@@ -71,7 +71,7 @@
             sp<IServiceManager> sm = defaultServiceManager();
             sp<IBinder> binder;
             do {
-                binder = sm->getService(String16("media.audio_flinger"));
+                binder = sm->getService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME));
                 if (binder != 0)
                     break;
                 ALOGW("AudioFlinger not published, waiting...");
@@ -83,7 +83,8 @@
                 reportNoError = true;
             }
             binder->linkToDeath(gAudioFlingerClient);
-            gAudioFlinger = interface_cast<IAudioFlinger>(binder);
+            gAudioFlinger = new AudioFlingerClientAdapter(
+                    interface_cast<media::IAudioFlingerService>(binder));
             LOG_ALWAYS_FATAL_IF(gAudioFlinger == 0);
             afc = gAudioFlingerClient;
             // Make sure callbacks can be received by gAudioFlingerClient
@@ -532,10 +533,10 @@
 Status AudioSystem::AudioFlingerClient::ioConfigChanged(
         media::AudioIoConfigEvent _event,
         const media::AudioIoDescriptor& _ioDesc) {
-    audio_io_config_event event = VALUE_OR_RETURN_STATUS(
+    audio_io_config_event event = VALUE_OR_RETURN_BINDER_STATUS(
             aidl2legacy_AudioIoConfigEvent_audio_io_config_event(_event));
     sp<AudioIoDescriptor> ioDesc(
-            VALUE_OR_RETURN_STATUS(aidl2legacy_AudioIoDescriptor_AudioIoDescriptor(_ioDesc)));
+            VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_AudioIoDescriptor_AudioIoDescriptor(_ioDesc)));
 
     ALOGV("ioConfigChanged() event %d", event);
 
@@ -1187,18 +1188,18 @@
     return aps->setAllowedCapturePolicy(uid, flags);
 }
 
-bool AudioSystem::isOffloadSupported(const audio_offload_info_t& info)
+audio_offload_mode_t AudioSystem::getOffloadSupport(const audio_offload_info_t& info)
 {
-    ALOGV("isOffloadSupported()");
+    ALOGV("%s", __func__);
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
-    if (aps == 0) return false;
-    return aps->isOffloadSupported(info);
+    if (aps == 0) return AUDIO_OFFLOAD_NOT_SUPPORTED;
+    return aps->getOffloadSupport(info);
 }
 
 status_t AudioSystem::listAudioPorts(audio_port_role_t role,
                                      audio_port_type_t type,
                                      unsigned int *num_ports,
-                                     struct audio_port *ports,
+                                     struct audio_port_v7 *ports,
                                      unsigned int *generation)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@@ -1206,7 +1207,7 @@
     return aps->listAudioPorts(role, type, num_ports, ports, generation);
 }
 
-status_t AudioSystem::getAudioPort(struct audio_port *port)
+status_t AudioSystem::getAudioPort(struct audio_port_v7 *port)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 14950a8..1b1e143 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -784,7 +784,7 @@
     int32_t flags = android_atomic_and(~(CBLK_STREAM_END_DONE | CBLK_DISABLED), &mCblk->mFlags);
 
     if (!(flags & CBLK_INVALID)) {
-        status = mAudioTrack->start();
+        mAudioTrack->start(&status);
         if (status == DEAD_OBJECT) {
             flags |= CBLK_INVALID;
         }
@@ -1477,7 +1477,8 @@
 status_t AudioTrack::attachAuxEffect(int effectId)
 {
     AutoMutex lock(mLock);
-    status_t status = mAudioTrack->attachAuxEffect(effectId);
+    status_t status;
+    mAudioTrack->attachAuxEffect(effectId, &status);
     if (status == NO_ERROR) {
         mAuxEffectId = effectId;
     }
@@ -1607,9 +1608,7 @@
     input.opPackageName = mOpPackageName;
 
     media::CreateTrackResponse response;
-    sp<IAudioTrack> track = audioFlinger->createTrack(VALUE_OR_FATAL(input.toAidl()),
-                                                      response,
-                                                      &status);
+    status = audioFlinger->createTrack(VALUE_OR_FATAL(input.toAidl()), response);
     IAudioFlinger::CreateTrackOutput output = VALUE_OR_FATAL(
             IAudioFlinger::CreateTrackOutput::fromAidl(
                     response));
@@ -1622,7 +1621,7 @@
         }
         goto exit;
     }
-    ALOG_ASSERT(track != 0);
+    ALOG_ASSERT(output.audioTrack != 0);
 
     mFrameCount = output.frameCount;
     mNotificationFramesAct = (uint32_t)output.notificationFrameCount;
@@ -1644,7 +1643,9 @@
     // so we are no longer responsible for releasing it.
 
     // FIXME compare to AudioRecord
-    sp<IMemory> iMem = track->getCblk();
+    std::optional<media::SharedFileRegion> sfr;
+    output.audioTrack->getCblk(&sfr);
+    sp<IMemory> iMem = VALUE_OR_FATAL(aidl2legacy_NullableSharedFileRegion_IMemory(sfr));
     if (iMem == 0) {
         ALOGE("%s(%d): Could not get control block", __func__, mPortId);
         status = NO_INIT;
@@ -1665,7 +1666,7 @@
         IInterface::asBinder(mAudioTrack)->unlinkToDeath(mDeathNotifier, this);
         mDeathNotifier.clear();
     }
-    mAudioTrack = track;
+    mAudioTrack = output.audioTrack;
     mCblkMemory = iMem;
     IPCThreadState::self()->flushCommands();
 
@@ -1721,7 +1722,7 @@
         }
     }
 
-    mAudioTrack->attachAuxEffect(mAuxEffectId);
+    mAudioTrack->attachAuxEffect(mAuxEffectId, &status);
 
     // If IAudioTrack is re-created, don't let the requested frameCount
     // decrease.  This can confuse clients that cache frameCount().
@@ -1965,7 +1966,8 @@
         ALOGW("%s(%d): releaseBuffer() track %p disabled due to previous underrun, restarting",
                 __func__, mPortId, this);
         // FIXME ignoring status
-        mAudioTrack->start();
+        status_t status;
+        mAudioTrack->start(&status);
     }
 }
 
@@ -2573,11 +2575,17 @@
             if (shaper.isStarted()) {
                 operationToEnd->setNormalizedTime(1.f);
             }
-            return mAudioTrack->applyVolumeShaper(shaper.mConfiguration, operationToEnd);
+            media::VolumeShaperConfiguration config;
+            shaper.mConfiguration->writeToParcelable(&config);
+            media::VolumeShaperOperation operation;
+            operationToEnd->writeToParcelable(&operation);
+            status_t status;
+            mAudioTrack->applyVolumeShaper(config, operation, &status);
+            return status;
         });
 
         if (mState == STATE_ACTIVE) {
-            result = mAudioTrack->start();
+            mAudioTrack->start(&result);
         }
         // server resets to zero so we offset
         mFramesWrittenServerOffset =
@@ -2647,7 +2655,9 @@
 status_t AudioTrack::setParameters(const String8& keyValuePairs)
 {
     AutoMutex lock(mLock);
-    return mAudioTrack->setParameters(keyValuePairs);
+    status_t status;
+    mAudioTrack->setParameters(keyValuePairs.c_str(), &status);
+    return status;
 }
 
 status_t AudioTrack::selectPresentation(int presentationId, int programId)
@@ -2659,7 +2669,9 @@
     ALOGV("%s(%d): PresentationId/ProgramId[%s]",
             __func__, mPortId, param.toString().string());
 
-    return mAudioTrack->setParameters(param.toString());
+    status_t status;
+    mAudioTrack->setParameters(param.toString().c_str(), &status);
+    return status;
 }
 
 VolumeShaper::Status AudioTrack::applyVolumeShaper(
@@ -2668,11 +2680,16 @@
 {
     AutoMutex lock(mLock);
     mVolumeHandler->setIdIfNecessary(configuration);
-    VolumeShaper::Status status = mAudioTrack->applyVolumeShaper(configuration, operation);
+    media::VolumeShaperConfiguration config;
+    configuration->writeToParcelable(&config);
+    media::VolumeShaperOperation op;
+    operation->writeToParcelable(&op);
+    VolumeShaper::Status status;
+    mAudioTrack->applyVolumeShaper(config, op, &status);
 
     if (status == DEAD_OBJECT) {
         if (restoreTrack_l("applyVolumeShaper") == OK) {
-            status = mAudioTrack->applyVolumeShaper(configuration, operation);
+            mAudioTrack->applyVolumeShaper(config, op, &status);
         }
     }
     if (status >= 0) {
@@ -2692,10 +2709,20 @@
 sp<VolumeShaper::State> AudioTrack::getVolumeShaperState(int id)
 {
     AutoMutex lock(mLock);
-    sp<VolumeShaper::State> state = mAudioTrack->getVolumeShaperState(id);
+    std::optional<media::VolumeShaperState> vss;
+    mAudioTrack->getVolumeShaperState(id, &vss);
+    sp<VolumeShaper::State> state;
+    if (vss.has_value()) {
+        state = new VolumeShaper::State();
+        state->readFromParcelable(vss.value());
+    }
     if (state.get() == nullptr && (mCblk->mFlags & CBLK_INVALID) != 0) {
         if (restoreTrack_l("getVolumeShaperState") == OK) {
-            state = mAudioTrack->getVolumeShaperState(id);
+            mAudioTrack->getVolumeShaperState(id, &vss);
+            if (vss.has_value()) {
+                state = new VolumeShaper::State();
+                state->readFromParcelable(vss.value());
+            }
         }
     }
     return state;
@@ -2789,7 +2816,11 @@
     status_t status;
     if (isOffloadedOrDirect_l()) {
         // use Binder to get timestamp
-        status = mAudioTrack->getTimestamp(timestamp);
+        media::AudioTimestampInternal ts;
+        mAudioTrack->getTimestamp(&ts, &status);
+        if (status == OK) {
+            timestamp = VALUE_OR_FATAL(aidl2legacy_AudioTimestampInternal_AudioTimestamp(ts));
+        }
     } else {
         // read timestamp from shared memory
         ExtendedTimestamp ets;
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 57142b0..20124df 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -24,90 +24,45 @@
 
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
-#include <media/AudioSanitizer.h>
-#include <media/IAudioPolicyService.h>
-#include <mediautils/ServiceUtilities.h>
-#include <mediautils/TimeCheck.h>
 #include "IAudioFlinger.h"
 
 namespace android {
 
-enum {
-    CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
-    CREATE_RECORD,
-    SAMPLE_RATE,
-    RESERVED,   // obsolete, was CHANNEL_COUNT
-    FORMAT,
-    FRAME_COUNT,
-    LATENCY,
-    SET_MASTER_VOLUME,
-    SET_MASTER_MUTE,
-    MASTER_VOLUME,
-    MASTER_MUTE,
-    SET_STREAM_VOLUME,
-    SET_STREAM_MUTE,
-    STREAM_VOLUME,
-    STREAM_MUTE,
-    SET_MODE,
-    SET_MIC_MUTE,
-    GET_MIC_MUTE,
-    SET_RECORD_SILENCED,
-    SET_PARAMETERS,
-    GET_PARAMETERS,
-    REGISTER_CLIENT,
-    GET_INPUTBUFFERSIZE,
-    OPEN_OUTPUT,
-    OPEN_DUPLICATE_OUTPUT,
-    CLOSE_OUTPUT,
-    SUSPEND_OUTPUT,
-    RESTORE_OUTPUT,
-    OPEN_INPUT,
-    CLOSE_INPUT,
-    INVALIDATE_STREAM,
-    SET_VOICE_VOLUME,
-    GET_RENDER_POSITION,
-    GET_INPUT_FRAMES_LOST,
-    NEW_AUDIO_UNIQUE_ID,
-    ACQUIRE_AUDIO_SESSION_ID,
-    RELEASE_AUDIO_SESSION_ID,
-    QUERY_NUM_EFFECTS,
-    QUERY_EFFECT,
-    GET_EFFECT_DESCRIPTOR,
-    CREATE_EFFECT,
-    MOVE_EFFECTS,
-    LOAD_HW_MODULE,
-    GET_PRIMARY_OUTPUT_SAMPLING_RATE,
-    GET_PRIMARY_OUTPUT_FRAME_COUNT,
-    SET_LOW_RAM_DEVICE,
-    LIST_AUDIO_PORTS,
-    GET_AUDIO_PORT,
-    CREATE_AUDIO_PATCH,
-    RELEASE_AUDIO_PATCH,
-    LIST_AUDIO_PATCHES,
-    SET_AUDIO_PORT_CONFIG,
-    GET_AUDIO_HW_SYNC_FOR_SESSION,
-    SYSTEM_READY,
-    FRAME_COUNT_HAL,
-    GET_MICROPHONES,
-    SET_MASTER_BALANCE,
-    GET_MASTER_BALANCE,
-    SET_EFFECT_SUSPENDED,
-    SET_AUDIO_HAL_PIDS
-};
+using aidl_utils::statusTFromBinderStatus;
+using binder::Status;
 
 #define MAX_ITEMS_PER_LIST 1024
 
+#define VALUE_OR_RETURN_BINDER(x)                                 \
+    ({                                                            \
+       auto _tmp = (x);                                           \
+       if (!_tmp.ok()) return Status::fromStatusT(_tmp.error());  \
+       std::move(_tmp.value()); \
+     })
+
+#define RETURN_STATUS_IF_ERROR(x)    \
+    {                                \
+       auto _tmp = (x);              \
+       if (_tmp != OK) return _tmp;  \
+    }
+
+#define RETURN_BINDER_IF_ERROR(x)                         \
+    {                                                     \
+       auto _tmp = (x);                                   \
+       if (_tmp != OK) return Status::fromStatusT(_tmp);  \
+    }
+
 ConversionResult<media::CreateTrackRequest> IAudioFlinger::CreateTrackInput::toAidl() const {
     media::CreateTrackRequest aidl;
     aidl.attr = VALUE_OR_RETURN(legacy2aidl_audio_attributes_t_AudioAttributesInternal(attr));
     aidl.config = VALUE_OR_RETURN(legacy2aidl_audio_config_t_AudioConfig(config));
-    aidl.clientInfo = VALUE_OR_RETURN(legacy2aidl_AudioClient(clientInfo));
+    aidl.clientInfo = VALUE_OR_RETURN(legacy2aidl_AudioClient_AudioClient(clientInfo));
     aidl.sharedBuffer = VALUE_OR_RETURN(legacy2aidl_NullableIMemory_SharedFileRegion(sharedBuffer));
     aidl.notificationsPerBuffer = VALUE_OR_RETURN(convertIntegral<int32_t>(notificationsPerBuffer));
     aidl.speed = speed;
     aidl.audioTrackCallback = audioTrackCallback;
     aidl.opPackageName = opPackageName;
-    aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_output_flags_mask(flags));
+    aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
     aidl.frameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(frameCount));
     aidl.notificationFrameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(notificationFrameCount));
     aidl.selectedDeviceId = VALUE_OR_RETURN(
@@ -121,14 +76,14 @@
     IAudioFlinger::CreateTrackInput legacy;
     legacy.attr = VALUE_OR_RETURN(aidl2legacy_AudioAttributesInternal_audio_attributes_t(aidl.attr));
     legacy.config = VALUE_OR_RETURN(aidl2legacy_AudioConfig_audio_config_t(aidl.config));
-    legacy.clientInfo = VALUE_OR_RETURN(aidl2legacy_AudioClient(aidl.clientInfo));
+    legacy.clientInfo = VALUE_OR_RETURN(aidl2legacy_AudioClient_AudioClient(aidl.clientInfo));
     legacy.sharedBuffer = VALUE_OR_RETURN(aidl2legacy_NullableSharedFileRegion_IMemory(aidl.sharedBuffer));
     legacy.notificationsPerBuffer = VALUE_OR_RETURN(
             convertIntegral<uint32_t>(aidl.notificationsPerBuffer));
     legacy.speed = aidl.speed;
     legacy.audioTrackCallback = aidl.audioTrackCallback;
     legacy.opPackageName = aidl.opPackageName;
-    legacy.flags = VALUE_OR_RETURN(aidl2legacy_audio_output_flags_mask(aidl.flags));
+    legacy.flags = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_output_flags_t_mask(aidl.flags));
     legacy.frameCount = VALUE_OR_RETURN(convertIntegral<size_t>(aidl.frameCount));
     legacy.notificationFrameCount = VALUE_OR_RETURN(
             convertIntegral<size_t>(aidl.notificationFrameCount));
@@ -141,7 +96,7 @@
 ConversionResult<media::CreateTrackResponse>
 IAudioFlinger::CreateTrackOutput::toAidl() const {
     media::CreateTrackResponse aidl;
-    aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_output_flags_mask(flags));
+    aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
     aidl.frameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(frameCount));
     aidl.notificationFrameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(notificationFrameCount));
     aidl.selectedDeviceId = VALUE_OR_RETURN(
@@ -153,6 +108,7 @@
     aidl.afLatencyMs = VALUE_OR_RETURN(convertIntegral<int32_t>(afLatencyMs));
     aidl.outputId = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(outputId));
     aidl.portId = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(portId));
+    aidl.audioTrack = audioTrack;
     return aidl;
 }
 
@@ -160,7 +116,7 @@
 IAudioFlinger::CreateTrackOutput::fromAidl(
         const media::CreateTrackResponse& aidl) {
     IAudioFlinger::CreateTrackOutput legacy;
-    legacy.flags = VALUE_OR_RETURN(aidl2legacy_audio_output_flags_mask(aidl.flags));
+    legacy.flags = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_output_flags_t_mask(aidl.flags));
     legacy.frameCount = VALUE_OR_RETURN(convertIntegral<size_t>(aidl.frameCount));
     legacy.notificationFrameCount = VALUE_OR_RETURN(
             convertIntegral<size_t>(aidl.notificationFrameCount));
@@ -173,6 +129,7 @@
     legacy.afLatencyMs = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.afLatencyMs));
     legacy.outputId = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_io_handle_t(aidl.outputId));
     legacy.portId = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.portId));
+    legacy.audioTrack = aidl.audioTrack;
     return legacy;
 }
 
@@ -181,10 +138,10 @@
     media::CreateRecordRequest aidl;
     aidl.attr = VALUE_OR_RETURN(legacy2aidl_audio_attributes_t_AudioAttributesInternal(attr));
     aidl.config = VALUE_OR_RETURN(legacy2aidl_audio_config_base_t_AudioConfigBase(config));
-    aidl.clientInfo = VALUE_OR_RETURN(legacy2aidl_AudioClient(clientInfo));
+    aidl.clientInfo = VALUE_OR_RETURN(legacy2aidl_AudioClient_AudioClient(clientInfo));
     aidl.opPackageName = VALUE_OR_RETURN(legacy2aidl_String16_string(opPackageName));
     aidl.riid = VALUE_OR_RETURN(legacy2aidl_audio_unique_id_t_int32_t(riid));
-    aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_input_flags_mask(flags));
+    aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_input_flags_t_int32_t_mask(flags));
     aidl.frameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(frameCount));
     aidl.notificationFrameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(notificationFrameCount));
     aidl.selectedDeviceId = VALUE_OR_RETURN(
@@ -199,10 +156,10 @@
     IAudioFlinger::CreateRecordInput legacy;
     legacy.attr = VALUE_OR_RETURN(aidl2legacy_AudioAttributesInternal_audio_attributes_t(aidl.attr));
     legacy.config = VALUE_OR_RETURN(aidl2legacy_AudioConfigBase_audio_config_base_t(aidl.config));
-    legacy.clientInfo = VALUE_OR_RETURN(aidl2legacy_AudioClient(aidl.clientInfo));
+    legacy.clientInfo = VALUE_OR_RETURN(aidl2legacy_AudioClient_AudioClient(aidl.clientInfo));
     legacy.opPackageName = VALUE_OR_RETURN(aidl2legacy_string_view_String16(aidl.opPackageName));
     legacy.riid = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_unique_id_t(aidl.riid));
-    legacy.flags = VALUE_OR_RETURN(aidl2legacy_audio_input_flags_mask(aidl.flags));
+    legacy.flags = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_input_flags_t_mask(aidl.flags));
     legacy.frameCount = VALUE_OR_RETURN(convertIntegral<size_t>(aidl.frameCount));
     legacy.notificationFrameCount = VALUE_OR_RETURN(
             convertIntegral<size_t>(aidl.notificationFrameCount));
@@ -215,7 +172,7 @@
 ConversionResult<media::CreateRecordResponse>
 IAudioFlinger::CreateRecordOutput::toAidl() const {
     media::CreateRecordResponse aidl;
-    aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_input_flags_mask(flags));
+    aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_input_flags_t_int32_t_mask(flags));
     aidl.frameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(frameCount));
     aidl.notificationFrameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(notificationFrameCount));
     aidl.selectedDeviceId = VALUE_OR_RETURN(
@@ -226,6 +183,7 @@
     aidl.cblk = VALUE_OR_RETURN(legacy2aidl_NullableIMemory_SharedFileRegion(cblk));
     aidl.buffers = VALUE_OR_RETURN(legacy2aidl_NullableIMemory_SharedFileRegion(buffers));
     aidl.portId = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(portId));
+    aidl.audioRecord = audioRecord;
     return aidl;
 }
 
@@ -233,7 +191,7 @@
 IAudioFlinger::CreateRecordOutput::fromAidl(
         const media::CreateRecordResponse& aidl) {
     IAudioFlinger::CreateRecordOutput legacy;
-    legacy.flags = VALUE_OR_RETURN(aidl2legacy_audio_input_flags_mask(aidl.flags));
+    legacy.flags = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_input_flags_t_mask(aidl.flags));
     legacy.frameCount = VALUE_OR_RETURN(convertIntegral<size_t>(aidl.frameCount));
     legacy.notificationFrameCount = VALUE_OR_RETURN(
             convertIntegral<size_t>(aidl.notificationFrameCount));
@@ -245,1549 +203,979 @@
     legacy.cblk = VALUE_OR_RETURN(aidl2legacy_NullableSharedFileRegion_IMemory(aidl.cblk));
     legacy.buffers = VALUE_OR_RETURN(aidl2legacy_NullableSharedFileRegion_IMemory(aidl.buffers));
     legacy.portId = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.portId));
+    legacy.audioRecord = aidl.audioRecord;
     return legacy;
 }
 
-class BpAudioFlinger : public BpInterface<IAudioFlinger>
-{
-public:
-    explicit BpAudioFlinger(const sp<IBinder>& impl)
-        : BpInterface<IAudioFlinger>(impl)
-    {
-    }
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// AudioFlingerClientAdapter
 
-    virtual sp<IAudioTrack> createTrack(const media::CreateTrackRequest& input,
-                                        media::CreateTrackResponse& output,
-                                        status_t* status)
-    {
-        Parcel data, reply;
-        sp<IAudioTrack> track;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+AudioFlingerClientAdapter::AudioFlingerClientAdapter(
+        const sp<media::IAudioFlingerService> delegate) : mDelegate(delegate) {}
 
-        if (status == nullptr) {
-            return track;
-        }
-
-        data.writeParcelable(input);
-
-        status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply);
-        if (lStatus != NO_ERROR) {
-            ALOGE("createTrack transaction error %d", lStatus);
-            *status = DEAD_OBJECT;
-            return track;
-        }
-        *status = reply.readInt32();
-        if (*status != NO_ERROR) {
-            ALOGE("createTrack returned error %d", *status);
-            return track;
-        }
-        track = interface_cast<IAudioTrack>(reply.readStrongBinder());
-        if (track == 0) {
-            ALOGE("createTrack returned an NULL IAudioTrack with status OK");
-            *status = DEAD_OBJECT;
-            return track;
-        }
-        output.readFromParcel(&reply);
-        return track;
-    }
-
-    virtual sp<media::IAudioRecord> createRecord(const media::CreateRecordRequest& input,
-                                                 media::CreateRecordResponse& output,
-                                                 status_t* status)
-    {
-        Parcel data, reply;
-        sp<media::IAudioRecord> record;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-
-        if (status == nullptr) {
-            return record;
-        }
-
-        data.writeParcelable(input);
-
-        status_t lStatus = remote()->transact(CREATE_RECORD, data, &reply);
-        if (lStatus != NO_ERROR) {
-            ALOGE("createRecord transaction error %d", lStatus);
-            *status = DEAD_OBJECT;
-            return record;
-        }
-        *status = reply.readInt32();
-        if (*status != NO_ERROR) {
-            ALOGE("createRecord returned error %d", *status);
-            return record;
-        }
-
-        record = interface_cast<media::IAudioRecord>(reply.readStrongBinder());
-        if (record == 0) {
-            ALOGE("createRecord returned a NULL IAudioRecord with status OK");
-            *status = DEAD_OBJECT;
-            return record;
-        }
-        output.readFromParcel(&reply);
-        return record;
-    }
-
-    virtual uint32_t sampleRate(audio_io_handle_t ioHandle) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) ioHandle);
-        remote()->transact(SAMPLE_RATE, data, &reply);
-        return reply.readInt32();
-    }
-
-    // RESERVED for channelCount()
-
-    virtual audio_format_t format(audio_io_handle_t output) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) output);
-        remote()->transact(FORMAT, data, &reply);
-        return (audio_format_t) reply.readInt32();
-    }
-
-    virtual size_t frameCount(audio_io_handle_t ioHandle) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) ioHandle);
-        remote()->transact(FRAME_COUNT, data, &reply);
-        return reply.readInt64();
-    }
-
-    virtual uint32_t latency(audio_io_handle_t output) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) output);
-        remote()->transact(LATENCY, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t setMasterVolume(float value)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeFloat(value);
-        remote()->transact(SET_MASTER_VOLUME, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t setMasterMute(bool muted)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(muted);
-        remote()->transact(SET_MASTER_MUTE, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual float masterVolume() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        remote()->transact(MASTER_VOLUME, data, &reply);
-        return reply.readFloat();
-    }
-
-    virtual bool masterMute() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        remote()->transact(MASTER_MUTE, data, &reply);
-        return reply.readInt32();
-    }
-
-    status_t setMasterBalance(float balance) override
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeFloat(balance);
-        status_t status = remote()->transact(SET_MASTER_BALANCE, data, &reply);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        return reply.readInt32();
-    }
-
-    status_t getMasterBalance(float *balance) const override
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_MASTER_BALANCE, data, &reply);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        status = (status_t)reply.readInt32();
-        if (status != NO_ERROR) {
-            return status;
-        }
-        *balance = reply.readFloat();
-        return NO_ERROR;
-    }
-
-    virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
-            audio_io_handle_t output)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) stream);
-        data.writeFloat(value);
-        data.writeInt32((int32_t) output);
-        remote()->transact(SET_STREAM_VOLUME, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t setStreamMute(audio_stream_type_t stream, bool muted)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) stream);
-        data.writeInt32(muted);
-        remote()->transact(SET_STREAM_MUTE, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual float streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) stream);
-        data.writeInt32((int32_t) output);
-        remote()->transact(STREAM_VOLUME, data, &reply);
-        return reply.readFloat();
-    }
-
-    virtual bool streamMute(audio_stream_type_t stream) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) stream);
-        remote()->transact(STREAM_MUTE, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t setMode(audio_mode_t mode)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(mode);
-        remote()->transact(SET_MODE, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t setMicMute(bool state)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(state);
-        remote()->transact(SET_MIC_MUTE, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual bool getMicMute() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        remote()->transact(GET_MIC_MUTE, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(portId);
-        data.writeInt32(silenced ? 1 : 0);
-        remote()->transact(SET_RECORD_SILENCED, data, &reply);
-    }
-
-    virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) ioHandle);
-        data.writeString8(keyValuePairs);
-        remote()->transact(SET_PARAMETERS, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) ioHandle);
-        data.writeString8(keys);
-        remote()->transact(GET_PARAMETERS, data, &reply);
-        return reply.readString8();
-    }
-
-    virtual void registerClient(const sp<media::IAudioFlingerClient>& client)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeStrongBinder(IInterface::asBinder(client));
-        remote()->transact(REGISTER_CLIENT, data, &reply);
-    }
-
-    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
-            audio_channel_mask_t channelMask) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(sampleRate);
-        data.writeInt32(format);
-        data.writeInt32(channelMask);
-        remote()->transact(GET_INPUTBUFFERSIZE, data, &reply);
-        return reply.readInt64();
-    }
-
-    virtual status_t openOutput(audio_module_handle_t module,
-                                audio_io_handle_t *output,
-                                audio_config_t *config,
-                                const sp<DeviceDescriptorBase>& device,
-                                uint32_t *latencyMs,
-                                audio_output_flags_t flags)
-    {
-        if (output == nullptr || config == nullptr || device == nullptr || latencyMs == nullptr) {
-            return BAD_VALUE;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(module);
-        data.write(config, sizeof(audio_config_t));
-        data.writeParcelable(*device);
-        data.writeInt32((int32_t) flags);
-        status_t status = remote()->transact(OPEN_OUTPUT, data, &reply);
-        if (status != NO_ERROR) {
-            *output = AUDIO_IO_HANDLE_NONE;
-            return status;
-        }
-        status = (status_t)reply.readInt32();
-        if (status != NO_ERROR) {
-            *output = AUDIO_IO_HANDLE_NONE;
-            return status;
-        }
-        *output = (audio_io_handle_t)reply.readInt32();
-        ALOGV("openOutput() returned output, %d", *output);
-        reply.read(config, sizeof(audio_config_t));
-        *latencyMs = reply.readInt32();
-        return NO_ERROR;
-    }
-
-    virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
-            audio_io_handle_t output2)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) output1);
-        data.writeInt32((int32_t) output2);
-        remote()->transact(OPEN_DUPLICATE_OUTPUT, data, &reply);
-        return (audio_io_handle_t) reply.readInt32();
-    }
-
-    virtual status_t closeOutput(audio_io_handle_t output)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) output);
-        remote()->transact(CLOSE_OUTPUT, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t suspendOutput(audio_io_handle_t output)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) output);
-        remote()->transact(SUSPEND_OUTPUT, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t restoreOutput(audio_io_handle_t output)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) output);
-        remote()->transact(RESTORE_OUTPUT, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t openInput(audio_module_handle_t module,
-                               audio_io_handle_t *input,
-                               audio_config_t *config,
-                               audio_devices_t *device,
-                               const String8& address,
-                               audio_source_t source,
-                               audio_input_flags_t flags)
-    {
-        if (input == NULL || config == NULL || device == NULL) {
-            return BAD_VALUE;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(module);
-        data.writeInt32(*input);
-        data.write(config, sizeof(audio_config_t));
-        data.writeInt32(*device);
-        data.writeString8(address);
-        data.writeInt32(source);
-        data.writeInt32(flags);
-        status_t status = remote()->transact(OPEN_INPUT, data, &reply);
-        if (status != NO_ERROR) {
-            *input = AUDIO_IO_HANDLE_NONE;
-            return status;
-        }
-        status = (status_t)reply.readInt32();
-        if (status != NO_ERROR) {
-            *input = AUDIO_IO_HANDLE_NONE;
-            return status;
-        }
-        *input = (audio_io_handle_t)reply.readInt32();
-        reply.read(config, sizeof(audio_config_t));
-        *device = (audio_devices_t)reply.readInt32();
-        return NO_ERROR;
-    }
-
-    virtual status_t closeInput(int input)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(input);
-        remote()->transact(CLOSE_INPUT, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t invalidateStream(audio_stream_type_t stream)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) stream);
-        remote()->transact(INVALIDATE_STREAM, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t setVoiceVolume(float volume)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeFloat(volume);
-        remote()->transact(SET_VOICE_VOLUME, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
-            audio_io_handle_t output) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) output);
-        remote()->transact(GET_RENDER_POSITION, data, &reply);
-        status_t status = reply.readInt32();
-        if (status == NO_ERROR) {
-            uint32_t tmp = reply.readInt32();
-            if (halFrames != NULL) {
-                *halFrames = tmp;
-            }
-            tmp = reply.readInt32();
-            if (dspFrames != NULL) {
-                *dspFrames = tmp;
-            }
-        }
-        return status;
-    }
-
-    virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) ioHandle);
-        status_t status = remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply);
-        if (status != NO_ERROR) {
-            return 0;
-        }
-        return (uint32_t) reply.readInt32();
-    }
-
-    virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) use);
-        status_t status = remote()->transact(NEW_AUDIO_UNIQUE_ID, data, &reply);
-        audio_unique_id_t id = AUDIO_UNIQUE_ID_ALLOCATE;
-        if (status == NO_ERROR) {
-            id = reply.readInt32();
-        }
-        return id;
-    }
-
-    void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) override
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(audioSession);
-        data.writeInt32((int32_t)pid);
-        data.writeInt32((int32_t)uid);
-        remote()->transact(ACQUIRE_AUDIO_SESSION_ID, data, &reply);
-    }
-
-    virtual void releaseAudioSessionId(audio_session_t audioSession, int pid)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(audioSession);
-        data.writeInt32(pid);
-        remote()->transact(RELEASE_AUDIO_SESSION_ID, data, &reply);
-    }
-
-    virtual status_t queryNumberEffects(uint32_t *numEffects) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        status_t status = remote()->transact(QUERY_NUM_EFFECTS, data, &reply);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        status = reply.readInt32();
-        if (status != NO_ERROR) {
-            return status;
-        }
-        if (numEffects != NULL) {
-            *numEffects = (uint32_t)reply.readInt32();
-        }
-        return NO_ERROR;
-    }
-
-    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const
-    {
-        if (pDescriptor == NULL) {
-            return BAD_VALUE;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(index);
-        status_t status = remote()->transact(QUERY_EFFECT, data, &reply);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        status = reply.readInt32();
-        if (status != NO_ERROR) {
-            return status;
-        }
-        reply.read(pDescriptor, sizeof(effect_descriptor_t));
-        return NO_ERROR;
-    }
-
-    virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid,
-                                         const effect_uuid_t *pType,
-                                         uint32_t preferredTypeFlag,
-                                         effect_descriptor_t *pDescriptor) const
-    {
-        if (pUuid == NULL || pType == NULL || pDescriptor == NULL) {
-            return BAD_VALUE;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.write(pUuid, sizeof(effect_uuid_t));
-        data.write(pType, sizeof(effect_uuid_t));
-        data.writeUint32(preferredTypeFlag);
-        status_t status = remote()->transact(GET_EFFECT_DESCRIPTOR, data, &reply);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        status = reply.readInt32();
-        if (status != NO_ERROR) {
-            return status;
-        }
-        reply.read(pDescriptor, sizeof(effect_descriptor_t));
-        return NO_ERROR;
-    }
-
-    virtual sp<media::IEffect> createEffect(
-                                    effect_descriptor_t *pDesc,
-                                    const sp<media::IEffectClient>& client,
-                                    int32_t priority,
-                                    audio_io_handle_t output,
-                                    audio_session_t sessionId,
-                                    const AudioDeviceTypeAddr& device,
-                                    const String16& opPackageName,
-                                    pid_t pid,
-                                    bool probe,
-                                    status_t *status,
-                                    int *id,
-                                    int *enabled)
-    {
-        Parcel data, reply;
-        sp<media::IEffect> effect;
-        if (pDesc == NULL) {
-            if (status != NULL) {
-                *status = BAD_VALUE;
-            }
-            return nullptr;
-        }
-
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.write(pDesc, sizeof(effect_descriptor_t));
-        data.writeStrongBinder(IInterface::asBinder(client));
-        data.writeInt32(priority);
-        data.writeInt32((int32_t) output);
-        data.writeInt32(sessionId);
-        if (data.writeParcelable(device) != NO_ERROR) {
-            if (status != NULL) {
-                *status = NO_INIT;
-            }
-            return nullptr;
-        }
-        data.writeString16(opPackageName);
-        data.writeInt32((int32_t) pid);
-        data.writeInt32(probe ? 1 : 0);
-
-        status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply);
-        if (lStatus != NO_ERROR) {
-            ALOGE("createEffect error: %s", strerror(-lStatus));
-        } else {
-            lStatus = reply.readInt32();
-            int tmp = reply.readInt32();
-            if (id != NULL) {
-                *id = tmp;
-            }
-            tmp = reply.readInt32();
-            if (enabled != NULL) {
-                *enabled = tmp;
-            }
-            effect = interface_cast<media::IEffect>(reply.readStrongBinder());
-            reply.read(pDesc, sizeof(effect_descriptor_t));
-        }
-        if (status != NULL) {
-            *status = lStatus;
-        }
-
-        return effect;
-    }
-
-    virtual status_t moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
-            audio_io_handle_t dstOutput)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(session);
-        data.writeInt32((int32_t) srcOutput);
-        data.writeInt32((int32_t) dstOutput);
-        remote()->transact(MOVE_EFFECTS, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual void setEffectSuspended(int effectId,
-                                    audio_session_t sessionId,
-                                    bool suspended)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(effectId);
-        data.writeInt32(sessionId);
-        data.writeInt32(suspended ? 1 : 0);
-        remote()->transact(SET_EFFECT_SUSPENDED, data, &reply);
-    }
-
-    virtual audio_module_handle_t loadHwModule(const char *name)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeCString(name);
-        remote()->transact(LOAD_HW_MODULE, data, &reply);
-        return (audio_module_handle_t) reply.readInt32();
-    }
-
-    virtual uint32_t getPrimaryOutputSamplingRate()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        remote()->transact(GET_PRIMARY_OUTPUT_SAMPLING_RATE, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual size_t getPrimaryOutputFrameCount()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        remote()->transact(GET_PRIMARY_OUTPUT_FRAME_COUNT, data, &reply);
-        return reply.readInt64();
-    }
-
-    virtual status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) override
-    {
-        Parcel data, reply;
-
-        static_assert(NO_ERROR == 0, "NO_ERROR must be 0");
-        return data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor())
-                ?: data.writeInt32((int) isLowRamDevice)
-                ?: data.writeInt64(totalMemory)
-                ?: remote()->transact(SET_LOW_RAM_DEVICE, data, &reply)
-                ?: reply.readInt32();
-    }
-
-    virtual status_t listAudioPorts(unsigned int *num_ports,
-                                    struct audio_port *ports)
-    {
-        if (num_ports == NULL || *num_ports == 0 || ports == NULL) {
-            return BAD_VALUE;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(*num_ports);
-        status_t status = remote()->transact(LIST_AUDIO_PORTS, data, &reply);
-        if (status != NO_ERROR ||
-                (status = (status_t)reply.readInt32()) != NO_ERROR) {
-            return status;
-        }
-        *num_ports = (unsigned int)reply.readInt32();
-        reply.read(ports, *num_ports * sizeof(struct audio_port));
-        return status;
-    }
-    virtual status_t getAudioPort(struct audio_port *port)
-    {
-        if (port == NULL) {
-            return BAD_VALUE;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.write(port, sizeof(struct audio_port));
-        status_t status = remote()->transact(GET_AUDIO_PORT, data, &reply);
-        if (status != NO_ERROR ||
-                (status = (status_t)reply.readInt32()) != NO_ERROR) {
-            return status;
-        }
-        reply.read(port, sizeof(struct audio_port));
-        return status;
-    }
-    virtual status_t createAudioPatch(const struct audio_patch *patch,
-                                       audio_patch_handle_t *handle)
-    {
-        if (patch == NULL || handle == NULL) {
-            return BAD_VALUE;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.write(patch, sizeof(struct audio_patch));
-        data.write(handle, sizeof(audio_patch_handle_t));
-        status_t status = remote()->transact(CREATE_AUDIO_PATCH, data, &reply);
-        if (status != NO_ERROR ||
-                (status = (status_t)reply.readInt32()) != NO_ERROR) {
-            return status;
-        }
-        reply.read(handle, sizeof(audio_patch_handle_t));
-        return status;
-    }
-    virtual status_t releaseAudioPatch(audio_patch_handle_t handle)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.write(&handle, sizeof(audio_patch_handle_t));
-        status_t status = remote()->transact(RELEASE_AUDIO_PATCH, data, &reply);
-        if (status != NO_ERROR) {
-            status = (status_t)reply.readInt32();
-        }
-        return status;
-    }
-    virtual status_t listAudioPatches(unsigned int *num_patches,
-                                      struct audio_patch *patches)
-    {
-        if (num_patches == NULL || *num_patches == 0 || patches == NULL) {
-            return BAD_VALUE;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(*num_patches);
-        status_t status = remote()->transact(LIST_AUDIO_PATCHES, data, &reply);
-        if (status != NO_ERROR ||
-                (status = (status_t)reply.readInt32()) != NO_ERROR) {
-            return status;
-        }
-        *num_patches = (unsigned int)reply.readInt32();
-        reply.read(patches, *num_patches * sizeof(struct audio_patch));
-        return status;
-    }
-    virtual status_t setAudioPortConfig(const struct audio_port_config *config)
-    {
-        if (config == NULL) {
-            return BAD_VALUE;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.write(config, sizeof(struct audio_port_config));
-        status_t status = remote()->transact(SET_AUDIO_PORT_CONFIG, data, &reply);
-        if (status != NO_ERROR) {
-            status = (status_t)reply.readInt32();
-        }
-        return status;
-    }
-    virtual audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(sessionId);
-        status_t status = remote()->transact(GET_AUDIO_HW_SYNC_FOR_SESSION, data, &reply);
-        if (status != NO_ERROR) {
-            return AUDIO_HW_SYNC_INVALID;
-        }
-        return (audio_hw_sync_t)reply.readInt32();
-    }
-    virtual status_t systemReady()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        return remote()->transact(SYSTEM_READY, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-    virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32((int32_t) ioHandle);
-        status_t status = remote()->transact(FRAME_COUNT_HAL, data, &reply);
-        if (status != NO_ERROR) {
-            return 0;
-        }
-        return reply.readInt64();
-    }
-    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_MICROPHONES, data, &reply);
-        if (status != NO_ERROR ||
-                (status = (status_t)reply.readInt32()) != NO_ERROR) {
-            return status;
-        }
-        status = reply.readParcelableVector(microphones);
-        return status;
-    }
-    virtual status_t setAudioHalPids(const std::vector<pid_t>& pids)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(pids.size());
-        for (auto pid : pids) {
-            data.writeInt32(pid);
-        }
-        status_t status = remote()->transact(SET_AUDIO_HAL_PIDS, data, &reply);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        return static_cast <status_t> (reply.readInt32());
-    }
-};
-
-IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
-
-// ----------------------------------------------------------------------
-
-status_t BnAudioFlinger::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    // make sure transactions reserved to AudioPolicyManager do not come from other processes
-    switch (code) {
-        case SET_STREAM_VOLUME:
-        case SET_STREAM_MUTE:
-        case OPEN_OUTPUT:
-        case OPEN_DUPLICATE_OUTPUT:
-        case CLOSE_OUTPUT:
-        case SUSPEND_OUTPUT:
-        case RESTORE_OUTPUT:
-        case OPEN_INPUT:
-        case CLOSE_INPUT:
-        case INVALIDATE_STREAM:
-        case SET_VOICE_VOLUME:
-        case MOVE_EFFECTS:
-        case SET_EFFECT_SUSPENDED:
-        case LOAD_HW_MODULE:
-        case LIST_AUDIO_PORTS:
-        case GET_AUDIO_PORT:
-        case CREATE_AUDIO_PATCH:
-        case RELEASE_AUDIO_PATCH:
-        case LIST_AUDIO_PATCHES:
-        case SET_AUDIO_PORT_CONFIG:
-        case SET_RECORD_SILENCED:
-            ALOGW("%s: transaction %d received from PID %d",
-                  __func__, code, IPCThreadState::self()->getCallingPid());
-            // return status only for non void methods
-            switch (code) {
-                case SET_RECORD_SILENCED:
-                case SET_EFFECT_SUSPENDED:
-                    break;
-                default:
-                    reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
-                    break;
-            }
-            return OK;
-        default:
-            break;
-    }
-
-    // make sure the following transactions come from system components
-    switch (code) {
-        case SET_MASTER_VOLUME:
-        case SET_MASTER_MUTE:
-        case SET_MODE:
-        case SET_MIC_MUTE:
-        case SET_LOW_RAM_DEVICE:
-        case SYSTEM_READY:
-        case SET_AUDIO_HAL_PIDS: {
-            if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
-                ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
-                      __func__, code, IPCThreadState::self()->getCallingPid(),
-                      IPCThreadState::self()->getCallingUid());
-                // return status only for non void methods
-                switch (code) {
-                    case SYSTEM_READY:
-                        break;
-                    default:
-                        reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
-                        break;
-                }
-                return OK;
-            }
-        } break;
-        default:
-            break;
-    }
-
-    // List of relevant events that trigger log merging.
-    // Log merging should activate during audio activity of any kind. This are considered the
-    // most relevant events.
-    // TODO should select more wisely the items from the list
-    switch (code) {
-        case CREATE_TRACK:
-        case CREATE_RECORD:
-        case SET_MASTER_VOLUME:
-        case SET_MASTER_MUTE:
-        case SET_MIC_MUTE:
-        case SET_PARAMETERS:
-        case CREATE_EFFECT:
-        case SYSTEM_READY: {
-            requestLogMerge();
-            break;
-        }
-        default:
-            break;
-    }
-
-    std::string tag("IAudioFlinger command " + std::to_string(code));
-    TimeCheck check(tag.c_str());
-
-    // Make sure we connect to Audio Policy Service before calling into AudioFlinger:
-    //  - AudioFlinger can call into Audio Policy Service with its global mutex held
-    //  - If this is the first time Audio Policy Service is queried from inside audioserver process
-    //  this will trigger Audio Policy Manager initialization.
-    //  - Audio Policy Manager initialization calls into AudioFlinger which will try to lock
-    //  its global mutex and a deadlock will occur.
-    if (IPCThreadState::self()->getCallingPid() != getpid()) {
-        AudioSystem::get_audio_policy_service();
-    }
-
-    switch (code) {
-        case CREATE_TRACK: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-
-            media::CreateTrackRequest input;
-            if (data.readParcelable(&input) != NO_ERROR) {
-                reply->writeInt32(DEAD_OBJECT);
-                return NO_ERROR;
-            }
-
-            status_t status;
-            media::CreateTrackResponse output;
-
-            sp<IAudioTrack> track= createTrack(input,
-                                               output,
-                                               &status);
-
-            LOG_ALWAYS_FATAL_IF((track != 0) != (status == NO_ERROR));
-            reply->writeInt32(status);
-            if (status != NO_ERROR) {
-                return NO_ERROR;
-            }
-            reply->writeStrongBinder(IInterface::asBinder(track));
-            output.writeToParcel(reply);
-            return NO_ERROR;
-        } break;
-        case CREATE_RECORD: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-
-            media::CreateRecordRequest input;
-            if (data.readParcelable(&input) != NO_ERROR) {
-                reply->writeInt32(DEAD_OBJECT);
-                return NO_ERROR;
-            }
-
-            status_t status;
-            media::CreateRecordResponse output;
-
-            sp<media::IAudioRecord> record = createRecord(input,
-                                                          output,
-                                                          &status);
-
-            LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
-            reply->writeInt32(status);
-            if (status != NO_ERROR) {
-                return NO_ERROR;
-            }
-            reply->writeStrongBinder(IInterface::asBinder(record));
-            output.writeToParcel(reply);
-            return NO_ERROR;
-        } break;
-        case SAMPLE_RATE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
-            return NO_ERROR;
-        } break;
-
-        // RESERVED for channelCount()
-
-        case FORMAT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
-            return NO_ERROR;
-        } break;
-        case FRAME_COUNT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt64( frameCount((audio_io_handle_t) data.readInt32()) );
-            return NO_ERROR;
-        } break;
-        case LATENCY: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( latency((audio_io_handle_t) data.readInt32()) );
-            return NO_ERROR;
-        } break;
-        case SET_MASTER_VOLUME: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( setMasterVolume(data.readFloat()) );
-            return NO_ERROR;
-        } break;
-        case SET_MASTER_MUTE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( setMasterMute(data.readInt32()) );
-            return NO_ERROR;
-        } break;
-        case MASTER_VOLUME: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeFloat( masterVolume() );
-            return NO_ERROR;
-        } break;
-        case MASTER_MUTE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( masterMute() );
-            return NO_ERROR;
-        } break;
-        case SET_MASTER_BALANCE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( setMasterBalance(data.readFloat()) );
-            return NO_ERROR;
-        } break;
-        case GET_MASTER_BALANCE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            float f;
-            const status_t status = getMasterBalance(&f);
-            reply->writeInt32((int32_t)status);
-            if (status == NO_ERROR) {
-                (void)reply->writeFloat(f);
-            }
-            return NO_ERROR;
-        } break;
-        case SET_STREAM_VOLUME: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int stream = data.readInt32();
-            float volume = data.readFloat();
-            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
-            reply->writeInt32( setStreamVolume((audio_stream_type_t) stream, volume, output) );
-            return NO_ERROR;
-        } break;
-        case SET_STREAM_MUTE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int stream = data.readInt32();
-            reply->writeInt32( setStreamMute((audio_stream_type_t) stream, data.readInt32()) );
-            return NO_ERROR;
-        } break;
-        case STREAM_VOLUME: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int stream = data.readInt32();
-            int output = data.readInt32();
-            reply->writeFloat( streamVolume((audio_stream_type_t) stream, output) );
-            return NO_ERROR;
-        } break;
-        case STREAM_MUTE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int stream = data.readInt32();
-            reply->writeInt32( streamMute((audio_stream_type_t) stream) );
-            return NO_ERROR;
-        } break;
-        case SET_MODE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_mode_t mode = (audio_mode_t) data.readInt32();
-            reply->writeInt32( setMode(mode) );
-            return NO_ERROR;
-        } break;
-        case SET_MIC_MUTE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int state = data.readInt32();
-            reply->writeInt32( setMicMute(state) );
-            return NO_ERROR;
-        } break;
-        case GET_MIC_MUTE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( getMicMute() );
-            return NO_ERROR;
-        } break;
-        case SET_RECORD_SILENCED: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_port_handle_t portId = data.readInt32();
-            bool silenced = data.readInt32() == 1;
-            setRecordSilenced(portId, silenced);
-            return NO_ERROR;
-        } break;
-        case SET_PARAMETERS: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
-            String8 keyValuePairs(data.readString8());
-            reply->writeInt32(setParameters(ioHandle, keyValuePairs));
-            return NO_ERROR;
-        } break;
-        case GET_PARAMETERS: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
-            String8 keys(data.readString8());
-            reply->writeString8(getParameters(ioHandle, keys));
-            return NO_ERROR;
-        } break;
-
-        case REGISTER_CLIENT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            sp<media::IAudioFlingerClient> client = interface_cast<media::IAudioFlingerClient>(
-                    data.readStrongBinder());
-            registerClient(client);
-            return NO_ERROR;
-        } break;
-        case GET_INPUTBUFFERSIZE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            uint32_t sampleRate = data.readInt32();
-            audio_format_t format = (audio_format_t) data.readInt32();
-            audio_channel_mask_t channelMask = (audio_channel_mask_t) data.readInt32();
-            reply->writeInt64( getInputBufferSize(sampleRate, format, channelMask) );
-            return NO_ERROR;
-        } break;
-        case OPEN_OUTPUT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
-            audio_config_t config = {};
-            if (data.read(&config, sizeof(audio_config_t)) != NO_ERROR) {
-                ALOGE("b/23905951");
-            }
-            sp<DeviceDescriptorBase> device = new DeviceDescriptorBase(AUDIO_DEVICE_NONE);
-            status_t status = NO_ERROR;
-            if ((status = data.readParcelable(device.get())) != NO_ERROR) {
-                reply->writeInt32((int32_t)status);
-                return NO_ERROR;
-            }
-            audio_output_flags_t flags = (audio_output_flags_t) data.readInt32();
-            uint32_t latencyMs = 0;
-            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-            status = openOutput(module, &output, &config, device, &latencyMs, flags);
-            ALOGV("OPEN_OUTPUT output, %d", output);
-            reply->writeInt32((int32_t)status);
-            if (status == NO_ERROR) {
-                reply->writeInt32((int32_t)output);
-                reply->write(&config, sizeof(audio_config_t));
-                reply->writeInt32(latencyMs);
-            }
-            return NO_ERROR;
-        } break;
-        case OPEN_DUPLICATE_OUTPUT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_io_handle_t output1 = (audio_io_handle_t) data.readInt32();
-            audio_io_handle_t output2 = (audio_io_handle_t) data.readInt32();
-            reply->writeInt32((int32_t) openDuplicateOutput(output1, output2));
-            return NO_ERROR;
-        } break;
-        case CLOSE_OUTPUT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(closeOutput((audio_io_handle_t) data.readInt32()));
-            return NO_ERROR;
-        } break;
-        case SUSPEND_OUTPUT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(suspendOutput((audio_io_handle_t) data.readInt32()));
-            return NO_ERROR;
-        } break;
-        case RESTORE_OUTPUT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(restoreOutput((audio_io_handle_t) data.readInt32()));
-            return NO_ERROR;
-        } break;
-        case OPEN_INPUT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
-            audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
-            audio_config_t config = {};
-            if (data.read(&config, sizeof(audio_config_t)) != NO_ERROR) {
-                ALOGE("b/23905951");
-            }
-            audio_devices_t device = (audio_devices_t)data.readInt32();
-            String8 address(data.readString8());
-            audio_source_t source = (audio_source_t)data.readInt32();
-            audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
-
-            status_t status = openInput(module, &input, &config,
-                                        &device, address, source, flags);
-            reply->writeInt32((int32_t) status);
-            if (status == NO_ERROR) {
-                reply->writeInt32((int32_t) input);
-                reply->write(&config, sizeof(audio_config_t));
-                reply->writeInt32(device);
-            }
-            return NO_ERROR;
-        } break;
-        case CLOSE_INPUT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(closeInput((audio_io_handle_t) data.readInt32()));
-            return NO_ERROR;
-        } break;
-        case INVALIDATE_STREAM: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_stream_type_t stream = (audio_stream_type_t) data.readInt32();
-            reply->writeInt32(invalidateStream(stream));
-            return NO_ERROR;
-        } break;
-        case SET_VOICE_VOLUME: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            float volume = data.readFloat();
-            reply->writeInt32( setVoiceVolume(volume) );
-            return NO_ERROR;
-        } break;
-        case GET_RENDER_POSITION: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
-            uint32_t halFrames = 0;
-            uint32_t dspFrames = 0;
-            status_t status = getRenderPosition(&halFrames, &dspFrames, output);
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->writeInt32(halFrames);
-                reply->writeInt32(dspFrames);
-            }
-            return NO_ERROR;
-        }
-        case GET_INPUT_FRAMES_LOST: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
-            reply->writeInt32((int32_t) getInputFramesLost(ioHandle));
-            return NO_ERROR;
-        } break;
-        case NEW_AUDIO_UNIQUE_ID: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(newAudioUniqueId((audio_unique_id_use_t) data.readInt32()));
-            return NO_ERROR;
-        } break;
-        case ACQUIRE_AUDIO_SESSION_ID: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_session_t audioSession = (audio_session_t) data.readInt32();
-            const pid_t pid = (pid_t)data.readInt32();
-            const uid_t uid = (uid_t)data.readInt32();
-            acquireAudioSessionId(audioSession, pid, uid);
-            return NO_ERROR;
-        } break;
-        case RELEASE_AUDIO_SESSION_ID: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_session_t audioSession = (audio_session_t) data.readInt32();
-            int pid = data.readInt32();
-            releaseAudioSessionId(audioSession, pid);
-            return NO_ERROR;
-        } break;
-        case QUERY_NUM_EFFECTS: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            uint32_t numEffects = 0;
-            status_t status = queryNumberEffects(&numEffects);
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->writeInt32((int32_t)numEffects);
-            }
-            return NO_ERROR;
-        }
-        case QUERY_EFFECT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            effect_descriptor_t desc = {};
-            status_t status = queryEffect(data.readInt32(), &desc);
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->write(&desc, sizeof(effect_descriptor_t));
-            }
-            return NO_ERROR;
-        }
-        case GET_EFFECT_DESCRIPTOR: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            effect_uuid_t uuid = {};
-            if (data.read(&uuid, sizeof(effect_uuid_t)) != NO_ERROR) {
-                android_errorWriteLog(0x534e4554, "139417189");
-            }
-            effect_uuid_t type = {};
-            if (data.read(&type, sizeof(effect_uuid_t)) != NO_ERROR) {
-                android_errorWriteLog(0x534e4554, "139417189");
-            }
-            uint32_t preferredTypeFlag = data.readUint32();
-            effect_descriptor_t desc = {};
-            status_t status = getEffectDescriptor(&uuid, &type, preferredTypeFlag, &desc);
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->write(&desc, sizeof(effect_descriptor_t));
-            }
-            return NO_ERROR;
-        }
-        case CREATE_EFFECT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            effect_descriptor_t desc = {};
-            if (data.read(&desc, sizeof(effect_descriptor_t)) != NO_ERROR) {
-                ALOGE("b/23905951");
-            }
-            sp<media::IEffectClient> client =
-                    interface_cast<media::IEffectClient>(data.readStrongBinder());
-            int32_t priority = data.readInt32();
-            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
-            audio_session_t sessionId = (audio_session_t) data.readInt32();
-            AudioDeviceTypeAddr device;
-            status_t status = NO_ERROR;
-            if ((status = data.readParcelable(&device)) != NO_ERROR) {
-                return status;
-            }
-            const String16 opPackageName = data.readString16();
-            pid_t pid = (pid_t)data.readInt32();
-            bool probe = data.readInt32() == 1;
-
-            int id = 0;
-            int enabled = 0;
-
-            sp<media::IEffect> effect = createEffect(&desc, client, priority, output, sessionId,
-                    device, opPackageName, pid, probe, &status, &id, &enabled);
-            reply->writeInt32(status);
-            reply->writeInt32(id);
-            reply->writeInt32(enabled);
-            reply->writeStrongBinder(IInterface::asBinder(effect));
-            reply->write(&desc, sizeof(effect_descriptor_t));
-            return NO_ERROR;
-        } break;
-        case MOVE_EFFECTS: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_session_t session = (audio_session_t) data.readInt32();
-            audio_io_handle_t srcOutput = (audio_io_handle_t) data.readInt32();
-            audio_io_handle_t dstOutput = (audio_io_handle_t) data.readInt32();
-            reply->writeInt32(moveEffects(session, srcOutput, dstOutput));
-            return NO_ERROR;
-        } break;
-        case SET_EFFECT_SUSPENDED: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int effectId = data.readInt32();
-            audio_session_t sessionId = (audio_session_t) data.readInt32();
-            bool suspended = data.readInt32() == 1;
-            setEffectSuspended(effectId, sessionId, suspended);
-            return NO_ERROR;
-        } break;
-        case LOAD_HW_MODULE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(loadHwModule(data.readCString()));
-            return NO_ERROR;
-        } break;
-        case GET_PRIMARY_OUTPUT_SAMPLING_RATE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(getPrimaryOutputSamplingRate());
-            return NO_ERROR;
-        } break;
-        case GET_PRIMARY_OUTPUT_FRAME_COUNT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt64(getPrimaryOutputFrameCount());
-            return NO_ERROR;
-        } break;
-        case SET_LOW_RAM_DEVICE: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int32_t isLowRamDevice;
-            int64_t totalMemory;
-            const status_t status =
-                    data.readInt32(&isLowRamDevice) ?:
-                    data.readInt64(&totalMemory) ?:
-                    setLowRamDevice(isLowRamDevice != 0, totalMemory);
-            (void)reply->writeInt32(status);
-            return NO_ERROR;
-        } break;
-        case LIST_AUDIO_PORTS: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            unsigned int numPortsReq = data.readInt32();
-            if (numPortsReq > MAX_ITEMS_PER_LIST) {
-                numPortsReq = MAX_ITEMS_PER_LIST;
-            }
-            unsigned int numPorts = numPortsReq;
-            struct audio_port *ports =
-                    (struct audio_port *)calloc(numPortsReq,
-                                                           sizeof(struct audio_port));
-            if (ports == NULL) {
-                reply->writeInt32(NO_MEMORY);
-                reply->writeInt32(0);
-                return NO_ERROR;
-            }
-            status_t status = listAudioPorts(&numPorts, ports);
-            reply->writeInt32(status);
-            reply->writeInt32(numPorts);
-            if (status == NO_ERROR) {
-                if (numPortsReq > numPorts) {
-                    numPortsReq = numPorts;
-                }
-                reply->write(ports, numPortsReq * sizeof(struct audio_port));
-            }
-            free(ports);
-            return NO_ERROR;
-        } break;
-        case GET_AUDIO_PORT: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            struct audio_port port = {};
-            status_t status = data.read(&port, sizeof(struct audio_port));
-            if (status != NO_ERROR) {
-                ALOGE("b/23905951");
-                return status;
-            }
-            status = AudioSanitizer::sanitizeAudioPort(&port);
-            if (status == NO_ERROR) {
-                status = getAudioPort(&port);
-            }
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->write(&port, sizeof(struct audio_port));
-            }
-            return NO_ERROR;
-        } break;
-        case CREATE_AUDIO_PATCH: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            struct audio_patch patch;
-            status_t status = data.read(&patch, sizeof(struct audio_patch));
-            if (status != NO_ERROR) {
-                return status;
-            }
-            audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
-            status = data.read(&handle, sizeof(audio_patch_handle_t));
-            if (status != NO_ERROR) {
-                ALOGE("b/23905951");
-                return status;
-            }
-            status = AudioSanitizer::sanitizeAudioPatch(&patch);
-            if (status == NO_ERROR) {
-                status = createAudioPatch(&patch, &handle);
-            }
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->write(&handle, sizeof(audio_patch_handle_t));
-            }
-            return NO_ERROR;
-        } break;
-        case RELEASE_AUDIO_PATCH: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            audio_patch_handle_t handle;
-            data.read(&handle, sizeof(audio_patch_handle_t));
-            status_t status = releaseAudioPatch(handle);
-            reply->writeInt32(status);
-            return NO_ERROR;
-        } break;
-        case LIST_AUDIO_PATCHES: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            unsigned int numPatchesReq = data.readInt32();
-            if (numPatchesReq > MAX_ITEMS_PER_LIST) {
-                numPatchesReq = MAX_ITEMS_PER_LIST;
-            }
-            unsigned int numPatches = numPatchesReq;
-            struct audio_patch *patches =
-                    (struct audio_patch *)calloc(numPatchesReq,
-                                                 sizeof(struct audio_patch));
-            if (patches == NULL) {
-                reply->writeInt32(NO_MEMORY);
-                reply->writeInt32(0);
-                return NO_ERROR;
-            }
-            status_t status = listAudioPatches(&numPatches, patches);
-            reply->writeInt32(status);
-            reply->writeInt32(numPatches);
-            if (status == NO_ERROR) {
-                if (numPatchesReq > numPatches) {
-                    numPatchesReq = numPatches;
-                }
-                reply->write(patches, numPatchesReq * sizeof(struct audio_patch));
-            }
-            free(patches);
-            return NO_ERROR;
-        } break;
-        case SET_AUDIO_PORT_CONFIG: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            struct audio_port_config config;
-            status_t status = data.read(&config, sizeof(struct audio_port_config));
-            if (status != NO_ERROR) {
-                return status;
-            }
-            status = AudioSanitizer::sanitizeAudioPortConfig(&config);
-            if (status == NO_ERROR) {
-                status = setAudioPortConfig(&config);
-            }
-            reply->writeInt32(status);
-            return NO_ERROR;
-        } break;
-        case GET_AUDIO_HW_SYNC_FOR_SESSION: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(getAudioHwSyncForSession((audio_session_t) data.readInt32()));
-            return NO_ERROR;
-        } break;
-        case SYSTEM_READY: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            systemReady();
-            return NO_ERROR;
-        } break;
-        case FRAME_COUNT_HAL: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt64( frameCountHAL((audio_io_handle_t) data.readInt32()) );
-            return NO_ERROR;
-        } break;
-        case GET_MICROPHONES: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            std::vector<media::MicrophoneInfo> microphones;
-            status_t status = getMicrophones(&microphones);
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->writeParcelableVector(microphones);
-            }
-            return NO_ERROR;
-        }
-        case SET_AUDIO_HAL_PIDS: {
-            CHECK_INTERFACE(IAudioFlinger, data, reply);
-            std::vector<pid_t> pids;
-            int32_t size;
-            status_t status = data.readInt32(&size);
-            if (status != NO_ERROR) {
-                return status;
-            }
-            if (size < 0) {
-                return BAD_VALUE;
-            }
-            if (size > MAX_ITEMS_PER_LIST) {
-                size = MAX_ITEMS_PER_LIST;
-            }
-            for (int32_t i = 0; i < size; i++) {
-                int32_t pid;
-                status =  data.readInt32(&pid);
-                if (status != NO_ERROR) {
-                    return status;
-                }
-                pids.push_back(pid);
-            }
-            reply->writeInt32(setAudioHalPids(pids));
-            return NO_ERROR;
-        }
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
+status_t AudioFlingerClientAdapter::createTrack(const media::CreateTrackRequest& input,
+                                                media::CreateTrackResponse& output) {
+    return statusTFromBinderStatus(mDelegate->createTrack(input, &output));
 }
 
-// ----------------------------------------------------------------------------
+status_t AudioFlingerClientAdapter::createRecord(const media::CreateRecordRequest& input,
+                                                 media::CreateRecordResponse& output) {
+    return statusTFromBinderStatus(mDelegate->createRecord(input, &output));
+}
+
+uint32_t AudioFlingerClientAdapter::sampleRate(audio_io_handle_t ioHandle) const {
+    auto result = [&]() -> ConversionResult<uint32_t> {
+        int32_t ioHandleAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
+        int32_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->sampleRate(ioHandleAidl, &aidlRet)));
+        return convertIntegral<uint32_t>(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(0);
+}
+
+audio_format_t AudioFlingerClientAdapter::format(audio_io_handle_t output) const {
+    auto result = [&]() -> ConversionResult<audio_format_t> {
+        int32_t outputAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(output));
+        media::audio::common::AudioFormat aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->format(outputAidl, &aidlRet)));
+        return aidl2legacy_AudioFormat_audio_format_t(aidlRet);
+    }();
+    return result.value_or(AUDIO_FORMAT_INVALID);
+}
+
+size_t AudioFlingerClientAdapter::frameCount(audio_io_handle_t ioHandle) const {
+    auto result = [&]() -> ConversionResult<size_t> {
+        int32_t ioHandleAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
+        int64_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->frameCount(ioHandleAidl, &aidlRet)));
+        return convertIntegral<size_t>(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(0);
+}
+
+uint32_t AudioFlingerClientAdapter::latency(audio_io_handle_t output) const {
+    auto result = [&]() -> ConversionResult<uint32_t> {
+        int32_t outputAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(output));
+        int32_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->latency(outputAidl, &aidlRet)));
+        return convertIntegral<uint32_t>(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(0);
+}
+
+status_t AudioFlingerClientAdapter::setMasterVolume(float value) {
+    return statusTFromBinderStatus(mDelegate->setMasterVolume(value));
+}
+
+status_t AudioFlingerClientAdapter::setMasterMute(bool muted) {
+    return statusTFromBinderStatus(mDelegate->setMasterMute(muted));
+}
+
+float AudioFlingerClientAdapter::masterVolume() const {
+    auto result = [&]() -> ConversionResult<float> {
+        float aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->masterVolume(&aidlRet)));
+        return aidlRet;
+    }();
+    // Failure is ignored.
+    return result.value_or(0.f);
+}
+
+bool AudioFlingerClientAdapter::masterMute() const {
+    auto result = [&]() -> ConversionResult<bool> {
+        bool aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(mDelegate->masterMute(&aidlRet)));
+        return aidlRet;
+    }();
+    // Failure is ignored.
+    return result.value_or(false);
+}
+
+status_t AudioFlingerClientAdapter::setMasterBalance(float balance) {
+    return statusTFromBinderStatus(mDelegate->setMasterBalance(balance));
+}
+
+status_t AudioFlingerClientAdapter::getMasterBalance(float* balance) const{
+    return statusTFromBinderStatus(mDelegate->getMasterBalance(balance));
+}
+
+status_t AudioFlingerClientAdapter::setStreamVolume(audio_stream_type_t stream, float value,
+                                                    audio_io_handle_t output) {
+    media::AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
+    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
+    return statusTFromBinderStatus(mDelegate->setStreamVolume(streamAidl, value, outputAidl));
+}
+
+status_t AudioFlingerClientAdapter::setStreamMute(audio_stream_type_t stream, bool muted) {
+    media::AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
+    return statusTFromBinderStatus(mDelegate->setStreamMute(streamAidl, muted));
+}
+
+float AudioFlingerClientAdapter::streamVolume(audio_stream_type_t stream,
+                                              audio_io_handle_t output) const {
+    auto result = [&]() -> ConversionResult<float> {
+        media::AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
+                legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
+        int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
+        float aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->streamVolume(streamAidl, outputAidl, &aidlRet)));
+        return aidlRet;
+    }();
+    // Failure is ignored.
+    return result.value_or(0.f);
+}
+
+bool AudioFlingerClientAdapter::streamMute(audio_stream_type_t stream) const {
+    auto result = [&]() -> ConversionResult<bool> {
+        media::AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
+                legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
+        bool aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->streamMute(streamAidl, &aidlRet)));
+        return aidlRet;
+    }();
+    // Failure is ignored.
+    return result.value_or(false);
+}
+
+status_t AudioFlingerClientAdapter::setMode(audio_mode_t mode) {
+    media::AudioMode modeAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_mode_t_AudioMode(mode));
+    return statusTFromBinderStatus(mDelegate->setMode(modeAidl));
+}
+
+status_t AudioFlingerClientAdapter::setMicMute(bool state) {
+    return statusTFromBinderStatus(mDelegate->setMicMute(state));
+}
+
+bool AudioFlingerClientAdapter::getMicMute() const {
+    auto result = [&]() -> ConversionResult<bool> {
+        bool aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getMicMute(&aidlRet)));
+        return aidlRet;
+    }();
+    // Failure is ignored.
+    return result.value_or(false);
+}
+
+void AudioFlingerClientAdapter::setRecordSilenced(audio_port_handle_t portId, bool silenced) {
+    auto result = [&]() -> status_t {
+        int32_t portIdAidl = VALUE_OR_RETURN_STATUS(
+                legacy2aidl_audio_port_handle_t_int32_t(portId));
+        return statusTFromBinderStatus(mDelegate->setRecordSilenced(portIdAidl, silenced));
+    }();
+    // Failure is ignored.
+    (void) result;
+}
+
+status_t AudioFlingerClientAdapter::setParameters(audio_io_handle_t ioHandle,
+                                                  const String8& keyValuePairs) {
+    int32_t ioHandleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
+    std::string keyValuePairsAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_String8_string(keyValuePairs));
+    return statusTFromBinderStatus(mDelegate->setParameters(ioHandleAidl, keyValuePairsAidl));
+}
+
+String8 AudioFlingerClientAdapter::getParameters(audio_io_handle_t ioHandle, const String8& keys)
+const {
+    auto result = [&]() -> ConversionResult<String8> {
+        int32_t ioHandleAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
+        std::string keysAidl = VALUE_OR_RETURN(legacy2aidl_String8_string(keys));
+        std::string aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getParameters(ioHandleAidl, keysAidl, &aidlRet)));
+        return aidl2legacy_string_view_String8(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(String8());
+}
+
+void AudioFlingerClientAdapter::registerClient(const sp<media::IAudioFlingerClient>& client) {
+    mDelegate->registerClient(client);
+    // Failure is ignored.
+}
+
+size_t AudioFlingerClientAdapter::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+                                                     audio_channel_mask_t channelMask) const {
+    auto result = [&]() -> ConversionResult<size_t> {
+        int32_t sampleRateAidl = VALUE_OR_RETURN(convertIntegral<int32_t>(sampleRate));
+        media::audio::common::AudioFormat formatAidl = VALUE_OR_RETURN(
+                legacy2aidl_audio_format_t_AudioFormat(format));
+        int32_t channelMaskAidl = VALUE_OR_RETURN(
+                legacy2aidl_audio_channel_mask_t_int32_t(channelMask));
+        int64_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getInputBufferSize(sampleRateAidl, formatAidl, channelMaskAidl,
+                                              &aidlRet)));
+        return convertIntegral<size_t>(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(0);
+}
+
+status_t AudioFlingerClientAdapter::openOutput(const media::OpenOutputRequest& request,
+                                               media::OpenOutputResponse* response) {
+    return statusTFromBinderStatus(mDelegate->openOutput(request, response));
+}
+
+audio_io_handle_t AudioFlingerClientAdapter::openDuplicateOutput(audio_io_handle_t output1,
+                                                                 audio_io_handle_t output2) {
+    auto result = [&]() -> ConversionResult<audio_io_handle_t> {
+        int32_t output1Aidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(output1));
+        int32_t output2Aidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(output2));
+        int32_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->openDuplicateOutput(output1Aidl, output2Aidl, &aidlRet)));
+        return aidl2legacy_int32_t_audio_io_handle_t(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(0);
+}
+
+status_t AudioFlingerClientAdapter::closeOutput(audio_io_handle_t output) {
+    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
+    return statusTFromBinderStatus(mDelegate->closeOutput(outputAidl));
+}
+
+status_t AudioFlingerClientAdapter::suspendOutput(audio_io_handle_t output) {
+    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
+    return statusTFromBinderStatus(mDelegate->suspendOutput(outputAidl));
+}
+
+status_t AudioFlingerClientAdapter::restoreOutput(audio_io_handle_t output) {
+    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
+    return statusTFromBinderStatus(mDelegate->restoreOutput(outputAidl));
+}
+
+status_t AudioFlingerClientAdapter::openInput(const media::OpenInputRequest& request,
+                                              media::OpenInputResponse* response) {
+    return statusTFromBinderStatus(mDelegate->openInput(request, response));
+}
+
+status_t AudioFlingerClientAdapter::closeInput(audio_io_handle_t input) {
+    int32_t inputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(input));
+    return statusTFromBinderStatus(mDelegate->closeInput(inputAidl));
+}
+
+status_t AudioFlingerClientAdapter::invalidateStream(audio_stream_type_t stream) {
+    media::AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
+    return statusTFromBinderStatus(mDelegate->invalidateStream(streamAidl));
+}
+
+status_t AudioFlingerClientAdapter::setVoiceVolume(float volume) {
+    return statusTFromBinderStatus(mDelegate->setVoiceVolume(volume));
+}
+
+status_t AudioFlingerClientAdapter::getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames,
+                                                      audio_io_handle_t output) const {
+    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
+    media::RenderPosition aidlRet;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->getRenderPosition(outputAidl, &aidlRet)));
+    if (halFrames != nullptr) {
+        *halFrames = VALUE_OR_RETURN_STATUS(convertIntegral<uint32_t>(aidlRet.halFrames));
+    }
+    if (dspFrames != nullptr) {
+        *dspFrames = VALUE_OR_RETURN_STATUS(convertIntegral<uint32_t>(aidlRet.dspFrames));
+    }
+    return OK;
+}
+
+uint32_t AudioFlingerClientAdapter::getInputFramesLost(audio_io_handle_t ioHandle) const {
+    auto result = [&]() -> ConversionResult<uint32_t> {
+        int32_t ioHandleAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
+        int32_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getInputFramesLost(ioHandleAidl, &aidlRet)));
+        return convertIntegral<uint32_t>(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(0);
+}
+
+audio_unique_id_t AudioFlingerClientAdapter::newAudioUniqueId(audio_unique_id_use_t use) {
+    auto result = [&]() -> ConversionResult<audio_unique_id_t> {
+        media::AudioUniqueIdUse useAidl = VALUE_OR_RETURN(
+                legacy2aidl_audio_unique_id_use_t_AudioUniqueIdUse(use));
+        int32_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->newAudioUniqueId(useAidl, &aidlRet)));
+        return aidl2legacy_int32_t_audio_unique_id_t(aidlRet);
+    }();
+    return result.value_or(AUDIO_UNIQUE_ID_ALLOCATE);
+}
+
+void AudioFlingerClientAdapter::acquireAudioSessionId(audio_session_t audioSession, pid_t pid,
+                                                      uid_t uid) {
+    [&]() -> status_t {
+        int32_t audioSessionAidl = VALUE_OR_RETURN_STATUS(
+                legacy2aidl_audio_session_t_int32_t(audioSession));
+        int32_t pidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(pid));
+        int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(uid));
+        return statusTFromBinderStatus(
+                mDelegate->acquireAudioSessionId(audioSessionAidl, pidAidl, uidAidl));
+    }();
+    // Failure is ignored.
+}
+
+void AudioFlingerClientAdapter::releaseAudioSessionId(audio_session_t audioSession, pid_t pid) {
+    [&]() -> status_t {
+        int32_t audioSessionAidl = VALUE_OR_RETURN_STATUS(
+                legacy2aidl_audio_session_t_int32_t(audioSession));
+        int32_t pidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(pid));
+        return statusTFromBinderStatus(
+                mDelegate->releaseAudioSessionId(audioSessionAidl, pidAidl));
+    }();
+    // Failure is ignored.
+}
+
+status_t AudioFlingerClientAdapter::queryNumberEffects(uint32_t* numEffects) const {
+    int32_t aidlRet;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->queryNumberEffects(&aidlRet)));
+    if (numEffects != nullptr) {
+        *numEffects = VALUE_OR_RETURN_STATUS(convertIntegral<uint32_t>(aidlRet));
+    }
+    return OK;
+}
+
+status_t
+AudioFlingerClientAdapter::queryEffect(uint32_t index, effect_descriptor_t* pDescriptor) const {
+    int32_t indexAidl = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(index));
+    media::EffectDescriptor aidlRet;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->queryEffect(indexAidl, &aidlRet)));
+    if (pDescriptor != nullptr) {
+        *pDescriptor = VALUE_OR_RETURN_STATUS(
+                aidl2legacy_EffectDescriptor_effect_descriptor_t(aidlRet));
+    }
+    return OK;
+}
+
+status_t AudioFlingerClientAdapter::getEffectDescriptor(const effect_uuid_t* pEffectUUID,
+                                                        const effect_uuid_t* pTypeUUID,
+                                                        uint32_t preferredTypeFlag,
+                                                        effect_descriptor_t* pDescriptor) const {
+    media::AudioUuid effectUuidAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_uuid_t_AudioUuid(*pEffectUUID));
+    media::AudioUuid typeUuidAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_uuid_t_AudioUuid(*pTypeUUID));
+    int32_t preferredTypeFlagAidl = VALUE_OR_RETURN_STATUS(
+            convertReinterpret<int32_t>(preferredTypeFlag));
+    media::EffectDescriptor aidlRet;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->getEffectDescriptor(effectUuidAidl, typeUuidAidl, preferredTypeFlagAidl,
+                                           &aidlRet)));
+    if (pDescriptor != nullptr) {
+        *pDescriptor = VALUE_OR_RETURN_STATUS(
+                aidl2legacy_EffectDescriptor_effect_descriptor_t(aidlRet));
+    }
+    return OK;
+}
+
+status_t AudioFlingerClientAdapter::createEffect(const media::CreateEffectRequest& request,
+                                                 media::CreateEffectResponse* response) {
+    return statusTFromBinderStatus(mDelegate->createEffect(request, response));
+}
+
+status_t
+AudioFlingerClientAdapter::moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
+                                       audio_io_handle_t dstOutput) {
+    int32_t sessionAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_session_t_int32_t(session));
+    int32_t srcOutputAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_io_handle_t_int32_t(srcOutput));
+    int32_t dstOutputAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_io_handle_t_int32_t(dstOutput));
+    return statusTFromBinderStatus(
+            mDelegate->moveEffects(sessionAidl, srcOutputAidl, dstOutputAidl));
+}
+
+void AudioFlingerClientAdapter::setEffectSuspended(int effectId,
+                                                   audio_session_t sessionId,
+                                                   bool suspended) {
+    [&]() -> status_t {
+        int32_t effectIdAidl = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(effectId));
+        int32_t sessionIdAidl = VALUE_OR_RETURN_STATUS(
+                legacy2aidl_audio_session_t_int32_t(sessionId));
+        return statusTFromBinderStatus(
+                mDelegate->setEffectSuspended(effectIdAidl, sessionIdAidl, suspended));
+    }();
+    // Failure is ignored.
+}
+
+audio_module_handle_t AudioFlingerClientAdapter::loadHwModule(const char* name) {
+    auto result = [&]() -> ConversionResult<audio_module_handle_t> {
+        std::string nameAidl(name);
+        int32_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->loadHwModule(nameAidl, &aidlRet)));
+        return aidl2legacy_int32_t_audio_module_handle_t(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(0);
+}
+
+uint32_t AudioFlingerClientAdapter::getPrimaryOutputSamplingRate() {
+    auto result = [&]() -> ConversionResult<uint32_t> {
+        int32_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getPrimaryOutputSamplingRate(&aidlRet)));
+        return convertIntegral<uint32_t>(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(0);
+}
+
+size_t AudioFlingerClientAdapter::getPrimaryOutputFrameCount() {
+    auto result = [&]() -> ConversionResult<size_t> {
+        int64_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getPrimaryOutputFrameCount(&aidlRet)));
+        return convertIntegral<size_t>(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(0);
+}
+
+status_t AudioFlingerClientAdapter::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) {
+    return statusTFromBinderStatus(mDelegate->setLowRamDevice(isLowRamDevice, totalMemory));
+}
+
+status_t AudioFlingerClientAdapter::getAudioPort(struct audio_port_v7* port) {
+    media::AudioPort portAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_v7_AudioPort(*port));
+    media::AudioPort aidlRet;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->getAudioPort(portAidl, &aidlRet)));
+    *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPort_audio_port_v7(aidlRet));
+    return OK;
+}
+
+status_t AudioFlingerClientAdapter::createAudioPatch(const struct audio_patch* patch,
+                                                     audio_patch_handle_t* handle) {
+    media::AudioPatch patchAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_AudioPatch(*patch));
+    int32_t aidlRet;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->createAudioPatch(patchAidl, &aidlRet)));
+    if (handle != nullptr) {
+        *handle = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_patch_handle_t(aidlRet));
+    }
+    return OK;
+}
+
+status_t AudioFlingerClientAdapter::releaseAudioPatch(audio_patch_handle_t handle) {
+    int32_t handleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_handle_t_int32_t(handle));
+    return statusTFromBinderStatus(mDelegate->releaseAudioPatch(handleAidl));
+}
+
+status_t AudioFlingerClientAdapter::listAudioPatches(unsigned int* num_patches,
+                                                     struct audio_patch* patches) {
+    std::vector<media::AudioPatch> aidlRet;
+    int32_t maxPatches = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*num_patches));
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->listAudioPatches(maxPatches, &aidlRet)));
+    *num_patches = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(aidlRet.size()));
+    return convertRange(aidlRet.begin(), aidlRet.end(), patches,
+                        aidl2legacy_AudioPatch_audio_patch);
+}
+
+status_t AudioFlingerClientAdapter::setAudioPortConfig(const struct audio_port_config* config) {
+    media::AudioPortConfig configAidl = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_port_config_AudioPortConfig(*config));
+    return statusTFromBinderStatus(mDelegate->setAudioPortConfig(configAidl));
+}
+
+audio_hw_sync_t AudioFlingerClientAdapter::getAudioHwSyncForSession(audio_session_t sessionId) {
+    auto result = [&]() -> ConversionResult<audio_hw_sync_t> {
+        int32_t sessionIdAidl = VALUE_OR_RETURN(legacy2aidl_audio_session_t_int32_t(sessionId));
+        int32_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->getAudioHwSyncForSession(sessionIdAidl, &aidlRet)));
+        return aidl2legacy_int32_t_audio_hw_sync_t(aidlRet);
+    }();
+    return result.value_or(AUDIO_HW_SYNC_INVALID);
+}
+
+status_t AudioFlingerClientAdapter::systemReady() {
+    return statusTFromBinderStatus(mDelegate->systemReady());
+}
+
+size_t AudioFlingerClientAdapter::frameCountHAL(audio_io_handle_t ioHandle) const {
+    auto result = [&]() -> ConversionResult<size_t> {
+        int32_t ioHandleAidl = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(ioHandle));
+        int64_t aidlRet;
+        RETURN_IF_ERROR(statusTFromBinderStatus(
+                mDelegate->frameCountHAL(ioHandleAidl, &aidlRet)));
+        return convertIntegral<size_t>(aidlRet);
+    }();
+    // Failure is ignored.
+    return result.value_or(0);
+}
+
+status_t
+AudioFlingerClientAdapter::getMicrophones(std::vector<media::MicrophoneInfo>* microphones) {
+    std::vector<media::MicrophoneInfoData> aidlRet;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+            mDelegate->getMicrophones(&aidlRet)));
+    if (microphones != nullptr) {
+        *microphones = VALUE_OR_RETURN_STATUS(
+                convertContainer<std::vector<media::MicrophoneInfo>>(aidlRet,
+                         media::aidl2legacy_MicrophoneInfo));
+    }
+    return OK;
+}
+
+status_t AudioFlingerClientAdapter::setAudioHalPids(const std::vector<pid_t>& pids) {
+    std::vector<int32_t> pidsAidl = VALUE_OR_RETURN_STATUS(
+            convertContainer<std::vector<int32_t>>(pids, legacy2aidl_pid_t_int32_t));
+    return statusTFromBinderStatus(mDelegate->setAudioHalPids(pidsAidl));
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// AudioFlingerServerAdapter
+AudioFlingerServerAdapter::AudioFlingerServerAdapter(
+        const sp<AudioFlingerServerAdapter::Delegate>& delegate) : mDelegate(delegate) {}
+
+status_t AudioFlingerServerAdapter::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                                               uint32_t flags) {
+    return mDelegate->onPreTransact(static_cast<Delegate::TransactionCode>(code), data, flags)
+           ?: BnAudioFlingerService::onTransact(code, data, reply, flags);
+}
+
+status_t AudioFlingerServerAdapter::dump(int fd, const Vector<String16>& args) {
+    return mDelegate->dump(fd, args);
+}
+
+Status AudioFlingerServerAdapter::createTrack(const media::CreateTrackRequest& request,
+                                              media::CreateTrackResponse* _aidl_return) {
+    return Status::fromStatusT(mDelegate->createTrack(request, *_aidl_return));
+}
+
+Status AudioFlingerServerAdapter::createRecord(const media::CreateRecordRequest& request,
+                                               media::CreateRecordResponse* _aidl_return) {
+    return Status::fromStatusT(mDelegate->createRecord(request, *_aidl_return));
+}
+
+Status AudioFlingerServerAdapter::sampleRate(int32_t ioHandle, int32_t* _aidl_return) {
+    audio_io_handle_t ioHandleLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(ioHandle));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(
+            convertIntegral<int32_t>(mDelegate->sampleRate(ioHandleLegacy)));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::format(int32_t output,
+                                         media::audio::common::AudioFormat* _aidl_return) {
+    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(output));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(
+            legacy2aidl_audio_format_t_AudioFormat(mDelegate->format(outputLegacy)));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::frameCount(int32_t ioHandle, int64_t* _aidl_return) {
+    audio_io_handle_t ioHandleLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(ioHandle));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(
+            convertIntegral<int64_t>(mDelegate->frameCount(ioHandleLegacy)));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::latency(int32_t output, int32_t* _aidl_return) {
+    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(output));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(
+            convertIntegral<int32_t>(mDelegate->latency(outputLegacy)));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::setMasterVolume(float value) {
+    return Status::fromStatusT(mDelegate->setMasterVolume(value));
+}
+
+Status AudioFlingerServerAdapter::setMasterMute(bool muted) {
+    return Status::fromStatusT(mDelegate->setMasterMute(muted));
+}
+
+Status AudioFlingerServerAdapter::masterVolume(float* _aidl_return) {
+    *_aidl_return = mDelegate->masterVolume();
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::masterMute(bool* _aidl_return) {
+    *_aidl_return = mDelegate->masterMute();
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::setMasterBalance(float balance) {
+    return Status::fromStatusT(mDelegate->setMasterBalance(balance));
+}
+
+Status AudioFlingerServerAdapter::getMasterBalance(float* _aidl_return) {
+    return Status::fromStatusT(mDelegate->getMasterBalance(_aidl_return));
+}
+
+Status AudioFlingerServerAdapter::setStreamVolume(media::AudioStreamType stream, float value,
+                                                  int32_t output) {
+    audio_stream_type_t streamLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_AudioStreamType_audio_stream_type_t(stream));
+    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(output));
+    return Status::fromStatusT(mDelegate->setStreamVolume(streamLegacy, value, outputLegacy));
+}
+
+Status AudioFlingerServerAdapter::setStreamMute(media::AudioStreamType stream, bool muted) {
+    audio_stream_type_t streamLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_AudioStreamType_audio_stream_type_t(stream));
+    return Status::fromStatusT(mDelegate->setStreamMute(streamLegacy, muted));
+}
+
+Status AudioFlingerServerAdapter::streamVolume(media::AudioStreamType stream, int32_t output,
+                                               float* _aidl_return) {
+    audio_stream_type_t streamLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_AudioStreamType_audio_stream_type_t(stream));
+    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(output));
+    *_aidl_return = mDelegate->streamVolume(streamLegacy, outputLegacy);
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::streamMute(media::AudioStreamType stream, bool* _aidl_return) {
+    audio_stream_type_t streamLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_AudioStreamType_audio_stream_type_t(stream));
+    *_aidl_return = mDelegate->streamMute(streamLegacy);
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::setMode(media::AudioMode mode) {
+    audio_mode_t modeLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioMode_audio_mode_t(mode));
+    return Status::fromStatusT(mDelegate->setMode(modeLegacy));
+}
+
+Status AudioFlingerServerAdapter::setMicMute(bool state) {
+    return Status::fromStatusT(mDelegate->setMicMute(state));
+}
+
+Status AudioFlingerServerAdapter::getMicMute(bool* _aidl_return) {
+    *_aidl_return = mDelegate->getMicMute();
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::setRecordSilenced(int32_t portId, bool silenced) {
+    audio_port_handle_t portIdLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_port_handle_t(portId));
+    mDelegate->setRecordSilenced(portIdLegacy, silenced);
+    return Status::ok();
+}
+
+Status
+AudioFlingerServerAdapter::setParameters(int32_t ioHandle, const std::string& keyValuePairs) {
+    audio_io_handle_t ioHandleLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(ioHandle));
+    String8 keyValuePairsLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_string_view_String8(keyValuePairs));
+    return Status::fromStatusT(mDelegate->setParameters(ioHandleLegacy, keyValuePairsLegacy));
+}
+
+Status AudioFlingerServerAdapter::getParameters(int32_t ioHandle, const std::string& keys,
+                                                std::string* _aidl_return) {
+    audio_io_handle_t ioHandleLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(ioHandle));
+    String8 keysLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_string_view_String8(keys));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(
+            legacy2aidl_String8_string(mDelegate->getParameters(ioHandleLegacy, keysLegacy)));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::registerClient(const sp<media::IAudioFlingerClient>& client) {
+    mDelegate->registerClient(client);
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::getInputBufferSize(int32_t sampleRate,
+                                                     media::audio::common::AudioFormat format,
+                                                     int32_t channelMask, int64_t* _aidl_return) {
+    uint32_t sampleRateLegacy = VALUE_OR_RETURN_BINDER(convertIntegral<uint32_t>(sampleRate));
+    audio_format_t formatLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_AudioFormat_audio_format_t(format));
+    audio_channel_mask_t channelMaskLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_channel_mask_t(channelMask));
+    size_t size = mDelegate->getInputBufferSize(sampleRateLegacy, formatLegacy, channelMaskLegacy);
+    *_aidl_return = VALUE_OR_RETURN_BINDER(convertIntegral<int64_t>(size));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::openOutput(const media::OpenOutputRequest& request,
+                                             media::OpenOutputResponse* _aidl_return) {
+    return Status::fromStatusT(mDelegate->openOutput(request, _aidl_return));
+}
+
+Status AudioFlingerServerAdapter::openDuplicateOutput(int32_t output1, int32_t output2,
+                                                      int32_t* _aidl_return) {
+    audio_io_handle_t output1Legacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(output1));
+    audio_io_handle_t output2Legacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(output2));
+    audio_io_handle_t result = mDelegate->openDuplicateOutput(output1Legacy, output2Legacy);
+    *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_io_handle_t_int32_t(result));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::closeOutput(int32_t output) {
+    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(output));
+    return Status::fromStatusT(mDelegate->closeOutput(outputLegacy));
+}
+
+Status AudioFlingerServerAdapter::suspendOutput(int32_t output) {
+    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(output));
+    return Status::fromStatusT(mDelegate->suspendOutput(outputLegacy));
+}
+
+Status AudioFlingerServerAdapter::restoreOutput(int32_t output) {
+    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(output));
+    return Status::fromStatusT(mDelegate->restoreOutput(outputLegacy));
+}
+
+Status AudioFlingerServerAdapter::openInput(const media::OpenInputRequest& request,
+                                            media::OpenInputResponse* _aidl_return) {
+    return Status::fromStatusT(mDelegate->openInput(request, _aidl_return));
+}
+
+Status AudioFlingerServerAdapter::closeInput(int32_t input) {
+    audio_io_handle_t inputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(input));
+    return Status::fromStatusT(mDelegate->closeInput(inputLegacy));
+}
+
+Status AudioFlingerServerAdapter::invalidateStream(media::AudioStreamType stream) {
+    audio_stream_type_t streamLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_AudioStreamType_audio_stream_type_t(stream));
+    return Status::fromStatusT(mDelegate->invalidateStream(streamLegacy));
+}
+
+Status AudioFlingerServerAdapter::setVoiceVolume(float volume) {
+    return Status::fromStatusT(mDelegate->setVoiceVolume(volume));
+}
+
+Status
+AudioFlingerServerAdapter::getRenderPosition(int32_t output, media::RenderPosition* _aidl_return) {
+    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(output));
+    uint32_t halFramesLegacy;
+    uint32_t dspFramesLegacy;
+    RETURN_BINDER_IF_ERROR(
+            mDelegate->getRenderPosition(&halFramesLegacy, &dspFramesLegacy, outputLegacy));
+    _aidl_return->halFrames = VALUE_OR_RETURN_BINDER(convertIntegral<int32_t>(halFramesLegacy));
+    _aidl_return->dspFrames = VALUE_OR_RETURN_BINDER(convertIntegral<int32_t>(dspFramesLegacy));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::getInputFramesLost(int32_t ioHandle, int32_t* _aidl_return) {
+    audio_io_handle_t ioHandleLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(ioHandle));
+    uint32_t result = mDelegate->getInputFramesLost(ioHandleLegacy);
+    *_aidl_return = VALUE_OR_RETURN_BINDER(convertIntegral<int32_t>(result));
+    return Status::ok();
+}
+
+Status
+AudioFlingerServerAdapter::newAudioUniqueId(media::AudioUniqueIdUse use, int32_t* _aidl_return) {
+    audio_unique_id_use_t useLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_AudioUniqueIdUse_audio_unique_id_use_t(use));
+    audio_unique_id_t result = mDelegate->newAudioUniqueId(useLegacy);
+    *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_unique_id_t_int32_t(result));
+    return Status::ok();
+}
+
+Status
+AudioFlingerServerAdapter::acquireAudioSessionId(int32_t audioSession, int32_t pid, int32_t uid) {
+    audio_session_t audioSessionLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_session_t(audioSession));
+    pid_t pidLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_int32_t_pid_t(pid));
+    uid_t uidLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_int32_t_uid_t(uid));
+    mDelegate->acquireAudioSessionId(audioSessionLegacy, pidLegacy, uidLegacy);
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::releaseAudioSessionId(int32_t audioSession, int32_t pid) {
+    audio_session_t audioSessionLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_session_t(audioSession));
+    pid_t pidLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_int32_t_pid_t(pid));
+    mDelegate->releaseAudioSessionId(audioSessionLegacy, pidLegacy);
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::queryNumberEffects(int32_t* _aidl_return) {
+    uint32_t result;
+    RETURN_BINDER_IF_ERROR(mDelegate->queryNumberEffects(&result));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(convertIntegral<uint32_t>(result));
+    return Status::ok();
+}
+
+Status
+AudioFlingerServerAdapter::queryEffect(int32_t index, media::EffectDescriptor* _aidl_return) {
+    uint32_t indexLegacy = VALUE_OR_RETURN_BINDER(convertIntegral<uint32_t>(index));
+    effect_descriptor_t result;
+    RETURN_BINDER_IF_ERROR(mDelegate->queryEffect(indexLegacy, &result));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(
+            legacy2aidl_effect_descriptor_t_EffectDescriptor(result));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::getEffectDescriptor(const media::AudioUuid& effectUUID,
+                                                      const media::AudioUuid& typeUUID,
+                                                      int32_t preferredTypeFlag,
+                                                      media::EffectDescriptor* _aidl_return) {
+    effect_uuid_t effectUuidLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_AudioUuid_audio_uuid_t(effectUUID));
+    effect_uuid_t typeUuidLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_AudioUuid_audio_uuid_t(typeUUID));
+    uint32_t preferredTypeFlagLegacy = VALUE_OR_RETURN_BINDER(
+            convertReinterpret<uint32_t>(preferredTypeFlag));
+    effect_descriptor_t result;
+    RETURN_BINDER_IF_ERROR(mDelegate->getEffectDescriptor(&effectUuidLegacy, &typeUuidLegacy,
+                                                          preferredTypeFlagLegacy, &result));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(
+            legacy2aidl_effect_descriptor_t_EffectDescriptor(result));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::createEffect(const media::CreateEffectRequest& request,
+                                               media::CreateEffectResponse* _aidl_return) {
+    return Status::fromStatusT(mDelegate->createEffect(request, _aidl_return));
+}
+
+Status
+AudioFlingerServerAdapter::moveEffects(int32_t session, int32_t srcOutput, int32_t dstOutput) {
+    audio_session_t sessionLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_session_t(session));
+    audio_io_handle_t srcOutputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(srcOutput));
+    audio_io_handle_t dstOutputLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(dstOutput));
+    return Status::fromStatusT(
+            mDelegate->moveEffects(sessionLegacy, srcOutputLegacy, dstOutputLegacy));
+}
+
+Status AudioFlingerServerAdapter::setEffectSuspended(int32_t effectId, int32_t sessionId,
+                                                     bool suspended) {
+    int effectIdLegacy = VALUE_OR_RETURN_BINDER(convertReinterpret<int>(effectId));
+    audio_session_t sessionIdLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_session_t(sessionId));
+    mDelegate->setEffectSuspended(effectIdLegacy, sessionIdLegacy, suspended);
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::loadHwModule(const std::string& name, int32_t* _aidl_return) {
+    audio_module_handle_t result = mDelegate->loadHwModule(name.c_str());
+    *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_module_handle_t_int32_t(result));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::getPrimaryOutputSamplingRate(int32_t* _aidl_return) {
+    *_aidl_return = VALUE_OR_RETURN_BINDER(
+            convertIntegral<int32_t>(mDelegate->getPrimaryOutputSamplingRate()));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::getPrimaryOutputFrameCount(int64_t* _aidl_return) {
+    *_aidl_return = VALUE_OR_RETURN_BINDER(
+            convertIntegral<int64_t>(mDelegate->getPrimaryOutputFrameCount()));
+    return Status::ok();
+
+}
+
+Status AudioFlingerServerAdapter::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) {
+    return Status::fromStatusT(mDelegate->setLowRamDevice(isLowRamDevice, totalMemory));
+}
+
+Status AudioFlingerServerAdapter::getAudioPort(const media::AudioPort& port,
+                                               media::AudioPort* _aidl_return) {
+    audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPort_audio_port_v7(port));
+    RETURN_BINDER_IF_ERROR(mDelegate->getAudioPort(&portLegacy));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_port_v7_AudioPort(portLegacy));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::createAudioPatch(const media::AudioPatch& patch,
+                                                   int32_t* _aidl_return) {
+    audio_patch patchLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPatch_audio_patch(patch));
+    audio_patch_handle_t handleLegacy;
+    RETURN_BINDER_IF_ERROR(mDelegate->createAudioPatch(&patchLegacy, &handleLegacy));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_patch_handle_t_int32_t(handleLegacy));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::releaseAudioPatch(int32_t handle) {
+    audio_patch_handle_t handleLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_patch_handle_t(handle));
+    return Status::fromStatusT(mDelegate->releaseAudioPatch(handleLegacy));
+}
+
+Status AudioFlingerServerAdapter::listAudioPatches(int32_t maxCount,
+                            std::vector<media::AudioPatch>* _aidl_return) {
+    unsigned int count = VALUE_OR_RETURN_BINDER(convertIntegral<unsigned int>(maxCount));
+    count = std::min(count, static_cast<unsigned int>(MAX_ITEMS_PER_LIST));
+    std::unique_ptr<audio_patch[]> patchesLegacy(new audio_patch[count]);
+    RETURN_BINDER_IF_ERROR(mDelegate->listAudioPatches(&count, patchesLegacy.get()));
+    RETURN_BINDER_IF_ERROR(convertRange(&patchesLegacy[0],
+                           &patchesLegacy[count],
+                           std::back_inserter(*_aidl_return),
+                           legacy2aidl_audio_patch_AudioPatch));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::setAudioPortConfig(const media::AudioPortConfig& config) {
+    audio_port_config configLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_AudioPortConfig_audio_port_config(config));
+    return Status::fromStatusT(mDelegate->setAudioPortConfig(&configLegacy));
+}
+
+Status AudioFlingerServerAdapter::getAudioHwSyncForSession(int32_t sessionId,
+                                                           int32_t* _aidl_return) {
+    audio_session_t sessionIdLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_session_t(sessionId));
+    audio_hw_sync_t result = mDelegate->getAudioHwSyncForSession(sessionIdLegacy);
+    *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_hw_sync_t_int32_t(result));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::systemReady() {
+    return Status::fromStatusT(mDelegate->systemReady());
+}
+
+Status AudioFlingerServerAdapter::frameCountHAL(int32_t ioHandle, int64_t* _aidl_return) {
+    audio_io_handle_t ioHandleLegacy = VALUE_OR_RETURN_BINDER(
+            aidl2legacy_int32_t_audio_io_handle_t(ioHandle));
+    size_t result = mDelegate->frameCountHAL(ioHandleLegacy);
+    *_aidl_return = VALUE_OR_RETURN_BINDER(convertIntegral<int64_t>(result));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::getMicrophones(
+        std::vector<media::MicrophoneInfoData>* _aidl_return) {
+    std::vector<media::MicrophoneInfo> resultLegacy;
+    RETURN_BINDER_IF_ERROR(mDelegate->getMicrophones(&resultLegacy));
+    *_aidl_return = VALUE_OR_RETURN_BINDER(convertContainer<std::vector<media::MicrophoneInfoData>>(
+            resultLegacy, media::legacy2aidl_MicrophoneInfo));
+    return Status::ok();
+}
+
+Status AudioFlingerServerAdapter::setAudioHalPids(const std::vector<int32_t>& pids) {
+    std::vector<pid_t> pidsLegacy = VALUE_OR_RETURN_BINDER(
+            convertContainer<std::vector<pid_t>>(pids, aidl2legacy_int32_t_pid_t));
+    RETURN_BINDER_IF_ERROR(mDelegate->setAudioHalPids(pidsLegacy));
+    return Status::ok();
+}
 
 } // namespace android
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 81f9dff..2828bcb 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -26,7 +26,7 @@
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
 #include <media/AudioEffect.h>
-#include <media/AudioSanitizer.h>
+#include <media/AudioValidator.h>
 #include <media/IAudioPolicyService.h>
 #include <mediautils/ServiceUtilities.h>
 #include <mediautils/TimeCheck.h>
@@ -69,7 +69,7 @@
     QUERY_DEFAULT_PRE_PROCESSING,
     SET_EFFECT_ENABLED,
     IS_STREAM_ACTIVE_REMOTELY,
-    IS_OFFLOAD_SUPPORTED,
+    GET_OFFLOAD_MODE_SUPPORTED,
     IS_DIRECT_OUTPUT_SUPPORTED,
     LIST_AUDIO_PORTS,
     GET_AUDIO_PORT,
@@ -529,7 +529,11 @@
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.write(desc, sizeof(effect_descriptor_t));
-        remote()->transact(GET_OUTPUT_FOR_EFFECT, data, &reply);
+        status_t status = remote()->transact(GET_OUTPUT_FOR_EFFECT, data, &reply);
+        if (status != NO_ERROR ||
+                (status = (status_t)reply.readInt32()) != NO_ERROR) {
+            return AUDIO_IO_HANDLE_NONE;
+        }
         return static_cast <audio_io_handle_t> (reply.readInt32());
     }
 
@@ -662,13 +666,13 @@
         return reply.readInt32();
     }
 
-    virtual bool isOffloadSupported(const audio_offload_info_t& info)
+    virtual audio_offload_mode_t getOffloadSupport(const audio_offload_info_t& info)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.write(&info, sizeof(audio_offload_info_t));
-        remote()->transact(IS_OFFLOAD_SUPPORTED, data, &reply);
-        return reply.readInt32();
+        remote()->transact(GET_OFFLOAD_MODE_SUPPORTED, data, &reply);
+        return static_cast<audio_offload_mode_t>(reply.readInt32());
     }
 
     virtual bool isDirectOutputSupported(const audio_config_base_t& config,
@@ -684,7 +688,7 @@
     virtual status_t listAudioPorts(audio_port_role_t role,
                                     audio_port_type_t type,
                                     unsigned int *num_ports,
-                                    struct audio_port *ports,
+                                    struct audio_port_v7 *ports,
                                     unsigned int *generation)
     {
         if (num_ports == NULL || (*num_ports != 0 && ports == NULL) ||
@@ -707,27 +711,27 @@
                 numPortsReq = *num_ports;
             }
             if (numPortsReq > 0) {
-                reply.read(ports, numPortsReq * sizeof(struct audio_port));
+                reply.read(ports, numPortsReq * sizeof(struct audio_port_v7));
             }
             *generation = reply.readInt32();
         }
         return status;
     }
 
-    virtual status_t getAudioPort(struct audio_port *port)
+    virtual status_t getAudioPort(struct audio_port_v7 *port)
     {
         if (port == NULL) {
             return BAD_VALUE;
         }
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
-        data.write(port, sizeof(struct audio_port));
+        data.write(port, sizeof(struct audio_port_v7));
         status_t status = remote()->transact(GET_AUDIO_PORT, data, &reply);
         if (status != NO_ERROR ||
                 (status = (status_t)reply.readInt32()) != NO_ERROR) {
             return status;
         }
-        reply.read(port, sizeof(struct audio_port));
+        reply.read(port, sizeof(struct audio_port_v7));
         return status;
     }
 
@@ -1587,6 +1591,7 @@
         case REGISTER_EFFECT:
         case UNREGISTER_EFFECT:
         case SET_EFFECT_ENABLED:
+        case GET_STRATEGY_FOR_STREAM:
         case GET_OUTPUT_FOR_ATTR:
         case MOVE_EFFECTS_TO_IO:
             ALOGW("%s: transaction %d received from PID %d",
@@ -1614,6 +1619,15 @@
 //      case SET_FORCE_USE:
         case INIT_STREAM_VOLUME:
         case SET_STREAM_VOLUME:
+        case SET_VOLUME_ATTRIBUTES:
+        case GET_STREAM_VOLUME:
+        case GET_VOLUME_ATTRIBUTES:
+        case GET_MIN_VOLUME_FOR_ATTRIBUTES:
+        case GET_MAX_VOLUME_FOR_ATTRIBUTES:
+        case IS_STREAM_ACTIVE:
+        case IS_STREAM_ACTIVE_REMOTELY:
+        case IS_SOURCE_ACTIVE:
+        case GET_DEVICES_FOR_STREAM:
         case REGISTER_POLICY_MIXES:
         case SET_MASTER_MONO:
         case GET_SURROUND_FORMATS:
@@ -1778,13 +1792,15 @@
             audio_io_handle_t output = 0;
             std::vector<audio_io_handle_t> secondaryOutputs;
 
-            status = AudioSanitizer::sanitizeAudioAttributes(&attr, "68953950");
-            if (status == NO_ERROR) {
-                status = getOutputForAttr(&attr,
-                                          &output, session, &stream, pid, uid,
-                                          &config,
-                                          flags, &selectedDeviceId, &portId, &secondaryOutputs);
+            status = AudioValidator::validateAudioAttributes(attr, "68953950");
+            if (status != NO_ERROR) {
+                reply->writeInt32(status);
+                return NO_ERROR;
             }
+            status = getOutputForAttr(&attr,
+                                      &output, session, &stream, pid, uid,
+                                      &config,
+                                      flags, &selectedDeviceId, &portId, &secondaryOutputs);
             reply->writeInt32(status);
             status = reply->write(&attr, sizeof(audio_attributes_t));
             if (status != NO_ERROR) {
@@ -1841,7 +1857,7 @@
             audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
             audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
 
-            status = AudioSanitizer::sanitizeAudioAttributes(&attr, "68953950");
+            status = AudioValidator::validateAudioAttributes(attr, "68953950");
             if (status == NO_ERROR) {
                 status = getInputForAttr(&attr, &input, riid, session, pid, uid,
                                          opPackageName, &config,
@@ -1931,7 +1947,7 @@
             int index = data.readInt32();
             audio_devices_t device = static_cast <audio_devices_t>(data.readInt32());
 
-            status = AudioSanitizer::sanitizeAudioAttributes(&attributes, "169572641");
+            status = AudioValidator::validateAudioAttributes(attributes, "169572641");
             if (status == NO_ERROR) {
                 status = setVolumeIndexForAttributes(attributes, index, device);
             }
@@ -1949,7 +1965,7 @@
             audio_devices_t device = static_cast <audio_devices_t>(data.readInt32());
 
             int index = 0;
-            status = AudioSanitizer::sanitizeAudioAttributes(&attributes, "169572641");
+            status = AudioValidator::validateAudioAttributes(attributes, "169572641");
             if (status == NO_ERROR) {
                 status = getVolumeIndexForAttributes(attributes, index, device);
             }
@@ -1969,7 +1985,7 @@
             }
 
             int index = 0;
-            status = AudioSanitizer::sanitizeAudioAttributes(&attributes, "169572641");
+            status = AudioValidator::validateAudioAttributes(attributes, "169572641");
             if (status == NO_ERROR) {
                 status = getMinVolumeIndexForAttributes(attributes, index);
             }
@@ -1989,7 +2005,7 @@
             }
 
             int index = 0;
-            status = AudioSanitizer::sanitizeAudioAttributes(&attributes, "169572641");
+            status = AudioValidator::validateAudioAttributes(attributes, "169572641");
             if (status == NO_ERROR) {
                 status = getMaxVolumeIndexForAttributes(attributes, index);
             }
@@ -2016,12 +2032,12 @@
                 android_errorWriteLog(0x534e4554, "73126106");
                 return status;
             }
-            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-            status = AudioSanitizer::sanitizeEffectDescriptor(&desc, "73126106");
+            status = AudioValidator::validateEffectDescriptor(desc, "73126106");
+            reply->writeInt32(status);
             if (status == NO_ERROR) {
-                output = getOutputForEffect(&desc);
+                audio_io_handle_t output = getOutputForEffect(&desc);
+                reply->writeInt32(static_cast <int32_t>(output));
             }
-            reply->writeInt32(static_cast <int32_t>(output));
             return NO_ERROR;
         } break;
 
@@ -2037,7 +2053,7 @@
             uint32_t strategy = data.readInt32();
             audio_session_t session = (audio_session_t) data.readInt32();
             int id = data.readInt32();
-            status = AudioSanitizer::sanitizeEffectDescriptor(&desc, "73126106");
+            status = AudioValidator::validateEffectDescriptor(desc, "73126106");
             if (status == NO_ERROR) {
                 status = registerEffect(&desc, io, strategy, session, id);
             }
@@ -2133,12 +2149,11 @@
             return status;
         }
 
-        case IS_OFFLOAD_SUPPORTED: {
+        case GET_OFFLOAD_MODE_SUPPORTED: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_offload_info_t info = {};
             data.read(&info, sizeof(audio_offload_info_t));
-            bool isSupported = isOffloadSupported(info);
-            reply->writeInt32(isSupported);
+            reply->writeInt32(static_cast<int32_t>(getOffloadSupport(info)));
             return NO_ERROR;
         }
 
@@ -2150,7 +2165,7 @@
             if (status != NO_ERROR) return status;
             status = data.read(&attributes, sizeof(audio_attributes_t));
             if (status != NO_ERROR) return status;
-            status = AudioSanitizer::sanitizeAudioAttributes(&attributes, "169572641");
+            status = AudioValidator::validateAudioAttributes(attributes, "169572641");
             if (status == NO_ERROR) {
                 status = isDirectOutputSupported(config, attributes);
             }
@@ -2167,8 +2182,8 @@
                 numPortsReq = MAX_ITEMS_PER_LIST;
             }
             unsigned int numPorts = numPortsReq;
-            struct audio_port *ports =
-                    (struct audio_port *)calloc(numPortsReq, sizeof(struct audio_port));
+            struct audio_port_v7 *ports =
+                    (struct audio_port_v7 *)calloc(numPortsReq, sizeof(struct audio_port_v7));
             if (ports == NULL) {
                 reply->writeInt32(NO_MEMORY);
                 reply->writeInt32(0);
@@ -2183,7 +2198,7 @@
                 if (numPortsReq > numPorts) {
                     numPortsReq = numPorts;
                 }
-                reply->write(ports, numPortsReq * sizeof(struct audio_port));
+                reply->write(ports, numPortsReq * sizeof(struct audio_port_v7));
                 reply->writeInt32(generation);
             }
             free(ports);
@@ -2192,19 +2207,19 @@
 
         case GET_AUDIO_PORT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            struct audio_port port = {};
-            status_t status = data.read(&port, sizeof(struct audio_port));
+            struct audio_port_v7 port = {};
+            status_t status = data.read(&port, sizeof(struct audio_port_v7));
             if (status != NO_ERROR) {
                 ALOGE("b/23912202");
                 return status;
             }
-            status = AudioSanitizer::sanitizeAudioPort(&port);
+            status = AudioValidator::validateAudioPort(port);
             if (status == NO_ERROR) {
                 status = getAudioPort(&port);
             }
             reply->writeInt32(status);
             if (status == NO_ERROR) {
-                reply->write(&port, sizeof(struct audio_port));
+                reply->write(&port, sizeof(struct audio_port_v7));
             }
             return NO_ERROR;
         }
@@ -2222,7 +2237,7 @@
                 ALOGE("b/23912202");
                 return status;
             }
-            status = AudioSanitizer::sanitizeAudioPatch(&patch);
+            status = AudioValidator::validateAudioPatch(patch);
             if (status == NO_ERROR) {
                 status = createAudioPatch(&patch, &handle);
             }
@@ -2279,8 +2294,10 @@
             if (status != NO_ERROR) {
                 return status;
             }
-            (void)AudioSanitizer::sanitizeAudioPortConfig(&config);
-            status = setAudioPortConfig(&config);
+            status = AudioValidator::validateAudioPortConfig(config);
+            if (status == NO_ERROR) {
+                status = setAudioPortConfig(&config);
+            }
             reply->writeInt32(status);
             return NO_ERROR;
         }
@@ -2365,11 +2382,11 @@
             if (status != NO_ERROR) {
                 return status;
             }
-            status = AudioSanitizer::sanitizeAudioPortConfig(&source);
+            status = AudioValidator::validateAudioPortConfig(source);
             if (status == NO_ERROR) {
                 // OK to not always sanitize attributes as startAudioSource() is not called if
                 // the port config is invalid.
-                status = AudioSanitizer::sanitizeAudioAttributes(&attributes, "68953950");
+                status = AudioValidator::validateAudioAttributes(attributes, "68953950");
             }
             audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
             if (status == NO_ERROR) {
diff --git a/media/libaudioclient/IAudioTrack.cpp b/media/libaudioclient/IAudioTrack.cpp
deleted file mode 100644
index 6219e7a..0000000
--- a/media/libaudioclient/IAudioTrack.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
-**
-** Copyright 2007, 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 "IAudioTrack"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-
-#include <media/IAudioTrack.h>
-
-namespace android {
-
-using media::VolumeShaper;
-
-enum {
-    GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
-    START,
-    STOP,
-    FLUSH,
-    RESERVED, // was MUTE
-    PAUSE,
-    ATTACH_AUX_EFFECT,
-    SET_PARAMETERS,
-    SELECT_PRESENTATION,
-    GET_TIMESTAMP,
-    SIGNAL,
-    APPLY_VOLUME_SHAPER,
-    GET_VOLUME_SHAPER_STATE,
-};
-
-class BpAudioTrack : public BpInterface<IAudioTrack>
-{
-public:
-    explicit BpAudioTrack(const sp<IBinder>& impl)
-        : BpInterface<IAudioTrack>(impl)
-    {
-    }
-
-    virtual sp<IMemory> getCblk() const
-    {
-        Parcel data, reply;
-        sp<IMemory> cblk;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_CBLK, data, &reply);
-        if (status == NO_ERROR) {
-            cblk = interface_cast<IMemory>(reply.readStrongBinder());
-            if (cblk != 0 && cblk->unsecurePointer() == NULL) {
-                cblk.clear();
-            }
-        }
-        return cblk;
-    }
-
-    virtual status_t start()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        status_t status = remote()->transact(START, data, &reply);
-        if (status == NO_ERROR) {
-            status = reply.readInt32();
-        } else {
-            ALOGW("start() error: %s", strerror(-status));
-        }
-        return status;
-    }
-
-    virtual void stop()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        remote()->transact(STOP, data, &reply);
-    }
-
-    virtual void flush()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        remote()->transact(FLUSH, data, &reply);
-    }
-
-    virtual void pause()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        remote()->transact(PAUSE, data, &reply);
-    }
-
-    virtual status_t attachAuxEffect(int effectId)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        data.writeInt32(effectId);
-        status_t status = remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
-        if (status == NO_ERROR) {
-            status = reply.readInt32();
-        } else {
-            ALOGW("attachAuxEffect() error: %s", strerror(-status));
-        }
-        return status;
-    }
-
-    virtual status_t setParameters(const String8& keyValuePairs) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        data.writeString8(keyValuePairs);
-        status_t status = remote()->transact(SET_PARAMETERS, data, &reply);
-        if (status == NO_ERROR) {
-            status = reply.readInt32();
-        }
-        return status;
-    }
-
-    /* Selects the presentation (if available) */
-    virtual status_t selectPresentation(int presentationId, int programId) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        data.writeInt32(presentationId);
-        data.writeInt32(programId);
-        status_t status = remote()->transact(SELECT_PRESENTATION, data, &reply);
-        if (status == NO_ERROR) {
-            status = reply.readInt32();
-        }
-        return status;
-    }
-
-    virtual status_t getTimestamp(AudioTimestamp& timestamp) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        status_t status = remote()->transact(GET_TIMESTAMP, data, &reply);
-        if (status == NO_ERROR) {
-            status = reply.readInt32();
-            if (status == NO_ERROR) {
-                timestamp.mPosition = reply.readInt32();
-                timestamp.mTime.tv_sec = reply.readInt32();
-                timestamp.mTime.tv_nsec = reply.readInt32();
-            }
-        }
-        return status;
-    }
-
-    virtual void signal() {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-        remote()->transact(SIGNAL, data, &reply);
-    }
-
-    virtual VolumeShaper::Status applyVolumeShaper(
-            const sp<VolumeShaper::Configuration>& configuration,
-            const sp<VolumeShaper::Operation>& operation) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-
-        status_t status = configuration.get() == nullptr
-                ? data.writeInt32(0)
-                :  data.writeInt32(1)
-                    ?: configuration->writeToParcel(&data);
-        if (status != NO_ERROR) {
-            return VolumeShaper::Status(status);
-        }
-
-        status = operation.get() == nullptr
-                ? status = data.writeInt32(0)
-                : data.writeInt32(1)
-                    ?: operation->writeToParcel(&data);
-        if (status != NO_ERROR) {
-            return VolumeShaper::Status(status);
-        }
-
-        int32_t remoteVolumeShaperStatus;
-        status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply)
-                 ?: reply.readInt32(&remoteVolumeShaperStatus);
-
-        return VolumeShaper::Status(status ?: remoteVolumeShaperStatus);
-    }
-
-    virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-
-        data.writeInt32(id);
-        status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
-        if (status != NO_ERROR) {
-            return nullptr;
-        }
-        sp<VolumeShaper::State> state = new VolumeShaper::State;
-        status = state->readFromParcel(&reply);
-        if (status != NO_ERROR) {
-            return nullptr;
-        }
-        return state;
-    }
-};
-
-IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
-
-// ----------------------------------------------------------------------
-
-status_t BnAudioTrack::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch (code) {
-        case GET_CBLK: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            reply->writeStrongBinder(IInterface::asBinder(getCblk()));
-            return NO_ERROR;
-        } break;
-        case START: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            reply->writeInt32(start());
-            return NO_ERROR;
-        } break;
-        case STOP: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            stop();
-            return NO_ERROR;
-        } break;
-        case FLUSH: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            flush();
-            return NO_ERROR;
-        } break;
-        case PAUSE: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            pause();
-            return NO_ERROR;
-        }
-        case ATTACH_AUX_EFFECT: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            reply->writeInt32(attachAuxEffect(data.readInt32()));
-            return NO_ERROR;
-        } break;
-        case SET_PARAMETERS: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            String8 keyValuePairs(data.readString8());
-            reply->writeInt32(setParameters(keyValuePairs));
-            return NO_ERROR;
-        } break;
-        case SELECT_PRESENTATION: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            reply->writeInt32(selectPresentation(data.readInt32(), data.readInt32()));
-            return NO_ERROR;
-        } break;
-        case GET_TIMESTAMP: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            AudioTimestamp timestamp;
-            status_t status = getTimestamp(timestamp);
-            reply->writeInt32(status);
-            if (status == NO_ERROR) {
-                reply->writeInt32(timestamp.mPosition);
-                reply->writeInt32(timestamp.mTime.tv_sec);
-                reply->writeInt32(timestamp.mTime.tv_nsec);
-            }
-            return NO_ERROR;
-        } break;
-        case SIGNAL: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            signal();
-            return NO_ERROR;
-        } break;
-        case APPLY_VOLUME_SHAPER: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            sp<VolumeShaper::Configuration> configuration;
-            sp<VolumeShaper::Operation> operation;
-
-            int32_t present;
-            status_t status = data.readInt32(&present);
-            if (status == NO_ERROR && present != 0) {
-                configuration = new VolumeShaper::Configuration();
-                status = configuration->readFromParcel(&data);
-            }
-            status = status ?: data.readInt32(&present);
-            if (status == NO_ERROR && present != 0) {
-                operation = new VolumeShaper::Operation();
-                status = operation->readFromParcel(&data);
-            }
-            if (status == NO_ERROR) {
-                status = (status_t)applyVolumeShaper(configuration, operation);
-            }
-            reply->writeInt32(status);
-            return NO_ERROR;
-        } break;
-        case GET_VOLUME_SHAPER_STATE: {
-            CHECK_INTERFACE(IAudioTrack, data, reply);
-            int id;
-            status_t status = data.readInt32(&id);
-            if (status == NO_ERROR) {
-                sp<VolumeShaper::State> state = getVolumeShaperState(id);
-                if (state.get() != nullptr) {
-                     status = state->writeToParcel(reply);
-                }
-            }
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-} // namespace android
diff --git a/media/libaudioclient/PlayerBase.cpp b/media/libaudioclient/PlayerBase.cpp
index c443865..9e7d89e 100644
--- a/media/libaudioclient/PlayerBase.cpp
+++ b/media/libaudioclient/PlayerBase.cpp
@@ -15,13 +15,14 @@
  */
 
 #include <binder/IServiceManager.h>
+#include <media/AidlConversionUtil.h>
 #include <media/PlayerBase.h>
 
 #define max(a, b) ((a) > (b) ? (a) : (b))
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
 namespace android {
-
+using aidl_utils::binderStatusFromStatusT;
 using media::VolumeShaperConfiguration;
 using media::VolumeShaperOperation;
 
@@ -150,7 +151,7 @@
     if (status != NO_ERROR) {
         ALOGW("PlayerBase::setVolume() error %d", status);
     }
-    return binder::Status::fromStatusT(status);
+    return binderStatusFromStatusT(status);
 }
 
 binder::Status PlayerBase::setPan(float pan) {
@@ -170,7 +171,7 @@
     if (status != NO_ERROR) {
         ALOGW("PlayerBase::setPan() error %d", status);
     }
-    return binder::Status::fromStatusT(status);
+    return binderStatusFromStatusT(status);
 }
 
 binder::Status PlayerBase::setStartDelayMs(int32_t delayMs __unused) {
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index 050ad65..ee78a2d 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -853,6 +853,11 @@
                       { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
           .repeatCnt = ToneGenerator::TONEGEN_INF,
           .repeatSegment = 0 },                               // TONE_INDIA_RINGTONE
+        { .segments = { { .duration = 1000, .waveFreq = { 440, 480, 0 }, 0, 0 },
+                        { .duration = 2000, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                               // TONE_TW_RINGTONE
 };
 
 // Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type
@@ -937,6 +942,16 @@
             TONE_SUP_ERROR,              // TONE_SUP_ERROR
             TONE_INDIA_CALL_WAITING,     // TONE_SUP_CALL_WAITING
             TONE_INDIA_RINGTONE          // TONE_SUP_RINGTONE
+        },
+        {   // TAIWAN
+            TONE_SUP_DIAL,               // TONE_SUP_DIAL
+            TONE_SUP_BUSY,               // TONE_SUP_BUSY
+            TONE_SUP_CONGESTION,         // TONE_SUP_CONGESTION
+            TONE_SUP_RADIO_ACK,          // TONE_SUP_RADIO_ACK
+            TONE_SUP_RADIO_NOTAVAIL,     // TONE_SUP_RADIO_NOTAVAIL
+            TONE_SUP_ERROR,              // TONE_SUP_ERROR
+            TONE_SUP_CALL_WAITING,       // TONE_SUP_CALL_WAITING
+            TONE_TW_RINGTONE             // TONE_SUP_RINGTONE
         }
 };
 
@@ -1010,6 +1025,8 @@
         mRegion = IRELAND;
     } else if (strstr(value, "in") != NULL) {
         mRegion = INDIA;
+    } else if (strstr(value, "tw") != NULL) {
+        mRegion = TAIWAN;
     } else {
         mRegion = CEPT;
     }
diff --git a/media/libaudioclient/TrackPlayerBase.cpp b/media/libaudioclient/TrackPlayerBase.cpp
index e571838..372b7c3 100644
--- a/media/libaudioclient/TrackPlayerBase.cpp
+++ b/media/libaudioclient/TrackPlayerBase.cpp
@@ -17,7 +17,7 @@
 #include <media/TrackPlayerBase.h>
 
 namespace android {
-
+using aidl_utils::binderStatusFromStatusT;
 using media::VolumeShaper;
 
 //--------------------------------------------------------------------------------------------------
@@ -115,7 +115,7 @@
     status_t s = spConfiguration->readFromParcelable(configuration)
             ?: spOperation->readFromParcelable(operation);
     if (s != OK) {
-        return binder::Status::fromStatusT(s);
+        return binderStatusFromStatusT(s);
     }
 
     if (mAudioTrack != 0) {
@@ -124,7 +124,7 @@
         if (status < 0) { // a non-negative value is the volume shaper id.
             ALOGE("TrackPlayerBase::applyVolumeShaper() failed with status %d", status);
         }
-        return binder::Status::fromStatusT(status);
+        return binderStatusFromStatusT(status);
     } else {
         ALOGD("TrackPlayerBase::applyVolumeShaper()"
               " no AudioTrack for volume control from IPlayer");
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/AudioDevice.aidl
similarity index 75%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to media/libaudioclient/aidl/android/media/AudioDevice.aidl
index d6e46cb..b200697 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioDevice.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -16,4 +16,11 @@
 
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * {@hide}
+ */
+parcelable AudioDevice {
+    /** Interpreted as audio_devices_t. */
+    int type;
+    @utf8InCpp String address;
+}
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/AudioEncapsulationMetadataType.aidl
similarity index 74%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to media/libaudioclient/aidl/android/media/AudioEncapsulationMetadataType.aidl
index d6e46cb..b03adfe 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioEncapsulationMetadataType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -13,7 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum AudioEncapsulationMetadataType {
+    NONE = 0,
+    FRAMEWORK_TUNER = 1,
+    DVB_AD_DESCRIPTOR = 2,
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioEncapsulationMode.aidl b/media/libaudioclient/aidl/android/media/AudioEncapsulationMode.aidl
index 74a6141..9e04e82 100644
--- a/media/libaudioclient/aidl/android/media/AudioEncapsulationMode.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioEncapsulationMode.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioEncapsulationMode {
      NONE = 0,
diff --git a/media/libaudioclient/aidl/android/media/AudioFlag.aidl b/media/libaudioclient/aidl/android/media/AudioFlag.aidl
index 2602fe5..58b493b 100644
--- a/media/libaudioclient/aidl/android/media/AudioFlag.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioFlag.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioFlag {
     AUDIBILITY_ENFORCED = 0,
diff --git a/media/libaudioclient/aidl/android/media/AudioGain.aidl b/media/libaudioclient/aidl/android/media/AudioGain.aidl
new file mode 100644
index 0000000..048b295
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioGain.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+/**
+ * {@hide}
+ */
+parcelable AudioGain {
+    int index;
+    boolean useInChannelMask;
+    boolean useForVolume;
+    /** Bitmask, indexed by AudioGainMode. */
+    int mode;
+    /** Interpreted as audio_channel_mask_t. */
+    int channelMask;
+    int minValue;
+    int maxValue;
+    int defaultValue;
+    int stepValue;
+    int minRampMs;
+    int maxRampMs;
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioGainMode.aidl b/media/libaudioclient/aidl/android/media/AudioGainMode.aidl
index 39395e5..e1b9f0b 100644
--- a/media/libaudioclient/aidl/android/media/AudioGainMode.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioGainMode.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioGainMode {
     JOINT    = 0,
diff --git a/media/libaudioclient/aidl/android/media/AudioInputFlags.aidl b/media/libaudioclient/aidl/android/media/AudioInputFlags.aidl
index 8f517e7..bfc0eb0 100644
--- a/media/libaudioclient/aidl/android/media/AudioInputFlags.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioInputFlags.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioInputFlags {
     FAST       = 0,
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/AudioMixLatencyClass.aidl
similarity index 79%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to media/libaudioclient/aidl/android/media/AudioMixLatencyClass.aidl
index d6e46cb..d70b364 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioMixLatencyClass.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -13,7 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum AudioMixLatencyClass {
+    LOW = 0,
+    NORMAL = 1,
+}
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/AudioMode.aidl
similarity index 70%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to media/libaudioclient/aidl/android/media/AudioMode.aidl
index d6e46cb..7067dd3 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioMode.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -13,7 +13,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum AudioMode {
+    INVALID = -2,
+    CURRENT = -1,
+    NORMAL = 0,
+    RINGTONE = 1,
+    IN_CALL = 2,
+    IN_COMMUNICATION = 3,
+    CALL_SCREEN = 4,
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioOutputFlags.aidl b/media/libaudioclient/aidl/android/media/AudioOutputFlags.aidl
index aebf871..cebd8f0 100644
--- a/media/libaudioclient/aidl/android/media/AudioOutputFlags.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioOutputFlags.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioOutputFlags {
     DIRECT           = 0,
@@ -32,4 +35,5 @@
     MMAP_NOIRQ       = 12,
     VOIP_RX          = 13,
     INCALL_MUSIC     = 14,
+    GAPLESS_OFFLOAD  = 15,
 }
diff --git a/media/libaudioclient/aidl/android/media/AudioPort.aidl b/media/libaudioclient/aidl/android/media/AudioPort.aidl
new file mode 100644
index 0000000..123aeb0
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioPort.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.media.AudioGain;
+import android.media.AudioPortConfig;
+import android.media.AudioPortExt;
+import android.media.AudioPortRole;
+import android.media.AudioPortType;
+import android.media.AudioProfile;
+
+/**
+ * {@hide}
+ */
+parcelable AudioPort {
+    /** Port unique ID. Interpreted as audio_port_handle_t. */
+    int id;
+    /** Sink or source. */
+    AudioPortRole role;
+    /** Device, mix ... */
+    AudioPortType type;
+    @utf8InCpp String name;
+    /** AudioProfiles supported by this port (format, Rates, Channels). */
+    AudioProfile[] profiles;
+    /** Gain controllers. */
+    AudioGain[] gains;
+    /** Current audio port configuration. */
+    AudioPortConfig activeConfig;
+    AudioPortExt ext;
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioPortConfigExt.aidl b/media/libaudioclient/aidl/android/media/AudioPortConfigExt.aidl
index 38da4f5..5d635b6 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortConfigExt.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortConfigExt.aidl
@@ -29,7 +29,7 @@
      * TODO(ytai): replace with the canonical representation for an empty union, as soon as it is
      *             established.
      */
-    boolean nothing;
+    boolean unspecified;
     /** Device specific info. */
     AudioPortConfigDeviceExt device;
     /** Mix specific info. */
diff --git a/media/libaudioclient/aidl/android/media/AudioPortConfigMixExtUseCase.aidl b/media/libaudioclient/aidl/android/media/AudioPortConfigMixExtUseCase.aidl
index 9e5e081..c61f044 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortConfigMixExtUseCase.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortConfigMixExtUseCase.aidl
@@ -29,7 +29,7 @@
      * TODO(ytai): replace with the canonical representation for an empty union, as soon as it is
      *             established.
      */
-    boolean nothing;
+    boolean unspecified;
     /** This to be set if the containing config has the AudioPortRole::SOURCE role. */
     AudioStreamType stream;
     /** This to be set if the containing config has the AudioPortRole::SINK role. */
diff --git a/media/libaudioclient/aidl/android/media/AudioPortConfigType.aidl b/media/libaudioclient/aidl/android/media/AudioPortConfigType.aidl
index c7bb4d8..6e22b8d 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortConfigType.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortConfigType.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioPortConfigType {
     SAMPLE_RATE  = 0,
diff --git a/media/libaudioclient/aidl/android/media/AudioPortDeviceExt.aidl b/media/libaudioclient/aidl/android/media/AudioPortDeviceExt.aidl
new file mode 100644
index 0000000..b758f23
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioPortDeviceExt.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.media.AudioDevice;
+
+/**
+ * {@hide}
+ */
+parcelable AudioPortDeviceExt {
+    /** Module the device is attached to. Interpreted as audio_module_handle_t. */
+    int hwModule;
+    AudioDevice device;
+    /** Bitmask, indexed by AudioEncapsulationMode. */
+    int encapsulationModes;
+    /** Bitmask, indexed by AudioEncapsulationMetadataType. */
+    int encapsulationMetadataTypes;
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioPortExt.aidl b/media/libaudioclient/aidl/android/media/AudioPortExt.aidl
new file mode 100644
index 0000000..453784b
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioPortExt.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.media.AudioPortDeviceExt;
+import android.media.AudioPortMixExt;
+import android.media.AudioPortSessionExt;
+
+/**
+ * {@hide}
+ */
+union AudioPortExt {
+    /**
+     * This represents an empty union. Value is ignored.
+     * TODO(ytai): replace with the canonical representation for an empty union, as soon as it is
+     *             established.
+     */
+    boolean unspecified;
+    /** Device specific info. */
+    AudioPortDeviceExt device;
+    /** Mix specific info. */
+    AudioPortMixExt mix;
+    /** Session specific info. */
+    AudioPortSessionExt session;
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioPortMixExt.aidl b/media/libaudioclient/aidl/android/media/AudioPortMixExt.aidl
new file mode 100644
index 0000000..62cdb8e
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioPortMixExt.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.media.AudioMixLatencyClass;
+
+/**
+ * {@hide}
+ */
+parcelable AudioPortMixExt {
+    /** Module the stream is attached to. Interpreted as audio_module_handle_t. */
+    int hwModule;
+    /** I/O handle of the input/output stream. Interpreted as audio_io_handle_t. */
+    int handle;
+    /** Latency class */
+    AudioMixLatencyClass latencyClass;
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioPortRole.aidl b/media/libaudioclient/aidl/android/media/AudioPortRole.aidl
index 3212325..ea2ef3a 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortRole.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortRole.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioPortRole {
     NONE = 0,
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/AudioPortSessionExt.aidl
similarity index 76%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to media/libaudioclient/aidl/android/media/AudioPortSessionExt.aidl
index d6e46cb..dbca168 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortSessionExt.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -16,4 +16,10 @@
 
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * {@hide}
+ */
+parcelable AudioPortSessionExt {
+    /** Audio session. Interpreted as audio_session_t. */
+    int session;
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioPortType.aidl b/media/libaudioclient/aidl/android/media/AudioPortType.aidl
index 90eea9a..9e6af49 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortType.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortType.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioPortType {
     NONE = 0,
diff --git a/media/libaudioclient/aidl/android/media/AudioProfile.aidl b/media/libaudioclient/aidl/android/media/AudioProfile.aidl
new file mode 100644
index 0000000..e5e8812
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioProfile.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.media.audio.common.AudioFormat;
+
+/**
+ * {@hide}
+ */
+parcelable AudioProfile {
+    @utf8InCpp String name;
+    /** The format for an audio profile should only be set when initialized. */
+    AudioFormat format;
+    /** Interpreted as audio_channel_mask_t. */
+    int[] channelMasks;
+    int[] samplingRates;
+    boolean isDynamicFormat;
+    boolean isDynamicChannels;
+    boolean isDynamicRate;
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioSourceType.aidl b/media/libaudioclient/aidl/android/media/AudioSourceType.aidl
index 35320f8..8673b92 100644
--- a/media/libaudioclient/aidl/android/media/AudioSourceType.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioSourceType.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioSourceType {
     INVALID = -1,
diff --git a/media/libaudioclient/aidl/android/media/AudioStreamType.aidl b/media/libaudioclient/aidl/android/media/AudioStreamType.aidl
index 803b87b..d777882 100644
--- a/media/libaudioclient/aidl/android/media/AudioStreamType.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioStreamType.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioStreamType {
     DEFAULT = -1,
diff --git a/media/libaudioclient/aidl/android/media/AudioTimestampInternal.aidl b/media/libaudioclient/aidl/android/media/AudioTimestampInternal.aidl
new file mode 100644
index 0000000..8bbfb57
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioTimestampInternal.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+/**
+ * The "Internal" timestamp is intended to disambiguate from the android.media.AudioTimestamp type.
+ *
+ * {@hide}
+ */
+parcelable AudioTimestampInternal {
+    /** A frame position in AudioTrack::getPosition() units. */
+    int position;
+    /** corresponding CLOCK_MONOTONIC when frame is expected to present. */
+    long sec;
+    int nsec;
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioUniqueIdUse.aidl b/media/libaudioclient/aidl/android/media/AudioUniqueIdUse.aidl
new file mode 100644
index 0000000..fdb6d2d
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioUniqueIdUse.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+package android.media;
+
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum AudioUniqueIdUse {
+    UNSPECIFIED = 0,
+    SESSION = 1, // audio_session_t
+                 // for allocated sessions, not special AUDIO_SESSION_*
+    MODULE = 2,  // audio_module_handle_t
+    EFFECT = 3,  // audio_effect_handle_t
+    PATCH = 4,   // audio_patch_handle_t
+    OUTPUT = 5,  // audio_io_handle_t
+    INPUT = 6,   // audio_io_handle_t
+    CLIENT = 7,  // client-side players and recorders
+                 // FIXME should move to a separate namespace;
+                 // these IDs are allocated by AudioFlinger on client request,
+                 // but are never used by AudioFlinger
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioUsage.aidl b/media/libaudioclient/aidl/android/media/AudioUsage.aidl
index 137e7ff..66c5c30 100644
--- a/media/libaudioclient/aidl/android/media/AudioUsage.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioUsage.aidl
@@ -15,6 +15,9 @@
  */
 package android.media;
 
+/**
+ * {@hide}
+ */
 @Backing(type="int")
 enum AudioUsage {
     UNKNOWN = 0,
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/AudioUuid.aidl
similarity index 73%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to media/libaudioclient/aidl/android/media/AudioUuid.aidl
index d6e46cb..bba9039 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioUuid.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -13,7 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * {@hide}
+ */
+parcelable AudioUuid {
+    int timeLow;
+    int timeMid;
+    int timeHiAndVersion;
+    int clockSeq;
+    byte[] node;  // Length = 6
+}
diff --git a/media/libaudioclient/aidl/android/media/CreateEffectRequest.aidl b/media/libaudioclient/aidl/android/media/CreateEffectRequest.aidl
new file mode 100644
index 0000000..8368854
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/CreateEffectRequest.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.media.AudioDevice;
+import android.media.EffectDescriptor;
+import android.media.IEffectClient;
+
+/**
+ * Input arguments of the createEffect() method.
+ *
+ * {@hide}
+ */
+parcelable CreateEffectRequest {
+    EffectDescriptor desc;
+    @nullable IEffectClient client;
+    int priority;
+    /** Interpreted as audio_io_handle_t. */
+    int output;
+    /** Interpreted as audio_session_t. */
+    int sessionId;
+    AudioDevice device;
+    @utf8InCpp String opPackageName;
+    /** Interpreted as pid_t. */
+    int pid;
+    boolean probe;
+}
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/CreateEffectResponse.aidl
similarity index 64%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to media/libaudioclient/aidl/android/media/CreateEffectResponse.aidl
index d6e46cb..0aa640a 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/CreateEffectResponse.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -16,4 +16,17 @@
 
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+import android.media.EffectDescriptor;
+import android.media.IEffect;
+
+/**
+ * Output arguments of the createEffect() method.
+ *
+ * {@hide}
+ */
+parcelable CreateEffectResponse {
+    int id;
+    boolean enabled;
+    @nullable IEffect effect;
+    EffectDescriptor desc;
+}
diff --git a/media/libaudioclient/aidl/android/media/CreateRecordResponse.aidl b/media/libaudioclient/aidl/android/media/CreateRecordResponse.aidl
index 0c9d7c3..d78b3fc 100644
--- a/media/libaudioclient/aidl/android/media/CreateRecordResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/CreateRecordResponse.aidl
@@ -16,6 +16,7 @@
 
 package android.media;
 
+import android.media.IAudioRecord;
 import android.media.SharedFileRegion;
 
 /**
@@ -40,4 +41,6 @@
     @nullable SharedFileRegion buffers;
     /** Interpreted as audio_port_handle_t. */
     int portId;
+    /** The newly created record. */
+    @nullable IAudioRecord audioRecord;
 }
diff --git a/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl b/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl
index 494e63f..6bdd8e4 100644
--- a/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl
@@ -16,6 +16,8 @@
 
 package android.media;
 
+import android.media.IAudioTrack;
+
 /**
  * CreateTrackOutput contains all output arguments returned by AudioFlinger to AudioTrack
  * when calling createTrack() including arguments that were passed as I/O for update by
@@ -39,4 +41,6 @@
     int outputId;
     /** Interpreted as audio_port_handle_t. */
     int portId;
+    /** The newly created track. */
+    @nullable IAudioTrack audioTrack;
 }
diff --git a/media/libaudioclient/aidl/android/media/EffectDescriptor.aidl b/media/libaudioclient/aidl/android/media/EffectDescriptor.aidl
new file mode 100644
index 0000000..35a3d74
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/EffectDescriptor.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.media.AudioUuid;
+
+/**
+ * {@hide}
+ */
+parcelable EffectDescriptor {
+    /** UUID of to the OpenSL ES interface implemented by this effect. */
+    AudioUuid type;
+    /** UUID for this particular implementation. */
+    AudioUuid uuid;
+    /** Version of the effect control API implemented. */
+    int apiVersion;
+    /** Effect engine capabilities/requirements flags. */
+    int flags;
+    /** CPU load indication.. */
+    int cpuLoad;
+    /** Data Memory usage.. */
+    int memoryUsage;
+    /** Human readable effect name. */
+    @utf8InCpp String name;
+    /** Human readable effect implementor name. */
+    @utf8InCpp String implementor;
+}
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
new file mode 100644
index 0000000..e63f391
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.media.AudioMode;
+import android.media.AudioPatch;
+import android.media.AudioPort;
+import android.media.AudioPortConfig;
+import android.media.AudioStreamType;
+import android.media.AudioUniqueIdUse;
+import android.media.AudioUuid;
+import android.media.CreateEffectRequest;
+import android.media.CreateEffectResponse;
+import android.media.CreateRecordRequest;
+import android.media.CreateRecordResponse;
+import android.media.CreateTrackRequest;
+import android.media.CreateTrackResponse;
+import android.media.OpenInputRequest;
+import android.media.OpenInputResponse;
+import android.media.OpenOutputRequest;
+import android.media.OpenOutputResponse;
+import android.media.EffectDescriptor;
+import android.media.IAudioFlingerClient;
+import android.media.IAudioRecord;
+import android.media.IAudioTrack;
+import android.media.MicrophoneInfoData;
+import android.media.RenderPosition;
+import android.media.audio.common.AudioFormat;
+
+/**
+ * {@hide}
+ */
+interface IAudioFlingerService {
+    /**
+     * Creates an audio track and registers it with AudioFlinger, or null if the track cannot be
+     * created.
+     */
+    CreateTrackResponse createTrack(in CreateTrackRequest request);
+
+    CreateRecordResponse createRecord(in CreateRecordRequest request);
+
+    // FIXME Surprisingly, format/latency don't work for input handles
+
+    /**
+     * Queries the audio hardware state. This state never changes, and therefore can be cached.
+     */
+    int sampleRate(int /* audio_io_handle_t */ ioHandle);
+
+    AudioFormat format(int /* audio_io_handle_t */ output);
+
+    long frameCount(int /* audio_io_handle_t */ ioHandle);
+
+    /**
+     * Return the estimated latency in milliseconds.
+     */
+    int latency(int  /* audio_io_handle_t */ output);
+
+    /*
+     * Sets/gets the audio hardware state. This will probably be used by
+     * the preference panel, mostly.
+     */
+    void setMasterVolume(float value);
+    void setMasterMute(boolean muted);
+
+    float masterVolume();
+    boolean masterMute();
+
+    void setMasterBalance(float balance);
+    float getMasterBalance();
+
+    /*
+     * Set/gets stream type state. This will probably be used by
+     * the preference panel, mostly.
+     */
+    void setStreamVolume(AudioStreamType stream, float value, int /* audio_io_handle_t */ output);
+    void setStreamMute(AudioStreamType stream, boolean muted);
+    float streamVolume(AudioStreamType stream, int /* audio_io_handle_t */ output);
+    boolean streamMute(AudioStreamType stream);
+
+    // set audio mode.
+    void setMode(AudioMode mode);
+
+    // mic mute/state
+    void setMicMute(boolean state);
+    boolean getMicMute();
+    void setRecordSilenced(int /* audio_port_handle_t */ portId,
+                           boolean silenced);
+
+    void setParameters(int /* audio_io_handle_t */ ioHandle,
+                       @utf8InCpp String keyValuePairs);
+    @utf8InCpp String getParameters(int /* audio_io_handle_t */ ioHandle,
+                                    @utf8InCpp String keys);
+
+    // Register an object to receive audio input/output change and track notifications.
+    // For a given calling pid, AudioFlinger disregards any registrations after the first.
+    // Thus the IAudioFlingerClient must be a singleton per process.
+    void registerClient(IAudioFlingerClient client);
+
+    // Retrieve the audio recording buffer size in bytes.
+    // FIXME This API assumes a route, and so should be deprecated.
+    long getInputBufferSize(int sampleRate,
+                            AudioFormat format,
+                            int /* audio_channel_mask_t */ channelMask);
+
+    OpenOutputResponse openOutput(in OpenOutputRequest request);
+    int /* audio_io_handle_t */ openDuplicateOutput(int /* audio_io_handle_t */ output1,
+                                                    int /* audio_io_handle_t */ output2);
+    void closeOutput(int /* audio_io_handle_t */ output);
+    void suspendOutput(int /* audio_io_handle_t */ output);
+    void restoreOutput(int /* audio_io_handle_t */ output);
+
+    OpenInputResponse openInput(in OpenInputRequest request);
+    void closeInput(int /* audio_io_handle_t */ input);
+
+    void invalidateStream(AudioStreamType stream);
+
+    void setVoiceVolume(float volume);
+
+    RenderPosition getRenderPosition(int /* audio_io_handle_t */ output);
+
+    int getInputFramesLost(int /* audio_io_handle_t */ ioHandle);
+
+    int /* audio_unique_id_t */ newAudioUniqueId(AudioUniqueIdUse use);
+
+    void acquireAudioSessionId(int /* audio_session_t */ audioSession,
+                               int /* pid_t */ pid,
+                               int /* uid_t */ uid);
+    void releaseAudioSessionId(int /* audio_session_t */ audioSession,
+                               int /* pid_t */ pid);
+
+    int queryNumberEffects();
+
+    EffectDescriptor queryEffect(int index);
+
+    /** preferredTypeFlag is interpreted as a uint32_t with the "effect flag" format. */
+    EffectDescriptor getEffectDescriptor(in AudioUuid effectUUID,
+                                         in AudioUuid typeUUID,
+                                         int preferredTypeFlag);
+
+    CreateEffectResponse createEffect(in CreateEffectRequest request);
+
+    void moveEffects(int /* audio_session_t */ session,
+                     int /* audio_io_handle_t */ srcOutput,
+                     int /* audio_io_handle_t */ dstOutput);
+
+    void setEffectSuspended(int effectId,
+                            int /* audio_session_t */ sessionId,
+                            boolean suspended);
+
+    int /* audio_module_handle_t */ loadHwModule(@utf8InCpp String name);
+
+    // helpers for android.media.AudioManager.getProperty(), see description there for meaning
+    // FIXME move these APIs to AudioPolicy to permit a more accurate implementation
+    // that looks on primary device for a stream with fast flag, primary flag, or first one.
+    int getPrimaryOutputSamplingRate();
+    long getPrimaryOutputFrameCount();
+
+    // Intended for AudioService to inform AudioFlinger of device's low RAM attribute,
+    // and should be called at most once.  For a definition of what "low RAM" means, see
+    // android.app.ActivityManager.isLowRamDevice().  The totalMemory parameter
+    // is obtained from android.app.ActivityManager.MemoryInfo.totalMem.
+    void setLowRamDevice(boolean isLowRamDevice, long totalMemory);
+
+    /* Get attributes for a given audio port */
+    AudioPort getAudioPort(in AudioPort port);
+
+    /* Create an audio patch between several source and sink ports */
+    int /* audio_patch_handle_t */ createAudioPatch(in AudioPatch patch);
+
+    /* Release an audio patch */
+    void releaseAudioPatch(int /* audio_patch_handle_t */ handle);
+
+    /* List existing audio patches */
+    AudioPatch[] listAudioPatches(int maxCount);
+    /* Set audio port configuration */
+    void setAudioPortConfig(in AudioPortConfig config);
+
+    /* Get the HW synchronization source used for an audio session */
+    int /* audio_hw_sync_t */ getAudioHwSyncForSession(int /* audio_session_t */ sessionId);
+
+    /* Indicate JAVA services are ready (scheduling, power management ...) */
+    oneway void systemReady();
+
+    // Returns the number of frames per audio HAL buffer.
+    long frameCountHAL(int /* audio_io_handle_t */ ioHandle);
+
+    /* List available microphones and their characteristics */
+    MicrophoneInfoData[] getMicrophones();
+
+    void setAudioHalPids(in int[] /* pid_t[] */ pids);
+}
diff --git a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
index ecf58b6..1772653 100644
--- a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
@@ -16,9 +16,13 @@
 
 package android.media;
 
-import android.media.MicrophoneInfo;
+import android.media.MicrophoneInfoData;
 
-/* Native code must specify namespace media (media::IAudioRecord) when referring to this class */
+/**
+ * Native code must specify namespace media (media::IAudioRecord) when referring to this class.
+ *
+ * {@hide}
+ */
 interface IAudioRecord {
 
   /* After it's created the track is not active. Call start() to
@@ -35,7 +39,7 @@
 
   /* Get a list of current active microphones.
    */
-  void getActiveMicrophones(out MicrophoneInfo[] activeMicrophones);
+  void getActiveMicrophones(out MicrophoneInfoData[] activeMicrophones);
 
   /* Set the microphone direction (for processing).
    */
diff --git a/media/libaudioclient/aidl/android/media/IAudioTrack.aidl b/media/libaudioclient/aidl/android/media/IAudioTrack.aidl
new file mode 100644
index 0000000..2b6c362
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/IAudioTrack.aidl
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.media.AudioTimestampInternal;
+import android.media.SharedFileRegion;
+import android.media.VolumeShaperConfiguration;
+import android.media.VolumeShaperOperation;
+import android.media.VolumeShaperState;
+
+/**
+ * Unless otherwise noted, methods returning int expect it to be interpreted as a status_t.
+ *
+ * {@hide}
+ */
+interface IAudioTrack {
+    /** Get this track's control block */
+    @nullable SharedFileRegion getCblk();
+
+    /**
+     * After it's created the track is not active. Call start() to
+     * make it active.
+     */
+    int start();
+
+    /**
+     * Stop a track. If set, the callback will cease being called and
+     * obtainBuffer will return an error. Buffers that are already released
+     * will continue to be processed, unless/until flush() is called.
+     */
+    void stop();
+
+    /**
+     * Flush a stopped or paused track. All pending/released buffers are discarded.
+     * This function has no effect if the track is not stopped or paused.
+     */
+    void flush();
+
+    /**
+     * Pause a track. If set, the callback will cease being called and
+     * obtainBuffer will return an error. Buffers that are already released
+     * will continue to be processed, unless/until flush() is called.
+     */
+    void pause();
+
+    /**
+     * Attach track auxiliary output to specified effect. Use effectId = 0
+     * to detach track from effect.
+     */
+    int attachAuxEffect(int effectId);
+
+    /** Send parameters to the audio hardware. */
+    int setParameters(@utf8InCpp String keyValuePairs);
+
+    /** Selects the presentation (if available). */
+    int selectPresentation(int presentationId, int programId);
+
+    /** Return NO_ERROR if timestamp is valid. */
+    int getTimestamp(out AudioTimestampInternal timestamp);
+
+    /** Signal the playback thread for a change in control block. */
+    void signal();
+
+    /** Sets the volume shaper. Returns the volume shaper status. */
+    int applyVolumeShaper(in VolumeShaperConfiguration configuration,
+                          in VolumeShaperOperation operation);
+
+    /** Gets the volume shaper state. */
+    @nullable VolumeShaperState getVolumeShaperState(int id);
+}
diff --git a/media/libaudioclient/aidl/android/media/IAudioTrackCallback.aidl b/media/libaudioclient/aidl/android/media/IAudioTrackCallback.aidl
index 21553b5..f593e22 100644
--- a/media/libaudioclient/aidl/android/media/IAudioTrackCallback.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioTrackCallback.aidl
@@ -17,7 +17,7 @@
 package android.media;
 
 /**
- * @hide
+ * {@hide}
  */
 interface IAudioTrackCallback {
     oneway void onCodecFormatChanged(in byte[] audioMetadata);
diff --git a/media/libaudioclient/aidl/android/media/ICaptureStateListener.aidl b/media/libaudioclient/aidl/android/media/ICaptureStateListener.aidl
index 8502282..3b2206a 100644
--- a/media/libaudioclient/aidl/android/media/ICaptureStateListener.aidl
+++ b/media/libaudioclient/aidl/android/media/ICaptureStateListener.aidl
@@ -16,6 +16,9 @@
 
 package android.media;
 
+/**
+ * {@hide}
+ */
 interface ICaptureStateListener {
     void setCaptureState(boolean active);
 }
diff --git a/media/libaudioclient/aidl/android/media/IEffect.aidl b/media/libaudioclient/aidl/android/media/IEffect.aidl
index 9548e46..813cd5c 100644
--- a/media/libaudioclient/aidl/android/media/IEffect.aidl
+++ b/media/libaudioclient/aidl/android/media/IEffect.aidl
@@ -21,7 +21,7 @@
 /**
  * The IEffect interface enables control of the effect module activity and parameters.
  *
- * @hide
+ * {@hide}
  */
 interface IEffect {
     /**
diff --git a/media/libaudioclient/aidl/android/media/IEffectClient.aidl b/media/libaudioclient/aidl/android/media/IEffectClient.aidl
index d1e331c..3b6bcf1 100644
--- a/media/libaudioclient/aidl/android/media/IEffectClient.aidl
+++ b/media/libaudioclient/aidl/android/media/IEffectClient.aidl
@@ -19,7 +19,7 @@
 /**
  * A callback interface for getting effect-related notifications.
  *
- * @hide
+ * {@hide}
  */
 interface IEffectClient {
     /**
diff --git a/media/libaudioclient/aidl/android/media/IPlayer.aidl b/media/libaudioclient/aidl/android/media/IPlayer.aidl
index 8c2c471..43bb7f3 100644
--- a/media/libaudioclient/aidl/android/media/IPlayer.aidl
+++ b/media/libaudioclient/aidl/android/media/IPlayer.aidl
@@ -20,7 +20,7 @@
 import android.media.VolumeShaperOperation;
 
 /**
- * @hide
+ * {@hide}
  */
 interface IPlayer {
     oneway void start();
diff --git a/media/libaudioclient/aidl/android/media/OpenInputRequest.aidl b/media/libaudioclient/aidl/android/media/OpenInputRequest.aidl
new file mode 100644
index 0000000..2e55526
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/OpenInputRequest.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.media.AudioConfig;
+import android.media.AudioDevice;
+import android.media.AudioSourceType;
+
+/**
+ * {@hide}
+ */
+parcelable OpenInputRequest {
+    /** Interpreted as audio_module_handle_t. */
+    int module;
+    /** Interpreted as audio_io_handle_t. */
+    int input;
+    AudioConfig config;
+    AudioDevice device;
+    AudioSourceType source;
+    /** Bitmask, indexed by AudioInputFlag. */
+    int flags;
+}
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/OpenInputResponse.aidl
similarity index 67%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to media/libaudioclient/aidl/android/media/OpenInputResponse.aidl
index d6e46cb..b613ba5 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/OpenInputResponse.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -16,4 +16,15 @@
 
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+import android.media.AudioConfig;
+import android.media.AudioDevice;
+
+/**
+ * {@hide}
+ */
+parcelable OpenInputResponse {
+    /** Interpreted as audio_io_handle_t. */
+    int input;
+    AudioConfig config;
+    AudioDevice device;
+}
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl
similarity index 60%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl
index d6e46cb..06b12e9 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -16,4 +16,18 @@
 
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+import android.media.AudioConfig;
+import android.media.AudioPort;
+
+/**
+ * {@hide}
+ */
+parcelable OpenOutputRequest {
+    /** Interpreted as audio_module_handle_t. */
+    int module;
+    AudioConfig config;
+    /** Type must be DEVICE. */
+    AudioPort device;
+    /** Bitmask, indexed by AudioOutputFlag. */
+    int flags;
+}
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/OpenOutputResponse.aidl
similarity index 65%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to media/libaudioclient/aidl/android/media/OpenOutputResponse.aidl
index d6e46cb..a051969 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/OpenOutputResponse.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -16,4 +16,16 @@
 
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+import android.media.AudioConfig;
+
+/**
+ * {@hide}
+ */
+parcelable OpenOutputResponse {
+    /** Interpreted as audio_io_handle_t. */
+    int output;
+    AudioConfig config;
+    int latencyMs;
+    /** Bitmask, indexed by AudioOutputFlag. */
+    int flags;
+}
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/media/libaudioclient/aidl/android/media/RenderPosition.aidl
similarity index 80%
rename from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
rename to media/libaudioclient/aidl/android/media/RenderPosition.aidl
index d6e46cb..98dc17a 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/media/libaudioclient/aidl/android/media/RenderPosition.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -16,4 +16,10 @@
 
 package android.media;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * {@hide}
+ */
+parcelable RenderPosition {
+    int halFrames;
+    int dspFrames;
+}
diff --git a/media/libaudioclient/include/media/AidlConversion.h b/media/libaudioclient/include/media/AidlConversion.h
index 4df8083..e3858b9 100644
--- a/media/libaudioclient/include/media/AidlConversion.h
+++ b/media/libaudioclient/include/media/AidlConversion.h
@@ -21,68 +21,42 @@
 
 #include <system/audio.h>
 
-#include <android-base/expected.h>
-
 #include <android/media/AudioAttributesInternal.h>
 #include <android/media/AudioClient.h>
 #include <android/media/AudioConfig.h>
 #include <android/media/AudioConfigBase.h>
+#include <android/media/AudioEncapsulationMode.h>
+#include <android/media/AudioEncapsulationMetadataType.h>
 #include <android/media/AudioFlag.h>
+#include <android/media/AudioGain.h>
 #include <android/media/AudioGainMode.h>
 #include <android/media/AudioInputFlags.h>
 #include <android/media/AudioIoConfigEvent.h>
 #include <android/media/AudioIoDescriptor.h>
+#include <android/media/AudioMixLatencyClass.h>
+#include <android/media/AudioMode.h>
 #include <android/media/AudioOutputFlags.h>
+#include <android/media/AudioPort.h>
 #include <android/media/AudioPortConfigType.h>
+#include <android/media/AudioPortDeviceExt.h>
+#include <android/media/AudioPortExt.h>
+#include <android/media/AudioPortMixExt.h>
+#include <android/media/AudioPortSessionExt.h>
+#include <android/media/AudioProfile.h>
+#include <android/media/AudioTimestampInternal.h>
+#include <android/media/AudioUniqueIdUse.h>
+#include <android/media/EffectDescriptor.h>
 
 #include <android/media/SharedFileRegion.h>
-
 #include <binder/IMemory.h>
+#include <media/AidlConversionUtil.h>
 #include <media/AudioClient.h>
 #include <media/AudioIoDescriptor.h>
+#include <media/AudioTimestamp.h>
+#include <system/audio_effect.h>
 
 namespace android {
 
-template <typename T>
-using ConversionResult = base::expected<T, status_t>;
-
-// Convenience macros for working with ConversionResult, useful for writing converted for aggregate
-// types.
-
-#define VALUE_OR_RETURN(result)                                \
-    ({                                                         \
-        auto _tmp = (result);                                  \
-        if (!_tmp.ok()) return base::unexpected(_tmp.error()); \
-        std::move(_tmp.value());                               \
-    })
-
-#define RETURN_IF_ERROR(result) \
-    if (status_t _tmp = (result); _tmp != OK) return base::unexpected(_tmp);
-
-/**
- * A generic template to safely cast between integral types, respecting limits of the destination
- * type.
- */
-template<typename To, typename From>
-ConversionResult<To> convertIntegral(From from) {
-    // Special handling is required for signed / vs. unsigned comparisons, since otherwise we may
-    // have the signed converted to unsigned and produce wrong results.
-    if (std::is_signed_v<From> && !std::is_signed_v<To>) {
-        if (from < 0 || from > std::numeric_limits<To>::max()) {
-            return base::unexpected(BAD_VALUE);
-        }
-    } else if (std::is_signed_v<To> && !std::is_signed_v<From>) {
-        if (from > std::numeric_limits<To>::max()) {
-            return base::unexpected(BAD_VALUE);
-        }
-    } else {
-        if (from < std::numeric_limits<To>::min() || from > std::numeric_limits<To>::max()) {
-            return base::unexpected(BAD_VALUE);
-        }
-    }
-    return static_cast<To>(from);
-}
-
 // maxSize is the size of the C-string buffer (including the 0-terminator), NOT the max length of
 // the string.
 status_t aidl2legacy_string(std::string_view aidl, char* dest, size_t maxSize);
@@ -103,10 +77,15 @@
 ConversionResult<audio_unique_id_t> aidl2legacy_int32_t_audio_unique_id_t(int32_t aidl);
 ConversionResult<int32_t> legacy2aidl_audio_unique_id_t_int32_t(audio_unique_id_t legacy);
 
-// The legacy enum is unnamed. Thus, we use int.
-ConversionResult<int> aidl2legacy_AudioPortConfigType(media::AudioPortConfigType aidl);
-// The legacy enum is unnamed. Thus, we use int.
-ConversionResult<media::AudioPortConfigType> legacy2aidl_AudioPortConfigType(int legacy);
+ConversionResult<audio_hw_sync_t> aidl2legacy_int32_t_audio_hw_sync_t(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_hw_sync_t_int32_t(audio_hw_sync_t legacy);
+
+// The legacy enum is unnamed. Thus, we use int32_t.
+ConversionResult<int32_t> aidl2legacy_AudioPortConfigType_int32_t(
+        media::AudioPortConfigType aidl);
+// The legacy enum is unnamed. Thus, we use int32_t.
+ConversionResult<media::AudioPortConfigType> legacy2aidl_int32_t_AudioPortConfigType(
+        int32_t legacy);
 
 ConversionResult<unsigned int> aidl2legacy_int32_t_config_mask(int32_t aidl);
 ConversionResult<int32_t> legacy2aidl_config_mask_int32_t(unsigned int legacy);
@@ -120,6 +99,9 @@
 ConversionResult<uid_t> aidl2legacy_int32_t_uid_t(int32_t aidl);
 ConversionResult<int32_t> legacy2aidl_uid_t_int32_t(uid_t legacy);
 
+ConversionResult<String8> aidl2legacy_string_view_String8(std::string_view aidl);
+ConversionResult<std::string> legacy2aidl_String8_string(const String8& legacy);
+
 ConversionResult<String16> aidl2legacy_string_view_String16(std::string_view aidl);
 ConversionResult<std::string> legacy2aidl_String16_string(const String16& legacy);
 
@@ -143,11 +125,13 @@
 ConversionResult<media::audio::common::AudioFormat> legacy2aidl_audio_format_t_AudioFormat(
         audio_format_t legacy);
 
-ConversionResult<int> aidl2legacy_AudioGainMode_int(media::AudioGainMode aidl);
-ConversionResult<media::AudioGainMode> legacy2aidl_int_AudioGainMode(int legacy);
+ConversionResult<audio_gain_mode_t>
+aidl2legacy_AudioGainMode_audio_gain_mode_t(media::AudioGainMode aidl);
+ConversionResult<media::AudioGainMode>
+legacy2aidl_audio_gain_mode_t_AudioGainMode(audio_gain_mode_t legacy);
 
-ConversionResult<audio_gain_mode_t> aidl2legacy_int32_t_audio_gain_mode_t(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_gain_mode_t_int32_t(audio_gain_mode_t legacy);
+ConversionResult<audio_gain_mode_t> aidl2legacy_int32_t_audio_gain_mode_t_mask(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_gain_mode_t_int32_t_mask(audio_gain_mode_t legacy);
 
 ConversionResult<audio_devices_t> aidl2legacy_int32_t_audio_devices_t(int32_t aidl);
 ConversionResult<int32_t> legacy2aidl_audio_devices_t_int32_t(audio_devices_t legacy);
@@ -167,20 +151,26 @@
 ConversionResult<media::AudioOutputFlags> legacy2aidl_audio_output_flags_t_AudioOutputFlags(
         audio_output_flags_t legacy);
 
-ConversionResult<audio_input_flags_t> aidl2legacy_audio_input_flags_mask(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_input_flags_mask(audio_input_flags_t legacy);
+ConversionResult<audio_input_flags_t> aidl2legacy_int32_t_audio_input_flags_t_mask(
+        int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_input_flags_t_int32_t_mask(
+        audio_input_flags_t legacy);
 
-ConversionResult<audio_output_flags_t> aidl2legacy_audio_output_flags_mask(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_output_flags_mask(audio_output_flags_t legacy);
+ConversionResult<audio_output_flags_t> aidl2legacy_int32_t_audio_output_flags_t_mask(
+        int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_output_flags_t_int32_t_mask(
+        audio_output_flags_t legacy);
 
 ConversionResult<audio_io_flags> aidl2legacy_AudioIoFlags_audio_io_flags(
         const media::AudioIoFlags& aidl, media::AudioPortRole role, media::AudioPortType type);
 ConversionResult<media::AudioIoFlags> legacy2aidl_audio_io_flags_AudioIoFlags(
         const audio_io_flags& legacy, audio_port_role_t role, audio_port_type_t type);
 
-ConversionResult<audio_port_config_device_ext> aidl2legacy_AudioPortConfigDeviceExt(
+ConversionResult<audio_port_config_device_ext>
+aidl2legacy_AudioPortConfigDeviceExt_audio_port_config_device_ext(
         const media::AudioPortConfigDeviceExt& aidl);
-ConversionResult<media::AudioPortConfigDeviceExt> legacy2aidl_AudioPortConfigDeviceExt(
+ConversionResult<media::AudioPortConfigDeviceExt>
+legacy2aidl_audio_port_config_device_ext_AudioPortConfigDeviceExt(
         const audio_port_config_device_ext& legacy);
 
 ConversionResult<audio_stream_type_t> aidl2legacy_AudioStreamType_audio_stream_type_t(
@@ -201,9 +191,11 @@
 ConversionResult<media::AudioPortConfigMixExt> legacy2aidl_AudioPortConfigMixExt(
         const audio_port_config_mix_ext& legacy, audio_port_role_t role);
 
-ConversionResult<audio_port_config_session_ext> aidl2legacy_AudioPortConfigSessionExt(
+ConversionResult<audio_port_config_session_ext>
+aidl2legacy_AudioPortConfigSessionExt_audio_port_config_session_ext(
         const media::AudioPortConfigSessionExt& aidl);
-ConversionResult<media::AudioPortConfigSessionExt> legacy2aidl_AudioPortConfigSessionExt(
+ConversionResult<media::AudioPortConfigSessionExt>
+legacy2aidl_audio_port_config_session_ext_AudioPortConfigSessionExt(
         const audio_port_config_session_ext& legacy);
 
 ConversionResult<audio_port_config> aidl2legacy_AudioPortConfig_audio_port_config(
@@ -222,8 +214,10 @@
 ConversionResult<media::AudioIoDescriptor> legacy2aidl_AudioIoDescriptor_AudioIoDescriptor(
         const sp<AudioIoDescriptor>& legacy);
 
-ConversionResult<AudioClient> aidl2legacy_AudioClient(const media::AudioClient& aidl);
-ConversionResult<media::AudioClient> legacy2aidl_AudioClient(const AudioClient& legacy);
+ConversionResult<AudioClient> aidl2legacy_AudioClient_AudioClient(
+        const media::AudioClient& aidl);
+ConversionResult<media::AudioClient> legacy2aidl_AudioClient_AudioClient(
+        const AudioClient& legacy);
 
 ConversionResult<audio_content_type_t>
 aidl2legacy_AudioContentType_audio_content_type_t(media::AudioContentType aidl);
@@ -251,9 +245,9 @@
 legacy2aidl_audio_attributes_t_AudioAttributesInternal(const audio_attributes_t& legacy);
 
 ConversionResult<audio_encapsulation_mode_t>
-aidl2legacy_audio_encapsulation_mode_t_AudioEncapsulationMode(media::AudioEncapsulationMode aidl);
+aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(media::AudioEncapsulationMode aidl);
 ConversionResult<media::AudioEncapsulationMode>
-legacy2aidl_AudioEncapsulationMode_audio_encapsulation_mode_t(audio_encapsulation_mode_t legacy);
+legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(audio_encapsulation_mode_t legacy);
 
 ConversionResult<audio_offload_info_t>
 aidl2legacy_AudioOffloadInfo_audio_offload_info_t(const media::AudioOffloadInfo& aidl);
@@ -280,4 +274,83 @@
 ConversionResult<std::optional<media::SharedFileRegion>>
 legacy2aidl_NullableIMemory_SharedFileRegion(const sp<IMemory>& legacy);
 
+ConversionResult<AudioTimestamp>
+aidl2legacy_AudioTimestampInternal_AudioTimestamp(const media::AudioTimestampInternal& aidl);
+ConversionResult<media::AudioTimestampInternal>
+legacy2aidl_AudioTimestamp_AudioTimestampInternal(const AudioTimestamp& legacy);
+
+ConversionResult<audio_uuid_t>
+aidl2legacy_AudioUuid_audio_uuid_t(const media::AudioUuid& aidl);
+ConversionResult<media::AudioUuid>
+legacy2aidl_audio_uuid_t_AudioUuid(const audio_uuid_t& legacy);
+
+ConversionResult<effect_descriptor_t>
+aidl2legacy_EffectDescriptor_effect_descriptor_t(const media::EffectDescriptor& aidl);
+ConversionResult<media::EffectDescriptor>
+legacy2aidl_effect_descriptor_t_EffectDescriptor(const effect_descriptor_t& legacy);
+
+ConversionResult<audio_encapsulation_metadata_type_t>
+aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t(
+        media::AudioEncapsulationMetadataType aidl);
+ConversionResult<media::AudioEncapsulationMetadataType>
+legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType(
+        audio_encapsulation_metadata_type_t legacy);
+
+ConversionResult<uint32_t>
+aidl2legacy_AudioEncapsulationMode_mask(int32_t aidl);
+ConversionResult<int32_t>
+legacy2aidl_AudioEncapsulationMode_mask(uint32_t legacy);
+
+ConversionResult<uint32_t>
+aidl2legacy_AudioEncapsulationMetadataType_mask(int32_t aidl);
+ConversionResult<int32_t>
+legacy2aidl_AudioEncapsulationMetadataType_mask(uint32_t legacy);
+
+ConversionResult<audio_mix_latency_class_t>
+aidl2legacy_AudioMixLatencyClass_audio_mix_latency_class_t(
+        media::AudioMixLatencyClass aidl);
+ConversionResult<media::AudioMixLatencyClass>
+legacy2aidl_audio_mix_latency_class_t_AudioMixLatencyClass(
+        audio_mix_latency_class_t legacy);
+
+ConversionResult<audio_port_device_ext>
+aidl2legacy_AudioPortDeviceExt_audio_port_device_ext(const media::AudioPortDeviceExt& aidl);
+ConversionResult<media::AudioPortDeviceExt>
+legacy2aidl_audio_port_device_ext_AudioPortDeviceExt(const audio_port_device_ext& legacy);
+
+ConversionResult<audio_port_mix_ext>
+aidl2legacy_AudioPortMixExt_audio_port_mix_ext(const media::AudioPortMixExt& aidl);
+ConversionResult<media::AudioPortMixExt>
+legacy2aidl_audio_port_mix_ext_AudioPortMixExt(const audio_port_mix_ext& legacy);
+
+ConversionResult<audio_port_session_ext>
+aidl2legacy_AudioPortSessionExt_audio_port_session_ext(const media::AudioPortSessionExt& aidl);
+ConversionResult<media::AudioPortSessionExt>
+legacy2aidl_audio_port_session_ext_AudioPortSessionExt(const audio_port_session_ext& legacy);
+
+ConversionResult<audio_profile>
+aidl2legacy_AudioProfile_audio_profile(const media::AudioProfile& aidl);
+ConversionResult<media::AudioProfile>
+legacy2aidl_audio_profile_AudioProfile(const audio_profile& legacy);
+
+ConversionResult<audio_gain>
+aidl2legacy_AudioGain_audio_gain(const media::AudioGain& aidl);
+ConversionResult<media::AudioGain>
+legacy2aidl_audio_gain_AudioGain(const audio_gain& legacy);
+
+ConversionResult<audio_port_v7>
+aidl2legacy_AudioPort_audio_port_v7(const media::AudioPort& aidl);
+ConversionResult<media::AudioPort>
+legacy2aidl_audio_port_v7_AudioPort(const audio_port_v7& legacy);
+
+ConversionResult<audio_mode_t>
+aidl2legacy_AudioMode_audio_mode_t(media::AudioMode aidl);
+ConversionResult<media::AudioMode>
+legacy2aidl_audio_mode_t_AudioMode(audio_mode_t legacy);
+
+ConversionResult<audio_unique_id_use_t>
+aidl2legacy_AudioUniqueIdUse_audio_unique_id_use_t(media::AudioUniqueIdUse aidl);
+ConversionResult<media::AudioUniqueIdUse>
+legacy2aidl_audio_unique_id_use_t_AudioUniqueIdUse(audio_unique_id_use_t legacy);
+
 }  // namespace android
diff --git a/media/libaudioclient/include/media/AidlConversionUtil.h b/media/libaudioclient/include/media/AidlConversionUtil.h
new file mode 100644
index 0000000..9453673
--- /dev/null
+++ b/media/libaudioclient/include/media/AidlConversionUtil.h
@@ -0,0 +1,230 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <limits>
+#include <type_traits>
+#include <utility>
+
+#include <android-base/expected.h>
+#include <binder/Status.h>
+
+namespace android {
+
+template <typename T>
+using ConversionResult = base::expected<T, status_t>;
+
+// Convenience macros for working with ConversionResult, useful for writing converted for aggregate
+// types.
+
+#define VALUE_OR_RETURN(result)                                \
+    ({                                                         \
+        auto _tmp = (result);                                  \
+        if (!_tmp.ok()) return base::unexpected(_tmp.error()); \
+        std::move(_tmp.value());                               \
+    })
+
+#define RETURN_IF_ERROR(result) \
+    if (status_t _tmp = (result); _tmp != OK) return base::unexpected(_tmp);
+
+#define VALUE_OR_RETURN_STATUS(x)           \
+    ({                                      \
+       auto _tmp = (x);                     \
+       if (!_tmp.ok()) return _tmp.error(); \
+       std::move(_tmp.value());             \
+     })
+
+/**
+ * A generic template to safely cast between integral types, respecting limits of the destination
+ * type.
+ */
+template<typename To, typename From>
+ConversionResult<To> convertIntegral(From from) {
+    // Special handling is required for signed / vs. unsigned comparisons, since otherwise we may
+    // have the signed converted to unsigned and produce wrong results.
+    if (std::is_signed_v<From> && !std::is_signed_v<To>) {
+        if (from < 0 || from > std::numeric_limits<To>::max()) {
+            return base::unexpected(BAD_VALUE);
+        }
+    } else if (std::is_signed_v<To> && !std::is_signed_v<From>) {
+        if (from > std::numeric_limits<To>::max()) {
+            return base::unexpected(BAD_VALUE);
+        }
+    } else {
+        if (from < std::numeric_limits<To>::min() || from > std::numeric_limits<To>::max()) {
+            return base::unexpected(BAD_VALUE);
+        }
+    }
+    return static_cast<To>(from);
+}
+
+/**
+ * A generic template to safely cast between types, that are intended to be the same size, but
+ * interpreted differently.
+ */
+template<typename To, typename From>
+ConversionResult<To> convertReinterpret(From from) {
+    static_assert(sizeof(From) == sizeof(To));
+    return static_cast<To>(from);
+}
+
+/**
+ * A generic template that helps convert containers of convertible types, using iterators.
+ */
+template<typename InputIterator, typename OutputIterator, typename Func>
+status_t convertRange(InputIterator start,
+                      InputIterator end,
+                      OutputIterator out,
+                      const Func& itemConversion) {
+    for (InputIterator iter = start; iter != end; ++iter, ++out) {
+        *out = VALUE_OR_RETURN_STATUS(itemConversion(*iter));
+    }
+    return OK;
+}
+
+/**
+ * A generic template that helps convert containers of convertible types.
+ */
+template<typename OutputContainer, typename InputContainer, typename Func>
+ConversionResult<OutputContainer>
+convertContainer(const InputContainer& input, const Func& itemConversion) {
+    OutputContainer output;
+    auto ins = std::inserter(output, output.begin());
+    for (const auto& item : input) {
+        *ins = VALUE_OR_RETURN(itemConversion(item));
+    }
+    return output;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Utilities for working with AIDL unions.
+// UNION_GET(obj, fieldname) returns a ConversionResult<T> containing either the strongly-typed
+//   value of the respective field, or BAD_VALUE if the union is not set to the requested field.
+// UNION_SET(obj, fieldname, value) sets the requested field to the given value.
+
+template<typename T, typename T::Tag tag>
+using UnionFieldType = std::decay_t<decltype(std::declval<T>().template get<tag>())>;
+
+template<typename T, typename T::Tag tag>
+ConversionResult<UnionFieldType<T, tag>> unionGetField(const T& u) {
+    if (u.getTag() != tag) {
+        return base::unexpected(BAD_VALUE);
+    }
+    return u.template get<tag>();
+}
+
+#define UNION_GET(u, field) \
+    unionGetField<std::decay_t<decltype(u)>, std::decay_t<decltype(u)>::Tag::field>(u)
+
+#define UNION_SET(u, field, value) \
+    (u).set<std::decay_t<decltype(u)>::Tag::field>(value)
+
+namespace aidl_utils {
+
+/**
+ * Return the equivalent Android status_t from a binder exception code.
+ *
+ * Generally one should use statusTFromBinderStatus() instead.
+ *
+ * Exception codes can be generated from a remote Java service exception, translate
+ * them for use on the Native side.
+ *
+ * Note: for EX_TRANSACTION_FAILED and EX_SERVICE_SPECIFIC a more detailed error code
+ * can be found from transactionError() or serviceSpecificErrorCode().
+ */
+static inline status_t statusTFromExceptionCode(int32_t exceptionCode) {
+    using namespace ::android::binder;
+    switch (exceptionCode) {
+        case Status::EX_NONE:
+            return OK;
+        case Status::EX_SECURITY: // Java SecurityException, rethrows locally in Java
+            return PERMISSION_DENIED;
+        case Status::EX_BAD_PARCELABLE: // Java BadParcelableException, rethrows in Java
+        case Status::EX_ILLEGAL_ARGUMENT: // Java IllegalArgumentException, rethrows in Java
+        case Status::EX_NULL_POINTER: // Java NullPointerException, rethrows in Java
+            return BAD_VALUE;
+        case Status::EX_ILLEGAL_STATE: // Java IllegalStateException, rethrows in Java
+        case Status::EX_UNSUPPORTED_OPERATION: // Java UnsupportedOperationException, rethrows
+            return INVALID_OPERATION;
+        case Status::EX_HAS_REPLY_HEADER: // Native strictmode violation
+        case Status::EX_PARCELABLE: // Java bootclass loader (not standard exception), rethrows
+        case Status::EX_NETWORK_MAIN_THREAD: // Java NetworkOnMainThreadException, rethrows
+        case Status::EX_TRANSACTION_FAILED: // Native - see error code
+        case Status::EX_SERVICE_SPECIFIC:  // Java ServiceSpecificException,
+                                           // rethrows in Java with integer error code
+            return UNKNOWN_ERROR;
+    }
+    return UNKNOWN_ERROR;
+}
+
+/**
+ * Return the equivalent Android status_t from a binder status.
+ *
+ * Used to handle errors from a AIDL method declaration
+ *
+ * [oneway] void method(type0 param0, ...)
+ *
+ * or the following (where return_type is not a status_t)
+ *
+ * return_type method(type0 param0, ...)
+ */
+static inline status_t statusTFromBinderStatus(const ::android::binder::Status &status) {
+    return status.isOk() ? OK // check OK,
+        : status.serviceSpecificErrorCode() // service-side error, not standard Java exception
+                                            // (fromServiceSpecificError)
+        ?: status.transactionError() // a native binder transaction error (fromStatusT)
+        ?: statusTFromExceptionCode(status.exceptionCode()); // a service-side error with a
+                                                    // standard Java exception (fromExceptionCode)
+}
+
+/**
+ * Return a binder::Status from native service status.
+ *
+ * This is used for methods not returning an explicit status_t,
+ * where Java callers expect an exception, not an integer return value.
+ */
+static inline ::android::binder::Status binderStatusFromStatusT(
+        status_t status, const char *optionalMessage = nullptr) {
+    const char * const emptyIfNull = optionalMessage == nullptr ? "" : optionalMessage;
+    // From binder::Status instructions:
+    //  Prefer a generic exception code when possible, then a service specific
+    //  code, and finally a status_t for low level failures or legacy support.
+    //  Exception codes and service specific errors map to nicer exceptions for
+    //  Java clients.
+
+    using namespace ::android::binder;
+    switch (status) {
+        case OK:
+            return Status::ok();
+        case PERMISSION_DENIED: // throw SecurityException on Java side
+            return Status::fromExceptionCode(Status::EX_SECURITY, emptyIfNull);
+        case BAD_VALUE: // throw IllegalArgumentException on Java side
+            return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, emptyIfNull);
+        case INVALID_OPERATION: // throw IllegalStateException on Java side
+            return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, emptyIfNull);
+    }
+
+    // A service specific error will not show on status.transactionError() so
+    // be sure to use statusTFromBinderStatus() for reliable error handling.
+
+    // throw a ServiceSpecificException.
+    return Status::fromServiceSpecificError(status, emptyIfNull);
+}
+
+} // namespace aidl_utils
+
+}  // namespace android
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index dfc1982..7a3692b 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -319,9 +319,10 @@
 
     static status_t setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t flags);
 
-    // Check if hw offload is possible for given format, stream type, sample rate,
-    // bit rate, duration, video and streaming or offload property is enabled
-    static bool isOffloadSupported(const audio_offload_info_t& info);
+    // Indicate if hw offload is possible for given format, stream type, sample rate,
+    // bit rate, duration, video and streaming or offload property is enabled and when possible
+    // if gapless transitions are supported.
+    static audio_offload_mode_t getOffloadSupport(const audio_offload_info_t& info);
 
     // check presence of audio flinger service.
     // returns NO_ERROR if binding to service succeeds, DEAD_OBJECT otherwise
@@ -331,11 +332,11 @@
     static status_t listAudioPorts(audio_port_role_t role,
                                    audio_port_type_t type,
                                    unsigned int *num_ports,
-                                   struct audio_port *ports,
+                                   struct audio_port_v7 *ports,
                                    unsigned int *generation);
 
     /* Get attributes for a given audio port */
-    static status_t getAudioPort(struct audio_port *port);
+    static status_t getAudioPort(struct audio_port_v7 *port);
 
     /* Create an audio patch between several source and sink ports */
     static status_t createAudioPatch(const struct audio_patch *patch,
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index de183d8..3728a16 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -17,18 +17,20 @@
 #ifndef ANDROID_AUDIOTRACK_H
 #define ANDROID_AUDIOTRACK_H
 
+#include <binder/IMemory.h>
 #include <cutils/sched_policy.h>
 #include <media/AudioSystem.h>
 #include <media/AudioTimestamp.h>
-#include <media/IAudioTrack.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/MediaMetricsItem.h>
 #include <media/Modulo.h>
+#include <media/VolumeShaper.h>
 #include <utils/threads.h>
 
 #include <string>
 
 #include "android/media/BnAudioTrackCallback.h"
+#include "android/media/IAudioTrack.h"
 #include "android/media/IAudioTrackCallback.h"
 
 namespace android {
@@ -1071,7 +1073,7 @@
             void     updateRoutedDeviceId_l();
 
     // Next 4 fields may be changed if IAudioTrack is re-created, but always != 0
-    sp<IAudioTrack>         mAudioTrack;
+    sp<media::IAudioTrack>  mAudioTrack;
     sp<IMemory>             mCblkMemory;
     audio_track_cblk_t*     mCblk;                  // re-load after mLock.unlock()
     audio_io_handle_t       mOutput = AUDIO_IO_HANDLE_NONE; // from AudioSystem::getOutputForAttr()
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 3491fda..9a8014d 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -24,12 +24,9 @@
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
 #include <binder/IInterface.h>
-#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
 #include <media/AidlConversion.h>
 #include <media/AudioClient.h>
 #include <media/DeviceDescriptorBase.h>
-#include <media/IAudioTrack.h>
 #include <system/audio.h>
 #include <system/audio_effect.h>
 #include <system/audio_policy.h>
@@ -38,24 +35,34 @@
 #include <string>
 #include <vector>
 
+#include <android/media/BnAudioFlingerService.h>
+#include <android/media/BpAudioFlingerService.h>
+#include "android/media/CreateEffectRequest.h"
+#include "android/media/CreateEffectResponse.h"
 #include "android/media/CreateRecordRequest.h"
 #include "android/media/CreateRecordResponse.h"
 #include "android/media/CreateTrackRequest.h"
 #include "android/media/CreateTrackResponse.h"
 #include "android/media/IAudioRecord.h"
 #include "android/media/IAudioFlingerClient.h"
+#include "android/media/IAudioTrack.h"
 #include "android/media/IAudioTrackCallback.h"
 #include "android/media/IEffect.h"
 #include "android/media/IEffectClient.h"
+#include "android/media/OpenInputRequest.h"
+#include "android/media/OpenInputResponse.h"
+#include "android/media/OpenOutputRequest.h"
+#include "android/media/OpenOutputResponse.h"
 
 namespace android {
 
 // ----------------------------------------------------------------------------
 
-class IAudioFlinger : public IInterface
-{
+class IAudioFlinger : public RefBase {
 public:
-    DECLARE_META_INTERFACE(AudioFlinger);
+    static constexpr char DEFAULT_SERVICE_NAME[] = "media.audio_flinger";
+
+    virtual ~IAudioFlinger() = default;
 
     /* CreateTrackInput contains all input arguments sent by AudioTrack to AudioFlinger
      * when calling createTrack() including arguments that will be updated by AudioFlinger
@@ -104,6 +111,7 @@
         uint32_t afLatencyMs;
         audio_io_handle_t outputId;
         audio_port_handle_t portId;
+        sp<media::IAudioTrack> audioTrack;
 
         ConversionResult<media::CreateTrackResponse> toAidl() const;
         static ConversionResult<CreateTrackOutput> fromAidl(const media::CreateTrackResponse& aidl);
@@ -152,24 +160,26 @@
         sp<IMemory> cblk;
         sp<IMemory> buffers;
         audio_port_handle_t portId;
+        sp<media::IAudioRecord> audioRecord;
 
         ConversionResult<media::CreateRecordResponse> toAidl() const;
-        static ConversionResult<CreateRecordOutput> fromAidl(const media::CreateRecordResponse& aidl);
+        static ConversionResult<CreateRecordOutput>
+        fromAidl(const media::CreateRecordResponse& aidl);
     };
 
-    // invariant on exit for all APIs that return an sp<>:
-    //   (return value != 0) == (*status == NO_ERROR)
-
     /* create an audio track and registers it with AudioFlinger.
-     * return null if the track cannot be created.
+     * The audioTrack field will be null if the track cannot be created and the status will reflect
+     * failure.
      */
-    virtual sp<IAudioTrack> createTrack(const media::CreateTrackRequest& input,
-                                        media::CreateTrackResponse& output,
-                                        status_t* status) = 0;
+    virtual status_t createTrack(const media::CreateTrackRequest& input,
+                                 media::CreateTrackResponse& output) = 0;
 
-    virtual sp<media::IAudioRecord> createRecord(const media::CreateRecordRequest& input,
-                                                 media::CreateRecordResponse& output,
-                                                 status_t* status) = 0;
+    /* create an audio record and registers it with AudioFlinger.
+     * The audioRecord field will be null if the track cannot be created and the status will reflect
+     * failure.
+     */
+    virtual status_t createRecord(const media::CreateRecordRequest& input,
+                                  media::CreateRecordResponse& output) = 0;
 
     // FIXME Surprisingly, format/latency don't work for input handles
 
@@ -232,25 +242,17 @@
     virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
             audio_channel_mask_t channelMask) const = 0;
 
-    virtual status_t openOutput(audio_module_handle_t module,
-                                audio_io_handle_t *output,
-                                audio_config_t *config,
-                                const sp<DeviceDescriptorBase>& device,
-                                uint32_t *latencyMs,
-                                audio_output_flags_t flags) = 0;
+    virtual status_t openOutput(const media::OpenOutputRequest& request,
+                                media::OpenOutputResponse* response) = 0;
     virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
                                     audio_io_handle_t output2) = 0;
     virtual status_t closeOutput(audio_io_handle_t output) = 0;
     virtual status_t suspendOutput(audio_io_handle_t output) = 0;
     virtual status_t restoreOutput(audio_io_handle_t output) = 0;
 
-    virtual status_t openInput(audio_module_handle_t module,
-                               audio_io_handle_t *input,
-                               audio_config_t *config,
-                               audio_devices_t *device,
-                               const String8& address,
-                               audio_source_t source,
-                               audio_input_flags_t flags) = 0;
+    virtual status_t openInput(const media::OpenInputRequest& request,
+                               media::OpenInputResponse* response) = 0;
+
     virtual status_t closeInput(audio_io_handle_t input) = 0;
 
     virtual status_t invalidateStream(audio_stream_type_t stream) = 0;
@@ -276,20 +278,8 @@
                                          uint32_t preferredTypeFlag,
                                          effect_descriptor_t *pDescriptor) const = 0;
 
-    virtual sp<media::IEffect> createEffect(
-                                    effect_descriptor_t *pDesc,
-                                    const sp<media::IEffectClient>& client,
-                                    int32_t priority,
-                                    // AudioFlinger doesn't take over handle reference from client
-                                    audio_io_handle_t output,
-                                    audio_session_t sessionId,
-                                    const AudioDeviceTypeAddr& device,
-                                    const String16& callingPackage,
-                                    pid_t pid,
-                                    bool probe,
-                                    status_t *status,
-                                    int *id,
-                                    int *enabled) = 0;
+    virtual status_t createEffect(const media::CreateEffectRequest& request,
+                                  media::CreateEffectResponse* response) = 0;
 
     virtual status_t moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
                                     audio_io_handle_t dstOutput) = 0;
@@ -312,12 +302,8 @@
     // is obtained from android.app.ActivityManager.MemoryInfo.totalMem.
     virtual status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) = 0;
 
-    /* List available audio ports and their attributes */
-    virtual status_t listAudioPorts(unsigned int *num_ports,
-                                    struct audio_port *ports) = 0;
-
     /* Get attributes for a given audio port */
-    virtual status_t getAudioPort(struct audio_port *port) = 0;
+    virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
 
     /* Create an audio patch between several source and sink ports */
     virtual status_t createAudioPatch(const struct audio_patch *patch,
@@ -347,22 +333,282 @@
     virtual status_t setAudioHalPids(const std::vector<pid_t>& pids) = 0;
 };
 
-
-// ----------------------------------------------------------------------------
-
-class BnAudioFlinger : public BnInterface<IAudioFlinger>
-{
+/**
+ * A client-side adapter, wrapping an IAudioFlingerService instance and presenting it as an
+ * IAudioFlinger. Intended to be used by legacy client code that was written against IAudioFlinger,
+ * before IAudioFlingerService was introduced as an AIDL service.
+ * New clients should not use this adapter, but rather IAudioFlingerService directly, via
+ * BpAudioFlingerService.
+ */
+class AudioFlingerClientAdapter : public IAudioFlinger {
 public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
+    explicit AudioFlingerClientAdapter(const sp<media::IAudioFlingerService> delegate);
 
-    // Requests media.log to start merging log buffers
-    virtual void requestLogMerge() = 0;
+    status_t createTrack(const media::CreateTrackRequest& input,
+                         media::CreateTrackResponse& output) override;
+    status_t createRecord(const media::CreateRecordRequest& input,
+                          media::CreateRecordResponse& output) override;
+    uint32_t sampleRate(audio_io_handle_t ioHandle) const override;
+    audio_format_t format(audio_io_handle_t output) const override;
+    size_t frameCount(audio_io_handle_t ioHandle) const override;
+    uint32_t latency(audio_io_handle_t output) const override;
+    status_t setMasterVolume(float value) override;
+    status_t setMasterMute(bool muted) override;
+    float masterVolume() const override;
+    bool masterMute() const override;
+    status_t setMasterBalance(float balance) override;
+    status_t getMasterBalance(float* balance) const override;
+    status_t setStreamVolume(audio_stream_type_t stream, float value,
+                             audio_io_handle_t output) override;
+    status_t setStreamMute(audio_stream_type_t stream, bool muted) override;
+    float streamVolume(audio_stream_type_t stream,
+                       audio_io_handle_t output) const override;
+    bool streamMute(audio_stream_type_t stream) const override;
+    status_t setMode(audio_mode_t mode) override;
+    status_t setMicMute(bool state) override;
+    bool getMicMute() const override;
+    void setRecordSilenced(audio_port_handle_t portId, bool silenced) override;
+    status_t setParameters(audio_io_handle_t ioHandle,
+                           const String8& keyValuePairs) override;
+    String8 getParameters(audio_io_handle_t ioHandle, const String8& keys)
+    const override;
+    void registerClient(const sp<media::IAudioFlingerClient>& client) override;
+    size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+                              audio_channel_mask_t channelMask) const override;
+    status_t openOutput(const media::OpenOutputRequest& request,
+                        media::OpenOutputResponse* response) override;
+    audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
+                                          audio_io_handle_t output2) override;
+    status_t closeOutput(audio_io_handle_t output) override;
+    status_t suspendOutput(audio_io_handle_t output) override;
+    status_t restoreOutput(audio_io_handle_t output) override;
+    status_t openInput(const media::OpenInputRequest& request,
+                       media::OpenInputResponse* response) override;
+    status_t closeInput(audio_io_handle_t input) override;
+    status_t invalidateStream(audio_stream_type_t stream) override;
+    status_t setVoiceVolume(float volume) override;
+    status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames,
+                               audio_io_handle_t output) const override;
+    uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const override;
+    audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) override;
+    void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) override;
+    void releaseAudioSessionId(audio_session_t audioSession, pid_t pid) override;
+    status_t queryNumberEffects(uint32_t* numEffects) const override;
+    status_t queryEffect(uint32_t index, effect_descriptor_t* pDescriptor) const override;
+    status_t getEffectDescriptor(const effect_uuid_t* pEffectUUID,
+                                 const effect_uuid_t* pTypeUUID,
+                                 uint32_t preferredTypeFlag,
+                                 effect_descriptor_t* pDescriptor) const override;
+    status_t createEffect(const media::CreateEffectRequest& request,
+                          media::CreateEffectResponse* response) override;
+    status_t moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
+                         audio_io_handle_t dstOutput) override;
+    void setEffectSuspended(int effectId,
+                            audio_session_t sessionId,
+                            bool suspended) override;
+    audio_module_handle_t loadHwModule(const char* name) override;
+    uint32_t getPrimaryOutputSamplingRate() override;
+    size_t getPrimaryOutputFrameCount() override;
+    status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) override;
+    status_t getAudioPort(struct audio_port_v7* port) override;
+    status_t createAudioPatch(const struct audio_patch* patch,
+                              audio_patch_handle_t* handle) override;
+    status_t releaseAudioPatch(audio_patch_handle_t handle) override;
+    status_t listAudioPatches(unsigned int* num_patches,
+                              struct audio_patch* patches) override;
+    status_t setAudioPortConfig(const struct audio_port_config* config) override;
+    audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) override;
+    status_t systemReady() override;
+    size_t frameCountHAL(audio_io_handle_t ioHandle) const override;
+    status_t getMicrophones(std::vector<media::MicrophoneInfo>* microphones) override;
+    status_t setAudioHalPids(const std::vector<pid_t>& pids) override;
+
+private:
+    const sp<media::IAudioFlingerService> mDelegate;
 };
 
-// ----------------------------------------------------------------------------
+/**
+ * A server-side adapter, wrapping an IAudioFlinger instance and presenting it as an
+ * IAudioFlingerService. Intended to be used by legacy server code that was written against
+ * IAudioFlinger, before IAudioFlingerService was introduced as an AIDL service.
+ * New servers should not use this adapter, but rather implement IAudioFlingerService directly, via
+ * BnAudioFlingerService.
+ */
+class AudioFlingerServerAdapter : public media::BnAudioFlingerService {
+public:
+    using Status = binder::Status;
+
+    /**
+     * Legacy server should implement this interface in order to be wrapped.
+     */
+    class Delegate : public IAudioFlinger {
+    protected:
+        friend class AudioFlingerServerAdapter;
+
+        enum class TransactionCode {
+            CREATE_TRACK = media::BnAudioFlingerService::TRANSACTION_createTrack,
+            CREATE_RECORD = media::BnAudioFlingerService::TRANSACTION_createRecord,
+            SAMPLE_RATE = media::BnAudioFlingerService::TRANSACTION_sampleRate,
+            FORMAT = media::BnAudioFlingerService::TRANSACTION_format,
+            FRAME_COUNT = media::BnAudioFlingerService::TRANSACTION_frameCount,
+            LATENCY = media::BnAudioFlingerService::TRANSACTION_latency,
+            SET_MASTER_VOLUME = media::BnAudioFlingerService::TRANSACTION_setMasterVolume,
+            SET_MASTER_MUTE = media::BnAudioFlingerService::TRANSACTION_setMasterMute,
+            MASTER_VOLUME = media::BnAudioFlingerService::TRANSACTION_masterVolume,
+            MASTER_MUTE = media::BnAudioFlingerService::TRANSACTION_masterMute,
+            SET_STREAM_VOLUME = media::BnAudioFlingerService::TRANSACTION_setStreamVolume,
+            SET_STREAM_MUTE = media::BnAudioFlingerService::TRANSACTION_setStreamMute,
+            STREAM_VOLUME = media::BnAudioFlingerService::TRANSACTION_streamVolume,
+            STREAM_MUTE = media::BnAudioFlingerService::TRANSACTION_streamMute,
+            SET_MODE = media::BnAudioFlingerService::TRANSACTION_setMode,
+            SET_MIC_MUTE = media::BnAudioFlingerService::TRANSACTION_setMicMute,
+            GET_MIC_MUTE = media::BnAudioFlingerService::TRANSACTION_getMicMute,
+            SET_RECORD_SILENCED = media::BnAudioFlingerService::TRANSACTION_setRecordSilenced,
+            SET_PARAMETERS = media::BnAudioFlingerService::TRANSACTION_setParameters,
+            GET_PARAMETERS = media::BnAudioFlingerService::TRANSACTION_getParameters,
+            REGISTER_CLIENT = media::BnAudioFlingerService::TRANSACTION_registerClient,
+            GET_INPUTBUFFERSIZE = media::BnAudioFlingerService::TRANSACTION_getInputBufferSize,
+            OPEN_OUTPUT = media::BnAudioFlingerService::TRANSACTION_openOutput,
+            OPEN_DUPLICATE_OUTPUT = media::BnAudioFlingerService::TRANSACTION_openDuplicateOutput,
+            CLOSE_OUTPUT = media::BnAudioFlingerService::TRANSACTION_closeOutput,
+            SUSPEND_OUTPUT = media::BnAudioFlingerService::TRANSACTION_suspendOutput,
+            RESTORE_OUTPUT = media::BnAudioFlingerService::TRANSACTION_restoreOutput,
+            OPEN_INPUT = media::BnAudioFlingerService::TRANSACTION_openInput,
+            CLOSE_INPUT = media::BnAudioFlingerService::TRANSACTION_closeInput,
+            INVALIDATE_STREAM = media::BnAudioFlingerService::TRANSACTION_invalidateStream,
+            SET_VOICE_VOLUME = media::BnAudioFlingerService::TRANSACTION_setVoiceVolume,
+            GET_RENDER_POSITION = media::BnAudioFlingerService::TRANSACTION_getRenderPosition,
+            GET_INPUT_FRAMES_LOST = media::BnAudioFlingerService::TRANSACTION_getInputFramesLost,
+            NEW_AUDIO_UNIQUE_ID = media::BnAudioFlingerService::TRANSACTION_newAudioUniqueId,
+            ACQUIRE_AUDIO_SESSION_ID = media::BnAudioFlingerService::TRANSACTION_acquireAudioSessionId,
+            RELEASE_AUDIO_SESSION_ID = media::BnAudioFlingerService::TRANSACTION_releaseAudioSessionId,
+            QUERY_NUM_EFFECTS = media::BnAudioFlingerService::TRANSACTION_queryNumberEffects,
+            QUERY_EFFECT = media::BnAudioFlingerService::TRANSACTION_queryEffect,
+            GET_EFFECT_DESCRIPTOR = media::BnAudioFlingerService::TRANSACTION_getEffectDescriptor,
+            CREATE_EFFECT = media::BnAudioFlingerService::TRANSACTION_createEffect,
+            MOVE_EFFECTS = media::BnAudioFlingerService::TRANSACTION_moveEffects,
+            LOAD_HW_MODULE = media::BnAudioFlingerService::TRANSACTION_loadHwModule,
+            GET_PRIMARY_OUTPUT_SAMPLING_RATE = media::BnAudioFlingerService::TRANSACTION_getPrimaryOutputSamplingRate,
+            GET_PRIMARY_OUTPUT_FRAME_COUNT = media::BnAudioFlingerService::TRANSACTION_getPrimaryOutputFrameCount,
+            SET_LOW_RAM_DEVICE = media::BnAudioFlingerService::TRANSACTION_setLowRamDevice,
+            GET_AUDIO_PORT = media::BnAudioFlingerService::TRANSACTION_getAudioPort,
+            CREATE_AUDIO_PATCH = media::BnAudioFlingerService::TRANSACTION_createAudioPatch,
+            RELEASE_AUDIO_PATCH = media::BnAudioFlingerService::TRANSACTION_releaseAudioPatch,
+            LIST_AUDIO_PATCHES = media::BnAudioFlingerService::TRANSACTION_listAudioPatches,
+            SET_AUDIO_PORT_CONFIG = media::BnAudioFlingerService::TRANSACTION_setAudioPortConfig,
+            GET_AUDIO_HW_SYNC_FOR_SESSION = media::BnAudioFlingerService::TRANSACTION_getAudioHwSyncForSession,
+            SYSTEM_READY = media::BnAudioFlingerService::TRANSACTION_systemReady,
+            FRAME_COUNT_HAL = media::BnAudioFlingerService::TRANSACTION_frameCountHAL,
+            GET_MICROPHONES = media::BnAudioFlingerService::TRANSACTION_getMicrophones,
+            SET_MASTER_BALANCE = media::BnAudioFlingerService::TRANSACTION_setMasterBalance,
+            GET_MASTER_BALANCE = media::BnAudioFlingerService::TRANSACTION_getMasterBalance,
+            SET_EFFECT_SUSPENDED = media::BnAudioFlingerService::TRANSACTION_setEffectSuspended,
+            SET_AUDIO_HAL_PIDS = media::BnAudioFlingerService::TRANSACTION_setAudioHalPids,
+        };
+
+        /**
+         * And optional hook, called on every transaction, before unparceling the data and
+         * dispatching to the respective method. Useful for bulk operations, such as logging or
+         * permission checks.
+         * If an error status is returned, the transaction will return immediately and will not be
+         * processed.
+         */
+        virtual status_t onPreTransact(TransactionCode code, const Parcel& data, uint32_t flags) {
+            (void) code;
+            (void) data;
+            (void) flags;
+            return OK;
+        };
+
+        /**
+         * An optional hook for implementing diagnostics dumping.
+         */
+        virtual status_t dump(int fd, const Vector<String16>& args) {
+            (void) fd;
+            (void) args;
+            return OK;
+        }
+    };
+
+    explicit AudioFlingerServerAdapter(
+            const sp<AudioFlingerServerAdapter::Delegate>& delegate);
+
+    status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override;
+    status_t dump(int fd, const Vector<String16>& args) override;
+
+    Status createTrack(const media::CreateTrackRequest& request,
+                       media::CreateTrackResponse* _aidl_return) override;
+    Status createRecord(const media::CreateRecordRequest& request,
+                        media::CreateRecordResponse* _aidl_return) override;
+    Status sampleRate(int32_t ioHandle, int32_t* _aidl_return) override;
+    Status format(int32_t output, media::audio::common::AudioFormat* _aidl_return) override;
+    Status frameCount(int32_t ioHandle, int64_t* _aidl_return) override;
+    Status latency(int32_t output, int32_t* _aidl_return) override;
+    Status setMasterVolume(float value) override;
+    Status setMasterMute(bool muted) override;
+    Status masterVolume(float* _aidl_return) override;
+    Status masterMute(bool* _aidl_return) override;
+    Status setMasterBalance(float balance) override;
+    Status getMasterBalance(float* _aidl_return) override;
+    Status setStreamVolume(media::AudioStreamType stream, float value, int32_t output) override;
+    Status setStreamMute(media::AudioStreamType stream, bool muted) override;
+    Status
+    streamVolume(media::AudioStreamType stream, int32_t output, float* _aidl_return) override;
+    Status streamMute(media::AudioStreamType stream, bool* _aidl_return) override;
+    Status setMode(media::AudioMode mode) override;
+    Status setMicMute(bool state) override;
+    Status getMicMute(bool* _aidl_return) override;
+    Status setRecordSilenced(int32_t portId, bool silenced) override;
+    Status setParameters(int32_t ioHandle, const std::string& keyValuePairs) override;
+    Status
+    getParameters(int32_t ioHandle, const std::string& keys, std::string* _aidl_return) override;
+    Status registerClient(const sp<media::IAudioFlingerClient>& client) override;
+    Status getInputBufferSize(int32_t sampleRate, media::audio::common::AudioFormat format,
+                              int32_t channelMask, int64_t* _aidl_return) override;
+    Status openOutput(const media::OpenOutputRequest& request,
+                      media::OpenOutputResponse* _aidl_return) override;
+    Status openDuplicateOutput(int32_t output1, int32_t output2, int32_t* _aidl_return) override;
+    Status closeOutput(int32_t output) override;
+    Status suspendOutput(int32_t output) override;
+    Status restoreOutput(int32_t output) override;
+    Status openInput(const media::OpenInputRequest& request,
+                     media::OpenInputResponse* _aidl_return) override;
+    Status closeInput(int32_t input) override;
+    Status invalidateStream(media::AudioStreamType stream) override;
+    Status setVoiceVolume(float volume) override;
+    Status getRenderPosition(int32_t output, media::RenderPosition* _aidl_return) override;
+    Status getInputFramesLost(int32_t ioHandle, int32_t* _aidl_return) override;
+    Status newAudioUniqueId(media::AudioUniqueIdUse use, int32_t* _aidl_return) override;
+    Status acquireAudioSessionId(int32_t audioSession, int32_t pid, int32_t uid) override;
+    Status releaseAudioSessionId(int32_t audioSession, int32_t pid) override;
+    Status queryNumberEffects(int32_t* _aidl_return) override;
+    Status queryEffect(int32_t index, media::EffectDescriptor* _aidl_return) override;
+    Status getEffectDescriptor(const media::AudioUuid& effectUUID, const media::AudioUuid& typeUUID,
+                               int32_t preferredTypeFlag,
+                               media::EffectDescriptor* _aidl_return) override;
+    Status createEffect(const media::CreateEffectRequest& request,
+                        media::CreateEffectResponse* _aidl_return) override;
+    Status moveEffects(int32_t session, int32_t srcOutput, int32_t dstOutput) override;
+    Status setEffectSuspended(int32_t effectId, int32_t sessionId, bool suspended) override;
+    Status loadHwModule(const std::string& name, int32_t* _aidl_return) override;
+    Status getPrimaryOutputSamplingRate(int32_t* _aidl_return) override;
+    Status getPrimaryOutputFrameCount(int64_t* _aidl_return) override;
+    Status setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) override;
+    Status getAudioPort(const media::AudioPort& port, media::AudioPort* _aidl_return) override;
+    Status createAudioPatch(const media::AudioPatch& patch, int32_t* _aidl_return) override;
+    Status releaseAudioPatch(int32_t handle) override;
+    Status listAudioPatches(int32_t maxCount,
+                            std::vector<media::AudioPatch>* _aidl_return) override;
+    Status setAudioPortConfig(const media::AudioPortConfig& config) override;
+    Status getAudioHwSyncForSession(int32_t sessionId, int32_t* _aidl_return) override;
+    Status systemReady() override;
+    Status frameCountHAL(int32_t ioHandle, int64_t* _aidl_return) override;
+    Status getMicrophones(std::vector<media::MicrophoneInfoData>* _aidl_return) override;
+    Status setAudioHalPids(const std::vector<int32_t>& pids) override;
+
+private:
+    const sp<AudioFlingerServerAdapter::Delegate> mDelegate;
+};
 
 }; // namespace android
 
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 837375d..df792e3 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -150,7 +150,7 @@
     virtual status_t setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t flags) = 0;
    // Check if offload is possible for given format, stream type, sample rate,
     // bit rate, duration, video and streaming or offload property is enabled
-    virtual bool isOffloadSupported(const audio_offload_info_t& info) = 0;
+    virtual audio_offload_mode_t getOffloadSupport(const audio_offload_info_t& info) = 0;
 
     // Check if direct playback is possible for given format, sample rate, channel mask and flags.
     virtual bool isDirectOutputSupported(const audio_config_base_t& config,
@@ -160,11 +160,11 @@
     virtual status_t listAudioPorts(audio_port_role_t role,
                                     audio_port_type_t type,
                                     unsigned int *num_ports,
-                                    struct audio_port *ports,
+                                    struct audio_port_v7 *ports,
                                     unsigned int *generation) = 0;
 
     /* Get attributes for a given audio port */
-    virtual status_t getAudioPort(struct audio_port *port) = 0;
+    virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
 
     /* Create an audio patch between several source and sink ports */
     virtual status_t createAudioPatch(const struct audio_patch *patch,
diff --git a/media/libaudioclient/include/media/IAudioTrack.h b/media/libaudioclient/include/media/IAudioTrack.h
deleted file mode 100644
index 06e786d..0000000
--- a/media/libaudioclient/include/media/IAudioTrack.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-#ifndef ANDROID_IAUDIOTRACK_H
-#define ANDROID_IAUDIOTRACK_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-#include <utils/String8.h>
-#include <media/AudioTimestamp.h>
-#include <media/VolumeShaper.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class IAudioTrack : public IInterface
-{
-public:
-    DECLARE_META_INTERFACE(AudioTrack);
-
-    /* Get this track's control block */
-    virtual sp<IMemory> getCblk() const = 0;
-
-    /* After it's created the track is not active. Call start() to
-     * make it active.
-     */
-    virtual status_t    start() = 0;
-
-    /* Stop a track. If set, the callback will cease being called and
-     * obtainBuffer will return an error. Buffers that are already released
-     * will continue to be processed, unless/until flush() is called.
-     */
-    virtual void        stop() = 0;
-
-    /* Flush a stopped or paused track. All pending/released buffers are discarded.
-     * This function has no effect if the track is not stopped or paused.
-     */
-    virtual void        flush() = 0;
-
-    /* Pause a track. If set, the callback will cease being called and
-     * obtainBuffer will return an error. Buffers that are already released
-     * will continue to be processed, unless/until flush() is called.
-     */
-    virtual void        pause() = 0;
-
-    /* Attach track auxiliary output to specified effect. Use effectId = 0
-     * to detach track from effect.
-     */
-    virtual status_t    attachAuxEffect(int effectId) = 0;
-
-    /* Send parameters to the audio hardware */
-    virtual status_t    setParameters(const String8& keyValuePairs) = 0;
-
-    /* Selects the presentation (if available) */
-    virtual status_t    selectPresentation(int presentationId, int programId) = 0;
-
-    /* Return NO_ERROR if timestamp is valid.  timestamp is undefined otherwise. */
-    virtual status_t    getTimestamp(AudioTimestamp& timestamp) = 0;
-
-    /* Signal the playback thread for a change in control block */
-    virtual void        signal() = 0;
-
-    /* Sets the volume shaper */
-    virtual media::VolumeShaper::Status applyVolumeShaper(
-            const sp<media::VolumeShaper::Configuration>& configuration,
-            const sp<media::VolumeShaper::Operation>& operation) = 0;
-
-    /* gets the volume shaper state */
-    virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnAudioTrack : public BnInterface<IAudioTrack>
-{
-public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_IAUDIOTRACK_H
diff --git a/media/libaudioclient/include/media/ToneGenerator.h b/media/libaudioclient/include/media/ToneGenerator.h
index 5b0689a..04357a8 100644
--- a/media/libaudioclient/include/media/ToneGenerator.h
+++ b/media/libaudioclient/include/media/ToneGenerator.h
@@ -218,6 +218,7 @@
         TONE_INDIA_CONGESTION,      // Congestion tone: 400 Hz, 250ms ON, 250ms OFF...
         TONE_INDIA_CALL_WAITING,    // Call waiting tone: 400 Hz, tone repeated in a 0.2s on, 0.1s off, 0.2s on, 7.5s off pattern.
         TONE_INDIA_RINGTONE,        // Ring tone: 400 Hz tone modulated with 25Hz, 0.4 on 0.2 off 0.4 on 2..0 off
+        TONE_TW_RINGTONE,           // Ring Tone: 440 Hz + 480 Hz repeated with pattern 1s on, 3s off.
         NUM_ALTERNATE_TONES
     };
 
@@ -230,6 +231,7 @@
         HONGKONG,
         IRELAND,
         INDIA,
+        TAIWAN,
         CEPT,
         NUM_REGIONS
     };
diff --git a/media/libaudioclient/tests/Android.bp b/media/libaudioclient/tests/Android.bp
index 350a780..21d18d3 100644
--- a/media/libaudioclient/tests/Android.bp
+++ b/media/libaudioclient/tests/Android.bp
@@ -7,6 +7,18 @@
 }
 
 cc_test {
+    name: "audio_aidl_status_tests",
+    defaults: ["libaudioclient_tests_defaults"],
+    srcs: ["audio_aidl_status_tests.cpp"],
+    shared_libs: [
+        "libaudioclient_aidl_conversion",
+        "libbinder",
+        "libcutils",
+        "libutils",
+    ],
+}
+
+cc_test {
     name: "test_create_audiotrack",
     defaults: ["libaudioclient_tests_defaults"],
     srcs: ["test_create_audiotrack.cpp",
diff --git a/media/libaudioclient/tests/audio_aidl_status_tests.cpp b/media/libaudioclient/tests/audio_aidl_status_tests.cpp
new file mode 100644
index 0000000..5517091
--- /dev/null
+++ b/media/libaudioclient/tests/audio_aidl_status_tests.cpp
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <media/AidlConversionUtil.h>
+#include <utils/Errors.h>
+
+using namespace android;
+using namespace android::aidl_utils;
+using android::binder::Status;
+
+// Tests for statusTFromBinderStatus() and binderStatusFromStatusT().
+
+// STATUS_T_SMALL_VALUE_LIMIT is an arbitrary limit where we exhaustively check status_t errors.
+// It is known that this limit doesn't cover UNKNOWN_ERROR ~ INT32_MIN.
+constexpr status_t STATUS_T_SMALL_VALUE_LIMIT = -1000;
+
+// Small status values are preserved on round trip
+TEST(audio_aidl_status_tests, statusRoundTripSmallValues) {
+    for (status_t status = 0; status > STATUS_T_SMALL_VALUE_LIMIT; --status) {
+        ASSERT_EQ(status, statusTFromBinderStatus(binderStatusFromStatusT(status)));
+    }
+}
+
+// Special status values are preserved on round trip.
+TEST(audio_aidl_status_tests, statusRoundTripSpecialValues) {
+    for (status_t status : {
+            OK,
+            UNKNOWN_ERROR,
+            NO_MEMORY,
+            INVALID_OPERATION,
+            BAD_VALUE,
+            BAD_TYPE,
+            NAME_NOT_FOUND,
+            PERMISSION_DENIED,
+            NO_INIT,
+            ALREADY_EXISTS,
+            DEAD_OBJECT,
+            FAILED_TRANSACTION,
+            BAD_INDEX,
+            NOT_ENOUGH_DATA,
+            WOULD_BLOCK,
+            TIMED_OUT,
+            UNKNOWN_TRANSACTION,
+            FDS_NOT_ALLOWED}) {
+        ASSERT_EQ(status, statusTFromBinderStatus(binderStatusFromStatusT(status)));
+    }
+}
+
+// Binder exceptions show as an error (not fixed at this time); these come fromExceptionCode().
+TEST(audio_aidl_status_tests, binderStatusExceptions) {
+    for (int exceptionCode : {
+            //Status::EX_NONE,
+            Status::EX_SECURITY,
+            Status::EX_BAD_PARCELABLE,
+            Status::EX_ILLEGAL_ARGUMENT,
+            Status::EX_NULL_POINTER,
+            Status::EX_ILLEGAL_STATE,
+            Status::EX_NETWORK_MAIN_THREAD,
+            Status::EX_UNSUPPORTED_OPERATION,
+            //Status::EX_SERVICE_SPECIFIC, -- tested fromServiceSpecificError()
+            Status::EX_PARCELABLE,
+            // This is special and Java specific; see Parcel.java.
+            Status::EX_HAS_REPLY_HEADER,
+            // This is special, and indicates to C++ binder proxies that the
+            // transaction has failed at a low level.
+            //Status::EX_TRANSACTION_FAILED, -- tested fromStatusT().
+            }) {
+        ASSERT_NE(OK, statusTFromBinderStatus(Status::fromExceptionCode(exceptionCode)));
+    }
+}
+
+// Binder transaction errors show exactly in status_t; these come fromStatusT().
+TEST(audio_aidl_status_tests, binderStatusTransactionError) {
+    for (status_t status : {
+            OK, // Note: fromStatusT does check if this is 0, so this is no error.
+            UNKNOWN_ERROR,
+            NO_MEMORY,
+            INVALID_OPERATION,
+            BAD_VALUE,
+            BAD_TYPE,
+            NAME_NOT_FOUND,
+            PERMISSION_DENIED,
+            NO_INIT,
+            ALREADY_EXISTS,
+            DEAD_OBJECT,
+            FAILED_TRANSACTION,
+            BAD_INDEX,
+            NOT_ENOUGH_DATA,
+            WOULD_BLOCK,
+            TIMED_OUT,
+            UNKNOWN_TRANSACTION,
+            FDS_NOT_ALLOWED}) {
+        ASSERT_EQ(status, statusTFromBinderStatus(Status::fromStatusT(status)));
+    }
+}
+
+// Binder service specific errors show in status_t; these come fromServiceSpecificError().
+TEST(audio_aidl_status_tests, binderStatusServiceSpecificError) {
+    // fromServiceSpecificError() still stores exception code if status is 0.
+    for (status_t status = -1; status > STATUS_T_SMALL_VALUE_LIMIT; --status) {
+        ASSERT_EQ(status, statusTFromBinderStatus(Status::fromServiceSpecificError(status)));
+    }
+}
+
+// Binder status with message.
+TEST(audio_aidl_status_tests, binderStatusMessage) {
+    const String8 message("abcd");
+    for (status_t status = -1; status > STATUS_T_SMALL_VALUE_LIMIT; --status) {
+        const Status binderStatus = binderStatusFromStatusT(status, message.c_str());
+        ASSERT_EQ(status, statusTFromBinderStatus(binderStatus));
+        ASSERT_EQ(message, binderStatus.exceptionMessage());
+    }
+}
diff --git a/media/libaudiofoundation/Android.bp b/media/libaudiofoundation/Android.bp
index a8e6c31..9296d0e 100644
--- a/media/libaudiofoundation/Android.bp
+++ b/media/libaudiofoundation/Android.bp
@@ -5,13 +5,21 @@
 
     export_include_dirs: ["include"],
     header_libs: [
+        "libaudioclient_aidl_conversion_util",
         "libaudio_system_headers",
         "libmedia_helper_headers",
     ],
     export_header_lib_headers: [
+        "libaudioclient_aidl_conversion_util",
         "libaudio_system_headers",
         "libmedia_helper_headers",
     ],
+    static_libs: [
+        "audioclient-types-aidl-unstable-cpp",
+    ],
+    export_static_lib_headers: [
+        "audioclient-types-aidl-unstable-cpp",
+    ],
     host_supported: true,
     target: {
         darwin: {
@@ -35,6 +43,8 @@
     ],
 
     shared_libs: [
+        "audioclient-types-aidl-unstable-cpp",
+        "libaudioclient_aidl_conversion",
         "libaudioutils",
         "libbase",
         "libbinder",
@@ -43,6 +53,11 @@
         "libutils",
     ],
 
+    export_shared_lib_headers: [
+        "audioclient-types-aidl-unstable-cpp",
+        "libaudioclient_aidl_conversion",
+    ],
+
     header_libs: [
         "libaudiofoundation_headers",
     ],
diff --git a/media/libaudiofoundation/AudioDeviceTypeAddr.cpp b/media/libaudiofoundation/AudioDeviceTypeAddr.cpp
index a47337b..8f1e113 100644
--- a/media/libaudiofoundation/AudioDeviceTypeAddr.cpp
+++ b/media/libaudiofoundation/AudioDeviceTypeAddr.cpp
@@ -155,4 +155,18 @@
     return stream.str();
 }
 
+ConversionResult<AudioDeviceTypeAddr>
+aidl2legacy_AudioDeviceTypeAddress(const media::AudioDevice& aidl) {
+    audio_devices_t type = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_devices_t(aidl.type));
+    return AudioDeviceTypeAddr(type, aidl.address);
+}
+
+ConversionResult<media::AudioDevice>
+legacy2aidl_AudioDeviceTypeAddress(const AudioDeviceTypeAddr& legacy) {
+    media::AudioDevice aidl;
+    aidl.type = VALUE_OR_RETURN(legacy2aidl_audio_devices_t_int32_t(legacy.mType));
+    aidl.address = legacy.getAddress();
+    return aidl;
+}
+
 } // namespace android
diff --git a/media/libaudiofoundation/AudioGain.cpp b/media/libaudiofoundation/AudioGain.cpp
index 759140e..1dee938 100644
--- a/media/libaudiofoundation/AudioGain.cpp
+++ b/media/libaudiofoundation/AudioGain.cpp
@@ -129,42 +129,51 @@
            mGain.max_ramp_ms == other->mGain.max_ramp_ms;
 }
 
-status_t AudioGain::writeToParcel(android::Parcel *parcel) const
-{
-    status_t status = NO_ERROR;
-    if ((status = parcel->writeInt32(mIndex)) != NO_ERROR) return status;
-    if ((status = parcel->writeBool(mUseInChannelMask)) != NO_ERROR) return status;
-    if ((status = parcel->writeBool(mUseForVolume)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mGain.mode)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mGain.channel_mask)) != NO_ERROR) return status;
-    if ((status = parcel->writeInt32(mGain.min_value)) != NO_ERROR) return status;
-    if ((status = parcel->writeInt32(mGain.max_value)) != NO_ERROR) return status;
-    if ((status = parcel->writeInt32(mGain.default_value)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mGain.step_value)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mGain.min_ramp_ms)) != NO_ERROR) return status;
-    status = parcel->writeUint32(mGain.max_ramp_ms);
-    return status;
+status_t AudioGain::writeToParcel(android::Parcel *parcel) const {
+    media::AudioGain parcelable;
+    return writeToParcelable(&parcelable)
+        ?: parcelable.writeToParcel(parcel);
 }
 
-status_t AudioGain::readFromParcel(const android::Parcel *parcel)
-{
-    status_t status = NO_ERROR;
-    if ((status = parcel->readInt32(&mIndex)) != NO_ERROR) return status;
-    if ((status = parcel->readBool(&mUseInChannelMask)) != NO_ERROR) return status;
-    if ((status = parcel->readBool(&mUseForVolume)) != NO_ERROR) return status;
-    uint32_t rawGainMode;
-    if ((status = parcel->readUint32(&rawGainMode)) != NO_ERROR) return status;
-    mGain.mode = static_cast<audio_gain_mode_t>(rawGainMode);
-    uint32_t rawChannelMask;
-    if ((status = parcel->readUint32(&rawChannelMask)) != NO_ERROR) return status;
-    mGain.channel_mask = static_cast<audio_channel_mask_t>(rawChannelMask);
-    if ((status = parcel->readInt32(&mGain.min_value)) != NO_ERROR) return status;
-    if ((status = parcel->readInt32(&mGain.max_value)) != NO_ERROR) return status;
-    if ((status = parcel->readInt32(&mGain.default_value)) != NO_ERROR) return status;
-    if ((status = parcel->readUint32(&mGain.step_value)) != NO_ERROR) return status;
-    if ((status = parcel->readUint32(&mGain.min_ramp_ms)) != NO_ERROR) return status;
-    status = parcel->readUint32(&mGain.max_ramp_ms);
-    return status;
+status_t AudioGain::writeToParcelable(media::AudioGain* parcelable) const {
+    parcelable->index = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(mIndex));
+    parcelable->useInChannelMask = mUseInChannelMask;
+    parcelable->useForVolume = mUseForVolume;
+    parcelable->mode = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_gain_mode_t_int32_t_mask(mGain.mode));
+    parcelable->channelMask = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_channel_mask_t_int32_t(mGain.channel_mask));
+    parcelable->minValue = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(mGain.min_value));
+    parcelable->maxValue = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(mGain.max_value));
+    parcelable->defaultValue = VALUE_OR_RETURN_STATUS(
+            convertIntegral<int32_t>(mGain.default_value));
+    parcelable->stepValue = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(mGain.step_value));
+    parcelable->minRampMs = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(mGain.min_ramp_ms));
+    parcelable->maxRampMs = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(mGain.max_ramp_ms));
+    return OK;
+}
+
+status_t AudioGain::readFromParcel(const android::Parcel *parcel) {
+    media::AudioGain parcelable;
+    return parcelable.readFromParcel(parcel)
+        ?: readFromParcelable(parcelable);
+}
+
+status_t AudioGain::readFromParcelable(const media::AudioGain& parcelable) {
+    mIndex = VALUE_OR_RETURN_STATUS(convertIntegral<int>(parcelable.index));
+    mUseInChannelMask = parcelable.useInChannelMask;
+    mUseForVolume = parcelable.useForVolume;
+    mGain.mode = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_int32_t_audio_gain_mode_t_mask(parcelable.mode));
+    mGain.channel_mask = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_int32_t_audio_channel_mask_t(parcelable.channelMask));
+    mGain.min_value = VALUE_OR_RETURN_STATUS(convertIntegral<int>(parcelable.minValue));
+    mGain.max_value = VALUE_OR_RETURN_STATUS(convertIntegral<int>(parcelable.maxValue));
+    mGain.default_value = VALUE_OR_RETURN_STATUS(convertIntegral<int>(parcelable.defaultValue));
+    mGain.step_value = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(parcelable.stepValue));
+    mGain.min_ramp_ms = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(parcelable.minRampMs));
+    mGain.max_ramp_ms = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(parcelable.maxRampMs));
+    return OK;
 }
 
 bool AudioGains::equals(const AudioGains &other) const
@@ -200,4 +209,34 @@
     return status;
 }
 
+ConversionResult<sp<AudioGain>>
+aidl2legacy_AudioGain(const media::AudioGain& aidl) {
+    sp<AudioGain> legacy = new AudioGain(0, false);
+    status_t status = legacy->readFromParcelable(aidl);
+    if (status != OK) {
+        return base::unexpected(status);
+    }
+    return legacy;
+}
+
+ConversionResult<media::AudioGain>
+legacy2aidl_AudioGain(const sp<AudioGain>& legacy) {
+    media::AudioGain aidl;
+    status_t status = legacy->writeToParcelable(&aidl);
+    if (status != OK) {
+        return base::unexpected(status);
+    }
+    return aidl;
+}
+
+ConversionResult<AudioGains>
+aidl2legacy_AudioGains(const std::vector<media::AudioGain>& aidl) {
+    return convertContainer<AudioGains>(aidl, aidl2legacy_AudioGain);
+}
+
+ConversionResult<std::vector<media::AudioGain>>
+legacy2aidl_AudioGains(const AudioGains& legacy) {
+    return convertContainer<std::vector<media::AudioGain>>(legacy, legacy2aidl_AudioGain);
+}
+
 } // namespace android
diff --git a/media/libaudiofoundation/AudioPort.cpp b/media/libaudiofoundation/AudioPort.cpp
index 1846a6b..20d8632 100644
--- a/media/libaudiofoundation/AudioPort.cpp
+++ b/media/libaudiofoundation/AudioPort.cpp
@@ -38,6 +38,21 @@
     }
 }
 
+void AudioPort::importAudioPort(const audio_port_v7 &port) {
+    for (size_t i = 0; i < port.num_audio_profiles; ++i) {
+        sp<AudioProfile> profile = new AudioProfile(port.audio_profiles[i].format,
+                ChannelMaskSet(port.audio_profiles[i].channel_masks,
+                        port.audio_profiles[i].channel_masks +
+                        port.audio_profiles->num_channel_masks),
+                SampleRateSet(port.audio_profiles[i].sample_rates,
+                        port.audio_profiles[i].sample_rates +
+                        port.audio_profiles[i].num_sample_rates));
+        if (!mProfiles.contains(profile)) {
+            addAudioProfile(profile);
+        }
+    }
+}
+
 void AudioPort::toAudioPort(struct audio_port *port) const {
     // TODO: update this function once audio_port structure reflects the new profile definition.
     // For compatibility reason: flatening the AudioProfile into audio_port structure.
@@ -62,21 +77,39 @@
             }
         }
     }
-    port->role = mRole;
-    port->type = mType;
-    strlcpy(port->name, mName.c_str(), AUDIO_PORT_MAX_NAME_LEN);
+    toAudioPortBase(port);
     port->num_sample_rates = flatenedRates.size();
     port->num_channel_masks = flatenedChannels.size();
     port->num_formats = flatenedFormats.size();
     std::copy(flatenedRates.begin(), flatenedRates.end(), port->sample_rates);
     std::copy(flatenedChannels.begin(), flatenedChannels.end(), port->channel_masks);
     std::copy(flatenedFormats.begin(), flatenedFormats.end(), port->formats);
+}
 
-    ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size());
+void AudioPort::toAudioPort(struct audio_port_v7 *port) const {
+    toAudioPortBase(port);
+    port->num_audio_profiles = 0;
+    for (const auto& profile : mProfiles) {
+        if (profile->isValid()) {
+            const SampleRateSet &sampleRates = profile->getSampleRates();
+            const ChannelMaskSet &channelMasks = profile->getChannels();
 
-    port->num_gains = std::min(mGains.size(), (size_t) AUDIO_PORT_MAX_GAINS);
-    for (size_t i = 0; i < port->num_gains; i++) {
-        port->gains[i] = mGains[i]->getGain();
+            if (sampleRates.size() > AUDIO_PORT_MAX_SAMPLING_RATES ||
+                    channelMasks.size() > AUDIO_PORT_MAX_CHANNEL_MASKS ||
+                    port->num_audio_profiles >= AUDIO_PORT_MAX_AUDIO_PROFILES) {
+                ALOGE("%s: bailing out: cannot export profiles to port config", __func__);
+                return;
+            }
+
+            auto& dstProfile = port->audio_profiles[port->num_audio_profiles++];
+            dstProfile.format = profile->getFormat();
+            dstProfile.num_sample_rates = sampleRates.size();
+            std::copy(sampleRates.begin(), sampleRates.end(),
+                    std::begin(dstProfile.sample_rates));
+            dstProfile.num_channel_masks = channelMasks.size();
+            std::copy(channelMasks.begin(), channelMasks.end(),
+                    std::begin(dstProfile.channel_masks));
+        }
     }
 }
 
@@ -117,32 +150,33 @@
 
 status_t AudioPort::writeToParcel(Parcel *parcel) const
 {
-    status_t status = NO_ERROR;
-    if ((status = parcel->writeUtf8AsUtf16(mName)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mType)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mRole)) != NO_ERROR) return status;
-    if ((status = parcel->writeParcelable(mProfiles)) != NO_ERROR) return status;
-    if ((status = parcel->writeParcelable(mGains)) != NO_ERROR) return status;
-    return status;
+    media::AudioPort parcelable;
+    return writeToParcelable(&parcelable)
+        ?: parcelable.writeToParcel(parcel);
 }
 
-status_t AudioPort::readFromParcel(const Parcel *parcel)
-{
-    status_t status = NO_ERROR;
-    if ((status = parcel->readUtf8FromUtf16(&mName)) != NO_ERROR) return status;
-    static_assert(sizeof(mType) == sizeof(uint32_t));
-    if ((status = parcel->readUint32(reinterpret_cast<uint32_t*>(&mType))) != NO_ERROR) {
-        return status;
-    }
-    static_assert(sizeof(mRole) == sizeof(uint32_t));
-    if ((status = parcel->readUint32(reinterpret_cast<uint32_t*>(&mRole))) != NO_ERROR) {
-        return status;
-    }
-    mProfiles.clear();
-    if ((status = parcel->readParcelable(&mProfiles)) != NO_ERROR) return status;
-    mGains.clear();
-    if ((status = parcel->readParcelable(&mGains)) != NO_ERROR) return status;
-    return status;
+status_t AudioPort::writeToParcelable(media::AudioPort* parcelable) const {
+    parcelable->name = mName;
+    parcelable->type = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_type_t_AudioPortType(mType));
+    parcelable->role = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_role_t_AudioPortRole(mRole));
+    parcelable->profiles = VALUE_OR_RETURN_STATUS(legacy2aidl_AudioProfileVector(mProfiles));
+    parcelable->gains = VALUE_OR_RETURN_STATUS(legacy2aidl_AudioGains(mGains));
+    return OK;
+}
+
+status_t AudioPort::readFromParcel(const Parcel *parcel) {
+    media::AudioPort parcelable;
+    return parcelable.readFromParcel(parcel)
+        ?: readFromParcelable(parcelable);
+}
+
+status_t AudioPort::readFromParcelable(const media::AudioPort& parcelable) {
+    mName = parcelable.name;
+    mType = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortType_audio_port_type_t(parcelable.type));
+    mRole = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortRole_audio_port_role_t(parcelable.role));
+    mProfiles = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioProfileVector(parcelable.profiles));
+    mGains = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioGains(parcelable.gains));
+    return OK;
 }
 
 // --- AudioPortConfig class implementation
@@ -243,50 +277,56 @@
            mGain.ramp_duration_ms == other->mGain.ramp_duration_ms;
 }
 
-status_t AudioPortConfig::writeToParcel(Parcel *parcel) const
-{
-    status_t status = NO_ERROR;
-    if ((status = parcel->writeUint32(mSamplingRate)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mFormat)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mChannelMask)) != NO_ERROR) return status;
-    if ((status = parcel->writeInt32(mId)) != NO_ERROR) return status;
-    // Write mGain to parcel.
-    if ((status = parcel->writeInt32(mGain.index)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mGain.mode)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mGain.channel_mask)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mGain.ramp_duration_ms)) != NO_ERROR) return status;
-    std::vector<int> values(std::begin(mGain.values), std::end(mGain.values));
-    if ((status = parcel->writeInt32Vector(values)) != NO_ERROR) return status;
-    return status;
+status_t AudioPortConfig::writeToParcel(Parcel *parcel) const {
+    media::AudioPortConfig parcelable;
+    return writeToParcelable(&parcelable)
+        ?: parcelable.writeToParcel(parcel);
 }
 
-status_t AudioPortConfig::readFromParcel(const Parcel *parcel)
-{
-    status_t status = NO_ERROR;
-    if ((status = parcel->readUint32(&mSamplingRate)) != NO_ERROR) return status;
-    static_assert(sizeof(mFormat) == sizeof(uint32_t));
-    if ((status = parcel->readUint32(reinterpret_cast<uint32_t*>(&mFormat))) != NO_ERROR) {
-        return status;
-    }
-    uint32_t rawChannelMask;
-    if ((status = parcel->readUint32(&rawChannelMask)) != NO_ERROR) return status;
-    mChannelMask = static_cast<audio_channel_mask_t>(rawChannelMask);
-    if ((status = parcel->readInt32(&mId)) != NO_ERROR) return status;
-    // Read mGain from parcel.
-    if ((status = parcel->readInt32(&mGain.index)) != NO_ERROR) return status;
-    uint32_t rawGainMode;
-    if ((status = parcel->readUint32(&rawGainMode)) != NO_ERROR) return status;
-    mGain.mode = static_cast<audio_gain_mode_t>(rawGainMode);
-    if ((status = parcel->readUint32(&rawChannelMask)) != NO_ERROR) return status;
-    mGain.channel_mask = static_cast<audio_channel_mask_t>(rawChannelMask);
-    if ((status = parcel->readUint32(&mGain.ramp_duration_ms)) != NO_ERROR) return status;
-    std::vector<int> values;
-    if ((status = parcel->readInt32Vector(&values)) != NO_ERROR) return status;
-    if (values.size() != std::size(mGain.values)) {
+status_t AudioPortConfig::writeToParcelable(media::AudioPortConfig* parcelable) const {
+    parcelable->sampleRate = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(mSamplingRate));
+    parcelable->format = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_format_t_AudioFormat(mFormat));
+    parcelable->channelMask = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_channel_mask_t_int32_t(mChannelMask));
+    parcelable->id = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(mId));
+    parcelable->gain.index = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(mGain.index));
+    parcelable->gain.mode = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_gain_mode_t_int32_t_mask(mGain.mode));
+    parcelable->gain.channelMask = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_audio_channel_mask_t_int32_t(mGain.channel_mask));
+    parcelable->gain.rampDurationMs = VALUE_OR_RETURN_STATUS(
+            convertIntegral<int32_t>(mGain.ramp_duration_ms));
+    parcelable->gain.values = VALUE_OR_RETURN_STATUS(convertContainer<std::vector<int32_t>>(
+            mGain.values, convertIntegral<int32_t, int>));
+    return OK;
+}
+
+status_t AudioPortConfig::readFromParcel(const Parcel *parcel) {
+    media::AudioPortConfig parcelable;
+    return parcelable.readFromParcel(parcel)
+        ?: readFromParcelable(parcelable);
+}
+
+status_t AudioPortConfig::readFromParcelable(const media::AudioPortConfig& parcelable) {
+    mSamplingRate = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(parcelable.sampleRate));
+    mFormat = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioFormat_audio_format_t(parcelable.format));
+    mChannelMask = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_int32_t_audio_channel_mask_t(parcelable.channelMask));
+    mId = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_port_handle_t(parcelable.id));
+    mGain.index = VALUE_OR_RETURN_STATUS(convertIntegral<int>(parcelable.gain.index));
+    mGain.mode = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_int32_t_audio_gain_mode_t_mask(parcelable.gain.mode));
+    mGain.channel_mask = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_int32_t_audio_channel_mask_t(parcelable.gain.channelMask));
+    mGain.ramp_duration_ms = VALUE_OR_RETURN_STATUS(
+            convertIntegral<unsigned int>(parcelable.gain.rampDurationMs));
+    if (parcelable.gain.values.size() > std::size(mGain.values)) {
         return BAD_VALUE;
     }
-    std::copy(values.begin(), values.end(), mGain.values);
-    return status;
+    for (size_t i = 0; i < parcelable.gain.values.size(); ++i) {
+        mGain.values[i] = VALUE_OR_RETURN_STATUS(convertIntegral<int>(parcelable.gain.values[i]));
+    }
+    return OK;
 }
 
 } // namespace android
diff --git a/media/libaudiofoundation/AudioProfile.cpp b/media/libaudiofoundation/AudioProfile.cpp
index 67b600e..3b47fed 100644
--- a/media/libaudiofoundation/AudioProfile.cpp
+++ b/media/libaudiofoundation/AudioProfile.cpp
@@ -130,44 +130,73 @@
            mIsDynamicRate == other->isDynamicRate();
 }
 
-status_t AudioProfile::writeToParcel(Parcel *parcel) const
-{
-    status_t status = NO_ERROR;
-    if ((status = parcel->writeUtf8AsUtf16(mName)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mFormat)) != NO_ERROR) return status;
-    std::vector<int> values(mChannelMasks.begin(), mChannelMasks.end());
-    if ((status = parcel->writeInt32Vector(values)) != NO_ERROR) return status;
-    values.clear();
-    values.assign(mSamplingRates.begin(), mSamplingRates.end());
-    if ((status = parcel->writeInt32Vector(values)) != NO_ERROR) return status;
-    if ((status = parcel->writeBool(mIsDynamicFormat)) != NO_ERROR) return status;
-    if ((status = parcel->writeBool(mIsDynamicChannels)) != NO_ERROR) return status;
-    if ((status = parcel->writeBool(mIsDynamicRate)) != NO_ERROR) return status;
-    return status;
+AudioProfile& AudioProfile::operator=(const AudioProfile& other) {
+    mName = other.mName;
+    mFormat = other.mFormat;
+    mChannelMasks = other.mChannelMasks;
+    mSamplingRates = other.mSamplingRates;
+    mIsDynamicFormat = other.mIsDynamicFormat;
+    mIsDynamicChannels = other.mIsDynamicChannels;
+    mIsDynamicRate = other.mIsDynamicRate;
+    return *this;
 }
 
-status_t AudioProfile::readFromParcel(const Parcel *parcel)
-{
-    status_t status = NO_ERROR;
-    if ((status = parcel->readUtf8FromUtf16(&mName)) != NO_ERROR) return status;
-    static_assert(sizeof(mFormat) == sizeof(uint32_t));
-    if ((status = parcel->readUint32(reinterpret_cast<uint32_t*>(&mFormat))) != NO_ERROR) {
+status_t AudioProfile::writeToParcel(Parcel *parcel) const {
+    media::AudioProfile parcelable = VALUE_OR_RETURN_STATUS(toParcelable());
+    return parcelable.writeToParcel(parcel);
+ }
+
+ConversionResult<media::AudioProfile>
+AudioProfile::toParcelable() const {
+    media::AudioProfile parcelable;
+    parcelable.name = mName;
+    parcelable.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormat(mFormat));
+    parcelable.channelMasks = VALUE_OR_RETURN(
+            convertContainer<std::vector<int32_t>>(mChannelMasks,
+                                                   legacy2aidl_audio_channel_mask_t_int32_t));
+    parcelable.samplingRates = VALUE_OR_RETURN(
+            convertContainer<std::vector<int32_t>>(mSamplingRates,
+                                                   convertIntegral<int32_t, uint32_t>));
+    parcelable.isDynamicFormat = mIsDynamicFormat;
+    parcelable.isDynamicChannels = mIsDynamicChannels;
+    parcelable.isDynamicRate = mIsDynamicRate;
+    return parcelable;
+}
+
+status_t AudioProfile::readFromParcel(const Parcel *parcel) {
+    media::AudioProfile parcelable;
+    if (status_t status = parcelable.readFromParcel(parcel); status != OK) {
         return status;
     }
-    std::vector<int> values;
-    if ((status = parcel->readInt32Vector(&values)) != NO_ERROR) return status;
-    mChannelMasks.clear();
-    for (auto raw : values) {
-        mChannelMasks.insert(static_cast<audio_channel_mask_t>(raw));
-    }
-    values.clear();
-    if ((status = parcel->readInt32Vector(&values)) != NO_ERROR) return status;
-    mSamplingRates.clear();
-    mSamplingRates.insert(values.begin(), values.end());
-    if ((status = parcel->readBool(&mIsDynamicFormat)) != NO_ERROR) return status;
-    if ((status = parcel->readBool(&mIsDynamicChannels)) != NO_ERROR) return status;
-    if ((status = parcel->readBool(&mIsDynamicRate)) != NO_ERROR) return status;
-    return status;
+    *this = *VALUE_OR_RETURN_STATUS(fromParcelable(parcelable));
+    return OK;
+}
+
+ConversionResult<sp<AudioProfile>>
+AudioProfile::fromParcelable(const media::AudioProfile& parcelable) {
+    sp<AudioProfile> legacy = new AudioProfile();
+    legacy->mName = parcelable.name;
+    legacy->mFormat = VALUE_OR_RETURN(aidl2legacy_AudioFormat_audio_format_t(parcelable.format));
+    legacy->mChannelMasks = VALUE_OR_RETURN(
+            convertContainer<ChannelMaskSet>(parcelable.channelMasks,
+                                             aidl2legacy_int32_t_audio_channel_mask_t));
+    legacy->mSamplingRates = VALUE_OR_RETURN(
+            convertContainer<SampleRateSet>(parcelable.samplingRates,
+                                            convertIntegral<uint32_t, int32_t>));
+    legacy->mIsDynamicFormat = parcelable.isDynamicFormat;
+    legacy->mIsDynamicChannels = parcelable.isDynamicChannels;
+    legacy->mIsDynamicRate = parcelable.isDynamicRate;
+    return legacy;
+}
+
+ConversionResult<sp<AudioProfile>>
+aidl2legacy_AudioProfile(const media::AudioProfile& aidl) {
+    return AudioProfile::fromParcelable(aidl);
+}
+
+ConversionResult<media::AudioProfile>
+legacy2aidl_AudioProfile(const sp<AudioProfile>& legacy) {
+    return legacy->toParcelable();
 }
 
 ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
@@ -260,6 +289,16 @@
     return false;
 }
 
+bool AudioProfileVector::contains(const sp<AudioProfile>& profile) const
+{
+    for (const auto& audioProfile : *this) {
+        if (audioProfile->equals(profile)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 void AudioProfileVector::dump(std::string *dst, int spaces) const
 {
     dst->append(base::StringPrintf("%*s- Profiles:\n", spaces, ""));
@@ -306,4 +345,14 @@
                       });
 }
 
+ConversionResult<AudioProfileVector>
+aidl2legacy_AudioProfileVector(const std::vector<media::AudioProfile>& aidl) {
+    return convertContainer<AudioProfileVector>(aidl, aidl2legacy_AudioProfile);
+}
+
+ConversionResult<std::vector<media::AudioProfile>>
+legacy2aidl_AudioProfileVector(const AudioProfileVector& legacy) {
+    return convertContainer<std::vector<media::AudioProfile>>(legacy, legacy2aidl_AudioProfile);
+}
+
 } // namespace android
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index 16cf71a..a3e9589 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -19,6 +19,7 @@
 
 #include <android-base/stringprintf.h>
 #include <audio_utils/string.h>
+#include <media/AidlConversion.h>
 #include <media/DeviceDescriptorBase.h>
 #include <media/TypeConverter.h>
 
@@ -80,13 +81,12 @@
 void DeviceDescriptorBase::toAudioPort(struct audio_port *port) const
 {
     ALOGV("DeviceDescriptorBase::toAudioPort() handle %d type %08x", mId, mDeviceTypeAddr.mType);
-    AudioPort::toAudioPort(port);
-    toAudioPortConfig(&port->active_config);
-    port->id = mId;
-    port->ext.device.type = mDeviceTypeAddr.mType;
-    port->ext.device.encapsulation_modes = mEncapsulationModes;
-    port->ext.device.encapsulation_metadata_types = mEncapsulationMetadataTypes;
-    (void)audio_utils_strlcpy_zerofill(port->ext.device.address, mDeviceTypeAddr.getAddress());
+    toAudioPortInternal(port);
+}
+
+void DeviceDescriptorBase::toAudioPort(struct audio_port_v7 *port) const {
+    ALOGV("DeviceDescriptorBase::toAudioPort() v7 handle %d type %08x", mId, mDeviceTypeAddr.mType);
+    toAudioPortInternal(port);
 }
 
 status_t DeviceDescriptorBase::setEncapsulationModes(uint32_t encapsulationModes) {
@@ -156,26 +156,53 @@
            mDeviceTypeAddr.equals(other->mDeviceTypeAddr);
 }
 
+
 status_t DeviceDescriptorBase::writeToParcel(Parcel *parcel) const
 {
-    status_t status = NO_ERROR;
-    if ((status = AudioPort::writeToParcel(parcel)) != NO_ERROR) return status;
-    if ((status = AudioPortConfig::writeToParcel(parcel)) != NO_ERROR) return status;
-    if ((status = parcel->writeParcelable(mDeviceTypeAddr)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mEncapsulationModes)) != NO_ERROR) return status;
-    if ((status = parcel->writeUint32(mEncapsulationMetadataTypes)) != NO_ERROR) return status;
-    return status;
+    media::AudioPort parcelable;
+    return writeToParcelable(&parcelable)
+        ?: parcelable.writeToParcel(parcel);
 }
 
-status_t DeviceDescriptorBase::readFromParcel(const Parcel *parcel)
-{
-    status_t status = NO_ERROR;
-    if ((status = AudioPort::readFromParcel(parcel)) != NO_ERROR) return status;
-    if ((status = AudioPortConfig::readFromParcel(parcel)) != NO_ERROR) return status;
-    if ((status = parcel->readParcelable(&mDeviceTypeAddr)) != NO_ERROR) return status;
-    if ((status = parcel->readUint32(&mEncapsulationModes)) != NO_ERROR) return status;
-    if ((status = parcel->readUint32(&mEncapsulationMetadataTypes)) != NO_ERROR) return status;
-    return status;
+status_t DeviceDescriptorBase::writeToParcelable(media::AudioPort* parcelable) const {
+    AudioPort::writeToParcelable(parcelable);
+    AudioPortConfig::writeToParcelable(&parcelable->activeConfig);
+    parcelable->id = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(mId));
+
+    media::AudioPortDeviceExt ext;
+    ext.device = VALUE_OR_RETURN_STATUS(legacy2aidl_AudioDeviceTypeAddress(mDeviceTypeAddr));
+    ext.encapsulationModes = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_AudioEncapsulationMode_mask(mEncapsulationModes));
+    ext.encapsulationMetadataTypes = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_AudioEncapsulationMetadataType_mask(mEncapsulationMetadataTypes));
+    UNION_SET(parcelable->ext, device, std::move(ext));
+    return OK;
+}
+
+status_t DeviceDescriptorBase::readFromParcel(const Parcel *parcel) {
+    media::AudioPort parcelable;
+    return parcelable.readFromParcel(parcel)
+        ?: readFromParcelable(parcelable);
+}
+
+status_t DeviceDescriptorBase::readFromParcelable(const media::AudioPort& parcelable) {
+    if (parcelable.type != media::AudioPortType::DEVICE) {
+        return BAD_VALUE;
+    }
+    status_t status = AudioPort::readFromParcelable(parcelable)
+                      ?: AudioPortConfig::readFromParcelable(parcelable.activeConfig);
+    if (status != OK) {
+        return status;
+    }
+
+    media::AudioPortDeviceExt ext = VALUE_OR_RETURN_STATUS(UNION_GET(parcelable.ext, device));
+    mDeviceTypeAddr = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_AudioDeviceTypeAddress(ext.device));
+    mEncapsulationModes = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_AudioEncapsulationMode_mask(ext.encapsulationModes));
+    mEncapsulationMetadataTypes = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_AudioEncapsulationMetadataType_mask(ext.encapsulationMetadataTypes));
+    return OK;
 }
 
 std::string toString(const DeviceDescriptorBaseVector& devices)
@@ -199,4 +226,24 @@
     return deviceTypeAddrs;
 }
 
+ConversionResult<sp<DeviceDescriptorBase>>
+aidl2legacy_DeviceDescriptorBase(const media::AudioPort& aidl) {
+    sp<DeviceDescriptorBase> result = new DeviceDescriptorBase(AUDIO_DEVICE_NONE);
+    status_t status = result->readFromParcelable(aidl);
+    if (status != OK) {
+        return base::unexpected(status);
+    }
+    return result;
+}
+
+ConversionResult<media::AudioPort>
+legacy2aidl_DeviceDescriptorBase(const sp<DeviceDescriptorBase>& legacy) {
+    media::AudioPort aidl;
+    status_t status = legacy->writeToParcelable(&aidl);
+    if (status != OK) {
+        return base::unexpected(status);
+    }
+    return aidl;
+}
+
 } // namespace android
diff --git a/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h b/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h
index 7497faf..34da233 100644
--- a/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h
+++ b/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h
@@ -19,9 +19,11 @@
 #include <string>
 #include <vector>
 
+#include <android/media/AudioDevice.h>
 #include <binder/Parcelable.h>
 #include <binder/Parcel.h>
 #include <media/AudioContainers.h>
+#include <media/AidlConversion.h>
 #include <system/audio.h>
 #include <utils/Errors.h>
 
@@ -84,4 +86,10 @@
 std::string dumpAudioDeviceTypeAddrVector(const AudioDeviceTypeAddrVector& deviceTypeAddrs,
                                           bool includeSensitiveInfo=false);
 
+// Conversion routines, according to AidlConversion.h conventions.
+ConversionResult<AudioDeviceTypeAddr>
+aidl2legacy_AudioDeviceTypeAddress(const media::AudioDevice& aidl);
+ConversionResult<media::AudioDevice>
+legacy2aidl_AudioDeviceTypeAddress(const AudioDeviceTypeAddr& legacy);
+
 } // namespace android
diff --git a/media/libaudiofoundation/include/media/AudioGain.h b/media/libaudiofoundation/include/media/AudioGain.h
index 859f1e7..a06b686 100644
--- a/media/libaudiofoundation/include/media/AudioGain.h
+++ b/media/libaudiofoundation/include/media/AudioGain.h
@@ -16,8 +16,10 @@
 
 #pragma once
 
+#include <android/media/AudioGain.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
+#include <media/AidlConversion.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <system/audio.h>
@@ -72,6 +74,9 @@
     status_t writeToParcel(Parcel* parcel) const override;
     status_t readFromParcel(const Parcel* parcel) override;
 
+    status_t writeToParcelable(media::AudioGain* parcelable) const;
+    status_t readFromParcelable(const media::AudioGain& parcelable);
+
 private:
     int               mIndex;
     struct audio_gain mGain;
@@ -79,6 +84,12 @@
     bool              mUseForVolume = false;
 };
 
+// Conversion routines, according to AidlConversion.h conventions.
+ConversionResult<sp<AudioGain>>
+aidl2legacy_AudioGain(const media::AudioGain& aidl);
+ConversionResult<media::AudioGain>
+legacy2aidl_AudioGain(const sp<AudioGain>& legacy);
+
 class AudioGains : public std::vector<sp<AudioGain> >, public Parcelable
 {
 public:
@@ -104,4 +115,10 @@
     status_t readFromParcel(const Parcel* parcel) override;
 };
 
+// Conversion routines, according to AidlConversion.h conventions.
+ConversionResult<AudioGains>
+aidl2legacy_AudioGains(const std::vector<media::AudioGain>& aidl);
+ConversionResult<std::vector<media::AudioGain>>
+legacy2aidl_AudioGains(const AudioGains& legacy);
+
 } // namespace android
diff --git a/media/libaudiofoundation/include/media/AudioPort.h b/media/libaudiofoundation/include/media/AudioPort.h
index 3c013cb..633e4e3 100644
--- a/media/libaudiofoundation/include/media/AudioPort.h
+++ b/media/libaudiofoundation/include/media/AudioPort.h
@@ -17,7 +17,10 @@
 #pragma once
 
 #include <string>
+#include <type_traits>
 
+#include <android/media/AudioPort.h>
+#include <android/media/AudioPortConfig.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
 #include <media/AudioGain.h>
@@ -48,6 +51,8 @@
 
     virtual void toAudioPort(struct audio_port *port) const;
 
+    virtual void toAudioPort(struct audio_port_v7 *port) const;
+
     virtual void addAudioProfile(const sp<AudioProfile> &profile) {
         mProfiles.add(profile);
     }
@@ -64,6 +69,8 @@
 
     virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
 
+    virtual void importAudioPort(const audio_port_v7& port);
+
     status_t checkGain(const struct audio_gain_config *gainConfig, int index) const {
         if (index < 0 || (size_t)index >= mGains.size()) {
             return BAD_VALUE;
@@ -86,12 +93,27 @@
     status_t writeToParcel(Parcel* parcel) const override;
     status_t readFromParcel(const Parcel* parcel) override;
 
+    status_t writeToParcelable(media::AudioPort* parcelable) const;
+    status_t readFromParcelable(const media::AudioPort& parcelable);
+
     AudioGains mGains; // gain controllers
 protected:
     std::string  mName;
     audio_port_type_t mType;
     audio_port_role_t mRole;
     AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
+private:
+    template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value
+                                        || std::is_same<T, struct audio_port_v7>::value, int> = 0>
+    void toAudioPortBase(T* port) const {
+        port->role = mRole;
+        port->type = mType;
+        strlcpy(port->name, mName.c_str(), AUDIO_PORT_MAX_NAME_LEN);
+        port->num_gains = std::min(mGains.size(), (size_t) AUDIO_PORT_MAX_GAINS);
+        for (size_t i = 0; i < port->num_gains; i++) {
+            port->gains[i] = mGains[i]->getGain();
+        }
+    }
 };
 
 
@@ -119,6 +141,8 @@
 
     status_t writeToParcel(Parcel* parcel) const override;
     status_t readFromParcel(const Parcel* parcel) override;
+    status_t writeToParcelable(media::AudioPortConfig* parcelable) const;
+    status_t readFromParcelable(const media::AudioPortConfig& parcelable);
 
 protected:
     unsigned int mSamplingRate = 0u;
diff --git a/media/libaudiofoundation/include/media/AudioProfile.h b/media/libaudiofoundation/include/media/AudioProfile.h
index 730138a..57592bc 100644
--- a/media/libaudiofoundation/include/media/AudioProfile.h
+++ b/media/libaudiofoundation/include/media/AudioProfile.h
@@ -19,8 +19,10 @@
 #include <string>
 #include <vector>
 
+#include <android/media/AudioProfile.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
+#include <media/AidlConversion.h>
 #include <media/AudioContainers.h>
 #include <system/audio.h>
 #include <utils/RefBase.h>
@@ -73,6 +75,9 @@
     status_t writeToParcel(Parcel* parcel) const override;
     status_t readFromParcel(const Parcel* parcel) override;
 
+    ConversionResult<media::AudioProfile> toParcelable() const;
+    static ConversionResult<sp<AudioProfile>> fromParcelable(const media::AudioProfile& parcelable);
+
 private:
     std::string  mName;
     audio_format_t mFormat; // The format for an audio profile should only be set when initialized.
@@ -82,8 +87,17 @@
     bool mIsDynamicFormat = false;
     bool mIsDynamicChannels = false;
     bool mIsDynamicRate = false;
+
+    AudioProfile() = default;
+    AudioProfile& operator=(const AudioProfile& other);
 };
 
+// Conversion routines, according to AidlConversion.h conventions.
+ConversionResult<sp<AudioProfile>>
+aidl2legacy_AudioProfile(const media::AudioProfile& aidl);
+ConversionResult<media::AudioProfile>
+legacy2aidl_AudioProfile(const sp<AudioProfile>& legacy);
+
 class AudioProfileVector : public std::vector<sp<AudioProfile>>, public Parcelable
 {
 public:
@@ -105,6 +119,8 @@
     bool hasDynamicProfile() const;
     bool hasDynamicRateFor(audio_format_t format) const;
 
+    bool contains(const sp<AudioProfile>& profile) const;
+
     virtual void dump(std::string *dst, int spaces) const;
 
     bool equals(const AudioProfileVector& other) const;
@@ -115,4 +131,11 @@
 
 bool operator == (const AudioProfile &left, const AudioProfile &right);
 
+// Conversion routines, according to AidlConversion.h conventions.
+ConversionResult<AudioProfileVector>
+aidl2legacy_AudioProfileVector(const std::vector<media::AudioProfile>& aidl);
+ConversionResult<std::vector<media::AudioProfile>>
+legacy2aidl_AudioProfileVector(const AudioProfileVector& legacy);
+
+
 } // namespace android
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index 0cbd1de..140ce36 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -18,6 +18,7 @@
 
 #include <vector>
 
+#include <android/media/AudioPort.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
 #include <media/AudioContainers.h>
@@ -54,6 +55,7 @@
 
     // AudioPort
     virtual void toAudioPort(struct audio_port *port) const;
+    virtual void toAudioPort(struct audio_port_v7 *port) const;
 
     status_t setEncapsulationModes(uint32_t encapsulationModes);
     status_t setEncapsulationMetadataTypes(uint32_t encapsulationMetadataTypes);
@@ -75,10 +77,25 @@
     status_t writeToParcel(Parcel* parcel) const override;
     status_t readFromParcel(const Parcel* parcel) override;
 
+    status_t writeToParcelable(media::AudioPort* parcelable) const;
+    status_t readFromParcelable(const media::AudioPort& parcelable);
+
 protected:
     AudioDeviceTypeAddr mDeviceTypeAddr;
     uint32_t mEncapsulationModes = 0;
     uint32_t mEncapsulationMetadataTypes = 0;
+private:
+    template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value
+                                        || std::is_same<T, struct audio_port_v7>::value, int> = 0>
+    void toAudioPortInternal(T* port) const {
+        AudioPort::toAudioPort(port);
+        toAudioPortConfig(&port->active_config);
+        port->id = mId;
+        port->ext.device.type = mDeviceTypeAddr.mType;
+        port->ext.device.encapsulation_modes = mEncapsulationModes;
+        port->ext.device.encapsulation_metadata_types = mEncapsulationMetadataTypes;
+        (void)audio_utils_strlcpy_zerofill(port->ext.device.address, mDeviceTypeAddr.getAddress());
+    }
 };
 
 using DeviceDescriptorBaseVector = std::vector<sp<DeviceDescriptorBase>>;
@@ -94,4 +111,10 @@
  */
 AudioDeviceTypeAddrVector deviceTypeAddrsFromDescriptors(const DeviceDescriptorBaseVector& devices);
 
+// Conversion routines, according to AidlConversion.h conventions.
+ConversionResult<sp<DeviceDescriptorBase>>
+aidl2legacy_DeviceDescriptorBase(const media::AudioPort& aidl);
+ConversionResult<media::AudioPort>
+legacy2aidl_DeviceDescriptorBase(const sp<DeviceDescriptorBase>& legacy);
+
 } // namespace android
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index fab0fea..482f40e 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -63,8 +63,6 @@
     export_include_dirs: ["include"],
 
     // This is needed because the stream interface includes media/MicrophoneInfo.h
-    // which is not in any library but has a dependency on headers from libbinder.
-    header_libs: ["libbinder_headers"],
-
-    export_header_lib_headers: ["libbinder_headers"],
+    header_libs: ["av-headers"],
+    export_header_lib_headers: ["av-headers"],
 }
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index df006b5..fe47881 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -26,6 +26,7 @@
         "android.hardware.audio.common-util",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
+        "av-types-aidl-unstable-cpp",
         "libaudiofoundation",
         "libaudiohal_deathhandler",
         "libaudioutils",
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 7d0d83d..0108816 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -48,6 +48,9 @@
 
 namespace {
 
+using ::android::hardware::audio::common::CPP_VERSION::AudioPort;
+using ::android::hardware::audio::common::CPP_VERSION::AudioPortConfig;
+
 status_t deviceAddressFromHal(
         audio_devices_t device, const char* halAddress, DeviceAddress* address) {
     address->device = AudioDevice(device);
@@ -212,7 +215,7 @@
         const struct audio_config *config, size_t *size) {
     if (mDevice == 0) return NO_INIT;
     AudioConfig hidlConfig;
-    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
+    HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
     Result retval;
     Return<void> ret = mDevice->getInputBufferSize(
             hidlConfig,
@@ -237,7 +240,7 @@
     status_t status = deviceAddressFromHal(deviceType, address, &hidlDevice);
     if (status != OK) return status;
     AudioConfig hidlConfig;
-    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
+    HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
     Result retval = Result::NOT_INITIALIZED;
     Return<void> ret = mDevice->openOutputStream(
             handle,
@@ -272,7 +275,7 @@
     status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
     if (status != OK) return status;
     AudioConfig hidlConfig;
-    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
+    HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
     Result retval = Result::NOT_INITIALIZED;
 #if MAJOR_VERSION == 2
     auto sinkMetadata = AudioSource(source);
@@ -388,6 +391,33 @@
     return processReturn("getAudioPort", ret, retval);
 }
 
+status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
+    if (mDevice == 0) return NO_INIT;
+    status_t status = NO_ERROR;
+#if MAJOR_VERSION >= 7
+    AudioPort hidlPort;
+    HidlUtils::audioPortFromHal(*port, &hidlPort);
+    Result retval;
+    Return<void> ret = mDevice->getAudioPort(
+            hidlPort,
+            [&](Result r, const AudioPort& p) {
+                retval = r;
+                if (retval == Result::OK) {
+                    HidlUtils::audioPortToHal(p, port);
+                }
+            });
+    status = processReturn("getAudioPort", ret, retval);
+#else
+    struct audio_port audioPort = {};
+    audio_populate_audio_port(port, &audioPort);
+    status = getAudioPort(&audioPort);
+    if (status == NO_ERROR) {
+        audio_populate_audio_port_v7(&audioPort, port);
+    }
+#endif
+    return status;
+}
+
 status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
     if (mDevice == 0) return NO_INIT;
     AudioPortConfig hidlConfig;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index d342d4a..abd4ad5 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -107,6 +107,9 @@
     // Fills the list of supported attributes for a given audio port.
     virtual status_t getAudioPort(struct audio_port *port);
 
+    // Fills the list of supported attributes for a given audio port.
+    virtual status_t getAudioPort(struct audio_port_v7 *port);
+
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config);
 
diff --git a/media/libaudiohal/impl/DeviceHalLocal.cpp b/media/libaudiohal/impl/DeviceHalLocal.cpp
index 8021d92..aa9e477 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.cpp
+++ b/media/libaudiohal/impl/DeviceHalLocal.cpp
@@ -180,6 +180,16 @@
     return mDev->get_audio_port(mDev, port);
 }
 
+status_t DeviceHalLocal::getAudioPort(struct audio_port_v7 *port) {
+    struct audio_port audioPort = {};
+    audio_populate_audio_port(port, &audioPort);
+    status_t status = getAudioPort(&audioPort);
+    if (status == NO_ERROR) {
+        audio_populate_audio_port_v7(&audioPort, port);
+    }
+    return status;
+}
+
 status_t DeviceHalLocal::setAudioPortConfig(const struct audio_port_config *config) {
     if (version() >= AUDIO_DEVICE_API_VERSION_3_0)
         return mDev->set_audio_port_config(mDev, config);
diff --git a/media/libaudiohal/impl/DeviceHalLocal.h b/media/libaudiohal/impl/DeviceHalLocal.h
index d85e2a7..195204b 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.h
+++ b/media/libaudiohal/impl/DeviceHalLocal.h
@@ -100,6 +100,9 @@
     // Fills the list of supported attributes for a given audio port.
     virtual status_t getAudioPort(struct audio_port *port);
 
+    // Fills the list of supported attributes for a given audio port.
+    virtual status_t getAudioPort(struct audio_port_v7 *port);
+
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config);
 
diff --git a/media/libaudiohal/impl/EffectHalHidl.cpp b/media/libaudiohal/impl/EffectHalHidl.cpp
index caf575c..506feb8 100644
--- a/media/libaudiohal/impl/EffectHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectHalHidl.cpp
@@ -25,9 +25,9 @@
 
 #include "EffectBufferHalHidl.h"
 #include "EffectHalHidl.h"
-#include "HidlUtils.h"
+#include "UuidUtils.h"
 
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
 using ::android::hardware::audio::common::utils::EnumBitfield;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::MQDescriptorSync;
@@ -58,8 +58,8 @@
 // static
 void EffectHalHidl::effectDescriptorToHal(
         const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor) {
-    HidlUtils::uuidToHal(descriptor.type, &halDescriptor->type);
-    HidlUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid);
+    UuidUtils::uuidToHal(descriptor.type, &halDescriptor->type);
+    UuidUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid);
     halDescriptor->flags = static_cast<uint32_t>(descriptor.flags);
     halDescriptor->cpuLoad = descriptor.cpuLoad;
     halDescriptor->memoryUsage = descriptor.memoryUsage;
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
index 80e2b87..35ac332 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -23,9 +23,9 @@
 #include "EffectBufferHalHidl.h"
 #include "EffectHalHidl.h"
 #include "EffectsFactoryHalHidl.h"
-#include "HidlUtils.h"
+#include "UuidUtils.h"
 
-using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
 using ::android::hardware::Return;
 
 namespace android {
@@ -85,7 +85,7 @@
     // TODO: check for nullptr
     if (mEffectsFactory == 0) return NO_INIT;
     Uuid hidlUuid;
-    HidlUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
+    UuidUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
     Result retval = Result::NOT_INITIALIZED;
     Return<void> ret = mEffectsFactory->getDescriptor(hidlUuid,
             [&](Result r, const EffectDescriptor& result) {
@@ -107,7 +107,7 @@
         int32_t deviceId __unused, sp<EffectHalInterface> *effect) {
     if (mEffectsFactory == 0) return NO_INIT;
     Uuid hidlUuid;
-    HidlUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
+    UuidUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
     Result retval = Result::NOT_INITIALIZED;
     Return<void> ret;
 #if MAJOR_VERSION >= 6
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 1e04b21..29ef011 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -106,6 +106,9 @@
     // Fills the list of supported attributes for a given audio port.
     virtual status_t getAudioPort(struct audio_port *port) = 0;
 
+    // Fills the list of supported attributes for a given audio port.
+    virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
+
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
 
diff --git a/media/libaudioprocessing/tests/fuzzer/Android.bp b/media/libaudioprocessing/tests/fuzzer/Android.bp
index 1df47b7..2a0dec4 100644
--- a/media/libaudioprocessing/tests/fuzzer/Android.bp
+++ b/media/libaudioprocessing/tests/fuzzer/Android.bp
@@ -8,3 +8,14 @@
     "libsndfile",
   ],
 }
+
+cc_fuzz {
+  name: "libaudioprocessing_record_buffer_converter_fuzzer",
+  srcs: [
+    "libaudioprocessing_record_buffer_converter_fuzzer.cpp",
+  ],
+  defaults: ["libaudioprocessing_test_defaults"],
+  static_libs: [
+    "libsndfile",
+  ],
+}
diff --git a/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_fuzz_utils.h b/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_fuzz_utils.h
new file mode 100644
index 0000000..5165925
--- /dev/null
+++ b/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_fuzz_utils.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#ifndef ANDROID_LIBAUDIOPROCESSING_FUZZ_UTILS_H
+#define ANDROID_LIBAUDIOPROCESSING_FUZZ_UTILS_H
+
+#include <media/AudioBufferProvider.h>
+#include <system/audio.h>
+
+namespace android {
+
+class Provider : public AudioBufferProvider {
+  const void* mAddr;        // base address
+  const size_t mNumFrames;  // total frames
+  const size_t mFrameSize;  // size of each frame in bytes
+  size_t mNextFrame;        // index of next frame to provide
+  size_t mUnrel;            // number of frames not yet released
+ public:
+  Provider(const void* addr, size_t frames, size_t frameSize)
+      : mAddr(addr),
+        mNumFrames(frames),
+        mFrameSize(frameSize),
+        mNextFrame(0),
+        mUnrel(0) {}
+  status_t getNextBuffer(Buffer* buffer) override {
+    if (buffer->frameCount > mNumFrames - mNextFrame) {
+      buffer->frameCount = mNumFrames - mNextFrame;
+    }
+    mUnrel = buffer->frameCount;
+    if (buffer->frameCount > 0) {
+      buffer->raw = (char*)mAddr + mFrameSize * mNextFrame;
+      return NO_ERROR;
+    } else {
+      buffer->raw = nullptr;
+      return NOT_ENOUGH_DATA;
+    }
+  }
+  void releaseBuffer(Buffer* buffer) override {
+    if (buffer->frameCount > mUnrel) {
+      mNextFrame += mUnrel;
+      mUnrel = 0;
+    } else {
+      mNextFrame += buffer->frameCount;
+      mUnrel -= buffer->frameCount;
+    }
+    buffer->frameCount = 0;
+    buffer->raw = nullptr;
+  }
+  void reset() { mNextFrame = 0; }
+};
+
+} // namespace android
+
+#endif // ANDROID_LIBAUDIOPROCESSING_FUZZ_UTILS_H
diff --git a/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_record_buffer_converter_fuzzer.cpp b/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_record_buffer_converter_fuzzer.cpp
new file mode 100644
index 0000000..017598c
--- /dev/null
+++ b/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_record_buffer_converter_fuzzer.cpp
@@ -0,0 +1,177 @@
+/*
+ * 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.
+ */
+
+#include "libaudioprocessing_fuzz_utils.h"
+#include "fuzzer/FuzzedDataProvider.h"
+#include <media/AudioResampler.h>
+#include <media/RecordBufferConverter.h>
+#include <stddef.h>
+#include <stdint.h>
+
+using namespace android;
+
+constexpr int MAX_FRAMES = 1024;
+
+#define AUDIO_FORMAT_PCM_MAIN 0
+
+// Copied and simplified from audio-hal-enums.h?l=571
+constexpr uint32_t FUZZ_AUDIO_FORMATS[] = {
+  AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_16_BIT,
+  AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_8_BIT,
+  AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_32_BIT,
+  AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_8_24_BIT,
+  AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_FLOAT,
+  AUDIO_FORMAT_PCM_MAIN | AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED,
+  0x01000000u,
+  0x02000000u,
+  0x03000000u,
+  0x04000000u,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_MAIN,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_LC,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_SSR,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_LTP,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_HE_V1,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_SCALABLE,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_ERLC,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_LD,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_HE_V2,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_ELD,
+  AUDIO_FORMAT_AAC | AUDIO_FORMAT_AAC_SUB_XHE,
+  0x05000000u,
+  0x06000000u,
+  0x07000000u,
+  0x08000000u,
+  0x09000000u,
+  0x0A000000u,
+  AUDIO_FORMAT_E_AC3 | AUDIO_FORMAT_E_AC3_SUB_JOC,
+  0x0B000000u,
+  0x0C000000u,
+  0x0D000000u,
+  0x0E000000u,
+  0x10000000u,
+  0x11000000u,
+  0x12000000u,
+  0x13000000u,
+  0x14000000u,
+  0x15000000u,
+  0x16000000u,
+  0x17000000u,
+  0x18000000u,
+  0x19000000u,
+  0x1A000000u,
+  0x1B000000u,
+  0x1C000000u,
+  0x1D000000u,
+  0x1E000000u,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_MAIN,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_LC,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_SSR,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_LTP,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_HE_V1,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_SCALABLE,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_ERLC,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_LD,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_HE_V2,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_ELD,
+  AUDIO_FORMAT_AAC_ADTS | AUDIO_FORMAT_AAC_SUB_XHE,
+  0x1F000000u,
+  0x20000000u,
+  0x21000000u,
+  0x22000000u,
+  0x23000000u,
+  0x24000000u,
+  AUDIO_FORMAT_MAT | AUDIO_FORMAT_MAT_SUB_1_0,
+  AUDIO_FORMAT_MAT | AUDIO_FORMAT_MAT_SUB_2_0,
+  AUDIO_FORMAT_MAT | AUDIO_FORMAT_MAT_SUB_2_1,
+  0x25000000u,
+  AUDIO_FORMAT_AAC_LATM | AUDIO_FORMAT_AAC_SUB_LC,
+  AUDIO_FORMAT_AAC_LATM | AUDIO_FORMAT_AAC_SUB_HE_V1,
+  AUDIO_FORMAT_AAC_LATM | AUDIO_FORMAT_AAC_SUB_HE_V2,
+  0x26000000u,
+  0x27000000u,
+  0x28000000u,
+  0x29000000u,
+  0x2A000000u,
+  0x2B000000u,
+  0xFFFFFFFFu,
+  AUDIO_FORMAT_PCM_MAIN,
+  AUDIO_FORMAT_PCM,
+};
+constexpr size_t NUM_AUDIO_FORMATS = std::size(FUZZ_AUDIO_FORMATS);
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  FuzzedDataProvider fdp(data, size);
+  fdp.ConsumeIntegral<int>();
+
+  const audio_channel_mask_t srcChannelMask = (audio_channel_mask_t)fdp.ConsumeIntegral<int>();
+  const audio_format_t srcFormat =
+      (audio_format_t)FUZZ_AUDIO_FORMATS[fdp.ConsumeIntegralInRange<int>(0, NUM_AUDIO_FORMATS - 1)];
+  const uint32_t srcSampleRate = fdp.ConsumeIntegralInRange<int>(1, 0x7fffffff);
+  const audio_channel_mask_t dstChannelMask = (audio_channel_mask_t)fdp.ConsumeIntegral<int>();
+  const audio_format_t dstFormat =
+      (audio_format_t)FUZZ_AUDIO_FORMATS[fdp.ConsumeIntegralInRange<int>(0, NUM_AUDIO_FORMATS - 1)];
+  const uint32_t dstSampleRate = fdp.ConsumeIntegralInRange<int>(1, 0x7fffffff);
+
+  // Certain formats will result in LOG_ALWAYS_FATAL errors that aren't interesting crashes
+  // for fuzzing.  Don't use those ones.
+  const uint32_t dstChannelCount = audio_channel_count_from_in_mask(dstChannelMask);
+  constexpr android::AudioResampler::src_quality quality =
+      android::AudioResampler::DEFAULT_QUALITY;
+  const int maxChannels =
+      quality < android::AudioResampler::DYN_LOW_QUALITY ? 2 : 8;
+  if (dstChannelCount < 1 || dstChannelCount > maxChannels) {
+    return 0;
+  }
+
+  const uint32_t srcChannelCount = audio_channel_count_from_in_mask(srcChannelMask);
+  if (srcChannelCount < 1 || srcChannelCount > maxChannels) {
+    return 0;
+  }
+
+  RecordBufferConverter converter(srcChannelMask, srcFormat, srcSampleRate,
+                                  dstChannelMask, dstFormat, dstSampleRate);
+  if (converter.initCheck() != NO_ERROR) {
+    return 0;
+  }
+
+  const uint32_t srcFrameSize = srcChannelCount * audio_bytes_per_sample(srcFormat);
+  const int srcNumFrames = fdp.ConsumeIntegralInRange<int>(0, MAX_FRAMES);
+  constexpr size_t metadataSize = 2 + 3 * sizeof(int) + 2 * sizeof(float);
+  std::vector<uint8_t> inputData = fdp.ConsumeBytes<uint8_t>(
+      metadataSize + (srcFrameSize * srcNumFrames));
+  Provider provider(inputData.data(), srcNumFrames, srcFrameSize);
+
+  const uint32_t dstFrameSize = dstChannelCount * audio_bytes_per_sample(dstFormat);
+  const size_t frames = fdp.ConsumeIntegralInRange<size_t>(0, MAX_FRAMES + 1);
+  int8_t dst[dstFrameSize * frames];
+  memset(dst, 0, sizeof(int8_t) * dstFrameSize * frames);
+
+  // Add a small number of loops to see if repeated calls to convert cause
+  // any change in behavior.
+  const int numLoops = fdp.ConsumeIntegralInRange<int>(1, 3);
+  for (int loop = 0; loop < numLoops; ++loop) {
+    switch (fdp.ConsumeIntegralInRange<int>(0, 1)) {
+      case 0:
+        converter.reset();
+        FALLTHROUGH_INTENDED;
+      case 1:
+        converter.convert(dst, &provider, frames);
+        break;
+    }
+  }
+
+  return 0;
+}
diff --git a/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_resampler_fuzzer.cpp b/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_resampler_fuzzer.cpp
index 938c610..65c9a3c 100644
--- a/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_resampler_fuzzer.cpp
+++ b/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_resampler_fuzzer.cpp
@@ -34,6 +34,8 @@
 #include <unistd.h>
 #include <utils/Vector.h>
 
+#include "libaudioprocessing_fuzz_utils.h"
+
 #include <memory>
 
 using namespace android;
@@ -53,46 +55,6 @@
     AudioResampler::DYN_HIGH_QUALITY,
 };
 
-class Provider : public AudioBufferProvider {
-  const void* mAddr;        // base address
-  const size_t mNumFrames;  // total frames
-  const size_t mFrameSize;  // size of each frame in bytes
-  size_t mNextFrame;        // index of next frame to provide
-  size_t mUnrel;            // number of frames not yet released
- public:
-  Provider(const void* addr, size_t frames, size_t frameSize)
-      : mAddr(addr),
-        mNumFrames(frames),
-        mFrameSize(frameSize),
-        mNextFrame(0),
-        mUnrel(0) {}
-  status_t getNextBuffer(Buffer* buffer) override {
-    if (buffer->frameCount > mNumFrames - mNextFrame) {
-      buffer->frameCount = mNumFrames - mNextFrame;
-    }
-    mUnrel = buffer->frameCount;
-    if (buffer->frameCount > 0) {
-      buffer->raw = (char*)mAddr + mFrameSize * mNextFrame;
-      return NO_ERROR;
-    } else {
-      buffer->raw = nullptr;
-      return NOT_ENOUGH_DATA;
-    }
-  }
-  virtual void releaseBuffer(Buffer* buffer) {
-    if (buffer->frameCount > mUnrel) {
-      mNextFrame += mUnrel;
-      mUnrel = 0;
-    } else {
-      mNextFrame += buffer->frameCount;
-      mUnrel -= buffer->frameCount;
-    }
-    buffer->frameCount = 0;
-    buffer->raw = nullptr;
-  }
-  void reset() { mNextFrame = 0; }
-};
-
 audio_format_t chooseFormat(AudioResampler::src_quality quality,
                             uint8_t input_byte) {
   switch (quality) {
diff --git a/media/libeffects/lvm/lib/Android.bp b/media/libeffects/lvm/lib/Android.bp
index 8f2f016..dbe0d62 100644
--- a/media/libeffects/lvm/lib/Android.bp
+++ b/media/libeffects/lvm/lib/Android.bp
@@ -131,12 +131,15 @@
     shared_libs: [
         "liblog",
     ],
+    static_libs: [
+        "libaudioutils",
+    ],
     header_libs: [
         "libhardware_headers",
     ],
     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 5b47aa6..1f0b459 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.cpp
@@ -21,6 +21,9 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVDBE.h"
 #include "LVDBE_Private.h"
 #include "VectorArithmetic.h"
@@ -107,12 +110,20 @@
     /*
      * Setup the high pass filter
      */
+#ifdef BIQUAD_OPT
+    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
+            ->setCoefficients<std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(coefs);
+#else
     LoadConst_Float(0,                                      /* Clear the history, value 0 */
                     (LVM_FLOAT*)&pInstance->pData->HPFTaps, /* Destination */
                     sizeof(pInstance->pData->HPFTaps) / sizeof(LVM_FLOAT)); /* Number of words */
     BQ_2I_D32F32Cll_TRC_WRA_01_Init(&pInstance->pCoef->HPFInstance, /* Initialise the filter */
                                     &pInstance->pData->HPFTaps,
                                     (BQ_FLOAT_Coefs_t*)&LVDBE_HPF_Table[Offset]);
+#endif
 
     /*
      * Setup the band pass filter
@@ -275,6 +286,15 @@
     LVDBE_Instance_t* pInstance = (LVDBE_Instance_t*)hInstance;
     LVMixer3_2St_FLOAT_st* pBypassMixer_Instance = &pInstance->pData->BypassMixer;
 
+#ifdef BIQUAD_OPT
+    /*
+     * Create biquad instance
+     */
+    pInstance->pBqInstance.reset(
+            new android::audio_utils::BiquadFilter<LVM_FLOAT>(pParams->NrChannels));
+    pInstance->pBqInstance->clear();
+#endif
+
     /*
      * Update the filters
      */
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
index 12af162..611b762 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.cpp
@@ -94,6 +94,14 @@
         return LVDBE_NULLADDRESS;
     }
 
+#ifdef BIQUAD_OPT
+    /*
+     * Create biquad instance
+     */
+    pInstance->pBqInstance.reset(
+            new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+#endif
+
     /*
      * Initialise the filters
      */
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
index 4fef1ef..fa85638 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
@@ -33,6 +33,9 @@
 /*                                                                                      */
 /****************************************************************************************/
 
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 #include "LVDBE.h" /* Calling or Application layer definitions */
 #include "BIQUAD.h"
 #include "LVC_Mixer.h"
@@ -63,7 +66,9 @@
     AGC_MIX_VOL_2St1Mon_FLOAT_t AGCInstance; /* AGC instance parameters */
 
     /* 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 */
     LVMixer3_1St_FLOAT_st BypassVolume;    /* Bypass volume scaler */
     LVMixer3_2St_FLOAT_st BypassMixer;     /* Bypass Mixer for Click Removal */
@@ -73,7 +78,9 @@
 /* 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;
 /* Instance structure */
@@ -86,6 +93,10 @@
     LVDBE_Data_FLOAT_t* pData; /* Instance data */
     LVDBE_Coef_FLOAT_t* pCoef; /* Instance coefficients */
     void* pScratch;            /* scratch pointer */
+#ifdef BIQUAD_OPT
+    std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+            pBqInstance; /* Biquad filter instance */
+#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 f4a4d6f..bd04a02 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
@@ -20,6 +20,9 @@
 /*    Includes                                                                          */
 /*                                                                                      */
 /****************************************************************************************/
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
 
 #include <string.h>  // memset
 #include "LVDBE.h"
@@ -125,10 +128,14 @@
          * Apply the high pass filter if selected
          */
         if (pInstance->Params.HPFSelect == LVDBE_HPF_ON) {
+#ifdef BIQUAD_OPT
+            pInstance->pBqInstance->process(pScratch, pScratch, NrFrames);
+#else
             BQ_MC_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance, /* Filter instance      */
                                        pScratch,                       /* Source               */
                                        pScratch,                       /* Destination          */
                                        (LVM_INT16)NrFrames, (LVM_INT16)NrChannels);
+#endif
         }
 
         /*
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 670b415..865baad 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -1021,6 +1021,16 @@
         ActiveParams.NrChannels = NrChannels;
         ActiveParams.ChMask = pConfig->inputCfg.channels;
 
+        if (NrChannels == 1) {
+            ActiveParams.SourceFormat = LVM_MONO;
+        } else if (NrChannels == 2) {
+            ActiveParams.SourceFormat = LVM_STEREO;
+        } else if (NrChannels > 2 && NrChannels <= LVM_MAX_CHANNELS) {
+            ActiveParams.SourceFormat = LVM_MULTICHANNEL;
+        } else {
+            return -EINVAL;
+        }
+
         LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
 
         LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "Effect_setConfig")
diff --git a/media/libeffects/preprocessing/.clang-format b/media/libeffects/preprocessing/.clang-format
new file mode 120000
index 0000000..f1b4f69
--- /dev/null
+++ b/media/libeffects/preprocessing/.clang-format
@@ -0,0 +1 @@
+../../../../../build/soong/scripts/system-clang-format
\ No newline at end of file
diff --git a/media/libeffects/preprocessing/Android.bp b/media/libeffects/preprocessing/Android.bp
index 16cd0ad..681e247 100644
--- a/media/libeffects/preprocessing/Android.bp
+++ b/media/libeffects/preprocessing/Android.bp
@@ -1,29 +1,31 @@
 // audio preprocessing wrapper
 cc_library_shared {
     name: "libaudiopreprocessing",
-
     vendor: true,
-
     relative_install_path: "soundfx",
-
     srcs: ["PreProcessing.cpp"],
-
-    shared_libs: [
-        "libwebrtc_audio_preprocessing",
-        "libspeexresampler",
-        "libutils",
-        "liblog",
+    local_include_dirs: [
+        ".",
     ],
-
     cflags: [
-        "-DWEBRTC_POSIX",
-        "-fvisibility=hidden",
         "-Wall",
         "-Werror",
+        "-Wextra",
+        "-Wno-unused-parameter",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libutils",
+    ],
+
+    static_libs: [
+        "webrtc_audio_processing",
     ],
 
     header_libs: [
         "libaudioeffects",
         "libhardware_headers",
+        "libwebrtc_absl_headers",
     ],
 }
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index c7afe2f..03ccc34 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -18,15 +18,15 @@
 #include <string.h>
 #define LOG_TAG "PreProcessing"
 //#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <hardware/audio_effect.h>
 #include <audio_effects/effect_aec.h>
 #include <audio_effects/effect_agc.h>
+#include <hardware/audio_effect.h>
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <audio_effects/effect_agc2.h>
 #include <audio_effects/effect_ns.h>
-#include <module_common_types.h>
 #include <audio_processing.h>
-#include "speex/speex_resampler.h"
+#include <module_common_types.h>
 
 // undefine to perform multi channels API functional tests
 //#define DUAL_MIC_TEST
@@ -39,26 +39,26 @@
 #define PREPROC_NUM_SESSIONS 8
 
 // types of pre processing modules
-enum preproc_id
-{
-    PREPROC_AGC,        // Automatic Gain Control
-    PREPROC_AEC,        // Acoustic Echo Canceler
-    PREPROC_NS,         // Noise Suppressor
+enum preproc_id {
+    PREPROC_AGC,  // Automatic Gain Control
+    PREPROC_AGC2,  // Automatic Gain Control 2
+    PREPROC_AEC,  // Acoustic Echo Canceler
+    PREPROC_NS,   // Noise Suppressor
     PREPROC_NUM_EFFECTS
 };
 
 // Session state
 enum preproc_session_state {
-    PREPROC_SESSION_STATE_INIT,        // initialized
-    PREPROC_SESSION_STATE_CONFIG       // configuration received
+    PREPROC_SESSION_STATE_INIT,   // initialized
+    PREPROC_SESSION_STATE_CONFIG  // configuration received
 };
 
 // Effect/Preprocessor state
 enum preproc_effect_state {
-    PREPROC_EFFECT_STATE_INIT,         // initialized
-    PREPROC_EFFECT_STATE_CREATED,      // webRTC engine created
-    PREPROC_EFFECT_STATE_CONFIG,       // configuration received/disabled
-    PREPROC_EFFECT_STATE_ACTIVE        // active/enabled
+    PREPROC_EFFECT_STATE_INIT,     // initialized
+    PREPROC_EFFECT_STATE_CREATED,  // webRTC engine created
+    PREPROC_EFFECT_STATE_CONFIG,   // configuration received/disabled
+    PREPROC_EFFECT_STATE_ACTIVE    // active/enabled
 };
 
 // handle on webRTC engine
@@ -71,74 +71,76 @@
 // Effect operation table. Functions for all pre processors are declared in sPreProcOps[] table.
 // Function pointer can be null if no action required.
 struct preproc_ops_s {
-    int (* create)(preproc_effect_t *fx);
-    int (* init)(preproc_effect_t *fx);
-    int (* reset)(preproc_effect_t *fx);
-    void (* enable)(preproc_effect_t *fx);
-    void (* disable)(preproc_effect_t *fx);
-    int (* set_parameter)(preproc_effect_t *fx, void *param, void *value);
-    int (* get_parameter)(preproc_effect_t *fx, void *param, uint32_t *size, void *value);
-    int (* set_device)(preproc_effect_t *fx, uint32_t device);
+    int (*create)(preproc_effect_t* fx);
+    int (*init)(preproc_effect_t* fx);
+    int (*reset)(preproc_effect_t* fx);
+    void (*enable)(preproc_effect_t* fx);
+    void (*disable)(preproc_effect_t* fx);
+    int (*set_parameter)(preproc_effect_t* fx, void* param, void* value);
+    int (*get_parameter)(preproc_effect_t* fx, void* param, uint32_t* size, void* value);
+    int (*set_device)(preproc_effect_t* fx, uint32_t device);
 };
 
 // Effect context
 struct preproc_effect_s {
-    const struct effect_interface_s *itfe;
-    uint32_t procId;                // type of pre processor (enum preproc_id)
-    uint32_t state;                 // current state (enum preproc_effect_state)
-    preproc_session_t *session;     // session the effect is on
-    const preproc_ops_t *ops;       // effect ops table
-    preproc_fx_handle_t engine;     // handle on webRTC engine
-    uint32_t type;                  // subtype of effect
+    const struct effect_interface_s* itfe;
+    uint32_t procId;             // type of pre processor (enum preproc_id)
+    uint32_t state;              // current state (enum preproc_effect_state)
+    preproc_session_t* session;  // session the effect is on
+    const preproc_ops_t* ops;    // effect ops table
+    preproc_fx_handle_t engine;  // handle on webRTC engine
+    uint32_t type;               // subtype of effect
 #ifdef DUAL_MIC_TEST
-    bool aux_channels_on;           // support auxiliary channels
-    size_t cur_channel_config;      // current auciliary channel configuration
+    bool aux_channels_on;       // support auxiliary channels
+    size_t cur_channel_config;  // current auciliary channel configuration
 #endif
 };
 
 // Session context
 struct preproc_session_s {
-    struct preproc_effect_s effects[PREPROC_NUM_EFFECTS]; // effects in this session
-    uint32_t state;                     // current state (enum preproc_session_state)
-    int id;                             // audio session ID
-    int io;                             // handle of input stream this session is on
-    webrtc::AudioProcessing* apm;       // handle on webRTC audio processing module (APM)
-    size_t apmFrameCount;               // buffer size for webRTC process (10 ms)
-    uint32_t apmSamplingRate;           // webRTC APM sampling rate (8/16 or 32 kHz)
-    size_t frameCount;                  // buffer size before input resampler ( <=> apmFrameCount)
-    uint32_t samplingRate;              // sampling rate at effect process interface
-    uint32_t inChannelCount;            // input channel count
-    uint32_t outChannelCount;           // output channel count
-    uint32_t createdMsk;                // bit field containing IDs of crested pre processors
-    uint32_t enabledMsk;                // bit field containing IDs of enabled pre processors
-    uint32_t processedMsk;              // bit field containing IDs of pre processors already
-                                        // processed in current round
-    webrtc::AudioFrame *procFrame;      // audio frame passed to webRTC AMP ProcessStream()
-    int16_t *inBuf;                     // input buffer used when resampling
-    size_t inBufSize;                   // input buffer size in frames
-    size_t framesIn;                    // number of frames in input buffer
-    SpeexResamplerState *inResampler;   // handle on input speex resampler
-    int16_t *outBuf;                    // output buffer used when resampling
-    size_t outBufSize;                  // output buffer size in frames
-    size_t framesOut;                   // number of frames in output buffer
-    SpeexResamplerState *outResampler;  // handle on output speex resampler
-    uint32_t revChannelCount;           // number of channels on reverse stream
-    uint32_t revEnabledMsk;             // bit field containing IDs of enabled pre processors
-                                        // with reverse channel
-    uint32_t revProcessedMsk;           // bit field containing IDs of pre processors with reverse
-                                        // channel already processed in current round
-    webrtc::AudioFrame *revFrame;       // audio frame passed to webRTC AMP AnalyzeReverseStream()
-    int16_t *revBuf;                    // reverse channel input buffer
-    size_t revBufSize;                  // reverse channel input buffer size
-    size_t framesRev;                   // number of frames in reverse channel input buffer
-    SpeexResamplerState *revResampler;  // handle on reverse channel input speex resampler
+    struct preproc_effect_s effects[PREPROC_NUM_EFFECTS];  // effects in this session
+    uint32_t state;                // current state (enum preproc_session_state)
+    int id;                        // audio session ID
+    int io;                        // handle of input stream this session is on
+    webrtc::AudioProcessing* apm;  // handle on webRTC audio processing module (APM)
+    // Audio Processing module builder
+    webrtc::AudioProcessingBuilder ap_builder;
+    size_t apmFrameCount;      // buffer size for webRTC process (10 ms)
+    uint32_t apmSamplingRate;  // webRTC APM sampling rate (8/16 or 32 kHz)
+    size_t frameCount;         // buffer size before input resampler ( <=> apmFrameCount)
+    uint32_t samplingRate;     // sampling rate at effect process interface
+    uint32_t inChannelCount;   // input channel count
+    uint32_t outChannelCount;  // output channel count
+    uint32_t createdMsk;       // bit field containing IDs of crested pre processors
+    uint32_t enabledMsk;       // bit field containing IDs of enabled pre processors
+    uint32_t processedMsk;     // bit field containing IDs of pre processors already
+                               // processed in current round
+    // audio config strucutre
+    webrtc::AudioProcessing::Config config;
+    webrtc::StreamConfig inputConfig;   // input stream configuration
+    webrtc::StreamConfig outputConfig;  // output stream configuration
+    int16_t* inBuf;    // input buffer used when resampling
+    size_t inBufSize;  // input buffer size in frames
+    size_t framesIn;   // number of frames in input buffer
+    int16_t* outBuf;    // output buffer used when resampling
+    size_t outBufSize;  // output buffer size in frames
+    size_t framesOut;   // number of frames in output buffer
+    uint32_t revChannelCount;  // number of channels on reverse stream
+    uint32_t revEnabledMsk;    // bit field containing IDs of enabled pre processors
+                               // with reverse channel
+    uint32_t revProcessedMsk;  // bit field containing IDs of pre processors with reverse
+                               // channel already processed in current round
+    webrtc::StreamConfig revConfig;     // reverse stream configuration.
+    int16_t* revBuf;    // reverse channel input buffer
+    size_t revBufSize;  // reverse channel input buffer size
+    size_t framesRev;   // number of frames in reverse channel input buffer
 };
 
 #ifdef DUAL_MIC_TEST
 enum {
-    PREPROC_CMD_DUAL_MIC_ENABLE = EFFECT_CMD_FIRST_PROPRIETARY, // enable dual mic mode
-    PREPROC_CMD_DUAL_MIC_PCM_DUMP_START,                        // start pcm capture
-    PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP                          // stop pcm capture
+    PREPROC_CMD_DUAL_MIC_ENABLE = EFFECT_CMD_FIRST_PROPRIETARY,  // enable dual mic mode
+    PREPROC_CMD_DUAL_MIC_PCM_DUMP_START,                         // start pcm capture
+    PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP                           // stop pcm capture
 };
 
 enum {
@@ -151,24 +153,22 @@
 };
 
 const channel_config_t sDualMicConfigs[CHANNEL_CFG_CNT] = {
-        {AUDIO_CHANNEL_IN_MONO , 0},
-        {AUDIO_CHANNEL_IN_STEREO , 0},
-        {AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
-        {AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
-};
+        {AUDIO_CHANNEL_IN_MONO, 0},
+        {AUDIO_CHANNEL_IN_STEREO, 0},
+        {AUDIO_CHANNEL_IN_FRONT, AUDIO_CHANNEL_IN_BACK},
+        {AUDIO_CHANNEL_IN_STEREO, AUDIO_CHANNEL_IN_RIGHT}};
 
 bool sHasAuxChannels[PREPROC_NUM_EFFECTS] = {
-        false,   // PREPROC_AGC
+        false,  // PREPROC_AGC
         true,   // PREPROC_AEC
         true,   // PREPROC_NS
 };
 
 bool gDualMicEnabled;
-FILE *gPcmDumpFh;
+FILE* gPcmDumpFh;
 static pthread_mutex_t gPcmDumpLock = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
-
 //------------------------------------------------------------------------------
 // Effect descriptors
 //------------------------------------------------------------------------------
@@ -178,68 +178,69 @@
 
 // Automatic Gain Control
 static const effect_descriptor_t sAgcDescriptor = {
-        { 0x0a8abfe0, 0x654c, 0x11e0, 0xba26, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type
-        { 0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid
+        {0x0a8abfe0, 0x654c, 0x11e0, 0xba26, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // type
+        {0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // uuid
         EFFECT_CONTROL_API_VERSION,
-        (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND),
-        0, //FIXME indicate CPU load
-        0, //FIXME indicate memory usage
+        (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
+        0,  // FIXME indicate CPU load
+        0,  // FIXME indicate memory usage
         "Automatic Gain Control",
-        "The Android Open Source Project"
-};
+        "The Android Open Source Project"};
+
+// Automatic Gain Control 2
+static const effect_descriptor_t sAgc2Descriptor = {
+        {0xae3c653b, 0xbe18, 0x4ab8, 0x8938, {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}},  // type
+        {0x89f38e65, 0xd4d2, 0x4d64, 0xad0e, {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}},  // uuid
+        EFFECT_CONTROL_API_VERSION,
+        (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
+        0,  // FIXME indicate CPU load
+        0,  // FIXME indicate memory usage
+        "Automatic Gain Control 2",
+        "The Android Open Source Project"};
 
 // Acoustic Echo Cancellation
 static const effect_descriptor_t sAecDescriptor = {
-        { 0x7b491460, 0x8d4d, 0x11e0, 0xbd61, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type
-        { 0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid
+        {0x7b491460, 0x8d4d, 0x11e0, 0xbd61, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // type
+        {0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // uuid
         EFFECT_CONTROL_API_VERSION,
-        (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND),
-        0, //FIXME indicate CPU load
-        0, //FIXME indicate memory usage
+        (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
+        0,  // FIXME indicate CPU load
+        0,  // FIXME indicate memory usage
         "Acoustic Echo Canceler",
-        "The Android Open Source Project"
-};
+        "The Android Open Source Project"};
 
 // Noise suppression
 static const effect_descriptor_t sNsDescriptor = {
-        { 0x58b4b260, 0x8e06, 0x11e0, 0xaa8e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type
-        { 0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid
+        {0x58b4b260, 0x8e06, 0x11e0, 0xaa8e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // type
+        {0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // uuid
         EFFECT_CONTROL_API_VERSION,
-        (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND),
-        0, //FIXME indicate CPU load
-        0, //FIXME indicate memory usage
+        (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
+        0,  // FIXME indicate CPU load
+        0,  // FIXME indicate memory usage
         "Noise Suppression",
-        "The Android Open Source Project"
-};
+        "The Android Open Source Project"};
 
-
-static const effect_descriptor_t *sDescriptors[PREPROC_NUM_EFFECTS] = {
-        &sAgcDescriptor,
-        &sAecDescriptor,
-        &sNsDescriptor
-};
+static const effect_descriptor_t* sDescriptors[PREPROC_NUM_EFFECTS] = {&sAgcDescriptor,
+                                                                       &sAgc2Descriptor,
+                                                                       &sAecDescriptor,
+                                                                       &sNsDescriptor};
 
 //------------------------------------------------------------------------------
 // Helper functions
 //------------------------------------------------------------------------------
 
-const effect_uuid_t * const sUuidToPreProcTable[PREPROC_NUM_EFFECTS] = {
-        FX_IID_AGC,
-        FX_IID_AEC,
-        FX_IID_NS
-};
+const effect_uuid_t* const sUuidToPreProcTable[PREPROC_NUM_EFFECTS] = {FX_IID_AGC,
+                                                                       FX_IID_AGC2,
+                                                                       FX_IID_AEC, FX_IID_NS};
 
-
-const effect_uuid_t * ProcIdToUuid(int procId)
-{
+const effect_uuid_t* ProcIdToUuid(int procId) {
     if (procId >= PREPROC_NUM_EFFECTS) {
         return EFFECT_UUID_NULL;
     }
     return sUuidToPreProcTable[procId];
 }
 
-uint32_t UuidToProcId(const effect_uuid_t * uuid)
-{
+uint32_t UuidToProcId(const effect_uuid_t* uuid) {
     size_t i;
     for (i = 0; i < PREPROC_NUM_EFFECTS; i++) {
         if (memcmp(uuid, sUuidToPreProcTable[i], sizeof(*uuid)) == 0) {
@@ -249,15 +250,13 @@
     return i;
 }
 
-bool HasReverseStream(uint32_t procId)
-{
+bool HasReverseStream(uint32_t procId) {
     if (procId == PREPROC_AEC) {
         return true;
     }
     return false;
 }
 
-
 //------------------------------------------------------------------------------
 // Automatic Gain Control (AGC)
 //------------------------------------------------------------------------------
@@ -266,499 +265,538 @@
 static const int kAgcDefaultCompGain = 9;
 static const bool kAgcDefaultLimiter = true;
 
-int  AgcInit (preproc_effect_t *effect)
-{
-    ALOGV("AgcInit");
-    webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
-    agc->set_mode(webrtc::GainControl::kFixedDigital);
-    agc->set_target_level_dbfs(kAgcDefaultTargetLevel);
-    agc->set_compression_gain_db(kAgcDefaultCompGain);
-    agc->enable_limiter(kAgcDefaultLimiter);
+int Agc2Init(preproc_effect_t* effect) {
+    ALOGV("Agc2Init");
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.gain_controller2.fixed_digital.gain_db = 0.f;
+    effect->session->config.gain_controller2.adaptive_digital.level_estimator =
+            effect->session->config.gain_controller2.kRms;
+    effect->session->config.gain_controller2.adaptive_digital.extra_saturation_margin_db = 2.f;
+    effect->session->apm->ApplyConfig(effect->session->config);
     return 0;
 }
 
-int  AgcCreate(preproc_effect_t *effect)
-{
-    webrtc::GainControl *agc = effect->session->apm->gain_control();
-    ALOGV("AgcCreate got agc %p", agc);
-    if (agc == NULL) {
-        ALOGW("AgcCreate Error");
-        return -ENOMEM;
-    }
-    effect->engine = static_cast<preproc_fx_handle_t>(agc);
+int AgcInit(preproc_effect_t* effect) {
+    ALOGV("AgcInit");
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.gain_controller1.target_level_dbfs = kAgcDefaultTargetLevel;
+    effect->session->config.gain_controller1.compression_gain_db = kAgcDefaultCompGain;
+    effect->session->config.gain_controller1.enable_limiter = kAgcDefaultLimiter;
+    effect->session->apm->ApplyConfig(effect->session->config);
+    return 0;
+}
+
+int Agc2Create(preproc_effect_t* effect) {
+    Agc2Init(effect);
+    return 0;
+}
+
+int AgcCreate(preproc_effect_t* effect) {
     AgcInit(effect);
     return 0;
 }
 
-int AgcGetParameter(preproc_effect_t *effect,
-                    void *pParam,
-                    uint32_t *pValueSize,
-                    void *pValue)
-{
+int Agc2GetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
     int status = 0;
-    uint32_t param = *(uint32_t *)pParam;
-    t_agc_settings *pProperties = (t_agc_settings *)pValue;
-    webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
+    uint32_t param = *(uint32_t*)pParam;
+    agc2_settings_t* pProperties = (agc2_settings_t*)pValue;
 
     switch (param) {
-    case AGC_PARAM_TARGET_LEVEL:
-    case AGC_PARAM_COMP_GAIN:
-        if (*pValueSize < sizeof(int16_t)) {
-            *pValueSize = 0;
-            return -EINVAL;
-        }
-        break;
-    case AGC_PARAM_LIMITER_ENA:
-        if (*pValueSize < sizeof(bool)) {
-            *pValueSize = 0;
-            return -EINVAL;
-        }
-        break;
-    case AGC_PARAM_PROPERTIES:
-        if (*pValueSize < sizeof(t_agc_settings)) {
-            *pValueSize = 0;
-            return -EINVAL;
-        }
-        break;
+        case AGC2_PARAM_FIXED_DIGITAL_GAIN:
+            if (*pValueSize < sizeof(float)) {
+                *pValueSize = 0.f;
+                return -EINVAL;
+            }
+            break;
+        case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
+            if (*pValueSize < sizeof(int32_t)) {
+                *pValueSize = 0;
+                return -EINVAL;
+            }
+            break;
+        case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
+            if (*pValueSize < sizeof(float)) {
+                *pValueSize = 0.f;
+                return -EINVAL;
+            }
+            break;
+        case AGC2_PARAM_PROPERTIES:
+            if (*pValueSize < sizeof(agc2_settings_t)) {
+                *pValueSize = 0;
+                return -EINVAL;
+            }
+            break;
 
-    default:
-        ALOGW("AgcGetParameter() unknown param %08x", param);
-        status = -EINVAL;
-        break;
+        default:
+            ALOGW("Agc2GetParameter() unknown param %08x", param);
+            status = -EINVAL;
+            break;
     }
 
+    effect->session->config = effect->session->apm->GetConfig();
     switch (param) {
-    case AGC_PARAM_TARGET_LEVEL:
-        *(int16_t *) pValue = (int16_t)(agc->target_level_dbfs() * -100);
-        ALOGV("AgcGetParameter() target level %d milliBels", *(int16_t *) pValue);
-        break;
-    case AGC_PARAM_COMP_GAIN:
-        *(int16_t *) pValue = (int16_t)(agc->compression_gain_db() * 100);
-        ALOGV("AgcGetParameter() comp gain %d milliBels", *(int16_t *) pValue);
-        break;
-    case AGC_PARAM_LIMITER_ENA:
-        *(bool *) pValue = (bool)agc->is_limiter_enabled();
-        ALOGV("AgcGetParameter() limiter enabled %s",
-             (*(int16_t *) pValue != 0) ? "true" : "false");
-        break;
-    case AGC_PARAM_PROPERTIES:
-        pProperties->targetLevel = (int16_t)(agc->target_level_dbfs() * -100);
-        pProperties->compGain = (int16_t)(agc->compression_gain_db() * 100);
-        pProperties->limiterEnabled = (bool)agc->is_limiter_enabled();
-        break;
-    default:
-        ALOGW("AgcGetParameter() unknown param %d", param);
-        status = -EINVAL;
-        break;
+        case AGC2_PARAM_FIXED_DIGITAL_GAIN:
+            *(float*)pValue =
+                    (float)(effect->session->config.gain_controller2.fixed_digital.gain_db);
+            ALOGV("Agc2GetParameter() target level %f dB", *(float*)pValue);
+            break;
+        case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
+            *(uint32_t*)pValue = (uint32_t)(
+                    effect->session->config.gain_controller2.adaptive_digital.level_estimator);
+            ALOGV("Agc2GetParameter() level estimator %d",
+                  *(webrtc::AudioProcessing::Config::GainController2::LevelEstimator*)pValue);
+            break;
+        case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
+            *(float*)pValue = (float)(effect->session->config.gain_controller2.adaptive_digital
+                                              .extra_saturation_margin_db);
+            ALOGV("Agc2GetParameter() extra saturation margin %f dB", *(float*)pValue);
+            break;
+        case AGC2_PARAM_PROPERTIES:
+            pProperties->fixedDigitalGain =
+                    (float)(effect->session->config.gain_controller2.fixed_digital.gain_db);
+            pProperties->level_estimator = (uint32_t)(
+                    effect->session->config.gain_controller2.adaptive_digital.level_estimator);
+            pProperties->extraSaturationMargin =
+                    (float)(effect->session->config.gain_controller2.adaptive_digital
+                                    .extra_saturation_margin_db);
+            break;
+        default:
+            ALOGW("Agc2GetParameter() unknown param %d", param);
+            status = -EINVAL;
+            break;
+    }
+
+    return status;
+}
+
+int AgcGetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
+    int status = 0;
+    uint32_t param = *(uint32_t*)pParam;
+    t_agc_settings* pProperties = (t_agc_settings*)pValue;
+
+    switch (param) {
+        case AGC_PARAM_TARGET_LEVEL:
+        case AGC_PARAM_COMP_GAIN:
+            if (*pValueSize < sizeof(int16_t)) {
+                *pValueSize = 0;
+                return -EINVAL;
+            }
+            break;
+        case AGC_PARAM_LIMITER_ENA:
+            if (*pValueSize < sizeof(bool)) {
+                *pValueSize = 0;
+                return -EINVAL;
+            }
+            break;
+        case AGC_PARAM_PROPERTIES:
+            if (*pValueSize < sizeof(t_agc_settings)) {
+                *pValueSize = 0;
+                return -EINVAL;
+            }
+            break;
+
+        default:
+            ALOGW("AgcGetParameter() unknown param %08x", param);
+            status = -EINVAL;
+            break;
+    }
+
+    effect->session->config = effect->session->apm->GetConfig();
+    switch (param) {
+        case AGC_PARAM_TARGET_LEVEL:
+            *(int16_t*)pValue =
+                    (int16_t)(effect->session->config.gain_controller1.target_level_dbfs * -100);
+            ALOGV("AgcGetParameter() target level %d milliBels", *(int16_t*)pValue);
+            break;
+        case AGC_PARAM_COMP_GAIN:
+            *(int16_t*)pValue =
+                    (int16_t)(effect->session->config.gain_controller1.compression_gain_db * -100);
+            ALOGV("AgcGetParameter() comp gain %d milliBels", *(int16_t*)pValue);
+            break;
+        case AGC_PARAM_LIMITER_ENA:
+            *(bool*)pValue = (bool)(effect->session->config.gain_controller1.enable_limiter);
+            ALOGV("AgcGetParameter() limiter enabled %s",
+                  (*(int16_t*)pValue != 0) ? "true" : "false");
+            break;
+        case AGC_PARAM_PROPERTIES:
+            pProperties->targetLevel =
+                    (int16_t)(effect->session->config.gain_controller1.target_level_dbfs * -100);
+            pProperties->compGain =
+                    (int16_t)(effect->session->config.gain_controller1.compression_gain_db * -100);
+            pProperties->limiterEnabled =
+                    (bool)(effect->session->config.gain_controller1.enable_limiter);
+            break;
+        default:
+            ALOGW("AgcGetParameter() unknown param %d", param);
+            status = -EINVAL;
+            break;
     }
     return status;
 }
 
-int AgcSetParameter (preproc_effect_t *effect, void *pParam, void *pValue)
-{
+int Agc2SetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
     int status = 0;
-    uint32_t param = *(uint32_t *)pParam;
-    t_agc_settings *pProperties = (t_agc_settings *)pValue;
-    webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
-
+    uint32_t param = *(uint32_t*)pParam;
+    float valueFloat = 0.f;
+    agc2_settings_t* pProperties = (agc2_settings_t*)pValue;
+    effect->session->config = effect->session->apm->GetConfig();
     switch (param) {
-    case AGC_PARAM_TARGET_LEVEL:
-        ALOGV("AgcSetParameter() target level %d milliBels", *(int16_t *)pValue);
-        status = agc->set_target_level_dbfs(-(*(int16_t *)pValue / 100));
-        break;
-    case AGC_PARAM_COMP_GAIN:
-        ALOGV("AgcSetParameter() comp gain %d milliBels", *(int16_t *)pValue);
-        status = agc->set_compression_gain_db(*(int16_t *)pValue / 100);
-        break;
-    case AGC_PARAM_LIMITER_ENA:
-        ALOGV("AgcSetParameter() limiter enabled %s", *(bool *)pValue ? "true" : "false");
-        status = agc->enable_limiter(*(bool *)pValue);
-        break;
-    case AGC_PARAM_PROPERTIES:
-        ALOGV("AgcSetParameter() properties level %d, gain %d limiter %d",
-             pProperties->targetLevel,
-             pProperties->compGain,
-             pProperties->limiterEnabled);
-        status = agc->set_target_level_dbfs(-(pProperties->targetLevel / 100));
-        if (status != 0) break;
-        status = agc->set_compression_gain_db(pProperties->compGain / 100);
-        if (status != 0) break;
-        status = agc->enable_limiter(pProperties->limiterEnabled);
-        break;
-    default:
-        ALOGW("AgcSetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
-        status = -EINVAL;
-        break;
+        case AGC2_PARAM_FIXED_DIGITAL_GAIN:
+            valueFloat = (float)(*(int32_t*)pValue);
+            ALOGV("Agc2SetParameter() fixed digital gain %f dB", valueFloat);
+            effect->session->config.gain_controller2.fixed_digital.gain_db = valueFloat;
+            break;
+        case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
+            ALOGV("Agc2SetParameter() level estimator %d",
+                  *(webrtc::AudioProcessing::Config::GainController2::LevelEstimator*)pValue);
+            effect->session->config.gain_controller2.adaptive_digital.level_estimator =
+                    (*(webrtc::AudioProcessing::Config::GainController2::LevelEstimator*)pValue);
+            break;
+        case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
+            valueFloat = (float)(*(int32_t*)pValue);
+            ALOGV("Agc2SetParameter() extra saturation margin %f dB", valueFloat);
+            effect->session->config.gain_controller2.adaptive_digital.extra_saturation_margin_db =
+                    valueFloat;
+            break;
+        case AGC2_PARAM_PROPERTIES:
+            ALOGV("Agc2SetParameter() properties gain %f, level %d margin %f",
+                  pProperties->fixedDigitalGain, pProperties->level_estimator,
+                  pProperties->extraSaturationMargin);
+            effect->session->config.gain_controller2.fixed_digital.gain_db =
+                    pProperties->fixedDigitalGain;
+            effect->session->config.gain_controller2.adaptive_digital.level_estimator =
+                    (webrtc::AudioProcessing::Config::GainController2::LevelEstimator)
+                            pProperties->level_estimator;
+            effect->session->config.gain_controller2.adaptive_digital.extra_saturation_margin_db =
+                    pProperties->extraSaturationMargin;
+            break;
+        default:
+            ALOGW("Agc2SetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
+            status = -EINVAL;
+            break;
     }
+    effect->session->apm->ApplyConfig(effect->session->config);
+
+    ALOGV("Agc2SetParameter() done status %d", status);
+
+    return status;
+}
+
+int AgcSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
+    int status = 0;
+    uint32_t param = *(uint32_t*)pParam;
+    t_agc_settings* pProperties = (t_agc_settings*)pValue;
+    effect->session->config = effect->session->apm->GetConfig();
+    switch (param) {
+        case AGC_PARAM_TARGET_LEVEL:
+            ALOGV("AgcSetParameter() target level %d milliBels", *(int16_t*)pValue);
+            effect->session->config.gain_controller1.target_level_dbfs =
+                    (-(*(int16_t*)pValue / 100));
+            break;
+        case AGC_PARAM_COMP_GAIN:
+            ALOGV("AgcSetParameter() comp gain %d milliBels", *(int16_t*)pValue);
+            effect->session->config.gain_controller1.compression_gain_db =
+                    (*(int16_t*)pValue / 100);
+            break;
+        case AGC_PARAM_LIMITER_ENA:
+            ALOGV("AgcSetParameter() limiter enabled %s", *(bool*)pValue ? "true" : "false");
+            effect->session->config.gain_controller1.enable_limiter = (*(bool*)pValue);
+            break;
+        case AGC_PARAM_PROPERTIES:
+            ALOGV("AgcSetParameter() properties level %d, gain %d limiter %d",
+                  pProperties->targetLevel, pProperties->compGain, pProperties->limiterEnabled);
+            effect->session->config.gain_controller1.target_level_dbfs =
+                    -(pProperties->targetLevel / 100);
+            effect->session->config.gain_controller1.compression_gain_db =
+                    pProperties->compGain / 100;
+            effect->session->config.gain_controller1.enable_limiter = pProperties->limiterEnabled;
+            break;
+        default:
+            ALOGW("AgcSetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
+            status = -EINVAL;
+            break;
+    }
+    effect->session->apm->ApplyConfig(effect->session->config);
 
     ALOGV("AgcSetParameter() done status %d", status);
 
     return status;
 }
 
-void AgcEnable(preproc_effect_t *effect)
-{
-    webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
-    ALOGV("AgcEnable agc %p", agc);
-    agc->Enable(true);
+void Agc2Enable(preproc_effect_t* effect) {
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.gain_controller2.enabled = true;
+    effect->session->apm->ApplyConfig(effect->session->config);
 }
 
-void AgcDisable(preproc_effect_t *effect)
-{
-    ALOGV("AgcDisable");
-    webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine);
-    agc->Enable(false);
+void AgcEnable(preproc_effect_t* effect) {
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.gain_controller1.enabled = true;
+    effect->session->apm->ApplyConfig(effect->session->config);
 }
 
+void Agc2Disable(preproc_effect_t* effect) {
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.gain_controller2.enabled = false;
+    effect->session->apm->ApplyConfig(effect->session->config);
+}
 
-static const preproc_ops_t sAgcOps = {
-        AgcCreate,
-        AgcInit,
-        NULL,
-        AgcEnable,
-        AgcDisable,
-        AgcSetParameter,
-        AgcGetParameter,
-        NULL
-};
+void AgcDisable(preproc_effect_t* effect) {
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.gain_controller1.enabled = false;
+    effect->session->apm->ApplyConfig(effect->session->config);
+}
 
+static const preproc_ops_t sAgcOps = {AgcCreate,       AgcInit,         NULL, AgcEnable, AgcDisable,
+                                      AgcSetParameter, AgcGetParameter, NULL};
+
+static const preproc_ops_t sAgc2Ops = {Agc2Create,       Agc2Init,    NULL,
+                                       Agc2Enable,       Agc2Disable, Agc2SetParameter,
+                                       Agc2GetParameter, NULL};
 
 //------------------------------------------------------------------------------
 // Acoustic Echo Canceler (AEC)
 //------------------------------------------------------------------------------
 
-static const webrtc::EchoControlMobile::RoutingMode kAecDefaultMode =
-        webrtc::EchoControlMobile::kEarpiece;
-static const bool kAecDefaultComfortNoise = true;
 
-int  AecInit (preproc_effect_t *effect)
-{
+int AecInit(preproc_effect_t* effect) {
     ALOGV("AecInit");
-    webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
-    aec->set_routing_mode(kAecDefaultMode);
-    aec->enable_comfort_noise(kAecDefaultComfortNoise);
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.echo_canceller.mobile_mode = true;
+    effect->session->apm->ApplyConfig(effect->session->config);
     return 0;
 }
 
-int  AecCreate(preproc_effect_t *effect)
-{
-    webrtc::EchoControlMobile *aec = effect->session->apm->echo_control_mobile();
-    ALOGV("AecCreate got aec %p", aec);
-    if (aec == NULL) {
-        ALOGW("AgcCreate Error");
-        return -ENOMEM;
-    }
-    effect->engine = static_cast<preproc_fx_handle_t>(aec);
-    AecInit (effect);
+int AecCreate(preproc_effect_t* effect) {
+    AecInit(effect);
     return 0;
 }
 
-int AecGetParameter(preproc_effect_t  *effect,
-                    void              *pParam,
-                    uint32_t          *pValueSize,
-                    void              *pValue)
-{
+int AecGetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
     int status = 0;
-    uint32_t param = *(uint32_t *)pParam;
+    uint32_t param = *(uint32_t*)pParam;
 
     if (*pValueSize < sizeof(uint32_t)) {
         return -EINVAL;
     }
     switch (param) {
-    case AEC_PARAM_ECHO_DELAY:
-    case AEC_PARAM_PROPERTIES:
-        *(uint32_t *)pValue = 1000 * effect->session->apm->stream_delay_ms();
-        ALOGV("AecGetParameter() echo delay %d us", *(uint32_t *)pValue);
-        break;
-    default:
-        ALOGW("AecGetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
-        status = -EINVAL;
-        break;
+        case AEC_PARAM_ECHO_DELAY:
+        case AEC_PARAM_PROPERTIES:
+            *(uint32_t*)pValue = 1000 * effect->session->apm->stream_delay_ms();
+            ALOGV("AecGetParameter() echo delay %d us", *(uint32_t*)pValue);
+            break;
+        case AEC_PARAM_MOBILE_MODE:
+            effect->session->config = effect->session->apm->GetConfig();
+            *(uint32_t*)pValue = effect->session->config.echo_canceller.mobile_mode;
+            ALOGV("AecGetParameter() mobile mode %d us", *(uint32_t*)pValue);
+            break;
+        default:
+            ALOGW("AecGetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
+            status = -EINVAL;
+            break;
     }
     return status;
 }
 
-int AecSetParameter (preproc_effect_t *effect, void *pParam, void *pValue)
-{
+int AecSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
     int status = 0;
-    uint32_t param = *(uint32_t *)pParam;
-    uint32_t value = *(uint32_t *)pValue;
+    uint32_t param = *(uint32_t*)pParam;
+    uint32_t value = *(uint32_t*)pValue;
 
     switch (param) {
-    case AEC_PARAM_ECHO_DELAY:
-    case AEC_PARAM_PROPERTIES:
-        status = effect->session->apm->set_stream_delay_ms(value/1000);
-        ALOGV("AecSetParameter() echo delay %d us, status %d", value, status);
-        break;
-    default:
-        ALOGW("AecSetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue);
-        status = -EINVAL;
-        break;
+        case AEC_PARAM_ECHO_DELAY:
+        case AEC_PARAM_PROPERTIES:
+            status = effect->session->apm->set_stream_delay_ms(value / 1000);
+            ALOGV("AecSetParameter() echo delay %d us, status %d", value, status);
+            break;
+        case AEC_PARAM_MOBILE_MODE:
+            effect->session->config = effect->session->apm->GetConfig();
+            effect->session->config.echo_canceller.mobile_mode = value;
+            ALOGV("AecSetParameter() mobile mode %d us", value);
+            effect->session->apm->ApplyConfig(effect->session->config);
+            break;
+        default:
+            ALOGW("AecSetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
+            status = -EINVAL;
+            break;
     }
     return status;
 }
 
-void AecEnable(preproc_effect_t *effect)
-{
-    webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
-    ALOGV("AecEnable aec %p", aec);
-    aec->Enable(true);
+void AecEnable(preproc_effect_t* effect) {
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.echo_canceller.enabled = true;
+    effect->session->apm->ApplyConfig(effect->session->config);
 }
 
-void AecDisable(preproc_effect_t *effect)
-{
-    ALOGV("AecDisable");
-    webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
-    aec->Enable(false);
+void AecDisable(preproc_effect_t* effect) {
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.echo_canceller.enabled = false;
+    effect->session->apm->ApplyConfig(effect->session->config);
 }
 
-int AecSetDevice(preproc_effect_t *effect, uint32_t device)
-{
+int AecSetDevice(preproc_effect_t* effect, uint32_t device) {
     ALOGV("AecSetDevice %08x", device);
-    webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine);
-    webrtc::EchoControlMobile::RoutingMode mode = webrtc::EchoControlMobile::kQuietEarpieceOrHeadset;
 
     if (audio_is_input_device(device)) {
         return 0;
     }
 
-    switch(device) {
-    case AUDIO_DEVICE_OUT_EARPIECE:
-        mode = webrtc::EchoControlMobile::kEarpiece;
-        break;
-    case AUDIO_DEVICE_OUT_SPEAKER:
-        mode = webrtc::EchoControlMobile::kSpeakerphone;
-        break;
-    case AUDIO_DEVICE_OUT_WIRED_HEADSET:
-    case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
-    case AUDIO_DEVICE_OUT_USB_HEADSET:
-    default:
-        break;
-    }
-    aec->set_routing_mode(mode);
     return 0;
 }
 
-static const preproc_ops_t sAecOps = {
-        AecCreate,
-        AecInit,
-        NULL,
-        AecEnable,
-        AecDisable,
-        AecSetParameter,
-        AecGetParameter,
-        AecSetDevice
-};
+static const preproc_ops_t sAecOps = {AecCreate,       AecInit,     NULL,
+                                      AecEnable,       AecDisable,  AecSetParameter,
+                                      AecGetParameter, AecSetDevice};
 
 //------------------------------------------------------------------------------
 // Noise Suppression (NS)
 //------------------------------------------------------------------------------
 
-static const webrtc::NoiseSuppression::Level kNsDefaultLevel = webrtc::NoiseSuppression::kModerate;
+static const webrtc::AudioProcessing::Config::NoiseSuppression::Level kNsDefaultLevel =
+        webrtc::AudioProcessing::Config::NoiseSuppression::kModerate;
 
-int  NsInit (preproc_effect_t *effect)
-{
+int NsInit(preproc_effect_t* effect) {
     ALOGV("NsInit");
-    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
-    ns->set_level(kNsDefaultLevel);
-    webrtc::Config config;
-    std::vector<webrtc::Point> geometry;
-    // TODO(aluebs): Make the geometry settable.
-    geometry.push_back(webrtc::Point(-0.03f, 0.f, 0.f));
-    geometry.push_back(webrtc::Point(-0.01f, 0.f, 0.f));
-    geometry.push_back(webrtc::Point(0.01f, 0.f, 0.f));
-    geometry.push_back(webrtc::Point(0.03f, 0.f, 0.f));
-    // The geometry needs to be set with Beamforming enabled.
-    config.Set<webrtc::Beamforming>(
-            new webrtc::Beamforming(true, geometry));
-    effect->session->apm->SetExtraOptions(config);
-    config.Set<webrtc::Beamforming>(
-            new webrtc::Beamforming(false, geometry));
-    effect->session->apm->SetExtraOptions(config);
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.noise_suppression.level = kNsDefaultLevel;
+    effect->session->apm->ApplyConfig(effect->session->config);
     effect->type = NS_TYPE_SINGLE_CHANNEL;
     return 0;
 }
 
-int  NsCreate(preproc_effect_t *effect)
-{
-    webrtc::NoiseSuppression *ns = effect->session->apm->noise_suppression();
-    ALOGV("NsCreate got ns %p", ns);
-    if (ns == NULL) {
-        ALOGW("AgcCreate Error");
-        return -ENOMEM;
-    }
-    effect->engine = static_cast<preproc_fx_handle_t>(ns);
-    NsInit (effect);
+int NsCreate(preproc_effect_t* effect) {
+    NsInit(effect);
     return 0;
 }
 
-int NsGetParameter(preproc_effect_t  *effect __unused,
-                   void              *pParam __unused,
-                   uint32_t          *pValueSize __unused,
-                   void              *pValue __unused)
-{
+int NsGetParameter(preproc_effect_t* effect __unused, void* pParam __unused,
+                   uint32_t* pValueSize __unused, void* pValue __unused) {
     int status = 0;
     return status;
 }
 
-int NsSetParameter (preproc_effect_t *effect, void *pParam, void *pValue)
-{
+int NsSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
     int status = 0;
-    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
-    uint32_t param = *(uint32_t *)pParam;
-    uint32_t value = *(uint32_t *)pValue;
-    switch(param) {
+    uint32_t param = *(uint32_t*)pParam;
+    uint32_t value = *(uint32_t*)pValue;
+    effect->session->config = effect->session->apm->GetConfig();
+    switch (param) {
         case NS_PARAM_LEVEL:
-            ns->set_level((webrtc::NoiseSuppression::Level)value);
+            effect->session->config.noise_suppression.level =
+                    (webrtc::AudioProcessing::Config::NoiseSuppression::Level)value;
             ALOGV("NsSetParameter() level %d", value);
             break;
-        case NS_PARAM_TYPE:
-        {
-            webrtc::Config config;
-            std::vector<webrtc::Point> geometry;
-            bool is_beamforming_enabled =
-                    value == NS_TYPE_MULTI_CHANNEL && ns->is_enabled();
-            config.Set<webrtc::Beamforming>(
-                    new webrtc::Beamforming(is_beamforming_enabled, geometry));
-            effect->session->apm->SetExtraOptions(config);
-            effect->type = value;
-            ALOGV("NsSetParameter() type %d", value);
-            break;
-        }
         default:
             ALOGW("NsSetParameter() unknown param %08x value %08x", param, value);
             status = -EINVAL;
     }
+    effect->session->apm->ApplyConfig(effect->session->config);
 
     return status;
 }
 
-void NsEnable(preproc_effect_t *effect)
-{
-    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
-    ALOGV("NsEnable ns %p", ns);
-    ns->Enable(true);
-    if (effect->type == NS_TYPE_MULTI_CHANNEL) {
-        webrtc::Config config;
-        std::vector<webrtc::Point> geometry;
-        config.Set<webrtc::Beamforming>(new webrtc::Beamforming(true, geometry));
-        effect->session->apm->SetExtraOptions(config);
-    }
+void NsEnable(preproc_effect_t* effect) {
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.noise_suppression.enabled = true;
+    effect->session->apm->ApplyConfig(effect->session->config);
 }
 
-void NsDisable(preproc_effect_t *effect)
-{
+void NsDisable(preproc_effect_t* effect) {
     ALOGV("NsDisable");
-    webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine);
-    ns->Enable(false);
-    webrtc::Config config;
-    std::vector<webrtc::Point> geometry;
-    config.Set<webrtc::Beamforming>(new webrtc::Beamforming(false, geometry));
-    effect->session->apm->SetExtraOptions(config);
+    effect->session->config = effect->session->apm->GetConfig();
+    effect->session->config.noise_suppression.enabled = false;
+    effect->session->apm->ApplyConfig(effect->session->config);
 }
 
-static const preproc_ops_t sNsOps = {
-        NsCreate,
-        NsInit,
-        NULL,
-        NsEnable,
-        NsDisable,
-        NsSetParameter,
-        NsGetParameter,
-        NULL
-};
+static const preproc_ops_t sNsOps = {NsCreate,  NsInit,         NULL,           NsEnable,
+                                     NsDisable, NsSetParameter, NsGetParameter, NULL};
 
-
-static const preproc_ops_t *sPreProcOps[PREPROC_NUM_EFFECTS] = {
-        &sAgcOps,
-        &sAecOps,
-        &sNsOps
-};
-
+static const preproc_ops_t* sPreProcOps[PREPROC_NUM_EFFECTS] = {&sAgcOps,
+                                                                &sAgc2Ops,
+                                                                &sAecOps, &sNsOps};
 
 //------------------------------------------------------------------------------
 // Effect functions
 //------------------------------------------------------------------------------
 
-void Session_SetProcEnabled(preproc_session_t *session, uint32_t procId, bool enabled);
+void Session_SetProcEnabled(preproc_session_t* session, uint32_t procId, bool enabled);
 
 extern "C" const struct effect_interface_s sEffectInterface;
 extern "C" const struct effect_interface_s sEffectInterfaceReverse;
 
-#define BAD_STATE_ABORT(from, to) \
-        LOG_ALWAYS_FATAL("Bad state transition from %d to %d", from, to);
+#define BAD_STATE_ABORT(from, to) LOG_ALWAYS_FATAL("Bad state transition from %d to %d", from, to);
 
-int Effect_SetState(preproc_effect_t *effect, uint32_t state)
-{
+int Effect_SetState(preproc_effect_t* effect, uint32_t state) {
     int status = 0;
     ALOGV("Effect_SetState proc %d, new %d old %d", effect->procId, state, effect->state);
-    switch(state) {
-    case PREPROC_EFFECT_STATE_INIT:
-        switch(effect->state) {
-        case PREPROC_EFFECT_STATE_ACTIVE:
-            effect->ops->disable(effect);
-            Session_SetProcEnabled(effect->session, effect->procId, false);
+    switch (state) {
+        case PREPROC_EFFECT_STATE_INIT:
+            switch (effect->state) {
+                case PREPROC_EFFECT_STATE_ACTIVE:
+                    effect->ops->disable(effect);
+                    Session_SetProcEnabled(effect->session, effect->procId, false);
+                    break;
+                case PREPROC_EFFECT_STATE_CONFIG:
+                case PREPROC_EFFECT_STATE_CREATED:
+                case PREPROC_EFFECT_STATE_INIT:
+                    break;
+                default:
+                    BAD_STATE_ABORT(effect->state, state);
+            }
+            break;
+        case PREPROC_EFFECT_STATE_CREATED:
+            switch (effect->state) {
+                case PREPROC_EFFECT_STATE_INIT:
+                    status = effect->ops->create(effect);
+                    break;
+                case PREPROC_EFFECT_STATE_CREATED:
+                case PREPROC_EFFECT_STATE_ACTIVE:
+                case PREPROC_EFFECT_STATE_CONFIG:
+                    ALOGE("Effect_SetState invalid transition");
+                    status = -ENOSYS;
+                    break;
+                default:
+                    BAD_STATE_ABORT(effect->state, state);
+            }
             break;
         case PREPROC_EFFECT_STATE_CONFIG:
-        case PREPROC_EFFECT_STATE_CREATED:
-        case PREPROC_EFFECT_STATE_INIT:
+            switch (effect->state) {
+                case PREPROC_EFFECT_STATE_INIT:
+                    ALOGE("Effect_SetState invalid transition");
+                    status = -ENOSYS;
+                    break;
+                case PREPROC_EFFECT_STATE_ACTIVE:
+                    effect->ops->disable(effect);
+                    Session_SetProcEnabled(effect->session, effect->procId, false);
+                    break;
+                case PREPROC_EFFECT_STATE_CREATED:
+                case PREPROC_EFFECT_STATE_CONFIG:
+                    break;
+                default:
+                    BAD_STATE_ABORT(effect->state, state);
+            }
+            break;
+        case PREPROC_EFFECT_STATE_ACTIVE:
+            switch (effect->state) {
+                case PREPROC_EFFECT_STATE_INIT:
+                case PREPROC_EFFECT_STATE_CREATED:
+                    ALOGE("Effect_SetState invalid transition");
+                    status = -ENOSYS;
+                    break;
+                case PREPROC_EFFECT_STATE_ACTIVE:
+                    // enabling an already enabled effect is just ignored
+                    break;
+                case PREPROC_EFFECT_STATE_CONFIG:
+                    effect->ops->enable(effect);
+                    Session_SetProcEnabled(effect->session, effect->procId, true);
+                    break;
+                default:
+                    BAD_STATE_ABORT(effect->state, state);
+            }
             break;
         default:
             BAD_STATE_ABORT(effect->state, state);
-        }
-        break;
-    case PREPROC_EFFECT_STATE_CREATED:
-        switch(effect->state) {
-        case PREPROC_EFFECT_STATE_INIT:
-            status = effect->ops->create(effect);
-            break;
-        case PREPROC_EFFECT_STATE_CREATED:
-        case PREPROC_EFFECT_STATE_ACTIVE:
-        case PREPROC_EFFECT_STATE_CONFIG:
-            ALOGE("Effect_SetState invalid transition");
-            status = -ENOSYS;
-            break;
-        default:
-            BAD_STATE_ABORT(effect->state, state);
-        }
-        break;
-    case PREPROC_EFFECT_STATE_CONFIG:
-        switch(effect->state) {
-        case PREPROC_EFFECT_STATE_INIT:
-            ALOGE("Effect_SetState invalid transition");
-            status = -ENOSYS;
-            break;
-        case PREPROC_EFFECT_STATE_ACTIVE:
-            effect->ops->disable(effect);
-            Session_SetProcEnabled(effect->session, effect->procId, false);
-            break;
-        case PREPROC_EFFECT_STATE_CREATED:
-        case PREPROC_EFFECT_STATE_CONFIG:
-            break;
-        default:
-            BAD_STATE_ABORT(effect->state, state);
-        }
-        break;
-    case PREPROC_EFFECT_STATE_ACTIVE:
-        switch(effect->state) {
-        case PREPROC_EFFECT_STATE_INIT:
-        case PREPROC_EFFECT_STATE_CREATED:
-            ALOGE("Effect_SetState invalid transition");
-            status = -ENOSYS;
-            break;
-        case PREPROC_EFFECT_STATE_ACTIVE:
-            // enabling an already enabled effect is just ignored
-            break;
-        case PREPROC_EFFECT_STATE_CONFIG:
-            effect->ops->enable(effect);
-            Session_SetProcEnabled(effect->session, effect->procId, true);
-            break;
-        default:
-            BAD_STATE_ABORT(effect->state, state);
-        }
-        break;
-    default:
-        BAD_STATE_ABORT(effect->state, state);
     }
     if (status == 0) {
         effect->state = state;
@@ -766,8 +804,7 @@
     return status;
 }
 
-int Effect_Init(preproc_effect_t *effect, uint32_t procId)
-{
+int Effect_Init(preproc_effect_t* effect, uint32_t procId) {
     if (HasReverseStream(procId)) {
         effect->itfe = &sEffectInterfaceReverse;
     } else {
@@ -779,21 +816,17 @@
     return 0;
 }
 
-int Effect_Create(preproc_effect_t *effect,
-               preproc_session_t *session,
-               effect_handle_t  *interface)
-{
+int Effect_Create(preproc_effect_t* effect, preproc_session_t* session,
+                  effect_handle_t* interface) {
     effect->session = session;
     *interface = (effect_handle_t)&effect->itfe;
     return Effect_SetState(effect, PREPROC_EFFECT_STATE_CREATED);
 }
 
-int Effect_Release(preproc_effect_t *effect)
-{
+int Effect_Release(preproc_effect_t* effect) {
     return Effect_SetState(effect, PREPROC_EFFECT_STATE_INIT);
 }
 
-
 //------------------------------------------------------------------------------
 // Session functions
 //------------------------------------------------------------------------------
@@ -803,8 +836,7 @@
 static const int kPreprocDefaultSr = 16000;
 static const int kPreProcDefaultCnl = 1;
 
-int Session_Init(preproc_session_t *session)
-{
+int Session_Init(preproc_session_t* session) {
     size_t i;
     int status = 0;
 
@@ -812,66 +844,45 @@
     session->id = 0;
     session->io = 0;
     session->createdMsk = 0;
-    session->apm = NULL;
     for (i = 0; i < PREPROC_NUM_EFFECTS && status == 0; i++) {
         status = Effect_Init(&session->effects[i], i);
     }
     return status;
 }
 
-
-extern "C" int Session_CreateEffect(preproc_session_t *session,
-                                    int32_t procId,
-                                    effect_handle_t  *interface)
-{
+extern "C" int Session_CreateEffect(preproc_session_t* session, int32_t procId,
+                                    effect_handle_t* interface) {
     int status = -ENOMEM;
 
     ALOGV("Session_CreateEffect procId %d, createdMsk %08x", procId, session->createdMsk);
 
     if (session->createdMsk == 0) {
-        session->apm = webrtc::AudioProcessing::Create();
+        session->apm = session->ap_builder.Create();
         if (session->apm == NULL) {
             ALOGW("Session_CreateEffect could not get apm engine");
             goto error;
         }
-        const webrtc::ProcessingConfig processing_config = {
-            {{kPreprocDefaultSr, kPreProcDefaultCnl},
-             {kPreprocDefaultSr, kPreProcDefaultCnl},
-             {kPreprocDefaultSr, kPreProcDefaultCnl},
-             {kPreprocDefaultSr, kPreProcDefaultCnl}}};
-        session->apm->Initialize(processing_config);
-        session->procFrame = new webrtc::AudioFrame();
-        if (session->procFrame == NULL) {
-            ALOGW("Session_CreateEffect could not allocate audio frame");
-            goto error;
-        }
-        session->revFrame = new webrtc::AudioFrame();
-        if (session->revFrame == NULL) {
-            ALOGW("Session_CreateEffect could not allocate reverse audio frame");
-            goto error;
-        }
         session->apmSamplingRate = kPreprocDefaultSr;
         session->apmFrameCount = (kPreprocDefaultSr) / 100;
         session->frameCount = session->apmFrameCount;
         session->samplingRate = kPreprocDefaultSr;
         session->inChannelCount = kPreProcDefaultCnl;
         session->outChannelCount = kPreProcDefaultCnl;
-        session->procFrame->sample_rate_hz_ = kPreprocDefaultSr;
-        session->procFrame->num_channels_ = kPreProcDefaultCnl;
+        session->inputConfig.set_sample_rate_hz(kPreprocDefaultSr);
+        session->inputConfig.set_num_channels(kPreProcDefaultCnl);
+        session->outputConfig.set_sample_rate_hz(kPreprocDefaultSr);
+        session->outputConfig.set_num_channels(kPreProcDefaultCnl);
         session->revChannelCount = kPreProcDefaultCnl;
-        session->revFrame->sample_rate_hz_ = kPreprocDefaultSr;
-        session->revFrame->num_channels_ = kPreProcDefaultCnl;
+        session->revConfig.set_sample_rate_hz(kPreprocDefaultSr);
+        session->revConfig.set_num_channels(kPreProcDefaultCnl);
         session->enabledMsk = 0;
         session->processedMsk = 0;
         session->revEnabledMsk = 0;
         session->revProcessedMsk = 0;
-        session->inResampler = NULL;
         session->inBuf = NULL;
         session->inBufSize = 0;
-        session->outResampler = NULL;
         session->outBuf = NULL;
         session->outBufSize = 0;
-        session->revResampler = NULL;
         session->revBuf = NULL;
         session->revBufSize = 0;
     }
@@ -880,45 +891,23 @@
         goto error;
     }
     ALOGV("Session_CreateEffect OK");
-    session->createdMsk |= (1<<procId);
+    session->createdMsk |= (1 << procId);
     return status;
 
 error:
     if (session->createdMsk == 0) {
-        delete session->revFrame;
-        session->revFrame = NULL;
-        delete session->procFrame;
-        session->procFrame = NULL;
         delete session->apm;
-        session->apm = NULL; // NOLINT(clang-analyzer-cplusplus.NewDelete)
+        session->apm = NULL;
     }
     return status;
 }
 
-int Session_ReleaseEffect(preproc_session_t *session,
-                          preproc_effect_t *fx)
-{
+int Session_ReleaseEffect(preproc_session_t* session, preproc_effect_t* fx) {
     ALOGW_IF(Effect_Release(fx) != 0, " Effect_Release() failed for proc ID %d", fx->procId);
-    session->createdMsk &= ~(1<<fx->procId);
+    session->createdMsk &= ~(1 << fx->procId);
     if (session->createdMsk == 0) {
         delete session->apm;
         session->apm = NULL;
-        delete session->procFrame;
-        session->procFrame = NULL;
-        delete session->revFrame;
-        session->revFrame = NULL;
-        if (session->inResampler != NULL) {
-            speex_resampler_destroy(session->inResampler);
-            session->inResampler = NULL;
-        }
-        if (session->outResampler != NULL) {
-            speex_resampler_destroy(session->outResampler);
-            session->outResampler = NULL;
-        }
-        if (session->revResampler != NULL) {
-            speex_resampler_destroy(session->revResampler);
-            session->revResampler = NULL;
-        }
         delete session->inBuf;
         session->inBuf = NULL;
         delete session->outBuf;
@@ -932,9 +921,7 @@
     return 0;
 }
 
-
-int Session_SetConfig(preproc_session_t *session, effect_config_t *config)
-{
+int Session_SetConfig(preproc_session_t* session, effect_config_t* config) {
     uint32_t inCnl = audio_channel_count_from_in_mask(config->inputCfg.channels);
     uint32_t outCnl = audio_channel_count_from_in_mask(config->outputCfg.channels);
 
@@ -944,46 +931,37 @@
         return -EINVAL;
     }
 
-    ALOGV("Session_SetConfig sr %d cnl %08x",
-         config->inputCfg.samplingRate, config->inputCfg.channels);
-    int status;
+    ALOGV("Session_SetConfig sr %d cnl %08x", config->inputCfg.samplingRate,
+          config->inputCfg.channels);
 
     // AEC implementation is limited to 16kHz
     if (config->inputCfg.samplingRate >= 32000 && !(session->createdMsk & (1 << PREPROC_AEC))) {
         session->apmSamplingRate = 32000;
-    } else
-    if (config->inputCfg.samplingRate >= 16000) {
+    } else if (config->inputCfg.samplingRate >= 16000) {
         session->apmSamplingRate = 16000;
     } else if (config->inputCfg.samplingRate >= 8000) {
         session->apmSamplingRate = 8000;
     }
 
-    const webrtc::ProcessingConfig processing_config = {
-      {{static_cast<int>(session->apmSamplingRate), inCnl},
-       {static_cast<int>(session->apmSamplingRate), outCnl},
-       {static_cast<int>(session->apmSamplingRate), inCnl},
-       {static_cast<int>(session->apmSamplingRate), inCnl}}};
-    status = session->apm->Initialize(processing_config);
-    if (status < 0) {
-        return -EINVAL;
-    }
 
     session->samplingRate = config->inputCfg.samplingRate;
     session->apmFrameCount = session->apmSamplingRate / 100;
     if (session->samplingRate == session->apmSamplingRate) {
         session->frameCount = session->apmFrameCount;
     } else {
-        session->frameCount = (session->apmFrameCount * session->samplingRate) /
-                session->apmSamplingRate  + 1;
+        session->frameCount =
+                (session->apmFrameCount * session->samplingRate) / session->apmSamplingRate;
     }
     session->inChannelCount = inCnl;
     session->outChannelCount = outCnl;
-    session->procFrame->num_channels_ = inCnl;
-    session->procFrame->sample_rate_hz_ = session->apmSamplingRate;
+    session->inputConfig.set_sample_rate_hz(session->samplingRate);
+    session->inputConfig.set_num_channels(inCnl);
+    session->outputConfig.set_sample_rate_hz(session->samplingRate);
+    session->outputConfig.set_num_channels(inCnl);
 
     session->revChannelCount = inCnl;
-    session->revFrame->num_channels_ = inCnl;
-    session->revFrame->sample_rate_hz_ = session->apmSamplingRate;
+    session->revConfig.set_sample_rate_hz(session->samplingRate);
+    session->revConfig.set_num_channels(inCnl);
 
     // force process buffer reallocation
     session->inBufSize = 0;
@@ -992,64 +970,11 @@
     session->framesOut = 0;
 
 
-    if (session->inResampler != NULL) {
-        speex_resampler_destroy(session->inResampler);
-        session->inResampler = NULL;
-    }
-    if (session->outResampler != NULL) {
-        speex_resampler_destroy(session->outResampler);
-        session->outResampler = NULL;
-    }
-    if (session->revResampler != NULL) {
-        speex_resampler_destroy(session->revResampler);
-        session->revResampler = NULL;
-    }
-    if (session->samplingRate != session->apmSamplingRate) {
-        int error;
-        session->inResampler = speex_resampler_init(session->inChannelCount,
-                                                    session->samplingRate,
-                                                    session->apmSamplingRate,
-                                                    RESAMPLER_QUALITY,
-                                                    &error);
-        if (session->inResampler == NULL) {
-            ALOGW("Session_SetConfig Cannot create speex resampler: %s",
-                 speex_resampler_strerror(error));
-            return -EINVAL;
-        }
-        session->outResampler = speex_resampler_init(session->outChannelCount,
-                                                    session->apmSamplingRate,
-                                                    session->samplingRate,
-                                                    RESAMPLER_QUALITY,
-                                                    &error);
-        if (session->outResampler == NULL) {
-            ALOGW("Session_SetConfig Cannot create speex resampler: %s",
-                 speex_resampler_strerror(error));
-            speex_resampler_destroy(session->inResampler);
-            session->inResampler = NULL;
-            return -EINVAL;
-        }
-        session->revResampler = speex_resampler_init(session->inChannelCount,
-                                                    session->samplingRate,
-                                                    session->apmSamplingRate,
-                                                    RESAMPLER_QUALITY,
-                                                    &error);
-        if (session->revResampler == NULL) {
-            ALOGW("Session_SetConfig Cannot create speex resampler: %s",
-                 speex_resampler_strerror(error));
-            speex_resampler_destroy(session->inResampler);
-            session->inResampler = NULL;
-            speex_resampler_destroy(session->outResampler);
-            session->outResampler = NULL;
-            return -EINVAL;
-        }
-    }
-
     session->state = PREPROC_SESSION_STATE_CONFIG;
     return 0;
 }
 
-void Session_GetConfig(preproc_session_t *session, effect_config_t *config)
-{
+void Session_GetConfig(preproc_session_t* session, effect_config_t* config) {
     memset(config, 0, sizeof(effect_config_t));
     config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate;
     config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
@@ -1060,37 +985,25 @@
             (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT);
 }
 
-int Session_SetReverseConfig(preproc_session_t *session, effect_config_t *config)
-{
+int Session_SetReverseConfig(preproc_session_t* session, effect_config_t* config) {
     if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
-            config->inputCfg.format != config->outputCfg.format ||
-            config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
+        config->inputCfg.format != config->outputCfg.format ||
+        config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
         return -EINVAL;
     }
 
-    ALOGV("Session_SetReverseConfig sr %d cnl %08x",
-         config->inputCfg.samplingRate, config->inputCfg.channels);
+    ALOGV("Session_SetReverseConfig sr %d cnl %08x", config->inputCfg.samplingRate,
+          config->inputCfg.channels);
 
     if (session->state < PREPROC_SESSION_STATE_CONFIG) {
         return -ENOSYS;
     }
     if (config->inputCfg.samplingRate != session->samplingRate ||
-            config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
+        config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
         return -EINVAL;
     }
     uint32_t inCnl = audio_channel_count_from_out_mask(config->inputCfg.channels);
-    const webrtc::ProcessingConfig processing_config = {
-       {{static_cast<int>(session->apmSamplingRate), session->inChannelCount},
-        {static_cast<int>(session->apmSamplingRate), session->outChannelCount},
-        {static_cast<int>(session->apmSamplingRate), inCnl},
-        {static_cast<int>(session->apmSamplingRate), inCnl}}};
-    int status = session->apm->Initialize(processing_config);
-    if (status < 0) {
-        return -EINVAL;
-    }
     session->revChannelCount = inCnl;
-    session->revFrame->num_channels_ = inCnl;
-    session->revFrame->sample_rate_hz_ = session->apmSamplingRate;
     // force process buffer reallocation
     session->revBufSize = 0;
     session->framesRev = 0;
@@ -1098,8 +1011,7 @@
     return 0;
 }
 
-void Session_GetReverseConfig(preproc_session_t *session, effect_config_t *config)
-{
+void Session_GetReverseConfig(preproc_session_t* session, effect_config_t* config) {
     memset(config, 0, sizeof(effect_config_t));
     config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate;
     config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
@@ -1109,25 +1021,14 @@
             (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT);
 }
 
-void Session_SetProcEnabled(preproc_session_t *session, uint32_t procId, bool enabled)
-{
+void Session_SetProcEnabled(preproc_session_t* session, uint32_t procId, bool enabled) {
     if (enabled) {
-        if(session->enabledMsk == 0) {
+        if (session->enabledMsk == 0) {
             session->framesIn = 0;
-            if (session->inResampler != NULL) {
-                speex_resampler_reset_mem(session->inResampler);
-            }
-            session->framesOut = 0;
-            if (session->outResampler != NULL) {
-                speex_resampler_reset_mem(session->outResampler);
-            }
         }
         session->enabledMsk |= (1 << procId);
         if (HasReverseStream(procId)) {
             session->framesRev = 0;
-            if (session->revResampler != NULL) {
-                speex_resampler_reset_mem(session->revResampler);
-            }
             session->revEnabledMsk |= (1 << procId);
         }
     } else {
@@ -1136,8 +1037,8 @@
             session->revEnabledMsk &= ~(1 << procId);
         }
     }
-    ALOGV("Session_SetProcEnabled proc %d, enabled %d enabledMsk %08x revEnabledMsk %08x",
-         procId, enabled, session->enabledMsk, session->revEnabledMsk);
+    ALOGV("Session_SetProcEnabled proc %d, enabled %d enabledMsk %08x revEnabledMsk %08x", procId,
+          enabled, session->enabledMsk, session->revEnabledMsk);
     session->processedMsk = 0;
     if (HasReverseStream(procId)) {
         session->revProcessedMsk = 0;
@@ -1151,8 +1052,7 @@
 static int sInitStatus = 1;
 static preproc_session_t sSessions[PREPROC_NUM_SESSIONS];
 
-preproc_session_t *PreProc_GetSession(int32_t procId, int32_t  sessionId, int32_t  ioId)
-{
+preproc_session_t* PreProc_GetSession(int32_t procId, int32_t sessionId, int32_t ioId) {
     size_t i;
     for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
         if (sSessions[i].id == sessionId) {
@@ -1172,7 +1072,6 @@
     return NULL;
 }
 
-
 int PreProc_Init() {
     size_t i;
     int status = 0;
@@ -1187,8 +1086,7 @@
     return sInitStatus;
 }
 
-const effect_descriptor_t *PreProc_GetDescriptor(const effect_uuid_t *uuid)
-{
+const effect_descriptor_t* PreProc_GetDescriptor(const effect_uuid_t* uuid) {
     size_t i;
     for (i = 0; i < PREPROC_NUM_EFFECTS; i++) {
         if (memcmp(&sDescriptors[i]->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
@@ -1198,35 +1096,31 @@
     return NULL;
 }
 
-
 extern "C" {
 
 //------------------------------------------------------------------------------
 // Effect Control Interface Implementation
 //------------------------------------------------------------------------------
 
-int PreProcessingFx_Process(effect_handle_t     self,
-                            audio_buffer_t    *inBuffer,
-                            audio_buffer_t    *outBuffer)
-{
-    preproc_effect_t * effect = (preproc_effect_t *)self;
+int PreProcessingFx_Process(effect_handle_t self, audio_buffer_t* inBuffer,
+                            audio_buffer_t* outBuffer) {
+    preproc_effect_t* effect = (preproc_effect_t*)self;
 
-    if (effect == NULL){
+    if (effect == NULL) {
         ALOGV("PreProcessingFx_Process() ERROR effect == NULL");
         return -EINVAL;
     }
-    preproc_session_t * session = (preproc_session_t *)effect->session;
+    preproc_session_t* session = (preproc_session_t*)effect->session;
 
-    if (inBuffer == NULL  || inBuffer->raw == NULL  ||
-            outBuffer == NULL || outBuffer->raw == NULL){
+    if (inBuffer == NULL || inBuffer->raw == NULL || outBuffer == NULL || outBuffer->raw == NULL) {
         ALOGW("PreProcessingFx_Process() ERROR bad pointer");
         return -EINVAL;
     }
 
-    session->processedMsk |= (1<<effect->procId);
+    session->processedMsk |= (1 << effect->procId);
 
-//    ALOGV("PreProcessingFx_Process In %d frames enabledMsk %08x processedMsk %08x",
-//         inBuffer->frameCount, session->enabledMsk, session->processedMsk);
+    //    ALOGV("PreProcessingFx_Process In %d frames enabledMsk %08x processedMsk %08x",
+    //         inBuffer->frameCount, session->enabledMsk, session->processedMsk);
 
     if ((session->processedMsk & session->enabledMsk) == session->enabledMsk) {
         effect->session->processedMsk = 0;
@@ -1237,11 +1131,9 @@
             if (outBuffer->frameCount < fr) {
                 fr = outBuffer->frameCount;
             }
-            memcpy(outBuffer->s16,
-                  session->outBuf,
-                  fr * session->outChannelCount * sizeof(int16_t));
-            memmove(session->outBuf,
-                    session->outBuf + fr * session->outChannelCount,
+            memcpy(outBuffer->s16, session->outBuf,
+                   fr * session->outChannelCount * sizeof(int16_t));
+            memmove(session->outBuf, session->outBuf + fr * session->outChannelCount,
                     (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
             session->framesOut -= fr;
             framesWr += fr;
@@ -1252,95 +1144,33 @@
             return 0;
         }
 
-        if (session->inResampler != NULL) {
-            size_t fr = session->frameCount - session->framesIn;
-            if (inBuffer->frameCount < fr) {
-                fr = inBuffer->frameCount;
-            }
-            if (session->inBufSize < session->framesIn + fr) {
-                int16_t *buf;
-                session->inBufSize = session->framesIn + fr;
-                buf = (int16_t *)realloc(session->inBuf,
-                                 session->inBufSize * session->inChannelCount * sizeof(int16_t));
-                if (buf == NULL) {
-                    session->framesIn = 0;
-                    free(session->inBuf);
-                    session->inBuf = NULL;
-                    return -ENOMEM;
-                }
-                session->inBuf = buf;
-            }
-            memcpy(session->inBuf + session->framesIn * session->inChannelCount,
-                   inBuffer->s16,
-                   fr * session->inChannelCount * sizeof(int16_t));
-#ifdef DUAL_MIC_TEST
-            pthread_mutex_lock(&gPcmDumpLock);
-            if (gPcmDumpFh != NULL) {
-                fwrite(inBuffer->raw,
-                       fr * session->inChannelCount * sizeof(int16_t), 1, gPcmDumpFh);
-            }
-            pthread_mutex_unlock(&gPcmDumpLock);
-#endif
-
-            session->framesIn += fr;
-            inBuffer->frameCount = fr;
-            if (session->framesIn < session->frameCount) {
-                return 0;
-            }
-            spx_uint32_t frIn = session->framesIn;
-            spx_uint32_t frOut = session->apmFrameCount;
-            if (session->inChannelCount == 1) {
-                speex_resampler_process_int(session->inResampler,
-                                            0,
-                                            session->inBuf,
-                                            &frIn,
-                                            session->procFrame->data_,
-                                            &frOut);
-            } else {
-                speex_resampler_process_interleaved_int(session->inResampler,
-                                                        session->inBuf,
-                                                        &frIn,
-                                                        session->procFrame->data_,
-                                                        &frOut);
-            }
-            memmove(session->inBuf,
-                    session->inBuf + frIn * session->inChannelCount,
-                    (session->framesIn - frIn) * session->inChannelCount * sizeof(int16_t));
-            session->framesIn -= frIn;
-        } else {
-            size_t fr = session->frameCount - session->framesIn;
-            if (inBuffer->frameCount < fr) {
-                fr = inBuffer->frameCount;
-            }
-            memcpy(session->procFrame->data_ + session->framesIn * session->inChannelCount,
-                   inBuffer->s16,
-                   fr * session->inChannelCount * sizeof(int16_t));
-
-#ifdef DUAL_MIC_TEST
-            pthread_mutex_lock(&gPcmDumpLock);
-            if (gPcmDumpFh != NULL) {
-                fwrite(inBuffer->raw,
-                       fr * session->inChannelCount * sizeof(int16_t), 1, gPcmDumpFh);
-            }
-            pthread_mutex_unlock(&gPcmDumpLock);
-#endif
-
-            session->framesIn += fr;
-            inBuffer->frameCount = fr;
-            if (session->framesIn < session->frameCount) {
-                return 0;
-            }
-            session->framesIn = 0;
+        size_t fr = session->frameCount - session->framesIn;
+        if (inBuffer->frameCount < fr) {
+            fr = inBuffer->frameCount;
         }
-        session->procFrame->samples_per_channel_ = session->apmFrameCount;
-
-        effect->session->apm->ProcessStream(session->procFrame);
+        session->framesIn += fr;
+        inBuffer->frameCount = fr;
+        if (session->framesIn < session->frameCount) {
+            return 0;
+        }
+        session->framesIn = 0;
+        if (int status = effect->session->apm->ProcessStream(
+                    (const int16_t* const)inBuffer->s16,
+                    (const webrtc::StreamConfig)effect->session->inputConfig,
+                    (const webrtc::StreamConfig)effect->session->outputConfig,
+                    (int16_t* const)outBuffer->s16);
+            status != 0) {
+            ALOGE("Process Stream failed with error %d\n", status);
+            return status;
+        }
+        outBuffer->frameCount = inBuffer->frameCount;
 
         if (session->outBufSize < session->framesOut + session->frameCount) {
-            int16_t *buf;
+            int16_t* buf;
             session->outBufSize = session->framesOut + session->frameCount;
-            buf = (int16_t *)realloc(session->outBuf,
-                             session->outBufSize * session->outChannelCount * sizeof(int16_t));
+            buf = (int16_t*)realloc(
+                    session->outBuf,
+                    session->outBufSize * session->outChannelCount * sizeof(int16_t));
             if (buf == NULL) {
                 session->framesOut = 0;
                 free(session->outBuf);
@@ -1350,39 +1180,13 @@
             session->outBuf = buf;
         }
 
-        if (session->outResampler != NULL) {
-            spx_uint32_t frIn = session->apmFrameCount;
-            spx_uint32_t frOut = session->frameCount;
-            if (session->inChannelCount == 1) {
-                speex_resampler_process_int(session->outResampler,
-                                    0,
-                                    session->procFrame->data_,
-                                    &frIn,
-                                    session->outBuf + session->framesOut * session->outChannelCount,
-                                    &frOut);
-            } else {
-                speex_resampler_process_interleaved_int(session->outResampler,
-                                    session->procFrame->data_,
-                                    &frIn,
-                                    session->outBuf + session->framesOut * session->outChannelCount,
-                                    &frOut);
-            }
-            session->framesOut += frOut;
-        } else {
-            memcpy(session->outBuf + session->framesOut * session->outChannelCount,
-                   session->procFrame->data_,
-                   session->frameCount * session->outChannelCount * sizeof(int16_t));
-            session->framesOut += session->frameCount;
-        }
-        size_t fr = session->framesOut;
+        fr = session->framesOut;
         if (framesRq - framesWr < fr) {
             fr = framesRq - framesWr;
         }
-        memcpy(outBuffer->s16 + framesWr * session->outChannelCount,
-              session->outBuf,
-              fr * session->outChannelCount * sizeof(int16_t));
-        memmove(session->outBuf,
-                session->outBuf + fr * session->outChannelCount,
+        memcpy(outBuffer->s16 + framesWr * session->outChannelCount, session->outBuf,
+               fr * session->outChannelCount * sizeof(int16_t));
+        memmove(session->outBuf, session->outBuf + fr * session->outChannelCount,
                 (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t));
         session->framesOut -= fr;
         outBuffer->frameCount += fr;
@@ -1393,39 +1197,32 @@
     }
 }
 
-int PreProcessingFx_Command(effect_handle_t  self,
-                            uint32_t            cmdCode,
-                            uint32_t            cmdSize,
-                            void                *pCmdData,
-                            uint32_t            *replySize,
-                            void                *pReplyData)
-{
-    preproc_effect_t * effect = (preproc_effect_t *) self;
+int PreProcessingFx_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
+                            void* pCmdData, uint32_t* replySize, void* pReplyData) {
+    preproc_effect_t* effect = (preproc_effect_t*)self;
 
-    if (effect == NULL){
+    if (effect == NULL) {
         return -EINVAL;
     }
 
-    //ALOGV("PreProcessingFx_Command: command %d cmdSize %d",cmdCode, cmdSize);
+    // ALOGV("PreProcessingFx_Command: command %d cmdSize %d",cmdCode, cmdSize);
 
-    switch (cmdCode){
+    switch (cmdCode) {
         case EFFECT_CMD_INIT:
-            if (pReplyData == NULL || *replySize != sizeof(int)){
+            if (pReplyData == NULL || *replySize != sizeof(int)) {
                 return -EINVAL;
             }
             if (effect->ops->init) {
                 effect->ops->init(effect);
             }
-            *(int *)pReplyData = 0;
+            *(int*)pReplyData = 0;
             break;
 
         case EFFECT_CMD_SET_CONFIG: {
-            if (pCmdData    == NULL||
-                cmdSize     != sizeof(effect_config_t)||
-                pReplyData  == NULL||
-                *replySize  != sizeof(int)){
+            if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || pReplyData == NULL ||
+                *replySize != sizeof(int)) {
                 ALOGV("PreProcessingFx_Command cmdCode Case: "
-                        "EFFECT_CMD_SET_CONFIG: ERROR");
+                      "EFFECT_CMD_SET_CONFIG: ERROR");
                 return -EINVAL;
             }
 #ifdef DUAL_MIC_TEST
@@ -1436,55 +1233,51 @@
                 effect->session->enabledMsk = 0;
             }
 #endif
-            *(int *)pReplyData = Session_SetConfig(effect->session, (effect_config_t *)pCmdData);
+            *(int*)pReplyData = Session_SetConfig(effect->session, (effect_config_t*)pCmdData);
 #ifdef DUAL_MIC_TEST
             if (gDualMicEnabled) {
                 effect->session->enabledMsk = enabledMsk;
             }
 #endif
-            if (*(int *)pReplyData != 0) {
+            if (*(int*)pReplyData != 0) {
                 break;
             }
             if (effect->state != PREPROC_EFFECT_STATE_ACTIVE) {
-                *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
+                *(int*)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
             }
-            } break;
+        } break;
 
         case EFFECT_CMD_GET_CONFIG:
-            if (pReplyData == NULL ||
-                *replySize != sizeof(effect_config_t)) {
+            if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) {
                 ALOGV("\tLVM_ERROR : PreProcessingFx_Command cmdCode Case: "
-                        "EFFECT_CMD_GET_CONFIG: ERROR");
+                      "EFFECT_CMD_GET_CONFIG: ERROR");
                 return -EINVAL;
             }
 
-            Session_GetConfig(effect->session, (effect_config_t *)pReplyData);
+            Session_GetConfig(effect->session, (effect_config_t*)pReplyData);
             break;
 
         case EFFECT_CMD_SET_CONFIG_REVERSE:
-            if (pCmdData == NULL ||
-                cmdSize != sizeof(effect_config_t) ||
-                pReplyData == NULL ||
+            if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || pReplyData == NULL ||
                 *replySize != sizeof(int)) {
                 ALOGV("PreProcessingFx_Command cmdCode Case: "
-                        "EFFECT_CMD_SET_CONFIG_REVERSE: ERROR");
+                      "EFFECT_CMD_SET_CONFIG_REVERSE: ERROR");
                 return -EINVAL;
             }
-            *(int *)pReplyData = Session_SetReverseConfig(effect->session,
-                                                          (effect_config_t *)pCmdData);
-            if (*(int *)pReplyData != 0) {
+            *(int*)pReplyData =
+                    Session_SetReverseConfig(effect->session, (effect_config_t*)pCmdData);
+            if (*(int*)pReplyData != 0) {
                 break;
             }
             break;
 
         case EFFECT_CMD_GET_CONFIG_REVERSE:
-            if (pReplyData == NULL ||
-                *replySize != sizeof(effect_config_t)){
+            if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) {
                 ALOGV("PreProcessingFx_Command cmdCode Case: "
-                        "EFFECT_CMD_GET_CONFIG_REVERSE: ERROR");
+                      "EFFECT_CMD_GET_CONFIG_REVERSE: ERROR");
                 return -EINVAL;
             }
-            Session_GetReverseConfig(effect->session, (effect_config_t *)pCmdData);
+            Session_GetReverseConfig(effect->session, (effect_config_t*)pCmdData);
             break;
 
         case EFFECT_CMD_RESET:
@@ -1494,80 +1287,74 @@
             break;
 
         case EFFECT_CMD_GET_PARAM: {
-            effect_param_t *p = (effect_param_t *)pCmdData;
+            effect_param_t* p = (effect_param_t*)pCmdData;
 
             if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) ||
-                    cmdSize < (sizeof(effect_param_t) + p->psize) ||
-                    pReplyData == NULL || replySize == NULL ||
-                    *replySize < (sizeof(effect_param_t) + p->psize)){
+                cmdSize < (sizeof(effect_param_t) + p->psize) || pReplyData == NULL ||
+                replySize == NULL || *replySize < (sizeof(effect_param_t) + p->psize)) {
                 ALOGV("PreProcessingFx_Command cmdCode Case: "
-                        "EFFECT_CMD_GET_PARAM: ERROR");
+                      "EFFECT_CMD_GET_PARAM: ERROR");
                 return -EINVAL;
             }
 
             memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
 
-            p = (effect_param_t *)pReplyData;
+            p = (effect_param_t*)pReplyData;
 
             int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
 
             if (effect->ops->get_parameter) {
-                p->status = effect->ops->get_parameter(effect, p->data,
-                                                       &p->vsize,
-                                                       p->data + voffset);
+                p->status =
+                        effect->ops->get_parameter(effect, p->data, &p->vsize, p->data + voffset);
                 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
             }
         } break;
 
-        case EFFECT_CMD_SET_PARAM:{
-            if (pCmdData == NULL||
-                    cmdSize < sizeof(effect_param_t) ||
-                    pReplyData == NULL || replySize == NULL ||
-                    *replySize != sizeof(int32_t)){
+        case EFFECT_CMD_SET_PARAM: {
+            if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) || pReplyData == NULL ||
+                replySize == NULL || *replySize != sizeof(int32_t)) {
                 ALOGV("PreProcessingFx_Command cmdCode Case: "
-                        "EFFECT_CMD_SET_PARAM: ERROR");
+                      "EFFECT_CMD_SET_PARAM: ERROR");
                 return -EINVAL;
             }
-            effect_param_t *p = (effect_param_t *) pCmdData;
+            effect_param_t* p = (effect_param_t*)pCmdData;
 
-            if (p->psize != sizeof(int32_t)){
+            if (p->psize != sizeof(int32_t)) {
                 ALOGV("PreProcessingFx_Command cmdCode Case: "
-                        "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)");
+                      "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)");
                 return -EINVAL;
             }
             if (effect->ops->set_parameter) {
-                *(int *)pReplyData = effect->ops->set_parameter(effect,
-                                                                (void *)p->data,
-                                                                p->data + p->psize);
+                *(int*)pReplyData =
+                        effect->ops->set_parameter(effect, (void*)p->data, p->data + p->psize);
             }
         } break;
 
         case EFFECT_CMD_ENABLE:
-            if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)){
+            if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
                 ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_ENABLE: ERROR");
                 return -EINVAL;
             }
-            *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_ACTIVE);
+            *(int*)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_ACTIVE);
             break;
 
         case EFFECT_CMD_DISABLE:
-            if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)){
+            if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
                 ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_DISABLE: ERROR");
                 return -EINVAL;
             }
-            *(int *)pReplyData  = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
+            *(int*)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
             break;
 
         case EFFECT_CMD_SET_DEVICE:
         case EFFECT_CMD_SET_INPUT_DEVICE:
-            if (pCmdData == NULL ||
-                cmdSize != sizeof(uint32_t)) {
+            if (pCmdData == NULL || cmdSize != sizeof(uint32_t)) {
                 ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_SET_DEVICE: ERROR");
                 return -EINVAL;
             }
 
             if (effect->ops->set_device) {
-                effect->ops->set_device(effect, *(uint32_t *)pCmdData);
+                effect->ops->set_device(effect, *(uint32_t*)pCmdData);
             }
             break;
 
@@ -1578,30 +1365,30 @@
 #ifdef DUAL_MIC_TEST
         ///// test commands start
         case PREPROC_CMD_DUAL_MIC_ENABLE: {
-            if (pCmdData == NULL|| cmdSize != sizeof(uint32_t) ||
-                    pReplyData == NULL || replySize == NULL) {
+            if (pCmdData == NULL || cmdSize != sizeof(uint32_t) || pReplyData == NULL ||
+                replySize == NULL) {
                 ALOGE("PreProcessingFx_Command cmdCode Case: "
-                        "PREPROC_CMD_DUAL_MIC_ENABLE: ERROR");
+                      "PREPROC_CMD_DUAL_MIC_ENABLE: ERROR");
                 *replySize = 0;
                 return -EINVAL;
             }
-            gDualMicEnabled = *(bool *)pCmdData;
+            gDualMicEnabled = *(bool*)pCmdData;
             if (gDualMicEnabled) {
                 effect->aux_channels_on = sHasAuxChannels[effect->procId];
             } else {
                 effect->aux_channels_on = false;
             }
-            effect->cur_channel_config = (effect->session->inChannelCount == 1) ?
-                    CHANNEL_CFG_MONO : CHANNEL_CFG_STEREO;
+            effect->cur_channel_config =
+                    (effect->session->inChannelCount == 1) ? CHANNEL_CFG_MONO : CHANNEL_CFG_STEREO;
 
             ALOGV("PREPROC_CMD_DUAL_MIC_ENABLE: %s", gDualMicEnabled ? "enabled" : "disabled");
             *replySize = sizeof(int);
-            *(int *)pReplyData = 0;
-            } break;
+            *(int*)pReplyData = 0;
+        } break;
         case PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: {
-            if (pCmdData == NULL|| pReplyData == NULL || replySize == NULL) {
+            if (pCmdData == NULL || pReplyData == NULL || replySize == NULL) {
                 ALOGE("PreProcessingFx_Command cmdCode Case: "
-                        "PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: ERROR");
+                      "PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: ERROR");
                 *replySize = 0;
                 return -EINVAL;
             }
@@ -1610,20 +1397,19 @@
                 fclose(gPcmDumpFh);
                 gPcmDumpFh = NULL;
             }
-            char *path = strndup((char *)pCmdData, cmdSize);
-            gPcmDumpFh = fopen((char *)path, "wb");
+            char* path = strndup((char*)pCmdData, cmdSize);
+            gPcmDumpFh = fopen((char*)path, "wb");
             pthread_mutex_unlock(&gPcmDumpLock);
-            ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: path %s gPcmDumpFh %p",
-                  path, gPcmDumpFh);
+            ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: path %s gPcmDumpFh %p", path, gPcmDumpFh);
             ALOGE_IF(gPcmDumpFh <= 0, "gPcmDumpFh open error %d %s", errno, strerror(errno));
             free(path);
             *replySize = sizeof(int);
-            *(int *)pReplyData = 0;
-            } break;
+            *(int*)pReplyData = 0;
+        } break;
         case PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: {
             if (pReplyData == NULL || replySize == NULL) {
                 ALOGE("PreProcessingFx_Command cmdCode Case: "
-                        "PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: ERROR");
+                      "PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: ERROR");
                 *replySize = 0;
                 return -EINVAL;
             }
@@ -1635,118 +1421,116 @@
             pthread_mutex_unlock(&gPcmDumpLock);
             ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP");
             *replySize = sizeof(int);
-            *(int *)pReplyData = 0;
-            } break;
-        ///// test commands end
+            *(int*)pReplyData = 0;
+        } break;
+            ///// test commands end
 
         case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: {
-            if(!gDualMicEnabled) {
+            if (!gDualMicEnabled) {
                 return -EINVAL;
             }
-            if (pCmdData == NULL|| cmdSize != 2 * sizeof(uint32_t) ||
-                    pReplyData == NULL || replySize == NULL) {
+            if (pCmdData == NULL || cmdSize != 2 * sizeof(uint32_t) || pReplyData == NULL ||
+                replySize == NULL) {
                 ALOGE("PreProcessingFx_Command cmdCode Case: "
-                        "EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: ERROR");
+                      "EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: ERROR");
                 *replySize = 0;
                 return -EINVAL;
             }
-            if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS ||
-                  !effect->aux_channels_on) {
+            if (*(uint32_t*)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
                 ALOGV("PreProcessingFx_Command feature EFFECT_FEATURE_AUX_CHANNELS not supported by"
-                        " fx %d", effect->procId);
-                *(uint32_t *)pReplyData = -ENOSYS;
+                      " fx %d",
+                      effect->procId);
+                *(uint32_t*)pReplyData = -ENOSYS;
                 *replySize = sizeof(uint32_t);
                 break;
             }
-            size_t num_configs = *((uint32_t *)pCmdData + 1);
-            if (*replySize < (2 * sizeof(uint32_t) +
-                              num_configs * sizeof(channel_config_t))) {
+            size_t num_configs = *((uint32_t*)pCmdData + 1);
+            if (*replySize < (2 * sizeof(uint32_t) + num_configs * sizeof(channel_config_t))) {
                 *replySize = 0;
                 return -EINVAL;
             }
 
-            *((uint32_t *)pReplyData + 1) = CHANNEL_CFG_CNT;
+            *((uint32_t*)pReplyData + 1) = CHANNEL_CFG_CNT;
             if (num_configs < CHANNEL_CFG_CNT ||
-                    *replySize < (2 * sizeof(uint32_t) +
-                                     CHANNEL_CFG_CNT * sizeof(channel_config_t))) {
-                *(uint32_t *)pReplyData = -ENOMEM;
+                *replySize < (2 * sizeof(uint32_t) + CHANNEL_CFG_CNT * sizeof(channel_config_t))) {
+                *(uint32_t*)pReplyData = -ENOMEM;
             } else {
                 num_configs = CHANNEL_CFG_CNT;
-                *(uint32_t *)pReplyData = 0;
+                *(uint32_t*)pReplyData = 0;
             }
             ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS num config %d",
                   num_configs);
 
             *replySize = 2 * sizeof(uint32_t) + num_configs * sizeof(channel_config_t);
-            *((uint32_t *)pReplyData + 1) = num_configs;
-            memcpy((uint32_t *)pReplyData + 2, &sDualMicConfigs, num_configs * sizeof(channel_config_t));
-            } break;
+            *((uint32_t*)pReplyData + 1) = num_configs;
+            memcpy((uint32_t*)pReplyData + 2, &sDualMicConfigs,
+                   num_configs * sizeof(channel_config_t));
+        } break;
         case EFFECT_CMD_GET_FEATURE_CONFIG:
-            if(!gDualMicEnabled) {
+            if (!gDualMicEnabled) {
                 return -EINVAL;
             }
-            if (pCmdData == NULL|| cmdSize != sizeof(uint32_t) ||
-                    pReplyData == NULL || replySize == NULL ||
-                    *replySize < sizeof(uint32_t) + sizeof(channel_config_t)) {
+            if (pCmdData == NULL || cmdSize != sizeof(uint32_t) || pReplyData == NULL ||
+                replySize == NULL || *replySize < sizeof(uint32_t) + sizeof(channel_config_t)) {
                 ALOGE("PreProcessingFx_Command cmdCode Case: "
-                        "EFFECT_CMD_GET_FEATURE_CONFIG: ERROR");
+                      "EFFECT_CMD_GET_FEATURE_CONFIG: ERROR");
                 return -EINVAL;
             }
-            if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
-                *(uint32_t *)pReplyData = -ENOSYS;
+            if (*(uint32_t*)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
+                *(uint32_t*)pReplyData = -ENOSYS;
                 *replySize = sizeof(uint32_t);
                 break;
             }
             ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_CONFIG");
-            *(uint32_t *)pReplyData = 0;
+            *(uint32_t*)pReplyData = 0;
             *replySize = sizeof(uint32_t) + sizeof(channel_config_t);
-            memcpy((uint32_t *)pReplyData + 1,
-                   &sDualMicConfigs[effect->cur_channel_config],
+            memcpy((uint32_t*)pReplyData + 1, &sDualMicConfigs[effect->cur_channel_config],
                    sizeof(channel_config_t));
             break;
         case EFFECT_CMD_SET_FEATURE_CONFIG: {
             ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG: "
-                    "gDualMicEnabled %d effect->aux_channels_on %d",
+                  "gDualMicEnabled %d effect->aux_channels_on %d",
                   gDualMicEnabled, effect->aux_channels_on);
-            if(!gDualMicEnabled) {
+            if (!gDualMicEnabled) {
                 return -EINVAL;
             }
-            if (pCmdData == NULL|| cmdSize != (sizeof(uint32_t) + sizeof(channel_config_t)) ||
-                    pReplyData == NULL || replySize == NULL ||
-                    *replySize < sizeof(uint32_t)) {
+            if (pCmdData == NULL || cmdSize != (sizeof(uint32_t) + sizeof(channel_config_t)) ||
+                pReplyData == NULL || replySize == NULL || *replySize < sizeof(uint32_t)) {
                 ALOGE("PreProcessingFx_Command cmdCode Case: "
-                        "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
-                        "pCmdData %p cmdSize %d pReplyData %p replySize %p *replySize %d",
-                        pCmdData, cmdSize, pReplyData, replySize, replySize ? *replySize : -1);
+                      "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
+                      "pCmdData %p cmdSize %d pReplyData %p replySize %p *replySize %d",
+                      pCmdData, cmdSize, pReplyData, replySize, replySize ? *replySize : -1);
                 return -EINVAL;
             }
             *replySize = sizeof(uint32_t);
-            if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
-                *(uint32_t *)pReplyData = -ENOSYS;
+            if (*(uint32_t*)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
+                *(uint32_t*)pReplyData = -ENOSYS;
                 ALOGV("PreProcessingFx_Command cmdCode Case: "
-                                        "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
-                                        "CmdData %d effect->aux_channels_on %d",
-                                        *(uint32_t *)pCmdData, effect->aux_channels_on);
+                      "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
+                      "CmdData %d effect->aux_channels_on %d",
+                      *(uint32_t*)pCmdData, effect->aux_channels_on);
                 break;
             }
             size_t i;
-            for (i = 0; i < CHANNEL_CFG_CNT;i++) {
-                if (memcmp((uint32_t *)pCmdData + 1,
-                           &sDualMicConfigs[i], sizeof(channel_config_t)) == 0) {
+            for (i = 0; i < CHANNEL_CFG_CNT; i++) {
+                if (memcmp((uint32_t*)pCmdData + 1, &sDualMicConfigs[i],
+                           sizeof(channel_config_t)) == 0) {
                     break;
                 }
             }
             if (i == CHANNEL_CFG_CNT) {
-                *(uint32_t *)pReplyData = -EINVAL;
+                *(uint32_t*)pReplyData = -EINVAL;
                 ALOGW("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG invalid config"
-                        "[%08x].[%08x]", *((uint32_t *)pCmdData + 1), *((uint32_t *)pCmdData + 2));
+                      "[%08x].[%08x]",
+                      *((uint32_t*)pCmdData + 1), *((uint32_t*)pCmdData + 2));
             } else {
                 effect->cur_channel_config = i;
-                *(uint32_t *)pReplyData = 0;
+                *(uint32_t*)pReplyData = 0;
                 ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG New config"
-                        "[%08x].[%08x]", sDualMicConfigs[i].main_channels, sDualMicConfigs[i].aux_channels);
+                      "[%08x].[%08x]",
+                      sDualMicConfigs[i].main_channels, sDualMicConfigs[i].aux_channels);
             }
-            } break;
+        } break;
 #endif
         default:
             return -EINVAL;
@@ -1754,11 +1538,8 @@
     return 0;
 }
 
-
-int PreProcessingFx_GetDescriptor(effect_handle_t   self,
-                                  effect_descriptor_t *pDescriptor)
-{
-    preproc_effect_t * effect = (preproc_effect_t *) self;
+int PreProcessingFx_GetDescriptor(effect_handle_t self, effect_descriptor_t* pDescriptor) {
+    preproc_effect_t* effect = (preproc_effect_t*)self;
 
     if (effect == NULL || pDescriptor == NULL) {
         return -EINVAL;
@@ -1769,137 +1550,79 @@
     return 0;
 }
 
-int PreProcessingFx_ProcessReverse(effect_handle_t     self,
-                                   audio_buffer_t    *inBuffer,
-                                   audio_buffer_t    *outBuffer __unused)
-{
-    preproc_effect_t * effect = (preproc_effect_t *)self;
+int PreProcessingFx_ProcessReverse(effect_handle_t self, audio_buffer_t* inBuffer,
+                                   audio_buffer_t* outBuffer __unused) {
+    preproc_effect_t* effect = (preproc_effect_t*)self;
 
-    if (effect == NULL){
+    if (effect == NULL) {
         ALOGW("PreProcessingFx_ProcessReverse() ERROR effect == NULL");
         return -EINVAL;
     }
-    preproc_session_t * session = (preproc_session_t *)effect->session;
+    preproc_session_t* session = (preproc_session_t*)effect->session;
 
-    if (inBuffer == NULL  || inBuffer->raw == NULL){
+    if (inBuffer == NULL || inBuffer->raw == NULL) {
         ALOGW("PreProcessingFx_ProcessReverse() ERROR bad pointer");
         return -EINVAL;
     }
 
-    session->revProcessedMsk |= (1<<effect->procId);
+    session->revProcessedMsk |= (1 << effect->procId);
 
-//    ALOGV("PreProcessingFx_ProcessReverse In %d frames revEnabledMsk %08x revProcessedMsk %08x",
-//         inBuffer->frameCount, session->revEnabledMsk, session->revProcessedMsk);
-
+    //    ALOGV("PreProcessingFx_ProcessReverse In %d frames revEnabledMsk %08x revProcessedMsk
+    //    %08x",
+    //         inBuffer->frameCount, session->revEnabledMsk, session->revProcessedMsk);
 
     if ((session->revProcessedMsk & session->revEnabledMsk) == session->revEnabledMsk) {
         effect->session->revProcessedMsk = 0;
-        if (session->revResampler != NULL) {
-            size_t fr = session->frameCount - session->framesRev;
-            if (inBuffer->frameCount < fr) {
-                fr = inBuffer->frameCount;
-            }
-            if (session->revBufSize < session->framesRev + fr) {
-                int16_t *buf;
-                session->revBufSize = session->framesRev + fr;
-                buf = (int16_t *)realloc(session->revBuf,
-                                 session->revBufSize * session->inChannelCount * sizeof(int16_t));
-                if (buf == NULL) {
-                    session->framesRev = 0;
-                    free(session->revBuf);
-                    session->revBuf = NULL;
-                    return -ENOMEM;
-                }
-                session->revBuf = buf;
-            }
-            memcpy(session->revBuf + session->framesRev * session->inChannelCount,
-                   inBuffer->s16,
-                   fr * session->inChannelCount * sizeof(int16_t));
-
-            session->framesRev += fr;
-            inBuffer->frameCount = fr;
-            if (session->framesRev < session->frameCount) {
-                return 0;
-            }
-            spx_uint32_t frIn = session->framesRev;
-            spx_uint32_t frOut = session->apmFrameCount;
-            if (session->inChannelCount == 1) {
-                speex_resampler_process_int(session->revResampler,
-                                            0,
-                                            session->revBuf,
-                                            &frIn,
-                                            session->revFrame->data_,
-                                            &frOut);
-            } else {
-                speex_resampler_process_interleaved_int(session->revResampler,
-                                                        session->revBuf,
-                                                        &frIn,
-                                                        session->revFrame->data_,
-                                                        &frOut);
-            }
-            memmove(session->revBuf,
-                    session->revBuf + frIn * session->inChannelCount,
-                    (session->framesRev - frIn) * session->inChannelCount * sizeof(int16_t));
-            session->framesRev -= frIn;
-        } else {
-            size_t fr = session->frameCount - session->framesRev;
-            if (inBuffer->frameCount < fr) {
-                fr = inBuffer->frameCount;
-            }
-            memcpy(session->revFrame->data_ + session->framesRev * session->inChannelCount,
-                   inBuffer->s16,
-                   fr * session->inChannelCount * sizeof(int16_t));
-            session->framesRev += fr;
-            inBuffer->frameCount = fr;
-            if (session->framesRev < session->frameCount) {
-                return 0;
-            }
-            session->framesRev = 0;
+        size_t fr = session->frameCount - session->framesRev;
+        if (inBuffer->frameCount < fr) {
+            fr = inBuffer->frameCount;
         }
-        session->revFrame->samples_per_channel_ = session->apmFrameCount;
-        effect->session->apm->AnalyzeReverseStream(session->revFrame);
+        session->framesRev += fr;
+        inBuffer->frameCount = fr;
+        if (session->framesRev < session->frameCount) {
+            return 0;
+        }
+        session->framesRev = 0;
+        if (int status = effect->session->apm->ProcessReverseStream(
+                    (const int16_t* const)inBuffer->s16,
+                    (const webrtc::StreamConfig)effect->session->revConfig,
+                    (const webrtc::StreamConfig)effect->session->revConfig,
+                    (int16_t* const)outBuffer->s16);
+            status != 0) {
+            ALOGE("Process Reverse Stream failed with error %d\n", status);
+            return status;
+        }
         return 0;
     } else {
         return -ENODATA;
     }
 }
 
-
 // effect_handle_t interface implementation for effect
 const struct effect_interface_s sEffectInterface = {
-    PreProcessingFx_Process,
-    PreProcessingFx_Command,
-    PreProcessingFx_GetDescriptor,
-    NULL
-};
+        PreProcessingFx_Process, PreProcessingFx_Command, PreProcessingFx_GetDescriptor, NULL};
 
 const struct effect_interface_s sEffectInterfaceReverse = {
-    PreProcessingFx_Process,
-    PreProcessingFx_Command,
-    PreProcessingFx_GetDescriptor,
-    PreProcessingFx_ProcessReverse
-};
+        PreProcessingFx_Process, PreProcessingFx_Command, PreProcessingFx_GetDescriptor,
+        PreProcessingFx_ProcessReverse};
 
 //------------------------------------------------------------------------------
 // Effect Library Interface Implementation
 //------------------------------------------------------------------------------
 
-int PreProcessingLib_Create(const effect_uuid_t *uuid,
-                            int32_t             sessionId,
-                            int32_t             ioId,
-                            effect_handle_t  *pInterface)
-{
+int PreProcessingLib_Create(const effect_uuid_t* uuid, int32_t sessionId, int32_t ioId,
+                            effect_handle_t* pInterface) {
     ALOGV("EffectCreate: uuid: %08x session %d IO: %d", uuid->timeLow, sessionId, ioId);
 
     int status;
-    const effect_descriptor_t *desc;
-    preproc_session_t *session;
+    const effect_descriptor_t* desc;
+    preproc_session_t* session;
     uint32_t procId;
 
     if (PreProc_Init() != 0) {
         return sInitStatus;
     }
-    desc =  PreProc_GetDescriptor(uuid);
+    desc = PreProc_GetDescriptor(uuid);
     if (desc == NULL) {
         ALOGW("EffectCreate: fx not found uuid: %08x", uuid->timeLow);
         return -EINVAL;
@@ -1920,14 +1643,13 @@
     return status;
 }
 
-int PreProcessingLib_Release(effect_handle_t interface)
-{
+int PreProcessingLib_Release(effect_handle_t interface) {
     ALOGV("EffectRelease start %p", interface);
     if (PreProc_Init() != 0) {
         return sInitStatus;
     }
 
-    preproc_effect_t *fx = (preproc_effect_t *)interface;
+    preproc_effect_t* fx = (preproc_effect_t*)interface;
 
     if (fx->session->id == 0) {
         return -EINVAL;
@@ -1935,17 +1657,15 @@
     return Session_ReleaseEffect(fx->session, fx);
 }
 
-int PreProcessingLib_GetDescriptor(const effect_uuid_t *uuid,
-                                   effect_descriptor_t *pDescriptor) {
-
-    if (pDescriptor == NULL || uuid == NULL){
+int PreProcessingLib_GetDescriptor(const effect_uuid_t* uuid, effect_descriptor_t* pDescriptor) {
+    if (pDescriptor == NULL || uuid == NULL) {
         return -EINVAL;
     }
 
-    const effect_descriptor_t *desc = PreProc_GetDescriptor(uuid);
+    const effect_descriptor_t* desc = PreProc_GetDescriptor(uuid);
     if (desc == NULL) {
         ALOGV("PreProcessingLib_GetDescriptor() not found");
-        return  -EINVAL;
+        return -EINVAL;
     }
 
     ALOGV("PreProcessingLib_GetDescriptor() got fx %s", desc->name);
@@ -1955,15 +1675,13 @@
 }
 
 // This is the only symbol that needs to be exported
-__attribute__ ((visibility ("default")))
-audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
-    .tag = AUDIO_EFFECT_LIBRARY_TAG,
-    .version = EFFECT_LIBRARY_API_VERSION,
-    .name = "Audio Preprocessing Library",
-    .implementor = "The Android Open Source Project",
-    .create_effect = PreProcessingLib_Create,
-    .release_effect = PreProcessingLib_Release,
-    .get_descriptor = PreProcessingLib_GetDescriptor
-};
+__attribute__((visibility("default"))) audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+        .tag = AUDIO_EFFECT_LIBRARY_TAG,
+        .version = EFFECT_LIBRARY_API_VERSION,
+        .name = "Audio Preprocessing Library",
+        .implementor = "The Android Open Source Project",
+        .create_effect = PreProcessingLib_Create,
+        .release_effect = PreProcessingLib_Release,
+        .get_descriptor = PreProcessingLib_GetDescriptor};
 
-}; // extern "C"
+};  // extern "C"
diff --git a/media/libeffects/preprocessing/benchmarks/Android.bp b/media/libeffects/preprocessing/benchmarks/Android.bp
new file mode 100644
index 0000000..262fd19
--- /dev/null
+++ b/media/libeffects/preprocessing/benchmarks/Android.bp
@@ -0,0 +1,24 @@
+cc_benchmark {
+    name: "preprocessing_benchmark",
+    vendor: true,
+    relative_install_path: "soundfx",
+    srcs: ["preprocessing_benchmark.cpp"],
+    shared_libs: [
+        "libaudiopreprocessing",
+        "libaudioutils",
+        "liblog",
+        "libutils",
+    ],
+    cflags: [
+        "-DWEBRTC_POSIX",
+        "-fvisibility=default",
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    header_libs: [
+        "libaudioeffects",
+        "libhardware_headers",
+        "libwebrtc_absl_headers",
+    ],
+}
diff --git a/media/libeffects/preprocessing/benchmarks/preprocessing_benchmark.cpp b/media/libeffects/preprocessing/benchmarks/preprocessing_benchmark.cpp
new file mode 100644
index 0000000..694a6c4
--- /dev/null
+++ b/media/libeffects/preprocessing/benchmarks/preprocessing_benchmark.cpp
@@ -0,0 +1,240 @@
+/*
+ * 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.
+ */
+
+/*******************************************************************
+ * A test result running on Pixel 3 for comparison.
+ * The first parameter indicates the channel mask index.
+ * The second parameter indicates the effect index.
+ * 0: Automatic Gain Control,
+ * 1: Acoustic Echo Canceler,
+ * 2: Noise Suppressor,
+ * 3: Automatic Gain Control 2
+ * ---------------------------------------------------------------
+ * Benchmark                     Time             CPU   Iterations
+ * ---------------------------------------------------------------
+ * BM_PREPROCESSING/1/0      59836 ns        59655 ns        11732
+ * BM_PREPROCESSING/1/1      66848 ns        66642 ns        10554
+ * BM_PREPROCESSING/1/2      20726 ns        20655 ns        33822
+ * BM_PREPROCESSING/1/3       5093 ns         5076 ns       137897
+ * BM_PREPROCESSING/2/0     117040 ns       116670 ns         5996
+ * BM_PREPROCESSING/2/1     120600 ns       120225 ns         5845
+ * BM_PREPROCESSING/2/2      38460 ns        38330 ns        18190
+ * BM_PREPROCESSING/2/3       6294 ns         6274 ns       111488
+ * BM_PREPROCESSING/3/0     232272 ns       231528 ns         3025
+ * BM_PREPROCESSING/3/1     226346 ns       225628 ns         3117
+ * BM_PREPROCESSING/3/2      75442 ns        75227 ns         9104
+ * BM_PREPROCESSING/3/3       9782 ns         9750 ns        71805
+ * BM_PREPROCESSING/4/0     290388 ns       289426 ns         2389
+ * BM_PREPROCESSING/4/1     279394 ns       278498 ns         2522
+ * BM_PREPROCESSING/4/2      94029 ns        93759 ns         7307
+ * BM_PREPROCESSING/4/3      11487 ns        11450 ns        61129
+ * BM_PREPROCESSING/5/0     347736 ns       346580 ns         2020
+ * BM_PREPROCESSING/5/1     331853 ns       330788 ns         2122
+ * BM_PREPROCESSING/5/2     112594 ns       112268 ns         6105
+ * BM_PREPROCESSING/5/3      13254 ns        13212 ns        52972
+ *******************************************************************/
+
+#include <audio_effects/effect_aec.h>
+#include <audio_effects/effect_agc.h>
+#include <array>
+#include <climits>
+#include <cstdlib>
+#include <random>
+#include <vector>
+#include <audio_effects/effect_agc2.h>
+#include <audio_effects/effect_ns.h>
+#include <benchmark/benchmark.h>
+#include <hardware/audio_effect.h>
+#include <log/log.h>
+#include <sys/stat.h>
+#include <system/audio.h>
+
+extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
+
+constexpr int kSampleRate = 16000;
+constexpr float kTenMilliSecVal = 0.01;
+constexpr unsigned int kStreamDelayMs = 0;
+constexpr effect_uuid_t kEffectUuids[] = {
+        // agc uuid
+        {0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+        // aec uuid
+        {0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+        // ns  uuid
+        {0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+        // agc2 uuid
+        {0x89f38e65, 0xd4d2, 0x4d64, 0xad0e, {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}},
+};
+constexpr size_t kNumEffectUuids = std::size(kEffectUuids);
+constexpr audio_channel_mask_t kChMasks[] = {
+        AUDIO_CHANNEL_IN_MONO,          AUDIO_CHANNEL_IN_STEREO, AUDIO_CHANNEL_IN_2POINT0POINT2,
+        AUDIO_CHANNEL_IN_2POINT1POINT2, AUDIO_CHANNEL_IN_6,
+};
+constexpr size_t kNumChMasks = std::size(kChMasks);
+
+// types of pre processing modules
+enum PreProcId {
+    PREPROC_AGC,  // Automatic Gain Control
+    PREPROC_AEC,  // Acoustic Echo Canceler
+    PREPROC_NS,   // Noise Suppressor
+    PREPROC_AGC2,  // Automatic Gain Control 2
+    PREPROC_NUM_EFFECTS
+};
+
+int preProcCreateEffect(effect_handle_t* pEffectHandle, uint32_t effectType,
+                        effect_config_t* pConfig, int sessionId, int ioId) {
+    if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&kEffectUuids[effectType],
+                                                                 sessionId, ioId, pEffectHandle);
+        status != 0) {
+        ALOGE("Audio Preprocessing create returned an error = %d\n", status);
+        return EXIT_FAILURE;
+    }
+    int reply = 0;
+    uint32_t replySize = sizeof(reply);
+    if (effectType == PREPROC_AEC) {
+        if (int status = (**pEffectHandle)
+                                 ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG_REVERSE,
+                                           sizeof(effect_config_t), pConfig, &replySize, &reply);
+            status != 0) {
+            ALOGE("Set config reverse command returned an error = %d\n", status);
+            return EXIT_FAILURE;
+        }
+    }
+    if (int status = (**pEffectHandle)
+                             ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG,
+                                       sizeof(effect_config_t), pConfig, &replySize, &reply);
+        status != 0) {
+        ALOGE("Set config command returned an error = %d\n", status);
+        return EXIT_FAILURE;
+    }
+    return reply;
+}
+
+int preProcSetConfigParam(effect_handle_t effectHandle, uint32_t paramType, uint32_t paramValue) {
+    int reply = 0;
+    uint32_t replySize = sizeof(reply);
+    uint32_t paramData[2] = {paramType, paramValue};
+    effect_param_t* effectParam = (effect_param_t*)malloc(sizeof(*effectParam) + sizeof(paramData));
+    memcpy(&effectParam->data[0], &paramData[0], sizeof(paramData));
+    effectParam->psize = sizeof(paramData[0]);
+    (*effectHandle)
+            ->command(effectHandle, EFFECT_CMD_SET_PARAM, sizeof(effect_param_t), effectParam,
+                      &replySize, &reply);
+    free(effectParam);
+    return reply;
+}
+
+short preProcGetShortVal(float paramValue) {
+    return static_cast<short>(paramValue * std::numeric_limits<short>::max());
+}
+
+static void BM_PREPROCESSING(benchmark::State& state) {
+    const size_t chMask = kChMasks[state.range(0) - 1];
+    const size_t channelCount = audio_channel_count_from_in_mask(chMask);
+
+    PreProcId effectType = (PreProcId)state.range(1);
+
+    int32_t sessionId = 1;
+    int32_t ioId = 1;
+    effect_handle_t effectHandle = nullptr;
+    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_16_BIT;
+
+    if (int status = preProcCreateEffect(&effectHandle, state.range(1), &config, sessionId, ioId);
+        status != 0) {
+        ALOGE("Create effect call returned error %i", status);
+        return;
+    }
+
+    int reply = 0;
+    uint32_t replySize = sizeof(reply);
+    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;
+    }
+
+    // Initialize input buffer with deterministic pseudo-random values
+    const int frameLength = (int)(kSampleRate * kTenMilliSecVal);
+    std::minstd_rand gen(chMask);
+    std::uniform_real_distribution<> dis(-1.0f, 1.0f);
+    std::vector<short> in(frameLength * channelCount);
+    for (auto& i : in) {
+        i = preProcGetShortVal(dis(gen));
+    }
+    std::vector<short> farIn(frameLength * channelCount);
+    for (auto& i : farIn) {
+        i = preProcGetShortVal(dis(gen));
+    }
+    std::vector<short> out(frameLength * channelCount);
+
+    // Run the test
+    for (auto _ : state) {
+        benchmark::DoNotOptimize(in.data());
+        benchmark::DoNotOptimize(out.data());
+        benchmark::DoNotOptimize(farIn.data());
+
+        audio_buffer_t inBuffer = {.frameCount = (size_t)frameLength, .s16 = in.data()};
+        audio_buffer_t outBuffer = {.frameCount = (size_t)frameLength, .s16 = out.data()};
+        audio_buffer_t farInBuffer = {.frameCount = (size_t)frameLength, .s16 = farIn.data()};
+
+        if (PREPROC_AEC == effectType) {
+            if (int status =
+                        preProcSetConfigParam(effectHandle, AEC_PARAM_ECHO_DELAY, kStreamDelayMs);
+                status != 0) {
+                ALOGE("preProcSetConfigParam returned Error %d\n", status);
+                return;
+            }
+        }
+        if (int status = (*effectHandle)->process(effectHandle, &inBuffer, &outBuffer);
+            status != 0) {
+            ALOGE("\nError: Process i = %d returned with error %d\n", (int)state.range(1), status);
+            return;
+        }
+        if (PREPROC_AEC == effectType) {
+            if (int status =
+                        (*effectHandle)->process_reverse(effectHandle, &farInBuffer, &outBuffer);
+                status != 0) {
+                ALOGE("\nError: Process reverse i = %d returned with error %d\n",
+                      (int)state.range(1), status);
+                return;
+            }
+        }
+    }
+    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 preprocessingArgs(benchmark::internal::Benchmark* b) {
+    for (int i = 1; i <= (int)kNumChMasks; i++) {
+        for (int j = 0; j < (int)kNumEffectUuids; ++j) {
+            b->Args({i, j});
+        }
+    }
+}
+
+BENCHMARK(BM_PREPROCESSING)->Apply(preprocessingArgs);
+
+BENCHMARK_MAIN();
diff --git a/media/libeffects/preprocessing/tests/Android.bp b/media/libeffects/preprocessing/tests/Android.bp
index 71f6e8f..b439880 100644
--- a/media/libeffects/preprocessing/tests/Android.bp
+++ b/media/libeffects/preprocessing/tests/Android.bp
@@ -13,16 +13,7 @@
         "libaudioutils",
         "liblog",
         "libutils",
-        "libwebrtc_audio_preprocessing",
     ],
-
-    cflags: [
-        "-DWEBRTC_POSIX",
-        "-fvisibility=default",
-        "-Wall",
-        "-Werror",
-    ],
-
     header_libs: [
         "libaudioeffects",
         "libhardware_headers",
diff --git a/media/libeffects/preprocessing/tests/PreProcessingTest.cpp b/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
index 5c81d78..5f223c9 100644
--- a/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
+++ b/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
@@ -14,23 +14,17 @@
  * limitations under the License.
  */
 
+#include <getopt.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <vector>
+
 #include <audio_effects/effect_aec.h>
 #include <audio_effects/effect_agc.h>
+#include <audio_effects/effect_agc2.h>
 #include <audio_effects/effect_ns.h>
-#include <audio_processing.h>
-#include <getopt.h>
-#include <hardware/audio_effect.h>
-#include <module_common_types.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <utils/Log.h>
-#include <utils/Timers.h>
-
-#include <audio_utils/channels.h>
-#include <audio_utils/primitives.h>
 #include <log/log.h>
-#include <system/audio.h>
 
 // This is the only symbol that needs to be imported
 extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
@@ -41,389 +35,445 @@
 
 // types of pre processing modules
 enum PreProcId {
-  PREPROC_AGC,  // Automatic Gain Control
-  PREPROC_AEC,  // Acoustic Echo Canceler
-  PREPROC_NS,   // Noise Suppressor
-  PREPROC_NUM_EFFECTS
+    PREPROC_AGC,  // Automatic Gain Control
+    PREPROC_AGC2,  // Automatic Gain Control 2
+    PREPROC_AEC,  // Acoustic Echo Canceler
+    PREPROC_NS,   // Noise Suppressor
+    PREPROC_NUM_EFFECTS
 };
 
 enum PreProcParams {
-  ARG_HELP = 1,
-  ARG_INPUT,
-  ARG_OUTPUT,
-  ARG_FAR,
-  ARG_FS,
-  ARG_CH_MASK,
-  ARG_AGC_TGT_LVL,
-  ARG_AGC_COMP_LVL,
-  ARG_AEC_DELAY,
-  ARG_NS_LVL,
+    ARG_HELP = 1,
+    ARG_INPUT,
+    ARG_OUTPUT,
+    ARG_FAR,
+    ARG_FS,
+    ARG_CH_MASK,
+    ARG_AGC_TGT_LVL,
+    ARG_AGC_COMP_LVL,
+    ARG_AEC_DELAY,
+    ARG_NS_LVL,
+    ARG_AGC2_GAIN,
+    ARG_AGC2_LVL,
+    ARG_AGC2_SAT_MGN
 };
 
 struct preProcConfigParams_t {
-  int samplingFreq = 16000;
-  audio_channel_mask_t chMask = AUDIO_CHANNEL_IN_MONO;
-  int nsLevel = 0;         // a value between 0-3
-  int agcTargetLevel = 3;  // in dB
-  int agcCompLevel = 9;    // in dB
-  int aecDelay = 0;        // in ms
+    int samplingFreq = 16000;
+    audio_channel_mask_t chMask = AUDIO_CHANNEL_IN_MONO;
+    int nsLevel = 0;         // a value between 0-3
+    int agcTargetLevel = 3;  // in dB
+    int agcCompLevel = 9;    // in dB
+    float agc2Gain = 0.f;              // in dB
+    float agc2SaturationMargin = 2.f;  // in dB
+    int agc2Level = 0;                 // either kRms(0) or kPeak(1)
+    int aecDelay = 0;  // in ms
 };
 
 const effect_uuid_t kPreProcUuids[PREPROC_NUM_EFFECTS] = {
-    {0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // agc uuid
-    {0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // aec uuid
-    {0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // ns  uuid
+        {0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // agc uuid
+        {0x89f38e65, 0xd4d2, 0x4d64, 0xad0e, {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}},  // agc2 uuid
+        {0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // aec uuid
+        {0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // ns  uuid
 };
 
 constexpr audio_channel_mask_t kPreProcConfigChMask[] = {
-    AUDIO_CHANNEL_IN_MONO,
-    AUDIO_CHANNEL_IN_STEREO,
-    AUDIO_CHANNEL_IN_FRONT_BACK,
-    AUDIO_CHANNEL_IN_6,
-    AUDIO_CHANNEL_IN_2POINT0POINT2,
-    AUDIO_CHANNEL_IN_2POINT1POINT2,
-    AUDIO_CHANNEL_IN_3POINT0POINT2,
-    AUDIO_CHANNEL_IN_3POINT1POINT2,
-    AUDIO_CHANNEL_IN_5POINT1,
-    AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO,
-    AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO,
-    AUDIO_CHANNEL_IN_VOICE_CALL_MONO,
+        AUDIO_CHANNEL_IN_MONO,
+        AUDIO_CHANNEL_IN_STEREO,
+        AUDIO_CHANNEL_IN_FRONT_BACK,
+        AUDIO_CHANNEL_IN_6,
+        AUDIO_CHANNEL_IN_2POINT0POINT2,
+        AUDIO_CHANNEL_IN_2POINT1POINT2,
+        AUDIO_CHANNEL_IN_3POINT0POINT2,
+        AUDIO_CHANNEL_IN_3POINT1POINT2,
+        AUDIO_CHANNEL_IN_5POINT1,
+        AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO,
+        AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO,
+        AUDIO_CHANNEL_IN_VOICE_CALL_MONO,
 };
 
 constexpr int kPreProcConfigChMaskCount = std::size(kPreProcConfigChMask);
 
 void printUsage() {
-  printf("\nUsage: ");
-  printf("\n     <executable> [options]\n");
-  printf("\nwhere options are, ");
-  printf("\n     --input <inputfile>");
-  printf("\n           path to the input file");
-  printf("\n     --output <outputfile>");
-  printf("\n           path to the output file");
-  printf("\n     --help");
-  printf("\n           Prints this usage information");
-  printf("\n     --fs <sampling_freq>");
-  printf("\n           Sampling frequency in Hz, default 16000.");
-  printf("\n     -ch_mask <channel_mask>\n");
-  printf("\n         0  - AUDIO_CHANNEL_IN_MONO");
-  printf("\n         1  - AUDIO_CHANNEL_IN_STEREO");
-  printf("\n         2  - AUDIO_CHANNEL_IN_FRONT_BACK");
-  printf("\n         3  - AUDIO_CHANNEL_IN_6");
-  printf("\n         4  - AUDIO_CHANNEL_IN_2POINT0POINT2");
-  printf("\n         5  - AUDIO_CHANNEL_IN_2POINT1POINT2");
-  printf("\n         6  - AUDIO_CHANNEL_IN_3POINT0POINT2");
-  printf("\n         7  - AUDIO_CHANNEL_IN_3POINT1POINT2");
-  printf("\n         8  - AUDIO_CHANNEL_IN_5POINT1");
-  printf("\n         9  - AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO");
-  printf("\n         10 - AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO ");
-  printf("\n         11 - AUDIO_CHANNEL_IN_VOICE_CALL_MONO ");
-  printf("\n         default 0");
-  printf("\n     --far <farend_file>");
-  printf("\n           Path to far-end file needed for echo cancellation");
-  printf("\n     --aec");
-  printf("\n           Enable Echo Cancellation, default disabled");
-  printf("\n     --ns");
-  printf("\n           Enable Noise Suppression, default disabled");
-  printf("\n     --agc");
-  printf("\n           Enable Gain Control, default disabled");
-  printf("\n     --ns_lvl <ns_level>");
-  printf("\n           Noise Suppression level in dB, default value 0dB");
-  printf("\n     --agc_tgt_lvl <target_level>");
-  printf("\n           AGC Target Level in dB, default value 3dB");
-  printf("\n     --agc_comp_lvl <comp_level>");
-  printf("\n           AGC Comp Level in dB, default value 9dB");
-  printf("\n     --aec_delay <delay>");
-  printf("\n           AEC delay value in ms, default value 0ms");
-  printf("\n");
+    printf("\nUsage: ");
+    printf("\n     <executable> [options]\n");
+    printf("\nwhere options are, ");
+    printf("\n     --input <inputfile>");
+    printf("\n           path to the input file");
+    printf("\n     --output <outputfile>");
+    printf("\n           path to the output file");
+    printf("\n     --help");
+    printf("\n           Prints this usage information");
+    printf("\n     --fs <sampling_freq>");
+    printf("\n           Sampling frequency in Hz, default 16000.");
+    printf("\n     -ch_mask <channel_mask>\n");
+    printf("\n         0  - AUDIO_CHANNEL_IN_MONO");
+    printf("\n         1  - AUDIO_CHANNEL_IN_STEREO");
+    printf("\n         2  - AUDIO_CHANNEL_IN_FRONT_BACK");
+    printf("\n         3  - AUDIO_CHANNEL_IN_6");
+    printf("\n         4  - AUDIO_CHANNEL_IN_2POINT0POINT2");
+    printf("\n         5  - AUDIO_CHANNEL_IN_2POINT1POINT2");
+    printf("\n         6  - AUDIO_CHANNEL_IN_3POINT0POINT2");
+    printf("\n         7  - AUDIO_CHANNEL_IN_3POINT1POINT2");
+    printf("\n         8  - AUDIO_CHANNEL_IN_5POINT1");
+    printf("\n         9  - AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO");
+    printf("\n         10 - AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO ");
+    printf("\n         11 - AUDIO_CHANNEL_IN_VOICE_CALL_MONO ");
+    printf("\n         default 0");
+    printf("\n     --far <farend_file>");
+    printf("\n           Path to far-end file needed for echo cancellation");
+    printf("\n     --aec");
+    printf("\n           Enable Echo Cancellation, default disabled");
+    printf("\n     --ns");
+    printf("\n           Enable Noise Suppression, default disabled");
+    printf("\n     --agc");
+    printf("\n           Enable Gain Control, default disabled");
+    printf("\n     --agc2");
+    printf("\n           Enable Gain Controller 2, default disabled");
+    printf("\n     --ns_lvl <ns_level>");
+    printf("\n           Noise Suppression level in dB, default value 0dB");
+    printf("\n     --agc_tgt_lvl <target_level>");
+    printf("\n           AGC Target Level in dB, default value 3dB");
+    printf("\n     --agc_comp_lvl <comp_level>");
+    printf("\n           AGC Comp Level in dB, default value 9dB");
+    printf("\n     --agc2_gain <fixed_digital_gain>");
+    printf("\n           AGC Fixed Digital Gain in dB, default value 0dB");
+    printf("\n     --agc2_lvl <level_estimator>");
+    printf("\n           AGC Adaptive Digital Level Estimator, default value kRms");
+    printf("\n     --agc2_sat_mgn <saturation_margin>");
+    printf("\n           AGC Adaptive Digital Saturation Margin in dB, default value 2dB");
+    printf("\n     --aec_delay <delay>");
+    printf("\n           AEC delay value in ms, default value 0ms");
+    printf("\n");
 }
 
 constexpr float kTenMilliSecVal = 0.01;
 
-int preProcCreateEffect(effect_handle_t *pEffectHandle, uint32_t effectType,
-                        effect_config_t *pConfig, int sessionId, int ioId) {
-  if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&kPreProcUuids[effectType],
-                                                               sessionId, ioId, pEffectHandle);
-      status != 0) {
-    ALOGE("Audio Preprocessing create returned an error = %d\n", status);
-    return EXIT_FAILURE;
-  }
-  int reply = 0;
-  uint32_t replySize = sizeof(reply);
-  if (effectType == PREPROC_AEC) {
+int preProcCreateEffect(effect_handle_t* pEffectHandle, uint32_t effectType,
+                        effect_config_t* pConfig, int sessionId, int ioId) {
+    if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&kPreProcUuids[effectType],
+                                                                 sessionId, ioId, pEffectHandle);
+        status != 0) {
+        ALOGE("Audio Preprocessing create returned an error = %d\n", status);
+        return EXIT_FAILURE;
+    }
+    int reply = 0;
+    uint32_t replySize = sizeof(reply);
+    if (effectType == PREPROC_AEC) {
+        (**pEffectHandle)
+                ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG_REVERSE, sizeof(effect_config_t),
+                          pConfig, &replySize, &reply);
+    }
     (**pEffectHandle)
-        ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG_REVERSE, sizeof(effect_config_t), pConfig,
-                  &replySize, &reply);
-  }
-  (**pEffectHandle)
-      ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), pConfig,
-                &replySize, &reply);
-  return reply;
+            ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), pConfig,
+                      &replySize, &reply);
+    return reply;
 }
 
 int preProcSetConfigParam(uint32_t paramType, uint32_t paramValue, effect_handle_t effectHandle) {
-  int reply = 0;
-  uint32_t replySize = sizeof(reply);
-  uint32_t paramData[2] = {paramType, paramValue};
-  effect_param_t *effectParam =
-      (effect_param_t *)malloc(sizeof(*effectParam) + sizeof(paramData));
-  memcpy(&effectParam->data[0], &paramData[0], sizeof(paramData));
-  effectParam->psize = sizeof(paramData[0]);
-  (*effectHandle)
-      ->command(effectHandle, EFFECT_CMD_SET_PARAM, sizeof(effect_param_t), effectParam,
-                &replySize, &reply);
-  free(effectParam);
-  return reply;
+    int reply = 0;
+    uint32_t replySize = sizeof(reply);
+    uint32_t paramData[2] = {paramType, paramValue};
+    effect_param_t* effectParam = (effect_param_t*)malloc(sizeof(*effectParam) + sizeof(paramData));
+    memcpy(&effectParam->data[0], &paramData[0], sizeof(paramData));
+    effectParam->psize = sizeof(paramData[0]);
+    (*effectHandle)
+            ->command(effectHandle, EFFECT_CMD_SET_PARAM, sizeof(effect_param_t), effectParam,
+                      &replySize, &reply);
+    free(effectParam);
+    return reply;
 }
 
-int main(int argc, const char *argv[]) {
-  if (argc == 1) {
-    printUsage();
-    return EXIT_FAILURE;
-  }
-  const char *inputFile = nullptr;
-  const char *outputFile = nullptr;
-  const char *farFile = nullptr;
-  int effectEn[PREPROC_NUM_EFFECTS] = {0};
-
-  const option long_opts[] = {
-      {"help", no_argument, nullptr, ARG_HELP},
-      {"input", required_argument, nullptr, ARG_INPUT},
-      {"output", required_argument, nullptr, ARG_OUTPUT},
-      {"far", required_argument, nullptr, ARG_FAR},
-      {"fs", required_argument, nullptr, ARG_FS},
-      {"ch_mask", required_argument, nullptr, ARG_CH_MASK},
-      {"agc_tgt_lvl", required_argument, nullptr, ARG_AGC_TGT_LVL},
-      {"agc_comp_lvl", required_argument, nullptr, ARG_AGC_COMP_LVL},
-      {"aec_delay", required_argument, nullptr, ARG_AEC_DELAY},
-      {"ns_lvl", required_argument, nullptr, ARG_NS_LVL},
-      {"aec", no_argument, &effectEn[PREPROC_AEC], 1},
-      {"agc", no_argument, &effectEn[PREPROC_AGC], 1},
-      {"ns", no_argument, &effectEn[PREPROC_NS], 1},
-      {nullptr, 0, nullptr, 0},
-  };
-  struct preProcConfigParams_t preProcCfgParams {};
-
-  while (true) {
-    const int opt = getopt_long(argc, (char *const *)argv, "i:o:", long_opts, nullptr);
-    if (opt == -1) {
-      break;
-    }
-    switch (opt) {
-      case ARG_HELP:
+int main(int argc, const char* argv[]) {
+    if (argc == 1) {
         printUsage();
-        return 0;
-      case ARG_INPUT: {
-        inputFile = (char *)optarg;
-        break;
-      }
-      case ARG_OUTPUT: {
-        outputFile = (char *)optarg;
-        break;
-      }
-      case ARG_FAR: {
-        farFile = (char *)optarg;
-        break;
-      }
-      case ARG_FS: {
-        preProcCfgParams.samplingFreq = atoi(optarg);
-        break;
-      }
-      case ARG_CH_MASK: {
-        int chMaskIdx = atoi(optarg);
-        if (chMaskIdx < 0 or chMaskIdx > kPreProcConfigChMaskCount) {
-          ALOGE("Channel Mask index not in correct range\n");
-          printUsage();
-          return EXIT_FAILURE;
-        }
-        preProcCfgParams.chMask = kPreProcConfigChMask[chMaskIdx];
-        break;
-      }
-      case ARG_AGC_TGT_LVL: {
-        preProcCfgParams.agcTargetLevel = atoi(optarg);
-        break;
-      }
-      case ARG_AGC_COMP_LVL: {
-        preProcCfgParams.agcCompLevel = atoi(optarg);
-        break;
-      }
-      case ARG_AEC_DELAY: {
-        preProcCfgParams.aecDelay = atoi(optarg);
-        break;
-      }
-      case ARG_NS_LVL: {
-        preProcCfgParams.nsLevel = atoi(optarg);
-        break;
-      }
-      default:
-        break;
-    }
-  }
-
-  if (inputFile == nullptr) {
-    ALOGE("Error: missing input file\n");
-    printUsage();
-    return EXIT_FAILURE;
-  }
-
-  std::unique_ptr<FILE, decltype(&fclose)> inputFp(fopen(inputFile, "rb"), &fclose);
-  if (inputFp == nullptr) {
-    ALOGE("Cannot open input file %s\n", inputFile);
-    return EXIT_FAILURE;
-  }
-
-  std::unique_ptr<FILE, decltype(&fclose)> farFp(fopen(farFile, "rb"), &fclose);
-  std::unique_ptr<FILE, decltype(&fclose)> outputFp(fopen(outputFile, "wb"), &fclose);
-  if (effectEn[PREPROC_AEC]) {
-    if (farFile == nullptr) {
-      ALOGE("Far end signal file required for echo cancellation \n");
-      return EXIT_FAILURE;
-    }
-    if (farFp == nullptr) {
-      ALOGE("Cannot open far end stream file %s\n", farFile);
-      return EXIT_FAILURE;
-    }
-    struct stat statInput, statFar;
-    (void)fstat(fileno(inputFp.get()), &statInput);
-    (void)fstat(fileno(farFp.get()), &statFar);
-    if (statInput.st_size != statFar.st_size) {
-      ALOGE("Near and far end signals are of different sizes");
-      return EXIT_FAILURE;
-    }
-  }
-  if (outputFile != nullptr && outputFp == nullptr) {
-    ALOGE("Cannot open output file %s\n", outputFile);
-    return EXIT_FAILURE;
-  }
-
-  int32_t sessionId = 1;
-  int32_t ioId = 1;
-  effect_handle_t effectHandle[PREPROC_NUM_EFFECTS] = {nullptr};
-  effect_config_t config;
-  config.inputCfg.samplingRate = config.outputCfg.samplingRate = preProcCfgParams.samplingFreq;
-  config.inputCfg.channels = config.outputCfg.channels = preProcCfgParams.chMask;
-  config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
-
-  // Create all the effect handles
-  for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
-    if (int status = preProcCreateEffect(&effectHandle[i], i, &config, sessionId, ioId);
-        status != 0) {
-      ALOGE("Create effect call returned error %i", status);
-      return EXIT_FAILURE;
-    }
-  }
-
-  for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
-    if (effectEn[i] == 1) {
-      int reply = 0;
-      uint32_t replySize = sizeof(reply);
-      (*effectHandle[i])
-          ->command(effectHandle[i], EFFECT_CMD_ENABLE, 0, nullptr, &replySize, &reply);
-      if (reply != 0) {
-        ALOGE("Command enable call returned error %d\n", reply);
         return EXIT_FAILURE;
-      }
     }
-  }
+    const char* inputFile = nullptr;
+    const char* outputFile = nullptr;
+    const char* farFile = nullptr;
+    int effectEn[PREPROC_NUM_EFFECTS] = {0};
 
-  // Set Config Params of the effects
-  if (effectEn[PREPROC_AGC]) {
-    if (int status = preProcSetConfigParam(AGC_PARAM_TARGET_LEVEL,
-                                           (uint32_t)preProcCfgParams.agcTargetLevel,
-                                           effectHandle[PREPROC_AGC]);
-        status != 0) {
-      ALOGE("Invalid AGC Target Level. Error %d\n", status);
-      return EXIT_FAILURE;
-    }
-    if (int status =
-            preProcSetConfigParam(AGC_PARAM_COMP_GAIN, (uint32_t)preProcCfgParams.agcCompLevel,
-                                  effectHandle[PREPROC_AGC]);
-        status != 0) {
-      ALOGE("Invalid AGC Comp Gain. Error %d\n", status);
-      return EXIT_FAILURE;
-    }
-  }
-  if (effectEn[PREPROC_NS]) {
-    if (int status = preProcSetConfigParam(NS_PARAM_LEVEL, (uint32_t)preProcCfgParams.nsLevel,
-                                           effectHandle[PREPROC_NS]);
-        status != 0) {
-      ALOGE("Invalid Noise Suppression level Error %d\n", status);
-      return EXIT_FAILURE;
-    }
-  }
+    const option long_opts[] = {
+            {"help", no_argument, nullptr, ARG_HELP},
+            {"input", required_argument, nullptr, ARG_INPUT},
+            {"output", required_argument, nullptr, ARG_OUTPUT},
+            {"far", required_argument, nullptr, ARG_FAR},
+            {"fs", required_argument, nullptr, ARG_FS},
+            {"ch_mask", required_argument, nullptr, ARG_CH_MASK},
+            {"agc_tgt_lvl", required_argument, nullptr, ARG_AGC_TGT_LVL},
+            {"agc_comp_lvl", required_argument, nullptr, ARG_AGC_COMP_LVL},
+            {"agc2_gain", required_argument, nullptr, ARG_AGC2_GAIN},
+            {"agc2_lvl", required_argument, nullptr, ARG_AGC2_LVL},
+            {"agc2_sat_mgn", required_argument, nullptr, ARG_AGC2_SAT_MGN},
+            {"aec_delay", required_argument, nullptr, ARG_AEC_DELAY},
+            {"ns_lvl", required_argument, nullptr, ARG_NS_LVL},
+            {"aec", no_argument, &effectEn[PREPROC_AEC], 1},
+            {"agc", no_argument, &effectEn[PREPROC_AGC], 1},
+            {"agc2", no_argument, &effectEn[PREPROC_AGC2], 1},
+            {"ns", no_argument, &effectEn[PREPROC_NS], 1},
+            {nullptr, 0, nullptr, 0},
+    };
+    struct preProcConfigParams_t preProcCfgParams {};
 
-  // Process Call
-  const int frameLength = (int)(preProcCfgParams.samplingFreq * kTenMilliSecVal);
-  const int ioChannelCount = audio_channel_count_from_in_mask(preProcCfgParams.chMask);
-  const int ioFrameSize = ioChannelCount * sizeof(short);
-  int frameCounter = 0;
-  while (true) {
-    std::vector<short> in(frameLength * ioChannelCount);
-    std::vector<short> out(frameLength * ioChannelCount);
-    std::vector<short> farIn(frameLength * ioChannelCount);
-    size_t samplesRead = fread(in.data(), ioFrameSize, frameLength, inputFp.get());
-    if (samplesRead == 0) {
-      break;
+    while (true) {
+        const int opt = getopt_long(argc, (char* const*)argv, "i:o:", long_opts, nullptr);
+        if (opt == -1) {
+            break;
+        }
+        switch (opt) {
+            case ARG_HELP:
+                printUsage();
+                return 0;
+            case ARG_INPUT: {
+                inputFile = (char*)optarg;
+                break;
+            }
+            case ARG_OUTPUT: {
+                outputFile = (char*)optarg;
+                break;
+            }
+            case ARG_FAR: {
+                farFile = (char*)optarg;
+                break;
+            }
+            case ARG_FS: {
+                preProcCfgParams.samplingFreq = atoi(optarg);
+                break;
+            }
+            case ARG_CH_MASK: {
+                int chMaskIdx = atoi(optarg);
+                if (chMaskIdx < 0 or chMaskIdx > kPreProcConfigChMaskCount) {
+                    ALOGE("Channel Mask index not in correct range\n");
+                    printUsage();
+                    return EXIT_FAILURE;
+                }
+                preProcCfgParams.chMask = kPreProcConfigChMask[chMaskIdx];
+                break;
+            }
+            case ARG_AGC_TGT_LVL: {
+                preProcCfgParams.agcTargetLevel = atoi(optarg);
+                break;
+            }
+            case ARG_AGC_COMP_LVL: {
+                preProcCfgParams.agcCompLevel = atoi(optarg);
+                break;
+            }
+            case ARG_AGC2_GAIN: {
+                preProcCfgParams.agc2Gain = atof(optarg);
+                break;
+            }
+            case ARG_AGC2_LVL: {
+                preProcCfgParams.agc2Level = atoi(optarg);
+                break;
+            }
+            case ARG_AGC2_SAT_MGN: {
+                preProcCfgParams.agc2SaturationMargin = atof(optarg);
+                break;
+            }
+            case ARG_AEC_DELAY: {
+                preProcCfgParams.aecDelay = atoi(optarg);
+                break;
+            }
+            case ARG_NS_LVL: {
+                preProcCfgParams.nsLevel = atoi(optarg);
+                break;
+            }
+            default:
+                break;
+        }
     }
-    audio_buffer_t inputBuffer, outputBuffer;
-    audio_buffer_t farInBuffer{};
-    inputBuffer.frameCount = samplesRead;
-    outputBuffer.frameCount = samplesRead;
-    inputBuffer.s16 = in.data();
-    outputBuffer.s16 = out.data();
 
-    if (farFp != nullptr) {
-      samplesRead = fread(farIn.data(), ioFrameSize, frameLength, farFp.get());
-      if (samplesRead == 0) {
-        break;
-      }
-      farInBuffer.frameCount = samplesRead;
-      farInBuffer.s16 = farIn.data();
+    if (inputFile == nullptr) {
+        ALOGE("Error: missing input file\n");
+        printUsage();
+        return EXIT_FAILURE;
+    }
+
+    std::unique_ptr<FILE, decltype(&fclose)> inputFp(fopen(inputFile, "rb"), &fclose);
+    if (inputFp == nullptr) {
+        ALOGE("Cannot open input file %s\n", inputFile);
+        return EXIT_FAILURE;
+    }
+
+    std::unique_ptr<FILE, decltype(&fclose)> farFp(fopen(farFile, "rb"), &fclose);
+    std::unique_ptr<FILE, decltype(&fclose)> outputFp(fopen(outputFile, "wb"), &fclose);
+    if (effectEn[PREPROC_AEC]) {
+        if (farFile == nullptr) {
+            ALOGE("Far end signal file required for echo cancellation \n");
+            return EXIT_FAILURE;
+        }
+        if (farFp == nullptr) {
+            ALOGE("Cannot open far end stream file %s\n", farFile);
+            return EXIT_FAILURE;
+        }
+        struct stat statInput, statFar;
+        (void)fstat(fileno(inputFp.get()), &statInput);
+        (void)fstat(fileno(farFp.get()), &statFar);
+        if (statInput.st_size != statFar.st_size) {
+            ALOGE("Near and far end signals are of different sizes");
+            return EXIT_FAILURE;
+        }
+    }
+    if (outputFile != nullptr && outputFp == nullptr) {
+        ALOGE("Cannot open output file %s\n", outputFile);
+        return EXIT_FAILURE;
+    }
+
+    int32_t sessionId = 1;
+    int32_t ioId = 1;
+    effect_handle_t effectHandle[PREPROC_NUM_EFFECTS] = {nullptr};
+    effect_config_t config;
+    config.inputCfg.samplingRate = config.outputCfg.samplingRate = preProcCfgParams.samplingFreq;
+    config.inputCfg.channels = config.outputCfg.channels = preProcCfgParams.chMask;
+    config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+
+    // Create all the effect handles
+    for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
+        if (int status = preProcCreateEffect(&effectHandle[i], i, &config, sessionId, ioId);
+            status != 0) {
+            ALOGE("Create effect call returned error %i", status);
+            return EXIT_FAILURE;
+        }
     }
 
     for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
-      if (effectEn[i] == 1) {
-        if (i == PREPROC_AEC) {
-          if (int status =
-                  preProcSetConfigParam(AEC_PARAM_ECHO_DELAY, (uint32_t)preProcCfgParams.aecDelay,
-                                        effectHandle[PREPROC_AEC]);
-              status != 0) {
-            ALOGE("preProcSetConfigParam returned Error %d\n", status);
-            return EXIT_FAILURE;
-          }
+        if (effectEn[i] == 1) {
+            int reply = 0;
+            uint32_t replySize = sizeof(reply);
+            (*effectHandle[i])
+                    ->command(effectHandle[i], EFFECT_CMD_ENABLE, 0, nullptr, &replySize, &reply);
+            if (reply != 0) {
+                ALOGE("Command enable call returned error %d\n", reply);
+                return EXIT_FAILURE;
+            }
         }
-        if (int status =
-                (*effectHandle[i])->process(effectHandle[i], &inputBuffer, &outputBuffer);
+    }
+
+    // Set Config Params of the effects
+    if (effectEn[PREPROC_AGC]) {
+        if (int status = preProcSetConfigParam(AGC_PARAM_TARGET_LEVEL,
+                                               (uint32_t)preProcCfgParams.agcTargetLevel,
+                                               effectHandle[PREPROC_AGC]);
             status != 0) {
-          ALOGE("\nError: Process i = %d returned with error %d\n", i, status);
-          return EXIT_FAILURE;
-        }
-        if (i == PREPROC_AEC) {
-          if (int status = (*effectHandle[i])
-                               ->process_reverse(effectHandle[i], &farInBuffer, &outputBuffer);
-              status != 0) {
-            ALOGE("\nError: Process reverse i = %d returned with error %d\n", i, status);
+            ALOGE("Invalid AGC Target Level. Error %d\n", status);
             return EXIT_FAILURE;
-          }
         }
-      }
+        if (int status = preProcSetConfigParam(AGC_PARAM_COMP_GAIN,
+                                               (uint32_t)preProcCfgParams.agcCompLevel,
+                                               effectHandle[PREPROC_AGC]);
+            status != 0) {
+            ALOGE("Invalid AGC Comp Gain. Error %d\n", status);
+            return EXIT_FAILURE;
+        }
     }
-    if (outputFp != nullptr) {
-      size_t samplesWritten =
-          fwrite(out.data(), ioFrameSize, outputBuffer.frameCount, outputFp.get());
-      if (samplesWritten != outputBuffer.frameCount) {
-        ALOGE("\nError: Output file writing failed");
-        break;
-      }
+    if (effectEn[PREPROC_AGC2]) {
+        if (int status = preProcSetConfigParam(AGC2_PARAM_FIXED_DIGITAL_GAIN,
+                                               (float)preProcCfgParams.agc2Gain,
+                                               effectHandle[PREPROC_AGC2]);
+            status != 0) {
+            ALOGE("Invalid AGC2 Fixed Digital Gain. Error %d\n", status);
+            return EXIT_FAILURE;
+        }
+        if (int status = preProcSetConfigParam(AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR,
+                                               (uint32_t)preProcCfgParams.agc2Level,
+                                               effectHandle[PREPROC_AGC2]);
+            status != 0) {
+            ALOGE("Invalid AGC2 Level Estimator. Error %d\n", status);
+            return EXIT_FAILURE;
+        }
+        if (int status = preProcSetConfigParam(AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN,
+                                               (float)preProcCfgParams.agc2SaturationMargin,
+                                               effectHandle[PREPROC_AGC2]);
+            status != 0) {
+            ALOGE("Invalid AGC2 Saturation Margin. Error %d\n", status);
+            return EXIT_FAILURE;
+        }
     }
-    frameCounter += frameLength;
-  }
-  // Release all the effect handles created
-  for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
-    if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle[i]);
-        status != 0) {
-      ALOGE("Audio Preprocessing release returned an error = %d\n", status);
-      return EXIT_FAILURE;
+    if (effectEn[PREPROC_NS]) {
+        if (int status = preProcSetConfigParam(NS_PARAM_LEVEL, (uint32_t)preProcCfgParams.nsLevel,
+                                               effectHandle[PREPROC_NS]);
+            status != 0) {
+            ALOGE("Invalid Noise Suppression level Error %d\n", status);
+            return EXIT_FAILURE;
+        }
     }
-  }
-  return EXIT_SUCCESS;
+
+    // Process Call
+    const int frameLength = (int)(preProcCfgParams.samplingFreq * kTenMilliSecVal);
+    const int ioChannelCount = audio_channel_count_from_in_mask(preProcCfgParams.chMask);
+    const int ioFrameSize = ioChannelCount * sizeof(short);
+    int frameCounter = 0;
+    while (true) {
+        std::vector<short> in(frameLength * ioChannelCount);
+        std::vector<short> out(frameLength * ioChannelCount);
+        std::vector<short> farIn(frameLength * ioChannelCount);
+        size_t samplesRead = fread(in.data(), ioFrameSize, frameLength, inputFp.get());
+        if (samplesRead == 0) {
+            break;
+        }
+        audio_buffer_t inputBuffer, outputBuffer;
+        audio_buffer_t farInBuffer{};
+        inputBuffer.frameCount = samplesRead;
+        outputBuffer.frameCount = samplesRead;
+        inputBuffer.s16 = in.data();
+        outputBuffer.s16 = out.data();
+
+        if (farFp != nullptr) {
+            samplesRead = fread(farIn.data(), ioFrameSize, frameLength, farFp.get());
+            if (samplesRead == 0) {
+                break;
+            }
+            farInBuffer.frameCount = samplesRead;
+            farInBuffer.s16 = farIn.data();
+        }
+
+        for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
+            if (effectEn[i] == 1) {
+                if (i == PREPROC_AEC) {
+                    if (int status = preProcSetConfigParam(AEC_PARAM_ECHO_DELAY,
+                                                           (uint32_t)preProcCfgParams.aecDelay,
+                                                           effectHandle[PREPROC_AEC]);
+                        status != 0) {
+                        ALOGE("preProcSetConfigParam returned Error %d\n", status);
+                        return EXIT_FAILURE;
+                    }
+                }
+                if (int status = (*effectHandle[i])
+                                         ->process(effectHandle[i], &inputBuffer, &outputBuffer);
+                    status != 0) {
+                    ALOGE("\nError: Process i = %d returned with error %d\n", i, status);
+                    return EXIT_FAILURE;
+                }
+                if (i == PREPROC_AEC) {
+                    if (int status = (*effectHandle[i])
+                                             ->process_reverse(effectHandle[i], &farInBuffer,
+                                                               &outputBuffer);
+                        status != 0) {
+                        ALOGE("\nError: Process reverse i = %d returned with error %d\n", i,
+                              status);
+                        return EXIT_FAILURE;
+                    }
+                }
+            }
+        }
+        if (outputFp != nullptr) {
+            size_t samplesWritten =
+                    fwrite(out.data(), ioFrameSize, outputBuffer.frameCount, outputFp.get());
+            if (samplesWritten != outputBuffer.frameCount) {
+                ALOGE("\nError: Output file writing failed");
+                break;
+            }
+        }
+        frameCounter += frameLength;
+    }
+    // Release all the effect handles created
+    for (int i = 0; i < PREPROC_NUM_EFFECTS; i++) {
+        if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle[i]);
+            status != 0) {
+            ALOGE("Audio Preprocessing release returned an error = %d\n", status);
+            return EXIT_FAILURE;
+        }
+    }
+    return EXIT_SUCCESS;
 }
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 1a7eb6f..f68f65d 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -5,12 +5,14 @@
 
     export_include_dirs: ["include"],
     header_libs: [
+        "av-headers",
         "libbase_headers",
         "libgui_headers",
         "libstagefright_headers",
         "media_plugin_headers",
     ],
     export_header_lib_headers: [
+        "av-headers",
         "libgui_headers",
         "libstagefright_headers",
         "media_plugin_headers",
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index 39caf53..7ed76d8 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -38,7 +38,8 @@
     FLAGS,
     SETMEDIACAS,
     NAME,
-    GETMETRICS
+    GETMETRICS,
+    SETENTRYPOINT
 };
 
 class BpMediaExtractor : public BpInterface<IMediaExtractor> {
@@ -142,6 +143,13 @@
         }
         return nm;
     }
+
+    virtual status_t setEntryPoint(EntryPoint entryPoint) {
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
+        data.writeInt32(static_cast<int32_t>(entryPoint));
+        return remote()->transact(SETENTRYPOINT, data, &reply);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(MediaExtractor, "android.media.IMediaExtractor");
@@ -232,6 +240,16 @@
             reply->writeString8(nm);
             return NO_ERROR;
         }
+        case SETENTRYPOINT: {
+            ALOGV("setEntryPoint");
+            CHECK_INTERFACE(IMediaExtractor, data, reply);
+            int32_t entryPoint;
+            status_t err = data.readInt32(&entryPoint);
+            if (err == OK) {
+                setEntryPoint(EntryPoint(entryPoint));
+            }
+            return err;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/include/android/IMediaExtractor.h b/media/libmedia/include/android/IMediaExtractor.h
index 3e035ad..f9cafde 100644
--- a/media/libmedia/include/android/IMediaExtractor.h
+++ b/media/libmedia/include/android/IMediaExtractor.h
@@ -63,6 +63,15 @@
     virtual status_t setMediaCas(const HInterfaceToken &casToken) = 0;
 
     virtual String8 name() = 0;
+
+    enum class EntryPoint {
+        SDK = 1,
+        NDK_WITH_JVM = 2,
+        NDK_NO_JVM = 3,
+        OTHER = 4,
+    };
+
+    virtual status_t setEntryPoint(EntryPoint entryPoint) = 0;
 };
 
 
diff --git a/media/libmediahelper/Android.bp b/media/libmediahelper/Android.bp
index 0779a8e..849debf 100644
--- a/media/libmediahelper/Android.bp
+++ b/media/libmediahelper/Android.bp
@@ -9,6 +9,12 @@
             enabled: false,
         },
     },
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.bluetooth.updatable",
+        "com.android.media",
+        "com.android.media.swcodec",
+    ],
 }
 
 cc_library {
@@ -20,7 +26,7 @@
     double_loadable: true,
     srcs: [
         "AudioParameter.cpp",
-        "AudioSanitizer.cpp",
+        "AudioValidator.cpp",
         "TypeConverter.cpp",
     ],
     cflags: [
diff --git a/media/libmediahelper/AudioSanitizer.cpp b/media/libmediahelper/AudioSanitizer.cpp
deleted file mode 100644
index 44ca956..0000000
--- a/media/libmediahelper/AudioSanitizer.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.
- */
-
-#include <media/AudioSanitizer.h>
-
-namespace android {
-
-    /** returns true if string overflow was prevented by zero termination */
-template <size_t size>
-bool preventStringOverflow(char (&s)[size]) {
-    if (strnlen(s, size) < size) return false;
-    s[size - 1] = '\0';
-    return true;
-}
-
-status_t safetyNetLog(status_t status, const char *bugNumber) {
-    if (status != NO_ERROR && bugNumber != nullptr) {
-        android_errorWriteLog(0x534e4554, bugNumber); // SafetyNet logging
-    }
-    return status;
-}
-
-status_t AudioSanitizer::sanitizeAudioAttributes(
-        audio_attributes_t *attr, const char *bugNumber)
-{
-    status_t status = NO_ERROR;
-    const size_t tagsMaxSize = AUDIO_ATTRIBUTES_TAGS_MAX_SIZE;
-    if (strnlen(attr->tags, tagsMaxSize) >= tagsMaxSize) {
-        status = BAD_VALUE;
-    }
-    attr->tags[tagsMaxSize - 1] = '\0';
-    return safetyNetLog(status, bugNumber);
-}
-
-/** returns BAD_VALUE if sanitization was required. */
-status_t AudioSanitizer::sanitizeEffectDescriptor(
-        effect_descriptor_t *desc, const char *bugNumber)
-{
-    status_t status = NO_ERROR;
-    if (preventStringOverflow(desc->name)
-        | /* always */ preventStringOverflow(desc->implementor)) {
-        status = BAD_VALUE;
-    }
-    return safetyNetLog(status, bugNumber);
-}
-
-/** returns BAD_VALUE if sanitization was required. */
-status_t AudioSanitizer::sanitizeAudioPortConfig(
-        struct audio_port_config *config, const char *bugNumber)
-{
-    status_t status = NO_ERROR;
-    if (config->type == AUDIO_PORT_TYPE_DEVICE &&
-        preventStringOverflow(config->ext.device.address)) {
-        status = BAD_VALUE;
-    }
-    return safetyNetLog(status, bugNumber);
-}
-
-/** returns BAD_VALUE if sanitization was required. */
-status_t AudioSanitizer::sanitizeAudioPort(
-        struct audio_port *port, const char *bugNumber)
-{
-    status_t status = NO_ERROR;
-    if (preventStringOverflow(port->name)) {
-        status = BAD_VALUE;
-    }
-    if (sanitizeAudioPortConfig(&port->active_config) != NO_ERROR) {
-        status = BAD_VALUE;
-    }
-    if (port->type == AUDIO_PORT_TYPE_DEVICE &&
-        preventStringOverflow(port->ext.device.address)) {
-        status = BAD_VALUE;
-    }
-    return safetyNetLog(status, bugNumber);
-}
-
-/** returns BAD_VALUE if sanitization was required. */
-status_t AudioSanitizer::sanitizeAudioPatch(
-        struct audio_patch *patch, const char *bugNumber)
-{
-    status_t status = NO_ERROR;
-    if (patch->num_sources > AUDIO_PATCH_PORTS_MAX) {
-        patch->num_sources = AUDIO_PATCH_PORTS_MAX;
-        status = BAD_VALUE;
-    }
-    if (patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
-        patch->num_sinks = AUDIO_PATCH_PORTS_MAX;
-        status = BAD_VALUE;
-    }
-    for (size_t i = 0; i < patch->num_sources; i++) {
-        if (sanitizeAudioPortConfig(&patch->sources[i]) != NO_ERROR) {
-            status = BAD_VALUE;
-        }
-    }
-    for (size_t i = 0; i < patch->num_sinks; i++) {
-        if (sanitizeAudioPortConfig(&patch->sinks[i]) != NO_ERROR) {
-            status = BAD_VALUE;
-        }
-    }
-    return safetyNetLog(status, bugNumber);
-}
-
-}; // namespace android
diff --git a/media/libmediahelper/AudioValidator.cpp b/media/libmediahelper/AudioValidator.cpp
new file mode 100644
index 0000000..e2fd8ae
--- /dev/null
+++ b/media/libmediahelper/AudioValidator.cpp
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+#include <media/AudioValidator.h>
+
+namespace android {
+
+/** returns true if string is overflow */
+template <size_t size>
+bool checkStringOverflow(const char (&s)[size]) {
+    return strnlen(s, size) >= size;
+}
+
+status_t safetyNetLog(status_t status, std::string_view bugNumber) {
+    if (status != NO_ERROR && !bugNumber.empty()) {
+        android_errorWriteLog(0x534e4554, bugNumber.data()); // SafetyNet logging
+    }
+    return status;
+}
+
+status_t AudioValidator::validateAudioAttributes(
+        const audio_attributes_t& attr, std::string_view bugNumber)
+{
+    status_t status = NO_ERROR;
+    const size_t tagsMaxSize = AUDIO_ATTRIBUTES_TAGS_MAX_SIZE;
+    if (strnlen(attr.tags, tagsMaxSize) >= tagsMaxSize) {
+        status = BAD_VALUE;
+    }
+    return safetyNetLog(status, bugNumber);
+}
+
+status_t AudioValidator::validateEffectDescriptor(
+        const effect_descriptor_t& desc, std::string_view bugNumber)
+{
+    status_t status = NO_ERROR;
+    if (checkStringOverflow(desc.name)
+        | /* always */ checkStringOverflow(desc.implementor)) {
+        status = BAD_VALUE;
+    }
+    return safetyNetLog(status, bugNumber);
+}
+
+status_t AudioValidator::validateAudioPortConfig(
+        const struct audio_port_config& config, std::string_view bugNumber)
+{
+    status_t status = NO_ERROR;
+    if (config.type == AUDIO_PORT_TYPE_DEVICE &&
+        checkStringOverflow(config.ext.device.address)) {
+        status = BAD_VALUE;
+    }
+    return safetyNetLog(status, bugNumber);
+}
+
+namespace {
+
+template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value
+                                    || std::is_same<T, struct audio_port_v7>::value, int> = 0>
+static status_t validateAudioPortInternal(const T& port, std::string_view bugNumber = {}) {
+    status_t status = NO_ERROR;
+    if (checkStringOverflow(port.name)) {
+        status = BAD_VALUE;
+    }
+    if (AudioValidator::validateAudioPortConfig(port.active_config) != NO_ERROR) {
+        status = BAD_VALUE;
+    }
+    if (port.type == AUDIO_PORT_TYPE_DEVICE &&
+        checkStringOverflow(port.ext.device.address)) {
+        status = BAD_VALUE;
+    }
+    return safetyNetLog(status, bugNumber);
+}
+
+} // namespace
+
+status_t AudioValidator::validateAudioPort(
+        const struct audio_port& port, std::string_view bugNumber)
+{
+    return validateAudioPortInternal(port, bugNumber);
+}
+
+status_t AudioValidator::validateAudioPort(
+        const struct audio_port_v7& port, std::string_view bugNumber)
+{
+    return validateAudioPortInternal(port, bugNumber);
+}
+
+/** returns BAD_VALUE if sanitization was required. */
+status_t AudioValidator::validateAudioPatch(
+        const struct audio_patch& patch, std::string_view bugNumber)
+{
+    status_t status = NO_ERROR;
+    if (patch.num_sources > AUDIO_PATCH_PORTS_MAX) {
+        status = BAD_VALUE;
+    }
+    if (patch.num_sinks > AUDIO_PATCH_PORTS_MAX) {
+        status = BAD_VALUE;
+    }
+    for (size_t i = 0; i < patch.num_sources; i++) {
+        if (validateAudioPortConfig(patch.sources[i]) != NO_ERROR) {
+            status = BAD_VALUE;
+        }
+    }
+    for (size_t i = 0; i < patch.num_sinks; i++) {
+        if (validateAudioPortConfig(patch.sinks[i]) != NO_ERROR) {
+            status = BAD_VALUE;
+        }
+    }
+    return safetyNetLog(status, bugNumber);
+}
+
+}; // namespace android
diff --git a/media/libmediahelper/include/media/AudioSanitizer.h b/media/libmediahelper/include/media/AudioSanitizer.h
deleted file mode 100644
index 1475c7b..0000000
--- a/media/libmediahelper/include/media/AudioSanitizer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_AUDIO_SANITIZER_H_
-#define ANDROID_AUDIO_SANITIZER_H_
-
-#include <system/audio.h>
-#include <system/audio_effect.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-namespace android {
-
-class AudioSanitizer {
-public:
-    static status_t sanitizeAudioAttributes(
-            audio_attributes_t *attr, const char *bugNumber = nullptr);
-
-    static status_t sanitizeEffectDescriptor(
-            effect_descriptor_t *desc, const char *bugNumber = nullptr);
-
-    static status_t sanitizeAudioPortConfig(
-            struct audio_port_config *config, const char *bugNumber = nullptr);
-
-    static status_t sanitizeAudioPort(
-            struct audio_port *port, const char *bugNumber = nullptr);
-
-    static status_t sanitizeAudioPatch(
-            struct audio_patch *patch, const char *bugNumber = nullptr);
-};
-
-}; // namespace android
-
-#endif  /*ANDROID_AUDIO_SANITIZER_H_*/
diff --git a/media/libmediahelper/include/media/AudioValidator.h b/media/libmediahelper/include/media/AudioValidator.h
new file mode 100644
index 0000000..008868e
--- /dev/null
+++ b/media/libmediahelper/include/media/AudioValidator.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AUDIO_VALIDATOR_H_
+#define ANDROID_AUDIO_VALIDATOR_H_
+
+#include <system/audio.h>
+#include <system/audio_effect.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <string_view>
+
+namespace android {
+
+/**
+ * AudioValidator is a class to validate audio data in binder call. NO_ERROR will be returned only
+ * when there is no error with the data.
+ */
+class AudioValidator {
+public:
+    /**
+     * Return NO_ERROR only when there is no error with the given audio attributes.
+     * Otherwise, return BAD_VALUE.
+     */
+    static status_t validateAudioAttributes(
+            const audio_attributes_t& attr, std::string_view bugNumber = {});
+
+    /**
+     * Return NO_ERROR only when there is no error with the given effect descriptor.
+     * Otherwise, return BAD_VALUE.
+     */
+    static status_t validateEffectDescriptor(
+            const effect_descriptor_t& desc, std::string_view bugNumber = {});
+
+    /**
+     * Return NO_ERROR only when there is no error with the given audio port config.
+     * Otherwise, return BAD_VALUE.
+     */
+    static status_t validateAudioPortConfig(
+            const struct audio_port_config& config, std::string_view bugNumber = {});
+
+    /**
+     * Return NO_ERROR only when there is no error with the given audio port.
+     * Otherwise, return BAD_VALUE.
+     */
+    static status_t validateAudioPort(
+            const struct audio_port& port, std::string_view bugNumber = {});
+
+    /**
+     * Return NO_ERROR only when there is no error with the given audio_port_v7.
+     * Otherwise, return BAD_VALUE.
+     */
+    static status_t validateAudioPort(
+            const struct audio_port_v7& port, std::string_view ugNumber = {});
+
+    /**
+     * Return NO_ERROR only when there is no error with the given audio patch.
+     * Otherwise, return BAD_VALUE.
+     */
+    static status_t validateAudioPatch(
+            const struct audio_patch& patch, std::string_view bugNumber = {});
+};
+
+}; // namespace android
+
+#endif  /*ANDROID_AUDIO_VALIDATOR_H_*/
diff --git a/media/libmediahelper/tests/typeconverter_tests.cpp b/media/libmediahelper/tests/typeconverter_tests.cpp
index ab55c13..d7bfb89 100644
--- a/media/libmediahelper/tests/typeconverter_tests.cpp
+++ b/media/libmediahelper/tests/typeconverter_tests.cpp
@@ -19,21 +19,22 @@
 #define LOG_TAG "TypeConverter_Test"
 #include <log/log.h>
 
-#include <audio_policy_configuration_V7_0.h>
+#include <android_audio_policy_configuration_V7_0.h>
 #include <media/TypeConverter.h>
 #include <system/audio.h>
 #include <xsdc/XsdcSupport.h>
 
 using namespace android;
 namespace xsd {
-using namespace audio::policy::configuration::V7_0;
+using namespace android::audio::policy::configuration::V7_0;
 }
 
 TEST(TypeConverter, ParseChannelMasks) {
     for (const auto enumVal : xsdc_enum_range<xsd::AudioChannelMask>{}) {
         const std::string stringVal = toString(enumVal);
         audio_channel_mask_t channelMask = channelMaskFromString(stringVal);
-        EXPECT_EQ(stringVal != "AUDIO_CHANNEL_NONE", audio_channel_mask_is_valid(channelMask))
+        EXPECT_EQ(enumVal != xsd::AudioChannelMask::AUDIO_CHANNEL_NONE,
+                audio_channel_mask_is_valid(channelMask))
                 << "Validity of \"" << stringVal << "\" is not as expected";
     }
 }
@@ -67,7 +68,7 @@
             EXPECT_TRUE(ChannelIndexConverter::toString(channelMask, stringValBack))
                     << "Conversion of indexed channel mask " << channelMask << " failed";
             EXPECT_EQ(stringVal, stringValBack);
-        } else if (stringVal == "AUDIO_CHANNEL_NONE") {
+        } else if (stringVal == toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE)) {
             EXPECT_FALSE(InputChannelConverter::fromString(stringVal, channelMask))
                     << "Conversion of \"" << stringVal << "\" succeeded (as input channel mask)";
             EXPECT_FALSE(OutputChannelConverter::fromString(stringVal, channelMask))
@@ -86,6 +87,8 @@
             EXPECT_TRUE(ChannelIndexConverter::toString(channelMask, stringValBack))
                     << "Conversion of indexed channel mask " << channelMask << " failed";
             EXPECT_EQ(stringVal, stringValBack);
+        } else {
+            FAIL() << "Unrecognized channel mask \"" << stringVal << "\"";
         }
     }
 }
@@ -107,7 +110,7 @@
         std::string stringValBack;
         EXPECT_TRUE(DeviceConverter::fromString(stringVal, device))
                 << "Conversion of \"" << stringVal << "\" failed";
-        if (stringVal != "AUDIO_DEVICE_NONE") {
+        if (enumVal != xsd::AudioDevice::AUDIO_DEVICE_NONE) {
             EXPECT_TRUE(audio_is_input_device(device) || audio_is_output_device(device))
                     << "Device \"" << stringVal << "\" is neither input, nor output device";
         } else {
@@ -144,17 +147,19 @@
             EXPECT_TRUE(OutputDeviceConverter::fromString(stringValBack, deviceBack))
                     << "Conversion of \"" << stringValBack << "\" failed";
             EXPECT_EQ(device, deviceBack);
-        } else if (stringVal == "AUDIO_DEVICE_NONE") {
+        } else if (stringVal == toString(xsd::AudioDevice::AUDIO_DEVICE_NONE)) {
             EXPECT_FALSE(InputDeviceConverter::fromString(stringVal, device))
                     << "Conversion of \"" << stringVal << "\" succeeded (as input device)";
             EXPECT_FALSE(OutputDeviceConverter::fromString(stringVal, device))
                     << "Conversion of \"" << stringVal << "\" succeeded (as output device)";
             EXPECT_EQ(stringVal, toString(device));
+        } else {
+            FAIL() << "Unrecognized audio device \"" << stringVal << "\"";
         }
     }
 }
 
-TEST (TypeConverter, ParseInOutFlags) {
+TEST(TypeConverter, ParseInOutFlags) {
     for (const auto enumVal : xsdc_enum_range<xsd::AudioInOutFlag>{}) {
         const std::string stringVal = toString(enumVal);
         if (stringVal.find("_INPUT_FLAG_") != std::string::npos) {
diff --git a/media/libmediametrics/Android.bp b/media/libmediametrics/Android.bp
index a63b8b4..c2e1dc9 100644
--- a/media/libmediametrics/Android.bp
+++ b/media/libmediametrics/Android.bp
@@ -3,7 +3,7 @@
     export_include_dirs: ["include"],
 }
 
-cc_library_shared {
+cc_library {
     name: "libmediametrics",
 
     srcs: [
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 3e7ee50..b2f6407 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -134,6 +134,7 @@
 
     ALOGV("Constructor");
 
+    mMetricsItem = NULL;
     mAnalyticsDirty = false;
     reset();
 }
@@ -208,10 +209,12 @@
 void StagefrightRecorder::flushAndResetMetrics(bool reinitialize) {
     ALOGV("flushAndResetMetrics");
     // flush anything we have, maybe setup a new record
-    if (mAnalyticsDirty && mMetricsItem != NULL) {
-        updateMetrics();
-        if (mMetricsItem->count() > 0) {
-            mMetricsItem->selfrecord();
+    if (mMetricsItem != NULL) {
+        if (mAnalyticsDirty) {
+            updateMetrics();
+            if (mMetricsItem->count() > 0) {
+                mMetricsItem->selfrecord();
+            }
         }
         delete mMetricsItem;
         mMetricsItem = NULL;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 13e1933..6a8c708 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -922,6 +922,11 @@
             firstEntry = false;
             int64_t mediaTimeUs;
             CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
+            if (mediaTimeUs < 0) {
+                ALOGD("fillAudioBuffer: reset negative media time %.2f secs to zero",
+                       mediaTimeUs / 1E6);
+                mediaTimeUs = 0;
+            }
             ALOGV("fillAudioBuffer: rendering audio at media time %.2f secs", mediaTimeUs / 1E6);
             setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);
         }
diff --git a/media/libmediatranscoding/Android.bp b/media/libmediatranscoding/Android.bp
index 7329c63..1934820 100644
--- a/media/libmediatranscoding/Android.bp
+++ b/media/libmediatranscoding/Android.bp
@@ -48,7 +48,7 @@
     },
 }
 
-cc_library_shared {
+cc_library {
     name: "libmediatranscoding",
 
     srcs: [
@@ -60,12 +60,12 @@
     ],
 
     shared_libs: [
+        "libandroid",
         "libbinder_ndk",
         "libcutils",
         "liblog",
         "libutils",
         "libmediatranscoder",
-        "libbinder",
         "libmediandk",
     ],
     export_shared_lib_headers: [
@@ -76,7 +76,6 @@
 
     static_libs: [
         "mediatranscoding_aidl_interface-ndk_platform",
-        "resourcemanager_aidl_interface-ndk_platform",
         "resourceobserver_aidl_interface-ndk_platform",
     ],
 
diff --git a/media/libmediatranscoding/TEST_MAPPING b/media/libmediatranscoding/TEST_MAPPING
new file mode 100644
index 0000000..f8a9db9
--- /dev/null
+++ b/media/libmediatranscoding/TEST_MAPPING
@@ -0,0 +1,32 @@
+{
+    "presubmit": [
+        {
+            "name": "MediaSampleQueueTests"
+        },
+        {
+            "name": "MediaSampleReaderNDKTests"
+        },
+        {
+            "name": "MediaSampleWriterTests"
+        },
+        {
+            "name": "MediaTrackTranscoderTests"
+        },
+        {
+            "name": "MediaTranscoderTests"
+        },
+        {
+            "name": "PassthroughTrackTranscoderTests"
+        },
+        {
+            "name": "TranscodingClientManager_tests"
+        },
+        {
+            "name": "TranscodingSessionController_tests"
+        },
+        {
+            "name": "VideoTrackTranscoderTests"
+        }
+    ]
+}
+
diff --git a/media/libmediatranscoding/TranscoderWrapper.cpp b/media/libmediatranscoding/TranscoderWrapper.cpp
index fffbfe9..da86187 100644
--- a/media/libmediatranscoding/TranscoderWrapper.cpp
+++ b/media/libmediatranscoding/TranscoderWrapper.cpp
@@ -192,7 +192,7 @@
                                         new ndk::ScopedAParcel());
             }
 
-            callback->onResourceLost();
+            callback->onResourceLost(clientId, sessionId);
         } else {
             callback->onError(clientId, sessionId, toTranscodingError(err));
         }
@@ -347,7 +347,8 @@
     mCurrentClientId = clientId;
     mCurrentSessionId = sessionId;
     mTranscoderCb = std::make_shared<CallbackImpl>(shared_from_this(), clientId, sessionId);
-    mTranscoder = MediaTranscoder::create(mTranscoderCb, pausedState);
+    mTranscoder = MediaTranscoder::create(mTranscoderCb, request.clientPid, request.clientUid,
+                                          pausedState);
     if (mTranscoder == nullptr) {
         ALOGE("failed to create transcoder");
         return AMEDIA_ERROR_UNKNOWN;
diff --git a/media/libmediatranscoding/TranscodingClientManager.cpp b/media/libmediatranscoding/TranscodingClientManager.cpp
index ae1f7a5..c0cc862 100644
--- a/media/libmediatranscoding/TranscodingClientManager.cpp
+++ b/media/libmediatranscoding/TranscodingClientManager.cpp
@@ -20,6 +20,7 @@
 #include <aidl/android/media/BnTranscodingClient.h>
 #include <aidl/android/media/IMediaTranscodingService.h>
 #include <android/binder_ibinder.h>
+#include <android/permission_manager.h>
 #include <inttypes.h>
 #include <media/TranscodingClientManager.h>
 #include <media/TranscodingRequest.h>
@@ -27,15 +28,11 @@
 #include <private/android_filesystem_config.h>
 #include <utils/Log.h>
 #include <utils/String16.h>
+
 namespace android {
 
 static_assert(sizeof(ClientIdType) == sizeof(void*), "ClientIdType should be pointer-sized");
 
-static constexpr const char* MEDIA_PROVIDER_PKG_NAMES[] = {
-        "com.android.providers.media.module",
-        "com.google.android.providers.media.module",
-};
-
 using ::aidl::android::media::BnTranscodingClient;
 using ::aidl::android::media::IMediaTranscodingService;  // For service error codes
 using ::aidl::android::media::TranscodingRequestParcel;
@@ -137,7 +134,7 @@
         in_clientUid = callingUid;
     } else if (in_clientUid < 0) {
         return Status::ok();
-    } else if (in_clientUid != callingUid && !owner->isTrustedCallingUid(callingUid)) {
+    } else if (in_clientUid != callingUid && !owner->isTrustedCaller(callingPid, callingUid)) {
         ALOGE("MediaTranscodingService::registerClient rejected (clientPid %d, clientUid %d) "
               "(don't trust callingUid %d)",
               in_clientPid, in_clientUid, callingUid);
@@ -154,7 +151,7 @@
         in_clientPid = callingPid;
     } else if (in_clientPid < 0) {
         return Status::ok();
-    } else if (in_clientPid != callingPid && !owner->isTrustedCallingUid(callingUid)) {
+    } else if (in_clientPid != callingPid && !owner->isTrustedCaller(callingPid, callingUid)) {
         ALOGE("MediaTranscodingService::registerClient rejected (clientPid %d, clientUid %d) "
               "(don't trust callingUid %d)",
               in_clientPid, in_clientUid, callingUid);
@@ -266,14 +263,8 @@
       : mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)),
         mSessionController(controller) {
     ALOGD("TranscodingClientManager started");
-    uid_t mpuid;
-    for (const char* pkgName : MEDIA_PROVIDER_PKG_NAMES) {
-        if (TranscodingUidPolicy::getUidForPackage(String16(pkgName), mpuid) == NO_ERROR) {
-            ALOGI("Found %s's uid: %d", pkgName, mpuid);
-            mMediaProviderUid.insert(mpuid);
-        } else {
-            ALOGW("Couldn't get uid for %s.", pkgName);
-        }
+    for (uid_t uid : {AID_ROOT, AID_SYSTEM, AID_SHELL, AID_MEDIA}) {
+        mTrustedUids.insert(uid);
     }
 }
 
@@ -305,20 +296,20 @@
     write(fd, result.string(), result.size());
 }
 
-bool TranscodingClientManager::isTrustedCallingUid(uid_t uid) {
-    if (uid > 0 && mMediaProviderUid.count(uid) > 0) {
+bool TranscodingClientManager::isTrustedCaller(pid_t pid, uid_t uid) {
+    if (uid > 0 && mTrustedUids.count(uid) > 0) {
         return true;
     }
 
-    switch (uid) {
-    case AID_ROOT:  // root user
-    case AID_SYSTEM:
-    case AID_SHELL:
-    case AID_MEDIA:  // mediaserver
+    int32_t result;
+    if (APermissionManager_checkPermission("android.permission.WRITE_MEDIA_STORAGE", pid, uid,
+                                           &result) == PERMISSION_MANAGER_STATUS_OK &&
+        result == PERMISSION_MANAGER_PERMISSION_GRANTED) {
+        mTrustedUids.insert(uid);
         return true;
-    default:
-        return false;
     }
+
+    return false;
 }
 
 status_t TranscodingClientManager::addClient(
diff --git a/media/libmediatranscoding/TranscodingResourcePolicy.cpp b/media/libmediatranscoding/TranscodingResourcePolicy.cpp
index 4fd8338..af53f64 100644
--- a/media/libmediatranscoding/TranscodingResourcePolicy.cpp
+++ b/media/libmediatranscoding/TranscodingResourcePolicy.cpp
@@ -21,7 +21,6 @@
 #include <aidl/android/media/IResourceObserverService.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
-#include <binder/IServiceManager.h>
 #include <media/TranscodingResourcePolicy.h>
 #include <utils/Log.h>
 
@@ -41,7 +40,7 @@
 }
 
 struct TranscodingResourcePolicy::ResourceObserver : public BnResourceObserver {
-    explicit ResourceObserver(TranscodingResourcePolicy* owner) : mOwner(owner), mPid(getpid()) {}
+    explicit ResourceObserver(TranscodingResourcePolicy* owner) : mOwner(owner) {}
 
     // IResourceObserver
     ::ndk::ScopedAStatus onStatusChanged(
@@ -51,12 +50,12 @@
               ::aidl::android::media::toString(event).c_str(), uid, pid,
               toString(observables[0]).c_str());
 
-        // Only report kIdle event for codec resources from other processes.
-        if (((uint64_t)event & (uint64_t)MediaObservableEvent::kIdle) != 0 && (pid != mPid)) {
+        // Only report kIdle event.
+        if (((uint64_t)event & (uint64_t)MediaObservableEvent::kIdle) != 0) {
             for (auto& observable : observables) {
                 if (observable.type == MediaObservableType::kVideoSecureCodec ||
                     observable.type == MediaObservableType::kVideoNonSecureCodec) {
-                    mOwner->onResourceAvailable();
+                    mOwner->onResourceAvailable(pid);
                     break;
                 }
             }
@@ -65,7 +64,6 @@
     }
 
     TranscodingResourcePolicy* mOwner;
-    const pid_t mPid;
 };
 
 // static
@@ -83,7 +81,9 @@
 }
 
 TranscodingResourcePolicy::TranscodingResourcePolicy()
-      : mRegistered(false), mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)) {
+      : mRegistered(false),
+        mResourceLostPid(-1),
+        mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)) {
     registerSelf();
 }
 
@@ -155,11 +155,20 @@
     mResourcePolicyCallback = cb;
 }
 
-void TranscodingResourcePolicy::onResourceAvailable() {
+void TranscodingResourcePolicy::setPidResourceLost(pid_t pid) {
+    std::scoped_lock lock{mCallbackLock};
+    mResourceLostPid = pid;
+}
+
+void TranscodingResourcePolicy::onResourceAvailable(pid_t pid) {
     std::shared_ptr<ResourcePolicyCallbackInterface> cb;
     {
         std::scoped_lock lock{mCallbackLock};
-        cb = mResourcePolicyCallback.lock();
+        // Only callback if codec resource is released from other processes.
+        if (mResourceLostPid != -1 && mResourceLostPid != pid) {
+            cb = mResourcePolicyCallback.lock();
+            mResourceLostPid = -1;
+        }
     }
 
     if (cb != nullptr) {
diff --git a/media/libmediatranscoding/TranscodingSessionController.cpp b/media/libmediatranscoding/TranscodingSessionController.cpp
index 1c3ee7e..49a7083 100644
--- a/media/libmediatranscoding/TranscodingSessionController.cpp
+++ b/media/libmediatranscoding/TranscodingSessionController.cpp
@@ -485,29 +485,34 @@
     });
 }
 
-void TranscodingSessionController::onResourceLost() {
+void TranscodingSessionController::onResourceLost(ClientIdType clientId, SessionIdType sessionId) {
     ALOGI("%s", __FUNCTION__);
 
-    std::scoped_lock lock{mLock};
-
-    if (mResourceLost) {
-        return;
-    }
-
-    // If we receive a resource loss event, the TranscoderLibrary already paused
-    // the transcoding, so we don't need to call onPaused to notify it to pause.
-    // Only need to update the session state here.
-    if (mCurrentSession != nullptr && mCurrentSession->state == Session::RUNNING) {
-        mCurrentSession->state = Session::PAUSED;
-        // Notify the client as a paused event.
-        auto clientCallback = mCurrentSession->callback.lock();
-        if (clientCallback != nullptr) {
-            clientCallback->onTranscodingPaused(mCurrentSession->key.second);
+    notifyClient(clientId, sessionId, "resource_lost", [=](const SessionKeyType& sessionKey) {
+        if (mResourceLost) {
+            return;
         }
-    }
-    mResourceLost = true;
 
-    validateState_l();
+        Session* resourceLostSession = &mSessionMap[sessionKey];
+        if (resourceLostSession->state != Session::RUNNING) {
+            ALOGW("session %s lost resource but is no longer running",
+                    sessionToString(sessionKey).c_str());
+            return;
+        }
+        // If we receive a resource loss event, the transcoder already paused the transcoding,
+        // so we don't need to call onPaused() to pause it. However, we still need to notify
+        // the client and update the session state here.
+        resourceLostSession->state = Session::PAUSED;
+        // Notify the client as a paused event.
+        auto clientCallback = resourceLostSession->callback.lock();
+        if (clientCallback != nullptr) {
+            clientCallback->onTranscodingPaused(sessionKey.second);
+        }
+        mResourcePolicy->setPidResourceLost(resourceLostSession->request.clientPid);
+        mResourceLost = true;
+
+        validateState_l();
+    });
 }
 
 void TranscodingSessionController::onTopUidsChanged(const std::unordered_set<uid_t>& uids) {
diff --git a/media/libmediatranscoding/TranscodingUidPolicy.cpp b/media/libmediatranscoding/TranscodingUidPolicy.cpp
index 084a871..a725387 100644
--- a/media/libmediatranscoding/TranscodingUidPolicy.cpp
+++ b/media/libmediatranscoding/TranscodingUidPolicy.cpp
@@ -17,16 +17,9 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "TranscodingUidPolicy"
 
-#include <aidl/android/media/BnResourceManagerClient.h>
-#include <aidl/android/media/IResourceManagerService.h>
+#include <android/activity_manager.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
-#include <android/content/pm/IPackageManagerNative.h>
-#include <binder/ActivityManager.h>
-#include <binder/IServiceManager.h>
-#include <binder/PermissionController.h>
-#include <cutils/misc.h>  // FIRST_APPLICATION_UID
-#include <cutils/multiuser.h>
 #include <inttypes.h>
 #include <media/TranscodingUidPolicy.h>
 #include <utils/Log.h>
@@ -36,158 +29,45 @@
 namespace android {
 
 constexpr static uid_t OFFLINE_UID = -1;
-constexpr static const char* kTranscodingTag = "transcoding";
-
-/*
- * The OOM score we're going to ask ResourceManager to use for our native transcoding
- * service. ResourceManager issues reclaims based on these scores. It gets the scores
- * from ActivityManagerService, which doesn't track native services. The values of the
- * OOM scores are defined in:
- * frameworks/base/services/core/java/com/android/server/am/ProcessList.java
- * We use SERVICE_ADJ which is lower priority than an app possibly visible to the
- * user, but higher priority than a cached app (which could be killed without disruption
- * to the user).
- */
-constexpr static int32_t SERVICE_ADJ = 500;
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::media::BnResourceManagerClient;
-using aidl::android::media::IResourceManagerService;
-
-/*
- * Placeholder ResourceManagerClient for registering process info override
- * with the IResourceManagerService. This is only used as a token by the service
- * to get notifications about binder death, not used for reclaiming resources.
- */
-struct TranscodingUidPolicy::ResourceManagerClient : public BnResourceManagerClient {
-    explicit ResourceManagerClient() = default;
-
-    Status reclaimResource(bool* _aidl_return) override {
-        *_aidl_return = false;
-        return Status::ok();
-    }
-
-    Status getName(::std::string* _aidl_return) override {
-        _aidl_return->clear();
-        return Status::ok();
-    }
-
-    virtual ~ResourceManagerClient() = default;
-};
-
-struct TranscodingUidPolicy::UidObserver : public BnUidObserver,
-                                           public virtual IBinder::DeathRecipient {
-    explicit UidObserver(TranscodingUidPolicy* owner) : mOwner(owner) {}
-
-    // IUidObserver
-    void onUidGone(uid_t uid, bool disabled) override;
-    void onUidActive(uid_t uid) override;
-    void onUidIdle(uid_t uid, bool disabled) override;
-    void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq,
-                           int32_t capability) override;
-
-    // IBinder::DeathRecipient implementation
-    void binderDied(const wp<IBinder>& who) override;
-
-    TranscodingUidPolicy* mOwner;
-};
-
-void TranscodingUidPolicy::UidObserver::onUidGone(uid_t uid __unused, bool disabled __unused) {}
-
-void TranscodingUidPolicy::UidObserver::onUidActive(uid_t uid __unused) {}
-
-void TranscodingUidPolicy::UidObserver::onUidIdle(uid_t uid __unused, bool disabled __unused) {}
-
-void TranscodingUidPolicy::UidObserver::onUidStateChanged(uid_t uid, int32_t procState,
-                                                          int64_t procStateSeq __unused,
-                                                          int32_t capability __unused) {
-    mOwner->onUidStateChanged(uid, procState);
-}
-
-void TranscodingUidPolicy::UidObserver::binderDied(const wp<IBinder>& /*who*/) {
-    ALOGW("TranscodingUidPolicy: ActivityManager has died");
-    // TODO(chz): this is a rare event (since if the AMS is dead, the system is
-    // probably dead as well). But we should try to reconnect.
-    mOwner->setUidObserverRegistered(false);
-}
-
-////////////////////////////////////////////////////////////////////////////
-
-//static
-status_t TranscodingUidPolicy::getUidForPackage(String16 packageName, /*inout*/ uid_t& uid) {
-    PermissionController pc;
-    uid = pc.getPackageUid(packageName, 0);
-    if (uid <= 0) {
-        ALOGE("Unknown package: '%s'", String8(packageName).string());
-        return BAD_VALUE;
-    }
-
-    uid = multiuser_get_uid(0 /*userId*/, uid);
-    return NO_ERROR;
-}
+constexpr static int32_t IMPORTANCE_UNKNOWN = INT32_MAX;
 
 TranscodingUidPolicy::TranscodingUidPolicy()
-      : mAm(std::make_shared<ActivityManager>()),
-        mUidObserver(new UidObserver(this)),
+      : mUidObserver(nullptr),
         mRegistered(false),
-        mTopUidState(ActivityManager::PROCESS_STATE_UNKNOWN) {
+        mTopUidState(IMPORTANCE_UNKNOWN) {
     registerSelf();
-    setProcessInfoOverride();
 }
 
 TranscodingUidPolicy::~TranscodingUidPolicy() {
     unregisterSelf();
 }
 
+void TranscodingUidPolicy::OnUidImportance(uid_t uid, int32_t uidImportance, void* cookie) {
+    TranscodingUidPolicy* owner = reinterpret_cast<TranscodingUidPolicy*>(cookie);
+    owner->onUidStateChanged(uid, uidImportance);
+}
+
 void TranscodingUidPolicy::registerSelf() {
-    status_t res = mAm->linkToDeath(mUidObserver.get());
-    mAm->registerUidObserver(
-            mUidObserver.get(),
-            ActivityManager::UID_OBSERVER_GONE | ActivityManager::UID_OBSERVER_IDLE |
-                    ActivityManager::UID_OBSERVER_ACTIVE | ActivityManager::UID_OBSERVER_PROCSTATE,
-            ActivityManager::PROCESS_STATE_UNKNOWN, String16(kTranscodingTag));
+    mUidObserver = AActivityManager_addUidImportanceListener(
+            &OnUidImportance, -1, (void*)this);
 
-    if (res == OK) {
-        Mutex::Autolock _l(mUidLock);
-
-        mRegistered = true;
-        ALOGI("TranscodingUidPolicy: Registered with ActivityManager");
-    } else {
-        mAm->unregisterUidObserver(mUidObserver.get());
-    }
-}
-
-void TranscodingUidPolicy::unregisterSelf() {
-    mAm->unregisterUidObserver(mUidObserver.get());
-    mAm->unlinkToDeath(mUidObserver.get());
-
-    Mutex::Autolock _l(mUidLock);
-
-    mRegistered = false;
-
-    ALOGI("TranscodingUidPolicy: Unregistered with ActivityManager");
-}
-
-void TranscodingUidPolicy::setProcessInfoOverride() {
-    ::ndk::SpAIBinder binder(AServiceManager_getService("media.resource_manager"));
-    std::shared_ptr<IResourceManagerService> service = IResourceManagerService::fromBinder(binder);
-    if (service == nullptr) {
-        ALOGE("Failed to get IResourceManagerService");
+    if (mUidObserver == nullptr) {
+        ALOGE("Failed to register uid observer");
         return;
     }
 
-    mProcInfoOverrideClient = ::ndk::SharedRefBase::make<ResourceManagerClient>();
-    Status status = service->overrideProcessInfo(
-            mProcInfoOverrideClient, getpid(), ActivityManager::PROCESS_STATE_SERVICE, SERVICE_ADJ);
-    if (!status.isOk()) {
-        ALOGW("Failed to setProcessInfoOverride.");
-    }
+    Mutex::Autolock _l(mUidLock);
+    mRegistered = true;
+    ALOGI("Registered uid observer");
 }
 
-void TranscodingUidPolicy::setUidObserverRegistered(bool registered) {
-    Mutex::Autolock _l(mUidLock);
+void TranscodingUidPolicy::unregisterSelf() {
+    AActivityManager_removeUidImportanceListener(mUidObserver);
+    mUidObserver = nullptr;
 
-    mRegistered = registered;
+    Mutex::Autolock _l(mUidLock);
+    mRegistered = false;
+    ALOGI("Unregistered uid observer");
 }
 
 void TranscodingUidPolicy::setCallback(const std::shared_ptr<UidPolicyCallbackInterface>& cb) {
@@ -205,9 +85,9 @@
         return;
     }
 
-    int32_t state = ActivityManager::PROCESS_STATE_UNKNOWN;
-    if (mRegistered && mAm->isUidActive(uid, String16(kTranscodingTag))) {
-        state = mAm->getUidProcessState(uid, String16(kTranscodingTag));
+    int32_t state = IMPORTANCE_UNKNOWN;
+    if (mRegistered && AActivityManager_isUidActive(uid)) {
+        state = AActivityManager_getUidImportance(uid);
     }
 
     ALOGV("%s: inserting new uid: %u, procState %d", __FUNCTION__, uid, state);
@@ -242,14 +122,14 @@
 bool TranscodingUidPolicy::isUidOnTop(uid_t uid) {
     Mutex::Autolock _l(mUidLock);
 
-    return mTopUidState != ActivityManager::PROCESS_STATE_UNKNOWN &&
+    return mTopUidState != IMPORTANCE_UNKNOWN &&
            mTopUidState == getProcState_l(uid);
 }
 
 std::unordered_set<uid_t> TranscodingUidPolicy::getTopUids() const {
     Mutex::Autolock _l(mUidLock);
 
-    if (mTopUidState == ActivityManager::PROCESS_STATE_UNKNOWN) {
+    if (mTopUidState == IMPORTANCE_UNKNOWN) {
         return std::unordered_set<uid_t>();
     }
 
@@ -267,11 +147,13 @@
         if (it != mUidStateMap.end() && it->second != procState) {
             // Top set changed if 1) the uid is in the current top uid set, or 2) the
             // new procState is at least the same priority as the current top uid state.
-            bool isUidCurrentTop = mTopUidState != ActivityManager::PROCESS_STATE_UNKNOWN &&
-                                   mStateUidMap[mTopUidState].count(uid) > 0;
-            bool isNewStateHigherThanTop = procState != ActivityManager::PROCESS_STATE_UNKNOWN &&
-                                           (procState <= mTopUidState ||
-                                            mTopUidState == ActivityManager::PROCESS_STATE_UNKNOWN);
+            bool isUidCurrentTop =
+                    mTopUidState != IMPORTANCE_UNKNOWN &&
+                    mStateUidMap[mTopUidState].count(uid) > 0;
+            bool isNewStateHigherThanTop =
+                    procState != IMPORTANCE_UNKNOWN &&
+                    (procState <= mTopUidState ||
+                     mTopUidState == IMPORTANCE_UNKNOWN);
             topUidSetChanged = (isUidCurrentTop || isNewStateHigherThanTop);
 
             // Move uid to the new procState.
@@ -299,11 +181,12 @@
 }
 
 void TranscodingUidPolicy::updateTopUid_l() {
-    mTopUidState = ActivityManager::PROCESS_STATE_UNKNOWN;
+    mTopUidState = IMPORTANCE_UNKNOWN;
 
     // Find the lowest uid state (ignoring PROCESS_STATE_UNKNOWN) with some monitored uids.
     for (auto stateIt = mStateUidMap.begin(); stateIt != mStateUidMap.end(); stateIt++) {
-        if (stateIt->first != ActivityManager::PROCESS_STATE_UNKNOWN && !stateIt->second.empty()) {
+        if (stateIt->first != IMPORTANCE_UNKNOWN &&
+            !stateIt->second.empty()) {
             mTopUidState = stateIt->first;
             break;
         }
@@ -317,7 +200,7 @@
     if (it != mUidStateMap.end()) {
         return it->second;
     }
-    return ActivityManager::PROCESS_STATE_UNKNOWN;
+    return IMPORTANCE_UNKNOWN;
 }
 
 }  // namespace android
diff --git a/media/libmediatranscoding/include/media/ResourcePolicyInterface.h b/media/libmediatranscoding/include/media/ResourcePolicyInterface.h
index 4a92af8..ecce252 100644
--- a/media/libmediatranscoding/include/media/ResourcePolicyInterface.h
+++ b/media/libmediatranscoding/include/media/ResourcePolicyInterface.h
@@ -27,6 +27,7 @@
     // Set the associated callback interface to send the events when resource
     // status changes. (Set to nullptr will stop the updates.)
     virtual void setCallback(const std::shared_ptr<ResourcePolicyCallbackInterface>& cb) = 0;
+    virtual void setPidResourceLost(pid_t pid) = 0;
 
 protected:
     virtual ~ResourcePolicyInterface() = default;
diff --git a/media/libmediatranscoding/include/media/TranscoderInterface.h b/media/libmediatranscoding/include/media/TranscoderInterface.h
index e17cd5a..6268aa5 100644
--- a/media/libmediatranscoding/include/media/TranscoderInterface.h
+++ b/media/libmediatranscoding/include/media/TranscoderInterface.h
@@ -64,7 +64,7 @@
     // If there is any session currently running, it will be paused. When resource contention
     // is solved, the controller should call TranscoderInterface's to either start a new session,
     // or resume a paused session.
-    virtual void onResourceLost() = 0;
+    virtual void onResourceLost(ClientIdType clientId, SessionIdType sessionId) = 0;
 
 protected:
     virtual ~TranscoderCallbackInterface() = default;
diff --git a/media/libmediatranscoding/include/media/TranscodingClientManager.h b/media/libmediatranscoding/include/media/TranscodingClientManager.h
index 451f993..be55c78 100644
--- a/media/libmediatranscoding/include/media/TranscodingClientManager.h
+++ b/media/libmediatranscoding/include/media/TranscodingClientManager.h
@@ -87,7 +87,7 @@
     TranscodingClientManager(const std::shared_ptr<ControllerClientInterface>& controller);
 
     // Checks if a user is trusted (and allowed to submit sessions on behalf of other uids)
-    bool isTrustedCallingUid(uid_t uid);
+    bool isTrustedCaller(pid_t pid, uid_t uid);
 
     /**
      * Removes an existing client from the manager.
@@ -109,7 +109,7 @@
     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
 
     std::shared_ptr<ControllerClientInterface> mSessionController;
-    std::unordered_set<uid_t> mMediaProviderUid;
+    std::unordered_set<uid_t> mTrustedUids;
 
     static std::atomic<ClientIdType> sCookieCounter;
     static std::mutex sCookie2ClientLock;
diff --git a/media/libmediatranscoding/include/media/TranscodingResourcePolicy.h b/media/libmediatranscoding/include/media/TranscodingResourcePolicy.h
index 0836eda..ee232e7 100644
--- a/media/libmediatranscoding/include/media/TranscodingResourcePolicy.h
+++ b/media/libmediatranscoding/include/media/TranscodingResourcePolicy.h
@@ -40,6 +40,7 @@
     ~TranscodingResourcePolicy();
 
     void setCallback(const std::shared_ptr<ResourcePolicyCallbackInterface>& cb) override;
+    void setPidResourceLost(pid_t pid) override;
 
 private:
     struct ResourceObserver;
@@ -51,6 +52,7 @@
     mutable std::mutex mCallbackLock;
     std::weak_ptr<ResourcePolicyCallbackInterface> mResourcePolicyCallback
             GUARDED_BY(mCallbackLock);
+    pid_t mResourceLostPid GUARDED_BY(mCallbackLock);
 
     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
 
@@ -58,7 +60,7 @@
 
     void registerSelf();
     void unregisterSelf();
-    void onResourceAvailable();
+    void onResourceAvailable(pid_t pid);
 };  // class TranscodingUidPolicy
 
 }  // namespace android
diff --git a/media/libmediatranscoding/include/media/TranscodingSessionController.h b/media/libmediatranscoding/include/media/TranscodingSessionController.h
index c082074..4215e06 100644
--- a/media/libmediatranscoding/include/media/TranscodingSessionController.h
+++ b/media/libmediatranscoding/include/media/TranscodingSessionController.h
@@ -58,7 +58,7 @@
     void onError(ClientIdType clientId, SessionIdType sessionId, TranscodingErrorCode err) override;
     void onProgressUpdate(ClientIdType clientId, SessionIdType sessionId,
                           int32_t progress) override;
-    void onResourceLost() override;
+    void onResourceLost(ClientIdType clientId, SessionIdType sessionId) override;
     // ~TranscoderCallbackInterface
 
     // UidPolicyCallbackInterface
diff --git a/media/libmediatranscoding/include/media/TranscodingUidPolicy.h b/media/libmediatranscoding/include/media/TranscodingUidPolicy.h
index 4c642de..4dde5a6 100644
--- a/media/libmediatranscoding/include/media/TranscodingUidPolicy.h
+++ b/media/libmediatranscoding/include/media/TranscodingUidPolicy.h
@@ -22,18 +22,16 @@
 #include <media/UidPolicyInterface.h>
 #include <sys/types.h>
 #include <utils/Condition.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
 
 #include <map>
 #include <mutex>
 #include <unordered_map>
 #include <unordered_set>
 
+struct AActivityManager_UidImportanceListener;
+
 namespace android {
 
-class ActivityManager;
 // Observer for UID lifecycle and provide information about the uid's app
 // priority used by the session controller.
 class TranscodingUidPolicy : public UidPolicyInterface {
@@ -49,28 +47,24 @@
     void setCallback(const std::shared_ptr<UidPolicyCallbackInterface>& cb) override;
     // ~UidPolicyInterface
 
-    static status_t getUidForPackage(String16 packageName, /*inout*/ uid_t& uid);
-
 private:
     void onUidStateChanged(uid_t uid, int32_t procState);
-    void setUidObserverRegistered(bool registerd);
     void registerSelf();
     void unregisterSelf();
-    void setProcessInfoOverride();
     int32_t getProcState_l(uid_t uid) NO_THREAD_SAFETY_ANALYSIS;
     void updateTopUid_l() NO_THREAD_SAFETY_ANALYSIS;
 
-    struct UidObserver;
+    static void OnUidImportance(uid_t uid, int32_t uidImportance, void* cookie);
+
     struct ResourceManagerClient;
     mutable Mutex mUidLock;
-    std::shared_ptr<ActivityManager> mAm;
-    sp<UidObserver> mUidObserver;
+    AActivityManager_UidImportanceListener* mUidObserver;
+
     bool mRegistered GUARDED_BY(mUidLock);
     int32_t mTopUidState GUARDED_BY(mUidLock);
     std::unordered_map<uid_t, int32_t> mUidStateMap GUARDED_BY(mUidLock);
     std::map<int32_t, std::unordered_set<uid_t>> mStateUidMap GUARDED_BY(mUidLock);
     std::weak_ptr<UidPolicyCallbackInterface> mUidPolicyCallback;
-    std::shared_ptr<ResourceManagerClient> mProcInfoOverrideClient;
 };  // class TranscodingUidPolicy
 
 }  // namespace android
diff --git a/media/libmediatranscoding/tests/Android.bp b/media/libmediatranscoding/tests/Android.bp
index 7b15b1b..8bff10a 100644
--- a/media/libmediatranscoding/tests/Android.bp
+++ b/media/libmediatranscoding/tests/Android.bp
@@ -1,4 +1,10 @@
 // Build the unit tests for libmediatranscoding.
+filegroup {
+    name: "test_assets",
+    path: "assets",
+    srcs: ["assets/**/*"],
+}
+
 cc_defaults {
     name: "libmediatranscoding_test_defaults",
 
@@ -8,15 +14,16 @@
     ],
 
     shared_libs: [
+        "libandroid",
         "libbinder_ndk",
         "libcutils",
         "liblog",
         "libutils",
-        "libmediatranscoding"
     ],
 
     static_libs: [
         "mediatranscoding_aidl_interface-ndk_platform",
+        "libmediatranscoding",
     ],
 
     cflags: [
diff --git a/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp b/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
index 4809d7a..fa52f63 100644
--- a/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
+++ b/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
@@ -44,11 +44,14 @@
 constexpr ClientIdType kClientId = 1000;
 constexpr SessionIdType kClientSessionId = 0;
 constexpr uid_t kClientUid = 5000;
+constexpr pid_t kClientPid = 10000;
 constexpr uid_t kInvalidUid = (uid_t)-1;
+constexpr pid_t kInvalidPid = (pid_t)-1;
 
 #define CLIENT(n) (kClientId + (n))
 #define SESSION(n) (kClientSessionId + (n))
 #define UID(n) (kClientUid + (n))
+#define PID(n) (kClientPid + (n))
 
 class TestUidPolicy : public UidPolicyInterface {
 public:
@@ -79,6 +82,31 @@
     std::weak_ptr<UidPolicyCallbackInterface> mUidPolicyCallback;
 };
 
+class TestResourcePolicy : public ResourcePolicyInterface {
+public:
+    TestResourcePolicy() { reset(); }
+    virtual ~TestResourcePolicy() = default;
+
+    // ResourcePolicyInterface
+    void setCallback(const std::shared_ptr<ResourcePolicyCallbackInterface>& /*cb*/) override {}
+    void setPidResourceLost(pid_t pid) override {
+        mResourceLostPid = pid;
+    }
+    // ~ResourcePolicyInterface
+
+    pid_t getPid() {
+        pid_t result = mResourceLostPid;
+        reset();
+        return result;
+    }
+
+private:
+    void reset() {
+        mResourceLostPid = kInvalidPid;
+    }
+    pid_t mResourceLostPid;
+};
+
 class TestTranscoder : public TranscoderInterface {
 public:
     TestTranscoder() : mLastError(TranscodingErrorCode::kUnknown) {}
@@ -216,8 +244,9 @@
         ALOGI("TranscodingSessionControllerTest set up");
         mTranscoder.reset(new TestTranscoder());
         mUidPolicy.reset(new TestUidPolicy());
-        mController.reset(new TranscodingSessionController(mTranscoder, mUidPolicy,
-                                                           nullptr /*resourcePolicy*/));
+        mResourcePolicy.reset(new TestResourcePolicy());
+        mController.reset(
+                new TranscodingSessionController(mTranscoder, mUidPolicy, mResourcePolicy));
         mUidPolicy->setCallback(mController);
 
         // Set priority only, ignore other fields for now.
@@ -239,6 +268,7 @@
 
     std::shared_ptr<TestTranscoder> mTranscoder;
     std::shared_ptr<TestUidPolicy> mUidPolicy;
+    std::shared_ptr<TestResourcePolicy> mResourcePolicy;
     std::shared_ptr<TranscodingSessionController> mController;
     TranscodingRequestParcel mOfflineRequest;
     TranscodingRequestParcel mRealtimeRequest;
@@ -552,10 +582,12 @@
 
     // Start with unspecified top UID.
     // Submit real-time session to CLIENT(0), session should start immediately.
+    mRealtimeRequest.clientPid = PID(0);
     mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
     EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
 
     // Submit offline session to CLIENT(0), should not start.
+    mOfflineRequest.clientPid = PID(0);
     mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
     EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
 
@@ -565,13 +597,22 @@
 
     // Submit real-time session to CLIENT(2) in different uid UID(1).
     // Should pause previous session and start new session.
+    mRealtimeRequest.clientPid = PID(1);
     mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
     EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
     EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
 
+    // Test 0: No call into ResourcePolicy if resource lost is from a non-running
+    // or non-existent session.
+    mController->onResourceLost(CLIENT(0), SESSION(0));
+    EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
+    mController->onResourceLost(CLIENT(3), SESSION(0));
+    EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
+
     // Test 1: No queue change during resource loss.
     // Signal resource lost.
-    mController->onResourceLost();
+    mController->onResourceLost(CLIENT(2), SESSION(0));
+    EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
     EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
 
     // Signal resource available, CLIENT(2) should resume.
@@ -580,7 +621,8 @@
 
     // Test 2: Change of queue order during resource loss.
     // Signal resource lost.
-    mController->onResourceLost();
+    mController->onResourceLost(CLIENT(2), SESSION(0));
+    EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
     EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
 
     // Move UID(0) back to top, should have no resume due to no resource.
@@ -593,13 +635,15 @@
 
     // Test 3: Adding new queue during resource loss.
     // Signal resource lost.
-    mController->onResourceLost();
+    mController->onResourceLost(CLIENT(0), SESSION(0));
+    EXPECT_EQ(mResourcePolicy->getPid(), PID(0));
     EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
 
     // Move UID(2) to top.
     mUidPolicy->setTop(UID(2));
 
     // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start due to no resource.
+    mRealtimeRequest.clientPid = PID(2);
     mController->submit(CLIENT(3), SESSION(0), UID(2), mRealtimeRequest, mClientCallback3);
     EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
 
diff --git a/media/libmediatranscoding/tests/assets/backyard_hevc_1920x1080_20Mbps.mp4 b/media/libmediatranscoding/tests/assets/TranscodingTestAssets/backyard_hevc_1920x1080_20Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/backyard_hevc_1920x1080_20Mbps.mp4
rename to media/libmediatranscoding/tests/assets/TranscodingTestAssets/backyard_hevc_1920x1080_20Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/cubicle_avc_480x240_aac_24KHz.mp4 b/media/libmediatranscoding/tests/assets/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/cubicle_avc_480x240_aac_24KHz.mp4
rename to media/libmediatranscoding/tests/assets/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4 b/media/libmediatranscoding/tests/assets/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4
rename to media/libmediatranscoding/tests/assets/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/jets_hevc_1280x720_20Mbps.mp4 b/media/libmediatranscoding/tests/assets/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/jets_hevc_1280x720_20Mbps.mp4
rename to media/libmediatranscoding/tests/assets/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/longtest_15s.mp4 b/media/libmediatranscoding/tests/assets/TranscodingTestAssets/longtest_15s.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/longtest_15s.mp4
rename to media/libmediatranscoding/tests/assets/TranscodingTestAssets/longtest_15s.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/plex_hevc_3840x2160_12Mbps.mp4 b/media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_12Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/plex_hevc_3840x2160_12Mbps.mp4
rename to media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_12Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/plex_hevc_3840x2160_20Mbps.mp4 b/media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_20Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/plex_hevc_3840x2160_20Mbps.mp4
rename to media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_20Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/push_assets.sh b/media/libmediatranscoding/tests/push_assets.sh
similarity index 93%
rename from media/libmediatranscoding/tests/assets/push_assets.sh
rename to media/libmediatranscoding/tests/push_assets.sh
index 8afc947..cc71514 100755
--- a/media/libmediatranscoding/tests/assets/push_assets.sh
+++ b/media/libmediatranscoding/tests/push_assets.sh
@@ -23,7 +23,7 @@
 
 adb shell mkdir -p /data/local/tmp/TranscodingTestAssets
 
-FILES=$ANDROID_BUILD_TOP/frameworks/av/media/libmediatranscoding/tests/assets/*
+FILES=$ANDROID_BUILD_TOP/frameworks/av/media/libmediatranscoding/tests/assets/TranscodingTestAssets/*
 for file in $FILES
 do 
 adb push --sync $file /data/local/tmp/TranscodingTestAssets
diff --git a/media/libmediatranscoding/transcoder/Android.bp b/media/libmediatranscoding/transcoder/Android.bp
index 1896412..aa7cdde 100644
--- a/media/libmediatranscoding/transcoder/Android.bp
+++ b/media/libmediatranscoding/transcoder/Android.bp
@@ -60,16 +60,8 @@
     },
 }
 
-cc_library_shared {
+cc_library {
     name: "libmediatranscoder",
     defaults: ["mediatranscoder_defaults"],
 }
 
-cc_library_shared {
-    name: "libmediatranscoder_asan",
-    defaults: ["mediatranscoder_defaults"],
-
-    sanitize: {
-        address: true,
-    },
-}
diff --git a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp b/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
index 827e49a..3d4ff15 100644
--- a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
@@ -206,11 +206,12 @@
     mCallbacks->onProgressUpdate(this, progress);
 }
 
-MediaTranscoder::MediaTranscoder(const std::shared_ptr<CallbackInterface>& callbacks)
-      : mCallbacks(callbacks) {}
+MediaTranscoder::MediaTranscoder(const std::shared_ptr<CallbackInterface>& callbacks, pid_t pid,
+                                 uid_t uid)
+      : mCallbacks(callbacks), mPid(pid), mUid(uid) {}
 
 std::shared_ptr<MediaTranscoder> MediaTranscoder::create(
-        const std::shared_ptr<CallbackInterface>& callbacks,
+        const std::shared_ptr<CallbackInterface>& callbacks, pid_t pid, uid_t uid,
         const std::shared_ptr<ndk::ScopedAParcel>& pausedState) {
     if (pausedState != nullptr) {
         LOG(INFO) << "Initializing from paused state.";
@@ -220,7 +221,7 @@
         return nullptr;
     }
 
-    return std::shared_ptr<MediaTranscoder>(new MediaTranscoder(callbacks));
+    return std::shared_ptr<MediaTranscoder>(new MediaTranscoder(callbacks, pid, uid));
 }
 
 media_status_t MediaTranscoder::configureSource(int fd) {
@@ -303,7 +304,7 @@
             }
         }
 
-        transcoder = VideoTrackTranscoder::create(shared_from_this());
+        transcoder = VideoTrackTranscoder::create(shared_from_this(), mPid, mUid);
 
         AMediaFormat* mergedFormat =
                 mergeMediaFormats(mSourceTrackFormats[trackIndex].get(), trackFormat);
diff --git a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
index fbc081f..ec62775 100644
--- a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "VideoTrackTranscoder"
 
 #include <android-base/logging.h>
+#include <android-base/properties.h>
 #include <media/NdkCommon.h>
 #include <media/VideoTrackTranscoder.h>
 #include <utils/AndroidThreads.h>
@@ -39,7 +40,8 @@
 // Default key frame interval in seconds.
 static constexpr float kDefaultKeyFrameIntervalSeconds = 1.0f;
 // Default codec operating rate.
-static constexpr int32_t kDefaultCodecOperatingRate = 240;
+static int32_t kDefaultCodecOperatingRate =
+        base::GetIntProperty("debug.media.transcoding.codec_max_operating_rate", /*default*/ 240);
 // Default codec priority.
 static constexpr int32_t kDefaultCodecPriority = 1;
 // Default bitrate, in case source estimation fails.
@@ -165,8 +167,10 @@
 
 // static
 std::shared_ptr<VideoTrackTranscoder> VideoTrackTranscoder::create(
-        const std::weak_ptr<MediaTrackTranscoderCallback>& transcoderCallback) {
-    return std::shared_ptr<VideoTrackTranscoder>(new VideoTrackTranscoder(transcoderCallback));
+        const std::weak_ptr<MediaTrackTranscoderCallback>& transcoderCallback, pid_t pid,
+        uid_t uid) {
+    return std::shared_ptr<VideoTrackTranscoder>(
+            new VideoTrackTranscoder(transcoderCallback, pid, uid));
 }
 
 VideoTrackTranscoder::~VideoTrackTranscoder() {
@@ -230,7 +234,7 @@
         return AMEDIA_ERROR_INVALID_PARAMETER;
     }
 
-    AMediaCodec* encoder = AMediaCodec_createEncoderByType(destinationMime);
+    AMediaCodec* encoder = AMediaCodec_createEncoderByTypeForClient(destinationMime, mPid, mUid);
     if (encoder == nullptr) {
         LOG(ERROR) << "Unable to create encoder for type " << destinationMime;
         return AMEDIA_ERROR_UNSUPPORTED;
@@ -260,7 +264,7 @@
         return AMEDIA_ERROR_INVALID_PARAMETER;
     }
 
-    mDecoder = AMediaCodec_createDecoderByType(sourceMime);
+    mDecoder = AMediaCodec_createDecoderByTypeForClient(sourceMime, mPid, mUid);
     if (mDecoder == nullptr) {
         LOG(ERROR) << "Unable to create decoder for type " << sourceMime;
         return AMEDIA_ERROR_UNSUPPORTED;
diff --git a/media/libmediatranscoding/transcoder/benchmark/Android.bp b/media/libmediatranscoding/transcoder/benchmark/Android.bp
index ce34702..6c87233 100644
--- a/media/libmediatranscoding/transcoder/benchmark/Android.bp
+++ b/media/libmediatranscoding/transcoder/benchmark/Android.bp
@@ -1,7 +1,9 @@
 cc_defaults {
     name: "benchmarkdefaults",
-    shared_libs: ["libmediatranscoder", "libmediandk", "libbase", "libbinder_ndk"],
-    static_libs: ["libgoogle-benchmark"],
+    shared_libs: ["libmediandk", "libbase", "libbinder_ndk", "libutils", "libnativewindow"],
+    static_libs: ["libmediatranscoder", "libgoogle-benchmark"],
+    test_config_template: "AndroidTestTemplate.xml",
+    test_suites: ["device-tests", "TranscoderBenchmarks"],
 }
 
 cc_test {
diff --git a/media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml b/media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
new file mode 100644
index 0000000..64085d8
--- /dev/null
+++ b/media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Unit test configuration for {MODULE}">
+    <option name="test-suite-tag" value="TranscoderBenchmarks" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="false" />
+        <option name="push-file" key="{MODULE}" value="/data/local/tmp/{MODULE}" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libmediatranscoding/transcoder/benchmark/TranscodingBenchmark-1.1.zip?unzip=true"
+            value="/data/local/tmp/TranscodingBenchmark/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
+        <option name="native-benchmark-device-path" value="/data/local/tmp" />
+        <option name="benchmark-module-name" value="{MODULE}" />
+    </test>
+</configuration>
+
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
index 465632f..9ee55e5 100644
--- a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
+++ b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
@@ -32,9 +32,12 @@
 #include <benchmark/benchmark.h>
 #include <fcntl.h>
 #include <media/MediaTranscoder.h>
+#include <iostream>
 
 using namespace android;
 
+const std::string PARAM_VIDEO_FRAME_RATE = "VideoFrameRate";
+
 class TranscoderCallbacks : public MediaTranscoder::CallbackInterface {
 public:
     virtual void onFinished(const MediaTranscoder* transcoder __unused) override {
@@ -123,7 +126,7 @@
     }
 
     for (auto _ : state) {
-        auto transcoder = MediaTranscoder::create(callbacks, nullptr);
+        auto transcoder = MediaTranscoder::create(callbacks);
 
         status = transcoder->configureSource(srcFd);
         if (status != AMEDIA_OK) {
@@ -151,7 +154,7 @@
             if (strncmp(mime, "video/", 6) == 0) {
                 int32_t frameCount;
                 if (AMediaFormat_getInt32(srcFormat, AMEDIAFORMAT_KEY_FRAME_COUNT, &frameCount)) {
-                    state.counters["VideoFrameRate"] =
+                    state.counters[PARAM_VIDEO_FRAME_RATE] =
                             benchmark::Counter(frameCount, benchmark::Counter::kIsRate);
                 }
             }
@@ -332,4 +335,69 @@
 TRANSCODER_BENCHMARK(BM_TranscodeAudioVideoPassthrough);
 TRANSCODER_BENCHMARK(BM_TranscodeVideoPassthrough);
 
-BENCHMARK_MAIN();
+class CustomCsvReporter : public benchmark::BenchmarkReporter {
+public:
+    CustomCsvReporter() : mPrintedHeader(false) {}
+    virtual bool ReportContext(const Context& context);
+    virtual void ReportRuns(const std::vector<Run>& reports);
+
+private:
+    void PrintRunData(const Run& report);
+
+    bool mPrintedHeader;
+    std::vector<std::string> mHeaders = {"name", "real_time", "cpu_time", PARAM_VIDEO_FRAME_RATE};
+};
+
+bool CustomCsvReporter::ReportContext(const Context& context __unused) {
+    return true;
+}
+
+void CustomCsvReporter::ReportRuns(const std::vector<Run>& reports) {
+    std::ostream& Out = GetOutputStream();
+
+    if (!mPrintedHeader) {
+        // print the header
+        for (auto header = mHeaders.begin(); header != mHeaders.end();) {
+            Out << *header++;
+            if (header != mHeaders.end()) Out << ",";
+        }
+        Out << "\n";
+        mPrintedHeader = true;
+    }
+
+    // print results for each run
+    for (const auto& run : reports) {
+        PrintRunData(run);
+    }
+}
+
+void CustomCsvReporter::PrintRunData(const Run& run) {
+    if (run.error_occurred) {
+        return;
+    }
+    std::ostream& Out = GetOutputStream();
+    Out << run.benchmark_name() << ",";
+    Out << run.GetAdjustedRealTime() << ",";
+    Out << run.GetAdjustedCPUTime() << ",";
+    auto frameRate = run.counters.find(PARAM_VIDEO_FRAME_RATE);
+    if (frameRate == run.counters.end()) {
+        Out << "NA"
+            << ",";
+    } else {
+        Out << frameRate->second << ",";
+    }
+    Out << '\n';
+}
+
+int main(int argc, char** argv) {
+    std::unique_ptr<benchmark::BenchmarkReporter> fileReporter;
+    for (int i = 1; i < argc; ++i) {
+        if (std::string(argv[i]).find("--benchmark_out") != std::string::npos) {
+            fileReporter.reset(new CustomCsvReporter);
+            break;
+        }
+    }
+    ::benchmark::Initialize(&argc, argv);
+    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
+    ::benchmark::RunSpecifiedBenchmarks(nullptr, fileReporter.get());
+}
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h b/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
index b995e6d..4e11ef5 100644
--- a/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
+++ b/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
@@ -20,6 +20,7 @@
 #include <android/binder_auto_utils.h>
 #include <media/MediaSampleWriter.h>
 #include <media/MediaTrackTranscoderCallback.h>
+#include <media/NdkMediaCodecPlatform.h>
 #include <media/NdkMediaError.h>
 #include <media/NdkMediaFormat.h>
 #include <utils/Mutex.h>
@@ -70,6 +71,7 @@
      */
     static std::shared_ptr<MediaTranscoder> create(
             const std::shared_ptr<CallbackInterface>& callbacks,
+            pid_t pid = AMEDIACODEC_CALLING_PID, uid_t uid = AMEDIACODEC_CALLING_UID,
             const std::shared_ptr<ndk::ScopedAParcel>& pausedState = nullptr);
 
     /** Configures source from path fd. */
@@ -118,7 +120,7 @@
     virtual ~MediaTranscoder() = default;
 
 private:
-    MediaTranscoder(const std::shared_ptr<CallbackInterface>& callbacks);
+    MediaTranscoder(const std::shared_ptr<CallbackInterface>& callbacks, pid_t pid, uid_t uid);
 
     // MediaTrackTranscoderCallback
     virtual void onTrackFormatAvailable(const MediaTrackTranscoder* transcoder) override;
@@ -145,6 +147,8 @@
     std::vector<std::shared_ptr<MediaTrackTranscoder>> mTrackTranscoders;
     std::mutex mTracksAddedMutex;
     std::unordered_set<const MediaTrackTranscoder*> mTracksAdded GUARDED_BY(mTracksAddedMutex);
+    pid_t mPid;
+    uid_t mUid;
 
     enum ThreadState {
         PENDING = 0,  // Not yet started.
diff --git a/media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h b/media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
index 267755d..d2ffb01 100644
--- a/media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
+++ b/media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
@@ -19,7 +19,7 @@
 
 #include <android/native_window.h>
 #include <media/MediaTrackTranscoder.h>
-#include <media/NdkMediaCodec.h>
+#include <media/NdkMediaCodecPlatform.h>
 #include <media/NdkMediaFormat.h>
 
 #include <condition_variable>
@@ -38,7 +38,8 @@
                              public MediaTrackTranscoder {
 public:
     static std::shared_ptr<VideoTrackTranscoder> create(
-            const std::weak_ptr<MediaTrackTranscoderCallback>& transcoderCallback);
+            const std::weak_ptr<MediaTrackTranscoderCallback>& transcoderCallback,
+            pid_t pid = AMEDIACODEC_CALLING_PID, uid_t uid = AMEDIACODEC_CALLING_UID);
 
     virtual ~VideoTrackTranscoder() override;
 
@@ -61,8 +62,9 @@
     };
     class CodecWrapper;
 
-    VideoTrackTranscoder(const std::weak_ptr<MediaTrackTranscoderCallback>& transcoderCallback)
-          : MediaTrackTranscoder(transcoderCallback){};
+    VideoTrackTranscoder(const std::weak_ptr<MediaTrackTranscoderCallback>& transcoderCallback,
+                         pid_t pid, uid_t uid)
+          : MediaTrackTranscoder(transcoderCallback), mPid(pid), mUid(uid){};
 
     // MediaTrackTranscoder
     media_status_t runTranscodeLoop(bool* stopped) override;
@@ -95,6 +97,8 @@
     BlockingQueue<std::function<void()>> mCodecMessageQueue;
     std::shared_ptr<AMediaFormat> mDestinationFormat;
     std::shared_ptr<AMediaFormat> mActualOutputFormat;
+    pid_t mPid;
+    uid_t mUid;
 };
 
 }  // namespace android
diff --git a/media/libmediatranscoding/transcoder/tests/Android.bp b/media/libmediatranscoding/transcoder/tests/Android.bp
index 8ad583f..d0ea802 100644
--- a/media/libmediatranscoding/transcoder/tests/Android.bp
+++ b/media/libmediatranscoding/transcoder/tests/Android.bp
@@ -1,10 +1,4 @@
 // Unit tests for libmediatranscoder.
-
-filegroup {
-    name: "test_assets",
-    srcs: ["assets/*"],
-}
-
 cc_defaults {
     name: "testdefaults",
 
@@ -13,13 +7,16 @@
         "libmedia_headers",
     ],
 
+    static_libs: [
+        "libmediatranscoder",
+    ],
     shared_libs: [
         "libbase",
         "libbinder_ndk",
         "libcrypto",
         "libcutils",
         "libmediandk",
-        "libmediatranscoder_asan",
+        "libnativewindow",
         "libutils",
     ],
 
@@ -34,7 +31,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        address: true,
     },
 
     data: [":test_assets"],
diff --git a/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml b/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
index a9a7e2e..6d781cd 100644
--- a/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
+++ b/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
@@ -17,12 +17,12 @@
     <option name="test-suite-tag" value="TranscoderTests" />
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="false" />
-        <option name="push-file"
-            key="assets"
-            value="/data/local/tmp/TranscodingTestAssets" />
+        <option name="push-file" key="TranscodingTestAssets" value="/data/local/tmp/TranscodingTestAssets" />
+        <option name="push-file" key="{MODULE}" value="/data/local/tmp/{MODULE}" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="{MODULE}" />
     </test>
 </configuration>
diff --git a/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp b/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
index 6de43a7..bfc1f3b 100644
--- a/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
+++ b/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
@@ -153,7 +153,7 @@
     media_status_t transcodeHelper(const char* srcPath, const char* destPath,
                                    FormatConfigurationCallback formatCallback,
                                    TranscodeExecutionControl executionControl = kRunToCompletion) {
-        auto transcoder = MediaTranscoder::create(mCallbacks, nullptr);
+        auto transcoder = MediaTranscoder::create(mCallbacks);
         EXPECT_NE(transcoder, nullptr);
 
         const int srcFd = open(srcPath, O_RDONLY);
@@ -339,8 +339,9 @@
     const char* destPath = "/data/local/tmp/MediaTranscoder_PreserveBitrate.MP4";
     testTranscodeVideo(srcPath, destPath, AMEDIA_MIMETYPE_VIDEO_AVC);
 
-    // Require maximum of 10% difference in file size.
-    EXPECT_LT(getFileSizeDiffPercent(srcPath, destPath, true /* absolute*/), 10);
+    // Require maximum of 25% difference in file size.
+    // TODO(b/174678336): Find a better test asset to tighten the threshold.
+    EXPECT_LT(getFileSizeDiffPercent(srcPath, destPath, true /* absolute*/), 25);
 }
 
 TEST_F(MediaTranscoderTests, TestCustomBitrate) {
@@ -352,8 +353,9 @@
     testTranscodeVideo(srcPath, destPath2, AMEDIA_MIMETYPE_VIDEO_AVC, 8 * 1000 * 1000);
 
     // The source asset is very short and heavily compressed from the beginning so don't expect the
-    // requested bitrate to be exactly matched. However 40% difference seems reasonable.
-    EXPECT_GT(getFileSizeDiffPercent(destPath1, destPath2), 40);
+    // requested bitrate to be exactly matched. However the 8mbps should at least be larger.
+    // TODO(b/174678336): Find a better test asset to tighten the threshold.
+    EXPECT_GT(getFileSizeDiffPercent(destPath1, destPath2), 10);
 }
 
 static AMediaFormat* getAVCVideoFormat(AMediaFormat* sourceFormat) {
diff --git a/media/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh b/media/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh
index b848b4c..792c541 100755
--- a/media/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh
+++ b/media/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh
@@ -20,7 +20,7 @@
 fi
 
 # Push the files onto the device.
-. $ANDROID_BUILD_TOP/frameworks/av/media/libmediatranscoding/tests/assets/push_assets.sh
+. $ANDROID_BUILD_TOP/frameworks/av/media/libmediatranscoding/tests/push_assets.sh
 
 echo "========================================"
 
diff --git a/media/libshmem/Android.bp b/media/libshmem/Android.bp
index b549b5d..62784ed 100644
--- a/media/libshmem/Android.bp
+++ b/media/libshmem/Android.bp
@@ -14,6 +14,9 @@
     name: "libshmemcompat",
     export_include_dirs: ["include"],
     srcs: ["ShmemCompat.cpp"],
+    host_supported: true,
+    vendor_available: true,
+    double_loadable: true,
     shared_libs: [
         "libbinder",
         "libshmemutil",
@@ -25,18 +28,31 @@
         "libutils",
         "shared-file-region-aidl-unstable-cpp",
     ],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_library {
     name: "libshmemutil",
     export_include_dirs: ["include"],
     srcs: ["ShmemUtil.cpp"],
+    host_supported: true,
+    vendor_available: true,
+    double_loadable: true,
     shared_libs: [
         "shared-file-region-aidl-unstable-cpp",
     ],
     export_shared_lib_headers: [
         "shared-file-region-aidl-unstable-cpp",
     ],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_test {
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index b9f9173..8f1da0d 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -5350,6 +5350,34 @@
                     if (mChannelMaskPresent) {
                         notify->setInt32("channel-mask", mChannelMask);
                     }
+
+                    if (!mIsEncoder && portIndex == kPortIndexOutput) {
+                        AString mime;
+                        if (mConfigFormat->findString("mime", &mime)
+                                && !strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime.c_str())) {
+
+                            OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE presentation;
+                            InitOMXParams(&presentation);
+                            err = mOMXNode->getParameter(
+                                    (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
+                                    &presentation, sizeof(presentation));
+                            if (err != OK) {
+                                return err;
+                            }
+                            notify->setInt32("aac-encoded-target-level",
+                                             presentation.nEncodedTargetLevel);
+                            notify->setInt32("aac-drc-cut-level", presentation.nDrcCut);
+                            notify->setInt32("aac-drc-boost-level", presentation.nDrcBoost);
+                            notify->setInt32("aac-drc-heavy-compression",
+                                             presentation.nHeavyCompression);
+                            notify->setInt32("aac-target-ref-level",
+                                             presentation.nTargetReferenceLevel);
+                            notify->setInt32("aac-drc-effect-type", presentation.nDrcEffectType);
+                            notify->setInt32("aac-drc-album-mode", presentation.nDrcAlbumMode);
+                            notify->setInt32("aac-drc-output-loudness",
+                                             presentation.nDrcOutputLoudness);
+                        }
+                    }
                     break;
                 }
 
@@ -5834,17 +5862,19 @@
 
         case ACodec::kWhatSetSurface:
         {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
             sp<RefBase> obj;
             CHECK(msg->findObject("surface", &obj));
 
             status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
 
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
+            sp<AReplyToken> replyID;
+            if (msg->senderAwaitsResponse(&replyID)) {
+                sp<AMessage> response = new AMessage;
+                response->setInt32("err", err);
+                response->postReply(replyID);
+            } else if (err != OK) {
+                mCodec->signalError(OMX_ErrorUndefined, err);
+            }
             break;
         }
 
@@ -7048,10 +7078,9 @@
         return err;
     }
 
-    using hardware::media::omx::V1_0::utils::TWOmxNode;
     err = statusFromBinderStatus(
             mCodec->mGraphicBufferSource->configure(
-                    new TWOmxNode(mCodec->mOMXNode),
+                    mCodec->mOMXNode->getHalInterface<IOmxNode>(),
                     static_cast<hardware::graphics::common::V1_0::Dataspace>(dataSpace)));
     if (err != OK) {
         ALOGE("[%s] Unable to configure for node (err %d)",
@@ -7808,6 +7837,58 @@
     // Ignore errors as failure is expected for codecs that aren't video encoders.
     (void)configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
 
+    AString mime;
+    if (!mIsEncoder
+            && (mConfigFormat->findString("mime", &mime))
+            && !strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime.c_str())) {
+        OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE presentation;
+        InitOMXParams(&presentation);
+        mOMXNode->getParameter(
+                    (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
+                    &presentation, sizeof(presentation));
+        int32_t value32 = 0;
+        bool updated = false;
+        if (params->findInt32("aac-pcm-limiter-enable", &value32)) {
+            presentation.nPCMLimiterEnable = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-encoded-target-level", &value32)) {
+            presentation.nEncodedTargetLevel = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-drc-cut-level", &value32)) {
+            presentation.nDrcCut = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-drc-boost-level", &value32)) {
+            presentation.nDrcBoost = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-drc-heavy-compression", &value32)) {
+            presentation.nHeavyCompression = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-target-ref-level", &value32)) {
+            presentation.nTargetReferenceLevel = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-drc-effect-type", &value32)) {
+            presentation.nDrcEffectType = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-drc-album-mode", &value32)) {
+            presentation.nDrcAlbumMode = value32;
+            updated = true;
+        }
+        if (!params->findInt32("aac-drc-output-loudness", &value32)) {
+            presentation.nDrcOutputLoudness = value32;
+            updated = true;
+        }
+        if (updated) {
+            mOMXNode->setParameter((OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
+                &presentation, sizeof(presentation));
+        }
+    }
     return setVendorParameters(params);
 }
 
@@ -8353,6 +8434,23 @@
             break;
         }
 
+        case kWhatSetSurface:
+        {
+            ALOGV("[%s] Deferring setSurface", mCodec->mComponentName.c_str());
+
+            sp<AReplyToken> replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            mCodec->deferMessage(msg);
+
+            sp<AMessage> response = new AMessage;
+            response->setInt32("err", OK);
+            response->postReply(replyID);
+
+            handled = true;
+            break;
+        }
+
         case kWhatCheckIfStuck:
         {
             int32_t generation = 0;
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index 965b6dd..d11408d 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -44,7 +44,7 @@
 namespace android {
 
 static const int64_t kBufferTimeOutUs = 10000LL; // 10 msec
-static const size_t kRetryCount = 50; // must be >0
+static const size_t kRetryCount = 100; // must be >0
 static const int64_t kDefaultSampleDurationUs = 33333LL; // 33ms
 
 sp<IMemory> allocVideoFrame(const sp<MetaData>& trackMeta,
@@ -121,15 +121,23 @@
             false /*allocRotated*/, true /*metaOnly*/);
 }
 
+bool isAvif(const sp<MetaData> &trackMeta) {
+    const char *mime;
+    return trackMeta->findCString(kKeyMIMEType, &mime)
+        && (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1)
+            || !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_AVIF));
+}
+
 bool findThumbnailInfo(
         const sp<MetaData> &trackMeta, int32_t *width, int32_t *height,
         uint32_t *type = NULL, const void **data = NULL, size_t *size = NULL) {
     uint32_t dummyType;
     const void *dummyData;
     size_t dummySize;
+    int codecConfigKey = isAvif(trackMeta) ? kKeyThumbnailAV1C : kKeyThumbnailHVCC;
     return trackMeta->findInt32(kKeyThumbnailWidth, width)
         && trackMeta->findInt32(kKeyThumbnailHeight, height)
-        && trackMeta->findData(kKeyThumbnailHVCC,
+        && trackMeta->findData(codecConfigKey,
                 type ?: &dummyType, data ?: &dummyData, size ?: &dummySize);
 }
 
@@ -752,7 +760,10 @@
         overrideMeta->remove(kKeyDisplayHeight);
         overrideMeta->setInt32(kKeyWidth, mWidth);
         overrideMeta->setInt32(kKeyHeight, mHeight);
-        overrideMeta->setData(kKeyHVCC, type, data, size);
+        // The AV1 codec configuration data is passed via CSD0 to the AV1
+        // decoder.
+        const int codecConfigKey = isAvif(trackMeta()) ? kKeyOpaqueCSD0 : kKeyHVCC;
+        overrideMeta->setData(codecConfigKey, type, data, size);
         options->setSeekTo(-1);
     } else {
         CHECK(trackMeta()->findInt32(kKeyWidth, &mWidth));
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 0af97df..447d599 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1137,11 +1137,24 @@
     if (!truncatePreAllocation()) {
         if (err == OK) { err = ERROR_IO; }
     }
+
+    // TODO(b/174770856) remove this measurement (and perhaps the fsync)
+    nsecs_t sync_started = systemTime(SYSTEM_TIME_REALTIME);
     if (fsync(mFd) != 0) {
         ALOGW("(ignored)fsync err:%s(%d)", std::strerror(errno), errno);
         // Don't bubble up fsync error, b/157291505.
         // if (err == OK) { err = ERROR_IO; }
     }
+    nsecs_t sync_finished = systemTime(SYSTEM_TIME_REALTIME);
+    nsecs_t sync_elapsed_ns = sync_finished - sync_started;
+    int64_t filesize = -1;
+    struct stat statbuf;
+    if (fstat(mFd, &statbuf) == 0) {
+        filesize = statbuf.st_size;
+    }
+    ALOGD("final fsync() takes %" PRId64 " ms, file size %" PRId64,
+          sync_elapsed_ns / 1000000, (int64_t) filesize);
+
     if (close(mFd) != 0) {
         ALOGE("close err:%s(%d)", std::strerror(errno), errno);
         if (err == OK) { err = ERROR_IO; }
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 6245014..f2c7dd6 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -50,8 +50,9 @@
       mSampleTimeUs(timeUs) {
 }
 
-NuMediaExtractor::NuMediaExtractor()
-    : mTotalBitrate(-1LL),
+NuMediaExtractor::NuMediaExtractor(EntryPoint entryPoint)
+    : mEntryPoint(entryPoint),
+      mTotalBitrate(-1LL),
       mDurationUs(-1LL) {
 }
 
@@ -93,6 +94,7 @@
     if (mImpl == NULL) {
         return ERROR_UNSUPPORTED;
     }
+    setEntryPointToRemoteMediaExtractor();
 
     status_t err = OK;
     if (!mCasToken.empty()) {
@@ -134,6 +136,7 @@
     if (mImpl == NULL) {
         return ERROR_UNSUPPORTED;
     }
+    setEntryPointToRemoteMediaExtractor();
 
     if (!mCasToken.empty()) {
         err = mImpl->setMediaCas(mCasToken);
@@ -168,6 +171,7 @@
     if (mImpl == NULL) {
         return ERROR_UNSUPPORTED;
     }
+    setEntryPointToRemoteMediaExtractor();
 
     if (!mCasToken.empty()) {
         err = mImpl->setMediaCas(mCasToken);
@@ -489,6 +493,16 @@
     }
 }
 
+void NuMediaExtractor::setEntryPointToRemoteMediaExtractor() {
+    if (mImpl == NULL) {
+        return;
+    }
+    status_t err = mImpl->setEntryPoint(mEntryPoint);
+    if (err != OK) {
+        ALOGW("Failed to set entry point with error %d.", err);
+    }
+}
+
 ssize_t NuMediaExtractor::fetchAllTrackSamples(
         int64_t seekTimeUs, MediaSource::ReadOptions::SeekMode mode) {
     TrackInfo *minInfo = NULL;
diff --git a/media/libstagefright/RemoteMediaExtractor.cpp b/media/libstagefright/RemoteMediaExtractor.cpp
index 25e43c2..381eb1a 100644
--- a/media/libstagefright/RemoteMediaExtractor.cpp
+++ b/media/libstagefright/RemoteMediaExtractor.cpp
@@ -39,6 +39,12 @@
 static const char *kExtractorFormat = "android.media.mediaextractor.fmt";
 static const char *kExtractorMime = "android.media.mediaextractor.mime";
 static const char *kExtractorTracks = "android.media.mediaextractor.ntrk";
+static const char *kExtractorEntryPoint = "android.media.mediaextractor.entry";
+
+static const char *kEntryPointSdk = "sdk";
+static const char *kEntryPointWithJvm = "ndk-with-jvm";
+static const char *kEntryPointNoJvm = "ndk-no-jvm";
+static const char *kEntryPointOther = "other";
 
 RemoteMediaExtractor::RemoteMediaExtractor(
         MediaExtractor *extractor,
@@ -74,6 +80,9 @@
             }
             // what else is interesting and not already available?
         }
+        // By default, we set the entry point to be "other". Clients of this
+        // class will override this value by calling setEntryPoint.
+        mMetricsItem->setCString(kExtractorEntryPoint, kEntryPointOther);
     }
 }
 
@@ -143,6 +152,28 @@
     return String8(mExtractor->name());
 }
 
+status_t RemoteMediaExtractor::setEntryPoint(EntryPoint entryPoint) {
+    const char* entryPointString;
+    switch (entryPoint) {
+      case EntryPoint::SDK:
+            entryPointString = kEntryPointSdk;
+            break;
+        case EntryPoint::NDK_WITH_JVM:
+            entryPointString = kEntryPointWithJvm;
+            break;
+        case EntryPoint::NDK_NO_JVM:
+            entryPointString = kEntryPointNoJvm;
+            break;
+        case EntryPoint::OTHER:
+            entryPointString = kEntryPointOther;
+            break;
+        default:
+            return BAD_VALUE;
+    }
+    mMetricsItem->setCString(kExtractorEntryPoint, entryPointString);
+    return OK;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 // static
diff --git a/media/libstagefright/TEST_MAPPING b/media/libstagefright/TEST_MAPPING
index 76fc74f..dff7b22 100644
--- a/media/libstagefright/TEST_MAPPING
+++ b/media/libstagefright/TEST_MAPPING
@@ -11,7 +11,7 @@
 
   ],
 
-  "presubmit": [
+  "presubmit-large": [
     {
       "name": "CtsMediaTestCases",
       "options": [
@@ -29,7 +29,9 @@
           "exclude-filter": "android.media.cts.AudioRecordTest"
         }
       ]
-    },
+    }
+  ],
+  "presubmit": [
     {
       "name": "mediacodecTest"
     }
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 67493f0..fbaa38e 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -770,6 +770,7 @@
         { "text-format-data", kKeyTextFormatData },
         { "thumbnail-csd-hevc", kKeyThumbnailHVCC },
         { "slow-motion-markers", kKeySlowMotionMarkers },
+        { "thumbnail-csd-av1c", kKeyThumbnailAV1C },
     }
 };
 
@@ -2191,7 +2192,7 @@
 #ifdef DISABLE_AUDIO_SYSTEM_OFFLOAD
     return false;
 #else
-    return AudioSystem::isOffloadSupported(info);
+    return AudioSystem::getOffloadSupport(info) != AUDIO_OFFLOAD_NOT_SUPPORTED;
 #endif
 }
 
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 2aeddd7..28a7a1e 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -38,6 +38,7 @@
 #define DRC_DEFAULT_MOBILE_DRC_HEAVY 1   /* switch for heavy compression for mobile conf */
 #define DRC_DEFAULT_MOBILE_DRC_EFFECT 3  /* MPEG-D DRC effect type; 3 => Limited playback range */
 #define DRC_DEFAULT_MOBILE_DRC_ALBUM 0  /* MPEG-D DRC album mode; 0 => album mode is disabled, 1 => album mode is enabled */
+#define DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS -1 /* decoder output loudness; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
 #define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
 #define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
 // names of properties that can be used to override the default DRC settings
@@ -230,6 +231,15 @@
     // For seven and eight channel input streams, enable 6.1 and 7.1 channel output
     aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1);
 
+    mDrcCompressMode = DRC_DEFAULT_MOBILE_DRC_HEAVY;
+    mDrcTargetRefLevel = DRC_DEFAULT_MOBILE_REF_LEVEL;
+    mDrcEncTargetLevel = DRC_DEFAULT_MOBILE_ENC_LEVEL;
+    mDrcBoostFactor = DRC_DEFAULT_MOBILE_DRC_BOOST;
+    mDrcAttenuationFactor = DRC_DEFAULT_MOBILE_DRC_CUT;
+    mDrcEffectType = DRC_DEFAULT_MOBILE_DRC_EFFECT;
+    mDrcAlbumMode = DRC_DEFAULT_MOBILE_DRC_ALBUM;
+    mDrcOutputLoudness = DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS;
+
     return status;
 }
 
@@ -358,6 +368,27 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioAndroidAacDrcPresentation:
+        {
+             OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE *aacPresParams =
+                    (OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE *)params;
+
+            ALOGD("get OMX_IndexParamAudioAndroidAacDrcPresentation");
+
+            if (!isValidOMXParam(aacPresParams)) {
+                return OMX_ErrorBadParameter;
+            }
+            aacPresParams->nDrcEffectType = mDrcEffectType;
+            aacPresParams->nDrcAlbumMode = mDrcAlbumMode;
+            aacPresParams->nDrcBoost =  mDrcBoostFactor;
+            aacPresParams->nDrcCut = mDrcAttenuationFactor;
+            aacPresParams->nHeavyCompression = mDrcCompressMode;
+            aacPresParams->nTargetReferenceLevel = mDrcTargetRefLevel;
+            aacPresParams->nEncodedTargetLevel = mDrcEncTargetLevel;
+            aacPresParams ->nDrcOutputLoudness = mDrcOutputLoudness;
+            return OMX_ErrorNone;
+        }
+
         default:
             return SimpleSoftOMXComponent::internalGetParameter(index, params);
     }
@@ -464,11 +495,13 @@
             if (aacPresParams->nDrcEffectType >= -1) {
                 ALOGV("set nDrcEffectType=%d", aacPresParams->nDrcEffectType);
                 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, aacPresParams->nDrcEffectType);
+                mDrcEffectType = aacPresParams->nDrcEffectType;
             }
             if (aacPresParams->nDrcAlbumMode >= -1) {
                 ALOGV("set nDrcAlbumMode=%d", aacPresParams->nDrcAlbumMode);
                 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_ALBUM_MODE,
                         aacPresParams->nDrcAlbumMode);
+                mDrcAlbumMode = aacPresParams->nDrcAlbumMode;
             }
             bool updateDrcWrapper = false;
             if (aacPresParams->nDrcBoost >= 0) {
@@ -476,34 +509,42 @@
                 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR,
                         aacPresParams->nDrcBoost);
                 updateDrcWrapper = true;
+                mDrcBoostFactor = aacPresParams->nDrcBoost;
             }
             if (aacPresParams->nDrcCut >= 0) {
                 ALOGV("set nDrcCut=%d", aacPresParams->nDrcCut);
                 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, aacPresParams->nDrcCut);
                 updateDrcWrapper = true;
+                mDrcAttenuationFactor = aacPresParams->nDrcCut;
             }
             if (aacPresParams->nHeavyCompression >= 0) {
                 ALOGV("set nHeavyCompression=%d", aacPresParams->nHeavyCompression);
                 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY,
                         aacPresParams->nHeavyCompression);
                 updateDrcWrapper = true;
+                mDrcCompressMode = aacPresParams->nHeavyCompression;
             }
             if (aacPresParams->nTargetReferenceLevel >= -1) {
                 ALOGV("set nTargetReferenceLevel=%d", aacPresParams->nTargetReferenceLevel);
                 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET,
                         aacPresParams->nTargetReferenceLevel);
                 updateDrcWrapper = true;
+                mDrcTargetRefLevel = aacPresParams->nTargetReferenceLevel;
             }
             if (aacPresParams->nEncodedTargetLevel >= 0) {
                 ALOGV("set nEncodedTargetLevel=%d", aacPresParams->nEncodedTargetLevel);
                 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET,
                         aacPresParams->nEncodedTargetLevel);
                 updateDrcWrapper = true;
+                mDrcEncTargetLevel = aacPresParams->nEncodedTargetLevel;
             }
             if (aacPresParams->nPCMLimiterEnable >= 0) {
                 aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE,
                         (aacPresParams->nPCMLimiterEnable != 0));
             }
+            if (aacPresParams ->nDrcOutputLoudness != DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS) {
+                mDrcOutputLoudness = aacPresParams ->nDrcOutputLoudness;
+            }
             if (updateDrcWrapper) {
                 mDrcWrap.update();
             }
@@ -854,6 +895,11 @@
                     // fall through
                 }
 
+                if ( mDrcOutputLoudness != mStreamInfo->outputLoudness) {
+                    ALOGD("update Loudness, before = %d, now = %d", mDrcOutputLoudness, mStreamInfo->outputLoudness);
+                    mDrcOutputLoudness = mStreamInfo->outputLoudness;
+                }
+
                 /*
                  * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
                  * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 5bee710..9f98aa1 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -85,6 +85,17 @@
     int32_t mOutputDelayRingBufferWritePos;
     int32_t mOutputDelayRingBufferReadPos;
     int32_t mOutputDelayRingBufferFilled;
+
+    //drc
+    int32_t mDrcCompressMode;
+    int32_t mDrcTargetRefLevel;
+    int32_t mDrcEncTargetLevel;
+    int32_t mDrcBoostFactor;
+    int32_t mDrcAttenuationFactor;
+    int32_t mDrcEffectType;
+    int32_t mDrcAlbumMode;
+    int32_t mDrcOutputLoudness;
+
     bool outputDelayRingBufferPutSamples(INT_PCM *samples, int numSamples);
     int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
     int32_t outputDelayRingBufferSamplesAvailable();
diff --git a/media/libstagefright/codecs/amrnb/dec/Android.bp b/media/libstagefright/codecs/amrnb/dec/Android.bp
index b8e00b3..9d0da17 100644
--- a/media/libstagefright/codecs/amrnb/dec/Android.bp
+++ b/media/libstagefright/codecs/amrnb/dec/Android.bp
@@ -1,76 +1,3 @@
-cc_library_static {
-    name: "libstagefright_amrnbdec",
-    vendor_available: true,
-    host_supported: true,
-    min_sdk_version: "29",
-
-    srcs: [
-        "src/a_refl.cpp",
-        "src/agc.cpp",
-        "src/amrdecode.cpp",
-        "src/b_cn_cod.cpp",
-        "src/bgnscd.cpp",
-        "src/c_g_aver.cpp",
-        "src/d1035pf.cpp",
-        "src/d2_11pf.cpp",
-        "src/d2_9pf.cpp",
-        "src/d3_14pf.cpp",
-        "src/d4_17pf.cpp",
-        "src/d8_31pf.cpp",
-        "src/d_gain_c.cpp",
-        "src/d_gain_p.cpp",
-        "src/d_plsf.cpp",
-        "src/d_plsf_3.cpp",
-        "src/d_plsf_5.cpp",
-        "src/dec_amr.cpp",
-        "src/dec_gain.cpp",
-        "src/dec_input_format_tab.cpp",
-        "src/dec_lag3.cpp",
-        "src/dec_lag6.cpp",
-        "src/dtx_dec.cpp",
-        "src/ec_gains.cpp",
-        "src/ex_ctrl.cpp",
-        "src/if2_to_ets.cpp",
-        "src/int_lsf.cpp",
-        "src/lsp_avg.cpp",
-        "src/ph_disp.cpp",
-        "src/post_pro.cpp",
-        "src/preemph.cpp",
-        "src/pstfilt.cpp",
-        "src/qgain475_tab.cpp",
-        "src/sp_dec.cpp",
-        "src/wmf_to_ets.cpp",
-    ],
-
-    export_include_dirs: ["src"],
-
-    cflags: [
-        "-DOSCL_UNUSED_ARG(x)=(void)(x)",
-        "-DOSCL_IMPORT_REF=",
-
-        "-Werror",
-    ],
-
-    version_script: "exports.lds",
-
-    //sanitize: {
-    //    misc_undefined: [
-    //        "signed-integer-overflow",
-    //    ],
-    //},
-
-    shared_libs: [
-        "libstagefright_amrnb_common",
-        "liblog",
-    ],
-
-    target: {
-        darwin: {
-            enabled: false,
-        },
-    },
-}
-
 //###############################################################################
 
 cc_library_shared {
@@ -79,8 +6,6 @@
 
     srcs: ["SoftAMR.cpp"],
 
-    local_include_dirs: ["src"],
-
     cflags: [
         "-DOSCL_IMPORT_REF=",
     ],
@@ -104,38 +29,3 @@
     ],
 }
 
-//###############################################################################
-cc_test {
-    name: "libstagefright_amrnbdec_test",
-    gtest: false,
-    host_supported: true,
-
-    srcs: ["test/amrnbdec_test.cpp"],
-
-    cflags: ["-Wall", "-Werror"],
-
-    local_include_dirs: ["src"],
-
-    static_libs: [
-        "libstagefright_amrnbdec",
-        "libsndfile",
-    ],
-
-    shared_libs: [
-        "libstagefright_amrnb_common",
-        "libaudioutils",
-        "liblog",
-    ],
-
-    target: {
-        darwin: {
-            enabled: false,
-        },
-    },
-
-    //sanitize: {
-    //    misc_undefined: [
-    //        "signed-integer-overflow",
-    //    ],
-    //},
-}
diff --git a/media/libstagefright/codecs/amrnb/enc/Android.bp b/media/libstagefright/codecs/amrnb/enc/Android.bp
index ff9a720..bdd1cdf 100644
--- a/media/libstagefright/codecs/amrnb/enc/Android.bp
+++ b/media/libstagefright/codecs/amrnb/enc/Android.bp
@@ -1,94 +1,3 @@
-cc_library_static {
-    name: "libstagefright_amrnbenc",
-    vendor_available: true,
-    min_sdk_version: "29",
-
-    srcs: [
-        "src/amrencode.cpp",
-        "src/autocorr.cpp",
-        "src/c1035pf.cpp",
-        "src/c2_11pf.cpp",
-        "src/c2_9pf.cpp",
-        "src/c3_14pf.cpp",
-        "src/c4_17pf.cpp",
-        "src/c8_31pf.cpp",
-        "src/calc_cor.cpp",
-        "src/calc_en.cpp",
-        "src/cbsearch.cpp",
-        "src/cl_ltp.cpp",
-        "src/cod_amr.cpp",
-        "src/convolve.cpp",
-        "src/cor_h.cpp",
-        "src/cor_h_x.cpp",
-        "src/cor_h_x2.cpp",
-        "src/corrwght_tab.cpp",
-        "src/dtx_enc.cpp",
-        "src/enc_lag3.cpp",
-        "src/enc_lag6.cpp",
-        "src/enc_output_format_tab.cpp",
-        "src/ets_to_if2.cpp",
-        "src/ets_to_wmf.cpp",
-        "src/g_adapt.cpp",
-        "src/g_code.cpp",
-        "src/g_pitch.cpp",
-        "src/gain_q.cpp",
-        "src/hp_max.cpp",
-        "src/inter_36.cpp",
-        "src/inter_36_tab.cpp",
-        "src/l_comp.cpp",
-        "src/l_extract.cpp",
-        "src/l_negate.cpp",
-        "src/lag_wind.cpp",
-        "src/lag_wind_tab.cpp",
-        "src/levinson.cpp",
-        "src/lpc.cpp",
-        "src/ol_ltp.cpp",
-        "src/p_ol_wgh.cpp",
-        "src/pitch_fr.cpp",
-        "src/pitch_ol.cpp",
-        "src/pre_big.cpp",
-        "src/pre_proc.cpp",
-        "src/prm2bits.cpp",
-        "src/q_gain_c.cpp",
-        "src/q_gain_p.cpp",
-        "src/qgain475.cpp",
-        "src/qgain795.cpp",
-        "src/qua_gain.cpp",
-        "src/s10_8pf.cpp",
-        "src/set_sign.cpp",
-        "src/sid_sync.cpp",
-        "src/sp_enc.cpp",
-        "src/spreproc.cpp",
-        "src/spstproc.cpp",
-        "src/ton_stab.cpp",
-    ],
-
-    header_libs: ["libstagefright_headers"],
-    export_include_dirs: ["src"],
-
-    cflags: [
-        "-DOSCL_UNUSED_ARG(x)=(void)(x)",
-        "-Werror",
-    ],
-
-    version_script: "exports.lds",
-
-    //addressing b/25409744
-    //sanitize: {
-    //    misc_undefined: [
-    //        "signed-integer-overflow",
-    //    ],
-    //},
-
-    shared_libs: ["libstagefright_amrnb_common"],
-
-    host_supported: true,
-    target: {
-        darwin: {
-            enabled: false,
-        },
-    },
-}
 
 //###############################################################################
 
@@ -98,8 +7,6 @@
 
     srcs: ["SoftAMRNBEncoder.cpp"],
 
-    local_include_dirs: ["src"],
-
     //addressing b/25409744
     //sanitize: {
     //    misc_undefined: [
@@ -114,26 +21,3 @@
     ],
 }
 
-//###############################################################################
-
-cc_test {
-    name: "libstagefright_amrnbenc_test",
-    gtest: false,
-
-    srcs: ["test/amrnb_enc_test.cpp"],
-
-    cflags: ["-Wall", "-Werror"],
-
-    local_include_dirs: ["src"],
-
-    static_libs: ["libstagefright_amrnbenc"],
-
-    shared_libs: ["libstagefright_amrnb_common"],
-
-    //addressing b/25409744
-    //sanitize: {
-    //    misc_undefined: [
-    //        "signed-integer-overflow",
-    //    ],
-    //},
-}
diff --git a/media/libstagefright/codecs/amrwb/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/amrwb/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/libstagefright/codecs/amrwb/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/libstagefright/codecs/amrwb/NOTICE b/media/libstagefright/codecs/amrwb/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/libstagefright/codecs/amrwb/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/media/libstagefright/codecs/amrwb/patent_disclaimer.txt b/media/libstagefright/codecs/amrwb/patent_disclaimer.txt
deleted file mode 100644
index b4bf11d..0000000
--- a/media/libstagefright/codecs/amrwb/patent_disclaimer.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-
-THIS IS NOT A GRANT OF PATENT RIGHTS.
-
-Google makes no representation or warranty that the codecs for which
-source code is made available hereunder are unencumbered by
-third-party patents.  Those intending to use this source code in
-hardware or software products are advised that implementations of
-these codecs, including in open source software or shareware, may
-require patent licenses from the relevant patent holders.
diff --git a/media/libstagefright/codecs/amrwbenc/Android.bp b/media/libstagefright/codecs/amrwbenc/Android.bp
index 70c672d..67a0f45 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/Android.bp
@@ -1,152 +1,3 @@
-cc_library_static {
-    name: "libstagefright_amrwbenc",
-    vendor_available: true,
-    min_sdk_version: "29",
-
-    srcs: [
-        "src/autocorr.c",
-        "src/az_isp.c",
-        "src/bits.c",
-        "src/c2t64fx.c",
-        "src/c4t64fx.c",
-        "src/convolve.c",
-        "src/cor_h_x.c",
-        "src/decim54.c",
-        "src/deemph.c",
-        "src/dtx.c",
-        "src/g_pitch.c",
-        "src/gpclip.c",
-        "src/homing.c",
-        "src/hp400.c",
-        "src/hp50.c",
-        "src/hp6k.c",
-        "src/hp_wsp.c",
-        "src/int_lpc.c",
-        "src/isp_az.c",
-        "src/isp_isf.c",
-        "src/lag_wind.c",
-        "src/levinson.c",
-        "src/log2.c",
-        "src/lp_dec2.c",
-        "src/math_op.c",
-        "src/oper_32b.c",
-        "src/p_med_ol.c",
-        "src/pit_shrp.c",
-        "src/pitch_f4.c",
-        "src/pred_lt4.c",
-        "src/preemph.c",
-        "src/q_gain2.c",
-        "src/q_pulse.c",
-        "src/qisf_ns.c",
-        "src/qpisf_2s.c",
-        "src/random.c",
-        "src/residu.c",
-        "src/scale.c",
-        "src/stream.c",
-        "src/syn_filt.c",
-        "src/updt_tar.c",
-        "src/util.c",
-        "src/voAMRWBEnc.c",
-        "src/voicefac.c",
-        "src/wb_vad.c",
-        "src/weight_a.c",
-        "src/mem_align.c",
-    ],
-
-    arch: {
-        arm: {
-            srcs: [
-                "src/asm/ARMV5E/convolve_opt.s",
-                "src/asm/ARMV5E/cor_h_vec_opt.s",
-                "src/asm/ARMV5E/Deemph_32_opt.s",
-                "src/asm/ARMV5E/Dot_p_opt.s",
-                "src/asm/ARMV5E/Filt_6k_7k_opt.s",
-                "src/asm/ARMV5E/Norm_Corr_opt.s",
-                "src/asm/ARMV5E/pred_lt4_1_opt.s",
-                "src/asm/ARMV5E/residu_asm_opt.s",
-                "src/asm/ARMV5E/scale_sig_opt.s",
-                "src/asm/ARMV5E/Syn_filt_32_opt.s",
-                "src/asm/ARMV5E/syn_filt_opt.s",
-            ],
-
-            cflags: [
-                "-DARM",
-                "-DASM_OPT",
-            ],
-            local_include_dirs: ["src/asm/ARMV5E"],
-
-            instruction_set: "arm",
-
-            neon: {
-                exclude_srcs: [
-                    "src/asm/ARMV5E/convolve_opt.s",
-                    "src/asm/ARMV5E/cor_h_vec_opt.s",
-                    "src/asm/ARMV5E/Deemph_32_opt.s",
-                    "src/asm/ARMV5E/Dot_p_opt.s",
-                    "src/asm/ARMV5E/Filt_6k_7k_opt.s",
-                    "src/asm/ARMV5E/Norm_Corr_opt.s",
-                    "src/asm/ARMV5E/pred_lt4_1_opt.s",
-                    "src/asm/ARMV5E/residu_asm_opt.s",
-                    "src/asm/ARMV5E/scale_sig_opt.s",
-                    "src/asm/ARMV5E/Syn_filt_32_opt.s",
-                    "src/asm/ARMV5E/syn_filt_opt.s",
-                ],
-
-                srcs: [
-                    "src/asm/ARMV7/convolve_neon.s",
-                    "src/asm/ARMV7/cor_h_vec_neon.s",
-                    "src/asm/ARMV7/Deemph_32_neon.s",
-                    "src/asm/ARMV7/Dot_p_neon.s",
-                    "src/asm/ARMV7/Filt_6k_7k_neon.s",
-                    "src/asm/ARMV7/Norm_Corr_neon.s",
-                    "src/asm/ARMV7/pred_lt4_1_neon.s",
-                    "src/asm/ARMV7/residu_asm_neon.s",
-                    "src/asm/ARMV7/scale_sig_neon.s",
-                    "src/asm/ARMV7/Syn_filt_32_neon.s",
-                    "src/asm/ARMV7/syn_filt_neon.s",
-                ],
-
-                // don't actually generate neon instructions, see bug 26932980
-                cflags: [
-                    "-DARMV7",
-                    "-mfpu=vfpv3",
-                ],
-                local_include_dirs: [
-                    "src/asm/ARMV5E",
-                    "src/asm/ARMV7",
-                ],
-            },
-
-        },
-    },
-
-    include_dirs: [
-        "frameworks/av/include",
-        "frameworks/av/media/libstagefright/include",
-    ],
-
-    local_include_dirs: ["src"],
-    export_include_dirs: ["inc"],
-
-    shared_libs: [
-        "libstagefright_enc_common",
-        "liblog",
-    ],
-
-    cflags: ["-Werror"],
-    sanitize: {
-        cfi: true,
-    },
-
-    host_supported: true,
-    target: {
-        darwin: {
-            enabled: false,
-        },
-    },
-}
-
-//###############################################################################
 
 cc_library_shared {
     name: "libstagefright_soft_amrwbenc",
diff --git a/media/libstagefright/codecs/amrwbenc/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/amrwbenc/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/libstagefright/codecs/amrwbenc/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/libstagefright/codecs/amrwbenc/NOTICE b/media/libstagefright/codecs/amrwbenc/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/libstagefright/codecs/amrwbenc/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
index 7a33c54..e5cccd8 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
@@ -1,64 +1,3 @@
-cc_library_static {
-    name: "libstagefright_m4vh263dec",
-    vendor_available: true,
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.media.swcodec",
-    ],
-    min_sdk_version: "29",
-    host_supported: true,
-    shared_libs: ["liblog"],
-
-    srcs: [
-        "src/bitstream.cpp",
-        "src/block_idct.cpp",
-        "src/cal_dc_scaler.cpp",
-        "src/combined_decode.cpp",
-        "src/conceal.cpp",
-        "src/datapart_decode.cpp",
-        "src/dcac_prediction.cpp",
-        "src/dec_pred_intra_dc.cpp",
-        "src/get_pred_adv_b_add.cpp",
-        "src/get_pred_outside.cpp",
-        "src/idct.cpp",
-        "src/idct_vca.cpp",
-        "src/mb_motion_comp.cpp",
-        "src/mb_utils.cpp",
-        "src/packet_util.cpp",
-        "src/post_filter.cpp",
-        "src/pvdec_api.cpp",
-        "src/scaling_tab.cpp",
-        "src/vlc_decode.cpp",
-        "src/vlc_dequant.cpp",
-        "src/vlc_tab.cpp",
-        "src/vop.cpp",
-        "src/zigzag_tab.cpp",
-    ],
-
-    local_include_dirs: ["src"],
-    export_include_dirs: ["include"],
-
-    cflags: [
-        "-Werror",
-    ],
-
-    version_script: "exports.lds",
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-
-    target: {
-        darwin: {
-            enabled: false,
-        },
-    },
-}
-
-//###############################################################################
 
 cc_library_shared {
     name: "libstagefright_soft_mpeg4dec",
@@ -66,8 +5,6 @@
 
     srcs: ["SoftMPEG4.cpp"],
 
-    local_include_dirs: ["src"],
-
     cflags: [
     ],
 
diff --git a/media/libstagefright/codecs/m4v_h263/enc/Android.bp b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
index 13d310d..9e120d3 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
@@ -1,55 +1,3 @@
-cc_library_static {
-    name: "libstagefright_m4vh263enc",
-    vendor_available: true,
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.media.swcodec",
-    ],
-    min_sdk_version: "29",
-    host_supported: true,
-    target: {
-        darwin: {
-            enabled: false,
-        },
-    },
-
-    srcs: [
-        "src/bitstream_io.cpp",
-        "src/combined_encode.cpp", "src/datapart_encode.cpp",
-        "src/dct.cpp",
-        "src/findhalfpel.cpp",
-        "src/fastcodemb.cpp",
-        "src/fastidct.cpp",
-        "src/fastquant.cpp",
-        "src/me_utils.cpp",
-        "src/mp4enc_api.cpp",
-        "src/rate_control.cpp",
-        "src/motion_est.cpp",
-        "src/motion_comp.cpp",
-        "src/sad.cpp",
-        "src/sad_halfpel.cpp",
-        "src/vlc_encode.cpp",
-        "src/vop.cpp",
-    ],
-
-    cflags: [
-        "-DBX_RC",
-        "-Werror",
-    ],
-
-    version_script: "exports.lds",
-
-    local_include_dirs: ["src"],
-    export_include_dirs: ["include"],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-}
-
 //###############################################################################
 
 cc_library_shared {
@@ -58,8 +6,6 @@
 
     srcs: ["SoftMPEG4Encoder.cpp"],
 
-    local_include_dirs: ["src"],
-
     cflags: [
         "-DBX_RC",
     ],
@@ -74,28 +20,3 @@
     },
 }
 
-//###############################################################################
-
-cc_test {
-    name: "libstagefright_m4vh263enc_test",
-    gtest: false,
-
-    srcs: ["test/m4v_h263_enc_test.cpp"],
-
-    local_include_dirs: ["src"],
-
-    cflags: [
-        "-DBX_RC",
-        "-Wall",
-        "-Werror",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-
-    static_libs: ["libstagefright_m4vh263enc"],
-}
diff --git a/media/libstagefright/codecs/m4v_h263/fuzzer/README.md b/media/libstagefright/codecs/m4v_h263/fuzzer/README.md
deleted file mode 100644
index c2a4f69..0000000
--- a/media/libstagefright/codecs/m4v_h263/fuzzer/README.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# Fuzzer for libstagefright_m4vh263dec decoder
-
-## Plugin Design Considerations
-The fuzzer plugin for MPEG4/H263 is designed based on the understanding of the
-codec and tries to achieve the following:
-
-##### Maximize code coverage
-Dict files (dictionary files) are created for MPEG4 and H263 to ensure that the required start
-bytes are present in every input file that goes to the fuzzer.
-This ensures that decoder does not reject any input file in the first check
-
-##### Maximize utilization of input data
-The plugin feeds the entire input data to the codec using a loop.
- * If the decode operation was successful, the input is advanced by the number of bytes consumed
-   in the decode call.
- * If the decode operation was un-successful, the input is advanced by 1 byte so that the fuzzer
-   can proceed to feed the next frame.
-
-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.
-
-##### Other considerations
- * Two fuzzer binaries - mpeg4_dec_fuzzer and h263_dec_fuzzer are generated based on the presence
-   of a flag - 'MPEG4'
- * The number of decode calls are kept to a maximum of 100 so that the fuzzer does not timeout.
-
-## Build
-
-This describes steps to build mpeg4_dec_fuzzer and h263_dec_fuzzer binary.
-
-### Android
-#### Steps to build
-Build the fuzzer
-```
-  $ mm -j$(nproc) mpeg4_dec_fuzzer
-  $ mm -j$(nproc) h263_dec_fuzzer
-```
-
-#### Steps to run
-Create a directory CORPUS_DIR and copy some MPEG4 or H263 files to that folder
-Push this directory to device.
-
-To run on device
-```
-  $ adb sync data
-  $ adb shell /data/fuzz/arm64/mpeg4_dec_fuzzer/mpeg4_dec_fuzzer CORPUS_DIR
-  $ adb shell /data/fuzz/arm64/h263_dec_fuzzer/h263_dec_fuzzer CORPUS_DIR
-```
-To run on host
-```
-  $ $ANDROID_HOST_OUT/fuzz/x86_64/mpeg4_dec_fuzzer/mpeg4_dec_fuzzer CORPUS_DIR
-  $ $ANDROID_HOST_OUT/fuzz/x86_64/h263_dec_fuzzer/h263_dec_fuzzer CORPUS_DIR
-```
-
-## References:
- * http://llvm.org/docs/LibFuzzer.html
- * https://github.com/google/oss-fuzz
diff --git a/media/libstagefright/codecs/mp3dec/Android.bp b/media/libstagefright/codecs/mp3dec/Android.bp
index 316d63c..61b248b 100644
--- a/media/libstagefright/codecs/mp3dec/Android.bp
+++ b/media/libstagefright/codecs/mp3dec/Android.bp
@@ -1,88 +1,3 @@
-cc_library_static {
-    name: "libstagefright_mp3dec",
-    vendor_available: true,
-    min_sdk_version: "29",
-
-    host_supported:true,
-    srcs: [
-        "src/pvmp3_normalize.cpp",
-        "src/pvmp3_alias_reduction.cpp",
-        "src/pvmp3_crc.cpp",
-        "src/pvmp3_decode_header.cpp",
-        "src/pvmp3_decode_huff_cw.cpp",
-        "src/pvmp3_getbits.cpp",
-        "src/pvmp3_dequantize_sample.cpp",
-        "src/pvmp3_framedecoder.cpp",
-        "src/pvmp3_get_main_data_size.cpp",
-        "src/pvmp3_get_side_info.cpp",
-        "src/pvmp3_get_scale_factors.cpp",
-        "src/pvmp3_mpeg2_get_scale_data.cpp",
-        "src/pvmp3_mpeg2_get_scale_factors.cpp",
-        "src/pvmp3_mpeg2_stereo_proc.cpp",
-        "src/pvmp3_huffman_decoding.cpp",
-        "src/pvmp3_huffman_parsing.cpp",
-        "src/pvmp3_tables.cpp",
-        "src/pvmp3_imdct_synth.cpp",
-        "src/pvmp3_mdct_6.cpp",
-        "src/pvmp3_dct_6.cpp",
-        "src/pvmp3_poly_phase_synthesis.cpp",
-        "src/pvmp3_equalizer.cpp",
-        "src/pvmp3_seek_synch.cpp",
-        "src/pvmp3_stereo_proc.cpp",
-        "src/pvmp3_reorder.cpp",
-
-        "src/pvmp3_polyphase_filter_window.cpp",
-        "src/pvmp3_mdct_18.cpp",
-        "src/pvmp3_dct_9.cpp",
-        "src/pvmp3_dct_16.cpp",
-    ],
-
-    arch: {
-        arm: {
-            exclude_srcs: [
-                "src/pvmp3_polyphase_filter_window.cpp",
-                "src/pvmp3_mdct_18.cpp",
-                "src/pvmp3_dct_9.cpp",
-                "src/pvmp3_dct_16.cpp",
-            ],
-            srcs: [
-                "src/asm/pvmp3_polyphase_filter_window_gcc.s",
-                "src/asm/pvmp3_mdct_18_gcc.s",
-                "src/asm/pvmp3_dct_9_gcc.s",
-                "src/asm/pvmp3_dct_16_gcc.s",
-            ],
-
-            instruction_set: "arm",
-        },
-    },
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-
-    include_dirs: ["frameworks/av/media/libstagefright/include"],
-
-    export_include_dirs: [
-        "include",
-        "src",
-    ],
-
-    cflags: [
-        "-DOSCL_UNUSED_ARG(x)=(void)(x)",
-        "-Werror",
-    ],
-
-    target: {
-        darwin: {
-            enabled: false,
-        },
-    },
-}
-
-//###############################################################################
 
 cc_library_shared {
     name: "libstagefright_soft_mp3dec",
@@ -90,11 +5,6 @@
 
     srcs: ["SoftMP3.cpp"],
 
-    local_include_dirs: [
-        "src",
-        "include",
-    ],
-
     version_script: "exports.lds",
 
     sanitize: {
@@ -107,34 +17,3 @@
     static_libs: ["libstagefright_mp3dec"],
 }
 
-//###############################################################################
-cc_test {
-    name: "libstagefright_mp3dec_test",
-    gtest: false,
-
-    srcs: [
-        "test/mp3dec_test.cpp",
-        "test/mp3reader.cpp",
-    ],
-
-    cflags: ["-Wall", "-Werror"],
-
-    local_include_dirs: [
-        "src",
-        "include",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-
-    static_libs: [
-        "libstagefright_mp3dec",
-        "libsndfile",
-    ],
-
-    shared_libs: ["libaudioutils"],
-}
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index b5d32ed..15cde20 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -23,7 +23,7 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaDefs.h>
 
-#include "include/pvmp3decoder_api.h"
+#include <pvmp3decoder_api.h>
 
 namespace android {
 
diff --git a/media/libstagefright/id3/TEST_MAPPING b/media/libstagefright/id3/TEST_MAPPING
index d070d25..d82d26e 100644
--- a/media/libstagefright/id3/TEST_MAPPING
+++ b/media/libstagefright/id3/TEST_MAPPING
@@ -7,7 +7,7 @@
     { "name": "ID3Test" }
   ],
 
-  "presubmit": [
+  "presubmit-large": [
     // this doesn't seem to run any tests.
     // but: cts-tradefed run -m CtsMediaTestCases -t android.media.cts.MediaMetadataRetrieverTest
     // does run he 32 and 64 bit tests, but not the instant tests
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
index 6b0d28f..f260510 100644
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ b/media/libstagefright/include/media/stagefright/MetaDataBase.h
@@ -62,6 +62,7 @@
     kKeyDVCC              = 'dvcc',  // raw data
     kKeyAV1C              = 'av1c',  // raw data
     kKeyThumbnailHVCC     = 'thvc',  // raw data
+    kKeyThumbnailAV1C     = 'tav1',  // raw data
     kKeyD263              = 'd263',  // raw data
     kKeyOpusHeader        = 'ohdr',  // raw data
     kKeyOpusCodecDelay    = 'ocod',  // uint64_t (codec delay in ns)
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 227cead..d8f2b00 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -47,12 +47,14 @@
         SAMPLE_FLAG_ENCRYPTED   = 2,
     };
 
+    typedef IMediaExtractor::EntryPoint EntryPoint;
+
     // identical to IMediaExtractor::GetTrackMetaDataFlags
     enum GetTrackFormatFlags {
         kIncludeExtensiveMetaData = 1, // reads sample table and possibly stream headers
     };
 
-    NuMediaExtractor();
+    explicit NuMediaExtractor(EntryPoint entryPoint);
 
     status_t setDataSource(
             const sp<MediaHTTPService> &httpService,
@@ -128,6 +130,8 @@
         uint32_t mTrackFlags;  // bitmask of "TrackFlags"
     };
 
+    const EntryPoint mEntryPoint;
+
     mutable Mutex mLock;
 
     sp<DataSource> mDataSource;
@@ -139,6 +143,8 @@
     int64_t mTotalBitrate;  // in bits/sec
     int64_t mDurationUs;
 
+    void setEntryPointToRemoteMediaExtractor();
+
     ssize_t fetchAllTrackSamples(
             int64_t seekTimeUs = -1ll,
             MediaSource::ReadOptions::SeekMode mode =
diff --git a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
index 2ce7bc7..25125f2 100644
--- a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
@@ -42,6 +42,7 @@
     virtual uint32_t flags() const;
     virtual status_t setMediaCas(const HInterfaceToken &casToken);
     virtual String8 name();
+    virtual status_t setEntryPoint(EntryPoint entryPoint);
 
 private:
     MediaExtractor *mExtractor;
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index ddb459f..44415aa 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -17,6 +17,10 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "SimpleSoftOMXComponent"
 #include <utils/Log.h>
+#include <OMX_Core.h>
+#include <OMX_Audio.h>
+#include <OMX_IndexExt.h>
+#include <OMX_AudioExt.h>
 
 #include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -74,7 +78,7 @@
 
     OMX_U32 portIndex;
 
-    switch (index) {
+    switch ((int)index) {
         case OMX_IndexParamPortDefinition:
         {
             const OMX_PARAM_PORTDEFINITIONTYPE *portDefs =
@@ -108,6 +112,19 @@
             break;
         }
 
+         case OMX_IndexParamAudioAndroidAacDrcPresentation:
+        {
+            if (mState == OMX_StateInvalid) {
+                return false;
+            }
+            const OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE *aacPresParams =
+                            (const OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE *)params;
+            if (!isValidOMXParam(aacPresParams)) {
+                return false;
+            }
+            return true;
+         }
+
         default:
             return false;
     }
diff --git a/media/libstagefright/renderfright/include/renderengine/RenderEngine.h b/media/libstagefright/renderfright/include/renderengine/RenderEngine.h
index 09a0f65..40fdff4 100644
--- a/media/libstagefright/renderfright/include/renderengine/RenderEngine.h
+++ b/media/libstagefright/renderfright/include/renderengine/RenderEngine.h
@@ -33,7 +33,7 @@
 /**
  * Allows to set RenderEngine backend to GLES (default) or Vulkan (NOT yet supported).
  */
-#define PROPERTY_DEBUG_RENDERENGINE_BACKEND "debug.renderengine.backend"
+#define PROPERTY_DEBUG_RENDERENGINE_BACKEND "debug.stagefright.renderengine.backend"
 
 struct ANativeWindowBuffer;
 
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index f57077c..07f9dd3 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -131,7 +131,7 @@
     unsigned start = (unsigned)((rand()* 1000LL)/RAND_MAX) + 15550;
     start &= ~1;
 
-    for (unsigned port = start; port < 65536; port += 2) {
+    for (unsigned port = start; port < 65535; port += 2) {
         struct sockaddr_in addr;
         memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
         addr.sin_family = AF_INET;
@@ -149,6 +149,13 @@
                  (const struct sockaddr *)&addr, sizeof(addr)) == 0) {
             *rtpPort = port;
             return;
+        } else {
+            // we should recreate a RTP socket to avoid bind other port in same RTP socket
+            close(*rtpSocket);
+
+            *rtpSocket = socket(AF_INET, SOCK_DGRAM, 0);
+            CHECK_GE(*rtpSocket, 0);
+            bumpSocketBufferSize(*rtpSocket);
         }
     }
 
diff --git a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
index 3be5e74..dbdb43c 100644
--- a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
+++ b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
@@ -493,7 +493,7 @@
       mPath(path),
       mStatus(NO_INIT) {
     // determine href_base
-    std::string::size_type end = path.rfind("/");
+    std::string::size_type end = path.rfind('/');
     if (end != std::string::npos) {
         mHrefBase = path.substr(0, end + 1);
     }
diff --git a/media/mtp/tests/Android.bp b/media/mtp/tests/MtpFfsHandleTest/Android.bp
similarity index 71%
rename from media/mtp/tests/Android.bp
rename to media/mtp/tests/MtpFfsHandleTest/Android.bp
index 0750208..e393067 100644
--- a/media/mtp/tests/Android.bp
+++ b/media/mtp/tests/MtpFfsHandleTest/Android.bp
@@ -1,5 +1,5 @@
 //
-// Copyright (C) 2017 The Android Open Source Project
+// 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.
@@ -30,18 +30,3 @@
     ],
 }
 
-cc_test {
-    name: "posix_async_io_test",
-    test_suites: ["device-tests"],
-    srcs: ["PosixAsyncIO_test.cpp"],
-    shared_libs: [
-        "libbase",
-        "libmtp",
-        "liblog",
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-}
diff --git a/media/mtp/tests/AndroidTest.xml b/media/mtp/tests/MtpFfsHandleTest/AndroidTest.xml
similarity index 95%
rename from media/mtp/tests/AndroidTest.xml
rename to media/mtp/tests/MtpFfsHandleTest/AndroidTest.xml
index c1f4753..38bab27 100644
--- a/media/mtp/tests/AndroidTest.xml
+++ b/media/mtp/tests/MtpFfsHandleTest/AndroidTest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- 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.
diff --git a/media/mtp/tests/MtpFfsHandle_test.cpp b/media/mtp/tests/MtpFfsHandleTest/MtpFfsHandle_test.cpp
similarity index 100%
rename from media/mtp/tests/MtpFfsHandle_test.cpp
rename to media/mtp/tests/MtpFfsHandleTest/MtpFfsHandle_test.cpp
diff --git a/media/mtp/tests/MtpFuzzer/Android.bp b/media/mtp/tests/MtpFuzzer/Android.bp
new file mode 100644
index 0000000..9cd4669
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/Android.bp
@@ -0,0 +1,31 @@
+cc_fuzz {
+    name: "mtp_fuzzer",
+    srcs: [
+        "mtp_fuzzer.cpp",
+        "MtpMockDatabase.cpp",
+    ],
+    shared_libs: [
+	"libmtp",
+	"libbase",
+	"liblog",
+	"libutils",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-DMTP_DEVICE",
+        "-Wno-unused-parameter",
+    ],
+    dictionary: "mtp_fuzzer.dict",
+    corpus: ["corpus/*"],
+
+    fuzz_config: {
+
+        cc: ["jameswei@google.com"],
+        componentid: 1344,
+        acknowledgement: [
+            "Grant Hernandez of Google",
+        ],
+    },
+}
diff --git a/media/mtp/tests/MtpFuzzer/MtpMockDatabase.cpp b/media/mtp/tests/MtpFuzzer/MtpMockDatabase.cpp
new file mode 100644
index 0000000..5d95aa2
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/MtpMockDatabase.cpp
@@ -0,0 +1,315 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <string>
+
+#define LOG_TAG "MtpFuzzer"
+
+#include <log/log.h>
+
+#include "MtpDebug.h"
+#include "MtpMockDatabase.h"
+#include "MtpObjectInfo.h"
+
+namespace android {
+
+MtpMockDatabase::MtpMockDatabase() : mLastObjectHandle(0) {}
+
+MtpMockDatabase::~MtpMockDatabase() {
+    for (MtpObjectInfo* i : mObjects) {
+        delete i;
+    }
+    mObjects.clear();
+}
+
+void MtpMockDatabase::addObject(MtpObjectInfo* info) {
+    assert(hasStorage(info->storageID));
+
+    // we take ownership
+    mObjects.push_back(info);
+
+    return;
+}
+
+MtpObjectHandle MtpMockDatabase::allocateObjectHandle() {
+    // this is in sync with our mObjects database
+    return mLastObjectHandle++;
+}
+
+// Called from SendObjectInfo to reserve a database entry for the incoming file.
+MtpObjectHandle MtpMockDatabase::beginSendObject(const char* path, MtpObjectFormat format,
+                                                 MtpObjectHandle parent, MtpStorageID storage) {
+    if (!hasStorage(storage)) {
+        ALOGW("%s: Tried to lookup storageID %u, but doesn't exist\n", __func__, storage);
+        return kInvalidObjectHandle;
+    }
+
+    ALOGD("MockDatabase %s: path=%s oformat=0x%04x parent_handle=%u "
+          "storage_id=%u\n",
+          __func__, path, format, parent, storage);
+
+    return mLastObjectHandle;
+}
+
+// Called to report success or failure of the SendObject file transfer.
+void MtpMockDatabase::endSendObject(MtpObjectHandle handle, bool succeeded) {
+    ALOGD("MockDatabase %s: ohandle=%u succeeded=%d\n", __func__, handle, succeeded);
+}
+
+// Called to rescan a file, such as after an edit.
+void MtpMockDatabase::rescanFile(const char* path, MtpObjectHandle handle, MtpObjectFormat format) {
+    ALOGD("MockDatabase %s: path=%s ohandle=%u, oformat=0x%04x\n", __func__, path, handle, format);
+}
+
+MtpObjectHandleList* MtpMockDatabase::getObjectList(MtpStorageID storageID, MtpObjectFormat format,
+                                                    MtpObjectHandle parent) {
+    ALOGD("MockDatabase %s: storage_id=%u oformat=0x%04x ohandle=%u\n", __func__, storageID, format,
+          parent);
+    return nullptr;
+}
+
+int MtpMockDatabase::getNumObjects(MtpStorageID storageID, MtpObjectFormat format,
+                                   MtpObjectHandle parent) {
+    ALOGD("MockDatabase %s: storage_id=%u oformat=0x%04x ohandle=%u\n", __func__, storageID, format,
+          parent);
+    // TODO: return MTP_RESPONSE_OK when it stops segfaulting
+    return 0;
+}
+
+// callee should delete[] the results from these
+// results can be NULL
+MtpObjectFormatList* MtpMockDatabase::getSupportedPlaybackFormats() {
+    ALOGD("MockDatabase %s\n", __func__);
+    return nullptr;
+}
+MtpObjectFormatList* MtpMockDatabase::getSupportedCaptureFormats() {
+    ALOGD("MockDatabase %s\n", __func__);
+    return nullptr;
+}
+MtpObjectPropertyList* MtpMockDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
+    ALOGD("MockDatabase %s: oformat=0x%04x\n", __func__, format);
+    return nullptr;
+}
+MtpDevicePropertyList* MtpMockDatabase::getSupportedDeviceProperties() {
+    ALOGD("MockDatabase %s\n", __func__);
+    return nullptr;
+}
+
+MtpResponseCode MtpMockDatabase::getObjectPropertyValue(MtpObjectHandle handle,
+                                                        MtpObjectProperty property,
+                                                        MtpDataPacket& packet) {
+    ALOGD("MockDatabase %s: ohandle=%u property=%s\n", __func__, handle,
+          MtpDebug::getObjectPropCodeName(property));
+    return MTP_RESPONSE_OK;
+}
+
+MtpResponseCode MtpMockDatabase::setObjectPropertyValue(MtpObjectHandle handle,
+                                                        MtpObjectProperty property,
+                                                        MtpDataPacket& packet) {
+    ALOGD("MockDatabase %s: ohandle=%u property=%s\n", __func__, handle,
+          MtpDebug::getObjectPropCodeName(property));
+    return MTP_RESPONSE_OK;
+}
+
+MtpResponseCode MtpMockDatabase::getDevicePropertyValue(MtpDeviceProperty property,
+                                                        MtpDataPacket& packet) {
+    ALOGD("MockDatabase %s: property=%s\n", __func__, MtpDebug::getDevicePropCodeName(property));
+    return MTP_RESPONSE_OK;
+}
+
+MtpResponseCode MtpMockDatabase::setDevicePropertyValue(MtpDeviceProperty property,
+                                                        MtpDataPacket& packet) {
+    ALOGD("MockDatabase %s: property=%s\n", __func__, MtpDebug::getDevicePropCodeName(property));
+    return MTP_RESPONSE_OK;
+}
+
+MtpResponseCode MtpMockDatabase::resetDeviceProperty(MtpDeviceProperty property) {
+    ALOGD("MockDatabase %s: property=%s\n", __func__, MtpDebug::getDevicePropCodeName(property));
+    return MTP_RESPONSE_OK;
+}
+
+MtpResponseCode MtpMockDatabase::getObjectPropertyList(MtpObjectHandle handle, uint32_t format,
+                                                       uint32_t property, int groupCode, int depth,
+                                                       MtpDataPacket& packet) {
+    ALOGD("MockDatabase %s: ohandle=%u format=%s property=%s groupCode=%d "
+          "depth=%d\n",
+          __func__, handle, MtpDebug::getFormatCodeName(format),
+          MtpDebug::getObjectPropCodeName(property), groupCode, depth);
+    return MTP_RESPONSE_OK;
+}
+
+MtpResponseCode MtpMockDatabase::getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info) {
+    ALOGD("MockDatabase %s: ohandle=%u\n", __func__, handle);
+
+    // used for the root
+    if (handle == kInvalidObjectHandle) {
+        return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
+    } else {
+        if (mObjects.size() == 0) {
+            return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
+        }
+
+        // this is used to let the fuzzer make progress, otherwise
+        // it has to brute-force a 32-bit handle
+        MtpObjectHandle reducedHandle = handle % mObjects.size();
+        MtpObjectInfo* obj = mObjects[reducedHandle];
+
+        // make a copy, but make sure to maintain ownership of string pointers
+        info = *obj;
+
+        // fixup the response handle
+        info.mHandle = handle;
+
+        if (obj->mName) info.mName = strdup(obj->mName);
+        if (obj->mKeywords) info.mKeywords = strdup(obj->mKeywords);
+
+        return MTP_RESPONSE_OK;
+    }
+}
+
+void* MtpMockDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
+    ALOGD("MockDatabase %s: ohandle=%u\n", __func__, handle);
+
+    size_t allocSize = handle % 0x1000;
+    void* data = calloc(allocSize, sizeof(uint8_t));
+    if (!data) {
+        return nullptr;
+    } else {
+        ALOGD("MockDatabase %s\n", __func__);
+        outThumbSize = allocSize;
+        return data;
+    }
+}
+
+MtpResponseCode MtpMockDatabase::getObjectFilePath(MtpObjectHandle handle,
+                                                   MtpStringBuffer& outFilePath,
+                                                   int64_t& outFileLength,
+                                                   MtpObjectFormat& outFormat) {
+    ALOGD("MockDatabase %s: ohandle=%u\n", __func__, handle);
+
+    if (mObjects.size() == 0) {
+        return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
+    }
+
+    // this is used to let the fuzzer make progress, otherwise
+    // it has to brute-force a 32-bit handle
+    MtpObjectHandle reducedHandle = handle % mObjects.size();
+    MtpObjectInfo* obj = mObjects[reducedHandle];
+    MtpStorage* storage = mStorage[obj->mStorageID];
+
+    // walk up the tree to build a full path of the object
+    MtpObjectHandle currentHandle = reducedHandle;
+    std::string path = "";
+
+    while (currentHandle != MTP_PARENT_ROOT) {
+        MtpObjectInfo* next = mObjects[currentHandle];
+
+        // prepend the name
+        if (path == "")
+            path = std::string(next->mName);
+        else
+            path = std::string(next->mName) + "/" + path;
+
+        currentHandle = next->mParent;
+    }
+
+    outFilePath.set(storage->getPath());
+    outFilePath.append("/");
+    outFilePath.append(path.c_str());
+
+    outFormat = obj->mFormat;
+
+    ALOGD("MockDatabase %s: get file %s\n", __func__, (const char*)outFilePath);
+
+    struct stat sstat;
+    // this should not happen unless our database view of the filesystem is out of
+    // sync
+    if (stat((const char*)outFilePath, &sstat) < 0) {
+        ALOGE("MockDatabase %s: unable to stat %s\n", __func__, (const char*)outFilePath);
+
+        return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
+    }
+
+    outFileLength = sstat.st_size;
+
+    return MTP_RESPONSE_OK;
+}
+
+MtpResponseCode MtpMockDatabase::beginDeleteObject(MtpObjectHandle handle) {
+    ALOGD("MockDatabase %s: ohandle=%u\n", __func__, handle);
+    return MTP_RESPONSE_OK;
+}
+void MtpMockDatabase::endDeleteObject(MtpObjectHandle handle, bool succeeded) {
+    ALOGD("MockDatabase %s: ohandle=%u succeeded=%d\n", __func__, handle, succeeded);
+    return;
+}
+
+MtpObjectHandleList* MtpMockDatabase::getObjectReferences(MtpObjectHandle handle) {
+    ALOGD("MockDatabase %s: ohandle=%u\n", __func__, handle);
+    return nullptr;
+}
+
+MtpResponseCode MtpMockDatabase::setObjectReferences(MtpObjectHandle handle,
+                                                     MtpObjectHandleList* references) {
+    ALOGD("MockDatabase %s: ohandle=%u\n", __func__, handle);
+    return MTP_RESPONSE_OK;
+}
+
+MtpProperty* MtpMockDatabase::getObjectPropertyDesc(MtpObjectProperty property,
+                                                    MtpObjectFormat format) {
+    ALOGD("MockDatabase %s: property=%s format=%s\n", __func__,
+          MtpDebug::getObjectPropCodeName(property), MtpDebug::getFormatCodeName(format));
+
+    return nullptr;
+}
+
+MtpProperty* MtpMockDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
+    ALOGD("MockDatabase %s: property=%s\n", __func__, MtpDebug::getDevicePropCodeName(property));
+    return nullptr;
+}
+
+MtpResponseCode MtpMockDatabase::beginMoveObject(MtpObjectHandle handle, MtpObjectHandle newParent,
+                                                 MtpStorageID newStorage) {
+    ALOGD("MockDatabase %s: ohandle=%u newParent=%u newStorage=%u\n", __func__, handle, newParent,
+          newStorage);
+    return MTP_RESPONSE_OK;
+}
+
+void MtpMockDatabase::endMoveObject(MtpObjectHandle oldParent, MtpObjectHandle newParent,
+                                    MtpStorageID oldStorage, MtpStorageID newStorage,
+                                    MtpObjectHandle handle, bool succeeded) {
+    ALOGD("MockDatabase %s: oldParent=%u newParent=%u oldStorage=%u newStorage=%u "
+          "ohandle=%u succeeded=%d\n",
+          __func__, oldParent, newParent, oldStorage, newStorage, handle, succeeded);
+    return;
+}
+
+MtpResponseCode MtpMockDatabase::beginCopyObject(MtpObjectHandle handle, MtpObjectHandle newParent,
+                                                 MtpStorageID newStorage) {
+    ALOGD("MockDatabase %s: ohandle=%u newParent=%u newStorage=%u\n", __func__, handle, newParent,
+          newStorage);
+    return MTP_RESPONSE_OK;
+}
+
+void MtpMockDatabase::endCopyObject(MtpObjectHandle handle, bool succeeded) {
+    ALOGD("MockDatabase %s: ohandle=%u succeeded=%d\n", __func__, handle, succeeded);
+}
+
+}; // namespace android
diff --git a/media/mtp/tests/MtpFuzzer/MtpMockDatabase.h b/media/mtp/tests/MtpFuzzer/MtpMockDatabase.h
new file mode 100644
index 0000000..876719e
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/MtpMockDatabase.h
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+#ifndef _MTP_MOCK_DATABASE_H
+#define _MTP_MOCK_DATABASE_H
+
+#include <map>
+
+#include "IMtpDatabase.h"
+#include "MtpStorage.h"
+
+namespace android {
+
+class MtpMockDatabase : public IMtpDatabase {
+    std::map<MtpStorageID, MtpStorage*> mStorage;
+    std::vector<MtpObjectInfo*> mObjects;
+    uint32_t mLastObjectHandle;
+
+public:
+    MtpMockDatabase();
+    virtual ~MtpMockDatabase();
+
+    // MtpFuzzer methods
+    void addStorage(MtpStorage* storage) {
+        // we don't own this
+        mStorage[storage->getStorageID()] = storage;
+    }
+
+    bool hasStorage(MtpStorageID storage) { return mStorage.find(storage) != mStorage.end(); }
+
+    void addObject(MtpObjectInfo* info);
+    MtpObjectHandle allocateObjectHandle();
+
+    // libmtp interface methods
+    // Called from SendObjectInfo to reserve a database entry for the incoming
+    // file.
+    MtpObjectHandle beginSendObject(const char* path, MtpObjectFormat format,
+                                    MtpObjectHandle parent, MtpStorageID storage);
+
+    // Called to report success or failure of the SendObject file transfer.
+    void endSendObject(MtpObjectHandle handle, bool succeeded);
+
+    // Called to rescan a file, such as after an edit.
+    void rescanFile(const char* path, MtpObjectHandle handle, MtpObjectFormat format);
+
+    MtpObjectHandleList* getObjectList(MtpStorageID storageID, MtpObjectFormat format,
+                                       MtpObjectHandle parent);
+
+    int getNumObjects(MtpStorageID storageID, MtpObjectFormat format, MtpObjectHandle parent);
+
+    // callee should delete[] the results from these
+    // results can be NULL
+    MtpObjectFormatList* getSupportedPlaybackFormats();
+    MtpObjectFormatList* getSupportedCaptureFormats();
+    MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat format);
+    MtpDevicePropertyList* getSupportedDeviceProperties();
+
+    MtpResponseCode getObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property,
+                                           MtpDataPacket& packet);
+
+    MtpResponseCode setObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property,
+                                           MtpDataPacket& packet);
+
+    MtpResponseCode getDevicePropertyValue(MtpDeviceProperty property, MtpDataPacket& packet);
+
+    MtpResponseCode setDevicePropertyValue(MtpDeviceProperty property, MtpDataPacket& packet);
+
+    MtpResponseCode resetDeviceProperty(MtpDeviceProperty property);
+
+    MtpResponseCode getObjectPropertyList(MtpObjectHandle handle, uint32_t format,
+                                          uint32_t property, int groupCode, int depth,
+                                          MtpDataPacket& packet);
+
+    MtpResponseCode getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info);
+
+    void* getThumbnail(MtpObjectHandle handle, size_t& outThumbSize);
+
+    MtpResponseCode getObjectFilePath(MtpObjectHandle handle, MtpStringBuffer& outFilePath,
+                                      int64_t& outFileLength, MtpObjectFormat& outFormat);
+
+    MtpResponseCode beginDeleteObject(MtpObjectHandle handle);
+    void endDeleteObject(MtpObjectHandle handle, bool succeeded);
+
+    MtpObjectHandleList* getObjectReferences(MtpObjectHandle handle);
+
+    MtpResponseCode setObjectReferences(MtpObjectHandle handle, MtpObjectHandleList* references);
+
+    MtpProperty* getObjectPropertyDesc(MtpObjectProperty property, MtpObjectFormat format);
+
+    MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property);
+
+    MtpResponseCode beginMoveObject(MtpObjectHandle handle, MtpObjectHandle newParent,
+                                    MtpStorageID newStorage);
+
+    void endMoveObject(MtpObjectHandle oldParent, MtpObjectHandle newParent,
+                       MtpStorageID oldStorage, MtpStorageID newStorage, MtpObjectHandle handle,
+                       bool succeeded);
+
+    MtpResponseCode beginCopyObject(MtpObjectHandle handle, MtpObjectHandle newParent,
+                                    MtpStorageID newStorage);
+    void endCopyObject(MtpObjectHandle handle, bool succeeded);
+};
+
+}; // namespace android
+
+#endif // _MTP_MOCK_DATABASE_H
diff --git a/media/mtp/tests/MtpFuzzer/MtpMockHandle.h b/media/mtp/tests/MtpFuzzer/MtpMockHandle.h
new file mode 100644
index 0000000..111485c
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/MtpMockHandle.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#ifndef _MTP_MOCK_HANDLE_H
+#define _MTP_MOCK_HANDLE_H
+
+#include <vector>
+
+typedef std::vector<uint8_t> packet_t;
+
+namespace android {
+class MtpMockHandle : public IMtpHandle {
+private:
+    size_t mPacketNumber;
+    size_t mPacketOffset;
+    std::vector<packet_t> mPackets;
+
+public:
+    MtpMockHandle() : mPacketNumber(0), mPacketOffset(0) {}
+
+    void add_packet(packet_t pkt) { mPackets.push_back(pkt); }
+
+    // Return number of bytes read/written, or -1 and errno is set
+    int read(void *data, size_t len) {
+        if (mPacketNumber >= mPackets.size()) {
+            return 0;
+        } else {
+            int readAmt = 0;
+            packet_t pkt = mPackets[mPacketNumber];
+
+            ALOGD("%s: sz %zu, pkt %zu+%zu/%zu\n", __func__, len, mPacketNumber, mPacketOffset,
+                  pkt.size());
+
+            // packet is bigger than what the caller can handle,
+            if (pkt.size() > len) {
+                memcpy(data, pkt.data() + mPacketOffset, len);
+
+                mPacketOffset += len;
+                readAmt = len;
+                // packet is equal or smaller than the caller buffer
+            } else {
+                memcpy(data, pkt.data() + mPacketOffset, pkt.size());
+
+                mPacketNumber++;
+                mPacketOffset = 0;
+                readAmt = pkt.size();
+            }
+
+            return readAmt;
+        }
+    }
+    int write(const void *data, size_t len) {
+        ALOGD("MockHandle %s: len=%zu\n", __func__, len);
+        // fake the write
+        return len;
+    }
+
+    // Return 0 if send/receive is successful, or -1 and errno is set
+    int receiveFile(mtp_file_range mfr, bool zero_packet) {
+        ALOGD("MockHandle %s\n", __func__);
+        return 0;
+    }
+    int sendFile(mtp_file_range mfr) {
+        ALOGD("MockHandle %s\n", __func__);
+        return 0;
+    }
+    int sendEvent(mtp_event me) {
+        ALOGD("MockHandle %s: len=%zu\n", __func__, me.length);
+        return 0;
+    }
+
+    // Return 0 if operation is successful, or -1 else
+    int start(bool ptp) { return 0; }
+
+    void close() {}
+
+    virtual ~MtpMockHandle() {}
+};
+}; // namespace android
+
+#endif // _MTP_MOCK_HANDLE_H
diff --git a/media/mtp/tests/MtpFuzzer/corpus/1-mtp-open_session.pkt b/media/mtp/tests/MtpFuzzer/corpus/1-mtp-open_session.pkt
new file mode 100644
index 0000000..38f8ed2
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/corpus/1-mtp-open_session.pkt
Binary files differ
diff --git a/media/mtp/tests/MtpFuzzer/corpus/2-mtp-get_device_info.pkt b/media/mtp/tests/MtpFuzzer/corpus/2-mtp-get_device_info.pkt
new file mode 100644
index 0000000..7759380
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/corpus/2-mtp-get_device_info.pkt
Binary files differ
diff --git a/media/mtp/tests/MtpFuzzer/corpus/3-mtp-get_object_handles.pkt b/media/mtp/tests/MtpFuzzer/corpus/3-mtp-get_object_handles.pkt
new file mode 100644
index 0000000..e88410f
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/corpus/3-mtp-get_object_handles.pkt
Binary files differ
diff --git a/media/mtp/tests/MtpFuzzer/corpus/4-mtp-get_object_info.pkt b/media/mtp/tests/MtpFuzzer/corpus/4-mtp-get_object_info.pkt
new file mode 100644
index 0000000..e283fb4
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/corpus/4-mtp-get_object_info.pkt
Binary files differ
diff --git a/media/mtp/tests/MtpFuzzer/corpus/5-mtp-send_object_info.pkt b/media/mtp/tests/MtpFuzzer/corpus/5-mtp-send_object_info.pkt
new file mode 100644
index 0000000..7627f88
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/corpus/5-mtp-send_object_info.pkt
Binary files differ
diff --git a/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp
new file mode 100644
index 0000000..f578462
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp
@@ -0,0 +1,165 @@
+/*
+ * 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.
+ */
+
+#include <android-base/unique_fd.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <string>
+
+#define LOG_TAG "MtpFuzzer"
+
+#include "IMtpHandle.h"
+#include "MtpMockDatabase.h"
+#include "MtpMockHandle.h"
+#include "MtpObjectInfo.h"
+#include "MtpServer.h"
+#include "MtpStorage.h"
+#include "MtpUtils.h"
+
+const char* storage_desc = "Fuzz Storage";
+// prefer tmpfs for file operations to avoid wearing out flash
+const char* storage_path = "/storage/fuzzer/0";
+const char* source_database = "srcdb/";
+
+namespace android {
+class MtpMockServer {
+public:
+    std::unique_ptr<MtpMockHandle> mHandle;
+    std::unique_ptr<MtpStorage> mStorage;
+    std::unique_ptr<MtpMockDatabase> mDatabase;
+    std::unique_ptr<MtpServer> mMtp;
+    int mStorageId;
+
+    MtpMockServer(const char* storage_path) : mStorageId(0) {
+        bool ptp = false;
+        const char* manu = "Google";
+        const char* model = "Pixel 3XL";
+        const char* version = "1.0";
+        const char* serial = "ABDEF1231";
+
+        // This is unused in our harness
+        int controlFd = -1;
+
+        mHandle = std::make_unique<MtpMockHandle>();
+        mStorage = std::make_unique<MtpStorage>(mStorageId, storage_path, storage_desc, true,
+                                                0x200000000L);
+        mDatabase = std::make_unique<MtpMockDatabase>();
+        mDatabase->addStorage(mStorage.get());
+
+        mMtp = std::make_unique<MtpServer>(mDatabase.get(), controlFd, ptp, manu, model, version,
+                                           serial);
+        mMtp->addStorage(mStorage.get());
+
+        // clear the old handle first, so we don't leak memory
+        delete mMtp->mHandle;
+        mMtp->mHandle = mHandle.get();
+    }
+
+    void run() { mMtp->run(); }
+
+    int createDatabaseFromSourceDir(const char* fromPath, const char* toPath,
+                                    MtpObjectHandle parentHandle) {
+        int ret = 0;
+        std::string fromPathStr(fromPath);
+        std::string toPathStr(toPath);
+
+        DIR* dir = opendir(fromPath);
+        if (!dir) {
+            ALOGE("opendir %s failed", fromPath);
+            return -1;
+        }
+        if (fromPathStr[fromPathStr.size() - 1] != '/') fromPathStr += '/';
+        if (toPathStr[toPathStr.size() - 1] != '/') toPathStr += '/';
+
+        struct dirent* entry;
+        while ((entry = readdir(dir))) {
+            const char* name = entry->d_name;
+
+            // ignore "." and ".."
+            if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
+                continue;
+            }
+
+            std::string oldFile = fromPathStr + name;
+            std::string newFile = toPathStr + name;
+
+            if (entry->d_type == DT_DIR) {
+                ret += makeFolder(newFile.c_str());
+
+                MtpObjectInfo* objectInfo = new MtpObjectInfo(mDatabase->allocateObjectHandle());
+                objectInfo->mStorageID = mStorage->getStorageID();
+                objectInfo->mParent = parentHandle;
+                objectInfo->mFormat = MTP_FORMAT_ASSOCIATION; // folder
+                objectInfo->mName = strdup(name);
+                objectInfo->mKeywords = strdup("");
+
+                mDatabase->addObject(objectInfo);
+
+                ret += createDatabaseFromSourceDir(oldFile.c_str(), newFile.c_str(),
+                                                   objectInfo->mHandle);
+            } else {
+                ret += copyFile(oldFile.c_str(), newFile.c_str());
+
+                MtpObjectInfo* objectInfo = new MtpObjectInfo(mDatabase->allocateObjectHandle());
+                objectInfo->mStorageID = mStorage->getStorageID();
+                objectInfo->mParent = parentHandle;
+                objectInfo->mFormat = MTP_FORMAT_TEXT;
+                objectInfo->mName = strdup(name);
+                objectInfo->mKeywords = strdup("");
+
+                mDatabase->addObject(objectInfo);
+            }
+        }
+
+        closedir(dir);
+        return ret;
+    }
+};
+}; // namespace android
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) __attribute__((optnone)) {
+    // reset our storage (from MtpUtils.h)
+    android::deletePath(storage_path);
+    android::makeFolder("/storage/fuzzer");
+    android::makeFolder(storage_path);
+
+    std::unique_ptr<android::MtpMockServer> mtp =
+            std::make_unique<android::MtpMockServer>(storage_path);
+
+    size_t off = 0;
+
+    // Packetize the input stream
+    for (size_t i = 0; i < size; i++) {
+        // A longer delimiter could be used, but this worked in practice
+        if (data[i] == '@') {
+            size_t pktsz = i - off;
+            if (pktsz > 0) {
+                packet_t pkt = packet_t((unsigned char*)data + off, (unsigned char*)data + i);
+                // insert into packet buffer
+                mtp->mHandle->add_packet(pkt);
+                off = i;
+            }
+        }
+    }
+
+    mtp->createDatabaseFromSourceDir(source_database, storage_path, MTP_PARENT_ROOT);
+    mtp->run();
+
+    return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_fuzzer.dict b/media/mtp/tests/MtpFuzzer/mtp_fuzzer.dict
new file mode 100644
index 0000000..4c3f136
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_fuzzer.dict
@@ -0,0 +1,74 @@
+mtp_operation_get_device_info="\x01\x10"
+mtp_operation_open_session="\x02\x10"
+mtp_operation_close_session="\x03\x10"
+mtp_operation_get_storage_ids="\x04\x10"
+mtp_operation_get_storage_info="\x05\x10"
+mtp_operation_get_num_objects="\x06\x10"
+mtp_operation_get_object_handles="\x07\x10"
+mtp_operation_get_object_info="\x08\x10"
+mtp_operation_get_object="\x09\x10"
+mtp_operation_get_thumb="\x0A\x10"
+mtp_operation_delete_object="\x0B\x10"
+mtp_operation_send_object_info="\x0C\x10"
+mtp_operation_send_object="\x0D\x10"
+mtp_operation_initiate_capture="\x0E\x10"
+mtp_operation_format_store="\x0F\x10"
+mtp_operation_reset_device="\x10\x10"
+mtp_operation_self_test="\x11\x10"
+mtp_operation_set_object_protection="\x12\x10"
+mtp_operation_power_down="\x13\x10"
+mtp_operation_get_device_prop_desc="\x14\x10"
+mtp_operation_get_device_prop_value="\x15\x10"
+mtp_operation_set_device_prop_value="\x16\x10"
+mtp_operation_reset_device_prop_value="\x17\x10"
+mtp_operation_terminate_open_capture="\x18\x10"
+mtp_operation_move_object="\x19\x10"
+mtp_operation_copy_object="\x1A\x10"
+mtp_operation_get_partial_object="\x1B\x10"
+mtp_operation_initiate_open_capture="\x1C\x10"
+mtp_operation_get_object_props_supported="\x01\x98"
+mtp_operation_get_object_prop_desc="\x02\x98"
+mtp_operation_get_object_prop_value="\x03\x98"
+mtp_operation_set_object_prop_value="\x04\x98"
+mtp_operation_get_object_prop_list="\x05\x98"
+mtp_operation_set_object_prop_list="\x06\x98"
+mtp_operation_get_interdependent_prop_desc="\x07\x98"
+mtp_operation_send_object_prop_list="\x08\x98"
+mtp_operation_get_object_references="\x10\x98"
+mtp_operation_set_object_references="\x11\x98"
+mtp_operation_skip="\x20\x98"
+mtp_operation_get_partial_object_64="\xC1\x95"
+mtp_operation_send_partial_object="\xC2\x95"
+mtp_operation_truncate_object="\xC3\x95"
+mtp_operation_begin_edit_object="\xC4\x95"
+mtp_operation_end_edit_object="\xC5\x95"
+
+# Association (for example, a folder)
+mtp_format_association="\x01\x30"
+
+# types
+mtp_type_undefined="\x00\x00"
+mtp_type_int8="\x01\x00"
+mtp_type_uint8="\x02\x00"
+mtp_type_int16="\x03\x00"
+mtp_type_uint16="\x04\x00"
+mtp_type_int32="\x05\x00"
+mtp_type_uint32="\x06\x00"
+mtp_type_int64="\x07\x00"
+mtp_type_uint64="\x08\x00"
+mtp_type_int128="\x09\x00"
+mtp_type_uint128="\x0A\x00"
+mtp_type_aint8="\x01\x40"
+mtp_type_auint8="\x02\x40"
+mtp_type_aint16="\x03\x40"
+mtp_type_auint16="\x04\x40"
+mtp_type_aint32="\x05\x40"
+mtp_type_auint32="\x06\x40"
+mtp_type_aint64="\x07\x40"
+mtp_type_auint64="\x08\x40"
+mtp_type_aint128="\x09\x40"
+mtp_type_auint128="\x0A\x40"
+mtp_type_str="\xFF\xFF"
+
+# also used for max size (>4GB)
+mtp_parent_root="\xFF\xFF\xFF\xFF"
diff --git a/media/mtp/tests/Android.bp b/media/mtp/tests/PosixAsyncIOTest/Android.bp
similarity index 71%
copy from media/mtp/tests/Android.bp
copy to media/mtp/tests/PosixAsyncIOTest/Android.bp
index 0750208..1d401b8 100644
--- a/media/mtp/tests/Android.bp
+++ b/media/mtp/tests/PosixAsyncIOTest/Android.bp
@@ -1,5 +1,5 @@
 //
-// Copyright (C) 2017 The Android Open Source Project
+// 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.
@@ -15,22 +15,6 @@
 //
 
 cc_test {
-    name: "mtp_ffs_handle_test",
-    test_suites: ["device-tests"],
-    srcs: ["MtpFfsHandle_test.cpp"],
-    shared_libs: [
-        "libbase",
-        "libmtp",
-        "liblog",
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-}
-
-cc_test {
     name: "posix_async_io_test",
     test_suites: ["device-tests"],
     srcs: ["PosixAsyncIO_test.cpp"],
diff --git a/media/mtp/tests/AndroidTest.xml b/media/mtp/tests/PosixAsyncIOTest/AndroidTest.xml
similarity index 77%
copy from media/mtp/tests/AndroidTest.xml
copy to media/mtp/tests/PosixAsyncIOTest/AndroidTest.xml
index c1f4753..cbb10fb 100644
--- a/media/mtp/tests/AndroidTest.xml
+++ b/media/mtp/tests/PosixAsyncIOTest/AndroidTest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- 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.
@@ -13,14 +13,14 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Config for mtp_ffs_handle_test">
+<configuration description="Config for posix_async_io_test">
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
-        <option name="push" value="mtp_ffs_handle_test->/data/local/tmp/mtp_ffs_handle_test" />
+        <option name="push" value="posix_async_io_test->/data/local/tmp/posix_async_io_test" />
     </target_preparer>
     <option name="test-suite-tag" value="apct" />
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="mtp_ffs_handle_test" />
+        <option name="module-name" value="posix_async_io_test" />
     </test>
 </configuration>
\ No newline at end of file
diff --git a/media/mtp/tests/PosixAsyncIO_test.cpp b/media/mtp/tests/PosixAsyncIOTest/PosixAsyncIO_test.cpp
similarity index 100%
rename from media/mtp/tests/PosixAsyncIO_test.cpp
rename to media/mtp/tests/PosixAsyncIOTest/PosixAsyncIO_test.cpp
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 755d6e6..ee4def5 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -116,7 +116,10 @@
 
     export_header_lib_headers: ["jni_headers"],
 
-    export_include_dirs: ["include"],
+    export_include_dirs: [
+        "include",
+        "include_platform",
+    ],
 
     export_shared_lib_headers: [
         "libgui",
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index d771095..1055dc4 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -19,7 +19,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "NdkMediaCodec"
 
-#include <media/NdkMediaCodec.h>
+#include <media/NdkMediaCodecPlatform.h>
 #include <media/NdkMediaError.h>
 #include <media/NdkMediaFormatPriv.h>
 #include "NdkMediaCryptoPriv.h"
@@ -312,7 +312,11 @@
 
 extern "C" {
 
-static AMediaCodec * createAMediaCodec(const char *name, bool name_is_type, bool encoder) {
+static AMediaCodec * createAMediaCodec(const char *name,
+                                       bool name_is_type,
+                                       bool encoder,
+                                       pid_t pid = android::MediaCodec::kNoPid,
+                                       uid_t uid = android::MediaCodec::kNoUid) {
     AMediaCodec *mData = new AMediaCodec();
     mData->mLooper = new ALooper;
     mData->mLooper->setName("NDK MediaCodec_looper");
@@ -326,9 +330,20 @@
         return NULL;
     }
     if (name_is_type) {
-        mData->mCodec = android::MediaCodec::CreateByType(mData->mLooper, name, encoder);
+        mData->mCodec = android::MediaCodec::CreateByType(
+                mData->mLooper,
+                name,
+                encoder,
+                nullptr /* err */,
+                pid,
+                uid);
     } else {
-        mData->mCodec = android::MediaCodec::CreateByComponentName(mData->mLooper, name);
+        mData->mCodec = android::MediaCodec::CreateByComponentName(
+                mData->mLooper,
+                name,
+                nullptr /* err */,
+                pid,
+                uid);
     }
     if (mData->mCodec == NULL) {  // failed to create codec
         AMediaCodec_delete(mData);
@@ -348,17 +363,38 @@
 
 EXPORT
 AMediaCodec* AMediaCodec_createCodecByName(const char *name) {
-    return createAMediaCodec(name, false, false);
+    return createAMediaCodec(name, false /* name_is_type */, false /* encoder */);
 }
 
 EXPORT
 AMediaCodec* AMediaCodec_createDecoderByType(const char *mime_type) {
-    return createAMediaCodec(mime_type, true, false);
+    return createAMediaCodec(mime_type, true /* name_is_type */, false /* encoder */);
 }
 
 EXPORT
 AMediaCodec* AMediaCodec_createEncoderByType(const char *name) {
-    return createAMediaCodec(name, true, true);
+    return createAMediaCodec(name, true /* name_is_type */, true /* encoder */);
+}
+
+EXPORT
+AMediaCodec* AMediaCodec_createCodecByNameForClient(const char *name,
+                                                    pid_t pid,
+                                                    uid_t uid) {
+    return createAMediaCodec(name, false /* name_is_type */, false /* encoder */, pid, uid);
+}
+
+EXPORT
+AMediaCodec* AMediaCodec_createDecoderByTypeForClient(const char *mime_type,
+                                                      pid_t pid,
+                                                      uid_t uid) {
+    return createAMediaCodec(mime_type, true /* name_is_type */, false /* encoder */, pid, uid);
+}
+
+EXPORT
+AMediaCodec* AMediaCodec_createEncoderByTypeForClient(const char *name,
+                                                      pid_t pid,
+                                                      uid_t uid) {
+    return createAMediaCodec(name, true /* name_is_type */, true /* encoder */, pid, uid);
 }
 
 EXPORT
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index 0da0740..0c65e9e 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -22,6 +22,7 @@
 #include <media/NdkMediaExtractor.h>
 #include <media/NdkMediaErrorPriv.h>
 #include <media/NdkMediaFormatPriv.h>
+#include "NdkJavaVMHelperPriv.h"
 #include "NdkMediaDataSourcePriv.h"
 
 
@@ -63,7 +64,10 @@
 AMediaExtractor* AMediaExtractor_new() {
     ALOGV("ctor");
     AMediaExtractor *mData = new AMediaExtractor();
-    mData->mImpl = new NuMediaExtractor();
+    mData->mImpl = new NuMediaExtractor(
+        NdkJavaVMHelper::getJNIEnv() != nullptr
+                ? NuMediaExtractor::EntryPoint::NDK_WITH_JVM
+                : NuMediaExtractor::EntryPoint::NDK_NO_JVM );
     return mData;
 }
 
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index 73c52a9..47214c5 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -371,6 +371,7 @@
 EXPORT const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID = "temporal-layer-id";
 EXPORT const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYERING = "ts-schema";
 EXPORT const char* AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA = "text-format-data";
+EXPORT const char* AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C = "thumbnail-csd-av1c";
 EXPORT const char* AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC = "thumbnail-csd-hevc";
 EXPORT const char* AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT = "thumbnail-height";
 EXPORT const char* AMEDIAFORMAT_KEY_THUMBNAIL_TIME = "thumbnail-time";
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 394b972..8f39929 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -324,6 +324,7 @@
 
 #if __ANDROID_API__ >= 31
 extern const char* AMEDIAFORMAT_KEY_SLOW_MOTION_MARKERS __INTRODUCED_IN(31);
+extern const char* AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C __INTRODUCED_IN(31);
 #endif /* __ANDROID_API__ >= 31 */
 
 __END_DECLS
diff --git a/media/ndk/include_platform/media/NdkMediaCodecPlatform.h b/media/ndk/include_platform/media/NdkMediaCodecPlatform.h
new file mode 100644
index 0000000..608346d
--- /dev/null
+++ b/media/ndk/include_platform/media/NdkMediaCodecPlatform.h
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+#ifndef _NDK_MEDIA_CODEC_PLATFORM_H
+#define _NDK_MEDIA_CODEC_PLATFORM_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#include <media/NdkMediaCodec.h>
+
+__BEGIN_DECLS
+
+/**
+ * Special uid and pid values used with AMediaCodec_createCodecByNameForClient,
+ * AMediaCodec_createDecoderByTypeForClient and AMediaCodec_createEncoderByTypeForClient.
+ *
+ * Introduced in API 31.
+ */
+enum {
+    /**
+     * Uid value to indicate using calling uid.
+     */
+    AMEDIACODEC_CALLING_UID = -1,
+    /**
+     * Pid value to indicate using calling pid.
+     */
+    AMEDIACODEC_CALLING_PID = -1,
+};
+
+#if __ANDROID_API__ >= 31
+
+/**
+ * Create codec by name on behalf of a client.
+ *
+ * The usage is similar to AMediaCodec_createCodecByName(), except that the codec instance
+ * will be attributed to the client of {uid, pid}, instead of the caller.
+ *
+ * Only certain privileged users are allowed to specify {uid, pid} that's different from the
+ * caller's. Without the privilege, this API will behave the same as
+ * AMediaCodec_createCodecByName().
+ *
+ * Available since API level 31.
+ */
+AMediaCodec* AMediaCodec_createCodecByNameForClient(const char *name,
+                                                    pid_t pid,
+                                                    uid_t uid) __INTRODUCED_IN(31);
+
+/**
+ * Create codec by mime type on behalf of a client.
+ *
+ * The usage is similar to AMediaCodec_createDecoderByType(), except that the codec instance
+ * will be attributed to the client of {uid, pid}, instead of the caller.
+ *
+ * Only certain privileged users are allowed to specify {uid, pid} that's different from the
+ * caller's. Without the privilege, this API will behave the same as
+ * AMediaCodec_createDecoderByType().
+ *
+ * Available since API level 31.
+ */
+AMediaCodec* AMediaCodec_createDecoderByTypeForClient(const char *mime_type,
+                                                      pid_t pid,
+                                                      uid_t uid) __INTRODUCED_IN(31);
+
+/**
+ * Create encoder by name on behalf of a client.
+ *
+ * The usage is similar to AMediaCodec_createEncoderByType(), except that the codec instance
+ * will be attributed to the client of {uid, pid}, instead of the caller.
+ *
+ * Only certain privileged users are allowed to specify {uid, pid} that's different from the
+ * caller's. Without the privilege, this API will behave the same as
+ * AMediaCodec_createEncoderByType().
+ *
+ * Available since API level 31.
+ */
+AMediaCodec* AMediaCodec_createEncoderByTypeForClient(const char *mime_type,
+                                                      pid_t pid,
+                                                      uid_t uid) __INTRODUCED_IN(31);
+
+#endif // __ANDROID_API__ >= 31
+
+__END_DECLS
+
+#endif //_NDK_MEDIA_CODEC_PLATFORM_H
+
+/** @} */
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index bd3337e..96f1710 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -138,6 +138,7 @@
     AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID; # var introduced=28
     AMEDIAFORMAT_KEY_TEMPORAL_LAYERING; # var introduced=28
     AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA; # var introduced=29
+    AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C; # var introduced=31
     AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC; # var introduced=29
     AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT; # var introduced=29
     AMEDIAFORMAT_KEY_THUMBNAIL_TIME; # var introduced=29
@@ -164,8 +165,11 @@
     AMediaCodecCryptoInfo_setPattern; # introduced=24
     AMediaCodec_configure;
     AMediaCodec_createCodecByName;
+    AMediaCodec_createCodecByNameForClient; # apex #introduced = 31
     AMediaCodec_createDecoderByType;
+    AMediaCodec_createDecoderByTypeForClient; # apex #introduced = 31
     AMediaCodec_createEncoderByType;
+    AMediaCodec_createEncoderByTypeForClient; # apex #introduced = 31
     AMediaCodec_delete;
     AMediaCodec_dequeueInputBuffer;
     AMediaCodec_dequeueOutputBuffer;
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 87ea084..e428e49 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -22,6 +22,7 @@
 #include <binder/IServiceManager.h>
 #include <binder/PermissionCache.h>
 #include "mediautils/ServiceUtilities.h"
+#include <system/audio-hal-enums.h>
 
 #include <iterator>
 #include <algorithm>
@@ -61,8 +62,20 @@
     return packages[0];
 }
 
+static int32_t getOpForSource(audio_source_t source) {
+  switch (source) {
+    case AUDIO_SOURCE_HOTWORD:
+      return AppOpsManager::OP_RECORD_AUDIO_HOTWORD;
+    case AUDIO_SOURCE_REMOTE_SUBMIX:
+      return AppOpsManager::OP_RECORD_AUDIO_OUTPUT;
+    case AUDIO_SOURCE_DEFAULT:
+    default:
+      return AppOpsManager::OP_RECORD_AUDIO;
+  }
+}
+
 static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
-        uid_t uid, bool start) {
+        uid_t uid, bool start, audio_source_t source) {
     // Okay to not track in app ops as audio server or media server is us and if
     // device is rooted security model is considered compromised.
     // system_server loses its RECORD_AUDIO permission when a secondary
@@ -87,16 +100,21 @@
     }
 
     AppOpsManager appOps;
-    const int32_t op = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
+    const int32_t op = getOpForSource(source);
     if (start) {
-        if (appOps.startOpNoThrow(op, uid, resolvedOpPackageName, /*startIfModeDefault*/ false)
-                != AppOpsManager::MODE_ALLOWED) {
-            ALOGE("Request denied by app op: %d", op);
+        if (int32_t mode = appOps.startOpNoThrow(
+                        op, uid, resolvedOpPackageName, /*startIfModeDefault*/ false);
+                mode != AppOpsManager::MODE_ALLOWED) {
+            ALOGE("Request start for \"%s\" (uid %d) denied by app op: %d, mode: %d",
+                    String8(resolvedOpPackageName).c_str(), uid, op, mode);
             return false;
         }
     } else {
-        if (appOps.checkOp(op, uid, resolvedOpPackageName) != AppOpsManager::MODE_ALLOWED) {
-            ALOGE("Request denied by app op: %d", op);
+        // Always use OP_RECORD_AUDIO for checks at creation time.
+        if (int32_t mode = appOps.checkOp(op, uid, resolvedOpPackageName);
+                mode != AppOpsManager::MODE_ALLOWED) {
+            ALOGE("Request check for \"%s\" (uid %d) denied by app op: %d, mode: %d",
+                    String8(resolvedOpPackageName).c_str(), uid, op, mode);
             return false;
         }
     }
@@ -105,14 +123,14 @@
 }
 
 bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
-    return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false);
+    return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false, AUDIO_SOURCE_DEFAULT);
 }
 
-bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid) {
-     return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true);
+bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, audio_source_t source) {
+     return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true, source);
 }
 
-void finishRecording(const String16& opPackageName, uid_t uid) {
+void finishRecording(const String16& opPackageName, uid_t uid, audio_source_t source) {
     // Okay to not track in app ops as audio server is us and if
     // device is rooted security model is considered compromised.
     if (isAudioServerOrRootUid(uid)) return;
@@ -125,7 +143,8 @@
     }
 
     AppOpsManager appOps;
-    const int32_t op = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
+
+    const int32_t op = getOpForSource(source);
     appOps.finishOp(op, uid, resolvedOpPackageName);
 }
 
diff --git a/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp b/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp
index 3d141b5..f4c815c 100644
--- a/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp
+++ b/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp
@@ -17,6 +17,7 @@
 #include <fcntl.h>
 
 #include <functional>
+#include  <type_traits>
 
 #include "fuzzer/FuzzedDataProvider.h"
 #include "mediautils/ServiceUtilities.h"
@@ -44,6 +45,8 @@
     FuzzedDataProvider data_provider(data, size);
     uid_t uid = data_provider.ConsumeIntegral<uid_t>();
     pid_t pid = data_provider.ConsumeIntegral<pid_t>();
+    audio_source_t source = static_cast<audio_source_t>(data_provider
+        .ConsumeIntegral<std::underlying_type_t<audio_source_t>>());
 
     // There is not state here, and order is not significant,
     // so we can simply call all of the target functions
@@ -54,8 +57,8 @@
     std::string packageNameStr = data_provider.ConsumeRandomLengthString(kMaxStringLen);
     android::String16 opPackageName(packageNameStr.c_str());
     android::recordingAllowed(opPackageName, pid, uid);
-    android::startRecording(opPackageName, pid, uid);
-    android::finishRecording(opPackageName, uid);
+    android::startRecording(opPackageName, pid, uid, source);
+    android::finishRecording(opPackageName, uid, source);
     android::captureAudioOutputAllowed(pid, uid);
     android::captureMediaOutputAllowed(pid, uid);
     android::captureHotwordAllowed(opPackageName, pid, uid);
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 212599a..0a82af6 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -24,6 +24,7 @@
 #include <binder/PermissionController.h>
 #include <cutils/multiuser.h>
 #include <private/android_filesystem_config.h>
+#include <system/audio-hal-enums.h>
 
 #include <map>
 #include <optional>
@@ -79,8 +80,8 @@
 }
 
 bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
-bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid);
-void finishRecording(const String16& opPackageName, uid_t uid);
+bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, audio_source_t source);
+void finishRecording(const String16& opPackageName, uid_t uid, audio_source_t source);
 bool captureAudioOutputAllowed(pid_t pid, uid_t uid);
 bool captureMediaOutputAllowed(pid_t pid, uid_t uid);
 bool captureVoiceCommunicationOutputAllowed(pid_t pid, uid_t uid);
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 7443320..87b5ff4 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -38,6 +38,7 @@
         "audioflinger-aidl-unstable-cpp",
         "audioclient-types-aidl-unstable-cpp",
         "av-types-aidl-unstable-cpp",
+        "effect-aidl-unstable-cpp",
         "libaudioclient_aidl_conversion",
         "libaudiofoundation",
         "libaudiohal",
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 4929346..78ad467 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -22,15 +22,6 @@
 // Define AUDIO_ARRAYS_STATIC_CHECK to check all audio arrays are correct
 #define AUDIO_ARRAYS_STATIC_CHECK 1
 
-#define VALUE_OR_FATAL(result)                   \
-    ({                                           \
-       auto _tmp = (result);                     \
-       LOG_ALWAYS_FATAL_IF(!_tmp.ok(),           \
-                           "Failed result (%d)", \
-                           _tmp.error());        \
-       std::move(_tmp.value());                  \
-     })
-
 #include "Configuration.h"
 #include <dirent.h>
 #include <math.h>
@@ -40,6 +31,7 @@
 #include <sys/resource.h>
 #include <thread>
 
+
 #include <android/os/IExternalVibratorService.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -50,8 +42,10 @@
 #include <media/audiohal/DevicesFactoryHalInterface.h>
 #include <media/audiohal/EffectsFactoryHalInterface.h>
 #include <media/AudioParameter.h>
+#include <media/IAudioPolicyService.h>
 #include <media/MediaMetricsItem.h>
 #include <media/TypeConverter.h>
+#include <mediautils/TimeCheck.h>
 #include <memunreachable/memunreachable.h>
 #include <utils/String16.h>
 #include <utils/threads.h>
@@ -78,6 +72,7 @@
 
 #include <media/IMediaLogService.h>
 #include <media/AidlConversion.h>
+#include <media/AudioValidator.h>
 #include <media/nbaio/Pipe.h>
 #include <media/nbaio/PipeReader.h>
 #include <mediautils/BatteryNotifier.h>
@@ -91,6 +86,15 @@
 
 #include "TypedLogger.h"
 
+#define VALUE_OR_FATAL(result)                   \
+    ({                                           \
+       auto _tmp = (result);                     \
+       LOG_ALWAYS_FATAL_IF(!_tmp.ok(),           \
+                           "Failed result (%d)", \
+                           _tmp.error());        \
+       std::move(_tmp.value());                  \
+     })
+
 // ----------------------------------------------------------------------------
 
 // Note: the following macro is used for extremely verbose logging message.  In
@@ -181,9 +185,15 @@
 
 // ----------------------------------------------------------------------------
 
+void AudioFlinger::instantiate() {
+    sp<IServiceManager> sm(defaultServiceManager());
+    sm->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME),
+                   new AudioFlingerServerAdapter(new AudioFlinger()), false,
+                   IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
+}
+
 AudioFlinger::AudioFlinger()
-    : BnAudioFlinger(),
-      mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
+    : mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
       mPrimaryHardwareDev(NULL),
       mAudioHwDevs(NULL),
       mHardwareStatus(AUDIO_HW_IDLE),
@@ -757,25 +767,11 @@
 
 // IAudioFlinger interface
 
-sp<IAudioTrack> AudioFlinger::createTrack(const media::CreateTrackRequest& _input,
-                                          media::CreateTrackResponse& _output,
-                                          status_t* status)
+status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input,
+                                   media::CreateTrackResponse& _output)
 {
     // Local version of VALUE_OR_RETURN, specific to this method's calling conventions.
-#define VALUE_OR_EXIT(expr)         \
-    ({                              \
-        auto _tmp = (expr);         \
-        if (!_tmp.ok()) {           \
-            *status = _tmp.error(); \
-            return nullptr;         \
-        }                           \
-        std::move(_tmp.value());    \
-    })
-
-    CreateTrackInput input = VALUE_OR_EXIT(CreateTrackInput::fromAidl(_input));
-
-#undef VALUE_OR_EXIT
-
+    CreateTrackInput input = VALUE_OR_RETURN_STATUS(CreateTrackInput::fromAidl(_input));
     CreateTrackOutput output;
 
     sp<PlaybackThread::Track> track;
@@ -1034,17 +1030,14 @@
         AudioSystem::moveEffectsToIo(effectIds, effectThreadId);
     }
 
+    output.audioTrack = new TrackHandle(track);
     _output = VALUE_OR_FATAL(output.toAidl());
 
-    // return handle to client
-    trackHandle = new TrackHandle(track);
-
 Exit:
     if (lStatus != NO_ERROR && output.outputId != AUDIO_IO_HANDLE_NONE) {
         AudioSystem::releaseOutput(portId);
     }
-    *status = lStatus;
-    return trackHandle;
+    return lStatus;
 }
 
 uint32_t AudioFlinger::sampleRate(audio_io_handle_t ioHandle) const
@@ -1468,7 +1461,7 @@
 }
 
 
-void AudioFlinger::broacastParametersToRecordThreads_l(const String8& keyValuePairs)
+void AudioFlinger::broadcastParametersToRecordThreads_l(const String8& keyValuePairs)
 {
     for (size_t i = 0; i < mRecordThreads.size(); i++) {
         mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
@@ -1626,7 +1619,7 @@
             int value;
             if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
                     (value != 0)) {
-                broacastParametersToRecordThreads_l(filteredKeyValuePairs);
+                broadcastParametersToRecordThreads_l(filteredKeyValuePairs);
             }
         }
     }
@@ -2018,24 +2011,10 @@
 
 // ----------------------------------------------------------------------------
 
-sp<media::IAudioRecord> AudioFlinger::createRecord(const media::CreateRecordRequest& _input,
-                                                   media::CreateRecordResponse& _output,
-                                                   status_t* status)
+status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input,
+                                    media::CreateRecordResponse& _output)
 {
-    // Local version of VALUE_OR_RETURN, specific to this method's calling conventions.
-#define VALUE_OR_EXIT(expr)         \
-    ({                              \
-        auto _tmp = (expr);         \
-        if (!_tmp.ok()) {           \
-            *status = _tmp.error(); \
-            return nullptr;         \
-        }                           \
-        std::move(_tmp.value());    \
-    })
-
-    CreateRecordInput input = VALUE_OR_EXIT(CreateRecordInput::fromAidl(_input));
-
-#undef VALUE_OR_EXIT
+    CreateRecordInput input = VALUE_OR_RETURN_STATUS(CreateRecordInput::fromAidl(_input));
     CreateRecordOutput output;
 
     sp<RecordThread::RecordTrack> recordTrack;
@@ -2175,11 +2154,9 @@
     output.buffers = recordTrack->getBuffers();
     output.portId = portId;
 
+    output.audioRecord = new RecordHandle(recordTrack);
     _output = VALUE_OR_FATAL(output.toAidl());
 
-    // return handle to client
-    recordHandle = new RecordHandle(recordTrack);
-
 Exit:
     if (lStatus != NO_ERROR) {
         // remove local strong reference to Client before deleting the RecordTrack so that the
@@ -2196,8 +2173,7 @@
         }
     }
 
-    *status = lStatus;
-    return recordHandle;
+    return lStatus;
 }
 
 
@@ -2369,6 +2345,11 @@
 {
     ALOGV(__func__);
 
+    status_t status = AudioValidator::validateAudioPortConfig(*config);
+    if (status != NO_ERROR) {
+        return status;
+    }
+
     audio_module_handle_t module;
     if (config->type == AUDIO_PORT_TYPE_DEVICE) {
         module = config->ext.device.hw_module;
@@ -2602,20 +2583,28 @@
     return 0;
 }
 
-status_t AudioFlinger::openOutput(audio_module_handle_t module,
-                                  audio_io_handle_t *output,
-                                  audio_config_t *config,
-                                  const sp<DeviceDescriptorBase>& device,
-                                  uint32_t *latencyMs,
-                                  audio_output_flags_t flags)
+status_t AudioFlinger::openOutput(const media::OpenOutputRequest& request,
+                                media::OpenOutputResponse* response)
 {
+    audio_module_handle_t module = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_int32_t_audio_module_handle_t(request.module));
+    audio_config_t config = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_AudioConfig_audio_config_t(request.config));
+    sp<DeviceDescriptorBase> device = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_DeviceDescriptorBase(request.device));
+    audio_output_flags_t flags = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_int32_t_audio_output_flags_t_mask(request.flags));
+
+    audio_io_handle_t output;
+    uint32_t latencyMs;
+
     ALOGI("openOutput() this %p, module %d Device %s, SamplingRate %d, Format %#08x, "
               "Channels %#x, flags %#x",
               this, module,
               device->toString().c_str(),
-              config->sample_rate,
-              config->format,
-              config->channel_mask,
+              config.sample_rate,
+              config.format,
+              config.channel_mask,
               flags);
 
     audio_devices_t deviceType = device->type();
@@ -2627,11 +2616,11 @@
 
     Mutex::Autolock _l(mLock);
 
-    sp<ThreadBase> thread = openOutput_l(module, output, config, deviceType, address, flags);
+    sp<ThreadBase> thread = openOutput_l(module, &output, &config, deviceType, address, flags);
     if (thread != 0) {
         if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0) {
             PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
-            *latencyMs = playbackThread->latency();
+            latencyMs = playbackThread->latency();
 
             // notify client processes of the new output creation
             playbackThread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
@@ -2651,6 +2640,11 @@
             MmapThread *mmapThread = (MmapThread *)thread.get();
             mmapThread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
         }
+        response->output = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
+        response->config = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_config_t_AudioConfig(config));
+        response->latencyMs = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(latencyMs));
+        response->flags = VALUE_OR_RETURN_STATUS(
+                legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
         return NO_ERROR;
     }
 
@@ -2803,22 +2797,36 @@
     return NO_ERROR;
 }
 
-status_t AudioFlinger::openInput(audio_module_handle_t module,
-                                          audio_io_handle_t *input,
-                                          audio_config_t *config,
-                                          audio_devices_t *devices,
-                                          const String8& address,
-                                          audio_source_t source,
-                                          audio_input_flags_t flags)
+status_t AudioFlinger::openInput(const media::OpenInputRequest& request,
+                                 media::OpenInputResponse* response)
 {
     Mutex::Autolock _l(mLock);
 
-    if (*devices == AUDIO_DEVICE_NONE) {
+    if (request.device.type == AUDIO_DEVICE_NONE) {
         return BAD_VALUE;
     }
 
+    audio_io_handle_t input = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_int32_t_audio_io_handle_t(request.input));
+    audio_config_t config = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_AudioConfig_audio_config_t(request.config));
+    AudioDeviceTypeAddr device = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_AudioDeviceTypeAddress(request.device));
+
     sp<ThreadBase> thread = openInput_l(
-            module, input, config, *devices, address, source, flags, AUDIO_DEVICE_NONE, String8{});
+            VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_module_handle_t(request.module)),
+            &input,
+            &config,
+            device.mType,
+            device.address().c_str(),
+            VALUE_OR_RETURN_STATUS(aidl2legacy_AudioSourceType_audio_source_t(request.source)),
+            VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_input_flags_t_mask(request.flags)),
+            AUDIO_DEVICE_NONE,
+            String8{});
+
+    response->input = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(input));
+    response->config = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_config_t_AudioConfig(config));
+    response->device = request.device;
 
     if (thread != 0) {
         // notify client processes of the new input creation
@@ -2832,7 +2840,7 @@
                                                          audio_io_handle_t *input,
                                                          audio_config_t *config,
                                                          audio_devices_t devices,
-                                                         const String8& address,
+                                                         const char* address,
                                                          audio_source_t source,
                                                          audio_input_flags_t flags,
                                                          audio_devices_t outputDevice,
@@ -2862,7 +2870,7 @@
     sp<DeviceHalInterface> inHwHal = inHwDev->hwDevice();
     sp<StreamInHalInterface> inStream;
     status_t status = inHwHal->openInputStream(
-            *input, devices, &halconfig, flags, address.string(), source,
+            *input, devices, &halconfig, flags, address, source,
             outputDevice, outputDeviceAddress, &inStream);
     ALOGV("openInput_l() openInputStream returned input %p, devices %#x, SamplingRate %d"
            ", Format %#x, Channels %#x, flags %#x, status %d addr %s",
@@ -2872,7 +2880,7 @@
             halconfig.format,
             halconfig.channel_mask,
             flags,
-            status, address.string());
+            status, address);
 
     // If the input could not be opened with the requested parameters and we can handle the
     // conversion internally, try to open again with the proposed parameters.
@@ -2886,7 +2894,7 @@
         ALOGV("openInput_l() reopening with proposed sampling rate and channel mask");
         inStream.clear();
         status = inHwHal->openInputStream(
-                *input, devices, &halconfig, flags, address.string(), source,
+                *input, devices, &halconfig, flags, address, source,
                 outputDevice, outputDeviceAddress, &inStream);
         // FIXME log this new status; HAL should not propose any further changes
     }
@@ -3202,7 +3210,8 @@
 // dumpToThreadLog_l() must be called with AudioFlinger::mLock held
 void AudioFlinger::dumpToThreadLog_l(const sp<ThreadBase> &thread)
 {
-    audio_utils::FdToString fdToString;
+    constexpr int THREAD_DUMP_TIMEOUT_MS = 2;
+    audio_utils::FdToString fdToString("- ", THREAD_DUMP_TIMEOUT_MS);
     const int fd = fdToString.fd();
     if (fd >= 0) {
         thread->dump(fd, {} /* args */);
@@ -3498,23 +3507,29 @@
     return status;
 }
 
-sp<media::IEffect> AudioFlinger::createEffect(
-        effect_descriptor_t *pDesc,
-        const sp<IEffectClient>& effectClient,
-        int32_t priority,
-        audio_io_handle_t io,
-        audio_session_t sessionId,
-        const AudioDeviceTypeAddr& device,
-        const String16& opPackageName,
-        pid_t pid,
-        bool probe,
-        status_t *status,
-        int *id,
-        int *enabled)
-{
-    status_t lStatus = NO_ERROR;
+status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request,
+                                    media::CreateEffectResponse* response) {
+    const sp<IEffectClient>& effectClient = request.client;
+    const int32_t priority = request.priority;
+    const AudioDeviceTypeAddr device = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_AudioDeviceTypeAddress(request.device));
+    const String16 opPackageName = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_string_view_String16(request.opPackageName));
+    pid_t pid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(request.pid));
+    const audio_session_t sessionId = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_int32_t_audio_session_t(request.sessionId));
+    audio_io_handle_t io = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_int32_t_audio_io_handle_t(request.output));
+    const effect_descriptor_t descIn = VALUE_OR_RETURN_STATUS(
+            aidl2legacy_EffectDescriptor_effect_descriptor_t(request.desc));
+    const bool probe = request.probe;
+
     sp<EffectHandle> handle;
-    effect_descriptor_t desc;
+    effect_descriptor_t descOut;
+    int enabledOut = 0;
+    int idOut = -1;
+
+    status_t lStatus = NO_ERROR;
 
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
     if (pid == -1 || !isAudioServerOrMediaServerUid(callingUid)) {
@@ -3526,12 +3541,7 @@
     }
 
     ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d, factory %p",
-            pid, effectClient.get(), priority, sessionId, io, mEffectsFactoryHal.get());
-
-    if (pDesc == NULL) {
-        lStatus = BAD_VALUE;
-        goto Exit;
-    }
+          pid, effectClient.get(), priority, sessionId, io, mEffectsFactoryHal.get());
 
     if (mEffectsFactoryHal == 0) {
         ALOGE("%s: no effects factory hal", __func__);
@@ -3588,7 +3598,7 @@
         // otherwise no preference.
         uint32_t preferredType = (sessionId == AUDIO_SESSION_OUTPUT_MIX ?
                                   EFFECT_FLAG_TYPE_AUXILIARY : EFFECT_FLAG_TYPE_MASK);
-        lStatus = getEffectDescriptor(&pDesc->uuid, &pDesc->type, preferredType, &desc);
+        lStatus = getEffectDescriptor(&descIn.uuid, &descIn.type, preferredType, &descOut);
         if (lStatus < 0) {
             ALOGW("createEffect() error %d from getEffectDescriptor", lStatus);
             goto Exit;
@@ -3596,20 +3606,20 @@
 
         // Do not allow auxiliary effects on a session different from 0 (output mix)
         if (sessionId != AUDIO_SESSION_OUTPUT_MIX &&
-             (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
+             (descOut.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
             lStatus = INVALID_OPERATION;
             goto Exit;
         }
 
         // check recording permission for visualizer
-        if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
+        if ((memcmp(&descOut.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
             // TODO: Do we need to start/stop op - i.e. is there recording being performed?
             !recordingAllowed(opPackageName, pid, callingUid)) {
             lStatus = PERMISSION_DENIED;
             goto Exit;
         }
 
-        const bool hapticPlaybackRequired = EffectModule::isHapticGenerator(&desc.type);
+        const bool hapticPlaybackRequired = EffectModule::isHapticGenerator(&descOut.type);
         if (hapticPlaybackRequired
                 && (sessionId == AUDIO_SESSION_DEVICE
                         || sessionId == AUDIO_SESSION_OUTPUT_MIX
@@ -3619,13 +3629,11 @@
             goto Exit;
         }
 
-        // return effect descriptor
-        *pDesc = desc;
         if (io == AUDIO_IO_HANDLE_NONE && sessionId == AUDIO_SESSION_OUTPUT_MIX) {
             // if the output returned by getOutputForEffect() is removed before we lock the
             // mutex below, the call to checkPlaybackThread_l(io) below will detect it
             // and we will exit safely
-            io = AudioSystem::getOutputForEffect(&desc);
+            io = AudioSystem::getOutputForEffect(&descOut);
             ALOGV("createEffect got output %d", io);
         }
 
@@ -3635,15 +3643,15 @@
             sp<Client> client = registerPid(pid);
             ALOGV("%s device type %#x address %s", __func__, device.mType, device.getAddress());
             handle = mDeviceEffectManager.createEffect_l(
-                    &desc, device, client, effectClient, mPatchPanel.patches_l(),
-                    enabled, &lStatus, probe);
+                    &descOut, device, client, effectClient, mPatchPanel.patches_l(),
+                    &enabledOut, &lStatus, probe);
             if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
                 // remove local strong reference to Client with mClientLock held
                 Mutex::Autolock _cl(mClientLock);
                 client.clear();
             } else {
                 // handle must be valid here, but check again to be safe.
-                if (handle.get() != nullptr && id != nullptr) *id = handle->id();
+                if (handle.get() != nullptr) idOut = handle->id();
             }
             goto Register;
         }
@@ -3673,8 +3681,8 @@
             // Detect if the effect is created after an AudioRecord is destroyed.
             if (getOrphanEffectChain_l(sessionId).get() != nullptr) {
                 ALOGE("%s: effect %s with no specified io handle is denied because the AudioRecord"
-                        " for session %d no longer exists",
-                         __func__, desc.name, sessionId);
+                      " for session %d no longer exists",
+                      __func__, descOut.name, sessionId);
                 lStatus = PERMISSION_DENIED;
                 goto Exit;
             }
@@ -3688,7 +3696,7 @@
             if (io == AUDIO_IO_HANDLE_NONE && mPlaybackThreads.size() > 0) {
                 io = mPlaybackThreads.keyAt(0);
             }
-            ALOGV("createEffect() got io %d for effect %s", io, desc.name);
+            ALOGV("createEffect() got io %d for effect %s", io, descOut.name);
         } else if (checkPlaybackThread_l(io) != nullptr) {
             // allow only one effect chain per sessionId on mPlaybackThreads.
             for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
@@ -3708,7 +3716,7 @@
                         mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId);
                 if ((sessionType & ThreadBase::EFFECT_SESSION) != 0) {
                     ALOGE("%s: effect %s io %d denied because session %d effect exists on io %d",
-                            __func__, desc.name, (int)io, (int)sessionId, (int)checkIo);
+                          __func__, descOut.name, (int) io, (int) sessionId, (int) checkIo);
                     android_errorWriteLog(0x534e4554, "123237974");
                     lStatus = BAD_VALUE;
                     goto Exit;
@@ -3755,14 +3763,14 @@
             }
         }
         handle = thread->createEffect_l(client, effectClient, priority, sessionId,
-                &desc, enabled, &lStatus, pinned, probe);
+                                        &descOut, &enabledOut, &lStatus, pinned, probe);
         if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
             // remove local strong reference to Client with mClientLock held
             Mutex::Autolock _cl(mClientLock);
             client.clear();
         } else {
             // handle must be valid here, but check again to be safe.
-            if (handle.get() != nullptr && id != nullptr) *id = handle->id();
+            if (handle.get() != nullptr) idOut = handle->id();
             // Invalidate audio session when haptic playback is created.
             if (hapticPlaybackRequired && oriThread != nullptr) {
                 // invalidateTracksForAudioSession will trigger locking the thread.
@@ -3785,9 +3793,14 @@
         handle.clear();
     }
 
+    response->id = idOut;
+    response->enabled = enabledOut != 0;
+    response->effect = handle;
+    response->desc = VALUE_OR_RETURN_STATUS(
+            legacy2aidl_effect_descriptor_t_EffectDescriptor(descOut));
+
 Exit:
-    *status = lStatus;
-    return handle;
+    return lStatus;
 }
 
 status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t srcOutput,
@@ -4036,10 +4049,109 @@
 
 // ----------------------------------------------------------------------------
 
-status_t AudioFlinger::onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+status_t AudioFlinger::onPreTransact(
+        TransactionCode code, const Parcel& /* data */, uint32_t /* flags */)
 {
-    return BnAudioFlinger::onTransact(code, data, reply, flags);
+    // make sure transactions reserved to AudioPolicyManager do not come from other processes
+    switch (code) {
+        case TransactionCode::SET_STREAM_VOLUME:
+        case TransactionCode::SET_STREAM_MUTE:
+        case TransactionCode::OPEN_OUTPUT:
+        case TransactionCode::OPEN_DUPLICATE_OUTPUT:
+        case TransactionCode::CLOSE_OUTPUT:
+        case TransactionCode::SUSPEND_OUTPUT:
+        case TransactionCode::RESTORE_OUTPUT:
+        case TransactionCode::OPEN_INPUT:
+        case TransactionCode::CLOSE_INPUT:
+        case TransactionCode::INVALIDATE_STREAM:
+        case TransactionCode::SET_VOICE_VOLUME:
+        case TransactionCode::MOVE_EFFECTS:
+        case TransactionCode::SET_EFFECT_SUSPENDED:
+        case TransactionCode::LOAD_HW_MODULE:
+        case TransactionCode::GET_AUDIO_PORT:
+        case TransactionCode::CREATE_AUDIO_PATCH:
+        case TransactionCode::RELEASE_AUDIO_PATCH:
+        case TransactionCode::LIST_AUDIO_PATCHES:
+        case TransactionCode::SET_AUDIO_PORT_CONFIG:
+        case TransactionCode::SET_RECORD_SILENCED:
+            ALOGW("%s: transaction %d received from PID %d",
+                  __func__, code, IPCThreadState::self()->getCallingPid());
+            // return status only for non void methods
+            switch (code) {
+                case TransactionCode::SET_RECORD_SILENCED:
+                case TransactionCode::SET_EFFECT_SUSPENDED:
+                    break;
+                default:
+                    return INVALID_OPERATION;
+            }
+            return OK;
+        default:
+            break;
+    }
+
+    // make sure the following transactions come from system components
+    switch (code) {
+        case TransactionCode::SET_MASTER_VOLUME:
+        case TransactionCode::SET_MASTER_MUTE:
+        case TransactionCode::MASTER_MUTE:
+        case TransactionCode::SET_MODE:
+        case TransactionCode::SET_MIC_MUTE:
+        case TransactionCode::SET_LOW_RAM_DEVICE:
+        case TransactionCode::SYSTEM_READY:
+        case TransactionCode::SET_AUDIO_HAL_PIDS: {
+            if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
+                ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
+                      __func__, code, IPCThreadState::self()->getCallingPid(),
+                      IPCThreadState::self()->getCallingUid());
+                // return status only for non void methods
+                switch (code) {
+                    case TransactionCode::SYSTEM_READY:
+                        break;
+                    default:
+                        return INVALID_OPERATION;
+                }
+                return OK;
+            }
+        } break;
+        default:
+            break;
+    }
+
+    // List of relevant events that trigger log merging.
+    // Log merging should activate during audio activity of any kind. This are considered the
+    // most relevant events.
+    // TODO should select more wisely the items from the list
+    switch (code) {
+        case TransactionCode::CREATE_TRACK:
+        case TransactionCode::CREATE_RECORD:
+        case TransactionCode::SET_MASTER_VOLUME:
+        case TransactionCode::SET_MASTER_MUTE:
+        case TransactionCode::SET_MIC_MUTE:
+        case TransactionCode::SET_PARAMETERS:
+        case TransactionCode::CREATE_EFFECT:
+        case TransactionCode::SYSTEM_READY: {
+            requestLogMerge();
+            break;
+        }
+        default:
+            break;
+    }
+
+    std::string tag("IAudioFlinger command " +
+                    std::to_string(static_cast<std::underlying_type_t<TransactionCode>>(code)));
+    TimeCheck check(tag.c_str());
+
+    // Make sure we connect to Audio Policy Service before calling into AudioFlinger:
+    //  - AudioFlinger can call into Audio Policy Service with its global mutex held
+    //  - If this is the first time Audio Policy Service is queried from inside audioserver process
+    //  this will trigger Audio Policy Manager initialization.
+    //  - Audio Policy Manager initialization calls into AudioFlinger which will try to lock
+    //  its global mutex and a deadlock will occur.
+    if (IPCThreadState::self()->getCallingPid() != getpid()) {
+        AudioSystem::get_audio_policy_service();
+    }
+
+    return OK;
 }
 
 } // namespace android
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2ff6af5..1cf1e67 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <limits.h>
 
+#include <android/media/BnAudioTrack.h>
 #include <android/media/IAudioFlingerClient.h>
 #include <android/media/IAudioTrackCallback.h>
 #include <android/os/BnExternalVibrationController.h>
@@ -43,7 +44,6 @@
 
 #include <cutils/properties.h>
 #include <media/IAudioFlinger.h>
-#include <media/IAudioTrack.h>
 #include <media/AudioSystem.h>
 #include <media/AudioTrack.h>
 #include <media/MmapStreamInterface.h>
@@ -123,25 +123,19 @@
 
 #define INCLUDING_FROM_AUDIOFLINGER_H
 
-class AudioFlinger :
-    public BinderService<AudioFlinger>,
-    public BnAudioFlinger
+class AudioFlinger : public AudioFlingerServerAdapter::Delegate
 {
-    friend class BinderService<AudioFlinger>;   // for AudioFlinger()
-
 public:
-    static const char* getServiceName() ANDROID_API { return "media.audio_flinger"; }
+    static void instantiate() ANDROID_API;
 
-    virtual     status_t    dump(int fd, const Vector<String16>& args);
+    status_t dump(int fd, const Vector<String16>& args) override;
 
     // IAudioFlinger interface, in binder opcode order
-    virtual sp<IAudioTrack> createTrack(const media::CreateTrackRequest& input,
-                                        media::CreateTrackResponse& output,
-                                        status_t* status) override;
+    status_t createTrack(const media::CreateTrackRequest& input,
+                         media::CreateTrackResponse& output) override;
 
-    virtual sp<media::IAudioRecord> createRecord(const media::CreateRecordRequest& input,
-                                                 media::CreateRecordResponse& output,
-                                                 status_t* status) override;
+    status_t createRecord(const media::CreateRecordRequest& input,
+                          media::CreateRecordResponse& output) override;
 
     virtual     uint32_t    sampleRate(audio_io_handle_t ioHandle) const;
     virtual     audio_format_t format(audio_io_handle_t output) const;
@@ -182,12 +176,8 @@
     virtual     size_t      getInputBufferSize(uint32_t sampleRate, audio_format_t format,
                                                audio_channel_mask_t channelMask) const;
 
-    virtual status_t openOutput(audio_module_handle_t module,
-                                audio_io_handle_t *output,
-                                audio_config_t *config,
-                                const sp<DeviceDescriptorBase>& device,
-                                uint32_t *latencyMs,
-                                audio_output_flags_t flags);
+    virtual status_t openOutput(const media::OpenOutputRequest& request,
+                                media::OpenOutputResponse* response);
 
     virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
                                                   audio_io_handle_t output2);
@@ -198,13 +188,8 @@
 
     virtual status_t restoreOutput(audio_io_handle_t output);
 
-    virtual status_t openInput(audio_module_handle_t module,
-                               audio_io_handle_t *input,
-                               audio_config_t *config,
-                               audio_devices_t *device,
-                               const String8& address,
-                               audio_source_t source,
-                               audio_input_flags_t flags);
+    virtual status_t openInput(const media::OpenInputRequest& request,
+                               media::OpenInputResponse* response);
 
     virtual status_t closeInput(audio_io_handle_t input);
 
@@ -233,19 +218,8 @@
                                          uint32_t preferredTypeFlag,
                                          effect_descriptor_t *descriptor) const;
 
-    virtual sp<media::IEffect> createEffect(
-                        effect_descriptor_t *pDesc,
-                        const sp<media::IEffectClient>& effectClient,
-                        int32_t priority,
-                        audio_io_handle_t io,
-                        audio_session_t sessionId,
-                        const AudioDeviceTypeAddr& device,
-                        const String16& opPackageName,
-                        pid_t pid,
-                        bool probe,
-                        status_t *status /*non-NULL*/,
-                        int *id,
-                        int *enabled);
+    virtual status_t createEffect(const media::CreateEffectRequest& request,
+                                  media::CreateEffectResponse* response);
 
     virtual status_t moveEffects(audio_session_t sessionId, audio_io_handle_t srcOutput,
                         audio_io_handle_t dstOutput);
@@ -266,7 +240,7 @@
                                     struct audio_port *ports);
 
     /* Get attributes for a given audio port */
-    virtual status_t getAudioPort(struct audio_port *port);
+    virtual status_t getAudioPort(struct audio_port_v7 *port);
 
     /* Create an audio patch between several source and sink ports */
     virtual status_t createAudioPatch(const struct audio_patch *patch,
@@ -292,11 +266,7 @@
 
     virtual status_t setAudioHalPids(const std::vector<pid_t>& pids);
 
-    virtual     status_t    onTransact(
-                                uint32_t code,
-                                const Parcel& data,
-                                Parcel* reply,
-                                uint32_t flags);
+    status_t onPreTransact(TransactionCode code, const Parcel& data, uint32_t flags) override;
 
     // end of IAudioFlinger interface
 
@@ -541,6 +511,7 @@
     const sp<MediaLogNotifier> mMediaLogNotifier;
 
     // This is a helper that is called during incoming binder calls.
+    // Requests media.log to start merging log buffers
     void requestLogMerge();
 
     class TrackHandle;
@@ -626,27 +597,30 @@
     }
 
     // server side of the client's IAudioTrack
-    class TrackHandle : public android::BnAudioTrack {
+    class TrackHandle : public android::media::BnAudioTrack {
     public:
         explicit            TrackHandle(const sp<PlaybackThread::Track>& track);
         virtual             ~TrackHandle();
-        virtual sp<IMemory> getCblk() const;
-        virtual status_t    start();
-        virtual void        stop();
-        virtual void        flush();
-        virtual void        pause();
-        virtual status_t    attachAuxEffect(int effectId);
-        virtual status_t    setParameters(const String8& keyValuePairs);
-        virtual status_t    selectPresentation(int presentationId, int programId);
-        virtual media::VolumeShaper::Status applyVolumeShaper(
-                const sp<media::VolumeShaper::Configuration>& configuration,
-                const sp<media::VolumeShaper::Operation>& operation) override;
-        virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override;
-        virtual status_t    getTimestamp(AudioTimestamp& timestamp);
-        virtual void        signal(); // signal playback thread for a change in control block
 
-        virtual status_t onTransact(
-            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+        binder::Status getCblk(std::optional<media::SharedFileRegion>* _aidl_return) override;
+        binder::Status start(int32_t* _aidl_return) override;
+        binder::Status stop() override;
+        binder::Status flush() override;
+        binder::Status pause() override;
+        binder::Status attachAuxEffect(int32_t effectId, int32_t* _aidl_return) override;
+        binder::Status setParameters(const std::string& keyValuePairs,
+                                     int32_t* _aidl_return) override;
+        binder::Status selectPresentation(int32_t presentationId, int32_t programId,
+                                          int32_t* _aidl_return) override;
+        binder::Status getTimestamp(media::AudioTimestampInternal* timestamp,
+                                    int32_t* _aidl_return) override;
+        binder::Status signal() override;
+        binder::Status applyVolumeShaper(const media::VolumeShaperConfiguration& configuration,
+                                         const media::VolumeShaperOperation& operation,
+                                         int32_t* _aidl_return) override;
+        binder::Status getVolumeShaperState(
+                int32_t id,
+                std::optional<media::VolumeShaperState>* _aidl_return) override;
 
     private:
         const sp<PlaybackThread::Track> mTrack;
@@ -661,7 +635,7 @@
                 int /*audio_session_t*/ triggerSession);
         virtual binder::Status   stop();
         virtual binder::Status   getActiveMicrophones(
-                std::vector<media::MicrophoneInfo>* activeMicrophones);
+                std::vector<media::MicrophoneInfoData>* activeMicrophones);
         virtual binder::Status   setPreferredMicrophoneDirection(
                 int /*audio_microphone_direction_t*/ direction);
         virtual binder::Status   setPreferredMicrophoneFieldDimension(float zoom);
@@ -707,7 +681,7 @@
                                            audio_io_handle_t *input,
                                            audio_config_t *config,
                                            audio_devices_t device,
-                                           const String8& address,
+                                           const char* address,
                                            audio_source_t source,
                                            audio_input_flags_t flags,
                                            audio_devices_t outputDevice,
@@ -787,7 +761,7 @@
 
                 std::vector< sp<EffectModule> > purgeStaleEffects_l();
 
-                void broacastParametersToRecordThreads_l(const String8& keyValuePairs);
+                void broadcastParametersToRecordThreads_l(const String8& keyValuePairs);
                 void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices);
                 void forwardParametersToDownstreamPatches_l(
                         audio_io_handle_t upStream, const String8& keyValuePairs,
diff --git a/services/audioflinger/AudioHwDevice.cpp b/services/audioflinger/AudioHwDevice.cpp
index dda164c..16b25f6 100644
--- a/services/audioflinger/AudioHwDevice.cpp
+++ b/services/audioflinger/AudioHwDevice.cpp
@@ -98,5 +98,9 @@
     return mHwDevice->supportsAudioPatches(&result) == OK ? result : false;
 }
 
+status_t AudioHwDevice::getAudioPort(struct audio_port_v7 *port) const {
+    return mHwDevice->getAudioPort(port);
+}
+
 
 }; // namespace android
diff --git a/services/audioflinger/AudioHwDevice.h b/services/audioflinger/AudioHwDevice.h
index 6709d17..fc2c693 100644
--- a/services/audioflinger/AudioHwDevice.h
+++ b/services/audioflinger/AudioHwDevice.h
@@ -83,6 +83,8 @@
 
     bool supportsAudioPatches() const;
 
+    status_t getAudioPort(struct audio_port_v7 *port) const;
+
 private:
     const audio_module_handle_t mHandle;
     const char * const          mModuleName;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index eaad6ef..3ab7737 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -60,6 +60,7 @@
 
 namespace android {
 
+using aidl_utils::statusTFromBinderStatus;
 using binder::Status;
 
 namespace {
@@ -3027,7 +3028,7 @@
                 bs = handle.second->disable(&status);
             }
             if (!bs.isOk()) {
-              status = bs.transactionError();
+              status = statusTFromBinderStatus(bs);
             }
         }
     }
@@ -3142,7 +3143,7 @@
             bs = (*handle)->disable(&status);
         }
         if (!bs.isOk()) {
-            status = bs.transactionError();
+            status = statusTFromBinderStatus(bs);
         }
     }
     return status;
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index b58fd8b..1e11660 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -25,6 +25,7 @@
 
 #include "AudioFlinger.h"
 #include <media/AudioParameter.h>
+#include <media/AudioValidator.h>
 #include <media/DeviceDescriptorBase.h>
 #include <media/PatchBuilder.h>
 #include <mediautils/ServiceUtilities.h>
@@ -55,8 +56,12 @@
 }
 
 /* Get supported attributes for a given audio port */
-status_t AudioFlinger::getAudioPort(struct audio_port *port)
-{
+status_t AudioFlinger::getAudioPort(struct audio_port_v7 *port) {
+    status_t status = AudioValidator::validateAudioPort(*port);
+    if (status != NO_ERROR) {
+        return status;
+    }
+
     Mutex::Autolock _l(mLock);
     return mPatchPanel.getAudioPort(port);
 }
@@ -65,6 +70,11 @@
 status_t AudioFlinger::createAudioPatch(const struct audio_patch *patch,
                                    audio_patch_handle_t *handle)
 {
+    status_t status = AudioValidator::validateAudioPatch(*patch);
+    if (status != NO_ERROR) {
+        return status;
+    }
+
     Mutex::Autolock _l(mLock);
     return mPatchPanel.createAudioPatch(patch, handle);
 }
@@ -103,10 +113,22 @@
 }
 
 /* Get supported attributes for a given audio port */
-status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port *port __unused)
+status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port_v7 *port)
 {
-    ALOGV(__func__);
-    return NO_ERROR;
+    if (port->type != AUDIO_PORT_TYPE_DEVICE) {
+        // Only query the HAL when the port is a device.
+        // TODO: implement getAudioPort for mix.
+        return INVALID_OPERATION;
+    }
+    AudioHwDevice* hwDevice = findAudioHwDeviceByModule(port->ext.device.hw_module);
+    if (hwDevice == nullptr) {
+        ALOGW("%s cannot find hw module %d", __func__, port->ext.device.hw_module);
+        return BAD_VALUE;
+    }
+    if (!hwDevice->supportsAudioPatches()) {
+        return INVALID_OPERATION;
+    }
+    return hwDevice->getAudioPort(port);
 }
 
 /* Connect a patch between several source and sink ports */
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 89d4eb1..2568dd3 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -52,7 +52,7 @@
                                     struct audio_port *ports);
 
     /* Get supported attributes for a given audio port */
-    status_t getAudioPort(struct audio_port *port);
+    status_t getAudioPort(struct audio_port_v7 *port);
 
     /* Create a patch between several source and sink ports */
     status_t createAudioPatch(const struct audio_patch *patch,
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index c1c3c44..ab2bc32 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7477,7 +7477,7 @@
                         (framesRead - part1) * mFrameSize);
             }
         }
-        rear = mRsmpInRear += framesRead;
+        mRsmpInRear = audio_utils::safe_add_overflow(mRsmpInRear, (int32_t)framesRead);
 
         size = activeTracks.size();
 
@@ -8684,6 +8684,7 @@
 
 void AudioFlinger::RecordThread::updateOutDevices(const DeviceDescriptorBaseVector& outDevices)
 {
+    Mutex::Autolock _l(mLock);
     mOutDevices = outDevices;
     mOutDeviceTypeAddrs = deviceTypeAddrsFromDescriptors(mOutDevices);
     for (size_t i = 0; i < mEffectChains.size(); i++) {
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 1a12a5f..6049f62 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -54,6 +54,8 @@
 
 namespace android {
 
+using aidl_utils::binderStatusFromStatusT;
+using binder::Status;
 using media::VolumeShaper;
 // ----------------------------------------------------------------------------
 //      TrackBase
@@ -319,64 +321,98 @@
     mTrack->destroy();
 }
 
-sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
-    return mTrack->getCblk();
+Status AudioFlinger::TrackHandle::getCblk(
+        std::optional<media::SharedFileRegion>* _aidl_return) {
+    *_aidl_return = legacy2aidl_NullableIMemory_SharedFileRegion(mTrack->getCblk()).value();
+    return Status::ok();
 }
 
-status_t AudioFlinger::TrackHandle::start() {
-    return mTrack->start();
+Status AudioFlinger::TrackHandle::start(int32_t* _aidl_return) {
+    *_aidl_return = mTrack->start();
+    return Status::ok();
 }
 
-void AudioFlinger::TrackHandle::stop() {
+Status AudioFlinger::TrackHandle::stop() {
     mTrack->stop();
+    return Status::ok();
 }
 
-void AudioFlinger::TrackHandle::flush() {
+Status AudioFlinger::TrackHandle::flush() {
     mTrack->flush();
+    return Status::ok();
 }
 
-void AudioFlinger::TrackHandle::pause() {
+Status AudioFlinger::TrackHandle::pause() {
     mTrack->pause();
+    return Status::ok();
 }
 
-status_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
-{
-    return mTrack->attachAuxEffect(EffectId);
+Status AudioFlinger::TrackHandle::attachAuxEffect(int32_t effectId,
+                                                  int32_t* _aidl_return) {
+    *_aidl_return = mTrack->attachAuxEffect(effectId);
+    return Status::ok();
 }
 
-status_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs) {
-    return mTrack->setParameters(keyValuePairs);
+Status AudioFlinger::TrackHandle::setParameters(const std::string& keyValuePairs,
+                                                int32_t* _aidl_return) {
+    *_aidl_return = mTrack->setParameters(String8(keyValuePairs.c_str()));
+    return Status::ok();
 }
 
-status_t AudioFlinger::TrackHandle::selectPresentation(int presentationId, int programId) {
-    return mTrack->selectPresentation(presentationId, programId);
+Status AudioFlinger::TrackHandle::selectPresentation(int32_t presentationId, int32_t programId,
+                                                     int32_t* _aidl_return) {
+    *_aidl_return = mTrack->selectPresentation(presentationId, programId);
+    return Status::ok();
 }
 
-VolumeShaper::Status AudioFlinger::TrackHandle::applyVolumeShaper(
-        const sp<VolumeShaper::Configuration>& configuration,
-        const sp<VolumeShaper::Operation>& operation) {
-    return mTrack->applyVolumeShaper(configuration, operation);
+Status AudioFlinger::TrackHandle::getTimestamp(media::AudioTimestampInternal* timestamp,
+                                               int32_t* _aidl_return) {
+    AudioTimestamp legacy;
+    *_aidl_return = mTrack->getTimestamp(legacy);
+    if (*_aidl_return != OK) {
+        return Status::ok();
+    }
+    *timestamp = legacy2aidl_AudioTimestamp_AudioTimestampInternal(legacy).value();
+    return Status::ok();
 }
 
-sp<VolumeShaper::State> AudioFlinger::TrackHandle::getVolumeShaperState(int id) {
-    return mTrack->getVolumeShaperState(id);
+Status AudioFlinger::TrackHandle::signal() {
+    mTrack->signal();
+    return Status::ok();
 }
 
-status_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp)
-{
-    return mTrack->getTimestamp(timestamp);
+Status AudioFlinger::TrackHandle::applyVolumeShaper(
+        const media::VolumeShaperConfiguration& configuration,
+        const media::VolumeShaperOperation& operation,
+        int32_t* _aidl_return) {
+    sp<VolumeShaper::Configuration> conf = new VolumeShaper::Configuration();
+    *_aidl_return = conf->readFromParcelable(configuration);
+    if (*_aidl_return != OK) {
+        return Status::ok();
+    }
+
+    sp<VolumeShaper::Operation> op = new VolumeShaper::Operation();
+    *_aidl_return = op->readFromParcelable(operation);
+    if (*_aidl_return != OK) {
+        return Status::ok();
+    }
+
+    *_aidl_return = mTrack->applyVolumeShaper(conf, op);
+    return Status::ok();
 }
 
-
-void AudioFlinger::TrackHandle::signal()
-{
-    return mTrack->signal();
-}
-
-status_t AudioFlinger::TrackHandle::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    return BnAudioTrack::onTransact(code, data, reply, flags);
+Status AudioFlinger::TrackHandle::getVolumeShaperState(
+        int32_t id,
+        std::optional<media::VolumeShaperState>* _aidl_return) {
+    sp<VolumeShaper::State> legacy = mTrack->getVolumeShaperState(id);
+    if (legacy == nullptr) {
+        _aidl_return->reset();
+        return Status::ok();
+    }
+    media::VolumeShaperState aidl;
+    legacy->writeToParcelable(&aidl);
+    *_aidl_return = aidl;
+    return Status::ok();
 }
 
 // ----------------------------------------------------------------------------
@@ -2097,7 +2133,7 @@
 binder::Status AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
         int /*audio_session_t*/ triggerSession) {
     ALOGV("%s()", __func__);
-    return binder::Status::fromStatusT(
+    return binderStatusFromStatusT(
         mRecordTrack->start((AudioSystem::sync_event_t)event, (audio_session_t) triggerSession));
 }
 
@@ -2112,22 +2148,27 @@
 }
 
 binder::Status AudioFlinger::RecordHandle::getActiveMicrophones(
-        std::vector<media::MicrophoneInfo>* activeMicrophones) {
+        std::vector<media::MicrophoneInfoData>* activeMicrophones) {
     ALOGV("%s()", __func__);
-    return binder::Status::fromStatusT(
-            mRecordTrack->getActiveMicrophones(activeMicrophones));
+    std::vector<media::MicrophoneInfo> mics;
+    status_t status = mRecordTrack->getActiveMicrophones(&mics);
+    activeMicrophones->resize(mics.size());
+    for (size_t i = 0; status == OK && i < mics.size(); ++i) {
+       status = mics[i].writeToParcelable(&activeMicrophones->at(i));
+    }
+    return binderStatusFromStatusT(status);
 }
 
 binder::Status AudioFlinger::RecordHandle::setPreferredMicrophoneDirection(
         int /*audio_microphone_direction_t*/ direction) {
     ALOGV("%s()", __func__);
-    return binder::Status::fromStatusT(mRecordTrack->setPreferredMicrophoneDirection(
+    return binderStatusFromStatusT(mRecordTrack->setPreferredMicrophoneDirection(
             static_cast<audio_microphone_direction_t>(direction)));
 }
 
 binder::Status AudioFlinger::RecordHandle::setPreferredMicrophoneFieldDimension(float zoom) {
     ALOGV("%s()", __func__);
-    return binder::Status::fromStatusT(mRecordTrack->setPreferredMicrophoneFieldDimension(zoom));
+    return binderStatusFromStatusT(mRecordTrack->setPreferredMicrophoneFieldDimension(zoom));
 }
 
 // ----------------------------------------------------------------------------
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 93819f5..f753836 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -220,16 +220,16 @@
     virtual status_t    dump(int fd) = 0;
 
     virtual status_t setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t flags) = 0;
-    virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo) = 0;
+    virtual audio_offload_mode_t getOffloadSupport(const audio_offload_info_t& offloadInfo) = 0;
     virtual bool isDirectOutputSupported(const audio_config_base_t& config,
                                          const audio_attributes_t& attributes) = 0;
 
     virtual status_t listAudioPorts(audio_port_role_t role,
                                     audio_port_type_t type,
                                     unsigned int *num_ports,
-                                    struct audio_port *ports,
+                                    struct audio_port_v7 *ports,
                                     unsigned int *generation) = 0;
-    virtual status_t getAudioPort(struct audio_port *port) = 0;
+    virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
     virtual status_t createAudioPatch(const struct audio_patch *patch,
                                        audio_patch_handle_t *handle,
                                        uid_t uid) = 0;
@@ -444,6 +444,8 @@
     // sessions to be preempted on modules that do not support sound trigger
     // recognition concurrently with audio capture.
     virtual void setSoundTriggerCaptureState(bool active) = 0;
+
+    virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
 };
 
 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index 6f47abc..a40f6aa 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -72,7 +72,7 @@
             const struct audio_port_config *srcConfig = NULL) const;
     virtual sp<AudioPort> getAudioPort() const { return mProfile; }
 
-    void toAudioPort(struct audio_port *port) const;
+    void toAudioPort(struct audio_port_v7 *port) const;
     void setPreemptedSessions(const SortedVector<audio_session_t>& sessions);
     SortedVector<audio_session_t> getPreemptedSessions() const;
     bool hasPreemptedSession(audio_session_t session) const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 1d9223e..5153dce 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -182,6 +182,7 @@
      * Active ref count of the client will be incremented/decremented through setActive API
      */
     virtual void setClientActive(const sp<TrackClientDescriptor>& client, bool active);
+    bool isClientActive(const sp<TrackClientDescriptor>& client);
 
     bool isActive(uint32_t inPastMs) const;
     bool isActive(VolumeSource volumeSource = VOLUME_SOURCE_NONE,
@@ -260,7 +261,7 @@
                            const struct audio_port_config *srcConfig = NULL) const;
     virtual sp<AudioPort> getAudioPort() const { return mPolicyAudioPort->asAudioPort(); }
 
-    virtual void toAudioPort(struct audio_port *port) const;
+    virtual void toAudioPort(struct audio_port_v7 *port) const;
 
     audio_module_handle_t getModuleHandle() const;
 
@@ -357,7 +358,7 @@
 
     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                            const struct audio_port_config *srcConfig = NULL) const;
-    virtual void toAudioPort(struct audio_port *port) const;
+    virtual void toAudioPort(struct audio_port_v7 *port) const;
 
         status_t open(const audio_config_t *config,
                       const DeviceVector &devices,
@@ -431,7 +432,7 @@
 
     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                            const struct audio_port_config *srcConfig = NULL) const;
-    virtual void toAudioPort(struct audio_port *port) const;
+    virtual void toAudioPort(struct audio_port_v7 *port) const;
 
     const sp<SourceClientDescriptor> mSource;
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index ca29591..7c712e3 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -65,9 +65,6 @@
 
     bool supportsFormat(audio_format_t format);
 
-    void setDynamic() { mIsDynamic = true; }
-    bool isDynamic() const { return mIsDynamic; }
-
     // PolicyAudioPortConfig
     virtual sp<PolicyAudioPort> getPolicyAudioPort() const {
         return static_cast<PolicyAudioPort*>(const_cast<DeviceDescriptor*>(this));
@@ -88,6 +85,7 @@
 
     // AudioPort
     virtual void toAudioPort(struct audio_port *port) const;
+    virtual void toAudioPort(struct audio_port_v7 *port) const;
 
     void importAudioPortAndPickAudioProfile(const sp<PolicyAudioPort>& policyPort,
                                             bool force = false);
@@ -97,11 +95,16 @@
     void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
 
 private:
+    template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value
+                                        || std::is_same<T, struct audio_port_v7>::value, int> = 0>
+    void toAudioPortInternal(T* port) const {
+        DeviceDescriptorBase::toAudioPort(port);
+        port->ext.device.hw_module = getModuleHandle();
+    }
+
     std::string mTagName; // Unique human readable identifier for a device port found in conf file.
     FormatVector        mEncodedFormats;
     audio_format_t      mCurrentEncodedFormat;
-    bool                mIsDynamic = false;
-    const std::string   mDeclaredAddress; // Original device address
 };
 
 class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index b5b10f3..23f0c9a 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -131,17 +131,8 @@
 public:
     sp<HwModule> getModuleFromName(const char *name) const;
 
-    /**
-     * @brief getModuleForDeviceType try to get a device from type / format on all modules
-     * @param device type to consider
-     * @param encodedFormat to consider
-     * @param[out] tagName if not null, if a matching device is found, will return the tagName
-     * of original device from XML file so that audio routes matchin rules work.
-     * @return valid module if considered device found, nullptr otherwise.
-     */
     sp<HwModule> getModuleForDeviceType(audio_devices_t device,
-                                        audio_format_t encodedFormat,
-                                        std::string *tagName = nullptr) const;
+                                        audio_format_t encodedFormat) const;
 
     sp<HwModule> getModuleForDevice(const sp<DeviceDescriptor> &device,
                                     audio_format_t encodedFormat) const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 11d3a99..621c630 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -112,19 +112,6 @@
     }
 
     /**
-     * @brief getTag
-     * @param deviceTypes to be considered
-     * @return tagName of first matching device for the considered types, empty string otherwise.
-     */
-    std::string getTag(const DeviceTypeSet& deviceTypes) const
-    {
-        if (supportsDeviceTypes(deviceTypes)) {
-            return mSupportedDevices.getDevicesFromTypes(deviceTypes).itemAt(0)->getTagName();
-        }
-        return {};
-    }
-
-    /**
      * @brief supportsDevice
      * @param device to be checked against
      *        forceCheckOnAddress if true, check on type and address whatever the type, otherwise
@@ -144,7 +131,7 @@
     bool devicesSupportEncodedFormats(DeviceTypeSet deviceTypes) const
     {
         if (deviceTypes.empty()) {
-            return true; // required for isOffloadSupported() check
+            return true; // required for getOffloadSupport() check
         }
         DeviceVector deviceList =
             mSupportedDevices.getDevicesFromTypes(deviceTypes);
@@ -163,12 +150,6 @@
     }
     void removeSupportedDevice(const sp<DeviceDescriptor> &device)
     {
-        ssize_t ret = mSupportedDevices.indexOf(device);
-        if (ret >= 0 && !mSupportedDevices.itemAt(ret)->isDynamic()) {
-            // devices equality checks only type, address, name and format
-            // Prevents from removing non dynamically added devices
-            return;
-        }
         mSupportedDevices.remove(device);
     }
     void setSupportedDevices(const DeviceVector &devices)
diff --git a/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h b/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h
index e6eef24..d2f6297 100644
--- a/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h
@@ -42,11 +42,6 @@
 
     virtual const std::string getTagName() const = 0;
 
-    bool equals(const sp<PolicyAudioPort> &right) const
-    {
-        return getTagName() == right->getTagName();
-    }
-
     virtual sp<AudioPort> asAudioPort() const = 0;
 
     virtual void setFlags(uint32_t flags)
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 4922ebe..7016a08 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -92,7 +92,7 @@
     dstConfig->ext.mix.usecase.source = source();
 }
 
-void AudioInputDescriptor::toAudioPort(struct audio_port *port) const
+void AudioInputDescriptor::toAudioPort(struct audio_port_v7 *port) const
 {
     ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle);
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 25f7c27..c4d7340 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -123,6 +123,12 @@
     client->setActive(active);
 }
 
+bool AudioOutputDescriptor::isClientActive(const sp<TrackClientDescriptor>& client)
+{
+    return client != nullptr &&
+            std::find(begin(mActiveClients), end(mActiveClients), client) != end(mActiveClients);
+}
+
 bool AudioOutputDescriptor::isActive(VolumeSource vs, uint32_t inPastMs, nsecs_t sysTime) const
 {
     return (vs == VOLUME_SOURCE_NONE) ?
@@ -209,7 +215,7 @@
     dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
 }
 
-void AudioOutputDescriptor::toAudioPort(struct audio_port *port) const
+void AudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
 {
     // Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
     mPolicyAudioPort->asAudioPort()->toAudioPort(port);
@@ -400,8 +406,7 @@
     dstConfig->ext.mix.handle = mIoHandle;
 }
 
-void SwAudioOutputDescriptor::toAudioPort(
-                                                    struct audio_port *port) const
+void SwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
 {
     ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
 
@@ -648,8 +653,7 @@
     mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
 }
 
-void HwAudioOutputDescriptor::toAudioPort(
-                                                    struct audio_port *port) const
+void HwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
 {
     mSource->srcDevice()->toAudioPort(port);
 }
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
index c8e4e76..2a18f19 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
@@ -39,12 +39,12 @@
 bool AudioRoute::supportsPatch(const sp<PolicyAudioPort> &srcPort,
                                const sp<PolicyAudioPort> &dstPort) const
 {
-    if (mSink == 0 || dstPort == 0 || !dstPort->equals(mSink)) {
+    if (mSink == 0 || dstPort == 0 || dstPort != mSink) {
         return false;
     }
     ALOGV("%s: sinks %s matching", __FUNCTION__, mSink->getTagName().c_str());
     for (const auto &sourcePort : mSources) {
-        if (sourcePort->equals(srcPort)) {
+        if (sourcePort == srcPort) {
             ALOGV("%s: sources %s matching", __FUNCTION__, sourcePort->getTagName().c_str());
             return true;
         }
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 6ff1a98..30b739c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -52,8 +52,7 @@
 DeviceDescriptor::DeviceDescriptor(const AudioDeviceTypeAddr &deviceTypeAddr,
                                    const std::string &tagName,
                                    const FormatVector &encodedFormats) :
-        DeviceDescriptorBase(deviceTypeAddr), mTagName(tagName), mEncodedFormats(encodedFormats),
-        mDeclaredAddress(deviceTypeAddr.getAddress())
+        DeviceDescriptorBase(deviceTypeAddr), mTagName(tagName), mEncodedFormats(encodedFormats)
 {
     mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
     /* If framework runs against a pre 5.0 Audio HAL, encoded formats are absent from the config.
@@ -76,10 +75,6 @@
 void DeviceDescriptor::detach() {
     mId = AUDIO_PORT_HANDLE_NONE;
     PolicyAudioPort::detach();
-    // The device address may have been overwritten on device connection
-    setAddress(mDeclaredAddress);
-    // Device Port does not have a name unless provided by setDeviceConnectionState
-    setName("");
 }
 
 template<typename T>
@@ -160,8 +155,12 @@
 void DeviceDescriptor::toAudioPort(struct audio_port *port) const
 {
     ALOGV("DeviceDescriptor::toAudioPort() handle %d type %08x", mId, mDeviceTypeAddr.mType);
-    DeviceDescriptorBase::toAudioPort(port);
-    port->ext.device.hw_module = getModuleHandle();
+    toAudioPortInternal(port);
+}
+
+void DeviceDescriptor::toAudioPort(struct audio_port_v7 *port) const {
+    ALOGV("DeviceDescriptor::toAudioPort() v7 handle %d type %08x", mId, mDeviceTypeAddr.mType);
+    toAudioPortInternal(port);
 }
 
 void DeviceDescriptor::importAudioPortAndPickAudioProfile(
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 2967014..d31e443 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -271,9 +271,8 @@
     return nullptr;
 }
 
-sp<HwModule> HwModuleCollection::getModuleForDeviceType(audio_devices_t type,
-                                                        audio_format_t encodedFormat,
-                                                        std::string *tagName) const
+sp <HwModule> HwModuleCollection::getModuleForDeviceType(audio_devices_t type,
+                                                         audio_format_t encodedFormat) const
 {
     for (const auto& module : *this) {
         const auto& profiles = audio_is_output_device(type) ?
@@ -285,15 +284,9 @@
                     sp <DeviceDescriptor> deviceDesc =
                             declaredDevices.getDevice(type, String8(), encodedFormat);
                     if (deviceDesc) {
-                        if (tagName != nullptr) {
-                            *tagName = deviceDesc->getTagName();
-                        }
                         return module;
                     }
                 } else {
-                    if (tagName != nullptr) {
-                        *tagName = profile->getTag({type});
-                    }
                     return module;
                 }
             }
@@ -332,32 +325,15 @@
     }
 
     for (const auto& hwModule : *this) {
-        if (!allowToCreate) {
-            auto dynamicDevices = hwModule->getDynamicDevices();
-            auto dynamicDevice = dynamicDevices.getDevice(deviceType, devAddress, encodedFormat);
-            if (dynamicDevice) {
-                return dynamicDevice;
-            }
-        }
         DeviceVector moduleDevices = hwModule->getAllDevices();
         auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress, encodedFormat);
-
-        // Prevent overwritting moduleDevice address if connected device does not have the same
-        // address (since getDevice with empty address ignores match on address), use dynamic device
-        if (moduleDevice && allowToCreate &&
-                (!moduleDevice->address().empty() &&
-                 (moduleDevice->address().compare(devAddress.c_str()) != 0))) {
-            break;
-        }
         if (moduleDevice) {
             if (encodedFormat != AUDIO_FORMAT_DEFAULT) {
                 moduleDevice->setEncodedFormat(encodedFormat);
             }
             if (allowToCreate) {
                 moduleDevice->attach(hwModule);
-                // Name may be overwritten, restored on detach.
                 moduleDevice->setAddress(devAddress.string());
-                // Name may be overwritten, restored on detach.
                 moduleDevice->setName(name);
             }
             return moduleDevice;
@@ -376,19 +352,18 @@
                                                       const char *name,
                                                       const audio_format_t encodedFormat) const
 {
-    std::string tagName = {};
-    sp<HwModule> hwModule = getModuleForDeviceType(type, encodedFormat, &tagName);
+    sp<HwModule> hwModule = getModuleForDeviceType(type, encodedFormat);
     if (hwModule == 0) {
         ALOGE("%s: could not find HW module for device %04x address %s", __FUNCTION__, type,
               address);
         return nullptr;
     }
 
-    sp<DeviceDescriptor> device = new DeviceDescriptor(type, tagName, address);
+    sp<DeviceDescriptor> device = new DeviceDescriptor(type, name, address);
     device->setName(name);
     device->setEncodedFormat(encodedFormat);
-    device->setDynamic();
-    // Add the device to the list of dynamic devices
+
+  // Add the device to the list of dynamic devices
     hwModule->addDynamicDevice(device);
     // Reciprocally attach the device to the module
     device->attach(hwModule);
@@ -400,7 +375,7 @@
     for (const auto &profile : profiles) {
         // Add the device as supported to all profile supporting "weakly" or not the device
         // according to its type
-        if (profile->supportsDevice(device, false /*matchAddress*/)) {
+        if (profile->supportsDevice(device, false /*matchAdress*/)) {
 
             // @todo quid of audio profile? import the profile from device of the same type?
             const auto &isoTypeDeviceForProfile =
@@ -431,9 +406,10 @@
 
         device->detach();
         // Only remove from dynamic list, not from declared list!!!
-        if (!hwModule->removeDynamicDevice(device)) {
+        if (!hwModule->getDynamicDevices().contains(device)) {
             return;
         }
+        hwModule->removeDynamicDevice(device);
         ALOGV("%s: removed dynamic device %s from module %s", __FUNCTION__,
               device->toString().c_str(), hwModule->getName());
 
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index 4510f63..3e42e2d 100644
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -151,7 +151,23 @@
     status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
             device_role_t role, AudioDeviceTypeAddrVector &devices) const override;
 
+    DeviceVector getActiveMediaDevices(const DeviceVector& availableDevices) const override;
+
 private:
+    /**
+     * Get media devices as the given role
+     *
+     * @param role the audio devices role
+     * @param availableDevices all available devices
+     * @param devices the DeviceVector to store devices as the given role
+     * @return NO_ERROR if all devices associated to the given role are present in available devices
+     *         NAME_NO_FOUND if there is no strategy for media or there are no devices associate to
+     *         the given role
+     *         NOT_ENOUGH_DATA if not all devices as given role are present in available devices
+     */
+    status_t getMediaDevicesForRole(device_role_t role, const DeviceVector& availableDevices,
+            DeviceVector& devices) const;
+
     AudioPolicyManagerObserver *mApmObserver = nullptr;
 
     ProductStrategyMap mProductStrategies;
diff --git a/services/audiopolicy/engine/common/include/LastRemovableMediaDevices.h b/services/audiopolicy/engine/common/include/LastRemovableMediaDevices.h
index a3053a4..d7f8b1e 100644
--- a/services/audiopolicy/engine/common/include/LastRemovableMediaDevices.h
+++ b/services/audiopolicy/engine/common/include/LastRemovableMediaDevices.h
@@ -36,6 +36,8 @@
     void setRemovableMediaDevices(sp<DeviceDescriptor> desc, audio_policy_dev_state_t state);
     std::vector<audio_devices_t> getLastRemovableMediaDevices(
             device_out_group_t group = GROUP_NONE) const;
+    sp<DeviceDescriptor> getLastRemovableMediaDevice(
+            const DeviceVector& excludedDevices, device_out_group_t group = GROUP_NONE) const;
 
 private:
     struct DeviceGroupDescriptor {
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 8c7fb97..2137dd0 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -588,6 +588,45 @@
     return NO_ERROR;
 }
 
+status_t EngineBase::getMediaDevicesForRole(device_role_t role,
+        const DeviceVector& availableDevices, DeviceVector& devices) const
+{
+    product_strategy_t strategy = getProductStrategyByName("STRATEGY_MEDIA" /*name*/);
+    if (strategy == PRODUCT_STRATEGY_NONE) {
+        strategy = getProductStrategyForStream(AUDIO_STREAM_MUSIC);
+    }
+    if (strategy == PRODUCT_STRATEGY_NONE) {
+        return NAME_NOT_FOUND;
+    }
+    AudioDeviceTypeAddrVector deviceAddrVec;
+    status_t status = getDevicesForRoleAndStrategy(strategy, role, deviceAddrVec);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    devices = availableDevices.getDevicesFromDeviceTypeAddrVec(deviceAddrVec);
+    return deviceAddrVec.size() == devices.size() ? NO_ERROR : NOT_ENOUGH_DATA;
+}
+
+DeviceVector EngineBase::getActiveMediaDevices(const DeviceVector& availableDevices) const
+{
+    // The priority of active devices as follows:
+    // 1: the available preferred devices for media
+    // 2: the latest connected removable media device that is enabled
+    DeviceVector activeDevices;
+    if (getMediaDevicesForRole(
+            DEVICE_ROLE_PREFERRED, availableDevices, activeDevices) != NO_ERROR) {
+        activeDevices.clear();
+        DeviceVector disabledDevices;
+        getMediaDevicesForRole(DEVICE_ROLE_DISABLED, availableDevices, disabledDevices);
+        sp<DeviceDescriptor> device =
+                mLastRemovableMediaDevices.getLastRemovableMediaDevice(disabledDevices);
+        if (device != nullptr) {
+            activeDevices.add(device);
+        }
+    }
+    return activeDevices;
+}
+
 void EngineBase::dump(String8 *dst) const
 {
     mProductStrategies.dump(dst, 2);
diff --git a/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp b/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp
index 96cc140..b3f8947 100644
--- a/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp
+++ b/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp
@@ -55,6 +55,17 @@
     return ret;
 }
 
+sp<DeviceDescriptor> LastRemovableMediaDevices::getLastRemovableMediaDevice(
+        const DeviceVector& excludedDevices, device_out_group_t group) const {
+    for (auto iter = mMediaDevices.begin(); iter != mMediaDevices.end(); ++iter) {
+        if ((group == GROUP_NONE || group == getDeviceOutGroup((iter->desc)->type())) &&
+                !excludedDevices.contains(iter->desc)) {
+            return iter->desc;
+        }
+    }
+    return nullptr;
+}
+
 device_out_group_t LastRemovableMediaDevices::getDeviceOutGroup(audio_devices_t device) const
 {
     switch (device) {
diff --git a/services/audiopolicy/engine/interface/EngineInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h
index f64608d..a9b536b 100644
--- a/services/audiopolicy/engine/interface/EngineInterface.h
+++ b/services/audiopolicy/engine/interface/EngineInterface.h
@@ -403,6 +403,12 @@
     virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
             device_role_t role, AudioDeviceTypeAddrVector &devices) const = 0;
 
+    /**
+     * @brief getActiveMediaDevices returns which devices will most likely to be used for media
+     * @param availableDevices all available devices
+     * @return collection of active devices
+     */
+    virtual DeviceVector getActiveMediaDevices(const DeviceVector& availableDevices) const = 0;
 
     virtual void dump(String8 *dst) const = 0;
 
diff --git a/services/audiopolicy/engineconfigurable/tools/buildCommonTypesStructureFile.py b/services/audiopolicy/engineconfigurable/tools/buildCommonTypesStructureFile.py
index f060d45..5083b14 100755
--- a/services/audiopolicy/engineconfigurable/tools/buildCommonTypesStructureFile.py
+++ b/services/audiopolicy/engineconfigurable/tools/buildCommonTypesStructureFile.py
@@ -126,9 +126,9 @@
     ignored_values = ['CNT', 'MAX', 'ALL', 'NONE']
 
     criteria_pattern = re.compile(
-        r"\s*(?P<type>(?:"+'|'.join(component_type_mapping_table.keys()) + "))_" \
-        r"(?P<literal>(?!" + '|'.join(ignored_values) + ")\w*)\s*=\s*" \
-        r"(?P<values>(?:0[xX])?[0-9a-fA-F]+)")
+        r"\s*V\((?P<type>(?:"+'|'.join(component_type_mapping_table.keys()) + "))_" \
+        r"(?P<literal>(?!" + '|'.join(ignored_values) + ")\w*)\s*,\s*" \
+        r"(?:AUDIO_DEVICE_BIT_IN \| )?(?P<values>(?:0[xX])[0-9a-fA-F]+|[0-9]+)")
 
     logging.info("Checking Android Header file {}".format(androidaudiobaseheaderFile))
 
@@ -164,6 +164,13 @@
 
             logging.debug("type:{}, literal:{}, values:{}.".format(component_type_name, component_type_literal, component_type_numerical_value))
 
+    if "stub" not in all_component_types["OutputDevicesMask"]:
+        all_component_types["OutputDevicesMask"]["stub"] = 0x40000000
+        logging.info("added stub output device mask")
+    if "stub" not in all_component_types["InputDevicesMask"]:
+        all_component_types["InputDevicesMask"]["stub"] = 0x40000000
+        logging.info("added stub input device mask")
+
     # Transform input source in inclusive criterion
     shift = len(all_component_types['OutputDevicesMask'])
     if shift > 32:
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 4a3e31f..86f4539 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -206,6 +206,9 @@
             // Reset active device codec
             device->setEncodedFormat(AUDIO_FORMAT_DEFAULT);
 
+            // remove device from mReportedFormatsMap cache
+            mReportedFormatsMap.erase(device);
+
             } break;
 
         default:
@@ -334,6 +337,9 @@
             mAvailableInputDevices.remove(device);
 
             checkInputsForDevice(device, state);
+
+            // remove device from mReportedFormatsMap cache
+            mReportedFormatsMap.erase(device);
         } break;
 
         default:
@@ -1954,6 +1960,12 @@
 
     ALOGV("releaseOutput() %d", outputDesc->mIoHandle);
 
+    sp<TrackClientDescriptor> client = outputDesc->getClient(portId);
+    if (outputDesc->isClientActive(client)) {
+        ALOGW("releaseOutput() inactivates portId %d in good faith", portId);
+        stopOutput(portId);
+    }
+
     if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
         if (outputDesc->mDirectOpenCount <= 0) {
             ALOGW("releaseOutput() invalid open count %d for output %d",
@@ -1965,9 +1977,7 @@
             mpClientInterface->onAudioPortListUpdate();
         }
     }
-    // stopOutput() needs to be successfully called before releaseOutput()
-    // otherwise there may be inaccurate stream reference counts.
-    // This is checked in outputDesc->removeClient below.
+
     outputDesc->removeClient(portId);
 }
 
@@ -3389,38 +3399,38 @@
 // This function checks for the parameters which can be offloaded.
 // This can be enhanced depending on the capability of the DSP and policy
 // of the system.
-bool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
+audio_offload_mode_t AudioPolicyManager::getOffloadSupport(const audio_offload_info_t& offloadInfo)
 {
-    ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
+    ALOGV("%s: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
      " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
-     offloadInfo.sample_rate, offloadInfo.channel_mask,
+     __func__, offloadInfo.sample_rate, offloadInfo.channel_mask,
      offloadInfo.format,
      offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
      offloadInfo.has_video);
 
     if (mMasterMono) {
-        return false; // no offloading if mono is set.
+        return AUDIO_OFFLOAD_NOT_SUPPORTED; // no offloading if mono is set.
     }
 
     // Check if offload has been disabled
     if (property_get_bool("audio.offload.disable", false /* default_value */)) {
-        ALOGV("offload disabled by audio.offload.disable");
-        return false;
+        ALOGV("%s: offload disabled by audio.offload.disable", __func__);
+        return AUDIO_OFFLOAD_NOT_SUPPORTED;
     }
 
     // Check if stream type is music, then only allow offload as of now.
     if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
     {
-        ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
-        return false;
+        ALOGV("%s: stream_type != MUSIC, returning false", __func__);
+        return AUDIO_OFFLOAD_NOT_SUPPORTED;
     }
 
     //TODO: enable audio offloading with video when ready
     const bool allowOffloadWithVideo =
             property_get_bool("audio.offload.video", false /* default_value */);
     if (offloadInfo.has_video && !allowOffloadWithVideo) {
-        ALOGV("isOffloadSupported: has_video == true, returning false");
-        return false;
+        ALOGV("%s: has_video == true, returning false", __func__);
+        return AUDIO_OFFLOAD_NOT_SUPPORTED;
     }
 
     //If duration is less than minimum value defined in property, return false
@@ -3428,13 +3438,14 @@
             "audio.offload.min.duration.secs", -1 /* default_value */);
     if (min_duration_secs >= 0) {
         if (offloadInfo.duration_us < min_duration_secs * 1000000LL) {
-            ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%d)",
-                    min_duration_secs);
-            return false;
+            ALOGV("%s: Offload denied by duration < audio.offload.min.duration.secs(=%d)",
+                    __func__, min_duration_secs);
+            return AUDIO_OFFLOAD_NOT_SUPPORTED;
         }
     } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
-        ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
-        return false;
+        ALOGV("%s: Offload denied by duration < default min(=%u)",
+                __func__, OFFLOAD_DEFAULT_MIN_DURATION_SECS);
+        return AUDIO_OFFLOAD_NOT_SUPPORTED;
     }
 
     // Do not allow offloading if one non offloadable effect is enabled. This prevents from
@@ -3444,7 +3455,7 @@
     // This may prevent offloading in rare situations where effects are left active by apps
     // in the background.
     if (mEffects.isNonOffloadableEffectEnabled()) {
-        return false;
+        return AUDIO_OFFLOAD_NOT_SUPPORTED;
     }
 
     // See if there is a profile to support this.
@@ -3455,8 +3466,14 @@
                                             offloadInfo.channel_mask,
                                             AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD,
                                             true /* directOnly */);
-    ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
-    return (profile != 0);
+    ALOGV("%s: profile %sfound", __func__, profile != 0 ? "" : "NOT ");
+    if (profile == nullptr) {
+        return AUDIO_OFFLOAD_NOT_SUPPORTED;
+    }
+    if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD) != 0) {
+        return AUDIO_OFFLOAD_GAPLESS_SUPPORTED;
+    }
+    return AUDIO_OFFLOAD_SUPPORTED;
 }
 
 bool AudioPolicyManager::isDirectOutputSupported(const audio_config_base_t& config,
@@ -3480,15 +3497,15 @@
 status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
                                             audio_port_type_t type,
                                             unsigned int *num_ports,
-                                            struct audio_port *ports,
+                                            struct audio_port_v7 *ports,
                                             unsigned int *generation)
 {
-    if (num_ports == NULL || (*num_ports != 0 && ports == NULL) ||
-            generation == NULL) {
+    if (num_ports == nullptr || (*num_ports != 0 && ports == nullptr) ||
+            generation == nullptr) {
         return BAD_VALUE;
     }
     ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports);
-    if (ports == NULL) {
+    if (ports == nullptr) {
         *num_ports = 0;
     }
 
@@ -3546,7 +3563,7 @@
     return NO_ERROR;
 }
 
-status_t AudioPolicyManager::getAudioPort(struct audio_port *port)
+status_t AudioPolicyManager::getAudioPort(struct audio_port_v7 *port)
 {
     if (port == nullptr || port->id == AUDIO_PORT_HANDLE_NONE) {
         return BAD_VALUE;
@@ -4328,14 +4345,28 @@
         // checkOutputsForDevice().
         for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
             sp<DeviceDescriptor> device = mAvailableOutputDevices[i];
-            FormatVector supportedFormats =
-                    device->getAudioPort()->getAudioProfiles().getSupportedFormats();
-            for (size_t j = 0; j < supportedFormats.size(); j++) {
-                if (mConfig.getSurroundFormats().count(supportedFormats[j]) != 0) {
-                    formats.insert(supportedFormats[j]);
+            audio_devices_t deviceType = device->type();
+            // Enabling/disabling formats are applied to only HDMI devices. So, this function
+            // returns formats reported by HDMI devices.
+            if (deviceType != AUDIO_DEVICE_OUT_HDMI) {
+                continue;
+            }
+            // Formats reported by sink devices
+            std::unordered_set<audio_format_t> formatset;
+            if (auto it = mReportedFormatsMap.find(device); it != mReportedFormatsMap.end()) {
+                formatset.insert(it->second.begin(), it->second.end());
+            }
+
+            // Formats hard-coded in the in policy configuration file (if any).
+            FormatVector encodedFormats = device->encodedFormats();
+            formatset.insert(encodedFormats.begin(), encodedFormats.end());
+            // Filter the formats which are supported by the vendor hardware.
+            for (auto it = formatset.begin(); it != formatset.end(); ++it) {
+                if (mConfig.getSurroundFormats().count(*it) != 0) {
+                    formats.insert(*it);
                 } else {
                     for (const auto& pair : mConfig.getSurroundFormats()) {
-                        if (pair.second.count(supportedFormats[j]) != 0) {
+                        if (pair.second.count(*it) != 0) {
                             formats.insert(pair.first);
                             break;
                         }
@@ -4833,7 +4864,15 @@
     }
 
     if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
-        // first list already open outputs that can be routed to this device
+        // first call getAudioPort to get the supported attributes from the HAL
+        struct audio_port_v7 port = {};
+        device->toAudioPort(&port);
+        status_t status = mpClientInterface->getAudioPort(&port);
+        if (status == NO_ERROR) {
+            device->importAudioPort(port);
+        }
+
+        // then list already open outputs that can be routed to this device
         for (size_t i = 0; i < mOutputs.size(); i++) {
             desc = mOutputs.valueAt(i);
             if (!desc->isDuplicated() && desc->supportsDevice(device)
@@ -4895,8 +4934,8 @@
                   deviceType, address.string(), profile.get(), profile->getName().c_str());
             desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
             audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-            status_t status = desc->open(nullptr, DeviceVector(device),
-                                         AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
+            status = desc->open(nullptr, DeviceVector(device),
+                                AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
 
             if (status == NO_ERROR) {
                 // Here is where the out_set_parameters() for card & device gets called
@@ -4920,9 +4959,8 @@
                     config.offload_info.channel_mask = config.channel_mask;
                     config.offload_info.format = config.format;
 
-                    status_t status = desc->open(&config, DeviceVector(device),
-                                                 AUDIO_STREAM_DEFAULT,
-                                                 AUDIO_OUTPUT_FLAG_NONE, &output);
+                    status = desc->open(&config, DeviceVector(device),
+                                        AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
                     if (status != NO_ERROR) {
                         output = AUDIO_IO_HANDLE_NONE;
                     }
@@ -4952,8 +4990,8 @@
                         // open a duplicating output thread for the new output and the primary output
                         sp<SwAudioOutputDescriptor> dupOutputDesc =
                                 new SwAudioOutputDescriptor(NULL, mpClientInterface);
-                        status_t status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
-                                                                         &duplicatedOutput);
+                        status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
+                                                                &duplicatedOutput);
                         if (status == NO_ERROR) {
                             // add duplicated output descriptor
                             addOutput(duplicatedOutput, dupOutputDesc);
@@ -6527,6 +6565,7 @@
             return;
         }
         FormatVector formats = formatsFromString(reply.string());
+        mReportedFormatsMap[devDesc] = formats;
         if (device == AUDIO_DEVICE_OUT_HDMI
                 || isDeviceOfModule(devDesc, AUDIO_HARDWARE_MODULE_ID_MSD)) {
             modifySurroundFormats(devDesc, &formats);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 217013f..00c4eab 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -225,7 +225,7 @@
         status_t dump(int fd) override;
 
         status_t setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t capturePolicy) override;
-        virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
+        virtual audio_offload_mode_t getOffloadSupport(const audio_offload_info_t& offloadInfo);
 
         virtual bool isDirectOutputSupported(const audio_config_base_t& config,
                                              const audio_attributes_t& attributes);
@@ -233,9 +233,9 @@
         virtual status_t listAudioPorts(audio_port_role_t role,
                                         audio_port_type_t type,
                                         unsigned int *num_ports,
-                                        struct audio_port *ports,
+                                        struct audio_port_v7 *ports,
                                         unsigned int *generation);
-        virtual status_t getAudioPort(struct audio_port *port);
+        virtual status_t getAudioPort(struct audio_port_v7 *port);
         virtual status_t createAudioPatch(const struct audio_patch *patch,
                                            audio_patch_handle_t *handle,
                                            uid_t uid) {
@@ -813,6 +813,9 @@
         std::unordered_set<audio_format_t> mManualSurroundFormats;
 
         std::unordered_map<uid_t, audio_flags_mask_t> mAllowedCapturePolicies;
+
+        // The map of device descriptor and formats reported by the device.
+        std::map<wp<DeviceDescriptor>, FormatVector> mReportedFormatsMap;
 private:
         void onNewAudioModulesAvailableInt(DeviceVector *newDevices);
 
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index 8a7a1b2..e823efa 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -15,6 +15,7 @@
 
     shared_libs: [
         "libaudioclient",
+        "libaudioclient_aidl_conversion",
         "libaudiofoundation",
         "libaudiopolicymanager",
         "libaudioutils",
@@ -28,6 +29,8 @@
         "libmediautils",
         "libsensorprivacy",
         "libutils",
+        "audioclient-types-aidl-unstable-cpp",
+        "audioflinger-aidl-unstable-cpp",
         "capture_state_listener-aidl-cpp",
     ],
 
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 9fa7a53..90b93e2 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -50,7 +50,22 @@
         ALOGW("%s: could not get AudioFlinger", __func__);
         return PERMISSION_DENIED;
     }
-    return af->openOutput(module, output, config, device, latencyMs, flags);
+
+    media::OpenOutputRequest request;
+    media::OpenOutputResponse response;
+
+    request.module = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_module_handle_t_int32_t(module));
+    request.config = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_config_t_AudioConfig(*config));
+    request.device = VALUE_OR_RETURN_STATUS(legacy2aidl_DeviceDescriptorBase(device));
+    request.flags = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
+
+    status_t status = af->openOutput(request, &response);
+    if (status == OK) {
+        *output = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_io_handle_t(response.output));
+        *config = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioConfig_audio_config_t(response.config));
+        *latencyMs = VALUE_OR_RETURN_STATUS(convertIntegral<uint32_t>(response.latencyMs));
+    }
+    return status;
 }
 
 audio_io_handle_t AudioPolicyService::AudioPolicyClient::openDuplicateOutput(
@@ -111,7 +126,22 @@
         return PERMISSION_DENIED;
     }
 
-    return af->openInput(module, input, config, device, address, source, flags);
+    AudioDeviceTypeAddr deviceTypeAddr(*device, address.c_str());
+
+    media::OpenInputRequest request;
+    request.module = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_module_handle_t_int32_t(module));
+    request.input = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(*input));
+    request.config = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_config_t_AudioConfig(*config));
+    request.device = VALUE_OR_RETURN_STATUS(legacy2aidl_AudioDeviceTypeAddress(deviceTypeAddr));
+    request.source = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_source_t_AudioSourceType(source));
+    request.flags = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_input_flags_t_int32_t_mask(flags));
+
+    media::OpenInputResponse response;
+    status_t status = af->openInput(request, &response);
+    if (status == OK) {
+        *input = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_module_handle_t(response.input));
+    }
+    return status;
 }
 
 status_t AudioPolicyService::AudioPolicyClient::closeInput(audio_io_handle_t input)
@@ -246,4 +276,14 @@
     mAudioPolicyService->mCaptureStateNotifier.setCaptureState(active);
 }
 
+status_t AudioPolicyService::AudioPolicyClient::getAudioPort(struct audio_port_v7 *port)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return PERMISSION_DENIED;
+    }
+    return af->getAudioPort(port);
+}
+
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index df8e4c5..517d6bf 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -547,7 +547,7 @@
 }
 
 std::string AudioPolicyService::getDeviceTypeStrForPortId(audio_port_handle_t portId) {
-    struct audio_port port = {};
+    struct audio_port_v7 port = {};
     port.id = portId;
     status_t status = mAudioPolicyManager->getAudioPort(&port);
     if (status == NO_ERROR && port.type == AUDIO_PORT_TYPE_DEVICE) {
@@ -573,7 +573,8 @@
     }
 
     // check calling permissions
-    if (!(startRecording(client->opPackageName, client->pid, client->uid)
+    if (!(startRecording(client->opPackageName, client->pid, client->uid,
+            client->attributes.source)
             || client->attributes.source == AUDIO_SOURCE_FM_TUNER)) {
         ALOGE("%s permission denied: recording not allowed for uid %d pid %d",
                 __func__, client->uid, client->pid);
@@ -661,7 +662,8 @@
         client->active = false;
         client->startTimeNs = 0;
         updateUidStates_l();
-        finishRecording(client->opPackageName, client->uid);
+        finishRecording(client->opPackageName, client->uid,
+                        client->attributes.source);
     }
 
     return status;
@@ -687,7 +689,8 @@
     updateUidStates_l();
 
     // finish the recording app op
-    finishRecording(client->opPackageName, client->uid);
+    finishRecording(client->opPackageName, client->uid,
+                    client->attributes.source);
     AutoCallerClear acc;
     return mAudioPolicyManager->stopInput(portId);
 }
@@ -1086,15 +1089,15 @@
     return mAudioPolicyManager->setAllowedCapturePolicy(uid, capturePolicy);
 }
 
-bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
+audio_offload_mode_t AudioPolicyService::getOffloadSupport(const audio_offload_info_t& info)
 {
     if (mAudioPolicyManager == NULL) {
         ALOGV("mAudioPolicyManager == NULL");
-        return false;
+        return AUDIO_OFFLOAD_NOT_SUPPORTED;
     }
     Mutex::Autolock _l(mLock);
     AutoCallerClear acc;
-    return mAudioPolicyManager->isOffloadSupported(info);
+    return mAudioPolicyManager->getOffloadSupport(info);
 }
 
 bool AudioPolicyService::isDirectOutputSupported(const audio_config_base_t& config,
@@ -1117,7 +1120,7 @@
 status_t AudioPolicyService::listAudioPorts(audio_port_role_t role,
                                             audio_port_type_t type,
                                             unsigned int *num_ports,
-                                            struct audio_port *ports,
+                                            struct audio_port_v7 *ports,
                                             unsigned int *generation)
 {
     Mutex::Autolock _l(mLock);
@@ -1128,7 +1131,7 @@
     return mAudioPolicyManager->listAudioPorts(role, type, num_ports, ports, generation);
 }
 
-status_t AudioPolicyService::getAudioPort(struct audio_port *port)
+status_t AudioPolicyService::getAudioPort(struct audio_port_v7 *port)
 {
     Mutex::Autolock _l(mLock);
     if (mAudioPolicyManager == NULL) {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 0b218c2..c032f24 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -192,16 +192,16 @@
     virtual status_t setVoiceVolume(float volume, int delayMs = 0);
     status_t setSupportedSystemUsages(const std::vector<audio_usage_t>& systemUsages);
     status_t setAllowedCapturePolicy(uint_t uid, audio_flags_mask_t capturePolicy) override;
-    virtual bool isOffloadSupported(const audio_offload_info_t &config);
+    virtual audio_offload_mode_t getOffloadSupport(const audio_offload_info_t &config);
     virtual bool isDirectOutputSupported(const audio_config_base_t& config,
                                          const audio_attributes_t& attributes);
 
     virtual status_t listAudioPorts(audio_port_role_t role,
                                     audio_port_type_t type,
                                     unsigned int *num_ports,
-                                    struct audio_port *ports,
+                                    struct audio_port_v7 *ports,
                                     unsigned int *generation);
-    virtual status_t getAudioPort(struct audio_port *port);
+    virtual status_t getAudioPort(struct audio_port_v7 *port);
     virtual status_t createAudioPatch(const struct audio_patch *patch,
                                        audio_patch_handle_t *handle);
     virtual status_t releaseAudioPatch(audio_patch_handle_t handle);
@@ -765,6 +765,8 @@
 
         void setSoundTriggerCaptureState(bool active) override;
 
+        status_t getAudioPort(struct audio_port_v7 *port) override;
+
      private:
         AudioPolicyService *mAudioPolicyService;
     };
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index ca03e1f..daedf31 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -45,6 +45,7 @@
 
 cc_test {
     name: "audio_health_tests",
+    require_root: true,
 
     shared_libs: [
         "libaudiofoundation",
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index bdddf06..433a6ff 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -121,6 +121,8 @@
 
     size_t getAudioPortListUpdateCount() const { return mAudioPortListUpdateCount; }
 
+    virtual void addSupportedFormat(audio_format_t /* format */) {}
+
 private:
     audio_module_handle_t mNextModuleHandle = AUDIO_MODULE_HANDLE_NONE + 1;
     audio_io_handle_t mNextIoHandle = AUDIO_IO_HANDLE_NONE + 1;
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClientForHdmi.h b/services/audiopolicy/tests/AudioPolicyManagerTestClientForHdmi.h
new file mode 100644
index 0000000..a5ad9b1
--- /dev/null
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClientForHdmi.h
@@ -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.
+ */
+
+#include <map>
+#include <set>
+
+#include <system/audio.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include "AudioPolicyTestClient.h"
+
+namespace android {
+
+class AudioPolicyManagerTestClientForHdmi : public AudioPolicyManagerTestClient {
+public:
+    String8 getParameters(audio_io_handle_t /* ioHandle */, const String8&  /* keys*/ ) override {
+        return mAudioParameters.toString();
+    }
+
+    void addSupportedFormat(audio_format_t format) override {
+        mAudioParameters.add(
+                String8(AudioParameter::keyStreamSupportedFormats),
+                String8(audio_format_to_string(format)));
+        mAudioParameters.addInt(String8(AudioParameter::keyStreamSupportedSamplingRates), 48000);
+        mAudioParameters.add(String8(AudioParameter::keyStreamSupportedChannels), String8(""));
+    }
+
+private:
+    AudioParameter mAudioParameters;
+};
+
+} // namespace android
\ No newline at end of file
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index c628e70..fa6b90f 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -87,6 +87,9 @@
                             audio_session_t sessionId __unused,
                             bool suspended __unused) {}
     void setSoundTriggerCaptureState(bool active __unused) override {};
+    status_t getAudioPort(struct audio_port_v7 *port __unused) override {
+        return INVALID_OPERATION;
+    };
 };
 
 } // namespace android
diff --git a/services/audiopolicy/tests/AudioPolicyTestManager.h b/services/audiopolicy/tests/AudioPolicyTestManager.h
index 8bab020..be860e5 100644
--- a/services/audiopolicy/tests/AudioPolicyTestManager.h
+++ b/services/audiopolicy/tests/AudioPolicyTestManager.h
@@ -29,6 +29,7 @@
     using AudioPolicyManager::getOutputs;
     using AudioPolicyManager::getAvailableOutputDevices;
     using AudioPolicyManager::getAvailableInputDevices;
+    using AudioPolicyManager::setSurroundFormatEnabled;
     uint32_t getAudioPortGeneration() const { return mAudioPortGeneration; }
 };
 
diff --git a/services/audiopolicy/tests/audio_health_tests.cpp b/services/audiopolicy/tests/audio_health_tests.cpp
index b5c67a1..ca2f0c6 100644
--- a/services/audiopolicy/tests/audio_health_tests.cpp
+++ b/services/audiopolicy/tests/audio_health_tests.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "AudioPolicy_Boot_Test"
 
+#include <string>
 #include <unordered_set>
 
 #include <gtest/gtest.h>
@@ -33,7 +34,7 @@
     unsigned int numPorts;
     unsigned int generation1;
     unsigned int generation;
-    struct audio_port *audioPorts = NULL;
+    struct audio_port_v7 *audioPorts = nullptr;
     int attempts = 10;
     do {
         if (attempts-- < 0) {
@@ -42,13 +43,14 @@
         }
         numPorts = 0;
         ASSERT_EQ(NO_ERROR, AudioSystem::listAudioPorts(
-                AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_DEVICE, &numPorts, NULL, &generation1));
+                AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_DEVICE, &numPorts, nullptr, &generation1));
         if (numPorts == 0) {
             free(audioPorts);
             GTEST_FAIL() << "Number of audio ports should not be zero";
         }
 
-        audioPorts = (struct audio_port *)realloc(audioPorts, numPorts * sizeof(struct audio_port));
+        audioPorts = (struct audio_port_v7 *)realloc(
+                audioPorts, numPorts * sizeof(struct audio_port_v7));
         status_t status = AudioSystem::listAudioPorts(
                 AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_DEVICE, &numPorts, audioPorts, &generation);
         if (status != NO_ERROR) {
@@ -74,3 +76,43 @@
         ASSERT_NE(attachedDevices.end(), attachedDevices.find(desc->type()));
     }
 }
+
+TEST(AudioHealthTest, ConnectSupportedDevice) {
+    AudioPolicyManagerTestClient client;
+    AudioPolicyTestManager manager(&client);
+    manager.loadConfig();
+    ASSERT_NE("AudioPolicyConfig::setDefault", manager.getConfig().getSource());
+
+    DeviceVector devices;
+    for (const auto& hwModule : manager.getConfig().getHwModules()) {
+        for (const auto& profile : hwModule->getOutputProfiles()) {
+            devices.merge(profile->getSupportedDevices());
+        }
+        for (const auto& profile : hwModule->getInputProfiles()) {
+            devices.merge(profile->getSupportedDevices());
+        }
+    }
+    for (const auto& device : devices) {
+        if (!audio_is_bluetooth_out_sco_device(device->type()) &&
+            !audio_is_bluetooth_in_sco_device(device->type())) {
+            // There are two reasons to only test connecting BT devices.
+            // 1) It is easier to construct a fake address.
+            // 2) This test will be run in presubmit. In that case, it makes sense to make the test
+            //    processing time short.
+            continue;
+        }
+        std::string address = "11:22:33:44:55:66";
+        ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+                AudioSystem::getDeviceConnectionState(device->type(), address.c_str()));
+        ASSERT_EQ(NO_ERROR, AudioSystem::setDeviceConnectionState(
+                device->type(), AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(),
+                "" /*device_name*/, AUDIO_FORMAT_DEFAULT));
+        ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+                AudioSystem::getDeviceConnectionState(device->type(), address.c_str()));
+        ASSERT_EQ(NO_ERROR, AudioSystem::setDeviceConnectionState(
+                device->type(), AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(),
+                "" /*device_name*/, AUDIO_FORMAT_DEFAULT));
+        ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+                AudioSystem::getDeviceConnectionState(device->type(), address.c_str()));
+    }
+}
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 7972dbf..889efac 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -33,6 +33,7 @@
 
 #include "AudioPolicyInterface.h"
 #include "AudioPolicyManagerTestClient.h"
+#include "AudioPolicyManagerTestClientForHdmi.h"
 #include "AudioPolicyTestClient.h"
 #include "AudioPolicyTestManager.h"
 
@@ -137,15 +138,16 @@
     // Tries to find a device port. If 'foundPort' isn't nullptr,
     // will generate a failure if the port hasn't been found.
     bool findDevicePort(audio_port_role_t role, audio_devices_t deviceType,
-            const std::string &address, audio_port *foundPort);
+            const std::string &address, audio_port_v7 *foundPort);
     static audio_port_handle_t getDeviceIdFromPatch(const struct audio_patch* patch);
+    virtual AudioPolicyManagerTestClient* getClient() { return new AudioPolicyManagerTestClient; }
 
     std::unique_ptr<AudioPolicyManagerTestClient> mClient;
     std::unique_ptr<AudioPolicyTestManager> mManager;
 };
 
 void AudioPolicyManagerTest::SetUp() {
-    mClient.reset(new AudioPolicyManagerTestClient);
+    mClient.reset(getClient());
     mManager.reset(new AudioPolicyTestManager(mClient.get()));
     SetUpManagerConfig();  // Subclasses may want to customize the config.
     ASSERT_EQ(NO_ERROR, mManager->initialize());
@@ -244,7 +246,7 @@
 }
 
 bool AudioPolicyManagerTest::findDevicePort(audio_port_role_t role,
-        audio_devices_t deviceType, const std::string &address, audio_port *foundPort) {
+        audio_devices_t deviceType, const std::string &address, audio_port_v7 *foundPort) {
     uint32_t numPorts = 0;
     uint32_t generation1;
     status_t ret;
@@ -254,7 +256,7 @@
     if (HasFailure()) return false;
 
     uint32_t generation2;
-    struct audio_port ports[numPorts];
+    struct audio_port_v7 ports[numPorts];
     ret = mManager->listAudioPorts(role, AUDIO_PORT_TYPE_DEVICE, &numPorts, ports, &generation2);
     EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
     EXPECT_EQ(generation1, generation2) << "Generations changed during ports retrieval";
@@ -668,6 +670,165 @@
     ASSERT_EQ(INVALID_OPERATION, ret);
 }
 
+class AudioPolicyManagerTestForHdmi
+        : public AudioPolicyManagerTestWithConfigurationFile {
+protected:
+    void SetUp() override;
+    std::string getConfigFile() override { return sTvConfig; }
+    std::map<audio_format_t, bool> getSurroundFormatsHelper(bool reported);
+    std::unordered_set<audio_format_t> getFormatsFromPorts();
+    AudioPolicyManagerTestClient* getClient() override {
+        return new AudioPolicyManagerTestClientForHdmi;
+    }
+    void TearDown() override;
+
+    static const std::string sTvConfig;
+
+};
+
+const std::string AudioPolicyManagerTestForHdmi::sTvConfig =
+        AudioPolicyManagerTestForHdmi::sExecutableDir +
+        "test_settop_box_surround_configuration.xml";
+
+void AudioPolicyManagerTestForHdmi::SetUp() {
+    AudioPolicyManagerTest::SetUp();
+    mClient->addSupportedFormat(AUDIO_FORMAT_E_AC3);
+    mManager->setDeviceConnectionState(
+            AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+            "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT);
+}
+
+void AudioPolicyManagerTestForHdmi::TearDown() {
+    mManager->setDeviceConnectionState(
+            AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+            "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT);
+    AudioPolicyManagerTest::TearDown();
+}
+
+std::map<audio_format_t, bool>
+        AudioPolicyManagerTestForHdmi::getSurroundFormatsHelper(bool reported) {
+    unsigned int numSurroundFormats = 0;
+    std::map<audio_format_t, bool> surroundFormatsMap;
+    status_t ret = mManager->getSurroundFormats(
+            &numSurroundFormats, nullptr /* surroundFormats */,
+            nullptr /* surroundFormatsEnabled */, reported);
+    EXPECT_EQ(NO_ERROR, ret);
+    if (ret != NO_ERROR) {
+        return surroundFormatsMap;
+    }
+    audio_format_t surroundFormats[numSurroundFormats];
+    memset(surroundFormats, 0, sizeof(audio_format_t) * numSurroundFormats);
+    bool surroundFormatsEnabled[numSurroundFormats];
+    memset(surroundFormatsEnabled, 0, sizeof(bool) * numSurroundFormats);
+    ret = mManager->getSurroundFormats(
+            &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
+    EXPECT_EQ(NO_ERROR, ret);
+    if (ret != NO_ERROR) {
+        return surroundFormatsMap;
+    }
+    for (int i = 0; i< numSurroundFormats; i++) {
+        surroundFormatsMap[surroundFormats[i]] = surroundFormatsEnabled[i];
+    }
+    return surroundFormatsMap;
+}
+
+std::unordered_set<audio_format_t>
+        AudioPolicyManagerTestForHdmi::getFormatsFromPorts() {
+    uint32_t numPorts = 0;
+    uint32_t generation1;
+    status_t ret;
+    std::unordered_set<audio_format_t> formats;
+    ret = mManager->listAudioPorts(
+            AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE, &numPorts, nullptr, &generation1);
+    EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
+    if (ret != NO_ERROR) {
+        return formats;
+    }
+    struct audio_port_v7 ports[numPorts];
+    ret = mManager->listAudioPorts(
+            AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE, &numPorts, ports, &generation1);
+    EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
+    if (ret != NO_ERROR) {
+        return formats;
+    }
+    for (const auto &port : ports) {
+        for (size_t i = 0; i < port.num_audio_profiles; ++i) {
+            formats.insert(port.audio_profiles[i].format);
+        }
+    }
+    return formats;
+}
+
+TEST_F(AudioPolicyManagerTestForHdmi, GetSurroundFormatsReturnsSupportedFormats) {
+    mManager->setForceUse(
+            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
+    auto surroundFormats = getSurroundFormatsHelper(false /*reported*/);
+    ASSERT_EQ(1, surroundFormats.count(AUDIO_FORMAT_E_AC3));
+}
+
+TEST_F(AudioPolicyManagerTestForHdmi,
+        GetSurroundFormatsReturnsManipulatedFormats) {
+    mManager->setForceUse(
+            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
+
+    status_t ret =
+            mManager->setSurroundFormatEnabled(AUDIO_FORMAT_E_AC3, false /*enabled*/);
+    ASSERT_EQ(NO_ERROR, ret);
+    auto surroundFormats = getSurroundFormatsHelper(false /*reported*/);
+    ASSERT_EQ(1, surroundFormats.count(AUDIO_FORMAT_E_AC3));
+    ASSERT_FALSE(surroundFormats[AUDIO_FORMAT_E_AC3]);
+
+    ret = mManager->setSurroundFormatEnabled(AUDIO_FORMAT_E_AC3, true /*enabled*/);
+    ASSERT_EQ(NO_ERROR, ret);
+    surroundFormats = getSurroundFormatsHelper(false /*reported*/);
+    ASSERT_EQ(1, surroundFormats.count(AUDIO_FORMAT_E_AC3));
+    ASSERT_TRUE(surroundFormats[AUDIO_FORMAT_E_AC3]);
+
+    ret = mManager->setSurroundFormatEnabled(AUDIO_FORMAT_E_AC3, false /*enabled*/);
+    ASSERT_EQ(NO_ERROR, ret);
+    surroundFormats = getSurroundFormatsHelper(false /*reported*/);
+    ASSERT_EQ(1, surroundFormats.count(AUDIO_FORMAT_E_AC3));
+    ASSERT_FALSE(surroundFormats[AUDIO_FORMAT_E_AC3]);
+}
+
+TEST_F(AudioPolicyManagerTestForHdmi,
+        ListAudioPortsReturnManipulatedHdmiFormats) {
+    mManager->setForceUse(
+            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
+
+    ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(AUDIO_FORMAT_E_AC3, false /*enabled*/));
+    auto formats = getFormatsFromPorts();
+    ASSERT_EQ(0, formats.count(AUDIO_FORMAT_E_AC3));
+
+    ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(AUDIO_FORMAT_E_AC3, true /*enabled*/));
+    formats = getFormatsFromPorts();
+    ASSERT_EQ(1, formats.count(AUDIO_FORMAT_E_AC3));
+}
+
+TEST_F(AudioPolicyManagerTestForHdmi,
+        GetReportedSurroundFormatsReturnsHdmiReportedFormats) {
+    mManager->setForceUse(
+            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
+    auto surroundFormats = getSurroundFormatsHelper(true /*reported*/);
+    ASSERT_EQ(1, surroundFormats.count(AUDIO_FORMAT_E_AC3));
+}
+
+TEST_F(AudioPolicyManagerTestForHdmi,
+        GetReportedSurroundFormatsReturnsNonManipulatedHdmiReportedFormats) {
+    mManager->setForceUse(
+            AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
+
+    status_t ret = mManager->setSurroundFormatEnabled(AUDIO_FORMAT_E_AC3, false /*enabled*/);
+    ASSERT_EQ(NO_ERROR, ret);
+    auto surroundFormats = getSurroundFormatsHelper(true /*reported*/);
+    ASSERT_EQ(1, surroundFormats.count(AUDIO_FORMAT_E_AC3));
+
+    ret = mManager->setSurroundFormatEnabled(AUDIO_FORMAT_E_AC3, true /*enabled*/);
+    ASSERT_EQ(NO_ERROR, ret);
+    surroundFormats = getSurroundFormatsHelper(true /*reported*/);
+    ASSERT_EQ(1, surroundFormats.count(AUDIO_FORMAT_E_AC3));
+}
+
 class AudioPolicyManagerTestDPNoRemoteSubmixModule : public AudioPolicyManagerTestDynamicPolicy {
 protected:
     std::string getConfigFile() override { return sPrimaryOnlyConfig; }
@@ -714,7 +875,7 @@
             {AUDIO_USAGE_ALARM, AUDIO_SOURCE_DEFAULT, RULE_MATCH_ATTRIBUTE_USAGE}
     };
 
-    struct audio_port mInjectionPort;
+    struct audio_port_v7 mInjectionPort;
     audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE;
 };
 
@@ -731,7 +892,7 @@
             AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig, mUsageRules);
     ASSERT_EQ(NO_ERROR, ret);
 
-    struct audio_port extractionPort;
+    struct audio_port_v7 extractionPort;
     ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
                     mMixAddress, &extractionPort));
 
@@ -900,7 +1061,7 @@
         {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_VOICE_COMMUNICATION, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET}
     };
 
-    struct audio_port mExtractionPort;
+    struct audio_port_v7 mExtractionPort;
     audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE;
 };
 
@@ -917,7 +1078,7 @@
             AUDIO_DEVICE_IN_REMOTE_SUBMIX, mMixAddress, audioConfig, mSourceRules);
     ASSERT_EQ(NO_ERROR, ret);
 
-    struct audio_port injectionPort;
+    struct audio_port_v7 injectionPort;
     ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
                     mMixAddress, &injectionPort));
 
@@ -1068,7 +1229,7 @@
             type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
             address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
 
-    audio_port devicePort;
+    audio_port_v7 devicePort;
     const audio_port_role_t role = audio_is_output_device(type)
             ? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
     ASSERT_TRUE(findDevicePort(role, type, address, &devicePort));
@@ -1129,7 +1290,7 @@
             flags, &output, &portId);
     sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
     ASSERT_NE(nullptr, outDesc.get());
-    audio_port port = {};
+    audio_port_v7 port = {};
     outDesc->toAudioPort(&port);
     mManager->releaseOutput(portId);
     ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
@@ -1211,7 +1372,7 @@
             findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", nullptr));
     mClient->swapAllowedModuleNames({"primary", "r_submix"});
     mManager->onNewAudioModulesAvailable();
-    struct audio_port port;
+    struct audio_port_v7 port;
     ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", &port));
 }
 
diff --git a/services/audiopolicy/tests/resources/Android.bp b/services/audiopolicy/tests/resources/Android.bp
index 4f50dad..2f6e925 100644
--- a/services/audiopolicy/tests/resources/Android.bp
+++ b/services/audiopolicy/tests/resources/Android.bp
@@ -5,5 +5,6 @@
         "test_audio_policy_primary_only_configuration.xml",
         "test_invalid_audio_policy_configuration.xml",
         "test_tv_apm_configuration.xml",
+        "test_settop_box_surround_configuration.xml",
     ],
 }
diff --git a/services/audiopolicy/tests/resources/test_settop_box_surround_configuration.xml b/services/audiopolicy/tests/resources/test_settop_box_surround_configuration.xml
new file mode 100644
index 0000000..6f7375e
--- /dev/null
+++ b/services/audiopolicy/tests/resources/test_settop_box_surround_configuration.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ 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.
+  -->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <globalConfiguration speaker_drc_enabled="false"/>
+    <modules>
+        <module name="primary" halVersion="2.0">
+            <attachedDevices>
+                <item>Stub</item>
+            </attachedDevices>
+            <defaultOutputDevice>Stub</defaultOutputDevice>
+            <mixPorts>
+                <mixPort name="primary pcm" role="source"
+                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="multichannel output" role="source"
+                         flags="AUDIO_OUTPUT_FLAG_DIRECT">
+                    <profile name="" />
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <devicePort tagName="Stub" type="AUDIO_DEVICE_OUT_STUB" role="sink" />
+                <devicePort tagName="HDMI" type="AUDIO_DEVICE_OUT_HDMI" role="sink" />
+            </devicePorts>
+            <routes>
+                <route type="mix" sink="Stub" sources="primary pcm"/>
+                <route type="mix" sink="HDMI" sources="primary pcm,multichannel output"/>
+            </routes>
+        </module>
+    </modules>
+</audioPolicyConfiguration>
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 4a36865..8cb40e0 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -69,11 +69,13 @@
         "hidl/Convert.cpp",
         "hidl/HidlCameraDeviceUser.cpp",
         "hidl/HidlCameraService.cpp",
+        "utils/CameraServiceProxyWrapper.cpp",
         "utils/CameraThreadState.cpp",
         "utils/CameraTraces.cpp",
         "utils/AutoConditionLock.cpp",
         "utils/ExifUtils.cpp",
         "utils/SessionConfigurationUtils.cpp",
+        "utils/SessionStatsBuilder.cpp",
         "utils/TagMonitor.cpp",
         "utils/LatencyHistogram.cpp",
     ],
@@ -115,7 +117,9 @@
         "android.frameworks.cameraservice.common@2.0",
         "android.frameworks.cameraservice.service@2.0",
         "android.frameworks.cameraservice.service@2.1",
+        "android.frameworks.cameraservice.service@2.2",
         "android.frameworks.cameraservice.device@2.0",
+        "android.frameworks.cameraservice.device@2.1",
         "android.hardware.camera.common@1.0",
         "android.hardware.camera.provider@2.4",
         "android.hardware.camera.provider@2.5",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 138e429..b4c0da3 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -21,6 +21,7 @@
 #include <algorithm>
 #include <climits>
 #include <stdio.h>
+#include <cstdlib>
 #include <cstring>
 #include <ctime>
 #include <string>
@@ -37,7 +38,6 @@
 #include <binder/ActivityManager.h>
 #include <binder/AppOpsManager.h>
 #include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
 #include <binder/MemoryBase.h>
 #include <binder/MemoryHeapBase.h>
 #include <binder/PermissionController.h>
@@ -75,6 +75,7 @@
 #include "utils/CameraTraces.h"
 #include "utils/TagMonitor.h"
 #include "utils/CameraThreadState.h"
+#include "utils/CameraServiceProxyWrapper.h"
 
 namespace {
     const char* kPermissionServiceName = "permission";
@@ -87,7 +88,6 @@
 using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
 using hardware::ICamera;
 using hardware::ICameraClient;
-using hardware::ICameraServiceProxy;
 using hardware::ICameraServiceListener;
 using hardware::camera::common::V1_0::CameraDeviceStatus;
 using hardware::camera::common::V1_0::TorchModeStatus;
@@ -134,9 +134,6 @@
 static constexpr int32_t kVendorClientState = 1;
 const String8 CameraService::kOfflineDevice("offline-");
 
-Mutex CameraService::sProxyMutex;
-sp<hardware::ICameraServiceProxy> CameraService::sCameraServiceProxy;
-
 CameraService::CameraService() :
         mEventLog(DEFAULT_EVENT_LOG_LENGTH),
         mNumberOfCameras(0),
@@ -178,7 +175,7 @@
 
     // This needs to be last call in this function, so that it's as close to
     // ServiceManager::addService() as possible.
-    CameraService::pingCameraServiceProxy();
+    CameraServiceProxyWrapper::pingCameraServiceProxy();
     ALOGI("CameraService pinged cameraservice proxy");
 }
 
@@ -228,29 +225,6 @@
     return OK;
 }
 
-sp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
-#ifndef __BRILLO__
-    Mutex::Autolock al(sProxyMutex);
-    if (sCameraServiceProxy == nullptr) {
-        sp<IServiceManager> sm = defaultServiceManager();
-        // Use checkService because cameraserver normally starts before the
-        // system server and the proxy service. So the long timeout that getService
-        // has before giving up is inappropriate.
-        sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
-        if (binder != nullptr) {
-            sCameraServiceProxy = interface_cast<ICameraServiceProxy>(binder);
-        }
-    }
-#endif
-    return sCameraServiceProxy;
-}
-
-void CameraService::pingCameraServiceProxy() {
-    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
-    if (proxyBinder == nullptr) return;
-    proxyBinder->pingForUserUpdate();
-}
-
 void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeStatus status) {
     Mutex::Autolock lock(mStatusListenerLock);
 
@@ -1573,7 +1547,11 @@
             "Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
             static_cast<int>(effectiveApiLevel));
 
+    nsecs_t openTimeNs = systemTime();
+
     sp<CLIENT> client = nullptr;
+    int facing = -1;
+    bool isNdk = (clientPackageName.size() == 0);
     {
         // Acquire mServiceLock and prevent other clients from connecting
         std::unique_ptr<AutoConditionLock> lock =
@@ -1638,7 +1616,6 @@
         // give flashlight a chance to close devices if necessary.
         mFlashlight->prepareDeviceOpen(cameraId);
 
-        int facing = -1;
         int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);
         if (facing == -1) {
             ALOGE("%s: Unable to get camera device \"%s\"  facing", __FUNCTION__, cameraId.string());
@@ -1718,11 +1695,18 @@
             // Otherwise, add client to active clients list
             finishConnectLocked(client, partial);
         }
+
+        client->setImageDumpMask(mImageDumpMask);
     } // lock is destroyed, allow further connect calls
 
     // Important: release the mutex here so the client can call back into the service from its
     // destructor (can be at the end of the call)
     device = client;
+
+    int32_t openLatencyMs = ns2ms(systemTime() - openTimeNs);
+    CameraServiceProxyWrapper::logOpen(cameraId, facing, clientPackageName,
+            effectiveApiLevel, isNdk, openLatencyMs);
+
     return ret;
 }
 
@@ -2880,14 +2864,6 @@
     // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
     sCameraService->updateStatus(StatusInternal::NOT_AVAILABLE, mCameraIdStr);
 
-    int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
-    if (canCastToApiClient(API_2)) {
-        apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
-    }
-    // Transition device state to OPEN
-    sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
-            mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
-
     sCameraService->mUidPolicy->registerMonitorUid(mClientUid);
 
     // Notify listeners of camera open/close status
@@ -2916,14 +2892,6 @@
         // Transition to PRESENT if the camera is not in either of the rejected states
         sCameraService->updateStatus(StatusInternal::PRESENT,
                 mCameraIdStr, rejected);
-
-        int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
-        if (canCastToApiClient(API_2)) {
-            apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
-        }
-        // Transition device state to CLOSED
-        sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
-                mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
     }
     // Always stop watching, even if no camera op is active
     if (mOpsCallback != nullptr && mAppOpsManager != nullptr) {
@@ -3803,14 +3771,6 @@
     onStatusUpdatedLocked(cameraId, status);
 }
 
-void CameraService::updateProxyDeviceState(int newState,
-        const String8& cameraId, int facing, const String16& clientName, int apiLevel) {
-    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
-    if (proxyBinder == nullptr) return;
-    String16 id(cameraId);
-    proxyBinder->notifyCameraState(id, newState, facing, clientName, apiLevel);
-}
-
 status_t CameraService::getTorchStatusLocked(
         const String8& cameraId,
         TorchModeStatus *status) const {
@@ -3923,6 +3883,10 @@
         return handleSetRotateAndCrop(args);
     } else if (args.size() >= 1 && args[0] == String16("get-rotate-and-crop")) {
         return handleGetRotateAndCrop(out);
+    } else if (args.size() >= 2 && args[0] == String16("set-image-dump-mask")) {
+        return handleSetImageDumpMask(args);
+    } else if (args.size() >= 1 && args[0] == String16("get-image-dump-mask")) {
+        return handleGetImageDumpMask(out);
     } else if (args.size() == 1 && args[0] == String16("help")) {
         printHelp(out);
         return NO_ERROR;
@@ -4022,6 +3986,30 @@
     return dprintf(out, "rotateAndCrop override: %d\n", mOverrideRotateAndCropMode);
 }
 
+status_t CameraService::handleSetImageDumpMask(const Vector<String16>& args) {
+    char *endPtr;
+    errno = 0;
+    String8 maskString8 = String8(args[1]);
+    long maskValue = strtol(maskString8.c_str(), &endPtr, 10);
+
+    if (errno != 0) return BAD_VALUE;
+    if (endPtr != maskString8.c_str() + maskString8.size()) return BAD_VALUE;
+    if (maskValue < 0 || maskValue > 1) return BAD_VALUE;
+
+    Mutex::Autolock lock(mServiceLock);
+
+    mImageDumpMask = maskValue;
+
+    return OK;
+}
+
+status_t CameraService::handleGetImageDumpMask(int out) {
+    Mutex::Autolock lock(mServiceLock);
+
+    return dprintf(out, "Image dump mask: %d\n", mImageDumpMask);
+}
+
+
 status_t CameraService::printHelp(int out) {
     return dprintf(out, "Camera service commands:\n"
         "  get-uid-state <PACKAGE> [--user USER_ID] gets the uid state\n"
@@ -4030,6 +4018,9 @@
         "  set-rotate-and-crop <ROTATION> overrides the rotate-and-crop value for AUTO backcompat\n"
         "      Valid values 0=0 deg, 1=90 deg, 2=180 deg, 3=270 deg, 4=No override\n"
         "  get-rotate-and-crop returns the current override rotate-and-crop value\n"
+        "  set-image-dump-mask <MASK> specifies the formats to be saved to disk\n"
+        "      Valid values 0=OFF, 1=ON for JPEG\n"
+        "  get-image-dump-mask returns the current image-dump-mask value\n"
         "  help print this message\n");
 }
 
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 6f37e9f..43b03e6 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -20,7 +20,6 @@
 #include <android/hardware/BnCameraService.h>
 #include <android/hardware/BnSensorPrivacyListener.h>
 #include <android/hardware/ICameraServiceListener.h>
-#include <android/hardware/ICameraServiceProxy.h>
 
 #include <cutils/multiuser.h>
 #include <utils/Vector.h>
@@ -211,16 +210,6 @@
     void                loadSoundLocked(sound_kind kind);
     void                decreaseSoundRef();
     void                increaseSoundRef();
-    /**
-     * Update the state of a given camera device (open/close/active/idle) with
-     * the camera proxy service in the system service
-     */
-    static void         updateProxyDeviceState(
-            int newState,
-            const String8& cameraId,
-            int facing,
-            const String16& clientName,
-            int apiLevel);
 
     /////////////////////////////////////////////////////////////////////
     // CameraDeviceFactory functionality
@@ -409,6 +398,8 @@
         // Check what API level is used for this client. This is used to determine which
         // superclass this can be cast to.
         virtual bool canCastToApiClient(apiLevel level) const;
+
+        void setImageDumpMask(int /*mask*/) { }
     protected:
         // Initialized in constructor
 
@@ -1047,6 +1038,12 @@
     // Get the rotate-and-crop AUTO override behavior
     status_t handleGetRotateAndCrop(int out);
 
+    // Set the mask for image dump to disk
+    status_t handleSetImageDumpMask(const Vector<String16>& args);
+
+    // Get the mask for image dump to disk
+    status_t handleGetImageDumpMask(int out);
+
     // Prints the shell command help
     status_t printHelp(int out);
 
@@ -1069,13 +1066,6 @@
     static StatusInternal mapToInternal(hardware::camera::common::V1_0::CameraDeviceStatus status);
     static int32_t mapToInterface(StatusInternal status);
 
-    // Guard mCameraServiceProxy
-    static Mutex sProxyMutex;
-    // Cached interface to the camera service proxy in system service
-    static sp<hardware::ICameraServiceProxy> sCameraServiceProxy;
-
-    static sp<hardware::ICameraServiceProxy> getCameraServiceProxy();
-    static void pingCameraServiceProxy();
 
     void broadcastTorchModeStatus(const String8& cameraId,
             hardware::camera::common::V1_0::TorchModeStatus status);
@@ -1095,6 +1085,9 @@
 
     // Current override rotate-and-crop mode
     uint8_t mOverrideRotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_AUTO;
+
+    // Current image dump mask
+    uint8_t mImageDumpMask = 0;
 };
 
 } // namespace android
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 09e2c3f..662b58f 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -34,6 +34,7 @@
 #include "api1/client2/CallbackProcessor.h"
 #include "api1/client2/ZslProcessor.h"
 #include "utils/CameraThreadState.h"
+#include "utils/CameraServiceProxyWrapper.h"
 
 #define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
 #define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
@@ -396,6 +397,7 @@
 
 binder::Status Camera2Client::disconnect() {
     ATRACE_CALL();
+    nsecs_t startTime = systemTime();
     Mutex::Autolock icl(mBinderSerializationLock);
 
     binder::Status res = binder::Status::ok();
@@ -457,6 +459,9 @@
 
     CameraService::Client::disconnect();
 
+    int32_t closeLatencyMs = ns2ms(systemTime() - startTime);
+    CameraServiceProxyWrapper::logClose(mCameraIdStr, closeLatencyMs);
+
     return res;
 }
 
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
index 8dc9863..8753dcf 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
@@ -172,7 +172,7 @@
     mBufferQueueDepth = mFrameListDepth + 1;
 
     mZslQueue.insertAt(0, mBufferQueueDepth);
-    mFrameList.insertAt(0, mFrameListDepth);
+    mFrameList.resize(mFrameListDepth);
     sp<CaptureSequencer> captureSequencer = mSequencer.promote();
     if (captureSequencer != 0) captureSequencer->setZslProcessor(this);
 }
@@ -208,7 +208,7 @@
     // Corresponding buffer has been cleared. No need to push into mFrameList
     if (timestamp <= mLatestClearedBufferTimestamp) return;
 
-    mFrameList.editItemAt(mFrameListHead) = result.mMetadata;
+    mFrameList[mFrameListHead] = result.mMetadata;
     mFrameListHead = (mFrameListHead + 1) % mFrameListDepth;
 }
 
@@ -671,7 +671,7 @@
 void ZslProcessor::clearZslResultQueueLocked() {
     mFrameList.clear();
     mFrameListHead = 0;
-    mFrameList.insertAt(0, mFrameListDepth);
+    mFrameList.resize(mFrameListDepth);
 }
 
 void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.h b/services/camera/libcameraservice/api1/client2/ZslProcessor.h
index 1db2403..3186233 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.h
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.h
@@ -125,7 +125,7 @@
     static const int32_t kDefaultMaxPipelineDepth = 4;
     size_t mBufferQueueDepth;
     size_t mFrameListDepth;
-    Vector<CameraMetadata> mFrameList;
+    std::vector<CameraMetadata> mFrameList;
     size_t mFrameListHead;
 
     ZslPair mNextPair;
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index e80838b..66eda5d 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -31,6 +31,7 @@
 #include "device3/Camera3Device.h"
 #include "device3/Camera3OutputStream.h"
 #include "api2/CameraDeviceClient.h"
+#include "utils/CameraServiceProxyWrapper.h"
 
 #include <camera_metadata_hidden.h>
 
@@ -471,7 +472,7 @@
 }
 
 binder::Status CameraDeviceClient::endConfigure(int operatingMode,
-        const hardware::camera2::impl::CameraMetadataNative& sessionParams,
+        const hardware::camera2::impl::CameraMetadataNative& sessionParams, int64_t startTimeMs,
         std::vector<int>* offlineStreamIds /*out*/) {
     ATRACE_CALL();
     ALOGV("%s: ending configure (%d input stream, %zu output surfaces)",
@@ -547,6 +548,11 @@
         for (const auto& offlineStreamId : *offlineStreamIds) {
             mStreamInfoMap[offlineStreamId].supportsOffline = true;
         }
+
+        nsecs_t configureEnd = systemTime();
+        int32_t configureDurationMs = ns2ms(configureEnd) - startTimeMs;
+        CameraServiceProxyWrapper::logStreamConfigured(mCameraIdStr, operatingMode,
+                false /*internalReconfig*/, configureDurationMs);
     }
 
     return res;
@@ -1708,14 +1714,16 @@
     mStreamingRequestId = REQUEST_ID_NONE;
 }
 
-void CameraDeviceClient::notifyIdle() {
+void CameraDeviceClient::notifyIdle(
+        int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+        const std::vector<hardware::CameraStreamStats>& streamStats) {
     // Thread safe. Don't bother locking.
     sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
 
     if (remoteCb != 0) {
         remoteCb->onDeviceIdle();
     }
-    Camera2ClientBase::notifyIdle();
+    Camera2ClientBase::notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
 }
 
 void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
@@ -1751,6 +1759,7 @@
 void CameraDeviceClient::detachDevice() {
     if (mDevice == 0) return;
 
+    nsecs_t startTime = systemTime();
     ALOGV("Camera %s: Stopping processors", mCameraIdStr.string());
 
     mFrameProcessor->removeListener(camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MIN_ID,
@@ -1785,6 +1794,9 @@
     mCompositeStreamMap.clear();
 
     Camera2ClientBase::detachDevice();
+
+    int32_t closeLatencyMs = ns2ms(systemTime() - startTime);
+    CameraServiceProxyWrapper::logClose(mCameraIdStr, closeLatencyMs);
 }
 
 /** Device-related methods */
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 2807aee..3f72eca 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -95,6 +95,7 @@
 
     virtual binder::Status endConfigure(int operatingMode,
             const hardware::camera2::impl::CameraMetadataNative& sessionParams,
+            int64_t startTimeMs,
             /*out*/
             std::vector<int>* offlineStreamIds) override;
 
@@ -196,7 +197,8 @@
      * Device listener interface
      */
 
-    virtual void notifyIdle();
+    virtual void notifyIdle(int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+                            const std::vector<hardware::CameraStreamStats>& streamStats);
     virtual void notifyError(int32_t errorCode,
                              const CaptureResultExtras& resultExtras);
     virtual void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp);
@@ -204,6 +206,7 @@
     virtual void notifyRequestQueueEmpty();
     virtual void notifyRepeatingRequestError(long lastFrameNumber);
 
+    void setImageDumpMask(int mask) { if (mDevice != nullptr) mDevice->setImageDumpMask(mask); }
     /**
      * Interface used by independent components of CameraDeviceClient.
      */
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 237c24b..62b5479 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -265,7 +265,9 @@
     }
 }
 
-void CameraOfflineSessionClient::notifyIdle() {
+void CameraOfflineSessionClient::notifyIdle(
+        int64_t /*requestCount*/, int64_t /*resultErrorCount*/, bool /*deviceError*/,
+        const std::vector<hardware::CameraStreamStats>& /*streamStats*/) {
     if (mRemoteCallback.get() != nullptr) {
         mRemoteCallback->onDeviceIdle();
     }
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index 03621c8..839c435 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -86,7 +86,8 @@
     // NotificationListener API
     void notifyError(int32_t errorCode, const CaptureResultExtras& resultExtras) override;
     void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp) override;
-    void notifyIdle() override;
+    void notifyIdle(int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+            const std::vector<hardware::CameraStreamStats>& streamStats) override;
     void notifyAutoFocus(uint8_t newState, int triggerId) override;
     void notifyAutoExposure(uint8_t newState, int triggerId) override;
     void notifyAutoWhitebalance(uint8_t newState, int triggerId) override;
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 4fe5adf..a7173d1 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -65,7 +65,6 @@
         mYuvBufferAcquired(false),
         mProducerListener(new ProducerListener()),
         mDequeuedOutputBufferCnt(0),
-        mLockedAppSegmentBufferCnt(0),
         mCodecOutputCounter(0),
         mQuality(-1),
         mGridTimestampUs(0),
@@ -635,7 +634,6 @@
             mAppSegmentConsumer->unlockBuffer(imgBuffer);
         } else {
             mPendingInputFrames[frameNumber].appSegmentBuffer = imgBuffer;
-            mLockedAppSegmentBufferCnt++;
         }
         mInputAppSegmentBuffers.erase(it);
         mAppSegmentFrameNumbers.pop();
@@ -898,10 +896,6 @@
                         strerror(-res), res);
                 return res;
             }
-        } else if (mLockedAppSegmentBufferCnt == kMaxAcquiredAppSegment) {
-            ALOGE("%s: Out-of-order app segment buffers reaches limit %u", __FUNCTION__,
-                    kMaxAcquiredAppSegment);
-            return INVALID_OPERATION;
         }
     }
 
@@ -1039,7 +1033,6 @@
     mAppSegmentConsumer->unlockBuffer(inputFrame.appSegmentBuffer);
     inputFrame.appSegmentBuffer.data = nullptr;
     inputFrame.exifError = false;
-    mLockedAppSegmentBufferCnt--;
 
     return OK;
 }
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.h b/services/camera/libcameraservice/api2/HeicCompositeStream.h
index 33ca69a..a373127 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.h
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.h
@@ -253,7 +253,6 @@
 
     // Keep all incoming APP segment Blob buffer pending further processing.
     std::vector<int64_t> mInputAppSegmentBuffers;
-    int32_t           mLockedAppSegmentBufferCnt;
 
     // Keep all incoming HEIC blob buffer pending further processing.
     std::vector<CodecOutputBufferInfo> mCodecOutputBuffers;
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 609698c..6fd8d45 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -27,12 +27,15 @@
 #include <gui/Surface.h>
 #include <gui/Surface.h>
 
+#include <camera/CameraSessionStats.h>
+
 #include "common/Camera2ClientBase.h"
 
 #include "api2/CameraDeviceClient.h"
 
 #include "device3/Camera3Device.h"
 #include "utils/CameraThreadState.h"
+#include "utils/CameraServiceProxyWrapper.h"
 
 namespace android {
 using namespace camera2;
@@ -194,7 +197,7 @@
 
     CameraService::BasicClient::disconnect();
 
-    ALOGV("Camera %s: Shut down complete complete", TClientBase::mCameraIdStr.string());
+    ALOGV("Camera %s: Shut down complete", TClientBase::mCameraIdStr.string());
 
     return res;
 }
@@ -245,13 +248,12 @@
 }
 
 template <typename TClientBase>
-void Camera2ClientBase<TClientBase>::notifyIdle() {
+void Camera2ClientBase<TClientBase>::notifyIdle(
+        int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+        const std::vector<hardware::CameraStreamStats>& streamStats) {
     if (mDeviceActive) {
-        getCameraService()->updateProxyDeviceState(
-            hardware::ICameraServiceProxy::CAMERA_STATE_IDLE, TClientBase::mCameraIdStr,
-            TClientBase::mCameraFacing, TClientBase::mClientPackageName,
-            ((mApi1CameraId < 0) ? hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2 :
-             hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1));
+        CameraServiceProxyWrapper::logIdle(TClientBase::mCameraIdStr,
+                requestCount, resultErrorCount, deviceError, streamStats);
     }
     mDeviceActive = false;
 
@@ -265,11 +267,7 @@
     (void)timestamp;
 
     if (!mDeviceActive) {
-        getCameraService()->updateProxyDeviceState(
-            hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE, TClientBase::mCameraIdStr,
-            TClientBase::mCameraFacing, TClientBase::mClientPackageName,
-            ((mApi1CameraId < 0) ? hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2 :
-             hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1));
+        CameraServiceProxyWrapper::logActive(TClientBase::mCameraIdStr);
     }
     mDeviceActive = true;
 
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index d7506af..1ce4393 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -66,7 +66,9 @@
 
     virtual void          notifyError(int32_t errorCode,
                                       const CaptureResultExtras& resultExtras);
-    virtual void          notifyIdle();
+    virtual void          notifyIdle(int64_t requestCount, int64_t resultErrorCount,
+                                     bool deviceError,
+                                     const std::vector<hardware::CameraStreamStats>& streamStats);
     virtual void          notifyShutter(const CaptureResultExtras& resultExtras,
                                         nsecs_t timestamp);
     virtual void          notifyAutoFocus(uint8_t newState, int triggerId);
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index a537ef5..77e660f 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -367,6 +367,14 @@
      * Get the status tracker of the camera device
      */
     virtual wp<camera3::StatusTracker> getStatusTracker() = 0;
+
+    /**
+     * Set bitmask for image dump flag
+     */
+    void setImageDumpMask(int mask) { mImageDumpMask = mask; }
+
+protected:
+    bool mImageDumpMask = 0;
 };
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/common/CameraOfflineSessionBase.h b/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
index 1f835a9..e02e146 100644
--- a/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
+++ b/services/camera/libcameraservice/common/CameraOfflineSessionBase.h
@@ -17,11 +17,14 @@
 #ifndef ANDROID_SERVERS_CAMERA_CAMERAOFFLINESESSIONBASE_H
 #define ANDROID_SERVERS_CAMERA_CAMERAOFFLINESESSIONBASE_H
 
+#include <vector>
+
 #include <utils/RefBase.h>
 #include <utils/String8.h>
 #include <utils/Timers.h>
 
 #include "camera/CaptureResult.h"
+#include "camera/CameraSessionStats.h"
 #include "FrameProducer.h"
 
 namespace android {
@@ -39,7 +42,8 @@
                              const CaptureResultExtras &resultExtras) = 0;
 
     // Required only for API2
-    virtual void notifyIdle() = 0;
+    virtual void notifyIdle(int64_t requestCount, int64_t resultError, bool deviceError,
+            const std::vector<hardware::CameraStreamStats>& streamStats) = 0;
     virtual void notifyShutter(const CaptureResultExtras &resultExtras,
             nsecs_t timestamp) = 0;
     virtual void notifyPrepared(int streamId) = 0;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index d27f11f..8754ad3 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -61,6 +61,7 @@
 #include "CameraService.h"
 #include "utils/CameraThreadState.h"
 #include "utils/TraceHFR.h"
+#include "utils/CameraServiceProxyWrapper.h"
 
 #include <algorithm>
 #include <tuple>
@@ -867,7 +868,7 @@
 status_t Camera3Device::convertMetadataListToRequestListLocked(
         const List<const PhysicalCameraSettingsList> &metadataList,
         const std::list<const SurfaceMap> &surfaceMaps,
-        bool repeating,
+        bool repeating, nsecs_t requestTimeNs,
         RequestList *requestList) {
     if (requestList == NULL) {
         CLOGE("requestList cannot be NULL.");
@@ -886,6 +887,7 @@
         }
 
         newRequest->mRepeating = repeating;
+        newRequest->mRequestTimeNs = requestTimeNs;
 
         // Setup burst Id and request Id
         newRequest->mResultExtras.burstId = burstId++;
@@ -953,6 +955,8 @@
         /*out*/
         int64_t *lastFrameNumber) {
     ATRACE_CALL();
+    nsecs_t requestTimeNs = systemTime();
+
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
@@ -965,7 +969,7 @@
     RequestList requestList;
 
     res = convertMetadataListToRequestListLocked(requests, surfaceMaps,
-            repeating, /*out*/&requestList);
+            repeating, requestTimeNs, /*out*/&requestList);
     if (res != OK) {
         // error logged by previous call
         return res;
@@ -997,7 +1001,7 @@
         const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
         requestStreamBuffers_cb _hidl_cb) {
     RequestBufferStates states {
-        mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams,
+        mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
         *this, *mInterface, *this};
     camera3::requestStreamBuffers(states, bufReqs, _hidl_cb);
     return hardware::Void();
@@ -1006,7 +1010,7 @@
 hardware::Return<void> Camera3Device::returnStreamBuffers(
         const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
     ReturnBufferStates states {
-        mId, mUseHalBufManager, mOutputStreams, *mInterface};
+        mId, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder, *mInterface};
     camera3::returnStreamBuffers(states, buffers);
     return hardware::Void();
 }
@@ -1054,7 +1058,8 @@
         mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
         mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
         mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
-        mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, *mInterface
+        mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+        *mInterface
     };
 
     for (const auto& result : results) {
@@ -1112,7 +1117,8 @@
         mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
         mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
         mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
-        mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, *mInterface
+        mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+        *mInterface
     };
 
     for (const auto& result : results) {
@@ -1152,7 +1158,8 @@
         mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
         mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
         mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
-        mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, *mInterface
+        mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+        *mInterface
     };
     for (const auto& msg : msgs) {
         camera3::notify(states, msg);
@@ -1449,12 +1456,16 @@
 
     newStream->setBufferManager(mBufferManager);
 
+    newStream->setImageDumpMask(mImageDumpMask);
+
     res = mOutputStreams.add(mNextStreamId, newStream);
     if (res < 0) {
         SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
         return res;
     }
 
+    mSessionStatsBuilder.addStream(mNextStreamId);
+
     *id = mNextStreamId++;
     mNeedConfig = true;
 
@@ -1578,6 +1589,7 @@
             CLOGE("Stream %d does not exist", id);
             return BAD_VALUE;
         }
+        mSessionStatsBuilder.removeStream(id);
     }
 
     // Delete output stream or the output part of a bi-directional stream.
@@ -2010,6 +2022,9 @@
         }
 
         mRequestThread->clear(/*out*/frameNumber);
+
+        // Stop session and stream counter
+        mSessionStatsBuilder.stopCounter();
     }
 
     return mRequestThread->flush();
@@ -2087,6 +2102,9 @@
 
 void Camera3Device::notifyStatus(bool idle) {
     ATRACE_CALL();
+    std::vector<int> streamIds;
+    std::vector<hardware::CameraStreamStats> streamStats;
+
     {
         // Need mLock to safely update state and synchronize to current
         // state of methods in flight.
@@ -2104,6 +2122,24 @@
         // Skip notifying listener if we're doing some user-transparent
         // state changes
         if (mPauseStateNotify) return;
+
+        // Populate stream statistics in case of Idle
+        if (idle) {
+            for (size_t i = 0; i < mOutputStreams.size(); i++) {
+                auto stream = mOutputStreams[i];
+                if (stream.get() == nullptr) continue;
+                streamIds.push_back(stream->getId());
+                Camera3Stream* camera3Stream = Camera3Stream::cast(stream->asHalStream());
+                int64_t usage = 0LL;
+                if (camera3Stream != nullptr) {
+                    usage = camera3Stream->getUsage();
+                }
+                streamStats.emplace_back(stream->getWidth(), stream->getHeight(),
+                    stream->getFormat(), stream->getDataSpace(), usage,
+                    stream->getMaxHalBuffers(),
+                    stream->getMaxTotalBuffers() - stream->getMaxHalBuffers());
+            }
+        }
     }
 
     sp<NotificationListener> listener;
@@ -2112,7 +2148,22 @@
         listener = mListener.promote();
     }
     if (idle && listener != NULL) {
-        listener->notifyIdle();
+        // Get session stats from the builder, and notify the listener.
+        int64_t requestCount, resultErrorCount;
+        bool deviceError;
+        std::map<int, StreamStats> streamStatsMap;
+        mSessionStatsBuilder.buildAndReset(&requestCount, &resultErrorCount,
+                &deviceError, &streamStatsMap);
+        for (size_t i = 0; i < streamIds.size(); i++) {
+            int streamId = streamIds[i];
+            auto stats = streamStatsMap.find(streamId);
+            if (stats != streamStatsMap.end()) {
+                streamStats[i].mRequestCount = stats->second.mRequestedFrameCount;
+                streamStats[i].mErrorCount = stats->second.mDroppedFrameCount;
+                streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs;
+            }
+        }
+        listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
     }
 }
 
@@ -2222,6 +2273,12 @@
         ALOGE("%s: Stream %d is not found.", __FUNCTION__, streamId);
         return BAD_VALUE;
     }
+
+    if (dropping) {
+        mSessionStatsBuilder.stopCounter(streamId);
+    } else {
+        mSessionStatsBuilder.startCounter(streamId);
+    }
     return stream->dropBuffers(dropping);
 }
 
@@ -2376,6 +2433,8 @@
     ATRACE_CALL();
     bool ret = false;
 
+    nsecs_t startTime = systemTime();
+
     Mutex::Autolock il(mInterfaceLock);
     nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
 
@@ -2423,6 +2482,9 @@
         ALOGE("%s: Failed to pause streaming: %d", __FUNCTION__, rc);
     }
 
+    CameraServiceProxyWrapper::logStreamConfigured(mId, mOperatingMode, true /*internalReconfig*/,
+        ns2ms(systemTime() - startTime));
+
     if (markClientActive) {
         mStatusTracker->markComponentActive(clientStatusId);
     }
@@ -2776,6 +2838,7 @@
     if (listener != NULL) {
         listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
                 CaptureResultExtras());
+        mSessionStatsBuilder.onDeviceError();
     }
 
     // Save stack trace. View by dumping it later.
@@ -2792,14 +2855,14 @@
         bool hasAppCallback, nsecs_t maxExpectedDuration,
         std::set<String8>& physicalCameraIds, bool isStillCapture,
         bool isZslCapture, bool rotateAndCropAuto, const std::set<std::string>& cameraIdsWithZoom,
-        const SurfaceMap& outputSurfaces) {
+        const SurfaceMap& outputSurfaces, nsecs_t requestTimeNs) {
     ATRACE_CALL();
     std::lock_guard<std::mutex> l(mInFlightLock);
 
     ssize_t res;
     res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
             hasAppCallback, maxExpectedDuration, physicalCameraIds, isStillCapture, isZslCapture,
-            rotateAndCropAuto, cameraIdsWithZoom, outputSurfaces));
+            rotateAndCropAuto, cameraIdsWithZoom, requestTimeNs, outputSurfaces));
     if (res < 0) return res;
 
     if (mInFlightMap.size() == 1) {
@@ -2869,7 +2932,7 @@
 
     FlushInflightReqStates states {
         mId, mInFlightLock, mInFlightMap, mUseHalBufManager,
-        listener, *this, *mInterface, *this};
+        listener, *this, *mInterface, *this, mSessionStatsBuilder};
 
     camera3::flushInflightRequests(states);
 }
@@ -3778,6 +3841,7 @@
         mInterface(interface),
         mListener(nullptr),
         mId(getId(parent)),
+        mFirstRepeating(false),
         mReconfigured(false),
         mDoPause(false),
         mPaused(true),
@@ -3908,6 +3972,7 @@
         *lastFrameNumber = mRepeatingLastFrameNumber;
     }
     mRepeatingRequests.clear();
+    mFirstRepeating = true;
     mRepeatingRequests.insert(mRepeatingRequests.begin(),
             requests.begin(), requests.end());
 
@@ -4697,7 +4762,7 @@
                 requestedPhysicalCameras, isStillCapture, isZslCapture,
                 captureRequest->mRotateAndCropAuto, mPrevCameraIdsWithZoom,
                 (mUseHalBufManager) ? uniqueSurfaceIdMap :
-                                      SurfaceMap{});
+                                      SurfaceMap{}, captureRequest->mRequestTimeNs);
         ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
                ", burstId = %" PRId32 ".",
                 __FUNCTION__,
@@ -5019,6 +5084,17 @@
             // list. Guarantees a complete in-sequence set of captures to
             // application.
             const RequestList &requests = mRepeatingRequests;
+            if (mFirstRepeating) {
+                mFirstRepeating = false;
+            } else {
+                for (auto& request : requests) {
+                    // For repeating requests, override timestamp request using
+                    // the time a request is inserted into the request queue,
+                    // because the original repeating request will have an old
+                    // fixed timestamp.
+                    request->mRequestTimeNs = systemTime();
+                }
+            }
             RequestList::const_iterator firstRequest =
                     requests.begin();
             nextRequest = *firstRequest;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index c579071..de7df81 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -471,6 +471,8 @@
 
     camera3::StreamSet         mOutputStreams;
     sp<camera3::Camera3Stream> mInputStream;
+    SessionStatsBuilder        mSessionStatsBuilder;
+
     int                        mNextStreamId;
     bool                       mNeedConfig;
 
@@ -520,6 +522,8 @@
         // Whether this capture request has its zoom ratio set to 1.0x before
         // the framework overrides it for camera HAL consumption.
         bool                                mZoomRatioIs1x;
+        // The systemTime timestamp when the request is created.
+        nsecs_t                             mRequestTimeNs;
 
 
         // Whether this capture request's distortion correction update has
@@ -538,7 +542,7 @@
     status_t convertMetadataListToRequestListLocked(
             const List<const PhysicalCameraSettingsList> &metadataList,
             const std::list<const SurfaceMap> &surfaceMaps,
-            bool repeating,
+            bool repeating, nsecs_t requestTimeNs,
             /*out*/
             RequestList *requestList);
 
@@ -961,6 +965,7 @@
         Condition          mRequestSubmittedSignal;
         RequestList        mRequestQueue;
         RequestList        mRepeatingRequests;
+        bool               mFirstRepeating;
         // The next batch of requests being prepped for submission to the HAL, no longer
         // on the request queue. Read-only even with mRequestLock held, outside
         // of threadLoop
@@ -1035,7 +1040,8 @@
             int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
             bool callback, nsecs_t maxExpectedDuration, std::set<String8>& physicalCameraIds,
             bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto,
-            const std::set<std::string>& cameraIdsWithZoom, const SurfaceMap& outputSurfaces);
+            const std::set<std::string>& cameraIdsWithZoom, const SurfaceMap& outputSurfaces,
+            nsecs_t requestTimeNs);
 
     /**
      * Tracking for idle detection
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index 448379c..ca62239 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -48,6 +48,7 @@
 
     virtual void     dump(int fd, const Vector<String16> &args) const;
 
+    int              getMaxTotalBuffers() const { return mTotalBufferCount; }
   protected:
     size_t            mTotalBufferCount;
     // sum of input and output buffers that are currently acquired by HAL
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
index 95f9633..a7e64ce 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
@@ -176,7 +176,7 @@
 
     FlushInflightReqStates states {
         mId, mOfflineReqsLock, mOfflineReqs, mUseHalBufManager,
-        listener, *this, mBufferRecords, *this};
+        listener, *this, mBufferRecords, *this, mSessionStatsBuilder};
 
     camera3::flushInflightRequests(states);
 
@@ -260,7 +260,8 @@
         mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
         mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
         mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
-        mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, mBufferRecords
+        mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+        mBufferRecords
     };
 
     std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
@@ -299,7 +300,8 @@
         mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
         mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
         mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
-        mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, mBufferRecords
+        mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+        mBufferRecords
     };
 
     std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
@@ -333,7 +335,8 @@
         mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
         mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
         mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
-        mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, mBufferRecords
+        mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+        mBufferRecords
     };
     for (const auto& msg : msgs) {
         camera3::notify(states, msg);
@@ -353,7 +356,7 @@
     }
 
     RequestBufferStates states {
-        mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams,
+        mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
         *this, mBufferRecords, *this};
     camera3::requestStreamBuffers(states, bufReqs, _hidl_cb);
     return hardware::Void();
@@ -370,7 +373,7 @@
     }
 
     ReturnBufferStates states {
-        mId, mUseHalBufManager, mOutputStreams, mBufferRecords};
+        mId, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder, mBufferRecords};
     camera3::returnStreamBuffers(states, buffers);
     return hardware::Void();
 }
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.h b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
index c4c7a85..5581964 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
@@ -36,7 +36,6 @@
 #include "device3/RotateAndCropMapper.h"
 #include "device3/ZoomRatioMapper.h"
 #include "utils/TagMonitor.h"
-#include "utils/LatencyHistogram.h"
 #include <camera_metadata_hidden.h>
 
 namespace android {
@@ -209,6 +208,7 @@
     sp<camera3::Camera3Stream> mInputStream;
     camera3::StreamSet mOutputStreams;
     camera3::BufferRecords mBufferRecords;
+    SessionStatsBuilder mSessionStatsBuilder;
 
     std::mutex mOfflineReqsLock;
     camera3::InFlightRequestMap mOfflineReqs;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 7b812f2..6dfc838 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -18,8 +18,15 @@
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
+#include <ctime>
+#include <fstream>
+
+#include <android-base/unique_fd.h>
+#include <ui/GraphicBuffer.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
+
+#include "api1/client2/JpegProcessor.h"
 #include "Camera3OutputStream.h"
 #include "utils/TraceHFR.h"
 
@@ -279,6 +286,12 @@
                   __FUNCTION__, mId, strerror(-res), res);
             return res;
         }
+        // If this is a JPEG output, and image dump mask is set, save image to
+        // disk.
+        if (getFormat() == HAL_PIXEL_FORMAT_BLOB && getDataSpace() == HAL_DATASPACE_V0_JFIF &&
+                mImageDumpMask) {
+            dumpImageToDisk(timestamp, anwBuffer, anwReleaseFence);
+        }
 
         res = queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence, surface_ids);
         if (shouldLogError(res, state)) {
@@ -957,6 +970,49 @@
     return (usage & GRALLOC_USAGE_HW_TEXTURE) != 0;
 }
 
+void Camera3OutputStream::dumpImageToDisk(nsecs_t timestamp,
+        ANativeWindowBuffer* anwBuffer, int fence) {
+    // Deriver output file name
+    std::string fileExtension = "jpg";
+    char imageFileName[64];
+    time_t now = time(0);
+    tm *localTime = localtime(&now);
+    snprintf(imageFileName, sizeof(imageFileName), "IMG_%4d%02d%02d_%02d%02d%02d_%" PRId64 ".%s",
+            1900 + localTime->tm_year, localTime->tm_mon, localTime->tm_mday,
+            localTime->tm_hour, localTime->tm_min, localTime->tm_sec,
+            timestamp, fileExtension.c_str());
+
+    // Lock the image for CPU read
+    sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(anwBuffer);
+    void* mapped = nullptr;
+    base::unique_fd fenceFd(dup(fence));
+    status_t res = graphicBuffer->lockAsync(GraphicBuffer::USAGE_SW_READ_OFTEN, &mapped,
+            fenceFd.get());
+    if (res != OK) {
+        ALOGE("%s: Failed to lock the buffer: %s (%d)", __FUNCTION__, strerror(-res), res);
+        return;
+    }
+
+    // Figure out actual file size
+    auto actualJpegSize = android::camera2::JpegProcessor::findJpegSize((uint8_t*)mapped, mMaxSize);
+    if (actualJpegSize == 0) {
+        actualJpegSize = mMaxSize;
+    }
+
+    // Output image data to file
+    std::string filePath = "/data/misc/cameraserver/";
+    filePath += imageFileName;
+    std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
+    if (!imageFile.is_open()) {
+        ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
+        graphicBuffer->unlock();
+        return;
+    }
+    imageFile.write((const char*)mapped, actualJpegSize);
+
+    graphicBuffer->unlock();
+}
+
 }; // namespace camera3
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index b4e49f9..55f0d41 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -210,6 +210,8 @@
      */
     static void applyZSLUsageQuirk(int format, uint64_t *consumerUsage /*inout*/);
 
+    void setImageDumpMask(int mask) { mImageDumpMask = mask; }
+
   protected:
     Camera3OutputStream(int id, camera3_stream_type_t type,
             uint32_t width, uint32_t height, int format,
@@ -325,9 +327,14 @@
     // STATE_ABANDONED
     static bool shouldLogError(status_t res, StreamState state);
 
+    // Dump images to disk before returning to consumer
+    void dumpImageToDisk(nsecs_t timestamp, ANativeWindowBuffer* anwBuffer, int fence);
+
     static const int32_t kDequeueLatencyBinSize = 5; // in ms
     CameraLatencyHistogram mDequeueBufferLatency;
 
+    int mImageDumpMask = 0;
+
 }; // class Camera3OutputStream
 
 } // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index 889ce86..f88b062 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -182,7 +182,33 @@
         return;
     }
 
-    insertResultLocked(states, &captureResult, frameNumber);
+    // Update partial result by removing keys remapped by DistortionCorrection, ZoomRatio,
+    // and RotationAndCrop mappers.
+    std::set<uint32_t> keysToRemove;
+
+    auto iter = states.distortionMappers.find(states.cameraId.c_str());
+    if (iter != states.distortionMappers.end()) {
+        const auto& remappedKeys = iter->second.getRemappedKeys();
+        keysToRemove.insert(remappedKeys.begin(), remappedKeys.end());
+    }
+
+    const auto& remappedKeys = states.zoomRatioMappers[states.cameraId.c_str()].getRemappedKeys();
+    keysToRemove.insert(remappedKeys.begin(), remappedKeys.end());
+
+    auto mapper = states.rotateAndCropMappers.find(states.cameraId.c_str());
+    if (mapper != states.rotateAndCropMappers.end()) {
+        const auto& remappedKeys = iter->second.getRemappedKeys();
+        keysToRemove.insert(remappedKeys.begin(), remappedKeys.end());
+    }
+
+    for (uint32_t key : keysToRemove) {
+        captureResult.mMetadata.erase(key);
+    }
+
+    // Send partial result
+    if (captureResult.mMetadata.entryCount() > 0) {
+        insertResultLocked(states, &captureResult, frameNumber);
+    }
 }
 
 void sendCaptureResult(
@@ -397,6 +423,7 @@
     InFlightRequestMap& inflightMap = states.inflightMap;
     const InFlightRequest &request = inflightMap.valueAt(idx);
     const uint32_t frameNumber = inflightMap.keyAt(idx);
+    SessionStatsBuilder& sessionStatsBuilder = states.sessionStatsBuilder;
 
     nsecs_t sensorTimestamp = request.sensorTimestamp;
     nsecs_t shutterTimestamp = request.shutterTimestamp;
@@ -433,7 +460,9 @@
         returnOutputBuffers(
             states.useHalBufManager, states.listener,
             request.pendingOutputBuffers.array(),
-            request.pendingOutputBuffers.size(), 0, /*timestampIncreasing*/true,
+            request.pendingOutputBuffers.size(), 0,
+            /*requested*/true, request.requestTimeNs, states.sessionStatsBuilder,
+            /*timestampIncreasing*/true,
             request.outputSurfaces, request.resultExtras,
             request.errorBufStrategy);
 
@@ -446,6 +475,8 @@
             states.lastCompletedRegularFrameNumber = frameNumber;
         }
 
+        sessionStatsBuilder.incResultCounter(request.skipResultMetadata);
+
         removeInFlightMapEntryLocked(states, idx);
         ALOGVV("%s: removed frame %d from InFlightMap", __FUNCTION__, frameNumber);
     }
@@ -602,7 +633,7 @@
         if (shutterTimestamp != 0) {
             returnAndRemovePendingOutputBuffers(
                 states.useHalBufManager, states.listener,
-                request);
+                request, states.sessionStatsBuilder);
         }
 
         if (result->result != NULL && !isPartialResult) {
@@ -799,7 +830,8 @@
         bool useHalBufManager,
         sp<NotificationListener> listener,
         const camera3_stream_buffer_t *outputBuffers, size_t numBuffers,
-        nsecs_t timestamp, bool timestampIncreasing,
+        nsecs_t timestamp, bool requested, nsecs_t requestTimeNs,
+        SessionStatsBuilder& sessionStatsBuilder, bool timestampIncreasing,
         const SurfaceMap& outputSurfaces,
         const CaptureResultExtras &inResultExtras,
         ERROR_BUF_STRATEGY errorBufStrategy) {
@@ -827,6 +859,10 @@
                 // has not got a output buffer handle filled yet. This is though illegal if HAL
                 // buffer management API is not being used.
                 ALOGE("%s: cannot return a null buffer!", __FUNCTION__);
+            } else {
+                if (requested) {
+                    sessionStatsBuilder.incCounter(streamId, /*dropped*/true, 0);
+                }
             }
             continue;
         }
@@ -850,10 +886,22 @@
         }
         // Note: stream may be deallocated at this point, if this buffer was
         // the last reference to it.
+        bool dropped = false;
         if (res == NO_INIT || res == DEAD_OBJECT) {
             ALOGV("Can't return buffer to its stream: %s (%d)", strerror(-res), res);
+            sessionStatsBuilder.stopCounter(streamId);
         } else if (res != OK) {
             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) {
+                dropped = true;
+            }
+        }
+        if (requested) {
+            nsecs_t bufferTimeNs = systemTime();
+            int32_t captureLatencyMs = ns2ms(bufferTimeNs - requestTimeNs);
+            sessionStatsBuilder.incCounter(streamId, dropped, captureLatencyMs);
         }
 
         // Long processing consumers can cause returnBuffer timeout for shared stream
@@ -863,7 +911,8 @@
             // cancel the buffer
             camera3_stream_buffer_t sb = outputBuffers[i];
             sb.status = CAMERA3_BUFFER_STATUS_ERROR;
-            stream->returnBuffer(sb, /*timestamp*/0, timestampIncreasing, std::vector<size_t> (),
+            stream->returnBuffer(sb, /*timestamp*/0,
+                    timestampIncreasing, std::vector<size_t> (),
                     inResultExtras.frameNumber);
 
             if (listener != nullptr) {
@@ -878,12 +927,14 @@
 }
 
 void returnAndRemovePendingOutputBuffers(bool useHalBufManager,
-        sp<NotificationListener> listener, InFlightRequest& request) {
+        sp<NotificationListener> listener, InFlightRequest& request,
+        SessionStatsBuilder& sessionStatsBuilder) {
     bool timestampIncreasing = !(request.zslCapture || request.hasInputBuffer);
     returnOutputBuffers(useHalBufManager, listener,
             request.pendingOutputBuffers.array(),
             request.pendingOutputBuffers.size(),
-            request.shutterTimestamp, timestampIncreasing,
+            request.shutterTimestamp, /*requested*/true,
+            request.requestTimeNs, sessionStatsBuilder, timestampIncreasing,
             request.outputSurfaces, request.resultExtras,
             request.errorBufStrategy);
 
@@ -966,7 +1017,7 @@
                     r.rotateAndCropAuto, r.cameraIdsWithZoom, r.physicalMetadatas);
             }
             returnAndRemovePendingOutputBuffers(
-                    states.useHalBufManager, states.listener, r);
+                    states.useHalBufManager, states.listener, r, states.sessionStatsBuilder);
 
             removeInFlightRequestIfReadyLocked(states, idx);
         }
@@ -1255,6 +1306,7 @@
                     ALOGV("%s: Can't get output buffer for stream %d: %s (%d)",
                             __FUNCTION__, streamId, strerror(-res), res);
                     bufRet.val.error(StreamBufferRequestError::STREAM_DISCONNECTED);
+                    states.sessionStatsBuilder.stopCounter(streamId);
                 } else {
                     ALOGE("%s: Can't get output buffer for stream %d: %s (%d)",
                             __FUNCTION__, streamId, strerror(-res), res);
@@ -1320,7 +1372,8 @@
                 sb.status = CAMERA3_BUFFER_STATUS_ERROR;
             }
             returnOutputBuffers(states.useHalBufManager, /*listener*/nullptr,
-                    streamBuffers.data(), numAllocatedBuffers, 0);
+                    streamBuffers.data(), numAllocatedBuffers, 0, /*requested*/false,
+                    /*requestTimeNs*/0, states.sessionStatsBuilder);
         }
     }
 
@@ -1377,22 +1430,23 @@
         }
         streamBuffer.stream = stream->asHalStream();
         returnOutputBuffers(states.useHalBufManager, /*listener*/nullptr,
-                &streamBuffer, /*size*/1, /*timestamp*/ 0);
+                &streamBuffer, /*size*/1, /*timestamp*/ 0, /*requested*/false,
+                /*requestTimeNs*/0, states.sessionStatsBuilder);
     }
 }
 
 void flushInflightRequests(FlushInflightReqStates& states) {
     ATRACE_CALL();
-    { // First return buffers cached in mInFlightMap
+    { // First return buffers cached in inFlightMap
         std::lock_guard<std::mutex> l(states.inflightLock);
         for (size_t idx = 0; idx < states.inflightMap.size(); idx++) {
             const InFlightRequest &request = states.inflightMap.valueAt(idx);
             returnOutputBuffers(
                 states.useHalBufManager, states.listener,
                 request.pendingOutputBuffers.array(),
-                request.pendingOutputBuffers.size(), 0,
-                /*timestampIncreasing*/true, request.outputSurfaces,
-                request.resultExtras, request.errorBufStrategy);
+                request.pendingOutputBuffers.size(), 0, /*requested*/true,
+                request.requestTimeNs, states.sessionStatsBuilder, /*timestampIncreasing*/true,
+                request.outputSurfaces, request.resultExtras, request.errorBufStrategy);
             ALOGW("%s: Frame %d |  Timestamp: %" PRId64 ", metadata"
                     " arrived: %s, buffers left: %d.\n", __FUNCTION__,
                     states.inflightMap.keyAt(idx), request.shutterTimestamp,
@@ -1464,7 +1518,8 @@
                 switch (halStream->stream_type) {
                     case CAMERA3_STREAM_OUTPUT:
                         res = stream->returnBuffer(streamBuffer, /*timestamp*/ 0,
-                                /*timestampIncreasing*/true, std::vector<size_t> (), frameNumber);
+                                /*timestampIncreasing*/true,
+                                std::vector<size_t> (), frameNumber);
                         if (res != OK) {
                             ALOGE("%s: Can't return output buffer for frame %d to"
                                   " stream %d: %s (%d)",  __FUNCTION__,
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.h b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
index 9946312..45c8a43 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
@@ -33,6 +33,7 @@
 #include "device3/InFlightRequest.h"
 #include "device3/Camera3Stream.h"
 #include "device3/Camera3OutputStreamInterface.h"
+#include "utils/SessionStatsBuilder.h"
 #include "utils/TagMonitor.h"
 
 namespace android {
@@ -51,7 +52,8 @@
             bool useHalBufManager,
             sp<NotificationListener> listener, // Only needed when outputSurfaces is not empty
             const camera3_stream_buffer_t *outputBuffers,
-            size_t numBuffers, nsecs_t timestamp, bool timestampIncreasing = true,
+            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
             const SurfaceMap& outputSurfaces = SurfaceMap{},
             // Used to send buffer error callback when failing to return buffer
@@ -64,7 +66,7 @@
     void returnAndRemovePendingOutputBuffers(
             bool useHalBufManager,
             sp<NotificationListener> listener, // Only needed when outputSurfaces is not empty
-            InFlightRequest& request);
+            InFlightRequest& request, SessionStatsBuilder& sessionStatsBuilder);
 
     // Camera3Device/Camera3OfflineSession internal states used in notify/processCaptureResult
     // callbacks
@@ -72,8 +74,8 @@
         const String8& cameraId;
         std::mutex& inflightLock;
         int64_t& lastCompletedRegularFrameNumber;
-        int64_t& lastCompletedZslFrameNumber;
         int64_t& lastCompletedReprocessFrameNumber;
+        int64_t& lastCompletedZslFrameNumber;
         InFlightRequestMap& inflightMap; // end of inflightLock scope
         std::mutex& outputLock;
         std::list<CaptureResult>& resultQueue;
@@ -98,6 +100,7 @@
         TagMonitor& tagMonitor;
         sp<Camera3Stream> inputStream;
         StreamSet& outputStreams;
+        SessionStatsBuilder& sessionStatsBuilder;
         sp<NotificationListener> listener;
         SetErrorInterface& setErrIntf;
         InflightRequestUpdateInterface& inflightIntf;
@@ -121,6 +124,7 @@
         std::mutex& reqBufferLock; // lock to serialize request buffer calls
         const bool useHalBufManager;
         StreamSet& outputStreams;
+        SessionStatsBuilder& sessionStatsBuilder;
         SetErrorInterface& setErrIntf;
         BufferRecordsInterface& bufferRecordsIntf;
         RequestBufferInterface& reqBufferIntf;
@@ -134,6 +138,7 @@
         const String8& cameraId;
         const bool useHalBufManager;
         StreamSet& outputStreams;
+        SessionStatsBuilder& sessionStatsBuilder;
         BufferRecordsInterface& bufferRecordsIntf;
     };
 
@@ -149,6 +154,7 @@
         InflightRequestUpdateInterface& inflightIntf;
         BufferRecordsInterface& bufferRecordsIntf;
         FlushBufferInterface& flushBufferIntf;
+        SessionStatsBuilder& sessionStatsBuilder;
     };
 
     void flushInflightRequests(FlushInflightReqStates& states);
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index f208561..9a8f6fe 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -152,6 +152,10 @@
     return mPhysicalCameraId;
 }
 
+int Camera3Stream::getMaxHalBuffers() const {
+    return camera3_stream::max_buffers;
+}
+
 void Camera3Stream::setOfflineProcessingSupport(bool support) {
     mSupportOfflineProcessing = support;
 }
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index d768d3d..3654f89 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -165,6 +165,7 @@
     void              setDataSpaceOverride(bool dataSpaceOverriden);
     bool              isDataSpaceOverridden() const;
     android_dataspace getOriginalDataSpace() const;
+    int               getMaxHalBuffers() const;
     const String8&    physicalCameraId() const;
 
     void              setOfflineProcessingSupport(bool) override;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 667e3bb..a053262 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -99,6 +99,8 @@
     virtual void setDataSpaceOverride(bool dataSpaceOverriden) = 0;
     virtual bool isDataSpaceOverridden() const = 0;
     virtual android_dataspace getOriginalDataSpace() const = 0;
+    virtual int getMaxHalBuffers() const = 0;
+    virtual int getMaxTotalBuffers() const = 0;
 
     /**
      * Offline processing
diff --git a/services/camera/libcameraservice/device3/CoordinateMapper.h b/services/camera/libcameraservice/device3/CoordinateMapper.h
index 5164856..558f4c0 100644
--- a/services/camera/libcameraservice/device3/CoordinateMapper.h
+++ b/services/camera/libcameraservice/device3/CoordinateMapper.h
@@ -18,16 +18,23 @@
 #define ANDROID_SERVERS_COORDINATEMAPPER_H
 
 #include <array>
+#include <set>
 
 namespace android {
 
 namespace camera3 {
 
 class CoordinateMapper {
-    // Right now only stores metadata tags containing 2D coordinates
-    // to be corrected.
+public:
+    // The result metadata tags that are to be re-mapped
+    const std::set<uint32_t>& getRemappedKeys() const {
+        return mRemappedKeys;
+    }
+
+    virtual ~CoordinateMapper() = default;
+
 protected:
-    // Metadata key lists to correct
+    // Metadata tags containing 2D coordinates to be corrected.
 
     // Both capture request and result
     static const std::array<uint32_t, 3> kMeteringRegionsToCorrect;
@@ -37,6 +44,10 @@
 
     // Only for capture results; don't clamp
     static const std::array<uint32_t, 2> kResultPointsToCorrectNoClamp;
+
+    virtual void initRemappedKeys() = 0;
+    std::set<uint32_t> mRemappedKeys;
+
 }; // class CoordinateMapper
 
 } // namespace camera3
diff --git a/services/camera/libcameraservice/device3/DistortionMapper.cpp b/services/camera/libcameraservice/device3/DistortionMapper.cpp
index 2f388f2..316303e 100644
--- a/services/camera/libcameraservice/device3/DistortionMapper.cpp
+++ b/services/camera/libcameraservice/device3/DistortionMapper.cpp
@@ -29,6 +29,20 @@
 
 
 DistortionMapper::DistortionMapper() : mValidMapping(false), mValidGrids(false) {
+    initRemappedKeys();
+}
+
+void DistortionMapper::initRemappedKeys() {
+    mRemappedKeys.insert(
+            kMeteringRegionsToCorrect.begin(),
+            kMeteringRegionsToCorrect.end());
+    mRemappedKeys.insert(
+            kRectsToCorrect.begin(),
+            kRectsToCorrect.end());
+    mRemappedKeys.insert(
+            kResultPointsToCorrectNoClamp.begin(),
+            kResultPointsToCorrectNoClamp.end());
+    mRemappedKeys.insert(ANDROID_DISTORTION_CORRECTION_MODE);
 }
 
 bool DistortionMapper::isDistortionSupported(const CameraMetadata &deviceInfo) {
diff --git a/services/camera/libcameraservice/device3/DistortionMapper.h b/services/camera/libcameraservice/device3/DistortionMapper.h
index 7dcb67b..5027bd0 100644
--- a/services/camera/libcameraservice/device3/DistortionMapper.h
+++ b/services/camera/libcameraservice/device3/DistortionMapper.h
@@ -32,7 +32,7 @@
  * Utilities to transform between raw (distorted) and warped (corrected) coordinate systems
  * for cameras that support geometric distortion
  */
-class DistortionMapper : private CoordinateMapper {
+class DistortionMapper : public CoordinateMapper {
   public:
     DistortionMapper();
 
@@ -43,7 +43,10 @@
             mArrayWidth(other.mArrayWidth), mArrayHeight(other.mArrayHeight),
             mActiveWidth(other.mActiveWidth), mActiveHeight(other.mActiveHeight),
             mArrayDiffX(other.mArrayDiffX), mArrayDiffY(other.mArrayDiffY),
-            mCorrectedGrid(other.mCorrectedGrid), mDistortedGrid(other.mDistortedGrid) {}
+            mCorrectedGrid(other.mCorrectedGrid), mDistortedGrid(other.mDistortedGrid) {
+            initRemappedKeys(); }
+
+    void initRemappedKeys() override;
 
     /**
      * Check whether distortion correction is supported by the camera HAL
diff --git a/services/camera/libcameraservice/device3/InFlightRequest.h b/services/camera/libcameraservice/device3/InFlightRequest.h
index da4f228..c7b7475 100644
--- a/services/camera/libcameraservice/device3/InFlightRequest.h
+++ b/services/camera/libcameraservice/device3/InFlightRequest.h
@@ -115,6 +115,9 @@
     // Requested camera ids (both logical and physical) with zoomRatio != 1.0f
     std::set<std::string> cameraIdsWithZoom;
 
+    // Time of capture request (from systemTime) in Ns
+    nsecs_t requestTimeNs;
+
     // What shared surfaces an output should go to
     SurfaceMap outputSurfaces;
 
@@ -135,14 +138,15 @@
             errorBufStrategy(ERROR_BUF_CACHE),
             stillCapture(false),
             zslCapture(false),
-            rotateAndCropAuto(false) {
+            rotateAndCropAuto(false),
+            requestTimeNs(0) {
     }
 
     InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
             bool hasAppCallback, nsecs_t maxDuration,
             const std::set<String8>& physicalCameraIdSet, bool isStillCapture,
             bool isZslCapture, bool rotateAndCropAuto, const std::set<std::string>& idsWithZoom,
-            const SurfaceMap& outSurfaces = SurfaceMap{}) :
+            nsecs_t requestNs, const SurfaceMap& outSurfaces = SurfaceMap{}) :
             shutterTimestamp(0),
             sensorTimestamp(0),
             requestStatus(OK),
@@ -159,6 +163,7 @@
             zslCapture(isZslCapture),
             rotateAndCropAuto(rotateAndCropAuto),
             cameraIdsWithZoom(idsWithZoom),
+            requestTimeNs(requestNs),
             outputSurfaces(outSurfaces) {
     }
 };
diff --git a/services/camera/libcameraservice/device3/RotateAndCropMapper.cpp b/services/camera/libcameraservice/device3/RotateAndCropMapper.cpp
index 3718f54..a02e5f6 100644
--- a/services/camera/libcameraservice/device3/RotateAndCropMapper.cpp
+++ b/services/camera/libcameraservice/device3/RotateAndCropMapper.cpp
@@ -27,6 +27,18 @@
 
 namespace camera3 {
 
+void RotateAndCropMapper::initRemappedKeys() {
+    mRemappedKeys.insert(
+            kMeteringRegionsToCorrect.begin(),
+            kMeteringRegionsToCorrect.end());
+    mRemappedKeys.insert(
+            kResultPointsToCorrectNoClamp.begin(),
+            kResultPointsToCorrectNoClamp.end());
+
+    mRemappedKeys.insert(ANDROID_SCALER_ROTATE_AND_CROP);
+    mRemappedKeys.insert(ANDROID_SCALER_CROP_REGION);
+}
+
 bool RotateAndCropMapper::isNeeded(const CameraMetadata* deviceInfo) {
     auto entry = deviceInfo->find(ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES);
     for (size_t i = 0; i < entry.count; i++) {
@@ -36,6 +48,8 @@
 }
 
 RotateAndCropMapper::RotateAndCropMapper(const CameraMetadata* deviceInfo) {
+    initRemappedKeys();
+
     auto entry = deviceInfo->find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
     if (entry.count != 4) return;
 
diff --git a/services/camera/libcameraservice/device3/RotateAndCropMapper.h b/services/camera/libcameraservice/device3/RotateAndCropMapper.h
index 459e27f..f9e2263 100644
--- a/services/camera/libcameraservice/device3/RotateAndCropMapper.h
+++ b/services/camera/libcameraservice/device3/RotateAndCropMapper.h
@@ -32,12 +32,14 @@
  * Utilities to transform between unrotated and rotated-and-cropped coordinate systems
  * for cameras that support SCALER_ROTATE_AND_CROP controls in AUTO mode.
  */
-class RotateAndCropMapper : private CoordinateMapper {
+class RotateAndCropMapper : public CoordinateMapper {
   public:
     static bool isNeeded(const CameraMetadata* deviceInfo);
 
     RotateAndCropMapper(const CameraMetadata* deviceInfo);
 
+    void initRemappedKeys() override;
+
     /**
      * Adjust capture request assuming rotate and crop AUTO is enabled
      */
diff --git a/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp b/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp
index a87de77..1bc2081 100644
--- a/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp
+++ b/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp
@@ -25,6 +25,19 @@
 
 namespace camera3 {
 
+void ZoomRatioMapper::initRemappedKeys() {
+    mRemappedKeys.insert(
+            kMeteringRegionsToCorrect.begin(),
+            kMeteringRegionsToCorrect.end());
+    mRemappedKeys.insert(
+            kRectsToCorrect.begin(),
+            kRectsToCorrect.end());
+    mRemappedKeys.insert(
+            kResultPointsToCorrectNoClamp.begin(),
+            kResultPointsToCorrectNoClamp.end());
+
+    mRemappedKeys.insert(ANDROID_CONTROL_ZOOM_RATIO);
+}
 
 status_t ZoomRatioMapper::initZoomRatioInTemplate(CameraMetadata *request) {
     camera_metadata_entry_t entry;
@@ -117,6 +130,8 @@
 
 ZoomRatioMapper::ZoomRatioMapper(const CameraMetadata* deviceInfo,
         bool supportNativeZoomRatio, bool usePrecorrectArray) {
+    initRemappedKeys();
+
     camera_metadata_ro_entry_t entry;
 
     entry = deviceInfo->find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
@@ -153,6 +168,19 @@
     entry = request->find(ANDROID_CONTROL_ZOOM_RATIO);
     if (entry.count == 1 && entry.data.f[0] != 1.0f) {
         zoomRatioIs1 = false;
+
+        // If cropRegion is windowboxing, override it with activeArray
+        camera_metadata_entry_t cropRegionEntry = request->find(ANDROID_SCALER_CROP_REGION);
+        if (cropRegionEntry.count == 4) {
+            int cropWidth = cropRegionEntry.data.i32[2];
+            int cropHeight = cropRegionEntry.data.i32[3];
+            if (cropWidth < mArrayWidth && cropHeight < mArrayHeight) {
+                cropRegionEntry.data.i32[0] = 0;
+                cropRegionEntry.data.i32[1] = 0;
+                cropRegionEntry.data.i32[2] = mArrayWidth;
+                cropRegionEntry.data.i32[3] = mArrayHeight;
+            }
+        }
     }
 
     if (mHalSupportsZoomRatio && zoomRatioIs1) {
diff --git a/services/camera/libcameraservice/device3/ZoomRatioMapper.h b/services/camera/libcameraservice/device3/ZoomRatioMapper.h
index 698f87f..3769299 100644
--- a/services/camera/libcameraservice/device3/ZoomRatioMapper.h
+++ b/services/camera/libcameraservice/device3/ZoomRatioMapper.h
@@ -33,7 +33,7 @@
  * - HAL supports zoomRatio and the application uses cropRegion, or
  * - HAL doesn't support zoomRatio, but the application uses zoomRatio
  */
-class ZoomRatioMapper : private CoordinateMapper {
+class ZoomRatioMapper : public CoordinateMapper {
   public:
     ZoomRatioMapper() = default;
     ZoomRatioMapper(const CameraMetadata *deviceInfo,
@@ -41,7 +41,9 @@
     ZoomRatioMapper(const ZoomRatioMapper& other) :
             mHalSupportsZoomRatio(other.mHalSupportsZoomRatio),
             mArrayWidth(other.mArrayWidth), mArrayHeight(other.mArrayHeight),
-            mIsValid(other.mIsValid) {}
+            mIsValid(other.mIsValid) { initRemappedKeys(); }
+
+    void initRemappedKeys() override;
 
     /**
      * Initialize request template with valid zoomRatio if necessary.
diff --git a/services/camera/libcameraservice/fuzzer/Android.bp b/services/camera/libcameraservice/fuzzer/Android.bp
new file mode 100644
index 0000000..c5b7f00
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/Android.bp
@@ -0,0 +1,44 @@
+// 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.
+
+cc_defaults {
+    name: "libcameraservice_fuzz_defaults",
+    fuzz_config: {
+        componentid: 41727
+    },
+}
+
+cc_fuzz {
+    name: "libcameraservice_distortion_mapper_fuzzer",
+    defaults: ["libcameraservice_fuzz_defaults"],
+    srcs: [
+        "DistortionMapperFuzzer.cpp",
+    ],
+    shared_libs: [
+        "libcameraservice",
+        "libcamera_client",
+    ],
+}
+
+cc_fuzz {
+    name: "libcameraservice_depth_processor_fuzzer",
+    defaults: ["libcameraservice_fuzz_defaults"],
+    srcs: [
+        "DepthProcessorFuzzer.cpp",
+    ],
+    shared_libs: [
+        "libcameraservice",
+    ],
+    corpus: ["corpus/*.jpg"],
+}
diff --git a/services/camera/libcameraservice/fuzzer/DepthProcessorFuzzer.cpp b/services/camera/libcameraservice/fuzzer/DepthProcessorFuzzer.cpp
new file mode 100644
index 0000000..650ca91
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/DepthProcessorFuzzer.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#include <array>
+#include <vector>
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "common/DepthPhotoProcessor.h"
+
+using namespace android;
+using namespace android::camera3;
+
+static const size_t kTestBufferWidth = 640;
+static const size_t kTestBufferHeight = 480;
+static const size_t kTestBufferDepthSize (kTestBufferWidth * kTestBufferHeight);
+
+void generateDepth16Buffer(const uint8_t* data, size_t size, std::array<uint16_t, kTestBufferDepthSize> *depth16Buffer /*out*/) {
+    FuzzedDataProvider dataProvider(data, size);
+    for (size_t i = 0; i < depth16Buffer->size(); i++) {
+        (*depth16Buffer)[i] = dataProvider.ConsumeIntegral<uint16_t>();
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    DepthPhotoInputFrame inputFrame;
+    // Worst case both depth and confidence maps have the same size as the main color image.
+    inputFrame.mMaxJpegSize = inputFrame.mMainJpegSize * 3;
+
+    std::vector<uint8_t> depthPhotoBuffer(inputFrame.mMaxJpegSize);
+    size_t actualDepthPhotoSize = 0;
+
+    std::array<uint16_t, kTestBufferDepthSize> depth16Buffer;
+    generateDepth16Buffer(data, size, &depth16Buffer);
+
+    inputFrame.mMainJpegBuffer = reinterpret_cast<const char*> (data);
+    inputFrame.mMainJpegSize = size;
+    inputFrame.mDepthMapBuffer = depth16Buffer.data();
+    inputFrame.mDepthMapStride = kTestBufferWidth;
+    inputFrame.mDepthMapWidth = kTestBufferWidth;
+    inputFrame.mDepthMapHeight = kTestBufferHeight;
+    processDepthPhotoFrame(
+        inputFrame,
+        depthPhotoBuffer.size(),
+        depthPhotoBuffer.data(),
+        &actualDepthPhotoSize);
+
+  return 0;
+}
diff --git a/services/camera/libcameraservice/fuzzer/DistortionMapperFuzzer.cpp b/services/camera/libcameraservice/fuzzer/DistortionMapperFuzzer.cpp
new file mode 100644
index 0000000..96bab4e
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/DistortionMapperFuzzer.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+#include <vector>
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "device3/DistortionMapper.h"
+#include <camera/CameraMetadata.h>
+
+using namespace android;
+using namespace android::camera3;
+
+int32_t testActiveArray[] = {100, 100, 1000, 750};
+float testICal[] = { 1000.f, 1000.f, 500.f, 500.f, 0.f };
+float identityDistortion[] = { 0.f, 0.f, 0.f, 0.f, 0.f};
+
+void setupTestMapper(DistortionMapper *m,
+        float distortion[5], float intrinsics[5],
+        int32_t activeArray[4], int32_t preCorrectionActiveArray[4]) {
+    CameraMetadata deviceInfo;
+
+    deviceInfo.update(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
+            preCorrectionActiveArray, 4);
+
+    deviceInfo.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
+            activeArray, 4);
+
+    deviceInfo.update(ANDROID_LENS_INTRINSIC_CALIBRATION,
+            intrinsics, 5);
+
+    deviceInfo.update(ANDROID_LENS_DISTORTION,
+            distortion, 5);
+
+    m->setupStaticInfo(deviceInfo);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider fdp(data, size);
+
+    DistortionMapper m;
+    setupTestMapper(&m, identityDistortion, testICal,
+        /*activeArray*/ testActiveArray,
+        /*preCorrectionActiveArray*/ testActiveArray);
+
+    bool clamp = fdp.ConsumeBool();
+    bool simple = fdp.ConsumeBool();
+    std::vector<int32_t> input;
+    for (int index = 0; fdp.remaining_bytes() > 0; index++) {
+        input.push_back(fdp.ConsumeIntegral<int32_t>());
+    }
+
+    // The size argument counts how many coordinate pairs there are, so
+    // it is expected to be 1/2 the size of the input.
+    m.mapCorrectedToRaw(input.data(), input.size()/2,  clamp, simple);
+
+    return 0;
+}
diff --git a/services/camera/libcameraservice/fuzzer/corpus/Canon_MakerNote_variant_type_1.jpg b/services/camera/libcameraservice/fuzzer/corpus/Canon_MakerNote_variant_type_1.jpg
new file mode 100644
index 0000000..1eb37d0
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/corpus/Canon_MakerNote_variant_type_1.jpg
Binary files differ
diff --git a/services/camera/libcameraservice/fuzzer/corpus/Fuji_MakerNote_variant_type_1.jpg b/services/camera/libcameraservice/fuzzer/corpus/Fuji_MakerNote_variant_type_1.jpg
new file mode 100644
index 0000000..75e0371
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/corpus/Fuji_MakerNote_variant_type_1.jpg
Binary files differ
diff --git a/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_2.jpg b/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_2.jpg
new file mode 100644
index 0000000..461d613
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_2.jpg
Binary files differ
diff --git a/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_3.jpg b/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_3.jpg
new file mode 100644
index 0000000..42498e2
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_3.jpg
Binary files differ
diff --git a/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_4.jpg b/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_4.jpg
new file mode 100644
index 0000000..233ff78
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_4.jpg
Binary files differ
diff --git a/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_5.jpg b/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_5.jpg
new file mode 100644
index 0000000..f083f75
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/corpus/Olympus_MakerNote_variant_type_5.jpg
Binary files differ
diff --git a/services/camera/libcameraservice/fuzzer/corpus/Pentax_MakerNote_variant_type_2.jpg b/services/camera/libcameraservice/fuzzer/corpus/Pentax_MakerNote_variant_type_2.jpg
new file mode 100644
index 0000000..0ef0ef2
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/corpus/Pentax_MakerNote_variant_type_2.jpg
Binary files differ
diff --git a/services/camera/libcameraservice/fuzzer/corpus/Pentax_MakerNote_variant_type_3.jpg b/services/camera/libcameraservice/fuzzer/corpus/Pentax_MakerNote_variant_type_3.jpg
new file mode 100644
index 0000000..d93b86f
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/corpus/Pentax_MakerNote_variant_type_3.jpg
Binary files differ
diff --git a/services/camera/libcameraservice/fuzzer/corpus/Pentax_MakerNote_variant_type_4.jpg b/services/camera/libcameraservice/fuzzer/corpus/Pentax_MakerNote_variant_type_4.jpg
new file mode 100644
index 0000000..297ea1c
--- /dev/null
+++ b/services/camera/libcameraservice/fuzzer/corpus/Pentax_MakerNote_variant_type_4.jpg
Binary files differ
diff --git a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
index bf89ca5..2509e6c 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
@@ -28,7 +28,7 @@
 namespace frameworks {
 namespace cameraservice {
 namespace device {
-namespace V2_0 {
+namespace V2_1 {
 namespace implementation {
 
 using hardware::cameraservice::utils::conversion::convertToHidl;
@@ -115,7 +115,7 @@
         // is guaranteed to be called serially by the client if it decides to
         // use fmq.
         if (e.settings.getDiscriminator() ==
-            FmqSizeOrMetadata::hidl_discriminator::fmqMetadataSize) {
+            V2_0::FmqSizeOrMetadata::hidl_discriminator::fmqMetadataSize) {
             /**
              * Get settings from the fmq.
              */
@@ -196,6 +196,12 @@
 
 Return<HStatus> HidlCameraDeviceUser::endConfigure(StreamConfigurationMode operatingMode,
                                                    const hidl_vec<uint8_t>& sessionParams) {
+    return endConfigure_2_1(operatingMode, sessionParams, systemTime());
+}
+
+Return<HStatus> HidlCameraDeviceUser::endConfigure_2_1(StreamConfigurationMode operatingMode,
+                                                   const hidl_vec<uint8_t>& sessionParams,
+                                                   nsecs_t startTimeNs) {
     android::CameraMetadata cameraMetadata;
     if (!convertFromHidl(sessionParams, &cameraMetadata)) {
         return HStatus::ILLEGAL_ARGUMENT;
@@ -203,7 +209,8 @@
 
     std::vector<int> offlineStreamIds;
     binder::Status ret = mDeviceRemote->endConfigure(convertFromHidl(operatingMode),
-                                                     cameraMetadata, &offlineStreamIds);
+                                                     cameraMetadata, ns2ms(startTimeNs),
+                                                     &offlineStreamIds);
     return B2HStatus(ret);
 }
 
diff --git a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h
index c3a80fe..0e2ab3d 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h
+++ b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h
@@ -24,6 +24,7 @@
 #include <android/frameworks/cameraservice/common/2.0/types.h>
 #include <android/frameworks/cameraservice/service/2.0/types.h>
 #include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
+#include <android/frameworks/cameraservice/device/2.1/ICameraDeviceUser.h>
 #include <android/frameworks/cameraservice/device/2.0/types.h>
 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
 #include <fmq/MessageQueue.h>
@@ -36,7 +37,7 @@
 namespace frameworks {
 namespace cameraservice {
 namespace device {
-namespace V2_0 {
+namespace V2_1 {
 namespace implementation {
 
 using frameworks::cameraservice::device::V2_0::StreamConfigurationMode;
@@ -50,7 +51,7 @@
 using CaptureRequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
 using TemplateId = frameworks::cameraservice::device::V2_0::TemplateId;
 
-using HCameraDeviceUser = device::V2_0::ICameraDeviceUser;
+using HCameraDeviceUser = device::V2_1::ICameraDeviceUser;
 using HCameraMetadata = cameraservice::service::V2_0::CameraMetadata;
 using HCaptureRequest = device::V2_0::CaptureRequest;
 using HSessionConfiguration = frameworks::cameraservice::device::V2_0::SessionConfiguration;
@@ -83,6 +84,10 @@
     virtual Return<HStatus> endConfigure(StreamConfigurationMode operatingMode,
                                          const hidl_vec<uint8_t>& sessionParams);
 
+    virtual Return<HStatus> endConfigure_2_1(StreamConfigurationMode operatingMode,
+                                         const hidl_vec<uint8_t>& sessionParams,
+                                         nsecs_t startTimeNs);
+
     virtual Return<HStatus> deleteStream(int32_t streamId) override;
 
     virtual Return<void> createStream(const HOutputConfiguration& outputConfiguration,
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index 9ea9526..aa1e95a 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -38,7 +38,7 @@
 using hardware::Void;
 
 using device::V2_0::implementation::H2BCameraDeviceCallbacks;
-using device::V2_0::implementation::HidlCameraDeviceUser;
+using device::V2_1::implementation::HidlCameraDeviceUser;
 using service::V2_0::implementation::H2BCameraServiceListener;
 using HCameraMetadataType = frameworks::cameraservice::common::V2_0::CameraMetadataType;
 using HVendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.h b/services/camera/libcameraservice/hidl/HidlCameraService.h
index 097f4c5..86a7cec 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.h
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.h
@@ -21,7 +21,7 @@
 #include <thread>
 
 #include <android/frameworks/cameraservice/common/2.0/types.h>
-#include <android/frameworks/cameraservice/service/2.1/ICameraService.h>
+#include <android/frameworks/cameraservice/service/2.2/ICameraService.h>
 #include <android/frameworks/cameraservice/service/2.0/types.h>
 #include <android/frameworks/cameraservice/device/2.0/types.h>
 
@@ -42,7 +42,7 @@
 
 using HCameraDeviceCallback = frameworks::cameraservice::device::V2_0::ICameraDeviceCallback;
 using HCameraMetadata = frameworks::cameraservice::service::V2_0::CameraMetadata;
-using HCameraService = frameworks::cameraservice::service::V2_1::ICameraService;
+using HCameraService = frameworks::cameraservice::service::V2_2::ICameraService;
 using HCameraServiceListener = frameworks::cameraservice::service::V2_0::ICameraServiceListener;
 using HCameraServiceListener2_1 = frameworks::cameraservice::service::V2_1::ICameraServiceListener;
 using HStatus = frameworks::cameraservice::common::V2_0::Status;
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
new file mode 100644
index 0000000..0557fcc
--- /dev/null
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
@@ -0,0 +1,244 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "CameraServiceProxyWrapper"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+
+#include <inttypes.h>
+#include <utils/Log.h>
+#include <binder/IServiceManager.h>
+
+#include "CameraServiceProxyWrapper.h"
+
+namespace android {
+
+using hardware::ICameraServiceProxy;
+using hardware::CameraSessionStats;
+
+Mutex CameraServiceProxyWrapper::sProxyMutex;
+sp<hardware::ICameraServiceProxy> CameraServiceProxyWrapper::sCameraServiceProxy;
+
+Mutex CameraServiceProxyWrapper::mLock;
+std::map<String8, std::shared_ptr<CameraServiceProxyWrapper::CameraSessionStatsWrapper>>
+        CameraServiceProxyWrapper::mSessionStatsMap;
+
+/**
+ * CameraSessionStatsWrapper functions
+ */
+
+void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onOpen() {
+    Mutex::Autolock l(mLock);
+
+    updateProxyDeviceState(mSessionStats);
+}
+
+void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onClose(int32_t latencyMs) {
+    Mutex::Autolock l(mLock);
+
+    mSessionStats.mNewCameraState = CameraSessionStats::CAMERA_STATE_CLOSED;
+    mSessionStats.mLatencyMs = latencyMs;
+    updateProxyDeviceState(mSessionStats);
+}
+
+void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onStreamConfigured(
+        int operatingMode, bool internalReconfig, int32_t latencyMs) {
+    Mutex::Autolock l(mLock);
+
+    if (internalReconfig) {
+        mSessionStats.mInternalReconfigure++;
+    } else {
+        mSessionStats.mLatencyMs = latencyMs;
+        mSessionStats.mSessionType = operatingMode;
+    }
+}
+
+void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onActive() {
+    Mutex::Autolock l(mLock);
+
+    mSessionStats.mNewCameraState = CameraSessionStats::CAMERA_STATE_ACTIVE;
+    updateProxyDeviceState(mSessionStats);
+
+    // Reset mCreationDuration to -1 to distinguish between 1st session
+    // after configuration, and all other sessions after configuration.
+    mSessionStats.mLatencyMs = -1;
+}
+
+void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onIdle(
+        int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+        const std::vector<hardware::CameraStreamStats>& streamStats) {
+    Mutex::Autolock l(mLock);
+
+    mSessionStats.mNewCameraState = CameraSessionStats::CAMERA_STATE_IDLE;
+    mSessionStats.mRequestCount = requestCount;
+    mSessionStats.mResultErrorCount = resultErrorCount;
+    mSessionStats.mDeviceError = deviceError;
+    mSessionStats.mStreamStats = streamStats;
+    updateProxyDeviceState(mSessionStats);
+
+    mSessionStats.mInternalReconfigure = 0;
+    mSessionStats.mStreamStats.clear();
+}
+
+/**
+ * CameraServiceProxyWrapper functions
+ */
+
+sp<ICameraServiceProxy> CameraServiceProxyWrapper::getCameraServiceProxy() {
+#ifndef __BRILLO__
+    Mutex::Autolock al(sProxyMutex);
+    if (sCameraServiceProxy == nullptr) {
+        sp<IServiceManager> sm = defaultServiceManager();
+        // Use checkService because cameraserver normally starts before the
+        // system server and the proxy service. So the long timeout that getService
+        // has before giving up is inappropriate.
+        sp<IBinder> binder = sm->checkService(String16("media.camera.proxy"));
+        if (binder != nullptr) {
+            sCameraServiceProxy = interface_cast<ICameraServiceProxy>(binder);
+        }
+    }
+#endif
+    return sCameraServiceProxy;
+}
+
+void CameraServiceProxyWrapper::pingCameraServiceProxy() {
+    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
+    if (proxyBinder == nullptr) return;
+    proxyBinder->pingForUserUpdate();
+}
+
+void CameraServiceProxyWrapper::updateProxyDeviceState(const CameraSessionStats& sessionStats) {
+    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
+    if (proxyBinder == nullptr) return;
+    proxyBinder->notifyCameraState(sessionStats);
+}
+
+void CameraServiceProxyWrapper::logStreamConfigured(const String8& id,
+        int operatingMode, bool internalConfig, int32_t latencyMs) {
+    std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
+    {
+        Mutex::Autolock l(mLock);
+        sessionStats = mSessionStatsMap[id];
+        if (sessionStats == nullptr) {
+            ALOGE("%s: SessionStatsMap should contain camera %s",
+                    __FUNCTION__, id.c_str());
+            return;
+        }
+    }
+
+    ALOGV("%s: id %s, operatingMode %d, internalConfig %d, latencyMs %d",
+            __FUNCTION__, id.c_str(), operatingMode, internalConfig, latencyMs);
+    sessionStats->onStreamConfigured(operatingMode, internalConfig, latencyMs);
+}
+
+void CameraServiceProxyWrapper::logActive(const String8& id) {
+    std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
+    {
+        Mutex::Autolock l(mLock);
+        sessionStats = mSessionStatsMap[id];
+        if (sessionStats == nullptr) {
+            ALOGE("%s: SessionStatsMap should contain camera %s when logActive is called",
+                    __FUNCTION__, id.c_str());
+            return;
+        }
+    }
+
+    ALOGV("%s: id %s", __FUNCTION__, id.c_str());
+    sessionStats->onActive();
+}
+
+void CameraServiceProxyWrapper::logIdle(const String8& id,
+        int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+        const std::vector<hardware::CameraStreamStats>& streamStats) {
+    std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
+    {
+        Mutex::Autolock l(mLock);
+        sessionStats = mSessionStatsMap[id];
+    }
+
+    if (sessionStats == nullptr) {
+        ALOGE("%s: SessionStatsMap should contain camera %s when logIdle is called",
+                __FUNCTION__, id.c_str());
+        return;
+    }
+
+    ALOGV("%s: id %s, requestCount %" PRId64 ", resultErrorCount %" PRId64 ", deviceError %d",
+            __FUNCTION__, id.c_str(), requestCount, resultErrorCount, deviceError);
+    for (size_t i = 0; i < streamStats.size(); i++) {
+        ALOGV("%s: streamStats[%zu]: w %d h %d, requestedCount %" PRId64 ", dropCount %"
+                PRId64 ", startTimeMs %d" ,
+                __FUNCTION__, i, streamStats[i].mWidth, streamStats[i].mHeight,
+                streamStats[i].mRequestCount, streamStats[i].mErrorCount,
+                streamStats[i].mStartLatencyMs);
+    }
+
+    sessionStats->onIdle(requestCount, resultErrorCount, deviceError, streamStats);
+}
+
+void CameraServiceProxyWrapper::logOpen(const String8& id, int facing,
+            const String16& clientPackageName, int effectiveApiLevel, bool isNdk,
+            int32_t latencyMs) {
+    std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
+    {
+        Mutex::Autolock l(mLock);
+        if (mSessionStatsMap.count(id) > 0) {
+            ALOGE("%s: SessionStatsMap shouldn't contain camera %s",
+                    __FUNCTION__, id.c_str());
+            return;
+        }
+
+        int apiLevel = CameraSessionStats::CAMERA_API_LEVEL_1;
+        if (effectiveApiLevel == 2) {
+            apiLevel = CameraSessionStats::CAMERA_API_LEVEL_2;
+        }
+
+        sessionStats = std::make_shared<CameraSessionStatsWrapper>(String16(id), facing,
+                CameraSessionStats::CAMERA_STATE_OPEN, clientPackageName,
+                apiLevel, isNdk, latencyMs);
+        mSessionStatsMap.emplace(id, sessionStats);
+        ALOGV("%s: Adding id %s", __FUNCTION__, id.c_str());
+    }
+
+    ALOGV("%s: id %s, facing %d, effectiveApiLevel %d, isNdk %d, latencyMs %d",
+            __FUNCTION__, id.c_str(), facing, effectiveApiLevel, isNdk, latencyMs);
+    sessionStats->onOpen();
+}
+
+void CameraServiceProxyWrapper::logClose(const String8& id, int32_t latencyMs) {
+    std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
+    {
+        Mutex::Autolock l(mLock);
+        if (mSessionStatsMap.count(id) == 0) {
+            ALOGE("%s: SessionStatsMap should contain camera %s before it's closed",
+                    __FUNCTION__, id.c_str());
+            return;
+        }
+
+        sessionStats = mSessionStatsMap[id];
+        if (sessionStats == nullptr) {
+            ALOGE("%s: SessionStatsMap should contain camera %s",
+                    __FUNCTION__, id.c_str());
+            return;
+        }
+        mSessionStatsMap.erase(id);
+        ALOGV("%s: Erasing id %s", __FUNCTION__, id.c_str());
+    }
+
+    ALOGV("%s: id %s, latencyMs %d", __FUNCTION__, id.c_str(), latencyMs);
+    sessionStats->onClose(latencyMs);
+}
+
+}; // namespace android
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
new file mode 100644
index 0000000..9525935
--- /dev/null
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_SERVICE_PROXY_WRAPPER_H_
+#define ANDROID_SERVERS_CAMERA_SERVICE_PROXY_WRAPPER_H_
+
+#include <android/hardware/ICameraServiceProxy.h>
+
+#include <utils/Mutex.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
+
+#include <camera/CameraSessionStats.h>
+
+namespace android {
+
+class CameraServiceProxyWrapper {
+private:
+    // Guard mCameraServiceProxy
+    static Mutex sProxyMutex;
+    // Cached interface to the camera service proxy in system service
+    static sp<hardware::ICameraServiceProxy> sCameraServiceProxy;
+
+    struct CameraSessionStatsWrapper {
+        hardware::CameraSessionStats mSessionStats;
+        Mutex mLock; // lock for per camera session stats
+
+        CameraSessionStatsWrapper(const String16& cameraId, int facing, int newCameraState,
+                const String16& clientName, int apiLevel, bool isNdk, int32_t latencyMs) :
+            mSessionStats(cameraId, facing, newCameraState, clientName, apiLevel, isNdk, latencyMs)
+            {}
+
+        void onOpen();
+        void onClose(int32_t latencyMs);
+        void onStreamConfigured(int operatingMode, bool internalReconfig, int32_t latencyMs);
+        void onActive();
+        void onIdle(int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+                const std::vector<hardware::CameraStreamStats>& streamStats);
+    };
+
+    // Lock for camera session stats map
+    static Mutex mLock;
+    // Map from camera id to the camera's session statistics
+    static std::map<String8, std::shared_ptr<CameraSessionStatsWrapper>> mSessionStatsMap;
+
+    /**
+     * Update the session stats of a given camera device (open/close/active/idle) with
+     * the camera proxy service in the system service
+     */
+    static void updateProxyDeviceState(
+            const hardware::CameraSessionStats& sessionStats);
+
+    static sp<hardware::ICameraServiceProxy> getCameraServiceProxy();
+
+public:
+    // Open
+    static void logOpen(const String8& id, int facing,
+            const String16& clientPackageName, int apiLevel, bool isNdk,
+            int32_t latencyMs);
+
+    // Close
+    static void logClose(const String8& id, int32_t latencyMs);
+
+    // Stream configuration
+    static void logStreamConfigured(const String8& id, int operatingMode, bool internalReconfig,
+            int32_t latencyMs);
+
+    // Session state becomes active
+    static void logActive(const String8& id);
+
+    // Session state becomes idle
+    static void logIdle(const String8& id,
+            int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+            const std::vector<hardware::CameraStreamStats>& streamStats);
+
+    // Ping camera service proxy for user update
+    static void pingCameraServiceProxy();
+};
+
+} // android
+
+#endif // ANDROID_SERVERS_CAMERA_SERVICE_PROXY_WRAPPER_H_
diff --git a/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp b/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
new file mode 100644
index 0000000..83965c4
--- /dev/null
+++ b/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "CameraSessionStatsBuilder"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include "SessionStatsBuilder.h"
+
+namespace android {
+
+status_t SessionStatsBuilder::addStream(int id) {
+    std::lock_guard<std::mutex> l(mLock);
+    StreamStats stats;
+    mStatsMap.emplace(id, stats);
+    return OK;
+}
+
+status_t SessionStatsBuilder::removeStream(int id) {
+    std::lock_guard<std::mutex> l(mLock);
+    mStatsMap.erase(id);
+    return OK;
+}
+
+void SessionStatsBuilder::buildAndReset(int64_t* requestCount,
+        int64_t* errorResultCount, bool* deviceError,
+        std::map<int, StreamStats> *statsMap) {
+    std::lock_guard<std::mutex> l(mLock);
+    *requestCount = mRequestCount;
+    *errorResultCount = mErrorResultCount;
+    *deviceError = mDeviceError;
+    *statsMap = mStatsMap;
+
+    // Reset internal states
+    mRequestCount = 0;
+    mErrorResultCount = 0;
+    mCounterStopped = false;
+    mDeviceError = false;
+    for (auto& streamStats : mStatsMap) {
+        streamStats.second.mRequestedFrameCount = 0;
+        streamStats.second.mDroppedFrameCount = 0;
+        streamStats.second.mCounterStopped = false;
+        streamStats.second.mStartLatencyMs = 0;
+    }
+}
+
+void SessionStatsBuilder::startCounter(int id) {
+    std::lock_guard<std::mutex> l(mLock);
+    mStatsMap[id].mCounterStopped = false;
+}
+
+void SessionStatsBuilder::stopCounter(int id) {
+    std::lock_guard<std::mutex> l(mLock);
+    mStatsMap[id].mCounterStopped = true;
+}
+
+void SessionStatsBuilder::incCounter(int id, bool dropped, int32_t captureLatencyMs) {
+    std::lock_guard<std::mutex> l(mLock);
+    auto it = mStatsMap.find(id);
+    if (it != mStatsMap.end()) {
+         if (!it->second.mCounterStopped) {
+             it->second.mRequestedFrameCount++;
+             if (dropped) {
+                 it->second.mDroppedFrameCount++;
+             } else if (it->second.mRequestedFrameCount == 1) {
+                 // The capture latency for the first request.
+                 it->second.mStartLatencyMs = captureLatencyMs;
+             }
+         }
+    }
+}
+
+void SessionStatsBuilder::stopCounter() {
+    std::lock_guard<std::mutex> l(mLock);
+    mCounterStopped = true;
+    for (auto& streamStats : mStatsMap) {
+        streamStats.second.mCounterStopped = true;
+    }
+}
+
+void SessionStatsBuilder::incResultCounter(bool dropped) {
+    std::lock_guard<std::mutex> l(mLock);
+    if (!mCounterStopped) {
+        mRequestCount ++;
+        if (dropped) mErrorResultCount++;
+    }
+}
+
+void SessionStatsBuilder::onDeviceError() {
+    std::lock_guard<std::mutex> l(mLock);
+    mDeviceError = true;
+}
+
+}; // namespace android
diff --git a/services/camera/libcameraservice/utils/SessionStatsBuilder.h b/services/camera/libcameraservice/utils/SessionStatsBuilder.h
new file mode 100644
index 0000000..7943637
--- /dev/null
+++ b/services/camera/libcameraservice/utils/SessionStatsBuilder.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_SERVICE_UTILS_SESSION_STATS_BUILDER_H
+#define ANDROID_SERVICE_UTILS_SESSION_STATS_BUILDER_H
+
+#include <utils/Errors.h>
+
+#include <mutex>
+#include <map>
+
+namespace android {
+
+// Helper class to build stream stats
+struct StreamStats {
+    int64_t mRequestedFrameCount;
+    int64_t mDroppedFrameCount;
+    bool mCounterStopped;
+    int32_t mStartLatencyMs;
+
+    StreamStats() : mRequestedFrameCount(0),
+                     mDroppedFrameCount(0),
+                     mCounterStopped(false),
+                     mStartLatencyMs(0) {}
+};
+
+// Helper class to build session stats
+class SessionStatsBuilder {
+public:
+
+    status_t addStream(int streamId);
+    status_t removeStream(int streamId);
+
+    // Return the session statistics and reset the internal states.
+    void buildAndReset(/*out*/int64_t* requestCount,
+            /*out*/int64_t* errorResultCount,
+            /*out*/bool* deviceError,
+            /*out*/std::map<int, StreamStats> *statsMap);
+
+    // Stream specific counter
+    void startCounter(int streamId);
+    void stopCounter(int streamId);
+    void incCounter(int streamId, bool dropped, int32_t captureLatencyMs);
+
+    // Session specific counter
+    void stopCounter();
+    void incResultCounter(bool dropped);
+    void onDeviceError();
+
+    SessionStatsBuilder() : mRequestCount(0), mErrorResultCount(0),
+             mCounterStopped(false), mDeviceError(false) {}
+private:
+    std::mutex mLock;
+    int64_t mRequestCount;
+    int64_t mErrorResultCount;
+    bool mCounterStopped;
+    bool mDeviceError;
+    // Map from stream id to stream statistics
+    std::map<int, StreamStats> mStatsMap;
+};
+
+}; // namespace android
+
+#endif // ANDROID_SERVICE_UTILS_SESSION_STATS_BUILDER_H
diff --git a/services/medialog/Android.bp b/services/medialog/Android.bp
index 74b63d5..3a27a43 100644
--- a/services/medialog/Android.bp
+++ b/services/medialog/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libmedialogservice",
 
     srcs: [
diff --git a/services/medialog/fuzzer/Android.bp b/services/medialog/fuzzer/Android.bp
new file mode 100644
index 0000000..2afaaae
--- /dev/null
+++ b/services/medialog/fuzzer/Android.bp
@@ -0,0 +1,33 @@
+cc_fuzz {
+    name: "media_log_fuzzer",
+    static_libs: [
+        "libmedialogservice",
+    ],
+    srcs: [
+        "media_log_fuzzer.cpp",
+    ],
+    header_libs: [
+        "libmedia_headers",
+    ],
+    shared_libs: [
+        "libaudioutils",
+        "libbinder",
+        "liblog",
+        "libmediautils",
+        "libnblog",
+        "libutils",
+    ],
+    include_dirs: [
+        "frameworks/av/services/medialog",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
diff --git a/services/medialog/fuzzer/README.md b/services/medialog/fuzzer/README.md
new file mode 100644
index 0000000..b79e5c8
--- /dev/null
+++ b/services/medialog/fuzzer/README.md
@@ -0,0 +1,50 @@
+# Fuzzer for libmedialogservice
+
+## Plugin Design Considerations
+The fuzzer plugin for libmedialogservice is designed based on the understanding of the
+service 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.
+
+medialogservice supports the following parameters:
+1. Writer name (parameter name: `writerNameIdx`)
+2. Log size (parameter name: `logSize`)
+3. Enable dump before unrgister API (parameter name: `shouldDumpBeforeUnregister`)
+5. size of string for log dump (parameter name: `numberOfLines`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `writerNameIdx` | 0. `0` 1. `1` | Value obtained from FuzzedDataProvider |
+| `logSize` | In the range `256 to 65536` | Value obtained from FuzzedDataProvider |
+| `shouldDumpBeforeUnregister` | 0. `0` 1. `1` | Value obtained from FuzzedDataProvider |
+| `numberOfLines` | In the range `0 to 65535` | Value obtained from FuzzedDataProvider |
+
+This also ensures that the plugin is always deterministic for any given input.
+
+## Build
+
+This describes steps to build media_log_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) media_log_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/media_log_fuzzer/media_log_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/services/medialog/fuzzer/media_log_fuzzer.cpp b/services/medialog/fuzzer/media_log_fuzzer.cpp
new file mode 100644
index 0000000..bd50d0f
--- /dev/null
+++ b/services/medialog/fuzzer/media_log_fuzzer.cpp
@@ -0,0 +1,76 @@
+/**
+ * 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.
+ */
+#include <binder/IMemory.h>
+#include <binder/MemoryDealer.h>
+#include <private/android_filesystem_config.h>
+#include "MediaLogService.h"
+#include "fuzzer/FuzzedDataProvider.h"
+
+constexpr const char* kWriterNames[2] = {"FastMixer", "FastCapture"};
+constexpr size_t kMinSize = 0x100;
+constexpr size_t kMaxSize = 0x10000;
+constexpr size_t kLogMemorySize = 400 * 1024;
+constexpr size_t kMaxNumLines = USHRT_MAX;
+
+using namespace android;
+
+class MediaLogFuzzer {
+   public:
+    void init();
+    void process(const uint8_t* data, size_t size);
+
+   private:
+    sp<MemoryDealer> mMemoryDealer = nullptr;
+    sp<MediaLogService> mService = nullptr;
+};
+
+void MediaLogFuzzer::init() {
+    setuid(AID_MEDIA);
+    mService = new MediaLogService();
+    mMemoryDealer = new MemoryDealer(kLogMemorySize, "MediaLogFuzzer", MemoryHeapBase::READ_ONLY);
+}
+
+void MediaLogFuzzer::process(const uint8_t* data, size_t size) {
+    FuzzedDataProvider fuzzedDataProvider(data, size);
+    size_t writerNameIdx =
+        fuzzedDataProvider.ConsumeIntegralInRange<size_t>(0, std::size(kWriterNames) - 1);
+    bool shouldDumpBeforeUnregister = fuzzedDataProvider.ConsumeBool();
+    size_t logSize = fuzzedDataProvider.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+    sp<IMemory> logBuffer = mMemoryDealer->allocate(NBLog::Timeline::sharedSize(logSize));
+    Vector<String16> args;
+    size_t numberOfLines = fuzzedDataProvider.ConsumeIntegralInRange<size_t>(0, kMaxNumLines);
+    for (size_t lineIdx = 0; lineIdx < numberOfLines; ++lineIdx) {
+        args.add(static_cast<String16>(fuzzedDataProvider.ConsumeRandomLengthString().c_str()));
+    }
+    const char* fileName = "logDumpFile";
+    int fd = memfd_create(fileName, MFD_ALLOW_SEALING);
+    fuzzedDataProvider.ConsumeData(logBuffer->unsecurePointer(), logBuffer->size());
+    mService->registerWriter(logBuffer, logSize, kWriterNames[writerNameIdx]);
+    if (shouldDumpBeforeUnregister) {
+        mService->dump(fd, args);
+        mService->unregisterWriter(logBuffer);
+    } else {
+        mService->unregisterWriter(logBuffer);
+        mService->dump(fd, args);
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    MediaLogFuzzer mediaLogFuzzer = MediaLogFuzzer();
+    mediaLogFuzzer.init();
+    mediaLogFuzzer.process(data, size);
+    return 0;
+}
diff --git a/services/mediametrics/Android.bp b/services/mediametrics/Android.bp
index 91590e1..3bb70f1 100644
--- a/services/mediametrics/Android.bp
+++ b/services/mediametrics/Android.bp
@@ -111,7 +111,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libmediametricsservice",
     defaults: [
         "mediametrics_flags_defaults",
diff --git a/services/mediametrics/fuzzer/Android.bp b/services/mediametrics/fuzzer/Android.bp
new file mode 100644
index 0000000..df4c867
--- /dev/null
+++ b/services/mediametrics/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: "mediametrics_service_fuzzer",
+
+    srcs: [
+        "mediametrics_service_fuzzer.cpp",
+    ],
+
+    static_libs: [
+        "libmediametrics",
+        "libmediametricsservice",
+        "libplatformprotos",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libcutils",
+        "liblog",
+        "libmedia_helper",
+        "libmediautils",
+        "libmemunreachable",
+        "libprotobuf-cpp-lite",
+        "libstagefright",
+        "libstatslog",
+        "libutils",
+    ],
+
+    include_dirs: [
+        "frameworks/av/services/mediametrics",
+        "system/media/audio_utils/include",
+    ],
+
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
diff --git a/services/mediametrics/fuzzer/README.md b/services/mediametrics/fuzzer/README.md
new file mode 100644
index 0000000..a13830e
--- /dev/null
+++ b/services/mediametrics/fuzzer/README.md
@@ -0,0 +1,54 @@
+# Fuzzer for libmediametricsservice
+
+## Plugin Design Considerations
+The fuzzer plugin for libmediametricsservice is designed based on the
+understanding of the service 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.
+
+Media Metrics Service contains the following modules:
+1. Media Metrics Item Manipulation (module name: `Item`)
+2. Media Metrics Time Machine Storage (module name: `TimeMachineStorage`)
+3. Media Metrics Transaction Log (module name: `TransactionLog`)
+4. Media Metrics Analytics Action (module name: `AnalyticsAction`)
+5. Media Metrics Audio Analytics (module name: `AudioAnalytics`)
+6. Media Metrics Timed Action (module name: `TimedAction`)
+
+| Module| Valid Input Values| Configured Value|
+|------------- |-------------| ----- |
+| `Item` | Key: `std::string`. Values: `INT32_MIN` to `INT32_MAX`, `INT64_MIN` to `INT64_MAX`, `std::string`, `double`, `pair<INT32_MIN to INT32_MAX, INT32_MIN to INT32_MAX>` | Value obtained from FuzzedDataProvider |
+| `TimeMachineStorage`   | Key: `std::string`. Values: `INT32_MIN` to `INT32_MAX`, `INT64_MIN` to `INT64_MAX`, `std::string`, `double`, `pair<INT32_MIN to INT32_MAX, INT32_MIN to INT32_MAX>` | Value obtained from FuzzedDataProvider |
+| `TranscationLog`   | `mediametrics::Item` | `mediametrics::Item` created by obtaining values from FuzzedDataProvider|
+| `AnalyticsAction`   | URL: `std::string` ending with .event, Value: `std::string`, action: A function | URL and Values obtained from FuzzedDataProvider, a placeholder function was passed as action|
+| `AudioAnalytics`   | `mediametrics::Item` | `mediametrics::Item` created by obtaining values from FuzzedDataProvider|
+| `TimedAction`   | time: `std::chrono::seconds`, function: `std::function` | `std::chrono::seconds` : value obtained from FuzzedDataProvider, `std::function`: a placeholder function was used. |
+
+This also ensures that the plugin is always deterministic for any given input.
+
+## Build
+
+This describes steps to build mediametrics_service_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mediametrics_service_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mediametrics_service_fuzzer/mediametrics_service_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp b/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp
new file mode 100644
index 0000000..0cb2594
--- /dev/null
+++ b/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp
@@ -0,0 +1,372 @@
+/******************************************************************************
+ *
+ * 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 <fuzzer/FuzzedDataProvider.h>
+#include <media/MediaMetricsItem.h>
+#include <stdio.h>
+#include <string.h>
+#include <utils/Log.h>
+#include <algorithm>
+
+#include "AudioTypes.h"
+#include "MediaMetricsService.h"
+#include "StringUtils.h"
+
+using namespace android;
+
+// low water mark
+constexpr size_t kLogItemsLowWater = 1;
+// high water mark
+constexpr size_t kLogItemsHighWater = 2;
+
+class MediaMetricsServiceFuzzer {
+   public:
+    void invokeStartsWith(const uint8_t *data, size_t size);
+    void invokeInstantiate(const uint8_t *data, size_t size);
+    void invokePackageInstallerCheck(const uint8_t *data, size_t size);
+    void invokeItemManipulation(const uint8_t *data, size_t size);
+    void invokeItemExpansion(const uint8_t *data, size_t size);
+    void invokeTimeMachineStorage(const uint8_t *data, size_t size);
+    void invokeTransactionLog(const uint8_t *data, size_t size);
+    void invokeAnalyticsAction(const uint8_t *data, size_t size);
+    void invokeAudioAnalytics(const uint8_t *data, size_t size);
+    void invokeTimedAction(const uint8_t *data, size_t size);
+    void process(const uint8_t *data, size_t size);
+};
+
+void MediaMetricsServiceFuzzer::invokeStartsWith(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    while (fdp.remaining_bytes()) {
+        android::mediametrics::startsWith(fdp.ConsumeRandomLengthString(),
+                                          fdp.ConsumeRandomLengthString());
+    }
+}
+
+void MediaMetricsServiceFuzzer::invokeInstantiate(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    sp mediaMetricsService = new MediaMetricsService();
+
+    while (fdp.remaining_bytes()) {
+        std::unique_ptr<mediametrics::Item> random_key(
+            mediametrics::Item::create(fdp.ConsumeRandomLengthString()));
+        mediaMetricsService->submit(random_key.get());
+        random_key->setInt32(fdp.ConsumeRandomLengthString().c_str(),
+                             fdp.ConsumeIntegral<int32_t>());
+        mediaMetricsService->submit(random_key.get());
+
+        std::unique_ptr<mediametrics::Item> audiotrack_key(
+            mediametrics::Item::create("audiotrack"));
+        mediaMetricsService->submit(audiotrack_key.get());
+        audiotrack_key->addInt32(fdp.ConsumeRandomLengthString().c_str(),
+                                 fdp.ConsumeIntegral<int32_t>());
+        mediaMetricsService->submit(audiotrack_key.get());
+    }
+}
+
+void MediaMetricsServiceFuzzer::invokePackageInstallerCheck(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    while (fdp.remaining_bytes()) {
+        MediaMetricsService::useUidForPackage(fdp.ConsumeRandomLengthString().c_str(),
+                                              fdp.ConsumeRandomLengthString().c_str());
+    }
+}
+
+void MediaMetricsServiceFuzzer::invokeItemManipulation(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+    mediametrics::Item item(fdp.ConsumeRandomLengthString().c_str());
+    while (fdp.remaining_bytes()) {
+        const uint8_t action = fdp.ConsumeIntegralInRange<uint8_t>(0, 16);
+        const std::string key = fdp.ConsumeRandomLengthString();
+        if (fdp.remaining_bytes() < 1 || key.length() < 1) {
+            break;
+        }
+        switch (action) {
+            case 0: {
+                item.setInt32(key.c_str(), fdp.ConsumeIntegral<int32_t>());
+                break;
+            }
+            case 1: {
+                item.addInt32(key.c_str(), fdp.ConsumeIntegral<int32_t>());
+                break;
+            }
+            case 2: {
+                int32_t i32 = 0;
+                item.getInt32(key.c_str(), &i32);
+                break;
+            }
+            case 3: {
+                item.setInt64(key.c_str(), fdp.ConsumeIntegral<int64_t>());
+                break;
+            }
+            case 4: {
+                item.addInt64(key.c_str(), fdp.ConsumeIntegral<int64_t>());
+                break;
+            }
+            case 5: {
+                int64_t i64 = 0;
+                item.getInt64(key.c_str(), &i64);
+                break;
+            }
+            case 6: {
+                item.setDouble(key.c_str(), fdp.ConsumeFloatingPoint<double>());
+                break;
+            }
+            case 7: {
+                item.addDouble(key.c_str(), fdp.ConsumeFloatingPoint<double>());
+                break;
+            }
+            case 8: {
+                double d = 0;
+                item.getDouble(key.c_str(), &d);
+                break;
+            }
+            case 9: {
+                item.setCString(key.c_str(), fdp.ConsumeRandomLengthString().c_str());
+                break;
+            }
+            case 10: {
+                char *s = nullptr;
+                item.getCString(key.c_str(), &s);
+                if (s) free(s);
+                break;
+            }
+            case 11: {
+                std::string s;
+                item.getString(key.c_str(), &s);
+                break;
+            }
+            case 12: {
+                item.setRate(key.c_str(), fdp.ConsumeIntegral<int64_t>(),
+                             fdp.ConsumeIntegral<int64_t>());
+                break;
+            }
+            case 13: {
+                int64_t b = 0, h = 0;
+                double d = 0;
+                item.getRate(key.c_str(), &b, &h, &d);
+                break;
+            }
+            case 14: {
+                (void)item.filter(key.c_str());
+                break;
+            }
+            case 15: {
+                const char *arr[1] = {""};
+                arr[0] = const_cast<char *>(key.c_str());
+                (void)item.filterNot(1, arr);
+                break;
+            }
+            case 16: {
+                (void)item.toString().c_str();
+                break;
+            }
+        }
+    }
+
+    Parcel p;
+    mediametrics::Item item2;
+
+    (void)item.writeToParcel(&p);
+    p.setDataPosition(0);  // rewind for reading
+    (void)item2.readFromParcel(p);
+
+    char *byteData = nullptr;
+    size_t length = 0;
+    (void)item.writeToByteString(&byteData, &length);
+    (void)item2.readFromByteString(byteData, length);
+    if (byteData) {
+        free(byteData);
+    }
+
+    sp mediaMetricsService = new MediaMetricsService();
+    mediaMetricsService->submit(&item2);
+}
+
+void MediaMetricsServiceFuzzer::invokeItemExpansion(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+    mediametrics::LogItem<1> item("FuzzItem");
+    item.setPid(fdp.ConsumeIntegral<int16_t>()).setUid(fdp.ConsumeIntegral<int16_t>());
+
+    while (fdp.remaining_bytes()) {
+        int32_t i = fdp.ConsumeIntegral<int32_t>();
+        item.set(std::to_string(i).c_str(), (int32_t)i);
+    }
+    item.updateHeader();
+
+    mediametrics::Item item2;
+    (void)item2.readFromByteString(item.getBuffer(), item.getLength());
+
+    sp mediaMetricsService = new MediaMetricsService();
+    mediaMetricsService->submit(&item2);
+}
+
+void MediaMetricsServiceFuzzer::invokeTimeMachineStorage(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+    auto item = std::make_shared<mediametrics::Item>("FuzzKey");
+    int32_t i32 = fdp.ConsumeIntegral<int32_t>();
+    int64_t i64 = fdp.ConsumeIntegral<int64_t>();
+    double d = fdp.ConsumeFloatingPoint<double>();
+    std::string str = fdp.ConsumeRandomLengthString();
+    std::pair<int64_t, int64_t> pair(fdp.ConsumeIntegral<int64_t>(),
+                                     fdp.ConsumeIntegral<int64_t>());
+    (*item).set("i32", i32).set("i64", i64).set("double", d).set("string", str).set("rate", pair);
+
+    android::mediametrics::TimeMachine timeMachine;
+    timeMachine.put(item, true);
+
+    timeMachine.get("Key", "i32", &i32, -1);
+
+    timeMachine.get("Key", "i64", &i64, -1);
+
+    timeMachine.get("Key", "double", &d, -1);
+
+    timeMachine.get("Key", "string", &str, -1);
+
+    timeMachine.get("Key.i32", &i32, -1);
+
+    timeMachine.get("Key.i64", &i64, -1);
+
+    timeMachine.get("Key.double", &d, -1);
+
+    str.clear();
+    timeMachine.get("Key.string", &str, -1);
+}
+
+void MediaMetricsServiceFuzzer::invokeTransactionLog(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+    auto item = std::make_shared<mediametrics::Item>("Key1");
+    (*item)
+        .set("one", fdp.ConsumeIntegral<int32_t>())
+        .set("two", fdp.ConsumeIntegral<int32_t>())
+        .setTimestamp(fdp.ConsumeIntegral<int32_t>());
+
+    android::mediametrics::TransactionLog transactionLog(
+        kLogItemsLowWater, kLogItemsHighWater);  // keep at most 2 items
+    transactionLog.size();
+
+    transactionLog.put(item);
+    transactionLog.size();
+
+    auto item2 = std::make_shared<mediametrics::Item>("Key2");
+    (*item2)
+        .set("three", fdp.ConsumeIntegral<int32_t>())
+        .set("[Key1]three", fdp.ConsumeIntegral<int32_t>())
+        .setTimestamp(fdp.ConsumeIntegral<int32_t>());
+
+    transactionLog.put(item2);
+    transactionLog.size();
+
+    auto item3 = std::make_shared<mediametrics::Item>("Key3");
+    (*item3)
+        .set("six", fdp.ConsumeIntegral<int32_t>())
+        .set("[Key1]four", fdp.ConsumeIntegral<int32_t>())  // affects Key1
+        .set("[Key1]five", fdp.ConsumeIntegral<int32_t>())  // affects key1
+        .setTimestamp(fdp.ConsumeIntegral<int32_t>());
+
+    transactionLog.put(item3);
+    transactionLog.size();
+}
+
+void MediaMetricsServiceFuzzer::invokeAnalyticsAction(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+    mediametrics::AnalyticsActions analyticsActions;
+    bool action = false;
+
+    while (fdp.remaining_bytes()) {
+        analyticsActions.addAction(
+            (fdp.ConsumeRandomLengthString() + std::string(".event")).c_str(),
+            fdp.ConsumeRandomLengthString(),
+            std::make_shared<mediametrics::AnalyticsActions::Function>(
+                [&](const std::shared_ptr<const android::mediametrics::Item> &) {
+                    action = true;
+                }));
+    }
+
+    FuzzedDataProvider fdp2 = FuzzedDataProvider(data, size);
+
+    while (fdp2.remaining_bytes()) {
+        // make a test item
+        auto item = std::make_shared<mediametrics::Item>(fdp2.ConsumeRandomLengthString().c_str());
+        (*item).set("event", fdp2.ConsumeRandomLengthString().c_str());
+
+        // get the actions and execute them
+        auto actions = analyticsActions.getActionsForItem(item);
+        for (const auto &action : actions) {
+            action->operator()(item);
+        }
+    }
+}
+
+void MediaMetricsServiceFuzzer::invokeAudioAnalytics(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    android::mediametrics::AudioAnalytics audioAnalytics;
+
+    while (fdp.remaining_bytes()) {
+        auto item = std::make_shared<mediametrics::Item>(fdp.ConsumeRandomLengthString().c_str());
+        int32_t transactionUid = fdp.ConsumeIntegral<int32_t>();  // arbitrary
+        (*item)
+            .set(fdp.ConsumeRandomLengthString().c_str(), fdp.ConsumeIntegral<int32_t>())
+            .set(fdp.ConsumeRandomLengthString().c_str(), fdp.ConsumeIntegral<int32_t>())
+            .set(AMEDIAMETRICS_PROP_ALLOWUID, transactionUid)
+            .setUid(transactionUid)
+            .setTimestamp(fdp.ConsumeIntegral<int32_t>());
+        audioAnalytics.submit(item, fdp.ConsumeBool());
+    }
+
+    audioAnalytics.dump(1000);
+}
+
+void MediaMetricsServiceFuzzer::invokeTimedAction(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    android::mediametrics::TimedAction timedAction;
+    std::atomic_int value = 0;
+
+    while (fdp.remaining_bytes()) {
+        timedAction.postIn(std::chrono::seconds(fdp.ConsumeIntegral<int32_t>()),
+                           [&value] { ++value; });
+        timedAction.size();
+    }
+}
+
+void MediaMetricsServiceFuzzer::process(const uint8_t *data, size_t size) {
+    invokeStartsWith(data, size);
+    invokeInstantiate(data, size);
+    invokePackageInstallerCheck(data, size);
+    invokeItemManipulation(data, size);
+    invokeItemExpansion(data, size);
+    invokeTimeMachineStorage(data, size);
+    invokeTransactionLog(data, size);
+    invokeAnalyticsAction(data, size);
+    invokeAudioAnalytics(data, size);
+    invokeTimedAction(data, size);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+    if (size < 1) {
+        return 0;
+    }
+    MediaMetricsServiceFuzzer mediaMetricsServiceFuzzer;
+    mediaMetricsServiceFuzzer.process(data, size);
+    return 0;
+}
diff --git a/services/mediametrics/statsd_audiopolicy.cpp b/services/mediametrics/statsd_audiopolicy.cpp
index 393c6ae..6ef2f2c 100644
--- a/services/mediametrics/statsd_audiopolicy.cpp
+++ b/services/mediametrics/statsd_audiopolicy.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_audiorecord.cpp b/services/mediametrics/statsd_audiorecord.cpp
index 43feda1..76f4b59 100644
--- a/services/mediametrics/statsd_audiorecord.cpp
+++ b/services/mediametrics/statsd_audiorecord.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_audiothread.cpp b/services/mediametrics/statsd_audiothread.cpp
index e867f5b..2ad2562 100644
--- a/services/mediametrics/statsd_audiothread.cpp
+++ b/services/mediametrics/statsd_audiothread.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_audiotrack.cpp b/services/mediametrics/statsd_audiotrack.cpp
index ee5b9b2..6b08a78 100644
--- a/services/mediametrics/statsd_audiotrack.cpp
+++ b/services/mediametrics/statsd_audiotrack.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_codec.cpp b/services/mediametrics/statsd_codec.cpp
index ec9354f..d502b30 100644
--- a/services/mediametrics/statsd_codec.cpp
+++ b/services/mediametrics/statsd_codec.cpp
@@ -33,7 +33,7 @@
 
 #include "cleaner.h"
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_extractor.cpp b/services/mediametrics/statsd_extractor.cpp
index 3d5739f..4180e0c 100644
--- a/services/mediametrics/statsd_extractor.cpp
+++ b/services/mediametrics/statsd_extractor.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
@@ -71,6 +71,22 @@
         metrics_proto.set_tracks(ntrk);
     }
 
+    // android.media.mediaextractor.entry       string
+    std::string entry_point_string;
+    if (item->getString("android.media.mediaextractor.entry", &entry_point_string)) {
+      stats::mediametrics::ExtractorData::EntryPoint entry_point;
+      if (entry_point_string == "sdk") {
+        entry_point = stats::mediametrics::ExtractorData_EntryPoint_SDK;
+      } else if (entry_point_string == "ndk-with-jvm") {
+        entry_point = stats::mediametrics::ExtractorData_EntryPoint_NDK_WITH_JVM;
+      } else if (entry_point_string == "ndk-no-jvm") {
+        entry_point = stats::mediametrics::ExtractorData_EntryPoint_NDK_NO_JVM;
+      } else {
+        entry_point = stats::mediametrics::ExtractorData_EntryPoint_OTHER;
+      }
+      metrics_proto.set_entry_point(entry_point);
+    }
+
     std::string serialized;
     if (!metrics_proto.SerializeToString(&serialized)) {
         ALOGE("Failed to serialize extractor metrics");
diff --git a/services/mediametrics/statsd_mediaparser.cpp b/services/mediametrics/statsd_mediaparser.cpp
index 3258ebf..262b2ae 100644
--- a/services/mediametrics/statsd_mediaparser.cpp
+++ b/services/mediametrics/statsd_mediaparser.cpp
@@ -31,7 +31,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_nuplayer.cpp b/services/mediametrics/statsd_nuplayer.cpp
index 488bdcb..a8d0f55 100644
--- a/services/mediametrics/statsd_nuplayer.cpp
+++ b/services/mediametrics/statsd_nuplayer.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediametrics/statsd_recorder.cpp b/services/mediametrics/statsd_recorder.cpp
index 6d5fca0..2e5ada4 100644
--- a/services/mediametrics/statsd_recorder.cpp
+++ b/services/mediametrics/statsd_recorder.cpp
@@ -32,7 +32,7 @@
 #include <statslog.h>
 
 #include "MediaMetricsService.h"
-#include "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.pb.h"
+#include "frameworks/proto_logging/stats/enums/stats/mediametrics/mediametrics.pb.h"
 #include "iface_statsd.h"
 
 namespace android {
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 32ac583..289cffd 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -22,6 +22,7 @@
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <binder/IMediaResourceMonitor.h>
+#include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <cutils/sched_policy.h>
 #include <dirent.h>
@@ -96,7 +97,7 @@
 
     service->overridePid(mPid, -1);
     // thiz is freed in the call below, so it must be last call referring thiz
-    service->removeResource(mPid, mClientId, false);
+    service->removeResource(mPid, mClientId, false /*checkValid*/);
 }
 
 class OverrideProcessInfoDeathNotifier : public DeathNotifier {
@@ -422,8 +423,12 @@
 
     Mutex::Autolock lock(mLock);
     if (!mProcessInfo->isValidPid(pid)) {
-        ALOGE("Rejected addResource call with invalid pid.");
-        return Status::fromServiceSpecificError(BAD_VALUE);
+        pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
+        ALOGW("%s called with untrusted pid %d, using calling pid %d, uid %d", __FUNCTION__,
+                pid, callingPid, callingUid);
+        pid = callingPid;
+        uid = callingUid;
     }
     ResourceInfos& infos = getResourceInfosForEdit(pid, mMap);
     ResourceInfo& info = getResourceInfoForEdit(uid, clientId, client, infos);
@@ -477,8 +482,10 @@
 
     Mutex::Autolock lock(mLock);
     if (!mProcessInfo->isValidPid(pid)) {
-        ALOGE("Rejected removeResource call with invalid pid.");
-        return Status::fromServiceSpecificError(BAD_VALUE);
+        pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
+                pid, callingPid);
+        pid = callingPid;
     }
     ssize_t index = mMap.indexOfKey(pid);
     if (index < 0) {
@@ -531,7 +538,7 @@
 }
 
 Status ResourceManagerService::removeClient(int32_t pid, int64_t clientId) {
-    removeResource(pid, clientId, true);
+    removeResource(pid, clientId, true /*checkValid*/);
     return Status::ok();
 }
 
@@ -543,8 +550,10 @@
 
     Mutex::Autolock lock(mLock);
     if (checkValid && !mProcessInfo->isValidPid(pid)) {
-        ALOGE("Rejected removeResource call with invalid pid.");
-        return Status::fromServiceSpecificError(BAD_VALUE);
+        pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
+                pid, callingPid);
+        pid = callingPid;
     }
     ssize_t index = mMap.indexOfKey(pid);
     if (index < 0) {
@@ -599,8 +608,10 @@
     {
         Mutex::Autolock lock(mLock);
         if (!mProcessInfo->isValidPid(callingPid)) {
-            ALOGE("Rejected reclaimResource call with invalid callingPid.");
-            return Status::fromServiceSpecificError(BAD_VALUE);
+            pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
+            ALOGW("%s called with untrusted pid %d, using actual calling pid %d", __FUNCTION__,
+                    callingPid, actualCallingPid);
+            callingPid = actualCallingPid;
         }
         const MediaResourceParcel *secureCodec = NULL;
         const MediaResourceParcel *nonSecureCodec = NULL;
@@ -836,8 +847,10 @@
 
     Mutex::Autolock lock(mLock);
     if (!mProcessInfo->isValidPid(pid)) {
-        ALOGE("Rejected markClientForPendingRemoval call with invalid pid.");
-        return Status::fromServiceSpecificError(BAD_VALUE);
+        pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
+                pid, callingPid);
+        pid = callingPid;
     }
     ssize_t index = mMap.indexOfKey(pid);
     if (index < 0) {
@@ -866,8 +879,10 @@
     {
         Mutex::Autolock lock(mLock);
         if (!mProcessInfo->isValidPid(pid)) {
-            ALOGE("Rejected reclaimResourcesFromClientsPendingRemoval call with invalid pid.");
-            return Status::fromServiceSpecificError(BAD_VALUE);
+            pid_t callingPid = IPCThreadState::self()->getCallingPid();
+            ALOGW("%s called with untrusted pid %d, using calling pid %d", __FUNCTION__,
+                    pid, callingPid);
+            pid = callingPid;
         }
 
         for (MediaResource::Type type : {MediaResource::Type::kSecureCodec,
diff --git a/services/mediaresourcemanager/ResourceObserverService.cpp b/services/mediaresourcemanager/ResourceObserverService.cpp
index 44fe72d..9cc6fe4 100644
--- a/services/mediaresourcemanager/ResourceObserverService.cpp
+++ b/services/mediaresourcemanager/ResourceObserverService.cpp
@@ -27,14 +27,6 @@
 
 #include "ResourceObserverService.h"
 
-namespace aidl {
-namespace android {
-namespace media {
-bool operator<(const MediaObservableFilter& lhs, const MediaObservableFilter &rhs) {
-    return lhs.type < rhs.type || (lhs.type == rhs.type && lhs.eventFilter < rhs.eventFilter);
-}
-}}} // namespace ::aidl::android::media
-
 namespace android {
 
 using ::aidl::android::media::MediaResourceParcel;
diff --git a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
index 4cf5f0a..8e29312 100644
--- a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
+++ b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
@@ -23,15 +23,6 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/ProcessInfoInterface.h>
 
-namespace aidl {
-namespace android {
-namespace media {
-bool operator== (const MediaResourceParcel& lhs, const MediaResourceParcel& rhs) {
-    return lhs.type == rhs.type && lhs.subType == rhs.subType &&
-            lhs.id == rhs.id && lhs.value == rhs.value;
-}
-}}}
-
 namespace android {
 
 using Status = ::ndk::ScopedAStatus;
diff --git a/services/mediaresourcemanager/test/ResourceObserverService_test.cpp b/services/mediaresourcemanager/test/ResourceObserverService_test.cpp
index 4c26246..e3d3e78 100644
--- a/services/mediaresourcemanager/test/ResourceObserverService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceObserverService_test.cpp
@@ -25,14 +25,6 @@
 #include "ResourceObserverService.h"
 #include "ResourceManagerServiceTestUtils.h"
 
-namespace aidl {
-namespace android {
-namespace media {
-bool operator==(const MediaObservableParcel& lhs, const MediaObservableParcel& rhs) {
-    return lhs.type == rhs.type && lhs.value == rhs.value;
-}
-}}} // namespace ::aidl::android::media
-
 namespace android {
 
 using ::aidl::android::media::BnResourceObserver;
diff --git a/services/mediatranscoding/Android.bp b/services/mediatranscoding/Android.bp
index 2dbcf5a..3d6821b 100644
--- a/services/mediatranscoding/Android.bp
+++ b/services/mediatranscoding/Android.bp
@@ -8,8 +8,8 @@
     ],
 
     shared_libs: [
+        "libandroid",
         "libbase",
-        "libbinder",
         "libbinder_ndk",
         "libcutils",
         "liblog",
@@ -40,8 +40,7 @@
 
     shared_libs: [
         "libbase",
-        // TODO(hkuang): Use libbinder_ndk
-        "libbinder",
+        "libbinder_ndk",
         "libutils",
         "liblog",
         "libbase",
diff --git a/services/mediatranscoding/MediaTranscodingService.cpp b/services/mediatranscoding/MediaTranscodingService.cpp
index 56f327e..64def5e 100644
--- a/services/mediatranscoding/MediaTranscodingService.cpp
+++ b/services/mediatranscoding/MediaTranscodingService.cpp
@@ -20,7 +20,7 @@
 
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
-#include <binder/IServiceManager.h>
+#include <android/permission_manager.h>
 #include <cutils/properties.h>
 #include <media/TranscoderWrapper.h>
 #include <media/TranscodingClientManager.h>
@@ -60,8 +60,12 @@
 binder_status_t MediaTranscodingService::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) {
     String8 result;
 
-    // TODO(b/161549994): Remove libbinder dependencies for mainline.
-    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+    uid_t callingUid = AIBinder_getCallingUid();
+    pid_t callingPid = AIBinder_getCallingPid();
+    int32_t permissionResult;
+    if (APermissionManager_checkPermission("android.permission.DUMP", callingPid, callingUid,
+                                           &permissionResult) != PERMISSION_MANAGER_STATUS_OK ||
+        permissionResult != PERMISSION_MANAGER_PERMISSION_GRANTED) {
         result.format(
                 "Permission Denial: "
                 "can't dump MediaTranscodingService from pid=%d, uid=%d\n",
diff --git a/services/mediatranscoding/main_mediatranscodingservice.cpp b/services/mediatranscoding/main_mediatranscodingservice.cpp
index 7d862e6..14c568e 100644
--- a/services/mediatranscoding/main_mediatranscodingservice.cpp
+++ b/services/mediatranscoding/main_mediatranscodingservice.cpp
@@ -15,8 +15,7 @@
  */
 
 #include <android-base/logging.h>
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
+#include <android/binder_process.h>
 
 #include "MediaTranscodingService.h"
 
@@ -25,12 +24,9 @@
 int main(int argc __unused, char** argv) {
     LOG(INFO) << "media transcoding service starting";
 
-    // TODO(hkuang): Start the service with libbinder_ndk.
     strcpy(argv[0], "media.transcoding");
-    sp<ProcessState> proc(ProcessState::self());
-    sp<IServiceManager> sm = defaultServiceManager();
     android::MediaTranscodingService::instantiate();
 
-    ProcessState::self()->startThreadPool();
-    IPCThreadState::self()->joinThreadPool();
+    ABinderProcess_startThreadPool();
+    ABinderProcess_joinThreadPool();
 }
diff --git a/services/mediatranscoding/tests/Android.bp b/services/mediatranscoding/tests/Android.bp
index 6497685..5a7c4cc 100644
--- a/services/mediatranscoding/tests/Android.bp
+++ b/services/mediatranscoding/tests/Android.bp
@@ -24,6 +24,7 @@
 
     static_libs: [
         "mediatranscoding_aidl_interface-ndk_platform",
+        "resourcemanager_aidl_interface-ndk_platform",
     ],
 
     required: [
diff --git a/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h b/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
index f4d3ff8..66cced5 100644
--- a/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
+++ b/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
@@ -176,17 +176,19 @@
         std::unique_lock lock(mLock);
 
         auto startTime = std::chrono::system_clock::now();
+        int64_t remainingUs = timeoutUs;
 
         std::list<Event>::iterator it;
         while (((it = std::find(mEventQueue.begin(), mEventQueue.end(), target)) ==
                 mEventQueue.end()) &&
-               timeoutUs > 0) {
-            std::cv_status status = mCondition.wait_for(lock, std::chrono::microseconds(timeoutUs));
+               remainingUs > 0) {
+            std::cv_status status =
+                    mCondition.wait_for(lock, std::chrono::microseconds(remainingUs));
             if (status == std::cv_status::timeout) {
                 break;
             }
             std::chrono::microseconds elapsedTime = std::chrono::system_clock::now() - startTime;
-            timeoutUs -= elapsedTime.count();
+            remainingUs = timeoutUs - elapsedTime.count();
         }
 
         if (it == mEventQueue.end()) {
diff --git a/services/mediatranscoding/tests/build_and_run_all_unit_tests.sh b/services/mediatranscoding/tests/build_and_run_all_unit_tests.sh
index 1b42a22..edf6778 100755
--- a/services/mediatranscoding/tests/build_and_run_all_unit_tests.sh
+++ b/services/mediatranscoding/tests/build_and_run_all_unit_tests.sh
@@ -14,7 +14,7 @@
 mm
 
 # Push the files onto the device.
-. $ANDROID_BUILD_TOP/frameworks/av/media/libmediatranscoding/tests/assets/push_assets.sh
+. $ANDROID_BUILD_TOP/frameworks/av/media/libmediatranscoding/tests/push_assets.sh
 
 echo "[==========] installing test apps"
 adb root
diff --git a/services/mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp b/services/mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp
index bf99efc..790e80b 100644
--- a/services/mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp
+++ b/services/mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp
@@ -17,7 +17,11 @@
 // Unit Test for MediaTranscodingService.
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "MediaTranscodingServiceRealTest"
+#define LOG_TAG "MediaTranscodingServiceResourceTest"
+
+#include <aidl/android/media/BnResourceManagerClient.h>
+#include <aidl/android/media/IResourceManagerService.h>
+#include <binder/ActivityManager.h>
 
 #include "MediaTranscodingServiceTestHelper.h"
 
@@ -43,6 +47,60 @@
 
 #define OUTPATH(name) "/data/local/tmp/MediaTranscodingService_" #name ".MP4"
 
+/*
+ * The OOM score we're going to ask ResourceManager to use for our native transcoding
+ * service. ResourceManager issues reclaims based on these scores. It gets the scores
+ * from ActivityManagerService, which doesn't track native services. The values of the
+ * OOM scores are defined in:
+ * frameworks/base/services/core/java/com/android/server/am/ProcessList.java
+ * We use SERVICE_ADJ which is lower priority than an app possibly visible to the
+ * user, but higher priority than a cached app (which could be killed without disruption
+ * to the user).
+ */
+constexpr static int32_t SERVICE_ADJ = 500;
+
+using Status = ::ndk::ScopedAStatus;
+using aidl::android::media::BnResourceManagerClient;
+using aidl::android::media::IResourceManagerService;
+
+/*
+ * Placeholder ResourceManagerClient for registering process info override
+ * with the IResourceManagerService. This is only used as a token by the service
+ * to get notifications about binder death, not used for reclaiming resources.
+ */
+struct ResourceManagerClient : public BnResourceManagerClient {
+    explicit ResourceManagerClient() = default;
+
+    Status reclaimResource(bool* _aidl_return) override {
+        *_aidl_return = false;
+        return Status::ok();
+    }
+
+    Status getName(::std::string* _aidl_return) override {
+        _aidl_return->clear();
+        return Status::ok();
+    }
+
+    virtual ~ResourceManagerClient() = default;
+};
+
+static std::shared_ptr<ResourceManagerClient> gResourceManagerClient =
+        ::ndk::SharedRefBase::make<ResourceManagerClient>();
+
+void TranscodingHelper_setProcessInfoOverride(int32_t procState, int32_t oomScore) {
+    ::ndk::SpAIBinder binder(AServiceManager_getService("media.resource_manager"));
+    std::shared_ptr<IResourceManagerService> service = IResourceManagerService::fromBinder(binder);
+    if (service == nullptr) {
+        ALOGE("Failed to get IResourceManagerService");
+        return;
+    }
+    Status status =
+            service->overrideProcessInfo(gResourceManagerClient, getpid(), procState, oomScore);
+    if (!status.isOk()) {
+        ALOGW("Failed to setProcessInfoOverride.");
+    }
+}
+
 class MediaTranscodingServiceResourceTest : public MediaTranscodingServiceTestBase {
 public:
     MediaTranscodingServiceResourceTest() { ALOGI("MediaTranscodingServiceResourceTest created"); }
@@ -62,9 +120,20 @@
  * cause the session to be paused. The activity will hold the codecs for a few seconds
  * before releasing them, and the transcoding service should be able to resume
  * and complete the session.
+ *
+ * Note that this test must run as root. We need to simulate submitting a request for a
+ * client {uid,pid} running at lower priority. As a cmd line test, it's not easy to get the
+ * pid of a living app, so we use our own {uid,pid} to submit. However, since we're a native
+ * process, RM doesn't have our proc info and the reclaim will fail. So we need to use
+ * RM's setProcessInfoOverride to override our proc info, which requires permission (unless root).
  */
 TEST_F(MediaTranscodingServiceResourceTest, TestResourceLost) {
-    ALOGD("TestResourceLost starting...");
+    ALOGD("TestResourceLost starting..., pid %d", ::getpid());
+
+    // We're going to submit the request using our own {uid,pid}. Since we're a native
+    // process, RM doesn't have our proc info and the reclaim will fail. So we need to use
+    // RM's setProcessInfoOverride to override our proc info.
+    TranscodingHelper_setProcessInfoOverride(ActivityManager::PROCESS_STATE_SERVICE, SERVICE_ADJ);
 
     EXPECT_TRUE(ShellHelper::RunCmd("input keyevent KEYCODE_WAKEUP"));
     EXPECT_TRUE(ShellHelper::RunCmd("wm dismiss-keyguard"));
@@ -81,8 +150,8 @@
 
     // Submit session to Client1.
     ALOGD("Submitting session to client1 (app A) ...");
-    EXPECT_TRUE(
-            mClient1->submit(0, srcPath0, dstPath0, TranscodingSessionPriority::kNormal, kBitRate));
+    EXPECT_TRUE(mClient1->submit(0, srcPath0, dstPath0, TranscodingSessionPriority::kNormal,
+                                 kBitRate, ::getpid(), ::getuid()));
 
     // Client1's session should start immediately.
     EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 5bccfd5..85b2057 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -72,24 +72,46 @@
 
 aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamRequest &request) {
     aaudio_result_t result = AAUDIO_OK;
-    audio_config_base_t config;
-    audio_port_handle_t deviceId;
-
     copyFrom(request.getConstantConfiguration());
-
-    const audio_attributes_t attributes = getAudioAttributesFrom(this);
-
     mMmapClient.clientUid = request.getUserId();
     mMmapClient.clientPid = request.getProcessId();
     mMmapClient.packageName.setTo(String16(""));
 
+    audio_format_t audioFormat = getFormat();
+
+    // FLOAT is not directly supported by the HAL so ask for a 24-bit.
+    bool isHighResRequested = audioFormat == AUDIO_FORMAT_PCM_FLOAT
+            || audioFormat == AUDIO_FORMAT_PCM_32_BIT;
+    if (isHighResRequested) {
+        // TODO remove these logs when finished debugging.
+        ALOGD("%s() change format from %d to 24_BIT_PACKED", __func__, audioFormat);
+        audioFormat = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    }
+
+    result = openWithFormat(audioFormat);
+    if (result == AAUDIO_OK) return result;
+
+    // TODO The HAL and AudioFlinger should be recommending a format if the open fails.
+    //      But that recommendation is not propagating back from the HAL.
+    //      So for now just try something very likely to work.
+    if (result == AAUDIO_ERROR_UNAVAILABLE && audioFormat == AUDIO_FORMAT_PCM_24_BIT_PACKED) {
+        ALOGD("%s() 24_BIT failed, perhaps due to format. Try again with 16_BIT", __func__);
+        audioFormat = AUDIO_FORMAT_PCM_16_BIT;
+        result = openWithFormat(audioFormat);
+    }
+    return result;
+}
+
+aaudio_result_t AAudioServiceEndpointMMAP::openWithFormat(audio_format_t audioFormat) {
+    aaudio_result_t result = AAUDIO_OK;
+    audio_config_base_t config;
+    audio_port_handle_t deviceId;
+
+    const audio_attributes_t attributes = getAudioAttributesFrom(this);
+
     mRequestedDeviceId = deviceId = getDeviceId();
 
     // Fill in config
-    audio_format_t audioFormat = getFormat();
-    if (audioFormat == AUDIO_FORMAT_DEFAULT || audioFormat == AUDIO_FORMAT_PCM_FLOAT) {
-        audioFormat = AUDIO_FORMAT_PCM_16_BIT;
-    }
     config.format = audioFormat;
 
     int32_t aaudioSampleRate = getSampleRate();
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h
index a2a0922..24b161d 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.h
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.h
@@ -88,6 +88,9 @@
     aaudio_result_t getExternalPosition(uint64_t *positionFrames, int64_t *timeNanos);
 
 private:
+
+    aaudio_result_t openWithFormat(audio_format_t audioFormat);
+
     MonotonicCounter                          mFramesTransferred;
 
     // Interface to the AudioFlinger MMAP support.
diff --git a/services/tuner/Android.bp b/services/tuner/Android.bp
index 0562b45..65d8d41 100644
--- a/services/tuner/Android.bp
+++ b/services/tuner/Android.bp
@@ -1,7 +1,34 @@
 filegroup {
     name: "tv_tuner_aidl",
     srcs: [
+        "aidl/android/media/tv/tuner/ITunerFrontend.aidl",
+        "aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl",
         "aidl/android/media/tv/tuner/ITunerService.aidl",
+        "aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendAnalogCapabilities.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendAtscCapabilities.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendAtsc3Capabilities.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendCableCapabilities.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendCapabilities.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendDvbsCapabilities.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendDvbtCapabilities.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendIsdbsCapabilities.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendIsdbs3Capabilities.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendIsdbtCapabilities.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendAnalogSettings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendAtsc3PlpSettings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendAtsc3Settings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendAtscSettings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendCableSettings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendDvbsCodeRate.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendDvbsSettings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendDvbtSettings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendIsdbs3Settings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendIsdbsSettings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendIsdbtSettings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendSettings.aidl",
+        "aidl/android/media/tv/tuner/TunerFrontendStatus.aidl",
+        "aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl",
     ],
     path: "aidl",
 }
@@ -20,6 +47,7 @@
 
     srcs: [
         "TunerService.cpp",
+        "TunerFrontend.cpp"
     ],
 
     shared_libs: [
@@ -70,4 +98,4 @@
         "-Werror",
         "-Wall",
     ],
-}
\ No newline at end of file
+}
diff --git a/services/tuner/TunerFrontend.cpp b/services/tuner/TunerFrontend.cpp
new file mode 100644
index 0000000..ba4553b
--- /dev/null
+++ b/services/tuner/TunerFrontend.cpp
@@ -0,0 +1,463 @@
+/**
+ * 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.
+ */
+
+#define LOG_TAG "TunerFrontend"
+
+#include "TunerFrontend.h"
+#include "TunerService.h"
+
+using ::aidl::android::media::tv::tuner::TunerAtsc3PlpInfo;
+using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3PlpSettings;
+using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard;
+using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType;
+using ::android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
+using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Bandwidth;
+using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3CodeRate;
+using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3DemodOutputFormat;
+using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Fec;
+using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Modulation;
+using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3TimeInterleaveMode;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbcAnnex;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbcModulation;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbcOuterFec;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbcSpectralInversion;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbsModulation;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbsPilot;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbsRolloff;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbsSettings;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbsStandard;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbsVcmMode;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbtPlpMode;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
+using ::android::hardware::tv::tuner::V1_0::FrontendInnerFec;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Coderate;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Modulation;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Rolloff;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Settings;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsCoderate;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsModulation;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsRolloff;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsSettings;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsStreamIdType;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtBandwidth;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtCoderate;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtGuardInterval;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtMode;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtModulation;
+using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings;
+using ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo;
+using ::android::hardware::tv::tuner::V1_0::FrontendScanType;
+using ::android::hardware::tv::tuner::V1_0::FrontendSettings;;
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+namespace android {
+
+TunerFrontend::TunerFrontend(sp<ITuner> tuner, int frontendHandle) {
+    mTuner = tuner;
+    mId = TunerService::getResourceIdFromHandle(frontendHandle);
+
+    if (mTuner != NULL) {
+        Result status;
+        mTuner->openFrontendById(mId, [&](Result result, const sp<IFrontend>& frontend) {
+            mFrontend = frontend;
+            status = result;
+        });
+        if (status != Result::SUCCESS) {
+            mFrontend = NULL;
+        }
+    }
+}
+
+TunerFrontend::~TunerFrontend() {}
+
+Status TunerFrontend::setCallback(
+        const std::shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) {
+    if (mFrontend == NULL) {
+        ALOGE("IFrontend is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    if (tunerFrontendCallback == NULL) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_ARGUMENT));
+    }
+
+    sp<IFrontendCallback> frontendCallback = new FrontendCallback(tunerFrontendCallback);
+    Result status = mFrontend->setCallback(frontendCallback);
+    if (status == Result::SUCCESS) {
+        return Status::ok();
+    }
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+Status TunerFrontend::tune(const TunerFrontendSettings& /*settings*/) {
+    return Status::ok();
+}
+
+Status TunerFrontend::stopTune() {
+    return Status::ok();
+}
+
+Status TunerFrontend::scan(const TunerFrontendSettings& settings, int frontendScanType) {
+    if (mFrontend == NULL) {
+        ALOGD("IFrontend is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    FrontendSettings frontendSettings;
+    switch (settings.getTag()) {
+        case TunerFrontendSettings::analog:
+            frontendSettings.analog({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::analog>().frequency),
+                .type = static_cast<FrontendAnalogType>(
+                        settings.get<TunerFrontendSettings::analog>().signalType),
+                .sifStandard = static_cast<FrontendAnalogSifStandard>(
+                        settings.get<TunerFrontendSettings::analog>().sifStandard),
+            });
+            break;
+        case TunerFrontendSettings::atsc:
+            frontendSettings.atsc({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::atsc>().frequency),
+                .modulation = static_cast<FrontendAtscModulation>(
+                        settings.get<TunerFrontendSettings::atsc>().modulation),
+            });
+            break;
+        case TunerFrontendSettings::atsc3:
+            frontendSettings.atsc3({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::atsc3>().frequency),
+                .bandwidth = static_cast<FrontendAtsc3Bandwidth>(
+                        settings.get<TunerFrontendSettings::atsc3>().bandwidth),
+                .demodOutputFormat = static_cast<FrontendAtsc3DemodOutputFormat>(
+                        settings.get<TunerFrontendSettings::atsc3>().demodOutputFormat),
+                .plpSettings = getAtsc3PlpSettings(settings.get<TunerFrontendSettings::atsc3>()),
+            });
+            break;
+        case TunerFrontendSettings::cable:
+            frontendSettings.dvbc({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::cable>().frequency),
+                .modulation = static_cast<FrontendDvbcModulation>(
+                        settings.get<TunerFrontendSettings::cable>().modulation),
+                .fec = static_cast<FrontendInnerFec>(
+                        settings.get<TunerFrontendSettings::cable>().innerFec),
+                .symbolRate = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::cable>().symbolRate),
+                .outerFec = static_cast<FrontendDvbcOuterFec>(
+                        settings.get<TunerFrontendSettings::cable>().outerFec),
+                .annex = static_cast<FrontendDvbcAnnex>(
+                        settings.get<TunerFrontendSettings::cable>().annex),
+                .spectralInversion = static_cast<FrontendDvbcSpectralInversion>(
+                        settings.get<TunerFrontendSettings::cable>().spectralInversion),
+            });
+            break;
+        case TunerFrontendSettings::dvbs:
+            frontendSettings.dvbs({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::dvbs>().frequency),
+                .modulation = static_cast<FrontendDvbsModulation>(
+                        settings.get<TunerFrontendSettings::dvbs>().modulation),
+                .coderate = getDvbsCodeRate(
+                        settings.get<TunerFrontendSettings::dvbs>().codeRate),
+                .symbolRate = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::dvbs>().symbolRate),
+                .rolloff = static_cast<FrontendDvbsRolloff>(
+                        settings.get<TunerFrontendSettings::dvbs>().rolloff),
+                .pilot = static_cast<FrontendDvbsPilot>(
+                        settings.get<TunerFrontendSettings::dvbs>().pilot),
+                .inputStreamId = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::dvbs>().inputStreamId),
+                .standard = static_cast<FrontendDvbsStandard>(
+                        settings.get<TunerFrontendSettings::dvbs>().standard),
+                .vcmMode = static_cast<FrontendDvbsVcmMode>(
+                        settings.get<TunerFrontendSettings::dvbs>().vcm),
+            });
+            break;
+        case TunerFrontendSettings::dvbt:
+            frontendSettings.dvbt({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::dvbt>().frequency),
+                .transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
+                        settings.get<TunerFrontendSettings::dvbt>().transmissionMode),
+                .bandwidth = static_cast<FrontendDvbtBandwidth>(
+                        settings.get<TunerFrontendSettings::dvbt>().bandwidth),
+                .constellation = static_cast<FrontendDvbtConstellation>(
+                        settings.get<TunerFrontendSettings::dvbt>().constellation),
+                .hierarchy = static_cast<FrontendDvbtHierarchy>(
+                        settings.get<TunerFrontendSettings::dvbt>().hierarchy),
+                .hpCoderate = static_cast<FrontendDvbtCoderate>(
+                        settings.get<TunerFrontendSettings::dvbt>().hpCodeRate),
+                .lpCoderate = static_cast<FrontendDvbtCoderate>(
+                        settings.get<TunerFrontendSettings::dvbt>().lpCodeRate),
+                .guardInterval = static_cast<FrontendDvbtGuardInterval>(
+                        settings.get<TunerFrontendSettings::dvbt>().guardInterval),
+                .isHighPriority = settings.get<TunerFrontendSettings::dvbt>().isHighPriority,
+                .standard = static_cast<FrontendDvbtStandard>(
+                        settings.get<TunerFrontendSettings::dvbt>().standard),
+                .isMiso = settings.get<TunerFrontendSettings::dvbt>().isMiso,
+                .plpMode = static_cast<FrontendDvbtPlpMode>(
+                        settings.get<TunerFrontendSettings::dvbt>().plpMode),
+                .plpId = static_cast<uint8_t>(
+                        settings.get<TunerFrontendSettings::dvbt>().plpId),
+                .plpGroupId = static_cast<uint8_t>(
+                        settings.get<TunerFrontendSettings::dvbt>().plpGroupId),
+            });
+            break;
+        case TunerFrontendSettings::isdbs:
+            frontendSettings.isdbs({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbs>().frequency),
+                .streamId = static_cast<uint16_t>(
+                        settings.get<TunerFrontendSettings::isdbs>().streamId),
+                .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
+                        settings.get<TunerFrontendSettings::isdbs>().streamIdType),
+                .modulation = static_cast<FrontendIsdbsModulation>(
+                        settings.get<TunerFrontendSettings::isdbs>().modulation),
+                .coderate = static_cast<FrontendIsdbsCoderate>(
+                        settings.get<TunerFrontendSettings::isdbs>().codeRate),
+                .symbolRate = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbs>().symbolRate),
+                .rolloff = static_cast<FrontendIsdbsRolloff>(
+                        settings.get<TunerFrontendSettings::isdbs>().rolloff),
+            });
+            break;
+        case TunerFrontendSettings::isdbs3:
+            frontendSettings.isdbs3({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbs3>().frequency),
+                .streamId = static_cast<uint16_t>(
+                        settings.get<TunerFrontendSettings::isdbs3>().streamId),
+                .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
+                        settings.get<TunerFrontendSettings::isdbs3>().streamIdType),
+                .modulation = static_cast<FrontendIsdbs3Modulation>(
+                        settings.get<TunerFrontendSettings::isdbs3>().modulation),
+                .coderate = static_cast<FrontendIsdbs3Coderate>(
+                        settings.get<TunerFrontendSettings::isdbs3>().codeRate),
+                .symbolRate = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbs3>().symbolRate),
+                .rolloff = static_cast<FrontendIsdbs3Rolloff>(
+                        settings.get<TunerFrontendSettings::isdbs3>().rolloff),
+            });
+            break;
+        case TunerFrontendSettings::isdbt:
+            frontendSettings.isdbt({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbt>().frequency),
+                .modulation = static_cast<FrontendIsdbtModulation>(
+                        settings.get<TunerFrontendSettings::isdbt>().modulation),
+                .bandwidth = static_cast<FrontendIsdbtBandwidth>(
+                        settings.get<TunerFrontendSettings::isdbt>().bandwidth),
+                .mode = static_cast<FrontendIsdbtMode>(
+                        settings.get<TunerFrontendSettings::isdbt>().mode),
+                .coderate = static_cast<FrontendIsdbtCoderate>(
+                        settings.get<TunerFrontendSettings::isdbt>().codeRate),
+                .guardInterval = static_cast<FrontendIsdbtGuardInterval>(
+                        settings.get<TunerFrontendSettings::isdbt>().guardInterval),
+                .serviceAreaId = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbt>().serviceAreaId),
+            });
+            break;
+        default:
+            break;
+    }
+    Result status = mFrontend->scan(
+            frontendSettings, static_cast<FrontendScanType>(frontendScanType));
+    if (status == Result::SUCCESS) {
+        return Status::ok();
+    }
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+Status TunerFrontend::stopScan() {
+    return Status::ok();
+}
+
+Status TunerFrontend::setLnb(int /*lnbHandle*/) {
+    return Status::ok();
+}
+
+Status TunerFrontend::setLna(bool /*bEnable*/) {
+    return Status::ok();
+}
+
+Status TunerFrontend::close() {
+    return Status::ok();
+}
+
+Status TunerFrontend::getStatus(const std::vector<int32_t>& /*statusTypes*/,
+		std::vector<TunerFrontendStatus>* /*_aidl_return*/) {
+    return Status::ok();
+}
+
+/////////////// FrontendCallback ///////////////////////
+
+Return<void> TunerFrontend::FrontendCallback::onEvent(FrontendEventType frontendEventType) {
+    ALOGD("FrontendCallback::onEvent, type=%d", frontendEventType);
+    mTunerFrontendCallback->onEvent((int)frontendEventType);
+    return Void();
+}
+
+Return<void> TunerFrontend::FrontendCallback::onScanMessage(
+        FrontendScanMessageType type, const FrontendScanMessage& message) {
+    ALOGD("FrontendCallback::onScanMessage, type=%d", type);
+    switch(type) {
+        case FrontendScanMessageType::LOCKED: {
+            if (message.isLocked()) {
+                mTunerFrontendCallback->onLocked();
+            }
+            break;
+        }
+        case FrontendScanMessageType::END: {
+            if (message.isEnd()) {
+                mTunerFrontendCallback->onScanStopped();
+            }
+            break;
+        }
+        case FrontendScanMessageType::PROGRESS_PERCENT: {
+            mTunerFrontendCallback->onProgress((int)message.progressPercent());
+            break;
+        }
+        case FrontendScanMessageType::FREQUENCY: {
+            auto f = message.frequencies();
+            std::vector<int32_t> frequencies(std::begin(f), std::end(f));
+            mTunerFrontendCallback->onFrequenciesReport(frequencies);
+            break;
+        }
+        case FrontendScanMessageType::SYMBOL_RATE: {
+            auto s = message.symbolRates();
+            std::vector<int32_t> symbolRates(std::begin(s), std::end(s));
+            mTunerFrontendCallback->onSymbolRates(symbolRates);
+            break;
+        }
+        case FrontendScanMessageType::HIERARCHY: {
+            mTunerFrontendCallback->onHierarchy((int)message.hierarchy());
+            break;
+        }
+        case FrontendScanMessageType::ANALOG_TYPE: {
+            mTunerFrontendCallback->onSignalType((int)message.analogType());
+            break;
+        }
+        case FrontendScanMessageType::PLP_IDS: {
+            auto p = message.plpIds();
+            std::vector<int32_t> plpIds(std::begin(p), std::end(p));
+            mTunerFrontendCallback->onPlpIds(plpIds);
+            break;
+        }
+        case FrontendScanMessageType::GROUP_IDS: {
+            auto g = message.groupIds();
+            std::vector<int32_t> groupIds(std::begin(g), std::end(g));
+            mTunerFrontendCallback->onGroupIds(groupIds);
+            break;
+        }
+        case FrontendScanMessageType::INPUT_STREAM_IDS: {
+            auto i = message.inputStreamIds();
+            std::vector<int32_t> streamIds(std::begin(i), std::end(i));
+            mTunerFrontendCallback->onInputStreamIds(streamIds);
+            break;
+        }
+        case FrontendScanMessageType::STANDARD: {
+            FrontendScanMessage::Standard std = message.std();
+            int standard;
+            if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sStd) {
+                standard = (int) std.sStd();
+                mTunerFrontendCallback->onDvbsStandard(standard);
+            } else if (std.getDiscriminator() ==
+                    FrontendScanMessage::Standard::hidl_discriminator::tStd) {
+                standard = (int) std.tStd();
+                mTunerFrontendCallback->onDvbsStandard(standard);
+            } else if (std.getDiscriminator() ==
+                    FrontendScanMessage::Standard::hidl_discriminator::sifStd) {
+                standard = (int) std.sifStd();
+                mTunerFrontendCallback->onAnalogSifStandard(standard);
+            }
+            break;
+        }
+        case FrontendScanMessageType::ATSC3_PLP_INFO: {
+            std::vector<FrontendScanAtsc3PlpInfo> plpInfos = message.atsc3PlpInfos();
+            std::vector<TunerAtsc3PlpInfo> tunerPlpInfos;
+            for (int i = 0; i < plpInfos.size(); i++) {
+                auto info = plpInfos[i];
+                int plpId = (int) info.plpId;
+                bool lls = (bool) info.bLlsFlag;
+                TunerAtsc3PlpInfo plpInfo{
+                    .plpId = plpId,
+                    .llsFlag = lls,
+                };
+                tunerPlpInfos.push_back(plpInfo);
+            }
+            mTunerFrontendCallback->onAtsc3PlpInfos(tunerPlpInfos);
+            break;
+        }
+        default:
+            break;
+    }
+    return Void();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+hidl_vec<FrontendAtsc3PlpSettings> TunerFrontend::getAtsc3PlpSettings(
+        const TunerFrontendAtsc3Settings& settings) {
+    int len = settings.plpSettings.size();
+    hidl_vec<FrontendAtsc3PlpSettings> plps = hidl_vec<FrontendAtsc3PlpSettings>(len);
+    // parse PLP settings
+    for (int i = 0; i < len; i++) {
+        uint8_t plpId = static_cast<uint8_t>(settings.plpSettings[i].plpId);
+        FrontendAtsc3Modulation modulation =
+                static_cast<FrontendAtsc3Modulation>(settings.plpSettings[i].modulation);
+        FrontendAtsc3TimeInterleaveMode interleaveMode =
+                static_cast<FrontendAtsc3TimeInterleaveMode>(
+                        settings.plpSettings[i].interleaveMode);
+        FrontendAtsc3CodeRate codeRate =
+                static_cast<FrontendAtsc3CodeRate>(settings.plpSettings[i].codeRate);
+        FrontendAtsc3Fec fec =
+                static_cast<FrontendAtsc3Fec>(settings.plpSettings[i].fec);
+        FrontendAtsc3PlpSettings frontendAtsc3PlpSettings {
+                .plpId = plpId,
+                .modulation = modulation,
+                .interleaveMode = interleaveMode,
+                .codeRate = codeRate,
+                .fec = fec,
+        };
+        plps[i] = frontendAtsc3PlpSettings;
+    }
+    return plps;
+}
+
+FrontendDvbsCodeRate TunerFrontend::getDvbsCodeRate(const TunerFrontendDvbsCodeRate& codeRate) {
+    FrontendInnerFec innerFec = static_cast<FrontendInnerFec>(codeRate.fec);
+    bool isLinear = codeRate.isLinear;
+    bool isShortFrames = codeRate.isShortFrames;
+    uint32_t bitsPer1000Symbol = static_cast<uint32_t>(codeRate.bitsPer1000Symbol);
+    FrontendDvbsCodeRate coderate {
+            .fec = innerFec,
+            .isLinear = isLinear,
+            .isShortFrames = isShortFrames,
+            .bitsPer1000Symbol = bitsPer1000Symbol,
+    };
+    return coderate;
+}
+}  // namespace android
diff --git a/services/tuner/TunerFrontend.h b/services/tuner/TunerFrontend.h
new file mode 100644
index 0000000..c7d3ddd
--- /dev/null
+++ b/services/tuner/TunerFrontend.h
@@ -0,0 +1,87 @@
+/**
+ * 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.
+ */
+
+#ifndef ANDROID_MEDIA_TUNERFRONTEND_H
+#define ANDROID_MEDIA_TUNERFRONTEND_H
+
+#include <aidl/android/media/tv/tuner/BnTunerFrontend.h>
+#include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <utils/Log.h>
+
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::tv::tuner::BnTunerFrontend;
+using ::aidl::android::media::tv::tuner::ITunerFrontendCallback;
+using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3Settings;
+using ::aidl::android::media::tv::tuner::TunerFrontendDvbsCodeRate;
+using ::aidl::android::media::tv::tuner::TunerFrontendSettings;
+using ::aidl::android::media::tv::tuner::TunerFrontendStatus;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3PlpSettings;
+using ::android::hardware::tv::tuner::V1_0::FrontendDvbsCodeRate;
+using ::android::hardware::tv::tuner::V1_0::FrontendEventType;
+using ::android::hardware::tv::tuner::V1_0::FrontendId;
+using ::android::hardware::tv::tuner::V1_0::FrontendScanMessage;
+using ::android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
+using ::android::hardware::tv::tuner::V1_0::IFrontend;
+using ::android::hardware::tv::tuner::V1_0::IFrontendCallback;
+using ::android::hardware::tv::tuner::V1_0::ITuner;
+
+
+namespace android {
+
+class TunerFrontend : public BnTunerFrontend {
+
+public:
+    TunerFrontend(sp<ITuner> tuner, int frontendHandle);
+    virtual ~TunerFrontend();
+    Status setCallback(
+            const std::shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) override;
+    Status tune(const TunerFrontendSettings& settings) override;
+    Status stopTune() override;
+    Status scan(const TunerFrontendSettings& settings, int frontendScanType) override;
+    Status stopScan() override;
+    Status setLnb(int lnbHandle) override;
+    Status setLna(bool bEnable) override;
+    Status close() override;
+    Status getStatus(const std::vector<int32_t>& statusTypes,
+            std::vector<TunerFrontendStatus>* _aidl_return) override;
+
+    struct FrontendCallback : public IFrontendCallback {
+        FrontendCallback(const std::shared_ptr<ITunerFrontendCallback> tunerFrontendCallback)
+                : mTunerFrontendCallback(tunerFrontendCallback) {};
+
+        virtual Return<void> onEvent(FrontendEventType frontendEventType);
+        virtual Return<void> onScanMessage(
+                FrontendScanMessageType type, const FrontendScanMessage& message);
+
+        std::shared_ptr<ITunerFrontendCallback> mTunerFrontendCallback;
+    };
+
+private:
+    hidl_vec<FrontendAtsc3PlpSettings> getAtsc3PlpSettings(
+            const TunerFrontendAtsc3Settings& settings);
+    FrontendDvbsCodeRate getDvbsCodeRate(const TunerFrontendDvbsCodeRate& codeRate);
+    int mId;
+    sp<ITuner> mTuner;
+    sp<IFrontend> mFrontend;
+};
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_TUNERFRONTEND_H
diff --git a/services/tuner/TunerService.cpp b/services/tuner/TunerService.cpp
index 92008a9..2b3de17 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -18,10 +18,22 @@
 
 #include <android/binder_manager.h>
 #include <utils/Log.h>
+#include "TunerFrontend.h"
 #include "TunerService.h"
 
+using ::aidl::android::media::tv::tuner::TunerFrontendAnalogCapabilities;
+using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3Capabilities;
+using ::aidl::android::media::tv::tuner::TunerFrontendAtscCapabilities;
+using ::aidl::android::media::tv::tuner::TunerFrontendCableCapabilities;
+using ::aidl::android::media::tv::tuner::TunerFrontendCapabilities;
+using ::aidl::android::media::tv::tuner::TunerFrontendDvbsCapabilities;
+using ::aidl::android::media::tv::tuner::TunerFrontendDvbtCapabilities;
+using ::aidl::android::media::tv::tuner::TunerFrontendIsdbs3Capabilities;
+using ::aidl::android::media::tv::tuner::TunerFrontendIsdbsCapabilities;
+using ::aidl::android::media::tv::tuner::TunerFrontendIsdbtCapabilities;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::tv::tuner::V1_0::FrontendId;
+using ::android::hardware::tv::tuner::V1_0::FrontendType;
 using ::android::hardware::tv::tuner::V1_0::Result;
 
 namespace android {
@@ -35,17 +47,17 @@
     std::shared_ptr<TunerService> service =
             ::ndk::SharedRefBase::make<TunerService>();
     AServiceManager_addService(service->asBinder().get(), getServiceName());
+    mTuner = ITuner::getService();
+    if (mTuner == nullptr) {
+        ALOGE("Failed to get ITuner service.");
+    }
 }
 
 Status TunerService::getFrontendIds(std::vector<int32_t>* ids, int32_t* /* _aidl_return */) {
     if (mTuner == nullptr) {
-        // TODO: create a method for init.
-        mTuner = ITuner::getService();
-        if (mTuner == nullptr) {
-            ALOGE("Failed to get ITuner service.");
-            return ::ndk::ScopedAStatus::fromServiceSpecificError(
-                    static_cast<int32_t>(Result::UNAVAILABLE));
-        }
+        ALOGE("ITuner service is not init.");
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::UNAVAILABLE));
     }
     hidl_vec<FrontendId> feIds;
     Result res;
@@ -59,7 +71,154 @@
     ids->resize(feIds.size());
     std::copy(feIds.begin(), feIds.end(), ids->begin());
 
-    return ::ndk::ScopedAStatus::ok();
+    return Status::ok();
 }
 
+Status TunerService::getFrontendInfo(
+        int32_t frontendHandle, TunerServiceFrontendInfo* _aidl_return) {
+    if (mTuner == nullptr) {
+        ALOGE("ITuner service is not init.");
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res;
+    FrontendInfo info;
+    int feId = getResourceIdFromHandle(frontendHandle);
+    mTuner->getFrontendInfo(feId, [&](Result r, const FrontendInfo& feInfo) {
+        info = feInfo;
+        res = r;
+    });
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+
+    TunerServiceFrontendInfo tunerInfo = convertToAidlFrontendInfo(feId, info);
+    *_aidl_return = tunerInfo;
+    return Status::ok();
+}
+
+Status TunerService::openFrontend(
+        int32_t frontendHandle, std::shared_ptr<ITunerFrontend>* _aidl_return) {
+    if (mTuner == nullptr) {
+        ALOGE("ITuner service is not init.");
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    *_aidl_return = ::ndk::SharedRefBase::make<TunerFrontend>(mTuner, frontendHandle);
+    return Status::ok();
+}
+
+TunerServiceFrontendInfo TunerService::convertToAidlFrontendInfo(int feId, FrontendInfo halInfo) {
+    TunerServiceFrontendInfo info{
+        .id = feId,
+        .type = (int)halInfo.type,
+        .minFrequency = (int)halInfo.minFrequency,
+        .maxFrequency = (int)halInfo.maxFrequency,
+        .minSymbolRate = (int)halInfo.minSymbolRate,
+        .maxSymbolRate = (int)halInfo.maxSymbolRate,
+        .acquireRange = (int)halInfo.acquireRange,
+        .exclusiveGroupId = (int)halInfo.exclusiveGroupId,
+    };
+    for (int i = 0; i < halInfo.statusCaps.size(); i++) {
+        info.statusCaps.push_back((int)halInfo.statusCaps[i]);
+    }
+
+    TunerFrontendCapabilities caps;
+    switch (halInfo.type) {
+        case FrontendType::ANALOG: {
+            TunerFrontendAnalogCapabilities analogCaps{
+                .typeCap = (int)halInfo.frontendCaps.analogCaps().typeCap,
+                .sifStandardCap = (int)halInfo.frontendCaps.analogCaps().sifStandardCap,
+            };
+            caps.set<TunerFrontendCapabilities::analogCaps>(analogCaps);
+            break;
+        }
+        case FrontendType::ATSC: {
+            TunerFrontendAtscCapabilities atscCaps{
+                .modulationCap = (int)halInfo.frontendCaps.atscCaps().modulationCap,
+            };
+            caps.set<TunerFrontendCapabilities::atscCaps>(atscCaps);
+            break;
+        }
+        case FrontendType::ATSC3: {
+            TunerFrontendAtsc3Capabilities atsc3Caps{
+                .bandwidthCap = (int)halInfo.frontendCaps.atsc3Caps().bandwidthCap,
+                .modulationCap = (int)halInfo.frontendCaps.atsc3Caps().modulationCap,
+                .timeInterleaveModeCap =
+                        (int)halInfo.frontendCaps.atsc3Caps().timeInterleaveModeCap,
+                .codeRateCap = (int)halInfo.frontendCaps.atsc3Caps().codeRateCap,
+                .demodOutputFormatCap = (int)halInfo.frontendCaps.atsc3Caps().demodOutputFormatCap,
+                .fecCap = (int)halInfo.frontendCaps.atsc3Caps().fecCap,
+            };
+            caps.set<TunerFrontendCapabilities::atsc3Caps>(atsc3Caps);
+            break;
+        }
+        case FrontendType::DVBC: {
+            TunerFrontendCableCapabilities cableCaps{
+                .modulationCap = (int)halInfo.frontendCaps.dvbcCaps().modulationCap,
+                .codeRateCap = (int)halInfo.frontendCaps.dvbcCaps().fecCap,
+                .annexCap = (int)halInfo.frontendCaps.dvbcCaps().annexCap,
+            };
+            caps.set<TunerFrontendCapabilities::cableCaps>(cableCaps);
+            break;
+        }
+        case FrontendType::DVBS: {
+            TunerFrontendDvbsCapabilities dvbsCaps{
+                .modulationCap = (int)halInfo.frontendCaps.dvbsCaps().modulationCap,
+                .codeRateCap = (long)halInfo.frontendCaps.dvbsCaps().innerfecCap,
+                .standard = (int)halInfo.frontendCaps.dvbsCaps().standard,
+            };
+            caps.set<TunerFrontendCapabilities::dvbsCaps>(dvbsCaps);
+            break;
+        }
+        case FrontendType::DVBT: {
+            TunerFrontendDvbtCapabilities dvbtCaps{
+                .transmissionModeCap = (int)halInfo.frontendCaps.dvbtCaps().transmissionModeCap,
+                .bandwidthCap = (int)halInfo.frontendCaps.dvbtCaps().bandwidthCap,
+                .constellationCap = (int)halInfo.frontendCaps.dvbtCaps().constellationCap,
+                .codeRateCap = (int)halInfo.frontendCaps.dvbtCaps().coderateCap,
+                .hierarchyCap = (int)halInfo.frontendCaps.dvbtCaps().hierarchyCap,
+                .guardIntervalCap = (int)halInfo.frontendCaps.dvbtCaps().guardIntervalCap,
+                .isT2Supported = (bool)halInfo.frontendCaps.dvbtCaps().isT2Supported,
+                .isMisoSupported = (bool)halInfo.frontendCaps.dvbtCaps().isMisoSupported,
+            };
+            caps.set<TunerFrontendCapabilities::dvbtCaps>(dvbtCaps);
+            break;
+        }
+        case FrontendType::ISDBS: {
+            TunerFrontendIsdbsCapabilities isdbsCaps{
+                .modulationCap = (int)halInfo.frontendCaps.isdbsCaps().modulationCap,
+                .codeRateCap = (int)halInfo.frontendCaps.isdbsCaps().coderateCap,
+            };
+            caps.set<TunerFrontendCapabilities::isdbsCaps>(isdbsCaps);
+            break;
+        }
+        case FrontendType::ISDBS3: {
+            TunerFrontendIsdbs3Capabilities isdbs3Caps{
+                .modulationCap = (int)halInfo.frontendCaps.isdbs3Caps().modulationCap,
+                .codeRateCap = (int)halInfo.frontendCaps.isdbs3Caps().coderateCap,
+            };
+            caps.set<TunerFrontendCapabilities::isdbs3Caps>(isdbs3Caps);
+            break;
+        }
+        case FrontendType::ISDBT: {
+            TunerFrontendIsdbtCapabilities isdbtCaps{
+                .modeCap = (int)halInfo.frontendCaps.isdbtCaps().modeCap,
+                .bandwidthCap = (int)halInfo.frontendCaps.isdbtCaps().bandwidthCap,
+                .modulationCap = (int)halInfo.frontendCaps.isdbtCaps().modulationCap,
+                .codeRateCap = (int)halInfo.frontendCaps.isdbtCaps().coderateCap,
+                .guardIntervalCap = (int)halInfo.frontendCaps.isdbtCaps().guardIntervalCap,
+            };
+            caps.set<TunerFrontendCapabilities::isdbtCaps>(isdbtCaps);
+            break;
+        }
+        default:
+            break;
+    }
+
+    info.caps = caps;
+    return info;
+}
 } // namespace android
diff --git a/services/tuner/TunerService.h b/services/tuner/TunerService.h
index bda6c65..36ccd3e 100644
--- a/services/tuner/TunerService.h
+++ b/services/tuner/TunerService.h
@@ -18,10 +18,14 @@
 #define ANDROID_MEDIA_TUNERSERVICE_H
 
 #include <aidl/android/media/tv/tuner/BnTunerService.h>
+#include <aidl/android/media/tv/tuner/TunerServiceFrontendInfo.h>
 #include <android/hardware/tv/tuner/1.0/ITuner.h>
 
 using Status = ::ndk::ScopedAStatus;
 using ::aidl::android::media::tv::tuner::BnTunerService;
+using ::aidl::android::media::tv::tuner::ITunerFrontend;
+using ::aidl::android::media::tv::tuner::TunerServiceFrontendInfo;
+using ::android::hardware::tv::tuner::V1_0::FrontendInfo;
 using ::android::hardware::tv::tuner::V1_0::ITuner;
 
 namespace android {
@@ -33,10 +37,20 @@
     static void instantiate();
     TunerService();
     virtual ~TunerService();
+
+    static int getResourceIdFromHandle(int resourceHandle) {
+        return (resourceHandle & 0x00ff0000) >> 16;
+    }
+
     Status getFrontendIds(std::vector<int32_t>* ids, int32_t* _aidl_return) override;
+    Status getFrontendInfo(int32_t frontendHandle, TunerServiceFrontendInfo* _aidl_return) override;
+    Status openFrontend(
+            int32_t frontendHandle, std::shared_ptr<ITunerFrontend>* _aidl_return) override;
 
 private:
     static sp<ITuner> mTuner;
+
+    TunerServiceFrontendInfo convertToAidlFrontendInfo(int feId, FrontendInfo halInfo);
 };
 
 } // namespace android
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
new file mode 100644
index 0000000..08d20a9
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
@@ -0,0 +1,85 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.ITunerFrontendCallback;
+import android.media.tv.tuner.TunerFrontendSettings;
+import android.media.tv.tuner.TunerFrontendStatus;
+import android.media.tv.tuner.TunerServiceFrontendInfo;
+
+/**
+ * Tuner Frontend interface handles tuner related operations.
+ *
+ * {@hide}
+ */
+interface ITunerFrontend {
+    /**
+     * Set the frontend callback.
+     *
+     * @param tunerFrontendCallback the callback to receive frontend related info.
+     */
+    void setCallback(in ITunerFrontendCallback tunerFrontendCallback);
+
+    /**
+     * Tunes the frontend to using the settings given.
+     *
+     * @param settings the settings to tune with.
+     */
+    void tune(in TunerFrontendSettings settings);
+
+    /**
+     * Stop the previous tuning.
+     */
+    void stopTune();
+
+    /**
+     * Scan the frontend to use the settings given.
+     *
+     * @param settings the settings to scan with.
+     * @param frontendScanType scan with given type.
+     */
+    void scan(in TunerFrontendSettings settings, in int frontendScanType);
+
+    /**
+     * Stop the previous scanning.
+     */
+    void stopScan();
+
+    /**
+     * Sets Low-Noise Block downconverter (LNB) for satellite frontend.
+     *
+     * @param lnbHandle lnb handle in use.
+     */
+    void setLnb(in int lnbHandle);
+
+    /**
+     * Enable or Disable Low Noise Amplifier (LNA).
+     *
+     * @param bEnable enable Lna or not.
+     */
+    void setLna(in boolean bEnable);
+
+    /**
+     * Releases the ITunerFrontend instance.
+     */
+    void close();
+
+    /**
+     * Gets the statuses of the frontend.
+     */
+    TunerFrontendStatus[] getStatus(in int[] statusTypes);
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl
new file mode 100644
index 0000000..ae62c15
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl
@@ -0,0 +1,96 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.TunerAtsc3PlpInfo;
+
+/**
+ * TunerFrontendCallback interface handles tuner frontend related callbacks.
+ *
+ * {@hide}
+ */
+interface ITunerFrontendCallback {
+    /**
+     * Notify the client that a new event happened on the frontend.
+     */
+    void onEvent(in int frontendEventType);
+
+    /**
+     * notify locked message to client from the ongoing scan.
+     */
+    void onLocked();
+
+    /**
+     * notify scan stopped message to client from the ongoing scan.
+     */
+    void onScanStopped();
+
+    /**
+     * notify progress message to client from the ongoing scan.
+     */
+    void onProgress(in int percent);
+
+    /**
+     * notify Frequencies message to client from the ongoing scan.
+     */
+    void onFrequenciesReport(in int[] frequency);
+
+    /**
+     * notify SymbolRates message to client from the ongoing scan.
+     */
+    void onSymbolRates(in int[] rates);
+
+    /**
+     * notify Hierarchy message to client from the ongoing scan.
+     */
+    void onHierarchy(in int hierarchy);
+
+    /**
+     * notify SignalType message to client from the ongoing scan.
+     */
+    void onSignalType(in int signalType);
+
+    /**
+     * notify PlpIds message to client from the ongoing scan.
+     */
+    void onPlpIds(in int[] plpIds);
+
+    /**
+     * notify GroupIds message to client from the ongoing scan.
+     */
+    void onGroupIds(in int[] groupIds);
+
+    /**
+     * notify InputStreamIds message to client from the ongoing scan.
+     */
+    void onInputStreamIds(in int[] inputStreamIds);
+
+    /**
+     * notify DvbsStandard message to client from the ongoing scan.
+     */
+    void onDvbsStandard(in int dvbsStandandard);
+
+    /**
+     * notify AnalogSifStandard message to client from the ongoing scan.
+     */
+    void onAnalogSifStandard(in int sifStandandard);
+
+    /**
+     * notify Atsc3PlpInfos message to client from the ongoing scan.
+     */
+    void onAtsc3PlpInfos(in TunerAtsc3PlpInfo[] atsc3PlpInfos);
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
index 53cd90d..5a0b47d 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
@@ -16,6 +16,9 @@
 
 package android.media.tv.tuner;
 
+import android.media.tv.tuner.ITunerFrontend;
+import android.media.tv.tuner.TunerServiceFrontendInfo;
+
 /**
  * TunerService interface handles tuner related operations.
  *
@@ -29,4 +32,20 @@
      * @return the result code of the operation.
      */
     int getFrontendIds(out int[] ids);
+
+    /**
+     * Retrieve the frontend's information.
+     *
+     * @param frontendHandle the handle of the frontend granted by TRM.
+     * @return the information of the frontend.
+     */
+    TunerServiceFrontendInfo getFrontendInfo(in int frontendHandle);
+
+    /**
+     * Open a Tuner Frontend interface.
+     *
+     * @param frontendHandle the handle of the frontend granted by TRM.
+     * @return the aidl interface of the frontend.
+     */
+    ITunerFrontend openFrontend(in int frontendHandle);
 }
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl
similarity index 64%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl
index d6e46cb..a0648a5 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright 2018 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,15 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.tv.tuner;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * Atsc3 Frontend Physical Layer Pipe Info.
+ *
+ * {@hide}
+ */
+parcelable TunerAtsc3PlpInfo {
+    int plpId;
+
+    boolean llsFlag;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAnalogCapabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAnalogCapabilities.aidl
new file mode 100644
index 0000000..74bf04e
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAnalogCapabilities.aidl
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Analog Frontend Capabilities interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendAnalogCapabilities {
+	/**
+     * Signal Type capability
+     */
+    int typeCap;
+
+    /**
+     * Standard Interchange Format (SIF) capability
+     */
+    int sifStandardCap;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAnalogSettings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAnalogSettings.aidl
new file mode 100644
index 0000000..b6d07c3
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAnalogSettings.aidl
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Analog Frontend Settings interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendAnalogSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    int signalType;
+
+    /**
+     * Standard Interchange Format (SIF) setting
+     */
+    int sifStandard;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtsc3Capabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtsc3Capabilities.aidl
new file mode 100644
index 0000000..6c9be77
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtsc3Capabilities.aidl
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * ATSC3 Frontend Capabilities interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendAtsc3Capabilities {
+    /**
+     * Bandwidth capability
+     */
+    int bandwidthCap;
+
+    /**
+     * Modulation capability
+     */
+    int modulationCap;
+
+    /**
+     * TimeInterleaveMode capability
+     */
+    int timeInterleaveModeCap;
+
+    /**
+     * CodeRate capability
+     */
+    int codeRateCap;
+
+    /**
+     * FEC capability
+     */
+    int fecCap;
+
+    /**
+     * Demodulator Output Format capability
+     */
+    int demodOutputFormatCap;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtsc3PlpSettings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtsc3PlpSettings.aidl
new file mode 100644
index 0000000..b29e1f7
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtsc3PlpSettings.aidl
@@ -0,0 +1,37 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Atsc3 Frontend Physical Layer Pipe Settings interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendAtsc3PlpSettings {
+    int plpId;
+
+    int modulation;
+
+    int interleaveMode;
+
+    int codeRate;
+
+    /**
+     * Forward Error Correction Type.
+     */
+    int fec;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtsc3Settings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtsc3Settings.aidl
new file mode 100644
index 0000000..32fb8c7
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtsc3Settings.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.TunerFrontendAtsc3PlpSettings;
+
+/**
+ * Atsc3 Frontend Settings interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendAtsc3Settings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Bandwidth of tuning band.
+     */
+    int bandwidth;
+
+    int demodOutputFormat;
+
+    TunerFrontendAtsc3PlpSettings[] plpSettings;
+}
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtscCapabilities.aidl
similarity index 61%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtscCapabilities.aidl
index d6e46cb..2b6c2fc 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtscCapabilities.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright 2018 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,16 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.tv.tuner;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * ATSC Frontend Capabilities interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendAtscCapabilities {
+    /**
+     * Modulation capability
+     */
+    int modulationCap;
+}
\ No newline at end of file
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtscSettings.aidl
similarity index 60%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtscSettings.aidl
index d6e46cb..c7a8c07 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendAtscSettings.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright 2018 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,18 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.tv.tuner;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * Atsc Frontend Settings interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendAtscSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    int modulation;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCableCapabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCableCapabilities.aidl
new file mode 100644
index 0000000..7df452a
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCableCapabilities.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Cable(DVBC) Frontend Capabilities interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendCableCapabilities {
+    /**
+     * Modulation capability
+     */
+    int modulationCap;
+
+    /**
+     * Code Rate capability
+     */
+    int codeRateCap; // inner FEC will converge to codeRate
+
+    /**
+     * Annex capability
+     */
+    int annexCap;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCableSettings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCableSettings.aidl
new file mode 100644
index 0000000..3984f2c
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCableSettings.aidl
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Cable Frontend Settings interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendCableSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    int modulation;
+
+    /**
+     * Inner Forward Error Correction type as specified in ETSI EN 300 468 V1.15.1
+     * and ETSI EN 302 307-2 V1.1.1.
+     */
+    long innerFec;
+
+    /**
+     * Symbols per second
+     */
+    int symbolRate;
+
+    /**
+     * Outer Forward Error Correction (FEC) Type.
+     */
+    int outerFec;
+
+    int annex;
+
+    /**
+     * Spectral Inversion Type.
+     */
+    int spectralInversion;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCapabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCapabilities.aidl
new file mode 100644
index 0000000..19f31f1
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCapabilities.aidl
@@ -0,0 +1,85 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.TunerFrontendAnalogCapabilities;
+import android.media.tv.tuner.TunerFrontendAtscCapabilities;
+import android.media.tv.tuner.TunerFrontendAtsc3Capabilities;
+import android.media.tv.tuner.TunerFrontendCableCapabilities;
+import android.media.tv.tuner.TunerFrontendDvbsCapabilities;
+import android.media.tv.tuner.TunerFrontendDvbtCapabilities;
+import android.media.tv.tuner.TunerFrontendIsdbsCapabilities;
+import android.media.tv.tuner.TunerFrontendIsdbs3Capabilities;
+import android.media.tv.tuner.TunerFrontendIsdbtCapabilities;
+
+/**
+ * Frontend Capabilities interface.
+ *
+ * Use a group of vectors as the workaround for Union structure that is not fully supported
+ * in AIDL currently.
+ *
+ * Client may use FrontendInfo.type as the discriminar to check the corresponding vector. If
+ * the vector is not null, it contains valid value.
+ *
+ * {@hide}
+ */
+union TunerFrontendCapabilities {
+    /**
+     * Analog Frontend Capabilities
+     */
+    TunerFrontendAnalogCapabilities analogCaps;
+
+    /**
+     * ATSC Frontend Capabilities
+     */
+    TunerFrontendAtscCapabilities atscCaps;
+
+    /**
+     * ATSC3 Frontend Capabilities
+     */
+    TunerFrontendAtsc3Capabilities atsc3Caps;
+
+    /**
+     * Cable Frontend Capabilities
+     */
+    TunerFrontendCableCapabilities cableCaps;
+
+    /**
+     * DVBS Frontend Capabilities
+     */
+    TunerFrontendDvbsCapabilities dvbsCaps;
+
+    /**
+     * DVBT Frontend Capabilities
+     */
+    TunerFrontendDvbtCapabilities dvbtCaps;
+
+    /**
+     * ISDB-S Frontend Capabilities
+     */
+    TunerFrontendIsdbsCapabilities isdbsCaps;
+
+    /**
+     * ISDB-S3 Frontend Capabilities
+     */
+    TunerFrontendIsdbs3Capabilities isdbs3Caps;
+
+    /**
+     * ISDB-T Frontend Capabilities
+     */
+    TunerFrontendIsdbtCapabilities isdbtCaps;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbsCapabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbsCapabilities.aidl
new file mode 100644
index 0000000..5e4322c
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbsCapabilities.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * DVBS Frontend Capabilities interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendDvbsCapabilities {
+    /**
+     * Modulation capability
+     */
+    int modulationCap;
+
+    /**
+     * Code Rate capability
+     */
+    long codeRateCap;  // inner FEC will converge to codeRate
+
+    /**
+     * Sub standards capability
+     */
+    int standard;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbsCodeRate.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbsCodeRate.aidl
new file mode 100644
index 0000000..59b7de3
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbsCodeRate.aidl
@@ -0,0 +1,42 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Dvbs Frontend CodeRate interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendDvbsCodeRate {
+    /**
+     * Inner Forward Error Correction type as specified in ETSI EN 300 468 V1.15.1
+     * and ETSI EN 302 307-2 V1.1.1.
+     */
+    long fec;
+
+    boolean isLinear;
+
+    /**
+     * true if enable short frame
+     */
+    boolean isShortFrames;
+
+    /**
+     * bits number in 1000 symbol. 0 if use the default.
+     */
+    int bitsPer1000Symbol;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbsSettings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbsSettings.aidl
new file mode 100644
index 0000000..554a502
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbsSettings.aidl
@@ -0,0 +1,56 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.TunerFrontendDvbsCodeRate;
+
+/**
+ * Dvbs Frontend Settings interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendDvbsSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    int modulation;
+
+    TunerFrontendDvbsCodeRate codeRate;
+
+    int symbolRate;
+
+    /**
+     * Roll off type.
+     */
+    int rolloff;
+
+    /**
+     * Pilot mode.
+     */
+    int pilot;
+
+    int inputStreamId;
+
+    int standard;
+
+    /**
+     * Vcm mode.
+     */
+    int vcm;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbtCapabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbtCapabilities.aidl
new file mode 100644
index 0000000..73f16dd
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbtCapabilities.aidl
@@ -0,0 +1,64 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * DVBT Frontend Capabilities interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendDvbtCapabilities {
+    /**
+     * Transmission Mode capability
+     */
+    int transmissionModeCap;
+
+    /**
+     * Bandwidth capability
+     */
+    int bandwidthCap;
+
+    /**
+     * Constellation capability
+     */
+    int constellationCap;
+
+    /**
+     * Code Rate capability
+     */
+    int codeRateCap;
+
+    /**
+     * Hierarchy Type capability
+     */
+    int hierarchyCap;
+
+    /**
+     * Guard Interval capability
+     */
+    int guardIntervalCap;
+
+    /**
+     * T2 Support capability
+     */
+    boolean isT2Supported;
+
+    /**
+     * Miso Support capability
+     */
+    boolean isMisoSupported;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbtSettings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbtSettings.aidl
new file mode 100644
index 0000000..c72396b
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDvbtSettings.aidl
@@ -0,0 +1,70 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Dvbt Frontend Settings interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendDvbtSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    int transmissionMode;
+
+    int bandwidth;
+
+    int constellation;
+
+    int hierarchy;
+
+    /**
+     * Code Rate for High Priority level
+     */
+    int hpCodeRate;
+
+    /**
+     * Code Rate for Low Priority level
+     */
+    int lpCodeRate;
+
+    int guardInterval;
+
+    boolean isHighPriority;
+
+    int standard;
+
+    boolean isMiso;
+
+    /**
+     * Physical Layer Pipe (PLP) mode
+     */
+    int plpMode;
+
+    /**
+     * Physical Layer Pipe (PLP) Id
+     */
+    int plpId;
+
+    /**
+     * Physical Layer Pipe (PLP) Group Id
+     */
+    int plpGroupId;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbs3Capabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbs3Capabilities.aidl
new file mode 100644
index 0000000..84dd67a
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbs3Capabilities.aidl
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * ISDB-S3 Frontend Capabilities interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendIsdbs3Capabilities {
+    /**
+     * Modulation capability
+     */
+    int modulationCap;
+
+    /**
+     * Code Rate capability
+     */
+    int codeRateCap;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbs3Settings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbs3Settings.aidl
new file mode 100644
index 0000000..0923868
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbs3Settings.aidl
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Isdbs3 Frontend Settings interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendIsdbs3Settings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    int streamId;
+
+    int streamIdType;
+
+    int modulation;
+
+    int codeRate;
+
+    /**
+     * Symbols per second
+     */
+    int symbolRate;
+
+    int rolloff;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbsCapabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbsCapabilities.aidl
new file mode 100644
index 0000000..15dfdf7
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbsCapabilities.aidl
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * ISDB-S Frontend Capabilities interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendIsdbsCapabilities {
+    /**
+     * Modulation capability
+     */
+    int modulationCap;
+
+    /**
+     * Code Rate capability
+     */
+    int codeRateCap;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbsSettings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbsSettings.aidl
new file mode 100644
index 0000000..2ae9092
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbsSettings.aidl
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Isdbs Frontend Settings interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendIsdbsSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    int streamId;
+
+    int streamIdType;
+
+    int modulation;
+
+    int codeRate;
+
+    /**
+     * Symbols per second
+     */
+    int symbolRate;
+
+    int rolloff;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbtCapabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbtCapabilities.aidl
new file mode 100644
index 0000000..c9295d8
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbtCapabilities.aidl
@@ -0,0 +1,49 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * ISDB-T Frontend Capabilities interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendIsdbtCapabilities {
+    /**
+     * ISDB-T Mode capability
+     */
+    int modeCap;
+
+    /**
+     * Bandwidth capability
+     */
+    int bandwidthCap;
+
+    /**
+     * Modulation capability
+     */
+    int modulationCap;
+
+    /**
+     * Code Rate capability
+     */
+    int codeRateCap;
+
+    /**
+     * Guard Interval capability
+     */
+    int guardIntervalCap;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbtSettings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbtSettings.aidl
new file mode 100644
index 0000000..191f3a6
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendIsdbtSettings.aidl
@@ -0,0 +1,41 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Isdbt Frontend Settings interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendIsdbtSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    int modulation;
+
+    int bandwidth;
+
+    int mode;
+
+    int codeRate;
+
+    int guardInterval;
+
+    int serviceAreaId;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendSettings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendSettings.aidl
new file mode 100644
index 0000000..a382941
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendSettings.aidl
@@ -0,0 +1,52 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.TunerFrontendAnalogSettings;
+import android.media.tv.tuner.TunerFrontendAtscSettings;
+import android.media.tv.tuner.TunerFrontendAtsc3Settings;
+import android.media.tv.tuner.TunerFrontendCableSettings;
+import android.media.tv.tuner.TunerFrontendDvbsSettings;
+import android.media.tv.tuner.TunerFrontendDvbtSettings;
+import android.media.tv.tuner.TunerFrontendIsdbsSettings;
+import android.media.tv.tuner.TunerFrontendIsdbs3Settings;
+import android.media.tv.tuner.TunerFrontendIsdbtSettings;
+
+/**
+ * Analog Frontend Settings interface.
+ *
+ * {@hide}
+ */
+union TunerFrontendSettings {
+    TunerFrontendAnalogSettings analog;
+
+    TunerFrontendAtscSettings atsc;
+
+    TunerFrontendAtsc3Settings atsc3;
+
+    TunerFrontendCableSettings cable;
+
+    TunerFrontendDvbsSettings dvbs;
+
+    TunerFrontendDvbtSettings dvbt;
+
+    TunerFrontendIsdbsSettings isdbs;
+
+    TunerFrontendIsdbs3Settings isdbs3;
+
+    TunerFrontendIsdbtSettings isdbt;
+}
diff --git a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendStatus.aidl
similarity index 68%
copy from media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
copy to services/tuner/aidl/android/media/tv/tuner/TunerFrontendStatus.aidl
index d6e46cb..41f9f0e 100644
--- a/media/libaudioclient/aidl/android/media/MicrophoneInfo.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendStatus.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright 2018 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,11 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.media.tv.tuner;
 
-parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+/**
+ * Tuner Frontend Status interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendStatus {}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl
new file mode 100644
index 0000000..ddcbcdc
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl
@@ -0,0 +1,77 @@
+/**
+ * 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.TunerFrontendCapabilities;
+
+/**
+ * FrontendInfo interface that carries tuner frontend information.
+ *
+ * {@hide}
+ */
+parcelable TunerServiceFrontendInfo {
+    /**
+     * Frontend Id
+     */
+    int id;
+
+    /**
+     * Frontend Type
+     */
+    int type;
+
+    /**
+     * Minimum Frequency in Hertz
+     */
+    int minFrequency;
+
+    /**
+     * Maximum Frequency in Hertz
+     */
+    int maxFrequency;
+
+    /**
+     * Minimum symbols per second
+     */
+    int minSymbolRate;
+
+    /**
+     * Maximum symbols per second
+     */
+    int maxSymbolRate;
+
+    /**
+     * Range in Hertz
+     */
+    int acquireRange;
+
+    /**
+     * Frontends are assigned with the same exclusiveGroupId if they can't
+     * function at same time. For instance, they share same hardware module.
+     */
+    int exclusiveGroupId;
+
+    /**
+     * A list of supported status types which client can inquiry
+     */
+    int[] statusCaps;
+
+    /**
+     * Frontend Capabilities
+     */
+    TunerFrontendCapabilities caps;
+}