Merge "mtp: avoid silent allocation overflow in MtpProperty"
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 4e2272d..2f485b9 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -74,6 +74,5 @@
 LOCAL_CFLAGS += -Wall -Wextra
 
 LOCAL_MODULE:= libcameraservice
-LOCAL_32_BIT_ONLY := true
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index b83c315..aa2071b 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -206,7 +206,7 @@
              */
         }
 
-        ALOGV("%s: After unplug, disconnected %d clients",
+        ALOGV("%s: After unplug, disconnected %zu clients",
               __FUNCTION__, clientsToDisconnect.size());
     }
 
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index 8a4ce4e..f5c28ed 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -18,6 +18,8 @@
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
+#include <inttypes.h>
+
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <utils/Vector.h>
@@ -585,8 +587,8 @@
             ALOGE("No timestamp field in capture frame!");
         }
         if (entry.data.i64[0] != mCaptureTimestamp) {
-            ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
-                    " captured buffer %lld",
+            ALOGW("Mismatched capture timestamps: Metadata frame %" PRId64 ","
+                    " captured buffer %" PRId64,
                     entry.data.i64[0],
                     mCaptureTimestamp);
         }
diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
index 19acae4..dd5b27c 100644
--- a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
@@ -168,7 +168,7 @@
                 continue;
             }
             if (faceScores[i] > 100) {
-                ALOGW("%s: Face index %d with out of range score %d",
+                ALOGW("%s: Face index %zu with out of range score %d",
                         __FUNCTION__, i, faceScores[i]);
             }
 
diff --git a/services/camera/libcameraservice/api1/client2/JpegCompressor.cpp b/services/camera/libcameraservice/api1/client2/JpegCompressor.cpp
index 2f0c67d..9ecab71 100644
--- a/services/camera/libcameraservice/api1/client2/JpegCompressor.cpp
+++ b/services/camera/libcameraservice/api1/client2/JpegCompressor.cpp
@@ -197,7 +197,7 @@
 void JpegCompressor::jpegInitDestination(j_compress_ptr cinfo) {
     ALOGV("%s", __FUNCTION__);
     JpegDestination *dest= static_cast<JpegDestination*>(cinfo->dest);
-    ALOGV("%s: Setting destination to %p, size %d",
+    ALOGV("%s: Setting destination to %p, size %zu",
             __FUNCTION__, dest->parent->mJpegBuffer->data, kMaxJpegSize);
     dest->next_output_byte = (JOCTET*)(dest->parent->mJpegBuffer->data);
     dest->free_in_buffer = kMaxJpegSize;
@@ -213,7 +213,7 @@
 void JpegCompressor::jpegTermDestination(j_compress_ptr cinfo) {
     (void) cinfo; // TODO: clean up
     ALOGV("%s", __FUNCTION__);
-    ALOGV("%s: Done writing JPEG data. %d bytes left in buffer",
+    ALOGV("%s: Done writing JPEG data. %zu bytes left in buffer",
             __FUNCTION__, cinfo->dest->free_in_buffer);
 }
 
diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
index fb8bd27..964d278 100644
--- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
@@ -243,7 +243,7 @@
         size_t heapSize = mCaptureHeap->getSize();
         if (jpegSize > heapSize) {
             ALOGW("%s: JPEG image is larger than expected, truncating "
-                    "(got %d, expected at most %d bytes)",
+                    "(got %zu, expected at most %zu bytes)",
                     __FUNCTION__, jpegSize, heapSize);
             jpegSize = heapSize;
         }
@@ -337,13 +337,13 @@
             size_t offset = size - MARKER_LENGTH;
             uint8_t *end = jpegBuffer + offset;
             if (checkJpegStart(jpegBuffer) && checkJpegEnd(end)) {
-                ALOGV("Found JPEG transport header, img size %d", size);
+                ALOGV("Found JPEG transport header, img size %zu", size);
                 return size;
             } else {
                 ALOGW("Found JPEG transport header with bad Image Start/End");
             }
         } else {
-            ALOGW("Found JPEG transport header with bad size %d", size);
+            ALOGW("Found JPEG transport header with bad size %zu", size);
         }
     }
 
@@ -359,15 +359,15 @@
         segment_t *segment = (segment_t*)(jpegBuffer + size);
         uint8_t type = checkJpegMarker(segment->marker);
         if (type == 0) { // invalid marker, no more segments, begin JPEG data
-            ALOGV("JPEG stream found beginning at offset %d", size);
+            ALOGV("JPEG stream found beginning at offset %zu", size);
             break;
         }
         if (type == EOI || size > maxSize - sizeof(segment_t)) {
-            ALOGE("Got premature End before JPEG data, offset %d", size);
+            ALOGE("Got premature End before JPEG data, offset %zu", size);
             return 0;
         }
         size_t length = ntohs(segment->length);
-        ALOGV("JFIF Segment, type %x length %x", type, length);
+        ALOGV("JFIF Segment, type %x length %zx", type, length);
         size += length + MARKER_LENGTH;
     }
 
@@ -387,10 +387,10 @@
     }
 
     if (size > maxSize) {
-        ALOGW("JPEG size %d too large, reducing to maxSize %d", size, maxSize);
+        ALOGW("JPEG size %zu too large, reducing to maxSize %zu", size, maxSize);
         size = maxSize;
     }
