Merge "Camera: clear buffer cache when stream is reconfigured"
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 97cf6bf..75075f1 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -30,3 +30,44 @@
     srcs: ["include/camera/**/*.h"],
     license: "NOTICE",
 }
+
+cc_library_shared {
+    name: "libcamera2ndk",
+    srcs: [
+        "NdkCameraManager.cpp",
+        "NdkCameraMetadata.cpp",
+        "NdkCameraDevice.cpp",
+        "NdkCaptureRequest.cpp",
+        "NdkCameraCaptureSession.cpp",
+        "impl/ACameraManager.cpp",
+        "impl/ACameraMetadata.cpp",
+        "impl/ACameraDevice.cpp",
+        "impl/ACameraCaptureSession.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "liblog",
+        "libgui",
+        "libutils",
+        "libandroid_runtime",
+        "libcamera_client",
+        "libstagefright_foundation",
+        "libcutils",
+        "libcamera_metadata",
+        "libmediandk",
+    ],
+    cflags: [
+        "-fvisibility=hidden",
+        "-DEXPORT=__attribute__ ((visibility (\"default\")))",
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    export_include_dirs: ["include"],
+    product_variables: {
+        pdk: {
+            enabled: false,
+        },
+    },
+    version_script: "libcamera2ndk.map.txt",
+}
diff --git a/camera/ndk/Android.mk b/camera/ndk/Android.mk
deleted file mode 100644
index 53addf1..0000000
--- a/camera/ndk/Android.mk
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# Copyright (C) 2015 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)
-
-ifneq ($(TARGET_BUILD_PDK), true)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=                  \
-    NdkCameraManager.cpp           \
-    NdkCameraMetadata.cpp          \
-    NdkCameraDevice.cpp            \
-    NdkCaptureRequest.cpp          \
-    NdkCameraCaptureSession.cpp    \
-    impl/ACameraManager.cpp        \
-    impl/ACameraMetadata.cpp       \
-    impl/ACameraDevice.cpp         \
-    impl/ACameraCaptureSession.cpp
-
-LOCAL_MODULE:= libcamera2ndk
-
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-LOCAL_CFLAGS += -fvisibility=hidden -D EXPORT='__attribute__ ((visibility ("default")))'
-LOCAL_CFLAGS += -Wall -Wextra -Werror
-
-LOCAL_LDFLAGS += -Wl,--version-script=$(LOCAL_PATH)/libcamera2ndk.map.txt
-
-LOCAL_SHARED_LIBRARIES := \
-    libbinder \
-    liblog \
-    libgui \
-    libutils \
-    libandroid_runtime \
-    libcamera_client \
-    libstagefright_foundation \
-    libcutils \
-    libcamera_metadata \
-    libmediandk
-
-include $(BUILD_SHARED_LIBRARY)
-
-endif
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index fc00a2d..9d341ae 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -32,6 +32,10 @@
     if (mType == ACM_CHARACTERISTICS) {
         filterUnsupportedFeatures();
         filterStreamConfigurations();
+        filterDurations(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
+        filterDurations(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
+        filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS);
+        filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
     }
     // TODO: filter request/result keys
 }
@@ -82,6 +86,72 @@
 
 
 void
+ACameraMetadata::filterDurations(uint32_t tag) {
+    const int STREAM_CONFIGURATION_SIZE = 4;
+    const int STREAM_FORMAT_OFFSET = 0;
+    const int STREAM_WIDTH_OFFSET = 1;
+    const int STREAM_HEIGHT_OFFSET = 2;
+    const int STREAM_DURATION_OFFSET = 3;
+    camera_metadata_entry entry = mData.find(tag);
+    if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT64) {
+        ALOGE("%s: malformed duration key %d! count %zu, type %d",
+                __FUNCTION__, tag, entry.count, entry.type);
+        return;
+    }
+    Vector<int64_t> filteredDurations;
+    filteredDurations.setCapacity(entry.count * 2);
+
+    for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
+        int64_t format = entry.data.i64[i + STREAM_FORMAT_OFFSET];
+        int64_t width = entry.data.i64[i + STREAM_WIDTH_OFFSET];
+        int64_t height = entry.data.i64[i + STREAM_HEIGHT_OFFSET];
+        int64_t duration = entry.data.i32[i + STREAM_DURATION_OFFSET];
+
+        // Leave the unfiltered format in so apps depending on previous wrong
+        // filter behavior continue to work
+        filteredDurations.push_back(format);
+        filteredDurations.push_back(width);
+        filteredDurations.push_back(height);
+        filteredDurations.push_back(duration);
+
+        // Translate HAL formats to NDK format
+        switch (tag) {
+            case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS:
+            case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS:
+                if (format == HAL_PIXEL_FORMAT_BLOB) {
+                    format = AIMAGE_FORMAT_JPEG;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                }
+                break;
+            case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS:
+            case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS:
+                if (format == HAL_PIXEL_FORMAT_BLOB) {
+                    format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                } else if (format == HAL_PIXEL_FORMAT_Y16) {
+                    format = AIMAGE_FORMAT_DEPTH16;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                }
+                break;
+            default:
+                // Should not reach here
+                ALOGE("%s: Unkown tag 0x%x", __FUNCTION__, tag);
+        }
+    }
+
+    mData.update(tag, filteredDurations);
+}
+
+void
 ACameraMetadata::filterStreamConfigurations() {
     const int STREAM_CONFIGURATION_SIZE = 4;
     const int STREAM_FORMAT_OFFSET = 0;
@@ -89,7 +159,7 @@
     const int STREAM_HEIGHT_OFFSET = 2;
     const int STREAM_IS_INPUT_OFFSET = 3;
     camera_metadata_entry entry = mData.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
-    if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT32) {
+    if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
         ALOGE("%s: malformed available stream configuration key! count %zu, type %d",
                 __FUNCTION__, entry.count, entry.type);
         return;
@@ -117,9 +187,17 @@
         filteredStreamConfigs.push_back(isInput);
     }
 
-    mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
+    if (filteredStreamConfigs.size() > 0) {
+        mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
+    }
 
     entry = mData.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
+    if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
+        ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d",
+                __FUNCTION__, entry.count, entry.type);
+        return;
+    }
+
     Vector<int32_t> filteredDepthStreamConfigs;
     filteredDepthStreamConfigs.setCapacity(entry.count);
 
@@ -144,7 +222,12 @@
         filteredDepthStreamConfigs.push_back(height);
         filteredDepthStreamConfigs.push_back(isInput);
     }
-    mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, filteredDepthStreamConfigs);
+
+    if (filteredDepthStreamConfigs.size() > 0) {
+        mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+                filteredDepthStreamConfigs);
+    }
+
 }
 
 bool
diff --git a/camera/ndk/impl/ACameraMetadata.h b/camera/ndk/impl/ACameraMetadata.h
index 0fd7efa..e76b80c 100644
--- a/camera/ndk/impl/ACameraMetadata.h
+++ b/camera/ndk/impl/ACameraMetadata.h
@@ -58,13 +58,16 @@
     camera_status_t getTags(/*out*/int32_t* numTags,
                             /*out*/const uint32_t** tags) const;
 
+    const CameraMetadata& getInternalData() const;
+
+  private:
+
     bool isNdkSupportedCapability(const int32_t capability);
     static inline bool isVendorTag(const uint32_t tag);
     static bool isCaptureRequestTag(const uint32_t tag);
     void filterUnsupportedFeatures(); // Hide features not yet supported by NDK
     void filterStreamConfigurations(); // Hide input streams, translate hal format to NDK formats
-
-    const CameraMetadata& getInternalData() const;
+    void filterDurations(uint32_t tag); // translate hal format to NDK formats
 
     template<typename INTERNAL_T, typename NDK_T>
     camera_status_t updateImpl(uint32_t tag, uint32_t count, const NDK_T* data) {
@@ -96,7 +99,6 @@
         }
     }
 
-  private:
     // guard access of public APIs: get/update/getTags
     mutable Mutex    mLock;
     CameraMetadata   mData;
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index eeca629..0142333 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -143,6 +143,7 @@
     uint8_t *mSrcBuffer;
 
     bool mIsHeif;
+    bool mIsAudio;
     sp<ItemTable> mItemTable;
 
     size_t parseNALSize(const uint8_t *data) const;
@@ -4030,6 +4031,7 @@
     }
 
     mIsPcm = !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW);
+    mIsAudio = !strncasecmp(mime, "audio/", 6);
 
     if (mIsPcm) {
         int32_t numChannels = 0;
@@ -4869,8 +4871,11 @@
                 findFlags = SampleTable::kFlagBefore;
             }
 
