Merge "Add functions to read MTP events from MTP devices."
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index b78f648..9368309 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -1062,6 +1062,9 @@
                     meta = extractor->getTrackMetaData(
                             i, MediaExtractor::kIncludeExtensiveMetaData);
 
+                    if (meta == NULL) {
+                        break;
+                    }
                     const char *mime;
                     meta->findCString(kKeyMIMEType, &mime);
 
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index a3f014b..18a933f 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -1104,8 +1104,10 @@
         case OPEN_OUTPUT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
-            audio_config_t config;
-            data.read(&config, sizeof(audio_config_t));
+            audio_config_t config = {};
+            if (data.read(&config, sizeof(audio_config_t)) != NO_ERROR) {
+                ALOGE("b/23905951");
+            }
             audio_devices_t devices = (audio_devices_t)data.readInt32();
             String8 address(data.readString8());
             audio_output_flags_t flags = (audio_output_flags_t) data.readInt32();
@@ -1149,8 +1151,10 @@
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
             audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
-            audio_config_t config;
-            data.read(&config, sizeof(audio_config_t));
+            audio_config_t config = {};
+            if (data.read(&config, sizeof(audio_config_t)) != NO_ERROR) {
+                ALOGE("b/23905951");
+            }
             audio_devices_t device = (audio_devices_t)data.readInt32();
             String8 address(data.readString8());
             audio_source_t source = (audio_source_t)data.readInt32();
@@ -1255,8 +1259,10 @@
         }
         case CREATE_EFFECT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            effect_descriptor_t desc;
-            data.read(&desc, sizeof(effect_descriptor_t));
+            effect_descriptor_t desc = {};
+            if (data.read(&desc, sizeof(effect_descriptor_t)) != NO_ERROR) {
+                ALOGE("b/23905951");
+            }
             sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder());
             int32_t priority = data.readInt32();
             audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
@@ -1333,8 +1339,10 @@
         } break;
         case GET_AUDIO_PORT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            struct audio_port port;
