Merge "Add libcgrouprc to APEX shared_libs list."
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index e4f12c8..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,7 +0,0 @@
-subdirs = [
-    "camera",
-    "drm/*",
-    "media/*",
-    "services/*",
-    "soundtrigger",
-]
diff --git a/camera/Android.bp b/camera/Android.bp
index 21588d4..2800595 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-subdirs = ["ndk"]
-
 cc_library_shared {
     name: "libcamera_client",
 
diff --git a/camera/CaptureResult.cpp b/camera/CaptureResult.cpp
index 928a6bc..1d8e8c4 100644
--- a/camera/CaptureResult.cpp
+++ b/camera/CaptureResult.cpp
@@ -39,6 +39,16 @@
     parcel->readInt64(&frameNumber);
     parcel->readInt32(&partialResultCount);
     parcel->readInt32(&errorStreamId);
+    auto physicalCameraIdPresent = parcel->readBool();
+    if (physicalCameraIdPresent) {
+        String16 cameraId;
+        status_t res = OK;
+        if ((res = parcel->readString16(&cameraId)) != OK) {
+            ALOGE("%s: Failed to read camera id: %d", __FUNCTION__, res);
+            return res;
+        }
+        errorPhysicalCameraId = cameraId;
+    }
 
     return OK;
 }
@@ -56,6 +66,16 @@
     parcel->writeInt64(frameNumber);
     parcel->writeInt32(partialResultCount);
     parcel->writeInt32(errorStreamId);
+    if (errorPhysicalCameraId.size() > 0) {
+        parcel->writeBool(true);
+        status_t res = OK;
+        if ((res = parcel->writeString16(errorPhysicalCameraId)) != OK) {
+            ALOGE("%s: Failed to write physical camera ID to parcel: %d", __FUNCTION__, res);
+            return res;
+        }
+    } else {
+        parcel->writeBool(false);
+    }
 
     return OK;
 }
diff --git a/camera/include/camera/CaptureResult.h b/camera/include/camera/CaptureResult.h
index 56fa178..ef830b5 100644
--- a/camera/include/camera/CaptureResult.h
+++ b/camera/include/camera/CaptureResult.h
@@ -70,6 +70,13 @@
     int32_t errorStreamId;
 
     /**
+     * For capture result errors, the physical camera ID in case the respective request contains
+     * a reference to physical camera device.
+     * Empty otherwise.
+     */
+    String16  errorPhysicalCameraId;
+
+    /**
      * Constructor initializes object as invalid by setting requestId to be -1.
      */
     CaptureResultExtras()
@@ -79,7 +86,8 @@
           precaptureTriggerId(0),
           frameNumber(0),
           partialResultCount(0),
-          errorStreamId(-1) {
+          errorStreamId(-1),
+          errorPhysicalCameraId() {
     }
 
     /**
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index c9db01e..25a81eb 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -45,6 +45,7 @@
 const char* CameraDevice::kSequenceIdKey     = "SequenceId";
 const char* CameraDevice::kFrameNumberKey    = "FrameNumber";
 const char* CameraDevice::kAnwKey            = "Anw";
+const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
 
 /**
  * CameraDevice Implementation
@@ -867,10 +868,19 @@
         failure->wasImageCaptured = (errorCode ==
                 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT);
 
-        sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
+        sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
+                kWhatCaptureFail, mHandler);
         msg->setPointer(kContextKey, cbh.mContext);
         msg->setObject(kSessionSpKey, session);
-        msg->setPointer(kCallbackFpKey, (void*) onError);
+        if (cbh.mIsLogicalCameraCallback) {
+            if (resultExtras.errorPhysicalCameraId.size() > 0) {
+                String8 cameraId(resultExtras.errorPhysicalCameraId);
+                msg->setString(kFailingPhysicalCameraId, cameraId.string(), cameraId.size());
+            }
+            msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
+        } else {
+            msg->setPointer(kCallbackFpKey, (void*) onError);
+        }
         msg->setObject(kCaptureRequestKey, request);
         msg->setObject(kCaptureFailureKey, failure);
         postSessionMsgAndCleanup(msg);
@@ -895,6 +905,7 @@
         case kWhatCaptureResult:
         case kWhatLogicalCaptureResult:
         case kWhatCaptureFail:
+        case kWhatLogicalCaptureFail:
         case kWhatCaptureSeqEnd:
         case kWhatCaptureSeqAbort:
         case kWhatCaptureBufferLost:
@@ -966,6 +977,7 @@
         case kWhatCaptureResult:
         case kWhatLogicalCaptureResult:
         case kWhatCaptureFail:
+        case kWhatLogicalCaptureFail:
         case kWhatCaptureSeqEnd:
         case kWhatCaptureSeqAbort:
         case kWhatCaptureBufferLost:
@@ -984,6 +996,7 @@
                 case kWhatCaptureResult:
                 case kWhatLogicalCaptureResult:
                 case kWhatCaptureFail:
+                case kWhatLogicalCaptureFail:
                 case kWhatCaptureBufferLost:
                     found = msg->findObject(kCaptureRequestKey, &obj);
                     if (!found) {
@@ -1138,6 +1151,39 @@
                     freeACaptureRequest(request);
                     break;
                 }
+                case kWhatLogicalCaptureFail:
+                {
+                    ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onFail == nullptr) {
+                        return;
+                    }
+
+                    found = msg->findObject(kCaptureFailureKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
+                        return;
+                    }
+                    sp<CameraCaptureFailure> failureSp(
+                            static_cast<CameraCaptureFailure*>(obj.get()));
+                    ALogicalCameraCaptureFailure failure;
+                    AString physicalCameraId;
+                    found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
+                    if (found && !physicalCameraId.empty()) {
+                        failure.physicalCameraId = physicalCameraId.c_str();
+                    } else {
+                        failure.physicalCameraId = nullptr;
+                    }
+                    failure.captureFailure = *failureSp;
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
+                    (*onFail)(context, session.get(), request, &failure);
+                    freeACaptureRequest(request);
+                    break;
+                }
                 case kWhatCaptureSeqEnd:
                 {
                     ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
@@ -1233,6 +1279,7 @@
 
     if (cbs != nullptr) {
         mOnCaptureCompleted = cbs->onCaptureCompleted;
+        mOnCaptureFailed = cbs->onCaptureFailed;
     }
 }
 
@@ -1248,6 +1295,7 @@
 
     if (lcbs != nullptr) {
         mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
+        mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
     }
 }
 
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 56741ce..c92a95f 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -214,6 +214,7 @@
         kWhatCaptureResult,    // onCaptureProgressed, onCaptureCompleted
         kWhatLogicalCaptureResult, // onLogicalCameraCaptureCompleted
         kWhatCaptureFail,      // onCaptureFailed
+        kWhatLogicalCaptureFail, // onLogicalCameraCaptureFailed
         kWhatCaptureSeqEnd,    // onCaptureSequenceCompleted
         kWhatCaptureSeqAbort,  // onCaptureSequenceAborted
         kWhatCaptureBufferLost,// onCaptureBufferLost
@@ -233,6 +234,7 @@
     static const char* kSequenceIdKey;
     static const char* kFrameNumberKey;
     static const char* kAnwKey;
+    static const char* kFailingPhysicalCameraId;
 
     class CallbackHandler : public AHandler {
       public:
@@ -281,6 +283,7 @@
             mOnCaptureProgressed = nullptr;
             mOnCaptureCompleted = nullptr;
             mOnLogicalCameraCaptureCompleted = nullptr;
+            mOnLogicalCameraCaptureFailed = nullptr;
             mOnCaptureFailed = nullptr;
             mOnCaptureSequenceCompleted = nullptr;
             mOnCaptureSequenceAborted = nullptr;
@@ -289,7 +292,6 @@
                 mContext = cbs->context;
                 mOnCaptureStarted = cbs->onCaptureStarted;
                 mOnCaptureProgressed = cbs->onCaptureProgressed;
-                mOnCaptureFailed = cbs->onCaptureFailed;
                 mOnCaptureSequenceCompleted = cbs->onCaptureSequenceCompleted;
                 mOnCaptureSequenceAborted = cbs->onCaptureSequenceAborted;
                 mOnCaptureBufferLost = cbs->onCaptureBufferLost;
@@ -305,6 +307,7 @@
         ACameraCaptureSession_captureCallback_result mOnCaptureProgressed;
         ACameraCaptureSession_captureCallback_result mOnCaptureCompleted;
         ACameraCaptureSession_logicalCamera_captureCallback_result mOnLogicalCameraCaptureCompleted;
+        ACameraCaptureSession_logicalCamera_captureCallback_failed mOnLogicalCameraCaptureFailed;
         ACameraCaptureSession_captureCallback_failed mOnCaptureFailed;
         ACameraCaptureSession_captureCallback_sequenceEnd mOnCaptureSequenceCompleted;
         ACameraCaptureSession_captureCallback_sequenceAbort mOnCaptureSequenceAborted;
diff --git a/camera/ndk/include/camera/NdkCameraCaptureSession.h b/camera/ndk/include/camera/NdkCameraCaptureSession.h
index d13a818..07176cf 100644
--- a/camera/ndk/include/camera/NdkCameraCaptureSession.h
+++ b/camera/ndk/include/camera/NdkCameraCaptureSession.h
@@ -676,6 +676,41 @@
         size_t physicalResultCount, const char** physicalCameraIds,
         const ACameraMetadata** physicalResults);
 
+/// Struct to describe a logical camera capture failure
+typedef struct ALogicalCameraCaptureFailure {
+    /**
+     * The {@link ACameraCaptureFailure} contains information about regular logical device capture
+     * failure.
+     */
+    struct ACameraCaptureFailure captureFailure;
+
+    /**
+     * The physical camera device ID in case the capture failure comes from a capture request
+     * with configured physical camera streams for a logical camera. physicalCameraId will be set
+     * to NULL in case the capture request has no associated physical camera device.
+     *
+     */
+    const char*    physicalCameraId;
+} ALogicalCameraCaptureFailure;
+
+/**
+ * The definition of logical camera capture failure callback.
+ *
+ * @param context The optional application context provided by user in
+ *                {@link ACameraCaptureSession_captureCallbacks}.
+ * @param session The camera capture session of interest.
+ * @param request The capture request of interest. Note that this pointer points to a copy of
+ *                capture request sent by application, so the address is different to what
+ *                application sent but the content will match. This request will be freed by
+ *                framework immediately after this callback returns.
+ * @param failure The {@link ALogicalCameraCaptureFailure} desribes the capture failure. The memory
+ *                is managed by camera framework. Do not access this pointer after this callback
+ *                returns.
+ */
+typedef void (*ACameraCaptureSession_logicalCamera_captureCallback_failed)(
+        void* context, ACameraCaptureSession* session,
+        ACaptureRequest* request, ALogicalCameraCaptureFailure* failure);
+
 /**
  * This has the same functionality as ACameraCaptureSession_captureCallbacks,
  * with the exception that an onLogicalCameraCaptureCompleted callback is
@@ -708,9 +743,24 @@
     ACameraCaptureSession_logicalCamera_captureCallback_result onLogicalCameraCaptureCompleted;
 
     /**
+     * This callback is called instead of {@link onLogicalCameraCaptureCompleted} when the
+     * camera device failed to produce a capture result for the
+     * request.
+     *
+     * <p>Other requests are unaffected, and some or all image buffers from
+     * the capture may have been pushed to their respective output
+     * streams.</p>
+     *
+     * <p>Note that the ACaptureRequest pointer in the callback will not match what application has
+     * submitted, but the contents the ACaptureRequest will match what application submitted.</p>
+     *
+     * @see ALogicalCameraCaptureFailure
+     */
+    ACameraCaptureSession_logicalCamera_captureCallback_failed onLogicalCameraCaptureFailed;
+
+    /**
      * Same as ACameraCaptureSession_captureCallbacks
      */
