QCamera2: process auto scene detection update

After got auto scene detection update through Meta data stream,
process and callback it to up-layer

Change-Id: I8e1ed06ec4456201b729f1367ec79cd565beed34
diff --git a/QCamera2/HAL/QCamera2HWI.cpp b/QCamera2/HAL/QCamera2HWI.cpp
index 3ae9c33..a774f2a 100644
--- a/QCamera2/HAL/QCamera2HWI.cpp
+++ b/QCamera2/HAL/QCamera2HWI.cpp
@@ -2669,6 +2669,64 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : processASDUpdate
+ *
+ * DESCRIPTION: process ASD update event
+ *
+ * PARAMETERS :
+ *   @scene: selected scene mode
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCamera2HardwareInterface::processASDUpdate(cam_auto_scene_t scene)
+{
+    //set ASD parameter
+    mParameters.set(QCameraParameters::KEY_SELECTED_AUTO_SCENE, mParameters.getASDStateString(scene));
+
+    size_t data_len = sizeof(cam_auto_scene_t);
+    size_t buffer_len = 1 *sizeof(int)       //meta type
+                      + 1 *sizeof(int)       //data len
+                      + data_len;            //data
+    camera_memory_t *asdBuffer = mGetMemory(-1,
+                                             buffer_len,
+                                             1,
+                                             mCallbackCookie);
+    if ( NULL == asdBuffer ) {
+        ALOGE("%s: Not enough memory for histogram data", __func__);
+        return NO_MEMORY;
+    }
+
+    int *pASDData = (int *)asdBuffer->data;
+    if (pASDData == NULL) {
+        ALOGE("%s: memory data ptr is NULL", __func__);
+        return UNKNOWN_ERROR;
+    }
+
+    pASDData[0] = CAMERA_META_DATA_ASD;
+    pASDData[1] = data_len;
+    pASDData[2] = scene;
+
+    qcamera_callback_argm_t cbArg;
+    memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
+    cbArg.cb_type = QCAMERA_DATA_CALLBACK;
+    cbArg.msg_type = CAMERA_MSG_META_DATA;
+    cbArg.data = asdBuffer;
+    cbArg.user_data = asdBuffer;
+    cbArg.cookie = this;
+    cbArg.release_cb = releaseCameraMemory;
+    int32_t rc = m_cbNotifier.notifyCallback(cbArg);
+    if (rc != NO_ERROR) {
+        ALOGE("%s: fail sending notification", __func__);
+        asdBuffer->release(asdBuffer);
+    }
+    return NO_ERROR;
+
+}
+
+
+/*===========================================================================
  * FUNCTION   : processJpegNotify
  *
  * DESCRIPTION: process jpeg event
diff --git a/QCamera2/HAL/QCamera2HWI.h b/QCamera2/HAL/QCamera2HWI.h
index 3a9ee70..4d0b7c4 100644
--- a/QCamera2/HAL/QCamera2HWI.h
+++ b/QCamera2/HAL/QCamera2HWI.h
@@ -308,6 +308,7 @@
     int32_t processAutoFocusEvent(cam_auto_focus_data_t &focus_data);
     int32_t processZoomEvent(cam_crop_data_t &crop_info);
     int32_t processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state);
+    int32_t processASDUpdate(cam_auto_scene_t scene);
     int32_t processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_job);
 
     int32_t sendEvtNotify(int32_t msg_type, int32_t ext1, int32_t ext2);
diff --git a/QCamera2/HAL/QCamera2HWICallbacks.cpp b/QCamera2/HAL/QCamera2HWICallbacks.cpp
index e590d31..271e8b4 100644
--- a/QCamera2/HAL/QCamera2HWICallbacks.cpp
+++ b/QCamera2/HAL/QCamera2HWICallbacks.cpp
@@ -317,6 +317,7 @@
     pme->dumpFrameToFile(stream, frame, QCAMERA_DUMP_FRM_PREVIEW);
 
     // Display the buffer.
+    ALOGV("%p displayBuffer %d E", pme, idx);
     int dequeuedIdx = memory->displayBuffer(idx);
     if (dequeuedIdx < 0 || dequeuedIdx >= memory->getCnt()) {
         ALOGD("%s: Invalid dequeued buffer index %d from display",
@@ -944,6 +945,25 @@
         pme->mExifParams.sensor_params = pMetaData->sensor_params;
     }
 
+    if (pMetaData->is_asd_decision_valid) {
+        qcamera_sm_internal_evt_payload_t *payload =
+            (qcamera_sm_internal_evt_payload_t *)malloc(sizeof(qcamera_sm_internal_evt_payload_t));
+        if (NULL != payload) {
+            memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
+            payload->evt_type = QCAMERA_INTERNAL_EVT_ASD_UPDATE;
+            payload->asd_data = pMetaData->scene;
+            int32_t rc = pme->processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
+            if (rc != NO_ERROR) {
+                ALOGE("%s: processEvt prep_snapshot failed", __func__);
+                free(payload);
+                payload = NULL;
+
+            }
+        } else {
+            ALOGE("%s: No memory for prep_snapshot qcamera_sm_internal_evt_payload_t", __func__);
+        }
+    }
+
     stream->bufDone(frame->buf_idx);
     free(super_frame);
 
diff --git a/QCamera2/HAL/QCameraParameters.cpp b/QCamera2/HAL/QCameraParameters.cpp
index 1c4f320..eeebef5 100644
--- a/QCamera2/HAL/QCameraParameters.cpp
+++ b/QCamera2/HAL/QCameraParameters.cpp
@@ -281,6 +281,8 @@
 const char QCameraParameters::FLIP_MODE_H[] = "flip-h";
 const char QCameraParameters::FLIP_MODE_VH[] = "flip-vh";
 
+const char QCameraParameters::KEY_SELECTED_AUTO_SCENE[] = "selected-auto-scene";
+
 static const char* portrait = "portrait";
 static const char* landscape = "landscape";
 
@@ -5924,6 +5926,38 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : getASDStateString
+ *
+ * DESCRIPTION: get ASD result in string format
+ *
+ * PARAMETERS :
+ *   @scene : selected scene mode
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+ const char *QCameraParameters::getASDStateString(cam_auto_scene_t scene)
+{
+    switch (scene) {
+      case S_NORMAL :
+        return "Normal";
+      case S_SCENERY:
+        return "Scenery";
+      case S_PORTRAIT:
+        return "Portrait";
+      case S_PORTRAIT_BACKLIGHT:
+        return "Portrait-Backlight";
+      case S_SCENERY_BACKLIGHT:
+        return "Scenery-Backlight";
+      case S_BACKLIGHT:
+        return "Backlight";
+      default:
+        return "<Unknown!>";
+      }
+}
+
+/*===========================================================================
  * FUNCTION   : parseNDimVector
  *
  * DESCRIPTION: helper function to parse a string like "(1, 2, 3, 4, ..., N)"
diff --git a/QCamera2/HAL/QCameraParameters.h b/QCamera2/HAL/QCameraParameters.h
index 4e048f2..7ffe992 100644
--- a/QCamera2/HAL/QCameraParameters.h
+++ b/QCamera2/HAL/QCameraParameters.h
@@ -344,6 +344,8 @@
     static const char FLIP_MODE_H[];
     static const char FLIP_MODE_VH[];
 
+    static const char KEY_SELECTED_AUTO_SCENE[];
+
     enum {
         CAMERA_ORIENTATION_UNKNOWN = 0,
         CAMERA_ORIENTATION_PORTRAIT = 1,
@@ -435,6 +437,7 @@
     bool isVideoFlipChanged() { return m_bVideoFlipChanged; };
     bool isSnapshotFlipChanged() { return m_bSnapshotFlipChanged; };
 
+    const char *getASDStateString(cam_auto_scene_t scene);
 private:
     int32_t setPreviewSize(const QCameraParameters& );
     int32_t setVideoSize(const QCameraParameters& );
diff --git a/QCamera2/HAL/QCameraStateMachine.cpp b/QCamera2/HAL/QCameraStateMachine.cpp
index 507f974..cc72381 100644
--- a/QCamera2/HAL/QCameraStateMachine.cpp
+++ b/QCamera2/HAL/QCameraStateMachine.cpp
@@ -1201,6 +1201,9 @@
             case QCAMERA_INTERNAL_EVT_CROP_INFO:
                 rc = m_parent->processZoomEvent(internal_evt->crop_data);
                 break;
+            case QCAMERA_INTERNAL_EVT_ASD_UPDATE:
+                rc = m_parent->processASDUpdate(internal_evt->asd_data);
+                break;
             default:
                 ALOGE("%s: Invalid internal event %d in state(%d)",
                             __func__, internal_evt->evt_type, m_state);
@@ -1335,6 +1338,9 @@
             case QCAMERA_INTERNAL_EVT_CROP_INFO:
                 rc = m_parent->processZoomEvent(internal_evt->crop_data);
                 break;
+            case QCAMERA_INTERNAL_EVT_ASD_UPDATE:
+                rc = m_parent->processASDUpdate(internal_evt->asd_data);
+                break;
             default:
                 ALOGE("%s: Invalid internal event %d in state(%d)",
                             __func__, internal_evt->evt_type, m_state);
@@ -1628,6 +1634,9 @@
             case QCAMERA_INTERNAL_EVT_CROP_INFO:
                 rc = m_parent->processZoomEvent(internal_evt->crop_data);
                 break;
+            case QCAMERA_INTERNAL_EVT_ASD_UPDATE:
+                rc = m_parent->processASDUpdate(internal_evt->asd_data);
+                break;
             default:
                 break;
             }
@@ -1980,6 +1989,9 @@
             case QCAMERA_INTERNAL_EVT_CROP_INFO:
                 rc = m_parent->processZoomEvent(internal_evt->crop_data);
                 break;
+            case QCAMERA_INTERNAL_EVT_ASD_UPDATE:
+                rc = m_parent->processASDUpdate(internal_evt->asd_data);
+                break;
             default:
                 break;
             }
@@ -2307,6 +2319,9 @@
             case QCAMERA_INTERNAL_EVT_CROP_INFO:
                 rc = m_parent->processZoomEvent(internal_evt->crop_data);
                 break;
+            case QCAMERA_INTERNAL_EVT_ASD_UPDATE:
+                rc = m_parent->processASDUpdate(internal_evt->asd_data);
+                break;
             default:
                 break;
             }
@@ -2656,6 +2671,9 @@
             case QCAMERA_INTERNAL_EVT_CROP_INFO:
                 rc = m_parent->processZoomEvent(internal_evt->crop_data);
                 break;
+            case QCAMERA_INTERNAL_EVT_ASD_UPDATE:
+                rc = m_parent->processASDUpdate(internal_evt->asd_data);
+                break;
             default:
                 break;
             }
diff --git a/QCamera2/HAL/QCameraStateMachine.h b/QCamera2/HAL/QCameraStateMachine.h
index 665c0ca..4e89346 100644
--- a/QCamera2/HAL/QCameraStateMachine.h
+++ b/QCamera2/HAL/QCameraStateMachine.h
@@ -135,6 +135,7 @@
     QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT, // face detection result
     QCAMERA_INTERNAL_EVT_HISTOGRAM_STATS,    // histogram
     QCAMERA_INTERNAL_EVT_CROP_INFO,          // crop info
+    QCAMERA_INTERNAL_EVT_ASD_UPDATE,         // asd update result
     QCAMERA_INTERNAL_EVT_MAX
 } qcamera_internal_evt_type_t;
 
@@ -146,6 +147,7 @@
         cam_face_detection_data_t faces_data;
         cam_hist_stats_t stats_data;
         cam_crop_data_t crop_data;
+        cam_auto_scene_t asd_data;
     };
 } qcamera_sm_internal_evt_payload_t;
 
diff --git a/QCamera2/stack/common/cam_types.h b/QCamera2/stack/common/cam_types.h
index 2fbd8ce..b9934b8 100644
--- a/QCamera2/stack/common/cam_types.h
+++ b/QCamera2/stack/common/cam_types.h
@@ -695,6 +695,16 @@
     uint32_t max_frame_idx;
 } cam_frame_idx_range_t;
 
+typedef enum {
+  S_NORMAL = 0,
+  S_SCENERY,
+  S_PORTRAIT,
+  S_PORTRAIT_BACKLIGHT,
+  S_SCENERY_BACKLIGHT,
+  S_BACKLIGHT,
+  S_MAX,
+} cam_auto_scene_t;
+
 typedef  struct {
     float aperture_value;
 } cam_sensor_params_t;
@@ -729,6 +739,8 @@
 
     uint32_t is_hdr_scene_data_valid;
     cam_asd_hdr_scene_data_t hdr_scene_data;
+    uint8_t is_asd_decision_valid;
+    cam_auto_scene_t scene; //scene type as decided by ASD
 
     char private_metadata[MAX_METADATA_PAYLOAD_SIZE];