Camera: support libhardware camera device 3.6

Add buffer management API support.

Test: VTS to be written. Need Pixel device impl to verify.
Bug: 120986771
Change-Id: Icdbc621f8cd17aa0868d3ac361867c44793a268c
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index fd785df..f2d7a47 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -44,13 +44,15 @@
 static constexpr int METADATA_SHRINK_REL_THRESHOLD = 2;
 
 HandleImporter CameraDeviceSession::sHandleImporter;
+buffer_handle_t CameraDeviceSession::sEmptyBuffer = nullptr;
+
 const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
 
 CameraDeviceSession::CameraDeviceSession(
     camera3_device_t* device,
     const camera_metadata_t* deviceInfo,
     const sp<ICameraDeviceCallback>& callback) :
-        camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
+        camera3_callback_ops({&sProcessCaptureResult, &sNotify, nullptr, nullptr}),
         mDevice(device),
         mDeviceVersion(device->common.version),
         mFreeBufEarly(shouldFreeBufEarly()),
@@ -246,10 +248,50 @@
     }
 }
 
+Status CameraDeviceSession::importBuffer(int32_t streamId,
+        uint64_t bufId, buffer_handle_t buf,
+        /*out*/buffer_handle_t** outBufPtr,
+        bool allowEmptyBuf) {
+
+    if (buf == nullptr && bufId == BUFFER_ID_NO_BUFFER) {
+        if (allowEmptyBuf) {
+            *outBufPtr = &sEmptyBuffer;
+            return Status::OK;
+        } else {
+            ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
+            return Status::ILLEGAL_ARGUMENT;
+        }
+    }
+
+    Mutex::Autolock _l(mInflightLock);
+    CirculatingBuffers& cbs = mCirculatingBuffers[streamId];
+    if (cbs.count(bufId) == 0) {
+        // Register a newly seen buffer
+        buffer_handle_t importedBuf = buf;
+        sHandleImporter.importBuffer(importedBuf);
+        if (importedBuf == nullptr) {
+            ALOGE("%s: output buffer for stream %d is invalid!", __FUNCTION__, streamId);
+            return Status::INTERNAL_ERROR;
+        } else {
+            cbs[bufId] = importedBuf;
+        }
+    }
+    *outBufPtr = &cbs[bufId];
+    return Status::OK;
+}
+
 Status CameraDeviceSession::importRequest(
         const CaptureRequest& request,
         hidl_vec<buffer_handle_t*>& allBufPtrs,
         hidl_vec<int>& allFences) {
+    return importRequestImpl(request, allBufPtrs, allFences);
+}
+
+Status CameraDeviceSession::importRequestImpl(
+        const CaptureRequest& request,
+        hidl_vec<buffer_handle_t*>& allBufPtrs,
+        hidl_vec<int>& allFences,
+        bool allowEmptyBuf) {
     bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
             request.inputBuffer.bufferId != 0);
     size_t numOutputBufs = request.outputBuffers.size();
@@ -277,25 +319,15 @@
     }
 
     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(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);
-            if (importedBuf == nullptr) {
-                ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i);
-                return Status::INTERNAL_ERROR;
-            } else {
-                cbs[bufId] = importedBuf;
-            }
+        Status st = importBuffer(
+                streamIds[i], allBufIds[i], allBufs[i], &allBufPtrs[i],
+                // Disallow empty buf for input stream, otherwise follow
+                // the allowEmptyBuf argument.
+                (hasInputBuf && i == numOutputBufs) ? false : allowEmptyBuf);
+        if (st != Status::OK) {
+            // Detailed error logs printed in importBuffer
+            return st;
         }
-        allBufPtrs[i] = &cbs[bufId];
     }
 
     // All buffers are imported. Now validate output buffer acquire fences
@@ -1271,18 +1303,26 @@
         ATRACE_END();
 
         // free all imported buffers
+        Mutex::Autolock _l(mInflightLock);
         for(auto& pair : mCirculatingBuffers) {
             CirculatingBuffers& buffers = pair.second;
             for (auto& p2 : buffers) {
                 sHandleImporter.freeBuffer(p2.second);
             }
+            buffers.clear();
         }
+        mCirculatingBuffers.clear();
 
         mClosed = true;
     }
     return Void();
 }
 
+uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t&, int) {
+    // No need to fill in bufferId by default
+    return BUFFER_ID_NO_BUFFER;
+}
+
 status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result,
                                                  const camera3_capture_result *hal_result) {
     uint32_t frameNumber = hal_result->frame_number;
@@ -1396,6 +1436,14 @@
         result.outputBuffers[i].streamId =
                 static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
         result.outputBuffers[i].buffer = nullptr;
+        if (hal_result->output_buffers[i].buffer != nullptr) {
+            result.outputBuffers[i].bufferId = getCapResultBufferId(
+                    *(hal_result->output_buffers[i].buffer),
+                    result.outputBuffers[i].streamId);
+        } else {
+            result.outputBuffers[i].bufferId = 0;
+        }
+
         result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status;
         // skip acquire fence since it's of no use to camera service
         if (hal_result->output_buffers[i].release_fence != -1) {
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index bcee259..a96c245 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -161,6 +161,7 @@
     std::map<uint32_t, bool> mInflightRawBoostPresent;
     ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest;
 
+    static const uint64_t BUFFER_ID_NO_BUFFER = 0;
     // buffers currently ciculating between HAL and camera service
     // key: bufferId sent via HIDL interface
     // value: imported buffer_handle_t
@@ -171,6 +172,7 @@
     std::map<int, CirculatingBuffers> mCirculatingBuffers;
 
     static HandleImporter sHandleImporter;
+    static buffer_handle_t sEmptyBuffer;
 
     bool mInitFail;
     bool mFirstRequest = false;
@@ -301,11 +303,23 @@
     Status initStatus() const;
 
     // Validate and import request's input buffer and acquire fence
-    Status importRequest(
+    virtual Status importRequest(
             const CaptureRequest& request,
             hidl_vec<buffer_handle_t*>& allBufPtrs,
             hidl_vec<int>& allFences);
 
+    Status importRequestImpl(
+            const CaptureRequest& request,
+            hidl_vec<buffer_handle_t*>& allBufPtrs,
+            hidl_vec<int>& allFences,
+            // Optional argument for ICameraDeviceSession@3.5 impl
+            bool allowEmptyBuf = false);
+
+    Status importBuffer(int32_t streamId,
+            uint64_t bufId, buffer_handle_t buf,
+            /*out*/buffer_handle_t** outBufPtr,
+            bool allowEmptyBuf);
+
     static void cleanupInflightFences(
             hidl_vec<int>& allFences, size_t numFences);
 
@@ -332,6 +346,11 @@
     static callbacks_process_capture_result_t sProcessCaptureResult;
     static callbacks_notify_t sNotify;
 
+    // By default camera service uses frameNumber/streamId pair to retrieve the buffer that
+    // was sent to HAL. Override this implementation if HAL is using buffers from buffer management
+    // APIs to send output buffer.
+    virtual uint64_t getCapResultBufferId(const buffer_handle_t& buf, int streamId);
+
     status_t constructCaptureResult(CaptureResult& result,
                                 const camera3_capture_result *hal_result);