QCamera2: HAL3: Support AF_STATE in both partial result and final result

Currently AF_STATE during AF_TRIGGER is sent 3 frames early
(apply_delay 2, and report_delay 1). Without AF_TRIGGER, the AF_STATE
is reported at the right time: after AF stats for the current readout
frame are analyzed.

In the case where AF_TRIGGER results in a state transition, send the new
state in partial result, and use last know AF state for all preceding
results. This shift applies to both TRIGGER_START and TRIGGER_CANCEL.

Also move af_mode back to partial result.

Test: Camera CTS, and AF_STATE during HDR+ burst.
Bug: 63766738
Change-Id: I968ca06d6909996a0b77d3b247ed0722ab92bb6a
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index 3d17918..5040bac 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -385,7 +385,8 @@
       mIsMainCamera(true),
       mLinkedCameraId(0),
       m_pRelCamSyncHeap(NULL),
-      m_pRelCamSyncBuf(NULL)
+      m_pRelCamSyncBuf(NULL),
+      mAfTrigger()
 {
     getLogLevel();
     m_perfLock.lock_init();
@@ -2966,6 +2967,7 @@
 
     return;
 }
+
 /*===========================================================================
  * FUNCTION   : handleMetadataWithLock
  *
@@ -3101,7 +3103,7 @@
                 i->bUrgentReceived = 1;
                 // Extract 3A metadata
                 result.result = translateCbUrgentMetadataToResultMetadata(
-                        metadata, lastUrgentMetadataInBatch);
+                        metadata, lastUrgentMetadataInBatch, urgent_frame_number);
                 // Populate metadata result
                 result.frame_number = urgent_frame_number;
                 result.num_output_buffers = 0;
@@ -3232,13 +3234,7 @@
 
             // atrace_begin(ATRACE_TAG_ALWAYS, "translateFromHalMetadata");
             result.result = translateFromHalMetadata(metadata,
-                    i->timestamp, i->request_id, i->jpegMetadata, i->pipeline_depth,
-                    i->capture_intent, i->hybrid_ae_enable,
-                     /* DevCamDebug metadata translateFromHalMetadata function call*/
-                    i->DevCamDebug_meta_enable,
-                    /* DevCamDebug metadata end */
-                    internalPproc, i->fwkCacMode,
-                    lastMetadataInBatch);
+                    *i, internalPproc, lastMetadataInBatch);
             // atrace_end(ATRACE_TAG_ALWAYS);
 
             saveExifParams(metadata);
@@ -5068,13 +5064,7 @@
  *
  * PARAMETERS :
  *   @metadata : metadata information from callback
- *   @timestamp: metadata buffer timestamp
- *   @request_id: request id
- *   @jpegMetadata: additional jpeg metadata
- *   @hybrid_ae_enable: whether hybrid ae is enabled
- *   // DevCamDebug metadata
- *   @DevCamDebug_meta_enable: enable DevCamDebug meta
- *   // DevCamDebug metadata end
+ *   @pendingRequest: pending request for this metadata
  *   @pprocDone: whether internal offline postprocsesing is done
  *   @lastMetadataInBatch: Boolean to indicate whether this is the last metadata
  *                         in a batch. Always true for non-batch mode.
@@ -5085,17 +5075,8 @@
 camera_metadata_t*
 QCamera3HardwareInterface::translateFromHalMetadata(
                                  metadata_buffer_t *metadata,
-                                 nsecs_t timestamp,
-                                 int32_t request_id,
-                                 const CameraMetadata& jpegMetadata,
-                                 uint8_t pipeline_depth,
-                                 uint8_t capture_intent,
-                                 uint8_t hybrid_ae_enable,
-                                 /* DevCamDebug metadata translateFromHalMetadata argument */
-                                 uint8_t DevCamDebug_meta_enable,
-                                 /* DevCamDebug metadata end */
+                                 const PendingRequestInfo& pendingRequest,
                                  bool pprocDone,
-                                 uint8_t fwk_cacMode,
                                  bool lastMetadataInBatch)
 {
     CameraMetadata camMetadata;
@@ -5107,22 +5088,22 @@
         return resultMetadata;
     }
 
-    if (jpegMetadata.entryCount())
-        camMetadata.append(jpegMetadata);
+    if (pendingRequest.jpegMetadata.entryCount())
+        camMetadata.append(pendingRequest.jpegMetadata);
 