-            uint32_t syncSampleIndex;
-            if (err == OK) {
+            uint32_t syncSampleIndex = sampleIndex;
+            // assume every audio sample is a sync sample. This works around
+            // seek issues with files that were incorrectly written with an
+            // empty or single-sample stss block for the audio track
+            if (err == OK && !mIsAudio) {
                 err = mSampleTable->findSyncSampleNear(
                         sampleIndex, &syncSampleIndex, findFlags);
             }
@@ -5587,6 +5592,7 @@
         FOURCC("mp41"),
         FOURCC("mp42"),
         FOURCC("dash"),
+        FOURCC("nvr1"),
 
         // Won't promise that the following file types can be played.
         // Just give these file types a chance.
diff --git a/media/libaaudio/src/fifo/FifoControllerBase.cpp b/media/libaaudio/src/fifo/FifoControllerBase.cpp
index 14a2be1..51a8e34 100644
--- a/media/libaaudio/src/fifo/FifoControllerBase.cpp
+++ b/media/libaaudio/src/fifo/FifoControllerBase.cpp
@@ -38,7 +38,7 @@
 
 fifo_frames_t FifoControllerBase::getReadIndex() {
     // % works with non-power of two sizes
-    return (fifo_frames_t) (getReadCounter() % mCapacity);
+    return (fifo_frames_t) ((uint64_t)getReadCounter() % mCapacity);
 }
 
 void FifoControllerBase::advanceReadIndex(fifo_frames_t numFrames) {
@@ -51,7 +51,7 @@
 
 fifo_frames_t FifoControllerBase::getWriteIndex() {
     // % works with non-power of two sizes
-    return (fifo_frames_t) (getWriteCounter() % mCapacity);
+    return (fifo_frames_t) ((uint64_t)getWriteCounter() % mCapacity);
 }
 
 void FifoControllerBase::advanceWriteIndex(fifo_frames_t numFrames) {
diff --git a/media/libaaudio/tests/test_atomic_fifo.cpp b/media/libaaudio/tests/test_atomic_fifo.cpp
index 0085217..0edfebe 100644
--- a/media/libaaudio/tests/test_atomic_fifo.cpp
+++ b/media/libaaudio/tests/test_atomic_fifo.cpp
@@ -23,12 +23,12 @@
 #include "fifo/FifoController.h"
 
 using android::fifo_frames_t;
+using android::fifo_counter_t;
 using android::FifoController;
 using android::FifoBuffer;
 using android::WrappingBuffer;
 
-//void foo() {
-TEST(test_fifi_controller, fifo_indices) {
+TEST(test_fifo_controller, fifo_indices) {
     // Values are arbitrary primes designed to trigger edge cases.
     constexpr int capacity = 83;
     constexpr int threshold = 47;
@@ -73,18 +73,59 @@
     ASSERT_EQ(threshold - advance2, fifoController.getEmptyFramesAvailable());
 }
 
+TEST(test_fifo_controller, fifo_wrap_around_zero) {
+    constexpr int capacity = 7; // arbitrary prime
+    constexpr int threshold = capacity;
+    FifoController fifoController(capacity, threshold);
+    ASSERT_EQ(capacity, fifoController.getCapacity());
+    ASSERT_EQ(threshold, fifoController.getThreshold());
+
+    fifoController.setReadCounter(-10); // a bit less than negative capacity
+    for (int i = 0; i < 20; i++) {
+        EXPECT_EQ(i - 10, fifoController.getReadCounter());
+        EXPECT_GE(fifoController.getReadIndex(), 0);
+        EXPECT_LT(fifoController.getReadIndex(), capacity);
+        fifoController.advanceReadIndex(1);
+    }
+
+    fifoController.setWriteCounter(-10);
+    for (int i = 0; i < 20; i++) {
+        EXPECT_EQ(i - 10, fifoController.getWriteCounter());
+        EXPECT_GE(fifoController.getWriteIndex(), 0);
+        EXPECT_LT(fifoController.getWriteIndex(), capacity);
+        fifoController.advanceWriteIndex(1);
+    }
+}
+
+
 // TODO consider using a template for other data types.
+
+// Create a big array and then use a region in the middle for the  unit tests.
+// Then we can scan the rest of the array to see if it got clobbered.
+static constexpr fifo_frames_t kBigArraySize = 1024;
+static constexpr fifo_frames_t kFifoDataOffset = 128; // starting index of FIFO data
+static constexpr int16_t       kSafeDataValue = 0x7654; // original value of BigArray
+
 class TestFifoBuffer {
 public:
     explicit TestFifoBuffer(fifo_frames_t capacity, fifo_frames_t threshold = 0)
-        : mFifoBuffer(sizeof(int16_t), capacity) {
+        : mFifoBuffer(sizeof(int16_t), capacity,
+                      &mReadIndex,
+                      &mWriteIndex,
+                      &mVeryBigArray[kFifoDataOffset]) // address of start of FIFO data
+    {
+
+        // Assume a frame is one int16_t.
         // For reading and writing.
-        mData = new int16_t[capacity];
         if (threshold <= 0) {
             threshold = capacity;
         }
         mFifoBuffer.setThreshold(threshold);
         mThreshold = threshold;
+
+        for (fifo_frames_t i = 0; i < kBigArraySize; i++) {
+            mVeryBigArray[i] = kSafeDataValue;
+        }
     }
 
     void checkMisc() {
@@ -92,26 +133,70 @@
         ASSERT_EQ(mThreshold, mFifoBuffer.getThreshold());
     }
 
+    void verifyAddressInRange(void *p, void *valid, size_t numBytes) {
+        uintptr_t p_int = (uintptr_t) p;
+        uintptr_t valid_int = (uintptr_t) valid;
+        EXPECT_GE(p_int, valid_int);
+        EXPECT_LT(p_int, (valid_int + numBytes));
+    }
+
+    void verifyStorageIntegrity() {
+        for (fifo_frames_t i = 0; i < kFifoDataOffset; i++) {
+            EXPECT_EQ(mVeryBigArray[i], kSafeDataValue);
+        }
+        fifo_frames_t firstFrameAfter = kFifoDataOffset + mFifoBuffer.getBufferCapacityInFrames();
+        for (fifo_frames_t i = firstFrameAfter; i < kBigArraySize; i++) {
+            EXPECT_EQ(mVeryBigArray[i], kSafeDataValue);
+        }
+    }
+
     // Verify that the available frames in each part add up correctly.
-    void checkWrappingBuffer() {
+    void verifyWrappingBuffer() {
         WrappingBuffer wrappingBuffer;
+
+
+        // Does the sum of the two parts match the available value returned?
+        // For EmptyRoom
         fifo_frames_t framesAvailable =
                 mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
         fifo_frames_t wrapAvailable = mFifoBuffer.getEmptyRoomAvailable(&wrappingBuffer);
         EXPECT_EQ(framesAvailable, wrapAvailable);
         fifo_frames_t bothAvailable = wrappingBuffer.numFrames[0] + wrappingBuffer.numFrames[1];
         EXPECT_EQ(framesAvailable, bothAvailable);
-
+        // For FullData
         framesAvailable =
                 mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
         wrapAvailable = mFifoBuffer.getFullDataAvailable(&wrappingBuffer);
         EXPECT_EQ(framesAvailable, wrapAvailable);
         bothAvailable = wrappingBuffer.numFrames[0] + wrappingBuffer.numFrames[1];
         EXPECT_EQ(framesAvailable, bothAvailable);
+
+        // Are frame counts in legal range?
+        fifo_frames_t capacity = mFifoBuffer.getBufferCapacityInFrames();
+        EXPECT_GE(wrappingBuffer.numFrames[0], 0);
+        EXPECT_LE(wrappingBuffer.numFrames[0], capacity);
+        EXPECT_GE(wrappingBuffer.numFrames[1], 0);
+        EXPECT_LE(wrappingBuffer.numFrames[1], capacity);
+
+        // Are addresses within the FIFO data area?
+        size_t validBytes = capacity * sizeof(int16_t);
+        if (wrappingBuffer.numFrames[0]) {
+            verifyAddressInRange(wrappingBuffer.data[0], mFifoStorage, validBytes);
+            uint8_t *last = ((uint8_t *)wrappingBuffer.data[0])
+                            + mFifoBuffer.convertFramesToBytes(wrappingBuffer.numFrames[0]) - 1;
+            verifyAddressInRange(last, mFifoStorage, validBytes);
+        }
+        if (wrappingBuffer.numFrames[1]) {
+            verifyAddressInRange(wrappingBuffer.data[1], mFifoStorage, validBytes);
+            uint8_t *last = ((uint8_t *)wrappingBuffer.data[1])
+                            + mFifoBuffer.convertFramesToBytes(wrappingBuffer.numFrames[1]) - 1;
+            verifyAddressInRange(last, mFifoStorage, validBytes);
+        }
+
     }
 
     // Write data but do not overflow.
-    void writeData(fifo_frames_t numFrames) {
+    void writeMultipleDataFrames(fifo_frames_t numFrames) {
         fifo_frames_t framesAvailable =
                 mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
         fifo_frames_t framesToWrite = std::min(framesAvailable, numFrames);
@@ -122,8 +207,8 @@
         ASSERT_EQ(framesToWrite, actual);
     }
 
-    // Read data but do not underflow.
-    void verifyData(fifo_frames_t numFrames) {
+    // Read whatever data is available, Do not underflow.
+    void verifyMultipleDataFrames(fifo_frames_t numFrames) {
         fifo_frames_t framesAvailable =
                 mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
         fifo_frames_t framesToRead = std::min(framesAvailable, numFrames);
@@ -134,20 +219,35 @@
         }
     }
 
+    // Read specified number of frames
+    void verifyRequestedData(fifo_frames_t numFrames) {
+        fifo_frames_t framesAvailable =
+                mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
+        ASSERT_LE(numFrames, framesAvailable);
+        fifo_frames_t framesToRead = std::min(framesAvailable, numFrames);
+        fifo_frames_t actual = mFifoBuffer.read(mData, framesToRead);
+        ASSERT_EQ(actual, numFrames);
+        for (int i = 0; i < actual; i++) {
+            ASSERT_EQ(mNextVerifyIndex++, mData[i]);
+        }
+    }
+
     // Wrap around the end of the buffer.
     void checkWrappingWriteRead() {
         constexpr int frames1 = 43;
         constexpr int frames2 = 15;
 
-        writeData(frames1);
-        checkWrappingBuffer();
-        verifyData(frames1);
-        checkWrappingBuffer();
+        writeMultipleDataFrames(frames1);
+        verifyWrappingBuffer();
+        verifyRequestedData(frames1);
+        verifyWrappingBuffer();
 
-        writeData(frames2);
-        checkWrappingBuffer();
-        verifyData(frames2);
-        checkWrappingBuffer();
+        writeMultipleDataFrames(frames2);
+        verifyWrappingBuffer();
+        verifyRequestedData(frames2);
+        verifyWrappingBuffer();
+
+        verifyStorageIntegrity();
     }
 
     // Write and Read a specific amount of data.
@@ -156,10 +256,12 @@
         // Wrap around with the smaller region in the second half.
         const int frames1 = capacity - 4;
         const int frames2 = 7; // arbitrary, small
-        writeData(frames1);
-        verifyData(frames1);
-        writeData(frames2);
-        verifyData(frames2);
+        writeMultipleDataFrames(frames1);
+        verifyRequestedData(frames1);
+        writeMultipleDataFrames(frames2);
+        verifyRequestedData(frames2);
+
+        verifyStorageIntegrity();
     }
 
     // Write and Read a specific amount of data.
@@ -168,10 +270,12 @@
         // Wrap around with the larger region in the second half.
         const int frames1 = capacity - 4;
         const int frames2 = capacity - 9; // arbitrary, large
-        writeData(frames1);
-        verifyData(frames1);
-        writeData(frames2);
-        verifyData(frames2);
+        writeMultipleDataFrames(frames1);
+        verifyRequestedData(frames1);
+        writeMultipleDataFrames(frames2);
+        verifyRequestedData(frames2);
+
+        verifyStorageIntegrity();
     }
 
     // Randomly read or write up to the maximum amount of data.
@@ -180,30 +284,67 @@
             fifo_frames_t framesEmpty =
                     mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
             fifo_frames_t numFrames = (fifo_frames_t)(drand48() * framesEmpty);
-            writeData(numFrames);
+            writeMultipleDataFrames(numFrames);
 
             fifo_frames_t framesFull =
                     mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
             numFrames = (fifo_frames_t)(drand48() * framesFull);
-            verifyData(numFrames);
+            verifyMultipleDataFrames(numFrames);
         }
+
+        verifyStorageIntegrity();
+    }
+
+    // Write and Read a specific amount of data.
+    void checkNegativeCounters() {
+        fifo_counter_t counter = -9876;
+        mFifoBuffer.setWriteCounter(counter);
+        mFifoBuffer.setReadCounter(counter);
+        checkWrappingWriteRead();
+    }
+
+    // Wrap over the boundary at 0x7FFFFFFFFFFFFFFF
+    // Note that the behavior of a signed overflow is technically undefined.
+    void checkHalfWrap() {
+        fifo_counter_t counter = INT64_MAX - 10;
+        mFifoBuffer.setWriteCounter(counter);
+        mFifoBuffer.setReadCounter(counter);
+        ASSERT_GT(mFifoBuffer.getWriteCounter(), 0);
+        checkWrappingWriteRead();
+        ASSERT_LT(mFifoBuffer.getWriteCounter(), 0); // did we wrap past INT64_MAX?
+    }
+
+    // Wrap over the boundary at 0xFFFFFFFFFFFFFFFF
+    void checkFullWrap() {
+        fifo_counter_t counter = -10;
+        mFifoBuffer.setWriteCounter(counter);
+        mFifoBuffer.setReadCounter(counter);
+        ASSERT_LT(mFifoBuffer.getWriteCounter(), 0);
+        writeMultipleDataFrames(20);
+        ASSERT_GT(mFifoBuffer.getWriteCounter(), 0); // did we wrap past zero?
+        verifyStorageIntegrity();
     }
 
     FifoBuffer     mFifoBuffer;
-    int16_t       *mData;
     fifo_frames_t  mNextWriteIndex = 0;
     fifo_frames_t  mNextVerifyIndex = 0;
     fifo_frames_t  mThreshold;
+
+    fifo_counter_t mReadIndex = 0;
+    fifo_counter_t mWriteIndex = 0;
+    int16_t        mVeryBigArray[kBigArraySize]; // Use the middle of this array for the FIFO.
+    int16_t       *mFifoStorage = &mVeryBigArray[kFifoDataOffset]; // Start here for storage.
+    int16_t        mData[kBigArraySize]{};
 };
 
-TEST(test_fifo_buffer, fifo_read_write) {
+TEST(test_fifo_buffer, fifo_write_read) {
     constexpr int capacity = 51; // arbitrary
     TestFifoBuffer tester(capacity);
     tester.checkMisc();
     tester.checkWriteRead();
 }
 
-TEST(test_fifo_buffer, fifo_wrapping_read_write) {
+TEST(test_fifo_buffer, fifo_wrapping_write_read) {
     constexpr int capacity = 59; // arbitrary, a little bigger this time
     TestFifoBuffer tester(capacity);
     tester.checkWrappingWriteRead();
@@ -227,3 +368,21 @@
     TestFifoBuffer tester(capacity, threshold);
     tester.checkRandomWriteRead();
 }
+
+TEST(test_fifo_buffer, fifo_negative_counters) {
+    constexpr int capacity = 49; // arbitrary
+    TestFifoBuffer tester(capacity);
+    tester.checkNegativeCounters();
+}
+
+TEST(test_fifo_buffer, fifo_half_wrap) {
+    constexpr int capacity = 57; // arbitrary
+    TestFifoBuffer tester(capacity);
+    tester.checkHalfWrap();
+}
+
+TEST(test_fifo_buffer, fifo_full_wrap) {
+    constexpr int capacity = 57; // arbitrary
+    TestFifoBuffer tester(capacity);
+    tester.checkFullWrap();
+}
diff --git a/media/libaudiohal/HalDeathHandlerHidl.cpp b/media/libaudiohal/HalDeathHandlerHidl.cpp
index 1e3ab58..6e33523 100644
--- a/media/libaudiohal/HalDeathHandlerHidl.cpp
+++ b/media/libaudiohal/HalDeathHandlerHidl.cpp
@@ -54,7 +54,7 @@
         handler.second();
     }
     ALOGE("HAL server crashed, audio server is restarting");
-    exit(1);
+    _exit(1);  // Avoid calling atexit handlers, as this code runs on a thread from RPC threadpool.
 }
 
 } // namespace android
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/libmedia/Android.bp b/media/libmedia/Android.bp
index 7deab05..7c0dab4 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -1,3 +1,10 @@
+cc_defaults {
+    name: "libmedia_defaults",
+    include_dirs: [
+        "bionic/libc/private",
+    ],
+}
+
 cc_library_headers {
     name: "libmedia_headers",
     vendor_available: true,
@@ -148,6 +155,8 @@
 cc_library {
     name: "libmedia",
 
+    defaults: [ "libmedia_defaults" ],
+
     srcs: [
         ":mediaupdateservice_aidl",
         "IDataSource.cpp",
@@ -256,6 +265,8 @@
 cc_library {
     name: "libmedia_player2_util",
 
+    defaults: [ "libmedia_defaults" ],
+
     srcs: [
         "BufferingSettings.cpp",
         "DataSourceDesc.cpp",
diff --git a/media/libmedia/MediaUtils.cpp b/media/libmedia/MediaUtils.cpp
index bcc7ebf..31972fa 100644
--- a/media/libmedia/MediaUtils.cpp
+++ b/media/libmedia/MediaUtils.cpp
@@ -22,23 +22,16 @@
 #include <sys/resource.h>
 #include <unistd.h>
 
+#include <bionic_malloc.h>
+
 #include "MediaUtils.h"
 
-extern "C" size_t __cfi_shadow_size();
 extern "C" void __scudo_set_rss_limit(size_t, int) __attribute__((weak));
 
 namespace android {
 
-void limitProcessMemory(
-    const char *property,
-    size_t numberOfBytes,
-    size_t percentageOfTotalMem) {
-
-    if (running_with_asan()) {
-        ALOGW("Running with (HW)ASan, skip enforcing memory limitations.");
-        return;
-    }
-
+void limitProcessMemory(const char *property, size_t numberOfBytes,
+                        size_t percentageOfTotalMem) {
     long pageSize = sysconf(_SC_PAGESIZE);
     long numPages = sysconf(_SC_PHYS_PAGES);
     size_t maxMem = SIZE_MAX;
@@ -66,38 +59,17 @@
         maxMem = propVal;
     }
 
-    // If 64-bit Scudo is in use, enforce the hard RSS limit (in MB).
-    if (maxMem != SIZE_MAX && sizeof(void *) == 8 &&
-        &__scudo_set_rss_limit != 0) {
+    // If Scudo is in use, enforce the hard RSS limit (in MB).
+    if (maxMem != SIZE_MAX && &__scudo_set_rss_limit != 0) {
       __scudo_set_rss_limit(maxMem >> 20, 1);
       ALOGV("Scudo hard RSS limit set to %zu MB", maxMem >> 20);
       return;
     }
 
-    // Increase by the size of the CFI shadow mapping. Most of the shadow is not
-    // backed with physical pages, and it is possible for the result to be
-    // higher than total physical memory. This is fine for RLIMIT_AS.
-    size_t cfi_size = __cfi_shadow_size();
-    if (cfi_size) {
-      ALOGV("cfi shadow size: %zu", cfi_size);
-      if (maxMem <= SIZE_MAX - cfi_size) {
-        maxMem += cfi_size;
-      } else {
-        maxMem = SIZE_MAX;
-      }
+    if (!android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &maxMem,
+                         sizeof(maxMem))) {
+      ALOGW("couldn't set allocation limit");
     }
-    ALOGV("actual limit: %zu", maxMem);
-
-    struct rlimit limit;
-    getrlimit(RLIMIT_AS, &limit);
-    ALOGV("original limits: %lld/%lld", (long long)limit.rlim_cur, (long long)limit.rlim_max);
-    limit.rlim_cur = maxMem;
-    setrlimit(RLIMIT_AS, &limit);
-    limit.rlim_cur = -1;
-    limit.rlim_max = -1;
-    getrlimit(RLIMIT_AS, &limit);
-    ALOGV("new limits: %lld/%lld", (long long)limit.rlim_cur, (long long)limit.rlim_max);
-
 }
 
 } // namespace android
diff --git a/media/libmedia/MediaUtils.h b/media/libmedia/MediaUtils.h
index 26075c4..f80dd30 100644
--- a/media/libmedia/MediaUtils.h
+++ b/media/libmedia/MediaUtils.h
@@ -19,13 +19,6 @@
 
 namespace android {
 
-extern "C" void __asan_init(void) __attribute__((weak));
-extern "C" void __hwasan_init(void) __attribute__((weak));
-
-static inline int running_with_asan() {
-    return &__asan_init != 0 || &__hwasan_init != 0;
-}
-
 /**
    Limit the amount of memory a process can allocate using setrlimit(RLIMIT_AS).
    The value to use will be read from the specified system property, or if the
diff --git a/media/libmedia/xsd/Android.bp b/media/libmedia/xsd/Android.bp
new file mode 100644
index 0000000..1635f70
--- /dev/null
+++ b/media/libmedia/xsd/Android.bp
@@ -0,0 +1,21 @@
+//
+// 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.
+//
+
+xsd_config {
+    name: "media_profiles",
+    srcs: ["media_profiles.xsd"],
+    package_name: "media.profiles",
+}
diff --git a/media/libmedia/xsd/api/current.txt b/media/libmedia/xsd/api/current.txt
new file mode 100644
index 0000000..05e8a49
--- /dev/null
+++ b/media/libmedia/xsd/api/current.txt
@@ -0,0 +1,147 @@
+// Signature format: 2.0
+package media.profiles {
+
+  public class Audio {
+    ctor public Audio();
+    method public int getBitRate();
+    method public int getChannels();
+    method public String getCodec();
+    method public int getSampleRate();
+    method public void setBitRate(int);
+    method public void setChannels(int);
+    method public void setCodec(String);
+    method public void setSampleRate(int);
+  }
+
+  public class AudioDecoderCap {
+    ctor public AudioDecoderCap();
+    method public boolean getEnabled();
+    method public String getName();
+    method public void setEnabled(boolean);
+    method public void setName(String);
+  }
+
+  public class AudioEncoderCap {
+    ctor public AudioEncoderCap();
+    method public boolean getEnabled();
+    method public int getMaxBitRate();
+    method public int getMaxChannels();
+    method public int getMaxSampleRate();
+    method public int getMinBitRate();
+    method public int getMinChannels();
+    method public int getMinSampleRate();
+    method public String getName();
+    method public void setEnabled(boolean);
+    method public void setMaxBitRate(int);
+    method public void setMaxChannels(int);
+    method public void setMaxSampleRate(int);
+    method public void setMinBitRate(int);
+    method public void setMinChannels(int);
+    method public void setMinSampleRate(int);
+    method public void setName(String);
+  }
+
+  public class CamcorderProfiles {
+    ctor public CamcorderProfiles();
+    method public int getCameraId();
+    method public java.util.List<media.profiles.EncoderProfile> getEncoderProfile();
+    method public java.util.List<media.profiles.CamcorderProfiles.ImageDecoding> getImageDecoding();
+    method public java.util.List<media.profiles.CamcorderProfiles.ImageEncoding> getImageEncoding();
+    method public void setCameraId(int);
+  }
+
+  public static class CamcorderProfiles.ImageDecoding {
+    ctor public CamcorderProfiles.ImageDecoding();
+    method public int getMemCap();
+    method public void setMemCap(int);
+  }
+
+  public static class CamcorderProfiles.ImageEncoding {
+    ctor public CamcorderProfiles.ImageEncoding();
+    method public int getQuality();
+    method public void setQuality(int);
+  }
+
+  public class EncoderProfile {
+    ctor public EncoderProfile();
+    method public java.util.List<media.profiles.Audio> getAudio();
+    method public int getDuration();
+    method public String getFileFormat();
+    method public String getQuality();
+    method public java.util.List<media.profiles.Video> getVideo();
+    method public void setDuration(int);
+    method public void setFileFormat(String);
+    method public void setQuality(String);
+  }
+
+  public class MediaSettings {
+    ctor public MediaSettings();
+    method public java.util.List<media.profiles.AudioDecoderCap> getAudioDecoderCap();
+    method public java.util.List<media.profiles.AudioEncoderCap> getAudioEncoderCap();
+    method public java.util.List<media.profiles.CamcorderProfiles> getCamcorderProfiles();
+    method public java.util.List<media.profiles.MediaSettings.EncoderOutputFileFormat> getEncoderOutputFileFormat();
+    method public java.util.List<media.profiles.VideoDecoderCap> getVideoDecoderCap();
+    method public java.util.List<media.profiles.VideoEncoderCap> getVideoEncoderCap();
+  }
+
+  public static class MediaSettings.EncoderOutputFileFormat {
+    ctor public MediaSettings.EncoderOutputFileFormat();
+    method public String getName();
+    method public void setName(String);
+  }
+
+  public class Video {
+    ctor public Video();
+    method public int getBitRate();
+    method public String getCodec();
+    method public int getFrameRate();
+    method public int getHeight();
+    method public int getWidth();
+    method public void setBitRate(int);
+    method public void setCodec(String);
+    method public void setFrameRate(int);
+    method public void setHeight(int);
+    method public void setWidth(int);
+  }
+
+  public class VideoDecoderCap {
+    ctor public VideoDecoderCap();
+    method public boolean getEnabled();
+    method public String getName();
+    method public void setEnabled(boolean);
+    method public void setName(String);
+  }
+
+  public class VideoEncoderCap {
+    ctor public VideoEncoderCap();
+    method public boolean getEnabled();
+    method public int getMaxBitRate();
+    method public int getMaxFrameHeight();
+    method public int getMaxFrameRate();
+    method public int getMaxFrameWidth();
+    method public int getMinBitRate();
+    method public int getMinFrameHeight();
+    method public int getMinFrameRate();
+    method public int getMinFrameWidth();
+    method public String getName();
+    method public void setEnabled(boolean);
+    method public void setMaxBitRate(int);
+    method public void setMaxFrameHeight(int);
+    method public void setMaxFrameRate(int);
+    method public void setMaxFrameWidth(int);
+    method public void setMinBitRate(int);
+    method public void setMinFrameHeight(int);
+    method public void setMinFrameRate(int);
+    method public void setMinFrameWidth(int);
+    method public void setName(String);
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method public static media.profiles.MediaSettings read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/media/libmedia/xsd/api/last_current.txt b/media/libmedia/xsd/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libmedia/xsd/api/last_current.txt
diff --git a/media/libmedia/xsd/api/last_removed.txt b/media/libmedia/xsd/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libmedia/xsd/api/last_removed.txt
diff --git a/media/libmedia/xsd/api/removed.txt b/media/libmedia/xsd/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/media/libmedia/xsd/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/media/libmedia/xsd/media_profiles.xsd b/media/libmedia/xsd/media_profiles.xsd
new file mode 100644
index 0000000..a02252a
--- /dev/null
+++ b/media/libmedia/xsd/media_profiles.xsd
@@ -0,0 +1,105 @@
+<?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.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:element name="MediaSettings">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="CamcorderProfiles" type="CamcorderProfiles" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="EncoderOutputFileFormat" minOccurs="0" maxOccurs="unbounded">
+                    <xs:complexType>
+                        <xs:attribute name="name" type="xs:string"/>
+                    </xs:complexType>
+                </xs:element>
+                <xs:element name="VideoEncoderCap" type="VideoEncoderCap" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="AudioEncoderCap" type="AudioEncoderCap" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="VideoDecoderCap" type="VideoDecoderCap" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="AudioDecoderCap" type="AudioDecoderCap" minOccurs="0" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    <xs:complexType name="CamcorderProfiles">
+        <xs:sequence>
+            <xs:element name="EncoderProfile" type="EncoderProfile" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="ImageEncoding" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="quality" type="xs:int"/>
+                </xs:complexType>
+            </xs:element>
+            <xs:element name="ImageDecoding" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="memCap" type="xs:int"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+        <xs:attribute name="cameraId" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="EncoderProfile">
+        <xs:sequence>
+            <xs:element name="Video" type="Video" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Audio" type="Audio" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="quality" type="xs:string"/>
+        <xs:attribute name="fileFormat" type="xs:string"/>
+        <xs:attribute name="duration" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="Video">
+        <xs:attribute name="codec" type="xs:string"/>
+        <xs:attribute name="bitRate" type="xs:int"/>
+        <xs:attribute name="width" type="xs:int"/>
+        <xs:attribute name="height" type="xs:int"/>
+        <xs:attribute name="frameRate" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="Audio">
+        <xs:attribute name="codec" type="xs:string"/>
+        <xs:attribute name="bitRate" type="xs:int"/>
+        <xs:attribute name="sampleRate" type="xs:int"/>
+        <xs:attribute name="channels" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="VideoEncoderCap">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="enabled" type="xs:boolean"/>
+        <xs:attribute name="minBitRate" type="xs:int"/>
+        <xs:attribute name="maxBitRate" type="xs:int"/>
+        <xs:attribute name="minFrameWidth" type="xs:int"/>
+        <xs:attribute name="maxFrameWidth" type="xs:int"/>
+        <xs:attribute name="minFrameHeight" type="xs:int"/>
+        <xs:attribute name="maxFrameHeight" type="xs:int"/>
+        <xs:attribute name="minFrameRate" type="xs:int"/>
+        <xs:attribute name="maxFrameRate" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="AudioEncoderCap">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="enabled" type="xs:boolean"/>
+        <xs:attribute name="minBitRate" type="xs:int"/>
+        <xs:attribute name="maxBitRate" type="xs:int"/>
+        <xs:attribute name="minSampleRate" type="xs:int"/>
+        <xs:attribute name="maxSampleRate" type="xs:int"/>
+        <xs:attribute name="minChannels" type="xs:int"/>
+        <xs:attribute name="maxChannels" type="xs:int"/>
+    </xs:complexType>
+    <xs:complexType name="VideoDecoderCap">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="enabled" type="xs:boolean"/>
+    </xs:complexType>
+    <xs:complexType name="AudioDecoderCap">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="enabled" type="xs:boolean"/>
+    </xs:complexType>
+</xs:schema>
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/libstagefright/Android.bp b/media/libstagefright/Android.bp
index bc7569f..89e7c54 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -137,6 +137,7 @@
         "libcamera_client",
         "libcutils",
         "libdl",
+        "libdl_android",
         "libdrmframework",
         "libgui",
         "libion",
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index ee6fe17..a91e92c 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -427,19 +427,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/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index e22ad0d..5d2291f 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -643,6 +643,10 @@
             output->mBufferQueue.clear();
             output->mEncoderReachedEOS = true;
             output->mErrorCode = err;
+            if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
+                mStopping = true;
+                mPuller->stop();
+            }
             output->mCond.signal();
 
             reachedEOS = true;
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp.cpp b/media/libstagefright/codecs/amrnb/common/src/lsp.cpp
index 0e3f772..81d9cde 100644
--- a/media/libstagefright/codecs/amrnb/common/src/lsp.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/lsp.cpp
@@ -173,7 +173,7 @@
     *st = NULL;
 
     /* allocate memory */
-    if ((s = (lspState *) malloc(sizeof(lspState))) == NULL)
+    if ((s = (lspState *) calloc(sizeof(lspState), 1)) == NULL)
     {
         /* fprintf(stderr, "lsp_init: can not malloc state structure\n"); */
         return -1;
@@ -182,11 +182,13 @@
     /* Initialize quantization state */
     if (0 != Q_plsf_init(&s->qSt))
     {
+        lsp_exit(&s);
         return -1;
     }
 
     if (0 != lsp_reset(s))
     {
+        lsp_exit(&s);
         return -1;
     }
 
diff --git a/media/libstagefright/codecs/amrnb/dec/src/sp_dec.cpp b/media/libstagefright/codecs/amrnb/dec/src/sp_dec.cpp
index 2989b74..49cafff 100644
--- a/media/libstagefright/codecs/amrnb/dec/src/sp_dec.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/src/sp_dec.cpp
@@ -268,13 +268,7 @@
     if (Decoder_amr_init(&s->decoder_amrState)
             || Post_Process_reset(&s->postHP_state))
     {
-        Speech_Decode_FrameState *tmp = s;
-        /*
-         *  dereferencing type-punned pointer avoid
-         *  breaking strict-aliasing rules
-         */
-        void** tempVoid = (void**) tmp;
-        GSMDecodeFrameExit(tempVoid);
+        free(s);
         return (-1);
     }
 
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/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/m4v_h263/enc/test/m4v_h263_enc_test.cpp b/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
index db2c61a..5554ebd 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
@@ -183,6 +183,10 @@
     // Initialize the encoder.
     if (!PVInitVideoEncoder(&handle, &encParams)) {
         fprintf(stderr, "Failed to initialize the encoder\n");
+        fclose(fpInput);
+        fclose(fpOutput);
+        free(inputBuf);
+        free(outputBuf);
         return EXIT_FAILURE;
     }
 
@@ -190,6 +194,10 @@
     int32_t headerLength = kOutputBufferSize;
     if (!PVGetVolHeader(&handle, outputBuf, &headerLength, 0)) {
         fprintf(stderr, "Failed to get VOL header\n");
+        fclose(fpInput);
+        fclose(fpOutput);
+        free(inputBuf);
+        free(outputBuf);
         return EXIT_FAILURE;
     }
     fwrite(outputBuf, 1, headerLength, fpOutput);
diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp
index 1a527b3..0e31804 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.cpp
+++ b/media/libstagefright/codecs/raw/SoftRaw.cpp
@@ -60,7 +60,7 @@
     def.eDir = OMX_DirInput;
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 64 * 1024;
+    def.nBufferSize = 192 * 1024;
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
@@ -78,7 +78,7 @@
     def.eDir = OMX_DirOutput;
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 64 * 1024;
+    def.nBufferSize = 192 * 1024;
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
diff --git a/media/libstagefright/xmlparser/Android.bp b/media/libstagefright/xmlparser/Android.bp
index edd8fbc..ed26e58 100644
--- a/media/libstagefright/xmlparser/Android.bp
+++ b/media/libstagefright/xmlparser/Android.bp
@@ -41,3 +41,9 @@
 
 }
 
+xsd_config {
+    name: "media_codecs",
+    srcs: ["media_codecs.xsd"],
+    package_name: "media.codecs",
+}
+
diff --git a/media/libstagefright/xmlparser/api/current.txt b/media/libstagefright/xmlparser/api/current.txt
new file mode 100644
index 0000000..f7f4c36
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/current.txt
@@ -0,0 +1,132 @@
+// Signature format: 2.0
+package media.codecs {
+
+  public class Alias {
+    ctor public Alias();
+    method public String getName();
+    method public void setName(String);
+  }
+
+  public class Decoders {
+    ctor public Decoders();
+    method public java.util.List<media.codecs.MediaCodec> getMediaCodec();
+  }
+
+  public class Encoders {
+    ctor public Encoders();
+    method public java.util.List<media.codecs.MediaCodec> getMediaCodec();
+  }
+
+  public class Feature {
+    ctor public Feature();
+    method public String getName();
+    method public String getOptional();
+    method public String getRequired();
+    method public String getValue();
+    method public void setName(String);
+    method public void setOptional(String);
+    method public void setRequired(String);
+    method public void setValue(String);
+  }
+
+  public class Include {
+    ctor public Include();
+    method public String getHref();
+    method public void setHref(String);
+  }
+
+  public class Included {
+    ctor public Included();
+    method public java.util.List<media.codecs.Decoders> getDecoders_optional();
+    method public java.util.List<media.codecs.Encoders> getEncoders_optional();
+    method public java.util.List<media.codecs.Include> getInclude_optional();
+    method public java.util.List<media.codecs.Settings> getSettings_optional();
+  }
+
+  public class Limit {
+    ctor public Limit();
+    method public String getIn();
+    method public String getMax();
+    method public String getMin();
+    method public String getName();
+    method public String getRange();
+    method public String getRanges();
+    method public String getScale();
+    method public String getValue();
+    method public String get_default();
+    method public void setIn(String);
+    method public void setMax(String);
+    method public void setMin(String);
+    method public void setName(String);
+    method public void setRange(String);
+    method public void setRanges(String);
+    method public void setScale(String);
+    method public void setValue(String);
+    method public void set_default(String);
+  }
+
+  public class MediaCodec {
+    ctor public MediaCodec();
+    method public java.util.List<media.codecs.Alias> getAlias_optional();
+    method public java.util.List<media.codecs.Feature> getFeature_optional();
+    method public java.util.List<media.codecs.Limit> getLimit_optional();
+    method public String getName();
+    method public java.util.List<media.codecs.Quirk> getQuirk_optional();
+    method public String getType();
+    method public java.util.List<media.codecs.Type> getType_optional();
+    method public String getUpdate();
+    method public void setName(String);
+    method public void setType(String);
+    method public void setUpdate(String);
+  }
+
+  public class MediaCodecs {
+    ctor public MediaCodecs();
+    method public java.util.List<media.codecs.Decoders> getDecoders_optional();
+    method public java.util.List<media.codecs.Encoders> getEncoders_optional();
+    method public java.util.List<media.codecs.Include> getInclude_optional();
+    method public java.util.List<media.codecs.Settings> getSettings_optional();
+  }
+
+  public class Quirk {
+    ctor public Quirk();
+    method public String getName();
+    method public void setName(String);
+  }
+
+  public class Setting {
+    ctor public Setting();
+    method public String getName();
+    method public String getUpdate();
+    method public String getValue();
+    method public void setName(String);
+    method public void setUpdate(String);
+    method public void setValue(String);
+  }
+
+  public class Settings {
+    ctor public Settings();
+    method public java.util.List<media.codecs.Setting> getSetting();
+  }
+
+  public class Type {
+    ctor public Type();
+    method public java.util.List<media.codecs.Alias> getAlias();
+    method public java.util.List<media.codecs.Feature> getFeature();
+    method public java.util.List<media.codecs.Limit> getLimit();
+    method public String getName();
+    method public String getUpdate();
+    method public void setName(String);
+    method public void setUpdate(String);
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method public static media.codecs.Included readIncluded(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static media.codecs.MediaCodecs readMediaCodecs(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/media/libstagefright/xmlparser/api/last_current.txt b/media/libstagefright/xmlparser/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/last_current.txt
diff --git a/media/libstagefright/xmlparser/api/last_removed.txt b/media/libstagefright/xmlparser/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/last_removed.txt
diff --git a/media/libstagefright/xmlparser/api/removed.txt b/media/libstagefright/xmlparser/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/media/libstagefright/xmlparser/media_codecs.xsd b/media/libstagefright/xmlparser/media_codecs.xsd
new file mode 100644
index 0000000..77193a2
--- /dev/null
+++ b/media/libstagefright/xmlparser/media_codecs.xsd
@@ -0,0 +1,108 @@
+<?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.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:element name="MediaCodecs">
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="Include" type="Include" maxOccurs="unbounded"/>
+                <xs:element name="Settings" type="Settings"/>
+                <xs:element name="Decoders" type="Decoders"/>
+                <xs:element name="Encoders" type="Encoders"/>
+            </xs:choice>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="Included">
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="Include" type="Include" maxOccurs="unbounded"/>
+                <xs:element name="Settings" type="Settings"/>
+                <xs:element name="Decoders" type="Decoders"/>
+                <xs:element name="Encoders" type="Encoders"/>
+            </xs:choice>
+        </xs:complexType>
+    </xs:element>
+    <xs:complexType name="Decoders">
+        <xs:sequence>
+            <xs:element name="MediaCodec" type="MediaCodec" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="Encoders">
+        <xs:sequence>
+            <xs:element name="MediaCodec" type="MediaCodec" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="Settings">
+        <xs:sequence>
+            <xs:element name="Setting" type="Setting" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="MediaCodec">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="Quirk" type="Quirk" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Type" type="Type" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Alias" type="Alias" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Limit" type="Limit" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Feature" type="Feature" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="type" type="xs:string"/>
+        <xs:attribute name="update" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Quirk">
+        <xs:attribute name="name" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Type">
+        <xs:sequence>
+            <xs:element name="Alias" type="Alias" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Limit" type="Limit" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="Feature" type="Feature" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="update" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Alias">
+        <xs:attribute name="name" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Limit">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="default" type="xs:string"/>
+        <xs:attribute name="in" type="xs:string"/>
+        <xs:attribute name="max" type="xs:string"/>
+        <xs:attribute name="min" type="xs:string"/>
+        <xs:attribute name="range" type="xs:string"/>
+        <xs:attribute name="ranges" type="xs:string"/>
+        <xs:attribute name="scale" type="xs:string"/>
+        <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Feature">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="optional" type="xs:string"/>
+        <xs:attribute name="required" type="xs:string"/>
+        <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Setting">
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="value" type="xs:string"/>
+        <xs:attribute name="update" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="Include">
+        <xs:attribute name="href" type="xs:string"/>
+    </xs:complexType>
+</xs:schema>
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/mediaserver/Android.bp b/media/mediaserver/Android.bp
index 16c7be9..186f9ea 100644
--- a/media/mediaserver/Android.bp
+++ b/media/mediaserver/Android.bp
@@ -25,7 +25,6 @@
     ],
 
     static_libs: [
-        "libicuandroid_utils",
         "libregistermsext",
     ],
 
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index ecddc48..7b22b05 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "mediaserver"
 //#define LOG_NDEBUG 0
 
+#include <aicu/AIcu.h>
 #include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
@@ -25,7 +26,6 @@
 #include "RegisterExtensions.h"
 
 // from LOCAL_C_INCLUDES
-#include "IcuUtils.h"
 #include "MediaPlayerService.h"
 #include "ResourceManagerService.h"
 
@@ -38,7 +38,7 @@
     sp<ProcessState> proc(ProcessState::self());
     sp<IServiceManager> sm(defaultServiceManager());
     ALOGI("ServiceManager: %p", sm.get());
-    InitializeIcuOrDie();
+    AIcu_initializeIcuOrDie();
     MediaPlayerService::instantiate();
     ResourceManagerService::instantiate();
     registerExtensions();
diff --git a/media/mediaserver/mediaserver.rc b/media/mediaserver/mediaserver.rc
index 8cfcd79..f6c325c 100644
--- a/media/mediaserver/mediaserver.rc
+++ b/media/mediaserver/mediaserver.rc
@@ -2,7 +2,5 @@
     class main
     user media
     group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
-    # TODO(b/123275379): Remove updatable when http://aosp/878198 has landed
-    updatable
     ioprio rt 4
     writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
diff --git a/media/mtp/PosixAsyncIO.cpp b/media/mtp/PosixAsyncIO.cpp
index 72c07cc..8205e3b 100644
--- a/media/mtp/PosixAsyncIO.cpp
+++ b/media/mtp/PosixAsyncIO.cpp
@@ -47,10 +47,10 @@
         CHECK(aiocbp->queued);
         int ret;
         if (aiocbp->read) {
-            ret = TEMP_FAILURE_RETRY(pread(aiocbp->aio_fildes,
+            ret = TEMP_FAILURE_RETRY(pread64(aiocbp->aio_fildes,
                     aiocbp->aio_buf, aiocbp->aio_nbytes, aiocbp->aio_offset));
         } else {
-            ret = TEMP_FAILURE_RETRY(pwrite(aiocbp->aio_fildes,
+            ret = TEMP_FAILURE_RETRY(pwrite64(aiocbp->aio_fildes,
                aiocbp->aio_buf, aiocbp->aio_nbytes, aiocbp->aio_offset));
         }
         {
@@ -139,7 +139,7 @@
     return 0;
 }
 
-void aio_prepare(struct aiocb *aiocbp, void* buf, size_t count, off_t offset) {
+void aio_prepare(struct aiocb *aiocbp, void* buf, size_t count, off64_t offset) {
     aiocbp->aio_buf = buf;
     aiocbp->aio_offset = offset;
     aiocbp->aio_nbytes = count;
diff --git a/media/mtp/PosixAsyncIO.h b/media/mtp/PosixAsyncIO.h
index 2bb5735..2bcae4c 100644
--- a/media/mtp/PosixAsyncIO.h
+++ b/media/mtp/PosixAsyncIO.h
@@ -32,7 +32,7 @@
     int aio_fildes;
     void *aio_buf;
 
-    off_t aio_offset;
+    off64_t aio_offset;
     size_t aio_nbytes;
 
     // Used internally
@@ -61,7 +61,7 @@
 ssize_t aio_return(struct aiocb *);
 
 // Helper method for setting aiocb members
-void aio_prepare(struct aiocb *, void*, size_t, off_t);
+void aio_prepare(struct aiocb *, void*, size_t, off64_t);
 
 #endif // POSIXASYNCIO_H
 
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 1b8ddd9..f23da9a 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -65,10 +65,11 @@
     ],
 
     shared_libs: [
+        "libandroid_runtime_lazy",
         "libbinder",
         "libmedia",
         "libmedia_omx",
-        "libmedia_jni",
+        "libmedia_jni_utils",
         "libmediadrm",
         "libmediaextractor",
         "libstagefright",
@@ -76,13 +77,18 @@
         "liblog",
         "libutils",
         "libcutils",
-        "libandroid",
-        "libandroid_runtime",
+        "libnativewindow",
         "libbinder",
         "libgui",
         "libui",
     ],
 
+    required: [
+        // libmediandk may be used by Java and non-Java things. When lower-level things use it,
+        // they shouldn't have to take on the cost of loading libandroid_runtime.
+        "libandroid_runtime",
+    ],
+
     export_include_dirs: ["include"],
 
     product_variables: {
diff --git a/media/ndk/NdkImage.cpp b/media/ndk/NdkImage.cpp
index 20b1667..1883f63 100644
--- a/media/ndk/NdkImage.cpp
+++ b/media/ndk/NdkImage.cpp
@@ -23,7 +23,7 @@
 #include "NdkImageReaderPriv.h"
 
 #include <android_media_Utils.h>
-#include <android_runtime/android_hardware_HardwareBuffer.h>
+#include <private/android/AHardwareBufferHelpers.h>
 #include <utils/Log.h>
 #include "hardware/camera3.h"
 
@@ -190,7 +190,7 @@
 
     auto lockedBuffer = std::make_unique<CpuConsumer::LockedBuffer>();
 
-    uint64_t grallocUsage = android_hardware_HardwareBuffer_convertToGrallocUsageBits(mUsage);
+    uint64_t grallocUsage = AHardwareBuffer_convertToGrallocUsageBits(mUsage);
 
     status_t ret =
             lockImageFromBuffer(mBuffer, grallocUsage, mBuffer->mFence->dup(), lockedBuffer.get());
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index be635ff..9d00df6 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -25,8 +25,8 @@
 #include <cutils/atomic.h>
 #include <utils/Log.h>
 #include <android_media_Utils.h>
-#include <android_runtime/android_view_Surface.h>
-#include <android_runtime/android_hardware_HardwareBuffer.h>
+#include <ui/PublicFormat.h>
+#include <private/android/AHardwareBufferHelpers.h>
 #include <grallocusage/GrallocUsageConversion.h>
 
 using namespace android;
@@ -261,9 +261,9 @@
 media_status_t
 AImageReader::init() {
     PublicFormat publicFormat = static_cast<PublicFormat>(mFormat);
-    mHalFormat = android_view_Surface_mapPublicFormatToHalFormat(publicFormat);
-    mHalDataSpace = android_view_Surface_mapPublicFormatToHalDataspace(publicFormat);
-    mHalUsage = android_hardware_HardwareBuffer_convertToGrallocUsageBits(mUsage);
+    mHalFormat = mapPublicFormatToHalFormat(publicFormat);
+    mHalDataSpace = mapPublicFormatToHalDataspace(publicFormat);
+    mHalUsage = AHardwareBuffer_convertToGrallocUsageBits(mUsage);
 
     sp<IGraphicBufferProducer> gbProducer;
     sp<IGraphicBufferConsumer> gbConsumer;
diff --git a/media/ndk/NdkMediaCrypto.cpp b/media/ndk/NdkMediaCrypto.cpp
index d7193ca..00d4520 100644
--- a/media/ndk/NdkMediaCrypto.cpp
+++ b/media/ndk/NdkMediaCrypto.cpp
@@ -29,7 +29,6 @@
 #include <binder/IServiceManager.h>
 #include <media/ICrypto.h>
 #include <media/IMediaDrmService.h>
-#include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index f32b83e..20707cc 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -25,7 +25,6 @@
 #include <utils/StrongPointer.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>
diff --git a/media/ndk/NdkMediaMuxer.cpp b/media/ndk/NdkMediaMuxer.cpp
index dffc4d7..44cafb2 100644
--- a/media/ndk/NdkMediaMuxer.cpp
+++ b/media/ndk/NdkMediaMuxer.cpp
@@ -29,7 +29,6 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaMuxer.h>
 #include <media/IMediaHTTPService.h>
-#include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index d6dae5b..c918941 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -35,6 +35,11 @@
         "-Werror",
     ],
 
+    include_dirs: [
+        // For android_mallopt definitions.
+        "bionic/libc/private"
+    ],
+
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
 }
diff --git a/media/utils/MemoryLeakTrackUtil.cpp b/media/utils/MemoryLeakTrackUtil.cpp
index 18f5f25..2988b52 100644
--- a/media/utils/MemoryLeakTrackUtil.cpp
+++ b/media/utils/MemoryLeakTrackUtil.cpp
@@ -22,6 +22,8 @@
 #include "media/MemoryLeakTrackUtil.h"
 #include <sstream>
 
+#include <bionic_malloc.h>
+
 /*
  * The code here originally resided in MediaPlayerService.cpp
  */
@@ -47,29 +49,22 @@
 
 namespace android {
 
-extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
-        size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
-
-extern "C" void free_malloc_leak_info(uint8_t* info);
-
 std::string dumpMemoryAddresses(size_t limit)
 {
-    uint8_t *info;
-    size_t overallSize;
-    size_t infoSize;
-    size_t totalMemory;
-    size_t backtraceSize;
-    get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize);
+    android_mallopt_leak_info_t leak_info;
+    if (!android_mallopt(M_GET_MALLOC_LEAK_INFO, &leak_info, sizeof(leak_info))) {
+      return "";
+    }
 
     size_t count;
-    if (info == nullptr || overallSize == 0 || infoSize == 0
-            || (count = overallSize / infoSize) == 0) {
+    if (leak_info.buffer == nullptr || leak_info.overall_size == 0 || leak_info.info_size == 0
+            || (count = leak_info.overall_size / leak_info.info_size) == 0) {
         ALOGD("no malloc info, libc.debug.malloc.program property should be set");
-        return std::string();
+        return "";
     }
 
     std::ostringstream oss;
-    oss << totalMemory << " bytes in " << count << " allocations\n";
+    oss << leak_info.total_memory << " bytes in " << count << " allocations\n";
     oss << "  ABI: '" ABI_STRING "'" << "\n\n";
     if (count > limit) count = limit;
 
@@ -83,14 +78,14 @@
             uintptr_t backtrace[];
         };
 
-        const AllocEntry * const e = (AllocEntry *)(info + i * infoSize);
+        const AllocEntry * const e = (AllocEntry *)(leak_info.buffer + i * leak_info.info_size);
 
         oss << (e->size * e->allocations)
                 << " bytes ( " << e->size << " bytes * " << e->allocations << " allocations )\n";
-        oss << backtrace_string(e->backtrace, backtraceSize) << "\n";
+        oss << backtrace_string(e->backtrace, leak_info.backtrace_size) << "\n";
     }
     oss << "\n";
-    free_malloc_leak_info(info);
+    android_mallopt(M_FREE_MALLOC_LEAK_INFO, &leak_info, sizeof(leak_info));
     return oss.str();
 }
 
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index bdd39c6..687b5a6 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3001,6 +3001,8 @@
     }
 
     {
+        Mutex::Autolock _l(mLock);
+
         if (!EffectsFactoryHalInterface::isNullUuid(&pDesc->uuid)) {
             // if uuid is specified, request effect descriptor
             lStatus = mEffectsFactoryHal->getDescriptor(&pDesc->uuid, &desc);
@@ -3056,6 +3058,8 @@
                 desc = d;
             }
         }
+    }
+    {
 
         // Do not allow auxiliary effects on a session different from 0 (output mix)
         if (sessionId != AUDIO_SESSION_OUTPUT_MIX &&
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index fbc2384..390ea36 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "APM::IOProfile"
 //#define LOG_NDEBUG 0
 
+#include <system/audio-base.h>
 #include "IOProfile.h"
 #include "HwModule.h"
 #include "AudioGain.h"
@@ -66,19 +67,23 @@
     audio_format_t myUpdatedFormat = format;
     audio_channel_mask_t myUpdatedChannelMask = channelMask;
     uint32_t myUpdatedSamplingRate = samplingRate;
+    const struct audio_port_config config = {
+        .config_mask = AUDIO_PORT_CONFIG_ALL & ~AUDIO_PORT_CONFIG_GAIN,
+        .sample_rate = samplingRate,
+        .channel_mask = channelMask,
+        .format = format,
+    };
     if (isRecordThread)
     {
-        if (checkCompatibleAudioProfile(
+        if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
+            if (checkExactAudioProfile(&config) != NO_ERROR) {
+                return false;
+            }
+        } else if (checkCompatibleAudioProfile(
                 myUpdatedSamplingRate, myUpdatedChannelMask, myUpdatedFormat) != NO_ERROR) {
             return false;
         }
     } else {
-        const struct audio_port_config config = {
-            .config_mask = AUDIO_PORT_CONFIG_ALL & ~AUDIO_PORT_CONFIG_GAIN,
-            .sample_rate = samplingRate,
-            .channel_mask = channelMask,
-            .format = format,
-        };
         if (checkExactAudioProfile(&config) != NO_ERROR) {
             return false;
         }
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index ba0244e..8a752b1 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2027,31 +2027,37 @@
     return mp;
 }
 
-void CameraService::loadSound() {
+void CameraService::increaseSoundRef() {
+    Mutex::Autolock lock(mSoundLock);
+    mSoundRef++;
+}
+
+void CameraService::loadSoundLocked(sound_kind kind) {
     ATRACE_CALL();
 
-    Mutex::Autolock lock(mSoundLock);
-    LOG1("CameraService::loadSound ref=%d", mSoundRef);
-    if (mSoundRef++) return;
-
-    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
-    if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
-        mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
-    }
-    mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
-    if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
-        mSoundPlayer[SOUND_RECORDING_START] =
+    LOG1("CameraService::loadSoundLocked ref=%d", mSoundRef);
+    if (SOUND_SHUTTER == kind && mSoundPlayer[SOUND_SHUTTER] == NULL) {
+        mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
+        if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
+            mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
+        }
+    } else if (SOUND_RECORDING_START == kind && mSoundPlayer[SOUND_RECORDING_START] ==  NULL) {
+        mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
+        if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
+            mSoundPlayer[SOUND_RECORDING_START] =
                 newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
-    }
-    mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
-    if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
-        mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
+        }
+    } else if (SOUND_RECORDING_STOP == kind && mSoundPlayer[SOUND_RECORDING_STOP] == NULL) {
+        mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
+        if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
+            mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
+        }
     }
 }
 
-void CameraService::releaseSound() {
+void CameraService::decreaseSoundRef() {
     Mutex::Autolock lock(mSoundLock);
-    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
+    LOG1("CameraService::decreaseSoundRef ref=%d", mSoundRef);
     if (--mSoundRef) return;
 
     for (int i = 0; i < NUM_SOUNDS; i++) {
@@ -2067,6 +2073,7 @@
 
     LOG1("playSound(%d)", kind);
     Mutex::Autolock lock(mSoundLock);
+    loadSoundLocked(kind);
     sp<MediaPlayer> player = mSoundPlayer[kind];
     if (player != 0) {
         player->seekTo(0);
@@ -2096,7 +2103,7 @@
 
     mRemoteCallback = cameraClient;
 
-    cameraService->loadSound();
+    cameraService->increaseSoundRef();
 
     LOG1("Client::Client X (pid %d, id %d)", callingPid, mCameraId);
 }
@@ -2106,7 +2113,7 @@
     ALOGV("~Client");
     mDestructionStarted = true;
 
-    sCameraService->releaseSound();
+    sCameraService->decreaseSoundRef();
     // unconditionally disconnect. function is idempotent
     Client::disconnect();
 }
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 624d1ca..991c770 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -177,10 +177,10 @@
         NUM_SOUNDS
     };
 
-    void                loadSound();
     void                playSound(sound_kind kind);
-    void                releaseSound();
-
+    void                loadSoundLocked(sound_kind kind);
+    void                decreaseSoundRef();
+    void                increaseSoundRef();
     /**
      * Update the state of a given camera device (open/close/active/idle) with
      * the camera proxy service in the system service
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 274bbc2..6106674 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -323,7 +323,7 @@
     // so. As documented in hardware/camera3.h:configure_streams().
     if (mState == STATE_IN_RECONFIG &&
             mOldUsage == mUsage &&
-            mOldMaxBuffers == camera3_stream::max_buffers) {
+            mOldMaxBuffers == camera3_stream::max_buffers && !mDataSpaceOverridden) {
         mState = STATE_CONFIGURED;
         return OK;
     }
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
index 5342898..4fa05c3 100644
--- a/services/mediaextractor/Android.mk
+++ b/services/mediaextractor/Android.mk
@@ -35,7 +35,6 @@
 LOCAL_SRC_FILES := main_extractorservice.cpp
 LOCAL_SHARED_LIBRARIES := libmedia libmediaextractorservice libbinder libutils \
     liblog libbase libandroidicu libavservices_minijail
-LOCAL_STATIC_LIBRARIES := libicuandroid_utils
 LOCAL_MODULE:= mediaextractor
 LOCAL_INIT_RC := mediaextractor.rc
 LOCAL_C_INCLUDES := frameworks/av/media/libmedia
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index 8d3359a..8655138 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -15,6 +15,7 @@
 ** limitations under the License.
 */
 
+#include <aicu/AIcu.h>
 #include <fcntl.h>
 #include <sys/prctl.h>
 #include <sys/wait.h>
@@ -29,7 +30,6 @@
 #include <utils/misc.h>
 
 // from LOCAL_C_INCLUDES
-#include "IcuUtils.h"
 #include "MediaExtractorService.h"
 #include "MediaExtractorUpdateService.h"
 #include "MediaUtils.h"
@@ -59,7 +59,7 @@
 
     SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
 
-    InitializeIcuOrDie();
+    AIcu_initializeIcuOrDie();
 
     strcpy(argv[0], "media.extractor");
     sp<ProcessState> proc(ProcessState::self());
diff --git a/services/mediaextractor/mediaextractor.rc b/services/mediaextractor/mediaextractor.rc
index 6b2d0a5..5fc2941 100644
--- a/services/mediaextractor/mediaextractor.rc
+++ b/services/mediaextractor/mediaextractor.rc
@@ -2,7 +2,5 @@
     class main
     user mediaex
     group drmrpc mediadrm
-    # TODO(b/123275379): Remove updatable when http://aosp/878198 has landed
-    updatable
     ioprio rt 4
     writepid /dev/cpuset/foreground/tasks
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
index 87018ed..964acf4 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
@@ -14,6 +14,7 @@
 setpriority: 1
 sigaltstack: 1
 openat: 1
+open: 1
 clone: 1
 read: 1
 clock_gettime: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
index d739ba1..56ad8df 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
@@ -11,6 +11,7 @@
 mmap2: 1
 madvise: 1
 openat: 1
+open: 1
 clock_gettime: 1
 writev: 1
 brk: 1