Camera3: Add ZSL stream support

Bug: 8563838

Change-Id: I2feda142ff5172aba17ade5c8d502f9bb5d5b766
diff --git a/services/camera/libcameraservice/camera3/Camera3Stream.cpp b/services/camera/libcameraservice/camera3/Camera3Stream.cpp
index bc259b6..f137227 100644
--- a/services/camera/libcameraservice/camera3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/camera3/Camera3Stream.cpp
@@ -178,26 +178,75 @@
 status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
-    return getBufferLocked(buffer);
+
+    status_t res = getBufferLocked(buffer);
+    if (res == OK) {
+        fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
+    }
+
+    return res;
 }
 
 status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
         nsecs_t timestamp) {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
-    return returnBufferLocked(buffer, timestamp);
+
+    status_t res = returnBufferLocked(buffer, timestamp);
+    if (res == OK) {
+        fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true);
+    }
+
+    return res;
 }
 
 status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
-    return getInputBufferLocked(buffer);
+
+    status_t res = getInputBufferLocked(buffer);
+    if (res == OK) {
+        fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
+    }
+
+    return res;
 }
 
 status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
-    return returnInputBufferLocked(buffer);
+
+    status_t res = returnInputBufferLocked(buffer);
+    if (res == OK) {
+        fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
+    }
+    return res;
+}
+
+void Camera3Stream::fireBufferListenersLocked(
+        const camera3_stream_buffer& /*buffer*/, bool acquired, bool output) {
+    List<wp<Camera3StreamBufferListener> >::iterator it, end;
+
+    // TODO: finish implementing
+
+    Camera3StreamBufferListener::BufferInfo info =
+        Camera3StreamBufferListener::BufferInfo();
+    info.mOutput = output;
+    // TODO: rest of fields
+
+    for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
+         it != end;
+         ++it) {
+
+        sp<Camera3StreamBufferListener> listener = it->promote();
+        if (listener != 0) {
+            if (acquired) {
+                listener->onBufferAcquired(info);
+            } else {
+                listener->onBufferReleased(info);
+            }
+        }
+    }
 }
 
 bool Camera3Stream::hasOutstandingBuffers() const {
@@ -290,6 +339,36 @@
     return INVALID_OPERATION;
 }
 
+void Camera3Stream::addBufferListener(
+        wp<Camera3StreamBufferListener> listener) {
+    Mutex::Autolock l(mLock);
+    mBufferListenerList.push_back(listener);
+}
+
+void Camera3Stream::removeBufferListener(
+        const sp<Camera3StreamBufferListener>& listener) {
+    Mutex::Autolock l(mLock);
+
+    bool erased = true;
+    List<wp<Camera3StreamBufferListener> >::iterator it, end;
+    for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
+         it != end;
+         ) {
+
+        if (*it == listener) {
+            it = mBufferListenerList.erase(it);
+            erased = true;
+        } else {
+            ++it;
+        }
+    }
+
+    if (!erased) {
+        ALOGW("%s: Could not find listener to remove, already removed",
+              __FUNCTION__);
+    }
+}
+
 }; // namespace camera3
 
 }; // namespace android