camera: fix the problem flash does not work in ZSL mode

Change-Id: Ic7bdd7797eb4446bc231f2b3fc2774dc013a4077
diff --git a/camera/QCamera/stack/mm-camera-interface/src/mm_camera.c b/camera/QCamera/stack/mm-camera-interface/src/mm_camera.c
index 826b5dd..2bfacfb 100755
--- a/camera/QCamera/stack/mm-camera-interface/src/mm_camera.c
+++ b/camera/QCamera/stack/mm-camera-interface/src/mm_camera.c
@@ -649,7 +649,7 @@
                                             sizeof(focus_distances_info_t),
                                             p_value);
         break;
-    case MM_CAMERA_PARM_QUERY_FALSH4SNAP:
+    case MM_CAMERA_PARM_QUERY_FLASH4SNAP:
         rc = mm_camera_send_native_ctrl_cmd(my_obj,
                                             CAMERA_QUERY_FLASH_FOR_SNAPSHOT,
                                             sizeof(int),
diff --git a/camera/QCameraHWI.cpp b/camera/QCameraHWI.cpp
index 7891bb7..1fc06a8 100644
--- a/camera/QCameraHWI.cpp
+++ b/camera/QCameraHWI.cpp
@@ -874,6 +874,10 @@
         case MM_CAMERA_INFO_EVT_ROI:
             roiEvent(event->e.roi, app_cb);
             break;
+        case MM_CAMERA_INFO_FLASH_FRAME_IDX:
+            zslFlashEvent(event->e.zsl_flash_info, app_cb);
+            break;
+
         default:
             break;
     }
@@ -881,6 +885,24 @@
     return;
 }
 