-    ALOGV("Final JPEG size %d", size);
+    ALOGV("Final JPEG size %zu", size);
     return size;
 }
 
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index 75ec426..d5be58c 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -948,7 +948,7 @@
         if (sceneModeOverrides.count !=
                 availableSceneModes.count * kModesPerSceneMode) {
             ALOGE("%s: Camera %d: Scene mode override list is an "
-                    "unexpected size: %d (expected %d)", __FUNCTION__,
+                    "unexpected size: %zu (expected %zu)", __FUNCTION__,
                     cameraId, sceneModeOverrides.count,
                     availableSceneModes.count);
             return NO_INIT;
@@ -1078,7 +1078,7 @@
         const char* tagName = get_camera_metadata_tag_name(tag);
         if (tagName == NULL) tagName = "<unknown>";
         ALOGE("Malformed static metadata entry '%s.%s' (%x):"
-                "Expected between %d and %d values, but got %d values",
+                "Expected between %zu and %zu values, but got %zu values",
                 tagSection, tagName, tag, minCount, maxCount, entry.count);
     }
 
@@ -2426,7 +2426,7 @@
     }
 
     if (areas.size() > maxRegions) {
-        ALOGE("%s: Too many areas requested: %d",
+        ALOGE("%s: Too many areas requested: %zu",
                 __FUNCTION__, areas.size());
         return BAD_VALUE;
     }
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
index 1844ea3..2064e2c 100644
--- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
@@ -225,14 +225,14 @@
     ATRACE_CALL();
     // Make sure we can support this many buffer slots
     if (count > BufferQueue::NUM_BUFFER_SLOTS) {
-        ALOGE("%s: Camera %d: Too many recording buffers requested: %d, max %d",
+        ALOGE("%s: Camera %d: Too many recording buffers requested: %zu, max %d",
                 __FUNCTION__, mId, count, BufferQueue::NUM_BUFFER_SLOTS);
         return BAD_VALUE;
     }
 
     Mutex::Autolock m(mMutex);
 
-    ALOGV("%s: Camera %d: New recording buffer count from encoder: %d",
+    ALOGV("%s: Camera %d: New recording buffer count from encoder: %zu",
             __FUNCTION__, mId, count);
 
     // Need to re-size consumer and heap
@@ -314,7 +314,7 @@
 
     bool newConsumer = false;
     if (mRecordingConsumer == 0) {
-        ALOGV("%s: Camera %d: Creating recording consumer with %d + 1 "
+        ALOGV("%s: Camera %d: Creating recording consumer with %zu + 1 "
                 "consumer-side buffers", __FUNCTION__, mId, mRecordingHeapCount);
         // Create CPU buffer queue endpoint. We need one more buffer here so that we can
         // always acquire and free a buffer when the heap is full; otherwise the consumer
@@ -437,7 +437,7 @@
         releaseAllRecordingFramesLocked();
     }
 
-    ALOGV("%s: Camera %d: %s started, recording heap has %d free of %d",
+    ALOGV("%s: Camera %d: %s started, recording heap has %zu free of %zu",
             __FUNCTION__, mId, (type == PREVIEW) ? "preview" : "recording",
             mRecordingHeapFree, mRecordingHeapCount);
 
@@ -660,8 +660,8 @@
 
         if (mRecordingHeap == 0) {
             const size_t bufferSize = 4 + sizeof(buffer_handle_t);
-            ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
-                    "size %d bytes", __FUNCTION__, mId,
+            ALOGV("%s: Camera %d: Creating recording heap with %zu buffers of "
+                    "size %zu bytes", __FUNCTION__, mId,
                     mRecordingHeapCount, bufferSize);
 
             mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
@@ -821,10 +821,10 @@
     }
 
     if (releasedCount > 0) {
-        ALOGW("%s: Camera %d: Force-freed %d outstanding buffers "
+        ALOGW("%s: Camera %d: Force-freed %zu outstanding buffers "
                 "from previous recording session", __FUNCTION__, mId, releasedCount);
         ALOGE_IF(releasedCount != mRecordingHeapCount - mRecordingHeapFree,
-            "%s: Camera %d: Force-freed %d buffers, but expected %d",
+            "%s: Camera %d: Force-freed %zu buffers, but expected %zu",
             __FUNCTION__, mId, releasedCount, mRecordingHeapCount - mRecordingHeapFree);
     }
 
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
index 07381ae..6ab9e1a 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
@@ -25,6 +25,8 @@
 #define ALOGVV(...) ((void)0)
 #endif
 
+#include <inttypes.h>
+
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <gui/Surface.h>
@@ -78,7 +80,7 @@
     entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
     nsecs_t timestamp = entry.data.i64[0];
     (void)timestamp;
-    ALOGVV("Got preview frame for timestamp %lld", timestamp);
+    ALOGVV("Got preview frame for timestamp %" PRId64, timestamp);
 
     if (mState != RUNNING) return;
 
@@ -463,7 +465,7 @@
 
     mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth;
 
-    ALOGVV("  Acquired buffer, timestamp %lld", queueHead.buffer.mTimestamp);
+    ALOGVV("  Acquired buffer, timestamp %" PRId64, queueHead.buffer.mTimestamp);
 
     findMatchesLocked();
 
@@ -482,7 +484,7 @@
                 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
                 frameTimestamp = entry.data.i64[0];
             }
-            ALOGVV("   %d: b: %lld\tf: %lld", i,
+            ALOGVV("   %d: b: %" PRId64 "\tf: %" PRId64, i,
                     bufferTimestamp, frameTimestamp );
         }
         if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) {
@@ -500,13 +502,13 @@
                     }
                     nsecs_t frameTimestamp = entry.data.i64[0];
                     if (bufferTimestamp == frameTimestamp) {
-                        ALOGVV("%s: Found match %lld", __FUNCTION__,
+                        ALOGVV("%s: Found match %" PRId64, __FUNCTION__,
                                 frameTimestamp);
                         match = true;
                     } else {
                         int64_t delta = abs(bufferTimestamp - frameTimestamp);
                         if ( delta < 1000000) {
-                            ALOGVV("%s: Found close match %lld (delta %lld)",
+                            ALOGVV("%s: Found close match %" PRId64 " (delta %" PRId64 ")",
                                     __FUNCTION__, bufferTimestamp, delta);
                             match = true;
                         }
@@ -542,7 +544,7 @@
             if (entry.count > 0) frameAeState = entry.data.u8[0];
         }
         String8 result =
-                String8::format("   %zu: b: %lld\tf: %lld, AE state: %d", i,
+                String8::format("   %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
                         bufferTimestamp, frameTimestamp, frameAeState);
         ALOGV("%s", result.string());
         if (fd != -1) {
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
index c1d0496..3949b90 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
@@ -25,6 +25,8 @@
 #define ALOGVV(...) ((void)0)
 #endif
 
+#include <inttypes.h>
+
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <gui/Surface.h>
@@ -68,7 +70,7 @@
     entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
     nsecs_t timestamp = entry.data.i64[0];
     (void)timestamp;
-    ALOGVV("Got preview metadata for timestamp %lld", timestamp);
+    ALOGVV("Got preview metadata for timestamp %" PRId64, timestamp);
 
     if (mState != RUNNING) return;
 
@@ -364,7 +366,7 @@
             if (entry.count > 0) frameAeState = entry.data.u8[0];
         }
         String8 result =
-                String8::format("   %zu: b: %lld\tf: %lld, AE state: %d", i,
+                String8::format("   %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
                         bufferTimestamp, frameTimestamp, frameAeState);
         ALOGV("%s", result.string());
         if (fd != -1) {
@@ -424,7 +426,7 @@
                 idx = j;
             }
 
-            ALOGVV("%s: Saw timestamp %lld", __FUNCTION__, frameTimestamp);
+            ALOGVV("%s: Saw timestamp %" PRId64, __FUNCTION__, frameTimestamp);
         }
     }
 
@@ -444,7 +446,7 @@
         ALOGW("%s: ZSL queue has no metadata frames", __FUNCTION__);
     }
 
-    ALOGV("%s: Candidate timestamp %lld (idx %d), empty frames: %d",
+    ALOGV("%s: Candidate timestamp %" PRId64 " (idx %zu), empty frames: %zu",
           __FUNCTION__, minTimestamp, idx, emptyCount);
 
     if (metadataIdx) {
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 187220e..1c9a342 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -159,7 +159,7 @@
 
     int32_t requestId = mRequestIdCounter++;
     metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
-    ALOGV("%s: Camera %d: Submitting request with ID %d",
+    ALOGV("%s: Camera %d: Creating request with ID %d",
           __FUNCTION__, mCameraId, requestId);
 
     if (streaming) {
@@ -186,6 +186,116 @@
     return res;
 }
 
+status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests,
+                                               bool streaming) {
+    ATRACE_CALL();
+    ALOGV("%s-start of function", __FUNCTION__);
+
+    status_t res;
+    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
+
+    Mutex::Autolock icl(mBinderSerializationLock);
+
+    if (!mDevice.get()) return DEAD_OBJECT;
+
+    if (requests.empty()) {
+        ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
+              __FUNCTION__, mCameraId);
+        return BAD_VALUE;
+    }
+
+    List<const CameraMetadata> metadataRequestList;
+    int32_t requestId = mRequestIdCounter;
+    uint32_t loopCounter = 0;
+
+    for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) {
+        sp<CaptureRequest> request = *it;
+        if (request == 0) {
+            ALOGE("%s: Camera %d: Sent null request.",
+                    __FUNCTION__, mCameraId);
+            return BAD_VALUE;
+        }
+
+        CameraMetadata metadata(request->mMetadata);
+        if (metadata.isEmpty()) {
+            ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
+                   __FUNCTION__, mCameraId);
+            return BAD_VALUE;
+        } else if (request->mSurfaceList.isEmpty()) {
+            ALOGE("%s: Camera %d: Requests must have at least one surface target. "
+                  "Rejecting request.", __FUNCTION__, mCameraId);
+            return BAD_VALUE;
+        }
+
+        if (!enforceRequestPermissions(metadata)) {
+            // Callee logs
+            return PERMISSION_DENIED;
+        }
+
+        /**
+         * Write in the output stream IDs which we calculate from
+         * the capture request's list of surface targets
+         */
+        Vector<int32_t> outputStreamIds;
+        outputStreamIds.setCapacity(request->mSurfaceList.size());
+        for (Vector<sp<Surface> >::iterator surfaceIt = 0;
+                surfaceIt != request->mSurfaceList.end(); ++surfaceIt) {
+            sp<Surface> surface = *surfaceIt;
+            if (surface == 0) continue;
+
+            sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
+            int idx = mStreamMap.indexOfKey(gbp->asBinder());
+
+            // Trying to submit request with surface that wasn't created
+            if (idx == NAME_NOT_FOUND) {
+                ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
+                      " we have not called createStream on",
+                      __FUNCTION__, mCameraId);
+                return BAD_VALUE;
+            }
+
+            int streamId = mStreamMap.valueAt(idx);
+            outputStreamIds.push_back(streamId);
+            ALOGV("%s: Camera %d: Appending output stream %d to request",
+                  __FUNCTION__, mCameraId, streamId);
+        }
+
+        metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
+                        outputStreamIds.size());
+
+        metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
+        loopCounter++; // loopCounter starts from 1
+        ALOGV("%s: Camera %d: Creating request with ID %d (%d of %d)",
+              __FUNCTION__, mCameraId, requestId, loopCounter, requests.size());
+
+        metadataRequestList.push_back(metadata);
+    }
+    mRequestIdCounter++;
+
+    if (streaming) {
+        res = mDevice->setStreamingRequestList(metadataRequestList);
+        if (res != OK) {
+            ALOGE("%s: Camera %d:  Got error %d after trying to set streaming "
+                  "request", __FUNCTION__, mCameraId, res);
+        } else {
+            mStreamingRequestList.push_back(requestId);
+        }
+    } else {
+        res = mDevice->captureList(metadataRequestList);
+        if (res != OK) {
+            ALOGE("%s: Camera %d: Got error %d after trying to set capture",
+                __FUNCTION__, mCameraId, res);
+        }
+    }
+
+    ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
+    if (res == OK) {
+        return requestId;
+    }
+
+    return res;
+}
+
 status_t CameraDeviceClient::cancelRequest(int requestId) {
     ATRACE_CALL();
     ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
@@ -284,7 +394,7 @@
         ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder());
         if (index != NAME_NOT_FOUND) {
             ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
-                  "(ID %d)",
+                  "(ID %zd)",
                   __FUNCTION__, mCameraId, index);
             return ALREADY_EXISTS;
         }
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index b9c16aa..e96e1ae 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -63,8 +63,11 @@
      */
 
     // Note that the callee gets a copy of the metadata.
-    virtual int           submitRequest(sp<CaptureRequest> request,
-                                        bool streaming = false);
+    virtual status_t           submitRequest(sp<CaptureRequest> request,
+                                             bool streaming = false);
+    // List of requests are copied.
+    virtual status_t           submitRequestList(List<sp<CaptureRequest> > requests,
+                                                 bool streaming = false);
     virtual status_t      cancelRequest(int requestId);
 
     // Returns -EBUSY if device is not idle
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 2d1253f..6a88c87 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -18,6 +18,8 @@
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
+#include <inttypes.h>
+
 #include <utils/Log.h>
 #include <utils/Trace.h>
 
@@ -236,7 +238,7 @@
     (void)requestId;
     (void)timestamp;
 
-    ALOGV("%s: Shutter notification for request id %d at time %lld",
+    ALOGV("%s: Shutter notification for request id %d at time %" PRId64,
             __FUNCTION__, requestId, timestamp);
 }
 
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index e80abf1..a4ae179 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -22,6 +22,7 @@
 #include <utils/String16.h>
 #include <utils/Vector.h>
 #include <utils/Timers.h>
+#include <utils/List.h>
 
 #include "hardware/camera2.h"
 #include "camera/CameraMetadata.h"
@@ -58,12 +59,22 @@
     virtual status_t capture(CameraMetadata &request) = 0;
 
     /**
+     * Submit a list of requests.
+     */
+    virtual status_t captureList(const List<const CameraMetadata> &requests) = 0;
+
+    /**
      * Submit request for streaming. The CameraDevice makes a copy of the
      * passed-in buffer and the caller retains ownership.
      */
     virtual status_t setStreamingRequest(const CameraMetadata &request) = 0;
 
     /**
+     * Submit a list of requests for streaming.
+     */
+    virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests) = 0;
+
+    /**
      * Clear the streaming request slot.
      */
     virtual status_t clearStreamingRequest() = 0;
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
index f2064fb..4d31667 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
@@ -183,7 +183,7 @@
             item++;
         }
     }
