DO NOT MERGE codecs: handle onReset() for a few encoders am: dd447c354e am: afaa438503 am: daaabdcaac  -s ours am: da9246fa5e  -s ours am: 1760d73fbc am: 55d8132edd  -s ours am: 292dc7e025 am: 1dfa590543 am: dbeeaf29d0 am: 3b57c387ed  -s ours am: 437d60bffb am: 028e36fe32 am: 5b83000768
am: e45718e94a

Change-Id: I62f8274399590f8278599052c5589bb32dd9869f
diff --git a/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp
index 86bf047..8356bcc 100644
--- a/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp
@@ -75,6 +75,8 @@
     }
     status_t res = session->provideKeyResponse(response);
     if (res == android::OK) {
+        // This is for testing AMediaDrm_setOnEventListener only.
+        sendEvent(kDrmPluginEventVendorDefined, 0, &scope, NULL);
         keySetId.clear();
     }
     return res;
@@ -90,6 +92,8 @@
         value = "ClearKey CDM";
     } else if (name == "algorithms") {
         value = "";
+    } else if (name == "listenerTestSupport") {
+        value = "true";
     } else {
         ALOGE("App requested unknown string property %s", name.string());
         return android::ERROR_DRM_CANNOT_HANDLE;
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 8fc410d..2ec89a4 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -87,7 +87,6 @@
     int64_t mStartTimeUs;
     int16_t mMaxAmplitude;
     int64_t mPrevSampleTimeUs;
-    int64_t mFirstSampleTimeUs;
     int64_t mInitialReadTimeUs;
     int64_t mNumFramesReceived;
     int64_t mNumClientOwnedBuffers;
diff --git a/include/media/stagefright/SimpleDecodingSource.h b/include/media/stagefright/SimpleDecodingSource.h
index 534097b..e6aee6a 100644
--- a/include/media/stagefright/SimpleDecodingSource.h
+++ b/include/media/stagefright/SimpleDecodingSource.h
@@ -71,12 +71,13 @@
     // Construct this using a codec, source and looper.
     SimpleDecodingSource(
             const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper,
-            bool usingSurface, const sp<AMessage> &format);
+            bool usingSurface, bool isVorbis, const sp<AMessage> &format);
 
     sp<MediaCodec> mCodec;
     sp<IMediaSource> mSource;
     sp<ALooper> mLooper;
     bool mUsingSurface;
+    bool mIsVorbis;
     enum State {
         INIT,
         STARTED,
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index ff5903d..a80c891 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -1274,6 +1274,9 @@
             return true;
         }
     }
+    if (exitPending()) {
+        return false;
+    }
     nsecs_t ns =  mReceiver.processAudioBuffer();
     switch (ns) {
     case 0:
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 790c6da..efdee77 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -60,7 +60,6 @@
       mStartTimeUs(0),
       mMaxAmplitude(0),
       mPrevSampleTimeUs(0),
-      mFirstSampleTimeUs(-1ll),
       mInitialReadTimeUs(0),
       mNumFramesReceived(0),
       mNumClientOwnedBuffers(0) {
@@ -277,12 +276,8 @@
     }
 
     if (mSampleRate != mOutSampleRate) {
-        if (mFirstSampleTimeUs < 0) {
-            mFirstSampleTimeUs = timeUs;
-        }
-        timeUs = mFirstSampleTimeUs + (timeUs - mFirstSampleTimeUs)
-                * (int64_t)mSampleRate / (int64_t)mOutSampleRate;
-        buffer->meta_data()->setInt64(kKeyTime, timeUs);
+            timeUs *= (int64_t)mSampleRate / (int64_t)mOutSampleRate;
+            buffer->meta_data()->setInt64(kKeyTime, timeUs);
     }
 
     *out = buffer;
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 161ddfc..ee5fdf0 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -567,6 +567,10 @@
     }
 
     for (size_t i = 0; i < numSyncSamples; ++i) {
+        if (mSyncSamples[i] == 0) {
+            ALOGE("b/32423862, unexpected zero value in stss");
+            continue;
+        }
         mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1;
     }
 
