Merge "camera3: Don't try to disconnect stream native windows more than once" into jb-mr2-dev
diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp
index 49fc3d8..a248b76 100644
--- a/services/camera/libcameraservice/camera2/Parameters.cpp
+++ b/services/camera/libcameraservice/camera2/Parameters.cpp
@@ -795,13 +795,21 @@
     previewCallbackFlags = 0;
     previewCallbackOneShot = false;
 
-    char value[PROPERTY_VALUE_MAX];
-    property_get("camera.disable_zsl_mode", value, "0");
-    if (!strcmp(value,"1")) {
-        ALOGI("Camera %d: Disabling ZSL mode", cameraId);
+    camera_metadata_ro_entry_t supportedHardwareLevel =
+        staticInfo(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
+    if (!supportedHardwareLevel.count || (supportedHardwareLevel.data.u8[0] ==
+            ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)) {
+        ALOGI("Camera %d: ZSL mode disabled for limited mode HALs", cameraId);
         zslMode = false;
     } else {
-        zslMode = true;
+        char value[PROPERTY_VALUE_MAX];
+        property_get("camera.disable_zsl_mode", value, "0");
+        if (!strcmp(value,"1")) {
+            ALOGI("Camera %d: Disabling ZSL mode", cameraId);
+            zslMode = false;
+        } else {
+            zslMode = true;
+        }
     }
 
     lightFx = LIGHTFX_NONE;
diff --git a/services/camera/libcameraservice/camera2/ZslProcessor3.cpp b/services/camera/libcameraservice/camera2/ZslProcessor3.cpp
index af3e266..2e06691 100644
--- a/services/camera/libcameraservice/camera2/ZslProcessor3.cpp
+++ b/services/camera/libcameraservice/camera2/ZslProcessor3.cpp
@@ -413,6 +413,8 @@
                 minTimestamp = frameTimestamp;
                 idx = j;
             }
+
+            ALOGVV("%s: Saw timestamp %lld", __FUNCTION__, frameTimestamp);
         }
     }
 
diff --git a/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp b/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp
index a2c97d4..2efeede 100644
--- a/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp
@@ -166,11 +166,20 @@
     int anwReleaseFence = releaseFence->dup();
 
     /**
+     * Release the lock briefly to avoid deadlock with
+     * StreamingProcessor::startStream -> Camera3Stream::isConfiguring (this
+     * thread will go into StreamingProcessor::onFrameAvailable) during
+     * queueBuffer
+     */
+    sp<ANativeWindow> currentConsumer = mConsumer;
+    mLock.unlock();
+
+    /**
      * Return buffer back to ANativeWindow
      */
     if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
         // Cancel buffer
-        res = mConsumer->cancelBuffer(mConsumer.get(),
+        res = currentConsumer->cancelBuffer(currentConsumer.get(),
                 container_of(buffer.buffer, ANativeWindowBuffer, handle),
                 anwReleaseFence);
         if (res != OK) {
@@ -178,7 +187,7 @@
                   " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
         }
     } else {
-        res = mConsumer->queueBuffer(mConsumer.get(),
+        res = currentConsumer->queueBuffer(currentConsumer.get(),
                 container_of(buffer.buffer, ANativeWindowBuffer, handle),
                 anwReleaseFence);
         if (res != OK) {
@@ -186,7 +195,7 @@
                   "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
         }
     }
-
+    mLock.lock();
     if (res != OK) {
         close(anwReleaseFence);
         return res;
diff --git a/services/camera/libcameraservice/camera3/Camera3OutputStream.h b/services/camera/libcameraservice/camera3/Camera3OutputStream.h
index ce317f9..774fbdd 100644
--- a/services/camera/libcameraservice/camera3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/camera3/Camera3OutputStream.h
@@ -66,6 +66,9 @@
     Camera3OutputStream(int id, camera3_stream_type_t type,
             uint32_t width, uint32_t height, int format);
 
+    /**
+     * Note that we release the lock briefly in this function
+     */
     virtual status_t returnBufferCheckedLocked(
             const camera3_stream_buffer &buffer,
             nsecs_t timestamp,
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
index 2fa78a4..cd39bad 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
@@ -101,12 +101,6 @@
 
     } // end scope of mMutex autolock
 
-    if (pinnedBuffer != 0) {
-        BI_LOGV("Pinned buffer frame %lld, timestamp %lld",
-                pinnedBuffer->getBufferItem().mFrameNumber,
-                pinnedBuffer->getBufferItem().mTimestamp);
-    }
-
     if (waitForFence) {
         status_t err = pinnedBuffer->getBufferItem().mFence->waitForever(
                 "RingBufferConsumer::pinSelectedBuffer");
@@ -172,6 +166,9 @@
     if (it == end) {
         BI_LOGE("Failed to pin buffer (timestamp %lld, framenumber %lld)",
                  item.mTimestamp, item.mFrameNumber);
+    } else {
+        BI_LOGV("Pinned buffer (frame %lld, timestamp %lld)",
+                item.mFrameNumber, item.mTimestamp);
     }
 }
 
@@ -182,7 +179,7 @@
 
     it = mBufferItemList.begin();
     end = mBufferItemList.end();
-    accIt = it;
+    accIt = end;
 
     if (it == end) {
         /**
@@ -197,12 +194,17 @@
 
     for (; it != end; ++it) {
         RingBufferItem& find = *it;
-        if (find.mTimestamp < accIt->mTimestamp && find.mPinCount <= 0) {
-            accIt = it;
+
+        if (find.mPinCount > 0) {
+            if (pinnedFrames != NULL) {
+                ++(*pinnedFrames);
+            }
+            // Filter out pinned frame when searching for buffer to release
+            continue;
         }
 
-        if (find.mPinCount > 0 && pinnedFrames != NULL) {
-            ++(*pinnedFrames);
+        if (find.mTimestamp < accIt->mTimestamp || accIt == end) {
+            accIt = it;
         }
     }
 
@@ -323,7 +325,11 @@
     }
 
     if (it == end) {
-        BI_LOGE("Failed to unpin buffer (timestamp %lld, framenumber %lld",
+        // This should never happen. If it happens, we have a bug.
+        BI_LOGE("Failed to unpin buffer (timestamp %lld, framenumber %lld)",
+                 item.mTimestamp, item.mFrameNumber);
+    } else {
+        BI_LOGV("Unpinned buffer (timestamp %lld, framenumber %lld)",
                  item.mTimestamp, item.mFrameNumber);
     }
 }