Camera: add interface to evict obsolete buffer caches

Test: fix CTS ReprocessCaptureTest
Bug: 34461678
Change-Id: Icde654b0c8423c31d7d39d180913ffa374e7de3c
diff --git a/camera/device/3.2/ICameraDeviceSession.hal b/camera/device/3.2/ICameraDeviceSession.hal
index e186c8d..731fc76 100644
--- a/camera/device/3.2/ICameraDeviceSession.hal
+++ b/camera/device/3.2/ICameraDeviceSession.hal
@@ -183,6 +183,11 @@
      * client, the HAL must process the requests in order of lowest index to
      * highest index.
      *
+     * The cachesToRemove argument contains a list of buffer caches (see
+     * StreamBuffer document for more information on buffer cache) to be removed
+     * by camera HAL. Camera HAL must remove these cache entries whether or not
+     * this method returns OK.
+     *
      * The actual request processing is asynchronous, with the results of
      * capture being returned by the HAL through the processCaptureResult()
      * call. This call requires the result metadata to be available, but output
@@ -238,7 +243,8 @@
      *     that HAL processed successfully before HAL runs into an error.
      *
      */
-    processCaptureRequest(vec<CaptureRequest> requests)
+    processCaptureRequest(vec<CaptureRequest> requests,
+            vec<BufferCache> cachesToRemove)
             generates (Status status, uint32_t numRequestProcessed);
 
     /**
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index fb1d1ff..5b3024b 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -678,8 +678,32 @@
     mCirculatingBuffers.erase(id);
 }
 
+void CameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove) {
+    Mutex::Autolock _l(mInflightLock);
+    for (auto& cache : cachesToRemove) {
+        auto cbsIt = mCirculatingBuffers.find(cache.streamId);
+        if (cbsIt == mCirculatingBuffers.end()) {
+            // The stream could have been removed
+            continue;
+        }
+        CirculatingBuffers& cbs = cbsIt->second;
+        auto it = cbs.find(cache.bufferId);
+        if (it != cbs.end()) {
+            sHandleImporter.freeBuffer(it->second);
+            cbs.erase(it);
+        } else {
+            ALOGE("%s: stream %d buffer %" PRIu64 " is not cached",
+                    __FUNCTION__, cache.streamId, cache.bufferId);
+        }
+    }
+}
+
 Return<void> CameraDeviceSession::processCaptureRequest(
-        const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb)  {
+        const hidl_vec<CaptureRequest>& requests,
+        const hidl_vec<BufferCache>& cachesToRemove,
+        processCaptureRequest_cb _hidl_cb)  {
+    updateBufferCaches(cachesToRemove);
+
     uint32_t numRequestProcessed = 0;
     Status s = Status::OK;
     for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index 8923c05..781056e 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -85,7 +85,9 @@
     Return<void> configureStreams(
             const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
     Return<void> processCaptureRequest(
-            const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb) override;
+            const hidl_vec<CaptureRequest>& requests,
+            const hidl_vec<BufferCache>& cachesToRemove,
+            processCaptureRequest_cb _hidl_cb) override;
     Return<Status> flush() override;
     Return<void> close() override;
 
@@ -234,6 +236,8 @@
 
     void cleanupBuffersLocked(int id);
 
+    void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove);
+
     Status processOneCaptureRequest(const CaptureRequest& request);
     /**
      * Static callback forwarding methods from HAL to instance
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index fd75528..5ae7a18 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -958,3 +958,25 @@
     uint32_t partialResult;
 
 };
+
+/**
+ * BufferCache:
+ *
+ * A list of cached bufferIds associated with a certain stream.
+ * Buffers are passed between camera service and camera HAL via bufferId except
+ * the first time a new buffer is being passed to HAL in CaptureRequest. Camera
+ * service and camera HAL therefore need to maintain a cached map of bufferId
+ * and corresponing native handle.
+ *
+ */
+struct BufferCache {
+    /**
+     * The ID of the stream this list is associated with.
+     */
+    int32_t streamId;
+
+    /**
+     * A cached buffer ID associated with streamId.
+     */
+    uint64_t bufferId;
+};