Merge "C2SoftVpxEnc: Fix initialiation of bitrate ratios" into rvc-dev
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index f408b6a..b58ebe2 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -35,6 +35,7 @@
 const char* CameraManagerGlobal::kPhysicalCameraIdKey   = "PhysicalCameraId";
 const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
 const char* CameraManagerGlobal::kContextKey    = "CallbackContext";
+const nsecs_t CameraManagerGlobal::kCallbackDrainTimeout = 5000000; // 5 ms
 Mutex                CameraManagerGlobal::sLock;
 CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
 
@@ -117,7 +118,7 @@
                 return nullptr;
             }
             if (mHandler == nullptr) {
-                mHandler = new CallbackHandler();
+                mHandler = new CallbackHandler(this);
             }
             mCbLooper->registerHandler(mHandler);
         }
@@ -211,6 +212,9 @@
 void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
         const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
     Mutex::Autolock _l(mLock);
+
+    drainPendingCallbacksLocked();
+
     Callback cb(callback);
     mCallbacks.erase(cb);
 }
@@ -223,10 +227,32 @@
 void CameraManagerGlobal::unregisterAvailabilityCallback(
         const ACameraManager_AvailabilityCallbacks *callback) {
     Mutex::Autolock _l(mLock);
+
+    drainPendingCallbacksLocked();
+
     Callback cb(callback);
     mCallbacks.erase(cb);
 }
 
+void CameraManagerGlobal::onCallbackCalled() {
+    Mutex::Autolock _l(mLock);
+    if (mPendingCallbackCnt > 0) {
+        mPendingCallbackCnt--;
+    }
+    mCallbacksCond.signal();
+}
+
+void CameraManagerGlobal::drainPendingCallbacksLocked() {
+    while (mPendingCallbackCnt > 0) {
+        auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
+        if (res != NO_ERROR) {
+            ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
+                    __FUNCTION__, strerror(-res), res);
+            break;
+        }
+    }
+}
+
 template<class T>
 void CameraManagerGlobal::registerAvailCallback(const T *callback) {
     Mutex::Autolock _l(mLock);
@@ -250,6 +276,7 @@
             msg->setPointer(kCallbackFpKey, (void *) cbFunc);
             msg->setPointer(kContextKey, cb.mContext);
             msg->setString(kCameraIdKey, AString(cameraId));
+            mPendingCallbackCnt++;
             msg->post();
 
             // Physical camera unavailable callback
@@ -263,6 +290,7 @@
                 msg->setPointer(kContextKey, cb.mContext);
                 msg->setString(kCameraIdKey, AString(cameraId));
                 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
+                mPendingCallbackCnt++;
                 msg->post();
             }
         }
@@ -323,6 +351,16 @@
 }
 
 void CameraManagerGlobal::CallbackHandler::onMessageReceived(
+      const sp<AMessage> &msg) {
+    onMessageReceivedInternal(msg);
+    if (msg->what() == kWhatSendSingleCallback ||
+            msg->what() == kWhatSendSingleAccessCallback ||
+            msg->what() == kWhatSendSinglePhysicalCameraCallback) {
+        notifyParent();
+    }
+}
+
+void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
         const sp<AMessage> &msg) {
     switch (msg->what()) {
         case kWhatSendSingleCallback:
@@ -405,6 +443,13 @@
     }
 }
 
+void CameraManagerGlobal::CallbackHandler::notifyParent() {
+    sp<CameraManagerGlobal> parent = mParent.promote();
+    if (parent != nullptr) {
+        parent->onCallbackCalled();
+    }
+}
+
 binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
     sp<CameraManagerGlobal> cm = mCameraManager.promote();
     if (cm != nullptr) {
@@ -445,6 +490,7 @@
         if (cbFp != nullptr) {
             msg->setPointer(kCallbackFpKey, (void *) cbFp);
             msg->setPointer(kContextKey, cb.mContext);
+            mPendingCallbackCnt++;
             msg->post();
         }
     }
@@ -491,6 +537,7 @@
             msg->setPointer(kCallbackFpKey, (void *) cbFp);
             msg->setPointer(kContextKey, cb.mContext);
             msg->setString(kCameraIdKey, AString(cameraId));
+            mPendingCallbackCnt++;
             msg->post();
         }
     }
@@ -545,6 +592,7 @@
             msg->setPointer(kContextKey, cb.mContext);
             msg->setString(kCameraIdKey, AString(cameraId));
             msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
+            mPendingCallbackCnt++;
             msg->post();
         }
     }
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index 7fba188..ccbfaa9 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -163,6 +163,12 @@
         ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
         void*                               mContext;
     };
+
+    android::Condition mCallbacksCond;
+    size_t mPendingCallbackCnt = 0;
+    void onCallbackCalled();
+    void drainPendingCallbacksLocked();
+
     std::set<Callback> mCallbacks;
 
     // definition of handler and message
@@ -175,10 +181,16 @@
     static const char* kPhysicalCameraIdKey;
     static const char* kCallbackFpKey;
     static const char* kContextKey;
+    static const nsecs_t kCallbackDrainTimeout;
     class CallbackHandler : public AHandler {
       public:
-        CallbackHandler() {}
+        CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {}
         void onMessageReceived(const sp<AMessage> &msg) override;
+
+      private:
+        wp<CameraManagerGlobal> mParent;
+        void notifyParent();
+        void onMessageReceivedInternal(const sp<AMessage> &msg);
     };
     sp<CallbackHandler> mHandler;
     sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
diff --git a/camera/ndk/include/camera/NdkCameraManager.h b/camera/ndk/include/camera/NdkCameraManager.h
index e2b71bf..0a2ee57 100644
--- a/camera/ndk/include/camera/NdkCameraManager.h
+++ b/camera/ndk/include/camera/NdkCameraManager.h
@@ -191,6 +191,9 @@
  *
  * <p>Removing a callback that isn't registered has no effect.</p>
  *
+ * <p>This function must not be called with a mutex lock also held by
+ * the availability callbacks.</p>
+ *
  * @param manager the {@link ACameraManager} of interest.
  * @param callback the {@link ACameraManager_AvailabilityCallbacks} to be unregistered.
  *
@@ -382,6 +385,9 @@
  *
  * <p>Removing a callback that isn't registered has no effect.</p>
  *
+ * <p>This function must not be called with a mutex lock also held by
+ * the extended availability callbacks.</p>
+ *
  * @param manager the {@link ACameraManager} of interest.
  * @param callback the {@link ACameraManager_ExtendedAvailabilityCallbacks} to be unregistered.
  *
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 4f9b0d1..16457ac 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -1895,27 +1895,66 @@
      * ACAMERA_SCALER_CROP_REGION can still be used to specify the horizontal or vertical
      * crop to achieve aspect ratios different than the native camera sensor.</p>
      * <p>By using this control, the application gains a simpler way to control zoom, which can
-     * be a combination of optical and digital zoom. More specifically, for a logical
-     * multi-camera with more than one focal length, using a floating point zoom ratio offers
-     * more zoom precision when a telephoto lens is used, as well as allowing zoom ratio of
-     * less than 1.0 to zoom out to a wide field of view.</p>
-     * <p>Note that the coordinate system of cropRegion, AE/AWB/AF regions, and faces now changes
-     * to the effective after-zoom field-of-view represented by rectangle of (0, 0,
-     * activeArrayWidth, activeArrayHeight).</p>
-     * <p>For example, if ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE is 4032*3024, and the preview stream
-     * is configured to the same 4:3 aspect ratio, the application can achieve 2.0x zoom in
-     * one of two ways:</p>
+     * be a combination of optical and digital zoom. For example, a multi-camera system may
+     * contain more than one lens with different focal lengths, and the user can use optical
+     * zoom by switching between lenses. Using zoomRatio has benefits in the scenarios below:
+     * <em> Zooming in from a wide-angle lens to a telephoto lens: A floating-point ratio provides
+     *   better precision compared to an integer value of ACAMERA_SCALER_CROP_REGION.
+     * </em> Zooming out from a wide lens to an ultrawide lens: zoomRatio supports zoom-out whereas
+     *   ACAMERA_SCALER_CROP_REGION doesn't.</p>
+     * <p>To illustrate, here are several scenarios of different zoom ratios, crop regions,
+     * and output streams, for a hypothetical camera device with an active array of size
+     * <code>(2000,1500)</code>.</p>
      * <ul>
-     * <li>zoomRatio = 2.0, scaler.cropRegion = (0, 0, 4032, 3024)</li>
-     * <li>zoomRatio = 1.0 (default), scaler.cropRegion = (1008, 756, 3024, 2268)</li>
+     * <li>Camera Configuration:<ul>
+     * <li>Active array size: <code>2000x1500</code> (3 MP, 4:3 aspect ratio)</li>
+     * <li>Output stream #1: <code>640x480</code> (VGA, 4:3 aspect ratio)</li>
+     * <li>Output stream #2: <code>1280x720</code> (720p, 16:9 aspect ratio)</li>
      * </ul>
-     * <p>If the application intends to set aeRegions to be top-left quarter of the preview
-     * field-of-view, the ACAMERA_CONTROL_AE_REGIONS should be set to (0, 0, 2016, 1512) with
+     * </li>
+     * <li>Case #1: 4:3 crop region with 2.0x zoom ratio<ul>
+     * <li>Zoomed field of view: 1/4 of original field of view</li>
+     * <li>Crop region: <code>Rect(0, 0, 2000, 1500) // (left, top, right, bottom)</code> (post zoom)</li>
+     * </ul>
+     * </li>
+     * <li><img alt="4:3 aspect ratio crop diagram" src="../images/camera2/metadata/android.control.zoomRatio/zoom-ratio-2-crop-43.png" /><ul>
+     * <li><code>640x480</code> stream source area: <code>(0, 0, 2000, 1500)</code> (equal to crop region)</li>
+     * <li><code>1280x720</code> stream source area: <code>(0, 187, 2000, 1312)</code> (letterboxed)</li>
+     * </ul>
+     * </li>
+     * <li>Case #2: 16:9 crop region with 2.0x zoom.<ul>
+     * <li>Zoomed field of view: 1/4 of original field of view</li>
+     * <li>Crop region: <code>Rect(0, 187, 2000, 1312)</code></li>
+     * <li><img alt="16:9 aspect ratio crop diagram" src="../images/camera2/metadata/android.control.zoomRatio/zoom-ratio-2-crop-169.png" /></li>
+     * <li><code>640x480</code> stream source area: <code>(250, 187, 1750, 1312)</code> (pillarboxed)</li>
+     * <li><code>1280x720</code> stream source area: <code>(0, 187, 2000, 1312)</code> (equal to crop region)</li>
+     * </ul>
+     * </li>
+     * <li>Case #3: 1:1 crop region with 0.5x zoom out to ultrawide lens.<ul>
+     * <li>Zoomed field of view: 4x of original field of view (switched from wide lens to ultrawide lens)</li>
+     * <li>Crop region: <code>Rect(250, 0, 1750, 1500)</code></li>
+     * <li><img alt="1:1 aspect ratio crop diagram" src="../images/camera2/metadata/android.control.zoomRatio/zoom-ratio-0.5-crop-11.png" /></li>
+     * <li><code>640x480</code> stream source area: <code>(250, 187, 1750, 1312)</code> (letterboxed)</li>
+     * <li><code>1280x720</code> stream source area: <code>(250, 328, 1750, 1172)</code> (letterboxed)</li>
+     * </ul>
+     * </li>
+     * </ul>
+     * <p>As seen from the graphs above, the coordinate system of cropRegion now changes to the
+     * effective after-zoom field-of-view, and is represented by the rectangle of (0, 0,
+     * activeArrayWith, activeArrayHeight). The same applies to AE/AWB/AF regions, and faces.
+     * This coordinate system change isn't applicable to RAW capture and its related
+     * metadata such as intrinsicCalibration and lensShadingMap.</p>
+     * <p>Using the same hypothetical example above, and assuming output stream #1 (640x480) is
+     * the viewfinder stream, the application can achieve 2.0x zoom in one of two ways:</p>
+     * <ul>
+     * <li>zoomRatio = 2.0, scaler.cropRegion = (0, 0, 2000, 1500)</li>
+     * <li>zoomRatio = 1.0 (default), scaler.cropRegion = (500, 375, 1500, 1125)</li>
+     * </ul>
+     * <p>If the application intends to set aeRegions to be top-left quarter of the viewfinder
+     * field-of-view, the ACAMERA_CONTROL_AE_REGIONS should be set to (0, 0, 1000, 750) with
      * zoomRatio set to 2.0. Alternatively, the application can set aeRegions to the equivalent
-     * region of (1008, 756, 2016, 1512) for zoomRatio of 1.0. If the application doesn't
+     * region of (500, 375, 1000, 750) for zoomRatio of 1.0. If the application doesn't
      * explicitly set ACAMERA_CONTROL_ZOOM_RATIO, its value defaults to 1.0.</p>
-     * <p>This coordinate system change isn't applicable to RAW capture and its related metadata
-     * such as intrinsicCalibration and lensShadingMap.</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>
@@ -1923,7 +1962,6 @@
      * @see ACAMERA_CONTROL_AE_REGIONS
      * @see ACAMERA_CONTROL_ZOOM_RATIO
      * @see ACAMERA_SCALER_CROP_REGION
-     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
     ACAMERA_CONTROL_ZOOM_RATIO =                                // float
             ACAMERA_CONTROL_START + 47,
@@ -2395,8 +2433,11 @@
      * frames before the lens can change to the requested focal length.
      * While the focal length is still changing, ACAMERA_LENS_STATE will
      * be set to MOVING.</p>
-     * <p>Optical zoom will not be supported on most devices.</p>
+     * <p>Optical zoom via this control will not be supported on most devices. Starting from API
+     * level 30, the camera device may combine optical and digital zoom through the
+     * ACAMERA_CONTROL_ZOOM_RATIO control.</p>
      *
+     * @see ACAMERA_CONTROL_ZOOM_RATIO
      * @see ACAMERA_LENS_APERTURE
      * @see ACAMERA_LENS_FOCUS_DISTANCE
      * @see ACAMERA_LENS_STATE
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index e2097b5..5aa9c46 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -45,6 +45,7 @@
 const char* CameraManagerGlobal::kPhysicalCameraIdKey   = "PhysicalCameraId";
 const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
 const char* CameraManagerGlobal::kContextKey    = "CallbackContext";
+const nsecs_t CameraManagerGlobal::kCallbackDrainTimeout = 5000000; // 5 ms
 Mutex                CameraManagerGlobal::sLock;
 CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
 
@@ -249,7 +250,7 @@
                 return nullptr;
             }
             if (mHandler == nullptr) {
-                mHandler = new CallbackHandler();
+                mHandler = new CallbackHandler(this);
             }
             mCbLooper->registerHandler(mHandler);
         }
@@ -317,6 +318,7 @@
 void CameraManagerGlobal::unregisterAvailabilityCallback(
         const ACameraManager_AvailabilityCallbacks *callback) {
     Mutex::Autolock _l(mLock);
+    drainPendingCallbacksLocked();
     Callback cb(callback);
     mCallbacks.erase(cb);
 }
@@ -329,10 +331,30 @@
 void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
         const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
     Mutex::Autolock _l(mLock);
+    drainPendingCallbacksLocked();
     Callback cb(callback);
     mCallbacks.erase(cb);
 }
 
+void CameraManagerGlobal::onCallbackCalled() {
+    Mutex::Autolock _l(mLock);
+    if (mPendingCallbackCnt > 0) {
+        mPendingCallbackCnt--;
+    }
+    mCallbacksCond.signal();
+}
+
+void CameraManagerGlobal::drainPendingCallbacksLocked() {
+    while (mPendingCallbackCnt > 0) {
+        auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
+        if (res != NO_ERROR) {
+            ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
+                    __FUNCTION__, strerror(-res), res);
+            break;
+        }
+    }
+}
+
 template <class T>
 void CameraManagerGlobal::registerAvailCallback(const T *callback) {
     Mutex::Autolock _l(mLock);
@@ -351,6 +373,7 @@
             msg->setPointer(kCallbackFpKey, (void *) cbFunc);
             msg->setPointer(kContextKey, cb.mContext);
             msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+            mPendingCallbackCnt++;
             msg->post();
 
             // Physical camera unavailable callback
@@ -363,6 +386,7 @@
                 msg->setPointer(kContextKey, cb.mContext);
                 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
                 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
+                mPendingCallbackCnt++;
                 msg->post();
             }
         }
@@ -406,6 +430,15 @@
 }
 
 void CameraManagerGlobal::CallbackHandler::onMessageReceived(
+      const sp<AMessage> &msg) {
+    onMessageReceivedInternal(msg);
+    if (msg->what() == kWhatSendSingleCallback ||
+            msg->what() == kWhatSendSinglePhysicalCameraCallback) {
+        notifyParent();
+    }
+}
+
+void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
         const sp<AMessage> &msg) {
     switch (msg->what()) {
         case kWhatSendSingleCallback:
@@ -466,6 +499,13 @@
     }
 }
 
+void CameraManagerGlobal::CallbackHandler::notifyParent() {
+    sp<CameraManagerGlobal> parent = mParent.promote();
+    if (parent != nullptr) {
+        parent->onCallbackCalled();
+    }
+}
+
 hardware::Return<void> CameraManagerGlobal::CameraServiceListener::onStatusChanged(
         const CameraStatusAndId &statusAndId) {
     sp<CameraManagerGlobal> cm = mCameraManager.promote();
@@ -512,6 +552,7 @@
         msg->setPointer(kCallbackFpKey, (void *) cbFp);
         msg->setPointer(kContextKey, cb.mContext);
         msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+        mPendingCallbackCnt++;
         msg->post();
     }
     if (status == CameraDeviceStatus::STATUS_NOT_PRESENT) {
@@ -577,6 +618,7 @@
             msg->setPointer(kContextKey, cb.mContext);
             msg->setString(kCameraIdKey, AString(cameraId.c_str()));
             msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
+            mPendingCallbackCnt++;
             msg->post();
         }
     }
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index 36c8e2b..85da3e9 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -156,6 +156,12 @@
         ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
         void*                               mContext;
     };
+
+    android::Condition mCallbacksCond;
+    size_t mPendingCallbackCnt = 0;
+    void onCallbackCalled();
+    void drainPendingCallbacksLocked();
+
     std::set<Callback> mCallbacks;
 
     // definition of handler and message
@@ -167,10 +173,15 @@
     static const char* kPhysicalCameraIdKey;
     static const char* kCallbackFpKey;
     static const char* kContextKey;
+    static const nsecs_t kCallbackDrainTimeout;
     class CallbackHandler : public AHandler {
       public:
-        CallbackHandler() {}
+        CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {}
         void onMessageReceived(const sp<AMessage> &msg) override;
+      private:
+        wp<CameraManagerGlobal> mParent;
+        void notifyParent();
+        void onMessageReceivedInternal(const sp<AMessage> &msg);
     };
     sp<CallbackHandler> mHandler;
     sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
diff --git a/drm/drmserver/Android.bp b/drm/drmserver/Android.bp
index f427834..b68e6c2 100644
--- a/drm/drmserver/Android.bp
+++ b/drm/drmserver/Android.bp
@@ -24,8 +24,8 @@
     ],
 
     shared_libs: [
-        "libmedia",
         "libmediametrics",
+        "libmediautils",
         "libcutils",
         "libutils",
         "liblog",
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 4b8b3f6..c830c6e 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -19,7 +19,7 @@
 #include <utils/Log.h>
 
 #include <private/android_filesystem_config.h>
-#include <media/MemoryLeakTrackUtil.h>
+#include <mediautils/MemoryLeakTrackUtil.h>
 
 #include <errno.h>
 #include <utils/threads.h>
diff --git a/drm/libmediadrm/DrmUtils.cpp b/drm/libmediadrm/DrmUtils.cpp
index 51c2e24..d85fa61 100644
--- a/drm/libmediadrm/DrmUtils.cpp
+++ b/drm/libmediadrm/DrmUtils.cpp
@@ -27,7 +27,7 @@
 #include <android/hardware/drm/1.2/IDrmFactory.h>
 #include <android/hardware/drm/1.3/ICryptoFactory.h>
 #include <android/hardware/drm/1.3/IDrmFactory.h>
-#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
 #include <hidl/HidlSupport.h>
 
 #include <utils/Errors.h>
@@ -41,7 +41,7 @@
 #include <mediadrm/ICrypto.h>
 #include <mediadrm/IDrm.h>
 
-using HServiceManager = ::android::hidl::manager::V1_0::IServiceManager;
+using HServiceManager = ::android::hidl::manager::V1_2::IServiceManager;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
@@ -72,7 +72,7 @@
         exit(-1);
     }
 