-    ALOGV("Got %d range listeners out of %d", listeners.size(), mRangeListeners.size());
+    ALOGV("Got %zu range listeners out of %zu", listeners.size(), mRangeListeners.size());
     List<sp<FilteredListener> >::iterator item = listeners.begin();
     for (; item != listeners.end(); item++) {
         (*item)->onFrameAvailable(requestId, frame);
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index f60ca98..0cc3a04 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -207,6 +207,12 @@
     return OK;
 }
 
+status_t Camera2Device::captureList(const List<const CameraMetadata> &requests) {
+    ATRACE_CALL();
+    ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__);
+    return INVALID_OPERATION;
+}
+
 
 status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
     ATRACE_CALL();
@@ -215,6 +221,12 @@
     return mRequestQueue.setStreamSlot(streamRequest.release());
 }
 
+status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests) {
+    ATRACE_CALL();
+    ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__);
+    return INVALID_OPERATION;
+}
+
 status_t Camera2Device::clearStreamingRequest() {
     ATRACE_CALL();
     return mRequestQueue.setStreamSlot(NULL);
@@ -987,7 +999,7 @@
         return BAD_VALUE;
     }
 
-    ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
+    ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu",
             __FUNCTION__, width, height, format, size);
 
     mConsumerInterface = consumer;
@@ -1059,7 +1071,7 @@
                 mSize, 1, mFormat);
         if (res != OK) {
             ALOGE("%s: Unable to configure compressed stream buffer geometry"
-                    " %d x %d, size %d for stream %d",
+                    " %d x %d, size %zu for stream %d",
                     __FUNCTION__, mWidth, mHeight, mSize, mId);
             return res;
         }
diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h
index 5b91f88..61bfd1a 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.h
+++ b/services/camera/libcameraservice/device2/Camera2Device.h
@@ -48,7 +48,9 @@
     virtual status_t dump(int fd, const Vector<String16>& args);
     virtual const CameraMetadata& info() const;
     virtual status_t capture(CameraMetadata &request);
+    virtual status_t captureList(const List<const CameraMetadata> &requests);
     virtual status_t setStreamingRequest(const CameraMetadata &request);
+    virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests);
     virtual status_t clearStreamingRequest();
     virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout);
     virtual status_t createStream(sp<ANativeWindow> consumer,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 08e03ce..51dcb89 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -37,6 +37,8 @@
     "%s: " fmt, __FUNCTION__,                    \
     ##__VA_ARGS__)
 
+#include <inttypes.h>
+
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <utils/Timers.h>
@@ -331,7 +333,7 @@
     } else {
         for (size_t i = 0; i < mInFlightMap.size(); i++) {
             InFlightRequest r = mInFlightMap.valueAt(i);
-            lines.appendFormat("      Frame %d |  Timestamp: %lld, metadata"
+            lines.appendFormat("      Frame %d |  Timestamp: %" PRId64 ", metadata"
                     " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
                     r.captureTimestamp, r.haveResultMetadata ? "true" : "false",
                     r.numBuffersLeft);
@@ -370,6 +372,45 @@
     return mDeviceInfo;
 }
 
+status_t Camera3Device::checkStatusOkToCaptureLocked() {
+    switch (mStatus) {
+        case STATUS_ERROR:
+            CLOGE("Device has encountered a serious error");
+            return INVALID_OPERATION;
+        case STATUS_UNINITIALIZED:
+            CLOGE("Device not initialized");
+            return INVALID_OPERATION;
+        case STATUS_UNCONFIGURED:
+        case STATUS_CONFIGURED:
+        case STATUS_ACTIVE:
+            // OK
+            break;
+        default:
+            SET_ERR_L("Unexpected status: %d", mStatus);
+            return INVALID_OPERATION;
+    }
+    return OK;
+}
+
+status_t Camera3Device::convertMetadataListToRequestListLocked(
+        const List<const CameraMetadata> &metadataList, RequestList *requestList) {
+    if (requestList == NULL) {
+        CLOGE("requestList cannot be NULL.");
+        return BAD_VALUE;
+    }
+
+    for (List<const CameraMetadata>::const_iterator it = metadataList.begin();
+            it != metadataList.end(); ++it) {
+        sp<CaptureRequest> newRequest = setUpRequestLocked(*it);
+        if (newRequest == 0) {
+            CLOGE("Can't create capture request");
+            return BAD_VALUE;
+        }
+        requestList->push_back(newRequest);
+    }
+    return OK;
+}
+
 status_t Camera3Device::capture(CameraMetadata &request) {
     ATRACE_CALL();
     status_t res;
@@ -410,10 +451,59 @@
                     kActiveTimeout/1e9);
         }
         ALOGV("Camera %d: Capture request enqueued", mId);
+    } else {
+        CLOGE("Cannot queue request. Impossible."); // queueRequest always returns OK.
+        return BAD_VALUE;
     }
     return res;
 }
 