diff --git a/media/libstagefright/SimpleDecodingSource.cpp b/media/libstagefright/SimpleDecodingSource.cpp
index de21c5e..2503a32 100644
--- a/media/libstagefright/SimpleDecodingSource.cpp
+++ b/media/libstagefright/SimpleDecodingSource.cpp
@@ -18,6 +18,7 @@
 
 #include <media/ICrypto.h>
 #include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/AUtils.h>
@@ -74,7 +75,10 @@
                 err = codec->getOutputFormat(&format);
             }
             if (err == OK) {
-                return new SimpleDecodingSource(codec, source, looper, surface != NULL, format);
+                return new SimpleDecodingSource(codec, source, looper,
+                        surface != NULL,
+                        strcmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS) == 0,
+                        format);
             }
 
             ALOGD("Failed to configure codec '%s'", componentName.c_str());
@@ -90,11 +94,12 @@
 
 SimpleDecodingSource::SimpleDecodingSource(
         const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper,
-        bool usingSurface, const sp<AMessage> &format)
+        bool usingSurface, bool isVorbis, const sp<AMessage> &format)
     : mCodec(codec),
       mSource(source),
       mLooper(looper),
       mUsingSurface(usingSurface),
+      mIsVorbis(isVorbis),
       mProtectedState(format) {
     mCodec->getName(&mComponentName);
 }