+void QCameraHardwareInterface::zslFlashEvent(struct zsl_flash_t evt, app_notify_cb_t *) {
+    ALOGE("%s: E", __func__);
+    ALOGE("flashEvent: numFrames = %d, frameId[0] = %d", evt.valid_entires, evt.frame_idx[0]);
+
+    int32_t value = 0;
+    if (native_set_parms(MM_CAMERA_PARM_AEC_LOCK,
+            sizeof(int32_t), (void *)(&value)) == false) {
+        ALOGE("error: can not unlock AEC");
+    }
+
+    status_t ret = mStreamSnap->takePictureZSL();
+    if (ret != MM_CAMERA_OK) {
+        ALOGE("%s: Error taking ZSL snapshot!", __func__);
+    }
+    ALOGE("%s: X", __func__);
+}
+
+
 void  QCameraHardwareInterface::processEvent(mm_camera_event_t *event)
 {
     app_notify_cb_t app_cb;
@@ -1603,11 +1625,38 @@
         mStreamSnap->setFullSizeLiveshot(false);
         if (isZSLMode()) {
             if (mStreamSnap != NULL) {
-                pausePreviewForZSL();
-                ret = mStreamSnap->takePictureZSL();
-                if (ret != MM_CAMERA_OK) {
-                    ALOGE("%s: Error taking ZSL snapshot!", __func__);
-                    ret = BAD_VALUE;
+                // Query if flash is required based on lighting condition
+                int32_t flash_expected = 0;
+                if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
+                          MM_CAMERA_PARM_QUERY_FLASH4SNAP, &flash_expected)){
+                    ALOGE("%s: error: can not get flash_expected value",
+                            __func__);
+                    return BAD_VALUE;
+                }
+                ALOGE("flash_expected = %d, mode = %d",
+                        flash_expected, getFlashMode());
+                if(getFlashMode() != LED_MODE_OFF && flash_expected) {
+                    // Flash is used
+                    takePicturePrepareHardware();
+
+                    pausePreviewForZSL();
+
+                    //start flash LED
+                    uint32_t value = 1;
+                    if(native_set_parms(MM_CAMERA_PARM_ZSL_FLASH, sizeof(value),
+                                           (void *)&value) == false) {
+                        ALOGE("%s: error: cannot set ZSL flash", __func__);
+                        return BAD_VALUE;
+                    }
+                    // takepictureZSL() will be called when the event for
+                    // zslflash is received
+                } else {
+                    //Flash is not used
+                    pausePreviewForZSL();
+                    if (MM_CAMERA_OK != mStreamSnap->takePictureZSL()) {
+                        ALOGE("%s: Error taking ZSL snapshot!", __func__);
+                        ret = BAD_VALUE;
+                    }
                 }
             }
             else {
diff --git a/camera/QCameraHWI.h b/camera/QCameraHWI.h
index 221eb8c..7288780 100644
--- a/camera/QCameraHWI.h
+++ b/camera/QCameraHWI.h
@@ -528,6 +528,7 @@
     void processInfoEvent(mm_camera_info_event_t *event, app_notify_cb_t *);
     void processprepareSnapshotEvent(cam_ctrl_status_t *);
     void roiEvent(fd_roi_t roi, app_notify_cb_t *);
+    void zslFlashEvent(struct zsl_flash_t evt, app_notify_cb_t *);
     void zoomEvent(cam_ctrl_status_t *status, app_notify_cb_t *);
     void autofocusevent(cam_ctrl_status_t *status, app_notify_cb_t *);
     void handleZoomEventForPreview(app_notify_cb_t *);
@@ -571,6 +572,7 @@
     status_t setJpegRotation(int isZSL);
     int getJpegRotation(void);
     int getISOSpeedValue();
+    int getFlashMode();
     status_t setAntibanding(const QCameraParameters& params);
     status_t setEffect(const QCameraParameters& params);
     status_t setExposureCompensation(const QCameraParameters &params);
diff --git a/camera/QCameraHWI_Parm.cpp b/camera/QCameraHWI_Parm.cpp
index 097b60c..aef8d17 100644
--- a/camera/QCameraHWI_Parm.cpp
+++ b/camera/QCameraHWI_Parm.cpp
@@ -2798,6 +2798,17 @@
     return NO_ERROR;
 }
 
+int QCameraHardwareInterface::getFlashMode() {
+    const char *str = mParameters.get(CameraParameters::KEY_FLASH_MODE);
+    if (str != NULL) {
+        int32_t value = attr_lookup(flash, sizeof(flash) / sizeof(str_map), str);
+        return value;
+    } else {
+        ALOGE("%s: Error: Flash parameter not-set (unexpected)", __func__);
+        return -1;
+    }
+}
+
 status_t QCameraHardwareInterface::setFlash(const QCameraParameters& params)
 {
     ALOGV("%s: E",__func__);
diff --git a/camera/QCameraHWI_Still.cpp b/camera/QCameraHWI_Still.cpp
index 9480416..e1aa098 100644
--- a/camera/QCameraHWI_Still.cpp
+++ b/camera/QCameraHWI_Still.cpp
@@ -2240,7 +2240,6 @@
     }
 
     if (isZSLMode()) {
-        prepareHardware();
         ret = initZSLSnapshot();
         if(ret != NO_ERROR) {
             ALOGE("%s : Error while Initializing ZSL snapshot",__func__);
diff --git a/camera/QCamera_Intf.h b/camera/QCamera_Intf.h
index da51bce..e113df5 100644
--- a/camera/QCamera_Intf.h
+++ b/camera/QCamera_Intf.h
@@ -44,7 +44,7 @@
 #define CEILING4(X)  (((X) + 0x0003) & 0xFFFC)
 #define CEILING2(X)  (((X) + 0x0001) & 0xFFFE)
 
-#define MAX_ROI 2
+#define MAX_ROI 4
 #define MAX_NUM_PARM 5
 #define MAX_NUM_OPS 2
 #define VIDEO_MAX_PLANES 8
@@ -349,7 +349,7 @@
     MM_CAMERA_PARM_CAMERA_ID,
     MM_CAMERA_PARM_CAMERA_INFO,
     MM_CAMERA_PARM_PREVIEW_SIZE, /*35*/
-    MM_CAMERA_PARM_QUERY_FALSH4SNAP,
+    MM_CAMERA_PARM_QUERY_FLASH4SNAP,
     MM_CAMERA_PARM_FOCUS_DISTANCES,
     MM_CAMERA_PARM_BUFFER_INFO,
     MM_CAMERA_PARM_JPEG_ROTATION,
@@ -422,6 +422,7 @@
     MM_CAMERA_PARM_RAW_SNAPSHOT_FMT,
     MM_CAMERA_PARM_FACIAL_FEATURE_INFO,
     MM_CAMERA_PARM_CAF_LOCK_CANCEL,
+    MM_CAMERA_PARM_ZSL_FLASH,
     MM_CAMERA_PARM_MAX
 } mm_camera_parm_type_t;
 
@@ -559,6 +560,7 @@
   CAMERA_SET_3A_CONVERGENCE,
   CAMERA_SET_PREVIEW_HFR, /*120*/
   CAMERA_GET_MAX_DIMENSION,
+  CAMERA_SET_ZSL_FLASH,
   CAMERA_GET_MAX_NUM_FACES_DECT,
   CAMERA_SET_CHANNEL_STREAM,
   CAMERA_GET_CHANNEL_STREAM,
@@ -932,11 +934,17 @@
   } d;
 };
 