+status_t Camera3Device::submitRequestsHelper(
+        const List<const CameraMetadata> &requests, bool repeating) {
+    ATRACE_CALL();
+    Mutex::Autolock il(mInterfaceLock);
+    Mutex::Autolock l(mLock);
+
+    status_t res = checkStatusOkToCaptureLocked();
+    if (res != OK) {
+        // error logged by previous call
+        return res;
+    }
+
+    RequestList requestList;
+
+    res = convertMetadataListToRequestListLocked(requests, /*out*/&requestList);
+    if (res != OK) {
+        // error logged by previous call
+        return res;
+    }
+
+    if (repeating) {
+        res = mRequestThread->setRepeatingRequests(requestList);
+    } else {
+        res = mRequestThread->queueRequestList(requestList);
+    }
+
+    if (res == OK) {
+        waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
+        if (res != OK) {
+            SET_ERR_L("Can't transition to active in %f seconds!",
+                    kActiveTimeout/1e9);
+        }
+        ALOGV("Camera %d: Capture request enqueued", mId);
+    } else {
+        CLOGE("Cannot queue request. Impossible.");
+        return BAD_VALUE;
+    }
+
+    return res;
+}
+
+status_t Camera3Device::captureList(const List<const CameraMetadata> &requests) {
+    ATRACE_CALL();
+
+    return submitRequestsHelper(requests, /*repeating*/false);
+}
 
 status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
     ATRACE_CALL();
