Merge "MediaMetrics: Add thread-safety checking" into rvc-dev
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index ebc7a8f..74e105e 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -67,8 +67,9 @@
       mLastTimestamp(0x7FFFFFFFFFFFFFFFull),
       mSignalledOutputEos(false),
       mSignalledError(false) {
-    memset(mTemporalLayerBitrateRatio, 0, sizeof(mTemporalLayerBitrateRatio));
-    mTemporalLayerBitrateRatio[0] = 100;
+    for (int i = 0; i < MAXTEMPORALLAYERS; i++) {
+        mTemporalLayerBitrateRatio[i] = 1.0f;
+    }
 }
 
 C2SoftVpxEnc::~C2SoftVpxEnc() {
@@ -123,7 +124,8 @@
         mFrameRate = mIntf->getFrameRate_l();
         mIntraRefresh = mIntf->getIntraRefresh_l();
         mRequestSync = mIntf->getRequestSync_l();
-        mTemporalLayers = mIntf->getTemporalLayers_l()->m.layerCount;
+        mLayering = mIntf->getTemporalLayers_l();
+        mTemporalLayers = mLayering->m.layerCount;
     }
 
     switch (mBitrateMode->value) {
@@ -225,6 +227,7 @@
             mTemporalPattern[5] = kTemporalUpdateGoldenRefAltRef;
             mTemporalPattern[6] = kTemporalUpdateLastRefAltRef;
             mTemporalPattern[7] = kTemporalUpdateNone;
+            mTemporalLayerBitrateRatio[0] = mLayering->m.bitrateRatios[0];
             mTemporalPatternLength = 8;
             break;
         case 3:
@@ -245,6 +248,8 @@
             mTemporalPattern[5] = kTemporalUpdateNone;
             mTemporalPattern[6] = kTemporalUpdateGoldenRefAltRef;
             mTemporalPattern[7] = kTemporalUpdateNone;
+            mTemporalLayerBitrateRatio[0] = mLayering->m.bitrateRatios[0];
+            mTemporalLayerBitrateRatio[1] = mLayering->m.bitrateRatios[1];
             mTemporalPatternLength = 8;
             break;
         default:
@@ -255,7 +260,7 @@
     for (size_t i = 0; i < mCodecConfiguration->ts_number_layers; i++) {
         mCodecConfiguration->ts_target_bitrate[i] =
             mCodecConfiguration->rc_target_bitrate *
-            mTemporalLayerBitrateRatio[i] / 100;
+            mTemporalLayerBitrateRatio[i];
     }
     if (mIntf->getSyncFramePeriod() >= 0) {
         mCodecConfiguration->kf_max_dist = mIntf->getSyncFramePeriod();
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.h b/media/codec2/components/vpx/C2SoftVpxEnc.h
index 62ccd1b..5e34b8a 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.h
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.h
@@ -180,7 +180,7 @@
      size_t mTemporalLayers;
 
      // Temporal layer bitrare ratio in percentage
-     uint32_t mTemporalLayerBitrateRatio[MAXTEMPORALLAYERS];
+     float_t mTemporalLayerBitrateRatio[MAXTEMPORALLAYERS];
 
      // Temporal pattern type
      TemporalPatternType mTemporalPatternType;
@@ -218,6 +218,7 @@
     std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
     std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
     std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
+    std::shared_ptr<C2StreamTemporalLayeringTuning::output> mLayering;
 
      C2_DO_NOT_COPY(C2SoftVpxEnc);
 };
diff --git a/media/libaaudio/src/client/AudioEndpoint.cpp b/media/libaaudio/src/client/AudioEndpoint.cpp
index 214f888..06f66d3 100644
--- a/media/libaaudio/src/client/AudioEndpoint.cpp
+++ b/media/libaaudio/src/client/AudioEndpoint.cpp
@@ -32,19 +32,12 @@
 #define RIDICULOUSLY_LARGE_FRAME_SIZE        4096
 
 AudioEndpoint::AudioEndpoint()
-    : mUpCommandQueue(nullptr)
-    , mDataQueue(nullptr)
-    , mFreeRunning(false)
+    : mFreeRunning(false)
     , mDataReadCounter(0)
     , mDataWriteCounter(0)
 {
 }
 
-AudioEndpoint::~AudioEndpoint() {
-    delete mDataQueue;
-    delete mUpCommandQueue;
-}
-
 // TODO Consider moving to a method in RingBufferDescriptor
 static aaudio_result_t AudioEndpoint_validateQueueDescriptor(const char *type,
                                                   const RingBufferDescriptor *descriptor) {
@@ -144,7 +137,7 @@
         return AAUDIO_ERROR_INTERNAL;
     }
 
-    mUpCommandQueue = new FifoBuffer(
+    mUpCommandQueue = std::make_unique<FifoBuffer>(
             descriptor->bytesPerFrame,
             descriptor->capacityInFrames,
             descriptor->readCounterAddress,
@@ -173,7 +166,7 @@
                                   ? &mDataWriteCounter
                                   : descriptor->writeCounterAddress;
 
-    mDataQueue = new FifoBuffer(
+    mDataQueue = std::make_unique<FifoBuffer>(
             descriptor->bytesPerFrame,
             descriptor->capacityInFrames,
             readCounterAddress,
@@ -194,18 +187,15 @@
     return mDataQueue->getEmptyRoomAvailable(wrappingBuffer);
 }
 
-int32_t AudioEndpoint::getEmptyFramesAvailable()
-{
+int32_t AudioEndpoint::getEmptyFramesAvailable() {
     return mDataQueue->getEmptyFramesAvailable();
 }
 
-int32_t AudioEndpoint::getFullFramesAvailable(WrappingBuffer *wrappingBuffer)
-{
+int32_t AudioEndpoint::getFullFramesAvailable(WrappingBuffer *wrappingBuffer) {
     return mDataQueue->getFullDataAvailable(wrappingBuffer);
 }
 
-int32_t AudioEndpoint::getFullFramesAvailable()
-{
+int32_t AudioEndpoint::getFullFramesAvailable() {
     return mDataQueue->getFullFramesAvailable();
 }
 
@@ -217,29 +207,24 @@
     mDataQueue->advanceReadIndex(deltaFrames);
 }
 
-void AudioEndpoint::setDataReadCounter(fifo_counter_t framesRead)
-{
+void AudioEndpoint::setDataReadCounter(fifo_counter_t framesRead) {
     mDataQueue->setReadCounter(framesRead);
 }
 
-fifo_counter_t AudioEndpoint::getDataReadCounter()
-{
+fifo_counter_t AudioEndpoint::getDataReadCounter() const {
     return mDataQueue->getReadCounter();
 }
 
-void AudioEndpoint::setDataWriteCounter(fifo_counter_t framesRead)
-{
+void AudioEndpoint::setDataWriteCounter(fifo_counter_t framesRead) {
     mDataQueue->setWriteCounter(framesRead);
 }
 
-fifo_counter_t AudioEndpoint::getDataWriteCounter()
-{
+fifo_counter_t AudioEndpoint::getDataWriteCounter() const {
     return mDataQueue->getWriteCounter();
 }
 
 int32_t AudioEndpoint::setBufferSizeInFrames(int32_t requestedFrames,
-                                            int32_t *actualFrames)
-{
+                                            int32_t *actualFrames) {
     if (requestedFrames < ENDPOINT_DATA_QUEUE_SIZE_MIN) {
         requestedFrames = ENDPOINT_DATA_QUEUE_SIZE_MIN;
     }
@@ -248,19 +233,17 @@
     return AAUDIO_OK;
 }
 
-int32_t AudioEndpoint::getBufferSizeInFrames() const
-{
+int32_t AudioEndpoint::getBufferSizeInFrames() const {
     return mDataQueue->getThreshold();
 }
 
-int32_t AudioEndpoint::getBufferCapacityInFrames() const
-{
+int32_t AudioEndpoint::getBufferCapacityInFrames() const {
     return (int32_t)mDataQueue->getBufferCapacityInFrames();
 }
 
 void AudioEndpoint::dump() const {
-    ALOGD("data readCounter  = %lld", (long long) mDataQueue->getReadCounter());
-    ALOGD("data writeCounter = %lld", (long long) mDataQueue->getWriteCounter());
+    ALOGD("data readCounter  = %lld", (long long) getDataReadCounter());
+    ALOGD("data writeCounter = %lld", (long long) getDataWriteCounter());
 }
 
 void AudioEndpoint::eraseDataMemory() {
diff --git a/media/libaaudio/src/client/AudioEndpoint.h b/media/libaaudio/src/client/AudioEndpoint.h
index f5b67e8..484d917 100644
--- a/media/libaaudio/src/client/AudioEndpoint.h
+++ b/media/libaaudio/src/client/AudioEndpoint.h
@@ -35,7 +35,6 @@
 
 public:
     AudioEndpoint();
-    virtual ~AudioEndpoint();
 
     /**
      * Configure based on the EndPointDescriptor_t.
@@ -67,11 +66,11 @@
      */
     void setDataReadCounter(android::fifo_counter_t framesRead);
 
-    android::fifo_counter_t getDataReadCounter();
+    android::fifo_counter_t getDataReadCounter() const;
 
     void setDataWriteCounter(android::fifo_counter_t framesWritten);
 
-    android::fifo_counter_t getDataWriteCounter();
+    android::fifo_counter_t getDataWriteCounter() const;
 
     /**
      * The result is not valid until after configure() is called.
@@ -94,8 +93,8 @@
     void dump() const;
 
 private:
-    android::FifoBuffer    *mUpCommandQueue;
-    android::FifoBuffer    *mDataQueue;
+    std::unique_ptr<android::FifoBuffer> mUpCommandQueue;
+    std::unique_ptr<android::FifoBuffer> mDataQueue;
     bool                    mFreeRunning;
     android::fifo_counter_t mDataReadCounter; // only used if free-running
     android::fifo_counter_t mDataWriteCounter; // only used if free-running
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 6723ec9..f89cde7 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -58,7 +58,6 @@
 AudioStreamInternal::AudioStreamInternal(AAudioServiceInterface  &serviceInterface, bool inService)
         : AudioStream()
         , mClockModel()
-        , mAudioEndpoint()
         , mServiceStreamHandle(AAUDIO_HANDLE_INVALID)
         , mInService(inService)
         , mServiceInterface(serviceInterface)
@@ -74,7 +73,6 @@
 aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
 
     aaudio_result_t result = AAUDIO_OK;
-    int32_t capacity;
     int32_t framesPerBurst;
     int32_t framesPerHardwareBurst;
     AAudioStreamRequest request;
@@ -173,7 +171,8 @@
     }
 
     // Configure endpoint based on descriptor.
-    result = mAudioEndpoint.configure(&mEndpointDescriptor, getDirection());
+    mAudioEndpoint = std::make_unique<AudioEndpoint>();
+    result = mAudioEndpoint->configure(&mEndpointDescriptor, getDirection());
     if (result != AAUDIO_OK) {
         goto error;
     }
@@ -201,9 +200,10 @@
     }
     mFramesPerBurst = framesPerBurst; // only save good value
 
-    capacity = mEndpointDescriptor.dataQueueDescriptor.capacityInFrames;
-    if (capacity < mFramesPerBurst || capacity > MAX_BUFFER_CAPACITY_IN_FRAMES) {
-        ALOGE("%s - bufferCapacity out of range = %d", __func__, capacity);
+    mBufferCapacityInFrames = mEndpointDescriptor.dataQueueDescriptor.capacityInFrames;
+    if (mBufferCapacityInFrames < mFramesPerBurst
+            || mBufferCapacityInFrames > MAX_BUFFER_CAPACITY_IN_FRAMES) {
+        ALOGE("%s - bufferCapacity out of range = %d", __func__, mBufferCapacityInFrames);
         result = AAUDIO_ERROR_OUT_OF_RANGE;
         goto error;
     }
@@ -230,7 +230,7 @@
         }
 
         const int32_t callbackBufferSize = mCallbackFrames * getBytesPerFrame();
-        mCallbackBuffer = new uint8_t[callbackBufferSize];
+        mCallbackBuffer = std::make_unique<uint8_t[]>(callbackBufferSize);
     }
 
     // For debugging and analyzing the distribution of MMAP timestamps.
@@ -239,7 +239,7 @@
     // You can use this offset to reduce glitching.
     // You can also use this offset to force glitching. By iterating over multiple
     // values you can reveal the distribution of the hardware timing jitter.
-    if (mAudioEndpoint.isFreeRunning()) { // MMAP?
+    if (mAudioEndpoint->isFreeRunning()) { // MMAP?
         int32_t offsetMicros = (getDirection() == AAUDIO_DIRECTION_OUTPUT)
                 ? AAudioProperty_getOutputMMapOffsetMicros()
                 : AAudioProperty_getInputMMapOffsetMicros();
@@ -251,7 +251,7 @@
         mTimeOffsetNanos = offsetMicros * AAUDIO_NANOS_PER_MICROSECOND;
     }
 
-    setBufferSize(capacity / 2); // Default buffer size to match Q
+    setBufferSize(mBufferCapacityInFrames / 2); // Default buffer size to match Q
 
     setState(AAUDIO_STREAM_STATE_OPEN);
 
@@ -279,8 +279,12 @@
         mServiceStreamHandle = AAUDIO_HANDLE_INVALID;
 
         mServiceInterface.closeStream(serviceStreamHandle);
-        delete[] mCallbackBuffer;
-        mCallbackBuffer = nullptr;
+        mCallbackBuffer.reset();
+
+        // Update local frame counters so we can query them after releasing the endpoint.
+        getFramesRead();
+        getFramesWritten();
+        mAudioEndpoint.reset();
         result = mEndPointParcelable.close();
         aaudio_result_t result2 = AudioStream::release_l();
         return (result != AAUDIO_OK) ? result : result2;
@@ -539,7 +543,7 @@
         case AAUDIO_SERVICE_EVENT_DISCONNECTED:
             // Prevent hardware from looping on old data and making buzzing sounds.
             if (getDirection() == AAUDIO_DIRECTION_OUTPUT) {
-                mAudioEndpoint.eraseDataMemory();
+                mAudioEndpoint->eraseDataMemory();
             }
             result = AAUDIO_ERROR_DISCONNECTED;
             setState(AAUDIO_STREAM_STATE_DISCONNECTED);
@@ -565,7 +569,10 @@
 
     while (result == AAUDIO_OK) {
         AAudioServiceMessage message;
-        if (mAudioEndpoint.readUpCommand(&message) != 1) {
+        if (!mAudioEndpoint) {
+            break;
+        }
+        if (mAudioEndpoint->readUpCommand(&message) != 1) {
             break; // no command this time, no problem
         }
         switch (message.what) {
@@ -593,7 +600,10 @@
 
     while (result == AAUDIO_OK) {
         AAudioServiceMessage message;
-        if (mAudioEndpoint.readUpCommand(&message) != 1) {
+        if (!mAudioEndpoint) {
+            break;
+        }
+        if (mAudioEndpoint->readUpCommand(&message) != 1) {
             break; // no command this time, no problem
         }
         switch (message.what) {
@@ -626,7 +636,7 @@
     const char * fifoName = "aaRdy";
     ATRACE_BEGIN(traceName);
     if (ATRACE_ENABLED()) {
-        int32_t fullFrames = mAudioEndpoint.getFullFramesAvailable();
+        int32_t fullFrames = mAudioEndpoint->getFullFramesAvailable();
         ATRACE_INT(fifoName, fullFrames);
     }
 
@@ -655,7 +665,7 @@
         if (timeoutNanoseconds == 0) {
             break; // don't block
         } else if (wakeTimeNanos != 0) {
-            if (!mAudioEndpoint.isFreeRunning()) {
+            if (!mAudioEndpoint->isFreeRunning()) {
                 // If there is software on the other end of the FIFO then it may get delayed.
                 // So wake up just a little after we expect it to be ready.
                 wakeTimeNanos += mWakeupDelayNanos;
@@ -680,12 +690,12 @@
                 ALOGW("processData(): past deadline by %d micros",
                       (int)((wakeTimeNanos - deadlineNanos) / AAUDIO_NANOS_PER_MICROSECOND));
                 mClockModel.dump();
-                mAudioEndpoint.dump();
+                mAudioEndpoint->dump();
                 break;
             }
 
             if (ATRACE_ENABLED()) {
-                int32_t fullFrames = mAudioEndpoint.getFullFramesAvailable();
+                int32_t fullFrames = mAudioEndpoint->getFullFramesAvailable();
                 ATRACE_INT(fifoName, fullFrames);
                 int64_t sleepForNanos = wakeTimeNanos - currentTimeNanos;
                 ATRACE_INT("aaSlpNs", (int32_t)sleepForNanos);
@@ -697,7 +707,7 @@
     }
 
     if (ATRACE_ENABLED()) {
-        int32_t fullFrames = mAudioEndpoint.getFullFramesAvailable();
+        int32_t fullFrames = mAudioEndpoint->getFullFramesAvailable();
         ATRACE_INT(fifoName, fullFrames);
     }
 
@@ -731,11 +741,15 @@
         adjustedFrames = std::min(maximumSize, adjustedFrames);
     }
 
-    // Clip against the actual size from the endpoint.
-    int32_t actualFrames = 0;
-    mAudioEndpoint.setBufferSizeInFrames(maximumSize, &actualFrames);
-    // actualFrames should be <= actual maximum size of endpoint
-    adjustedFrames = std::min(actualFrames, adjustedFrames);
+    if (mAudioEndpoint) {
+        // Clip against the actual size from the endpoint.
+        int32_t actualFrames = 0;
+        // Set to maximum size so we can write extra data when ready in order to reduce glitches.
+        // The amount we keep in the buffer is controlled by mBufferSizeInFrames.
+        mAudioEndpoint->setBufferSizeInFrames(maximumSize, &actualFrames);
+        // actualFrames should be <= actual maximum size of endpoint
+        adjustedFrames = std::min(actualFrames, adjustedFrames);
+    }
 
     mBufferSizeInFrames = adjustedFrames;
     ALOGV("%s(%d) returns %d", __func__, requestedFrames, adjustedFrames);
@@ -747,7 +761,7 @@
 }
 
 int32_t AudioStreamInternal::getBufferCapacity() const {
-    return mAudioEndpoint.getBufferCapacityInFrames();
+    return mBufferCapacityInFrames;
 }
 
 int32_t AudioStreamInternal::getFramesPerBurst() const {
@@ -760,5 +774,5 @@
 }
 
 bool AudioStreamInternal::isClockModelInControl() const {
-    return isActive() && mAudioEndpoint.isFreeRunning() && mClockModel.isRunning();
+    return isActive() && mAudioEndpoint->isFreeRunning() && mClockModel.isRunning();
 }
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 095f30c..61591b3 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -155,7 +155,8 @@
 
     IsochronousClockModel    mClockModel;      // timing model for chasing the HAL
 
-    AudioEndpoint            mAudioEndpoint;   // source for reads or sink for writes
+    std::unique_ptr<AudioEndpoint> mAudioEndpoint;   // source for reads or sink for writes
+
     aaudio_handle_t          mServiceStreamHandle; // opaque handle returned from service
 
     int32_t                  mFramesPerBurst = MIN_FRAMES_PER_BURST; // frames per HAL transfer
@@ -164,7 +165,7 @@
     // Offset from underlying frame position.
     int64_t                  mFramesOffsetFromService = 0; // offset for timestamps
 
-    uint8_t                 *mCallbackBuffer = nullptr;
+    std::unique_ptr<uint8_t[]> mCallbackBuffer;
     int32_t                  mCallbackFrames = 0;
 
     // The service uses this for SHARED mode.
@@ -178,6 +179,9 @@
 
     float                    mStreamVolume = 1.0f;
 
+    int64_t                  mLastFramesWritten = 0;
+    int64_t                  mLastFramesRead = 0;
+
 private:
     /*
      * Asynchronous write with data conversion.
@@ -207,6 +211,8 @@
     int32_t                  mDeviceChannelCount = 0;
 
     int32_t                  mBufferSizeInFrames = 0; // local threshold to control latency
+    int32_t                  mBufferCapacityInFrames = 0;
+
 
 };
 
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index 9684ee4..9fa2e40 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -42,8 +42,8 @@
 AudioStreamInternalCapture::~AudioStreamInternalCapture() {}
 
 void AudioStreamInternalCapture::advanceClientToMatchServerPosition() {
-    int64_t readCounter = mAudioEndpoint.getDataReadCounter();
-    int64_t writeCounter = mAudioEndpoint.getDataWriteCounter();
+    int64_t readCounter = mAudioEndpoint->getDataReadCounter();
+    int64_t writeCounter = mAudioEndpoint->getDataWriteCounter();
 
     // Bump offset so caller does not see the retrograde motion in getFramesRead().
     int64_t offset = readCounter - writeCounter;
@@ -53,7 +53,7 @@
 
     // Force readCounter to match writeCounter.
     // This is because we cannot change the write counter in the hardware.
-    mAudioEndpoint.setDataReadCounter(writeCounter);
+    mAudioEndpoint->setDataReadCounter(writeCounter);
 }
 
 // Write the data, block if needed and timeoutMillis > 0
@@ -86,7 +86,7 @@
     }
     // If we have gotten this far then we have at least one timestamp from server.
 
-    if (mAudioEndpoint.isFreeRunning()) {
+    if (mAudioEndpoint->isFreeRunning()) {
         //ALOGD("AudioStreamInternalCapture::processDataNow() - update remote counter");
         // Update data queue based on the timing model.
         // Jitter in the DSP can cause late writes to the FIFO.
@@ -95,7 +95,7 @@
         // that the DSP could have written the data.
         int64_t estimatedRemoteCounter = mClockModel.convertLatestTimeToPosition(currentNanoTime);
         // TODO refactor, maybe use setRemoteCounter()
-        mAudioEndpoint.setDataWriteCounter(estimatedRemoteCounter);
+        mAudioEndpoint->setDataWriteCounter(estimatedRemoteCounter);
     }
 
     // This code assumes that we have already received valid timestamps.
@@ -108,8 +108,8 @@
 
     // If the capture buffer is full beyond capacity then consider it an overrun.
     // For shared streams, the xRunCount is passed up from the service.
-    if (mAudioEndpoint.isFreeRunning()
-        && mAudioEndpoint.getFullFramesAvailable() > mAudioEndpoint.getBufferCapacityInFrames()) {
+    if (mAudioEndpoint->isFreeRunning()
+        && mAudioEndpoint->getFullFramesAvailable() > mAudioEndpoint->getBufferCapacityInFrames()) {
         mXRunCount++;
         if (ATRACE_ENABLED()) {
             ATRACE_INT("aaOverRuns", mXRunCount);
@@ -143,7 +143,7 @@
                 // Calculate frame position based off of the readCounter because
                 // the writeCounter might have just advanced in the background,
                 // causing us to sleep until a later burst.
-                int64_t nextPosition = mAudioEndpoint.getDataReadCounter() + mFramesPerBurst;
+                int64_t nextPosition = mAudioEndpoint->getDataReadCounter() + mFramesPerBurst;
                 wakeTime = mClockModel.convertPositionToLatestTime(nextPosition);
             }
                 break;
@@ -166,7 +166,7 @@
     uint8_t *destination = (uint8_t *) buffer;
     int32_t framesLeft = numFrames;
 
-    mAudioEndpoint.getFullFramesAvailable(&wrappingBuffer);
+    mAudioEndpoint->getFullFramesAvailable(&wrappingBuffer);
 
     // Read data in one or two parts.
     for (int partIndex = 0; framesLeft > 0 && partIndex < WrappingBuffer::SIZE; partIndex++) {
@@ -208,26 +208,29 @@
     }
 
     int32_t framesProcessed = numFrames - framesLeft;
-    mAudioEndpoint.advanceReadIndex(framesProcessed);
+    mAudioEndpoint->advanceReadIndex(framesProcessed);
 
     //ALOGD("readNowWithConversion() returns %d", framesProcessed);
     return framesProcessed;
 }
 
 int64_t AudioStreamInternalCapture::getFramesWritten() {
-    const int64_t framesWrittenHardware = isClockModelInControl()
-            ? mClockModel.convertTimeToPosition(AudioClock::getNanoseconds())
-            : mAudioEndpoint.getDataWriteCounter();
-    // Add service offset and prevent retrograde motion.
-    mLastFramesWritten = std::max(mLastFramesWritten,
-                                  framesWrittenHardware + mFramesOffsetFromService);
+    if (mAudioEndpoint) {
+        const int64_t framesWrittenHardware = isClockModelInControl()
+                ? mClockModel.convertTimeToPosition(AudioClock::getNanoseconds())
+                : mAudioEndpoint->getDataWriteCounter();
+        // Add service offset and prevent retrograde motion.
+        mLastFramesWritten = std::max(mLastFramesWritten,
+                                      framesWrittenHardware + mFramesOffsetFromService);
+    }
     return mLastFramesWritten;
 }
 
 int64_t AudioStreamInternalCapture::getFramesRead() {
-    int64_t frames = mAudioEndpoint.getDataReadCounter() + mFramesOffsetFromService;
-    //ALOGD("getFramesRead() returns %lld", (long long)frames);
-    return frames;
+    if (mAudioEndpoint) {
+        mLastFramesRead = mAudioEndpoint->getDataReadCounter() + mFramesOffsetFromService;
+    }
+    return mLastFramesRead;
 }
 
 // Read data from the stream and pass it to the callback for processing.
@@ -243,7 +246,7 @@
         int64_t timeoutNanos = calculateReasonableTimeout(mCallbackFrames);
 
         // This is a BLOCKING READ!
-        result = read(mCallbackBuffer, mCallbackFrames, timeoutNanos);
+        result = read(mCallbackBuffer.get(), mCallbackFrames, timeoutNanos);
         if ((result != mCallbackFrames)) {
             ALOGE("callbackLoop: read() returned %d", result);
             if (result >= 0) {
@@ -255,7 +258,7 @@
         }
 
         // Call application using the AAudio callback interface.
-        callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
+        callbackResult = maybeCallDataCallback(mCallbackBuffer.get(), mCallbackFrames);
 
         if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
             ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.h b/media/libaaudio/src/client/AudioStreamInternalCapture.h
index 294dbaf..6436a53 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.h
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.h
@@ -68,8 +68,6 @@
      * @return frames written or negative error
      */
     aaudio_result_t readNowWithConversion(void *buffer, int32_t numFrames);
-
-    int64_t       mLastFramesWritten = 0; // used to prevent retrograde motion
 };
 
 } /* namespace aaudio */
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 536009a..1303daf 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -87,8 +87,8 @@
 }
 
 void AudioStreamInternalPlay::advanceClientToMatchServerPosition() {
-    int64_t readCounter = mAudioEndpoint.getDataReadCounter();
-    int64_t writeCounter = mAudioEndpoint.getDataWriteCounter();
+    int64_t readCounter = mAudioEndpoint->getDataReadCounter();
+    int64_t writeCounter = mAudioEndpoint->getDataWriteCounter();
 
     // Bump offset so caller does not see the retrograde motion in getFramesRead().
     int64_t offset = writeCounter - readCounter;
@@ -98,7 +98,7 @@
 
     // Force writeCounter to match readCounter.
     // This is because we cannot change the read counter in the hardware.
-    mAudioEndpoint.setDataWriteCounter(readCounter);
+    mAudioEndpoint->setDataWriteCounter(readCounter);
 }
 
 void AudioStreamInternalPlay::onFlushFromServer() {
@@ -135,11 +135,11 @@
     // If we have gotten this far then we have at least one timestamp from server.
 
     // If a DMA channel or DSP is reading the other end then we have to update the readCounter.
-    if (mAudioEndpoint.isFreeRunning()) {
+    if (mAudioEndpoint->isFreeRunning()) {
         // Update data queue based on the timing model.
         int64_t estimatedReadCounter = mClockModel.convertTimeToPosition(currentNanoTime);
         // ALOGD("AudioStreamInternal::processDataNow() - estimatedReadCounter = %d", (int)estimatedReadCounter);
-        mAudioEndpoint.setDataReadCounter(estimatedReadCounter);
+        mAudioEndpoint->setDataReadCounter(estimatedReadCounter);
     }
 
     if (mNeedCatchUp.isRequested()) {
@@ -151,7 +151,7 @@
 
     // If the read index passed the write index then consider it an underrun.
     // For shared streams, the xRunCount is passed up from the service.
-    if (mAudioEndpoint.isFreeRunning() && mAudioEndpoint.getFullFramesAvailable() < 0) {
+    if (mAudioEndpoint->isFreeRunning() && mAudioEndpoint->getFullFramesAvailable() < 0) {
         mXRunCount++;
         if (ATRACE_ENABLED()) {
             ATRACE_INT("aaUnderRuns", mXRunCount);
@@ -170,7 +170,7 @@
     // Sleep if there is too much data in the buffer.
     // Calculate an ideal time to wake up.
     if (wakeTimePtr != nullptr
-            && (mAudioEndpoint.getFullFramesAvailable() >= getBufferSize())) {
+            && (mAudioEndpoint->getFullFramesAvailable() >= getBufferSize())) {
         // By default wake up a few milliseconds from now.  // TODO review
         int64_t wakeTime = currentNanoTime + (1 * AAUDIO_NANOS_PER_MILLISECOND);
         aaudio_stream_state_t state = getState();
@@ -188,7 +188,7 @@
             {
                 // Sleep until the readCounter catches up and we only have
                 // the getBufferSize() frames of data sitting in the buffer.
-                int64_t nextReadPosition = mAudioEndpoint.getDataWriteCounter() - getBufferSize();
+                int64_t nextReadPosition = mAudioEndpoint->getDataWriteCounter() - getBufferSize();
                 wakeTime = mClockModel.convertPositionToTime(nextReadPosition);
             }
                 break;
@@ -210,7 +210,7 @@
     uint8_t *byteBuffer = (uint8_t *) buffer;
     int32_t framesLeft = numFrames;
 
-    mAudioEndpoint.getEmptyFramesAvailable(&wrappingBuffer);
+    mAudioEndpoint->getEmptyFramesAvailable(&wrappingBuffer);
 
     // Write data in one or two parts.
     int partIndex = 0;
@@ -236,24 +236,28 @@
         partIndex++;
     }
     int32_t framesWritten = numFrames - framesLeft;
-    mAudioEndpoint.advanceWriteIndex(framesWritten);
+    mAudioEndpoint->advanceWriteIndex(framesWritten);
 
     return framesWritten;
 }
 
 int64_t AudioStreamInternalPlay::getFramesRead() {
-    const int64_t framesReadHardware = isClockModelInControl()
-            ? mClockModel.convertTimeToPosition(AudioClock::getNanoseconds())
-            : mAudioEndpoint.getDataReadCounter();
-    // Add service offset and prevent retrograde motion.
-    mLastFramesRead = std::max(mLastFramesRead, framesReadHardware + mFramesOffsetFromService);
+    if (mAudioEndpoint) {
+        const int64_t framesReadHardware = isClockModelInControl()
+                ? mClockModel.convertTimeToPosition(AudioClock::getNanoseconds())
+                : mAudioEndpoint->getDataReadCounter();
+        // Add service offset and prevent retrograde motion.
+        mLastFramesRead = std::max(mLastFramesRead, framesReadHardware + mFramesOffsetFromService);
+    }
     return mLastFramesRead;
 }
 
 int64_t AudioStreamInternalPlay::getFramesWritten() {
-    const int64_t framesWritten = mAudioEndpoint.getDataWriteCounter()
-                               + mFramesOffsetFromService;
-    return framesWritten;
+    if (mAudioEndpoint) {
+        mLastFramesWritten = mAudioEndpoint->getDataWriteCounter()
+                             + mFramesOffsetFromService;
+    }
+    return mLastFramesWritten;
 }
 
 
@@ -268,11 +272,11 @@
     // result might be a frame count
     while (mCallbackEnabled.load() && isActive() && (result >= 0)) {
         // Call application using the AAudio callback interface.
-        callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
+        callbackResult = maybeCallDataCallback(mCallbackBuffer.get(), mCallbackFrames);
 
         if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
             // Write audio data to stream. This is a BLOCKING WRITE!
-            result = write(mCallbackBuffer, mCallbackFrames, timeoutNanos);
+            result = write(mCallbackBuffer.get(), mCallbackFrames, timeoutNanos);
             if ((result != mCallbackFrames)) {
                 if (result >= 0) {
                     // Only wrote some of the frames requested. Must have timed out.
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.h b/media/libaaudio/src/client/AudioStreamInternalPlay.h
index cab2942..2e93157 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.h
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.h
@@ -92,8 +92,6 @@
     aaudio_result_t writeNowWithConversion(const void *buffer,
                                            int32_t numFrames);
 
-    int64_t                  mLastFramesRead = 0; // used to prevent retrograde motion
-
     AAudioFlowGraph          mFlowGraph;
 
 };
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index f51db70..4252dfd 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -111,6 +111,33 @@
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
+    switch (getState()) {
+        // Is this a good time to start?
+        case AAUDIO_STREAM_STATE_OPEN:
+        case AAUDIO_STREAM_STATE_PAUSING:
+        case AAUDIO_STREAM_STATE_PAUSED:
+        case AAUDIO_STREAM_STATE_STOPPING:
+        case AAUDIO_STREAM_STATE_STOPPED:
+        case AAUDIO_STREAM_STATE_FLUSHED:
+            break; // Proceed with starting.
+
+        // Already started?
+        case AAUDIO_STREAM_STATE_STARTING:
+        case AAUDIO_STREAM_STATE_STARTED:
+            ALOGW("%s() stream was already started, state = %s", __func__,
+                  AudioGlobal_convertStreamStateToText(getState()));
+            return AAUDIO_ERROR_INVALID_STATE;
+
+        // Don't start when the stream is dead!
+        case AAUDIO_STREAM_STATE_DISCONNECTED:
+        case AAUDIO_STREAM_STATE_CLOSING:
+        case AAUDIO_STREAM_STATE_CLOSED:
+        default:
+            ALOGW("%s() stream is dead, state = %s", __func__,
+                  AudioGlobal_convertStreamStateToText(getState()));
+            return AAUDIO_ERROR_INVALID_STATE;
+    }
+
     aaudio_result_t result = requestStart();
     if (result == AAUDIO_OK) {
         // We only call this for logging in "dumpsys audio". So ignore return code.
@@ -156,8 +183,8 @@
         case AAUDIO_STREAM_STATE_CLOSING:
         case AAUDIO_STREAM_STATE_CLOSED:
         default:
-            ALOGW("safePause() stream not running, state = %s",
-                  AudioGlobal_convertStreamStateToText(getState()));
+            ALOGW("%s() stream not running, state = %s",
+                  __func__, AudioGlobal_convertStreamStateToText(getState()));
             return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -268,6 +295,11 @@
     if (mState == AAUDIO_STREAM_STATE_CLOSED) {
         ALOGE("%s(%d) tried to set to %d but already CLOSED", __func__, getId(), state);
 
+    // Once CLOSING, we can only move to CLOSED state.
+    } else if (mState == AAUDIO_STREAM_STATE_CLOSING
+               && state != AAUDIO_STREAM_STATE_CLOSED) {
+        ALOGE("%s(%d) tried to set to %d but already CLOSING", __func__, getId(), state);
+
     // Once DISCONNECTED, we can only move to CLOSING or CLOSED state.
     } else if (mState == AAUDIO_STREAM_STATE_DISCONNECTED
                && !(state == AAUDIO_STREAM_STATE_CLOSING
diff --git a/media/libaaudio/tests/test_various.cpp b/media/libaaudio/tests/test_various.cpp
index 5bb1046..1c26615 100644
--- a/media/libaaudio/tests/test_various.cpp
+++ b/media/libaaudio/tests/test_various.cpp
@@ -28,15 +28,20 @@
 
 // Callback function that does nothing.
 aaudio_data_callback_result_t NoopDataCallbackProc(
-        AAudioStream *stream,
-        void *userData,
+        AAudioStream * stream,
+        void * /* userData */,
         void *audioData,
         int32_t numFrames
 ) {
-    (void) stream;
-    (void) userData;
-    (void) audioData;
-    (void) numFrames;
+    int channels = AAudioStream_getChannelCount(stream);
+    int numSamples = channels * numFrames;
+    bool allZeros = true;
+    float * const floatData = reinterpret_cast<float *>(audioData);
+    for (int i = 0; i < numSamples; i++) {
+        allZeros &= (floatData[i] == 0.0f);
+        floatData[i] = 0.0f;
+    }
+    EXPECT_TRUE(allZeros);
     return AAUDIO_CALLBACK_RESULT_CONTINUE;
 }
 
@@ -56,6 +61,7 @@
                                         nullptr);
     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
     AAudioStreamBuilder_setSharingMode(aaudioBuilder, sharingMode);
+    AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
 
     // Create an AAudioStream using the Builder.
     ASSERT_EQ(AAUDIO_OK,
@@ -69,12 +75,33 @@
     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
 
     EXPECT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
-    aaudio_stream_state_t state = AAudioStream_getState(aaudioStream);
-    EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, state);
+    EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
 
     // We should be able to call this again without crashing.
     EXPECT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
-    state = AAudioStream_getState(aaudioStream);
+    EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
+
+    // We expect these not to crash.
+    AAudioStream_setBufferSizeInFrames(aaudioStream, 0);
+    AAudioStream_setBufferSizeInFrames(aaudioStream, 99999999);
+
+    // We should NOT be able to start or change a stream after it has been released.
+    EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, AAudioStream_requestStart(aaudioStream));
+    EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
+    EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, AAudioStream_requestPause(aaudioStream));
+    EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
+    EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, AAudioStream_requestStop(aaudioStream));
+    EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
+
+    // Does this crash?
+    EXPECT_LT(0, AAudioStream_getFramesRead(aaudioStream));
+    EXPECT_LT(0, AAudioStream_getFramesWritten(aaudioStream));
+
+    // Verify Closing State. Does this crash?
+    aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
+    EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
+                                                         AAUDIO_STREAM_STATE_UNKNOWN, &state,
+                                                         500 * NANOS_PER_MILLISECOND));
     EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, state);
 
     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
@@ -114,6 +141,7 @@
     // Request stream properties.
     AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
+    AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
 
     // Create an AAudioStream using the Builder.
     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 4762b63..0d20f20 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -156,6 +156,7 @@
 
 aidl_interface {
     name: "capture_state_listener-aidl",
+    unstable: true,
     local_include_dir: "aidl",
     srcs: [
         "aidl/android/media/ICaptureStateListener.aidl",
diff --git a/media/libeffects/config/Android.bp b/media/libeffects/config/Android.bp
index 8476f82..8493e30 100644
--- a/media/libeffects/config/Android.bp
+++ b/media/libeffects/config/Android.bp
@@ -15,6 +15,7 @@
         "libtinyxml2",
         "libutils",
         "libmedia_helper",
+        "libcutils",
     ],
 
     header_libs: ["libaudio_system_headers"],
diff --git a/media/libeffects/config/include/media/EffectsConfig.h b/media/libeffects/config/include/media/EffectsConfig.h
index ef10e0d..57d4dd7 100644
--- a/media/libeffects/config/include/media/EffectsConfig.h
+++ b/media/libeffects/config/include/media/EffectsConfig.h
@@ -35,11 +35,6 @@
 /** Default path of effect configuration file. Relative to DEFAULT_LOCATIONS. */
 constexpr const char* DEFAULT_NAME = "audio_effects.xml";
 
-/** Default path of effect configuration file.
- * The /vendor partition is the recommended one, the others are deprecated.
- */
-constexpr const char* DEFAULT_LOCATIONS[] = {"/odm/etc", "/vendor/etc", "/system/etc"};
-
 /** Directories where the effect libraries will be search for. */
 constexpr const char* LD_EFFECT_LIBRARY_PATH[] =
 #ifdef __LP64__
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index 85fbf11..26eaaf8 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -27,6 +27,7 @@
 
 #include <media/EffectsConfig.h>
 #include <media/TypeConverter.h>
+#include <system/audio_config.h>
 
 using namespace tinyxml2;
 
@@ -338,7 +339,7 @@
         return parseWithPath(path);
     }
 
-    for (const std::string& location : DEFAULT_LOCATIONS) {
+    for (const std::string& location : audio_get_configuration_paths()) {
         std::string defaultPath = location + '/' + DEFAULT_NAME;
         if (access(defaultPath.c_str(), R_OK) != 0) {
             continue;
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 1df7c88..62a86e7 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -33,6 +33,7 @@
 
 aidl_interface {
     name: "resourcemanager_aidl_interface",
+    unstable: true,
     local_include_dir: "aidl",
     srcs: [
         "aidl/android/media/IResourceManagerClient.aidl",
diff --git a/media/libmediatranscoding/Android.bp b/media/libmediatranscoding/Android.bp
index 7468426..f948bd8 100644
--- a/media/libmediatranscoding/Android.bp
+++ b/media/libmediatranscoding/Android.bp
@@ -17,6 +17,7 @@
 // AIDL interfaces of MediaTranscoding.
 aidl_interface {
     name: "mediatranscoding_aidl_interface",
+    unstable: true,
     local_include_dir: "aidl",
     srcs: [
         "aidl/android/media/IMediaTranscodingService.aidl",
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp
index df6cd03..a5c7f5e 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp
@@ -659,20 +659,12 @@
     huffcodetab       *pHuff;
 
     pVars = (tmp3dec_file *)pMem;
-
-    pVars->num_channels = 0;
+    memset(pVars, 0, sizeof(*pVars));
 
     pExt->totalNumberOfBitsUsed = 0;
     pExt->inputBufferCurrentLength = 0;
     pExt->inputBufferUsedLength    = 0;
 
-    pVars->mainDataStream.offset = 0;
-
-    pv_memset((void*)pVars->mainDataBuffer,
-              0,
-              BUFSIZE*sizeof(*pVars->mainDataBuffer));
-
-
     pVars->inputStream.pBuffer = pExt->pInputBuffer;
 
     /*
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index aaa28bc..d5272bc 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -152,10 +152,16 @@
 bool AudioOutputDescriptor::setVolume(float volumeDb,
                                       VolumeSource volumeSource,
                                       const StreamTypeVector &/*streams*/,
-                                      const DeviceTypeSet& /*deviceTypes*/,
+                                      const DeviceTypeSet& deviceTypes,
                                       uint32_t delayMs,
                                       bool force)
 {
+
+    if (!supportedDevices().containsDeviceAmongTypes(deviceTypes)) {
+        ALOGV("%s output ID %d unsupported device %s",
+                __func__, getId(), toString(deviceTypes).c_str());
+        return false;
+    }
     // We actually change the volume if:
     // - the float value returned by computeVolume() changed
     // - the force flag is set
diff --git a/services/audiopolicy/engine/config/include/EngineConfig.h b/services/audiopolicy/engine/config/include/EngineConfig.h
index 7f5ed5e..5d22c24 100644
--- a/services/audiopolicy/engine/config/include/EngineConfig.h
+++ b/services/audiopolicy/engine/config/include/EngineConfig.h
@@ -31,9 +31,6 @@
 /** Default path of audio policy usages configuration file. */
 constexpr char DEFAULT_PATH[] = "/vendor/etc/audio_policy_engine_configuration.xml";
 
-/** Directories where the effect libraries will be search for. */
-constexpr const char* POLICY_USAGE_LIBRARY_PATH[] = {"/odm/etc/", "/vendor/etc/", "/system/etc/"};
-
 using AttributesVector = std::vector<audio_attributes_t>;
 using StreamVector = std::vector<audio_stream_type_t>;
 
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index 7f8cdd9..4842cb2 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -21,6 +21,7 @@
 #include <cutils/properties.h>
 #include <media/TypeConverter.h>
 #include <media/convert.h>
+#include <system/audio_config.h>
 #include <utils/Log.h>
 #include <libxml/parser.h>
 #include <libxml/xinclude.h>
@@ -693,9 +694,6 @@
     return deserializeLegacyVolumeCollection(doc, cur, volumeGroups, nbSkippedElements);
 }
 
-static const char *kConfigLocationList[] = {"/odm/etc", "/vendor/etc", "/system/etc"};
-static const int kConfigLocationListSize =
-        (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
 static const int gApmXmlConfigFilePathMaxLength = 128;
 
 static constexpr const char *apmXmlConfigFileName = "audio_policy_configuration.xml";
@@ -715,9 +713,9 @@
     fileNames.push_back(apmXmlConfigFileName);
 
     for (const char* fileName : fileNames) {
-        for (int i = 0; i < kConfigLocationListSize; i++) {
+        for (const auto& path : audio_get_configuration_paths()) {
             snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
-                     "%s/%s", kConfigLocationList[i], fileName);
+                     "%s/%s", path.c_str(), fileName);
             ret = parseLegacyVolumeFile(audioPolicyXmlConfigFile, volumeGroups);
             if (ret == NO_ERROR) {
                 return ret;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 3d16977..f1c2ab5 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -47,6 +47,7 @@
 #include <media/AudioParameter.h>
 #include <private/android_filesystem_config.h>
 #include <system/audio.h>
+#include <system/audio_config.h>
 #include "AudioPolicyManager.h"
 #include <Serializer.h>
 #include "TypeConverter.h"
@@ -4367,12 +4368,6 @@
     return mAudioPortGeneration++;
 }
 
-// Treblized audio policy xml config will be located in /odm/etc or /vendor/etc.
-static const char *kConfigLocationList[] =
-        {"/odm/etc", "/vendor/etc", "/system/etc"};
-static const int kConfigLocationListSize =
-        (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
-
 static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
     char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
     std::vector<const char*> fileNames;
@@ -4394,9 +4389,9 @@
     fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);
 
     for (const char* fileName : fileNames) {
-        for (int i = 0; i < kConfigLocationListSize; i++) {
+        for (const auto& path : audio_get_configuration_paths()) {
             snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
-                     "%s/%s", kConfigLocationList[i], fileName);
+                     "%s/%s", path.c_str(), fileName);
             ret = deserializeAudioPolicyFile(audioPolicyXmlConfigFile, &config);
             if (ret == NO_ERROR) {
                 config.setSource(audioPolicyXmlConfigFile);