Camera: VTS: Wait for release fence before consuming buffers

The camera HAL may signal release fence after processCaptureResult.
If the VTS test waits for the release fence in the context of the
capture result, there is possibility of deadlock.

Rather, we should wait for the releaseFence in a different thread
context to really emulate the real application behavior.

Test: atest VtsAidlHalCameraProvider_TargetTest
Bug: 241281568
Change-Id: Id1d92e901aae1cab084846d252ef090fcda182d7
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index 70ab7a0..be5bcb5 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -2000,6 +2000,8 @@
                     ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
                 }
 
+                waitForReleaseFence(inflightReq->resultOutputBuffers);
+
                 ASSERT_FALSE(inflightReq->errorCodeValid);
                 ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
                 verify10BitMetadata(mHandleImporter, *inflightReq, profile);
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 2c2f1b2..c352d7d 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -34,6 +34,7 @@
 #include <grallocusage/GrallocUsageConversion.h>
 #include <hardware/gralloc1.h>
 #include <simple_device_cb.h>
+#include <ui/Fence.h>
 #include <ui/GraphicBufferAllocator.h>
 #include <regex>
 #include <typeinfo>
@@ -139,6 +140,25 @@
     }
 }
 
+void CameraAidlTest::waitForReleaseFence(
+        std::vector<InFlightRequest::StreamBufferAndTimestamp>& resultOutputBuffers) {
+    for (auto& bufferAndTimestamp : resultOutputBuffers) {
+        // wait for the fence timestamp and store it along with the buffer
+        android::sp<android::Fence> releaseFence = nullptr;
+        const native_handle_t* releaseFenceHandle = bufferAndTimestamp.buffer.releaseFence;
+        if (releaseFenceHandle != nullptr && releaseFenceHandle->numFds == 1 &&
+            releaseFenceHandle->data[0] >= 0) {
+            releaseFence = new android::Fence(releaseFenceHandle->data[0]);
+        }
+        if (releaseFence && releaseFence->isValid()) {
+            releaseFence->wait(/*ms*/ 300);
+            nsecs_t releaseTime = releaseFence->getSignalTime();
+            if (bufferAndTimestamp.timeStamp < releaseTime)
+                bufferAndTimestamp.timeStamp = releaseTime;
+        }
+    }
+}
+
 std::vector<std::string> CameraAidlTest::getCameraDeviceNames(
         std::shared_ptr<ICameraProvider>& provider, bool addSecureOnly) {
     std::vector<std::string> cameraDeviceNames;
@@ -2373,6 +2393,7 @@
                                std::chrono::seconds(kStreamBufferTimeoutSec);
                 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
             }
+            waitForReleaseFence(inflightReq->resultOutputBuffers);
 
             ASSERT_FALSE(inflightReq->errorCodeValid);
             ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index d828cee..9fa84d3 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -488,6 +488,9 @@
             aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap
                     profile);
 
+    static void waitForReleaseFence(
+            std::vector<InFlightRequest::StreamBufferAndTimestamp>& resultOutputBuffers);
+
     // Map from frame number to the in-flight request state
     typedef std::unordered_map<uint32_t, std::shared_ptr<InFlightRequest>> InFlightMap;
 
diff --git a/camera/provider/aidl/vts/device_cb.cpp b/camera/provider/aidl/vts/device_cb.cpp
index 4698b4a..b23c691 100644
--- a/camera/provider/aidl/vts/device_cb.cpp
+++ b/camera/provider/aidl/vts/device_cb.cpp
@@ -19,7 +19,6 @@
 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
 #include <aidlcommonsupport/NativeHandle.h>
 #include <grallocusage/GrallocUsageConversion.h>
-#include <ui/Fence.h>
 #include <cinttypes>
 
 using ::aidl::android::hardware::camera::device::BufferStatus;
@@ -419,13 +418,6 @@
     }
 
     for (const auto& buffer : results.outputBuffers) {
-        // wait for the fence timestamp and store it along with the buffer
-        // TODO: Check if we really need the dup here
-        android::sp<android::Fence> releaseFence = nullptr;
-        if (buffer.releaseFence.fds.size() == 1 && buffer.releaseFence.fds[0].get() >= 0) {
-            releaseFence = new android::Fence(dup(buffer.releaseFence.fds[0].get()));
-        }
-
         CameraAidlTest::InFlightRequest::StreamBufferAndTimestamp streamBufferAndTimestamp;
         auto outstandingBuffers = mUseHalBufManager ? mOutstandingBufferIds :
             request->mOutstandingBufferIds;
@@ -438,12 +430,6 @@
                                            ::android::makeFromAidl(buffer.acquireFence),
                                            ::android::makeFromAidl(buffer.releaseFence)};
         streamBufferAndTimestamp.timeStamp = systemTime();
-        if (releaseFence && releaseFence->isValid()) {
-            releaseFence->wait(/*ms*/ 300);
-            nsecs_t releaseTime = releaseFence->getSignalTime();
-            if (streamBufferAndTimestamp.timeStamp < releaseTime)
-                streamBufferAndTimestamp.timeStamp = releaseTime;
-        }
         request->resultOutputBuffers.push_back(streamBufferAndTimestamp);
     }
     // If shutter event is received notify the pending threads.