@@ -460,6 +550,11 @@
     return res;
 }
 
+status_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests) {
+    ATRACE_CALL();
+
+    return submitRequestsHelper(requests, /*repeating*/true);
+}
 
 sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
         const CameraMetadata &request) {
@@ -662,7 +757,7 @@
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
-    ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, size %d",
+    ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, size %zu",
             mId, mNextStreamId, width, height, format, size);
 
     status_t res;
@@ -904,6 +999,10 @@
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
+    return waitUntilDrainedLocked();
+}
+
+status_t Camera3Device::waitUntilDrainedLocked() {
     switch (mStatus) {
         case STATUS_UNINITIALIZED:
         case STATUS_UNCONFIGURED:
@@ -1008,7 +1107,7 @@
         if (res == TIMED_OUT) {
             return res;
         } else if (res != OK) {
-            ALOGW("%s: Camera %d: No frame in %lld ns: %s (%d)",
+            ALOGW("%s: Camera %d: No frame in %" PRId64 " ns: %s (%d)",
                     __FUNCTION__, mId, timeout, strerror(-res), res);
             return res;
         }
@@ -1114,7 +1213,7 @@
     if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) {
         res = mHal3Device->ops->flush(mHal3Device);
     } else {
-        res = waitUntilDrained();
+        res = waitUntilDrainedLocked();
     }
 
     return res;
@@ -1672,7 +1771,7 @@
         // Sanity check - if we have too many in-flight frames, something has
         // likely gone wrong
         if (mInFlightMap.size() > kInFlightWarnLimit) {
-            CLOGE("In-flight list too large: %d", mInFlightMap.size());
+            CLOGE("In-flight list too large: %zu", mInFlightMap.size());
         }
 
     }
@@ -1722,7 +1821,7 @@
             gotResult = false;
         } else if (timestamp != entry.data.i64[0]) {
             SET_ERR("Timestamp mismatch between shutter notify and result"
-                    " metadata for frame %d (%lld vs %lld respectively)",
+                    " metadata for frame %d (%" PRId64 " vs %" PRId64 " respectively)",
                     frameNumber, timestamp, entry.data.i64[0]);
             gotResult = false;
         }
@@ -1744,7 +1843,7 @@
         // Note: stream may be deallocated at this point, if this buffer was the
         // last reference to it.
         if (res != OK) {
-            ALOGE("Can't return buffer %d for frame %d to its stream: "
+            ALOGE("Can't return buffer %zu for frame %d to its stream: "
                     " %s (%d)", i, frameNumber, strerror(-res), res);
         }
     }
