Camera: add bufferId field to StreamBuffer

This gives each buffer a unique identifier and allow camera server
to only send one unique to HAL process once.

Bug: 30985004
Change-Id: I6aff498c5667dd71fd70b3881fd60b0ecc366e0a
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 201a3b4..5f7b950 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -307,31 +307,40 @@
         hidl_vec<buffer_handle_t*>& allBufPtrs,
         hidl_vec<int>& allFences) {
     bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
-            request.inputBuffer.buffer.getNativeHandle() != nullptr);
+            request.inputBuffer.bufferId != 0);
     size_t numOutputBufs = request.outputBuffers.size();
     size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
     // Validate all I/O buffers
     hidl_vec<buffer_handle_t> allBufs;
+    hidl_vec<uint64_t> allBufIds;
     allBufs.resize(numBufs);
+    allBufIds.resize(numBufs);
     allBufPtrs.resize(numBufs);
     allFences.resize(numBufs);
     std::vector<int32_t> streamIds(numBufs);
 
     for (size_t i = 0; i < numOutputBufs; i++) {
         allBufs[i] = request.outputBuffers[i].buffer.getNativeHandle();
+        allBufIds[i] = request.outputBuffers[i].bufferId;
         allBufPtrs[i] = &allBufs[i];
         streamIds[i] = request.outputBuffers[i].streamId;
     }
     if (hasInputBuf) {
         allBufs[numOutputBufs] = request.inputBuffer.buffer.getNativeHandle();
+        allBufIds[numOutputBufs] = request.inputBuffer.bufferId;
         allBufPtrs[numOutputBufs] = &allBufs[numOutputBufs];
         streamIds[numOutputBufs] = request.inputBuffer.streamId;
     }
 
     for (size_t i = 0; i < numBufs; i++) {
         buffer_handle_t buf = allBufs[i];
+        uint64_t bufId = allBufIds[i];
         CirculatingBuffers& cbs = mCirculatingBuffers[streamIds[i]];
-        if (cbs.count(buf) == 0) {
+        if (cbs.count(bufId) == 0) {
+            if (buf == nullptr) {
+                ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
+                return Status::ILLEGAL_ARGUMENT;
+            }
             // Register a newly seen buffer
             buffer_handle_t importedBuf = buf;
             sHandleImporter.importBuffer(importedBuf);
@@ -339,10 +348,10 @@
                 ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i);
                 return Status::INTERNAL_ERROR;
             } else {
-                cbs[buf] = importedBuf;
+                cbs[bufId] = importedBuf;
             }
         }
-        allBufPtrs[i] = &cbs[buf];
+        allBufPtrs[i] = &cbs[bufId];
     }
 
     // All buffers are imported. Now validate output buffer acquire fences
@@ -509,7 +518,7 @@
     hidl_vec<buffer_handle_t*> allBufPtrs;
     hidl_vec<int> allFences;
     bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
-            request.inputBuffer.buffer.getNativeHandle() != nullptr);
+            request.inputBuffer.bufferId != 0);
     size_t numOutputBufs = request.outputBuffers.size();
     size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
     status = importRequest(request, allBufPtrs, allFences);
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index 498617e..ca9d24d 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -100,44 +100,12 @@
     // (streamID, frameNumber) -> inflight buffer cache
     std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t>  mInflightBuffers;
 
-    struct BufferHasher {
-        size_t operator()(const buffer_handle_t& buf) const {
-            if (buf == nullptr)
-                return 0;
-
-            size_t result = 1;
-            result = 31 * result + buf->numFds;
-            result = 31 * result + buf->numInts;
-            int length = buf->numFds + buf->numInts;
-            for (int i = 0; i < length; i++) {
-                result = 31 * result + buf->data[i];
-            }
-            return result;
-        }
-    };
-
-    struct BufferComparator {
-        bool operator()(const buffer_handle_t& buf1, const buffer_handle_t& buf2) const {
-            if (buf1->numFds == buf2->numFds && buf1->numInts == buf2->numInts) {
-                int length = buf1->numFds + buf1->numInts;
-                for (int i = 0; i < length; i++) {
-                    if (buf1->data[i] != buf2->data[i]) {
-                        return false;
-                    }
-                }
-                return true;
-            }
-            return false;
-        }
-    };
-
     // buffers currently ciculating between HAL and camera service
-    // key: buffer_handle_t sent via HIDL interface
+    // key: bufferId sent via HIDL interface
     // value: imported buffer_handle_t
     // Buffer will be imported during process_capture_request and will be freed
     // when the its stream is deleted or camera device session is closed
-    typedef std::unordered_map<buffer_handle_t, buffer_handle_t,
-            BufferHasher, BufferComparator> CirculatingBuffers;
+    typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
     // Stream ID -> circulating buffers map
     std::map<int, CirculatingBuffers> mCirculatingBuffers;
 
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index 1e0924c..c07a670 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -405,16 +405,33 @@
     /**
      * The ID of the stream this buffer is associated with. -1 indicates an
      * invalid (empty) StreamBuffer, in which case buffer must also point to
-     * null.
+     * null and bufferId must be 0.
      */
     int32_t streamId;
 
     /**
+     * The unique ID of the buffer within this StreamBuffer. 0 indicates this
+     * StreamBuffer contains no buffer.
+     * For StreamBuffers sent to the HAL in a CaptureRequest, this ID uniquely
+     * identifies a buffer. When a buffer is sent to HAL for the first time,
+     * both bufferId and buffer handle must be filled. HAL must keep track of
+     * the mapping between bufferId and corresponding buffer until the
+     * corresponding stream is removed from stream configuration or until camera
+     * device session is closed. After the first time a buffer is introduced to
+     * HAL, in the future camera service must refer to the same buffer using
+     * only bufferId, and keep the buffer handle null.
+     */
+    uint64_t bufferId;
+
+    /**
      * The graphics buffer handle to the buffer.
      *
-     * For StreamBuffers sent to the HAL in a CaptureRequest, this must be a
+     * For StreamBuffers sent to the HAL in a CaptureRequest, if the bufferId
+     * is not seen by the HAL before, this buffer handle is guaranteed to be a
      * valid handle to a graphics buffer, with dimensions and format matching
-     * that of the stream.
+     * that of the stream. If the bufferId has been sent to the HAL before, this
+     * buffer handle must be null and HAL must look up the actual buffer handle
+     * to use from its own bufferId to buffer handle map.
      *
      * For StreamBuffers returned in a CaptureResult, this must be null, since
      * the handle to the buffer is already known to the client (since the client