Camera3: Add mechanism for Daemon to dynamically fetch requests

Bug: 17396657
Change-Id: I5b483a42a1127191458c5082528ee700f8db1d04
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index 6a37c65..b6e691b 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -403,6 +403,14 @@
                 obj->mCallbackOps->notify(obj->mCallbackOps, &notify_msg);
                 break;
 
+            case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
+                CDBG("%s: HAL got request pull from Daemon", __func__);
+                pthread_mutex_lock(&obj->mMutex);
+                obj->mWokenUpByDaemon = true;
+                obj->unblockRequestIfNecessary();
+                pthread_mutex_unlock(&obj->mMutex);
+                break;
+
             default:
                 CDBG_HIGH("%s: Warning: Unhandled event %d", __func__,
                         evt->server_event_type);
@@ -2029,6 +2037,8 @@
                 return rc;
             }
         }
+        mWokenUpByDaemon = false;
+        mPendingRequest = 0;
     }
 
     uint32_t frameNumber = request->frame_number;
@@ -2227,7 +2237,7 @@
     //Block on conditional variable
 
     mPendingRequest++;
-    while (mPendingRequest >= MAX_INFLIGHT_REQUESTS) {
+    while (mPendingRequest >= MIN_INFLIGHT_REQUESTS) {
         if (!isValidTimeout) {
             CDBG("%s: Blocking on conditional wait", __func__);
             pthread_cond_wait(&mRequestCond, &mMutex);
@@ -2242,6 +2252,11 @@
             }
         }
         CDBG("%s: Unblocked", __func__);
+        if (mWokenUpByDaemon) {
+            mWokenUpByDaemon = false;
+            if (mPendingRequest < MAX_INFLIGHT_REQUESTS)
+                break;
+        }
     }
     pthread_mutex_unlock(&mMutex);
 
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index d639c4e..57c8d1a 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -312,6 +312,7 @@
     PendingBuffersMap mPendingBuffersMap;
     pthread_cond_t mRequestCond;
     int mPendingRequest;
+    bool mWokenUpByDaemon;
     int32_t mCurrentRequestId;
     camera3_capture_result_t *mLoopBackResult;
     nsecs_t mLoopBackTimestamp;
diff --git a/camera/QCamera2/stack/common/cam_types.h b/camera/QCamera2/stack/common/cam_types.h
index aeda46e..9f6bd2c 100644
--- a/camera/QCamera2/stack/common/cam_types.h
+++ b/camera/QCamera2/stack/common/cam_types.h
@@ -116,7 +116,8 @@
 #define GPS_PROCESSING_METHOD_SIZE 33
 #define GPS_PROCESSING_METHOD_SIZE_IN_WORD (33+3)/4
 
-#define MAX_INFLIGHT_REQUESTS  4
+#define MAX_INFLIGHT_REQUESTS  6
+#define MIN_INFLIGHT_REQUESTS  3
 
 typedef enum {
     CAM_HAL_V1 = 1,
@@ -679,6 +680,7 @@
     CAM_EVENT_TYPE_AUTO_FOCUS_DONE = (1<<1),
     CAM_EVENT_TYPE_ZOOM_DONE       = (1<<2),
     CAM_EVENT_TYPE_DAEMON_DIED     = (1<<3),
+    CAM_EVENT_TYPE_DAEMON_PULL_REQ = (1<<4),
     CAM_EVENT_TYPE_MAX
 } cam_event_type_t;
 
diff --git a/camera/QCamera2/stack/mm-camera-interface/src/mm_camera.c b/camera/QCamera2/stack/mm-camera-interface/src/mm_camera.c
index fdde077..5f282ed 100644
--- a/camera/QCamera2/stack/mm-camera-interface/src/mm_camera.c
+++ b/camera/QCamera2/stack/mm-camera-interface/src/mm_camera.c
@@ -160,6 +160,10 @@
         if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
             msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
             switch (msm_evt->command) {
+            case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
+                evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ;
+                mm_camera_enqueue_evt(my_obj, &evt);
+                break;
             case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
                 pthread_mutex_lock(&my_obj->evt_lock);
                 my_obj->evt_rcvd.server_event_type = msm_evt->command;