@@ -1834,7 +1933,7 @@
                         frameNumber);
                 break;
             }
-            ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %lld",
+            ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
                     mId, __FUNCTION__, frameNumber, requestId, timestamp);
             // Call listener, if any
             if (listener != NULL) {
@@ -1895,6 +1994,19 @@
     return OK;
 }
 
+status_t Camera3Device::RequestThread::queueRequestList(
+        List<sp<CaptureRequest> > &requests) {
+    Mutex::Autolock l(mRequestLock);
+    for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
+            ++it) {
+        mRequestQueue.push_back(*it);
+    }
+
+    unpauseForNewRequests();
+
+    return OK;
+}
+
 
 status_t Camera3Device::RequestThread::queueTrigger(
         RequestTrigger trigger[],
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 9007a9b..7ea8bcf 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -79,7 +79,9 @@
     // Capture and setStreamingRequest will configure streams if currently in
     // idle state
     virtual status_t capture(CameraMetadata &request);
+    virtual status_t captureList(const List<const CameraMetadata> &requests);
     virtual status_t setStreamingRequest(const CameraMetadata &request);
+    virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests);
     virtual status_t clearStreamingRequest();
 
     virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout);
@@ -201,6 +203,14 @@
     };
     typedef List<sp<CaptureRequest> > RequestList;
 
+    status_t checkStatusOkToCaptureLocked();
+
+    status_t convertMetadataListToRequestListLocked(
+            const List<const CameraMetadata> &metadataList,
+            /*out*/RequestList *requestList);
+
+    status_t submitRequestsHelper(const List<const CameraMetadata> &requests, bool repeating);
+
     /**
      * Get the last request submitted to the hal by the request thread.
      *
@@ -236,6 +246,13 @@
     status_t waitUntilStateThenRelock(bool active, nsecs_t timeout);
 
     /**
+     * Implementation of waitUntilDrained. On success, will transition to IDLE state.
+     *
+     * Need to be called with mLock and mInterfaceLock held.
+     */
+    status_t waitUntilDrainedLocked();
+
+    /**
      * Do common work for setting up a streaming or single capture request.
      * On success, will transition to ACTIVE if in IDLE.
      */
@@ -312,6 +329,8 @@
 
         status_t queueRequest(sp<CaptureRequest> request);
 
+        status_t queueRequestList(List<sp<CaptureRequest> > &requests);
+
         /**
          * Remove all queued and repeating requests, and pending triggers
          */
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index 42e02d8..d662cc2 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -18,8 +18,7 @@
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
-// This is needed for stdint.h to define INT64_MAX in C++
-#define __STDC_LIMIT_MACROS
+#include <inttypes.h>
 
 #include <utils/Log.h>
 #include <utils/Trace.h>