-    ACameraCaptureSession_captureCallback_failed        onCaptureFailed;
     ACameraCaptureSession_captureCallback_sequenceEnd   onCaptureSequenceCompleted;
     ACameraCaptureSession_captureCallback_sequenceAbort onCaptureSequenceAborted;
     ACameraCaptureSession_captureCallback_bufferLost    onCaptureBufferLost;
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index acf6999..99b613e 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -5695,6 +5695,8 @@
      * <p>In both cases, all images generated for a particular capture request still carry the same
      * timestamps, so that they can be used to look up the matching frame number and
      * onCaptureStarted callback.</p>
+     * <p>This tag is only applicable if the logical camera device supports concurrent physical
+     * streams from different physical cameras.</p>
      */
     ACAMERA_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE =             // byte (acamera_metadata_enum_android_logical_multi_camera_sensor_sync_type_t)
             ACAMERA_LOGICAL_MULTI_CAMERA_START + 1,
@@ -7581,14 +7583,23 @@
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING           = 10,
 
     /**
-     * <p>The camera device is a logical camera backed by two or more physical cameras. In
-     * API level 28, the physical cameras must also be exposed to the application via
-     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList">CameraManager#getCameraIdList</a>. Starting from API
-     * level 29, some or all physical cameras may not be independently exposed to the
-     * application, in which case the physical camera IDs will not be available in
-     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList">CameraManager#getCameraIdList</a>. But the application
-     * can still query the physical cameras' characteristics by calling
-     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraCharacteristics">CameraManager#getCameraCharacteristics</a>.</p>
+     * <p>The camera device is a logical camera backed by two or more physical cameras.</p>
+     * <p>In API level 28, the physical cameras must also be exposed to the application via
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList">CameraManager#getCameraIdList</a>.</p>
+     * <p>Starting from API level 29, some or all physical cameras may not be independently
+     * exposed to the application, in which case the physical camera IDs will not be
+     * available in <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList">CameraManager#getCameraIdList</a>. But the
+     * application can still query the physical cameras' characteristics by calling
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraCharacteristics">CameraManager#getCameraCharacteristics</a>. Additionally,
+     * if a physical camera is hidden from camera ID list, the mandatory stream combinations
+     * for that physical camera must be supported through the logical camera using physical
+     * streams.</p>
+     * <p>Combinations of logical and physical streams, or physical streams from different
+     * physical cameras are not guaranteed. However, if the camera device supports
+     * {@link ACameraDevice_isSessionConfigurationSupported },
+     * application must be able to query whether a stream combination involving physical
+     * streams is supported by calling
+     * {@link ACameraDevice_isSessionConfigurationSupported }.</p>
      * <p>Camera application shouldn't assume that there are at most 1 rear camera and 1 front
      * camera in the system. For an application that switches between front and back cameras,
      * the recommendation is to switch between the first rear camera and the first front
@@ -7613,24 +7624,6 @@
      *   the same.</li>
      * <li>The logical camera must be LIMITED or higher device.</li>
      * </ul>
-     * <p>Both the logical camera device and its underlying physical devices support the
-     * mandatory stream combinations required for their device levels.</p>
-     * <p>Additionally, for each guaranteed stream combination, the logical camera supports:</p>
-     * <ul>
-     * <li>For each guaranteed stream combination, the logical camera supports replacing one
-     *   logical {@link AIMAGE_FORMAT_YUV_420_888 YUV_420_888}
-     *   or raw stream with two physical streams of the same size and format, each from a
-     *   separate physical camera, given that the size and format are supported by both
-     *   physical cameras.</li>
-     * <li>If the logical camera doesn't advertise RAW capability, but the underlying physical
-     *   cameras do, the logical camera will support guaranteed stream combinations for RAW
-     *   capability, except that the RAW streams will be physical streams, each from a separate
-     *   physical camera. This is usually the case when the physical cameras have different
-     *   sensor sizes.</li>
-     * </ul>
-     * <p>Using physical streams in place of a logical stream of the same size and format will
-     * not slow down the frame rate of the capture, as long as the minimum frame duration
-     * of the physical and logical streams are the same.</p>
      * <p>A logical camera device's dynamic metadata may contain
      * ACAMERA_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID to notify the application of the current
      * active physical camera Id. An active physical camera is the physical camera from which
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index d7d774b..b18c897 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -55,6 +55,7 @@
 const char* CameraDevice::kSequenceIdKey     = "SequenceId";
 const char* CameraDevice::kFrameNumberKey    = "FrameNumber";
 const char* CameraDevice::kAnwKey            = "Anw";
+const char* CameraDevice::kFailingPhysicalCameraId= "FailingPhysicalCameraId";
 
 /**
  * CameraDevice Implementation
@@ -299,7 +300,6 @@
     OutputConfigurationWrapper outConfigW;
     OutputConfiguration &outConfig = outConfigW.mOutputConfiguration;
     outConfig.rotation = utils::convertToHidl(output->mRotation);
-    outConfig.windowGroupId = -1; // ndk doesn't support inter OutputConfiguration buffer sharing.
     outConfig.windowHandles.resize(output->mSharedWindows.size() + 1);
     outConfig.windowHandles[0] = output->mWindow;
     outConfig.physicalCameraId = output->mPhysicalCameraId;
@@ -894,10 +894,19 @@
         failure->sequenceId  = sequenceId;
         failure->wasImageCaptured = (errorCode == ErrorCode::CAMERA_RESULT);
 
-        sp<AMessage> msg = new AMessage(kWhatCaptureFail, mHandler);
+        sp<AMessage> msg = new AMessage(cbh.mIsLogicalCameraCallback ? kWhatLogicalCaptureFail :
+                kWhatCaptureFail, mHandler);
         msg->setPointer(kContextKey, cbh.mContext);
         msg->setObject(kSessionSpKey, session);
-        msg->setPointer(kCallbackFpKey, (void*) onError);
+        if (cbh.mIsLogicalCameraCallback) {
+            if (resultExtras.errorPhysicalCameraId.size() > 0) {
+                msg->setString(kFailingPhysicalCameraId, resultExtras.errorPhysicalCameraId.c_str(),
+                        resultExtras.errorPhysicalCameraId.size());
+            }
+            msg->setPointer(kCallbackFpKey, (void*) cbh.mOnLogicalCameraCaptureFailed);
+        } else {
+            msg->setPointer(kCallbackFpKey, (void*) onError);
+        }
         msg->setObject(kCaptureRequestKey, request);
         msg->setObject(kCaptureFailureKey, failure);
         postSessionMsgAndCleanup(msg);
@@ -919,6 +928,7 @@
         case kWhatCaptureResult:
         case kWhatLogicalCaptureResult:
         case kWhatCaptureFail:
+        case kWhatLogicalCaptureFail:
         case kWhatCaptureSeqEnd:
         case kWhatCaptureSeqAbort:
         case kWhatCaptureBufferLost:
@@ -990,6 +1000,7 @@
         case kWhatCaptureResult:
         case kWhatLogicalCaptureResult:
         case kWhatCaptureFail:
+        case kWhatLogicalCaptureFail:
         case kWhatCaptureSeqEnd:
         case kWhatCaptureSeqAbort:
         case kWhatCaptureBufferLost:
@@ -1009,6 +1020,7 @@
                 case kWhatCaptureResult:
                 case kWhatLogicalCaptureResult:
                 case kWhatCaptureFail:
+                case kWhatLogicalCaptureFail:
                 case kWhatCaptureBufferLost:
                     found = msg->findObject(kCaptureRequestKey, &obj);
                     if (!found) {
@@ -1161,6 +1173,39 @@
                     freeACaptureRequest(request);
                     break;
                 }
+                case kWhatLogicalCaptureFail:
+                {
+                    ACameraCaptureSession_logicalCamera_captureCallback_failed onFail;
+                    found = msg->findPointer(kCallbackFpKey, (void**) &onFail);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture fail callback!", __FUNCTION__);
+                        return;
+                    }
+                    if (onFail == nullptr) {
+                        return;
+                    }
+
+                    found = msg->findObject(kCaptureFailureKey, &obj);
+                    if (!found) {
+                        ALOGE("%s: Cannot find capture failure!", __FUNCTION__);
+                        return;
+                    }
+                    sp<CameraCaptureFailure> failureSp(
+                            static_cast<CameraCaptureFailure*>(obj.get()));
+                    ALogicalCameraCaptureFailure failure;
+                    AString physicalCameraId;
+                    found = msg->findString(kFailingPhysicalCameraId, &physicalCameraId);
+                    if (found && !physicalCameraId.empty()) {
+                        failure.physicalCameraId = physicalCameraId.c_str();
+                    } else {
+                        failure.physicalCameraId = nullptr;
+                    }
+                    failure.captureFailure = *failureSp;
+                    ACaptureRequest* request = allocateACaptureRequest(requestSp, device->getId());
+                    (*onFail)(context, session.get(), request, &failure);
+                    freeACaptureRequest(request);
+                    break;
+                }
                 case kWhatCaptureSeqEnd:
                 {
                     ACameraCaptureSession_captureCallback_sequenceEnd onSeqEnd;
@@ -1256,6 +1301,7 @@
 
     if (cbs != nullptr) {
         mOnCaptureCompleted = cbs->onCaptureCompleted;
+        mOnCaptureFailed = cbs->onCaptureFailed;
     }
 }
 
@@ -1271,6 +1317,7 @@
 
     if (lcbs != nullptr) {
         mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
+        mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
     }
 }
 
@@ -1368,8 +1415,9 @@
 CameraDevice::ServiceCallback::onDeviceError(
         ErrorCode errorCode,
         const CaptureResultExtras& resultExtras) {
-    ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d",
-            errorCode, resultExtras.frameNumber, resultExtras.requestId, resultExtras.burstId);
+    ALOGD("Device error received, code %d, frame number %" PRId64 ", request ID %d, subseq ID %d"
+            " physical camera ID %s", errorCode, resultExtras.frameNumber, resultExtras.requestId,
+            resultExtras.burstId, resultExtras.errorPhysicalCameraId.c_str());
     auto ret = Void();
     sp<CameraDevice> dev = mDevice.promote();
     if (dev == nullptr) {
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.h b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
index 47e6f56..7036017 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
@@ -242,6 +242,7 @@
         kWhatCaptureResult,    // onCaptureProgressed, onCaptureCompleted
         kWhatLogicalCaptureResult, // onLogicalCameraCaptureCompleted
         kWhatCaptureFail,      // onCaptureFailed
+        kWhatLogicalCaptureFail, // onLogicalCameraCaptureFailed
         kWhatCaptureSeqEnd,    // onCaptureSequenceCompleted
         kWhatCaptureSeqAbort,  // onCaptureSequenceAborted
         kWhatCaptureBufferLost,// onCaptureBufferLost
@@ -261,6 +262,7 @@
     static const char* kSequenceIdKey;
     static const char* kFrameNumberKey;
     static const char* kAnwKey;
+    static const char* kFailingPhysicalCameraId;
 
     class CallbackHandler : public AHandler {
       public:
@@ -307,6 +309,7 @@
             mOnCaptureProgressed = nullptr;
             mOnCaptureCompleted = nullptr;
             mOnLogicalCameraCaptureCompleted = nullptr;
+            mOnLogicalCameraCaptureFailed = nullptr;
             mOnCaptureFailed = nullptr;
             mOnCaptureSequenceCompleted = nullptr;
             mOnCaptureSequenceAborted = nullptr;
@@ -315,7 +318,6 @@
                 mContext = cbs->context;
                 mOnCaptureStarted = cbs->onCaptureStarted;
                 mOnCaptureProgressed = cbs->onCaptureProgressed;
-                mOnCaptureFailed = cbs->onCaptureFailed;
                 mOnCaptureSequenceCompleted = cbs->onCaptureSequenceCompleted;
                 mOnCaptureSequenceAborted = cbs->onCaptureSequenceAborted;
                 mOnCaptureBufferLost = cbs->onCaptureBufferLost;
@@ -332,6 +334,7 @@
         ACameraCaptureSession_captureCallback_result mOnCaptureProgressed;
         ACameraCaptureSession_captureCallback_result mOnCaptureCompleted;
         ACameraCaptureSession_logicalCamera_captureCallback_result mOnLogicalCameraCaptureCompleted;
+        ACameraCaptureSession_logicalCamera_captureCallback_failed mOnLogicalCameraCaptureFailed;
         ACameraCaptureSession_captureCallback_failed mOnCaptureFailed;
         ACameraCaptureSession_captureCallback_sequenceEnd mOnCaptureSequenceCompleted;
         ACameraCaptureSession_captureCallback_sequenceAbort mOnCaptureSequenceAborted;
diff --git a/camera/ndk/ndk_vendor/impl/utils.h b/camera/ndk/ndk_vendor/impl/utils.h
index 2f1006d..a03c7bc 100644
--- a/camera/ndk/ndk_vendor/impl/utils.h
+++ b/camera/ndk/ndk_vendor/impl/utils.h
@@ -99,7 +99,15 @@
         return mOutputConfiguration;
     }
 
-    OutputConfigurationWrapper() = default;
+    OutputConfigurationWrapper() {
+        mOutputConfiguration.rotation = OutputConfiguration::Rotation::R0;
+        // The ndk currently doesn't support deferred surfaces
+        mOutputConfiguration.isDeferred = false;
+        mOutputConfiguration.width = 0;
+        mOutputConfiguration.height = 0;
+        // ndk doesn't support inter OutputConfiguration buffer sharing.
+        mOutputConfiguration.windowGroupId = -1;
+    };
 
     OutputConfigurationWrapper(OutputConfiguration &outputConfiguration)
             : mOutputConfiguration((outputConfiguration)) { }
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index c51f93b..7368775 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -323,7 +323,13 @@
             }
             ch->mCompletedCaptureCallbackCount++;
         },
-        nullptr, // onCaptureFailed
+        [] (void * /*ctx*/, ACameraCaptureSession* /*session*/, ACaptureRequest* /*request*/,
+                ALogicalCameraCaptureFailure* failure) {
+            if (failure->physicalCameraId) {
+                ALOGD("%s: Physical camera id: %s result failure", __FUNCTION__,
+                        failure->physicalCameraId);
+            }
+        },
         nullptr, // onCaptureSequenceCompleted
         nullptr, // onCaptureSequenceAborted
         nullptr, // onCaptureBufferLost
