Merge "stagefright: null-terminate vendor OMX string extensions" into pi-dev
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index fc60fd4..1826cc1 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -37,7 +37,9 @@
 #include <media/stagefright/MetaDataUtils.h>
 #include <utils/String8.h>
 
+#include <arpa/inet.h>
 #include <inttypes.h>
+#include <vector>
 
 namespace android {
 
@@ -584,31 +586,15 @@
     }
 
     const uint8_t *data = (const uint8_t *)mbuf->data() + mbuf->range_offset();
-    bool blockEncrypted = data[0] & 0x1;
-    if (blockEncrypted && mbuf->range_length() < 9) {
+    bool encrypted = data[0] & 0x1;
+    bool partitioned = data[0] & 0x2;
+    if (encrypted && mbuf->range_length() < 9) {
         // 1-byte signal + 8-byte IV
         return ERROR_MALFORMED;
     }
 
     MetaDataBase &meta = mbuf->meta_data();
-    if (blockEncrypted) {
-        /*
-         *  0                   1                   2                   3
-         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-         *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         *  |  Signal Byte  |                                               |
-         *  +-+-+-+-+-+-+-+-+             IV                                |
-         *  |                                                               |
-         *  |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         *  |               |                                               |
-         *  |-+-+-+-+-+-+-+-+                                               |
-         *  :               Bytes 1..N of encrypted frame                   :
-         *  |                                                               |
-         *  |                                                               |
-         *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         */
-        int32_t plainSizes[] = { 0 };
-        int32_t encryptedSizes[] = { static_cast<int32_t>(mbuf->range_length() - 9) };
+    if (encrypted) {
         uint8_t ctrCounter[16] = { 0 };
         uint32_t type;
         const uint8_t *keyId;
@@ -618,9 +604,83 @@
         meta.setData(kKeyCryptoKey, 0, keyId, keyIdSize);
         memcpy(ctrCounter, data + 1, 8);
         meta.setData(kKeyCryptoIV, 0, ctrCounter, 16);
-        meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes));
-        meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes));
-        mbuf->set_range(9, mbuf->range_length() - 9);
+        if (partitioned) {
+            /*  0                   1                   2                   3
+             *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+             * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+             * |  Signal Byte  |                                               |
+             * +-+-+-+-+-+-+-+-+             IV                                |
+             * |                                                               |
+             * |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+             * |               | num_partition |     Partition 0 offset ->     |
+             * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+             * |     -> Partition 0 offset     |              ...              |
+             * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+             * |             ...               |     Partition n-1 offset ->   |
+             * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+             * |     -> Partition n-1 offset   |                               |
+             * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
+             * |                    Clear/encrypted sample data                |
+             * |                                                               |
+             * |                                                               |
+             * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+             */
+            if (mbuf->range_length() < 10) {
+                return ERROR_MALFORMED;
+            }
+            uint8_t numPartitions = data[9];
+            if (mbuf->range_length() - 10 < numPartitions * sizeof(uint32_t)) {
+                return ERROR_MALFORMED;
+            }
+            std::vector<uint32_t> plainSizes, encryptedSizes;
+            uint32_t prev = 0;
+            uint32_t frameOffset = 10 + numPartitions * sizeof(uint32_t);
+            const uint32_t *partitions = reinterpret_cast<const uint32_t*>(data + 10);
+            for (uint32_t i = 0; i <= numPartitions; ++i) {
+                uint32_t p_i = i < numPartitions
+                        ? ntohl(partitions[i])
+                        : (mbuf->range_length() - frameOffset);
+                if (p_i < prev) {
+                    return ERROR_MALFORMED;
+                }
+                uint32_t size = p_i - prev;
+                prev = p_i;
+                if (i % 2) {
+                    encryptedSizes.push_back(size);
+                } else {
+                    plainSizes.push_back(size);
+                }
+            }
+            if (plainSizes.size() > encryptedSizes.size()) {
+                encryptedSizes.push_back(0);
+            }
+            uint32_t sizeofPlainSizes = sizeof(uint32_t) * plainSizes.size();
+            uint32_t sizeofEncryptedSizes = sizeof(uint32_t) * encryptedSizes.size();
+            meta.setData(kKeyPlainSizes, 0, plainSizes.data(), sizeofPlainSizes);
+            meta.setData(kKeyEncryptedSizes, 0, encryptedSizes.data(), sizeofEncryptedSizes);
+            mbuf->set_range(frameOffset, mbuf->range_length() - frameOffset);
+        } else {
+            /*
+             *  0                   1                   2                   3
+             *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+             *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+             *  |  Signal Byte  |                                               |
+             *  +-+-+-+-+-+-+-+-+             IV                                |
+             *  |                                                               |
+             *  |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+             *  |               |                                               |
+             *  |-+-+-+-+-+-+-+-+                                               |
+             *  :               Bytes 1..N of encrypted frame                   :
+             *  |                                                               |
+             *  |                                                               |
+             *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+             */
+            int32_t plainSizes[] = { 0 };
+            int32_t encryptedSizes[] = { static_cast<int32_t>(mbuf->range_length() - 9) };
+            meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes));
+            meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes));
+            mbuf->set_range(9, mbuf->range_length() - 9);
+        }
     } else {
         /*
          *  0                   1                   2                   3
diff --git a/media/libaaudio/src/fifo/FifoBuffer.cpp b/media/libaaudio/src/fifo/FifoBuffer.cpp
index 9b9744e..b09258e 100644
--- a/media/libaaudio/src/fifo/FifoBuffer.cpp
+++ b/media/libaaudio/src/fifo/FifoBuffer.cpp
@@ -22,6 +22,8 @@
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
+#include <algorithm>
+
 #include "FifoControllerBase.h"
 #include "FifoController.h"
 #include "FifoControllerIndirect.h"
@@ -85,15 +87,14 @@
     wrappingBuffer->data[1] = nullptr;
     wrappingBuffer->numFrames[1] = 0;
     if (framesAvailable > 0) {
-
         uint8_t *source = &mStorage[convertFramesToBytes(startIndex)];
         // Does the available data cross the end of the FIFO?
         if ((startIndex + framesAvailable) > mFrameCapacity) {
             wrappingBuffer->data[0] = source;
-            wrappingBuffer->numFrames[0] = mFrameCapacity - startIndex;
+            fifo_frames_t firstFrames = mFrameCapacity - startIndex;
+            wrappingBuffer->numFrames[0] = firstFrames;
             wrappingBuffer->data[1] = &mStorage[0];
-            wrappingBuffer->numFrames[1] = mFrameCapacity - startIndex;
-
+            wrappingBuffer->numFrames[1] = framesAvailable - firstFrames;
         } else {
             wrappingBuffer->data[0] = source;
             wrappingBuffer->numFrames[0] = framesAvailable;
@@ -102,18 +103,19 @@
         wrappingBuffer->data[0] = nullptr;
         wrappingBuffer->numFrames[0] = 0;
     }
-
 }
 
 fifo_frames_t FifoBuffer::getFullDataAvailable(WrappingBuffer *wrappingBuffer) {
-    fifo_frames_t framesAvailable = mFifo->getFullFramesAvailable();
+    // The FIFO might be overfull so clip to capacity.
+    fifo_frames_t framesAvailable = std::min(mFifo->getFullFramesAvailable(), mFrameCapacity);
     fifo_frames_t startIndex = mFifo->getReadIndex();
     fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
     return framesAvailable;
 }
 
 fifo_frames_t FifoBuffer::getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer) {
-    fifo_frames_t framesAvailable = mFifo->getEmptyFramesAvailable();
+    // The FIFO might have underrun so clip to capacity.
+    fifo_frames_t framesAvailable = std::min(mFifo->getEmptyFramesAvailable(), mFrameCapacity);
     fifo_frames_t startIndex = mFifo->getWriteIndex();
     fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
     return framesAvailable;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c87b5eb..83e56b6 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1055,8 +1055,16 @@
             return BAD_VALUE;
         }
 
+        std::string cameraName;
+        err = mCameraProviderManager->getCameraDeviceName(
+                std::string(cameraId.c_str()), cameraName);
+        if (err != OK) {
+            ALOGE("%s: Failed to find camera device name for id %s: %d",
+                  __FUNCTION__, cameraId.c_str(), err);
+            return err;
+        }
         // Make descriptor for incoming client
-        clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
+        clientDescriptor = CameraClientManager::makeClientDescriptor(String8(cameraName.c_str()),
                 sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
                 state->getConflicting(),
                 priorityScores[priorityScores.size() - 1],
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 077e05e..9b1b131 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -391,6 +391,16 @@
     return ret;
 }
 
+status_t CameraProviderManager::getCameraDeviceName(const std::string& id, std::string& name) {
+    std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+    auto deviceInfo = findDeviceInfoLocked(id);
+    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
+
+    name = deviceInfo->mName;
+    return OK;
+}
+
 status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
     for (const auto& providerInfo : mProviders) {
         if (providerInfo->mProviderName == newProvider) {
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index bbe6789..43b69d5 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -230,6 +230,11 @@
             hardware::hidl_version minVersion = hardware::hidl_version{0,0},
             hardware::hidl_version maxVersion = hardware::hidl_version{1000,0}) const;
 
+    /*
+     * Get device name for a particular camera Id
+     */
+    status_t getCameraDeviceName(const std::string& id, std::string& name);
+
 private:
     // All private members, unless otherwise noted, expect mInterfaceMutex to be locked before use
     mutable std::mutex mInterfaceMutex;