+struct zsl_flash_t {
+    uint32_t frame_idx[5];
+    uint8_t valid_entires;
+};
+
 typedef struct  {
   uint32_t event_id;
   union {
     mm_camera_histo_mem_info_t histo_mem_info;
     struct fd_roi_t roi;
+    struct zsl_flash_t zsl_flash_info;
   } e;
 } mm_camera_info_event_t;
 
diff --git a/camera/mm-camera-interface/mm_camera.c b/camera/mm-camera-interface/mm_camera.c
index 9caa0c0..4de1f47 100644
--- a/camera/mm-camera-interface/mm_camera.c
+++ b/camera/mm-camera-interface/mm_camera.c
@@ -362,6 +362,10 @@
         mm_jpeg_encoder_setRotation(*((int *)parm->p_value),isZSL);
         return MM_CAMERA_OK;
 
+    case MM_CAMERA_PARM_ZSL_FLASH:
+      return mm_camera_send_native_ctrl_cmd(my_obj,
+                  CAMERA_SET_ZSL_FLASH, sizeof(uint32_t), (void *)parm->p_value);
+
     case MM_CAMERA_PARM_ASD_ENABLE:
       return mm_camera_send_native_ctrl_cmd(my_obj,
                   CAMERA_SET_ASD_ENABLE, sizeof(uint32_t), (void *)parm->p_value);
@@ -590,7 +594,7 @@
     case MM_CAMERA_PARM_FOCUS_DISTANCES:
         return mm_camera_send_native_ctrl_cmd(my_obj,   CAMERA_GET_PARM_FOCUS_DISTANCES,
                      sizeof(focus_distances_info_t), (void *)parm->p_value);
-  case MM_CAMERA_PARM_QUERY_FALSH4SNAP:
+  case MM_CAMERA_PARM_QUERY_FLASH4SNAP:
         return mm_camera_send_native_ctrl_cmd(my_obj,   CAMERA_QUERY_FLASH_FOR_SNAPSHOT,
                      sizeof(int), (void *)parm->p_value);
   case MM_CAMERA_PARM_3D_FRAME_FORMAT:
@@ -833,6 +837,11 @@
             rc = mm_camera_ch_fn(my_obj, ch_type,
                     MM_CAMERA_STATE_EVT_STREAM_ON, NULL);
             break;
+        case MM_CAMERA_OPS_PREPARE_SNAPSHOT:
+            rc = mm_camera_send_native_ctrl_timeout_cmd(my_obj,CAMERA_PREPARE_SNAPSHOT, 0, NULL, 2000);
+            CDBG("%s: prepare snapshot done opcode = %d, rc= %d\n", __func__, opcode, rc);
+            break;
+
         default:
             break;
         }