diff --git a/drm/libdrmframework/Android.bp b/drm/libdrmframework/Android.bp
index 43ba72b..940c17d 100644
--- a/drm/libdrmframework/Android.bp
+++ b/drm/libdrmframework/Android.bp
@@ -39,4 +39,3 @@
     cflags: ["-Werror"],
 }
 
-subdirs = ["plugins/*"]
diff --git a/drm/libdrmframework/plugins/common/Android.bp b/drm/libdrmframework/plugins/common/Android.bp
deleted file mode 100644
index 213e57f..0000000
--- a/drm/libdrmframework/plugins/common/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["util"]
diff --git a/drm/libdrmframework/plugins/forward-lock/Android.bp b/drm/libdrmframework/plugins/forward-lock/Android.bp
deleted file mode 100644
index f884c14..0000000
--- a/drm/libdrmframework/plugins/forward-lock/Android.bp
+++ /dev/null
@@ -1,4 +0,0 @@
-subdirs = [
-    "FwdLockEngine",
-    "internal-format",
-]
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/Android.bp b/drm/libdrmframework/plugins/forward-lock/internal-format/Android.bp
deleted file mode 100644
index 9f58e26..0000000
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/Android.bp
+++ /dev/null
@@ -1,5 +0,0 @@
-subdirs = [
-    "common",
-    "converter",
-    "decoder",
-]
diff --git a/drm/mediadrm/Android.bp b/drm/mediadrm/Android.bp
deleted file mode 100644
index b9f07f1..0000000
--- a/drm/mediadrm/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["plugins/*"]
diff --git a/drm/mediadrm/plugins/clearkey/default/Android.bp b/drm/mediadrm/plugins/clearkey/default/Android.bp
index 7ba5708..9803d32 100644
--- a/drm/mediadrm/plugins/clearkey/default/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/default/Android.bp
@@ -61,7 +61,3 @@
     },
 }
 
-//########################################################################
-// Build unit tests
-
-subdirs = ["tests"]
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
index 137e775..71eb1ac 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.cpp
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -153,7 +153,7 @@
       mSentCodecSpecificData(false),
       mInputTimeSet(false),
       mInputSize(0),
-      mInputTimeUs(-1ll),
+      mInputTimeUs(0),
       mSignalledError(false),
       mOutIndex(0u) {
 }
@@ -179,7 +179,7 @@
     mSentCodecSpecificData = false;
     mInputTimeSet = false;
     mInputSize = 0u;
-    mInputTimeUs = -1ll;
+    mInputTimeUs = 0;
     mSignalledError = false;
     return C2_OK;
 }
@@ -197,6 +197,7 @@
     mSentCodecSpecificData = false;
     mInputTimeSet = false;
     mInputSize = 0u;
+    mInputTimeUs = 0;
     return C2_OK;
 }
 
@@ -558,6 +559,7 @@
     mSentCodecSpecificData = false;
     mInputTimeSet = false;
     mInputSize = 0u;
+    mInputTimeUs = 0;
 
     // TODO: we don't have any pending work at this time to drain.
     return C2_OK;
diff --git a/media/extractors/Android.bp b/media/extractors/Android.bp
deleted file mode 100644
index e8176cf..0000000
--- a/media/extractors/Android.bp
+++ /dev/null
@@ -1,3 +0,0 @@
-subdirs = [
-    "*",
-]
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 5ff1c59..5a31c58 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <log/log.h>
 #include <utils/Log.h>
 
 #include "AC4Parser.h"
@@ -81,7 +82,7 @@
                 const Trex *trex,
                 off64_t firstMoofOffset,
                 const sp<ItemTable> &itemTable,
-                int32_t elstShiftStartTicks);
+                uint64_t elstShiftStartTicks);
     virtual status_t init();
 
     virtual media_status_t start();
@@ -147,7 +148,7 @@
 
     // Start offset from composition time to presentation time.
     // Support shift only for video tracks through mElstShiftStartTicks for now.
-    int32_t mElstShiftStartTicks;
+    uint64_t mElstShiftStartTicks;
 
     size_t parseNALSize(const uint8_t *data) const;
     status_t parseChunk(off64_t *offset);
@@ -397,7 +398,6 @@
     while (track) {
         Track *next = track->next;
 
-        AMediaFormat_delete(track->meta);
         delete track;
         track = next;
     }
@@ -672,7 +672,6 @@
 
             ALOGV("adding HEIF image track %u", imageIndex);
             Track *track = new Track;
-            track->next = NULL;
             if (mLastTrack != NULL) {
                 mLastTrack->next = track;
             } else {
@@ -682,10 +681,7 @@
 
             track->meta = meta;
             AMediaFormat_setInt32(track->meta, AMEDIAFORMAT_KEY_TRACK_ID, imageIndex);
-            track->includes_expensive_metadata = false;
-            track->skipTrack = false;
             track->timescale = 1000000;
-            track->elstShiftStartTicks = 0;
         }
     }
 
@@ -967,7 +963,6 @@
 
                 ALOGV("adding new track");
                 Track *track = new Track;
-                track->next = NULL;
                 if (mLastTrack) {
                     mLastTrack->next = track;
                 } else {
@@ -975,15 +970,9 @@
                 }
                 mLastTrack = track;
 
-                track->includes_expensive_metadata = false;
-                track->skipTrack = false;
-                track->timescale = 0;
                 track->meta = AMediaFormat_new();
                 AMediaFormat_setString(track->meta,
                         AMEDIAFORMAT_KEY_MIME, "application/octet-stream");
-                track->has_elst = false;
-                track->subsample_encryption = false;
-                track->elstShiftStartTicks = 0;
             }
 
             off64_t stop_offset = *offset + chunk_size;
@@ -1033,6 +1022,7 @@
                     mLastTrack->skipTrack = true;
                 }
 
+
                 if (mLastTrack->skipTrack) {
                     ALOGV("skipping this track...");
                     Track *cur = mFirstTrack;
@@ -1053,6 +1043,21 @@
 
                     return OK;
                 }