@@ -54,8 +53,8 @@
 
 bool Camera3IOStreamBase::hasOutstandingBuffersLocked() const {
     nsecs_t signalTime = mCombinedFence->getSignalTime();
-    ALOGV("%s: Stream %d: Has %d outstanding buffers,"
-            " buffer signal time is %lld",
+    ALOGV("%s: Stream %d: Has %zu outstanding buffers,"
+            " buffer signal time is %" PRId64,
             __FUNCTION__, mId, mDequeuedBufferCount, signalTime);
     if (mDequeuedBufferCount > 0 || signalTime == INT64_MAX) {
         return true;
@@ -73,7 +72,7 @@
     lines.appendFormat("      Max size: %zu\n", mMaxSize);
     lines.appendFormat("      Usage: %d, max HAL buffers: %d\n",
             camera3_stream::usage, camera3_stream::max_buffers);
-    lines.appendFormat("      Frames produced: %d, last timestamp: %lld ns\n",
+    lines.appendFormat("      Frames produced: %d, last timestamp: %" PRId64 " ns\n",
             mFrameCount, mLastTimestamp);
     lines.appendFormat("      Total buffers: %zu, currently dequeued: %zu\n",
             mTotalBufferCount, mDequeuedBufferCount);
@@ -119,7 +118,7 @@
     }
 
     if (mDequeuedBufferCount > 0) {
-        ALOGE("%s: Can't disconnect with %d buffers still dequeued!",
+        ALOGE("%s: Can't disconnect with %zu buffers still dequeued!",
                 __FUNCTION__, mDequeuedBufferCount);
         return INVALID_OPERATION;
     }
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 6d2cf94..70406f1 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -353,7 +353,7 @@
     }
     if (bufferIdx == bufferCount) {
         // Got all buffers, register with HAL
-        ALOGV("%s: Registering %d buffers with camera HAL",
+        ALOGV("%s: Registering %zu buffers with camera HAL",
                 __FUNCTION__, bufferCount);
         ATRACE_BEGIN("camera3->register_stream_buffers");
         res = hal3Device->ops->register_stream_buffers(hal3Device,
diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
index 04deac5..09e14c5 100644
--- a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
@@ -18,6 +18,8 @@
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
+#include <inttypes.h>
+
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include "Camera3ZslStream.h"
@@ -299,7 +301,7 @@
 
     if (actual != timestamp) {
         ALOGW("%s: ZSL buffer candidate search didn't find an exact match --"
-              " requested timestamp = %lld, actual timestamp = %lld",
+              " requested timestamp = %" PRId64 ", actual timestamp = %" PRId64,
               __FUNCTION__, timestamp, actual);
     }
 
diff --git a/services/camera/libcameraservice/device3/StatusTracker.cpp b/services/camera/libcameraservice/device3/StatusTracker.cpp
index ab5419f..723b5c2 100644
--- a/services/camera/libcameraservice/device3/StatusTracker.cpp
+++ b/services/camera/libcameraservice/device3/StatusTracker.cpp
@@ -18,9 +18,6 @@
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
-// This is needed for stdint.h to define INT64_MAX in C++
-#define __STDC_LIMIT_MACROS
-
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <ui/Fence.h>
@@ -52,7 +49,7 @@
         ALOGV("%s: Adding new component %d", __FUNCTION__, id);
 
         err = mStates.add(id, IDLE);
-        ALOGE_IF(err < 0, "%s: Can't add new component %d: %s (%d)",
+        ALOGE_IF(err < 0, "%s: Can't add new component %d: %s (%zd)",
                 __FUNCTION__, id, strerror(-err), err);
     }
 
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
index 9a6dc28..e4ec5fd 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
@@ -17,6 +17,9 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "RingBufferConsumer"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <inttypes.h>
+
 #include <utils/Log.h>
 
 #include <gui/RingBufferConsumer.h>
@@ -164,10 +167,10 @@
     }
 
     if (it == end) {
-        BI_LOGE("Failed to pin buffer (timestamp %lld, framenumber %lld)",
+        BI_LOGE("Failed to pin buffer (timestamp %" PRId64 ", framenumber %" PRIu64 ")",
                  item.mTimestamp, item.mFrameNumber);
     } else {
-        BI_LOGV("Pinned buffer (frame %lld, timestamp %lld)",
+        BI_LOGV("Pinned buffer (frame %" PRIu64 ", timestamp %" PRId64 ")",
                 item.mFrameNumber, item.mTimestamp);
     }
 }
@@ -222,12 +225,12 @@
 
         if (err != OK) {
             BI_LOGE("Failed to add release fence to buffer "
-                    "(timestamp %lld, framenumber %lld",
+                    "(timestamp %" PRId64 ", framenumber %" PRIu64,
                     item.mTimestamp, item.mFrameNumber);
             return err;
         }
 
-        BI_LOGV("Attempting to release buffer timestamp %lld, frame %lld",
+        BI_LOGV("Attempting to release buffer timestamp %" PRId64 ", frame %" PRIu64,
                 item.mTimestamp, item.mFrameNumber);
 
         // item.mGraphicBuffer was populated with the proper graphic-buffer
@@ -241,7 +244,7 @@
             return err;
         }
 
-        BI_LOGV("Buffer timestamp %lld, frame %lld evicted",
+        BI_LOGV("Buffer timestamp %" PRId64 ", frame %" PRIu64 " evicted",
                 item.mTimestamp, item.mFrameNumber);
 
         size_t currentSize = mBufferItemList.size();
@@ -294,8 +297,8 @@
             return;
         }
 
-        BI_LOGV("New buffer acquired (timestamp %lld), "
-                "buffer items %u out of %d",
+        BI_LOGV("New buffer acquired (timestamp %" PRId64 "), "
+                "buffer items %zu out of %d",
                 item.mTimestamp,
                 mBufferItemList.size(), mBufferCount);
 
@@ -321,7 +324,7 @@
 
             if (res != OK) {
                 BI_LOGE("Failed to add release fence to buffer "
-                        "(timestamp %lld, framenumber %lld",
+                        "(timestamp %" PRId64 ", framenumber %" PRIu64,
                         item.mTimestamp, item.mFrameNumber);
                 return;
             }
@@ -333,10 +336,10 @@
 
     if (it == end) {
         // This should never happen. If it happens, we have a bug.
-        BI_LOGE("Failed to unpin buffer (timestamp %lld, framenumber %lld)",
+        BI_LOGE("Failed to unpin buffer (timestamp %" PRId64 ", framenumber %" PRIu64 ")",
                  item.mTimestamp, item.mFrameNumber);
     } else {
-        BI_LOGV("Unpinned buffer (timestamp %lld, framenumber %lld)",
+        BI_LOGV("Unpinned buffer (timestamp %" PRId64 ", framenumber %" PRIu64 ")",
                  item.mTimestamp, item.mFrameNumber);
     }
 }