-    camMetadata.update(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
-    camMetadata.update(ANDROID_REQUEST_ID, &request_id, 1);
-    camMetadata.update(ANDROID_REQUEST_PIPELINE_DEPTH, &pipeline_depth, 1);
-    camMetadata.update(ANDROID_CONTROL_CAPTURE_INTENT, &capture_intent, 1);
-    camMetadata.update(NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE, &hybrid_ae_enable, 1);
+    camMetadata.update(ANDROID_SENSOR_TIMESTAMP, &pendingRequest.timestamp, 1);
+    camMetadata.update(ANDROID_REQUEST_ID, &pendingRequest.request_id, 1);
+    camMetadata.update(ANDROID_REQUEST_PIPELINE_DEPTH, &pendingRequest.pipeline_depth, 1);
+    camMetadata.update(ANDROID_CONTROL_CAPTURE_INTENT, &pendingRequest.capture_intent, 1);
+    camMetadata.update(NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE, &pendingRequest.hybrid_ae_enable, 1);
     if (mBatchSize == 0) {
         // DevCamDebug metadata translateFromHalMetadata. Only update this one for non-HFR mode
-        camMetadata.update(DEVCAMDEBUG_META_ENABLE, &DevCamDebug_meta_enable, 1);
+        camMetadata.update(DEVCAMDEBUG_META_ENABLE, &pendingRequest.DevCamDebug_meta_enable, 1);
     }
 
     // atrace_begin(ATRACE_TAG_ALWAYS, "DevCamDebugInfo");
     // Only update DevCameraDebug metadta conditionally: non-HFR mode and it is enabled.
-    if (mBatchSize == 0 && DevCamDebug_meta_enable != 0) {
+    if (mBatchSize == 0 && pendingRequest.DevCamDebug_meta_enable != 0) {
         // DevCamDebug metadata translateFromHalMetadata AF
         IF_META_AVAILABLE(int32_t, DevCamDebug_af_lens_position,
                 CAM_INTF_META_DEV_CAM_AF_LENS_POSITION, metadata) {
@@ -5930,24 +5911,19 @@
                 hAeRegions->rect.height);
     }
 
-    IF_META_AVAILABLE(uint32_t, focusMode, CAM_INTF_PARM_FOCUS_MODE, metadata) {
-        int val = lookupFwkName(FOCUS_MODES_MAP, METADATA_MAP_SIZE(FOCUS_MODES_MAP), *focusMode);
-        if (NAME_NOT_FOUND != val) {
-            uint8_t fwkAfMode = (uint8_t)val;
-            camMetadata.update(ANDROID_CONTROL_AF_MODE, &fwkAfMode, 1);
-            LOGD("Metadata : ANDROID_CONTROL_AF_MODE %d", val);
+    if (!pendingRequest.focusStateSent) {
+        if (pendingRequest.focusStateValid) {
+            camMetadata.update(ANDROID_CONTROL_AF_STATE, &pendingRequest.focusState, 1);
+            LOGD("Metadata : ANDROID_CONTROL_AF_STATE %u", pendingRequest.focusState);
         } else {
-            LOGH("Metadata not found : ANDROID_CONTROL_AF_MODE %d",
-                    val);
+            IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, metadata) {
+                uint8_t fwk_afState = (uint8_t) *afState;
+                camMetadata.update(ANDROID_CONTROL_AF_STATE, &fwk_afState, 1);
+                LOGD("Metadata : ANDROID_CONTROL_AF_STATE %u", *afState);
+            }
         }
     }
 
-    IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, metadata) {
-        uint8_t fwk_afState = (uint8_t) *afState;
-        camMetadata.update(ANDROID_CONTROL_AF_STATE, &fwk_afState, 1);
-        LOGD("Metadata : ANDROID_CONTROL_AF_STATE %u", *afState);
-    }
-
     IF_META_AVAILABLE(float, focusDistance, CAM_INTF_META_LENS_FOCUS_DISTANCE, metadata) {
         camMetadata.update(ANDROID_LENS_FOCUS_DISTANCE , focusDistance, 1);
     }
@@ -6115,10 +6091,10 @@
                 uint8_t resultCacMode = (uint8_t)val;
                 // check whether CAC result from CB is equal to Framework set CAC mode
                 // If not equal then set the CAC mode came in corresponding request
-                if (fwk_cacMode != resultCacMode) {
-                    resultCacMode = fwk_cacMode;
+                if (pendingRequest.fwkCacMode != resultCacMode) {
+                    resultCacMode = pendingRequest.fwkCacMode;
                 }
-                LOGD("fwk_cacMode=%d resultCacMode=%d", fwk_cacMode, resultCacMode);
+                LOGD("fwk_cacMode=%d resultCacMode=%d", pendingRequest.fwkCacMode, resultCacMode);
                 camMetadata.update(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &resultCacMode, 1);
             } else {
                 LOGE("Invalid CAC camera parameter: %d", *cacMode);
@@ -6273,13 +6249,15 @@
  *   @lastUrgentMetadataInBatch: Boolean to indicate whether this is the last
  *                               urgent metadata in a batch. Always true for
  *                               non-batch mode.
+ *   @frame_number :             frame number for this urgent metadata
  *
  * RETURN     : camera_metadata_t*
  *              metadata in a format specified by fwk
  *==========================================================================*/
 camera_metadata_t*
 QCamera3HardwareInterface::translateCbUrgentMetadataToResultMetadata
-                                (metadata_buffer_t *metadata, bool lastUrgentMetadataInBatch)
+                                (metadata_buffer_t *metadata, bool lastUrgentMetadataInBatch,
+                                 uint32_t frame_number)
 {
     CameraMetadata camMetadata;
     camera_metadata_t *resultMetadata;
@@ -6314,16 +6292,53 @@
         LOGD("urgent Metadata : ANDROID_CONTROL_AE_STATE %u", *ae_state);
     }
 
-    IF_META_AVAILABLE(cam_trigger_t, af_trigger, CAM_INTF_META_AF_TRIGGER, metadata) {
-        camMetadata.update(ANDROID_CONTROL_AF_TRIGGER,
-                &af_trigger->trigger, 1);
-        LOGD("urgent Metadata : CAM_INTF_META_AF_TRIGGER = %d",
-                 af_trigger->trigger);
-        camMetadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &af_trigger->trigger_id, 1);
-        LOGD("urgent Metadata : ANDROID_CONTROL_AF_TRIGGER_ID = %d",
-                af_trigger->trigger_id);
+    IF_META_AVAILABLE(uint32_t, focusMode, CAM_INTF_PARM_FOCUS_MODE, metadata) {
+        int val = lookupFwkName(FOCUS_MODES_MAP, METADATA_MAP_SIZE(FOCUS_MODES_MAP), *focusMode);
+        if (NAME_NOT_FOUND != val) {
+            uint8_t fwkAfMode = (uint8_t)val;
+            camMetadata.update(ANDROID_CONTROL_AF_MODE, &fwkAfMode, 1);
+            LOGD("urgent Metadata : ANDROID_CONTROL_AF_MODE %d", val);
+        } else {
+            LOGH("urgent Metadata not found : ANDROID_CONTROL_AF_MODE %d",
+                    val);
+        }
     }
 
+    IF_META_AVAILABLE(cam_trigger_t, af_trigger, CAM_INTF_META_AF_TRIGGER, metadata) {
+        LOGD("urgent Metadata : CAM_INTF_META_AF_TRIGGER = %d",
+            af_trigger->trigger);
+        LOGD("urgent Metadata : ANDROID_CONTROL_AF_TRIGGER_ID = %d",
+            af_trigger->trigger_id);
+
+        IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, metadata) {
+            mAfTrigger = *af_trigger;
+            uint32_t fwk_AfState = (uint32_t) *afState;
+
+            // If this is the result for a new trigger, check if there is new early
+            // af state. If there is, use the last af state for all results
+            // preceding current partial frame number.
+            for (auto & pendingRequest : mPendingRequestsList) {
+                if (pendingRequest.frame_number < frame_number) {
+                    pendingRequest.focusStateValid = true;
+                    pendingRequest.focusState = fwk_AfState;
+                } else if (pendingRequest.frame_number == frame_number) {
+                    IF_META_AVAILABLE(uint32_t, earlyAfState, CAM_INTF_META_EARLY_AF_STATE, metadata) {
+                        // Check if early AF state for trigger exists. If yes, send AF state as
+                        // partial result for better latency.
+                        uint8_t fwkEarlyAfState = (uint8_t) *earlyAfState;
+                        pendingRequest.focusStateSent = true;
+                        camMetadata.update(ANDROID_CONTROL_AF_STATE, &fwkEarlyAfState, 1);
+                        LOGD("urgent Metadata(%d) : ANDROID_CONTROL_AF_STATE %u",
+                                 frame_number, fwkEarlyAfState);
+                    }
+                }
+            }
+        }
+    }
+    camMetadata.update(ANDROID_CONTROL_AF_TRIGGER,
+        &mAfTrigger.trigger, 1);
+    camMetadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &mAfTrigger.trigger_id, 1);
+
     IF_META_AVAILABLE(int32_t, whiteBalance, CAM_INTF_PARM_WHITE_BALANCE, metadata) {
         int val = lookupFwkName(WHITE_BALANCE_MODES_MAP,
                 METADATA_MAP_SIZE(WHITE_BALANCE_MODES_MAP), *whiteBalance);
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index 35ba96e..47735d8 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -191,16 +191,9 @@
     int translateToHalMetadata(const camera3_capture_request_t *request,
             metadata_buffer_t *parm, uint32_t snapshotStreamId);
     camera_metadata_t* translateCbUrgentMetadataToResultMetadata (
-                             metadata_buffer_t *metadata, bool lastUrgentMetadataInBatch);
-    camera_metadata_t* translateFromHalMetadata(metadata_buffer_t *metadata,
-                            nsecs_t timestamp, int32_t request_id,
-                            const CameraMetadata& jpegMetadata, uint8_t pipeline_depth,
-                            uint8_t capture_intent, uint8_t hybrid_ae_enable,
-                            /* DevCamDebug metadata translateFromHalMetadata augment .h */
-                            uint8_t DevCamDebug_meta_enable,
-                            /* DevCamDebug metadata end */
-                            bool pprocDone, uint8_t fwk_cacMode,
-                            bool lastMetadataInBatch);
+            metadata_buffer_t *metadata, bool lastUrgentMetadataInBatch,
+            uint32_t frame_number);
+
     camera_metadata_t* saveRequestSettings(const CameraMetadata& jpegMetadata,
                             camera3_capture_request_t *request);
     int initParameters();
@@ -434,6 +427,10 @@
         /* DevCamDebug metadata PendingRequestInfo */
         uint8_t DevCamDebug_meta_enable;
         /* DevCamDebug metadata end */
+
+        bool focusStateSent;
+        bool focusStateValid;
+        uint8_t focusState;
     } PendingRequestInfo;
     typedef struct {
         uint32_t frame_number;
@@ -552,6 +549,11 @@
     int (*LINK_get_surface_pixel_alignment)();
     uint32_t mSurfaceStridePadding;
 
+    camera_metadata_t* translateFromHalMetadata(metadata_buffer_t *metadata,
+                            const PendingRequestInfo& pendingRequest,
+                            bool pprocDone,
+                            bool lastMetadataInBatch);
+
     State mState;
     //Dual camera related params
     bool mIsDeviceLinked;
@@ -562,6 +564,7 @@
     cam_sync_related_sensors_event_info_t m_relCamSyncInfo;
     bool m60HzZone;
 
+    cam_trigger_t mAfTrigger;
 };
 
 }; // namespace qcamera