+
+                // place things we built elsewhere into their final locations
+
+                // put aggregated tx3g data into the metadata
+                if (mLastTrack->mTx3gFilled > 0) {
+                    ALOGV("Putting %zu bytes of tx3g data into meta data",
+                          mLastTrack->mTx3gFilled);
+                    AMediaFormat_setBuffer(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA,
+                        mLastTrack->mTx3gBuffer, mLastTrack->mTx3gFilled);
+                    // drop it now to reduce our footprint
+                    free(mLastTrack->mTx3gBuffer);
+                    mLastTrack->mTx3gBuffer = NULL;
+                }
+
             } else if (chunk_type == FOURCC("moov")) {
                 mInitCheck = OK;
 
@@ -2553,41 +2558,55 @@
             if (mLastTrack == NULL)
                 return ERROR_MALFORMED;
 
-            void *data;
-            size_t size = 0;
-            if (!AMediaFormat_getBuffer(mLastTrack->meta,
-                    AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA, &data, &size)) {
-                size = 0;
-            }
-
-            if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) {
+            // complain about ridiculous chunks
+            if (chunk_size > kMaxAtomSize) {
                 return ERROR_MALFORMED;
             }
 
-            uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size];
-            if (buffer == NULL) {
+            // complain about empty atoms
+            if (chunk_data_size <= 0) {
+                ALOGE("b/124330204");
+                android_errorWriteLog(0x534e4554, "124330204");
                 return ERROR_MALFORMED;
             }
 
-            if (size > 0) {
-                memcpy(buffer, data, size);
+            // should fill buffer based on "data_offset" and "chunk_data_size"
+            // instead of *offset and chunk_size;
+            // but we've been feeding the extra data to consumers for multiple releases and
+            // if those apps are compensating for it, we'd break them with such a change
+            //
+
+            if (mLastTrack->mTx3gSize - mLastTrack->mTx3gFilled < chunk_size) {
+                size_t growth = kTx3gGrowth;
+                if (growth < chunk_size) {
+                    growth = chunk_size;
+                }
+                // although this disallows 2 tx3g atoms of nearly kMaxAtomSize...
+                if ((uint64_t) mLastTrack->mTx3gSize + growth > kMaxAtomSize) {
+                    ALOGE("b/124330204 - too much space");
+                    android_errorWriteLog(0x534e4554, "124330204");
+                    return ERROR_MALFORMED;
+                }
+                uint8_t *updated = (uint8_t *)realloc(mLastTrack->mTx3gBuffer,
+                                                mLastTrack->mTx3gSize + growth);
+                if (updated == NULL) {
+                    return ERROR_MALFORMED;
+                }
+                mLastTrack->mTx3gBuffer = updated;
+                mLastTrack->mTx3gSize += growth;
             }
 
-            if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
+            if ((size_t)(mDataSource->readAt(*offset,
+                                             mLastTrack->mTx3gBuffer + mLastTrack->mTx3gFilled,
+                                             chunk_size))
                     < chunk_size) {
-                delete[] buffer;
-                buffer = NULL;
 
                 // advance read pointer so we don't end up reading this again
                 *offset += chunk_size;
                 return ERROR_IO;
             }
 
-            AMediaFormat_setBuffer(mLastTrack->meta,
-                    AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA, buffer, size + chunk_size);
-
-            delete[] buffer;
-
+            mLastTrack->mTx3gFilled += chunk_size;
             *offset += chunk_size;
             break;
         }
@@ -4040,7 +4059,7 @@
 
     if (track->has_elst and !strncasecmp("video/", mime, 6) and track->elst_media_time > 0) {
         track->elstShiftStartTicks = track->elst_media_time;
-        ALOGV("video track->elstShiftStartTicks :%" PRId64, track->elst_media_time);
+        ALOGV("video track->elstShiftStartTicks :%" PRIu64, track->elstShiftStartTicks);
     }
 
     MPEG4Source *source =  new MPEG4Source(
@@ -4450,7 +4469,7 @@
         const Trex *trex,
         off64_t firstMoofOffset,
         const sp<ItemTable> &itemTable,
-        int32_t elstShiftStartTicks)
+        uint64_t elstShiftStartTicks)
     : mFormat(format),
       mDataSource(dataSource),
       mTimescale(timeScale),
@@ -4576,7 +4595,7 @@
             // Start offset should be less or equal to composition time of first sample.
             // ISO : sample_composition_time_offset, version 0 (unsigned) for major brands.
             mElstShiftStartTicks = std::min(mElstShiftStartTicks,
-                (*mCurrentSamples.begin()).compositionOffset);
+                                            (uint64_t)(*mCurrentSamples.begin()).compositionOffset);
         }
         return err;
     }
@@ -4586,7 +4605,7 @@
         err = mSampleTable->getMetaDataForSample(0, NULL, NULL, &firstSampleCTS);
         // Start offset should be less or equal to composition time of first sample.
         // Composition time stamp of first sample cannot be negative.
-        mElstShiftStartTicks = std::min(mElstShiftStartTicks, (int32_t)firstSampleCTS);
+        mElstShiftStartTicks = std::min(mElstShiftStartTicks, firstSampleCTS);
     }
 
     return err;
@@ -5239,8 +5258,30 @@
         sampleCtsOffset = 0;
     }
 
-    if (size < (off64_t)sampleCount * bytesPerSample) {
-        return -EINVAL;
+    if (bytesPerSample != 0) {
+        if (size < (off64_t)sampleCount * bytesPerSample) {
+            return -EINVAL;
+        }
+    } else {
+        if (sampleDuration == 0) {
+            ALOGW("b/123389881 sampleDuration == 0");
+            android_errorWriteLog(0x534e4554, "124389881 zero");
+            return -EINVAL;
+        }
+
+        // apply some sanity (vs strict legality) checks
+        //
+        // clamp the count of entries in the trun box, to avoid spending forever parsing
+        // this box. Clamping (vs error) lets us play *something*.
+        // 1 million is about 400 msecs on a Pixel3, should be no more than a couple seconds
+        // on the slowest devices.
+        static constexpr uint32_t kMaxTrunSampleCount = 1000000;
+        if (sampleCount > kMaxTrunSampleCount) {
+            ALOGW("b/123389881 clamp sampleCount(%u) @ kMaxTrunSampleCount(%u)",
+                  sampleCount, kMaxTrunSampleCount);
+            android_errorWriteLog(0x534e4554, "124389881 count");
+
+        }
     }
 
     Sample tmp;
@@ -5496,7 +5537,11 @@
             err = mSampleTable->getMetaDataForSample(
                     mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts);
             if(err == OK) {
-                cts -= mElstShiftStartTicks;
+                /* Composition Time Stamp cannot be negative. Some files have video Sample
+                * Time(STTS)delta with zero value(b/117402420).  Hence subtract only
+                * min(cts, mElstShiftStartTicks), so that audio tracks can be played.
+                */
+                cts -= std::min(cts, mElstShiftStartTicks);
             }
 
         } else {
@@ -5780,8 +5825,8 @@
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
 
         seekTimeUs += ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
-        ALOGV("shifted seekTimeUs :%" PRId64 ", mElstShiftStartTicks:%" PRId32, seekTimeUs,
-                mElstShiftStartTicks);
+        ALOGV("shifted seekTimeUs :%" PRId64 ", mElstShiftStartTicks:%" PRIu64, seekTimeUs,
+              mElstShiftStartTicks);
 
         int numSidxEntries = mSegments.size();
         if (numSidxEntries != 0) {
@@ -5837,7 +5882,7 @@
 
     off64_t offset = 0;
     size_t size = 0;
-    uint32_t cts = 0;
+    uint64_t cts = 0;
     bool isSyncSample = false;
     bool newBuffer = false;
     if (mBuffer == NULL || mCurrentSampleIndex >= mCurrentSamples.size()) {
@@ -5869,7 +5914,11 @@
         offset = smpl->offset;
         size = smpl->size;
         cts = mCurrentTime + smpl->compositionOffset;
-        cts -= mElstShiftStartTicks;
+        /* Composition Time Stamp cannot be negative. Some files have video Sample
+        * Time(STTS)delta with zero value(b/117402420).  Hence subtract only
+        * min(cts, mElstShiftStartTicks), so that audio tracks can be played.
+        */
+        cts -= std::min(cts, mElstShiftStartTicks);
 
         mCurrentTime += smpl->duration;
         isSyncSample = (mCurrentSampleIndex == 0);
diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h
index fadfb50..031e793 100644
--- a/media/extractors/mp4/MPEG4Extractor.h
+++ b/media/extractors/mp4/MPEG4Extractor.h
@@ -83,12 +83,47 @@
         bool includes_expensive_metadata;
         bool skipTrack;
         bool has_elst;
+        /* signed int, ISO Spec allows media_time = -1 for other use cases.
+         * but we don't support empty edits for now.
+         */
         int64_t elst_media_time;
         uint64_t elst_segment_duration;
-        int32_t elstShiftStartTicks;
+        // unsigned int, shift start offset only when media_time > 0.
+        uint64_t elstShiftStartTicks;
         bool subsample_encryption;
+
+        uint8_t *mTx3gBuffer;
+        size_t mTx3gSize, mTx3gFilled;
+
+
+        Track() {
+            next = NULL;
+            meta = NULL;
+            timescale = 0;
+            includes_expensive_metadata = false;
+            skipTrack = false;
+            has_elst = false;
+            elst_media_time = 0;
+            elstShiftStartTicks = 0;
+            subsample_encryption = false;
+            mTx3gBuffer = NULL;
+            mTx3gSize = mTx3gFilled = 0;
+        }
+        ~Track() {
+            if (meta) {
+                AMediaFormat_delete(meta);
+                meta = NULL;
+            }
+            free (mTx3gBuffer);
+            mTx3gBuffer = NULL;
+        }
+
+      private:
+        DISALLOW_EVIL_CONSTRUCTORS(Track);
     };
 
+    static const int kTx3gGrowth = 16 * 1024;
+
     Vector<SidxEntry> mSidxEntries;
     off64_t mMoofOffset;
     bool mMoofFound;
diff --git a/media/libaaudio/Android.bp b/media/libaaudio/Android.bp
index 4857008..16958f9 100644
--- a/media/libaaudio/Android.bp
+++ b/media/libaaudio/Android.bp
@@ -35,4 +35,3 @@
     version_script: "libaaudio.map.txt",
 }
 
-subdirs = ["*"]
diff --git a/media/libaaudio/examples/Android.bp b/media/libaaudio/examples/Android.bp
index 639fab2..49bd5ee 100644
--- a/media/libaaudio/examples/Android.bp
+++ b/media/libaaudio/examples/Android.bp
@@ -1,5 +1,3 @@
-subdirs = ["*"]
-
 cc_library_headers {
     name: "libaaudio_example_utils",
     export_include_dirs: ["utils"],
diff --git a/media/libaaudio/tests/Android.bp b/media/libaaudio/tests/Android.bp
index cb243a0..958bb2e 100644
--- a/media/libaaudio/tests/Android.bp
+++ b/media/libaaudio/tests/Android.bp
@@ -196,3 +196,10 @@
         "libutils",
     ],
 }