-    serviceManager->listByInterface(Hal::descriptor, [&](const hidl_vec<hidl_string> &registered) {
+    serviceManager->listManifestByInterface(Hal::descriptor, [&](const hidl_vec<hidl_string> &registered) {
         for (const auto &instance : registered) {
             auto factory = Hal::getService(instance);
             if (factory != nullptr) {
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 546eb3e..8b7f57d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -356,6 +356,11 @@
 
     Status status = Status::OK;
     bool isOfflineLicense = responseString.find(kOfflineLicense) != std::string::npos;
+    if (scopeId.size() < kKeySetIdPrefix.size()) {
+        android_errorWriteLog(0x534e4554, "144507096");
+        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>());
+        return Void();
+    }
     bool isRelease = (memcmp(scopeId.data(), kKeySetIdPrefix.data(), kKeySetIdPrefix.size()) == 0);
     if (isRelease) {
         keySetId.assign(scopeId.begin(), scopeId.end());
diff --git a/include/media/MmapStreamInterface.h b/include/media/MmapStreamInterface.h
index 0196a0c..b3bf16d 100644
--- a/include/media/MmapStreamInterface.h
+++ b/include/media/MmapStreamInterface.h
@@ -107,12 +107,15 @@
      * createMmapBuffer() must be called before calling start()
      *
      * \param[in] client a AudioClient struct describing the client starting on this stream.
+     * \param[in] attr audio attributes provided by the client.
      * \param[out] handle unique handle for this instance. Used with stop().
      * \return OK in case of success.
      *         NO_INIT in case of initialization error
      *         INVALID_OPERATION if called out of sequence
      */
-    virtual status_t start(const AudioClient& client, audio_port_handle_t *handle) = 0;
+    virtual status_t start(const AudioClient& client,
+                           const audio_attributes_t *attr,
+                           audio_port_handle_t *handle) = 0;
 
     /**
      * Stop a stream operating in mmap mode.
diff --git a/include/media/VolumeShaper.h b/include/media/VolumeShaper.h
index 79afd6c..fe519bb 100644
--- a/include/media/VolumeShaper.h
+++ b/include/media/VolumeShaper.h
@@ -132,7 +132,7 @@
             , mDurationMs(1000.) {
         }
 
-        explicit Configuration(const Configuration &configuration)
+        Configuration(const Configuration &configuration)
             : Interpolator<S, T>(*static_cast<const Interpolator<S, T> *>(&configuration))
             , RefBase()
             , mType(configuration.mType)
@@ -361,7 +361,7 @@
             : Operation(flags, replaceId, std::numeric_limits<S>::quiet_NaN() /* xOffset */) {
         }
 
-        explicit Operation(const Operation &operation)
+        Operation(const Operation &operation)
             : Operation(operation.mFlags, operation.mReplaceId, operation.mXOffset) {
         }
 
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
index f44f0d5..cf1c14c 100644
--- a/media/audioserver/Android.mk
+++ b/media/audioserver/Android.mk
@@ -39,7 +39,7 @@
 	frameworks/av/media/libaaudio/include \
 	frameworks/av/media/libaaudio/src \
 	frameworks/av/media/libaaudio/src/binding \
-	frameworks/av/media/libmedia \
+	frameworks/av/media/libmedia/include \
 	external/sonic \
 
 LOCAL_MODULE := audioserver
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index 5484613..f9bef5f 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -6,16 +6,22 @@
     capabilities BLOCK_SUSPEND
     ioprio rt 4
     writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
-    onrestart restart vendor.audio-hal
-    onrestart restart vendor.audio-hal-4-0-msd
-    # Keep the original service names for backward compatibility
-    onrestart restart vendor.audio-hal-2-0
-    onrestart restart audio-hal-2-0
+
+    onrestart setprop sys.audio.restart.hal 1
 
 on property:vts.native_server.on=1
     stop audioserver
 on property:vts.native_server.on=0
     start audioserver
 
+on property:sys.audio.restart.hal=1
+    restart vendor.audio-hal
+    restart vendor.audio-hal-4-0-msd
+    # Keep the original service names for backward compatibility
+    restart vendor.audio-hal-2-0
+    restart audio-hal-2-0
+    # reset the property
+    setprop sys.audio.restart.hal 0
+
 on init
     mkdir /dev/socket/audioserver 0775 audioserver audioserver
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index 4a2ac1d..f9f4f31 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -26,6 +26,7 @@
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
 #include <hidl/HidlTransportSupport.h>
+#include <mediautils/LimitProcessMemory.h>
 #include <utils/Log.h>
 
 // from LOCAL_C_INCLUDES
@@ -35,7 +36,6 @@
 #include "AAudioService.h"
 #include "utility/AAudioUtilities.h"
 #include "MediaLogService.h"
-#include "MediaUtils.h"
 
 using namespace android;
 
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index 56813c4..c1edb98 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -35,6 +35,7 @@
 constexpr char COMPONENT_NAME[] = "c2.android.avc.decoder";
 constexpr uint32_t kDefaultOutputDelay = 8;
 constexpr uint32_t kMaxOutputDelay = 16;
+constexpr uint32_t kMinInputBytes = 4;
 }  // namespace
 
 class C2SoftAvcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
@@ -501,7 +502,7 @@
 status_t C2SoftAvcDec::initDecoder() {
     if (OK != createDecoder()) return UNKNOWN_ERROR;
     mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
-    mStride = ALIGN128(mWidth);
+    mStride = ALIGN32(mWidth);
     mSignalledError = false;
     resetPlugin();
     (void) setNumCores();
@@ -519,10 +520,20 @@
                                  size_t inSize,
                                  uint32_t tsMarker) {
     uint32_t displayStride = mStride;
+    if (outBuffer) {
+        C2PlanarLayout layout;
+        layout = outBuffer->layout();
+        displayStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+    }
     uint32_t displayHeight = mHeight;
     size_t lumaSize = displayStride * displayHeight;
     size_t chromaSize = lumaSize >> 2;
 
+    if (mStride != displayStride) {
+        mStride = displayStride;
+        if (OK != setParams(mStride, IVD_DECODE_FRAME)) return false;
+    }
+
     ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
     ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
     if (inBuffer) {
@@ -756,24 +767,21 @@
         ALOGE("not supposed to be here, invalid decoder context");
         return C2_CORRUPTED;
     }
-    if (mStride != ALIGN128(mWidth)) {
-        mStride = ALIGN128(mWidth);
-        if (OK != setParams(mStride, IVD_DECODE_FRAME)) return C2_CORRUPTED;
-    }
     if (mOutBlock &&
-            (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
+            (mOutBlock->width() != ALIGN32(mWidth) || mOutBlock->height() != mHeight)) {
         mOutBlock.reset();
     }
     if (!mOutBlock) {
         uint32_t format = HAL_PIXEL_FORMAT_YV12;
         C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
+        c2_status_t err =
+            pool->fetchGraphicBlock(ALIGN32(mWidth), mHeight, format, usage, &mOutBlock);
         if (err != C2_OK) {
             ALOGE("fetchGraphicBlock for Output failed with status %d", err);
             return err;
         }
         ALOGV("provided (%dx%d) required (%dx%d)",
-              mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
+              mOutBlock->width(), mOutBlock->height(), ALIGN32(mWidth), mHeight);
     }
 
     return C2_OK;
@@ -817,7 +825,7 @@
           inSize, (int)work->input.ordinal.timestamp.peeku(),
           (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
     size_t inPos = 0;
-    while (inPos < inSize) {
+    while (inPos < inSize && inSize - inPos >= kMinInputBytes) {
         if (C2_OK != ensureDecoderState(pool)) {
             mSignalledError = true;
             work->workletsProcessed = 1u;
@@ -904,12 +912,12 @@
                 work->result = C2_CORRUPTED;
                 return;
             }
-            continue;
         }
         if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
             if (mHeaderDecoded == false) {
                 mHeaderDecoded = true;
-                setParams(ALIGN128(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
+                mStride = ALIGN32(s_decode_op.u4_pic_wd);
+                setParams(mStride, IVD_DECODE_FRAME);
             }
             if (s_decode_op.u4_pic_wd != mWidth || s_decode_op.u4_pic_ht != mHeight) {
                 mWidth = s_decode_op.u4_pic_wd;
@@ -937,16 +945,7 @@
         if (s_decode_op.u4_output_present) {
             finishWork(s_decode_op.u4_ts, work);
         }
-        if (0 == s_decode_op.u4_num_bytes_consumed) {
-            ALOGD("Bytes consumed is zero. Ignoring remaining bytes");
-            break;
-        }
         inPos += s_decode_op.u4_num_bytes_consumed;
-        if (hasPicture && (inSize - inPos)) {
-            ALOGD("decoded frame in current access nal, ignoring further trailing bytes %d",
-                  (int)inSize - (int)inPos);
-            break;
-        }
     }
     if (eos) {
         drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
diff --git a/media/codec2/components/avc/C2SoftAvcDec.h b/media/codec2/components/avc/C2SoftAvcDec.h
index ed27493..bd84de0 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.h
+++ b/media/codec2/components/avc/C2SoftAvcDec.h
@@ -39,8 +39,7 @@
 #define ivdext_ctl_set_num_cores_op_t   ih264d_ctl_set_num_cores_op_t
 #define ivdext_ctl_get_vui_params_ip_t  ih264d_ctl_get_vui_params_ip_t
 #define ivdext_ctl_get_vui_params_op_t  ih264d_ctl_get_vui_params_op_t
-#define ALIGN64(x)                      ((((x) + 63) >> 6) << 6)
-#define ALIGN128(x)                     ((((x) + 127) >> 7) << 7)
+#define ALIGN32(x)                      ((((x) + 31) >> 5) << 5)
 #define MAX_NUM_CORES                   4
 #define IVDEXT_CMD_CTL_SET_NUM_CORES    \
         (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index e3d419c..ab93ce3 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -103,7 +103,7 @@
 
         addParameter(
                 DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
-                .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
+                .withDefault(new C2StreamPictureSizeInfo::input(0u, 16, 16))
                 .withFields({
                     C2F(mSize, width).inRange(2, 2560, 2),
                     C2F(mSize, height).inRange(2, 2560, 2),
@@ -129,7 +129,7 @@
 
         addParameter(
                 DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
-                .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
+                .withDefault(new C2StreamFrameRateInfo::output(0u, 1.))
                 // TODO: More restriction?
                 .withFields({C2F(mFrameRate, value).greaterThan(0.)})
                 .withSetter(Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
diff --git a/media/codec2/components/base/SimpleC2Interface.cpp b/media/codec2/components/base/SimpleC2Interface.cpp
index c849a4e..5c019f3 100644
--- a/media/codec2/components/base/SimpleC2Interface.cpp
+++ b/media/codec2/components/base/SimpleC2Interface.cpp
@@ -21,6 +21,7 @@
 // use MediaDefs here vs. MediaCodecConstants as this is not MediaCodec specific/dependent
 #include <media/stagefright/foundation/MediaDefs.h>
 
+#include <C2PlatformSupport.h>
 #include <SimpleC2Interface.h>
 
 namespace android {
@@ -85,22 +86,24 @@
     C2Allocator::id_t rawAllocator = C2AllocatorStore::DEFAULT_LINEAR;
     C2BlockPool::local_id_t rawPoolId = C2BlockPool::BASIC_LINEAR;
     C2BufferData::type_t codedBufferType = C2BufferData::LINEAR;
-    C2Allocator::id_t codedAllocator = C2AllocatorStore::DEFAULT_LINEAR;
+    int poolMask = GetCodec2PoolMask();
+    C2Allocator::id_t preferredLinearId = GetPreferredLinearAllocatorId(poolMask);
+    C2Allocator::id_t codedAllocator = preferredLinearId;
     C2BlockPool::local_id_t codedPoolId = C2BlockPool::BASIC_LINEAR;
 
     switch (domain) {
-        case C2Component::DOMAIN_IMAGE:
+        case C2Component::DOMAIN_IMAGE: [[fallthrough]];
         case C2Component::DOMAIN_VIDEO:
             // TODO: should we define raw image? The only difference is timestamp handling
             rawBufferType = C2BufferData::GRAPHIC;
             rawMediaType = MEDIA_MIMETYPE_VIDEO_RAW;
-            rawAllocator = C2AllocatorStore::DEFAULT_GRAPHIC;
+            rawAllocator = C2PlatformAllocatorStore::GRALLOC;
             rawPoolId = C2BlockPool::BASIC_GRAPHIC;
             break;
         case C2Component::DOMAIN_AUDIO:
             rawBufferType = C2BufferData::LINEAR;
             rawMediaType = MEDIA_MIMETYPE_AUDIO_RAW;
-            rawAllocator = C2AllocatorStore::DEFAULT_LINEAR;
+            rawAllocator = preferredLinearId;
             rawPoolId = C2BlockPool::BASIC_LINEAR;
             break;
         default:
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 6db4387..e4b911d 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -497,7 +497,7 @@
 status_t C2SoftHevcDec::initDecoder() {
     if (OK != createDecoder()) return UNKNOWN_ERROR;
     mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
-    mStride = ALIGN128(mWidth);
+    mStride = ALIGN32(mWidth);
     mSignalledError = false;
     resetPlugin();
     (void) setNumCores();
@@ -515,10 +515,20 @@
                                   size_t inSize,
                                   uint32_t tsMarker) {
     uint32_t displayStride = mStride;
+    if (outBuffer) {
+        C2PlanarLayout layout;
+        layout = outBuffer->layout();
+        displayStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+    }
     uint32_t displayHeight = mHeight;
     size_t lumaSize = displayStride * displayHeight;
     size_t chromaSize = lumaSize >> 2;
 
+    if (mStride != displayStride) {
+        mStride = displayStride;
+        if (OK != setParams(mStride, IVD_DECODE_FRAME)) return false;
+    }
+
     ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
     ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
     if (inBuffer) {
@@ -752,24 +762,21 @@
         ALOGE("not supposed to be here, invalid decoder context");
         return C2_CORRUPTED;
     }
-    if (mStride != ALIGN128(mWidth)) {
-        mStride = ALIGN128(mWidth);
-        if (OK != setParams(mStride, IVD_DECODE_FRAME)) return C2_CORRUPTED;
-    }
     if (mOutBlock &&
-            (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
+            (mOutBlock->width() != ALIGN32(mWidth) || mOutBlock->height() != mHeight)) {
         mOutBlock.reset();
     }
     if (!mOutBlock) {
         uint32_t format = HAL_PIXEL_FORMAT_YV12;
         C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
+        c2_status_t err =
+            pool->fetchGraphicBlock(ALIGN32(mWidth), mHeight, format, usage, &mOutBlock);
         if (err != C2_OK) {
             ALOGE("fetchGraphicBlock for Output failed with status %d", err);
             return err;
         }
         ALOGV("provided (%dx%d) required (%dx%d)",
-              mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
+              mOutBlock->width(), mOutBlock->height(), ALIGN32(mWidth), mHeight);
     }
 
     return C2_OK;
@@ -904,7 +911,7 @@
         if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
             if (mHeaderDecoded == false) {
                 mHeaderDecoded = true;
-                setParams(ALIGN128(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
+                setParams(ALIGN32(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
             }
             if (s_decode_op.u4_pic_wd != mWidth ||  s_decode_op.u4_pic_ht != mHeight) {
                 mWidth = s_decode_op.u4_pic_wd;
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.h b/media/codec2/components/hevc/C2SoftHevcDec.h
index aecd101..600d7c1 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.h
+++ b/media/codec2/components/hevc/C2SoftHevcDec.h
@@ -37,8 +37,7 @@
 #define ivdext_ctl_set_num_cores_op_t   ihevcd_cxa_ctl_set_num_cores_op_t
 #define ivdext_ctl_get_vui_params_ip_t  ihevcd_cxa_ctl_get_vui_params_ip_t
 #define ivdext_ctl_get_vui_params_op_t  ihevcd_cxa_ctl_get_vui_params_op_t
-#define ALIGN64(x)                      ((((x) + 63) >> 6) << 6)
-#define ALIGN128(x)                     ((((x) + 127) >> 7) << 7)
+#define ALIGN32(x)                      ((((x) + 31) >> 5) << 5)
 #define MAX_NUM_CORES                   4
 #define IVDEXT_CMD_CTL_SET_NUM_CORES    \
         (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index 19ccbf9..c2d2540 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -628,6 +628,7 @@
         mComplexity = mIntf->getComplexity_l();
         mQuality = mIntf->getQuality_l();
         mGop = mIntf->getGop_l();
+        mRequestSync = mIntf->getRequestSync_l();
     }
 
     c2_status_t status = initEncParams();
@@ -956,7 +957,7 @@
         }
     }
 
-    // handle dynamic config parameters
+    // handle dynamic bitrate change
     {
         IntfImpl::Lock lock = mIntf->lock();
         std::shared_ptr<C2StreamBitrateInfo::output> bitrate = mIntf->getBitrate_l();
@@ -983,6 +984,26 @@
         work->workletsProcessed = 1u;
         return;
     }
+    // handle request key frame
+    {
+        IntfImpl::Lock lock = mIntf->lock();
+        std::shared_ptr<C2StreamRequestSyncFrameTuning::output> requestSync;
+        requestSync = mIntf->getRequestSync_l();
+        lock.unlock();
+        if (requestSync != mRequestSync) {
+            // we can handle IDR immediately
+            if (requestSync->value) {
+                // unset request
+                C2StreamRequestSyncFrameTuning::output clearSync(0u, C2_FALSE);
+                std::vector<std::unique_ptr<C2SettingResult>> failures;
+                mIntf->config({ &clearSync }, C2_MAY_BLOCK, &failures);
+                ALOGV("Got sync request");
+                //Force this as an IDR frame
+                s_encode_ip.i4_force_idr_flag = 1;
+            }
+            mRequestSync = requestSync;
+        }
+    }
 
     uint64_t timeDelay = 0;
     uint64_t timeTaken = 0;
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.h b/media/codec2/components/hevc/C2SoftHevcEnc.h
index 140b4a9..5ea4602 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.h
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.h
@@ -88,6 +88,7 @@
     std::shared_ptr<C2StreamComplexityTuning::output> mComplexity;
     std::shared_ptr<C2StreamQualityTuning::output> mQuality;
     std::shared_ptr<C2StreamGopTuning::output> mGop;
+    std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
 #ifdef FILE_DUMP_ENABLE
     char mInFile[200];
     char mOutFile[200];
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index e0365fc..c7ca18c 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -571,7 +571,7 @@
     if (OK != createDecoder()) return UNKNOWN_ERROR;
 
     mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
-    mStride = ALIGN64(mWidth);
+    mStride = ALIGN32(mWidth);
     mSignalledError = false;
     resetPlugin();
     (void) setNumCores();
@@ -589,10 +589,20 @@
                                    size_t inSize,
                                    uint32_t tsMarker) {
     uint32_t displayStride = mStride;
+    if (outBuffer) {
+        C2PlanarLayout layout;
+        layout = outBuffer->layout();
+        displayStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+    }
     uint32_t displayHeight = mHeight;
     size_t lumaSize = displayStride * displayHeight;
     size_t chromaSize = lumaSize >> 2;
 
+    if (mStride != displayStride) {
+        mStride = displayStride;
+        if (OK != setParams(mStride)) return false;
+    }
+
     ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
     ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
     if (inBuffer) {
@@ -833,24 +843,21 @@
         ALOGE("not supposed to be here, invalid decoder context");
         return C2_CORRUPTED;
     }
-    if (mStride != ALIGN64(mWidth)) {
-        mStride = ALIGN64(mWidth);
-        if (OK != setParams(mStride)) return C2_CORRUPTED;
-    }
     if (mOutBlock &&
-            (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
+            (mOutBlock->width() != ALIGN32(mWidth) || mOutBlock->height() != mHeight)) {
         mOutBlock.reset();
     }
     if (!mOutBlock) {
         uint32_t format = HAL_PIXEL_FORMAT_YV12;
         C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
+        c2_status_t err =
+            pool->fetchGraphicBlock(ALIGN32(mWidth), mHeight, format, usage, &mOutBlock);
         if (err != C2_OK) {
             ALOGE("fetchGraphicBlock for Output failed with status %d", err);
             return err;
         }
         ALOGV("provided (%dx%d) required (%dx%d)",
-              mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
+              mOutBlock->width(), mOutBlock->height(), ALIGN32(mWidth), mHeight);
     }
 
     return C2_OK;
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
index 65d3b87..fd66304a 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
@@ -37,7 +37,7 @@
 #define ivdext_ctl_set_num_cores_op_t   impeg2d_ctl_set_num_cores_op_t
 #define ivdext_ctl_get_seq_info_ip_t    impeg2d_ctl_get_seq_info_ip_t
 #define ivdext_ctl_get_seq_info_op_t    impeg2d_ctl_get_seq_info_op_t
-#define ALIGN64(x)                      ((((x) + 63) >> 6) << 6)
+#define ALIGN32(x)                      ((((x) + 31) >> 5) << 5)
 #define MAX_NUM_CORES                   4
 #define IVDEXT_CMD_CTL_SET_NUM_CORES    \
         (IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index c7d73f4..3eef1e3 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -784,7 +784,13 @@
         }
 
     }
-    CHECK(img->fmt == VPX_IMG_FMT_I420 || img->fmt == VPX_IMG_FMT_I42016);
+    if(img->fmt != VPX_IMG_FMT_I420 && img->fmt != VPX_IMG_FMT_I42016) {
+        ALOGE("img->fmt %d not supported", img->fmt);
+        mSignalledError = true;
+        work->workletsProcessed = 1u;
+        work->result = C2_CORRUPTED;
+        return false;
+    }
 
     std::shared_ptr<C2GraphicBlock> block;
     uint32_t format = HAL_PIXEL_FORMAT_YV12;
diff --git a/media/codec2/hidl/1.0/vts/functional/common/Android.bp b/media/codec2/hidl/1.0/vts/functional/common/Android.bp
index a011ba3..3b4e232 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/common/Android.bp
@@ -1,7 +1,7 @@
 cc_library_static {
     name: "VtsHalMediaC2V1_0CommonUtil",
     defaults: [
-        "VtsHalTargetTestDefaults",
+        "Vts10HalTargetTestDefaults",
         "libcodec2-hidl-client-defaults",
     ],
 
@@ -19,7 +19,7 @@
 cc_defaults {
     name: "VtsHalMediaC2V1_0Defaults",
     defaults: [
-        "VtsHalTargetTestDefaults",
+        "Vts10HalTargetTestDefaults",
         "libcodec2-hidl-client-defaults",
     ],
 
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index 265eeb7..d7cc175 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -127,20 +127,26 @@
     mDelay = delay;
     mPadding = padding;
     mSampleRate = sampleRate;
-    setSkipCutBuffer(delay, padding, channelCount);
+    mChannelCount = channelCount;
+    setSkipCutBuffer(delay, padding);
 }
 
 void OutputBuffers::updateSkipCutBuffer(int32_t sampleRate, int32_t channelCount) {
     if (mSkipCutBuffer == nullptr) {
         return;
     }
+    if (mSampleRate == sampleRate && mChannelCount == channelCount) {
+        return;
+    }
     int32_t delay = mDelay;
     int32_t padding = mPadding;
     if (sampleRate != mSampleRate) {
         delay = ((int64_t)delay * sampleRate) / mSampleRate;
         padding = ((int64_t)padding * sampleRate) / mSampleRate;
     }
-    setSkipCutBuffer(delay, padding, channelCount);
+    mSampleRate = sampleRate;
+    mChannelCount = channelCount;
+    setSkipCutBuffer(delay, padding);
 }
 
 void OutputBuffers::submit(const sp<MediaCodecBuffer> &buffer) {
@@ -153,14 +159,14 @@
     mSkipCutBuffer = scb;
 }
 
-void OutputBuffers::setSkipCutBuffer(int32_t skip, int32_t cut, int32_t channelCount) {
+void OutputBuffers::setSkipCutBuffer(int32_t skip, int32_t cut) {
     if (mSkipCutBuffer != nullptr) {
         size_t prevSize = mSkipCutBuffer->size();
         if (prevSize != 0u) {
             ALOGD("[%s] Replacing SkipCutBuffer holding %zu bytes", mName, prevSize);
         }
     }
-    mSkipCutBuffer = new SkipCutBuffer(skip, cut, channelCount);
+    mSkipCutBuffer = new SkipCutBuffer(skip, cut, mChannelCount);
 }
 
 // LocalBufferPool
@@ -255,6 +261,7 @@
     std::shared_ptr<C2Buffer> result = mBuffers[index].compBuffer.lock();
     if (!result) {
         result = clientBuffer->asC2Buffer();
+        clientBuffer->clearC2BufferRefs();
         mBuffers[index].compBuffer = result;
     }
     if (c2buffer) {
@@ -373,6 +380,7 @@
     std::shared_ptr<C2Buffer> result = mBuffers[index].compBuffer.lock();
     if (!result) {
         result = clientBuffer->asC2Buffer();
+        clientBuffer->clearC2BufferRefs();
         mBuffers[index].compBuffer = result;
     }
     if (c2buffer) {
diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h
index bae08e0..85ca5d5 100644
--- a/media/codec2/sfplugin/CCodecBuffers.h
+++ b/media/codec2/sfplugin/CCodecBuffers.h
@@ -228,8 +228,9 @@
     int32_t mDelay;
     int32_t mPadding;
     int32_t mSampleRate;
+    int32_t mChannelCount;
 
-    void setSkipCutBuffer(int32_t skip, int32_t cut, int32_t channelCount);
+    void setSkipCutBuffer(int32_t skip, int32_t cut);
 
     DISALLOW_EVIL_CONSTRUCTORS(OutputBuffers);
 };
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index b6d18e2..5b3a62f 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -111,7 +111,11 @@
 }
 
 std::shared_ptr<C2Buffer> DummyContainerBuffer::asC2Buffer() {
-    return std::move(mBufferRef);
+    return mBufferRef;
+}
+
+void DummyContainerBuffer::clearC2BufferRefs() {
+    mBufferRef.reset();
 }
 
 bool DummyContainerBuffer::canCopy(const std::shared_ptr<C2Buffer> &) const {
@@ -187,7 +191,11 @@
 }
 
 std::shared_ptr<C2Buffer> ConstLinearBlockBuffer::asC2Buffer() {
-    return std::move(mBufferRef);
+    return mBufferRef;
+}
+
+void ConstLinearBlockBuffer::clearC2BufferRefs() {
+    mBufferRef.reset();
 }
 
 // GraphicView2MediaImageConverter
@@ -689,8 +697,12 @@
 }
 
 std::shared_ptr<C2Buffer> ConstGraphicBlockBuffer::asC2Buffer() {
+    return mBufferRef;
+}
+
+void ConstGraphicBlockBuffer::clearC2BufferRefs() {
     mView.reset();
-    return std::move(mBufferRef);
+    mBufferRef.reset();
 }
 
 bool ConstGraphicBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
diff --git a/media/codec2/sfplugin/Codec2Buffer.h b/media/codec2/sfplugin/Codec2Buffer.h
index 09475ef..ff79946 100644
--- a/media/codec2/sfplugin/Codec2Buffer.h
+++ b/media/codec2/sfplugin/Codec2Buffer.h
@@ -59,6 +59,8 @@
 
     sp<ABuffer> getImageData() const { return mImageData; }
 
+    virtual void clearC2BufferRefs() {}
+
 protected:
     /**
      * canCopy() implementation for linear buffers.
@@ -102,6 +104,7 @@
             const std::shared_ptr<C2Buffer> &buffer = nullptr);
 
     std::shared_ptr<C2Buffer> asC2Buffer() override;
+    void clearC2BufferRefs() override;
     bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
     bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
 
@@ -161,6 +164,7 @@
     virtual ~ConstLinearBlockBuffer() = default;
 
     std::shared_ptr<C2Buffer> asC2Buffer() override;
+    void clearC2BufferRefs() override;
 
 private:
     ConstLinearBlockBuffer(
@@ -280,6 +284,7 @@
     virtual ~ConstGraphicBlockBuffer() = default;
 
     std::shared_ptr<C2Buffer> asC2Buffer() override;
+    void clearC2BufferRefs() override;
     bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
     bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
 
diff --git a/media/extractors/flac/Android.bp b/media/extractors/flac/Android.bp
index 3675611..826c1a0 100644
--- a/media/extractors/flac/Android.bp
+++ b/media/extractors/flac/Android.bp
@@ -9,6 +9,7 @@
     ],
 
     shared_libs: [
+        "libbase",
         "libbinder_ndk",
     ],
 
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp
index 5329bd1..0617e88 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/extractors/flac/FLACExtractor.cpp
@@ -24,6 +24,7 @@
 // libFLAC parser
 #include "FLAC/stream_decoder.h"
 
+#include <android-base/properties.h>
 #include <android/binder_ibinder.h> // for AIBinder_getCallingUid
 #include <audio_utils/primitives.h>
 #include <media/MediaExtractorPluginApi.h>
@@ -47,7 +48,8 @@
 // (Note: duplicated with WAVExtractor.cpp)
 static inline bool shouldExtractorOutputFloat(int bitsPerSample)
 {
-    return bitsPerSample > 16 && AIBinder_getCallingUid() == AID_MEDIA;
+    return bitsPerSample > 16 && AIBinder_getCallingUid() == AID_MEDIA
+                              && android::base::GetBoolProperty("media.extractor.float", true);
 }
 
 class FLACParser;
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index ce82861..54f1fa2 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -19,6 +19,7 @@
 
 #include <ctype.h>
 #include <inttypes.h>
+#include <algorithm>
 #include <memory>
 #include <stdint.h>
 #include <stdlib.h>
@@ -112,6 +113,7 @@
     const Trex *mTrex;
     off64_t mFirstMoofOffset;
     off64_t mCurrentMoofOffset;
+    off64_t mCurrentMoofSize;
     off64_t mNextMoofOffset;
     uint32_t mCurrentTime; // in media timescale ticks
     int32_t mLastParsedTrackId;
@@ -149,9 +151,13 @@
     bool mIsAudio;
     sp<ItemTable> mItemTable;
 
-    // Start offset from composition time to presentation time.
-    // Support shift only for video tracks through mElstShiftStartTicks for now.
+    /* Shift start offset (move to earlier time) when media_time > 0,
+     * in media time scale.
+     */
     uint64_t mElstShiftStartTicks;
+    /* Initial start offset (move to later time), empty edit list entry
+     * in media time scale.
+     */
     uint64_t mElstInitialEmptyEditTicks;
 
     size_t parseNALSize(const uint8_t *data) const;
@@ -160,8 +166,9 @@
     status_t parseTrackFragmentRun(off64_t offset, off64_t size);
     status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size);
     status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size);
-    status_t parseClearEncryptedSizes(off64_t offset, bool isSubsampleEncryption, uint32_t flags);
-    status_t parseSampleEncryption(off64_t offset);
+    status_t parseClearEncryptedSizes(off64_t offset, bool isSampleEncryption,
+            uint32_t flags, off64_t size);
+    status_t parseSampleEncryption(off64_t offset, off64_t size);
     // returns -1 for invalid layer ID
     int32_t parseHEVCLayerId(const uint8_t *data, size_t size);
 
@@ -1070,6 +1077,8 @@
                     // drop it now to reduce our footprint
                     free(mLastTrack->mTx3gBuffer);
                     mLastTrack->mTx3gBuffer = NULL;
+                    mLastTrack->mTx3gFilled = 0;
+                    mLastTrack->mTx3gSize = 0;
                 }
 
                 const char *mime;
@@ -1215,7 +1224,6 @@
                 off64_t entriesoffset = data_offset + 8;
                 uint64_t segment_duration;
                 int64_t media_time;
-                uint64_t empty_edit_ticks = 0;
                 bool empty_edit_present = false;
                 for (int i = 0; i < entry_count; ++i) {
                     switch (version) {
@@ -1247,45 +1255,33 @@
                     }
                     // Empty edit entry would have to be first entry.
                     if (media_time == -1 && i == 0) {
-                        int64_t durationUs;
-                        if (AMediaFormat_getInt64(mFileMetaData, AMEDIAFORMAT_KEY_DURATION,
-                                                  &durationUs)) {
-                            empty_edit_ticks = segment_duration;
-                            ALOGV("initial empty edit ticks: %" PRIu64, empty_edit_ticks);
-                            empty_edit_present = true;
-                        }
-                    }
-                    // Process second entry only when the first entry was an empty edit entry.
-                    if (empty_edit_present && i == 1) {
-                        int64_t durationUs;
-                        if (AMediaFormat_getInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION,
-                                                  &durationUs) &&
-                            mHeaderTimescale != 0) {
-                            // Support only segment_duration<=track_duration and media_time==0 case.
-                            uint64_t segmentDurationUs =
-                                    segment_duration * 1000000 / mHeaderTimescale;
-                            if (segmentDurationUs == 0 || segmentDurationUs > durationUs ||
-                                media_time != 0) {
-                                ALOGW("for now, unsupported second entry in empty edit list");
-                            }
-                        }
+                        empty_edit_present = true;
+                        ALOGV("initial empty edit ticks: %" PRIu64, segment_duration);
+                        /* In movie header timescale, and needs to be converted to media timescale
+                         * after we get that from a track's 'mdhd' atom,
+                         * which at times come after 'elst'.
+                         */
+                        mLastTrack->elst_initial_empty_edit_ticks = segment_duration;
+                    } else if (media_time >= 0 && i == 0) {
+                        ALOGV("first edit list entry - from gapless playback files");
+                        mLastTrack->elst_media_time = media_time;
+                        mLastTrack->elst_segment_duration = segment_duration;
+                        ALOGV("segment_duration: %" PRIu64 " media_time: %" PRId64,
+                              segment_duration, media_time);
+                        // media_time is in media timescale as are STTS/CTTS entries.
+                        mLastTrack->elst_shift_start_ticks = media_time;
+                    } else if (empty_edit_present && i == 1) {
+                        // Process second entry only when the first entry was an empty edit entry.
+                        ALOGV("second edit list entry");
+                        mLastTrack->elst_shift_start_ticks = media_time;
+                    } else {
+                        ALOGW("for now, unsupported entry in edit list %" PRIu32, entry_count);
                     }
                 }
                 // save these for later, because the elst atom might precede
                 // the atoms that actually gives us the duration and sample rate
                 // needed to calculate the padding and delay values
                 mLastTrack->elst_needs_processing = true;
-                if (empty_edit_present) {
-                    /* In movie header timescale, and needs to be converted to media timescale once
-                     * we get that from a track's 'mdhd' atom, which at times come after 'elst'.
-                     */
-                    mLastTrack->elst_initial_empty_edit_ticks = empty_edit_ticks;
-                } else {
-                    mLastTrack->elst_media_time = media_time;
-                    mLastTrack->elst_segment_duration = segment_duration;
-                    ALOGV("segment_duration: %" PRIu64 " media_time: %" PRId64, segment_duration,
-                          media_time);
-                }
             }
             break;
         }
@@ -2791,6 +2787,10 @@
             // if those apps are compensating for it, we'd break them with such a change
             //
 
+            if (mLastTrack->mTx3gBuffer == NULL) {
+                mLastTrack->mTx3gSize = 0;
+                mLastTrack->mTx3gFilled = 0;
+            }
             if (mLastTrack->mTx3gSize - mLastTrack->mTx3gFilled < chunk_size) {
                 size_t growth = kTx3gGrowth;
                 if (growth < chunk_size) {
@@ -2898,7 +2898,7 @@
                 return ERROR_MALFORMED;
             }
 
-            parseID3v2MetaData(data_offset + 6);
+            parseID3v2MetaData(data_offset + 6, chunk_data_size - 6);
 
             break;
         }
@@ -4169,8 +4169,19 @@
     return OK;
 }
 
-void MPEG4Extractor::parseID3v2MetaData(off64_t offset) {
-    ID3 id3(mDataSource, true /* ignorev1 */, offset);
+void MPEG4Extractor::parseID3v2MetaData(off64_t offset, uint64_t size) {
+    uint8_t *buffer = new (std::nothrow) uint8_t[size];
+    if (buffer == NULL) {
+        return;
+    }
+    if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) {
+        delete[] buffer;
+        buffer = NULL;
+        return;
+    }
+
+    ID3 id3(buffer, size, true /* ignorev1 */);
+    delete[] buffer;
 
     if (id3.isValid()) {
         struct Map {
@@ -4324,9 +4335,9 @@
         }
     }
 
-    // media_time is in media timescale as are STTS/CTTS entries.
-    track->elst_shift_start_ticks = track->elst_media_time;
     ALOGV("track->elst_shift_start_ticks :%" PRIu64, track->elst_shift_start_ticks);
+
+    uint64_t elst_initial_empty_edit_ticks = 0;
     if (mHeaderTimescale != 0) {
         // Convert empty_edit_ticks from movie timescale to media timescale.
         uint64_t elst_initial_empty_edit_ticks_mul = 0, elst_initial_empty_edit_ticks_add = 0;
@@ -4337,15 +4348,15 @@
             ALOGE("track->elst_initial_empty_edit_ticks overflow");
             return nullptr;
         }
-        track->elst_initial_empty_edit_ticks = elst_initial_empty_edit_ticks_add / mHeaderTimescale;
-        ALOGV("track->elst_initial_empty_edit_ticks :%" PRIu64,
-              track->elst_initial_empty_edit_ticks);
+        elst_initial_empty_edit_ticks = elst_initial_empty_edit_ticks_add / mHeaderTimescale;
     }
+    ALOGV("elst_initial_empty_edit_ticks in MediaTimeScale :%" PRIu64,
+          elst_initial_empty_edit_ticks);
 
     MPEG4Source* source =
             new MPEG4Source(track->meta, mDataSource, track->timescale, track->sampleTable,
                             mSidxEntries, trex, mMoofOffset, itemTable,
-                            track->elst_shift_start_ticks, track->elst_initial_empty_edit_ticks);
+                            track->elst_shift_start_ticks, elst_initial_empty_edit_ticks);
     if (source->init() != OK) {
         delete source;
         return NULL;
@@ -4850,6 +4861,7 @@
       mTrex(trex),
       mFirstMoofOffset(firstMoofOffset),
       mCurrentMoofOffset(firstMoofOffset),
+      mCurrentMoofSize(0),
       mNextMoofOffset(-1),
       mCurrentTime(0),
       mDefaultEncryptedByteBlock(0),
@@ -5100,6 +5112,9 @@
         case FOURCC("moof"): {
             off64_t stop_offset = *offset + chunk_size;
             *offset = data_offset;
+            if (chunk_type == FOURCC("moof")) {
+                mCurrentMoofSize = chunk_data_size;
+            }
             while (*offset < stop_offset) {
                 status_t err = parseChunk(offset);
                 if (err != OK) {
@@ -5188,7 +5203,7 @@
 
         case FOURCC("senc"): {
             status_t err;
-            if ((err = parseSampleEncryption(data_offset)) != OK) {
+            if ((err = parseSampleEncryption(data_offset, chunk_data_size)) != OK) {
                 return err;
             }
             *offset += chunk_size;
@@ -5381,11 +5396,11 @@
 
     drmoffset += mCurrentMoofOffset;
 
-    return parseClearEncryptedSizes(drmoffset, false, 0);
+    return parseClearEncryptedSizes(drmoffset, false, 0, mCurrentMoofSize);
 }
 
 status_t MPEG4Source::parseClearEncryptedSizes(
-        off64_t offset, bool isSubsampleEncryption, uint32_t flags) {
+        off64_t offset, bool isSampleEncryption, uint32_t flags, off64_t size) {
 
     int32_t ivlength;
     if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, &ivlength)) {
@@ -5399,11 +5414,15 @@
     }
 
     uint32_t sampleCount = mCurrentSampleInfoCount;
-    if (isSubsampleEncryption) {
+    if (isSampleEncryption) {
+        if (size < 4) {
+            return ERROR_MALFORMED;
+        }
         if (!mDataSource->getUInt32(offset, &sampleCount)) {
             return ERROR_IO;
         }
         offset += 4;
+        size -= 4;
     }
 
     // read CencSampleAuxiliaryDataFormats
@@ -5418,14 +5437,18 @@
         }
 
         memset(smpl->iv, 0, 16);
+        if (size < ivlength) {
+            return ERROR_MALFORMED;
+        }
         if (mDataSource->readAt(offset, smpl->iv, ivlength) != ivlength) {
             return ERROR_IO;
         }
 
         offset += ivlength;
+        size -= ivlength;
 
         bool readSubsamples;
-        if (isSubsampleEncryption) {
+        if (isSampleEncryption) {
             readSubsamples = flags & 2;
         } else {
             int32_t smplinfosize = mCurrentDefaultSampleInfoSize;
@@ -5437,13 +5460,20 @@
 
         if (readSubsamples) {
             uint16_t numsubsamples;
+            if (size < 2) {
+                return ERROR_MALFORMED;
+            }
             if (!mDataSource->getUInt16(offset, &numsubsamples)) {
                 return ERROR_IO;
             }
             offset += 2;
+            size -= 2;
             for (size_t j = 0; j < numsubsamples; j++) {
                 uint16_t numclear;
                 uint32_t numencrypted;
+                if (size < 6) {
+                    return ERROR_MALFORMED;
+                }
                 if (!mDataSource->getUInt16(offset, &numclear)) {
                     return ERROR_IO;
                 }
@@ -5452,6 +5482,7 @@
                     return ERROR_IO;
                 }
                 offset += 4;
+                size -= 6;
                 smpl->clearsizes.add(numclear);
                 smpl->encryptedsizes.add(numencrypted);
             }
@@ -5464,12 +5495,15 @@
     return OK;
 }
 
-status_t MPEG4Source::parseSampleEncryption(off64_t offset) {
+status_t MPEG4Source::parseSampleEncryption(off64_t offset, off64_t chunk_data_size) {
     uint32_t flags;
+    if (chunk_data_size < 4) {
+        return ERROR_MALFORMED;
+    }
     if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
         return ERROR_MALFORMED;
     }
-    return parseClearEncryptedSizes(offset + 4, true, flags);
+    return parseClearEncryptedSizes(offset + 4, true, flags, chunk_data_size - 4);
 }
 
 status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
@@ -5846,7 +5880,7 @@
     ReadOptions::SeekMode mode;
 
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
-
+        ALOGV("seekTimeUs:%" PRId64, seekTimeUs);
         if (mIsHeif) {
             CHECK(mSampleTable == NULL);
             CHECK(mItemTable != NULL);
@@ -5885,9 +5919,22 @@
                     break;
             }
             if( mode != ReadOptions::SEEK_FRAME_INDEX) {
-                seekTimeUs += ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
-                ALOGV("shifted seekTimeUs :%" PRId64 ", mElstShiftStartTicks:%" PRIu64, seekTimeUs,
-                      mElstShiftStartTicks);
+                int64_t elstInitialEmptyEditUs = 0, elstShiftStartUs = 0;
+                if (mElstInitialEmptyEditTicks > 0) {
+                    elstInitialEmptyEditUs = ((long double)mElstInitialEmptyEditTicks * 1000000) /
+                                             mTimescale;
+                    /* Sample's composition time from ctts/stts entries are non-negative(>=0).
+                     * Hence, lower bound on seekTimeUs is 0.
+                     */
+                    seekTimeUs = std::max(seekTimeUs - elstInitialEmptyEditUs, (int64_t)0);
+                }
+                if (mElstShiftStartTicks > 0) {
+                    elstShiftStartUs = ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
+                    seekTimeUs += elstShiftStartUs;
+                }
+                ALOGV("shifted seekTimeUs:%" PRId64 ", elstInitialEmptyEditUs:%" PRIu64
+                      ", elstShiftStartUs:%" PRIu64, seekTimeUs, elstInitialEmptyEditUs,
+                      elstShiftStartUs);
             }
 
             uint32_t sampleIndex;
@@ -5933,7 +5980,16 @@
 
             if (mode == ReadOptions::SEEK_CLOSEST
                 || mode == ReadOptions::SEEK_FRAME_INDEX) {
-                sampleTime -= mElstShiftStartTicks;
+                if (mElstInitialEmptyEditTicks > 0) {
+                    sampleTime += mElstInitialEmptyEditTicks;
+                }
+                if (mElstShiftStartTicks > 0){
+                    if (sampleTime > mElstShiftStartTicks) {
+                        sampleTime -= mElstShiftStartTicks;
+                    } else {
+                        sampleTime = 0;
+                    }
+                }
                 targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
             }
 
@@ -5976,12 +6032,12 @@
             if(err == OK) {
                 if (mElstInitialEmptyEditTicks > 0) {
                     cts += mElstInitialEmptyEditTicks;
-                } else {
+                }
+                if (mElstShiftStartTicks > 0) {
                     // cts can be negative. for example, initial audio samples for gapless playback.
                     cts -= (int64_t)mElstShiftStartTicks;
                 }
             }
-
         } else {
             err = mItemTable->getImageOffsetAndSize(
                     options && options->getSeekTo(&seekTimeUs, &mode) ?
@@ -6261,10 +6317,23 @@
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
-
-        seekTimeUs += ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
-        ALOGV("shifted seekTimeUs :%" PRId64 ", mElstShiftStartTicks:%" PRIu64, seekTimeUs,
-              mElstShiftStartTicks);
+        ALOGV("seekTimeUs:%" PRId64, seekTimeUs);
+        int64_t elstInitialEmptyEditUs = 0, elstShiftStartUs = 0;
+        if (mElstInitialEmptyEditTicks > 0) {
+            elstInitialEmptyEditUs = ((long double)mElstInitialEmptyEditTicks * 1000000) /
+                                     mTimescale;
+            /* Sample's composition time from ctts/stts entries are non-negative(>=0).
+             * Hence, lower bound on seekTimeUs is 0.
+             */
+            seekTimeUs = std::max(seekTimeUs - elstInitialEmptyEditUs, (int64_t)0);
+        }
+        if (mElstShiftStartTicks > 0){
+            elstShiftStartUs = ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
+            seekTimeUs += elstShiftStartUs;
+        }
+        ALOGV("shifted seekTimeUs:%" PRId64 ", elstInitialEmptyEditUs:%" PRIu64
+              ", elstShiftStartUs:%" PRIu64, seekTimeUs, elstInitialEmptyEditUs,
+              elstShiftStartUs);
 
         int numSidxEntries = mSegments.size();
         if (numSidxEntries != 0) {
@@ -6355,7 +6424,8 @@
 
         if (mElstInitialEmptyEditTicks > 0) {
             cts += mElstInitialEmptyEditTicks;
-        } else {
+        }
+        if (mElstShiftStartTicks > 0) {
             // cts can be negative. for example, initial audio samples for gapless playback.
             cts -= (int64_t)mElstShiftStartTicks;
         }
diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h
index 53ec6bc..1e49d50 100644
--- a/media/extractors/mp4/MPEG4Extractor.h
+++ b/media/extractors/mp4/MPEG4Extractor.h
@@ -88,9 +88,9 @@
          */
         int64_t elst_media_time;
         uint64_t elst_segment_duration;
-        // Shift start offset only when media_time > 0.
+        // Shift start offset (move to earlier time) when media_time > 0.
         uint64_t elst_shift_start_ticks;
-        // Initial start offset, empty edit list entry.
+        // Initial start offset (move to later time), from empty edit list entry.
         uint64_t elst_initial_empty_edit_ticks;
         bool subsample_encryption;
 
@@ -161,7 +161,7 @@
     status_t parseITunesMetaData(off64_t offset, size_t size);
     status_t parseColorInfo(off64_t offset, size_t size);
     status_t parse3GPPMetaData(off64_t offset, size_t size, int depth);
-    void parseID3v2MetaData(off64_t offset);
+    void parseID3v2MetaData(off64_t offset, uint64_t size);
     status_t parseQTMetaKey(off64_t data_offset, size_t data_size);
     status_t parseQTMetaVal(int32_t keyId, off64_t data_offset, size_t data_size);
 
diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp
index 8ce5c3f..5d38a81 100644
--- a/media/extractors/wav/Android.bp
+++ b/media/extractors/wav/Android.bp
@@ -10,6 +10,7 @@
     ],
 
     shared_libs: [
+        "libbase",
         "libbinder_ndk",
     ],
 
diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/extractors/wav/WAVExtractor.cpp
index 4fa7f27..d19447a 100644
--- a/media/extractors/wav/WAVExtractor.cpp
+++ b/media/extractors/wav/WAVExtractor.cpp
@@ -20,6 +20,7 @@
 
 #include "WAVExtractor.h"
 
+#include <android-base/properties.h>
 #include <android/binder_ibinder.h> // for AIBinder_getCallingUid
 #include <audio_utils/primitives.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -43,7 +44,8 @@
 // (Note: duplicated with FLACExtractor.cpp)
 static inline bool shouldExtractorOutputFloat(int bitsPerSample)
 {
-    return bitsPerSample > 16 && AIBinder_getCallingUid() == AID_MEDIA;
+    return bitsPerSample > 16 && AIBinder_getCallingUid() == AID_MEDIA
+                              && android::base::GetBoolProperty("media.extractor.float", true);
 }
 
 enum {
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.h b/media/libaaudio/src/binding/AAudioBinderClient.h
index f9da8b4..e8c91fc 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.h
+++ b/media/libaaudio/src/binding/AAudioBinderClient.h
@@ -98,8 +98,9 @@
                                                   pid_t clientThreadId) override;
 
     aaudio_result_t startClient(aaudio_handle_t streamHandle __unused,
-                                      const android::AudioClient& client __unused,
-                                      audio_port_handle_t *clientHandle) override {
+                                const android::AudioClient& client __unused,
+                                const audio_attributes_t *attr __unused,
+                                audio_port_handle_t *clientHandle __unused) override {
         return AAUDIO_ERROR_UNAVAILABLE;
     }
 
diff --git a/media/libaaudio/src/binding/AAudioServiceInterface.h b/media/libaaudio/src/binding/AAudioServiceInterface.h
index a64405b..9c28cc7 100644
--- a/media/libaaudio/src/binding/AAudioServiceInterface.h
+++ b/media/libaaudio/src/binding/AAudioServiceInterface.h
@@ -89,8 +89,9 @@
                                                   pid_t clientThreadId) = 0;
 
     virtual aaudio_result_t startClient(aaudio_handle_t streamHandle,
-                                      const android::AudioClient& client,
-                                      audio_port_handle_t *clientHandle) = 0;
+                                        const android::AudioClient& client,
+                                        const audio_attributes_t *attr,
+                                        audio_port_handle_t *clientHandle) = 0;
 
     virtual aaudio_result_t stopClient(aaudio_handle_t streamHandle,
                                        audio_port_handle_t clientHandle) = 0;
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index b6548e6..076c92d 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -230,7 +230,7 @@
         }
 
         const int32_t callbackBufferSize = mCallbackFrames * getBytesPerFrame();
-        mCallbackBuffer = new uint8_t[callbackBufferSize];
+        mCallbackBuffer = std::make_unique<uint8_t[]>(callbackBufferSize);
     }
 
     // For debugging and analyzing the distribution of MMAP timestamps.
@@ -279,8 +279,7 @@
         mServiceStreamHandle = AAUDIO_HANDLE_INVALID;
 
         mServiceInterface.closeStream(serviceStreamHandle);
-        delete[] mCallbackBuffer;
-        mCallbackBuffer = nullptr;
+        mCallbackBuffer.reset();
         result = mEndPointParcelable.close();
         aaudio_result_t result2 = AudioStream::release_l();
         return (result != AAUDIO_OK) ? result : result2;
@@ -429,13 +428,14 @@
 }
 
 aaudio_result_t AudioStreamInternal::startClient(const android::AudioClient& client,
+                                                 const audio_attributes_t *attr,
                                                  audio_port_handle_t *portHandle) {
     ALOGV("%s() called", __func__);
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
         return AAUDIO_ERROR_INVALID_STATE;
     }
     aaudio_result_t result =  mServiceInterface.startClient(mServiceStreamHandle,
-                                                            client, portHandle);
+                                                            client, attr, portHandle);
     ALOGV("%s(%d) returning %d", __func__, *portHandle, result);
     return result;
 }
@@ -713,12 +713,8 @@
 aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) {
     int32_t adjustedFrames = requestedFrames;
     const int32_t maximumSize = getBufferCapacity() - mFramesPerBurst;
-    // The buffer size can be set to zero.
-    // This means that the callback may be called when the internal buffer becomes empty.
-    // This will be fine on some devices in ideal circumstances and will result in the
-    // lowest possible latency.
-    // If there are glitches then they should be detected as XRuns and the size can be increased.
-    static const int32_t minimumSize = 0;
+    // Minimum size should be a multiple number of bursts.
+    const int32_t minimumSize = 1 * mFramesPerBurst;
 
     // Clip to minimum size so that rounding up will work better.
     adjustedFrames = std::max(minimumSize, adjustedFrames);
@@ -730,12 +726,14 @@
         // Round to the next highest burst size.
         int32_t numBursts = (adjustedFrames + mFramesPerBurst - 1) / mFramesPerBurst;
         adjustedFrames = numBursts * mFramesPerBurst;
+        // Clip just in case maximumSize is not a multiple of mFramesPerBurst.
+        adjustedFrames = std::min(maximumSize, adjustedFrames);
     }
 
     // Clip against the actual size from the endpoint.
     int32_t actualFrames = 0;
     mAudioEndpoint.setBufferSizeInFrames(maximumSize, &actualFrames);
-    // actualFrames should be <= maximumSize
+    // actualFrames should be <= actual maximum size of endpoint
     adjustedFrames = std::min(actualFrames, adjustedFrames);
 
     mBufferSizeInFrames = adjustedFrames;
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 8843a8a..42f2889 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -90,6 +90,7 @@
     int64_t calculateReasonableTimeout();
 
     aaudio_result_t startClient(const android::AudioClient& client,
+                                const audio_attributes_t *attr,
                                 audio_port_handle_t *clientHandle);
 
     aaudio_result_t stopClient(audio_port_handle_t clientHandle);
@@ -163,7 +164,7 @@
     // Offset from underlying frame position.
     int64_t                  mFramesOffsetFromService = 0; // offset for timestamps
 
-    uint8_t                 *mCallbackBuffer = nullptr;
+    std::unique_ptr<uint8_t[]> mCallbackBuffer;
     int32_t                  mCallbackFrames = 0;
 
     // The service uses this for SHARED mode.
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index 9684ee4..32cf368 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -243,7 +243,7 @@
         int64_t timeoutNanos = calculateReasonableTimeout(mCallbackFrames);
 
         // This is a BLOCKING READ!
-        result = read(mCallbackBuffer, mCallbackFrames, timeoutNanos);
+        result = read(mCallbackBuffer.get(), mCallbackFrames, timeoutNanos);
         if ((result != mCallbackFrames)) {
             ALOGE("callbackLoop: read() returned %d", result);
             if (result >= 0) {
@@ -255,7 +255,7 @@
         }
 
         // Call application using the AAudio callback interface.
-        callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
+        callbackResult = maybeCallDataCallback(mCallbackBuffer.get(), mCallbackFrames);
 
         if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
             ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 536009a..b50a512 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -268,11 +268,11 @@
     // result might be a frame count
     while (mCallbackEnabled.load() && isActive() && (result >= 0)) {
         // Call application using the AAudio callback interface.
-        callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
+        callbackResult = maybeCallDataCallback(mCallbackBuffer.get(), mCallbackFrames);
 
         if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
             // Write audio data to stream. This is a BLOCKING WRITE!
-            result = write(mCallbackBuffer, mCallbackFrames, timeoutNanos);
+            result = write(mCallbackBuffer.get(), mCallbackFrames, timeoutNanos);
             if ((result != mCallbackFrames)) {
                 if (result >= 0) {
                     // Only wrote some of the frames requested. Must have timed out.
diff --git a/media/libaaudio/src/client/IsochronousClockModel.cpp b/media/libaaudio/src/client/IsochronousClockModel.cpp
index bd46d05..f0dcd44 100644
--- a/media/libaaudio/src/client/IsochronousClockModel.cpp
+++ b/media/libaaudio/src/client/IsochronousClockModel.cpp
@@ -47,6 +47,7 @@
         , mMarkerNanoTime(0)
         , mSampleRate(48000)
         , mFramesPerBurst(48)
+        , mBurstPeriodNanos(0) // this will be updated before use
         , mMaxMeasuredLatenessNanos(0)
         , mLatenessForDriftNanos(kInitialLatenessForDriftNanos)
         , mState(STATE_STOPPED)
@@ -57,9 +58,6 @@
     }
 }
 
-IsochronousClockModel::~IsochronousClockModel() {
-}
-
 void IsochronousClockModel::setPositionAndTime(int64_t framePosition, int64_t nanoTime) {
     ALOGV("setPositionAndTime, %lld, %lld", (long long) framePosition, (long long) nanoTime);
     mMarkerFramePosition = framePosition;
@@ -186,7 +184,7 @@
             // Calculate upper region that will trigger a drift forwards.
             mLatenessForDriftNanos = mMaxMeasuredLatenessNanos - (mMaxMeasuredLatenessNanos >> 4);
         } else { // decrease
-            // If these is an outlier in lateness then mMaxMeasuredLatenessNanos can go high
+            // If this is an outlier in lateness then mMaxMeasuredLatenessNanos can go high
             // and stay there. So we slowly reduce mMaxMeasuredLatenessNanos for better
             // long term stability. The two opposing forces will keep mMaxMeasuredLatenessNanos
             // within a reasonable range.
diff --git a/media/libaaudio/src/client/IsochronousClockModel.h b/media/libaaudio/src/client/IsochronousClockModel.h
index 40f066b..6280013 100644
--- a/media/libaaudio/src/client/IsochronousClockModel.h
+++ b/media/libaaudio/src/client/IsochronousClockModel.h
@@ -35,7 +35,7 @@
 
 public:
     IsochronousClockModel();
-    virtual ~IsochronousClockModel();
+    virtual ~IsochronousClockModel() = default;
 
     void start(int64_t nanoTime);
     void stop(int64_t nanoTime);
@@ -130,6 +130,7 @@
 private:
 
     int32_t getLateTimeOffsetNanos() const;
+    void update();
 
     enum clock_model_state_t {
         STATE_STOPPED,
@@ -164,7 +165,6 @@
     // distribution of timestamps relative to earliest
     std::unique_ptr<android::audio_utils::Histogram>   mHistogramMicros;
 
-    void update();
 };
 
 } /* namespace aaudio */
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index d54d043..6da63e8 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -215,6 +215,9 @@
             : (aaudio_session_id_t) mAudioTrack->getSessionId();
     setSessionId(actualSessionId);
 
+    mInitialBufferCapacity = getBufferCapacity();
+    mInitialFramesPerBurst = getFramesPerBurst();
+
     mAudioTrack->addAudioDeviceCallback(mDeviceCallback);
 
     // Update performance mode based on the actual stream flags.
@@ -265,7 +268,16 @@
 
             // Stream got rerouted so we disconnect.
         case AudioTrack::EVENT_NEW_IAUDIOTRACK:
-            processCallbackCommon(AAUDIO_CALLBACK_OPERATION_DISCONNECTED, info);
+            // request stream disconnect if the restored AudioTrack has properties not matching
+            // what was requested initially
+            if (mAudioTrack->channelCount() != getSamplesPerFrame()
+                    || mAudioTrack->format() != getFormat()
+                    || mAudioTrack->getSampleRate() != getSampleRate()
+                    || mAudioTrack->getRoutedDeviceId() != getDeviceId()
+                    || getBufferCapacity() != mInitialBufferCapacity
+                    || getFramesPerBurst() != mInitialFramesPerBurst) {
+                processCallbackCommon(AAUDIO_CALLBACK_OPERATION_DISCONNECTED, info);
+            }
             break;
 
         default:
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.h b/media/libaaudio/src/legacy/AudioStreamTrack.h
index 550f693..93a1ff4 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.h
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.h
@@ -104,6 +104,10 @@
 
     // TODO add 64-bit position reporting to AudioTrack and use it.
     aaudio_wrapping_frames_t         mPositionWhenPausing = 0;
+
+    // initial AudioTrack frame count and notification period
+    int32_t mInitialBufferCapacity = 0;
+    int32_t mInitialFramesPerBurst = 0;
 };
 
 } /* namespace aaudio */
diff --git a/media/libaaudio/tests/test_various.cpp b/media/libaaudio/tests/test_various.cpp
index 5bb1046..41693e8 100644
--- a/media/libaaudio/tests/test_various.cpp
+++ b/media/libaaudio/tests/test_various.cpp
@@ -28,15 +28,20 @@
 
 // Callback function that does nothing.
 aaudio_data_callback_result_t NoopDataCallbackProc(
-        AAudioStream *stream,
-        void *userData,
+        AAudioStream * stream,
+        void * /* userData */,
         void *audioData,
         int32_t numFrames
 ) {
-    (void) stream;
-    (void) userData;
-    (void) audioData;
-    (void) numFrames;
+    int channels = AAudioStream_getChannelCount(stream);
+    int numSamples = channels * numFrames;
+    bool allZeros = true;
+    float * const floatData = reinterpret_cast<float *>(audioData);
+    for (int i = 0; i < numSamples; i++) {
+        allZeros &= (floatData[i] == 0.0f);
+        floatData[i] = 0.0f;
+    }
+    EXPECT_TRUE(allZeros);
     return AAUDIO_CALLBACK_RESULT_CONTINUE;
 }
 
@@ -56,6 +61,7 @@
                                         nullptr);
     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
     AAudioStreamBuilder_setSharingMode(aaudioBuilder, sharingMode);
+    AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
 
     // Create an AAudioStream using the Builder.
     ASSERT_EQ(AAUDIO_OK,
@@ -114,6 +120,7 @@
     // Request stream properties.
     AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
+    AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
 
     // Create an AAudioStream using the Builder.
     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 65afc8d..0d20f20 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -21,6 +21,7 @@
         "AudioVolumeGroup.cpp",
     ],
     shared_libs: [
+        "capture_state_listener-aidl-cpp",
         "libaudiofoundation",
         "libaudioutils",
         "libbinder",
@@ -34,6 +35,9 @@
     ],
     include_dirs: ["system/media/audio_utils/include"],
     export_include_dirs: ["include"],
+    export_shared_lib_headers: [
+        "capture_state_listener-aidl-cpp",
+    ],
 }
 
 cc_library_shared {
@@ -73,6 +77,7 @@
         "TrackPlayerBase.cpp",
     ],
     shared_libs: [
+        "capture_state_listener-aidl-cpp",
         "libaudiofoundation",
         "libaudioutils",
         "libaudiopolicy",
@@ -148,3 +153,12 @@
     ],
     path: "aidl",
 }
+
+aidl_interface {
+    name: "capture_state_listener-aidl",
+    unstable: true,
+    local_include_dir: "aidl",
+    srcs: [
+        "aidl/android/media/ICaptureStateListener.aidl",
+    ],
+}
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index c183ab0..3ead6cb 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -151,11 +151,13 @@
     // audio flinger will not be retained. initCheck() will return the creation status
     // but all other APIs will return invalid operation.
     if (probe || iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) {
-        char typeBuffer[64], uuidBuffer[64];
+        char typeBuffer[64] = {}, uuidBuffer[64] = {};
         guidToString(type, typeBuffer, sizeof(typeBuffer));
         guidToString(uuid, uuidBuffer, sizeof(uuidBuffer));
         ALOGE_IF(!probe, "set(): AudioFlinger could not create effect %s / %s, status: %d",
-                typeBuffer, uuidBuffer, mStatus);
+                type != nullptr ? typeBuffer : "NULL",
+                uuid != nullptr ? uuidBuffer : "NULL",
+                mStatus);
         if (!probe && iEffect == 0) {
             mStatus = NO_INIT;
         }
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index f9d1798..fc50e07 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -394,7 +394,7 @@
     AutoMutex lock(mLock);
 
     status_t status = NO_ERROR;
-    mediametrics::Defer([&] {
+    mediametrics::Defer defer([&] {
         mediametrics::LogItem(mMetricsId)
             .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_START)
             .set(AMEDIAMETRICS_PROP_DURATIONNS, (int64_t)(systemTime() - beginNs))
@@ -411,6 +411,9 @@
     mFramesReadServerOffset -= mFramesRead + framesFlushed;
     mFramesRead = 0;
     mProxy->clearTimestamp();  // timestamp is invalid until next server push
+    mPreviousTimestamp.clear();
+    mTimestampRetrogradePositionReported = false;
+    mTimestampRetrogradeTimeReported = false;
 
     // reset current position as seen by client to 0
     mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition());
@@ -467,7 +470,7 @@
 {
     const int64_t beginNs = systemTime();
     AutoMutex lock(mLock);
-    mediametrics::Defer([&] {
+    mediametrics::Defer defer([&] {
         mediametrics::LogItem(mMetricsId)
             .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_STOP)
             .set(AMEDIAMETRICS_PROP_DURATIONNS, (int64_t)(systemTime() - beginNs))
@@ -600,6 +603,39 @@
                 timestamp->mPosition[i] += mFramesReadServerOffset;
             }
         }
+
+        bool timestampRetrogradeTimeReported = false;
+        bool timestampRetrogradePositionReported = false;
+        for (int i = 0; i < ExtendedTimestamp::LOCATION_MAX; ++i) {
+            if (timestamp->mTimeNs[i] >= 0 && mPreviousTimestamp.mTimeNs[i] >= 0) {
+                if (timestamp->mTimeNs[i] < mPreviousTimestamp.mTimeNs[i]) {
+                    if (!mTimestampRetrogradeTimeReported) {
+                        ALOGD("%s: retrograde time adjusting [%d] current:%lld to previous:%lld",
+                                __func__, i, (long long)timestamp->mTimeNs[i],
+                                (long long)mPreviousTimestamp.mTimeNs[i]);
+                        timestampRetrogradeTimeReported = true;
+                    }
+                    timestamp->mTimeNs[i] = mPreviousTimestamp.mTimeNs[i];
+                }
+                if (timestamp->mPosition[i] < mPreviousTimestamp.mPosition[i]) {
+                    if (!mTimestampRetrogradePositionReported) {
+                        ALOGD("%s: retrograde position"
+                                " adjusting [%d] current:%lld to previous:%lld",
+                                __func__, i, (long long)timestamp->mPosition[i],
+                                (long long)mPreviousTimestamp.mPosition[i]);
+                        timestampRetrogradePositionReported = true;
+                    }
+                    timestamp->mPosition[i] = mPreviousTimestamp.mPosition[i];
+                }
+            }
+        }
+        mPreviousTimestamp = *timestamp;
+        if (timestampRetrogradeTimeReported) {
+            mTimestampRetrogradeTimeReported = true;
+        }
+        if (timestampRetrogradePositionReported) {
+            mTimestampRetrogradePositionReported = true;
+        }
     }
     return status;
 }
@@ -1340,7 +1376,7 @@
 {
     status_t result = NO_ERROR;  // logged: make sure to set this before returning.
     const int64_t beginNs = systemTime();
-    mediametrics::Defer([&] {
+    mediametrics::Defer defer([&] {
         mediametrics::LogItem(mMetricsId)
             .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_RESTORE)
             .set(AMEDIAMETRICS_PROP_DURATIONNS, (int64_t)(systemTime() - beginNs))
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index f030ab0..6357da4 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -18,6 +18,8 @@
 //#define LOG_NDEBUG 0
 
 #include <utils/Log.h>
+
+#include <android/media/BnCaptureStateListener.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 #include <binder/IPCThreadState.h>
@@ -44,11 +46,16 @@
 dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
 record_config_callback AudioSystem::gRecordConfigCallback = NULL;
 
+// Required to be held while calling into gSoundTriggerCaptureStateListener.
+Mutex gSoundTriggerCaptureStateListenerLock;
+sp<AudioSystem::CaptureStateListener> gSoundTriggerCaptureStateListener = nullptr;
+
 // establish binder interface to AudioFlinger service
 const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
 {
     sp<IAudioFlinger> af;
     sp<AudioFlingerClient> afc;
+    bool reportNoError = false;
     {
         Mutex::Autolock _l(gLock);
         if (gAudioFlinger == 0) {
@@ -64,7 +71,7 @@
             if (gAudioFlingerClient == NULL) {
                 gAudioFlingerClient = new AudioFlingerClient();
             } else {
-                reportError(NO_ERROR);
+                reportNoError = true;
             }
             binder->linkToDeath(gAudioFlingerClient);
             gAudioFlinger = interface_cast<IAudioFlinger>(binder);
@@ -80,6 +87,7 @@
         af->registerClient(afc);
         IPCThreadState::self()->restoreCallingIdentity(token);
     }
+    if (reportNoError) reportError(NO_ERROR);
     return af;
 }
 
@@ -886,7 +894,6 @@
                                         audio_stream_type_t *stream,
                                         pid_t pid,
                                         uid_t uid,
-                                        const String16& opPackageName,
                                         const audio_config_t *config,
                                         audio_output_flags_t flags,
                                         audio_port_handle_t *selectedDeviceId,
@@ -896,7 +903,7 @@
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return NO_INIT;
     return aps->getOutputForAttr(attr, output, session, stream, pid, uid,
-                                 opPackageName, config,
+                                 config,
                                  flags, selectedDeviceId, portId, secondaryOutputs);
 }
 
@@ -1480,6 +1487,14 @@
     return aps->setA11yServicesUids(uids);
 }
 
+status_t AudioSystem::setCurrentImeUid(uid_t uid)
+{
+    const sp <IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    return aps->setCurrentImeUid(uid);
+}
+
 bool AudioSystem::isHapticPlaybackSupported()
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@@ -1616,6 +1631,48 @@
     return aps->getPreferredDeviceForStrategy(strategy, device);
 }
 
+class CaptureStateListenerImpl : public media::BnCaptureStateListener,
+                                 public IBinder::DeathRecipient {
+public:
+    binder::Status setCaptureState(bool active) override {
+        Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
+        gSoundTriggerCaptureStateListener->onStateChanged(active);
+        return binder::Status::ok();
+    }
+
+    void binderDied(const wp<IBinder>&) override {
+        Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
+        gSoundTriggerCaptureStateListener->onServiceDied();
+        gSoundTriggerCaptureStateListener = nullptr;
+    }
+};
+
+status_t AudioSystem::registerSoundTriggerCaptureStateListener(
+    const sp<CaptureStateListener>& listener) {
+    const sp<IAudioPolicyService>& aps =
+            AudioSystem::get_audio_policy_service();
+    if (aps == 0) {
+        return PERMISSION_DENIED;
+    }
+
+    sp<CaptureStateListenerImpl> wrapper = new CaptureStateListenerImpl();
+
+    Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
+
+    bool active;
+    status_t status =
+        aps->registerSoundTriggerCaptureStateListener(wrapper, &active);
+    if (status != NO_ERROR) {
+        listener->onServiceDied();
+        return NO_ERROR;
+    }
+    gSoundTriggerCaptureStateListener = listener;
+    listener->onStateChanged(active);
+    sp<IBinder> binder = IInterface::asBinder(aps);
+    binder->linkToDeath(wrapper);
+    return NO_ERROR;
+}
+
 // ---------------------------------------------------------------------------
 
 int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 2f95886..8b357a3 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -73,7 +73,7 @@
 static inline struct timespec convertNsToTimespec(int64_t ns) {
     struct timespec tv;
     tv.tv_sec = static_cast<time_t>(ns / NANOS_PER_SECOND);
-    tv.tv_nsec = static_cast<long>(ns % NANOS_PER_SECOND);
+    tv.tv_nsec = static_cast<int64_t>(ns % NANOS_PER_SECOND);
     return tv;
 }
 
@@ -639,7 +639,7 @@
     AutoMutex lock(mLock);
 
     status_t status = NO_ERROR; // logged: make sure to set this before returning.
-    mediametrics::Defer([&] {
+    mediametrics::Defer defer([&] {
         mediametrics::LogItem(mMetricsId)
             .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_START)
             .set(AMEDIAMETRICS_PROP_DURATIONNS, (int64_t)(systemTime() - beginNs))
@@ -772,7 +772,7 @@
     const int64_t beginNs = systemTime();
 
     AutoMutex lock(mLock);
-    mediametrics::Defer([&]() {
+    mediametrics::Defer defer([&]() {
         mediametrics::LogItem(mMetricsId)
             .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_STOP)
             .set(AMEDIAMETRICS_PROP_DURATIONNS, (int64_t)(systemTime() - beginNs))
@@ -832,7 +832,7 @@
 {
     const int64_t beginNs = systemTime();
     AutoMutex lock(mLock);
-    mediametrics::Defer([&]() {
+    mediametrics::Defer defer([&]() {
         mediametrics::LogItem(mMetricsId)
             .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_FLUSH)
             .set(AMEDIAMETRICS_PROP_DURATIONNS, (int64_t)(systemTime() - beginNs))
@@ -1767,7 +1767,7 @@
     } else if (waitCount > 0) {
         time_t ms = WAIT_PERIOD_MS * (time_t) waitCount;
         timeout.tv_sec = ms / 1000;
-        timeout.tv_nsec = (long) (ms % 1000) * 1000000;
+        timeout.tv_nsec = (ms % 1000) * 1000000;
         requested = &timeout;
     } else {
         ALOGE("%s(%d): invalid waitCount %d", __func__, mPortId, waitCount);
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index f1213a3..60af84b 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -22,6 +22,7 @@
 #include <math.h>
 #include <sys/types.h>
 
+#include <android/media/ICaptureStateListener.h>
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
 #include <media/AudioEffect.h>
@@ -32,6 +33,8 @@
 
 namespace android {
 
+using media::ICaptureStateListener;
+
 enum {
     SET_DEVICE_CONNECTION_STATE = IBinder::FIRST_CALL_TRANSACTION,
     GET_DEVICE_CONNECTION_STATE,
@@ -114,6 +117,8 @@
     GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
     GET_DEVICES_FOR_ATTRIBUTES,
     AUDIO_MODULES_UPDATED,  // oneway
+    SET_CURRENT_IME_UID,
+    REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER,
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -215,7 +220,6 @@
                               audio_stream_type_t *stream,
                               pid_t pid,
                               uid_t uid,
-                              const String16& opPackageName,
                               const audio_config_t *config,
                               audio_output_flags_t flags,
                               audio_port_handle_t *selectedDeviceId,
@@ -254,7 +258,6 @@
             }
             data.writeInt32(pid);
             data.writeInt32(uid);
-            data.writeString16(opPackageName);
             data.write(config, sizeof(audio_config_t));
             data.writeInt32(static_cast <uint32_t>(flags));
             data.writeInt32(*selectedDeviceId);
@@ -1147,6 +1150,18 @@
         return static_cast <status_t> (reply.readInt32());
     }
 
+    virtual status_t setCurrentImeUid(uid_t uid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        status_t status = remote()->transact(SET_CURRENT_IME_UID, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return static_cast <status_t> (reply.readInt32());
+    }
+
     virtual bool isHapticPlaybackSupported()
     {
         Parcel data, reply;
@@ -1459,6 +1474,27 @@
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         remote()->transact(AUDIO_MODULES_UPDATED, data, &reply, IBinder::FLAG_ONEWAY);
     }
+
+    status_t registerSoundTriggerCaptureStateListener(
+            const sp<media::ICaptureStateListener>& listener,
+            bool* result) override {
+        Parcel data, reply;
+        status_t status;
+        status =
+            data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        if (status != NO_ERROR) return status;
+        status = data.writeStrongBinder(IInterface::asBinder(listener));
+        if (status != NO_ERROR) return status;
+        status =
+            remote()->transact(REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER,
+                               data,
+                               &reply,
+                               0);
+        if (status != NO_ERROR) return status;
+        status = reply.readBool(result);
+        if (status != NO_ERROR) return status;
+        return NO_ERROR;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1531,7 +1567,9 @@
         case GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
         case GET_DEVICES_FOR_ATTRIBUTES:
         case SET_ALLOWED_CAPTURE_POLICY:
-        case AUDIO_MODULES_UPDATED: {
+        case AUDIO_MODULES_UPDATED:
+        case SET_CURRENT_IME_UID:
+        case REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER: {
             if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                       __func__, code, IPCThreadState::self()->getCallingPid(),
@@ -1656,11 +1694,6 @@
             }
             pid_t pid = (pid_t)data.readInt32();
             uid_t uid = (uid_t)data.readInt32();
-            String16 opPackageName;
-            status = data.readString16(&opPackageName);
-            if (status != NO_ERROR) {
-                return status;
-            }
             audio_config_t config;
             memset(&config, 0, sizeof(audio_config_t));
             data.read(&config, sizeof(audio_config_t));
@@ -1672,7 +1705,7 @@
             std::vector<audio_io_handle_t> secondaryOutputs;
             status = getOutputForAttr(&attr,
                     &output, session, &stream, pid, uid,
-                    opPackageName, &config,
+                    &config,
                     flags, &selectedDeviceId, &portId, &secondaryOutputs);
             reply->writeInt32(status);
             status = reply->write(&attr, sizeof(audio_attributes_t));
@@ -2687,6 +2720,43 @@
             return NO_ERROR;
         } break;
 
+        case SET_CURRENT_IME_UID: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            int32_t uid;
+            status_t status = data.readInt32(&uid);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            status = setCurrentImeUid(uid);
+            reply->writeInt32(static_cast <int32_t>(status));
+            return NO_ERROR;
+        }
+
+        case REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            sp<IBinder> binder = data.readStrongBinder();
+            if (binder == nullptr) {
+                return BAD_VALUE;
+            }
+            sp<ICaptureStateListener>
+                listener = interface_cast<ICaptureStateListener>(
+                binder);
+            if (listener == nullptr) {
+                return BAD_VALUE;
+            }
+            bool ret;
+            status_t status =
+                registerSoundTriggerCaptureStateListener(listener, &ret);
+            LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
+                                "Server returned unexpected status code: %d",
+                                status);
+            status = reply->writeBool(ret);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            return NO_ERROR;
+        } break;
+
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libaudioclient/aidl/android/media/ICaptureStateListener.aidl b/media/libaudioclient/aidl/android/media/ICaptureStateListener.aidl
new file mode 100644
index 0000000..8502282
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/ICaptureStateListener.aidl
@@ -0,0 +1,21 @@
+/*
+ * 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;
+
+interface ICaptureStateListener {
+    void setCaptureState(boolean active);
+}
diff --git a/media/libaudioclient/include/media/AudioAttributes.h b/media/libaudioclient/include/media/AudioAttributes.h
index 0a35e9e..001c629 100644
--- a/media/libaudioclient/include/media/AudioAttributes.h
+++ b/media/libaudioclient/include/media/AudioAttributes.h
@@ -28,7 +28,7 @@
 {
 public:
     AudioAttributes() = default;
-    AudioAttributes(const audio_attributes_t &attributes) : mAttributes(attributes) {}
+    AudioAttributes(const audio_attributes_t &attributes) : mAttributes(attributes) {} // NOLINT
     AudioAttributes(volume_group_t groupId,
                     audio_stream_type_t stream,
                     const audio_attributes_t &attributes) :
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 5c300ed..b3c1cdf 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -711,6 +711,10 @@
 
     bool                    mInOverrun;         // whether recorder is currently in overrun state
 
+    ExtendedTimestamp       mPreviousTimestamp{}; // used to detect retrograde motion
+    bool                    mTimestampRetrogradePositionReported = false; // reduce log spam
+    bool                    mTimestampRetrogradeTimeReported = false;     // reduce log spam
+
 private:
     class DeathNotifier : public IBinder::DeathRecipient {
     public:
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index aebc875..19c2cbd 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -241,7 +241,6 @@
                                      audio_stream_type_t *stream,
                                      pid_t pid,
                                      uid_t uid,
-                                     const String16& opPackageName,
                                      const audio_config_t *config,
                                      audio_output_flags_t flags,
                                      audio_port_handle_t *selectedDeviceId,
@@ -400,6 +399,7 @@
 
     static status_t setAssistantUid(uid_t uid);
     static status_t setA11yServicesUids(const std::vector<uid_t>& uids);
+    static status_t setCurrentImeUid(uid_t uid);
 
     static bool     isHapticPlaybackSupported();
 
@@ -436,6 +436,30 @@
     static status_t getDeviceForStrategy(product_strategy_t strategy,
             AudioDeviceTypeAddr &device);
 
+    // A listener for capture state changes.
+    class CaptureStateListener : public RefBase {
+    public:
+        // Called whenever capture state changes.
+        virtual void onStateChanged(bool active) = 0;
+        // Called whenever the service dies (and hence our listener is no longer
+        // registered).
+        virtual void onServiceDied() = 0;
+
+        virtual ~CaptureStateListener() = default;
+    };
+
+    // Regiseters a listener for sound trigger capture state changes.
+    // There may only be one such listener registered at any point.
+    // The listener onStateChanged() method will be invoked sychronously from
+    // this call with the initial value.
+    // The listener onServiceDied() method will be invoked sychronously from
+    // this call if initial attempt to register failed.
+    // If the audio policy service cannot be reached, this method will return
+    // PERMISSION_DENIED and will not invoke the callback, otherwise, it will
+    // return NO_ERROR.
+    static status_t registerSoundTriggerCaptureStateListener(
+            const sp<CaptureStateListener>& listener);
+
     // ----------------------------------------------------------------------------
 
     class AudioVolumeGroupCallback : public RefBase
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 4adaaea..afae4d8 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -947,7 +947,7 @@
     class AudioTrackThread : public Thread
     {
     public:
-        AudioTrackThread(AudioTrack& receiver);
+        explicit AudioTrackThread(AudioTrack& receiver);
 
         // Do not call Thread::requestExitAndWait() without first calling requestExit().
         // Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough.
@@ -1226,7 +1226,7 @@
 private:
     class DeathNotifier : public IBinder::DeathRecipient {
     public:
-        DeathNotifier(AudioTrack* audioTrack) : mAudioTrack(audioTrack) { }
+        explicit DeathNotifier(AudioTrack* audioTrack) : mAudioTrack(audioTrack) { }
     protected:
         virtual void        binderDied(const wp<IBinder>& who);
     private:
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index c9d9716..612ce7a 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -71,7 +71,6 @@
             if (clientInfo.readFromParcel(parcel) != NO_ERROR) {
                 return DEAD_OBJECT;
             }
-            opPackageName = parcel->readString16();
             if (parcel->readInt32() != 0) {
                 // TODO: Using unsecurePointer() has some associated security
                 //       pitfalls (see declaration for details).
@@ -101,7 +100,6 @@
             (void)parcel->write(&attr, sizeof(audio_attributes_t));
             (void)parcel->write(&config, sizeof(audio_config_t));
             (void)clientInfo.writeToParcel(parcel);
-            (void)parcel->writeString16(opPackageName);
             if (sharedBuffer != 0) {
                 (void)parcel->writeInt32(1);
                 (void)parcel->writeStrongBinder(IInterface::asBinder(sharedBuffer));
@@ -125,7 +123,6 @@
         audio_attributes_t attr;
         audio_config_t config;
         AudioClient clientInfo;
-        String16 opPackageName;
         sp<IMemory> sharedBuffer;
         uint32_t notificationsPerBuffer;
         float speed;
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index ec3461e..bb1c07f 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -31,6 +31,11 @@
 #include <vector>
 
 namespace android {
+namespace media {
+// Must be pre-declared, or else there isn't a good way to generate a header
+// library.
+class ICaptureStateListener;
+}
 
 // ----------------------------------------------------------------------------
 
@@ -65,7 +70,6 @@
                                       audio_stream_type_t *stream,
                                       pid_t pid,
                                       uid_t uid,
-                                      const String16& opPackageName,
                                       const audio_config_t *config,
                                       audio_output_flags_t flags,
                                       audio_port_handle_t *selectedDeviceId,
@@ -222,6 +226,7 @@
 
     virtual status_t setAssistantUid(uid_t uid) = 0;
     virtual status_t setA11yServicesUids(const std::vector<uid_t>& uids) = 0;
+    virtual status_t setCurrentImeUid(uid_t uid) = 0;
 
     virtual bool     isHapticPlaybackSupported() = 0;
     virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0;
@@ -243,6 +248,12 @@
 
     virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
                                                    AudioDeviceTypeAddr &device) = 0;
+
+    // The return code here is only intended to represent transport errors. The
+    // actual server implementation should always return NO_ERROR.
+    virtual status_t registerSoundTriggerCaptureStateListener(
+        const sp<media::ICaptureStateListener>& listener,
+        bool* result) = 0;
 };
 
 
diff --git a/media/libeffects/config/Android.bp b/media/libeffects/config/Android.bp
index 8476f82..8493e30 100644
--- a/media/libeffects/config/Android.bp
+++ b/media/libeffects/config/Android.bp
@@ -15,6 +15,7 @@
         "libtinyxml2",
         "libutils",
         "libmedia_helper",
+        "libcutils",
     ],
 
     header_libs: ["libaudio_system_headers"],
diff --git a/media/libeffects/config/include/media/EffectsConfig.h b/media/libeffects/config/include/media/EffectsConfig.h
index ef10e0d..57d4dd7 100644
--- a/media/libeffects/config/include/media/EffectsConfig.h
+++ b/media/libeffects/config/include/media/EffectsConfig.h
@@ -35,11 +35,6 @@
 /** Default path of effect configuration file. Relative to DEFAULT_LOCATIONS. */
 constexpr const char* DEFAULT_NAME = "audio_effects.xml";
 
-/** Default path of effect configuration file.
- * The /vendor partition is the recommended one, the others are deprecated.
- */
-constexpr const char* DEFAULT_LOCATIONS[] = {"/odm/etc", "/vendor/etc", "/system/etc"};
-
 /** Directories where the effect libraries will be search for. */
 constexpr const char* LD_EFFECT_LIBRARY_PATH[] =
 #ifdef __LP64__
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index 85fbf11..26eaaf8 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -27,6 +27,7 @@
 
 #include <media/EffectsConfig.h>
 #include <media/TypeConverter.h>
+#include <system/audio_config.h>
 
 using namespace tinyxml2;
 
@@ -338,7 +339,7 @@
         return parseWithPath(path);
     }
 
-    for (const std::string& location : DEFAULT_LOCATIONS) {
+    for (const std::string& location : audio_get_configuration_paths()) {
         std::string defaultPath = location + '/' + DEFAULT_NAME;
         if (access(defaultPath.c_str(), R_OK) != 0) {
             continue;
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 867187d..62a86e7 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -33,6 +33,7 @@
 
 aidl_interface {
     name: "resourcemanager_aidl_interface",
+    unstable: true,
     local_include_dir: "aidl",
     srcs: [
         "aidl/android/media/IResourceManagerClient.aidl",
@@ -272,7 +273,6 @@
         "IRemoteDisplay.cpp",
         "IRemoteDisplayClient.cpp",
         "IStreamSource.cpp",
-        "MediaUtils.cpp",
         "Metadata.cpp",
         "mediarecorder.cpp",
         "IMediaMetadataRetriever.cpp",
@@ -295,7 +295,6 @@
     },
 
     header_libs: [
-        "bionic_libc_platform_headers",
         "libstagefright_headers",
         "media_ndk_headers",
     ],
@@ -334,7 +333,6 @@
     ],
 
     static_libs: [
-        "libc_malloc_debug_backtrace", // for memory heap analysis
         "resourcemanager_aidl_interface-ndk_platform",
     ],
 
diff --git a/media/libmedia/include/media/Modulo.h b/media/libmedia/include/media/Modulo.h
index 23280ac..c66928d 100644
--- a/media/libmedia/include/media/Modulo.h
+++ b/media/libmedia/include/media/Modulo.h
@@ -90,7 +90,7 @@
     typedef typename std::make_unsigned<T>::type unsignedT;
 
     Modulo() { } // intentionally uninitialized data
-    Modulo(const T &value) { mValue = value; }
+    Modulo(const T &value) { mValue = value; } // NOLINT
     const T & value() const { return mValue; } // not assignable
     signedT signedValue() const { return mValue; }
     unsignedT unsignedValue() const { return mValue; }
diff --git a/media/libmediametrics/include/media/MediaMetricsItem.h b/media/libmediametrics/include/media/MediaMetricsItem.h
index 08720f1..8477f8d 100644
--- a/media/libmediametrics/include/media/MediaMetricsItem.h
+++ b/media/libmediametrics/include/media/MediaMetricsItem.h
@@ -208,11 +208,11 @@
 
 template<size_t N>
 static inline bool startsWith(const std::string &s, const char (&comp)[N]) {
-    return !strncmp(s.c_str(), comp, N - 1);
+    return !strncmp(s.c_str(), comp, N - 1); // last char is null termination
 }
 
 static inline bool startsWith(const std::string& s, const std::string& comp) {
-    return !strncmp(s.c_str(), comp.c_str(), comp.size() - 1);
+    return !strncmp(s.c_str(), comp.c_str(), comp.size());
 }
 
 /**
@@ -223,7 +223,7 @@
 class Defer {
 public:
     template <typename U>
-    Defer(U &&f) : mThunk(std::forward<U>(f)) {}
+    explicit Defer(U &&f) : mThunk(std::forward<U>(f)) {}
     ~Defer() { mThunk(); }
 
 private:
@@ -522,7 +522,7 @@
     BufferedItem(const BufferedItem&) = delete;
     BufferedItem& operator=(const BufferedItem&) = delete;
 
-    BufferedItem(const std::string key, char *begin, char *end)
+    BufferedItem(const std::string& key, char *begin, char *end)
         : BufferedItem(key.c_str(), begin, end) { }
 
     BufferedItem(const char *key, char *begin, char *end)
@@ -687,7 +687,7 @@
 template <size_t N = 4096>
 class LogItem : public BufferedItem {
 public:
-    explicit LogItem(const std::string key) : LogItem(key.c_str()) { }
+    explicit LogItem(const std::string& key) : LogItem(key.c_str()) { }
 
     // Since this class will not be defined before the base class, we initialize variables
     // in our own order.
@@ -742,10 +742,10 @@
             mElem = other.mElem;
             return *this;
         }
-        Prop(Prop&& other) {
+        Prop(Prop&& other) noexcept {
             *this = std::move(other);
         }
-        Prop& operator=(Prop&& other) {
+        Prop& operator=(Prop&& other) noexcept {
             mName = std::move(other.mName);
             mElem = std::move(other.mElem);
             return *this;
@@ -856,7 +856,7 @@
     // Iteration of props within item
     class iterator {
     public:
-        iterator(const std::map<std::string, Prop>::const_iterator &_it) : it(_it) { }
+        explicit iterator(const std::map<std::string, Prop>::const_iterator &_it) : it(_it) { }
         iterator &operator++() {
             ++it;
             return *this;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 81ffcbc..42a0622 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -57,7 +57,6 @@
 #include <media/MediaMetadataRetrieverInterface.h>
 #include <media/Metadata.h>
 #include <media/AudioTrack.h>
-#include <media/MemoryLeakTrackUtil.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/MediaCodecList.h>
@@ -68,7 +67,7 @@
 #include <media/stagefright/foundation/ALooperRoster.h>
 #include <media/stagefright/SurfaceUtils.h>
 #include <mediautils/BatteryNotifier.h>
-
+#include <mediautils/MemoryLeakTrackUtil.h>
 #include <memunreachable/memunreachable.h>
 #include <system/audio.h>
 
diff --git a/media/libmediatranscoding/Android.bp b/media/libmediatranscoding/Android.bp
index 7468426..f948bd8 100644
--- a/media/libmediatranscoding/Android.bp
+++ b/media/libmediatranscoding/Android.bp
@@ -17,6 +17,7 @@
 // AIDL interfaces of MediaTranscoding.
 aidl_interface {
     name: "mediatranscoding_aidl_interface",
+    unstable: true,
     local_include_dir: "aidl",
     srcs: [
         "aidl/android/media/IMediaTranscodingService.aidl",
diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp
index e5115d9..fa13f32 100644
--- a/media/libstagefright/ACodecBufferChannel.cpp
+++ b/media/libstagefright/ACodecBufferChannel.cpp
@@ -134,7 +134,12 @@
     }
     ssize_t result = -1;
     ssize_t codecDataOffset = 0;
-    if (mCrypto != NULL) {
+    if (numSubSamples == 1
+            && subSamples[0].mNumBytesOfClearData == 0
+            && subSamples[0].mNumBytesOfEncryptedData == 0) {
+        // We don't need to go through crypto or descrambler if the input is empty.
+        result = 0;
+    } else if (mCrypto != NULL) {
         hardware::drm::V1_0::DestinationBuffer destination;
         if (secure) {
             destination.type = DrmBufferType::NATIVE_HANDLE;
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 7fec072..1395c27 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -221,6 +221,7 @@
 
 void MediaCodecSource::Puller::resume() {
     Mutexed<Queue>::Locked queue(mQueue);
+    queue->flush();
     queue->mPaused = false;
 }
 
diff --git a/media/libstagefright/bqhelper/GraphicBufferSource.cpp b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
index 986c9ac..cff14ac 100644
--- a/media/libstagefright/bqhelper/GraphicBufferSource.cpp
+++ b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
@@ -1423,7 +1423,7 @@
     // stall since no future events are expected.
     mEndOfStream = true;
 
-    if (mExecuting && !haveAvailableBuffers_l()) {
+    if (mStopTimeUs == -1 && mExecuting && !haveAvailableBuffers_l()) {
         submitEndOfInputStream_l();
     }
 
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AData.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AData.h
index c6c12ff..87cf58b 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/AData.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AData.h
@@ -28,6 +28,10 @@
 #undef HIDE
 #define HIDE __attribute__((visibility("hidden")))
 
+// The internals of AUnion cause problems with CFI
+#undef  NO_CFI
+#define NO_CFI __attribute__((no_sanitize("cfi")))
+
 namespace android {
 
 /**
@@ -93,7 +97,7 @@
      * \param args      arbitrary arguments for constructor
      */
     template<typename T, typename ...Args>
-    inline static void emplace(size_t totalSize, T *addr, Args&&... args) {
+    inline static void NO_CFI emplace(size_t totalSize, T *addr, Args&&... args) {
         new(addr)T(std::forward<Args>(args)...);
         // clear slack space - this is not technically required
         constexpr size_t size = sizeof(T);
@@ -160,7 +164,7 @@
     template<
             typename T, typename ...Args,
             typename=typename std::enable_if<is_one_of<T, void, Ts...>::value>::type>
-    inline void emplace(Args&&... args) {
+    inline void NO_CFI emplace(Args&&... args) {
         _AUnion_impl::emplace(
                 sizeof(_type), reinterpret_cast<T*>(&mValue), std::forward<Args>(args)...);
     }
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
index 1e434cb..7bd33c1 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
@@ -203,6 +203,14 @@
     unsigned mSerial;
 };
 
+bool AMPEG4ElementaryAssembler::initCheck() {
+    if(mSizeLength == 0 || mIndexLength == 0 || mIndexDeltaLength == 0) {
+        android_errorWriteLog(0x534e4554, "124777537");
+        return false;
+    }
+    return true;
+}
+
 ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket(
         const sp<ARTPSource> &source) {
     List<sp<ABuffer> > *queue = source->queue();
@@ -250,12 +258,16 @@
     } else {
         // hexdump(buffer->data(), buffer->size());
         if (buffer->size() < 2) {
+            android_errorWriteLog(0x534e4554, "124783982");
+            queue->erase(queue->begin());
             return MALFORMED_PACKET;
         }
 
         unsigned AU_headers_length = U16_AT(buffer->data());  // in bits
 
         if (buffer->size() < 2 + (AU_headers_length + 7) / 8) {
+            android_errorWriteLog(0x534e4554, "124783982");
+            queue->erase(queue->begin());
             return MALFORMED_PACKET;
         }
 
@@ -338,6 +350,12 @@
             ABitReader bits(buffer->data() + offset, buffer->size() - offset);
 
             unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength);
+            if (buffer->size() < auxSize) {
+                ALOGE("b/123940919 auxSize %u", auxSize);
+                android_errorWriteLog(0x534e4554, "123940919");
+                queue->erase(queue->begin());
+                return MALFORMED_PACKET;
+            }
 
             offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8;
         }
@@ -346,7 +364,15 @@
              it != headers.end(); ++it) {
             const AUHeader &header = *it;
 
+            if (buffer->size() < header.mSize) {
+                ALOGE("b/123940919 AU_size %u", header.mSize);
+                android_errorWriteLog(0x534e4554, "123940919");
+                queue->erase(queue->begin());
+                return MALFORMED_PACKET;
+            }
             if (buffer->size() < offset + header.mSize) {
+                android_errorWriteLog(0x534e4554, "124783982");
+                queue->erase(queue->begin());
                 return MALFORMED_PACKET;
             }
 
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h
index 693fca5..57b7d71 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h
@@ -36,6 +36,7 @@
     AMPEG4ElementaryAssembler(
             const sp<AMessage> &notify, const AString &desc,
             const AString &params);
+    virtual bool initCheck();
 
 protected:
     virtual ~AMPEG4ElementaryAssembler();
diff --git a/media/libstagefright/rtsp/ARTPAssembler.h b/media/libstagefright/rtsp/ARTPAssembler.h
index 7c147be..4082d4c 100644
--- a/media/libstagefright/rtsp/ARTPAssembler.h
+++ b/media/libstagefright/rtsp/ARTPAssembler.h
@@ -39,6 +39,7 @@
 
     void onPacketReceived(const sp<ARTPSource> &source);
     virtual void onByeReceived() = 0;
+    virtual bool initCheck() { return true; }
 
 protected:
     virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source) = 0;
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 4afa6f4..f5f8128 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -82,6 +82,10 @@
     } else {
         TRESPASS();
     }
+
+    if (mAssembler != NULL && !mAssembler->initCheck()) {
+        mAssembler.clear();
+    }
 }
 
 static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
@@ -89,7 +93,7 @@
 }
 
 void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
-    if (queuePacket(buffer) && mAssembler != NULL) {
+    if (mAssembler != NULL && queuePacket(buffer)) {
         mAssembler->onPacketReceived(this);
     }
 }
@@ -171,7 +175,9 @@
 }
 
 void ARTPSource::byeReceived() {
-    mAssembler->onByeReceived();
+    if (mAssembler != NULL) {
+        mAssembler->onByeReceived();
+    }
 }
 
 void ARTPSource::addFIR(const sp<ABuffer> &buffer) {
diff --git a/media/libstagefright/timedtext/TextDescriptions.cpp b/media/libstagefright/timedtext/TextDescriptions.cpp
index 0dc7722..2c2d11d 100644
--- a/media/libstagefright/timedtext/TextDescriptions.cpp
+++ b/media/libstagefright/timedtext/TextDescriptions.cpp
@@ -445,51 +445,75 @@
                     | *(tmpData + 10) << 8 | *(tmpData + 11);
                 parcel->writeInt32(rgba);
 
+                // tx3g box contains class FontTableBox() which extends ftab box
+                // This information is part of the 3gpp Timed Text Format
+                // Specification#: 26.245 / Section: 5.16(Sample Description Format)
+                // https://www.3gpp.org/ftp/Specs/archive/26_series/26.245/
+
                 tmpData += 12;
                 remaining -= 12;
 
-                if (remaining < 2) {
+                if (remaining < 8) {
                     return OK;
                 }
 
-                size_t dataPos = parcel->dataPosition();
-
-                parcel->writeInt32(KEY_STRUCT_FONT_LIST);
-                uint16_t count = U16_AT(tmpData);
-                parcel->writeInt32(count);
-
-                tmpData += 2;
-                remaining -= 2;
-
-                for (int i = 0; i < count; i++) {
-                    if (remaining < 3) {
-                        // roll back
-                        parcel->setDataPosition(dataPos);
-                        return OK;
-                    }
-                    // font ID
-                    parcel->writeInt32(U16_AT(tmpData));
-
-                    // font name length
-                    parcel->writeInt32(*(tmpData + 2));
-
-                    size_t len = *(tmpData + 2);
-
-                    tmpData += 3;
-                    remaining -= 3;
-
-                    if (remaining < len) {
-                        // roll back
-                        parcel->setDataPosition(dataPos);
-                        return OK;
-                    }
-
-                    parcel->write(tmpData, len);
-                    tmpData += len;
-                    remaining -= len;
+                size_t subChunkSize = U32_AT(tmpData);
+                if(remaining < subChunkSize) {
+                    return OK;
                 }
 
-                // there is a "DisparityBox" after this according to the spec, but we ignore it
+                uint32_t subChunkType = U32_AT(tmpData + 4);
+
+                if (subChunkType == FOURCC('f', 't', 'a', 'b'))
+                {
+                    tmpData += 8;
+                    size_t subChunkRemaining = subChunkSize - 8;
+
+                    if(subChunkRemaining < 2) {
+                        return OK;
+                    }
+                    size_t dataPos = parcel->dataPosition();
+
+                    parcel->writeInt32(KEY_STRUCT_FONT_LIST);
+                    uint16_t count = U16_AT(tmpData);
+                    parcel->writeInt32(count);
+
+                    tmpData += 2;
+                    subChunkRemaining -= 2;
+
+                    for (int i = 0; i < count; i++) {
+                        if (subChunkRemaining < 3) {
+                            // roll back
+                            parcel->setDataPosition(dataPos);
+                            return OK;
+                        }
+                        // font ID
+                        parcel->writeInt32(U16_AT(tmpData));
+
+                        // font name length
+                        size_t len = *(tmpData + 2);
+
+                        parcel->writeInt32(len);
+
+                        tmpData += 3;
+                        subChunkRemaining -=3;
+
+                        if (subChunkRemaining < len) {
+                            // roll back
+                            parcel->setDataPosition(dataPos);
+                            return OK;
+                        }
+
+                        parcel->writeByteArray(len, tmpData);
+                        tmpData += len;
+                        subChunkRemaining -= len;
+                    }
+                    tmpData += subChunkRemaining;
+                    remaining -= subChunkSize;
+                } else {
+                    tmpData += subChunkSize;
+                    remaining -= subChunkSize;
+                }
                 break;
             }
             default:
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index b7037e9..e3f1e44 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -19,6 +19,7 @@
         "AImageReaderUtils.cpp",
         "BatteryNotifier.cpp",
         "ISchedulingPolicyService.cpp",
+        "LimitProcessMemory.cpp",
         "MemoryLeakTrackUtil.cpp",
         "ProcessInfo.cpp",
         "SchedulingPolicyService.cpp",
diff --git a/media/libmedia/MediaUtils.cpp b/media/utils/LimitProcessMemory.cpp
similarity index 97%
rename from media/libmedia/MediaUtils.cpp
rename to media/utils/LimitProcessMemory.cpp
index 2efb30e..623138f 100644
--- a/media/libmedia/MediaUtils.cpp
+++ b/media/utils/LimitProcessMemory.cpp
@@ -23,8 +23,7 @@
 #include <unistd.h>
 
 #include <bionic/malloc.h>
-
-#include "MediaUtils.h"
+#include <mediautils/LimitProcessMemory.h>
 
 extern "C" void __scudo_set_rss_limit(size_t, int) __attribute__((weak));
 
diff --git a/media/utils/MemoryLeakTrackUtil.cpp b/media/utils/MemoryLeakTrackUtil.cpp
index 6166859..fdb8c4f 100644
--- a/media/utils/MemoryLeakTrackUtil.cpp
+++ b/media/utils/MemoryLeakTrackUtil.cpp
@@ -19,7 +19,7 @@
 #define LOG_TAG "MemoryLeackTrackUtil"
 #include <utils/Log.h>
 
-#include "media/MemoryLeakTrackUtil.h"
+#include <mediautils/MemoryLeakTrackUtil.h>
 #include <sstream>
 
 #include <bionic/malloc.h>
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 7fd4d0a..87ea084 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -223,25 +223,6 @@
     return ok;
 }
 
-bool accessCallAudioAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
-    static const String16 sAccessCallAudio("android.permission.ACCESS_CALL_AUDIO");
-    PermissionController permissionController;
-    const String16 resolvedOpPackageName = resolveCallingPackage(
-         permissionController, opPackageName, uid);
-    if (resolvedOpPackageName.size() == 0) {
-        ALOGE("accessCallAudioAllowed - FAIL - package not found.");
-        return false;
-    }
-    AppOpsManager appOps;
-    const int32_t op = appOps.permissionToOpCode(sAccessCallAudio);
-    const int32_t opResult = appOps.noteOp(op, uid, resolvedOpPackageName);
-    if (opResult == PermissionController::MODE_DEFAULT) {
-        // Only allow in case this is a system app with the proper privilege permission
-        return PermissionCache::checkPermission(sAccessCallAudio, pid, uid);
-    }
-    return opResult == PermissionController::MODE_ALLOWED;
-}
-
 // privileged behavior needed by Dialer, Settings, SetupWizard and CellBroadcastReceiver
 bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid) {
     static const String16 sWriteSecureSettings("android.permission.WRITE_SECURE_SETTINGS");
@@ -278,29 +259,28 @@
     return NO_ERROR;
 }
 
-void MediaPackageManager::loadPackageManager() {
-    if (mPackageManager != nullptr) {
-        return;
-    }
+sp<content::pm::IPackageManagerNative> MediaPackageManager::retreivePackageManager() {
     const sp<IServiceManager> sm = defaultServiceManager();
     if (sm == nullptr) {
         ALOGW("%s: failed to retrieve defaultServiceManager", __func__);
-        return;
+        return nullptr;
     }
     sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName));
     if (packageManager == nullptr) {
         ALOGW("%s: failed to retrieve native package manager", __func__);
-        return;
+        return nullptr;
     }
-    mPackageManager = interface_cast<content::pm::IPackageManagerNative>(packageManager);
+    return interface_cast<content::pm::IPackageManagerNative>(packageManager);
 }
 
 std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) {
-    /** Can not fetch package manager at construction it may not yet be registered. */
-    loadPackageManager();
     if (mPackageManager == nullptr) {
-        ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
-        return std::nullopt;
+        /** Can not fetch package manager at construction it may not yet be registered. */
+        mPackageManager = retreivePackageManager();
+        if (mPackageManager == nullptr) {
+            ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
+            return std::nullopt;
+        }
     }
 
     std::vector<std::string> packageNames;
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index 4a3e470..59d74de 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -100,7 +100,6 @@
 bool TimeCheck::TimeCheckThread::threadLoop()
 {
     status_t status = TIMED_OUT;
-    const char *tag;
     {
         AutoMutex _l(mMutex);
 
@@ -109,6 +108,7 @@
         }
 
         nsecs_t endTimeNs = INT64_MAX;
+        const char *tag = "<unspecified>";
         // KeyedVector mMonitorRequests is ordered so take first entry as next timeout
         if (mMonitorRequests.size() != 0) {
             endTimeNs = mMonitorRequests.keyAt(0);
diff --git a/media/libmedia/MediaUtils.h b/media/utils/include/mediautils/LimitProcessMemory.h
similarity index 86%
rename from media/libmedia/MediaUtils.h
rename to media/utils/include/mediautils/LimitProcessMemory.h
index f80dd30..7f48b4f 100644
--- a/media/libmedia/MediaUtils.h
+++ b/media/utils/include/mediautils/LimitProcessMemory.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef _MEDIA_UTILS_H
-#define _MEDIA_UTILS_H
+#ifndef ANDROID_MEDIAUTILS_LIMIT_PROCESS_MEMORY_H
+#define ANDROID_MEDIAUTILS_LIMIT_PROCESS_MEMORY_H
 
 namespace android {
 
@@ -32,4 +32,4 @@
 
 }   // namespace android
 
-#endif  // _MEDIA_UTILS_H
+#endif // ANDROID_MEDIAUTILS_LIMIT_PROCESS_MEMORY_H
diff --git a/media/libmedia/include/media/MemoryLeakTrackUtil.h b/media/utils/include/mediautils/MemoryLeakTrackUtil.h
similarity index 100%
rename from media/libmedia/include/media/MemoryLeakTrackUtil.h
rename to media/utils/include/mediautils/MemoryLeakTrackUtil.h
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 060e849..212599a 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -93,7 +93,6 @@
 bool dumpAllowed();
 bool modifyPhoneStateAllowed(pid_t pid, uid_t uid);
 bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid);
-bool accessCallAudioAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
 
 status_t checkIMemory(const sp<IMemory>& iMemory);
 
@@ -111,7 +110,7 @@
 private:
     static constexpr const char* nativePackageManagerName = "package_native";
     std::optional<bool> doIsAllowed(uid_t uid);
-    void loadPackageManager();
+    sp<content::pm::IPackageManagerNative> retreivePackageManager();
     sp<content::pm::IPackageManagerNative> mPackageManager; // To check apps manifest
     uint_t mPackageManagerErrors = 0;
     struct Package {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ecda56b..03c16f3 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -67,10 +67,10 @@
 #include <powermanager/PowerManager.h>
 
 #include <media/IMediaLogService.h>
-#include <media/MemoryLeakTrackUtil.h>
 #include <media/nbaio/Pipe.h>
 #include <media/nbaio/PipeReader.h>
 #include <mediautils/BatteryNotifier.h>
+#include <mediautils/MemoryLeakTrackUtil.h>
 #include <mediautils/ServiceUtilities.h>
 #include <mediautils/TimeCheck.h>
 #include <private/android_filesystem_config.h>
@@ -343,7 +343,7 @@
         ret = AudioSystem::getOutputForAttr(&localAttr, &io,
                                             actualSessionId,
                                             &streamType, client.clientPid, client.clientUid,
-                                            client.packageName, &fullConfig,
+                                            &fullConfig,
                                             (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
                                                     AUDIO_OUTPUT_FLAG_DIRECT),
                                             deviceId, &portId, &secondaryOutputs);
@@ -783,9 +783,8 @@
     output.outputId = AUDIO_IO_HANDLE_NONE;
     output.selectedDeviceId = input.selectedDeviceId;
     lStatus = AudioSystem::getOutputForAttr(&localAttr, &output.outputId, sessionId, &streamType,
-                                            clientPid, clientUid, input.opPackageName,
-                                            &input.config, input.flags, &output.selectedDeviceId,
-                                            &portId, &secondaryOutputs);
+                                            clientPid, clientUid, &input.config, input.flags,
+                                            &output.selectedDeviceId, &portId, &secondaryOutputs);
 
     if (lStatus != NO_ERROR || output.outputId == AUDIO_IO_HANDLE_NONE) {
         ALOGE("createTrack() getOutputForAttr() return error %d or invalid output handle", lStatus);
@@ -1186,15 +1185,21 @@
     }
 
     AutoMutex lock(mHardwareLock);
+    sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev->hwDevice();
+    if (primaryDev == nullptr) {
+        ALOGW("%s: no primary HAL device", __func__);
+        return INVALID_OPERATION;
+    }
     mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
+    ret = primaryDev->setMicMute(state);
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
         sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
-        status_t result = dev->setMicMute(state);
-        if (result != NO_ERROR) {
-            ret = result;
+        if (dev != primaryDev) {
+            (void)dev->setMicMute(state);
         }
     }
     mHardwareStatus = AUDIO_HW_IDLE;
+    ALOGW_IF(ret != NO_ERROR, "%s: error %d setting state to HAL", __func__, ret);
     return ret;
 }
 
@@ -1204,20 +1209,18 @@
     if (ret != NO_ERROR) {
         return false;
     }
-    bool mute = true;
-    bool state = AUDIO_MODE_INVALID;
     AutoMutex lock(mHardwareLock);
-    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
-    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
-        sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
-        status_t result = dev->getMicMute(&state);
-        if (result == NO_ERROR) {
-            mute = mute && state;
-        }
+    sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev->hwDevice();
+    if (primaryDev == nullptr) {
+        ALOGW("%s: no primary HAL device", __func__);
+        return false;
     }
+    bool state;
+    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
+    ret = primaryDev->getMicMute(&state);
     mHardwareStatus = AUDIO_HW_IDLE;
-
-    return mute;
+    ALOGE_IF(ret != NO_ERROR, "%s: error %d getting state from HAL", __func__, ret);
+    return (ret == NO_ERROR) && state;
 }
 
 void AudioFlinger::setRecordSilenced(audio_port_handle_t portId, bool silenced)
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 40519b0..5c20a2d 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -681,7 +681,8 @@
                                           struct audio_mmap_buffer_info *info);
         virtual status_t getMmapPosition(struct audio_mmap_position *position);
         virtual status_t start(const AudioClient& client,
-                                         audio_port_handle_t *handle);
+                               const audio_attributes_t *attr,
+                               audio_port_handle_t *handle);
         virtual status_t stop(audio_port_handle_t handle);
         virtual status_t standby();
 
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 8a65122..55f2952 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -29,6 +29,7 @@
 #include <system/audio_effects/effect_visualizer.h>
 #include <audio_utils/channels.h>
 #include <audio_utils/primitives.h>
+#include <media/AudioCommonTypes.h>
 #include <media/AudioContainers.h>
 #include <media/AudioEffect.h>
 #include <media/AudioDeviceTypeAddr.h>
@@ -212,8 +213,8 @@
     bool registered = false;
     bool doEnable = false;
     bool enabled = false;
-    audio_io_handle_t io;
-    uint32_t strategy;
+    audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
+    uint32_t strategy = PRODUCT_STRATEGY_NONE;
 
     {
         Mutex::Autolock _l(mLock);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 65cf96c..105fa14 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -8633,10 +8633,10 @@
 }
 
 status_t AudioFlinger::MmapThreadHandle::start(const AudioClient& client,
-        audio_port_handle_t *handle)
+        const audio_attributes_t *attr, audio_port_handle_t *handle)
 
 {
-    return mThread->start(client, handle);
+    return mThread->start(client, attr, handle);
 }
 
 status_t AudioFlinger::MmapThreadHandle::stop(audio_port_handle_t handle)
@@ -8741,6 +8741,7 @@
 }
 
 status_t AudioFlinger::MmapThread::start(const AudioClient& client,
+                                         const audio_attributes_t *attr,
                                          audio_port_handle_t *handle)
 {
     ALOGV("%s clientUid %d mStandby %d mPortId %d *handle %d", __FUNCTION__,
@@ -8774,7 +8775,6 @@
                                             &stream,
                                             client.clientPid,
                                             client.clientUid,
-                                            client.packageName,
                                             &config,
                                             flags,
                                             &deviceId,
@@ -8832,9 +8832,10 @@
     }
 
     // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
-    sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId,
-                                        isOutput(), client.clientUid, client.clientPid,
-                                        IPCThreadState::self()->getCallingPid(), portId);
+    sp<MmapTrack> track = new MmapTrack(this, attr == nullptr ? mAttr : *attr, mSampleRate, mFormat,
+                                        mChannelMask, mSessionId, isOutput(), client.clientUid,
+                                        client.clientPid, IPCThreadState::self()->getCallingPid(),
+                                        portId);
 
     if (isOutput()) {
         // force volume update when a new track is added
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 8149e95..e5a6196 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1776,7 +1776,9 @@
     status_t createMmapBuffer(int32_t minSizeFrames,
                                       struct audio_mmap_buffer_info *info);
     status_t getMmapPosition(struct audio_mmap_position *position);
-    status_t start(const AudioClient& client, audio_port_handle_t *handle);
+    status_t start(const AudioClient& client,
+                   const audio_attributes_t *attr,
+                   audio_port_handle_t *handle);
     status_t stop(audio_port_handle_t handle);
     status_t standby();
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
index 6e29632..6167f95 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
@@ -34,6 +34,8 @@
     virtual audio_patch_handle_t getPatchHandle() const = 0;
 
     virtual void setPatchHandle(audio_patch_handle_t handle) = 0;
+
+    virtual bool isMmap() = 0;
 };
 
 template <class IoDescriptor, class Filter>
@@ -41,11 +43,24 @@
         IoDescriptor& desc, Filter filter, bool& active, const DeviceVector& devices)
 {
     auto activeClients = desc->clientsList(true /*activeOnly*/);
-    auto activeClientsWithRoute =
-        desc->clientsList(true /*activeOnly*/, filter, true /*preferredDevice*/);
     active = activeClients.size() > 0;
-    if (active && activeClients.size() == activeClientsWithRoute.size()) {
-        return devices.getDeviceFromId(activeClientsWithRoute[0]->preferredDeviceId());
+
+    if (active) {
+        // On MMAP IOs, the preferred device is selected by the first client (virtual client
+        // created when the mmap stream is opened). This client is never active.
+        // On non MMAP IOs, the preferred device is honored only if all active clients have
+        // a preferred device in which case the first client drives the selection.
+        if (desc->isMmap()) {
+            // The client list is never empty on a MMAP IO
+            return devices.getDeviceFromId(
+                    desc->clientsList(false /*activeOnly*/)[0]->preferredDeviceId());
+        } else {
+            auto activeClientsWithRoute =
+                desc->clientsList(true /*activeOnly*/, filter, true /*preferredDevice*/);
+            if (activeClients.size() == activeClientsWithRoute.size()) {
+                return devices.getDeviceFromId(activeClientsWithRoute[0]->preferredDeviceId());
+            }
+        }
     }
     return nullptr;
 }
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index c67a006..6f47abc 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -92,6 +92,12 @@
     audio_config_base_t getConfig() const override;
     audio_patch_handle_t getPatchHandle() const override;
     void setPatchHandle(audio_patch_handle_t handle) override;
+    bool isMmap() override {
+        if (getPolicyAudioPort() != nullptr) {
+            return getPolicyAudioPort()->isMmap();
+        }
+        return false;
+    }
 
     status_t open(const audio_config_t *config,
                   const sp<DeviceDescriptor> &device,
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 41f7dfc..39d1140 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -268,6 +268,12 @@
     audio_config_base_t getConfig() const override;
     audio_patch_handle_t getPatchHandle() const override;
     void setPatchHandle(audio_patch_handle_t handle) override;
+    bool isMmap() override {
+        if (getPolicyAudioPort() != nullptr) {
+            return getPolicyAudioPort()->isMmap();
+        }
+        return false;
+    }
 
     TrackClientVector clientsList(bool activeOnly = false,
                                   product_strategy_t strategy = PRODUCT_STRATEGY_NONE,
diff --git a/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h b/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h
index 99df3c0..d2f6297 100644
--- a/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h
@@ -107,6 +107,15 @@
                 (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
     }
 
+    inline bool isMmap() const
+    {
+        return (asAudioPort()->getType() == AUDIO_PORT_TYPE_MIX)
+                && (((asAudioPort()->getRole() == AUDIO_PORT_ROLE_SOURCE) &&
+                        ((mFlags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) != 0))
+                    || ((asAudioPort()->getRole() == AUDIO_PORT_ROLE_SINK) &&
+                        ((mFlags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0)));
+    }
+
     void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); }
     const AudioRouteVector &getRoutes() const { return mRoutes; }
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index aaa28bc..d5272bc 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -152,10 +152,16 @@
 bool AudioOutputDescriptor::setVolume(float volumeDb,
                                       VolumeSource volumeSource,
                                       const StreamTypeVector &/*streams*/,
-                                      const DeviceTypeSet& /*deviceTypes*/,
+                                      const DeviceTypeSet& deviceTypes,
                                       uint32_t delayMs,
                                       bool force)
 {
+
+    if (!supportedDevices().containsDeviceAmongTypes(deviceTypes)) {
+        ALOGV("%s output ID %d unsupported device %s",
+                __func__, getId(), toString(deviceTypes).c_str());
+        return false;
+    }
     // We actually change the volume if:
     // - the float value returned by computeVolume() changed
     // - the force flag is set
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
index fe15ff6..151c7bb 100644
--- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -73,10 +73,18 @@
 audio_stream_type_t ProductStrategy::getStreamTypeForAttributes(
         const audio_attributes_t &attr) const
 {
-    const auto iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
+    const auto &iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
                                    [&attr](const auto &supportedAttr) {
         return AudioProductStrategy::attributesMatches(supportedAttr.mAttributes, attr); });
-    return iter != end(mAttributesVector) ? iter->mStream : AUDIO_STREAM_DEFAULT;
+    if (iter == end(mAttributesVector)) {
+        return AUDIO_STREAM_DEFAULT;
+    }
+    audio_stream_type_t streamType = iter->mStream;
+    ALOGW_IF(streamType == AUDIO_STREAM_DEFAULT,
+             "%s: Strategy %s supporting attributes %s has not stream type associated"
+             "fallback on MUSIC. Do not use stream volume API", __func__, mName.c_str(),
+             toString(attr).c_str());
+    return streamType != AUDIO_STREAM_DEFAULT ? streamType : AUDIO_STREAM_MUSIC;
 }
 
 audio_attributes_t ProductStrategy::getAttributesForStreamType(audio_stream_type_t streamType) const
diff --git a/services/audiopolicy/engine/config/include/EngineConfig.h b/services/audiopolicy/engine/config/include/EngineConfig.h
index 7f5ed5e..5d22c24 100644
--- a/services/audiopolicy/engine/config/include/EngineConfig.h
+++ b/services/audiopolicy/engine/config/include/EngineConfig.h
@@ -31,9 +31,6 @@
 /** Default path of audio policy usages configuration file. */
 constexpr char DEFAULT_PATH[] = "/vendor/etc/audio_policy_engine_configuration.xml";
 
-/** Directories where the effect libraries will be search for. */
-constexpr const char* POLICY_USAGE_LIBRARY_PATH[] = {"/odm/etc/", "/vendor/etc/", "/system/etc/"};
-
 using AttributesVector = std::vector<audio_attributes_t>;
 using StreamVector = std::vector<audio_stream_type_t>;
 
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index 7f8cdd9..4842cb2 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -21,6 +21,7 @@
 #include <cutils/properties.h>
 #include <media/TypeConverter.h>
 #include <media/convert.h>
+#include <system/audio_config.h>
 #include <utils/Log.h>
 #include <libxml/parser.h>
 #include <libxml/xinclude.h>
@@ -693,9 +694,6 @@
     return deserializeLegacyVolumeCollection(doc, cur, volumeGroups, nbSkippedElements);
 }
 
-static const char *kConfigLocationList[] = {"/odm/etc", "/vendor/etc", "/system/etc"};
-static const int kConfigLocationListSize =
-        (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
 static const int gApmXmlConfigFilePathMaxLength = 128;
 
 static constexpr const char *apmXmlConfigFileName = "audio_policy_configuration.xml";
@@ -715,9 +713,9 @@
     fileNames.push_back(apmXmlConfigFileName);
 
     for (const char* fileName : fileNames) {
-        for (int i = 0; i < kConfigLocationListSize; i++) {
+        for (const auto& path : audio_get_configuration_paths()) {
             snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
-                     "%s/%s", kConfigLocationList[i], fileName);
+                     "%s/%s", path.c_str(), fileName);
             ret = parseLegacyVolumeFile(audioPolicyXmlConfigFile, volumeGroups);
             if (ret == NO_ERROR) {
                 return ret;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index ffc3a0f..f1c2ab5 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -47,6 +47,7 @@
 #include <media/AudioParameter.h>
 #include <private/android_filesystem_config.h>
 #include <system/audio.h>
+#include <system/audio_config.h>
 #include "AudioPolicyManager.h"
 #include <Serializer.h>
 #include "TypeConverter.h"
@@ -133,12 +134,14 @@
     sp<DeviceDescriptor> device =
             mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat,
                                            state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
-    if (device == 0) {
-        return INVALID_OPERATION;
-    }
+    return device ? setDeviceConnectionStateInt(device, state) : INVALID_OPERATION;
+}
 
+status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescriptor> &device,
+                                                         audio_policy_dev_state_t state)
+{
     // handle output devices
-    if (audio_is_output_device(deviceType)) {
+    if (audio_is_output_device(device->type())) {
         SortedVector <audio_io_handle_t> outputs;
 
         ssize_t index = mAvailableOutputDevices.indexOf(device);
@@ -155,7 +158,7 @@
                 return INVALID_OPERATION;
             }
             ALOGV("%s() connecting device %s format %x",
-                    __func__, device->toString().c_str(), encodedFormat);
+                    __func__, device->toString().c_str(), device->getEncodedFormat());
 
             // register new device as available
             if (mAvailableOutputDevices.add(device) < 0) {
@@ -217,16 +220,13 @@
         // output device used by a dynamic policy of type recorder as no
         // playback use case is affected.
         bool doCheckForDeviceAndOutputChanges = true;
-        if (device->type() == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
-                && strncmp(device_address, "0", AUDIO_DEVICE_MAX_ADDRESS_LEN) != 0) {
+        if (device->type() == AUDIO_DEVICE_OUT_REMOTE_SUBMIX && device->address() != "0") {
             for (audio_io_handle_t output : outputs) {
                 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
                 sp<AudioPolicyMix> policyMix = desc->mPolicyMix.promote();
                 if (policyMix != nullptr
                         && policyMix->mMixType == MIX_TYPE_RECORDERS
-                        && strncmp(device_address,
-                                   policyMix->mDeviceAddress.string(),
-                                   AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
+                        && device->address() == policyMix->mDeviceAddress.string()) {
                     doCheckForDeviceAndOutputChanges = false;
                     break;
                 }
@@ -272,7 +272,7 @@
                 // a valid device selection on those outputs.
                 bool force = (msdOutDevices.isEmpty() || msdOutDevices != desc->devices())
                         && !desc->isDuplicated()
-                        && (!device_distinguishes_on_address(deviceType)
+                        && (!device_distinguishes_on_address(device->type())
                                 // always force when disconnecting (a non-duplicated device)
                                 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
                 setOutputDevices(desc, newDevices, force, 0);
@@ -288,7 +288,7 @@
     }  // end if is output device
 
     // handle input devices
-    if (audio_is_input_device(deviceType)) {
+    if (audio_is_input_device(device->type())) {
         ssize_t index = mAvailableInputDevices.indexOf(device);
         switch (state)
         {
@@ -2406,9 +2406,7 @@
     for (size_t i = 0; i < mInputs.size(); i++) {
         const sp<AudioInputDescriptor> input = mInputs.valueAt(i);
         if (input->clientsList().size() == 0
-                || !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())
-                || (input->getPolicyAudioPort()->getFlags()
-                        & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
+                || !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())) {
             inputsToClose.push_back(mInputs.keyAt(i));
         } else {
             bool close = false;
@@ -2457,6 +2455,10 @@
                                                   audio_devices_t device)
 {
     auto attributes = mEngine->getAttributesForStreamType(stream);
+    if (attributes == AUDIO_ATTRIBUTES_INITIALIZER) {
+        ALOGW("%s: no group for stream %s, bailing out", __func__, toString(stream).c_str());
+        return NO_ERROR;
+    }
     ALOGV("%s: stream %s attributes=%s", __func__,
           toString(stream).c_str(), toString(attributes).c_str());
     return setVolumeIndexForAttributes(attributes, index, device);
@@ -3755,6 +3757,22 @@
             removeAudioPatch(patchDesc->getHandle());
             nextAudioPortGeneration();
             mpClientInterface->onAudioPatchListUpdate();
+            // SW Bridge
+            if (patch->num_sources > 1 && patch->sources[1].type == AUDIO_PORT_TYPE_MIX) {
+                sp<SwAudioOutputDescriptor> outputDesc =
+                        mOutputs.getOutputFromId(patch->sources[1].id);
+                if (outputDesc == NULL) {
+                    ALOGE("%s output not found for id %d", __func__, patch->sources[0].id);
+                    return BAD_VALUE;
+                }
+                // Reset handle so that setOutputDevice will force new AF patch to reach the sink
+                outputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
+                setOutputDevices(outputDesc,
+                                 getNewOutputDevices(outputDesc, true /*fromCache*/),
+                                 true, /*force*/
+                                 0,
+                                 NULL);
+            }
         } else {
             return BAD_VALUE;
         }
@@ -4350,12 +4368,6 @@
     return mAudioPortGeneration++;
 }
 
-// Treblized audio policy xml config will be located in /odm/etc or /vendor/etc.
-static const char *kConfigLocationList[] =
-        {"/odm/etc", "/vendor/etc", "/system/etc"};
-static const int kConfigLocationListSize =
-        (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
-
 static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
     char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
     std::vector<const char*> fileNames;
@@ -4377,9 +4389,9 @@
     fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);
 
     for (const char* fileName : fileNames) {
-        for (int i = 0; i < kConfigLocationListSize; i++) {
+        for (const auto& path : audio_get_configuration_paths()) {
             snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
-                     "%s/%s", kConfigLocationList[i], fileName);
+                     "%s/%s", path.c_str(), fileName);
             ret = deserializeAudioPolicyFile(audioPolicyXmlConfigFile, &config);
             if (ret == NO_ERROR) {
                 config.setSource(audioPolicyXmlConfigFile);
@@ -4444,7 +4456,7 @@
 
     // after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices;
     // open all output streams needed to access attached devices
-    onNewAudioModulesAvailable();
+    onNewAudioModulesAvailableInt(nullptr /*newDevices*/);
 
     // make sure default device is reachable
     if (mDefaultOutputDevice == 0 || !mAvailableOutputDevices.contains(mDefaultOutputDevice)) {
@@ -4501,6 +4513,16 @@
 
 void AudioPolicyManager::onNewAudioModulesAvailable()
 {
+    DeviceVector newDevices;
+    onNewAudioModulesAvailableInt(&newDevices);
+    if (!newDevices.empty()) {
+        nextAudioPortGeneration();
+        mpClientInterface->onAudioPortListUpdate();
+    }
+}
+
+void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
+{
     for (const auto& hwModule : mHwModulesAll) {
         if (std::find(mHwModules.begin(), mHwModules.end(), hwModule) != mHwModules.end()) {
             continue;
@@ -4564,6 +4586,7 @@
                 if (!device->isAttached()) {
                     device->attach(hwModule);
                     mAvailableOutputDevices.add(device);
+                    if (newDevices) newDevices->add(device);
                     setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
                 }
             }
@@ -4619,6 +4642,7 @@
                     device->attach(hwModule);
                     device->importAudioPortAndPickAudioProfile(inProfile, true);
                     mAvailableInputDevices.add(device);
+                    if (newDevices) newDevices->add(device);
                     setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
                 }
             }
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 8121f86..c142880 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -788,6 +788,8 @@
 
         std::unordered_map<uid_t, audio_flags_mask_t> mAllowedCapturePolicies;
 private:
+        void onNewAudioModulesAvailableInt(DeviceVector *newDevices);
+
         // Add or remove AC3 DTS encodings based on user preferences.
         void modifySurroundFormats(const sp<DeviceDescriptor>& devDesc, FormatVector *formatsPtr);
         void modifySurroundChannelMasks(ChannelMaskSet *channelMasksPtr);
@@ -878,6 +880,8 @@
                                              const char *device_address,
                                              const char *device_name,
                                              audio_format_t encodedFormat);
+        status_t setDeviceConnectionStateInt(const sp<DeviceDescriptor> &device,
+                                             audio_policy_dev_state_t state);
 
         void setEngineDeviceConnectionState(const sp<DeviceDescriptor> device,
                                       audio_policy_dev_state_t state);
diff --git a/services/audiopolicy/service/Android.mk b/services/audiopolicy/service/Android.mk
index 80f4eab..94e4811 100644
--- a/services/audiopolicy/service/Android.mk
+++ b/services/audiopolicy/service/Android.mk
@@ -6,7 +6,8 @@
     AudioPolicyService.cpp \
     AudioPolicyEffects.cpp \
     AudioPolicyInterfaceImpl.cpp \
-    AudioPolicyClientImpl.cpp
+    AudioPolicyClientImpl.cpp \
+    CaptureStateNotifier.cpp
 
 LOCAL_C_INCLUDES := \
     frameworks/av/services/audioflinger \
@@ -32,7 +33,7 @@
     libmediautils \
     libeffectsconfig \
     libsensorprivacy \
-    soundtrigger_middleware-aidl-cpp
+    capture_state_listener-aidl-cpp
 
 LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
     libsensorprivacy
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 5b81b9d..9fa7a53 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -19,7 +19,6 @@
 
 #include "AudioPolicyService.h"
 
-#include <android/media/soundtrigger_middleware/ISoundTriggerMiddlewareService.h>
 #include <utils/Log.h>
 
 #include "BinderProxy.h"
@@ -242,12 +241,9 @@
     return AudioSystem::newAudioUniqueId(use);
 }
 
-void AudioPolicyService::AudioPolicyClient::setSoundTriggerCaptureState(bool active) {
-    using media::soundtrigger_middleware::ISoundTriggerMiddlewareService;
-
-    static BinderProxy<ISoundTriggerMiddlewareService>
-        proxy("soundtrigger_middleware");
-    proxy.waitServiceOrDie()->setExternalCaptureState(active);
+void AudioPolicyService::AudioPolicyClient::setSoundTriggerCaptureState(bool active)
+{
+    mAudioPolicyService->mCaptureStateNotifier.setCaptureState(active);
 }
 
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 0da3b9c..9577160 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -219,7 +219,6 @@
                                               audio_stream_type_t *stream,
                                               pid_t pid,
                                               uid_t uid,
-                                              const String16& opPackageName,
                                               const audio_config_t *config,
                                               audio_output_flags_t flags,
                                               audio_port_handle_t *selectedDeviceId,
@@ -266,8 +265,7 @@
         case AudioPolicyInterface::API_OUTPUT_LEGACY:
             break;
         case AudioPolicyInterface::API_OUTPUT_TELEPHONY_TX:
-          if (!modifyPhoneStateAllowed(pid, uid) &&
-              !accessCallAudioAllowed(opPackageName, pid, uid)) {
+            if (!modifyPhoneStateAllowed(pid, uid)) {
                 ALOGE("%s() permission denied: modify phone state not allowed for uid %d",
                     __func__, uid);
                 result = PERMISSION_DENIED;
@@ -464,22 +462,15 @@
     }
 
     bool canCaptureOutput = captureAudioOutputAllowed(pid, uid);
-    bool canCaptureTelephonyOutput = canCaptureOutput
-        || accessCallAudioAllowed(opPackageName, pid, uid);
-
-    if ((attr->source == AUDIO_SOURCE_ECHO_REFERENCE ||
-         attr->source == AUDIO_SOURCE_FM_TUNER) &&
+    if ((inputSource == AUDIO_SOURCE_VOICE_UPLINK ||
+        inputSource == AUDIO_SOURCE_VOICE_DOWNLINK ||
+        inputSource == AUDIO_SOURCE_VOICE_CALL ||
+        inputSource == AUDIO_SOURCE_ECHO_REFERENCE||
+        inputSource == AUDIO_SOURCE_FM_TUNER) &&
         !canCaptureOutput) {
         return PERMISSION_DENIED;
     }
 
-    if ((attr->source == AUDIO_SOURCE_VOICE_UPLINK ||
-        attr->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
-        attr->source == AUDIO_SOURCE_VOICE_CALL) &&
-        !canCaptureTelephonyOutput) {
-        return PERMISSION_DENIED;
-    }
-
     bool canCaptureHotword = captureHotwordAllowed(opPackageName, pid, uid);
     if ((inputSource == AUDIO_SOURCE_HOTWORD) && !canCaptureHotword) {
         return BAD_VALUE;
@@ -511,11 +502,6 @@
                 break;
             case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
                 // FIXME: use the same permission as for remote submix for now.
-                if (!canCaptureTelephonyOutput) {
-                    ALOGE("getInputForAttr() permission denied: call capture not allowed");
-                    status = PERMISSION_DENIED;
-                }
-                break;
             case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
                 if (!canCaptureOutput) {
                     ALOGE("getInputForAttr() permission denied: capture not allowed");
@@ -543,13 +529,9 @@
             return status;
         }
 
-        bool allowAudioCapture = canCaptureOutput ||
-            (inputType == AudioPolicyInterface::API_INPUT_TELEPHONY_RX &&
-             canCaptureTelephonyOutput);
-
         sp<AudioRecordClient> client = new AudioRecordClient(*attr, *input, uid, pid, session, *portId,
                                                              *selectedDeviceId, opPackageName,
-                                                             allowAudioCapture, canCaptureHotword);
+                                                             canCaptureOutput, canCaptureHotword);
         mAudioRecordClients.add(*portId, client);
     }
 
@@ -1438,6 +1420,13 @@
     return NO_ERROR;
 }
 
+status_t AudioPolicyService::setCurrentImeUid(uid_t uid)
+{
+    Mutex::Autolock _l(mLock);
+    mUidPolicy->setCurrentImeUid(uid);
+    return NO_ERROR;
+}
+
 bool AudioPolicyService::isHapticPlaybackSupported()
 {
     if (mAudioPolicyManager == NULL) {
@@ -1534,4 +1523,12 @@
     return mAudioPolicyManager->getPreferredDeviceForStrategy(strategy, device);
 }
 
+status_t AudioPolicyService::registerSoundTriggerCaptureStateListener(
+    const sp<media::ICaptureStateListener>& listener,
+    bool* result)
+{
+    *result = mCaptureStateNotifier.RegisterListener(listener);
+    return NO_ERROR;
+}
+
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index bf38477..d743be9 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -57,9 +57,13 @@
 // ----------------------------------------------------------------------------
 
 AudioPolicyService::AudioPolicyService()
-    : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
-      mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
-{
+    : BnAudioPolicyService(),
+      mpAudioPolicyDev(NULL),
+      mpAudioPolicy(NULL),
+      mAudioPolicyManager(NULL),
+      mAudioPolicyClient(NULL),
+      mPhoneState(AUDIO_MODE_INVALID),
+      mCaptureStateNotifier(false) {
 }
 
 void AudioPolicyService::onFirstRef()
@@ -437,6 +441,8 @@
 //            OR all active clients are using HOTWORD source
 //        AND no call is active
 //            OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+//    OR the client is the current InputMethodService
+//        AND a RTT call is active AND the source is VOICE_RECOGNITION
 //    OR Any client
 //        AND The assistant is not on TOP
 //        AND is on TOP or latest started
@@ -543,7 +549,7 @@
     //  else
     //    favor the privacy sensitive case
     if (topActive != nullptr && topSensitiveActive != nullptr
-            && !topActive->canCaptureCallOrOutput) {
+            && !topActive->canCaptureOutput) {
         topActive = nullptr;
     }
 
@@ -559,8 +565,8 @@
                                  false : current->uid == topSensitiveActive->uid;
 
         auto canCaptureIfInCallOrCommunication = [&](const auto &recordClient) {
-            bool canCaptureCall = recordClient->canCaptureCallOrOutput;
-            bool canCaptureCommunication = recordClient->canCaptureCallOrOutput
+            bool canCaptureCall = recordClient->canCaptureOutput;
+            bool canCaptureCommunication = recordClient->canCaptureOutput
                 || recordClient->uid == mPhoneStateOwnerUid
                 || isServiceUid(mPhoneStateOwnerUid);
             return !(isInCall && !canCaptureCall)
@@ -575,7 +581,7 @@
         bool allowCapture = !isAssistantOnTop
                 && (isTopOrLatestActive || isTopOrLatestSensitive)
                 && !(isSensitiveActive
-                    && !(isTopOrLatestSensitive || current->canCaptureCallOrOutput))
+                    && !(isTopOrLatestSensitive || current->canCaptureOutput))
                 && canCaptureIfInCallOrCommunication(current);
 
         if (isVirtualSource(source)) {
@@ -596,7 +602,7 @@
             } else {
                 if (((isAssistantOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
                         source == AUDIO_SOURCE_HOTWORD)
-                        && !(isSensitiveActive && !current->canCaptureCallOrOutput)
+                        && !(isSensitiveActive && !current->canCaptureOutput)
                         && canCaptureIfInCallOrCommunication(current)) {
                     allowCapture = true;
                 }
@@ -609,7 +615,7 @@
             //     OR
             //         Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD
             if (!isAssistantOnTop
-                    && !(isSensitiveActive && !current->canCaptureCallOrOutput)
+                    && !(isSensitiveActive && !current->canCaptureOutput)
                     && canCaptureIfInCallOrCommunication(current)) {
                 allowCapture = true;
             }
@@ -627,6 +633,12 @@
                     && canCaptureIfInCallOrCommunication(current)) {
                 allowCapture = true;
             }
+        } else if (mUidPolicy->isCurrentImeUid(current->uid)) {
+            // For current InputMethodService allow capture if:
+            //     A RTT call is active AND the source is VOICE_RECOGNITION
+            if (rttCallActive && source == AUDIO_SOURCE_VOICE_RECOGNITION) {
+                allowCapture = true;
+            }
         }
         setAppState_l(current->portId,
                       allowCapture ? apmStatFromAmState(mUidPolicy->getUidState(current->uid)) :
@@ -945,7 +957,7 @@
         }
     }
     ActivityManager am;
-    bool active = am.isUidActive(uid, String16("audioserver"));
+    bool active = am.isUidActiveOrForeground(uid, String16("audioserver"));
     {
         Mutex::Autolock _l(mLock);
         mCachedUids.insert(std::pair<uid_t,
@@ -990,7 +1002,7 @@
         }
     }
     ActivityManager am;
-    bool active = am.isUidActive(uid, String16("audioserver"));
+    bool active = am.isUidActiveOrForeground(uid, String16("audioserver"));
     int state = ActivityManager::PROCESS_STATE_UNKNOWN;
     if (active) {
         state = am.getUidProcessState(uid, String16("audioserver"));
@@ -1876,7 +1888,7 @@
 
 void AudioPolicyService::onNewAudioModulesAvailable()
 {
-    mAudioCommandThread->audioModulesUpdateCommand();
+    mOutputCommandThread->audioModulesUpdateCommand();
 }
 
 
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index ff99124..f77a481 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -34,6 +34,7 @@
 #include <media/AudioPolicy.h>
 #include <mediautils/ServiceUtilities.h>
 #include "AudioPolicyEffects.h"
+#include "CaptureStateNotifier.h"
 #include <AudioPolicyInterface.h>
 #include <android/hardware/BnSensorPrivacyListener.h>
 
@@ -83,7 +84,6 @@
                               audio_stream_type_t *stream,
                               pid_t pid,
                               uid_t uid,
-                              const String16& opPackageName,
                               const audio_config_t *config,
                               audio_output_flags_t flags,
                               audio_port_handle_t *selectedDeviceId,
@@ -262,6 +262,7 @@
 
     virtual status_t setAssistantUid(uid_t uid);
     virtual status_t setA11yServicesUids(const std::vector<uid_t>& uids);
+    virtual status_t setCurrentImeUid(uid_t uid);
 
     virtual bool     isHapticPlaybackSupported();
 
@@ -274,6 +275,10 @@
     virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
                                                        volume_group_t &volumeGroup);
 
+    status_t registerSoundTriggerCaptureStateListener(
+        const sp<media::ICaptureStateListener>& listener,
+        bool* result) override;
+
     virtual status_t setRttEnabled(bool enabled);
 
             bool isCallScreenModeSupported() override;
@@ -372,7 +377,7 @@
     public:
         explicit UidPolicy(wp<AudioPolicyService> service)
                 : mService(service), mObserverRegistered(false),
-                  mAssistantUid(0), mRttEnabled(false) {}
+                  mAssistantUid(0), mCurrentImeUid(0), mRttEnabled(false) {}
 
         void registerSelf();
         void unregisterSelf();
@@ -387,6 +392,8 @@
         void setA11yUids(const std::vector<uid_t>& uids) { mA11yUids.clear(); mA11yUids = uids; }
         bool isA11yUid(uid_t uid);
         bool isA11yOnTop();
+        void setCurrentImeUid(uid_t uid) { mCurrentImeUid = uid; }
+        bool isCurrentImeUid(uid_t uid) { return uid == mCurrentImeUid; }
         void setRttEnabled(bool enabled) { mRttEnabled = enabled; }
         bool isRttEnabled() { return mRttEnabled; }
 
@@ -418,6 +425,7 @@
         std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
         uid_t mAssistantUid;
         std::vector<uid_t> mA11yUids;
+        uid_t mCurrentImeUid;
         bool mRttEnabled;
     };
 
@@ -812,16 +820,15 @@
                           const audio_io_handle_t io, uid_t uid, pid_t pid,
                           const audio_session_t session, audio_port_handle_t portId,
                           const audio_port_handle_t deviceId, const String16& opPackageName,
-                          bool canCaptureCallOrOutput, bool canCaptureHotword) :
+                          bool canCaptureOutput, bool canCaptureHotword) :
                     AudioClient(attributes, io, uid, pid, session, portId, deviceId),
                     opPackageName(opPackageName), startTimeNs(0),
-                    canCaptureCallOrOutput(canCaptureCallOrOutput),
-                    canCaptureHotword(canCaptureHotword) {}
+                    canCaptureOutput(canCaptureOutput), canCaptureHotword(canCaptureHotword) {}
                 ~AudioRecordClient() override = default;
 
         const String16 opPackageName;        // client package name
         nsecs_t startTimeNs;
-        const bool canCaptureCallOrOutput;
+        const bool canCaptureOutput;
         const bool canCaptureHotword;
     };
 
@@ -895,6 +902,8 @@
     DefaultKeyedVector< audio_port_handle_t, sp<AudioPlaybackClient> >   mAudioPlaybackClients;
 
     MediaPackageManager mPackageManager; // To check allowPlaybackCapture
+
+    CaptureStateNotifier mCaptureStateNotifier;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/service/CaptureStateNotifier.cpp b/services/audiopolicy/service/CaptureStateNotifier.cpp
new file mode 100644
index 0000000..135e0a2
--- /dev/null
+++ b/services/audiopolicy/service/CaptureStateNotifier.cpp
@@ -0,0 +1,67 @@
+#define LOG_TAG "CaptureStateNotifier"
+
+#include "CaptureStateNotifier.h"
+
+#include <android/media/ICaptureStateListener.h>
+#include <binder/IBinder.h>
+#include <utils/Log.h>
+
+namespace android {
+
+using media::ICaptureStateListener;
+
+class CaptureStateNotifier::DeathRecipient : public IBinder::DeathRecipient {
+public:
+    DeathRecipient(CaptureStateNotifier* notifier) : mNotifier(notifier) {}
+
+    void binderDied(const wp<IBinder>&) override {
+        mNotifier->binderDied();
+    }
+
+private:
+    CaptureStateNotifier* const mNotifier;
+};
+
+CaptureStateNotifier::CaptureStateNotifier(bool initialActive)
+    : mDeathRecipient(new DeathRecipient(this)), mActive(
+    initialActive) {}
+
+CaptureStateNotifier::~CaptureStateNotifier() {
+    LOG_ALWAYS_FATAL_IF(mListener != nullptr);
+}
+
+bool CaptureStateNotifier::RegisterListener(const sp<ICaptureStateListener>& listener) {
+    std::lock_guard<std::mutex> _l(mMutex);
+    LOG_ALWAYS_FATAL_IF(mListener != nullptr);
+    LOG_ALWAYS_FATAL_IF(listener == nullptr);
+
+    ALOGI("Registering a listener");
+    sp<IBinder> binder = IInterface::asBinder(listener);
+    if (binder != nullptr) {
+        status_t status = binder->linkToDeath(mDeathRecipient);
+        if (status == NO_ERROR) {
+            mListener = listener;
+        } else {
+            ALOGE("Failed to register death listener: %u", status);
+        }
+    } else {
+        ALOGE("Listener failed to cast to a binder.");
+    }
+    return mActive;
+}
+
+void CaptureStateNotifier::setCaptureState(bool active) {
+    std::lock_guard<std::mutex> _l(mMutex);
+    mActive = active;
+    if (mListener) {
+        mListener->setCaptureState(active);
+    }
+}
+
+void CaptureStateNotifier::binderDied() {
+    std::lock_guard<std::mutex> _l(mMutex);
+    mListener.clear();
+    ALOGI("Listener binder died");
+}
+
+}  // namespace android
\ No newline at end of file
diff --git a/services/audiopolicy/service/CaptureStateNotifier.h b/services/audiopolicy/service/CaptureStateNotifier.h
new file mode 100644
index 0000000..166de2a
--- /dev/null
+++ b/services/audiopolicy/service/CaptureStateNotifier.h
@@ -0,0 +1,75 @@
+/*
+ * 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 <mutex>
+#include <binder/IBinder.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+namespace media {
+// Must be pre-declared, or else there isn't a good way to generate a header
+// library.
+class ICaptureStateListener;
+}
+
+// A utility for managing capture state change notifications.
+//
+// We are making some strong assumptions, for the sake of simplicity:
+// - There is no way to explicitly unregister listeners. The only way for a
+//   listener to unregister is by dying.
+// - There's only at most one listener at a given time. Attempting to register
+//   a second listener will cause a crash.
+// - This class isn't really meant to ever be destroyed. We expose a destructor
+//   because it is convenient to use this class as a global instance or a member
+//   of another class, but it will crash if destroyed while a listener is
+//   registered.
+//
+// All of these assumptions can be lifted if there is ever a need.
+//
+// This class is thread-safe.
+class CaptureStateNotifier {
+public:
+    // Ctor.
+    // Accepts the initial active state.
+    explicit CaptureStateNotifier(bool initialActive);
+
+    // Register a listener to be notified of state changes.
+    // The current state is returned and from that point on any change will be
+    // notified of.
+    bool RegisterListener(const sp<media::ICaptureStateListener>& listener);
+
+    // Change the current capture state.
+    // Active means "actively capturing".
+    void setCaptureState(bool active);
+
+    // Dtor. Do not actually call at runtime. Will cause a crash if a listener
+    // is registered.
+    ~CaptureStateNotifier();
+
+private:
+    std::mutex mMutex;
+    sp<media::ICaptureStateListener> mListener;
+    sp<IBinder::DeathRecipient> mDeathRecipient;
+    bool mActive;
+
+    class DeathRecipient;
+
+    void binderDied();
+};
+
+}  // namespace android
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index af69466..e1721ea 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -94,6 +94,10 @@
         return NO_ERROR;
     }
 
+    void onAudioPortListUpdate() override {
+        ++mAudioPortListUpdateCount;
+    }
+
     // Helper methods for tests
     size_t getActivePatchesCount() const { return mActivePatches.size(); }
 
@@ -111,12 +115,15 @@
         mAllowedModuleNames.swap(names);
     }
 
+    size_t getAudioPortListUpdateCount() const { return mAudioPortListUpdateCount; }
+
 private:
     audio_module_handle_t mNextModuleHandle = AUDIO_MODULE_HANDLE_NONE + 1;
     audio_io_handle_t mNextIoHandle = AUDIO_IO_HANDLE_NONE + 1;
     audio_patch_handle_t mNextPatchHandle = AUDIO_PATCH_HANDLE_NONE + 1;
     std::map<audio_patch_handle_t, struct audio_patch> mActivePatches;
     std::set<std::string> mAllowedModuleNames;
+    size_t mAudioPortListUpdateCount = 0;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/tests/AudioPolicyTestManager.h b/services/audiopolicy/tests/AudioPolicyTestManager.h
index 922a538..8bab020 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;
+    uint32_t getAudioPortGeneration() const { return mAudioPortGeneration; }
 };
 
 }  // namespace android
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 7d92f34..a0074bc 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -104,8 +104,10 @@
             audio_port_handle_t *portId = nullptr);
     PatchCountCheck snapshotPatchCount() { return PatchCountCheck(mClient.get()); }
 
-    void findDevicePort(audio_port_role_t role, audio_devices_t deviceType,
-            const std::string &address, audio_port &foundPort);
+    // 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);
     static audio_port_handle_t getDeviceIdFromPatch(const struct audio_patch* patch);
 
     std::unique_ptr<AudioPolicyManagerTestClient> mClient;
@@ -211,30 +213,36 @@
     ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
 }
 
-void AudioPolicyManagerTest::findDevicePort(audio_port_role_t role,
-        audio_devices_t deviceType, const std::string &address, audio_port &foundPort) {
+bool AudioPolicyManagerTest::findDevicePort(audio_port_role_t role,
+        audio_devices_t deviceType, const std::string &address, audio_port *foundPort) {
     uint32_t numPorts = 0;
     uint32_t generation1;
     status_t ret;
 
     ret = mManager->listAudioPorts(role, AUDIO_PORT_TYPE_DEVICE, &numPorts, nullptr, &generation1);
-    ASSERT_EQ(NO_ERROR, ret);
+    EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
+    if (HasFailure()) return false;
 
     uint32_t generation2;
     struct audio_port ports[numPorts];
     ret = mManager->listAudioPorts(role, AUDIO_PORT_TYPE_DEVICE, &numPorts, ports, &generation2);
-    ASSERT_EQ(NO_ERROR, ret);
-    ASSERT_EQ(generation1, generation2);
+    EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
+    EXPECT_EQ(generation1, generation2) << "Generations changed during ports retrieval";
+    if (HasFailure()) return false;
 
     for (const auto &port : ports) {
         if (port.role == role && port.ext.device.type == deviceType &&
                 (strncmp(port.ext.device.address, address.c_str(),
                          AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
-            foundPort = port;
-            return;
+            if (foundPort) *foundPort = port;
+            return true;
         }
     }
-    GTEST_FAIL() << "Device port with role " << role << " and address " << address << "not found";
+    if (foundPort) {
+        ADD_FAILURE() << "Device port with role " << role << " and address "
+                      << address << " not found";
+    }
+    return false;
 }
 
 audio_port_handle_t AudioPolicyManagerTest::getDeviceIdFromPatch(
@@ -694,8 +702,8 @@
     ASSERT_EQ(NO_ERROR, ret);
 
     struct audio_port extractionPort;
-    findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
-            mMixAddress, extractionPort);
+    ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
+                    mMixAddress, &extractionPort));
 
     audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
     audio_source_t source = AUDIO_SOURCE_REMOTE_SUBMIX;
@@ -707,8 +715,8 @@
     ASSERT_EQ(NO_ERROR, mManager->startInput(mPortId));
     ASSERT_EQ(extractionPort.id, selectedDeviceId);
 
-    findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-            mMixAddress, mInjectionPort);
+    ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+                    mMixAddress, &mInjectionPort));
 }
 
 void AudioPolicyManagerTestDPPlaybackReRouting::TearDown() {
@@ -879,8 +887,8 @@
     ASSERT_EQ(NO_ERROR, ret);
 
     struct audio_port injectionPort;
-    findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-            mMixAddress, injectionPort);
+    ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+                    mMixAddress, &injectionPort));
 
     audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
     audio_usage_t usage = AUDIO_USAGE_VIRTUAL_SOURCE;
@@ -892,8 +900,8 @@
     ASSERT_EQ(NO_ERROR, mManager->startOutput(mPortId));
     ASSERT_EQ(injectionPort.id, getDeviceIdFromPatch(mClient->getLastAddedPatch()));
 
-    findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
-            mMixAddress, mExtractionPort);
+    ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
+                    mMixAddress, &mExtractionPort));
 }
 
 void AudioPolicyManagerTestDPMixRecordInjection::TearDown() {
@@ -1028,7 +1036,7 @@
     audio_port devicePort;
     const audio_port_role_t role = audio_is_output_device(type)
             ? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
-    findDevicePort(role, type, address, devicePort);
+    ASSERT_TRUE(findDevicePort(role, type, address, &devicePort));
 
     audio_port_handle_t routedPortId = devicePort.id;
     // Try start input or output according to the device type
@@ -1162,3 +1170,21 @@
     ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_AVAILABLE, mManager->getDeviceConnectionState(
                     AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0"));
 }
+
+TEST_F(AudioPolicyManagerDynamicHwModulesTest, ListAddedAudioPorts) {
+    ASSERT_FALSE(
+            findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", nullptr));
+    mClient->swapAllowedModuleNames({"primary", "r_submix"});
+    mManager->onNewAudioModulesAvailable();
+    struct audio_port port;
+    ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", &port));
+}
+
+TEST_F(AudioPolicyManagerDynamicHwModulesTest, ClientIsUpdated) {
+    const size_t prevAudioPortListUpdateCount = mClient->getAudioPortListUpdateCount();
+    const uint32_t prevAudioPortGeneration = mManager->getAudioPortGeneration();
+    mClient->swapAllowedModuleNames({"primary", "r_submix"});
+    mManager->onNewAudioModulesAvailable();
+    EXPECT_GT(mClient->getAudioPortListUpdateCount(), prevAudioPortListUpdateCount);
+    EXPECT_GT(mManager->getAudioPortGeneration(), prevAudioPortGeneration);
+}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 9bc79e0..f92d673 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2742,7 +2742,7 @@
         mClientPackageName(clientPackageName),
         mClientPid(clientPid), mClientUid(clientUid),
         mServicePid(servicePid),
-        mDisconnected(false),
+        mDisconnected(false), mUidIsTrusted(false),
         mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE),
         mRemoteBinder(remoteCallback)
 {
@@ -2791,6 +2791,8 @@
     if (getCurrentServingCall() != BinderCallType::HWBINDER) {
         mAppOpsManager = std::make_unique<AppOpsManager>();
     }
+
+    mUidIsTrusted = isTrustedCallingUid(mClientUid);
 }
 
 CameraService::BasicClient::~BasicClient() {
@@ -2905,7 +2907,9 @@
             return PERMISSION_DENIED;
         }
 
-        if (res == AppOpsManager::MODE_IGNORED) {
+        // If the calling Uid is trusted (a native service), the AppOpsManager could
+        // return MODE_IGNORED. Do not treat such case as error.
+        if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) {
             ALOGI("Camera %s: Access for \"%s\" has been restricted",
                     mCameraIdStr.string(), String8(mClientPackageName).string());
             // Return the same error as for device policy manager rejection
@@ -3188,7 +3192,9 @@
             // some polling which should happen pretty rarely anyway as the race is hard
             // to hit.
             active = mActiveUids.find(uid) != mActiveUids.end();
-            if (!active) active = am.isUidActive(uid, callingPackage);
+            if (!active) {
+                active = am.isUidActiveOrForeground(uid, callingPackage);
+            }
             if (active) {
                 break;
             }
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 1adf15a..18cf77a 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -323,6 +323,7 @@
         const uid_t                     mClientUid;
         const pid_t                     mServicePid;
         bool                            mDisconnected;
+        bool                            mUidIsTrusted;
 
         mutable Mutex                   mAudioRestrictionLock;
         int32_t                         mAudioRestriction;
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 1d62a74..ebb0555 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -733,6 +733,10 @@
 
     ALOGV("%s: state == %d, restart = %d", __FUNCTION__, params.state, restart);
 
+    if (params.state == Parameters::DISCONNECTED) {
+        ALOGE("%s: Camera %d has been disconnected.", __FUNCTION__, mCameraId);
+        return INVALID_OPERATION;
+    }
     if ( (params.state == Parameters::PREVIEW ||
                     params.state == Parameters::RECORD ||
                     params.state == Parameters::VIDEO_SNAPSHOT)
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 8f20685..237c24b 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -197,7 +197,9 @@
             return PERMISSION_DENIED;
         }
 
-        if (res == AppOpsManager::MODE_IGNORED) {
+        // If the calling Uid is trusted (a native service), the AppOpsManager could
+        // return MODE_IGNORED. Do not treat such case as error.
+        if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) {
             ALOGI("Offline Camera %s: Access for \"%s\" has been restricted",
                     mCameraIdStr.string(), String8(mClientPackageName).string());
             // Return the same error as for device policy manager rejection
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index cc369fa..10b653e 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -841,13 +841,6 @@
         itDuration++; itSize++;
     }
 
-    c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
-            dynamicDepthEntries.data(), dynamicDepthEntries.size());
-    c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS,
-            dynamicDepthMinDurationEntries.data(), dynamicDepthMinDurationEntries.size());
-    c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS,
-            dynamicDepthStallDurationEntries.data(), dynamicDepthStallDurationEntries.size());
-
     std::vector<int32_t> supportedChTags;
     supportedChTags.reserve(chTags.count + 3);
     supportedChTags.insert(supportedChTags.end(), chTags.data.i32,
@@ -855,6 +848,12 @@
     supportedChTags.push_back(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
     supportedChTags.push_back(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS);
     supportedChTags.push_back(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS);
+    c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
+            dynamicDepthEntries.data(), dynamicDepthEntries.size());
+    c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS,
+            dynamicDepthMinDurationEntries.data(), dynamicDepthMinDurationEntries.size());
+    c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS,
+            dynamicDepthStallDurationEntries.data(), dynamicDepthStallDurationEntries.size());
     c.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, supportedChTags.data(),
             supportedChTags.size());
 
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 87bdef6..2d46122 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1722,6 +1722,13 @@
             return res;
         }
 
+        // Fill in JPEG_QUALITY if not available
+        if (!mRequestTemplateCache[templateId].exists(ANDROID_JPEG_QUALITY)) {
+            static const uint8_t kDefaultJpegQuality = 95;
+            mRequestTemplateCache[templateId].update(ANDROID_JPEG_QUALITY,
+                    &kDefaultJpegQuality, 1);
+        }
+
         *request = mRequestTemplateCache[templateId];
         mLastTemplateId = templateId;
     }
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index 238356e..4c8366f 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -246,6 +246,8 @@
                 frameNumber);
         return;
     }
+    nsecs_t sensorTimestamp = timestamp.data.i64[0];
+
     for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
         camera_metadata_entry timestamp =
                 physicalMetadata.mPhysicalCameraMetadata.find(ANDROID_SENSOR_TIMESTAMP);
@@ -337,7 +339,7 @@
                 CameraMetadata(m.mPhysicalCameraMetadata));
     }
     states.tagMonitor.monitorMetadata(TagMonitor::RESULT,
-            frameNumber, timestamp.data.i64[0], captureResult.mMetadata,
+            frameNumber, sensorTimestamp, captureResult.mMetadata,
             monitoredPhysicalMetadata);
 
     insertResultLocked(states, &captureResult, frameNumber);
diff --git a/services/camera/libcameraservice/tests/Android.mk b/services/camera/libcameraservice/tests/Android.mk
index fa5d69e..3ead715 100644
--- a/services/camera/libcameraservice/tests/Android.mk
+++ b/services/camera/libcameraservice/tests/Android.mk
@@ -48,6 +48,8 @@
 
 LOCAL_CFLAGS += -Wall -Wextra -Werror
 
+LOCAL_SANITIZE := address
+
 LOCAL_MODULE:= cameraservice_test
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_MODULE_TAGS := tests
diff --git a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
index a8f6889..855b5ab 100644
--- a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
@@ -40,8 +40,15 @@
  */
 struct TestDeviceInterface : public device::V3_2::ICameraDevice {
     std::vector<hardware::hidl_string> mDeviceNames;
+    android::hardware::hidl_vec<uint8_t> mCharacteristics;
+
+    TestDeviceInterface(std::vector<hardware::hidl_string> deviceNames,
+            android::hardware::hidl_vec<uint8_t> chars) :
+        mDeviceNames(deviceNames), mCharacteristics(chars) {}
+
     TestDeviceInterface(std::vector<hardware::hidl_string> deviceNames) :
         mDeviceNames(deviceNames) {}
+
     using getResourceCost_cb = std::function<void(
             hardware::camera::common::V1_0::Status status,
             const hardware::camera::common::V1_0::CameraResourceCost& resourceCost)>;
@@ -58,8 +65,7 @@
             const hardware::hidl_vec<uint8_t>& cameraCharacteristics)>;
     hardware::Return<void> getCameraCharacteristics(
             getCameraCharacteristics_cb _hidl_cb) override {
-        hardware::hidl_vec<uint8_t> cameraCharacteristics;
-        _hidl_cb(Status::OK, cameraCharacteristics);
+        _hidl_cb(Status::OK, mCharacteristics);
         return hardware::Void();
     }
 
@@ -100,6 +106,13 @@
         mDeviceInterface(new TestDeviceInterface(devices)),
         mVendorTagSections (vendorSection) {}
 
+    TestICameraProvider(const std::vector<hardware::hidl_string> &devices,
+            const hardware::hidl_vec<common::V1_0::VendorTagSection> &vendorSection,
+            android::hardware::hidl_vec<uint8_t> chars) :
+        mDeviceNames(devices),
+        mDeviceInterface(new TestDeviceInterface(devices, chars)),
+        mVendorTagSections (vendorSection) {}
+
     virtual hardware::Return<Status> setCallback(
             const sp<provider::V2_4::ICameraProviderCallback>& callbacks) override {
         mCalledCounter[SET_CALLBACK]++;
@@ -243,6 +256,52 @@
     void onNewProviderRegistered() override {}
 };
 
+TEST(CameraProviderManagerTest, InitializeDynamicDepthTest) {
+    std::vector<hardware::hidl_string> deviceNames;
+    deviceNames.push_back("device@3.2/test/0");
+    hardware::hidl_vec<common::V1_0::VendorTagSection> vendorSection;
+    status_t res;
+    sp<CameraProviderManager> providerManager = new CameraProviderManager();
+    sp<TestStatusListener> statusListener = new TestStatusListener();
+    TestInteractionProxy serviceProxy;
+
+    android::hardware::hidl_vec<uint8_t> chars;
+    CameraMetadata meta;
+    int32_t charKeys[] = { ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE,
+            ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS };
+    meta.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, charKeys,
+            sizeof(charKeys) / sizeof(charKeys[0]));
+    uint8_t depthIsExclusive = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE;
+    meta.update(ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE, &depthIsExclusive, 1);
+    int32_t sizes[] = { HAL_PIXEL_FORMAT_BLOB,
+            640, 480, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT };
+    meta.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, sizes,
+            sizeof(sizes) / sizeof(sizes[0]));
+    sizes[0] = HAL_PIXEL_FORMAT_Y16;
+    meta.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, sizes,
+            sizeof(sizes) / sizeof(sizes[0]));
+    int64_t durations[] = { HAL_PIXEL_FORMAT_BLOB, 640, 480, 0 };
+    meta.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, durations,
+            sizeof(durations) / sizeof(durations[0]));
+    meta.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, durations,
+            sizeof(durations) / sizeof(durations[0]));
+    durations[0]= HAL_PIXEL_FORMAT_Y16;
+    meta.update(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS, durations,
+            sizeof(durations) / sizeof(durations[0]));
+    meta.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS, durations,
+            sizeof(durations) / sizeof(durations[0]));
+    camera_metadata_t* metaBuffer = const_cast<camera_metadata_t*>(meta.getAndLock());
+    chars.setToExternal(reinterpret_cast<uint8_t*>(metaBuffer),
+            get_camera_metadata_size(metaBuffer));
+
+    sp<TestICameraProvider> provider =  new TestICameraProvider(deviceNames,
+            vendorSection, chars);
+    serviceProxy.setProvider(provider);
+
+    res = providerManager->initialize(statusListener, &serviceProxy);
+    ASSERT_EQ(res, OK) << "Unable to initialize provider manager";
+}
+
 TEST(CameraProviderManagerTest, InitializeTest) {
     std::vector<hardware::hidl_string> deviceNames;
     deviceNames.push_back("device@3.2/test/0");
diff --git a/services/camera/libcameraservice/tests/RotateAndCropMapperTest.cpp b/services/camera/libcameraservice/tests/RotateAndCropMapperTest.cpp
index c638d40..3c187cd 100644
--- a/services/camera/libcameraservice/tests/RotateAndCropMapperTest.cpp
+++ b/services/camera/libcameraservice/tests/RotateAndCropMapperTest.cpp
@@ -38,10 +38,9 @@
 
 #define EXPECT_EQUAL_WITHIN_N(vec, array, N, msg)   \
 { \
-    std::vector<int32_t> vec_diff; \
-    std::transform(vec.begin(), vec.end(), array, \
-            std::back_inserter(vec_diff), std::minus()); \
-    EXPECT_THAT(vec_diff, Each(AllOf(Ge(-N), Le(N)))) << msg; \
+    for (size_t i = 0; i < vec.size(); i++) { \
+        EXPECT_THAT(vec[i] - array[i], AllOf(Ge(-N), Le(N))) << msg " failed at index:" << i; \
+    } \
 }
 
 int32_t testActiveArray[] = {100, 100, 4000, 3000};
diff --git a/services/mediacodec/registrant/CodecServiceRegistrant.cpp b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
index 83d233e..184251a 100644
--- a/services/mediacodec/registrant/CodecServiceRegistrant.cpp
+++ b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
@@ -17,11 +17,13 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "CodecServiceRegistrant"
 
+#include <android-base/properties.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
 
 #include <C2Component.h>
 #include <C2PlatformSupport.h>
+#include <codec2/hidl/1.0/ComponentStore.h>
 #include <codec2/hidl/1.1/ComponentStore.h>
 #include <codec2/hidl/1.1/Configurable.h>
 #include <codec2/hidl/1.1/types.h>
@@ -43,6 +45,10 @@
 // Converter from IComponentStore to C2ComponentStore.
 class H2C2ComponentStore : public C2ComponentStore {
 protected:
+    using IComponentStore =
+        ::android::hardware::media::c2::V1_0::IComponentStore;
+    using IConfigurable =
+        ::android::hardware::media::c2::V1_0::IConfigurable;
     sp<IComponentStore> mStore;
     sp<IConfigurable> mConfigurable;
 public:
@@ -399,36 +405,67 @@
 } // unnamed namespace
 
 extern "C" void RegisterCodecServices() {
-    using namespace ::android::hardware::media::c2::V1_1;
     LOG(INFO) << "Creating software Codec2 service...";
-    sp<ComponentStore> store =
-        new ComponentStore(::android::GetCodec2PlatformComponentStore());
-    if (store == nullptr) {
-        LOG(ERROR) <<
-                "Cannot create software Codec2 service.";
-    } else {
-        if (!ionPropertiesDefined()) {
-            std::string preferredStoreName = "default";
-            sp<IComponentStore> preferredStore =
-                IComponentStore::getService(preferredStoreName.c_str());
-            if (preferredStore) {
-                ::android::SetPreferredCodec2ComponentStore(
-                        std::make_shared<H2C2ComponentStore>(preferredStore));
-                LOG(INFO) <<
-                        "Preferred Codec2 store is set to \"" <<
-                        preferredStoreName << "\".";
-            } else {
-                LOG(INFO) <<
-                        "Preferred Codec2 store is defaulted to \"software\".";
+    std::shared_ptr<C2ComponentStore> store =
+        android::GetCodec2PlatformComponentStore();
+    if (!store) {
+        LOG(ERROR) << "Failed to create Codec2 service.";
+        return;
+    }
+
+    using namespace ::android::hardware::media::c2;
+
+    int platformVersion =
+        android::base::GetIntProperty("ro.build.version.sdk", int32_t(29));
+    // STOPSHIP: Remove code name checking once platform version bumps up to 30.
+    std::string codeName =
+        android::base::GetProperty("ro.build.version.codename", "");
+    if (codeName == "R") {
+        platformVersion = 30;
+    }
+
+    switch (platformVersion) {
+        case 30: {
+            android::sp<V1_1::IComponentStore> storeV1_1 =
+                new V1_1::utils::ComponentStore(store);
+            if (storeV1_1->registerAsService("software") != android::OK) {
+                LOG(ERROR) << "Cannot register software Codec2 v1.1 service.";
+                return;
             }
+            break;
         }
-        if (store->registerAsService("software") != android::OK) {
-            LOG(ERROR) <<
-                    "Cannot register software Codec2 service.";
-        } else {
-            LOG(INFO) <<
-                    "Software Codec2 service created.";
+        case 29: {
+            android::sp<V1_0::IComponentStore> storeV1_0 =
+                new V1_0::utils::ComponentStore(store);
+            if (storeV1_0->registerAsService("software") != android::OK) {
+                LOG(ERROR) << "Cannot register software Codec2 v1.0 service.";
+                return;
+            }
+            break;
+        }
+        default: {
+            LOG(ERROR) << "The platform version " << platformVersion <<
+                          " is not supported.";
+            return;
         }
     }
+    if (!ionPropertiesDefined()) {
+        using IComponentStore =
+            ::android::hardware::media::c2::V1_0::IComponentStore;
+        std::string const preferredStoreName = "default";
+        sp<IComponentStore> preferredStore =
+            IComponentStore::getService(preferredStoreName.c_str());
+        if (preferredStore) {
+            ::android::SetPreferredCodec2ComponentStore(
+                    std::make_shared<H2C2ComponentStore>(preferredStore));
+            LOG(INFO) <<
+                    "Preferred Codec2 store is set to \"" <<
+                    preferredStoreName << "\".";
+        } else {
+            LOG(INFO) <<
+                    "Preferred Codec2 store is defaulted to \"software\".";
+        }
+    }
+    LOG(INFO) << "Software Codec2 service created and registered.";
 }
 
diff --git a/services/mediaextractor/Android.bp b/services/mediaextractor/Android.bp
index 548b7f6..0b25d62 100644
--- a/services/mediaextractor/Android.bp
+++ b/services/mediaextractor/Android.bp
@@ -29,6 +29,7 @@
     shared_libs: [
         "libmedia",
         "libmediaextractorservice",
+        "libmediautils",
         "libbinder",
         "libutils",
         "liblog",
@@ -50,8 +51,6 @@
     },
     init_rc: ["mediaextractor.rc"],
 
-    include_dirs: ["frameworks/av/media/libmedia"],
-
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index afb7692..f21574f 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -21,7 +21,7 @@
 #include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
-
+#include <mediautils/LimitProcessMemory.h>
 #include <string>
 
 #include <android-base/logging.h>
@@ -32,7 +32,6 @@
 
 // from LOCAL_C_INCLUDES
 #include "MediaExtractorService.h"
-#include "MediaUtils.h"
 #include "minijail.h"
 
 using namespace android;
diff --git a/services/mediametrics/AnalyticsState.h b/services/mediametrics/AnalyticsState.h
index 290ed21..b648947 100644
--- a/services/mediametrics/AnalyticsState.h
+++ b/services/mediametrics/AnalyticsState.h
@@ -84,8 +84,11 @@
      * delivered.
      *
      * \param lines the maximum number of lines in the string returned.
+     * \param sinceNs the nanoseconds since Unix epoch to start dump (0 shows all)
+     * \param prefix the desired key prefix to match (nullptr shows all)
      */
-    std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const {
+    std::pair<std::string, int32_t> dump(
+            int32_t lines = INT32_MAX, int64_t sinceNs = 0, const char *prefix = nullptr) const {
         std::stringstream ss;
         int32_t ll = lines;
 
@@ -94,7 +97,7 @@
             --ll;
         }
         if (ll > 0) {
-            auto [s, l] = mTransactionLog.dump(ll);
+            auto [s, l] = mTransactionLog.dump(ll, sinceNs, prefix);
             ss << s;
             ll -= l;
         }
@@ -103,7 +106,7 @@
             --ll;
         }
         if (ll > 0) {
-            auto [s, l] = mTimeMachine.dump(ll);
+            auto [s, l] = mTimeMachine.dump(ll, sinceNs, prefix);
             ss << s;
             ll -= l;
         }
diff --git a/services/mediametrics/Android.bp b/services/mediametrics/Android.bp
index ec59ec1..58f3ea8 100644
--- a/services/mediametrics/Android.bp
+++ b/services/mediametrics/Android.bp
@@ -57,6 +57,7 @@
         "liblog",
         "libmediametrics",
         "libmediautils",
+        "libmemunreachable",
         "libprotobuf-cpp-lite",
         "libstatslog",
         "libutils",
diff --git a/services/mediametrics/AudioAnalytics.cpp b/services/mediametrics/AudioAnalytics.cpp
index 126e501..3f9a42f 100644
--- a/services/mediametrics/AudioAnalytics.cpp
+++ b/services/mediametrics/AudioAnalytics.cpp
@@ -107,13 +107,14 @@
     return NO_ERROR;
 }
 
-std::pair<std::string, int32_t> AudioAnalytics::dump(int32_t lines) const
+std::pair<std::string, int32_t> AudioAnalytics::dump(
+        int32_t lines, int64_t sinceNs, const char *prefix) const
 {
     std::stringstream ss;
     int32_t ll = lines;
 
     if (ll > 0) {
-        auto [s, l] = mAnalyticsState->dump(ll);
+        auto [s, l] = mAnalyticsState->dump(ll, sinceNs, prefix);
         ss << s;
         ll -= l;
     }
@@ -122,7 +123,7 @@
         --ll;
     }
     if (ll > 0) {
-        auto [s, l] = mPreviousAnalyticsState->dump(ll);
+        auto [s, l] = mPreviousAnalyticsState->dump(ll, sinceNs, prefix);
         ss << s;
         ll -= l;
     }
diff --git a/services/mediametrics/AudioAnalytics.h b/services/mediametrics/AudioAnalytics.h
index 4a42e22..ba4c3f2 100644
--- a/services/mediametrics/AudioAnalytics.h
+++ b/services/mediametrics/AudioAnalytics.h
@@ -60,8 +60,17 @@
      * delivered.
      *
      * \param lines the maximum number of lines in the string returned.
+     * \param sinceNs the nanoseconds since Unix epoch to start dump (0 shows all)
+     * \param prefix the desired key prefix to match (nullptr shows all)
      */
-    std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const;
+    std::pair<std::string, int32_t> dump(
+            int32_t lines = INT32_MAX, int64_t sinceNs = 0, const char *prefix = nullptr) const;
+
+    void clear() {
+        // underlying state is locked.
+        mPreviousAnalyticsState->clear();
+        mAnalyticsState->clear();
+    }
 
 private:
 
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index a6fefd2..b9703ba 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -26,6 +26,8 @@
 #include <audio_utils/clock.h>                 // clock conversions
 #include <binder/IPCThreadState.h>             // get calling uid
 #include <cutils/properties.h>                 // for property_get
+#include <mediautils/MemoryLeakTrackUtil.h>
+#include <memunreachable/memunreachable.h>
 #include <private/android_filesystem_config.h> // UID
 
 namespace android {
@@ -205,91 +207,112 @@
         return NO_ERROR;
     }
 
-    // crack any parameters
-    const String16 protoOption("--proto");
-    const String16 clearOption("--clear");
+    static const String16 allOption("--all");
+    static const String16 clearOption("--clear");
+    static const String16 heapOption("--heap");
+    static const String16 helpOption("--help");
+    static const String16 prefixOption("--prefix");
+    static const String16 sinceOption("--since");
+    static const String16 unreachableOption("--unreachable");
+
+    bool all = false;
     bool clear = false;
-    const String16 sinceOption("--since");
-    nsecs_t ts_since = 0;
-    const String16 helpOption("--help");
-    const String16 onlyOption("--only");
-    std::string only;
-    const int n = args.size();
-    for (int i = 0; i < n; i++) {
-        if (args[i] == clearOption) {
+    bool heap = false;
+    bool unreachable = false;
+    int64_t sinceNs = 0;
+    std::string prefix;
+
+    const size_t n = args.size();
+    for (size_t i = 0; i < n; i++) {
+        if (args[i] == allOption) {
+            all = true;
+        } else if (args[i] == clearOption) {
             clear = true;
-        } else if (args[i] == protoOption) {
-            i++;
-            if (i < n) {
-                // ignore
-            } else {
-                result.append("missing value for -proto\n\n");
-            }
-        } else if (args[i] == sinceOption) {
-            i++;
-            if (i < n) {
-                String8 value(args[i]);
-                char *endp;
-                const char *p = value.string();
-                ts_since = strtoll(p, &endp, 10);
-                if (endp == p || *endp != '\0') {
-                    ts_since = 0;
-                }
-            } else {
-                ts_since = 0;
-            }
-            // command line is milliseconds; internal units are nano-seconds
-            ts_since *= NANOS_PER_MILLISECOND;
-        } else if (args[i] == onlyOption) {
-            i++;
-            if (i < n) {
-                String8 value(args[i]);
-                only = value.string();
-            }
+        } else if (args[i] == heapOption) {
+            heap = true;
         } else if (args[i] == helpOption) {
             // TODO: consider function area dumping.
             // dumpsys media.metrics audiotrack,codec
             // or dumpsys media.metrics audiotrack codec
 
             result.append("Recognized parameters:\n");
-            result.append("--help        this help message\n");
-            result.append("--proto #     dump using protocol #");
-            result.append("--clear       clears out saved records\n");
-            result.append("--only X      process records for component X\n");
-            result.append("--since X     include records since X\n");
-            result.append("             (X is milliseconds since the UNIX epoch)\n");
+            result.append("--all         show all records\n");
+            result.append("--clear       clear out saved records\n");
+            result.append("--heap        show heap usage (top 100)\n");
+            result.append("--help        display help\n");
+            result.append("--prefix X    process records for component X\n");
+            result.append("--since X     X < 0: records from -X seconds in the past\n");
+            result.append("              X = 0: ignore\n");
+            result.append("              X > 0: records from X seconds since Unix epoch\n");
+            result.append("--unreachable show unreachable memory (leaks)\n");
             write(fd, result.string(), result.size());
             return NO_ERROR;
+        } else if (args[i] == prefixOption) {
+            ++i;
+            if (i < n) {
+                prefix = String8(args[i]).string();
+            }
+        } else if (args[i] == sinceOption) {
+            ++i;
+            if (i < n) {
+                String8 value(args[i]);
+                char *endp;
+                const char *p = value.string();
+                long long sec = strtoll(p, &endp, 10);
+                if (endp == p || *endp != '\0' || sec == 0) {
+                    sinceNs = 0;
+                } else if (sec < 0) {
+                    sinceNs = systemTime(SYSTEM_TIME_REALTIME) + sec * NANOS_PER_SECOND;
+                } else {
+                    sinceNs = sec * NANOS_PER_SECOND;
+                }
+            }
+        } else if (args[i] == unreachableOption) {
+            unreachable = true;
         }
     }
 
     {
         std::lock_guard _l(mLock);
 
-        result.appendFormat("Dump of the %s process:\n", kServiceName);
-        dumpHeaders_l(result, ts_since);
-        dumpRecent_l(result, ts_since, only.c_str());
-
         if (clear) {
             mItemsDiscarded += mItems.size();
             mItems.clear();
-            // shall we clear the summary data too?
-        }
-        // TODO: maybe consider a better way of dumping audio analytics info.
-        constexpr int32_t linesToDump = 1000;
-        auto [ dumpString, lines ] = mAudioAnalytics.dump(linesToDump);
-        result.append(dumpString.c_str());
-        if (lines == linesToDump) {
-            result.append("-- some lines may be truncated --\n");
+            mAudioAnalytics.clear();
+        } else {
+            result.appendFormat("Dump of the %s process:\n", kServiceName);
+            const char *prefixptr = prefix.size() > 0 ? prefix.c_str() : nullptr;
+            dumpHeaders_l(result, sinceNs, prefixptr);
+            dumpQueue_l(result, sinceNs, prefixptr);
+
+            // TODO: maybe consider a better way of dumping audio analytics info.
+            const int32_t linesToDump = all ? INT32_MAX : 1000;
+            auto [ dumpString, lines ] = mAudioAnalytics.dump(linesToDump, sinceNs, prefixptr);
+            result.append(dumpString.c_str());
+            if (lines == linesToDump) {
+                result.append("-- some lines may be truncated --\n");
+            }
         }
     }
-
     write(fd, result.string(), result.size());
+
+    // Check heap and unreachable memory outside of lock.
+    if (heap) {
+        dprintf(fd, "\nDumping heap:\n");
+        std::string s = dumpMemoryAddresses(100 /* limit */);
+        write(fd, s.c_str(), s.size());
+    }
+    if (unreachable) {
+        dprintf(fd, "\nDumping unreachable memory:\n");
+        // TODO - should limit be an argument parameter?
+        std::string s = GetUnreachableMemoryString(true /* contents */, 100 /* limit */);
+        write(fd, s.c_str(), s.size());
+    }
     return NO_ERROR;
 }
 
 // dump headers
-void MediaMetricsService::dumpHeaders_l(String8 &result, nsecs_t ts_since)
+void MediaMetricsService::dumpHeaders_l(String8 &result, int64_t sinceNs, const char* prefix)
 {
     if (mediametrics::Item::isEnabled()) {
         result.append("Metrics gathering: enabled\n");
@@ -303,54 +326,36 @@
             "Records Discarded: %lld (by Count: %lld by Expiration: %lld)\n",
             (long long)mItemsDiscarded, (long long)mItemsDiscardedCount,
             (long long)mItemsDiscardedExpire);
-    if (ts_since != 0) {
+    if (prefix != nullptr) {
+        result.appendFormat("Restricting to prefix %s", prefix);
+    }
+    if (sinceNs != 0) {
         result.appendFormat(
             "Emitting Queue entries more recent than: %lld\n",
-            (long long)ts_since);
+            (long long)sinceNs);
     }
 }
 
-void MediaMetricsService::dumpRecent_l(
-        String8 &result, nsecs_t ts_since, const char * only)
+// TODO: should prefix be a set<string>?
+void MediaMetricsService::dumpQueue_l(String8 &result, int64_t sinceNs, const char* prefix)
 {
-    if (only != nullptr && *only == '\0') {
-        only = nullptr;
-    }
-    result.append("\nFinalized Metrics (oldest first):\n");
-    dumpQueue_l(result, ts_since, only);
-
-    // show who is connected and injecting records?
-    // talk about # records fed to the 'readers'
-    // talk about # records we discarded, perhaps "discarded w/o reading" too
-}
-
-void MediaMetricsService::dumpQueue_l(String8 &result) {
-    dumpQueue_l(result, (nsecs_t) 0, nullptr /* only */);
-}
-
-void MediaMetricsService::dumpQueue_l(
-        String8 &result, nsecs_t ts_since, const char * only) {
-    int slot = 0;
-
     if (mItems.empty()) {
         result.append("empty\n");
-    } else {
-        for (const auto &item : mItems) {
-            nsecs_t when = item->getTimestamp();
-            if (when < ts_since) {
-                continue;
-            }
-            // TODO: Only should be a set<string>
-            if (only != nullptr &&
-                    item->getKey() /* std::string */ != only) {
-                ALOGV("%s: omit '%s', it's not '%s'",
-                        __func__, item->getKey().c_str(), only);
-                continue;
-            }
-            result.appendFormat("%5d: %s\n",
-                   slot, item->toString().c_str());
-            slot++;
+        return;
+    }
+
+    int slot = 0;
+    for (const auto &item : mItems) {         // TODO: consider std::lower_bound() on mItems
+        if (item->getTimestamp() < sinceNs) { // sinceNs == 0 means all items shown
+            continue;
         }
+        if (prefix != nullptr && !startsWith(item->getKey(), prefix)) {
+            ALOGV("%s: omit '%s', it's not '%s'",
+                    __func__, item->getKey().c_str(), prefix);
+            continue;
+        }
+        result.appendFormat("%5d: %s\n", slot, item->toString().c_str());
+        slot++;
     }
 }
 
diff --git a/services/mediametrics/MediaMetricsService.h b/services/mediametrics/MediaMetricsService.h
index 935bee2..a93f7fb 100644
--- a/services/mediametrics/MediaMetricsService.h
+++ b/services/mediametrics/MediaMetricsService.h
@@ -85,11 +85,8 @@
     bool expirations_l(const std::shared_ptr<const mediametrics::Item>& item);
 
     // support for generating output
-    void dumpQueue_l(String8 &result);
-    void dumpQueue_l(String8 &result, nsecs_t, const char *only);
-    void dumpHeaders_l(String8 &result, nsecs_t ts_since);
-    void dumpSummaries_l(String8 &result, nsecs_t ts_since, const char * only);
-    void dumpRecent_l(String8 &result, nsecs_t ts_since, const char * only);
+    void dumpQueue_l(String8 &result, int64_t sinceNs, const char* prefix);
+    void dumpHeaders_l(String8 &result, int64_t sinceNs, const char* prefix);
 
     // The following variables accessed without mLock
 
diff --git a/services/mediametrics/TimeMachine.h b/services/mediametrics/TimeMachine.h
index a4c3693..29adeae 100644
--- a/services/mediametrics/TimeMachine.h
+++ b/services/mediametrics/TimeMachine.h
@@ -149,8 +149,11 @@
             int32_t ll = lines;
             for (auto& tsPair : mPropertyMap) {
                 if (ll <= 0) break;
-                ss << dump(mKey, tsPair, time);
-                --ll;
+                std::string s = dump(mKey, tsPair, time);
+                if (s.size() > 0) {
+                    --ll;
+                    ss << s;
+                }
             }
             return { ss.str(), lines - ll };
         }
@@ -165,7 +168,7 @@
             const auto timeSequence = tsPair.second;
             auto eptr = timeSequence.lower_bound(time);
             if (eptr == timeSequence.end()) {
-                return tsPair.first + "={};\n";
+                return {}; // don't dump anything. tsPair.first + "={};\n";
             }
             std::stringstream ss;
             ss << key << "." << tsPair.first << "={";
@@ -316,7 +319,7 @@
                 if (it == mHistory.end()) continue;
                 remoteKeyHistory = it->second;
             }
-            std::lock_guard(getLockForKey(remoteKey));
+            std::lock_guard lock(getLockForKey(remoteKey));
             remoteKeyHistory->putProp(remoteName, prop, time);
         }
         return NO_ERROR;
@@ -407,24 +410,22 @@
      *
      * \param lines the maximum number of lines in the string returned.
      * \param key selects only that key.
-     * \param time to start the dump from.
+     * \param sinceNs the nanoseconds since Unix epoch to start dump (0 shows all)
+     * \param prefix the desired key prefix to match (nullptr shows all)
      */
     std::pair<std::string, int32_t> dump(
-            int32_t lines = INT32_MAX, const std::string &key = {}, int64_t time = 0) const {
+            int32_t lines = INT32_MAX, int64_t sinceNs = 0, const char *prefix = nullptr) const {
         std::lock_guard lock(mLock);
-        if (!key.empty()) {  // use std::regex
-            const auto it = mHistory.find(key);
-            if (it == mHistory.end()) return {};
-            std::lock_guard lock(getLockForKey(it->first));
-            return it->second->dump(lines, time);
-        }
-
         std::stringstream ss;
         int32_t ll = lines;
-        for (const auto &[lkey, lhist] : mHistory) {
-            std::lock_guard lock(getLockForKey(lkey));
-            if (lines <= 0) break;
-            auto [s, l] = lhist->dump(ll, time);
+
+        for (auto it = prefix != nullptr ? mHistory.lower_bound(prefix) : mHistory.begin();
+                it != mHistory.end();
+                ++it) {
+            if (ll <= 0) break;
+            if (prefix != nullptr && !startsWith(it->first, prefix)) break;
+            std::lock_guard lock(getLockForKey(it->first));
+            auto [s, l] = it->second->dump(ll, sinceNs);
             ss << s;
             ll -= l;
         }
@@ -440,7 +441,7 @@
 
     // Finds a KeyHistory from a URL.  Returns nullptr if not found.
     std::shared_ptr<KeyHistory> getKeyHistoryFromUrl(
-            std::string url, std::string* key, std::string *prop) const {
+            const std::string& url, std::string* key, std::string *prop) const {
         std::lock_guard lock(mLock);
 
         auto it = mHistory.upper_bound(url);
diff --git a/services/mediametrics/TransactionLog.h b/services/mediametrics/TransactionLog.h
index 190a99e..4f09bb0 100644
--- a/services/mediametrics/TransactionLog.h
+++ b/services/mediametrics/TransactionLog.h
@@ -127,8 +127,11 @@
      * for subsequent line limiting.
      *
      * \param lines the maximum number of lines in the string returned.
+     * \param sinceNs the nanoseconds since Unix epoch to start dump (0 shows all)
+     * \param prefix the desired key prefix to match (nullptr shows all)
      */
-    std::pair<std::string, int32_t> dump(int32_t lines) const {
+    std::pair<std::string, int32_t> dump(
+            int32_t lines, int64_t sinceNs, const char *prefix = nullptr) const {
         std::stringstream ss;
         int32_t ll = lines;
         std::lock_guard lock(mLock);
@@ -138,26 +141,25 @@
             ss << "Consolidated:\n";
             --ll;
         }
-        for (const auto &log : mLog) {
-            if (ll <= 0) break;
-            ss << "  " << log.second->toString() << "\n";
-            --ll;
-        }
+        auto [s, l] = dumpMapTimeItem(mLog, ll, sinceNs, prefix);
+        ss << s;
+        ll -= l;
 
         // Grouped by item key (category)
         if (ll > 0) {
             ss << "Categorized:\n";
             --ll;
         }
-        for (const auto &itemMap : mItemMap) {
+
+        for (auto it = prefix != nullptr ? mItemMap.lower_bound(prefix) : mItemMap.begin();
+                it != mItemMap.end();
+                ++it) {
             if (ll <= 0) break;
-            ss << " " << itemMap.first << "\n";
-            --ll;
-            for (const auto &item : itemMap.second) {
-                if (ll <= 0) break;
-                ss << "  " << item.second->toString() << "\n";
-                --ll;
-            }
+            if (prefix != nullptr && !startsWith(it->first, prefix)) break;
+            auto [s, l] = dumpMapTimeItem(it->second, ll - 1, sinceNs, prefix);
+            if (l == 0) continue; // don't show empty groups (due to sinceNs).
+            ss << " " << it->first << "\n" << s;
+            ll -= l + 1;
         }
         return { ss.str(), lines - ll };
     }
@@ -184,6 +186,24 @@
     using MapTimeItem =
             std::multimap<int64_t /* time */, std::shared_ptr<const mediametrics::Item>>;
 
+    static std::pair<std::string, int32_t> dumpMapTimeItem(
+            const MapTimeItem& mapTimeItem,
+            int32_t lines, int64_t sinceNs = 0, const char *prefix = nullptr) {
+        std::stringstream ss;
+        int32_t ll = lines;
+        // Note: for our data, mapTimeItem.lower_bound(0) == mapTimeItem.begin().
+        for (auto it = mapTimeItem.lower_bound(sinceNs);
+                it != mapTimeItem.end(); ++it) {
+            if (ll <= 0) break;
+            if (prefix != nullptr && !startsWith(it->second->getKey(), prefix)) {
+                continue;
+            }
+            ss << "  " << it->second->toString() << "\n";
+            --ll;
+        }
+        return { ss.str(), lines - ll };
+    }
+
     // GUARDED_BY mLock
     /**
      * Garbage collects if the TimeMachine size exceeds the high water mark.
diff --git a/services/mediametrics/main_mediametrics.cpp b/services/mediametrics/main_mediametrics.cpp
index ec392e2..6992c32 100644
--- a/services/mediametrics/main_mediametrics.cpp
+++ b/services/mediametrics/main_mediametrics.cpp
@@ -23,12 +23,17 @@
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
-
+#include <mediautils/LimitProcessMemory.h>
 
 int main(int argc __unused, char **argv __unused)
 {
     using namespace android;
 
+    limitProcessMemory(
+        "media.metrics.maxmem", /* property that defines limit */
+        (size_t)128 * (1 << 20), /* SIZE_MAX, upper limit in bytes */
+        10 /* upper limit as percentage of physical RAM */);
+
     signal(SIGPIPE, SIG_IGN);
 
     // to match the service name
diff --git a/services/mediametrics/tests/mediametrics_tests.cpp b/services/mediametrics/tests/mediametrics_tests.cpp
index b8e566e..78eb71c 100644
--- a/services/mediametrics/tests/mediametrics_tests.cpp
+++ b/services/mediametrics/tests/mediametrics_tests.cpp
@@ -79,7 +79,7 @@
     const int mFinal;
 
     public:
-      Thunk(decltype(mF) f, int final) : mF(f), mFinal(final) {}
+      explicit Thunk(decltype(mF) f, int final) : mF(std::move(f)), mFinal(final) {}
       ~Thunk() { mF(mFinal); }
       void thunk(int value) { mF(value); }
   };
@@ -139,7 +139,7 @@
     std::function<void()> mF;
 
     public:
-      Thunk(decltype(mF) f) : mF(f) {}
+      explicit Thunk(decltype(mF) f) : mF(std::move(f)) {}
       void thunk() { mF(); }
   };
 
diff --git a/services/minijail/Android.bp b/services/minijail/Android.bp
index 0713a87..5ea6d1e 100644
--- a/services/minijail/Android.bp
+++ b/services/minijail/Android.bp
@@ -39,4 +39,5 @@
     srcs: [
         "av_services_minijail_unittest.cpp",
     ],
+    test_suites: ["device-tests"],
 }
diff --git a/services/minijail/TEST_MAPPING b/services/minijail/TEST_MAPPING
new file mode 100644
index 0000000..0d89760
--- /dev/null
+++ b/services/minijail/TEST_MAPPING
@@ -0,0 +1,5 @@
+{
+  "presubmit": [
+    { "name": "libavservices_minijail_unittest" }
+  ]
+}
diff --git a/services/minijail/av_services_minijail_unittest.cpp b/services/minijail/av_services_minijail_unittest.cpp
index 31313f8..896a764 100644
--- a/services/minijail/av_services_minijail_unittest.cpp
+++ b/services/minijail/av_services_minijail_unittest.cpp
@@ -34,13 +34,32 @@
         "mmap: 1\n"
         "munmap: 1\n";
 
+    const std::string third_policy_ =
+        "open: 1\n"
+        "close: 1\n";
+
     const std::string full_policy_ = base_policy_ + std::string("\n") + additional_policy_;
+    const std::string triple_policy_ = base_policy_ +
+                                       std::string("\n") + additional_policy_ +
+                                       std::string("\n") + third_policy_;
 };
 
 TEST_F(WritePolicyTest, OneFile)
 {
     std::string final_string;
-    android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, std::string()));
+    // vector with an empty pathname
+    android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, {std::string()}));
+    EXPECT_LE(0, fd.get());
+    bool success = android::base::ReadFdToString(fd.get(), &final_string);
+    EXPECT_TRUE(success);
+    EXPECT_EQ(final_string, base_policy_);
+}
+
+TEST_F(WritePolicyTest, OneFileAlternate)
+{
+    std::string final_string;
+    // empty vector
+    android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, {}));
     EXPECT_LE(0, fd.get());
     bool success = android::base::ReadFdToString(fd.get(), &final_string);
     EXPECT_TRUE(success);
@@ -50,9 +69,19 @@
 TEST_F(WritePolicyTest, TwoFiles)
 {
     std::string final_string;
-    android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, additional_policy_));
+    android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, {additional_policy_}));
     EXPECT_LE(0, fd.get());
     bool success = android::base::ReadFdToString(fd.get(), &final_string);
     EXPECT_TRUE(success);
     EXPECT_EQ(final_string, full_policy_);
 }
+
+TEST_F(WritePolicyTest, ThreeFiles)
+{
+    std::string final_string;
+    android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, {additional_policy_, third_policy_}));
+    EXPECT_LE(0, fd.get());
+    bool success = android::base::ReadFdToString(fd.get(), &final_string);
+    EXPECT_TRUE(success);
+    EXPECT_EQ(final_string, triple_policy_);
+}
diff --git a/services/minijail/minijail.cpp b/services/minijail/minijail.cpp
index f213287..c7832b9 100644
--- a/services/minijail/minijail.cpp
+++ b/services/minijail/minijail.cpp
@@ -29,7 +29,7 @@
 namespace android {
 
 int WritePolicyToPipe(const std::string& base_policy_content,
-                      const std::string& additional_policy_content)
+                      const std::vector<std::string>& additional_policy_contents)
 {
     int pipefd[2];
     if (pipe(pipefd) == -1) {
@@ -40,9 +40,11 @@
     base::unique_fd write_end(pipefd[1]);
     std::string content = base_policy_content;
 
-    if (additional_policy_content.length() > 0) {
-        content += "\n";
-        content += additional_policy_content;
+    for (auto one_content : additional_policy_contents) {
+        if (one_content.length() > 0) {
+            content += "\n";
+            content += one_content;
+        }
     }
 
     if (!base::WriteStringToFd(content, write_end.get())) {
@@ -53,29 +55,34 @@
     return pipefd[0];
 }
 
-void SetUpMinijail(const std::string& base_policy_path, const std::string& additional_policy_path)
+void SetUpMinijail(const std::string& base_policy_path,
+                   const std::string& additional_policy_path)
 {
-    // No seccomp policy defined for this architecture.
-    if (access(base_policy_path.c_str(), R_OK) == -1) {
-        LOG(WARNING) << "No seccomp policy defined for this architecture.";
-        return;
-    }
+    SetUpMinijailList(base_policy_path, {additional_policy_path});
+}
 
+void SetUpMinijailList(const std::string& base_policy_path,
+                   const std::vector<std::string>& additional_policy_paths)
+{
     std::string base_policy_content;
-    std::string additional_policy_content;
+    std::vector<std::string> additional_policy_contents;
     if (!base::ReadFileToString(base_policy_path, &base_policy_content,
                                 false /* follow_symlinks */)) {
         LOG(FATAL) << "Could not read base policy file '" << base_policy_path << "'";
     }
 
-    if (additional_policy_path.length() > 0 &&
-        !base::ReadFileToString(additional_policy_path, &additional_policy_content,
-                                false /* follow_symlinks */)) {
-        LOG(WARNING) << "Could not read additional policy file '" << additional_policy_path << "'";
-        additional_policy_content = std::string();
+    for (auto one_policy_path : additional_policy_paths) {
+        std::string one_policy_content;
+        if (one_policy_path.length() > 0 &&
+                !base::ReadFileToString(one_policy_path, &one_policy_content,
+                    false /* follow_symlinks */)) {
+            // TODO: harder failure (fatal unless ENOENT?)
+            LOG(WARNING) << "Could not read additional policy file '" << one_policy_path << "'";
+        }
+        additional_policy_contents.push_back(one_policy_content);
     }
 
-    base::unique_fd policy_fd(WritePolicyToPipe(base_policy_content, additional_policy_content));
+    base::unique_fd policy_fd(WritePolicyToPipe(base_policy_content, additional_policy_contents));
     if (policy_fd.get() == -1) {
         LOG(FATAL) << "Could not write seccomp policy to fd";
     }
diff --git a/services/minijail/minijail.h b/services/minijail/minijail.h
index c8a2149..298af86 100644
--- a/services/minijail/minijail.h
+++ b/services/minijail/minijail.h
@@ -16,11 +16,15 @@
 #define AV_SERVICES_MINIJAIL_MINIJAIL
 
 #include <string>
+#include <vector>
 
 namespace android {
 int WritePolicyToPipe(const std::string& base_policy_content,
-                      const std::string& additional_policy_content);
-void SetUpMinijail(const std::string& base_policy_path, const std::string& additional_policy_path);
+                      const std::vector<std::string>& additional_policy_contents);
+void SetUpMinijail(const std::string& base_policy_path,
+                   const std::string& additional_policy_path);
+void SetUpMinijailList(const std::string& base_policy_path,
+                       const std::vector<std::string>& additional_policy_paths);
 }
 
 #endif  // AV_SERVICES_MINIJAIL_MINIJAIL
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index af8c67b..aba8e08 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -310,14 +310,15 @@
 }
 
 aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle,
-                                  const android::AudioClient& client,
-                                  audio_port_handle_t *clientHandle) {
+                                           const android::AudioClient& client,
+                                           const audio_attributes_t *attr,
+                                           audio_port_handle_t *clientHandle) {
     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
     if (serviceStream.get() == nullptr) {
         ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle);
         return AAUDIO_ERROR_INVALID_HANDLE;
     }
-    aaudio_result_t result = serviceStream->startClient(client, clientHandle);
+    aaudio_result_t result = serviceStream->startClient(client, attr, clientHandle);
     return checkForPendingClose(serviceStream, result);
 }
 
diff --git a/services/oboeservice/AAudioService.h b/services/oboeservice/AAudioService.h
index 43a59c3..eddb5a0 100644
--- a/services/oboeservice/AAudioService.h
+++ b/services/oboeservice/AAudioService.h
@@ -77,8 +77,9 @@
                                                   pid_t tid) override;
 
     aaudio_result_t startClient(aaudio::aaudio_handle_t streamHandle,
-                                      const android::AudioClient& client,
-                                      audio_port_handle_t *clientHandle) override;
+                                const android::AudioClient& client,
+                                const audio_attributes_t *attr,
+                                audio_port_handle_t *clientHandle) override;
 
     aaudio_result_t stopClient(aaudio::aaudio_handle_t streamHandle,
                                        audio_port_handle_t clientHandle) override;
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 2753f1f..647dcf7 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -138,3 +138,36 @@
     }
     return true;
 }
+
+// static
+audio_attributes_t AAudioServiceEndpoint::getAudioAttributesFrom(
+        const AAudioStreamParameters *params) {
+    if (params == nullptr) {
+        return {};
+    }
+    const aaudio_direction_t direction = params->getDirection();
+
+    const audio_content_type_t contentType =
+            AAudioConvert_contentTypeToInternal(params->getContentType());
+    // Usage only used for OUTPUT
+    const audio_usage_t usage = (direction == AAUDIO_DIRECTION_OUTPUT)
+            ? AAudioConvert_usageToInternal(params->getUsage())
+            : AUDIO_USAGE_UNKNOWN;
+    const audio_source_t source = (direction == AAUDIO_DIRECTION_INPUT)
+            ? AAudioConvert_inputPresetToAudioSource(params->getInputPreset())
+            : AUDIO_SOURCE_DEFAULT;
+    audio_flags_mask_t flags;
+    if (direction == AAUDIO_DIRECTION_OUTPUT) {
+        flags = AUDIO_FLAG_LOW_LATENCY
+            | AAudioConvert_allowCapturePolicyToAudioFlagsMask(params->getAllowedCapturePolicy());
+    } else {
+        flags = AUDIO_FLAG_LOW_LATENCY
+            | AAudioConvert_privacySensitiveToAudioFlagsMask(params->isPrivacySensitive());
+    }
+    return {
+            .content_type = contentType,
+            .usage = usage,
+            .source = source,
+            .flags = flags,
+            .tags = "" };
+}
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index a2f66a5..a6bb019 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -60,6 +60,7 @@
                                        audio_port_handle_t clientHandle) = 0;
 
     virtual aaudio_result_t startClient(const android::AudioClient& client,
+                                        const audio_attributes_t *attr,
                                         audio_port_handle_t *clientHandle) {
         ALOGD("AAudioServiceEndpoint::startClient(...) AAUDIO_ERROR_UNAVAILABLE");
         return AAUDIO_ERROR_UNAVAILABLE;
@@ -118,6 +119,8 @@
 
     void                     disconnectRegisteredStreams();
 
+    static audio_attributes_t getAudioAttributesFrom(const AAudioStreamParameters *params);
+
     mutable std::mutex       mLockStreams;
     std::vector<android::sp<AAudioServiceStreamBase>> mRegisteredStreams;
 
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 5bdb8eb..af2710d 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -79,32 +79,7 @@
 
     copyFrom(request.getConstantConfiguration());
 
-    aaudio_direction_t direction = getDirection();
-
-    const audio_content_type_t contentType =
-            AAudioConvert_contentTypeToInternal(getContentType());
-    // Usage only used for OUTPUT
-    const audio_usage_t usage = (direction == AAUDIO_DIRECTION_OUTPUT)
-            ? AAudioConvert_usageToInternal(getUsage())
-            : AUDIO_USAGE_UNKNOWN;
-    const audio_source_t source = (direction == AAUDIO_DIRECTION_INPUT)
-            ? AAudioConvert_inputPresetToAudioSource(getInputPreset())
-            : AUDIO_SOURCE_DEFAULT;
-    audio_flags_mask_t flags;
-    if (direction == AAUDIO_DIRECTION_OUTPUT) {
-        flags = AUDIO_FLAG_LOW_LATENCY
-            | AAudioConvert_allowCapturePolicyToAudioFlagsMask(getAllowedCapturePolicy());
-    } else {
-        flags = AUDIO_FLAG_LOW_LATENCY
-            | AAudioConvert_privacySensitiveToAudioFlagsMask(isPrivacySensitive());
-    }
-    const audio_attributes_t attributes = {
-            .content_type = contentType,
-            .usage = usage,
-            .source = source,
-            .flags = flags,
-            .tags = ""
-    };
+    const audio_attributes_t attributes = getAudioAttributesFrom(this);
 
     mMmapClient.clientUid = request.getUserId();
     mMmapClient.clientPid = request.getProcessId();
@@ -127,6 +102,8 @@
 
     int32_t aaudioSamplesPerFrame = getSamplesPerFrame();
 
+    const aaudio_direction_t direction = getDirection();
+
     if (direction == AAUDIO_DIRECTION_OUTPUT) {
         config.channel_mask = (aaudioSamplesPerFrame == AAUDIO_UNSPECIFIED)
                               ? AUDIO_CHANNEL_OUT_STEREO
@@ -269,7 +246,12 @@
     // Start the client on behalf of the AAudio service.
     // Use the port handle that was provided by openMmapStream().
     audio_port_handle_t tempHandle = mPortHandle;
-    aaudio_result_t result = startClient(mMmapClient, &tempHandle);
+    audio_attributes_t attr = {};
+    if (stream != nullptr) {
+        attr = getAudioAttributesFrom(stream.get());
+    }
+    aaudio_result_t result = startClient(
+            mMmapClient, stream == nullptr ? nullptr : &attr, &tempHandle);
     // When AudioFlinger is passed a valid port handle then it should not change it.
     LOG_ALWAYS_FATAL_IF(tempHandle != mPortHandle,
                         "%s() port handle not expected to change from %d to %d",
@@ -294,9 +276,10 @@
 }
 
 aaudio_result_t AAudioServiceEndpointMMAP::startClient(const android::AudioClient& client,
+                                                       const audio_attributes_t *attr,
                                                        audio_port_handle_t *clientHandle) {
     if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
-    status_t status = mMmapStream->start(client, clientHandle);
+    status_t status = mMmapStream->start(client, attr, clientHandle);
     return AAudioConvert_androidToAAudioResult(status);
 }
 
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h
index 5e815e0..f599066 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.h
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.h
@@ -59,7 +59,8 @@
                                audio_port_handle_t clientHandle) override;
 
     aaudio_result_t startClient(const android::AudioClient& client,
-                                        audio_port_handle_t *clientHandle)  override;
+                                const audio_attributes_t *attr,
+                                audio_port_handle_t *clientHandle)  override;
 
     aaudio_result_t stopClient(audio_port_handle_t clientHandle)  override;
 
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index 9b3b3b8..21253c8 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -152,7 +152,9 @@
     }
 
     if (result == AAUDIO_OK) {
-        result = getStreamInternal()->startClient(sharedStream->getAudioClient(), clientHandle);
+        const audio_attributes_t attr = getAudioAttributesFrom(sharedStream.get());
+        result = getStreamInternal()->startClient(
+                sharedStream->getAudioClient(), &attr, clientHandle);
         if (result != AAUDIO_OK) {
             if (--mRunningStreamCount == 0) { // atomic
                 stopSharingThread();
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index 097bc64..aaab567 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -111,7 +111,8 @@
     virtual aaudio_result_t flush();
 
 
-    virtual aaudio_result_t startClient(const android::AudioClient& client __unused,
+    virtual aaudio_result_t startClient(const android::AudioClient& client,
+                                        const audio_attributes_t *attr __unused,
                                         audio_port_handle_t *clientHandle __unused) {
         ALOGD("AAudioServiceStreamBase::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client);
         return AAUDIO_ERROR_UNAVAILABLE;
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index f4e72b7..639a0a8 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -86,7 +86,7 @@
     aaudio_result_t result = AAudioServiceStreamBase::startDevice();
     if (!mInService && result == AAUDIO_OK) {
         // Note that this can sometimes take 200 to 300 msec for a cold start!
-        result = startClient(mMmapClient, &mClientHandle);
+        result = startClient(mMmapClient, nullptr /*const audio_attributes_t* */, &mClientHandle);
     }
     return result;
 }
@@ -117,14 +117,15 @@
 }
 
 aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client,
-                                                       audio_port_handle_t *clientHandle) {
+                                                     const audio_attributes_t *attr,
+                                                     audio_port_handle_t *clientHandle) {
     sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
     if (endpoint == nullptr) {
         ALOGE("%s() has no endpoint", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
     // Start the client on behalf of the application. Generate a new porthandle.
-    aaudio_result_t result = endpoint->startClient(client, clientHandle);
+    aaudio_result_t result = endpoint->startClient(client, attr, clientHandle);
     return result;
 }
 
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.h b/services/oboeservice/AAudioServiceStreamMMAP.h
index 3d56623..9105469 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.h
+++ b/services/oboeservice/AAudioServiceStreamMMAP.h
@@ -63,6 +63,7 @@
     aaudio_result_t stop() override;
 
     aaudio_result_t startClient(const android::AudioClient& client,
+                                const audio_attributes_t *attr,
                                 audio_port_handle_t *clientHandle) override;
 
     aaudio_result_t stopClient(audio_port_handle_t clientHandle) override;