Camera2: Skeleton for output frame processing, plus face detect

- Plumbing for processing output metadata frames from the HAL
- Support for passing face detection metadata from said frames
  to the application.
- Switch calls on ICameraClient interface to use separate mutex to
  avoid deadlock scenarios with messages being communicated from the
  HAL to the camera user while calls from the user to the service are
  active.

Bug: 6243944

Change-Id: Id4cf821d9c5c3c0069be4c0f669874b6ff0d1ecd
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index 7c97e1e..bbdee39 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -340,6 +340,14 @@
     }
 }
 
+status_t Camera2Device::setFrameListener(FrameListener *listener) {
+    return mFrameQueue.setListener(listener);
+}
+
+status_t Camera2Device::getNextFrame(camera_metadata_t **frame) {
+    return mFrameQueue.dequeue(frame);
+}
+
 status_t Camera2Device::triggerAutofocus(uint32_t id) {
     status_t res;
     ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
@@ -384,6 +392,13 @@
 }
 
 /**
+ * Camera2Device::FrameListener
+ */
+
+Camera2Device::FrameListener::~FrameListener() {
+}
+
+/**
  * Camera2Device::MetadataQueue
  */
 
@@ -392,7 +407,8 @@
             mFrameCount(0),
             mCount(0),
             mStreamSlotCount(0),
-            mSignalConsumer(true)
+            mSignalConsumer(true),
+            mListener(NULL)
 {
     camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
     camera2_request_queue_src_ops::request_count = consumer_buffer_count;
@@ -510,6 +526,12 @@
     return OK;
 }
 
+status_t Camera2Device::MetadataQueue::setListener(FrameListener *listener) {
+    Mutex::Autolock l(mMutex);
+    mListener = listener;
+    return OK;
+}
+
 status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
 {
     ALOGV("%s: E", __FUNCTION__);
@@ -622,6 +644,13 @@
         res = mDevice->ops->notify_request_queue_not_empty(mDevice);
         mMutex.lock();
     }
+    if (mListener != NULL) {
+        FrameListener *listener = mListener;
+        mMutex.unlock();
+        ALOGVV("%s: Signaling listener", __FUNCTION__);
+        listener->onNewFrameAvailable();
+        mMutex.lock();
+    }
     return res;
 }