+
+cc_test {
+    name: "test_full_queue",
+    defaults: ["libaaudio_tests_defaults"],
+    srcs: ["test_full_queue.cpp"],
+    shared_libs: ["libaaudio"],
+}
diff --git a/media/libaaudio/tests/test_full_queue.cpp b/media/libaaudio/tests/test_full_queue.cpp
new file mode 100644
index 0000000..12d4fa3
--- /dev/null
+++ b/media/libaaudio/tests/test_full_queue.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// Test whether a stream dies if it is written to after a delay.
+// Maybe because the message queue from the AAudio service fills up.
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <aaudio/AAudio.h>
+#include <gtest/gtest.h>
+
+constexpr int64_t kNanosPerSecond = 1000000000;
+constexpr int64_t kTimeoutNanos = kNanosPerSecond / 2;
+constexpr int kNumFrames = 256;
+constexpr int kChannelCount = 2;
+
+static void checkFullQueue(aaudio_performance_mode_t perfMode,
+                           int32_t sleepMillis) {
+    std::unique_ptr<float[]> buffer = std::make_unique<float[]>(
+            kNumFrames * kChannelCount);
+
+    AAudioStreamBuilder *aaudioBuilder = nullptr;
+
+    // Use an AAudioStreamBuilder to contain requested parameters.
+    ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
+
+    AAudioStreamBuilder_setChannelCount(aaudioBuilder, kChannelCount);
+
+    // Request stream properties.
+    AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
+
+    // Create an AAudioStream using the Builder.
+    AAudioStream *aaudioStream = nullptr;
+    ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder,
+            &aaudioStream));
+    AAudioStreamBuilder_delete(aaudioBuilder);
+
+    EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
+
+    // Sleep for awhile. This might kill the stream.
+    usleep(sleepMillis * 1000); // 1000 millis in a microsecond
+
+    for (int i = 0; i < 10; i++) {
+        const aaudio_result_t result = AAudioStream_write(aaudioStream,
+                buffer.get(),
+                kNumFrames,
+                kTimeoutNanos);
+        EXPECT_EQ(kNumFrames, result);
+        if (kNumFrames != result) break;
+    }
+
+    EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
+
+    EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
+}
+
+TEST(test_full_queue, aaudio_full_queue_perf_none_50) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 50 /* sleepMillis */);
+}
+
+TEST(test_full_queue, aaudio_full_queue_perf_none_200) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 200 /* sleepMillis */);
+}
+
+TEST(test_full_queue, aaudio_full_queue_perf_none_1000) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_NONE, 1000 /* sleepMillis */);
+}
+
+TEST(test_full_queue, aaudio_full_queue_low_latency_50) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 50 /* sleepMillis */);
+}
+
+TEST(test_full_queue, aaudio_full_queue_low_latency_200) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 200 /* sleepMillis */);
+}
+
+TEST(test_full_queue, aaudio_full_queue_low_latency_1000) {
+    checkFullQueue(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 1000 /* sleepMillis */);
+}
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 6c8e6a4..c08dddb 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -49,7 +49,7 @@
 
     // Instrument audio signal power logging.
     // Note: This assumes channel mask, format, and sample rate do not change after creation.
