Merge "Explicit define getFrameAtIndex as pure virtual function."
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 5db60f3..56ddd4f 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -22,6 +22,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
 
 #include "IAudioFlinger.h"
@@ -836,6 +837,35 @@
 status_t BnAudioFlinger::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
+    // make sure transactions reserved to AudioPolicyManager do not come from other processes
+    switch (code) {
+        case SET_STREAM_VOLUME:
+        case SET_STREAM_MUTE:
+        case SET_MODE:
+        case OPEN_OUTPUT:
+        case OPEN_DUPLICATE_OUTPUT:
+        case CLOSE_OUTPUT:
+        case SUSPEND_OUTPUT:
+        case RESTORE_OUTPUT:
+        case OPEN_INPUT:
+        case CLOSE_INPUT:
+        case INVALIDATE_STREAM:
+        case SET_VOICE_VOLUME:
+        case MOVE_EFFECTS:
+        case LOAD_HW_MODULE:
+        case LIST_AUDIO_PORTS:
+        case GET_AUDIO_PORT:
+        case CREATE_AUDIO_PATCH:
+        case RELEASE_AUDIO_PATCH:
+        case LIST_AUDIO_PATCHES:
+        case SET_AUDIO_PORT_CONFIG:
+            ALOGW("%s: transaction %d received from PID %d",
+                  __func__, code, IPCThreadState::self()->getCallingPid());
+            return INVALID_OPERATION;
+        default:
+            break;
+    }
+
     // Whitelist of relevant events to trigger log merging.
     // Log merging should activate during audio activity of any kind. This are considered the
     // most relevant events.
@@ -845,12 +875,8 @@
         case CREATE_RECORD:
         case SET_MASTER_VOLUME:
         case SET_MASTER_MUTE:
-        case SET_STREAM_VOLUME:
-        case SET_STREAM_MUTE:
         case SET_MIC_MUTE:
         case SET_PARAMETERS:
-        case OPEN_INPUT:
-        case SET_VOICE_VOLUME:
         case CREATE_EFFECT:
         case SYSTEM_READY: {
             requestLogMerge();
@@ -859,6 +885,7 @@
         default:
             break;
     }
+
     switch (code) {
         case CREATE_TRACK: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 970ae90..53bc1b7 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -22,6 +22,7 @@
 #include <math.h>
 #include <sys/types.h>
 
+#include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
 
 #include <media/AudioEffect.h>
@@ -831,10 +832,33 @@
 
 // ----------------------------------------------------------------------
 
-
 status_t BnAudioPolicyService::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
+    // make sure transactions reserved to AudioFlinger do not come from other processes
+    switch (code) {
+        case START_OUTPUT:
+        case STOP_OUTPUT:
+        case RELEASE_OUTPUT:
+        case GET_INPUT_FOR_ATTR:
+        case START_INPUT:
+        case STOP_INPUT:
+        case RELEASE_INPUT:
+        case GET_STRATEGY_FOR_STREAM:
+        case GET_OUTPUT_FOR_EFFECT:
+        case REGISTER_EFFECT:
+        case UNREGISTER_EFFECT:
+        case SET_EFFECT_ENABLED:
+        case GET_OUTPUT_FOR_ATTR:
+        case ACQUIRE_SOUNDTRIGGER_SESSION:
+        case RELEASE_SOUNDTRIGGER_SESSION:
+            ALOGW("%s: transaction %d received from PID %d",
+                  __func__, code, IPCThreadState::self()->getCallingPid());
+            return INVALID_OPERATION;
+        default:
+            break;
+    }
+
     switch (code) {
         case SET_DEVICE_CONNECTION_STATE: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 146e9e8..8ebae11 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -3330,14 +3330,19 @@
         //ALOGV("\tEffect_process Not Calling process with %d effects enabled, %d called: Effect %d",
         //pContext->pBundledContext->NumberEffectsEnabled,
         //pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);
-        // 2 is for stereo input
+
         if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
-            for (size_t i=0; i < outBuffer->frameCount*2; i++){
-                outBuffer->s16[i] =
-                        clamp16((LVM_INT32)outBuffer->s16[i] + (LVM_INT32)inBuffer->s16[i]);
+            for (size_t i = 0; i < outBuffer->frameCount * FCC_2; ++i){
+#ifdef NATIVE_FLOAT_BUFFER
+                outBuffer->f32[i] += inBuffer->f32[i];
+#else
+                outBuffer->s16[i] = clamp16((LVM_INT32)outBuffer->s16[i] + inBuffer->s16[i]);
+#endif
             }
         } else if (outBuffer->raw != inBuffer->raw) {
-            memcpy(outBuffer->raw, inBuffer->raw, outBuffer->frameCount*sizeof(LVM_INT16)*2);
+            memcpy(outBuffer->raw,
+                    inBuffer->raw,
+                    outBuffer->frameCount * sizeof(effect_buffer_t) * FCC_2);
         }
     }
 
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 0e82339..c33f9f5 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -594,7 +594,7 @@
                     deltaSmpl = CAPTURE_BUF_SIZE;
                 }
 
