Merge "Camera3: don't let dequeueBuffer block indefinitely"
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 5a20c21..843b182 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -3052,7 +3052,7 @@
         mFlushLock.lock();
     }
 
-    ALOGVV("%s: %d: submitting %d requests in a batch.", __FUNCTION__, __LINE__,
+    ALOGVV("%s: %d: submitting %zu requests in a batch.", __FUNCTION__, __LINE__,
             mNextRequests.size());
     for (auto& nextRequest : mNextRequests) {
         // Submit request and block until ready for next one
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index d09951a..dff5a49 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -435,6 +435,12 @@
                 __FUNCTION__, mTransform, strerror(-res), res);
     }
 
+    // Set dequeueBuffer/attachBuffer timeout if the consumer is not hw composer or hw texture.
+    // We need skip these cases as timeout will disable the non-blocking (async) mode.
+    if (!(isConsumedByHWComposer() || isConsumedByHWTexture())) {
+        mConsumer->setDequeueTimeout(kDequeueBufferTimeout);
+    }
+
     /**
      * Camera3 Buffer manager is only supported by HAL3.3 onwards, as the older HALs requires
      * buffers to be statically allocated for internal static buffer registration, while the
@@ -633,6 +639,17 @@
     return (usage & GRALLOC_USAGE_HW_COMPOSER) != 0;
 }
 
+bool Camera3OutputStream::isConsumedByHWTexture() const {
+    uint32_t usage = 0;
+    status_t res = getEndpointUsage(&usage);
+    if (res != OK) {
+        ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
+        return false;
+    }
+
+    return (usage & GRALLOC_USAGE_HW_TEXTURE) != 0;
+}
+
 }; // namespace camera3
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 7d28b05..7f7d6d2 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -117,6 +117,11 @@
      */
     bool isConsumedByHWComposer() const;
 
+    /**
+     * Return if this output stream is consumed by hardware texture.
+     */
+    bool isConsumedByHWTexture() const;
+
     class BufferReleasedListener : public BnProducerListener {
         public:
           BufferReleasedListener(wp<Camera3OutputStream> parent) : mParent(parent) {}
@@ -160,6 +165,9 @@
 
     sp<Surface> mConsumer;
   private:
+
+    static const nsecs_t       kDequeueBufferTimeout   = 1000000000; // 1 sec
+
     int               mTransform;
 
     virtual status_t  setTransformLocked(int transform);