-    if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
+    if (mStream != nullptr /* && mStreamPowerLog.isUserDebugOrEngBuild() */) {
         // Obtain audio properties (see StreamHalHidl::getAudioProperties() below).
         Return<void> ret = mStream->getAudioProperties(
                 [&](auto sr, auto m, auto f) {
diff --git a/media/libaudiohal/impl/StreamHalLocal.cpp b/media/libaudiohal/impl/StreamHalLocal.cpp
index 7d5ce05..4818fd8 100644
--- a/media/libaudiohal/impl/StreamHalLocal.cpp
+++ b/media/libaudiohal/impl/StreamHalLocal.cpp
@@ -33,7 +33,7 @@
           mStream(stream) {
     // Instrument audio signal power logging.
     // Note: This assumes channel mask, format, and sample rate do not change after creation.
-    if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
+    if (mStream != nullptr /* && mStreamPowerLog.isUserDebugOrEngBuild() */) {
         mStreamPowerLog.init(mStream->get_sample_rate(mStream),
                 mStream->get_channels(mStream),
                 mStream->get_format(mStream));
diff --git a/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp b/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
index 0b883f1..c03c6ed 100644
--- a/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
+++ b/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
@@ -25,6 +25,7 @@
 #include <new>
 
 #include <log/log.h>
+#include <sys/param.h>
 
 #include <audio_effects/effect_dynamicsprocessing.h>
 #include <dsp/DPBase.h>
@@ -225,10 +226,6 @@
     } //switch
 }
 
-static inline bool isPowerOf2(unsigned long n) {
-    return (n & (n - 1)) == 0;
-}
-
 void DP_configureVariant(DynamicsProcessingContext *pContext, int newVariant) {
     ALOGV("DP_configureVariant %d", newVariant);
     switch(newVariant) {
@@ -242,7 +239,7 @@
                 desiredBlock);
         if (desiredBlock < minBlockSize) {
             currentBlock = minBlockSize;
-        } else if (!isPowerOf2(desiredBlock)) {
+        } else if (!powerof2(desiredBlock)) {
             //find next highest power of 2.
             currentBlock = 1 << (32 - __builtin_clz(desiredBlock));
         }
@@ -1297,4 +1294,3 @@
 };
 
 }; // extern "C"
-
diff --git a/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp b/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp
index d06fd70..1f53978 100644
--- a/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp
+++ b/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp
@@ -20,6 +20,7 @@
 #include <log/log.h>
 #include "DPFrequency.h"
 #include <algorithm>
+#include <sys/param.h>
 
 namespace dp_fx {
 
@@ -30,10 +31,6 @@
 #define CIRCULAR_BUFFER_UPSAMPLE 4  //4 times buffer size
 
 static constexpr float MIN_ENVELOPE = 1e-6f; //-120 dB
-//helper functionS
-static inline bool isPowerOf2(unsigned long n) {
-    return (n & (n - 1)) == 0;
-}
 static constexpr float EPSILON = 0.0000001f;
 
 static inline bool isZero(float f) {
@@ -151,7 +148,7 @@
     } else if (mBlockSize < MIN_BLOCKSIZE) {
         mBlockSize = MIN_BLOCKSIZE;
     } else {
-        if (!isPowerOf2(blockSize)) {
+        if (!powerof2(blockSize)) {
             //find next highest power of 2.
             mBlockSize = 1 << (32 - __builtin_clz(blockSize));
         }
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
index 1d95342..1b27cb4 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
@@ -793,6 +793,15 @@
         {
             EQNB_Params.SourceFormat = LVEQNB_STEREO;
         }
+#ifdef SUPPORT_MC
+        /* Note: Currently SourceFormat field of EQNB is not been
+         *       used by the module.
+         */
+        else if (LocalParams.SourceFormat == LVM_MULTICHANNEL)
+        {
+            EQNB_Params.SourceFormat = LVEQNB_MULTICHANNEL;
+        }
+#endif
         else
         {
             EQNB_Params.SourceFormat = LVEQNB_MONOINSTEREO;     /* Force to Mono-in-Stereo mode */
@@ -862,7 +871,16 @@
             CS_Params.SpeakerType  = LVCS_HEADPHONES;
         }
 
+#ifdef SUPPORT_MC
+        /* Concert sound module processes only the left and right channels
+         * data. So the Source Format is set to LVCS_STEREO for multichannel
+         * input also.
+         */
+        if (LocalParams.SourceFormat == LVM_STEREO ||
+            LocalParams.SourceFormat == LVM_MULTICHANNEL)
+#else
         if (LocalParams.SourceFormat == LVM_STEREO)    /* Mono format not supported */
+#endif
         {
             CS_Params.SourceFormat = LVCS_STEREO;
         }
diff --git a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
index 385dbcf..804f1bf 100644
--- a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
+++ b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
@@ -184,6 +184,9 @@
 {
     LVEQNB_STEREO       = 0,
     LVEQNB_MONOINSTEREO = 1,
+#ifdef SUPPORT_MC
+    LVEQNB_MULTICHANNEL = 2,
+#endif
     LVEQNB_SOURCE_MAX   = LVM_MAXINT_32
 } LVEQNB_SourceFormat_en;
 
diff --git a/media/libmedia/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp
index 4dece96..50826c5 100644
--- a/media/libmedia/IMediaSource.cpp
+++ b/media/libmedia/IMediaSource.cpp
@@ -368,13 +368,13 @@
                         ALOGV("Use shared memory: %zu", length);
                         transferBuf = buf;
                     } else {
-                        ALOGD("Large buffer %zu without IMemory!", length);
+                        ALOGV("Large buffer %zu without IMemory!", length);
                         ret = mGroup->acquire_buffer(
                                 (MediaBufferBase **)&transferBuf, false /* nonBlocking */, length);
                         if (ret != OK
                                 || transferBuf == nullptr
                                 || transferBuf->mMemory == nullptr) {
-                            ALOGW("Failed to acquire shared memory, size %zu, ret %d",
+                            ALOGV("Failed to acquire shared memory, size %zu, ret %d",
                                     length, ret);
                             if (transferBuf != nullptr) {
                                 transferBuf->release();
diff --git a/media/libmedia/include/media/IMediaSource.h b/media/libmedia/include/media/IMediaSource.h
index 5ab6e37..381df24 100644
--- a/media/libmedia/include/media/IMediaSource.h
+++ b/media/libmedia/include/media/IMediaSource.h
@@ -124,7 +124,8 @@
         return false;
     }
 
-    static const size_t kBinderMediaBuffers = 4; // buffers managed by BnMediaSource
+    // align buffer count with video request size in NuMediaExtractor::selectTrack()
+    static const size_t kBinderMediaBuffers = 8; // buffers managed by BnMediaSource
     static const size_t kTransferSharedAsSharedThreshold = 4 * 1024;  // if >= shared, else inline
     static const size_t kTransferInlineAsSharedThreshold = 8 * 1024; // if >= shared, else inline
     static const size_t kInlineMaxTransfer = 64 * 1024; // Binder size limited to BINDER_VM_SIZE.
diff --git a/media/libmedia/xsd/vts/Android.bp b/media/libmedia/xsd/vts/Android.bp
new file mode 100644
index 0000000..b590a12
--- /dev/null
+++ b/media/libmedia/xsd/vts/Android.bp
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "vts_mediaProfiles_validate_test",
+    srcs: [
+        "ValidateMediaProfiles.cpp"
+    ],
+    static_libs: [
+        "android.hardware.audio.common.test.utility",
+        "libxml2",
+    ],
+    shared_libs: [
+        "liblog",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/media/libmedia/xsd/vts/Android.mk b/media/libmedia/xsd/vts/Android.mk
new file mode 100644
index 0000000..52c3779
--- /dev/null
+++ b/media/libmedia/xsd/vts/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2019 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsValidateMediaProfiles
+include test/vts/tools/build/Android.host_config.mk
diff --git a/media/libmedia/xsd/vts/AndroidTest.xml b/media/libmedia/xsd/vts/AndroidTest.xml
new file mode 100644
index 0000000..e68721b
--- /dev/null
+++ b/media/libmedia/xsd/vts/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS VtsValidateMediaProfiles.">
+    <option name="config-descriptor:metadata" key="plan" value="vts-treble" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="abort-on-push-failure" value="false"/>
+        <option name="push-group" value="HostDrivenTest.push"/>
+        <option name="push" value="DATA/etc/media_profiles.xsd->/data/local/tmp/media_profiles.xsd"/>
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-module-name" value="VtsValidateMediaProfiles"/>
+        <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_mediaProfiles_validate_test/vts_mediaProfiles_validate_test" />
+        <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_mediaProfiles_validate_test/vts_mediaProfiles_validate_test" />
+        <option name="binary-test-type" value="gtest"/>
+        <option name="test-timeout" value="30s"/>
+    </test>
+</configuration>
diff --git a/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp b/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
new file mode 100644
index 0000000..ff9b060
--- /dev/null
+++ b/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "utility/ValidateXml.h"
+
+TEST(CheckConfig, mediaProfilesValidation) {
+    RecordProperty("description",
+                   "Verify that the media profiles file "
+                   "is valid according to the schema");
+
+    const char* location = "/vendor/etc";
+
+    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS("media_profiles_V1_0.xml", {location},
+                                            "/data/local/tmp/media_profiles.xsd");
+}
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index 46a1c24..0776172 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -11,6 +11,7 @@
     ],
 
     shared_libs: [
+        "android.hardware.media.c2@1.0",
         "android.hardware.media.omx@1.0",
         "libbase",
         "libaudioclient",
@@ -21,7 +22,6 @@
         "libdl",
         "libgui",
         "libhidlbase",
-        "libhidlmemory",
         "liblog",
         "libmedia",
         "libmedia_omx",
@@ -70,5 +70,3 @@
 
 }
 
-subdirs = ["*"]
-
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index da95817..5061024 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -34,6 +34,8 @@
 
 #include <utils/misc.h>
 
+#include <android/hardware/media/omx/1.0/IOmxStore.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <binder/MemoryHeapBase.h>
@@ -650,17 +652,17 @@
         const sp<MediaPlayerBase>& listener,
         int which) {
     mService = service;
-    mOmx = nullptr;
+    mHService = nullptr;
     mListener = listener;
     mWhich = which;
 }
 
 MediaPlayerService::Client::ServiceDeathNotifier::ServiceDeathNotifier(
-        const sp<IOmx>& omx,
+        const sp<android::hidl::base::V1_0::IBase>& hService,
         const sp<MediaPlayerBase>& listener,
         int which) {
     mService = nullptr;
-    mOmx = omx;
+    mHService = hService;
     mListener = listener;
     mWhich = which;
 }
@@ -692,9 +694,9 @@
     if (mService != nullptr) {
         mService->unlinkToDeath(this);
         mService = nullptr;
-    } else if (mOmx != nullptr) {
-        mOmx->unlinkToDeath(this);
-        mOmx = nullptr;
+    } else if (mHService != nullptr) {
+        mHService->unlinkToDeath(this);
+        mHService = nullptr;
     }
 }
 
@@ -714,10 +716,12 @@
         mExtractorDeathListener->unlinkToDeath();
         mExtractorDeathListener = nullptr;
     }
-    if (mCodecDeathListener != nullptr) {
-        mCodecDeathListener->unlinkToDeath();
-        mCodecDeathListener = nullptr;
+    for (const sp<ServiceDeathNotifier>& codecDeathListener : mCodecDeathListeners) {
+        if (codecDeathListener != nullptr) {
+            codecDeathListener->unlinkToDeath();
+        }
     }
+    mCodecDeathListeners.clear();
 }
 
 sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
@@ -741,20 +745,56 @@
             new ServiceDeathNotifier(binder, p, MEDIAEXTRACTOR_PROCESS_DEATH);
     binder->linkToDeath(extractorDeathListener);
 
-    sp<IOmx> omx = IOmx::getService();
-    if (omx == nullptr) {
-        ALOGE("IOmx service is not available");
-        return NULL;
+    std::vector<sp<ServiceDeathNotifier>> codecDeathListeners;
+    {
+        using ::android::hidl::base::V1_0::IBase;
+
+        // Listen to OMX's IOmxStore/default
+        {
+            sp<IBase> store = ::android::hardware::media::omx::V1_0::
+                    IOmxStore::getService();
+            if (store == nullptr) {
+                ALOGD("OMX service is not available");
+            } else {
+                sp<ServiceDeathNotifier> codecDeathListener =
+                        new ServiceDeathNotifier(store, p, MEDIACODEC_PROCESS_DEATH);
+                store->linkToDeath(codecDeathListener, 0);
+                codecDeathListeners.emplace_back(codecDeathListener);
+            }
+        }
+
+        // Listen to Codec2's IComponentStore/software
+        // TODO: Listen to all Codec2 services.
+        {
+            sp<IBase> store = ::android::hardware::media::c2::V1_0::
+                    IComponentStore::getService();
+            if (store == nullptr) {
+                ALOGD("Codec2 system service is not available");
+            } else {
+                sp<ServiceDeathNotifier> codecDeathListener =
+                        new ServiceDeathNotifier(store, p, MEDIACODEC_PROCESS_DEATH);
+                store->linkToDeath(codecDeathListener, 0);
+                codecDeathListeners.emplace_back(codecDeathListener);
+            }
+
+            store = ::android::hardware::media::c2::V1_0::
+                    IComponentStore::getService("software");
+            if (store == nullptr) {
+                ALOGD("Codec2 swcodec service is not available");
+            } else {
+                sp<ServiceDeathNotifier> codecDeathListener =
+                        new ServiceDeathNotifier(store, p, MEDIACODEC_PROCESS_DEATH);
+                store->linkToDeath(codecDeathListener, 0);
+                codecDeathListeners.emplace_back(codecDeathListener);
+            }
+        }
     }
-    sp<ServiceDeathNotifier> codecDeathListener =
-            new ServiceDeathNotifier(omx, p, MEDIACODEC_PROCESS_DEATH);
-    omx->linkToDeath(codecDeathListener, 0);
 
     Mutex::Autolock lock(mLock);
 
     clearDeathNotifiers_l();
     mExtractorDeathListener = extractorDeathListener;
-    mCodecDeathListener = codecDeathListener;
+    mCodecDeathListeners.swap(codecDeathListeners);
     mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p);
 
     if (!p->hardwareOutput()) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index bfb7cc2..26bfa71 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -30,7 +30,7 @@
 #include <media/Metadata.h>
 #include <media/stagefright/foundation/ABase.h>
 
-#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <hidl/HidlSupport.h>
 
 #include <system/audio.h>
 
@@ -42,7 +42,6 @@
 class IDataSource;
 class IMediaRecorder;
 class IMediaMetadataRetriever;
-class IOMX;
 class IRemoteDisplay;
 class IRemoteDisplayClient;
 class MediaRecorderClient;
@@ -70,7 +69,6 @@
 class MediaPlayerService : public BnMediaPlayerService
 {
     class Client;
-    typedef ::android::hardware::media::omx::V1_0::IOmx IOmx;
 
     class AudioOutput : public MediaPlayerBase::AudioSink
     {
@@ -400,7 +398,7 @@
                     const sp<MediaPlayerBase>& listener,
                     int which);
             ServiceDeathNotifier(
-                    const sp<IOmx>& omx,
+                    const sp<android::hidl::base::V1_0::IBase>& hService,
                     const sp<MediaPlayerBase>& listener,
                     int which);
             virtual ~ServiceDeathNotifier();
@@ -413,7 +411,7 @@
         private:
             int mWhich;
             sp<IBinder> mService;
-            sp<IOmx> mOmx;
+            sp<android::hidl::base::V1_0::IBase> mHService; // HIDL service
             wp<MediaPlayerBase> mListener;
         };
 
@@ -509,7 +507,7 @@
         media::Metadata::Filter mMetadataUpdated;  // protected by mLock
 
         sp<ServiceDeathNotifier> mExtractorDeathListener;
-        sp<ServiceDeathNotifier> mCodecDeathListener;
+        std::vector<sp<ServiceDeathNotifier>> mCodecDeathListeners;
         sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedListener;
 #if CALLBACK_ANTAGONIZER
                     Antagonizer*                  mAntagonizer;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
index 0156ad2..a2cc13e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
@@ -328,6 +328,11 @@
     const size_t *userData = (size_t *)mpegUserData->data();
 
     for (size_t i = 0; i < mpegUserData->size() / sizeof(size_t); ++i) {
+        if (accessUnit->size() < userData[i]) {
+            ALOGW("b/129068792, skip invalid offset for user data");
+            android_errorWriteLog(0x534e4554, "129068792");
+            continue;
+        }
         trackAdded |= parseMPEGUserDataUnit(
                 timeUs, accessUnit->data() + userData[i], accessUnit->size() - userData[i]);
     }
@@ -337,6 +342,12 @@
 
 // returns true if a new CC track is found
 bool NuPlayer::CCDecoder::parseMPEGUserDataUnit(int64_t timeUs, const uint8_t *data, size_t size) {
+    if (size < 9) {
+        ALOGW("b/129068792, MPEG user data size too small %zu", size);
+        android_errorWriteLog(0x534e4554, "129068792");
+        return false;
+    }
+
     ABitReader br(data + 4, 5);
 
     uint32_t user_identifier = br.getBits(32);
@@ -389,8 +400,14 @@
                 mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2);
                 br.skipBits(16);
             } else if (mDTVCCPacket->size() > 0 && cc_type == 2) {
-                memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2);
-                mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2);
+                if (mDTVCCPacket->capacity() - mDTVCCPacket->size() >= 2) {
+                    memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2);
+                    mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2);
+                } else {
+                    ALOGW("b/129068792, skip CC due to too much data(%zu, %zu)",
+                          mDTVCCPacket->capacity(), mDTVCCPacket->size());
+                    android_errorWriteLog(0x534e4554, "129068792");
+                }
                 br.skipBits(16);
             } else if (cc_type == 0 || cc_type == 1) {
                 uint8_t cc_data_1 = br.getBits(8) & 0x7f;
@@ -477,6 +494,11 @@
             size_t trackIndex = getTrackIndex(kTrackTypeCEA708, service_number, &trackAdded);
             if (mSelectedTrack == (ssize_t)trackIndex) {
                 sp<ABuffer> ccPacket = new ABuffer(block_size);
+                if (ccPacket->capacity() == 0) {
+                    ALOGW("b/129068792, no memory available, %zu", block_size);
+                    android_errorWriteLog(0x534e4554, "129068792");
+                    return false;
+                }
                 memcpy(ccPacket->data(), br.data(), block_size);
                 mCCMap.add(timeUs, ccPacket);
             }
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index da35889..b05718c 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -227,6 +227,7 @@
 
     export_shared_lib_headers: [
         "libgui",
+        "libhidlmemory",
         "libmedia",
         "android.hidl.allocator@1.0",
     ],
@@ -319,21 +320,3 @@
     },
 }
 
-subdirs = [
-    "codec2",
-    "codecs/*",
-    "colorconversion",
-    "filters",
-    "flac/dec",
-    "foundation",
-    "http",
-    "httplive",
-    "id3",
-    "mpeg2ts",
-    "omx",
-    "rtsp",
-    "tests",
-    "timedtext",
-    "webm",
-    "xmlparser",
-]
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index a713900..d78d729 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -431,19 +431,17 @@
 void AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) {
     const size_t bufferSize = buffer->range_length();
     const size_t frameSize = mRecord->frameSize();
-    const int64_t timestampUs =
-                mPrevSampleTimeUs +
-                    ((1000000LL * (bufferSize / frameSize)) +
-                        (mSampleRate >> 1)) / mSampleRate;
-
     if (mNumFramesReceived == 0) {
         buffer->meta_data().setInt64(kKeyAnchorTime, mStartTimeUs);
     }
-
+    mNumFramesReceived += bufferSize / frameSize;
+    const int64_t timestampUs =
+                mStartTimeUs +
+                    ((1000000LL * mNumFramesReceived) +
+                        (mSampleRate >> 1)) / mSampleRate;
     buffer->meta_data().setInt64(kKeyTime, mPrevSampleTimeUs);
     buffer->meta_data().setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
     mPrevSampleTimeUs = timestampUs;
-    mNumFramesReceived += bufferSize / frameSize;
     mBuffersReceived.push_back(buffer);
     mFrameAvailableCondition.signal();
 }