-                int32_t capturePoint = pContext->mCaptureIdx - deltaSmpl;
+                int32_t capturePoint = (int32_t)pContext->mCaptureIdx - deltaSmpl;
                 // a negative capturePoint means we wrap the buffer.
                 if (capturePoint < 0) {
                     uint32_t size = -capturePoint;
diff --git a/media/libmedia/IMediaHTTPService.cpp b/media/libmedia/IMediaHTTPService.cpp
index 062a07a..74d8ee8 100644
--- a/media/libmedia/IMediaHTTPService.cpp
+++ b/media/libmedia/IMediaHTTPService.cpp
@@ -34,7 +34,7 @@
         : BpInterface<IMediaHTTPService>(impl) {
     }
 
-    virtual sp<IMediaHTTPConnection> makeHTTPConnection() {
+    virtual sp<MediaHTTPConnection> makeHTTPConnection() {
         Parcel data, reply;
         data.writeInterfaceToken(
                 IMediaHTTPService::getInterfaceDescriptor());
diff --git a/media/libmedia/include/media/IMediaHTTPConnection.h b/media/libmedia/include/media/IMediaHTTPConnection.h
index 2a63eb7..0fb6bb1 100644
--- a/media/libmedia/include/media/IMediaHTTPConnection.h
+++ b/media/libmedia/include/media/IMediaHTTPConnection.h
@@ -19,16 +19,15 @@
 #define I_MEDIA_HTTP_CONNECTION_H_
 
 #include <binder/IInterface.h>
+#include <media/MediaHTTPConnection.h>
 #include <media/stagefright/foundation/ABase.h>
 #include <utils/KeyedVector.h>
 
 namespace android {
 
-struct IMediaHTTPConnection;
-
 /** MUST stay in sync with IMediaHTTPConnection.aidl */
 
-struct IMediaHTTPConnection : public IInterface {
+struct IMediaHTTPConnection : public MediaHTTPConnection, public IInterface {
     DECLARE_META_INTERFACE(MediaHTTPConnection);
 
     virtual bool connect(
diff --git a/media/libmedia/include/media/IMediaHTTPService.h b/media/libmedia/include/media/IMediaHTTPService.h
index f66d6c8..e948b78 100644
--- a/media/libmedia/include/media/IMediaHTTPService.h
+++ b/media/libmedia/include/media/IMediaHTTPService.h
@@ -19,18 +19,19 @@
 #define I_MEDIA_HTTP_SERVICE_H_
 
 #include <binder/IInterface.h>
+#include <media/MediaHTTPService.h>
 #include <media/stagefright/foundation/ABase.h>
 
 namespace android {
 
-struct IMediaHTTPConnection;
+struct MediaHTTPConnection;
 
 /** MUST stay in sync with IMediaHTTPService.aidl */
 
-struct IMediaHTTPService : public IInterface {
+struct IMediaHTTPService : public MediaHTTPService, public IInterface {
     DECLARE_META_INTERFACE(MediaHTTPService);
 
-    virtual sp<IMediaHTTPConnection> makeHTTPConnection() = 0;
+    virtual sp<MediaHTTPConnection> makeHTTPConnection() = 0;
 
 private:
     DISALLOW_EVIL_CONSTRUCTORS(IMediaHTTPService);
diff --git a/media/libmedia/include/media/MediaHTTPConnection.h b/media/libmedia/include/media/MediaHTTPConnection.h
new file mode 100644
index 0000000..82a79e5
--- /dev/null
+++ b/media/libmedia/include/media/MediaHTTPConnection.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_HTTP_CONNECTION_H_
+
+#define MEDIA_HTTP_CONNECTION_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+struct MediaHTTPConnection : public virtual RefBase {
+    MediaHTTPConnection() {}
+
+    virtual bool connect(
+            const char *uri, const KeyedVector<String8, String8> *headers) = 0;
+
+    virtual void disconnect() = 0;
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
+    virtual off64_t getSize() = 0;
+    virtual status_t getMIMEType(String8 *mimeType) = 0;
+    virtual status_t getUri(String8 *uri) = 0;
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(MediaHTTPConnection);
+};
+
+}  // namespace android
+
+#endif  // MEDIA_HTTP_CONNECTION_H_
diff --git a/media/libmedia/include/media/MediaHTTPService.h b/media/libmedia/include/media/MediaHTTPService.h
new file mode 100644
index 0000000..6e9f125
--- /dev/null
+++ b/media/libmedia/include/media/MediaHTTPService.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_HTTP_SERVICE_H_
+
+#define MEDIA_HTTP_SERVICE_H_
+
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+struct MediaHTTPConnection;
+
+struct MediaHTTPService : public virtual RefBase {
+    MediaHTTPService() {}
+
+    virtual sp<MediaHTTPConnection> makeHTTPConnection() = 0;
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(MediaHTTPService);
+};
+
+}  // namespace android
+
+#endif  // MEDIA_HTTP_SERVICE_H_
diff --git a/media/libstagefright/DataSourceFactory.cpp b/media/libstagefright/DataSourceFactory.cpp
index aee858c..54bf0cc 100644
--- a/media/libstagefright/DataSourceFactory.cpp
+++ b/media/libstagefright/DataSourceFactory.cpp
@@ -19,8 +19,8 @@
 #include "include/HTTPBase.h"
 #include "include/NuCachedSource2.h"
 
-#include <media/IMediaHTTPConnection.h>
-#include <media/IMediaHTTPService.h>
+#include <media/MediaHTTPConnection.h>
+#include <media/MediaHTTPService.h>
 #include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/DataURISource.h>
 #include <media/stagefright/FileSource.h>
@@ -31,7 +31,7 @@
 
 // static
 sp<DataSource> DataSourceFactory::CreateFromURI(
-        const sp<IMediaHTTPService> &httpService,
+        const sp<MediaHTTPService> &httpService,
         const char *uri,
         const KeyedVector<String8, String8> *headers,
         String8 *contentType,
@@ -50,7 +50,7 @@
         }
 
         if (httpSource == NULL) {
-            sp<IMediaHTTPConnection> conn = httpService->makeHTTPConnection();
+            sp<MediaHTTPConnection> conn = httpService->makeHTTPConnection();
             if (conn == NULL) {
                 ALOGE("Failed to make http connection from http service!");
                 return NULL;
@@ -101,12 +101,12 @@
     return source->initCheck() != OK ? nullptr : source;
 }
 
-sp<DataSource> DataSourceFactory::CreateMediaHTTP(const sp<IMediaHTTPService> &httpService) {
+sp<DataSource> DataSourceFactory::CreateMediaHTTP(const sp<MediaHTTPService> &httpService) {
     if (httpService == NULL) {
         return NULL;
     }
 
-    sp<IMediaHTTPConnection> conn = httpService->makeHTTPConnection();
+    sp<MediaHTTPConnection> conn = httpService->makeHTTPConnection();
     if (conn == NULL) {
         return NULL;
     } else {
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 1fe5f60..8db00f0 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -2951,212 +2951,215 @@
             mGotStartKeyFrame = true;
         }
 ////////////////////////////////////////////////////////////////////////////////
-        if (mStszTableEntries->count() == 0) {
-            mFirstSampleTimeRealUs = systemTime() / 1000;
-            mStartTimestampUs = timestampUs;
-            mOwner->setStartTimestampUs(mStartTimestampUs);
-            previousPausedDurationUs = mStartTimestampUs;
-        }
 
-        if (mResumed) {
-            int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
-            if (WARN_UNLESS(durExcludingEarlierPausesUs >= 0ll, "for %s track", trackName)) {
-                copy->release();
-                mSource->stop();
-                mIsMalformed = true;
-                break;
-            }
-
-            int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs;
-            if (WARN_UNLESS(pausedDurationUs >= lastDurationUs, "for %s track", trackName)) {
-                copy->release();
-                mSource->stop();
-                mIsMalformed = true;
-                break;
-            }
-
-            previousPausedDurationUs += pausedDurationUs - lastDurationUs;
-            mResumed = false;
-        }
-        TimestampDebugHelperEntry timestampDebugEntry;
-        timestampUs -= previousPausedDurationUs;
-        timestampDebugEntry.pts = timestampUs;
-        if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
-            copy->release();
-            mSource->stop();
-            mIsMalformed = true;
-            break;
-        }
-
-        if (mIsVideo) {
-            /*
-             * Composition time: timestampUs
-             * Decoding time: decodingTimeUs
-             * Composition time offset = composition time - decoding time
-             */
-            int64_t decodingTimeUs;
-            CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs));
-            decodingTimeUs -= previousPausedDurationUs;
-
-            // ensure non-negative, monotonic decoding time
-            if (mLastDecodingTimeUs < 0) {
-                decodingTimeUs = std::max((int64_t)0, decodingTimeUs);
-            } else {
-                // increase decoding time by at least the larger vaule of 1 tick and
-                // 0.1 milliseconds. This needs to take into account the possible
-                // delta adjustment in DurationTicks in below.
-                decodingTimeUs = std::max(mLastDecodingTimeUs +
-                        std::max(100, divUp(1000000, mTimeScale)), decodingTimeUs);
-            }
-
-            mLastDecodingTimeUs = decodingTimeUs;
-            timestampDebugEntry.dts = decodingTimeUs;
-            timestampDebugEntry.frameType = isSync ? "Key frame" : "Non-Key frame";
-            // Insert the timestamp into the mTimestampDebugHelper
-            if (mTimestampDebugHelper.size() >= kTimestampDebugCount) {
-                mTimestampDebugHelper.pop_front();
-            }
-            mTimestampDebugHelper.push_back(timestampDebugEntry);
-
-            cttsOffsetTimeUs =
-                    timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs;
-            if (WARN_UNLESS(cttsOffsetTimeUs >= 0ll, "for %s track", trackName)) {
-                copy->release();
-                mSource->stop();
-                mIsMalformed = true;
-                break;
-            }
-
-            timestampUs = decodingTimeUs;
-            ALOGV("decoding time: %" PRId64 " and ctts offset time: %" PRId64,
-                timestampUs, cttsOffsetTimeUs);
-
-            // Update ctts box table if necessary
-            currCttsOffsetTimeTicks =
-                    (cttsOffsetTimeUs * mTimeScale + 500000LL) / 1000000LL;
-            if (WARN_UNLESS(currCttsOffsetTimeTicks <= 0x0FFFFFFFFLL, "for %s track", trackName)) {
-                copy->release();
-                mSource->stop();
-                mIsMalformed = true;
-                break;
-            }
-
+        if (!mIsHeic) {
             if (mStszTableEntries->count() == 0) {
-                // Force the first ctts table entry to have one single entry
-                // so that we can do adjustment for the initial track start
-                // time offset easily in writeCttsBox().
-                lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
-                addOneCttsTableEntry(1, currCttsOffsetTimeTicks);
-                cttsSampleCount = 0;      // No sample in ctts box is pending
-            } else {
-                if (currCttsOffsetTimeTicks != lastCttsOffsetTimeTicks) {
-                    addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
-                    lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
-                    cttsSampleCount = 1;  // One sample in ctts box is pending
+                mFirstSampleTimeRealUs = systemTime() / 1000;
+                mStartTimestampUs = timestampUs;
+                mOwner->setStartTimestampUs(mStartTimestampUs);
+                previousPausedDurationUs = mStartTimestampUs;
+            }
+
+            if (mResumed) {
+                int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
+                if (WARN_UNLESS(durExcludingEarlierPausesUs >= 0ll, "for %s track", trackName)) {
+                    copy->release();
+                    mSource->stop();
+                    mIsMalformed = true;
+                    break;
+                }
+
+                int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs;
+                if (WARN_UNLESS(pausedDurationUs >= lastDurationUs, "for %s track", trackName)) {
+                    copy->release();
+                    mSource->stop();
+                    mIsMalformed = true;
+                    break;
+                }
+
+                previousPausedDurationUs += pausedDurationUs - lastDurationUs;
+                mResumed = false;
+            }
+            TimestampDebugHelperEntry timestampDebugEntry;
+            timestampUs -= previousPausedDurationUs;
+            timestampDebugEntry.pts = timestampUs;
+            if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
+                copy->release();
+                mSource->stop();
+                mIsMalformed = true;
+                break;
+            }
+
+            if (mIsVideo) {
+                /*
+                 * Composition time: timestampUs
+                 * Decoding time: decodingTimeUs
+                 * Composition time offset = composition time - decoding time
+                 */
+                int64_t decodingTimeUs;
+                CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs));
+                decodingTimeUs -= previousPausedDurationUs;
+
+                // ensure non-negative, monotonic decoding time
+                if (mLastDecodingTimeUs < 0) {
+                    decodingTimeUs = std::max((int64_t)0, decodingTimeUs);
                 } else {
-                    ++cttsSampleCount;
+                    // increase decoding time by at least the larger vaule of 1 tick and
+                    // 0.1 milliseconds. This needs to take into account the possible
+                    // delta adjustment in DurationTicks in below.
+                    decodingTimeUs = std::max(mLastDecodingTimeUs +
+                            std::max(100, divUp(1000000, mTimeScale)), decodingTimeUs);
                 }
-            }
 
-            // Update ctts time offset range
-            if (mStszTableEntries->count() == 0) {
-                mMinCttsOffsetTicks = currCttsOffsetTimeTicks;
-                mMaxCttsOffsetTicks = currCttsOffsetTimeTicks;
-            } else {
-                if (currCttsOffsetTimeTicks > mMaxCttsOffsetTicks) {
-                    mMaxCttsOffsetTicks = currCttsOffsetTimeTicks;
-                } else if (currCttsOffsetTimeTicks < mMinCttsOffsetTicks) {
+                mLastDecodingTimeUs = decodingTimeUs;
+                timestampDebugEntry.dts = decodingTimeUs;
+                timestampDebugEntry.frameType = isSync ? "Key frame" : "Non-Key frame";
+                // Insert the timestamp into the mTimestampDebugHelper
+                if (mTimestampDebugHelper.size() >= kTimestampDebugCount) {
+                    mTimestampDebugHelper.pop_front();
+                }
+                mTimestampDebugHelper.push_back(timestampDebugEntry);
+
+                cttsOffsetTimeUs =
+                        timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs;
+                if (WARN_UNLESS(cttsOffsetTimeUs >= 0ll, "for %s track", trackName)) {
+                    copy->release();
+                    mSource->stop();
+                    mIsMalformed = true;
+                    break;
+                }
+
+                timestampUs = decodingTimeUs;
+                ALOGV("decoding time: %" PRId64 " and ctts offset time: %" PRId64,
+                    timestampUs, cttsOffsetTimeUs);
+
+                // Update ctts box table if necessary
+                currCttsOffsetTimeTicks =
+                        (cttsOffsetTimeUs * mTimeScale + 500000LL) / 1000000LL;
+                if (WARN_UNLESS(currCttsOffsetTimeTicks <= 0x0FFFFFFFFLL, "for %s track", trackName)) {
+                    copy->release();
+                    mSource->stop();
+                    mIsMalformed = true;
+                    break;
+                }
+
+                if (mStszTableEntries->count() == 0) {
+                    // Force the first ctts table entry to have one single entry
+                    // so that we can do adjustment for the initial track start
+                    // time offset easily in writeCttsBox().
+                    lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
+                    addOneCttsTableEntry(1, currCttsOffsetTimeTicks);
+                    cttsSampleCount = 0;      // No sample in ctts box is pending
+                } else {
+                    if (currCttsOffsetTimeTicks != lastCttsOffsetTimeTicks) {
+                        addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
+                        lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
+                        cttsSampleCount = 1;  // One sample in ctts box is pending
+                    } else {
+                        ++cttsSampleCount;
+                    }
+                }
+
+                // Update ctts time offset range
+                if (mStszTableEntries->count() == 0) {
                     mMinCttsOffsetTicks = currCttsOffsetTimeTicks;
-                    mMinCttsOffsetTimeUs = cttsOffsetTimeUs;
+                    mMaxCttsOffsetTicks = currCttsOffsetTimeTicks;
+                } else {
+                    if (currCttsOffsetTimeTicks > mMaxCttsOffsetTicks) {
+                        mMaxCttsOffsetTicks = currCttsOffsetTimeTicks;
+                    } else if (currCttsOffsetTimeTicks < mMinCttsOffsetTicks) {
+                        mMinCttsOffsetTicks = currCttsOffsetTimeTicks;
+                        mMinCttsOffsetTimeUs = cttsOffsetTimeUs;
+                    }
                 }
             }
-        }
 
-        if (mOwner->isRealTimeRecording()) {
-            if (mIsAudio) {
-                updateDriftTime(meta_data);
-            }
-        }
-
-        if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
-            copy->release();
-            mSource->stop();
-            mIsMalformed = true;
-            break;
-        }
-
-        ALOGV("%s media time stamp: %" PRId64 " and previous paused duration %" PRId64,
-                trackName, timestampUs, previousPausedDurationUs);
-        if (timestampUs > mTrackDurationUs) {
-            mTrackDurationUs = timestampUs;
-        }
-
-        // We need to use the time scale based ticks, rather than the
-        // timestamp itself to determine whether we have to use a new
-        // stts entry, since we may have rounding errors.
-        // The calculation is intended to reduce the accumulated
-        // rounding errors.
-        currDurationTicks =
-            ((timestampUs * mTimeScale + 500000LL) / 1000000LL -
-                (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
-        if (currDurationTicks < 0ll) {
-            ALOGE("do not support out of order frames (timestamp: %lld < last: %lld for %s track",
-                    (long long)timestampUs, (long long)lastTimestampUs, trackName);
-            copy->release();
-            mSource->stop();
-            mIsMalformed = true;
-            break;
-        }
-
-        // if the duration is different for this sample, see if it is close enough to the previous
-        // duration that we can fudge it and use the same value, to avoid filling the stts table
-        // with lots of near-identical entries.
-        // "close enough" here means that the current duration needs to be adjusted by less
-        // than 0.1 milliseconds
-        if (lastDurationTicks && (currDurationTicks != lastDurationTicks)) {
-            int64_t deltaUs = ((lastDurationTicks - currDurationTicks) * 1000000LL
-                    + (mTimeScale / 2)) / mTimeScale;
-            if (deltaUs > -100 && deltaUs < 100) {
-                // use previous ticks, and adjust timestamp as if it was actually that number
-                // of ticks
-                currDurationTicks = lastDurationTicks;
-                timestampUs += deltaUs;
-            }
-        }
-        mStszTableEntries->add(htonl(sampleSize));
-        if (mStszTableEntries->count() > 2) {
-
-            // Force the first sample to have its own stts entry so that
-            // we can adjust its value later to maintain the A/V sync.
-            if (mStszTableEntries->count() == 3 || currDurationTicks != lastDurationTicks) {
-                addOneSttsTableEntry(sampleCount, lastDurationTicks);
-                sampleCount = 1;
-            } else {
-                ++sampleCount;
+            if (mOwner->isRealTimeRecording()) {
+                if (mIsAudio) {
+                    updateDriftTime(meta_data);
+                }
             }
 
-        }
-        if (mSamplesHaveSameSize) {
-            if (mStszTableEntries->count() >= 2 && previousSampleSize != sampleSize) {
-                mSamplesHaveSameSize = false;
+            if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
+                copy->release();
+                mSource->stop();
+                mIsMalformed = true;
+                break;
             }
-            previousSampleSize = sampleSize;
-        }
-        ALOGV("%s timestampUs/lastTimestampUs: %" PRId64 "/%" PRId64,
-                trackName, timestampUs, lastTimestampUs);
-        lastDurationUs = timestampUs - lastTimestampUs;
-        lastDurationTicks = currDurationTicks;
-        lastTimestampUs = timestampUs;
 
-        if (isSync != 0) {
-            addOneStssTableEntry(mStszTableEntries->count());
-        }
-
-        if (mTrackingProgressStatus) {
-            if (mPreviousTrackTimeUs <= 0) {
-                mPreviousTrackTimeUs = mStartTimestampUs;
+            ALOGV("%s media time stamp: %" PRId64 " and previous paused duration %" PRId64,
+                    trackName, timestampUs, previousPausedDurationUs);
+            if (timestampUs > mTrackDurationUs) {
+                mTrackDurationUs = timestampUs;
             }
-            trackProgressStatus(timestampUs);
+
+            // We need to use the time scale based ticks, rather than the
+            // timestamp itself to determine whether we have to use a new
+            // stts entry, since we may have rounding errors.
+            // The calculation is intended to reduce the accumulated
+            // rounding errors.
+            currDurationTicks =
+                ((timestampUs * mTimeScale + 500000LL) / 1000000LL -
+                    (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
+            if (currDurationTicks < 0ll) {
+                ALOGE("do not support out of order frames (timestamp: %lld < last: %lld for %s track",
+                        (long long)timestampUs, (long long)lastTimestampUs, trackName);
+                copy->release();
+                mSource->stop();
+                mIsMalformed = true;
+                break;
+            }
+
+            // if the duration is different for this sample, see if it is close enough to the previous
+            // duration that we can fudge it and use the same value, to avoid filling the stts table
+            // with lots of near-identical entries.
+            // "close enough" here means that the current duration needs to be adjusted by less
+            // than 0.1 milliseconds
+            if (lastDurationTicks && (currDurationTicks != lastDurationTicks)) {
+                int64_t deltaUs = ((lastDurationTicks - currDurationTicks) * 1000000LL
+                        + (mTimeScale / 2)) / mTimeScale;
+                if (deltaUs > -100 && deltaUs < 100) {
+                    // use previous ticks, and adjust timestamp as if it was actually that number
+                    // of ticks
+                    currDurationTicks = lastDurationTicks;
+                    timestampUs += deltaUs;
+                }
+            }
+            mStszTableEntries->add(htonl(sampleSize));
+            if (mStszTableEntries->count() > 2) {
+
+                // Force the first sample to have its own stts entry so that
+                // we can adjust its value later to maintain the A/V sync.
+                if (mStszTableEntries->count() == 3 || currDurationTicks != lastDurationTicks) {
+                    addOneSttsTableEntry(sampleCount, lastDurationTicks);
+                    sampleCount = 1;
+                } else {
+                    ++sampleCount;
+                }
+
+            }
+            if (mSamplesHaveSameSize) {
+                if (mStszTableEntries->count() >= 2 && previousSampleSize != sampleSize) {
+                    mSamplesHaveSameSize = false;
+                }
+                previousSampleSize = sampleSize;
+            }
+            ALOGV("%s timestampUs/lastTimestampUs: %" PRId64 "/%" PRId64,
+                    trackName, timestampUs, lastTimestampUs);
+            lastDurationUs = timestampUs - lastTimestampUs;
+            lastDurationTicks = currDurationTicks;
+            lastTimestampUs = timestampUs;
+
+            if (isSync != 0) {
+                addOneStssTableEntry(mStszTableEntries->count());
+            }
+
+            if (mTrackingProgressStatus) {
+                if (mPreviousTrackTimeUs <= 0) {
+                    mPreviousTrackTimeUs = mStartTimestampUs;
+                }
+                trackProgressStatus(timestampUs);
+            }
         }
         if (!hasMultipleTracks) {
             size_t bytesWritten;
@@ -4331,9 +4334,12 @@
     }
 
     // patch up the mPrimaryItemId and count items with prop associations
+    uint16_t firstVisibleItemId = 0;
     for (size_t index = 0; index < mItems.size(); index++) {
         if (mItems[index].isPrimary) {
             mPrimaryItemId = mItems[index].itemId;
+        } else if (!firstVisibleItemId && !mItems[index].isHidden) {
+            firstVisibleItemId = mItems[index].itemId;
         }
 
         if (!mItems[index].properties.empty()) {
@@ -4342,8 +4348,13 @@
     }
 
     if (mPrimaryItemId == 0) {
-        ALOGW("didn't find primary, using first item");
-        mPrimaryItemId = mItems[0].itemId;
+        if (firstVisibleItemId > 0) {
+            ALOGW("didn't find primary, using first visible item");
+            mPrimaryItemId = firstVisibleItemId;
+        } else {
+            ALOGW("no primary and no visible item, using first item");
+            mPrimaryItemId = mItems[0].itemId;
+        }
     }
 
     beginBox("meta");
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index a176382..17c9648 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -72,7 +72,7 @@
 }
 
 status_t NuMediaExtractor::setDataSource(
-        const sp<IMediaHTTPService> &httpService,
+        const sp<MediaHTTPService> &httpService,
         const char *path,
         const KeyedVector<String8, String8> *headers) {
     Mutex::Autolock autoLock(mLock);
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 358c743..32fdbd3 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -1170,6 +1170,12 @@
     ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat;
     source = NULL;
     if ((inputBufferHeader != NULL) && inputBufferHeader->nFilledLen) {
+        OMX_ERRORTYPE error = validateInputBuffer(inputBufferHeader);
+        if (error != OMX_ErrorNone) {
+            ALOGE("b/69065651");
+            android_errorWriteLog(0x534e4554, "69065651");
+            return error;
+        }
         source = inputBufferHeader->pBuffer + inputBufferHeader->nOffset;
 
         if (mInputDataIsMeta) {
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index 7b90a01..f6a7b0e 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -434,6 +434,14 @@
         }
 
         if (inHeader->nFilledLen > 0) {
+            OMX_ERRORTYPE error = validateInputBuffer(inHeader);
+            if (error != OMX_ErrorNone) {
+                ALOGE("b/69065651");
+                android_errorWriteLog(0x534e4554, "69065651");
+                mSignalledError = true;
+                notify(OMX_EventError, error, 0, 0);
+                return;
+            }
             const uint8_t *inputData = NULL;
             if (mInputDataIsMeta) {
                 inputData =
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index a5666da..f6257b1 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -653,6 +653,13 @@
             return;
         }
 
+        OMX_ERRORTYPE error = validateInputBuffer(inputBufferHeader);
+        if (error != OMX_ErrorNone) {
+            ALOGE("b/27569635");
+            android_errorWriteLog(0x534e4554, "27569635");
+            notify(OMX_EventError, error, 0, 0);
+            return;
+        }
         const uint8_t *source =
             inputBufferHeader->pBuffer + inputBufferHeader->nOffset;
 
@@ -668,14 +675,6 @@
                 return;
             }
         } else {
-            if (inputBufferHeader->nFilledLen < frameSize) {
-                android_errorWriteLog(0x534e4554, "27569635");
-                notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
-                return;
-            } else if (inputBufferHeader->nFilledLen > frameSize) {
-                ALOGW("Input buffer contains too many pixels");
-            }
-
             if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
                 ConvertYUV420SemiPlanarToYUV420Planar(
                         source, mConversionBuffer, mWidth, mHeight);
diff --git a/media/libstagefright/http/MediaHTTP.cpp b/media/libstagefright/http/MediaHTTP.cpp
index 5b18814..84837e8 100644
--- a/media/libstagefright/http/MediaHTTP.cpp
+++ b/media/libstagefright/http/MediaHTTP.cpp
@@ -25,11 +25,11 @@
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/Utils.h>
 
-#include <media/IMediaHTTPConnection.h>
+#include <media/MediaHTTPConnection.h>
 
 namespace android {
 
-MediaHTTP::MediaHTTP(const sp<IMediaHTTPConnection> &conn)
+MediaHTTP::MediaHTTP(const sp<MediaHTTPConnection> &conn)
     : mInitCheck((conn != NULL) ? OK : NO_INIT),
       mHTTPConnection(conn),
       mCachedSizeValid(false),
diff --git a/media/libstagefright/httplive/HTTPDownloader.cpp b/media/libstagefright/httplive/HTTPDownloader.cpp
index 3fef764..72604e3 100644
--- a/media/libstagefright/httplive/HTTPDownloader.cpp
+++ b/media/libstagefright/httplive/HTTPDownloader.cpp
@@ -22,8 +22,8 @@
 #include "M3UParser.h"
 
 #include <media/DataSource.h>
-#include <media/IMediaHTTPConnection.h>
-#include <media/IMediaHTTPService.h>
+#include <media/MediaHTTPConnection.h>
+#include <media/MediaHTTPService.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaHTTP.h>
@@ -36,7 +36,7 @@
 namespace android {
 
 HTTPDownloader::HTTPDownloader(
-        const sp<IMediaHTTPService> &httpService,
+        const sp<MediaHTTPService> &httpService,
         const KeyedVector<String8, String8> &headers) :
     mHTTPDataSource(new MediaHTTP(httpService->makeHTTPConnection())),
     mExtraHeaders(headers),
diff --git a/media/libstagefright/httplive/HTTPDownloader.h b/media/libstagefright/httplive/HTTPDownloader.h
index 1db4a48..0d4bd31 100644
--- a/media/libstagefright/httplive/HTTPDownloader.h
+++ b/media/libstagefright/httplive/HTTPDownloader.h
@@ -28,12 +28,12 @@
 struct ABuffer;
 class DataSource;
 struct HTTPBase;
-struct IMediaHTTPService;
+struct MediaHTTPService;
 struct M3UParser;
 
 struct HTTPDownloader : public RefBase {
     HTTPDownloader(
-            const sp<IMediaHTTPService> &httpService,
+            const sp<MediaHTTPService> &httpService,
             const KeyedVector<String8, String8> &headers);
 
     void reconnect();
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 4c2e0d4..1e2e684 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -26,7 +26,7 @@
 #include "mpeg2ts/AnotherPacketSource.h"
 
 #include <cutils/properties.h>
-#include <media/IMediaHTTPService.h>
+#include <media/MediaHTTPService.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
@@ -274,7 +274,7 @@
 
 LiveSession::LiveSession(
         const sp<AMessage> &notify, uint32_t flags,
-        const sp<IMediaHTTPService> &httpService)
+        const sp<MediaHTTPService> &httpService)
     : mNotify(notify),
       mFlags(flags),
       mHTTPService(httpService),
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index abf8cf0..7a6d487 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -33,7 +33,7 @@
 struct AnotherPacketSource;
 class DataSource;
 struct HTTPBase;
-struct IMediaHTTPService;
+struct MediaHTTPService;
 struct LiveDataSource;
 struct M3UParser;
 struct PlaylistFetcher;
@@ -71,7 +71,7 @@
     LiveSession(
             const sp<AMessage> &notify,
             uint32_t flags,
-            const sp<IMediaHTTPService> &httpService);
+            const sp<MediaHTTPService> &httpService);
 
     void setBufferingSettings(const BufferingSettings &buffering);
 
@@ -187,7 +187,7 @@
 
     sp<AMessage> mNotify;
     uint32_t mFlags;
-    sp<IMediaHTTPService> mHTTPService;
+    sp<MediaHTTPService> mHTTPService;
 
     bool mBuffering;
     bool mInPreparationPhase;
diff --git a/media/libstagefright/include/SDPLoader.h b/media/libstagefright/include/SDPLoader.h
index 2c4f543..b901c97 100644
--- a/media/libstagefright/include/SDPLoader.h
+++ b/media/libstagefright/include/SDPLoader.h
@@ -25,7 +25,7 @@
 namespace android {
 
 struct HTTPBase;
-struct IMediaHTTPService;
+struct MediaHTTPService;
 
 struct SDPLoader : public AHandler {
     enum Flags {
@@ -38,7 +38,7 @@
     SDPLoader(
             const sp<AMessage> &notify,
             uint32_t flags,
-            const sp<IMediaHTTPService> &httpService);
+            const sp<MediaHTTPService> &httpService);
 
     void load(const char* url, const KeyedVector<String8, String8> *headers);
 
diff --git a/media/libstagefright/include/media/stagefright/DataSourceFactory.h b/media/libstagefright/include/media/stagefright/DataSourceFactory.h
index 89add13..2a1d491 100644
--- a/media/libstagefright/include/media/stagefright/DataSourceFactory.h
+++ b/media/libstagefright/include/media/stagefright/DataSourceFactory.h
@@ -23,20 +23,20 @@
 
 namespace android {
 
-struct IMediaHTTPService;
+struct MediaHTTPService;
 class String8;
 struct HTTPBase;
 
 class DataSourceFactory {
 public:
     static sp<DataSource> CreateFromURI(
-            const sp<IMediaHTTPService> &httpService,
+            const sp<MediaHTTPService> &httpService,
             const char *uri,
             const KeyedVector<String8, String8> *headers = NULL,
             String8 *contentType = NULL,
             HTTPBase *httpSource = NULL);
 
-    static sp<DataSource> CreateMediaHTTP(const sp<IMediaHTTPService> &httpService);
+    static sp<DataSource> CreateMediaHTTP(const sp<MediaHTTPService> &httpService);
     static sp<DataSource> CreateFromFd(int fd, int64_t offset, int64_t length);
 };
 
diff --git a/media/libstagefright/include/media/stagefright/MediaHTTP.h b/media/libstagefright/include/media/stagefright/MediaHTTP.h
index 006d8d8..94a2ecd 100644
--- a/media/libstagefright/include/media/stagefright/MediaHTTP.h
+++ b/media/libstagefright/include/media/stagefright/MediaHTTP.h
@@ -24,10 +24,10 @@
 
 namespace android {
 
-struct IMediaHTTPConnection;
+struct MediaHTTPConnection;
 
 struct MediaHTTP : public HTTPBase {
-    MediaHTTP(const sp<IMediaHTTPConnection> &conn);
+    MediaHTTP(const sp<MediaHTTPConnection> &conn);
 
     virtual status_t connect(
             const char *uri,
@@ -56,7 +56,7 @@
 
 private:
     status_t mInitCheck;
-    sp<IMediaHTTPConnection> mHTTPConnection;
+    sp<MediaHTTPConnection> mHTTPConnection;
 
     KeyedVector<String8, String8> mLastHeaders;
     AString mLastURI;
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 5af0745..eed0f05 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -34,7 +34,7 @@
 struct ABuffer;
 struct AMessage;
 class DataSource;
-struct IMediaHTTPService;
+struct MediaHTTPService;
 class MediaBuffer;
 class MediaExtractor;
 struct MediaSource;
@@ -54,7 +54,7 @@
     NuMediaExtractor();
 
     status_t setDataSource(
-            const sp<IMediaHTTPService> &httpService,
+            const sp<MediaHTTPService> &httpService,
             const char *path,
             const KeyedVector<String8, String8> *headers = NULL);
 
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index fa15ab3..2fbbb44 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -664,4 +664,17 @@
     return SimpleSoftOMXComponent::getExtensionIndex(name, index);
 }
 
+OMX_ERRORTYPE SoftVideoEncoderOMXComponent::validateInputBuffer(
+        const OMX_BUFFERHEADERTYPE *inputBufferHeader) {
+    size_t frameSize = mInputDataIsMeta ?
+            max(sizeof(VideoNativeMetadata), sizeof(VideoGrallocMetadata))
+            : mWidth * mHeight * 3 / 2;
+    if (inputBufferHeader->nFilledLen < frameSize) {
+        return OMX_ErrorUndefined;
+    } else if (inputBufferHeader->nFilledLen > frameSize) {
+        ALOGW("Input buffer contains more data than expected.");
+    }
+    return OMX_ErrorNone;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
index db5496a..2d6f31b 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
@@ -67,6 +67,8 @@
 
     virtual OMX_ERRORTYPE getExtensionIndex(const char *name, OMX_INDEXTYPE *index);
 
+    OMX_ERRORTYPE validateInputBuffer(const OMX_BUFFERHEADERTYPE *inputBufferHeader);
+
     enum {
         kInputPortIndex = 0,
         kOutputPortIndex = 1,
diff --git a/media/libstagefright/rtsp/SDPLoader.cpp b/media/libstagefright/rtsp/SDPLoader.cpp
index 0f46c83..d459cbd 100644
--- a/media/libstagefright/rtsp/SDPLoader.cpp
+++ b/media/libstagefright/rtsp/SDPLoader.cpp
@@ -22,8 +22,8 @@
 
 #include "ASessionDescription.h"
 
-#include <media/IMediaHTTPConnection.h>
-#include <media/IMediaHTTPService.h>
+#include <media/MediaHTTPConnection.h>
+#include <media/MediaHTTPService.h>
 #include <media/stagefright/MediaHTTP.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -36,7 +36,7 @@
 SDPLoader::SDPLoader(
         const sp<AMessage> &notify,
         uint32_t flags,
-        const sp<IMediaHTTPService> &httpService)
+        const sp<MediaHTTPService> &httpService)
     : mNotify(notify),
       mFlags(flags),
       mNetLooper(new ALooper),
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index e0d0d7b..bfb0fe2 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -296,6 +296,43 @@
     const bool auxType =
             (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY;
 
+    // safeInputOutputSampleCount is 0 if the channel count between input and output
+    // buffers do not match. This prevents automatic accumulation or copying between the
+    // input and output effect buffers without an intermediary effect process.
+    // TODO: consider implementing channel conversion.
+    const size_t safeInputOutputSampleCount =
+            inChannelCount != outChannelCount ? 0
+                    : outChannelCount * std::min(
+                            mConfig.inputCfg.buffer.frameCount,
+                            mConfig.outputCfg.buffer.frameCount);
+    const auto accumulateInputToOutput = [this, safeInputOutputSampleCount]() {
+#ifdef FLOAT_EFFECT_CHAIN
+        accumulate_float(
+                mConfig.outputCfg.buffer.f32,
+                mConfig.inputCfg.buffer.f32,
+                safeInputOutputSampleCount);
+#else
+        accumulate_i16(
+                mConfig.outputCfg.buffer.s16,
+                mConfig.inputCfg.buffer.s16,
+                safeInputOutputSampleCount);
+#endif
+    };
+    const auto copyInputToOutput = [this, safeInputOutputSampleCount]() {
+#ifdef FLOAT_EFFECT_CHAIN
+        memcpy(
+                mConfig.outputCfg.buffer.f32,
+                mConfig.inputCfg.buffer.f32,
+                safeInputOutputSampleCount * sizeof(*mConfig.outputCfg.buffer.f32));
+
+#else
+        memcpy(
+                mConfig.outputCfg.buffer.s16,
+                mConfig.inputCfg.buffer.s16,
+                safeInputOutputSampleCount * sizeof(*mConfig.outputCfg.buffer.s16));
+#endif
+    };
+
     if (isProcessEnabled()) {
         int ret;
         if (isProcessImplemented()) {
@@ -308,97 +345,69 @@
                     static_assert(sizeof(float) <= sizeof(int32_t),
                             "in-place conversion requires sizeof(float) <= sizeof(int32_t)");
 
-                    const int32_t * const p32 = mConfig.inputCfg.buffer.s32;
-                    float * const pFloat = mConfig.inputCfg.buffer.f32;
-                    memcpy_to_float_from_q4_27(pFloat, p32, mConfig.inputCfg.buffer.frameCount);
-                } else {
-                    memcpy_to_i16_from_q4_27(mConfig.inputCfg.buffer.s16,
+                    memcpy_to_float_from_q4_27(
+                            mConfig.inputCfg.buffer.f32,
+                            mConfig.inputCfg.buffer.s32,
+                            mConfig.inputCfg.buffer.frameCount);
+                } else
+#endif
+                {
+                    memcpy_to_i16_from_q4_27(
+                            mConfig.inputCfg.buffer.s16,
                             mConfig.inputCfg.buffer.s32,
                             mConfig.inputCfg.buffer.frameCount);
                 }
-#else
-                memcpy_to_i16_from_q4_27(mConfig.inputCfg.buffer.s16,
-                                            mConfig.inputCfg.buffer.s32,
-                                            mConfig.inputCfg.buffer.frameCount);
-#endif
             }
 #ifdef FLOAT_EFFECT_CHAIN
-            if (mSupportsFloat) {
-                ret = mEffectInterface->process();
-            } else {
-                {   // convert input to int16_t as effect doesn't support float.
-                    if (!auxType) {
-                        if (mInBuffer16.get() == nullptr) {
-                            ALOGW("%s: mInBuffer16 is null, bypassing", __func__);
-                            goto data_bypass;
-                        }
-                        const float * const pIn = mInBuffer->audioBuffer()->f32;
-                        int16_t * const pIn16 = mInBuffer16->audioBuffer()->s16;
-                        memcpy_to_i16_from_float(
-                                pIn16, pIn, inChannelCount * mConfig.inputCfg.buffer.frameCount);
+            if (!mSupportsFloat) { // convert input to int16_t as effect doesn't support float.
+                if (!auxType) {
+                    if (mInConversionBuffer.get() == nullptr) {
+                        ALOGW("%s: mInConversionBuffer is null, bypassing", __func__);
+                        goto data_bypass;
                     }
-                    if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
-                        if (mOutBuffer16.get() == nullptr) {
-                            ALOGW("%s: mOutBuffer16 is null, bypassing", __func__);
-                            goto data_bypass;
-                        }
-                        int16_t * const pOut16 = mOutBuffer16->audioBuffer()->s16;
-                        const float * const pOut = mOutBuffer->audioBuffer()->f32;
-                        memcpy_to_i16_from_float(
-                                pOut16,
-                                pOut,
-                                outChannelCount * mConfig.outputCfg.buffer.frameCount);
-                    }
+                    memcpy_to_i16_from_float(
+                            mInConversionBuffer->audioBuffer()->s16,
+                            mInBuffer->audioBuffer()->f32,
+                            inChannelCount * mConfig.inputCfg.buffer.frameCount);
                 }
-
-                ret = mEffectInterface->process();
-
-                {   // convert output back to float.
-                    const int16_t * const pOut16 = mOutBuffer16->audioBuffer()->s16;
-                    float * const pOut = mOutBuffer->audioBuffer()->f32;
-                    memcpy_to_float_from_i16(
-                            pOut, pOut16, outChannelCount * mConfig.outputCfg.buffer.frameCount);
+                if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+                    if (mOutConversionBuffer.get() == nullptr) {
+                        ALOGW("%s: mOutConversionBuffer is null, bypassing", __func__);
+                        goto data_bypass;
+                    }
+                    memcpy_to_i16_from_float(
+                            mOutConversionBuffer->audioBuffer()->s16,
+                            mOutBuffer->audioBuffer()->f32,
+                            outChannelCount * mConfig.outputCfg.buffer.frameCount);
                 }
             }
-#else
+#endif
+
             ret = mEffectInterface->process();
+
+#ifdef FLOAT_EFFECT_CHAIN
+            if (!mSupportsFloat) { // convert output int16_t back to float.
+                memcpy_to_float_from_i16(
+                        mOutBuffer->audioBuffer()->f32,
+                        mOutConversionBuffer->audioBuffer()->s16,
+                        outChannelCount * mConfig.outputCfg.buffer.frameCount);
+            }
 #endif
         } else {
 #ifdef FLOAT_EFFECT_CHAIN
             data_bypass:
 #endif
             if (!auxType  /* aux effects do not require data bypass */
-                    && mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw
-                    && inChannelCount == outChannelCount) {
-                const size_t sampleCount = std::min(
-                        mConfig.inputCfg.buffer.frameCount,
-                        mConfig.outputCfg.buffer.frameCount) * outChannelCount;
-
-#ifdef FLOAT_EFFECT_CHAIN
-                const float * const in = mConfig.inputCfg.buffer.f32;
-                float * const out = mConfig.outputCfg.buffer.f32;
-
+                    && mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
                 if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
-                    accumulate_float(out, in, sampleCount);
+                    accumulateInputToOutput();
                 } else {
-                    memcpy(mConfig.outputCfg.buffer.f32, mConfig.inputCfg.buffer.f32,
-                            sampleCount * sizeof(*mConfig.outputCfg.buffer.f32));
+                    copyInputToOutput();
                 }
-
-#else
-                const int16_t * const in = mConfig.inputCfg.buffer.s16;
-                int16_t * const out = mConfig.outputCfg.buffer.s16;
-
-                if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
-                    accumulate_i16(out, in, sampleCount);
-                } else {
-                    memcpy(mConfig.outputCfg.buffer.s16, mConfig.inputCfg.buffer.s16,
-                            sampleCount * sizeof(*mConfig.outputCfg.buffer.s16));
-                }
-#endif
             }
             ret = -ENODATA;
         }
+
         // force transition to IDLE state when engine is ready
         if (mState == STOPPED && ret == -ENODATA) {
             mDisableWaitCnt = 1;
@@ -417,21 +426,8 @@
         // If an insert effect is idle and input buffer is different from output buffer,
         // accumulate input onto output
         sp<EffectChain> chain = mChain.promote();
-        if (chain != 0
-                && chain->activeTrackCnt() != 0
-                && inChannelCount == outChannelCount) {
-            const size_t sampleCount = std::min(
-                    mConfig.inputCfg.buffer.frameCount,
-                    mConfig.outputCfg.buffer.frameCount) * outChannelCount;
-#ifdef FLOAT_EFFECT_CHAIN
-            const float * const in = mConfig.inputCfg.buffer.f32;
-            float * const out = mConfig.outputCfg.buffer.f32;
-            accumulate_float(out, in, sampleCount);
-#else
-            const int16_t * const in = mConfig.inputCfg.buffer.s16;
-            int16_t * const out = mConfig.outputCfg.buffer.s16;
-            accumulate_i16(out, in, sampleCount);
-#endif
+        if (chain.get() != nullptr && chain->activeTrackCnt() != 0) {
+            accumulateInputToOutput();
         }
     }
 }
@@ -906,7 +902,7 @@
     mEffectInterface->setInBuffer(buffer);
 
 #ifdef FLOAT_EFFECT_CHAIN
-    // aux effects do in place conversion to float - we don't allocate mInBuffer16 for them.
+    // aux effects do in place conversion to float - we don't allocate mInConversionBuffer.
     // Theoretically insert effects can also do in-place conversions (destroying
     // the original buffer) when the output buffer is identical to the input buffer,
     // but we don't optimize for it here.
@@ -920,17 +916,17 @@
         ALOGV("%s: setInBuffer updating for inChannels:%d inFrameCount:%zu total size:%zu",
                 __func__, inChannels, inFrameCount, size);
 
-        if (size > 0 && (mInBuffer16.get() == nullptr || size > mInBuffer16->getSize())) {
-            mInBuffer16.clear();
-            ALOGV("%s: allocating mInBuffer16 %zu", __func__, size);
-            (void)EffectBufferHalInterface::allocate(size, &mInBuffer16);
+        if (size > 0 && (mInConversionBuffer.get() == nullptr
+                || size > mInConversionBuffer->getSize())) {
+            mInConversionBuffer.clear();
+            ALOGV("%s: allocating mInConversionBuffer %zu", __func__, size);
+            (void)EffectBufferHalInterface::allocate(size, &mInConversionBuffer);
         }
-        if (mInBuffer16.get() != nullptr) {
-            // FIXME: confirm buffer has enough size.
-            mInBuffer16->setFrameCount(inFrameCount);
-            mEffectInterface->setInBuffer(mInBuffer16);
+        if (mInConversionBuffer.get() != nullptr) {
+            mInConversionBuffer->setFrameCount(inFrameCount);
+            mEffectInterface->setInBuffer(mInConversionBuffer);
         } else if (size > 0) {
-            ALOGE("%s cannot create mInBuffer16", __func__);
+            ALOGE("%s cannot create mInConversionBuffer", __func__);
         }
     }
 #endif
@@ -948,7 +944,7 @@
     mEffectInterface->setOutBuffer(buffer);
 
 #ifdef FLOAT_EFFECT_CHAIN
-    // Note: Any effect that does not accumulate does not need mOutBuffer16 and
+    // Note: Any effect that does not accumulate does not need mOutConversionBuffer and
     // can do in-place conversion from int16_t to float.  We don't optimize here.
     if (!mSupportsFloat && mOutBuffer.get() != nullptr) {
         const size_t outFrameCount = mConfig.outputCfg.buffer.frameCount;
@@ -958,16 +954,17 @@
         ALOGV("%s: setOutBuffer updating for outChannels:%d outFrameCount:%zu total size:%zu",
                 __func__, outChannels, outFrameCount, size);
 
-        if (size > 0 && (mOutBuffer16.get() == nullptr || size > mOutBuffer16->getSize())) {
-            mOutBuffer16.clear();
-            ALOGV("%s: allocating mOutBuffer16 %zu", __func__, size);
-            (void)EffectBufferHalInterface::allocate(size, &mOutBuffer16);
+        if (size > 0 && (mOutConversionBuffer.get() == nullptr
+                || size > mOutConversionBuffer->getSize())) {
+            mOutConversionBuffer.clear();
+            ALOGV("%s: allocating mOutConversionBuffer %zu", __func__, size);
+            (void)EffectBufferHalInterface::allocate(size, &mOutConversionBuffer);
         }
-        if (mOutBuffer16.get() != nullptr) {
-            mOutBuffer16->setFrameCount(outFrameCount);
-            mEffectInterface->setOutBuffer(mOutBuffer16);
+        if (mOutConversionBuffer.get() != nullptr) {
+            mOutConversionBuffer->setFrameCount(outFrameCount);
+            mEffectInterface->setOutBuffer(mOutConversionBuffer);
         } else if (size > 0) {
-            ALOGE("%s cannot create mOutBuffer16", __func__);
+            ALOGE("%s cannot create mOutConversionBuffer", __func__);
         }
     }
 #endif
@@ -1241,6 +1238,20 @@
     return s;
 }
 
+static std::string dumpInOutBuffer(bool isInput, const sp<EffectBufferHalInterface> &buffer) {
+    std::stringstream ss;
+
+    if (buffer.get() == nullptr) {
+        return "nullptr"; // make different than below
+    } else if (buffer->externalData() != nullptr) {
+        ss << (isInput ? buffer->externalData() : buffer->audioBuffer()->raw)
+                << " -> "
+                << (isInput ? buffer->audioBuffer()->raw : buffer->externalData());
+    } else {
+        ss << buffer->audioBuffer()->raw;
+    }
+    return ss.str();
+}
 
 void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args __unused)
 {
@@ -1305,19 +1316,13 @@
     result.append(buffer);
 
 #ifdef FLOAT_EFFECT_CHAIN
-    if (!mSupportsFloat) {
-        int16_t* pIn16 = mInBuffer16 != 0 ? mInBuffer16->audioBuffer()->s16 : NULL;
-        int16_t* pOut16 = mOutBuffer16 != 0 ? mOutBuffer16->audioBuffer()->s16 : NULL;
 
-        result.append("\t\t- Float and int16 buffers\n");
-        result.append("\t\t\tIn_float   In_int16   Out_float  Out_int16\n");
-        snprintf(buffer, SIZE,"\t\t\t%p %p %p %p\n",
-                mConfig.inputCfg.buffer.raw,
-                pIn16,
-                pOut16,
-                mConfig.outputCfg.buffer.raw);
-        result.append(buffer);
-    }
+    result.appendFormat("\t\t- HAL buffers:\n"
+            "\t\t\tIn(%s) InConversion(%s) Out(%s) OutConversion(%s)\n",
+            dumpInOutBuffer(true /* isInput */, mInBuffer).c_str(),
+            dumpInOutBuffer(true /* isInput */, mInConversionBuffer).c_str(),
+            dumpInOutBuffer(false /* isInput */, mOutBuffer).c_str(),
+            dumpInOutBuffer(false /* isInput */, mOutConversionBuffer).c_str());
 #endif
 
     snprintf(buffer, SIZE, "\t\t%zu Clients:\n", mHandles.size());
@@ -2161,19 +2166,6 @@
     }
 }
 
-static void dumpInOutBuffer(
-        char *dump, size_t dumpSize, bool isInput, EffectBufferHalInterface *buffer) {
-    if (buffer == nullptr) {
-        snprintf(dump, dumpSize, "%p", buffer);
-    } else if (buffer->externalData() != nullptr) {
-        snprintf(dump, dumpSize, "%p -> %p",
-                isInput ? buffer->externalData() : buffer->audioBuffer()->raw,
-                isInput ? buffer->audioBuffer()->raw : buffer->externalData());
-    } else {
-        snprintf(dump, dumpSize, "%p", buffer->audioBuffer()->raw);
-    }
-}
-
 void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
 {
     const size_t SIZE = 256;
@@ -2191,15 +2183,13 @@
             result.append("\tCould not lock mutex:\n");
         }
 
-        char inBufferStr[64], outBufferStr[64];
-        dumpInOutBuffer(inBufferStr, sizeof(inBufferStr), true, mInBuffer.get());
-        dumpInOutBuffer(outBufferStr, sizeof(outBufferStr), false, mOutBuffer.get());
-        snprintf(buffer, SIZE, "\t%-*s%-*s   Active tracks:\n",
-                (int)strlen(inBufferStr), "In buffer    ",
-                (int)strlen(outBufferStr), "Out buffer      ");
-        result.append(buffer);
-        snprintf(buffer, SIZE, "\t%s   %s   %d\n", inBufferStr, outBufferStr, mActiveTrackCnt);
-        result.append(buffer);
+        const std::string inBufferStr = dumpInOutBuffer(true /* isInput */, mInBuffer);
+        const std::string outBufferStr = dumpInOutBuffer(false /* isInput */, mOutBuffer);
+        result.appendFormat("\t%-*s%-*s   Active tracks:\n",
+                (int)inBufferStr.size(), "In buffer    ",
+                (int)outBufferStr.size(), "Out buffer      ");
+        result.appendFormat("\t%s   %s   %d\n",
+                inBufferStr.c_str(), outBufferStr.c_str(), mActiveTrackCnt);
         write(fd, result.string(), result.size());
 
         for (size_t i = 0; i < numEffects; ++i) {
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 1864e0f..eea3208 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -171,8 +171,8 @@
 
 #ifdef FLOAT_EFFECT_CHAIN
     bool    mSupportsFloat;         // effect supports float processing
-    sp<EffectBufferHalInterface> mInBuffer16;  // Buffers for interacting with HAL at 16 bits
-    sp<EffectBufferHalInterface> mOutBuffer16;
+    sp<EffectBufferHalInterface> mInConversionBuffer;  // Buffers for HAL conversion if needed.
+    sp<EffectBufferHalInterface> mOutConversionBuffer;
 #endif
 };
 
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index 6475f22..2e4fb8c 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -78,7 +78,12 @@
     uint32_t bounds = mBounds;
     uint32_t newestOpen = bounds & 0xFFFF;
     uint32_t oldestClosed = bounds >> 16;
-    uint32_t n = (newestOpen - oldestClosed) & 0xFFFF;
+
+    //uint32_t n = (newestOpen - oldestClosed) & 0xFFFF;
+    uint32_t n;
+    __builtin_sub_overflow(newestOpen, oldestClosed, &n);
+    n = n & 0xFFFF;
+
     if (n > mSamplingN) {
         ALOGE("too many samples %u", n);
         n = mSamplingN;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 1445572..cdd8ca0 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1102,11 +1102,12 @@
 
 void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
 {
-    for (size_t i = 0; i < mSyncEvents.size(); i++) {
+    for (size_t i = 0; i < mSyncEvents.size();) {
         if (mSyncEvents[i]->type() == type) {
             mSyncEvents[i]->trigger();
             mSyncEvents.removeAt(i);
-            i--;
+        } else {
+            ++i;
         }
     }
 }
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 118f0d2..ec04ef7 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -34,11 +34,7 @@
 {
 public:
     IOProfile(const String8 &name, audio_port_role_t role)
-        : AudioPort(name, AUDIO_PORT_TYPE_MIX, role),
-          maxOpenCount((role == AUDIO_PORT_ROLE_SOURCE) ? 1 : 0),
-          curOpenCount(0),
-          maxActiveCount(1),
-          curActiveCount(0) {}
+        : AudioPort(name, AUDIO_PORT_TYPE_MIX, role) {}
 
     // For a Profile aka MixPort, tag name and name are equivalent.
     virtual const String8 getTagName() const { return getName(); }
@@ -107,34 +103,6 @@
 
     const DeviceVector &getSupportedDevices() const { return mSupportedDevices; }
 
-    bool canOpenNewIo() {
-        if (maxOpenCount == 0 || curOpenCount < maxOpenCount) {
-            return true;
-        }
-        return false;
-    }
-
-    bool canStartNewIo() {
-        if (maxActiveCount == 0 || curActiveCount < maxActiveCount) {
-            return true;
-        }
-        return false;
-    }
-
-    // Maximum number of input or output streams that can be simultaneously opened for this profile.
-    // By convention 0 means no limit. To respect legacy behavior, initialized to 1 for output
-    // profiles and 0 for input profiles
-    uint32_t     maxOpenCount;
-    // Number of streams currently opened for this profile.
-    uint32_t     curOpenCount;
-    // Maximum number of input or output streams that can be simultaneously active for this profile.
-    // By convention 0 means no limit. To respect legacy behavior, initialized to 0 for output
-    // profiles and 1 for input profiles
-    uint32_t     maxActiveCount;
-    // Number of streams currently active for this profile. This is not the number of active clients
-    // (AudioTrack or AudioRecord) but the number of active HAL streams.
-    uint32_t     curActiveCount;
-
 private:
     DeviceVector mSupportedDevices; // supported devices: this input/output can be routed from/to
 };
diff --git a/services/audiopolicy/common/managerdefinitions/include/Serializer.h b/services/audiopolicy/common/managerdefinitions/include/Serializer.h
index 3b0e209..078b582 100644
--- a/services/audiopolicy/common/managerdefinitions/include/Serializer.h
+++ b/services/audiopolicy/common/managerdefinitions/include/Serializer.h
@@ -92,8 +92,6 @@
         static const char name[];
         static const char role[];
         static const char flags[];
-        static const char maxOpenCount[];
-        static const char maxActiveCount[];
     };
 
     typedef IOProfile Element;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 737872d..624e688 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -236,7 +236,6 @@
         mFormat = lConfig.format;
         mId = AudioPort::getNextUniqueId();
         mIoHandle = *input;
-        mProfile->curOpenCount++;
     }
 
     return status;
@@ -247,10 +246,6 @@
 {
     if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
         mClientInterface->closeInput(mIoHandle);
-        LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
-                            __FUNCTION__, mProfile->curOpenCount);
-        mProfile->curOpenCount--;
-        mIoHandle = AUDIO_IO_HANDLE_NONE;
     }
 }
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index be5a1c1..f96c5bc 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -444,7 +444,6 @@
         mFormat = lConfig.format;
         mId = AudioPort::getNextUniqueId();
         mIoHandle = *output;
-        mProfile->curOpenCount++;
     }
 
     return status;
@@ -459,11 +458,6 @@
         mClientInterface->setParameters(mIoHandle, param.toString());
 
         mClientInterface->closeOutput(mIoHandle);
-
-        LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
-                            __FUNCTION__, mProfile->curOpenCount);
-        mProfile->curOpenCount--;
-        mIoHandle = AUDIO_IO_HANDLE_NONE;
     }
 }
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index cc56fb8..32a46f3 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -252,60 +252,40 @@
 
 sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
 {
-    sp <HwModule> module;
-
-    for (size_t i = 0; i < size(); i++)
-    {
-        if (strcmp(itemAt(i)->getName(), name) == 0) {
-            return itemAt(i);
+    for (const auto& module : *this) {
+        if (strcmp(module->getName(), name) == 0) {
+            return module;
         }
     }
-    return module;
+    return nullptr;
 }
 
-
 sp <HwModule> HwModuleCollection::getModuleForDevice(audio_devices_t device) const
 {
-    sp <HwModule> module;
-
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->getHandle() == 0) {
-            continue;
-        }
-        if (audio_is_output_device(device)) {
-            for (size_t j = 0; j < itemAt(i)->mOutputProfiles.size(); j++)
-            {
-                if (itemAt(i)->mOutputProfiles[j]->supportDevice(device)) {
-                    return itemAt(i);
-                }
-            }
-        } else {
-            for (size_t j = 0; j < itemAt(i)->mInputProfiles.size(); j++) {
-                if (itemAt(i)->mInputProfiles[j]->supportDevice(device)) {
-                    return itemAt(i);
-                }
+    for (const auto& module : *this) {
+        IOProfileCollection& profiles = audio_is_output_device(device) ?
+                module->mOutputProfiles : module->mInputProfiles;
+        for (const auto& profile : profiles) {
+            if (profile->supportDevice(device)) {
+                return module;
             }
         }
     }
-    return module;
+    return nullptr;
 }
 
-sp<DeviceDescriptor>  HwModuleCollection::getDeviceDescriptor(const audio_devices_t device,
-                                                              const char *device_address,
-                                                              const char *device_name,
-                                                              bool matchAdress) const
+sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t device,
+                                                             const char *device_address,
+                                                             const char *device_name,
+                                                             bool matchAdress) const
 {
-    String8 address = (device_address == NULL) ? String8("") : String8(device_address);
+    String8 address = (device_address == nullptr) ? String8("") : String8(device_address);
     // handle legacy remote submix case where the address was not always specified
     if (device_distinguishes_on_address(device) && (address.length() == 0)) {
         address = String8("0");
     }
 
-    for (size_t i = 0; i < size(); i++) {
-        const sp<HwModule> hwModule = itemAt(i);
-        if (hwModule->mHandle == 0) {
-            continue;
-        }
+    for (const auto& hwModule : *this) {
         DeviceVector declaredDevices = hwModule->getDeclaredDevices();
         DeviceVector deviceList = declaredDevices.getDevicesFromTypeAddr(device, address);
         if (!deviceList.isEmpty()) {
@@ -340,4 +320,5 @@
     return NO_ERROR;
 }
 
+
 } //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index fc89672..74ef4ec 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -122,16 +122,6 @@
     result.append("\n");
     write(fd, result.string(), result.size());
     mSupportedDevices.dump(fd, String8("Supported"), 4, false);
-
-    result.clear();
-    snprintf(buffer, SIZE, "\n    - maxOpenCount: %u - curOpenCount: %u\n",
-             maxOpenCount, curOpenCount);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "    - maxActiveCount: %u - curActiveCount: %u\n",
-             maxActiveCount, curActiveCount);
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
 }
 
 void IOProfile::log()
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index aa589f4..0908ffc 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -217,8 +217,6 @@
 const char MixPortTraits::Attributes::name[] = "name";
 const char MixPortTraits::Attributes::role[] = "role";
 const char MixPortTraits::Attributes::flags[] = "flags";
-const char MixPortTraits::Attributes::maxOpenCount[] = "maxOpenCount";
-const char MixPortTraits::Attributes::maxActiveCount[] = "maxActiveCount";
 
 status_t MixPortTraits::deserialize(_xmlDoc *doc, const _xmlNode *child, PtrElement &mixPort,
                                     PtrSerializingCtx /*serializingContext*/)
@@ -261,14 +259,6 @@
             mixPort->setFlags(InputFlagConverter::maskFromString(flags));
         }
     }
-    string maxOpenCount = getXmlAttribute(child, Attributes::maxOpenCount);
-    if (!maxOpenCount.empty()) {
-        convertTo(maxOpenCount, mixPort->maxOpenCount);
-    }
-    string maxActiveCount = getXmlAttribute(child, Attributes::maxActiveCount);
-    if (!maxActiveCount.empty()) {
-        convertTo(maxActiveCount, mixPort->maxActiveCount);
-    }
     // Deserialize children
     AudioGainTraits::Collection gains;
     deserializeCollection<AudioGainTraits>(doc, child, gains, NULL);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index b363779..bfefbf8 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -721,12 +721,9 @@
 
     sp<IOProfile> profile;
 
-    for (size_t i = 0; i < mHwModules.size(); i++) {
-        if (mHwModules[i]->mHandle == 0) {
-            continue;
-        }
-        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
-            sp<IOProfile> curProfile = mHwModules[i]->mOutputProfiles[j];
+    for (const auto& hwModule : mHwModules) {
+        for (size_t j = 0; j < hwModule->mOutputProfiles.size(); j++) {
+            sp<IOProfile> curProfile = hwModule->mOutputProfiles[j];
             if (!curProfile->isCompatibleProfile(device, String8(""),
                     samplingRate, NULL /*updatedSamplingRate*/,
                     format, NULL /*updatedFormat*/,
@@ -926,29 +923,37 @@
     }
 
     if (profile != 0) {
+        sp<SwAudioOutputDescriptor> outputDesc = NULL;
+
         for (size_t i = 0; i < mOutputs.size(); i++) {
             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
             if (!desc->isDuplicated() && (profile == desc->mProfile)) {
+                outputDesc = desc;
                 // reuse direct output if currently open by the same client
                 // and configured with same parameters
-                if ((config->sample_rate == desc->mSamplingRate) &&
-                    audio_formats_match(config->format, desc->mFormat) &&
-                    (config->channel_mask == desc->mChannelMask) &&
-                    (session == desc->mDirectClientSession)) {
-                    desc->mDirectOpenCount++;
-                    ALOGV("getOutputForDevice() reusing direct output %d for session %d",
-                        mOutputs.keyAt(i), session);
-                    return mOutputs.keyAt(i);
+                if ((config->sample_rate == outputDesc->mSamplingRate) &&
+                    audio_formats_match(config->format, outputDesc->mFormat) &&
+                    (config->channel_mask == outputDesc->mChannelMask)) {
+                  if (session == outputDesc->mDirectClientSession) {
+                      outputDesc->mDirectOpenCount++;
+                      ALOGV("getOutputForDevice() reusing direct output %d for session %d",
+                            mOutputs.keyAt(i), session);
+                      return mOutputs.keyAt(i);
+                  } else {
+                      ALOGV("getOutputForDevice() do not reuse direct output because"
+                              "current client (%d) is not the same as requesting client (%d)",
+                            outputDesc->mDirectClientSession, session);
+                      goto non_direct_output;
+                  }
                 }
             }
         }
-
-        if (!profile->canOpenNewIo()) {
-            goto non_direct_output;
+        // close direct output if currently open and configured with different parameters
+        if (outputDesc != NULL) {
+            closeOutput(outputDesc->mIoHandle);
         }
 
-        sp<SwAudioOutputDescriptor> outputDesc =
-                new SwAudioOutputDescriptor(profile, mpClientInterface);
+        outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
         status = outputDesc->open(config, device, String8(""), stream, flags, &output);
 
         // only accept an output with the requested parameters
@@ -1106,13 +1111,6 @@
 
     sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
 
-    if (!outputDesc->isActive()) {
-        if (!outputDesc->mProfile->canStartNewIo()) {
-            return INVALID_OPERATION;
-        }
-        outputDesc->mProfile->curActiveCount++;
-    }
-
     // Routing?
     mOutputRoutes.incRouteActivity(session);
 
@@ -1140,12 +1138,6 @@
 
     if (status != NO_ERROR) {
         mOutputRoutes.decRouteActivity(session);
-        if (!outputDesc->isActive()) {
-            LOG_ALWAYS_FATAL_IF(outputDesc->mProfile->curActiveCount < 1,
-                                "%s invalid profile active count %u",
-                                __FUNCTION__, outputDesc->mProfile->curActiveCount);
-            outputDesc->mProfile->curActiveCount--;
-        }
         return status;
     }
     // Automatically enable the remote submix input when output is started on a re routing mix
@@ -1334,15 +1326,7 @@
         }
     }
 
-    status_t status = stopSource(outputDesc, stream, forceDeviceUpdate);
-
-    if (status == NO_ERROR && !outputDesc->isActive()) {
-        LOG_ALWAYS_FATAL_IF(outputDesc->mProfile->curActiveCount < 1,
-                            "%s invalid profile active count %u",
-                            __FUNCTION__, outputDesc->mProfile->curActiveCount);
-        outputDesc->mProfile->curActiveCount--;
-    }
-    return status;
+    return stopSource(outputDesc, stream, forceDeviceUpdate);
 }
 
 status_t AudioPolicyManager::stopSource(const sp<AudioOutputDescriptor>& outputDesc,
@@ -1728,10 +1712,6 @@
     }
 #endif
 
-    if (!profile->canOpenNewIo()) {
-        return AUDIO_IO_HANDLE_NONE;
-    }
-
     sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile, mpClientInterface);
 
     audio_config_t lConfig = AUDIO_CONFIG_INITIALIZER;
@@ -1969,13 +1949,6 @@
         setInputDevice(input, device, true /* force */);
 
         if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
-            if (!inputDesc->mProfile->canStartNewIo()) {
-                mInputRoutes.decRouteActivity(session);
-                audioSession->changeActiveCount(-1);
-                return INVALID_OPERATION;
-            }
-            inputDesc->mProfile->curActiveCount++;
-
             // if input maps to a dynamic policy with an activity listener, notify of state change
             if ((inputDesc->mPolicyMix != NULL)
                     && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
@@ -2045,11 +2018,6 @@
         if (inputDesc->isActive()) {
             setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
         } else {
-            LOG_ALWAYS_FATAL_IF(inputDesc->mProfile->curActiveCount < 1,
-                                "%s invalid profile active count %u",
-                                __FUNCTION__, inputDesc->mProfile->curActiveCount);
-            inputDesc->mProfile->curActiveCount--;
-
             // if input maps to a dynamic policy with an activity listener, notify of state change
             if ((inputDesc->mPolicyMix != NULL)
                     && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
@@ -2424,23 +2392,16 @@
             break;
         }
         if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
-            // Loop back through "remote submix"
-            if (rSubmixModule == 0) {
-                for (size_t j = 0; i < mHwModules.size(); j++) {
-                    if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[j]->mName) == 0
-                            && mHwModules[j]->mHandle != 0) {
-                        rSubmixModule = mHwModules[j];
-                        break;
-                    }
-                }
-            }
-
             ALOGV("registerPolicyMixes() mix %zu of %zu is LOOP_BACK", i, mixes.size());
-
             if (rSubmixModule == 0) {
-                ALOGE(" Unable to find audio module for submix, aborting mix %zu registration", i);
-                res = INVALID_OPERATION;
-                break;
+                rSubmixModule = mHwModules.getModuleFromName(
+                        AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX);
+                if (rSubmixModule == 0) {
+                    ALOGE(" Unable to find audio module for submix, aborting mix %zu registration",
+                            i);
+                    res = INVALID_OPERATION;
+                    break;
+                }
             }
 
             String8 address = mixes[i].mDeviceAddress;
@@ -2523,18 +2484,13 @@
         if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
 
             if (rSubmixModule == 0) {
-                for (size_t j = 0; i < mHwModules.size(); j++) {
-                    if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[j]->mName) == 0
-                            && mHwModules[j]->mHandle != 0) {
-                        rSubmixModule = mHwModules[j];
-                        break;
-                    }
+                rSubmixModule = mHwModules.getModuleFromName(
+                        AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX);
+                if (rSubmixModule == 0) {
+                    res = INVALID_OPERATION;
+                    continue;
                 }
             }
-            if (rSubmixModule == 0) {
-                res = INVALID_OPERATION;
-                continue;
-            }
 
             String8 address = mixes[i].mDeviceAddress;
 
@@ -2611,7 +2567,7 @@
 
     mAvailableOutputDevices.dump(fd, String8("Available output"));
     mAvailableInputDevices.dump(fd, String8("Available input"));
-    mHwModules.dump(fd);
+    mHwModulesAll.dump(fd);
     mOutputs.dump(fd);
     mInputs.dump(fd);
     mVolumeCurves->dump(fd);
@@ -3555,13 +3511,13 @@
 
 #ifdef USE_XML_AUDIO_POLICY_CONF
     mVolumeCurves = new VolumeCurvesCollection();
-    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
+    AudioPolicyConfig config(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
                              mDefaultOutputDevice, speakerDrcEnabled,
                              static_cast<VolumeCurvesCollection *>(mVolumeCurves));
     if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
 #else
     mVolumeCurves = new StreamDescriptorCollection();
-    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
+    AudioPolicyConfig config(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
                              mDefaultOutputDevice, speakerDrcEnabled);
     if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
             (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
@@ -3593,28 +3549,23 @@
     // open all output streams needed to access attached devices
     audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
     audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
-    for (size_t i = 0; i < mHwModules.size(); i++) {
-        mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
-        if (mHwModules[i]->mHandle == 0) {
-            ALOGW("could not open HW module %s", mHwModules[i]->getName());
+    for (const auto& hwModule : mHwModulesAll) {
+        hwModule->mHandle = mpClientInterface->loadHwModule(hwModule->getName());
+        if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
+            ALOGW("could not open HW module %s", hwModule->getName());
             continue;
         }
+        mHwModules.push_back(hwModule);
         // open all output streams needed to access attached devices
         // except for direct output streams that are only opened when they are actually
         // required by an app.
         // This also validates mAvailableOutputDevices list
-        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
+        for (size_t j = 0; j < hwModule->mOutputProfiles.size(); j++)
         {
-            const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
-
-            if (!outProfile->canOpenNewIo()) {
-                ALOGE("Invalid Output profile max open count %u for profile %s",
-                      outProfile->maxOpenCount, outProfile->getTagName().c_str());
-                continue;
-            }
+            const sp<IOProfile> outProfile = hwModule->mOutputProfiles[j];
 
             if (!outProfile->hasSupportedDevices()) {
-                ALOGW("Output profile contains no device on module %s", mHwModules[i]->getName());
+                ALOGW("Output profile contains no device on module %s", hwModule->getName());
                 continue;
             }
             if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
@@ -3648,13 +3599,13 @@
             if (status != NO_ERROR) {
                 ALOGW("Cannot open output stream for device %08x on hw module %s",
                       outputDesc->mDevice,
-                      mHwModules[i]->getName());
+                      hwModule->getName());
             } else {
                 for (size_t k = 0; k  < supportedDevices.size(); k++) {
                     ssize_t index = mAvailableOutputDevices.indexOf(supportedDevices[k]);
                     // give a valid ID to an attached device once confirmed it is reachable
                     if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
-                        mAvailableOutputDevices[index]->attach(mHwModules[i]);
+                        mAvailableOutputDevices[index]->attach(hwModule);
                     }
                 }
                 if (mPrimaryOutput == 0 &&
@@ -3672,18 +3623,12 @@
         }
         // open input streams needed to access attached devices to validate
         // mAvailableInputDevices list
-        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
+        for (size_t j = 0; j < hwModule->mInputProfiles.size(); j++)
         {
-            const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
-
-            if (!inProfile->canOpenNewIo()) {
-                ALOGE("Invalid Input profile max open count %u for profile %s",
-                      inProfile->maxOpenCount, inProfile->getTagName().c_str());
-                continue;
-            }
+            const sp<IOProfile> inProfile = hwModule->mInputProfiles[j];
 
             if (!inProfile->hasSupportedDevices()) {
-                ALOGW("Input profile contains no device on module %s", mHwModules[i]->getName());
+                ALOGW("Input profile contains no device on module %s", hwModule->getName());
                 continue;
             }
             // chose first device present in profile's SupportedDevices also part of
@@ -3712,7 +3657,7 @@
                     if (index >= 0) {
                         sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
                         if (!devDesc->isAttached()) {
-                            devDesc->attach(mHwModules[i]);
+                            devDesc->attach(hwModule);
                             devDesc->importAudioPort(inProfile, true);
                         }
                     }
@@ -3721,7 +3666,7 @@
             } else {
                 ALOGW("Cannot open input stream for device %08x on hw module %s",
                       profileType,
-                      mHwModules[i]->getName());
+                      hwModule->getName());
             }
         }
     }
@@ -3771,6 +3716,7 @@
    mOutputs.clear();
    mInputs.clear();
    mHwModules.clear();
+   mHwModulesAll.clear();
 }
 
 status_t AudioPolicyManager::initCheck()
@@ -3842,19 +3788,17 @@
         }
         // then look for output profiles that can be routed to this device
         SortedVector< sp<IOProfile> > profiles;
-        for (size_t i = 0; i < mHwModules.size(); i++)
+        for (const auto& hwModule : mHwModules)
         {
-            if (mHwModules[i]->mHandle == 0) {
-                continue;
-            }
-            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
+            for (size_t j = 0; j < hwModule->mOutputProfiles.size(); j++)
             {
-                sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
+                sp<IOProfile> profile = hwModule->mOutputProfiles[j];
                 if (profile->supportDevice(device)) {
                     if (!device_distinguishes_on_address(device) ||
                             profile->supportDeviceAddress(address)) {
                         profiles.add(profile);
-                        ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
+                        ALOGV("checkOutputsForDevice(): adding profile %zu from module %s",
+                                j, hwModule->getName());
                     }
                 }
             }
@@ -3889,12 +3833,6 @@
                 continue;
             }
 
-            if (!profile->canOpenNewIo()) {
-                ALOGW("Max Output number %u already opened for this profile %s",
-                      profile->maxOpenCount, profile->getTagName().c_str());
-                continue;
-            }
-
             ALOGV("opening output for device %08x with params %s profile %p name %s",
                   device, address.string(), profile.get(), profile->getName().string());
             desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
@@ -4024,17 +3962,15 @@
             }
         }
         // Clear any profiles associated with the disconnected device.
-        for (size_t i = 0; i < mHwModules.size(); i++)
+        for (const auto& hwModule : mHwModules)
         {
-            if (mHwModules[i]->mHandle == 0) {
-                continue;
-            }
-            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
+            for (size_t j = 0; j < hwModule->mOutputProfiles.size(); j++)
             {
-                sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
+                sp<IOProfile> profile = hwModule->mOutputProfiles[j];
                 if (profile->supportDevice(device)) {
                     ALOGV("checkOutputsForDevice(): "
-                            "clearing direct output profile %zu on module %zu", j, i);
+                            "clearing direct output profile %zu on module %s",
+                            j, hwModule->getName());
                     profile->clearAudioProfiles();
                 }
             }
@@ -4068,23 +4004,20 @@
 
         // then look for input profiles that can be routed to this device
         SortedVector< sp<IOProfile> > profiles;
-        for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
+        for (const auto& hwModule : mHwModules)
         {
-            if (mHwModules[module_idx]->mHandle == 0) {
-                continue;
-            }
             for (size_t profile_index = 0;
-                 profile_index < mHwModules[module_idx]->mInputProfiles.size();
+                 profile_index < hwModule->mInputProfiles.size();
                  profile_index++)
             {
-                sp<IOProfile> profile = mHwModules[module_idx]->mInputProfiles[profile_index];
+                sp<IOProfile> profile = hwModule->mInputProfiles[profile_index];
 
                 if (profile->supportDevice(device)) {
                     if (!device_distinguishes_on_address(device) ||
                             profile->supportDeviceAddress(address)) {
                         profiles.add(profile);
-                        ALOGV("checkInputsForDevice(): adding profile %zu from module %zu",
-                              profile_index, module_idx);
+                        ALOGV("checkInputsForDevice(): adding profile %zu from module %s",
+                                profile_index, hwModule->getName());
                     }
                 }
             }
@@ -4100,7 +4033,6 @@
         for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
 
             sp<IOProfile> profile = profiles[profile_index];
-
             // nothing to do if one input is already opened for this profile
             size_t input_index;
             for (input_index = 0; input_index < mInputs.size(); input_index++) {
@@ -4116,12 +4048,6 @@
                 continue;
             }
 
-            if (!profile->canOpenNewIo()) {
-                ALOGW("Max Input number %u already opened for this profile %s",
-                      profile->maxOpenCount, profile->getTagName().c_str());
-                continue;
-            }
-
             desc = new AudioInputDescriptor(profile, mpClientInterface);
             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
             status_t status = desc->open(nullptr,
@@ -4178,17 +4104,14 @@
             }
         }
         // Clear any profiles associated with the disconnected device.
-        for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
-            if (mHwModules[module_index]->mHandle == 0) {
-                continue;
-            }
+        for (const auto& hwModule : mHwModules) {
             for (size_t profile_index = 0;
-                 profile_index < mHwModules[module_index]->mInputProfiles.size();
+                 profile_index < hwModule->mInputProfiles.size();
                  profile_index++) {
-                sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index];
+                sp<IOProfile> profile = hwModule->mInputProfiles[profile_index];
                 if (profile->supportDevice(device)) {
-                    ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu",
-                          profile_index, module_index);
+                    ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %s",
+                            profile_index, hwModule->getName());
                     profile->clearAudioProfiles();
                 }
             }
@@ -5027,14 +4950,11 @@
     // TODO: perhaps isCompatibleProfile should return a "matching" score so we can return
     // the best matching profile, not the first one.
 
-    for (size_t i = 0; i < mHwModules.size(); i++)
+    for (const auto& hwModule : mHwModules)
     {
-        if (mHwModules[i]->mHandle == 0) {
-            continue;
-        }
-        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
+        for (size_t j = 0; j < hwModule->mInputProfiles.size(); j++)
         {
-            sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];
+            sp<IOProfile> profile = hwModule->mInputProfiles[j];
             // profile->log();
             if (profile->isCompatibleProfile(device, address, samplingRate,
                                              &samplingRate /*updatedSamplingRate*/,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 2d41bd1..b61bc2d 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -266,7 +266,7 @@
         {
             return mDefaultOutputDevice;
         }
-protected:
+
         void addOutput(audio_io_handle_t output, const sp<SwAudioOutputDescriptor>& outputDesc);
         void removeOutput(audio_io_handle_t output);
         void addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc);
@@ -530,7 +530,9 @@
         EffectDescriptorCollection mEffects;  // list of registered audio effects
         bool    mA2dpSuspended;  // true if A2DP output is suspended
         sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
-        HwModuleCollection mHwModules;
+        HwModuleCollection mHwModules; // contains only modules that have been loaded successfully
+        HwModuleCollection mHwModulesAll; // normally not needed, used during construction and for
+                                          // dumps
 
         volatile int32_t mAudioPortGeneration;
 
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index 9348ecd..caa0703 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -26,10 +26,6 @@
 LOCAL_32_BIT_ONLY := true
 LOCAL_INIT_RC := android.hardware.media.omx@1.0-service.rc
 
-ifeq ($(PRODUCT_FULL_TREBLE),true)
-LOCAL_CFLAGS += -DUSE_VNDBINDER
-endif
-
 include $(BUILD_EXECUTABLE)
 
 # service seccomp policy
diff --git a/services/mediacodec/main_codecservice.cpp b/services/mediacodec/main_codecservice.cpp
index 6f14a42..701ca6e 100644
--- a/services/mediacodec/main_codecservice.cpp
+++ b/services/mediacodec/main_codecservice.cpp
@@ -40,10 +40,8 @@
     signal(SIGPIPE, SIG_IGN);
     SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
 
-#ifdef USE_VNDBINDER
     android::ProcessState::initWithDriver("/dev/vndbinder");
     android::ProcessState::self()->startThreadPool();
-#endif // USE_VNDBINDER
 
     ::android::hardware::configureRpcThreadpool(64, false);