Camera: Mark streams unpreparable when using HAL buffer management
With CameraHal buffer management enabled there is a window of
opportunity where camera clients will be able to prepare streams
that already have submitted capture requests. Depending on timing
if the client is able to trigger prepare immediately after
submitting a capture request, then CameraHal might not be able to
request a buffer quickly enough and the prepare operation will
succeed which contradicts the public API guarantees.
To avoid this, mark the requested stream as unpreparable before
sending the request over to CameraHal.
Bug: 162884320
Test: Camera CTS
Change-Id: If9678fe440a5fbf12a6b2e424b9e63dd40d91fa8
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 8754ad3..1b36b93 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -4686,6 +4686,10 @@
buffer.status = CAMERA3_BUFFER_STATUS_OK;
buffer.acquire_fence = -1;
buffer.release_fence = -1;
+ // Mark the output stream as unpreparable to block clients from calling
+ // 'prepare' after this request reaches CameraHal and before the respective
+ // buffers are requested.
+ outputStream->markUnpreparable();
} else {
res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
waitDuration,
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 9a8f6fe..13c6a17 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -418,6 +418,13 @@
return mStreamUnpreparable;
}
+void Camera3Stream::markUnpreparable() {
+ ATRACE_CALL();
+
+ Mutex::Autolock l(mLock);
+ mStreamUnpreparable = true;
+}
+
status_t Camera3Stream::startPrepare(int maxCount, bool blockRequest) {
ATRACE_CALL();
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 3654f89..f36d2f0 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -227,6 +227,11 @@
bool isUnpreparable();
/**
+ * Mark the stream as unpreparable.
+ */
+ void markUnpreparable() override;
+
+ /**
* Start stream preparation. May only be called in the CONFIGURED state,
* when no valid buffers have yet been returned to this stream. Prepares
* up to maxCount buffers, or the maximum number of buffers needed by the
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index a053262..f6eb4bd 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -165,6 +165,11 @@
virtual bool isUnpreparable() = 0;
/**
+ * Mark the stream as unpreparable.
+ */
+ virtual void markUnpreparable() = 0;
+
+ /**
* Start stream preparation. May only be called in the CONFIGURED state,
* when no valid buffers have yet been returned to this stream. Prepares
* up to maxCount buffers, or the maximum number of buffers needed by the