diff --git a/camera/QCamera2/stack/common/cam_intf.h b/camera/QCamera2/stack/common/cam_intf.h
index 700c5de..b99ff62 100644
--- a/camera/QCamera2/stack/common/cam_intf.h
+++ b/camera/QCamera2/stack/common/cam_intf.h
@@ -1009,6 +1009,8 @@
     INCLUDE(CAM_INTF_META_DEV_CAM_AWB_DECISION,         int32_t,                     1);
     /* DevCamDebug metadata end */
     INCLUDE(CAM_INTF_META_ISP_POST_STATS_SENSITIVITY,   float,                       1);
+    INCLUDE(CAM_INTF_META_EARLY_AF_STATE,               uint32_t,                    1);
+
 } metadata_data_t;
 
 /* Update clear_metadata_buffer() function when a new is_xxx_valid is added to
diff --git a/camera/QCamera2/stack/common/cam_types.h b/camera/QCamera2/stack/common/cam_types.h
index 5e928c1..91b7352 100644
--- a/camera/QCamera2/stack/common/cam_types.h
+++ b/camera/QCamera2/stack/common/cam_types.h
@@ -2225,6 +2225,8 @@
     CAM_INTF_META_AF_SCENE_CHANGE,
     /* Gain applied post stats collection in ISP */
     CAM_INTF_META_ISP_POST_STATS_SENSITIVITY,
+    /* Early AF state due to trigger */
+    CAM_INTF_META_EARLY_AF_STATE,
     CAM_INTF_PARM_MAX
 } cam_intf_parm_type_t;