@@ -280,16 +285,25 @@
             if (in_buf != NULL) {
                 int64_t timestampUs = 0;
                 CHECK(in_buf->meta_data()->findInt64(kKeyTime, &timestampUs));
-                if (in_buf->range_length() > in_buffer->capacity()) {
+                if (in_buf->range_length() + (mIsVorbis ? 4 : 0) > in_buffer->capacity()) {
                     ALOGW("'%s' received %zu input bytes for buffer of size %zu",
                             mComponentName.c_str(),
-                            in_buf->range_length(), in_buffer->capacity());
+                            in_buf->range_length() + (mIsVorbis ? 4 : 0), in_buffer->capacity());
                 }
+                size_t cpLen = min(in_buf->range_length(), in_buffer->capacity());
                 memcpy(in_buffer->base(), (uint8_t *)in_buf->data() + in_buf->range_offset(),
-                       min(in_buf->range_length(), in_buffer->capacity()));
+                        cpLen );
+
+                if (mIsVorbis) {
+                    int32_t numPageSamples;
+                    if (!in_buf->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) {
+                        numPageSamples = -1;
+                    }
+                    memcpy(in_buffer->base() + cpLen, &numPageSamples, sizeof(numPageSamples));
+                }
 
                 res = mCodec->queueInputBuffer(
-                        in_ix, 0 /* offset */, in_buf->range_length(),
+                        in_ix, 0 /* offset */, in_buf->range_length() + (mIsVorbis ? 4 : 0),
                         timestampUs, 0 /* flags */);
                 if (res != OK) {
                     ALOGI("[%s] failed to queue input buffer #%zu", mComponentName.c_str(), in_ix);
diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp
index d1b2f54..1c170b8 100644
--- a/media/libstagefright/WVMExtractor.cpp
+++ b/media/libstagefright/WVMExtractor.cpp
@@ -42,13 +42,9 @@
 
 namespace android {
 
-static Mutex gWVMutex;
-
 WVMExtractor::WVMExtractor(const sp<DataSource> &source)
     : mDataSource(source)
 {
-    Mutex::Autolock autoLock(gWVMutex);
-
     if (!getVendorLibHandle()) {
         return;
     }
@@ -169,8 +165,6 @@
     const sp<DataSource> &source, String8 *mimeType, float *confidence,
         sp<AMessage> *) {
 
-    Mutex::Autolock autoLock(gWVMutex);
-
     if (!WVMExtractor::getVendorLibHandle()) {
         return false;
     }
diff --git a/media/libstagefright/foundation/MediaBufferGroup.cpp b/media/libstagefright/foundation/MediaBufferGroup.cpp
index 54f768a..8e4d064 100644
--- a/media/libstagefright/foundation/MediaBufferGroup.cpp
+++ b/media/libstagefright/foundation/MediaBufferGroup.cpp
@@ -39,6 +39,12 @@
 MediaBufferGroup::MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit)
     : mGrowthLimit(growthLimit) {
 
+    if (mGrowthLimit > 0 && buffers > mGrowthLimit) {
+        ALOGW("Preallocated buffers %zu > growthLimit %zu, increasing growthLimit",
+                buffers, mGrowthLimit);
+        mGrowthLimit = buffers;
+    }
+
     if (buffer_size >= kSharedMemoryThreshold) {
         ALOGD("creating MemoryDealer");
         // Using a single MemoryDealer is efficient for a group of shared memory objects.
@@ -102,9 +108,22 @@
 void MediaBufferGroup::add_buffer(MediaBuffer *buffer) {
     Mutex::Autolock autoLock(mLock);
 
+    // if we're above our growth limit, release buffers if we can
+    for (auto it = mBuffers.begin();
+            mGrowthLimit > 0
+            && mBuffers.size() >= mGrowthLimit
+            && it != mBuffers.end();) {
+        if ((*it)->refcount() == 0) {
+            (*it)->setObserver(nullptr);
+            (*it)->release();
+            it = mBuffers.erase(it);
+        } else {
+            ++it;
+        }
+    }
+
     buffer->setObserver(this);
     mBuffers.emplace_back(buffer);
-    // optionally: mGrowthLimit = max(mGrowthLimit, mBuffers.size());
 }
 
 bool MediaBufferGroup::has_buffers() {
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 93d6584..0c4056d 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -792,7 +792,8 @@
         if (mPrevCaptureUs < 0ll) {
             // first capture
             mPrevCaptureUs = timeUs;
-            mPrevFrameUs = timeUs;
+            // adjust the first sample timestamp.
+            mPrevFrameUs = (timeUs * mTimePerFrameUs) / mTimePerCaptureUs;
         } else {
             // snap to nearest capture point
             int64_t nFrames = (timeUs + mTimePerCaptureUs / 2 - mPrevCaptureUs)
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index 0381edf..0e9bc34 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -16,17 +16,38 @@
 
 #define LOG_TAG "MtpDataPacket"
 
+#include "MtpDataPacket.h"
+
+#include <algorithm>
+#include <fcntl.h>
 #include <stdio.h>
 #include <sys/types.h>
-#include <fcntl.h>
-
 #include <usbhost/usbhost.h>
-
-#include "MtpDataPacket.h"
 #include "MtpStringBuffer.h"
 
 namespace android {
 
+namespace {
+// Reads the exact |count| bytes from |fd| to |buf|.
+// Returns |count| if it succeed to read the bytes. Otherwise returns -1. If it reaches EOF, the
+// function regards it as an error.
+ssize_t readExactBytes(int fd, void* buf, size_t count) {
+    if (count > SSIZE_MAX) {
+        return -1;
+    }
+    size_t read_count = 0;
+    while (read_count < count) {
+        int result = read(fd, static_cast<int8_t*>(buf) + read_count, count - read_count);
+        // Assume that EOF is error.
+        if (result <= 0) {
+            return -1;
+        }
+        read_count += result;
+    }
+    return read_count == count ? count : -1;
+}
+}  // namespace
+
 MtpDataPacket::MtpDataPacket()
     :   MtpPacket(MTP_BUFFER_SIZE),   // MAX_USBFS_BUFFER_SIZE
         mOffset(MTP_CONTAINER_HEADER_SIZE)
@@ -511,29 +532,104 @@
     return length;
 }
 
-int MtpDataPacket::writeDataHeader(struct usb_request *request, uint32_t length) {
-    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
-    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
-    request->buffer = mBuffer;
-    request->buffer_length = MTP_CONTAINER_HEADER_SIZE;
-    int ret = transfer(request);
-    return (ret < 0 ? ret : 0);
-}
+int MtpDataPacket::write(struct usb_request *request, UrbPacketDivisionMode divisionMode) {
+    if (mPacketSize < MTP_CONTAINER_HEADER_SIZE || mPacketSize > MTP_BUFFER_SIZE) {
+        ALOGE("Illegal packet size.");
+        return -1;
+    }
 
-int MtpDataPacket::write(struct usb_request *request) {
     MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
     MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
-    request->buffer = mBuffer;
-    request->buffer_length = mPacketSize;
-    int ret = transfer(request);
-    return (ret < 0 ? ret : 0);
+
+    size_t processedBytes = 0;
+    while (processedBytes < mPacketSize) {
+        const size_t write_size =
+                processedBytes == 0 && divisionMode == FIRST_PACKET_ONLY_HEADER ?
+                        MTP_CONTAINER_HEADER_SIZE : mPacketSize - processedBytes;
+        request->buffer = mBuffer + processedBytes;
+        request->buffer_length = write_size;
+        const int result = transfer(request);
+        if (result < 0) {
+            ALOGE("Failed to write bytes to the device.");
+            return -1;
+        }
+        processedBytes += result;
+    }
+
+    return processedBytes == mPacketSize ? processedBytes : -1;
 }
 
-int MtpDataPacket::write(struct usb_request *request, void* buffer, uint32_t length) {
-    request->buffer = buffer;
-    request->buffer_length = length;
-    int ret = transfer(request);
-    return (ret < 0 ? ret : 0);
+int MtpDataPacket::write(struct usb_request *request,
+                         UrbPacketDivisionMode divisionMode,
+                         int fd,
+                         size_t payloadSize) {
+    // Obtain the greatest multiple of minimum packet size that is not greater than
+    // MTP_BUFFER_SIZE.
+    if (request->max_packet_size <= 0) {
+        ALOGE("Cannot determine bulk transfer size due to illegal max packet size %d.",
+              request->max_packet_size);
+        return -1;
+    }
+    const size_t maxBulkTransferSize =
+            MTP_BUFFER_SIZE - (MTP_BUFFER_SIZE % request->max_packet_size);
+    const size_t containerLength = payloadSize + MTP_CONTAINER_HEADER_SIZE;
+    size_t processedBytes = 0;
+    bool readError = false;
+
+    // Bind the packet with given request.
+    request->buffer = mBuffer;
+    allocate(maxBulkTransferSize);
+
+    while (processedBytes < containerLength) {
+        size_t bulkTransferSize = 0;
+
+        // prepare header.
+        const bool headerSent = processedBytes != 0;
+        if (!headerSent) {
+            MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, containerLength);
+            MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
+            bulkTransferSize += MTP_CONTAINER_HEADER_SIZE;
+        }
+
+        // Prepare payload.
+        if (headerSent || divisionMode == FIRST_PACKET_HAS_PAYLOAD) {
+            const size_t processedPayloadBytes =
+                    headerSent ? processedBytes - MTP_CONTAINER_HEADER_SIZE : 0;
+            const size_t maxRead = payloadSize - processedPayloadBytes;
+            const size_t maxWrite = maxBulkTransferSize - bulkTransferSize;
+            const size_t bulkTransferPayloadSize = std::min(maxRead, maxWrite);
+            // prepare payload.
+            if (!readError) {
+                const ssize_t result = readExactBytes(
+                        fd,
+                        mBuffer + bulkTransferSize,
+                        bulkTransferPayloadSize);
+                if (result < 0) {
+                    ALOGE("Found an error while reading data from FD. Send 0 data instead.");
+                    readError = true;
+                }
+            }
+            if (readError) {
+                memset(mBuffer + bulkTransferSize, 0, bulkTransferPayloadSize);
+            }
+            bulkTransferSize += bulkTransferPayloadSize;
+        }
+
+        // Bulk transfer.
+        mPacketSize = bulkTransferSize;
+        request->buffer_length = bulkTransferSize;
+        const int result = transfer(request);
+        if (result != static_cast<ssize_t>(bulkTransferSize)) {
+            // Cannot recover writing error.
+            ALOGE("Found an error while write data to MtpDevice.");
+            return -1;
+        }
+
+        // Update variables.
+        processedBytes += bulkTransferSize;
+    }
+
+    return readError ? -1 : processedBytes;
 }
 
 #endif // MTP_HOST
diff --git a/media/mtp/MtpDataPacket.h b/media/mtp/MtpDataPacket.h
index 6240f28..82e0ee4 100644
--- a/media/mtp/MtpDataPacket.h
+++ b/media/mtp/MtpDataPacket.h
@@ -93,7 +93,6 @@
     inline void         putEmptyString() { putUInt8(0); }
     inline void         putEmptyArray() { putUInt32(0); }
 
-
 #ifdef MTP_DEVICE
     // fill our buffer with data from the given file descriptor
     int                 read(int fd);
@@ -110,9 +109,15 @@
     int                 readDataWait(struct usb_device *device);
     int                 readDataHeader(struct usb_request *ep);
 
-    int                 writeDataHeader(struct usb_request *ep, uint32_t length);
-    int                 write(struct usb_request *ep);
-    int                 write(struct usb_request *ep, void* buffer, uint32_t length);
+    // Write a whole data packet with payload to the end point given by a request. |divisionMode|
+    // specifies whether to divide header and payload. See |UrbPacketDivisionMode| for meanings of
+    // each value. Return the number of bytes (including header size) sent to the device on success.
+    // Otherwise -1.
+    int                 write(struct usb_request *request, UrbPacketDivisionMode divisionMode);
+    // Similar to previous write method but it reads the payload from |fd|. If |size| is larger than
+    // MTP_BUFFER_SIZE, the data will be sent by multiple bulk transfer requests.
+    int                 write(struct usb_request *request, UrbPacketDivisionMode divisionMode,
+                              int fd, size_t size);
 #endif
 
     inline bool         hasData() const { return mPacketSize > MTP_CONTAINER_HEADER_SIZE; }
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index bd89a51..e3d2ec6 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -220,7 +220,10 @@
         mTransactionID(0),
         mReceivedResponse(false),
         mProcessingEvent(false),
-        mCurrentEventHandle(0)
+        mCurrentEventHandle(0),
+        mLastSendObjectInfoTransactionID(0),
+        mLastSendObjectInfoObjectHandle(0),
+        mPacketDivisionMode(FIRST_PACKET_HAS_PAYLOAD)
 {
     mRequestIn1 = usb_request_new(device, ep_in);
     mRequestIn2 = usb_request_new(device, ep_in);
@@ -490,6 +493,8 @@
    if (sendRequest(MTP_OPERATION_SEND_OBJECT_INFO) && sendData()) {
         MtpResponseCode ret = readResponse();
         if (ret == MTP_RESPONSE_OK) {
+            mLastSendObjectInfoTransactionID = mRequest.getTransactionID();
+            mLastSendObjectInfoObjectHandle = mResponse.getParameter(3);
             info->mStorageID = mResponse.getParameter(1);
             info->mParent = mResponse.getParameter(2);
             info->mHandle = mResponse.getParameter(3);
@@ -502,31 +507,21 @@
 bool MtpDevice::sendObject(MtpObjectHandle handle, int size, int srcFD) {
     Mutex::Autolock autoLock(mMutex);
 
-    int remaining = size;
-    mRequest.reset();
-    mRequest.setParameter(1, handle);
-    bool error = false;
-    if (sendRequest(MTP_OPERATION_SEND_OBJECT)) {
-        // send data header
-        writeDataHeader(MTP_OPERATION_SEND_OBJECT, remaining);
-
-        // USB writes greater than 16K don't work
-        char buffer[MTP_BUFFER_SIZE];
-        while (remaining > 0) {
-            int count = read(srcFD, buffer, sizeof(buffer));
-            if (count > 0) {
-                if (mData.write(mRequestOut, buffer, count) < 0) {
-                    error = true;
-                }
-                // FIXME check error
-                remaining -= count;
-            } else {
-                break;
-            }
-        }
+    if (mLastSendObjectInfoTransactionID + 1 != mTransactionID ||
+            mLastSendObjectInfoObjectHandle != handle) {
+        ALOGE("A sendObject request must follow the sendObjectInfo request.");
+        return false;
     }
-    MtpResponseCode ret = readResponse();
-    return (remaining == 0 && ret == MTP_RESPONSE_OK && !error);
+
+    mRequest.reset();
+    if (sendRequest(MTP_OPERATION_SEND_OBJECT)) {
+        mData.setOperationCode(mRequest.getOperationCode());
+        mData.setTransactionID(mRequest.getTransactionID());
+        const int writeResult = mData.write(mRequestOut, mPacketDivisionMode, srcFD, size);
+        const MtpResponseCode ret = readResponse();
+        return ret == MTP_RESPONSE_OK && writeResult > 0;
+    }
+    return false;
 }
 
 bool MtpDevice::deleteObject(MtpObjectHandle handle) {
@@ -698,8 +693,8 @@
         return false;
     }
 
-    // If object size 0 byte, the remote device can reply response packet
-    // without sending any data packets.
+    // If object size 0 byte, the remote device may reply a response packet without sending any data
+    // packets.
     if (mData.getContainerType() == MTP_CONTAINER_TYPE_RESPONSE) {
         mResponse.copyFrom(mData);
         return mResponse.getResponseCode() == MTP_RESPONSE_OK;
@@ -722,6 +717,14 @@
     {
         int initialDataLength = 0;
         void* const initialData = mData.getData(&initialDataLength);
+        if (fullLength > MTP_CONTAINER_HEADER_SIZE && initialDataLength == 0) {
+            // According to the MTP spec, the responder (MTP device) can choose two ways of sending
+            // data. a) The first packet contains the head and as much of the payload as possible
+            // b) The first packet contains only the header. The initiator (MTP host) needs
+            // to remember which way the responder used, and send upcoming data in the same way.
+            ALOGD("Found short packet that contains only a header.");
+            mPacketDivisionMode = FIRST_PACKET_ONLY_HEADER;
+        }
         if (initialData) {
             if (initialDataLength > 0) {
                 if (!callback(initialData, offset, initialDataLength, clientData)) {
@@ -845,7 +848,7 @@
     ALOGV("sendData\n");
     mData.setOperationCode(mRequest.getOperationCode());
     mData.setTransactionID(mRequest.getTransactionID());
-    int ret = mData.write(mRequestOut);
+    int ret = mData.write(mRequestOut, mPacketDivisionMode);
     mData.dump();
     return (ret >= 0);
 }
@@ -872,12 +875,6 @@
     }
 }
 
-bool MtpDevice::writeDataHeader(MtpOperationCode operation, int dataLength) {
-    mData.setOperationCode(operation);
-    mData.setTransactionID(mRequest.getTransactionID());
-    return (!mData.writeDataHeader(mRequestOut, dataLength));
-}
-
 MtpResponseCode MtpDevice::readResponse() {
     ALOGV("readResponse\n");
     if (mReceivedResponse) {
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index 4be44cf..c84c842 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -62,11 +62,18 @@
     bool                    mProcessingEvent;
     int                     mCurrentEventHandle;
 
+    // to check if a sendObject request follows the last sendObjectInfo request.
+    MtpTransactionID        mLastSendObjectInfoTransactionID;
+    MtpObjectHandle         mLastSendObjectInfoObjectHandle;
+
     // to ensure only one MTP transaction at a time
     Mutex                   mMutex;
     Mutex                   mEventMutex;
     Mutex                   mEventMutexForInterrupt;
 
+    // Remember the device's packet division mode.
+    UrbPacketDivisionMode   mPacketDivisionMode;
+
 public:
     typedef bool (*ReadObjectCallback)
             (void* data, uint32_t offset, uint32_t length, void* clientData);
diff --git a/media/mtp/MtpTypes.h b/media/mtp/MtpTypes.h
index 720c854..c749c66 100644
--- a/media/mtp/MtpTypes.h
+++ b/media/mtp/MtpTypes.h
@@ -73,6 +73,13 @@
 
 typedef String8    MtpString;
 
+enum UrbPacketDivisionMode {
+    // First packet only contains a header.
+    FIRST_PACKET_ONLY_HEADER,
+    // First packet contains payload much as possible.
+    FIRST_PACKET_HAS_PAYLOAD
+};
+
 }; // namespace android
 
 #endif // _MTP_TYPES_H
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index be71f43..166e6f1 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -221,8 +221,7 @@
 
 
 static bool findId(AMediaDrm *mObj, const AMediaDrmByteArray &id, List<idvec_t>::iterator &iter) {
-    iter = mObj->mIds.begin();
-    while (iter != mObj->mIds.end()) {
+    for (iter = mObj->mIds.begin(); iter != mObj->mIds.end(); ++iter) {
         if (iter->array() == id.ptr && iter->size() == id.length) {
             return true;
         }
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index d0df6d1..6124fed 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -467,8 +467,8 @@
         // CameraInfo is for android.hardware.Camera which does not
         // support external camera facing. The closest approximation would be
         // front camera.
-        if (cameraInfo->orientation == CAMERA_FACING_EXTERNAL) {
-            cameraInfo->orientation = CAMERA_FACING_FRONT;
+        if (cameraInfo->facing == CAMERA_FACING_EXTERNAL) {
+            cameraInfo->facing = CAMERA_FACING_FRONT;
         }
     }
     return rc;
@@ -2532,7 +2532,8 @@
                 write(fd, result.string(), result.size());
             } else {
                 result.appendFormat("  Facing: %s\n",
-                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
+                        info.facing == CAMERA_FACING_BACK ? "BACK" :
+                                info.facing == CAMERA_FACING_FRONT ? "FRONT" : "EXTERNAL");
                 result.appendFormat("  Orientation: %d\n", info.orientation);
                 int deviceVersion;
                 if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0) {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 48a2a99..eece01b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2222,6 +2222,14 @@
     }
 }
 
+void Camera3Device::removeInFlightMapEntryLocked(int idx) {
+    mInFlightMap.removeItemsAt(idx, 1);
+
+    // Indicate idle inFlightMap to the status tracker
+    if (mInFlightMap.size() == 0) {
+        mStatusTracker->markComponentIdle(mInFlightStatusId, Fence::NO_FENCE);
+    }
+}
 
 void Camera3Device::removeInFlightRequestIfReadyLocked(int idx) {
 
@@ -2257,13 +2265,7 @@
         returnOutputBuffers(request.pendingOutputBuffers.array(),
             request.pendingOutputBuffers.size(), 0);
 
-        mInFlightMap.removeItemsAt(idx, 1);
-
-        // Indicate idle inFlightMap to the status tracker
-        if (mInFlightMap.size() == 0) {
-            mStatusTracker->markComponentIdle(mInFlightStatusId, Fence::NO_FENCE);
-        }
-
+        removeInFlightMapEntryLocked(idx);
         ALOGVV("%s: removed frame %d from InFlightMap", __FUNCTION__, frameNumber);
      }
 
@@ -3438,6 +3440,20 @@
                         captureRequest->mResultExtras);
             }
         }
+
+        // Remove yet-to-be submitted inflight request from inflightMap
+        {
+          sp<Camera3Device> parent = mParent.promote();
+          if (parent != NULL) {
+              Mutex::Autolock l(parent->mInFlightLock);
+              ssize_t idx = parent->mInFlightMap.indexOfKey(captureRequest->mResultExtras.frameNumber);
+              if (idx >= 0) {
+                  ALOGV("%s: Remove inflight request from queue: frameNumber %" PRId64,
+                        __FUNCTION__, captureRequest->mResultExtras.frameNumber);
+                  parent->removeInFlightMapEntryLocked(idx);
+              }
+          }
+        }
     }
 
     Mutex::Autolock l(mRequestLock);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 17893a9..f422813 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -849,6 +849,9 @@
 
     /**** Scope for mInFlightLock ****/
 
+    // Remove the in-flight map entry of the given index from mInFlightMap.
+    // It must only be called with mInFlightLock held.
+    void removeInFlightMapEntryLocked(int idx);
     // Remove the in-flight request of the given index from mInFlightMap
     // if it's no longer needed. It must only be called with mInFlightLock held.
     void removeInFlightRequestIfReadyLocked(int idx);