-            data.read(&port, sizeof(struct audio_port));
+            struct audio_port port = {};
+            if (data.read(&port, sizeof(struct audio_port)) != NO_ERROR) {
+                ALOGE("b/23905951");
+            }
             status_t status = getAudioPort(&port);
             reply->writeInt32(status);
             if (status == NO_ERROR) {
@@ -1346,8 +1354,10 @@
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             struct audio_patch patch;
             data.read(&patch, sizeof(struct audio_patch));
-            audio_patch_handle_t handle;
-            data.read(&handle, sizeof(audio_patch_handle_t));
+            audio_patch_handle_t handle = {};
+            if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) {
+                ALOGE("b/23905951");
+            }
             status_t status = createAudioPatch(&patch, &handle);
             reply->writeInt32(status);
             if (status == NO_ERROR) {
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 7e6b9fc..0cc954f 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -1148,8 +1148,10 @@
 
         case GET_AUDIO_PORT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            struct audio_port port;
-            data.read(&port, sizeof(struct audio_port));
+            struct audio_port port = {};
+            if (data.read(&port, sizeof(struct audio_port)) != NO_ERROR) {
+                ALOGE("b/23912202");
+            }
             status_t status = getAudioPort(&port);
             reply->writeInt32(status);
             if (status == NO_ERROR) {
@@ -1162,8 +1164,10 @@
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             struct audio_patch patch;
             data.read(&patch, sizeof(struct audio_patch));
-            audio_patch_handle_t handle;
-            data.read(&handle, sizeof(audio_patch_handle_t));
+            audio_patch_handle_t handle = {};
+            if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) {
+                ALOGE("b/23912202");
+            }
             status_t status = createAudioPatch(&patch, &handle);
             reply->writeInt32(status);
             if (status == NO_ERROR) {
@@ -1292,7 +1296,7 @@
             data.read(&source, sizeof(struct audio_port_config));
             audio_attributes_t attributes;
             data.read(&attributes, sizeof(audio_attributes_t));
-            audio_io_handle_t handle;
+            audio_io_handle_t handle = {};
             status_t status = startAudioSource(&source, &attributes, &handle);
             reply->writeInt32(status);
             reply->writeInt32(handle);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index fbe463b..9cc7542 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -112,6 +112,7 @@
       mVideoRenderingStarted(false),
       mVideoRenderingStartGeneration(0),
       mAudioRenderingStartGeneration(0),
+      mRenderingDataDelivered(false),
       mLastAudioMediaTimeUs(-1),
       mAudioOffloadPauseTimeoutGeneration(0),
       mAudioTornDown(false),
@@ -663,11 +664,16 @@
 void NuPlayer::Renderer::prepareForMediaRenderingStart_l() {
     mAudioRenderingStartGeneration = mAudioDrainGeneration;
     mVideoRenderingStartGeneration = mVideoDrainGeneration;
+    mRenderingDataDelivered = false;
 }
 
 void NuPlayer::Renderer::notifyIfMediaRenderingStarted_l() {
     if (mVideoRenderingStartGeneration == mVideoDrainGeneration &&
         mAudioRenderingStartGeneration == mAudioDrainGeneration) {
+        mRenderingDataDelivered = true;
+        if (mPaused) {
+            return;
+        }
         mVideoRenderingStartGeneration = -1;
         mAudioRenderingStartGeneration = -1;
 
@@ -822,6 +828,10 @@
 }
 
 bool NuPlayer::Renderer::onDrainAudioQueue() {
+    // do not drain audio during teardown as queued buffers may be invalid.
+    if (mAudioTornDown) {
+        return false;
+    }
     // TODO: This call to getPosition checks if AudioTrack has been created
     // in AudioSink before draining audio. If AudioTrack doesn't exist, then
     // CHECKs on getPosition will fail.
@@ -1527,6 +1537,7 @@
         cancelAudioOffloadPauseTimeout();
         status_t err = mAudioSink->start();
         if (err != OK) {
+            ALOGE("cannot start AudioSink err %d", err);
             notifyAudioTearDown();
         }
     }
@@ -1534,7 +1545,10 @@
     {
         Mutex::Autolock autoLock(mLock);
         mPaused = false;
-
+        // rendering started message may have been delayed if we were paused.
+        if (mRenderingDataDelivered) {
+            notifyIfMediaRenderingStarted_l();
+        }
         // configure audiosink as we did not do it when pausing
         if (mAudioSink != NULL && mAudioSink->ready()) {
             mAudioSink->setPlaybackRate(mPlaybackSettings);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index de5f9a9..43e2fde 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -177,6 +177,7 @@
     bool mVideoRenderingStarted;
     int32_t mVideoRenderingStartGeneration;
     int32_t mAudioRenderingStartGeneration;
+    bool mRenderingDataDelivered;
 
     // the media timestamp of last audio sample right before EOS.
     int64_t mLastAudioMediaTimeUs;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 29791e3..b0efebc 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2292,11 +2292,11 @@
             // The widevine extractor does its own caching.
 
 #if 0
-            mCachedSource = new NuCachedSource2(
+            mCachedSource = NuCachedSource2::Create(
                     new ThrottledSource(
                         mConnectingDataSource, 50 * 1024 /* bytes/sec */));
 #else
-            mCachedSource = new NuCachedSource2(
+            mCachedSource = NuCachedSource2::Create(
                     mConnectingDataSource,
                     cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
                     disconnectAtHighwatermark);
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 75ef288..5020c6c 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -246,7 +246,7 @@
                 *contentType = httpSource->getMIMEType();
             }
 
-            source = new NuCachedSource2(
+            source = NuCachedSource2::Create(
                     httpSource,
                     cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
                     disconnectAtHighwatermark);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index ec758d5..9085ed7 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -572,6 +572,7 @@
 }
 
 status_t MediaCodec::reclaim() {
+    ALOGD("MediaCodec::reclaim(%p) %s", this, mInitName.c_str());
     sp<AMessage> msg = new AMessage(kWhatRelease, this);
     msg->setInt32("reclaimed", 1);
 
@@ -1175,8 +1176,10 @@
                         resourceType = String8(kResourceNonSecureCodec);
                     }
 
-                    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
-                    addResource(resourceType, String8(subtype), 1);
+                    if (mIsVideo) {
+                        // audio codec is currently ignored.
+                        addResource(resourceType, String8(kResourceVideoCodec), 1);
+                    }
 
                     (new AMessage)->postReply(mReplyID);
                     break;
diff --git a/media/libstagefright/MediaSync.cpp b/media/libstagefright/MediaSync.cpp
index 3a45e25..12669b1 100644
--- a/media/libstagefright/MediaSync.cpp
+++ b/media/libstagefright/MediaSync.cpp
@@ -635,7 +635,7 @@
 
     ALOGV("acquired buffer %#llx from input", (long long)bufferItem.mGraphicBuffer->getId());
 
-    status = mInput->detachBuffer(bufferItem.mBuf);
+    status = mInput->detachBuffer(bufferItem.mSlot);
     if (status != NO_ERROR) {
         ALOGE("detaching buffer from input failed (%d)", status);
         if (status == NO_INIT) {
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index f82636b..d6255d6 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -224,9 +224,6 @@
     // So whenever we call DataSource::readAt it may end up in a call to
     // IMediaHTTPConnection::readAt and therefore call back into JAVA.
     mLooper->start(false /* runOnCallingThread */, true /* canCallJava */);
-
-    Mutex::Autolock autoLock(mLock);
-    (new AMessage(kWhatFetchMore, mReflector))->post();
 }
 
 NuCachedSource2::~NuCachedSource2() {
@@ -237,6 +234,18 @@
     mCache = NULL;
 }
 
+// static
+sp<NuCachedSource2> NuCachedSource2::Create(
+        const sp<DataSource> &source,
+        const char *cacheConfig,
+        bool disconnectAtHighwatermark) {
+    sp<NuCachedSource2> instance = new NuCachedSource2(
+            source, cacheConfig, disconnectAtHighwatermark);
+    Mutex::Autolock autoLock(instance->mLock);
+    (new AMessage(kWhatFetchMore, instance->mReflector))->post();
+    return instance;
+}
+
 status_t NuCachedSource2::getEstimatedBandwidthKbps(int32_t *kbps) {
     if (mSource->flags() & kIsHTTPBasedSource) {
         HTTPBase* source = static_cast<HTTPBase *>(mSource.get());
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index f24cf3a..962b2de 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -186,6 +186,10 @@
 
     for (size_t i = 0; i < mImpl->countTracks(); ++i) {
         sp<MetaData> meta = mImpl->getTrackMetaData(i);
+        if (meta == NULL) {
+            ALOGW("no metadata for track %zu", i);
+            continue;
+        }
 
         int32_t bitrate;
         if (!meta->findInt32(kKeyBitRate, &bitrate)) {
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index e1879b4..5f565e2 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -23,6 +23,7 @@
 #include <cutils/properties.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/base64.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaBufferGroup.h>
@@ -1207,93 +1208,18 @@
 
 }
 
-// The returned buffer should be free()d.
-static uint8_t *DecodeBase64(const char *s, size_t size, size_t *outSize) {
-    *outSize = 0;
-
-    if ((size % 4) != 0) {
-        return NULL;
-    }
-
-    size_t n = size;
-    size_t padding = 0;
-    if (n >= 1 && s[n - 1] == '=') {
-        padding = 1;
-
-        if (n >= 2 && s[n - 2] == '=') {
-            padding = 2;
-        }
-    }
-
-    // We divide first to avoid overflow. It's OK to do this because we
-    // already made sure that size % 4 == 0.
-    size_t outLen = (size / 4) * 3 - padding;
-
-    void *buffer = malloc(outLen);
-    if (buffer == NULL) {
-        return NULL;
-    }
-
-    uint8_t *out = (uint8_t *)buffer;
-    size_t j = 0;
-    uint32_t accum = 0;
-    for (size_t i = 0; i < n; ++i) {
-        char c = s[i];
-        unsigned value;
-        if (c >= 'A' && c <= 'Z') {
-            value = c - 'A';
-        } else if (c >= 'a' && c <= 'z') {
-            value = 26 + c - 'a';
-        } else if (c >= '0' && c <= '9') {
-            value = 52 + c - '0';
-        } else if (c == '+') {
-            value = 62;
-        } else if (c == '/') {
-            value = 63;
-        } else if (c != '=') {
-            break;
-        } else {
-            if (i < n - padding) {
-                break;
-            }
-
-            value = 0;
-        }
-
-        accum = (accum << 6) | value;
-
-        if (((i + 1) % 4) == 0) {
-            out[j++] = (accum >> 16);
-
-            if (j < outLen) { out[j++] = (accum >> 8) & 0xff; }
-            if (j < outLen) { out[j++] = accum & 0xff; }
-
-            accum = 0;
-        }
-    }
-
-    // Check if we exited the loop early.
-    if (j < outLen) {
-        free(buffer);
-        return NULL;
-    }
-
-    *outSize = outLen;
-    return (uint8_t *)buffer;
-}
-
 static void extractAlbumArt(
         const sp<MetaData> &fileMeta, const void *data, size_t size) {
     ALOGV("extractAlbumArt from '%s'", (const char *)data);
 
-    size_t flacSize;
-    uint8_t *flac = DecodeBase64((const char *)data, size, &flacSize);
-
-    if (flac == NULL) {
+    sp<ABuffer> flacBuffer = decodeBase64(AString((const char *)data, size));
+    if (flacBuffer == NULL) {
         ALOGE("malformed base64 encoded data.");
         return;
     }
 
+    size_t flacSize = flacBuffer->size();
+    uint8_t *flac = flacBuffer->data();
     ALOGV("got flac of size %zu", flacSize);
 
     uint32_t picType;
@@ -1303,24 +1229,24 @@
     char type[128];
 
     if (flacSize < 8) {
-        goto exit;
+        return;
     }
 
     picType = U32_AT(flac);
 
     if (picType != 3) {
         // This is not a front cover.
-        goto exit;
+        return;
     }
 
     typeLen = U32_AT(&flac[4]);
     if (typeLen > sizeof(type) - 1) {
-        goto exit;
+        return;
     }
 
     // we've already checked above that flacSize >= 8
     if (flacSize - 8 < typeLen) {
-        goto exit;
+        return;
     }
 
     memcpy(type, &flac[8], typeLen);
@@ -1330,24 +1256,23 @@
 
     if (!strcmp(type, "-->")) {
         // This is not inline cover art, but an external url instead.
-        goto exit;
+        return;
     }
 
     if (flacSize < 32 || flacSize - 32 < typeLen) {
-        goto exit;
+        return;
     }
 
     descLen = U32_AT(&flac[8 + typeLen]);
     if (flacSize - 32 - typeLen < descLen) {
-        goto exit;
+        return;
     }
 
     dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]);
 
-
     // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0
     if (flacSize - 32 - typeLen - descLen < dataLen) {
-        goto exit;
+        return;
     }
 
     ALOGV("got image data, %zu trailing bytes",
@@ -1357,10 +1282,6 @@
             kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen);
 
     fileMeta->setCString(kKeyAlbumArtMIME, type);
-
-exit:
-    free(flac);
-    flac = NULL;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index e8abf48..e4bf67a 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -308,9 +308,9 @@
 
             // First time seeing the buffer?  Added it to the SMS slot
             if (item.mGraphicBuffer != NULL) {
-                mSlots[item.mBuf].mGraphicBuffer = item.mGraphicBuffer;
+                mSlots[item.mSlot].mGraphicBuffer = item.mGraphicBuffer;
             }
-            mSlots[item.mBuf].mFrameNumber = item.mFrameNumber;
+            mSlots[item.mSlot].mFrameNumber = item.mFrameNumber;
 
             // check for the timing of this buffer
             if (mNumFramesReceived == 0 && !mUseAbsoluteTimestamps) {
@@ -320,7 +320,7 @@
                     if (item.mTimestamp < mStartTimeNs) {
                         // This frame predates start of record, discard
                         mConsumer->releaseBuffer(
-                                item.mBuf, item.mFrameNumber, EGL_NO_DISPLAY,
+                                item.mSlot, item.mFrameNumber, EGL_NO_DISPLAY,
                                 EGL_NO_SYNC_KHR, Fence::NO_FENCE);
                         continue;
                     }
@@ -346,13 +346,13 @@
         return ERROR_END_OF_STREAM;
     }
 
-    mCurrentSlot = item.mBuf;
+    mCurrentSlot = item.mSlot;
 
     // First time seeing the buffer?  Added it to the SMS slot
     if (item.mGraphicBuffer != NULL) {
-        mSlots[item.mBuf].mGraphicBuffer = item.mGraphicBuffer;
+        mSlots[item.mSlot].mGraphicBuffer = item.mGraphicBuffer;
     }
-    mSlots[item.mBuf].mFrameNumber = item.mFrameNumber;
+    mSlots[item.mSlot].mFrameNumber = item.mFrameNumber;
 
     mCurrentBuffers.push_back(mSlots[mCurrentSlot].mGraphicBuffer);
     int64_t prevTimeStamp = mCurrentTimestamp;
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 7c8d441..f8d9573 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -89,8 +89,14 @@
 
 status_t convertMetaDataToMessage(
         const sp<MetaData> &meta, sp<AMessage> *format) {
+
     format->clear();
 
+    if (meta == NULL) {
+        ALOGE("convertMetaDataToMessage: NULL input");
+        return BAD_VALUE;
+    }
+
     const char *mime;
     CHECK(meta->findCString(kKeyMIMEType, &mime));
 
diff --git a/media/libstagefright/filters/GraphicBufferListener.cpp b/media/libstagefright/filters/GraphicBufferListener.cpp
index a606315..c1aaa17 100644
--- a/media/libstagefright/filters/GraphicBufferListener.cpp
+++ b/media/libstagefright/filters/GraphicBufferListener.cpp
@@ -101,11 +101,11 @@
     if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
         // shouldn't happen, since we track num frames available
         ALOGE("frame was not available");
-        item.mBuf = -1;
+        item.mSlot = -1;
         return item;
     } else if (err != OK) {
         ALOGE("acquireBuffer returned err=%d", err);
-        item.mBuf = -1;
+        item.mSlot = -1;
         return item;
     }
 
@@ -119,8 +119,8 @@
     // If this is the first time we're seeing this buffer, add it to our
     // slot table.
     if (item.mGraphicBuffer != NULL) {
-        ALOGV("setting mBufferSlot %d", item.mBuf);
-        mBufferSlot[item.mBuf] = item.mGraphicBuffer;
+        ALOGV("setting mBufferSlot %d", item.mSlot);
+        mBufferSlot[item.mSlot] = item.mGraphicBuffer;
     }
 
     return item;
@@ -128,24 +128,24 @@
 
 sp<GraphicBuffer> GraphicBufferListener::getBuffer(BufferItem item) {
     sp<GraphicBuffer> buf;
-    if (item.mBuf < 0 || item.mBuf >= BufferQueue::NUM_BUFFER_SLOTS) {
-        ALOGE("getBuffer() received invalid BufferItem: mBuf==%d", item.mBuf);
+    if (item.mSlot < 0 || item.mSlot >= BufferQueue::NUM_BUFFER_SLOTS) {
+        ALOGE("getBuffer() received invalid BufferItem: mSlot==%d", item.mSlot);
         return buf;
     }
 
-    buf = mBufferSlot[item.mBuf];
+    buf = mBufferSlot[item.mSlot];
     CHECK(buf.get() != NULL);
 
     return buf;
 }
 
 status_t GraphicBufferListener::releaseBuffer(BufferItem item) {
-    if (item.mBuf < 0 || item.mBuf >= BufferQueue::NUM_BUFFER_SLOTS) {
-        ALOGE("getBuffer() received invalid BufferItem: mBuf==%d", item.mBuf);
+    if (item.mSlot < 0 || item.mSlot >= BufferQueue::NUM_BUFFER_SLOTS) {
+        ALOGE("getBuffer() received invalid BufferItem: mSlot==%d", item.mSlot);
         return ERROR_OUT_OF_RANGE;
     }
 
-    mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
+    mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
 
     return OK;
diff --git a/media/libstagefright/filters/MediaFilter.cpp b/media/libstagefright/filters/MediaFilter.cpp
index 0cf6b06..cd69418 100644
--- a/media/libstagefright/filters/MediaFilter.cpp
+++ b/media/libstagefright/filters/MediaFilter.cpp
@@ -773,7 +773,7 @@
     convertRGBAToARGB(
             (uint8_t*)bufPtr, buf->getWidth(), buf->getHeight(),
             buf->getStride(), inputInfo->mData->data());
-    inputInfo->mBufferID = item.mBuf;
+    inputInfo->mBufferID = item.mSlot;
     inputInfo->mGeneration = mGeneration;
     inputInfo->mOutputFlags = 0;
     inputInfo->mStatus = BufferInfo::OWNED_BY_US;
diff --git a/media/libstagefright/foundation/base64.cpp b/media/libstagefright/foundation/base64.cpp
index dcf5bef..7da7db9 100644
--- a/media/libstagefright/foundation/base64.cpp
+++ b/media/libstagefright/foundation/base64.cpp
@@ -22,11 +22,11 @@
 namespace android {
 
 sp<ABuffer> decodeBase64(const AString &s) {
-    if ((s.size() % 4) != 0) {
+    size_t n = s.size();
+    if ((n % 4) != 0) {
         return NULL;
     }
 
-    size_t n = s.size();
     size_t padding = 0;
     if (n >= 1 && s.c_str()[n - 1] == '=') {
         padding = 1;
@@ -40,11 +40,16 @@
         }
     }
 
-    size_t outLen = 3 * s.size() / 4 - padding;
+    // We divide first to avoid overflow. It's OK to do this because we
+    // already made sure that n % 4 == 0.
+    size_t outLen = (n / 4) * 3 - padding;
 
     sp<ABuffer> buffer = new ABuffer(outLen);
 
     uint8_t *out = buffer->data();
+    if (out == NULL || buffer->size() < outLen) {
+        return NULL;
+    }
     size_t j = 0;
     uint32_t accum = 0;
     for (size_t i = 0; i < n; ++i) {
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index 4252706..a29bdf9 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -28,7 +28,7 @@
 struct PageCache;
 
 struct NuCachedSource2 : public DataSource {
-    NuCachedSource2(
+    static sp<NuCachedSource2> Create(
             const sp<DataSource> &source,
             const char *cacheConfig = NULL,
             bool disconnectAtHighwatermark = false);
@@ -72,6 +72,11 @@
 private:
     friend struct AHandlerReflector<NuCachedSource2>;
 
+    NuCachedSource2(
+            const sp<DataSource> &source,
+            const char *cacheConfig,
+            bool disconnectAtHighwatermark);
+
     enum {
         kPageSize                       = 65536,
         kDefaultHighWaterThreshold      = 20 * 1024 * 1024,
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 1a7dc9d..acdc4b0 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -64,19 +64,19 @@
             return;
         }
 
-        err = consumer->detachBuffer(bi.mBuf);
+        err = consumer->detachBuffer(bi.mSlot);
         if (err != OK) {
             ALOGE("PersistentProxyListener: detachBuffer failed (%d)", err);
             return;
         }
 
-        err = consumer->attachBuffer(&bi.mBuf, bi.mGraphicBuffer);
+        err = consumer->attachBuffer(&bi.mSlot, bi.mGraphicBuffer);
         if (err != OK) {
             ALOGE("PersistentProxyListener: attachBuffer failed (%d)", err);
             return;
         }
 
-        err = consumer->releaseBuffer(bi.mBuf, 0,
+        err = consumer->releaseBuffer(bi.mSlot, 0,
                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, bi.mFence);
         if (err != OK) {
             ALOGE("PersistentProxyListener: releaseBuffer failed (%d)", err);
@@ -382,7 +382,7 @@
     // Find matching entry in our cached copy of the BufferQueue slots.
     // If we find a match, release that slot.  If we don't, the BufferQueue
     // has dropped that GraphicBuffer, and there's nothing for us to release.
-    int id = codecBuffer.mBuf;
+    int id = codecBuffer.mSlot;
     sp<Fence> fence = new Fence(fenceFd);
     if (mBufferSlot[id] != NULL &&
         mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) {
@@ -476,7 +476,7 @@
             ++mNumBufferAcquired;
             --mNumFramesAvailable;
 
-            releaseBuffer(item.mBuf, item.mFrameNumber,
+            releaseBuffer(item.mSlot, item.mFrameNumber,
                     item.mGraphicBuffer, item.mFence);
         }
         return;
@@ -530,8 +530,8 @@
     // If this is the first time we're seeing this buffer, add it to our
     // slot table.
     if (item.mGraphicBuffer != NULL) {
-        ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf);
-        mBufferSlot[item.mBuf] = item.mGraphicBuffer;
+        ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mSlot);
+        mBufferSlot[item.mSlot] = item.mGraphicBuffer;
     }
 
     err = UNKNOWN_ERROR;
@@ -557,10 +557,10 @@
     }
 
     if (err != OK) {
-        ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf);
-        releaseBuffer(item.mBuf, item.mFrameNumber, item.mGraphicBuffer, item.mFence);
+        ALOGV("submitBuffer_l failed, releasing bq slot %d", item.mSlot);
+        releaseBuffer(item.mSlot, item.mFrameNumber, item.mGraphicBuffer, item.mFence);
     } else {
-        ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi);
+        ALOGV("buffer submitted (bq %d, cbi %d)", item.mSlot, cbi);
         setLatestBuffer_l(item, dropped);
     }
 
@@ -600,7 +600,7 @@
     }
 
     BufferItem item;
-    item.mBuf = mLatestBufferId;
+    item.mSlot = mLatestBufferId;
     item.mFrameNumber = mLatestBufferFrameNum;
     item.mTimestamp = mRepeatLastFrameTimestamp;
     item.mFence = mLatestBufferFence;
@@ -642,7 +642,7 @@
         }
     }
 
-    mLatestBufferId = item.mBuf;
+    mLatestBufferId = item.mSlot;
     mLatestBufferFrameNum = item.mFrameNumber;
     mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
 
@@ -754,8 +754,8 @@
     }
 
     CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
-    codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf];
-    codecBuffer.mBuf = item.mBuf;
+    codecBuffer.mGraphicBuffer = mBufferSlot[item.mSlot];
+    codecBuffer.mSlot = item.mSlot;
     codecBuffer.mFrameNumber = item.mFrameNumber;
 
     OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
@@ -880,11 +880,11 @@
             // If this is the first time we're seeing this buffer, add it to our
             // slot table.
             if (item.mGraphicBuffer != NULL) {
-                ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mBuf);
-                mBufferSlot[item.mBuf] = item.mGraphicBuffer;
+                ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mSlot);
+                mBufferSlot[item.mSlot] = item.mGraphicBuffer;
             }
 
-            releaseBuffer(item.mBuf, item.mFrameNumber,
+            releaseBuffer(item.mSlot, item.mFrameNumber,
                     item.mGraphicBuffer, item.mFence);
         }
         return;
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 2f929d9..7150684 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -195,7 +195,7 @@
         uint64_t mFrameNumber;
 
         // buffer producer's buffer slot for buffer
-        int mBuf;
+        int mSlot;
 
         sp<GraphicBuffer> mGraphicBuffer;
     };
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 8694a04..eb0c5b2 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -292,14 +292,26 @@
 
 status_t OMX::sendCommand(
         node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
-    return findInstance(node)->sendCommand(cmd, param);
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->sendCommand(cmd, param);
 }
 
 status_t OMX::getParameter(
         node_id node, OMX_INDEXTYPE index,
         void *params, size_t size) {
     ALOGV("getParameter(%u %#x %p %zd)", node, index, params, size);
-    return findInstance(node)->getParameter(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->getParameter(
             index, params, size);
 }
 
@@ -307,84 +319,162 @@
         node_id node, OMX_INDEXTYPE index,
         const void *params, size_t size) {
     ALOGV("setParameter(%u %#x %p %zd)", node, index, params, size);
-    return findInstance(node)->setParameter(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->setParameter(
             index, params, size);
 }
 
 status_t OMX::getConfig(
         node_id node, OMX_INDEXTYPE index,
         void *params, size_t size) {
-    return findInstance(node)->getConfig(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->getConfig(
             index, params, size);
 }
 
 status_t OMX::setConfig(
         node_id node, OMX_INDEXTYPE index,
         const void *params, size_t size) {
-    return findInstance(node)->setConfig(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->setConfig(
             index, params, size);
 }
 
 status_t OMX::getState(
         node_id node, OMX_STATETYPE* state) {
-    return findInstance(node)->getState(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->getState(
             state);
 }
 
 status_t OMX::enableGraphicBuffers(
         node_id node, OMX_U32 port_index, OMX_BOOL enable) {
-    return findInstance(node)->enableGraphicBuffers(port_index, enable);
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->enableGraphicBuffers(port_index, enable);
 }
 
 status_t OMX::getGraphicBufferUsage(
         node_id node, OMX_U32 port_index, OMX_U32* usage) {
-    return findInstance(node)->getGraphicBufferUsage(port_index, usage);
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->getGraphicBufferUsage(port_index, usage);
 }
 
 status_t OMX::storeMetaDataInBuffers(
         node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
-    return findInstance(node)->storeMetaDataInBuffers(port_index, enable, type);
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->storeMetaDataInBuffers(port_index, enable, type);
 }
 
 status_t OMX::prepareForAdaptivePlayback(
         node_id node, OMX_U32 portIndex, OMX_BOOL enable,
         OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
-    return findInstance(node)->prepareForAdaptivePlayback(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->prepareForAdaptivePlayback(
             portIndex, enable, maxFrameWidth, maxFrameHeight);
 }
 
 status_t OMX::configureVideoTunnelMode(
         node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
         OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
-    return findInstance(node)->configureVideoTunnelMode(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->configureVideoTunnelMode(
             portIndex, tunneled, audioHwSync, sidebandHandle);
 }
 
 status_t OMX::useBuffer(
         node_id node, OMX_U32 port_index, const sp<IMemory> &params,
         buffer_id *buffer, OMX_U32 allottedSize) {
-    return findInstance(node)->useBuffer(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->useBuffer(
             port_index, params, buffer, allottedSize);
 }
 
 status_t OMX::useGraphicBuffer(
         node_id node, OMX_U32 port_index,
         const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
-    return findInstance(node)->useGraphicBuffer(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->useGraphicBuffer(
             port_index, graphicBuffer, buffer);
 }
 
 status_t OMX::updateGraphicBufferInMeta(
         node_id node, OMX_U32 port_index,
         const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
-    return findInstance(node)->updateGraphicBufferInMeta(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->updateGraphicBufferInMeta(
             port_index, graphicBuffer, buffer);
 }
 
 status_t OMX::createInputSurface(
         node_id node, OMX_U32 port_index,
         sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) {
-    return findInstance(node)->createInputSurface(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->createInputSurface(
             port_index, bufferProducer, type);
 }
 
@@ -398,35 +488,71 @@
 status_t OMX::setInputSurface(
         node_id node, OMX_U32 port_index,
         const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) {
-    return findInstance(node)->setInputSurface(port_index, bufferConsumer, type);
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->setInputSurface(port_index, bufferConsumer, type);
 }
 
 
 status_t OMX::signalEndOfInputStream(node_id node) {
-    return findInstance(node)->signalEndOfInputStream();
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->signalEndOfInputStream();
 }
 
 status_t OMX::allocateBuffer(
         node_id node, OMX_U32 port_index, size_t size,
         buffer_id *buffer, void **buffer_data) {
-    return findInstance(node)->allocateBuffer(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->allocateBuffer(
             port_index, size, buffer, buffer_data);
 }
 
 status_t OMX::allocateBufferWithBackup(
         node_id node, OMX_U32 port_index, const sp<IMemory> &params,
         buffer_id *buffer, OMX_U32 allottedSize) {
-    return findInstance(node)->allocateBufferWithBackup(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->allocateBufferWithBackup(
             port_index, params, buffer, allottedSize);
 }
 
 status_t OMX::freeBuffer(node_id node, OMX_U32 port_index, buffer_id buffer) {
-    return findInstance(node)->freeBuffer(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->freeBuffer(
             port_index, buffer);
 }
 
 status_t OMX::fillBuffer(node_id node, buffer_id buffer, int fenceFd) {
-    return findInstance(node)->fillBuffer(buffer, fenceFd);
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->fillBuffer(buffer, fenceFd);
 }
 
 status_t OMX::emptyBuffer(
@@ -434,7 +560,13 @@
         buffer_id buffer,
         OMX_U32 range_offset, OMX_U32 range_length,
         OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
-    return findInstance(node)->emptyBuffer(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->emptyBuffer(
             buffer, range_offset, range_length, flags, timestamp, fenceFd);
 }
 
@@ -442,7 +574,13 @@
         node_id node,
         const char *parameter_name,
         OMX_INDEXTYPE *index) {
-    return findInstance(node)->getExtensionIndex(
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->getExtensionIndex(
             parameter_name, index);
 }
 
@@ -452,7 +590,13 @@
         InternalOptionType type,
         const void *data,
         size_t size) {
-    return findInstance(node)->setInternalOption(port_index, type, data, size);
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return NAME_NOT_FOUND;
+    }
+
+    return instance->setInternalOption(port_index, type, data, size);
 }
 
 OMX_ERRORTYPE OMX::OnEvent(
@@ -462,9 +606,14 @@
         OMX_IN OMX_U32 nData2,
         OMX_IN OMX_PTR pEventData) {
     ALOGV("OnEvent(%d, %" PRIu32", %" PRIu32 ")", eEvent, nData1, nData2);
+    OMXNodeInstance *instance = findInstance(node);
+
+    if (instance == NULL) {
+        return OMX_ErrorComponentNotFound;
+    }
 
     // Forward to OMXNodeInstance.
-    findInstance(node)->onEvent(eEvent, nData1, nData2);
+    instance->onEvent(eEvent, nData1, nData2);
 
     sp<OMX::CallbackDispatcher> dispatcher = findDispatcher(node);
 
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index a354d58..5598d5d 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -46,6 +46,10 @@
     ALOGV("private ctor");
     AMediaFormat* mData = new AMediaFormat();
     mData->mFormat = *((sp<AMessage>*)data);
+    if (mData->mFormat == NULL) {
+        ALOGW("got NULL format");
+        mData->mFormat = new AMessage;
+    }
     return mData;
 }
 
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0f89c16..151f662 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3479,6 +3479,12 @@
         if (state->mCommand != FastMixerState::MIX_WRITE &&
                 (kUseFastMixer != FastMixer_Dynamic || state->mTrackMask > 1)) {
             if (state->mCommand == FastMixerState::COLD_IDLE) {
+
+                // FIXME workaround for first HAL write being CPU bound on some devices
+                ATRACE_BEGIN("write");
+                mOutput->write((char *)mSinkBuffer, 0);
+                ATRACE_END();
+
                 int32_t old = android_atomic_inc(&mFastMixerFutex);
                 if (old == -1) {
                     (void) syscall(__NR_futex, &mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index f7da209..b3fac0b 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -432,7 +432,10 @@
     }
     // only allocate a fast track index if we were able to allocate a normal track name
     if (flags & IAudioFlinger::TRACK_FAST) {
-        mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads();
+        // FIXME: Not calling framesReadyIsCalledByMultipleThreads() exposes a potential
+        // race with setSyncEvent(). However, if we call it, we cannot properly start
+        // static fast tracks (SoundPool) immediately after stopping.
+        //mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads();
         ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
         int i = __builtin_ctz(thread->mFastTrackAvailMask);
         ALOG_ASSERT(0 < i && i < (int)FastMixerState::kMaxFastTracks);
diff --git a/services/audiopolicy/enginedefault/src/Gains.cpp b/services/audiopolicy/enginedefault/src/Gains.cpp
index 78f2909..d06365c 100644
--- a/services/audiopolicy/enginedefault/src/Gains.cpp
+++ b/services/audiopolicy/enginedefault/src/Gains.cpp
@@ -171,10 +171,10 @@
     },
     { // AUDIO_STREAM_TTS
       // "Transmitted Through Speaker": always silent except on DEVICE_CATEGORY_SPEAKER
-        Gains::sSilentVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        Gains::sLinearVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        Gains::sSilentVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sSilentVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sSilentVolumeCurve,    // DEVICE_CATEGORY_HEADSET
+        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        Gains::sSilentVolumeCurve,    // DEVICE_CATEGORY_EARPIECE
+        Gains::sSilentVolumeCurve     // DEVICE_CATEGORY_EXT_MEDIA
     },
     { // AUDIO_STREAM_ACCESSIBILITY
         Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 7e33e0c..2aaefe9 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2265,7 +2265,7 @@
 
     String8 result("Dump of the Camera Service:\n");
     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
-        result.appendFormat("Permission Denial: "
+        result = result.format("Permission Denial: "
                 "can't dump CameraService from pid=%d, uid=%d\n",
                 getCallingPid(),
                 getCallingUid());
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index 442eb75..44447b4 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -214,8 +214,8 @@
                 supportedPreviewFormats);
     }
 
-    previewFpsRange[0] = availableFpsRanges.data.i32[0];
-    previewFpsRange[1] = availableFpsRanges.data.i32[1];
+    previewFpsRange[0] = fastInfo.bestStillCaptureFpsRange[0];
+    previewFpsRange[1] = fastInfo.bestStillCaptureFpsRange[1];
 
     // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
     // still have to do something sane for them
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
index 66d7b00..88a0f50 100644
--- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
@@ -788,7 +788,7 @@
                 return NO_MEMORY;
             }
             for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
-                if (mRecordingBuffers[i].mBuf !=
+                if (mRecordingBuffers[i].mSlot !=
                         BufferItemConsumer::INVALID_BUFFER_SLOT) {
                     ALOGE("%s: Camera %d: Non-empty recording buffers list!",
                             __FUNCTION__, mId);
@@ -878,7 +878,7 @@
     size_t itemIndex;
     for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
         const BufferItem item = mRecordingBuffers[itemIndex];
-        if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
+        if (item.mSlot != BufferItemConsumer::INVALID_BUFFER_SLOT &&
                 item.mGraphicBuffer->getNativeBuffer() == payload->pBuffer) {
                 break;
         }
@@ -923,7 +923,7 @@
     size_t releasedCount = 0;
     for (size_t itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
         const BufferItem item = mRecordingBuffers[itemIndex];
-        if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT) {
+        if (item.mSlot != BufferItemConsumer::INVALID_BUFFER_SLOT) {
             res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
             if (res != OK) {
                 ALOGE("%s: Camera %d: Unable to free recording frame "
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 691764f..96299b3 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -487,9 +487,12 @@
     status_t res = returnBufferLocked(buffer, timestamp);
     if (res == OK) {
         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true);
-        mOutputBufferReturnedSignal.signal();
     }
 
+    // Even if returning the buffer failed, we still want to signal whoever is waiting for the
+    // buffer to be returned.
+    mOutputBufferReturnedSignal.signal();
+
     return res;
 }
 
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
index 8cd6800..65816e0 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
@@ -229,7 +229,7 @@
 
         // item.mGraphicBuffer was populated with the proper graphic-buffer
         // at acquire even if it was previously acquired
-        err = addReleaseFenceLocked(item.mBuf,
+        err = addReleaseFenceLocked(item.mSlot,
                 item.mGraphicBuffer, item.mFence);
 
         if (err != OK) {
@@ -244,7 +244,7 @@
 
         // item.mGraphicBuffer was populated with the proper graphic-buffer
         // at acquire even if it was previously acquired
-        err = releaseBufferLocked(item.mBuf, item.mGraphicBuffer,
+        err = releaseBufferLocked(item.mSlot, item.mGraphicBuffer,
                                   EGL_NO_DISPLAY,
                                   EGL_NO_SYNC_KHR);
         if (err != OK) {
@@ -318,7 +318,7 @@
 
         mLatestTimestamp = item.mTimestamp;
 
-        item.mGraphicBuffer = mSlots[item.mBuf].mGraphicBuffer;
+        item.mGraphicBuffer = mSlots[item.mSlot].mGraphicBuffer;
     } // end of mMutex lock
 
     ConsumerBase::onFrameAvailable(item);
@@ -335,7 +335,7 @@
 
         RingBufferItem& find = *it;
         if (item.mGraphicBuffer == find.mGraphicBuffer) {
-            status_t res = addReleaseFenceLocked(item.mBuf,
+            status_t res = addReleaseFenceLocked(item.mSlot,
                     item.mGraphicBuffer, item.mFence);
 
             if (res != OK) {
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.h b/services/camera/libcameraservice/gui/RingBufferConsumer.h
index 83e7298..243ea31 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.h
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.h
@@ -133,7 +133,7 @@
         }
 
         bool isEmpty() {
-            return mBufferItem.mBuf == BufferQueue::INVALID_BUFFER_SLOT;
+            return mBufferItem.mSlot == BufferQueue::INVALID_BUFFER_SLOT;
         }
 
         BufferItem& getBufferItem() { return mBufferItem; }
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index e54cc5a..4790754 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -96,6 +96,15 @@
     const size_t SIZE = 256;
     char buffer[SIZE];
 
+    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+        result.format("Permission Denial: "
+                "can't dump ResourceManagerService from pid=%d, uid=%d\n",
+                IPCThreadState::self()->getCallingPid(),
+                IPCThreadState::self()->getCallingUid());
+        write(fd, result.string(), result.size());
+        return PERMISSION_DENIED;
+    }
+
     snprintf(buffer, SIZE, "ResourceManagerService: %p\n", this);
     result.append(buffer);
     result.append("  Policies:\n");