diff --git a/media/libstagefright/DataURISource.cpp b/media/libstagefright/DataURISource.cpp
index 3dc345f..b975b38 100644
--- a/media/libstagefright/DataURISource.cpp
+++ b/media/libstagefright/DataURISource.cpp
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #include <media/stagefright/DataURISource.h>
 
 #include <media/stagefright/foundation/ABuffer.h>
@@ -39,15 +38,27 @@
     AString tmp(&uri[5], commaPos - &uri[5]);
 
     if (tmp.endsWith(";base64")) {
-        AString encoded(commaPos + 1);
 
-        // Strip CR and LF...
-        for (size_t i = encoded.size(); i > 0;) {
-            i--;
-            if (encoded.c_str()[i] == '\r' || encoded.c_str()[i] == '\n') {
-                encoded.erase(i, 1);
+        // strip all CR and LF characters.
+        const char *src = commaPos+1;
+        int len = strlen(src) + 1;
+        char *cleansed = (char *) malloc(len);
+        if (cleansed == NULL) return NULL;
+        char *keeping = cleansed;
+        int left = len;
+        for (int i = 0; i < len ; i++)
+        {
+            const char c = *src++;
+            if (c == '\r' || c == '\n') {
+                continue;
             }
+            *keeping++ = c;
+            left--;
         }
+        memset(keeping, 0, left);
+
+        AString encoded(cleansed);
+        free(cleansed);
 
         buffer = decodeBase64(encoded);
 
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 1ec419a..2f13dc9 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -72,6 +72,7 @@
 static const int64_t kInitialDelayTimeUs     = 700000LL;
 static const int64_t kMaxMetadataSize = 0x4000000LL;   // 64MB max per-frame metadata size
 static const int64_t kMaxCttsOffsetTimeUs = 30 * 60 * 1000000LL;  // 30 minutes
+static const size_t kESDSScratchBufferSize = 10;  // kMaxAtomSize in Mpeg4Extractor 64MB
 
 static const char kMetaKey_Version[]    = "com.android.version";
 static const char kMetaKey_Manufacturer[]      = "com.android.manufacturer";
@@ -3882,22 +3883,52 @@
     mOwner->endBox();
 }
 
+static void generateEsdsSize(size_t dataLength, size_t* sizeGenerated, uint8_t* buffer) {
+    size_t offset = 0, cur = 0;
+    size_t more = 0x00;
+    *sizeGenerated = 0;
+    /* Start with the LSB(7 bits) of dataLength and build the byte sequence upto MSB.
+     * Continuation flag(most significant bit) will be set on the first N-1 bytes.
+     */
+    do {
+        buffer[cur++] = (dataLength & 0x7f) | more;
+        dataLength >>= 7;
+        more = 0x80;
+        ++(*sizeGenerated);
+    } while (dataLength > 0u);
+    --cur;
+    // Reverse the newly formed byte sequence.
+    while (cur > offset) {
+        uint8_t tmp = buffer[cur];
+        buffer[cur--] = buffer[offset];
+        buffer[offset++] = tmp;
+    }
+}
+
 void MPEG4Writer::Track::writeMp4aEsdsBox() {
-    mOwner->beginBox("esds");
     CHECK(mCodecSpecificData);
     CHECK_GT(mCodecSpecificDataSize, 0u);
 
-    // Make sure all sizes encode to a single byte.
-    CHECK_LT(mCodecSpecificDataSize + 23, 128u);
+    uint8_t sizeESDBuffer[kESDSScratchBufferSize];
+    uint8_t sizeDCDBuffer[kESDSScratchBufferSize];
+    uint8_t sizeDSIBuffer[kESDSScratchBufferSize];
+    size_t sizeESD = 0;
+    size_t sizeDCD = 0;
+    size_t sizeDSI = 0;
+    generateEsdsSize(mCodecSpecificDataSize, &sizeDSI, sizeDSIBuffer);
+    generateEsdsSize(mCodecSpecificDataSize + sizeDSI + 14, &sizeDCD, sizeDCDBuffer);
+    generateEsdsSize(mCodecSpecificDataSize + sizeDSI + sizeDCD + 21, &sizeESD, sizeESDBuffer);
+
+    mOwner->beginBox("esds");
 
     mOwner->writeInt32(0);     // version=0, flags=0
     mOwner->writeInt8(0x03);   // ES_DescrTag
-    mOwner->writeInt8(23 + mCodecSpecificDataSize);
+    mOwner->write(sizeESDBuffer, sizeESD);
     mOwner->writeInt16(0x0000);// ES_ID
     mOwner->writeInt8(0x00);
 
     mOwner->writeInt8(0x04);   // DecoderConfigDescrTag
-    mOwner->writeInt8(15 + mCodecSpecificDataSize);
+    mOwner->write(sizeDCDBuffer, sizeDCD);
     mOwner->writeInt8(0x40);   // objectTypeIndication ISO/IEC 14492-2
     mOwner->writeInt8(0x15);   // streamType AudioStream
 
@@ -3912,7 +3943,7 @@
     mOwner->writeInt32(avgBitrate);
 
     mOwner->writeInt8(0x05);   // DecoderSpecificInfoTag
-    mOwner->writeInt8(mCodecSpecificDataSize);
+    mOwner->write(sizeDSIBuffer, sizeDSI);
     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
 
     static const uint8_t kData2[] = {
@@ -3929,20 +3960,27 @@
     CHECK(mCodecSpecificData);
     CHECK_GT(mCodecSpecificDataSize, 0u);
 
-    // Make sure all sizes encode to a single byte.
-    CHECK_LT(23 + mCodecSpecificDataSize, 128u);
+    uint8_t sizeESDBuffer[kESDSScratchBufferSize];
+    uint8_t sizeDCDBuffer[kESDSScratchBufferSize];
+    uint8_t sizeDSIBuffer[kESDSScratchBufferSize];
+    size_t sizeESD = 0;
+    size_t sizeDCD = 0;
+    size_t sizeDSI = 0;
+    generateEsdsSize(mCodecSpecificDataSize, &sizeDSI, sizeDSIBuffer);
+    generateEsdsSize(mCodecSpecificDataSize + sizeDSI + 14, &sizeDCD, sizeDCDBuffer);
+    generateEsdsSize(mCodecSpecificDataSize + sizeDSI + sizeDCD + 21, &sizeESD, sizeESDBuffer);
 
     mOwner->beginBox("esds");
 
     mOwner->writeInt32(0);    // version=0, flags=0
 
     mOwner->writeInt8(0x03);  // ES_DescrTag
-    mOwner->writeInt8(23 + mCodecSpecificDataSize);
+    mOwner->write(sizeESDBuffer, sizeESD);
     mOwner->writeInt16(0x0000);  // ES_ID
     mOwner->writeInt8(0x1f);
 
     mOwner->writeInt8(0x04);  // DecoderConfigDescrTag
-    mOwner->writeInt8(15 + mCodecSpecificDataSize);
+    mOwner->write(sizeDCDBuffer, sizeDCD);
     mOwner->writeInt8(0x20);  // objectTypeIndication ISO/IEC 14492-2
     mOwner->writeInt8(0x11);  // streamType VisualStream
 
@@ -3960,7 +3998,7 @@
 
     mOwner->writeInt8(0x05);  // DecoderSpecificInfoTag
 
-    mOwner->writeInt8(mCodecSpecificDataSize);
+    mOwner->write(sizeDSIBuffer, sizeDSI);
     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
 
     static const uint8_t kData2[] = {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index d4e4000..b6b7784 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1052,8 +1052,9 @@
         }
 
         // Prevent possible integer overflow in downstream code.
-        if ((uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) {
-            ALOGE("buffer size is too big, width=%d, height=%d", mVideoWidth, mVideoHeight);
+        if (mVideoWidth < 0 || mVideoHeight < 0 ||
+               (uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) {
+            ALOGE("Invalid size(s), width=%d, height=%d", mVideoWidth, mVideoHeight);
             return BAD_VALUE;
         }
     }
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index c3d85ee..50e454c 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -831,7 +831,9 @@
 }
 
 void MediaCodecSource::onPause(int64_t pauseStartTimeUs) {
-    if ((mFlags & FLAG_USE_SURFACE_INPUT) && (mEncoder != NULL)) {
+    if (mStopping || mOutput.lock()->mEncoderReachedEOS) {
+        // Nothing to do
+    } else if ((mFlags & FLAG_USE_SURFACE_INPUT) && (mEncoder != NULL)) {
         sp<AMessage> params = new AMessage;
         params->setInt32(PARAMETER_KEY_SUSPEND, true);
         params->setInt64(PARAMETER_KEY_SUSPEND_TIME, pauseStartTimeUs);
diff --git a/media/libstagefright/codecs/amrnb/Android.bp b/media/libstagefright/codecs/amrnb/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/amrnb/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp b/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp
index 41a9e98..621fda8 100644
--- a/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp
@@ -67,6 +67,7 @@
     int bytesRead = fread(header, 1, kFileHeaderSize, fpInput);
     if (bytesRead != kFileHeaderSize || memcmp(header, "#!AMR\n", kFileHeaderSize)) {
         fprintf(stderr, "Invalid AMR-NB file\n");
+        fclose(fpInput);
         return 1;
     }
 
@@ -79,6 +80,7 @@
     SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo);
     if(!handle){
         fprintf(stderr, "Could not create %s\n", argv[2]);
+        fclose(fpInput);
         return 1;
     }
 
@@ -87,6 +89,8 @@
     int err = GSMInitDecode(&amrHandle, (Word8*)"AMRNBDecoder");
     if(err != 0){
         fprintf(stderr, "Error creating AMR-NB decoder instance\n");
+        fclose(fpInput);
+        sf_close(handle);
         return 1;
     }
 
diff --git a/media/libstagefright/codecs/amrwbenc/Android.bp b/media/libstagefright/codecs/amrwbenc/Android.bp
index 8327500..262962f 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/Android.bp
@@ -175,6 +175,3 @@
     compile_multilib: "32",
 }
 
-//###############################################################################
-
-subdirs = ["SampleCode"]
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
index 7c094f3..7282de4 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
@@ -134,14 +134,16 @@
 	if(handle == 0)
 	{
 		printf("open dll error......");
-		return -1;
+		ret = -1;
+		goto safe_exit;
 	}
 
 	pfunc = dlsym(handle, "voGetAMRWBEncAPI");
 	if(pfunc == 0)
 	{
 		printf("open function error......");
-		return -1;
+		ret = -1;
+		goto safe_exit;
 	}
 
 	pGetAPI = (VOGETAUDIOENCAPI)pfunc;
@@ -150,7 +152,8 @@
 	if(returnCode)
 	{
 		printf("get APIs error......");
-		return -1;
+		ret = -1;
+		goto safe_exit;
 	}
 #else
 	ret = voGetAMRWBEncAPI(&AudioAPI);
@@ -253,7 +256,8 @@
 		fclose(fdst);
 
 #ifdef LINUX
-	dlclose(handle);
+	if (handle)
+		dlclose(handle);
 #endif
 
 	return ret;
diff --git a/media/libstagefright/codecs/flac/Android.bp b/media/libstagefright/codecs/flac/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/flac/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/g711/Android.bp b/media/libstagefright/codecs/g711/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/g711/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/gsm/Android.bp b/media/libstagefright/codecs/gsm/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/gsm/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/m4v_h263/Android.bp b/media/libstagefright/codecs/m4v_h263/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/m4v_h263/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/on2/Android.bp b/media/libstagefright/codecs/on2/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/on2/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/opus/Android.bp b/media/libstagefright/codecs/opus/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/opus/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/codecs/vorbis/Android.bp b/media/libstagefright/codecs/vorbis/Android.bp
deleted file mode 100644
index b44c296..0000000
--- a/media/libstagefright/codecs/vorbis/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["*"]
diff --git a/media/libstagefright/data/media_codecs_google_audio.xml b/media/libstagefright/data/media_codecs_google_audio.xml
index 632088a..8899adc 100644
--- a/media/libstagefright/data/media_codecs_google_audio.xml
+++ b/media/libstagefright/data/media_codecs_google_audio.xml
@@ -58,7 +58,7 @@
         </MediaCodec>
         <MediaCodec name="OMX.google.raw.decoder" type="audio/raw">
             <Limit name="channel-count" max="8" />
-            <Limit name="sample-rate" ranges="8000-96000" />
+            <Limit name="sample-rate" ranges="8000-192000" />
             <Limit name="bitrate" range="1-10000000" />
         </MediaCodec>
         <MediaCodec name="OMX.google.flac.decoder" type="audio/flac">
diff --git a/media/libstagefright/data/media_codecs_google_c2_audio.xml b/media/libstagefright/data/media_codecs_google_c2_audio.xml
index 47a9715..be2404d 100644
--- a/media/libstagefright/data/media_codecs_google_c2_audio.xml
+++ b/media/libstagefright/data/media_codecs_google_c2_audio.xml
@@ -67,7 +67,7 @@
         <MediaCodec name="c2.android.raw.decoder" type="audio/raw">
             <Alias name="OMX.google.raw.decoder" />
             <Limit name="channel-count" max="8" />
-            <Limit name="sample-rate" ranges="8000-96000" />
+            <Limit name="sample-rate" ranges="8000-192000" />
             <Limit name="bitrate" range="1-10000000" />
         </MediaCodec>
         <MediaCodec name="c2.android.flac.decoder" type="audio/flac">
diff --git a/media/libstagefright/omx/Android.bp b/media/libstagefright/omx/Android.bp
index b959f6c..c06aca5 100644
--- a/media/libstagefright/omx/Android.bp
+++ b/media/libstagefright/omx/Android.bp
@@ -170,6 +170,3 @@
     cflags: ["-Wall", "-Werror"],
 }
 
-//###############################################################################
-
-subdirs = ["tests"]
diff --git a/media/libstagefright/xmlparser/vts/Android.bp b/media/libstagefright/xmlparser/vts/Android.bp
new file mode 100644
index 0000000..3f93e9e
--- /dev/null
+++ b/media/libstagefright/xmlparser/vts/Android.bp
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "vts_mediaCodecs_validate_test",
+    srcs: [
+        "ValidateMediaCodecs.cpp"
+    ],
+    static_libs: [
+        "android.hardware.audio.common.test.utility",
+        "libxml2",
+    ],
+    shared_libs: [
+        "liblog",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/media/libstagefright/xmlparser/vts/Android.mk b/media/libstagefright/xmlparser/vts/Android.mk
new file mode 100644
index 0000000..d5290ba
--- /dev/null
+++ b/media/libstagefright/xmlparser/vts/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2019 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsValidateMediaCodecs
+include test/vts/tools/build/Android.host_config.mk
diff --git a/media/libstagefright/xmlparser/vts/AndroidTest.xml b/media/libstagefright/xmlparser/vts/AndroidTest.xml
new file mode 100644
index 0000000..97ee107
--- /dev/null
+++ b/media/libstagefright/xmlparser/vts/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS VtsValidateMediaCodecs.">
+    <option name="config-descriptor:metadata" key="plan" value="vts-treble" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="abort-on-push-failure" value="false"/>
+        <option name="push-group" value="HostDrivenTest.push"/>
+        <option name="push" value="DATA/etc/media_codecs.xsd->/data/local/tmp/media_codecs.xsd"/>
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-module-name" value="VtsValidateMediaCodecs"/>
+        <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_mediaCodecs_validate_test/vts_mediaCodecs_validate_test" />
+        <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_mediaCodecs_validate_test/vts_mediaCodecs_validate_test" />
+        <option name="binary-test-type" value="gtest"/>
+        <option name="test-timeout" value="30s"/>
+    </test>
+</configuration>
diff --git a/media/libstagefright/xmlparser/vts/ValidateMediaCodecs.cpp b/media/libstagefright/xmlparser/vts/ValidateMediaCodecs.cpp
new file mode 100644
index 0000000..b07833e
--- /dev/null
+++ b/media/libstagefright/xmlparser/vts/ValidateMediaCodecs.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dirent.h>
+#include <regex>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string>
+
+#include "utility/ValidateXml.h"
+
+static void get_files_in_dirs(const char* dir_path, std::vector<std::string>& files) {
+    DIR* d;
+    struct dirent* de;
+
+    d = opendir(dir_path);
+    if (d == nullptr) {
+        return;
+    }
+
+    while ((de = readdir(d))) {
+        if (de->d_type != DT_REG) {
+            continue;
+        }
+        if (std::regex_match(de->d_name, std::regex("(media_codecs)(.*)(.xml)"))) {
+            files.push_back(de->d_name);
+        }
+    }
+    closedir(d);
+}
+
+TEST(CheckConfig, mediaCodecsValidation) {
+    RecordProperty("description",
+                   "Verify that the media codecs file "
+                   "is valid according to the schema");
+
+    const char* location = "/vendor/etc";
+
+    std::vector<std::string> files;
+    get_files_in_dirs(location, files);
+
+    for (std::string file_name : files) {
+        EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(file_name.c_str(), {location},
+                                                "/data/local/tmp/media_codecs.xsd");
+    }
+}
diff --git a/media/mtp/Android.bp b/media/mtp/Android.bp
index 2cf9b82..66a3139 100644
--- a/media/mtp/Android.bp
+++ b/media/mtp/Android.bp
@@ -54,6 +54,3 @@
     ],
 }
 
-subdirs = [
-    "tests",
-]
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index ec7ff57..96a8337 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -398,6 +398,13 @@
         if (!moduleDevices.contains(device)) {
             continue;
         }
+
+        // removal of remote submix devices associated with a dynamic policy is
+        // handled by removeOutputProfile() and removeInputProfile()
+        if (audio_is_remote_submix_device(device->type()) && device->address() != "0") {
+            continue;
+        }
+
         device->detach();
         // Only remove from dynamic list, not from declared list!!!
         if (!hwModule->getDynamicDevices().contains(device)) {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index ef99dea..bc0dafe 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -3782,10 +3782,12 @@
             hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR;
 
     int streamId = 0;
+    String16 physicalCameraId;
     if (msg.error_stream != NULL) {
         Camera3Stream *stream =
                 Camera3Stream::cast(msg.error_stream);
         streamId = stream->getId();
+        physicalCameraId = String16(stream->physicalCameraId());
     }
     ALOGV("Camera %s: %s: HAL error, frame %d, stream %d: %d",
             mId.string(), __FUNCTION__, msg.frame_number,
@@ -3807,13 +3809,29 @@
                     InFlightRequest &r = mInFlightMap.editValueAt(idx);
                     r.requestStatus = msg.error_code;
                     resultExtras = r.resultExtras;
-                    if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT == errorCode
+                    bool logicalDeviceResultError = false;
+                    if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT ==
+                            errorCode) {
+                        if (physicalCameraId.size() > 0) {
+                            String8 cameraId(physicalCameraId);
+                            if (r.physicalCameraIds.find(cameraId) == r.physicalCameraIds.end()) {
+                                ALOGE("%s: Reported result failure for physical camera device: %s "
+                                        " which is not part of the respective request!",
+                                        __FUNCTION__, cameraId.string());
+                                break;
+                            }
+                            resultExtras.errorPhysicalCameraId = physicalCameraId;
+                        } else {
+                            logicalDeviceResultError = true;
+                        }
+                    }
+
+                    if (logicalDeviceResultError
                             ||  hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST ==
                             errorCode) {
                         r.skipResultMetadata = true;
                     }
-                    if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT ==
-                            errorCode) {
+                    if (logicalDeviceResultError) {
                         // In case of missing result check whether the buffers
                         // returned. If they returned, then remove inflight
                         // request.
diff --git a/services/camera/libcameraservice/hidl/Convert.cpp b/services/camera/libcameraservice/hidl/Convert.cpp
index c2ed23a..866c3b5 100644
--- a/services/camera/libcameraservice/hidl/Convert.cpp
+++ b/services/camera/libcameraservice/hidl/Convert.cpp
@@ -157,6 +157,8 @@
     hCaptureResultExtras.frameNumber = captureResultExtras.frameNumber;
     hCaptureResultExtras.partialResultCount = captureResultExtras.partialResultCount;
     hCaptureResultExtras.errorStreamId = captureResultExtras.errorStreamId;
+    hCaptureResultExtras.errorPhysicalCameraId = hidl_string(String8(
+            captureResultExtras.errorPhysicalCameraId).string());
     return hCaptureResultExtras;
 }
 
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index b16b5dc..880a3d7 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -343,6 +343,20 @@
     return writeUpMessageQueue(&command);
 }
 
+bool AAudioServiceStreamBase::isUpMessageQueueBusy() {
+    std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
+    if (mUpMessageQueue == nullptr) {
+        ALOGE("%s(): mUpMessageQueue null! - stream not open", __func__);
+        return true;
+    }
+    int32_t framesAvailable = mUpMessageQueue->getFifoBuffer()
+        ->getFullFramesAvailable();
+    int32_t capacity = mUpMessageQueue->getFifoBuffer()
+        ->getBufferCapacityInFrames();
+    // Is it half full or more
+    return framesAvailable >= (capacity / 2);
+}
+
 aaudio_result_t AAudioServiceStreamBase::writeUpMessageQueue(AAudioServiceMessage *command) {
     std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
     if (mUpMessageQueue == nullptr) {
@@ -366,6 +380,13 @@
 
 aaudio_result_t AAudioServiceStreamBase::sendCurrentTimestamp() {
     AAudioServiceMessage command;
+    // It is not worth filling up the queue with timestamps.
+    // That can cause the stream to get suspended.
+    // So just drop the timestamp if the queue is getting full.
+    if (isUpMessageQueueBusy()) {
+        return AAUDIO_OK;
+    }
+
     // Send a timestamp for the clock model.
     aaudio_result_t result = getFreeRunningPosition(&command.timestamp.position,
                                                     &command.timestamp.timestamp);
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index ffc768b..097bc64 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -312,6 +312,12 @@
     android::wp<AAudioServiceEndpoint> mServiceEndpointWeak;
 
 private:
+
+    /**
+     * @return true if the queue is getting full.
+     */
+    bool isUpMessageQueueBusy();
+
     aaudio_handle_t         mHandle = -1;
     bool                    mFlowing = false;